Blame view

fs/fuse/inode.c 41.2 KB
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1
2
  /*
    FUSE: Filesystem in Userspace
1729a16c2   Miklos Szeredi   fuse: style fixes
3
    Copyright (C) 2001-2008  Miklos Szeredi <miklos@szeredi.hu>
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
4
5
6
7
8
9
10
11
12
13
  
    This program can be distributed under the terms of the GNU GPL.
    See the file COPYING.
  */
  
  #include "fuse_i.h"
  
  #include <linux/pagemap.h>
  #include <linux/slab.h>
  #include <linux/file.h>
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
14
15
16
  #include <linux/seq_file.h>
  #include <linux/init.h>
  #include <linux/module.h>
487ea5af6   Csaba Henk   fuse: limit user-...
17
  #include <linux/moduleparam.h>
c30da2e98   David Howells   fuse: convert to ...
18
19
  #include <linux/fs_context.h>
  #include <linux/fs_parser.h>
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
20
  #include <linux/statfs.h>
9c8ef5614   Miklos Szeredi   [PATCH] fuse: scr...
21
  #include <linux/random.h>
e8edc6e03   Alexey Dobriyan   Detach sched.h fr...
22
  #include <linux/sched.h>
dbd561d23   Miklos Szeredi   fuse: add export ...
23
  #include <linux/exportfs.h>
60bcc88ad   Seth Forshee   fuse: Add posix A...
24
  #include <linux/posix_acl.h>
0b6e9ea04   Seth Forshee   fuse: Add support...
25
  #include <linux/pid_namespace.h>
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
26
27
28
29
  
  MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
  MODULE_DESCRIPTION("Filesystem in Userspace");
  MODULE_LICENSE("GPL");
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
30
  static struct kmem_cache *fuse_inode_cachep;
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
31
32
  struct list_head fuse_conn_list;
  DEFINE_MUTEX(fuse_mutex);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
33

e4dca7b7a   Kees Cook   treewide: Fix fun...
34
  static int set_global_limit(const char *val, const struct kernel_param *kp);
487ea5af6   Csaba Henk   fuse: limit user-...
35

79a9d9943   Csaba Henk   fuse: add fusectl...
36
  unsigned max_user_bgreq;
487ea5af6   Csaba Henk   fuse: limit user-...
37
38
39
40
41
42
  module_param_call(max_user_bgreq, set_global_limit, param_get_uint,
  		  &max_user_bgreq, 0644);
  __MODULE_PARM_TYPE(max_user_bgreq, "uint");
  MODULE_PARM_DESC(max_user_bgreq,
   "Global limit for the maximum number of backgrounded requests an "
   "unprivileged user can set");
79a9d9943   Csaba Henk   fuse: add fusectl...
43
  unsigned max_user_congthresh;
487ea5af6   Csaba Henk   fuse: limit user-...
44
45
46
47
48
49
  module_param_call(max_user_congthresh, set_global_limit, param_get_uint,
  		  &max_user_congthresh, 0644);
  __MODULE_PARM_TYPE(max_user_congthresh, "uint");
  MODULE_PARM_DESC(max_user_congthresh,
   "Global limit for the maximum congestion threshold an "
   "unprivileged user can set");
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
50
  #define FUSE_SUPER_MAGIC 0x65735546
d1875dbaa   Miklos Szeredi   mount options: fi...
51
  #define FUSE_DEFAULT_BLKSIZE 512
7a6d3c8b3   Csaba Henk   fuse: make the nu...
52
53
54
55
56
  /** Maximum number of outstanding background requests */
  #define FUSE_DEFAULT_MAX_BACKGROUND 12
  
  /** Congestion starts at 75% of maximum */
  #define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4)
c30da2e98   David Howells   fuse: convert to ...
57
58
59
  #ifdef CONFIG_BLOCK
  static struct file_system_type fuseblk_fs_type;
  #endif
a2daff680   Randy Dunlap   fuse: fix non-ANS...
60
  struct fuse_forget_link *fuse_alloc_forget(void)
07e77dca8   Miklos Szeredi   fuse: separate qu...
61
  {
dc69e98c2   Khazhismel Kumykov   fuse: kmemcg acco...
62
  	return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL_ACCOUNT);
07e77dca8   Miklos Szeredi   fuse: separate qu...
63
  }
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
64
65
  static struct inode *fuse_alloc_inode(struct super_block *sb)
  {
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
66
  	struct fuse_inode *fi;
9031a69cf   zhangliguang   fuse: clean up fu...
67
68
  	fi = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL);
  	if (!fi)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
69
  		return NULL;
0a0898cf4   Miklos Szeredi   [PATCH] fuse: use...
70
  	fi->i_time = 0;
2f1e81965   Miklos Szeredi   fuse: allow fine ...
71
  	fi->inval_mask = 0;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
72
  	fi->nodeid = 0;
9e6268db4   Miklos Szeredi   [PATCH] FUSE - re...
73
  	fi->nlookup = 0;
fbee36b92   John Muir   fuse: fix uniniti...
74
  	fi->attr_version = 0;
45c72cd73   Pavel Shilovsky   fuse: fix stat ca...
75
  	fi->orig_ino = 0;
4582a4ab2   Feng Shuo   FUSE: Adapt readd...
76
  	fi->state = 0;
5c672ab3f   Miklos Szeredi   fuse: serialize d...
77
  	mutex_init(&fi->mutex);
6ae330cad   Vivek Goyal   virtiofs: seriali...
78
  	init_rwsem(&fi->i_mmap_sem);
f15ecfef0   Kirill Tkhai   fuse: Introduce f...
79
  	spin_lock_init(&fi->lock);
07e77dca8   Miklos Szeredi   fuse: separate qu...
80
  	fi->forget = fuse_alloc_forget();
c2d0ad00d   Vivek Goyal   virtiofs: impleme...
81
82
83
84
85
  	if (!fi->forget)
  		goto out_free;
  
  	if (IS_ENABLED(CONFIG_FUSE_DAX) && !fuse_dax_inode_alloc(sb, fi))
  		goto out_free_forget;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
86

9031a69cf   zhangliguang   fuse: clean up fu...
87
  	return &fi->inode;
c2d0ad00d   Vivek Goyal   virtiofs: impleme...
88
89
90
91
92
93
  
  out_free_forget:
  	kfree(fi->forget);
  out_free:
  	kmem_cache_free(fuse_inode_cachep, fi);
  	return NULL;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
94
  }
9baf28bbf   Al Viro   fuse: switch to -...
95
  static void fuse_free_inode(struct inode *inode)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
96
  {
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
97
  	struct fuse_inode *fi = get_fuse_inode(inode);
9baf28bbf   Al Viro   fuse: switch to -...
98

5c672ab3f   Miklos Szeredi   fuse: serialize d...
99
  	mutex_destroy(&fi->mutex);
07e77dca8   Miklos Szeredi   fuse: separate qu...
100
  	kfree(fi->forget);
c2d0ad00d   Vivek Goyal   virtiofs: impleme...
101
102
103
  #ifdef CONFIG_FUSE_DAX
  	kfree(fi->dax);
  #endif
9baf28bbf   Al Viro   fuse: switch to -...
104
  	kmem_cache_free(fuse_inode_cachep, fi);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
105
  }
b57922d97   Al Viro   convert remaining...
106
  static void fuse_evict_inode(struct inode *inode)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
107
  {
9baf28bbf   Al Viro   fuse: switch to -...
108
  	struct fuse_inode *fi = get_fuse_inode(inode);
91b0abe36   Johannes Weiner   mm + fs: store sh...
109
  	truncate_inode_pages_final(&inode->i_data);
dbd5768f8   Jan Kara   vfs: Rename end_w...
110
  	clear_inode(inode);
1751e8a6c   Linus Torvalds   Rename superblock...
111
  	if (inode->i_sb->s_flags & SB_ACTIVE) {
1e9a4ed93   Miklos Szeredi   [PATCH] FUSE - mo...
112
  		struct fuse_conn *fc = get_fuse_conn(inode);
c2d0ad00d   Vivek Goyal   virtiofs: impleme...
113
114
115
  
  		if (FUSE_IS_DAX(inode))
  			fuse_dax_inode_cleanup(inode);
1866d779d   Max Reitz   fuse: Allow fuse_...
116
117
118
119
120
  		if (fi->nlookup) {
  			fuse_queue_forget(fc, fi->forget, fi->nodeid,
  					  fi->nlookup);
  			fi->forget = NULL;
  		}
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
121
  	}
36cf9ae54   Miklos Szeredi   fuse: fix bad inode
122
  	if (S_ISREG(inode->i_mode) && !fuse_is_bad(inode)) {
9baf28bbf   Al Viro   fuse: switch to -...
123
124
125
  		WARN_ON(!list_empty(&fi->write_files));
  		WARN_ON(!list_empty(&fi->queued_writes));
  	}
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
126
  }
0189a2d36   Miklos Szeredi   fuse: use ->recon...
127
  static int fuse_reconfigure(struct fs_context *fc)
714212593   Miklos Szeredi   [PATCH] fuse: add...
128
  {
0189a2d36   Miklos Szeredi   fuse: use ->recon...
129
  	struct super_block *sb = fc->root->d_sb;
02b9984d6   Theodore Ts'o   fs: push sync_fil...
130
  	sync_filesystem(sb);
0189a2d36   Miklos Szeredi   fuse: use ->recon...
131
  	if (fc->sb_flags & SB_MANDLOCK)
714212593   Miklos Szeredi   [PATCH] fuse: add...
132
133
134
135
  		return -EINVAL;
  
  	return 0;
  }
45c72cd73   Pavel Shilovsky   fuse: fix stat ca...
136
137
138
139
140
141
142
143
144
145
146
  /*
   * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
   * so that it will fit.
   */
  static ino_t fuse_squash_ino(u64 ino64)
  {
  	ino_t ino = (ino_t) ino64;
  	if (sizeof(ino_t) < sizeof(u64))
  		ino ^= ino64 >> (sizeof(u64) - sizeof(ino_t)) * 8;
  	return ino;
  }
3be5a52b3   Miklos Szeredi   fuse: support wri...
147
148
  void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
  				   u64 attr_valid)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
149
  {
9ffbb9162   Miklos Szeredi   [PATCH] fuse: fix...
150
  	struct fuse_conn *fc = get_fuse_conn(inode);
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
151
  	struct fuse_inode *fi = get_fuse_inode(inode);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
152

f15ecfef0   Kirill Tkhai   fuse: Introduce f...
153
  	lockdep_assert_held(&fi->lock);
4510d86fb   Kirill Tkhai   fuse: Convert fc-...
154
  	fi->attr_version = atomic64_inc_return(&fc->attr_version);
1fb69e781   Miklos Szeredi   fuse: fix race be...
155
  	fi->i_time = attr_valid;
2f1e81965   Miklos Szeredi   fuse: allow fine ...
156
  	WRITE_ONCE(fi->inval_mask, 0);
1fb69e781   Miklos Szeredi   fuse: fix race be...
157

45c72cd73   Pavel Shilovsky   fuse: fix stat ca...
158
  	inode->i_ino     = fuse_squash_ino(attr->ino);
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
159
  	inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
bfe868486   Miklos Szeredi   filesystems: add ...
160
  	set_nlink(inode, attr->nlink);
8cb08329b   Eric W. Biederman   fuse: Support fus...
161
162
  	inode->i_uid     = make_kuid(fc->user_ns, attr->uid);
  	inode->i_gid     = make_kgid(fc->user_ns, attr->gid);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
163
164
165
  	inode->i_blocks  = attr->blocks;
  	inode->i_atime.tv_sec   = attr->atime;
  	inode->i_atime.tv_nsec  = attr->atimensec;
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
166
167
168
169
  	/* mtime from server may be stale due to local buffered write */
  	if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) {
  		inode->i_mtime.tv_sec   = attr->mtime;
  		inode->i_mtime.tv_nsec  = attr->mtimensec;
31f3267b4   Maxim Patlasov   fuse: trust kerne...
170
171
  		inode->i_ctime.tv_sec   = attr->ctime;
  		inode->i_ctime.tv_nsec  = attr->ctimensec;
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
172
  	}
e00d2c2d4   Miklos Szeredi   fuse: truncate on...
173

