aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r--fs/fuse/dir.c33
1 files changed, 12 insertions, 21 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 8b8eebc5614b..b3089a083d30 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -362,19 +362,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
362} 362}
363 363
364/* 364/*
365 * Synchronous release for the case when something goes wrong in CREATE_OPEN
366 */
367static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff,
368 u64 nodeid, int flags)
369{
370 fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE);
371 ff->reserved_req->force = 1;
372 fuse_request_send(fc, ff->reserved_req);
373 fuse_put_request(fc, ff->reserved_req);
374 kfree(ff);
375}
376
377/*
378 * Atomic create+open operation 365 * Atomic create+open operation
379 * 366 *
380 * If the filesystem doesn't support this, then fall back to separate 367 * If the filesystem doesn't support this, then fall back to separate
@@ -445,12 +432,14 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
445 goto out_free_ff; 432 goto out_free_ff;
446 433
447 fuse_put_request(fc, req); 434 fuse_put_request(fc, req);
435 ff->fh = outopen.fh;
436 ff->nodeid = outentry.nodeid;
437 ff->open_flags = outopen.open_flags;
448 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 438 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
449 &outentry.attr, entry_attr_timeout(&outentry), 0); 439 &outentry.attr, entry_attr_timeout(&outentry), 0);
450 if (!inode) { 440 if (!inode) {
451 flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 441 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
452 ff->fh = outopen.fh; 442 fuse_sync_release(ff, flags);
453 fuse_sync_release(fc, ff, outentry.nodeid, flags);
454 fuse_send_forget(fc, forget_req, outentry.nodeid, 1); 443 fuse_send_forget(fc, forget_req, outentry.nodeid, 1);
455 return -ENOMEM; 444 return -ENOMEM;
456 } 445 }
@@ -460,11 +449,11 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
460 fuse_invalidate_attr(dir); 449 fuse_invalidate_attr(dir);
461 file = lookup_instantiate_filp(nd, entry, generic_file_open); 450 file = lookup_instantiate_filp(nd, entry, generic_file_open);
462 if (IS_ERR(file)) { 451 if (IS_ERR(file)) {
463 ff->fh = outopen.fh; 452 fuse_sync_release(ff, flags);
464 fuse_sync_release(fc, ff, outentry.nodeid, flags);
465 return PTR_ERR(file); 453 return PTR_ERR(file);
466 } 454 }
467 fuse_finish_open(inode, file, ff, &outopen); 455 file->private_data = fuse_file_get(ff);
456 fuse_finish_open(inode, file);
468 return 0; 457 return 0;
469 458
470 out_free_ff: 459 out_free_ff:
@@ -1035,7 +1024,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
1035 req->out.argpages = 1; 1024 req->out.argpages = 1;
1036 req->num_pages = 1; 1025 req->num_pages = 1;
1037 req->pages[0] = page; 1026 req->pages[0] = page;
1038 fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); 1027 fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, FUSE_READDIR);
1039 fuse_request_send(fc, req); 1028 fuse_request_send(fc, req);
1040 nbytes = req->out.args[0].size; 1029 nbytes = req->out.args[0].size;
1041 err = req->out.h.error; 1030 err = req->out.h.error;
@@ -1101,12 +1090,14 @@ static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
1101 1090
1102static int fuse_dir_open(struct inode *inode, struct file *file) 1091static int fuse_dir_open(struct inode *inode, struct file *file)
1103{ 1092{
1104 return fuse_open_common(inode, file, 1); 1093 return fuse_open_common(inode, file, true);
1105} 1094}
1106 1095
1107static int fuse_dir_release(struct inode *inode, struct file *file) 1096static int fuse_dir_release(struct inode *inode, struct file *file)
1108{ 1097{
1109 return fuse_release_common(inode, file, 1); 1098 fuse_release_common(file, FUSE_RELEASEDIR);
1099
1100 return 0;
1110} 1101}
1111 1102
1112static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync) 1103static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)