Blame view

fs/fuse/inode.c 35.8 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);
f15ecfef0   Kirill Tkhai   fuse: Introduce f...
78
  	spin_lock_init(&fi->lock);
07e77dca8   Miklos Szeredi   fuse: separate qu...
79
80
  	fi->forget = fuse_alloc_forget();
  	if (!fi->forget) {
9031a69cf   zhangliguang   fuse: clean up fu...
81
  		kmem_cache_free(fuse_inode_cachep, fi);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
82
83
  		return NULL;
  	}
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
84

9031a69cf   zhangliguang   fuse: clean up fu...
85
  	return &fi->inode;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
86
  }
9baf28bbf   Al Viro   fuse: switch to -...
87
  static void fuse_free_inode(struct inode *inode)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
88
  {
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
89
  	struct fuse_inode *fi = get_fuse_inode(inode);
9baf28bbf   Al Viro   fuse: switch to -...
90

5c672ab3f   Miklos Szeredi   fuse: serialize d...
91
  	mutex_destroy(&fi->mutex);
07e77dca8   Miklos Szeredi   fuse: separate qu...
92
  	kfree(fi->forget);
9baf28bbf   Al Viro   fuse: switch to -...
93
  	kmem_cache_free(fuse_inode_cachep, fi);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
94
  }
b57922d97   Al Viro   convert remaining...
95
  static void fuse_evict_inode(struct inode *inode)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
96
  {
9baf28bbf   Al Viro   fuse: switch to -...
97
  	struct fuse_inode *fi = get_fuse_inode(inode);
91b0abe36   Johannes Weiner   mm + fs: store sh...
98
  	truncate_inode_pages_final(&inode->i_data);
dbd5768f8   Jan Kara   vfs: Rename end_w...
99
  	clear_inode(inode);
1751e8a6c   Linus Torvalds   Rename superblock...
100
  	if (inode->i_sb->s_flags & SB_ACTIVE) {
1e9a4ed93   Miklos Szeredi   [PATCH] FUSE - mo...
101
  		struct fuse_conn *fc = get_fuse_conn(inode);
07e77dca8   Miklos Szeredi   fuse: separate qu...
102
103
  		fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup);
  		fi->forget = NULL;
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
104
  	}
9baf28bbf   Al Viro   fuse: switch to -...
105
106
107
108
  	if (S_ISREG(inode->i_mode) && !is_bad_inode(inode)) {
  		WARN_ON(!list_empty(&fi->write_files));
  		WARN_ON(!list_empty(&fi->queued_writes));
  	}
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
109
  }
0189a2d36   Miklos Szeredi   fuse: use ->recon...
110
  static int fuse_reconfigure(struct fs_context *fc)
714212593   Miklos Szeredi   [PATCH] fuse: add...
111
  {
0189a2d36   Miklos Szeredi   fuse: use ->recon...
112
  	struct super_block *sb = fc->root->d_sb;
02b9984d6   Theodore Ts'o   fs: push sync_fil...
113
  	sync_filesystem(sb);
0189a2d36   Miklos Szeredi   fuse: use ->recon...
114
  	if (fc->sb_flags & SB_MANDLOCK)
714212593   Miklos Szeredi   [PATCH] fuse: add...
115
116
117
118
  		return -EINVAL;
  
  	return 0;
  }
45c72cd73   Pavel Shilovsky   fuse: fix stat ca...
119
120
121
122
123
124
125
126
127
128
129
  /*
   * 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...
130
131
  void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
  				   u64 attr_valid)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
132
  {
9ffbb9162   Miklos Szeredi   [PATCH] fuse: fix...
133
  	struct fuse_conn *fc = get_fuse_conn(inode);
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
134
  	struct fuse_inode *fi = get_fuse_inode(inode);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
135

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

45c72cd73   Pavel Shilovsky   fuse: fix stat ca...
141
  	inode->i_ino     = fuse_squash_ino(attr->ino);
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
142
  	inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
bfe868486   Miklos Szeredi   filesystems: add ...
143
  	set_nlink(inode, attr->nlink);
8cb08329b   Eric W. Biederman   fuse: Support fus...
144
145
  	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
146
147
148
  	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...
149
150
151
152
  	/* 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...
153
154
  		inode->i_ctime.tv_sec   = attr->ctime;
  		inode->i_ctime.tv_nsec  = attr->ctimensec;
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
155
  	}
e00d2c2d4   Miklos Szeredi   fuse: truncate on...
156

0e9663ee4   Miklos Szeredi   fuse: add blksize...
157
158
159
160
  	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...
161
162
163
164
165
166
  	/*
  	 * 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 ...
167
  	if (!fc->default_permissions)
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
168
  		inode->i_mode &= ~S_ISVTX;
45c72cd73   Pavel Shilovsky   fuse: fix stat ca...
169
170
  
  	fi->orig_ino = attr->ino;
3be5a52b3   Miklos Szeredi   fuse: support wri...
171
172
173
174
175
176
177
  }
  
  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...
178
  	bool is_wb = fc->writeback_cache;
3be5a52b3   Miklos Szeredi   fuse: support wri...
179
  	loff_t oldsize;
a64ba10f6   Arnd Bergmann   fuse: convert las...
180
  	struct timespec64 old_mtime;
3be5a52b3   Miklos Szeredi   fuse: support wri...
181

f15ecfef0   Kirill Tkhai   fuse: Introduce f...
182
  	spin_lock(&fi->lock);
06a7c3c27   Maxim Patlasov   fuse: hotfix trun...
183
184
  	if ((attr_version != 0 && fi->attr_version > attr_version) ||
  	    test_bit(FUSE_I_SIZE_UNSTABLE, &fi->state)) {
f15ecfef0   Kirill Tkhai   fuse: Introduce f...
185
  		spin_unlock(&fi->lock);
3be5a52b3   Miklos Szeredi   fuse: support wri...
186
187
  		return;
  	}
a64ba10f6   Arnd Bergmann   fuse: convert las...
188
  	old_mtime = inode->i_mtime;
3be5a52b3   Miklos Szeredi   fuse: support wri...
189
  	fuse_change_attributes_common(inode, attr, attr_valid);
ebc14c4db   Miklos Szeredi   fuse: fix permiss...
190

e00d2c2d4   Miklos Szeredi   fuse: truncate on...
191
  	oldsize = inode->i_size;
8373200b1   Pavel Emelyanov   fuse: Trust kerne...
192
193
194
195
196
197
198
  	/*
  	 * 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...
199
  	spin_unlock(&fi->lock);
e00d2c2d4   Miklos Szeredi   fuse: truncate on...
200

8373200b1   Pavel Emelyanov   fuse: Trust kerne...
201
  	if (!is_wb && S_ISREG(inode->i_mode)) {
eed2179ef   Brian Foster   fuse: invalidate ...
202
203
204
  		bool inval = false;
  
  		if (oldsize != attr->size) {
7caef2676   Kirill A. Shutemov   truncate: drop 'o...
205
  			truncate_pagecache(inode, attr->size);
ad2ba64dd   Kirill Smelkov   fuse: allow files...
206
207
  			if (!fc->explicit_inval_data)
  				inval = true;
eed2179ef   Brian Foster   fuse: invalidate ...
208
  		} else if (fc->auto_inval_data) {
a64ba10f6   Arnd Bergmann   fuse: convert las...
209
  			struct timespec64 new_mtime = {
eed2179ef   Brian Foster   fuse: invalidate ...
210
211
212
213
214
215
216
217
  				.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...
218
  			if (!timespec64_equal(&old_mtime, &new_mtime))
eed2179ef   Brian Foster   fuse: invalidate ...
219
220
221
222
223
  				inval = true;
  		}
  
  		if (inval)
  			invalidate_inode_pages2(inode->i_mapping);
e00d2c2d4   Miklos Szeredi   fuse: truncate on...
224
  	}
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
225
226
227
228
229
  }
  
  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...
230
  	inode->i_size = attr->size;
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
231
232
  	inode->i_mtime.tv_sec  = attr->mtime;
  	inode->i_mtime.tv_nsec = attr->mtimensec;
31f3267b4   Maxim Patlasov   fuse: trust kerne...
233
234
  	inode->i_ctime.tv_sec  = attr->ctime;
  	inode->i_ctime.tv_nsec = attr->ctimensec;
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
235
236
  	if (S_ISREG(inode->i_mode)) {
  		fuse_init_common(inode);
b6aeadeda   Miklos Szeredi   [PATCH] FUSE - fi...
237
  		fuse_init_file_inode(inode);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
238
239
240
241
242
243
244
245
246
  	} 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...
247
248
  	} else
  		BUG();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
249
  }
3b463ae0c   John Muir   fuse: invalidatio...
250
  int fuse_inode_eq(struct inode *inode, void *_nodeidp)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
251
  {
b48badf01   Miklos Szeredi   fuse: fix node ID...
252
  	u64 nodeid = *(u64 *) _nodeidp;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
253
254
255
256
257
258
259
260
  	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...
261
  	u64 nodeid = *(u64 *) _nodeidp;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
262
263
264
  	get_fuse_inode(inode)->nodeid = nodeid;
  	return 0;
  }
b48badf01   Miklos Szeredi   fuse: fix node ID...
265
  struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
1fb69e781   Miklos Szeredi   fuse: fix race be...
266
267
  			int generation, struct fuse_attr *attr,
  			u64 attr_valid, u64 attr_version)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
268
269
  {
  	struct inode *inode;
9e6268db4   Miklos Szeredi   [PATCH] FUSE - re...
270
  	struct fuse_inode *fi;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
271
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
272
273
274
275
276
277
278
  
   retry:
  	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...
279
  		inode->i_flags |= S_NOATIME;
d31433c8b   Maxim Patlasov   fuse: do not use ...
280
  		if (!fc->writeback_cache || !S_ISREG(attr->mode))
b0aa76065   Maxim Patlasov   fuse: Trust kerne...
281
  			inode->i_flags |= S_NOCMTIME;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
282
  		inode->i_generation = generation;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
283
284
285
  		fuse_init_inode(inode, attr);
  		unlock_new_inode(inode);
  	} else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
286
287
288
  		/* Inode has changed type, any I/O on the old should fail */
  		make_bad_inode(inode);
  		iput(inode);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