0e9663ee4   Miklos Szeredi   fuse: add blksize...
174
175
176
177
  	if (attr->blksize != 0)
  		inode->i_blkbits = ilog2(attr->blksize);
  	else
  		inode->i_blkbits = inode->i_sb->s_blocksize_bits;
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
178
179
180
181
182
183
  	/*
  	 * Don't set the sticky bit in i_mode, unless we want the VFS
  	 * to check permissions.  This prevents failures due to the
  	 * check in may_delete().
  	 */
  	fi->orig_i_mode = inode->i_mode;
29433a299   Miklos Szeredi   fuse: get rid of ...
184
  	if (!fc->default_permissions)
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
185
  		inode->i_mode &= ~S_ISVTX;
45c72cd73   Pavel Shilovsky   fuse: fix stat ca...
186
187
  
  	fi->orig_ino = attr->ino;
3be5a52b3   Miklos Szeredi   fuse: support wri...
188
189
190
191
192
193
194
  }
  
  void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
  			    u64 attr_valid, u64 attr_version)
  {
  	struct fuse_conn *fc = get_fuse_conn(inode);
  	struct fuse_inode *fi = get_fuse_inode(inode);
8373200b1   Pavel Emelyanov   fuse: Trust kerne...
195
  	bool is_wb = fc->writeback_cache;
3be5a52b3   Miklos Szeredi   fuse: support wri...
196
  	loff_t oldsize;
a64ba10f6   Arnd Bergmann   fuse: convert las...
197
  	struct timespec64 old_mtime;
3be5a52b3   Miklos Szeredi   fuse: support wri...
198

f15ecfef0   Kirill Tkhai   fuse: Introduce f...
199
  	spin_lock(&fi->lock);
06a7c3c27   Maxim Patlasov   fuse: hotfix trun...
200
201
  	if ((attr_version != 0 && fi->attr_version > attr_version) ||
  	    test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
f15ecfef0   Kirill Tkhai   fuse: Introduce f...
202
  		spin_unlock(&fi->lock);
3be5a52b3   Miklos Szeredi   fuse: support wri...
203
204
  		return;
  	}
a64ba10f6   Arnd Bergmann   fuse: convert las...
205
  	old_mtime = inode->i_mtime;
3be5a52b3   Miklos Szeredi   fuse: support wri...
206
  	fuse_change_attributes_common(inode, attr, attr_valid);
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
207

e00d2c2d4   Miklos Szeredi   fuse: truncate on...
208
  	oldsize = inode->i_size;
8373200b1   Pavel Emelyanov   fuse: Trust kerne...
209
210
211
212
213
214
215
  	/*
  	 * In case of writeback_cache enabled, the cached writes beyond EOF
  	 * extend local i_size without keeping userspace server in sync. So,
  	 * attr->size coming from server can be stale. We cannot trust it.
  	 */
  	if (!is_wb || !S_ISREG(inode->i_mode))
  		i_size_write(inode, attr->size);
f15ecfef0   Kirill Tkhai   fuse: Introduce f...
216
  	spin_unlock(&fi->lock);
e00d2c2d4   Miklos Szeredi   fuse: truncate on...
217

8373200b1   Pavel Emelyanov   fuse: Trust kerne...
218
  	if (!is_wb && S_ISREG(inode->i_mode)) {
eed2179ef   Brian Foster   fuse: invalidate ...
219
220
221
  		bool inval = false;
  
  		if (oldsize != attr->size) {
7caef2676   Kirill A. Shutemov   truncate: drop 'o...
222
  			truncate_pagecache(inode, attr->size);
ad2ba64dd   Kirill Smelkov   fuse: allow files...
223
224
  			if (!fc->explicit_inval_data)
  				inval = true;
eed2179ef   Brian Foster   fuse: invalidate ...
225
  		} else if (fc->auto_inval_data) {
a64ba10f6   Arnd Bergmann   fuse: convert las...
226
  			struct timespec64 new_mtime = {
eed2179ef   Brian Foster   fuse: invalidate ...
227
228
229
230
231
232
233
234
  				.tv_sec = attr->mtime,
  				.tv_nsec = attr->mtimensec,
  			};
  
  			/*
  			 * Auto inval mode also checks and invalidates if mtime
  			 * has changed.
  			 */
a64ba10f6   Arnd Bergmann   fuse: convert las...
235
  			if (!timespec64_equal(&old_mtime, &new_mtime))
eed2179ef   Brian Foster   fuse: invalidate ...
236
237
238
239
240
  				inval = true;
  		}
  
  		if (inval)
  			invalidate_inode_pages2(inode->i_mapping);
e00d2c2d4   Miklos Szeredi   fuse: truncate on...
241
  	}
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
242
243
244
245
246
  }
  
  static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
  {
  	inode->i_mode = attr->mode & S_IFMT;
9ffbb9162   Miklos Szeredi   [PATCH] fuse: fix...
247
  	inode->i_size = attr->size;
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
248
249
  	inode->i_mtime.tv_sec  = attr->mtime;
  	inode->i_mtime.tv_nsec = attr->mtimensec;
31f3267b4   Maxim Patlasov   fuse: trust kerne...
250
251
  	inode->i_ctime.tv_sec  = attr->ctime;
  	inode->i_ctime.tv_nsec = attr->ctimensec;
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
252
253
  	if (S_ISREG(inode->i_mode)) {
  		fuse_init_common(inode);
b6aeadeda   Miklos Szeredi   [PATCH] FUSE - fi...
254
  		fuse_init_file_inode(inode);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
255
256
257
258
259
260
261
262
263
  	} else if (S_ISDIR(inode->i_mode))
  		fuse_init_dir(inode);
  	else if (S_ISLNK(inode->i_mode))
  		fuse_init_symlink(inode);
  	else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
  		 S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
  		fuse_init_common(inode);
  		init_special_inode(inode, inode->i_mode,
  				   new_decode_dev(attr->rdev));
39ee059af   Miklos Szeredi   [PATCH] fuse: che...
264
265
  	} else
  		BUG();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
266
  }
fcee216be   Max Reitz   fuse: split fuse_...
267
  static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
268
  {
b48badf01   Miklos Szeredi   fuse: fix node ID...
269
  	u64 nodeid = *(u64 *) _nodeidp;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
270
271
272
273
274
275
276
277
  	if (get_node_id(inode) == nodeid)
  		return 1;
  	else
  		return 0;
  }
  
  static int fuse_inode_set(struct inode *inode, void *_nodeidp)
  {
b48badf01   Miklos Szeredi   fuse: fix node ID...
278
  	u64 nodeid = *(u64 *) _nodeidp;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
279
280
281
  	get_fuse_inode(inode)->nodeid = nodeid;
  	return 0;
  }
b48badf01   Miklos Szeredi   fuse: fix node ID...
282
  struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
1fb69e781   Miklos Szeredi   fuse: fix race be...
283
284
  			int generation, struct fuse_attr *attr,
  			u64 attr_valid, u64 attr_version)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
285
286
  {
  	struct inode *inode;
9e6268db4   Miklos Szeredi   [PATCH] FUSE - re...
287
  	struct fuse_inode *fi;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
288
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
289

bf109c640   Max Reitz   fuse: implement c...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  	/*
  	 * Auto mount points get their node id from the submount root, which is
  	 * not a unique identifier within this filesystem.
  	 *
  	 * To avoid conflicts, do not place submount points into the inode hash
  	 * table.
  	 */
  	if (fc->auto_submounts && (attr->flags & FUSE_ATTR_SUBMOUNT) &&
  	    S_ISDIR(attr->mode)) {
  		inode = new_inode(sb);
  		if (!inode)
  			return NULL;
  
  		fuse_init_inode(inode, attr);
  		get_fuse_inode(inode)->nodeid = nodeid;
  		inode->i_flags |= S_AUTOMOUNT;
  		goto done;
  	}
  
  retry:
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
310
311
312
313
314
  	inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
  	if (!inode)
  		return NULL;
  
  	if ((inode->i_state & I_NEW)) {
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
315
  		inode->i_flags |= S_NOATIME;
d31433c8b   Maxim Patlasov   fuse: do not use ...
316
  		if (!fc->writeback_cache || !S_ISREG(attr->mode))
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
317
  			inode->i_flags |= S_NOCMTIME;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
318
  		inode->i_generation = generation;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
319
320
321
  		fuse_init_inode(inode, attr);
  		unlock_new_inode(inode);
  	} else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
322
  		/* Inode has changed type, any I/O on the old should fail */
36cf9ae54   Miklos Szeredi   fuse: fix bad inode
323
  		fuse_make_bad(inode);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
324
  		iput(inode);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
325
326
  		goto retry;
  	}
bf109c640   Max Reitz   fuse: implement c...
327
  done:
9e6268db4   Miklos Szeredi   [PATCH] FUSE - re...
328
  	fi = get_fuse_inode(inode);
c9d8f5f06   Kirill Tkhai   fuse: Protect fi-...
329
  	spin_lock(&fi->lock);
1729a16c2   Miklos Szeredi   fuse: style fixes
330
  	fi->nlookup++;
c9d8f5f06   Kirill Tkhai   fuse: Protect fi-...
331
  	spin_unlock(&fi->lock);
1fb69e781   Miklos Szeredi   fuse: fix race be...
332
  	fuse_change_attributes(inode, attr, attr_valid, attr_version);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
333
334
  	return inode;
  }
fcee216be   Max Reitz   fuse: split fuse_...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
  struct inode *fuse_ilookup(struct fuse_conn *fc, u64 nodeid,
  			   struct fuse_mount **fm)
  {
  	struct fuse_mount *fm_iter;
  	struct inode *inode;
  
  	WARN_ON(!rwsem_is_locked(&fc->killsb));
  	list_for_each_entry(fm_iter, &fc->mounts, fc_entry) {
  		if (!fm_iter->sb)
  			continue;
  
  		inode = ilookup5(fm_iter->sb, nodeid, fuse_inode_eq, &nodeid);
  		if (inode) {
  			if (fm)
  				*fm = fm_iter;
  			return inode;
  		}
  	}
  
  	return NULL;
  }
  
  int fuse_reverse_inval_inode(struct fuse_conn *fc, u64 nodeid,
3b463ae0c   John Muir   fuse: invalidatio...
358
359
  			     loff_t offset, loff_t len)
  {
5ddd9ced9   Miklos Szeredi   fuse: update attr...
360
  	struct fuse_inode *fi;
3b463ae0c   John Muir   fuse: invalidatio...
361
362
363
  	struct inode *inode;
  	pgoff_t pg_start;
  	pgoff_t pg_end;
fcee216be   Max Reitz   fuse: split fuse_...
364
  	inode = fuse_ilookup(fc, nodeid, NULL);
3b463ae0c   John Muir   fuse: invalidatio...
365
366
  	if (!inode)
  		return -ENOENT;
5ddd9ced9   Miklos Szeredi   fuse: update attr...
367
368
369
370
  	fi = get_fuse_inode(inode);
  	spin_lock(&fi->lock);
  	fi->attr_version = atomic64_inc_return(&fc->attr_version);
  	spin_unlock(&fi->lock);
3b463ae0c   John Muir   fuse: invalidatio...
371
  	fuse_invalidate_attr(inode);
60bcc88ad   Seth Forshee   fuse: Add posix A...
372
  	forget_all_cached_acls(inode);
3b463ae0c   John Muir   fuse: invalidatio...
373
  	if (offset >= 0) {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
374
  		pg_start = offset >> PAGE_SHIFT;
3b463ae0c   John Muir   fuse: invalidatio...
375
376
377
  		if (len <= 0)
  			pg_end = -1;
  		else
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
378
  			pg_end = (offset + len - 1) >> PAGE_SHIFT;
3b463ae0c   John Muir   fuse: invalidatio...
379
380
381
382
383
384
  		invalidate_inode_pages2_range(inode->i_mapping,
  					      pg_start, pg_end);
  	}
  	iput(inode);
  	return 0;
  }
63576c13b   Miklos Szeredi   fuse: fix initial...
385
  bool fuse_lock_inode(struct inode *inode)
5c672ab3f   Miklos Szeredi   fuse: serialize d...
386
  {
63576c13b   Miklos Szeredi   fuse: fix initial...
387
388
389
  	bool locked = false;
  
  	if (!get_fuse_conn(inode)->parallel_dirops) {
5c672ab3f   Miklos Szeredi   fuse: serialize d...
390
  		mutex_lock(&get_fuse_inode(inode)->mutex);
63576c13b   Miklos Szeredi   fuse: fix initial...
391
392
393
394
  		locked = true;
  	}
  
  	return locked;
5c672ab3f   Miklos Szeredi   fuse: serialize d...
395
  }
