Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse update from Miklos Szeredi:
"A bugfix and cleanups"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: release: private_data cannot be NULL
fuse: cleanup fuse_file refcounting
fuse: add missing FR_FORCE

+13 -18
+1 -1
fs/fuse/dir.c
··· 473 473 if (err) { 474 474 fuse_sync_release(ff, flags); 475 475 } else { 476 - file->private_data = fuse_file_get(ff); 476 + file->private_data = ff; 477 477 fuse_finish_open(inode, file); 478 478 } 479 479 return err;
+12 -16
fs/fuse/file.c
··· 58 58 } 59 59 60 60 INIT_LIST_HEAD(&ff->write_entry); 61 - atomic_set(&ff->count, 0); 61 + atomic_set(&ff->count, 1); 62 62 RB_CLEAR_NODE(&ff->polled_node); 63 63 init_waitqueue_head(&ff->poll_wait); 64 64 ··· 75 75 kfree(ff); 76 76 } 77 77 78 - struct fuse_file *fuse_file_get(struct fuse_file *ff) 78 + static struct fuse_file *fuse_file_get(struct fuse_file *ff) 79 79 { 80 80 atomic_inc(&ff->count); 81 81 return ff; ··· 100 100 iput(req->misc.release.inode); 101 101 fuse_put_request(ff->fc, req); 102 102 } else if (sync) { 103 + __set_bit(FR_FORCE, &req->flags); 103 104 __clear_bit(FR_BACKGROUND, &req->flags); 104 105 fuse_request_send(ff->fc, req); 105 106 iput(req->misc.release.inode); ··· 147 146 ff->open_flags &= ~FOPEN_DIRECT_IO; 148 147 149 148 ff->nodeid = nodeid; 150 - file->private_data = fuse_file_get(ff); 149 + file->private_data = ff; 151 150 152 151 return 0; 153 152 } ··· 246 245 247 246 void fuse_release_common(struct file *file, int opcode) 248 247 { 249 - struct fuse_file *ff; 250 - struct fuse_req *req; 248 + struct fuse_file *ff = file->private_data; 249 + struct fuse_req *req = ff->reserved_req; 251 250 252 - ff = file->private_data; 253 - if (unlikely(!ff)) 254 - return; 255 - 256 - req = ff->reserved_req; 257 251 fuse_prepare_release(ff, file->f_flags, opcode); 258 252 259 253 if (ff->flock) { ··· 293 297 294 298 void fuse_sync_release(struct fuse_file *ff, int flags) 295 299 { 296 - WARN_ON(atomic_read(&ff->count) > 1); 300 + WARN_ON(atomic_read(&ff->count) != 1); 297 301 fuse_prepare_release(ff, flags, FUSE_RELEASE); 298 - __set_bit(FR_FORCE, &ff->reserved_req->flags); 299 - __clear_bit(FR_BACKGROUND, &ff->reserved_req->flags); 300 - fuse_request_send(ff->fc, ff->reserved_req); 301 - fuse_put_request(ff->fc, ff->reserved_req); 302 - kfree(ff); 302 + /* 303 + * iput(NULL) is a no-op and since the refcount is 1 and everything's 304 + * synchronous, we are fine with not doing igrab() here" 305 + */ 306 + fuse_file_put(ff, true); 303 307 } 304 308 EXPORT_SYMBOL_GPL(fuse_sync_release); 305 309
-1
fs/fuse/fuse_i.h
··· 732 732 int fuse_open_common(struct inode *inode, struct file *file, bool isdir); 733 733 734 734 struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); 735 - struct fuse_file *fuse_file_get(struct fuse_file *ff); 736 735 void fuse_file_free(struct fuse_file *ff); 737 736 void fuse_finish_open(struct inode *inode, struct file *file); 738 737