289
290
  		goto retry;
  	}
9e6268db4   Miklos Szeredi   [PATCH] FUSE - re...
291
  	fi = get_fuse_inode(inode);
c9d8f5f06   Kirill Tkhai   fuse: Protect fi-...
292
  	spin_lock(&fi->lock);
1729a16c2   Miklos Szeredi   fuse: style fixes
293
  	fi->nlookup++;
c9d8f5f06   Kirill Tkhai   fuse: Protect fi-...
294
  	spin_unlock(&fi->lock);
1fb69e781   Miklos Szeredi   fuse: fix race be...
295
  	fuse_change_attributes(inode, attr, attr_valid, attr_version);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
296
297
  	return inode;
  }
3b463ae0c   John Muir   fuse: invalidatio...
298
299
300
  int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
  			     loff_t offset, loff_t len)
  {
5ddd9ced9   Miklos Szeredi   fuse: update attr...
301
302
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
  	struct fuse_inode *fi;
3b463ae0c   John Muir   fuse: invalidatio...
303
304
305
306
307
308
309
  	struct inode *inode;
  	pgoff_t pg_start;
  	pgoff_t pg_end;
  
  	inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid);
  	if (!inode)
  		return -ENOENT;
5ddd9ced9   Miklos Szeredi   fuse: update attr...
310
311
312
313
  	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...
314
  	fuse_invalidate_attr(inode);
60bcc88ad   Seth Forshee   fuse: Add posix A...
315
  	forget_all_cached_acls(inode);
3b463ae0c   John Muir   fuse: invalidatio...
316
  	if (offset >= 0) {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
317
  		pg_start = offset >> PAGE_SHIFT;
3b463ae0c   John Muir   fuse: invalidatio...
318
319
320
  		if (len <= 0)
  			pg_end = -1;
  		else
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
321
  			pg_end = (offset + len - 1) >> PAGE_SHIFT;
3b463ae0c   John Muir   fuse: invalidatio...
322
323
324
325
326
327
  		invalidate_inode_pages2_range(inode->i_mapping,
  					      pg_start, pg_end);
  	}
  	iput(inode);
  	return 0;
  }
63576c13b   Miklos Szeredi   fuse: fix initial...
328
  bool fuse_lock_inode(struct inode *inode)
5c672ab3f   Miklos Szeredi   fuse: serialize d...
329
  {
63576c13b   Miklos Szeredi   fuse: fix initial...
330
331
332
  	bool locked = false;
  
  	if (!get_fuse_conn(inode)->parallel_dirops) {
5c672ab3f   Miklos Szeredi   fuse: serialize d...
333
  		mutex_lock(&get_fuse_inode(inode)->mutex);
63576c13b   Miklos Szeredi   fuse: fix initial...
334
335
336
337
  		locked = true;
  	}
  
  	return locked;
5c672ab3f   Miklos Szeredi   fuse: serialize d...
338
  }
63576c13b   Miklos Szeredi   fuse: fix initial...
339
  void fuse_unlock_inode(struct inode *inode, bool locked)
5c672ab3f   Miklos Szeredi   fuse: serialize d...
340
  {
63576c13b   Miklos Szeredi   fuse: fix initial...
341
  	if (locked)
5c672ab3f   Miklos Szeredi   fuse: serialize d...
342
343
  		mutex_unlock(&get_fuse_inode(inode)->mutex);
  }
42faad996   Al Viro   [PATCH] restore s...
344
  static void fuse_umount_begin(struct super_block *sb)
69a53bf26   Miklos Szeredi   [PATCH] fuse: add...
345
  {
15c8e72e8   Vivek Goyal   fuse: allow skipp...
346
347
348
349
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
  
  	if (!fc->no_force_umount)
  		fuse_abort_conn(fc);
69a53bf26   Miklos Szeredi   [PATCH] fuse: add...
350
  }
0ec7ca41f   Miklos Szeredi   [PATCH] fuse: add...
351
352
  static void fuse_send_destroy(struct fuse_conn *fc)
  {
1ccd1ea24   Miklos Szeredi   fuse: convert des...
353
354
355
356
357
358
359
  	if (fc->conn_init) {
  		FUSE_ARGS(args);
  
  		args.opcode = FUSE_DESTROY;
  		args.force = true;
  		args.nocreds = true;
  		fuse_simple_request(fc, &args);
0ec7ca41f   Miklos Szeredi   [PATCH] fuse: add...
360
361
  	}
  }
a325f9b92   Tejun Heo   fuse: update fuse...
362
363
364
  static void fuse_put_super(struct super_block *sb)
  {
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
bbd997979   Miklos Szeredi   cuse: fix fuse_co...
365
366
367
368
  	mutex_lock(&fuse_mutex);
  	list_del(&fc->entry);
  	fuse_ctl_remove_conn(fc);
  	mutex_unlock(&fuse_mutex);
bbd997979   Miklos Szeredi   cuse: fix fuse_co...
369

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
370
  	fuse_conn_put(fc);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
371
  }
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
372
373
374
375
  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...
376
  	stbuf->f_frsize  = attr->frsize;
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
377
378
379
380
381
382
383
384
  	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...
385
  static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
386
  {
726c33422   David Howells   [PATCH] VFS: Perm...
387
  	struct super_block *sb = dentry->d_sb;
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
388
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
7078187a7   Miklos Szeredi   fuse: introduce f...
389
  	FUSE_ARGS(args);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
390
391
  	struct fuse_statfs_out outarg;
  	int err;
c2132c1bc   Anatol Pomozov   Do not use RCU fo...
392
  	if (!fuse_allow_current_process(fc)) {
e57ac6837   Miklos Szeredi   fuse: fix allowin...
393
394
395
  		buf->f_type = FUSE_SUPER_MAGIC;
  		return 0;
  	}
de5f12025   Miklos Szeredi   [PATCH] fuse: add...
396
  	memset(&outarg, 0, sizeof(outarg));
d5b485435   Miklos Szeredi   fuse: flatten 'st...
397
398
399
400
401
402
  	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;
7078187a7   Miklos Szeredi   fuse: introduce f...
403
  	err = fuse_simple_request(fc, &args);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
404
405
  	if (!err)
  		convert_fuse_statfs(buf, &outarg.st);
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
406
407
  	return err;
  }
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
408
  enum {
c30da2e98   David Howells   fuse: convert to ...
409
410
  	OPT_SOURCE,
  	OPT_SUBTYPE,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
411
412
413
  	OPT_FD,
  	OPT_ROOTMODE,
  	OPT_USER_ID,
87729a551   Miklos Szeredi   [PATCH] FUSE: tig...
414
  	OPT_GROUP_ID,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
415
416
  	OPT_DEFAULT_PERMISSIONS,
  	OPT_ALLOW_OTHER,
db50b96c0   Miklos Szeredi   [PATCH] FUSE - re...
417
  	OPT_MAX_READ,
d80916140   Miklos Szeredi   [PATCH] fuse: add...
418
  	OPT_BLKSIZE,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
419
420
  	OPT_ERR
  };