63576c13b   Miklos Szeredi   fuse: fix initial...
396
  void fuse_unlock_inode(struct inode *inode, bool locked)
5c672ab3f   Miklos Szeredi   fuse: serialize d...
397
  {
63576c13b   Miklos Szeredi   fuse: fix initial...
398
  	if (locked)
5c672ab3f   Miklos Szeredi   fuse: serialize d...
399
400
  		mutex_unlock(&get_fuse_inode(inode)->mutex);
  }
42faad996   Al Viro   [PATCH] restore s...
401
  static void fuse_umount_begin(struct super_block *sb)
69a53bf26   Miklos Szeredi   [PATCH] fuse: add...
402
  {
15c8e72e8   Vivek Goyal   fuse: allow skipp...
403
404
405
406
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
  
  	if (!fc->no_force_umount)
  		fuse_abort_conn(fc);
69a53bf26   Miklos Szeredi   [PATCH] fuse: add...
407
  }
fcee216be   Max Reitz   fuse: split fuse_...
408
  static void fuse_send_destroy(struct fuse_mount *fm)
0ec7ca41f   Miklos Szeredi   [PATCH] fuse: add...
409
  {
fcee216be   Max Reitz   fuse: split fuse_...
410
  	if (fm->fc->conn_init) {
1ccd1ea24   Miklos Szeredi   fuse: convert des...
411
412
413
414
415
  		FUSE_ARGS(args);
  
  		args.opcode = FUSE_DESTROY;
  		args.force = true;
  		args.nocreds = true;
fcee216be   Max Reitz   fuse: split fuse_...
416
  		fuse_simple_request(fm, &args);
0ec7ca41f   Miklos Szeredi   [PATCH] fuse: add...
417
418
  	}
  }
a325f9b92   Tejun Heo   fuse: update fuse...
419
420
  static void fuse_put_super(struct super_block *sb)
  {
fcee216be   Max Reitz   fuse: split fuse_...
421
  	struct fuse_mount *fm = get_fuse_mount_super(sb);
a325f9b92   Tejun Heo   fuse: update fuse...
422

fcee216be   Max Reitz   fuse: split fuse_...
423
  	fuse_mount_put(fm);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
424
  }
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
425
426
427
428
  static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
  {
  	stbuf->f_type    = FUSE_SUPER_MAGIC;
  	stbuf->f_bsize   = attr->bsize;
de5f12025   Miklos Szeredi   [PATCH] fuse: add...
429
  	stbuf->f_frsize  = attr->frsize;
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
430
431
432
433
434
435
436
437
  	stbuf->f_blocks  = attr->blocks;
  	stbuf->f_bfree   = attr->bfree;
  	stbuf->f_bavail  = attr->bavail;
  	stbuf->f_files   = attr->files;
  	stbuf->f_ffree   = attr->ffree;
  	stbuf->f_namelen = attr->namelen;
  	/* fsid is left zero */
  }
726c33422   David Howells   [PATCH] VFS: Perm...
438
  static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
439
  {
726c33422   David Howells   [PATCH] VFS: Perm...
440
  	struct super_block *sb = dentry->d_sb;
fcee216be   Max Reitz   fuse: split fuse_...
441
  	struct fuse_mount *fm = get_fuse_mount_super(sb);
7078187a7   Miklos Szeredi   fuse: introduce f...
442
  	FUSE_ARGS(args);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
443
444
  	struct fuse_statfs_out outarg;
  	int err;
fcee216be   Max Reitz   fuse: split fuse_...
445
  	if (!fuse_allow_current_process(fm->fc)) {
e57ac6837   Miklos Szeredi   fuse: fix allowin...
446
447
448
  		buf->f_type = FUSE_SUPER_MAGIC;
  		return 0;
  	}
de5f12025   Miklos Szeredi   [PATCH] fuse: add...
449
  	memset(&outarg, 0, sizeof(outarg));
d5b485435   Miklos Szeredi   fuse: flatten 'st...
450
451
452
453
454
455
  	args.in_numargs = 0;
  	args.opcode = FUSE_STATFS;
  	args.nodeid = get_node_id(d_inode(dentry));
  	args.out_numargs = 1;
  	args.out_args[0].size = sizeof(outarg);
  	args.out_args[0].value = &outarg;
fcee216be   Max Reitz   fuse: split fuse_...
456
  	err = fuse_simple_request(fm, &args);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
457
458
  	if (!err)
  		convert_fuse_statfs(buf, &outarg.st);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
459
460
  	return err;
  }
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
461
  enum {
c30da2e98   David Howells   fuse: convert to ...
462
463
  	OPT_SOURCE,
  	OPT_SUBTYPE,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
464
465
466
  	OPT_FD,
  	OPT_ROOTMODE,
  	OPT_USER_ID,
87729a551   Miklos Szeredi   [PATCH] FUSE: tig...
467
  	OPT_GROUP_ID,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
468
469
  	OPT_DEFAULT_PERMISSIONS,
  	OPT_ALLOW_OTHER,
db50b96c0   Miklos Szeredi   [PATCH] FUSE - re...
470
  	OPT_MAX_READ,
d80916140   Miklos Szeredi   [PATCH] fuse: add...
471
  	OPT_BLKSIZE,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
472
473
  	OPT_ERR
  };
d7167b149   Al Viro   fs_parse: fold fs...
474
  static const struct fs_parameter_spec fuse_fs_parameters[] = {
c30da2e98   David Howells   fuse: convert to ...
475
476
477
478
479
480
481
482
483
  	fsparam_string	("source",		OPT_SOURCE),
  	fsparam_u32	("fd",			OPT_FD),
  	fsparam_u32oct	("rootmode",		OPT_ROOTMODE),
  	fsparam_u32	("user_id",		OPT_USER_ID),
  	fsparam_u32	("group_id",		OPT_GROUP_ID),
  	fsparam_flag	("default_permissions",	OPT_DEFAULT_PERMISSIONS),
  	fsparam_flag	("allow_other",		OPT_ALLOW_OTHER),
  	fsparam_u32	("max_read",		OPT_MAX_READ),
  	fsparam_u32	("blksize",		OPT_BLKSIZE),
c7eb68696   David Howells   vfs: subtype hand...
484
  	fsparam_string	("subtype",		OPT_SUBTYPE),
c30da2e98   David Howells   fuse: convert to ...
485
486
  	{}
  };
c30da2e98   David Howells   fuse: convert to ...
487
  static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
233a01fa9   Miklos Szeredi   fuse: handle larg...
488
  {
c30da2e98   David Howells   fuse: convert to ...
489
490
491
  	struct fs_parse_result result;
  	struct fuse_fs_context *ctx = fc->fs_private;
  	int opt;
b330966f7   Miklos Szeredi   fuse: reject opti...
492
493
494
495
496
497
498
499
500
501
  	if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
  		/*
  		 * Ignore options coming from mount(MS_REMOUNT) for backward
  		 * compatibility.
  		 */
  		if (fc->oldapi)
  			return 0;
  
  		return invalfc(fc, "No changes allowed in reconfigure");
  	}
e8b20a474   Miklos Szeredi   fuse: ignore 'dat...
502

d7167b149   Al Viro   fs_parse: fold fs...
503
  	opt = fs_parse(fc, fuse_fs_parameters, param, &result);
c30da2e98   David Howells   fuse: convert to ...
504
505
506
507
508
509
  	if (opt < 0)
  		return opt;
  
  	switch (opt) {
  	case OPT_SOURCE:
  		if (fc->source)
2e28c49ea   Al Viro   fuse: switch to u...
510
  			return invalfc(fc, "Multiple sources specified");
c30da2e98   David Howells   fuse: convert to ...
511
512
513
514
515
516
  		fc->source = param->string;
  		param->string = NULL;
  		break;
  
  	case OPT_SUBTYPE:
  		if (ctx->subtype)
2e28c49ea   Al Viro   fuse: switch to u...
517
  			return invalfc(fc, "Multiple subtypes specified");
c30da2e98   David Howells   fuse: convert to ...
518
519
520
521
522
523
  		ctx->subtype = param->string;
  		param->string = NULL;
  		return 0;
  
  	case OPT_FD:
  		ctx->fd = result.uint_32;
cabdb4fa2   zhengbin   fuse: use true,fa...
524
  		ctx->fd_present = true;
c30da2e98   David Howells   fuse: convert to ...
525
526
527
528
  		break;
  
  	case OPT_ROOTMODE:
  		if (!fuse_valid_type(result.uint_32))
2e28c49ea   Al Viro   fuse: switch to u...
529
  			return invalfc(fc, "Invalid rootmode");
c30da2e98   David Howells   fuse: convert to ...
530
  		ctx->rootmode = result.uint_32;
cabdb4fa2   zhengbin   fuse: use true,fa...
531
  		ctx->rootmode_present = true;
c30da2e98   David Howells   fuse: convert to ...
532
533
534
535
536
  		break;
  
  	case OPT_USER_ID:
  		ctx->user_id = make_kuid(fc->user_ns, result.uint_32);
  		if (!uid_valid(ctx->user_id))
2e28c49ea   Al Viro   fuse: switch to u...
537
  			return invalfc(fc, "Invalid user_id");
cabdb4fa2   zhengbin   fuse: use true,fa...
538
  		ctx->user_id_present = true;
c30da2e98   David Howells   fuse: convert to ...
539
540
541
542
543
  		break;
  
  	case OPT_GROUP_ID:
  		ctx->group_id = make_kgid(fc->user_ns, result.uint_32);
  		if (!gid_valid(ctx->group_id))
2e28c49ea   Al Viro   fuse: switch to u...
544
  			return invalfc(fc, "Invalid group_id");
cabdb4fa2   zhengbin   fuse: use true,fa...
545
  		ctx->group_id_present = true;
c30da2e98   David Howells   fuse: convert to ...
546
547
548
  		break;
  
  	case OPT_DEFAULT_PERMISSIONS:
cabdb4fa2   zhengbin   fuse: use true,fa...
549
  		ctx->default_permissions = true;
c30da2e98   David Howells   fuse: convert to ...
550
551
552
  		break;
  
  	case OPT_ALLOW_OTHER:
cabdb4fa2   zhengbin   fuse: use true,fa...
553
  		ctx->allow_other = true;
c30da2e98   David Howells   fuse: convert to ...
554
555
556
557
558
559
560
561
  		break;
  
  	case OPT_MAX_READ:
  		ctx->max_read = result.uint_32;
  		break;
  
  	case OPT_BLKSIZE:
  		if (!ctx->is_bdev)
2e28c49ea   Al Viro   fuse: switch to u...
562
  			return invalfc(fc, "blksize only supported for fuseblk");
c30da2e98   David Howells   fuse: convert to ...
563
564
565
566
567
  		ctx->blksize = result.uint_32;
  		break;
  
  	default:
  		return -EINVAL;
233a01fa9   Miklos Szeredi   fuse: handle larg...
568
  	}
c30da2e98   David Howells   fuse: convert to ...
569
570
  
  	return 0;
233a01fa9   Miklos Szeredi   fuse: handle larg...
571
  }
c30da2e98   David Howells   fuse: convert to ...
572
  static void fuse_free_fc(struct fs_context *fc)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
573
  {
c30da2e98   David Howells   fuse: convert to ...
574
  	struct fuse_fs_context *ctx = fc->fs_private;
5a5336827   Miklos Szeredi   [PATCH] fuse: str...
575

c30da2e98   David Howells   fuse: convert to ...
576
577
578
579
  	if (ctx) {
  		kfree(ctx->subtype);
  		kfree(ctx);
  	}
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
580
  }
34c80b1d9   Al Viro   vfs: switch ->sho...
581
  static int fuse_show_options(struct seq_file *m, struct dentry *root)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
582
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
583
584
  	struct super_block *sb = root->d_sb;
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
585

f4fd4ae35   Vivek Goyal   virtiofs: get rid...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
  	if (fc->legacy_opts_show) {
  		seq_printf(m, ",user_id=%u",
  			   from_kuid_munged(fc->user_ns, fc->user_id));
  		seq_printf(m, ",group_id=%u",
  			   from_kgid_munged(fc->user_ns, fc->group_id));
  		if (fc->default_permissions)
  			seq_puts(m, ",default_permissions");
  		if (fc->allow_other)
  			seq_puts(m, ",allow_other");
  		if (fc->max_read != ~0)
  			seq_printf(m, ",max_read=%u", fc->max_read);
  		if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE)
  			seq_printf(m, ",blksize=%lu", sb->s_blocksize);
  	}
