aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-17 12:41:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-17 12:41:32 -0500
commitc103b21c20ee3d173ccccb7d5ca8f5b8bc02cac3 (patch)
tree9fed771f32b878b5bd16f2251052c5177820fcd2
parent603ba7e41bf5d405aba22294af5d075d8898176d (diff)
parent1c68271cf1bfe7f3664b6dbf4ffd5fe11130be5c (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse update from Miklos Szeredi: "The first part makes sure we don't hold up umount with pending async requests. In addition to being a cleanup, this is a small behavioral change (for the better) and unlikely to break anything. The second part prepares for a cleanup of the fuse device I/O code by adding a helper for simple request submission, with some savings in line numbers already realized" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: use file_inode() in fuse_file_fallocate() fuse: introduce fuse_simple_request() helper fuse: reduce max out args fuse: hold inode instead of path after release fuse: flush requests on umount fuse: don't wake up reserved req in fuse_conn_kill()
-rw-r--r--fs/fuse/cuse.c2
-rw-r--r--fs/fuse/dev.c29
-rw-r--r--fs/fuse/dir.c538
-rw-r--r--fs/fuse/file.c230
-rw-r--r--fs/fuse/fuse_i.h45
-rw-r--r--fs/fuse/inode.c39
6 files changed, 359 insertions, 524 deletions
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index 966ace8b243f..28d0c7abba1c 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -415,7 +415,7 @@ err_unlock:
415err_region: 415err_region:
416 unregister_chrdev_region(devt, 1); 416 unregister_chrdev_region(devt, 1);
417err: 417err:
418 fuse_conn_kill(fc); 418 fuse_abort_conn(fc);
419 goto out; 419 goto out;
420} 420}
421 421
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index ca887314aba9..ba1107977f2e 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -511,6 +511,35 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
511} 511}
512EXPORT_SYMBOL_GPL(fuse_request_send); 512EXPORT_SYMBOL_GPL(fuse_request_send);
513 513
514ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
515{
516 struct fuse_req *req;
517 ssize_t ret;
518
519 req = fuse_get_req(fc, 0);
520 if (IS_ERR(req))
521 return PTR_ERR(req);
522
523 req->in.h.opcode = args->in.h.opcode;
524 req->in.h.nodeid = args->in.h.nodeid;
525 req->in.numargs = args->in.numargs;
526 memcpy(req->in.args, args->in.args,
527 args->in.numargs * sizeof(struct fuse_in_arg));
528 req->out.argvar = args->out.argvar;
529 req->out.numargs = args->out.numargs;
530 memcpy(req->out.args, args->out.args,
531 args->out.numargs * sizeof(struct fuse_arg));
532 fuse_request_send(fc, req);
533 ret = req->out.h.error;
534 if (!ret && args->out.argvar) {
535 BUG_ON(args->out.numargs != 1);
536 ret = req->out.args[0].size;
537 }
538 fuse_put_request(fc, req);
539
540 return ret;
541}
542
514static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 543static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
515 struct fuse_req *req) 544 struct fuse_req *req)
516{ 545{
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index df562cc87763..252b8a5de8b5 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -145,22 +145,22 @@ static void fuse_invalidate_entry(struct dentry *entry)
145 fuse_invalidate_entry_cache(entry); 145 fuse_invalidate_entry_cache(entry);
146} 146}
147 147
148static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_req *req, 148static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
149 u64 nodeid, struct qstr *name, 149 u64 nodeid, struct qstr *name,
150 struct fuse_entry_out *outarg) 150 struct fuse_entry_out *outarg)
151{ 151{
152 memset(outarg, 0, sizeof(struct fuse_entry_out)); 152 memset(outarg, 0, sizeof(struct fuse_entry_out));
153 req->in.h.opcode = FUSE_LOOKUP; 153 args->in.h.opcode = FUSE_LOOKUP;
154 req->in.h.nodeid = nodeid; 154 args->in.h.nodeid = nodeid;
155 req->in.numargs = 1; 155 args->in.numargs = 1;
156 req->in.args[0].size = name->len + 1; 156 args->in.args[0].size = name->len + 1;
157 req->in.args[0].value = name->name; 157 args->in.args[0].value = name->name;
158 req->out.numargs = 1; 158 args->out.numargs = 1;
159 if (fc->minor < 9) 159 if (fc->minor < 9)
160 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; 160 args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
161 else 161 else
162 req->out.args[0].size = sizeof(struct fuse_entry_out); 162 args->out.args[0].size = sizeof(struct fuse_entry_out);
163 req->out.args[0].value = outarg; 163 args->out.args[0].value = outarg;
164} 164}
165 165
166u64 fuse_get_attr_version(struct fuse_conn *fc) 166u64 fuse_get_attr_version(struct fuse_conn *fc)
@@ -200,9 +200,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
200 goto invalid; 200 goto invalid;
201 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) || 201 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
202 (flags & LOOKUP_REVAL)) { 202 (flags & LOOKUP_REVAL)) {
203 int err;
204 struct fuse_entry_out outarg; 203 struct fuse_entry_out outarg;
205 struct fuse_req *req; 204 FUSE_ARGS(args);
206 struct fuse_forget_link *forget; 205 struct fuse_forget_link *forget;
207 u64 attr_version; 206 u64 attr_version;
208 207
@@ -215,31 +214,23 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
215 goto out; 214 goto out;
216 215
217 fc = get_fuse_conn(inode); 216 fc = get_fuse_conn(inode);
218 req = fuse_get_req_nopages(fc);
219 ret = PTR_ERR(req);
220 if (IS_ERR(req))
221 goto out;
222 217
223 forget = fuse_alloc_forget(); 218 forget = fuse_alloc_forget();
224 if (!forget) { 219 ret = -ENOMEM;
225 fuse_put_request(fc, req); 220 if (!forget)
226 ret = -ENOMEM;
227 goto out; 221 goto out;
228 }
229 222
230 attr_version = fuse_get_attr_version(fc); 223 attr_version = fuse_get_attr_version(fc);
231 224
232 parent = dget_parent(entry); 225 parent = dget_parent(entry);
233 fuse_lookup_init(fc, req, get_node_id(parent->d_inode), 226 fuse_lookup_init(fc, &args, get_node_id(parent->d_inode),
234 &entry->d_name, &outarg); 227 &entry->d_name, &outarg);
235 fuse_request_send(fc, req); 228 ret = fuse_simple_request(fc, &args);
236 dput(parent); 229 dput(parent);
237 err = req->out.h.error;
238 fuse_put_request(fc, req);
239 /* Zero nodeid is same as -ENOENT */ 230 /* Zero nodeid is same as -ENOENT */
240 if (!err && !outarg.nodeid) 231 if (!ret && !outarg.nodeid)
241 err = -ENOENT; 232 ret = -ENOENT;
242 if (!err) { 233 if (!ret) {
243 fi = get_fuse_inode(inode); 234 fi = get_fuse_inode(inode);
244 if (outarg.nodeid != get_node_id(inode)) { 235 if (outarg.nodeid != get_node_id(inode)) {
245 fuse_queue_forget(fc, forget, outarg.nodeid, 1); 236 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
@@ -250,7 +241,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
250 spin_unlock(&fc->lock); 241 spin_unlock(&fc->lock);
251 } 242 }
252 kfree(forget); 243 kfree(forget);
253 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) 244 if (ret == -ENOMEM)
245 goto out;
246 if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
254 goto invalid; 247 goto invalid;
255 248
256 fuse_change_attributes(inode, &outarg.attr, 249 fuse_change_attributes(inode, &outarg.attr,
@@ -296,7 +289,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
296 struct fuse_entry_out *outarg, struct inode **inode) 289 struct fuse_entry_out *outarg, struct inode **inode)
297{ 290{
298 struct fuse_conn *fc = get_fuse_conn_super(sb); 291 struct fuse_conn *fc = get_fuse_conn_super(sb);
299 struct fuse_req *req; 292 FUSE_ARGS(args);
300 struct fuse_forget_link *forget; 293 struct fuse_forget_link *forget;
301 u64 attr_version; 294 u64 attr_version;
302 int err; 295 int err;
@@ -306,24 +299,16 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
306 if (name->len > FUSE_NAME_MAX) 299 if (name->len > FUSE_NAME_MAX)
307 goto out; 300 goto out;
308 301
309 req = fuse_get_req_nopages(fc);
310 err = PTR_ERR(req);
311 if (IS_ERR(req))
312 goto out;
313 302
314 forget = fuse_alloc_forget(); 303 forget = fuse_alloc_forget();
315 err = -ENOMEM; 304 err = -ENOMEM;
316 if (!forget) { 305 if (!forget)
317