d7167b149   Al Viro   fs_parse: fold fs...
421
  static const struct fs_parameter_spec fuse_fs_parameters[] = {
c30da2e98   David Howells   fuse: convert to ...
422
423
424
425
426
427
428
429
430
  	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...
431
  	fsparam_string	("subtype",		OPT_SUBTYPE),
c30da2e98   David Howells   fuse: convert to ...
432
433
  	{}
  };
c30da2e98   David Howells   fuse: convert to ...
434
  static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
233a01fa9   Miklos Szeredi   fuse: handle larg...
435
  {
c30da2e98   David Howells   fuse: convert to ...
436
437
438
  	struct fs_parse_result result;
  	struct fuse_fs_context *ctx = fc->fs_private;
  	int opt;
b330966f7   Miklos Szeredi   fuse: reject opti...
439
440
441
442
443
444
445
446
447
448
  	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...
449

d7167b149   Al Viro   fs_parse: fold fs...
450
  	opt = fs_parse(fc, fuse_fs_parameters, param, &result);
c30da2e98   David Howells   fuse: convert to ...
451
452
453
454
455
456
  	if (opt < 0)
  		return opt;
  
  	switch (opt) {
  	case OPT_SOURCE:
  		if (fc->source)
2e28c49ea   Al Viro   fuse: switch to u...
457
  			return invalfc(fc, "Multiple sources specified");
c30da2e98   David Howells   fuse: convert to ...
458
459
460
461
462
463
  		fc->source = param->string;
  		param->string = NULL;
  		break;
  
  	case OPT_SUBTYPE:
  		if (ctx->subtype)
2e28c49ea   Al Viro   fuse: switch to u...
464
  			return invalfc(fc, "Multiple subtypes specified");
c30da2e98   David Howells   fuse: convert to ...
465
466
467
468
469
470
  		ctx->subtype = param->string;
  		param->string = NULL;
  		return 0;
  
  	case OPT_FD:
  		ctx->fd = result.uint_32;
cabdb4fa2   zhengbin   fuse: use true,fa...
471
  		ctx->fd_present = true;
c30da2e98   David Howells   fuse: convert to ...
472
473
474
475
  		break;
  
  	case OPT_ROOTMODE:
  		if (!fuse_valid_type(result.uint_32))
2e28c49ea   Al Viro   fuse: switch to u...
476
  			return invalfc(fc, "Invalid rootmode");
c30da2e98   David Howells   fuse: convert to ...
477
  		ctx->rootmode = result.uint_32;
cabdb4fa2   zhengbin   fuse: use true,fa...
478
  		ctx->rootmode_present = true;
c30da2e98   David Howells   fuse: convert to ...
479
480
481
482
483
  		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...
484
  			return invalfc(fc, "Invalid user_id");
cabdb4fa2   zhengbin   fuse: use true,fa...
485
  		ctx->user_id_present = true;
c30da2e98   David Howells   fuse: convert to ...
486
487
488
489
490
  		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...
491
  			return invalfc(fc, "Invalid group_id");
cabdb4fa2   zhengbin   fuse: use true,fa...
492
  		ctx->group_id_present = true;
c30da2e98   David Howells   fuse: convert to ...
493
494
495
  		break;
  
  	case OPT_DEFAULT_PERMISSIONS:
cabdb4fa2   zhengbin   fuse: use true,fa...
496
  		ctx->default_permissions = true;
c30da2e98   David Howells   fuse: convert to ...
497
498
499
  		break;
  
  	case OPT_ALLOW_OTHER:
cabdb4fa2   zhengbin   fuse: use true,fa...
500
  		ctx->allow_other = true;
c30da2e98   David Howells   fuse: convert to ...
501
502
503
504
505
506
507
508
  		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...
509
  			return invalfc(fc, "blksize only supported for fuseblk");
c30da2e98   David Howells   fuse: convert to ...
510
511
512
513
514
  		ctx->blksize = result.uint_32;
  		break;
  
  	default:
  		return -EINVAL;
233a01fa9   Miklos Szeredi   fuse: handle larg...
515
  	}
c30da2e98   David Howells   fuse: convert to ...
516
517
  
  	return 0;
233a01fa9   Miklos Szeredi   fuse: handle larg...
518
  }
c30da2e98   David Howells   fuse: convert to ...
519
  static void fuse_free_fc(struct fs_context *fc)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
520
  {
c30da2e98   David Howells   fuse: convert to ...
521
  	struct fuse_fs_context *ctx = fc->fs_private;
5a5336827   Miklos Szeredi   [PATCH] fuse: str...
522

c30da2e98   David Howells   fuse: convert to ...
523
524
525
526
  	if (ctx) {
  		kfree(ctx->subtype);
  		kfree(ctx);
  	}
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
527
  }
34c80b1d9   Al Viro   vfs: switch ->sho...
528
  static int fuse_show_options(struct seq_file *m, struct dentry *root)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
529
  {
34c80b1d9   Al Viro   vfs: switch ->sho...
530
531
  	struct super_block *sb = root->d_sb;
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
532

3f22c7467   Miklos Szeredi   virtio-fs: don't ...
533
534
  	if (fc->no_mount_options)
  		return 0;
8cb08329b   Eric W. Biederman   fuse: Support fus...
535
536
  	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));
29433a299   Miklos Szeredi   fuse: get rid of ...
537
  	if (fc->default_permissions)
1e9a4ed93   Miklos Szeredi   [PATCH] FUSE - mo...
538
  		seq_puts(m, ",default_permissions");
29433a299   Miklos Szeredi   fuse: get rid of ...
539
  	if (fc->allow_other)
1e9a4ed93   Miklos Szeredi   [PATCH] FUSE - mo...
540
  		seq_puts(m, ",allow_other");
db50b96c0   Miklos Szeredi   [PATCH] FUSE - re...
541
542
  	if (fc->max_read != ~0)
  		seq_printf(m, ",max_read=%u", fc->max_read);
34c80b1d9   Al Viro   vfs: switch ->sho...
543
544
  	if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE)
  		seq_printf(m, ",blksize=%lu", sb->s_blocksize);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
545
546
  	return 0;
  }
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
547
548
549
  static void fuse_iqueue_init(struct fuse_iqueue *fiq,
  			     const struct fuse_iqueue_ops *ops,
  			     void *priv)
f88996a93   Miklos Szeredi   fuse: separate ou...
550
551
  {
  	memset(fiq, 0, sizeof(struct fuse_iqueue));
76e43c8cc   Eric Biggers   fuse: fix deadloc...
552
  	spin_lock_init(&fiq->lock);
f88996a93   Miklos Szeredi   fuse: separate ou...
553
554
555
556
  	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 -...
557
  	fiq->connected = 1;
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
558
559
  	fiq->ops = ops;
  	fiq->priv = priv;
f88996a93   Miklos Szeredi   fuse: separate ou...
560
  }
3a2b5b9cd   Miklos Szeredi   fuse: separate ou...
561
562
  static void fuse_pqueue_init(struct fuse_pqueue *fpq)
  {
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
563
  	unsigned int i;
45a91cb1a   Miklos Szeredi   fuse: pqueue locking
564
  	spin_lock_init(&fpq->lock);
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
565
566
  	for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
  		INIT_LIST_HEAD(&fpq->processing[i]);
3a2b5b9cd   Miklos Szeredi   fuse: separate ou...
567
  	INIT_LIST_HEAD(&fpq->io);
e96edd94d   Miklos Szeredi   fuse: duplicate -...
568
  	fpq->connected = 1;
3a2b5b9cd   Miklos Szeredi   fuse: separate ou...
569
  }
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
570
571
  void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns,
  		    const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