1dd539577   Vivek Goyal   virtiofs: add a m...
600
601
602
603
  #ifdef CONFIG_FUSE_DAX
  	if (fc->dax)
  		seq_puts(m, ",dax");
  #endif
3f22c7467   Miklos Szeredi   virtio-fs: don't ...
604

d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
605
606
  	return 0;
  }
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
607
608
609
  static void fuse_iqueue_init(struct fuse_iqueue *fiq,
  			     const struct fuse_iqueue_ops *ops,
  			     void *priv)
f88996a93   Miklos Szeredi   fuse: separate ou...
610
611
  {
  	memset(fiq, 0, sizeof(struct fuse_iqueue));
76e43c8cc   Eric Biggers   fuse: fix deadloc...
612
  	spin_lock_init(&fiq->lock);
f88996a93   Miklos Szeredi   fuse: separate ou...
613
614
615
616
  	init_waitqueue_head(&fiq->waitq);
  	INIT_LIST_HEAD(&fiq->pending);
  	INIT_LIST_HEAD(&fiq->interrupts);
  	fiq->forget_list_tail = &fiq->forget_list_head;
e16714d87   Miklos Szeredi   fuse: duplicate -...
617
  	fiq->connected = 1;
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
618
619
  	fiq->ops = ops;
  	fiq->priv = priv;
f88996a93   Miklos Szeredi   fuse: separate ou...
620
  }
3a2b5b9cd   Miklos Szeredi   fuse: separate ou...
621
622
  static void fuse_pqueue_init(struct fuse_pqueue *fpq)
  {
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
623
  	unsigned int i;
45a91cb1a   Miklos Szeredi   fuse: pqueue locking
624
  	spin_lock_init(&fpq->lock);
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
625
626
  	for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
  		INIT_LIST_HEAD(&fpq->processing[i]);
3a2b5b9cd   Miklos Szeredi   fuse: separate ou...
627
  	INIT_LIST_HEAD(&fpq->io);
e96edd94d   Miklos Szeredi   fuse: duplicate -...
628
  	fpq->connected = 1;
3a2b5b9cd   Miklos Szeredi   fuse: separate ou...
629
  }
fcee216be   Max Reitz   fuse: split fuse_...
630
631
  void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
  		    struct user_namespace *user_ns,
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
632
  		    const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
633
  {
0d179aa59   Tejun Heo   fuse: separate ou...
634
635
  	memset(fc, 0, sizeof(*fc));
  	spin_lock_init(&fc->lock);
ae2dffa39   Kirill Tkhai   fuse: introduce f...
636
  	spin_lock_init(&fc->bg_lock);
314603f83   Alessio Balsini   FROMLIST: fuse: D...
637
  	spin_lock_init(&fc->passthrough_req_lock);
3b463ae0c   John Muir   fuse: invalidatio...
638
  	init_rwsem(&fc->killsb);
095fc40ac   Elena Reshetova   fuse: convert fus...
639
  	refcount_set(&fc->count, 1);
c3696046b   Miklos Szeredi   fuse: separate pq...
640
  	atomic_set(&fc->dev_count, 1);
0d179aa59   Tejun Heo   fuse: separate ou...
641
  	init_waitqueue_head(&fc->blocked_waitq);
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
642
  	fuse_iqueue_init(&fc->iq, fiq_ops, fiq_priv);
0d179aa59   Tejun Heo   fuse: separate ou...
643
644
  	INIT_LIST_HEAD(&fc->bg_queue);
  	INIT_LIST_HEAD(&fc->entry);
cc080e9e9   Miklos Szeredi   fuse: introduce p...
645
  	INIT_LIST_HEAD(&fc->devices);
314603f83   Alessio Balsini   FROMLIST: fuse: D...
646
  	idr_init(&fc->passthrough_req);
0d179aa59   Tejun Heo   fuse: separate ou...
647
  	atomic_set(&fc->num_waiting, 0);
7a6d3c8b3   Csaba Henk   fuse: make the nu...
648
649
  	fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
  	fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
75126f550   Miklos Szeredi   fuse: use atomic6...
650
  	atomic64_set(&fc->khctr, 0);
0d179aa59   Tejun Heo   fuse: separate ou...
651
  	fc->polled_files = RB_ROOT;
0aada8847   Maxim Patlasov   fuse: skip blocki...
652
  	fc->blocked = 0;
796523fb2   Maxim Patlasov   fuse: add flag fc...
653
  	fc->initialized = 0;
e16714d87   Miklos Szeredi   fuse: duplicate -...
654
  	fc->connected = 1;
4510d86fb   Kirill Tkhai   fuse: Convert fc-...
655
  	atomic64_set(&fc->attr_version, 1);
0d179aa59   Tejun Heo   fuse: separate ou...
656
  	get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
0b6e9ea04   Seth Forshee   fuse: Add support...
657
  	fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
8cb08329b   Eric W. Biederman   fuse: Support fus...
658
  	fc->user_ns = get_user_ns(user_ns);
8a3177db5   Miklos Szeredi   cuse: fix ioctl
659
  	fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
fcee216be   Max Reitz   fuse: split fuse_...
660
661
662
663
664
  
  	INIT_LIST_HEAD(&fc->mounts);
  	list_add(&fm->fc_entry, &fc->mounts);
  	fm->fc = fc;
  	refcount_set(&fm->count, 1);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
665
  }
0d179aa59   Tejun Heo   fuse: separate ou...
666
  EXPORT_SYMBOL_GPL(fuse_conn_init);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
667

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
668
669
  void fuse_conn_put(struct fuse_conn *fc)
  {
095fc40ac   Elena Reshetova   fuse: convert fus...
670
  	if (refcount_dec_and_test(&fc->count)) {
a62a8ef9d   Stefan Hajnoczi   virtio-fs: add vi...
671
  		struct fuse_iqueue *fiq = &fc->iq;
1dd539577   Vivek Goyal   virtiofs: add a m...
672
673
  		if (IS_ENABLED(CONFIG_FUSE_DAX))
  			fuse_dax_conn_free(fc);
a62a8ef9d   Stefan Hajnoczi   virtio-fs: add vi...
674
675
  		if (fiq->ops->release)
  			fiq->ops->release(fiq);
0b6e9ea04   Seth Forshee   fuse: Add support...
676
  		put_pid_ns(fc->pid_ns);
8cb08329b   Eric W. Biederman   fuse: Support fus...
677
  		put_user_ns(fc->user_ns);
43901aabd   Tejun Heo   fuse: add fuse_co...
678
  		fc->release(fc);
d2a85164a   Miklos Szeredi   [PATCH] fuse: fix...
679
  	}
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
680
  }
08cbf542b   Tejun Heo   fuse: export symb...
681
  EXPORT_SYMBOL_GPL(fuse_conn_put);
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
682
683
684
  
  struct fuse_conn *fuse_conn_get(struct fuse_conn *fc)
  {
095fc40ac   Elena Reshetova   fuse: convert fus...
685
  	refcount_inc(&fc->count);
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
686
687
  	return fc;
  }
08cbf542b   Tejun Heo   fuse: export symb...
688
  EXPORT_SYMBOL_GPL(fuse_conn_get);
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
689

fcee216be   Max Reitz   fuse: split fuse_...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
  void fuse_mount_put(struct fuse_mount *fm)
  {
  	if (refcount_dec_and_test(&fm->count)) {
  		if (fm->fc)
  			fuse_conn_put(fm->fc);
  		kfree(fm);
  	}
  }
  EXPORT_SYMBOL_GPL(fuse_mount_put);
  
  struct fuse_mount *fuse_mount_get(struct fuse_mount *fm)
  {
  	refcount_inc(&fm->count);
  	return fm;
  }
  EXPORT_SYMBOL_GPL(fuse_mount_get);
b93f858ab   Tejun Heo   fuse: add fuse_ p...
706
  static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
707
708
709
710
711
712
  {
  	struct fuse_attr attr;
  	memset(&attr, 0, sizeof(attr));
  
  	attr.mode = mode;
  	attr.ino = FUSE_ROOT_ID;
074406fa6   Miklos Szeredi   fuse: set i_nlink...
713
  	attr.nlink = 1;
1fb69e781   Miklos Szeredi   fuse: fix race be...
714
  	return fuse_iget(sb, 1, 0, &attr, 0, 0);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
715
  }
1729a16c2   Miklos Szeredi   fuse: style fixes
716
  struct fuse_inode_handle {
dbd561d23   Miklos Szeredi   fuse: add export ...
717
718
719
720
721
722
723
  	u64 nodeid;
  	u32 generation;
  };
  
  static struct dentry *fuse_get_dentry(struct super_block *sb,
  				      struct fuse_inode_handle *handle)
  {
33670fa29   Miklos Szeredi   fuse: nfs export ...
724
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
dbd561d23   Miklos Szeredi   fuse: add export ...
725
726
727
728
729
730
731
732
  	struct inode *inode;
  	struct dentry *entry;
  	int err = -ESTALE;
  
  	if (handle->nodeid == 0)
  		goto out_err;
  
  	inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &handle->nodeid);
33670fa29   Miklos Szeredi   fuse: nfs export ...
733
734
  	if (!inode) {
  		struct fuse_entry_out outarg;
13983d062   Al Viro   qstr: constify in...
735
  		const struct qstr name = QSTR_INIT(".", 1);
33670fa29   Miklos Szeredi   fuse: nfs export ...
736
737
738
  
  		if (!fc->export_support)
  			goto out_err;
33670fa29   Miklos Szeredi   fuse: nfs export ...
739
740
741
742
743
744
745
746
747
748
749
750
  		err = fuse_lookup_name(sb, handle->nodeid, &name, &outarg,
  				       &inode);
  		if (err && err != -ENOENT)
  			goto out_err;
  		if (err || !inode) {
  			err = -ESTALE;
  			goto out_err;
  		}
  		err = -EIO;
  		if (get_node_id(inode) != handle->nodeid)
  			goto out_iput;
  	}
dbd561d23   Miklos Szeredi   fuse: add export ...
751
752
753
  	err = -ESTALE;
  	if (inode->i_generation != handle->generation)
  		goto out_iput;
440037287   Christoph Hellwig   [PATCH] switch al...
754
  	entry = d_obtain_alias(inode);
c35eebe99   Al Viro   switch fuse
755
  	if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID)
dbd561d23   Miklos Szeredi   fuse: add export ...
756
  		fuse_invalidate_entry_cache(entry);
dbd561d23   Miklos Szeredi   fuse: add export ...
757
758
759
760
761
762
763
764
  
  	return entry;
  
   out_iput:
  	iput(inode);
   out_err:
  	return ERR_PTR(err);
  }
b0b0382bb   Al Viro   ->encode_fh() API...
765
766
  static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len,
  			   struct inode *parent)
dbd561d23   Miklos Szeredi   fuse: add export ...
767
  {
b0b0382bb   Al Viro   ->encode_fh() API...
768
  	int len = parent ? 6 : 3;
dbd561d23   Miklos Szeredi   fuse: add export ...
769
770
  	u64 nodeid;
  	u32 generation;
5fe0c2378   Aneesh Kumar K.V   exportfs: Return ...
771
772
  	if (*max_len < len) {
  		*max_len = len;
94e07a759   Namjae Jeon   fs: encode_fh: re...
773
  		return  FILEID_INVALID;
5fe0c2378   Aneesh Kumar K.V   exportfs: Return ...
774
  	}
dbd561d23   Miklos Szeredi   fuse: add export ...
775
776
777
778
779
780
781
  
  	nodeid = get_fuse_inode(inode)->nodeid;
  	generation = inode->i_generation;
  
  	fh[0] = (u32)(nodeid >> 32);
  	fh[1] = (u32)(nodeid & 0xffffffff);
  	fh[2] = generation;
b0b0382bb   Al Viro   ->encode_fh() API...
782
  	if (parent) {
dbd561d23   Miklos Szeredi   fuse: add export ...
783
784
  		nodeid = get_fuse_inode(parent)->nodeid;
  		generation = parent->i_generation;
dbd561d23   Miklos Szeredi   fuse: add export ...
785
786
787
788
789
790
791
  
  		fh[3] = (u32)(nodeid >> 32);
  		fh[4] = (u32)(nodeid & 0xffffffff);
  		fh[5] = generation;
  	}
  
  	*max_len = len;
b0b0382bb   Al Viro   ->encode_fh() API...
792
  	return parent ? 0x82 : 0x81;
dbd561d23   Miklos Szeredi   fuse: add export ...
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
  }
  
  static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
  		struct fid *fid, int fh_len, int fh_type)
  {
  	struct fuse_inode_handle handle;
  
  	if ((fh_type != 0x81 && fh_type != 0x82) || fh_len < 3)
  		return NULL;
  
  	handle.nodeid = (u64) fid->raw[0] << 32;
  	handle.nodeid |= (u64) fid->raw[1];
  	handle.generation = fid->raw[2];
  	return fuse_get_dentry(sb, &handle);
  }
  
  static struct dentry *fuse_fh_to_parent(struct super_block *sb,
  		struct fid *fid, int fh_len, int fh_type)
  {
  	struct fuse_inode_handle parent;
  
  	if (fh_type != 0x82 || fh_len < 6)
  		return NULL;
  
  	parent.nodeid = (u64) fid->raw[3] << 32;
  	parent.nodeid |= (u64) fid->raw[4];
  	parent.generation = fid->raw[5];
  	return fuse_get_dentry(sb, &parent);
  }
33670fa29   Miklos Szeredi   fuse: nfs export ...
822
823
  static struct dentry *fuse_get_parent(struct dentry *child)
  {
2b0143b5c   David Howells   VFS: normal files...
824
  	struct inode *child_inode = d_inode(child);
33670fa29   Miklos Szeredi   fuse: nfs export ...
825
826
827
828
  	struct fuse_conn *fc = get_fuse_conn(child_inode);
  	struct inode *inode;
  	struct dentry *parent;
  	struct fuse_entry_out outarg;
13983d062   Al Viro   qstr: constify in...
829
  	const struct qstr name = QSTR_INIT("..", 2);
33670fa29   Miklos Szeredi   fuse: nfs export ...
830
831
832
833
  	int err;
  
  	if (!fc->export_support)
  		return ERR_PTR(-ESTALE);
33670fa29   Miklos Szeredi   fuse: nfs export ...
834
835
  	err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode),
  			       &name, &outarg, &inode);
440037287   Christoph Hellwig   [PATCH] switch al...
836
837
838
  	if (err) {
  		if (err == -ENOENT)
  			return ERR_PTR(-ESTALE);
33670fa29   Miklos Szeredi   fuse: nfs export ...
839
  		return ERR_PTR(err);
33670fa29   Miklos Szeredi   fuse: nfs export ...
840
  	}
440037287   Christoph Hellwig   [PATCH] switch al...
841
842
  
  	parent = d_obtain_alias(inode);
c35eebe99   Al Viro   switch fuse
843
  	if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID)
33670fa29   Miklos Szeredi   fuse: nfs export ...
844
  		fuse_invalidate_entry_cache(parent);
33670fa29   Miklos Szeredi   fuse: nfs export ...
845
846
847
  
  	return parent;
  }
dbd561d23   Miklos Szeredi   fuse: add export ...
848
849
850
851
852
  
  static const struct export_operations fuse_export_operations = {
  	.fh_to_dentry	= fuse_fh_to_dentry,
  	.fh_to_parent	= fuse_fh_to_parent,
  	.encode_fh	= fuse_encode_fh,
33670fa29   Miklos Szeredi   fuse: nfs export ...
853
  	.get_parent	= fuse_get_parent,
dbd561d23   Miklos Szeredi   fuse: add export ...
854
  };
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
855
  static const struct super_operations fuse_super_operations = {
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
856
  	.alloc_inode    = fuse_alloc_inode,
9baf28bbf   Al Viro   fuse: switch to -...
857
  	.free_inode     = fuse_free_inode,
b57922d97   Al Viro   convert remaining...
858
  	.evict_inode	= fuse_evict_inode,
1e18bda86   Miklos Szeredi   fuse: add .write_...
859
  	.write_inode	= fuse_write_inode,
ead5f0b5f   Miklos Szeredi   fuse: delete inod...
860
  	.drop_inode	= generic_delete_inode,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
861
  	.put_super	= fuse_put_super,
69a53bf26   Miklos Szeredi   [PATCH] fuse: add...
862
  	.umount_begin	= fuse_umount_begin,
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
863
  	.statfs		= fuse_statfs,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
864
865
  	.show_options	= fuse_show_options,
  };
487ea5af6   Csaba Henk   fuse: limit user-...
866
867
  static void sanitize_global_limit(unsigned *limit)
  {
f22f812d5   Miklos Szeredi   fuse: fix request...
868
869
870
871
  	/*
  	 * The default maximum number of async requests is calculated to consume
  	 * 1/2^13 of the total memory, assuming 392 bytes per request.
  	 */
487ea5af6   Csaba Henk   fuse: limit user-...
872
  	if (*limit == 0)
f22f812d5   Miklos Szeredi   fuse: fix request...
873
  		*limit = ((totalram_pages() << PAGE_SHIFT) >> 13) / 392;
487ea5af6   Csaba Henk   fuse: limit user-...
874
875
876
877
  
  	if (*limit >= 1 << 16)
  		*limit = (1 << 16) - 1;
  }
e4dca7b7a   Kees Cook   treewide: Fix fun...
878
  static int set_global_limit(const char *val, const struct kernel_param *kp)
487ea5af6   Csaba Henk   fuse: limit user-...
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
  {
  	int rv;
  
  	rv = param_set_uint(val, kp);
  	if (rv)
  		return rv;
  
  	sanitize_global_limit((unsigned *)kp->arg);
  
  	return 0;
  }
  
  static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)
  {
  	int cap_sys_admin = capable(CAP_SYS_ADMIN);
  
  	if (arg->minor < 13)
  		return;
  
  	sanitize_global_limit(&max_user_bgreq);
  	sanitize_global_limit(&max_user_congthresh);
ae2dffa39   Kirill Tkhai   fuse: introduce f...
900
  	spin_lock(&fc->bg_lock);
487ea5af6   Csaba Henk   fuse: limit user-...
901
902
903
904
905
906
907
908
909
910
911
912
913
  	if (arg->max_background) {
  		fc->max_background = arg->max_background;
  
  		if (!cap_sys_admin && fc->max_background > max_user_bgreq)
  			fc->max_background = max_user_bgreq;
  	}
  	if (arg->congestion_threshold) {
  		fc->congestion_threshold = arg->congestion_threshold;
  
  		if (!cap_sys_admin &&
  		    fc->congestion_threshold > max_user_congthresh)
  			fc->congestion_threshold = max_user_congthresh;
  	}
ae2dffa39   Kirill Tkhai   fuse: introduce f...
914
  	spin_unlock(&fc->bg_lock);
487ea5af6   Csaba Henk   fuse: limit user-...
915
  }
615047eff   Miklos Szeredi   fuse: convert ini...
916
917
918
919
920
  struct fuse_init_args {
  	struct fuse_args args;
  	struct fuse_init_in in;
  	struct fuse_init_out out;
  };
fcee216be   Max Reitz   fuse: split fuse_...
921
  static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
615047eff   Miklos Szeredi   fuse: convert ini...
922
  			       int error)
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
923
  {
fcee216be   Max Reitz   fuse: split fuse_...
924
  	struct fuse_conn *fc = fm->fc;
615047eff   Miklos Szeredi   fuse: convert ini...
925
926
  	struct fuse_init_args *ia = container_of(args, typeof(*ia), args);
  	struct fuse_init_out *arg = &ia->out;
fd1a1dc6f   Stefan Hajnoczi   virtiofs: impleme...
927
  	bool ok = true;
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
928

615047eff   Miklos Szeredi   fuse: convert ini...
929
  	if (error || arg->major != FUSE_KERNEL_VERSION)
fd1a1dc6f   Stefan Hajnoczi   virtiofs: impleme...
930
  		ok = false;
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
931
  	else {
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
932
  		unsigned long ra_pages;
487ea5af6   Csaba Henk   fuse: limit user-...
933
  		process_init_limits(fc, arg);
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
934
  		if (arg->minor >= 6) {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
935
  			ra_pages = arg->max_readahead / PAGE_SIZE;
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
936
937
  			if (arg->flags & FUSE_ASYNC_READ)
  				fc->async_read = 1;
714212593   Miklos Szeredi   [PATCH] fuse: add...
938
939
  			if (!(arg->flags & FUSE_POSIX_LOCKS))
  				fc->no_lock = 1;
37fb3a30b   Miklos Szeredi   fuse: fix flock
940
941
942
  			if (arg->minor >= 17) {
  				if (!(arg->flags & FUSE_FLOCK_LOCKS))
  					fc->no_flock = 1;
24114504c   Miklos Szeredi   fuse: fix flock b...
943
944
945
  			} else {
  				if (!(arg->flags & FUSE_POSIX_LOCKS))
  					fc->no_flock = 1;
37fb3a30b   Miklos Szeredi   fuse: fix flock
946
  			}
6ff958edb   Miklos Szeredi   fuse: add atomic ...
947
948
  			if (arg->flags & FUSE_ATOMIC_O_TRUNC)
  				fc->atomic_o_trunc = 1;
33670fa29   Miklos Szeredi   fuse: nfs export ...
949
950
951
952
953
  			if (arg->minor >= 9) {
  				/* LOOKUP has dependency on proto version */
  				if (arg->flags & FUSE_EXPORT_SUPPORT)
  					fc->export_support = 1;
  			}
78bb6cb9a   Miklos Szeredi   fuse: add flag to...
954
955
  			if (arg->flags & FUSE_BIG_WRITES)
  				fc->big_writes = 1;
e0a43ddcc   Miklos Szeredi   fuse: allow umask...
956
957
  			if (arg->flags & FUSE_DONT_MASK)
  				fc->dont_mask = 1;
72d0d248c   Brian Foster   fuse: add FUSE_AU...
958
959
  			if (arg->flags & FUSE_AUTO_INVAL_DATA)
  				fc->auto_inval_data = 1;
ad2ba64dd   Kirill Smelkov   fuse: allow files...
960
961
  			else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA)
  				fc->explicit_inval_data = 1;
28420dad2   Miklos Szeredi   fuse: fix readdir...
962
  			if (arg->flags & FUSE_DO_READDIRPLUS) {
0b05b1838   Anand V. Avati   fuse: implement N...
963
  				fc->do_readdirplus = 1;
28420dad2   Miklos Szeredi   fuse: fix readdir...
964
965
966
  				if (arg->flags & FUSE_READDIRPLUS_AUTO)
  					fc->readdirplus_auto = 1;
  			}
60b9df7a5   Miklos Szeredi   fuse: add flag to...
967
968
  			if (arg->flags & FUSE_ASYNC_DIO)
  				fc->async_dio = 1;
4d99ff8f1   Pavel Emelyanov   fuse: Turn writeb...
969
970
  			if (arg->flags & FUSE_WRITEBACK_CACHE)
  				fc->writeback_cache = 1;
5c672ab3f   Miklos Szeredi   fuse: serialize d...
971
972
  			if (arg->flags & FUSE_PARALLEL_DIROPS)
  				fc->parallel_dirops = 1;
5e940c1dd   Miklos Szeredi   fuse: handle kill...
973
974
  			if (arg->flags & FUSE_HANDLE_KILLPRIV)
  				fc->handle_killpriv = 1;
e27c9d387   Miklos Szeredi   fuse: fuse: add t...
975
  			if (arg->time_gran && arg->time_gran <= 1000000000)
fcee216be   Max Reitz   fuse: split fuse_...
976
  				fm->sb->s_time_gran = arg->time_gran;
60bcc88ad   Seth Forshee   fuse: Add posix A...
977
  			if ((arg->flags & FUSE_POSIX_ACL)) {
29433a299   Miklos Szeredi   fuse: get rid of ...
978
  				fc->default_permissions = 1;
60bcc88ad   Seth Forshee   fuse: Add posix A...
979
  				fc->posix_acl = 1;
fcee216be   Max Reitz   fuse: split fuse_...
980
  				fm->sb->s_xattr = fuse_acl_xattr_handlers;
60bcc88ad   Seth Forshee   fuse: Add posix A...
981
  			}
5571f1e65   Dan Schatzberg   fuse: enable cach...
982
983
  			if (arg->flags & FUSE_CACHE_SYMLINKS)
  				fc->cache_symlinks = 1;
3b7008b22   Szymon Lukasz   fuse: return -ECO...
984
985
  			if (arg->flags & FUSE_ABORT_ERROR)
  				fc->abort_err = 1;
5da784cce   Constantine Shulyupin   fuse: add max_pag...
986
987
988
989
990
  			if (arg->flags & FUSE_MAX_PAGES) {
  				fc->max_pages =
  					min_t(unsigned int, FUSE_MAX_MAX_PAGES,
  					max_t(unsigned int, arg->max_pages, 1));
  			}
fd1a1dc6f   Stefan Hajnoczi   virtiofs: impleme...
991
992
993
994
995
  			if (IS_ENABLED(CONFIG_FUSE_DAX) &&
  			    arg->flags & FUSE_MAP_ALIGNMENT &&
  			    !fuse_dax_check_alignment(fc, arg->map_alignment)) {
  				ok = false;
  			}
314603f83   Alessio Balsini   FROMLIST: fuse: D...
996
997
998
999
1000
1001
  			if (arg->flags & FUSE_PASSTHROUGH) {
  				fc->passthrough = 1;
  				/* Prevent further stacking */
  				fm->sb->s_stack_depth =
  					FILESYSTEM_MAX_STACK_DEPTH;
  			}
714212593   Miklos Szeredi   [PATCH] fuse: add...
1002
  		} else {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
1003
  			ra_pages = fc->max_read / PAGE_SIZE;
714212593   Miklos Szeredi   [PATCH] fuse: add...
1004
  			fc->no_lock = 1;
37fb3a30b   Miklos Szeredi   fuse: fix flock
1005
  			fc->no_flock = 1;
714212593   Miklos Szeredi   [PATCH] fuse: add...
1006
  		}
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
1007

fcee216be   Max Reitz   fuse: split fuse_...
1008
1009
  		fm->sb->s_bdi->ra_pages =
  				min(fm->sb->s_bdi->ra_pages, ra_pages);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
1010
1011
  		fc->minor = arg->minor;
  		fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
f948d5643   Miklos Szeredi   fuse: fix thinko ...
1012
  		fc->max_write = max_t(unsigned, 4096, fc->max_write);
0ec7ca41f   Miklos Szeredi   [PATCH] fuse: add...
1013
  		fc->conn_init = 1;
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
1014
  	}