572
  {
0d179aa59   Tejun Heo   fuse: separate ou...
573
574
  	memset(fc, 0, sizeof(*fc));
  	spin_lock_init(&fc->lock);
ae2dffa39   Kirill Tkhai   fuse: introduce f...
575
  	spin_lock_init(&fc->bg_lock);
3b463ae0c   John Muir   fuse: invalidatio...
576
  	init_rwsem(&fc->killsb);
095fc40ac   Elena Reshetova   fuse: convert fus...
577
  	refcount_set(&fc->count, 1);
c3696046b   Miklos Szeredi   fuse: separate pq...
578
  	atomic_set(&fc->dev_count, 1);
0d179aa59   Tejun Heo   fuse: separate ou...
579
  	init_waitqueue_head(&fc->blocked_waitq);
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
580
  	fuse_iqueue_init(&fc->iq, fiq_ops, fiq_priv);
0d179aa59   Tejun Heo   fuse: separate ou...
581
582
  	INIT_LIST_HEAD(&fc->bg_queue);
  	INIT_LIST_HEAD(&fc->entry);
cc080e9e9   Miklos Szeredi   fuse: introduce p...
583
  	INIT_LIST_HEAD(&fc->devices);
0d179aa59   Tejun Heo   fuse: separate ou...
584
  	atomic_set(&fc->num_waiting, 0);
7a6d3c8b3   Csaba Henk   fuse: make the nu...
585
586
  	fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
  	fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
75126f550   Miklos Szeredi   fuse: use atomic6...
587
  	atomic64_set(&fc->khctr, 0);
0d179aa59   Tejun Heo   fuse: separate ou...
588
  	fc->polled_files = RB_ROOT;
0aada8847   Maxim Patlasov   fuse: skip blocki...
589
  	fc->blocked = 0;
796523fb2   Maxim Patlasov   fuse: add flag fc...
590
  	fc->initialized = 0;
e16714d87   Miklos Szeredi   fuse: duplicate -...
591
  	fc->connected = 1;
4510d86fb   Kirill Tkhai   fuse: Convert fc-...
592
  	atomic64_set(&fc->attr_version, 1);
0d179aa59   Tejun Heo   fuse: separate ou...
593
  	get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
0b6e9ea04   Seth Forshee   fuse: Add support...
594
  	fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
8cb08329b   Eric W. Biederman   fuse: Support fus...
595
  	fc->user_ns = get_user_ns(user_ns);
8a3177db5   Miklos Szeredi   cuse: fix ioctl
596
  	fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
597
  }
0d179aa59   Tejun Heo   fuse: separate ou...
598
  EXPORT_SYMBOL_GPL(fuse_conn_init);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
599

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
600
601
  void fuse_conn_put(struct fuse_conn *fc)
  {
095fc40ac   Elena Reshetova   fuse: convert fus...
602
  	if (refcount_dec_and_test(&fc->count)) {
a62a8ef9d   Stefan Hajnoczi   virtio-fs: add vi...
603
604
605
606
  		struct fuse_iqueue *fiq = &fc->iq;
  
  		if (fiq->ops->release)
  			fiq->ops->release(fiq);
0b6e9ea04   Seth Forshee   fuse: Add support...
607
  		put_pid_ns(fc->pid_ns);
8cb08329b   Eric W. Biederman   fuse: Support fus...
608
  		put_user_ns(fc->user_ns);
43901aabd   Tejun Heo   fuse: add fuse_co...
609
  		fc->release(fc);
d2a85164a   Miklos Szeredi   [PATCH] fuse: fix...
610
  	}
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
611
  }
08cbf542b   Tejun Heo   fuse: export symb...
612
  EXPORT_SYMBOL_GPL(fuse_conn_put);
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
613
614
615
  
  struct fuse_conn *fuse_conn_get(struct fuse_conn *fc)
  {
095fc40ac   Elena Reshetova   fuse: convert fus...
616
  	refcount_inc(&fc->count);
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
617
618
  	return fc;
  }
08cbf542b   Tejun Heo   fuse: export symb...
619
  EXPORT_SYMBOL_GPL(fuse_conn_get);
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
620

b93f858ab   Tejun Heo   fuse: add fuse_ p...
621
  static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
622
623
624
625
626
627
  {
  	struct fuse_attr attr;
  	memset(&attr, 0, sizeof(attr));
  
  	attr.mode = mode;
  	attr.ino = FUSE_ROOT_ID;
074406fa6   Miklos Szeredi   fuse: set i_nlink...
628
  	attr.nlink = 1;
1fb69e781   Miklos Szeredi   fuse: fix race be...
629
  	return fuse_iget(sb, 1, 0, &attr, 0, 0);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
630
  }
1729a16c2   Miklos Szeredi   fuse: style fixes
631
  struct fuse_inode_handle {
dbd561d23   Miklos Szeredi   fuse: add export ...
632
633
634
635
636
637
638
  	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 ...
639
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
dbd561d23   Miklos Szeredi   fuse: add export ...
640
641
642
643
644
645
646
647
  	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 ...
648
649
  	if (!inode) {
  		struct fuse_entry_out outarg;
13983d062   Al Viro   qstr: constify in...
650
  		const struct qstr name = QSTR_INIT(".", 1);
33670fa29   Miklos Szeredi   fuse: nfs export ...
651
652
653
  
  		if (!fc->export_support)
  			goto out_err;
33670fa29   Miklos Szeredi   fuse: nfs export ...
654
655
656
657
658
659
660
661
662
663
664
665
  		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 ...
666
667
668
  	err = -ESTALE;
  	if (inode->i_generation != handle->generation)
  		goto out_iput;
440037287   Christoph Hellwig   [PATCH] switch al...
669
  	entry = d_obtain_alias(inode);
c35eebe99   Al Viro   switch fuse
670
  	if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID)
dbd561d23   Miklos Szeredi   fuse: add export ...
671
  		fuse_invalidate_entry_cache(entry);
dbd561d23   Miklos Szeredi   fuse: add export ...
672
673
674
675
676
677
678
679
  
  	return entry;
  
   out_iput:
  	iput(inode);
   out_err:
  	return ERR_PTR(err);
  }
b0b0382bb   Al Viro   ->encode_fh() API...
680
681
  static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len,
  			   struct inode *parent)
dbd561d23   Miklos Szeredi   fuse: add export ...
682
  {
b0b0382bb   Al Viro   ->encode_fh() API...
683
  	int len = parent ? 6 : 3;
dbd561d23   Miklos Szeredi   fuse: add export ...
684
685
  	u64 nodeid;
  	u32 generation;
5fe0c2378   Aneesh Kumar K.V   exportfs: Return ...
686
687
  	if (*max_len < len) {
  		*max_len = len;
94e07a759   Namjae Jeon   fs: encode_fh: re...
688
  		return  FILEID_INVALID;
5fe0c2378   Aneesh Kumar K.V   exportfs: Return ...
689
  	}
dbd561d23   Miklos Szeredi   fuse: add export ...
690
691
692
693
694
695
696
  
  	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...
697
  	if (parent) {
dbd561d23   Miklos Szeredi   fuse: add export ...
698
699
  		nodeid = get_fuse_inode(parent)->nodeid;
  		generation = parent->i_generation;
dbd561d23   Miklos Szeredi   fuse: add export ...
700
701
702
703
704
705
706
  
  		fh[3] = (u32)(nodeid >> 32);
  		fh[4] = (u32)(nodeid & 0xffffffff);
  		fh[5] = generation;
  	}
  
  	*max_len = len;
b0b0382bb   Al Viro   ->encode_fh() API...
707
  	return parent ? 0x82 : 0x81;
dbd561d23   Miklos Szeredi   fuse: add export ...
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
  }
  
  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 ...
737
738
  static struct dentry *fuse_get_parent(struct dentry *child)
  {
2b0143b5c   David Howells   VFS: normal files...
739
  	struct inode *child_inode = d_inode(child);
33670fa29   Miklos Szeredi   fuse: nfs export ...
740
741
742
743
  	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...
744
  	const struct qstr name = QSTR_INIT("..", 2);
33670fa29   Miklos Szeredi   fuse: nfs export ...
745
746
747
748
  	int err;
  
  	if (!fc->export_support)
  		return ERR_PTR(-ESTALE);
33670fa29   Miklos Szeredi   fuse: nfs export ...
749
750
  	err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode),
  			       &name, &outarg, &inode);