615047eff   Miklos Szeredi   fuse: convert ini...
1015
  	kfree(ia);
fd1a1dc6f   Stefan Hajnoczi   virtiofs: impleme...
1016
1017
1018
1019
  	if (!ok) {
  		fc->conn_init = 0;
  		fc->conn_error = 1;
  	}
9759bd518   Miklos Szeredi   fuse: add memory ...
1020
  	fuse_set_initialized(fc);
08a53cdce   Miklos Szeredi   [PATCH] fuse: acc...
1021
  	wake_up_all(&fc->blocked_waitq);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
1022
  }
fcee216be   Max Reitz   fuse: split fuse_...
1023
  void fuse_send_init(struct fuse_mount *fm)
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
1024
  {
615047eff   Miklos Szeredi   fuse: convert ini...
1025
  	struct fuse_init_args *ia;
095da6cbb   Miklos Szeredi   [PATCH] fuse: fix...
1026

615047eff   Miklos Szeredi   fuse: convert ini...
1027
1028
1029
1030
  	ia = kzalloc(sizeof(*ia), GFP_KERNEL | __GFP_NOFAIL);
  
  	ia->in.major = FUSE_KERNEL_VERSION;
  	ia->in.minor = FUSE_KERNEL_MINOR_VERSION;
fcee216be   Max Reitz   fuse: split fuse_...
1031
  	ia->in.max_readahead = fm->sb->s_bdi->ra_pages * PAGE_SIZE;
615047eff   Miklos Szeredi   fuse: convert ini...
1032
1033
  	ia->in.flags |=
  		FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
37fb3a30b   Miklos Szeredi   fuse: fix flock
1034
  		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
69fe05c90   Miklos Szeredi   fuse: add missing...
1035
  		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
9446385f0   Wei Fang   fuse: fix wrong a...
1036
  		FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
4d99ff8f1   Pavel Emelyanov   fuse: Turn writeb...
1037
  		FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
5c672ab3f   Miklos Szeredi   fuse: serialize d...
1038
  		FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT |
3b7008b22   Szymon Lukasz   fuse: return -ECO...
1039
  		FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL |
d9a9ea94f   Chad Austin   fuse: support cli...
1040
  		FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS |
314603f83   Alessio Balsini   FROMLIST: fuse: D...
1041
1042
  		FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA |
  		FUSE_PASSTHROUGH;
fd1a1dc6f   Stefan Hajnoczi   virtiofs: impleme...
1043
  #ifdef CONFIG_FUSE_DAX
fcee216be   Max Reitz   fuse: split fuse_...
1044
  	if (fm->fc->dax)
fd1a1dc6f   Stefan Hajnoczi   virtiofs: impleme...
1045
1046
  		ia->in.flags |= FUSE_MAP_ALIGNMENT;
  #endif
bf109c640   Max Reitz   fuse: implement c...
1047
1048
  	if (fm->fc->auto_submounts)
  		ia->in.flags |= FUSE_SUBMOUNTS;
615047eff   Miklos Szeredi   fuse: convert ini...
1049
1050
1051
1052
1053
  	ia->args.opcode = FUSE_INIT;
  	ia->args.in_numargs = 1;
  	ia->args.in_args[0].size = sizeof(ia->in);
  	ia->args.in_args[0].value = &ia->in;
  	ia->args.out_numargs = 1;
3ad2f3fbb   Daniel Mack   tree-wide: Assort...
1054
  	/* Variable length argument used for backward compatibility
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
1055
1056
  	   with interface version < 7.5.  Rest of init_out is zeroed
  	   by do_get_request(), so a short reply is not a problem */
cabdb4fa2   zhengbin   fuse: use true,fa...
1057
  	ia->args.out_argvar = true;
615047eff   Miklos Szeredi   fuse: convert ini...
1058
1059
1060
1061
1062
  	ia->args.out_args[0].size = sizeof(ia->out);
  	ia->args.out_args[0].value = &ia->out;
  	ia->args.force = true;
  	ia->args.nocreds = true;
  	ia->args.end = process_init_reply;
fcee216be   Max Reitz   fuse: split fuse_...
1063
1064
  	if (fuse_simple_background(fm, &ia->args, GFP_KERNEL) != 0)
  		process_init_reply(fm, &ia->args, -ENOTCONN);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
1065
  }
95a84cdb1   Vivek Goyal   fuse: export fuse...
1066
  EXPORT_SYMBOL_GPL(fuse_send_init);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
1067

314603f83   Alessio Balsini   FROMLIST: fuse: D...
1068
1069
  static int free_fuse_passthrough(int id, void *p, void *data)
  {
89d676706   Alessio Balsini   FROMLIST: fuse: P...
1070
1071
1072
1073
  	struct fuse_passthrough *passthrough = (struct fuse_passthrough *)p;
  
  	fuse_passthrough_release(passthrough);
  	kfree(p);
314603f83   Alessio Balsini   FROMLIST: fuse: D...
1074
1075
  	return 0;
  }
783863d64   Miklos Szeredi   fuse: dissociate ...
1076
  void fuse_free_conn(struct fuse_conn *fc)
43901aabd   Tejun Heo   fuse: add fuse_co...
1077
  {
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1078
  	WARN_ON(!list_empty(&fc->devices));
314603f83   Alessio Balsini   FROMLIST: fuse: D...
1079
1080
  	idr_for_each(&fc->passthrough_req, free_fuse_passthrough, NULL);
  	idr_destroy(&fc->passthrough_req);
dd3e2c55a   Al Viro   fuse: rcu-delay f...
1081
  	kfree_rcu(fc, rcu);
43901aabd   Tejun Heo   fuse: add fuse_co...
1082
  }
783863d64   Miklos Szeredi   fuse: dissociate ...
1083
  EXPORT_SYMBOL_GPL(fuse_free_conn);
43901aabd   Tejun Heo   fuse: add fuse_co...
1084

a325f9b92   Tejun Heo   fuse: update fuse...
1085
1086
1087
  static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
  {
  	int err;
5f7f7543f   Jan Kara   fuse: Convert to ...
1088
  	char *suffix = "";
a325f9b92   Tejun Heo   fuse: update fuse...
1089

69c8ebf83   Jan Kara   fuseblk: Fix warn...
1090
  	if (sb->s_bdev) {
5f7f7543f   Jan Kara   fuse: Convert to ...
1091
  		suffix = "-fuseblk";
69c8ebf83   Jan Kara   fuseblk: Fix warn...
1092
1093
1094
1095
1096
1097
1098
  		/*
  		 * sb->s_bdi points to blkdev's bdi however we want to redirect
  		 * it to our private bdi...
  		 */
  		bdi_put(sb->s_bdi);
  		sb->s_bdi = &noop_backing_dev_info;
  	}
5f7f7543f   Jan Kara   fuse: Convert to ...
1099
1100
  	err = super_setup_bdi_name(sb, "%u:%u%s", MAJOR(fc->dev),
  				   MINOR(fc->dev), suffix);
a325f9b92   Tejun Heo   fuse: update fuse...
1101
1102
  	if (err)
  		return err;
5f7f7543f   Jan Kara   fuse: Convert to ...
1103
  	/* fuse does it's own writeback accounting */
823423ef5   Christoph Hellwig   bdi: invert BDI_C...
1104
1105
  	sb->s_bdi->capabilities &= ~BDI_CAP_WRITEBACK_ACCT;
  	sb->s_bdi->capabilities |= BDI_CAP_STRICTLIMIT;
a325f9b92   Tejun Heo   fuse: update fuse...
1106

a325f9b92   Tejun Heo   fuse: update fuse...
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
  	/*
  	 * For a single fuse filesystem use max 1% of dirty +
  	 * writeback threshold.
  	 *
  	 * This gives about 1M of write buffer for memory maps on a
  	 * machine with 1G and 10% dirty_ratio, which should be more
  	 * than enough.
  	 *
  	 * Privileged users can raise it by writing to
  	 *
  	 *    /sys/class/bdi/<bdi>/max_ratio
  	 */
5f7f7543f   Jan Kara   fuse: Convert to ...
1119
  	bdi_set_max_ratio(sb->s_bdi, 1);
a325f9b92   Tejun Heo   fuse: update fuse...
1120
1121
1122
  
  	return 0;
  }
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1123
  struct fuse_dev *fuse_dev_alloc(void)
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1124
1125
  {
  	struct fuse_dev *fud;
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1126
  	struct list_head *pq;
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1127
1128
  
  	fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL);
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1129
1130
  	if (!fud)
  		return NULL;
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1131

be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1132
1133
1134
1135
  	pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL);
  	if (!pq) {
  		kfree(fud);
  		return NULL;
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1136
  	}
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1137
  	fud->pq.processing = pq;
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1138
  	fuse_pqueue_init(&fud->pq);
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1139
1140
1141
1142
1143
1144
1145
  	return fud;
  }
  EXPORT_SYMBOL_GPL(fuse_dev_alloc);
  
  void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc)
  {
  	fud->fc = fuse_conn_get(fc);
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1146
1147
1148
  	spin_lock(&fc->lock);
  	list_add_tail(&fud->entry, &fc->devices);
  	spin_unlock(&fc->lock);
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1149
1150
  }
  EXPORT_SYMBOL_GPL(fuse_dev_install);
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1151

0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1152
1153
1154
1155
1156
1157
1158
1159
1160
  struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc)
  {
  	struct fuse_dev *fud;
  
  	fud = fuse_dev_alloc();
  	if (!fud)
  		return NULL;
  
  	fuse_dev_install(fud, fc);
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1161
1162
  	return fud;
  }
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1163
  EXPORT_SYMBOL_GPL(fuse_dev_alloc_install);
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
  
  void fuse_dev_free(struct fuse_dev *fud)
  {
  	struct fuse_conn *fc = fud->fc;
  
  	if (fc) {
  		spin_lock(&fc->lock);
  		list_del(&fud->entry);
  		spin_unlock(&fc->lock);
  
  		fuse_conn_put(fc);
  	}
d72f70da6   Takeshi Misawa   fuse: Fix memory ...
1176
  	kfree(fud->pq.processing);
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1177
1178
1179
  	kfree(fud);
  }
  EXPORT_SYMBOL_GPL(fuse_dev_free);
1866d779d   Max Reitz   fuse: Allow fuse_...
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
  static void fuse_fill_attr_from_inode(struct fuse_attr *attr,
  				      const struct fuse_inode *fi)
  {
  	*attr = (struct fuse_attr){
  		.ino		= fi->inode.i_ino,
  		.size		= fi->inode.i_size,
  		.blocks		= fi->inode.i_blocks,
  		.atime		= fi->inode.i_atime.tv_sec,
  		.mtime		= fi->inode.i_mtime.tv_sec,
  		.ctime		= fi->inode.i_ctime.tv_sec,
  		.atimensec	= fi->inode.i_atime.tv_nsec,
  		.mtimensec	= fi->inode.i_mtime.tv_nsec,
  		.ctimensec	= fi->inode.i_ctime.tv_nsec,
  		.mode		= fi->inode.i_mode,
  		.nlink		= fi->inode.i_nlink,
  		.uid		= fi->inode.i_uid.val,
  		.gid		= fi->inode.i_gid.val,
  		.rdev		= fi->inode.i_rdev,
  		.blksize	= 1u << fi->inode.i_blkbits,
  	};
  }
  
  static void fuse_sb_defaults(struct super_block *sb)
  {
  	sb->s_magic = FUSE_SUPER_MAGIC;
  	sb->s_op = &fuse_super_operations;
  	sb->s_xattr = fuse_xattr_handlers;
  	sb->s_maxbytes = MAX_LFS_FILESIZE;
  	sb->s_time_gran = 1;
  	sb->s_export_op = &fuse_export_operations;
  	sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE;
  	if (sb->s_user_ns != &init_user_ns)
  		sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER;
  	sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION);
  
  	/*
  	 * If we are not in the initial user namespace posix
  	 * acls must be translated.
  	 */
  	if (sb->s_user_ns != &init_user_ns)
  		sb->s_xattr = fuse_no_acl_xattr_handlers;
  }
  
  int fuse_fill_super_submount(struct super_block *sb,
  			     struct fuse_inode *parent_fi)
  {
  	struct fuse_mount *fm = get_fuse_mount_super(sb);
  	struct super_block *parent_sb = parent_fi->inode.i_sb;
  	struct fuse_attr root_attr;
  	struct inode *root;
  
  	fuse_sb_defaults(sb);
  	fm->sb = sb;
  
  	WARN_ON(sb->s_bdi != &noop_backing_dev_info);
  	sb->s_bdi = bdi_get(parent_sb->s_bdi);
  
  	sb->s_xattr = parent_sb->s_xattr;
  	sb->s_time_gran = parent_sb->s_time_gran;
  	sb->s_blocksize = parent_sb->s_blocksize;
  	sb->s_blocksize_bits = parent_sb->s_blocksize_bits;
  	sb->s_subtype = kstrdup(parent_sb->s_subtype, GFP_KERNEL);
  	if (parent_sb->s_subtype && !sb->s_subtype)
  		return -ENOMEM;
  
  	fuse_fill_attr_from_inode(&root_attr, parent_fi);
  	root = fuse_iget(sb, parent_fi->nodeid, 0, &root_attr, 0, 0);
  	/*
  	 * This inode is just a duplicate, so it is not looked up and
  	 * its nlookup should not be incremented.  fuse_iget() does
  	 * that, though, so undo it here.
  	 */
  	get_fuse_inode(root)->nlookup--;
  	sb->s_d_op = &fuse_dentry_operations;
  	sb->s_root = d_make_root(root);
  	if (!sb->s_root)
  		return -ENOMEM;
  
  	return 0;
  }
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1260
  int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1261
  {
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1262
  	struct fuse_dev *fud = NULL;
fcee216be   Max Reitz   fuse: split fuse_...
1263
1264
  	struct fuse_mount *fm = get_fuse_mount_super(sb);
  	struct fuse_conn *fc = fm->fc;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1265
  	struct inode *root;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1266
  	struct dentry *root_dentry;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1267
  	int err;
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1268
  	err = -EINVAL;
1751e8a6c   Linus Torvalds   Rename superblock...
1269
  	if (sb->s_flags & SB_MANDLOCK)
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1270
  		goto err;
714212593   Miklos Szeredi   [PATCH] fuse: add...
1271

1866d779d   Max Reitz   fuse: Allow fuse_...
1272
  	fuse_sb_defaults(sb);
9e1f1de02   Al Viro   more conservative...
1273

0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1274
  	if (ctx->is_bdev) {
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1275
  #ifdef CONFIG_BLOCK
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1276
  		err = -EINVAL;
c30da2e98   David Howells   fuse: convert to ...
1277
  		if (!sb_set_blocksize(sb, ctx->blksize))
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1278
  			goto err;
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1279
  #endif
d80916140   Miklos Szeredi   [PATCH] fuse: add...
1280
  	} else {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
1281
1282
  		sb->s_blocksize = PAGE_SIZE;
  		sb->s_blocksize_bits = PAGE_SHIFT;
d80916140   Miklos Szeredi   [PATCH] fuse: add...
1283
  	}
c30da2e98   David Howells   fuse: convert to ...
1284
1285
1286
  
  	sb->s_subtype = ctx->subtype;
  	ctx->subtype = NULL;
1dd539577   Vivek Goyal   virtiofs: add a m...
1287
1288
1289
1290
1291
  	if (IS_ENABLED(CONFIG_FUSE_DAX)) {
  		err = fuse_dax_conn_alloc(fc, ctx->dax_dev);
  		if (err)
  			goto err;
  	}
e45b2546e   Eric W. Biederman   fuse: Ensure posi...
1292

7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1293
1294
1295
1296
  	if (ctx->fudptr) {
  		err = -ENOMEM;
  		fud = fuse_dev_alloc_install(fc);
  		if (!fud)
1dd539577   Vivek Goyal   virtiofs: add a m...
1297
  			goto err_free_dax;
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1298
  	}
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1299

a325f9b92   Tejun Heo   fuse: update fuse...
1300
  	fc->dev = sb->s_dev;
fcee216be   Max Reitz   fuse: split fuse_...
1301
  	fm->sb = sb;
a325f9b92   Tejun Heo   fuse: update fuse...
1302
1303
  	err = fuse_bdi_init(fc, sb);
  	if (err)
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1304
  		goto err_dev_free;
0d179aa59   Tejun Heo   fuse: separate ou...
1305

e0a43ddcc   Miklos Szeredi   fuse: allow umask...
1306
  	/* Handle umasking inside the fuse code */
1751e8a6c   Linus Torvalds   Rename superblock...
1307
  	if (sb->s_flags & SB_POSIXACL)
e0a43ddcc   Miklos Szeredi   fuse: allow umask...
1308
  		fc->dont_mask = 1;
1751e8a6c   Linus Torvalds   Rename superblock...
1309
  	sb->s_flags |= SB_POSIXACL;
e0a43ddcc   Miklos Szeredi   fuse: allow umask...
1310

c30da2e98   David Howells   fuse: convert to ...
1311
1312
1313
1314
  	fc->default_permissions = ctx->default_permissions;
  	fc->allow_other = ctx->allow_other;
  	fc->user_id = ctx->user_id;
  	fc->group_id = ctx->group_id;
f4fd4ae35   Vivek Goyal   virtiofs: get rid...
1315
  	fc->legacy_opts_show = ctx->legacy_opts_show;
1866d779d   Max Reitz   fuse: Allow fuse_...
1316
  	fc->max_read = max_t(unsigned int, 4096, ctx->max_read);
783863d64   Miklos Szeredi   fuse: dissociate ...
1317
  	fc->destroy = ctx->destroy;
15c8e72e8   Vivek Goyal   fuse: allow skipp...
1318
1319
  	fc->no_control = ctx->no_control;
  	fc->no_force_umount = ctx->no_force_umount;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1320

d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1321
  	err = -ENOMEM;
c30da2e98   David Howells   fuse: convert to ...
1322
  	root = fuse_get_root_inode(sb, ctx->rootmode);
0ce267ff9   Miklos Szeredi   fuse: fix root de...
1323
  	sb->s_d_op = &fuse_root_dentry_operations;
48fde701a   Al Viro   switch open-coded...
1324
1325
  	root_dentry = d_make_root(root);
  	if (!root_dentry)
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1326
  		goto err_dev_free;
0ce267ff9   Miklos Szeredi   fuse: fix root de...
1327
  	/* Root dentry doesn't have .d_revalidate */
c35eebe99   Al Viro   switch fuse
1328
  	sb->s_d_op = &fuse_dentry_operations;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1329

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1330
  	mutex_lock(&fuse_mutex);
8aa09a50b   Miklos Szeredi   [fuse] fix race b...
1331
  	err = -EINVAL;
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1332
  	if (ctx->fudptr && *ctx->fudptr)
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1333
  		goto err_unlock;
8aa09a50b   Miklos Szeredi   [fuse] fix race b...
1334

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1335
1336
1337
1338
1339
  	err = fuse_ctl_add_conn(fc);
  	if (err)
  		goto err_unlock;
  
  	list_add_tail(&fc->entry, &fuse_conn_list);
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1340
  	sb->s_root = root_dentry;
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1341
1342
  	if (ctx->fudptr)
  		*ctx->fudptr = fud;
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1343
  	mutex_unlock(&fuse_mutex);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1344
1345
1346
1347
1348
1349
  	return 0;
  
   err_unlock:
  	mutex_unlock(&fuse_mutex);
  	dput(root_dentry);
   err_dev_free:
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1350
1351
  	if (fud)
  		fuse_dev_free(fud);
1dd539577   Vivek Goyal   virtiofs: add a m...
1352
1353
1354
   err_free_dax:
  	if (IS_ENABLED(CONFIG_FUSE_DAX))
  		fuse_dax_conn_free(fc);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
   err:
  	return err;
  }
  EXPORT_SYMBOL_GPL(fuse_fill_super_common);
  
  static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc)
  {
  	struct fuse_fs_context *ctx = fsc->fs_private;
  	struct file *file;
  	int err;
  	struct fuse_conn *fc;
fcee216be   Max Reitz   fuse: split fuse_...
1366
  	struct fuse_mount *fm;
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
  
  	err = -EINVAL;
  	file = fget(ctx->fd);
  	if (!file)
  		goto err;
  
  	/*
  	 * Require mount to happen from the same user namespace which
  	 * opened /dev/fuse to prevent potential attacks.
  	 */
  	if ((file->f_op != &fuse_dev_operations) ||
  	    (file->f_cred->user_ns != sb->s_user_ns))
  		goto err_fput;
  	ctx->fudptr = &file->private_data;
  
  	fc = kmalloc(sizeof(*fc), GFP_KERNEL);
  	err = -ENOMEM;
  	if (!fc)
  		goto err_fput;
fcee216be   Max Reitz   fuse: split fuse_...
1386
1387
1388
1389
1390
1391
1392
  	fm = kzalloc(sizeof(*fm), GFP_KERNEL);
  	if (!fm) {
  		kfree(fc);
  		goto err_fput;
  	}
  
  	fuse_conn_init(fc, fm, sb->s_user_ns, &fuse_dev_fiq_ops, NULL);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1393
  	fc->release = fuse_free_conn;
fcee216be   Max Reitz   fuse: split fuse_...
1394
1395
  
  	sb->s_fs_info = fm;
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1396
1397
1398
1399
  
  	err = fuse_fill_super_common(sb, ctx);
  	if (err)
  		goto err_put_conn;
0720b3159   Miklos Szeredi   [PATCH] fuse: sim...
1400
1401
1402
1403
1404
1405
  	/*
  	 * atomic_dec_and_test() in fput() provides the necessary
  	 * memory barrier for file->private_data to be visible on all
  	 * CPUs after this
  	 */
  	fput(file);
fcee216be   Max Reitz   fuse: split fuse_...
1406
  	fuse_send_init(get_fuse_mount_super(sb));
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1407
  	return 0;
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1408
   err_put_conn:
fcee216be   Max Reitz   fuse: split fuse_...
1409
  	fuse_mount_put(fm);
543b8f866   Tetsuo Handa   fuse: don't keep ...
1410
  	sb->s_fs_info = NULL;
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1411
1412
1413
   err_fput:
  	fput(file);
   err:
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1414
1415
  	return err;
  }