440037287   Christoph Hellwig   [PATCH] switch al...
751
752
753
  	if (err) {
  		if (err == -ENOENT)
  			return ERR_PTR(-ESTALE);
33670fa29   Miklos Szeredi   fuse: nfs export ...
754
  		return ERR_PTR(err);
33670fa29   Miklos Szeredi   fuse: nfs export ...
755
  	}
440037287   Christoph Hellwig   [PATCH] switch al...
756
757
  
  	parent = d_obtain_alias(inode);
c35eebe99   Al Viro   switch fuse
758
  	if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID)
33670fa29   Miklos Szeredi   fuse: nfs export ...
759
  		fuse_invalidate_entry_cache(parent);
33670fa29   Miklos Szeredi   fuse: nfs export ...
760
761
762
  
  	return parent;
  }
dbd561d23   Miklos Szeredi   fuse: add export ...
763
764
765
766
767
  
  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 ...
768
  	.get_parent	= fuse_get_parent,
dbd561d23   Miklos Szeredi   fuse: add export ...
769
  };
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
770
  static const struct super_operations fuse_super_operations = {
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
771
  	.alloc_inode    = fuse_alloc_inode,
9baf28bbf   Al Viro   fuse: switch to -...
772
  	.free_inode     = fuse_free_inode,
b57922d97   Al Viro   convert remaining...
773
  	.evict_inode	= fuse_evict_inode,
1e18bda86   Miklos Szeredi   fuse: add .write_...
774
  	.write_inode	= fuse_write_inode,
ead5f0b5f   Miklos Szeredi   fuse: delete inod...
775
  	.drop_inode	= generic_delete_inode,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
776
  	.put_super	= fuse_put_super,
69a53bf26   Miklos Szeredi   [PATCH] fuse: add...
777
  	.umount_begin	= fuse_umount_begin,
e5e5558e9   Miklos Szeredi   [PATCH] FUSE - re...
778
  	.statfs		= fuse_statfs,
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
779
780
  	.show_options	= fuse_show_options,
  };
487ea5af6   Csaba Henk   fuse: limit user-...
781
782
  static void sanitize_global_limit(unsigned *limit)
  {
f22f812d5   Miklos Szeredi   fuse: fix request...
783
784
785
786
  	/*
  	 * 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-...
787
  	if (*limit == 0)
f22f812d5   Miklos Szeredi   fuse: fix request...
788
  		*limit = ((totalram_pages() << PAGE_SHIFT) >> 13) / 392;
487ea5af6   Csaba Henk   fuse: limit user-...
789
790
791
792
  
  	if (*limit >= 1 << 16)
  		*limit = (1 << 16) - 1;
  }
e4dca7b7a   Kees Cook   treewide: Fix fun...
793
  static int set_global_limit(const char *val, const struct kernel_param *kp)
487ea5af6   Csaba Henk   fuse: limit user-...
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
  {
  	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...
815
  	spin_lock(&fc->bg_lock);
487ea5af6   Csaba Henk   fuse: limit user-...
816
817
818
819
820
821
822
823
824
825
826
827
828
  	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...
829
  	spin_unlock(&fc->bg_lock);
487ea5af6   Csaba Henk   fuse: limit user-...
830
  }
615047eff   Miklos Szeredi   fuse: convert ini...
831
832
833
834
835
836
837
838
  struct fuse_init_args {
  	struct fuse_args args;
  	struct fuse_init_in in;
  	struct fuse_init_out out;
  };
  
  static void process_init_reply(struct fuse_conn *fc, struct fuse_args *args,
  			       int error)
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
839
  {
615047eff   Miklos Szeredi   fuse: convert ini...
840
841
  	struct fuse_init_args *ia = container_of(args, typeof(*ia), args);
  	struct fuse_init_out *arg = &ia->out;
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
842

615047eff   Miklos Szeredi   fuse: convert ini...
843
  	if (error || arg->major != FUSE_KERNEL_VERSION)
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
844
845
  		fc->conn_error = 1;
  	else {
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
846
  		unsigned long ra_pages;
487ea5af6   Csaba Henk   fuse: limit user-...
847
  		process_init_limits(fc, arg);
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
848
  		if (arg->minor >= 6) {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
849
  			ra_pages = arg->max_readahead / PAGE_SIZE;
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
850
851
  			if (arg->flags & FUSE_ASYNC_READ)
  				fc->async_read = 1;
714212593   Miklos Szeredi   [PATCH] fuse: add...
852
853
  			if (!(arg->flags & FUSE_POSIX_LOCKS))
  				fc->no_lock = 1;
37fb3a30b   Miklos Szeredi   fuse: fix flock
854
855
856
  			if (arg->minor >= 17) {
  				if (!(arg->flags & FUSE_FLOCK_LOCKS))
  					fc->no_flock = 1;
24114504c   Miklos Szeredi   fuse: fix flock b...
857
858
859
  			} else {
  				if (!(arg->flags & FUSE_POSIX_LOCKS))
  					fc->no_flock = 1;
37fb3a30b   Miklos Szeredi   fuse: fix flock
860
  			}
6ff958edb   Miklos Szeredi   fuse: add atomic ...
861
862
  			if (arg->flags & FUSE_ATOMIC_O_TRUNC)
  				fc->atomic_o_trunc = 1;
33670fa29   Miklos Szeredi   fuse: nfs export ...
863
864
865
866
867
  			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...
868
869
  			if (arg->flags & FUSE_BIG_WRITES)
  				fc->big_writes = 1;
e0a43ddcc   Miklos Szeredi   fuse: allow umask...
870
871
  			if (arg->flags & FUSE_DONT_MASK)
  				fc->dont_mask = 1;
72d0d248c   Brian Foster   fuse: add FUSE_AU...
872
873
  			if (arg->flags & FUSE_AUTO_INVAL_DATA)
  				fc->auto_inval_data = 1;
ad2ba64dd   Kirill Smelkov   fuse: allow files...
874
875
  			else if (arg->flags & FUSE_EXPLICIT_INVAL_DATA)
  				fc->explicit_inval_data = 1;
28420dad2   Miklos Szeredi   fuse: fix readdir...
876
  			if (arg->flags & FUSE_DO_READDIRPLUS) {
0b05b1838   Anand V. Avati   fuse: implement N...
877
  				fc->do_readdirplus = 1;
28420dad2   Miklos Szeredi   fuse: fix readdir...
878
879
880
  				if (arg->flags & FUSE_READDIRPLUS_AUTO)
  					fc->readdirplus_auto = 1;
  			}
60b9df7a5   Miklos Szeredi   fuse: add flag to...
881
882
  			if (arg->flags & FUSE_ASYNC_DIO)
  				fc->async_dio = 1;
4d99ff8f1   Pavel Emelyanov   fuse: Turn writeb...
883
884
  			if (arg->flags & FUSE_WRITEBACK_CACHE)
  				fc->writeback_cache = 1;
5c672ab3f   Miklos Szeredi   fuse: serialize d...
885
886
  			if (arg->flags & FUSE_PARALLEL_DIROPS)
  				fc->parallel_dirops = 1;
5e940c1dd   Miklos Szeredi   fuse: handle kill...
887
888
  			if (arg->flags & FUSE_HANDLE_KILLPRIV)
  				fc->handle_killpriv = 1;
e27c9d387   Miklos Szeredi   fuse: fuse: add t...
889
890
  			if (arg->time_gran && arg->time_gran <= 1000000000)
  				fc->sb->s_time_gran = arg->time_gran;
60bcc88ad   Seth Forshee   fuse: Add posix A...
891
  			if ((arg->flags & FUSE_POSIX_ACL)) {
29433a299   Miklos Szeredi   fuse: get rid of ...
892
  				fc->default_permissions = 1;
60bcc88ad   Seth Forshee   fuse: Add posix A...
893
894
895
  				fc->posix_acl = 1;
  				fc->sb->s_xattr = fuse_acl_xattr_handlers;
  			}
5571f1e65   Dan Schatzberg   fuse: enable cach...
896
897
  			if (arg->flags & FUSE_CACHE_SYMLINKS)
  				fc->cache_symlinks = 1;
3b7008b22   Szymon Lukasz   fuse: return -ECO...
898
899
  			if (arg->flags & FUSE_ABORT_ERROR)
  				fc->abort_err = 1;
5da784cce   Constantine Shulyupin   fuse: add max_pag...
900
901
902
903
904
  			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));
  			}
714212593   Miklos Szeredi   [PATCH] fuse: add...
905
  		} else {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
906
  			ra_pages = fc->max_read / PAGE_SIZE;
714212593   Miklos Szeredi   [PATCH] fuse: add...
907
  			fc->no_lock = 1;
37fb3a30b   Miklos Szeredi   fuse: fix flock
908
  			fc->no_flock = 1;
714212593   Miklos Szeredi   [PATCH] fuse: add...
909
  		}
9cd684551   Miklos Szeredi   [PATCH] fuse: fix...
910

5f7f7543f   Jan Kara   fuse: Convert to ...
911
912
  		fc->sb->s_bdi->ra_pages =
  				min(fc->sb->s_bdi->ra_pages, ra_pages);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
913
914
  		fc->minor = arg->minor;
  		fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
f948d5643   Miklos Szeredi   fuse: fix thinko ...
915
  		fc->max_write = max_t(unsigned, 4096, fc->max_write);
0ec7ca41f   Miklos Szeredi   [PATCH] fuse: add...
916
  		fc->conn_init = 1;
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
917
  	}
615047eff   Miklos Szeredi   fuse: convert ini...
918
  	kfree(ia);
9759bd518   Miklos Szeredi   fuse: add memory ...
919
  	fuse_set_initialized(fc);
08a53cdce   Miklos Szeredi   [PATCH] fuse: acc...
920
  	wake_up_all(&fc->blocked_waitq);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
921
  }
95a84cdb1   Vivek Goyal   fuse: export fuse...
922
  void fuse_send_init(struct fuse_conn *fc)
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
923
  {
615047eff   Miklos Szeredi   fuse: convert ini...
924
  	struct fuse_init_args *ia;
095da6cbb   Miklos Szeredi   [PATCH] fuse: fix...
925

615047eff   Miklos Szeredi   fuse: convert ini...
926
927
928
929
930
931
932
  	ia = kzalloc(sizeof(*ia), GFP_KERNEL | __GFP_NOFAIL);
  
  	ia->in.major = FUSE_KERNEL_VERSION;
  	ia->in.minor = FUSE_KERNEL_MINOR_VERSION;
  	ia->in.max_readahead = fc->sb->s_bdi->ra_pages * PAGE_SIZE;
  	ia->in.flags |=
  		FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
37fb3a30b   Miklos Szeredi   fuse: fix flock
933
  		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
69fe05c90   Miklos Szeredi   fuse: add missing...
934
  		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
9446385f0   Wei Fang   fuse: fix wrong a...
935
  		FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
4d99ff8f1   Pavel Emelyanov   fuse: Turn writeb...
936
  		FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
5c672ab3f   Miklos Szeredi   fuse: serialize d...
937
  		FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT |
3b7008b22   Szymon Lukasz   fuse: return -ECO...
938
  		FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL |
d9a9ea94f   Chad Austin   fuse: support cli...
939
  		FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS |
ad2ba64dd   Kirill Smelkov   fuse: allow files...
940
  		FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA;
615047eff   Miklos Szeredi   fuse: convert ini...
941
942
943
944
945
  	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...
946
  	/* Variable length argument used for backward compatibility
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
947
948
  	   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...
949
  	ia->args.out_argvar = true;
615047eff   Miklos Szeredi   fuse: convert ini...
950
951
952
953
954
955
956
957
  	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;
  
  	if (fuse_simple_background(fc, &ia->args, GFP_KERNEL) != 0)
  		process_init_reply(fc, &ia->args, -ENOTCONN);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
958
  }
95a84cdb1   Vivek Goyal   fuse: export fuse...
959
  EXPORT_SYMBOL_GPL(fuse_send_init);
9b9a04693   Miklos Szeredi   [PATCH] fuse: mov...
960

783863d64   Miklos Szeredi   fuse: dissociate ...
961
  void fuse_free_conn(struct fuse_conn *fc)
43901aabd   Tejun Heo   fuse: add fuse_co...
962
  {
cc080e9e9   Miklos Szeredi   fuse: introduce p...
963
  	WARN_ON(!list_empty(&fc->devices));
dd3e2c55a   Al Viro   fuse: rcu-delay f...
964
  	kfree_rcu(fc, rcu);
43901aabd   Tejun Heo   fuse: add fuse_co...
965
  }
783863d64   Miklos Szeredi   fuse: dissociate ...
966
  EXPORT_SYMBOL_GPL(fuse_free_conn);
43901aabd   Tejun Heo   fuse: add fuse_co...
967

a325f9b92   Tejun Heo   fuse: update fuse...
968
969
970
  static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
  {
  	int err;
5f7f7543f   Jan Kara   fuse: Convert to ...
971
  	char *suffix = "";
a325f9b92   Tejun Heo   fuse: update fuse...
972

69c8ebf83   Jan Kara   fuseblk: Fix warn...
973
  	if (sb->s_bdev) {
5f7f7543f   Jan Kara   fuse: Convert to ...
974
  		suffix = "-fuseblk";
69c8ebf83   Jan Kara   fuseblk: Fix warn...
975
976
977
978
979
980
981
  		/*
  		 * 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 ...
982
983
  	err = super_setup_bdi_name(sb, "%u:%u%s", MAJOR(fc->dev),
  				   MINOR(fc->dev), suffix);
a325f9b92   Tejun Heo   fuse: update fuse...
984
985
  	if (err)
  		return err;
b5420237e   Nikolay Borisov   mm: refactor read...
986
  	sb->s_bdi->ra_pages = VM_READAHEAD_PAGES;
5f7f7543f   Jan Kara   fuse: Convert to ...
987
988
  	/* fuse does it's own writeback accounting */
  	sb->s_bdi->capabilities = BDI_CAP_NO_ACCT_WB | BDI_CAP_STRICTLIMIT;
a325f9b92   Tejun Heo   fuse: update fuse...
989

a325f9b92   Tejun Heo   fuse: update fuse...
990
991
992
993
994
995
996
997
998
999
1000
1001
  	/*
  	 * 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 ...
1002
  	bdi_set_max_ratio(sb->s_bdi, 1);
a325f9b92   Tejun Heo   fuse: update fuse...
1003
1004
1005
  
  	return 0;
  }
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1006
  struct fuse_dev *fuse_dev_alloc(void)
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1007
1008
  {
  	struct fuse_dev *fud;
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1009
  	struct list_head *pq;
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1010
1011
  
  	fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL);
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1012
1013
  	if (!fud)
  		return NULL;
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1014

be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1015
1016
1017
1018
  	pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL);
  	if (!pq) {
  		kfree(fud);
  		return NULL;
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1019
  	}
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1020
  	fud->pq.processing = pq;
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1021
  	fuse_pqueue_init(&fud->pq);
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1022
1023
1024
1025
1026
1027
1028
  	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...
1029
1030
1031
  	spin_lock(&fc->lock);
  	list_add_tail(&fud->entry, &fc->devices);
  	spin_unlock(&fc->lock);
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1032
1033
  }
  EXPORT_SYMBOL_GPL(fuse_dev_install);
be2ff42c5   Kirill Tkhai   fuse: Use hash ta...
1034

0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1035
1036
1037
1038
1039
1040
1041
1042
1043
  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...
1044
1045
  	return fud;
  }
0cd1eb9a4   Vivek Goyal   fuse: separate fu...
1046
  EXPORT_SYMBOL_GPL(fuse_dev_alloc_install);
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
  
  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 ...
1059
  	kfree(fud->pq.processing);
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1060
1061
1062
  	kfree(fud);
  }
  EXPORT_SYMBOL_GPL(fuse_dev_free);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1063
  int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1064
  {
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1065
  	struct fuse_dev *fud = NULL;
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1066
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1067
  	struct inode *root;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1068
  	struct dentry *root_dentry;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1069
  	int err;
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1070
  	err = -EINVAL;
1751e8a6c   Linus Torvalds   Rename superblock...
1071
  	if (sb->s_flags & SB_MANDLOCK)
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1072
  		goto err;
714212593   Miklos Szeredi   [PATCH] fuse: add...
1073

1751e8a6c   Linus Torvalds   Rename superblock...
1074
  	sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION);
9e1f1de02   Al Viro   more conservative...
1075

0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1076
  	if (ctx->is_bdev) {
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1077
  #ifdef CONFIG_BLOCK
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1078
  		err = -EINVAL;
c30da2e98   David Howells   fuse: convert to ...
1079
  		if (!sb_set_blocksize(sb, ctx->blksize))
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1080
  			goto err;
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1081
  #endif
d80916140   Miklos Szeredi   [PATCH] fuse: add...
1082
  	} else {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
1083
1084
  		sb->s_blocksize = PAGE_SIZE;
  		sb->s_blocksize_bits = PAGE_SHIFT;
d80916140   Miklos Szeredi   [PATCH] fuse: add...
1085
  	}
c30da2e98   David Howells   fuse: convert to ...
1086
1087
1088
  
  	sb->s_subtype = ctx->subtype;
  	ctx->subtype = NULL;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1089
1090
  	sb->s_magic = FUSE_SUPER_MAGIC;
  	sb->s_op = &fuse_super_operations;
703c73629   Seth Forshee   fuse: Use generic...
1091
  	sb->s_xattr = fuse_xattr_handlers;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1092
  	sb->s_maxbytes = MAX_LFS_FILESIZE;
0a2da9b2e   Miklos Szeredi   fuse: allow nanos...
1093
  	sb->s_time_gran = 1;
dbd561d23   Miklos Szeredi   fuse: add export ...
1094
  	sb->s_export_op = &fuse_export_operations;
0834136ae   Mimi Zohar   fuse: define the ...
1095
1096
1097
  	sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE;
  	if (sb->s_user_ns != &init_user_ns)
  		sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1098

e45b2546e   Eric W. Biederman   fuse: Ensure posi...
1099
1100
1101
1102
1103
1104
  	/*
  	 * 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;
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1105
1106
1107
1108
1109
1110
  	if (ctx->fudptr) {
  		err = -ENOMEM;
  		fud = fuse_dev_alloc_install(fc);
  		if (!fud)
  			goto err;
  	}
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1111

a325f9b92   Tejun Heo   fuse: update fuse...
1112
  	fc->dev = sb->s_dev;
3b463ae0c   John Muir   fuse: invalidatio...
1113
  	fc->sb = sb;
a325f9b92   Tejun Heo   fuse: update fuse...
1114
1115
  	err = fuse_bdi_init(fc, sb);
  	if (err)
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1116
  		goto err_dev_free;
0d179aa59   Tejun Heo   fuse: separate ou...
1117

e0a43ddcc   Miklos Szeredi   fuse: allow umask...
1118
  	/* Handle umasking inside the fuse code */
1751e8a6c   Linus Torvalds   Rename superblock...
1119
  	if (sb->s_flags & SB_POSIXACL)
e0a43ddcc   Miklos Szeredi   fuse: allow umask...
1120
  		fc->dont_mask = 1;
1751e8a6c   Linus Torvalds   Rename superblock...
1121
  	sb->s_flags |= SB_POSIXACL;
e0a43ddcc   Miklos Szeredi   fuse: allow umask...
1122

c30da2e98   David Howells   fuse: convert to ...
1123
1124
1125
1126
1127
  	fc->default_permissions = ctx->default_permissions;
  	fc->allow_other = ctx->allow_other;
  	fc->user_id = ctx->user_id;
  	fc->group_id = ctx->group_id;
  	fc->max_read = max_t(unsigned, 4096, ctx->max_read);
783863d64   Miklos Szeredi   fuse: dissociate ...
1128
  	fc->destroy = ctx->destroy;
15c8e72e8   Vivek Goyal   fuse: allow skipp...
1129
1130
  	fc->no_control = ctx->no_control;
  	fc->no_force_umount = ctx->no_force_umount;
3f22c7467   Miklos Szeredi   virtio-fs: don't ...
1131
  	fc->no_mount_options = ctx->no_mount_options;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1132

d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1133
  	err = -ENOMEM;
c30da2e98   David Howells   fuse: convert to ...
1134
  	root = fuse_get_root_inode(sb, ctx->rootmode);
0ce267ff9   Miklos Szeredi   fuse: fix root de...
1135
  	sb->s_d_op = &fuse_root_dentry_operations;
48fde701a   Al Viro   switch open-coded...
1136
1137
  	root_dentry = d_make_root(root);
  	if (!root_dentry)
cc080e9e9   Miklos Szeredi   fuse: introduce p...
1138
  		goto err_dev_free;
0ce267ff9   Miklos Szeredi   fuse: fix root de...
1139
  	/* Root dentry doesn't have .d_revalidate */
c35eebe99   Al Viro   switch fuse
1140
  	sb->s_d_op = &fuse_dentry_operations;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1141

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1142
  	mutex_lock(&fuse_mutex);
8aa09a50b   Miklos Szeredi   [fuse] fix race b...
1143
  	err = -EINVAL;
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1144
  	if (ctx->fudptr && *ctx->fudptr)
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1145
  		goto err_unlock;
8aa09a50b   Miklos Szeredi   [fuse] fix race b...
1146

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1147
1148
1149
1150
1151
  	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...
1152
  	sb->s_root = root_dentry;
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1153
1154
  	if (ctx->fudptr)
  		*ctx->fudptr = fud;
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1155
  	mutex_unlock(&fuse_mutex);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1156
1157
1158
1159
1160
1161
  	return 0;
  
   err_unlock:
  	mutex_unlock(&fuse_mutex);
  	dput(root_dentry);
   err_dev_free:
7fd3abfa8   Vivek Goyal   virtiofs: do not ...
1162
1163
  	if (fud)
  		fuse_dev_free(fud);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
   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;
  
  	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;
ae3aad77f   Stefan Hajnoczi   fuse: add fuse_iq...
1194
  	fuse_conn_init(fc, sb->s_user_ns, &fuse_dev_fiq_ops, NULL);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1195
1196
1197
1198
1199
1200
  	fc->release = fuse_free_conn;
  	sb->s_fs_info = fc;
  
  	err = fuse_fill_super_common(sb, ctx);
  	if (err)
  		goto err_put_conn;
0720b3159   Miklos Szeredi   [PATCH] fuse: sim...
1201
1202
1203
1204
1205
1206
  	/*
  	 * 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);
0cc2656cd   Stefan Hajnoczi   fuse: extract fus...
1207
  	fuse_send_init(get_fuse_conn_super(sb));
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1208
  	return 0;
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1209
   err_put_conn:
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1210
  	fuse_conn_put(fc);
543b8f866   Tetsuo Handa   fuse: don't keep ...
1211
  	sb->s_fs_info = NULL;
c2b8f0069   Miklos Szeredi   fuse: fuse_fill_s...
1212
1213
1214
   err_fput:
  	fput(file);
   err:
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1215
1216
  	return err;
  }
c30da2e98   David Howells   fuse: convert to ...
1217
  static int fuse_get_tree(struct fs_context *fc)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1218
  {
c30da2e98   David Howells   fuse: convert to ...
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
  	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...
1236
  	.reconfigure	= fuse_reconfigure,
c30da2e98   David Howells   fuse: convert to ...
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
  	.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;
  
  #ifdef CONFIG_BLOCK
783863d64   Miklos Szeredi   fuse: dissociate ...
1255
  	if (fc->fs_type == &fuseblk_fs_type) {
c30da2e98   David Howells   fuse: convert to ...
1256
  		ctx->is_bdev = true;
783863d64   Miklos Szeredi   fuse: dissociate ...
1257
1258
  		ctx->destroy = true;
  	}
c30da2e98   David Howells   fuse: convert to ...
1259
1260
1261
1262
1263
  #endif
  
  	fc->fs_private = ctx;
  	fc->ops = &fuse_context_ops;
  	return 0;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1264
  }
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1265
  static void fuse_sb_destroy(struct super_block *sb)
3b463ae0c   John Muir   fuse: invalidatio...
1266
1267
1268
1269
  {
  	struct fuse_conn *fc = get_fuse_conn_super(sb);
  
  	if (fc) {
1ccd1ea24   Miklos Szeredi   fuse: convert des...
1270
1271
  		if (fc->destroy)
  			fuse_send_destroy(fc);
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1272

eb98e3bdf   Miklos Szeredi   fuse: clean up ab...
1273
  		fuse_abort_conn(fc);
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1274
  		fuse_wait_aborted(fc);
3b463ae0c   John Muir   fuse: invalidatio...
1275
1276
1277
1278
  		down_write(&fc->killsb);
  		fc->sb = NULL;
  		up_write(&fc->killsb);
  	}
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1279
  }
3b463ae0c   John Muir   fuse: invalidatio...
1280

783863d64   Miklos Szeredi   fuse: dissociate ...
1281
  void fuse_kill_sb_anon(struct super_block *sb)
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1282
1283
  {
  	fuse_sb_destroy(sb);
3b463ae0c   John Muir   fuse: invalidatio...
1284
1285
  	kill_anon_super(sb);
  }
783863d64   Miklos Szeredi   fuse: dissociate ...
1286
  EXPORT_SYMBOL_GPL(fuse_kill_sb_anon);
3b463ae0c   John Muir   fuse: invalidatio...
1287

875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1288
1289
1290
  static struct file_system_type fuse_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "fuse",
4ad769f3c   Eric W. Biederman   fuse: Allow fully...
1291
  	.fs_flags	= FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
c30da2e98   David Howells   fuse: convert to ...
1292
  	.init_fs_context = fuse_init_fs_context,
d7167b149   Al Viro   fs_parse: fold fs...
1293
  	.parameters	= fuse_fs_parameters,
3b463ae0c   John Muir   fuse: invalidatio...
1294
  	.kill_sb	= fuse_kill_sb_anon,
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1295
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
1296
  MODULE_ALIAS_FS("fuse");
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1297
1298
  
  #ifdef CONFIG_BLOCK
3b463ae0c   John Muir   fuse: invalidatio...
1299
1300
  static void fuse_kill_sb_blk(struct super_block *sb)
  {
e8f3bd773   Miklos Szeredi   fuse: Fix oops at...
1301
  	fuse_sb_destroy(sb);
3b463ae0c   John Muir   fuse: invalidatio...
1302
1303
  	kill_block_super(sb);
  }
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1304
1305
1306
  static struct file_system_type fuseblk_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "fuseblk",
c30da2e98   David Howells   fuse: convert to ...
1307
  	.init_fs_context = fuse_init_fs_context,
d7167b149   Al Viro   fs_parse: fold fs...
1308
  	.parameters	= fuse_fs_parameters,
3b463ae0c   John Muir   fuse: invalidatio...
1309
  	.kill_sb	= fuse_kill_sb_blk,
edad01e2a   Alexey Dobriyan   fuse: ->fs_flags ...
1310
  	.fs_flags	= FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1311
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
1312
  MODULE_ALIAS_FS("fuseblk");
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1313

875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
  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...
1333
  static void fuse_inode_init_once(void *foo)
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1334
  {
1729a16c2   Miklos Szeredi   fuse: style fixes
1335
  	struct inode *inode = foo;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1336

a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
1337
  	inode_init_once(inode);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1338
1339
1340
1341
1342
  }
  
  static int __init fuse_fs_init(void)
  {
  	int err;
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1343
  	fuse_inode_cachep = kmem_cache_create("fuse_inode",
df206988e   Johannes Weiner   fs: fuse: account...
1344
1345
1346
  			sizeof(struct fuse_inode), 0,
  			SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT,
  			fuse_inode_init_once);
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1347
1348
  	err = -ENOMEM;
  	if (!fuse_inode_cachep)
988f03256   Al Viro   fuse: register_fi...
1349
1350
1351
1352
1353
1354
1355
1356
1357
  		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...
1358
1359
  
  	return 0;
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1360

988f03256   Al Viro   fuse: register_fi...
1361
   out3:
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1362
  	unregister_fuseblk();
988f03256   Al Viro   fuse: register_fi...
1363
1364
   out2:
  	kmem_cache_destroy(fuse_inode_cachep);
d6392f873   Miklos Szeredi   [PATCH] fuse: add...
1365
   out:
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1366
1367
1368
1369
1370
1371
  	return err;
  }
  
  static void fuse_fs_cleanup(void)
  {
  	unregister_filesystem(&fuse_fs_type);
875d95ec9   Miklos Szeredi   [PATCH] fuse: fix...
1372
  	unregister_fuseblk();
8c0a85377   Kirill A. Shutemov   fs: push rcu_barr...
1373
1374
1375
1376
1377
1378
  
  	/*
  	 * Make sure all delayed rcu free inodes are flushed before we
  	 * destroy cache.
  	 */
  	rcu_barrier();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1379
1380
  	kmem_cache_destroy(fuse_inode_cachep);
  }
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1381
  static struct kobject *fuse_kobj;
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1382