c30da2e98   David Howells   fuse: convert to ...
1416
  static int fuse_get_tree(struct fs_context *fc)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1417
  {
c30da2e98   David Howells   fuse: convert to ...
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
  	struct fuse_fs_context *ctx = fc->fs_private;
  
  	if (!ctx->fd_present || !ctx->rootmode_present ||
  	    !ctx->user_id_present || !ctx->group_id_present)
  		return -EINVAL;
  
  #ifdef CONFIG_BLOCK
  	if (ctx->is_bdev)
  		return get_tree_bdev(fc, fuse_fill_super);
  #endif
  
  	return get_tree_nodev(fc, fuse_fill_super);
  }
  
  static const struct fs_context_operations fuse_context_ops = {
  	.free		= fuse_free_fc,
  	.parse_param	= fuse_parse_param,
0189a2d36   Miklos Szeredi   fuse: use ->recon...
1435
  	.reconfigure	= fuse_reconfigure,
c30da2e98   David Howells   fuse: convert to ...
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
  	.get_tree	= fuse_get_tree,
  };
  
  /*
   * Set up the filesystem mount context.
   */
  static int fuse_init_fs_context(struct fs_context *fc)
  {
  	struct fuse_fs_context *ctx;
  
  	ctx = kzalloc(sizeof(struct fuse_fs_context), GFP_KERNEL);
  	if (!ctx)
  		return -ENOMEM;
  
  	ctx->max_read = ~0;
  	ctx->blksize = FUSE_DEFAULT_BLKSIZE;
f4fd4ae35   Vivek Goyal   virtiofs: get rid...
1452
  	ctx->legacy_opts_show = true;
c30da2e98   David Howells   fuse: convert to ...
1453
1454
  
  #ifdef CONFIG_BLOCK
783863d64   Miklos Szeredi   fuse: dissociate ...
1455
  	if (fc->fs_type == &fuseblk_fs_type) {
c30da2e98   David Howells   fuse: convert to ...
1456
  		ctx->is_bdev = true;
783863d64   Miklos Szeredi   fuse: dissociate ...
1457
1458
  		ctx->destroy = true;
  	}
c30da2e98   David Howells   fuse: convert to ...
1459
1460
1461
1462
1463
  #endif
  
  	fc->fs_private = ctx;
  	fc->ops = &fuse_context_ops;
  	return 0;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1464
  }
fcee216be   Max Reitz   fuse: split fuse_...
1465
  bool fuse_mount_remove(struct fuse_mount *fm)
3b463ae0c   John Muir   fuse: invalidatio...
1466
  {
fcee216be   Max Reitz   fuse: split fuse_...
1467
1468
  	struct fuse_conn *fc = fm->fc;
  	bool last = false;
3b463ae0c   John Muir   fuse: invalidatio...
1469

fcee216be   Max Reitz   fuse: split fuse_...
1470
1471
1472
1473
1474
  	down_write(&fc->killsb);
  	list_del_init(&fm->fc_entry);
  	if (list_empty(&fc->mounts))
  		last = true;
  	up_write(&fc->killsb);
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1475

fcee216be   Max Reitz   fuse: split fuse_...
1476
1477
1478
  	return last;
  }
  EXPORT_SYMBOL_GPL(fuse_mount_remove);
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1479

fcee216be   Max Reitz   fuse: split fuse_...
1480
1481
1482
1483
1484
1485
1486
1487
1488
  void fuse_conn_destroy(struct fuse_mount *fm)
  {
  	struct fuse_conn *fc = fm->fc;
  
  	if (fc->destroy)
  		fuse_send_destroy(fm);
  
  	fuse_abort_conn(fc);
  	fuse_wait_aborted(fc);
413daa1a3   Miklos Szeredi   fuse: connection ...
1489
1490
1491
1492
1493
1494
  
  	if (!list_empty(&fc->entry)) {
  		mutex_lock(&fuse_mutex);
  		list_del(&fc->entry);
  		fuse_ctl_remove_conn(fc);
  		mutex_unlock(&fuse_mutex);
3b463ae0c   John Muir   fuse: invalidatio...
1495
  	}
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1496
  }
fcee216be   Max Reitz   fuse: split fuse_...
1497
  EXPORT_SYMBOL_GPL(fuse_conn_destroy);
3b463ae0c   John Muir   fuse: invalidatio...
1498

fcee216be   Max Reitz   fuse: split fuse_...
1499
  static void fuse_kill_sb_anon(struct super_block *sb)
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1500
  {
fcee216be   Max Reitz   fuse: split fuse_...
1501
1502
1503
1504
1505
1506
1507
1508
  	struct fuse_mount *fm = get_fuse_mount_super(sb);
  	bool last;
  
  	if (fm) {
  		last = fuse_mount_remove(fm);
  		if (last)
  			fuse_conn_destroy(fm);
  	}
3b463ae0c   John Muir   fuse: invalidatio...
1509
1510
  	kill_anon_super(sb);
  }
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1511
1512
1513
  static struct file_system_type fuse_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "fuse",
4ad769f3c   Eric W. Biederman   fuse: Allow fully...
1514
  	.fs_flags	= FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
c30da2e98   David Howells   fuse: convert to ...
1515
  	.init_fs_context = fuse_init_fs_context,
d7167b149   Al Viro   fs_parse: fold fs...
1516
  	.parameters	= fuse_fs_parameters,
3b463ae0c   John Muir   fuse: invalidatio...
1517
  	.kill_sb	= fuse_kill_sb_anon,
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1518
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
1519
  MODULE_ALIAS_FS("fuse");
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1520
1521
  
  #ifdef CONFIG_BLOCK
3b463ae0c   John Muir   fuse: invalidatio...
1522
1523
  static void fuse_kill_sb_blk(struct super_block *sb)
  {
fcee216be   Max Reitz   fuse: split fuse_...
1524
1525
1526
1527
1528
1529
1530
1531
  	struct fuse_mount *fm = get_fuse_mount_super(sb);
  	bool last;
  
  	if (fm) {
  		last = fuse_mount_remove(fm);
  		if (last)
  			fuse_conn_destroy(fm);
  	}
3b463ae0c   John Muir   fuse: invalidatio...
1532
1533
  	kill_block_super(sb);
  }
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1534
1535
1536
  static struct file_system_type fuseblk_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "fuseblk",
c30da2e98   David Howells   fuse: convert to ...
1537
  	.init_fs_context = fuse_init_fs_context,
d7167b149   Al Viro   fs_parse: fold fs...
1538
  	.parameters	= fuse_fs_parameters,
3b463ae0c   John Muir   fuse: invalidatio...
1539
  	.kill_sb	= fuse_kill_sb_blk,
edad01e2a   Alexey Dobriyan   fuse: ->fs_flags ...
1540
  	.fs_flags	= FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1541
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
1542
  MODULE_ALIAS_FS("fuseblk");
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1543

875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
  static inline int register_fuseblk(void)
  {
  	return register_filesystem(&fuseblk_fs_type);
  }
  
  static inline void unregister_fuseblk(void)
  {
  	unregister_filesystem(&fuseblk_fs_type);
  }
  #else
  static inline int register_fuseblk(void)
  {
  	return 0;
  }
  
  static inline void unregister_fuseblk(void)
  {
  }
  #endif
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
1563
  static void fuse_inode_init_once(void *foo)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1564
  {
1729a16c2   Miklos Szeredi   fuse: style fixes
1565
  	struct inode *inode = foo;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1566

a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
1567
  	inode_init_once(inode);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1568
1569
1570
1571
1572
  }
  
  static int __init fuse_fs_init(void)
  {
  	int err;
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1573
  	fuse_inode_cachep = kmem_cache_create("fuse_inode",
df206988e   Johannes Weiner   fs: fuse: account...
1574
1575
1576
  			sizeof(struct fuse_inode), 0,
  			SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT,
  			fuse_inode_init_once);
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1577
1578
  	err = -ENOMEM;
  	if (!fuse_inode_cachep)
988f03256   Al Viro   fuse: register_fi...
1579
1580
1581
1582
1583
1584
1585
1586
1587
  		goto out;
  
  	err = register_fuseblk();
  	if (err)
  		goto out2;
  
  	err = register_filesystem(&fuse_fs_type);
  	if (err)
  		goto out3;
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1588
1589
  
  	return 0;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1590

988f03256   Al Viro   fuse: register_fi...
1591
   out3:
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1592
  	unregister_fuseblk();
988f03256   Al Viro   fuse: register_fi...
1593
1594
   out2:
  	kmem_cache_destroy(fuse_inode_cachep);
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1595
   out:
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1596
1597
1598
1599
1600
1601
  	return err;
  }
  
  static void fuse_fs_cleanup(void)
  {
  	unregister_filesystem(&fuse_fs_type);
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1602
  	unregister_fuseblk();
8c0a85377   Kirill A. Shutemov   fs: push rcu_barr...
1603
1604
1605
1606
1607
1608
  
  	/*
  	 * Make sure all delayed rcu free inodes are flushed before we
  	 * destroy cache.
  	 */
  	rcu_barrier();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1609
1610
  	kmem_cache_destroy(fuse_inode_cachep);
  }
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1611
  static struct kobject *fuse_kobj;
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1612

f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1613
1614
1615
  static int fuse_sysfs_init(void)
  {
  	int err;
00d266662   Greg Kroah-Hartman   kobject: convert ...
1616
  	fuse_kobj = kobject_create_and_add("fuse", fs_kobj);
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1617
1618
  	if (!fuse_kobj) {
  		err = -ENOMEM;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1619
  		goto out_err;
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1620
  	}
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1621

f9bb48825   Eric W. Biederman   sysfs: Create mou...
1622
1623
  	err = sysfs_create_mount_point(fuse_kobj, "connections");
  	if (err)
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1624
1625
1626
1627
1628
  		goto out_fuse_unregister;
  
  	return 0;
  
   out_fuse_unregister:
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
1629
  	kobject_put(fuse_kobj);
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1630
1631
1632
1633
1634
1635
   out_err:
  	return err;
  }
  
  static void fuse_sysfs_cleanup(void)
  {
f9bb48825   Eric W. Biederman   sysfs: Create mou...
1636
  	sysfs_remove_mount_point(fuse_kobj, "connections");
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
1637
  	kobject_put(fuse_kobj);
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1638
  }
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1639
1640
1641
  static int __init fuse_init(void)
  {
  	int res;
f2294482f   Kirill Smelkov   fuse: convert pri...
1642
1643
1644
  	pr_info("init (API version %i.%i)
  ",
  		FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1645

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1646
  	INIT_LIST_HEAD(&fuse_conn_list);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1647
1648
1649
  	res = fuse_fs_init();
  	if (res)
  		goto err;
334f485df   Miklos Szeredi   [PATCH] FUSE - de...
1650
1651
1652
  	res = fuse_dev_init();
  	if (res)
  		goto err_fs_cleanup;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1653
1654
1655
  	res = fuse_sysfs_init();
  	if (res)
  		goto err_dev_cleanup;
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1656
1657
1658
  	res = fuse_ctl_init();
  	if (res)
  		goto err_sysfs_cleanup;
487ea5af6   Csaba Henk   fuse: limit user-...
1659
1660
  	sanitize_global_limit(&max_user_bgreq);
  	sanitize_global_limit(&max_user_congthresh);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1661
  	return 0;
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1662
1663
   err_sysfs_cleanup:
  	fuse_sysfs_cleanup();
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1664
1665
   err_dev_cleanup:
  	fuse_dev_cleanup();
334f485df   Miklos Szeredi   [PATCH] FUSE - de...
1666
1667
   err_fs_cleanup:
  	fuse_fs_cleanup();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1668
1669
1670
1671
1672
1673
   err:
  	return res;
  }
  
  static void __exit fuse_exit(void)
  {
f2294482f   Kirill Smelkov   fuse: convert pri...
1674
1675
  	pr_debug("exit
  ");
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1676

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1677
  	fuse_ctl_cleanup();
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1678
  	fuse_sysfs_cleanup();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1679
  	fuse_fs_cleanup();
334f485df   Miklos Szeredi   [PATCH] FUSE - de...
1680
  	fuse_dev_cleanup();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1681
1682
1683
1684
  }
  
  module_init(fuse_init);
  module_exit(fuse_exit);