f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1383
1384
1385
  static int fuse_sysfs_init(void)
  {
  	int err;
00d266662   Greg Kroah-Hartman   kobject: convert ...
1386
  	fuse_kobj = kobject_create_and_add("fuse", fs_kobj);
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1387
1388
  	if (!fuse_kobj) {
  		err = -ENOMEM;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1389
  		goto out_err;
5c89e17e9   Greg Kroah-Hartman   kobject: convert ...
1390
  	}
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1391

f9bb48825   Eric W. Biederman   sysfs: Create mou...
1392
1393
  	err = sysfs_create_mount_point(fuse_kobj, "connections");
  	if (err)
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1394
1395
1396
1397
1398
  		goto out_fuse_unregister;
  
  	return 0;
  
   out_fuse_unregister:
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
1399
  	kobject_put(fuse_kobj);
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1400
1401
1402
1403
1404
1405
   out_err:
  	return err;
  }
  
  static void fuse_sysfs_cleanup(void)
  {
f9bb48825   Eric W. Biederman   sysfs: Create mou...
1406
  	sysfs_remove_mount_point(fuse_kobj, "connections");
197b12d67   Greg Kroah-Hartman   Kobject: convert ...
1407
  	kobject_put(fuse_kobj);
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1408
  }
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1409
1410
1411
  static int __init fuse_init(void)
  {
  	int res;
f2294482f   Kirill Smelkov   fuse: convert pri...
1412
1413
1414
  	pr_info("init (API version %i.%i)
  ",
  		FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1415

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1416
  	INIT_LIST_HEAD(&fuse_conn_list);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1417
1418
1419
  	res = fuse_fs_init();
  	if (res)
  		goto err;
334f485df   Miklos Szeredi   [PATCH] FUSE - de...
1420
1421
1422
  	res = fuse_dev_init();
  	if (res)
  		goto err_fs_cleanup;
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1423
1424
1425
  	res = fuse_sysfs_init();
  	if (res)
  		goto err_dev_cleanup;
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1426
1427
1428
  	res = fuse_ctl_init();
  	if (res)
  		goto err_sysfs_cleanup;
487ea5af6   Csaba Henk   fuse: limit user-...
1429
1430
  	sanitize_global_limit(&max_user_bgreq);
  	sanitize_global_limit(&max_user_congthresh);
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1431
  	return 0;
bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1432
1433
   err_sysfs_cleanup:
  	fuse_sysfs_cleanup();
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1434
1435
   err_dev_cleanup:
  	fuse_dev_cleanup();
334f485df   Miklos Szeredi   [PATCH] FUSE - de...
1436
1437
   err_fs_cleanup:
  	fuse_fs_cleanup();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1438
1439
1440
1441
1442
1443
   err:
  	return res;
  }
  
  static void __exit fuse_exit(void)
  {
f2294482f   Kirill Smelkov   fuse: convert pri...
1444
1445
  	pr_debug("exit
  ");
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1446

bafa96541   Miklos Szeredi   [PATCH] fuse: add...
1447
  	fuse_ctl_cleanup();
f543f253f   Miklos Szeredi   [PATCH] fuse: mak...
1448
  	fuse_sysfs_cleanup();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1449
  	fuse_fs_cleanup();
334f485df   Miklos Szeredi   [PATCH] FUSE - de...
1450
  	fuse_dev_cleanup();
d8a5ba454   Miklos Szeredi   [PATCH] FUSE - core
1451
1452
1453
1454
  }
  
  module_init(fuse_init);
  module_exit(fuse_exit);