diff options
| author | Miklos Szeredi <mszeredi@redhat.com> | 2017-02-22 14:08:25 -0500 |
|---|---|---|
| committer | Miklos Szeredi <mszeredi@redhat.com> | 2017-02-22 14:08:25 -0500 |
| commit | 267d84449f52349ee252db684ed95ede18e51744 (patch) | |
| tree | 9ed80653721635aabd7dcb425b5779a7c33eddff /fs | |
| parent | 2e38bea99a80eab408adee27f873a188d57b76cb (diff) | |
fuse: cleanup fuse_file refcounting
struct fuse_file is stored in file->private_data. Make this always be a
counting reference for consistency.
This also allows fuse_sync_release() to call fuse_file_put() instead of
partially duplicating its functionality.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/fuse/dir.c | 2 | ||||
| -rw-r--r-- | fs/fuse/file.c | 18 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 1 |
3 files changed, 10 insertions, 11 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 811fd8929a18..e816166ce42f 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -473,7 +473,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
| 473 | if (err) { | 473 | if (err) { |
| 474 | fuse_sync_release(ff, flags); | 474 | fuse_sync_release(ff, flags); |
| 475 | } else { | 475 | } else { |
| 476 | file->private_data = fuse_file_get(ff); | 476 | file->private_data = ff; |
| 477 | fuse_finish_open(inode, file); | 477 | fuse_finish_open(inode, file); |
| 478 | } | 478 | } |
| 479 | return err; | 479 | return err; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 5ec5870e423a..a5f79c59fe1e 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -58,7 +58,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) | |||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | INIT_LIST_HEAD(&ff->write_entry); | 60 | INIT_LIST_HEAD(&ff->write_entry); |
| 61 | atomic_set(&ff->count, 0); | 61 | atomic_set(&ff->count, 1); |
| 62 | RB_CLEAR_NODE(&ff->polled_node); | 62 | RB_CLEAR_NODE(&ff->polled_node); |
| 63 | init_waitqueue_head(&ff->poll_wait); | 63 | init_waitqueue_head(&ff->poll_wait); |
| 64 | 64 | ||
| @@ -75,7 +75,7 @@ void fuse_file_free(struct fuse_file *ff) | |||
| 75 | kfree(ff); | 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 | atomic_inc(&ff->count); | 80 | atomic_inc(&ff->count); |
| 81 | return ff; | 81 | return ff; |
| @@ -147,7 +147,7 @@ int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, | |||
| 147 | ff->open_flags &= ~FOPEN_DIRECT_IO; | 147 | ff->open_flags &= ~FOPEN_DIRECT_IO; |
| 148 | 148 | ||
| 149 | ff->nodeid = nodeid; | 149 | ff->nodeid = nodeid; |
| 150 | file->private_data = fuse_file_get(ff); | 150 | file->private_data = ff; |
| 151 | 151 | ||
| 152 | return 0; | 152 | return 0; |
| 153 | } | 153 | } |
| @@ -298,13 +298,13 @@ static int fuse_release(struct inode *inode, struct file *file) | |||
| 298 | 298 | ||
| 299 | void fuse_sync_release(struct fuse_file *ff, int flags) | 299 | void fuse_sync_release(struct fuse_file *ff, int flags) |
| 300 | { | 300 | { |
| 301 | WARN_ON(atomic_read(&ff->count) > 1); | 301 | WARN_ON(atomic_read(&ff->count) != 1); |
| 302 | fuse_prepare_release(ff, flags, FUSE_RELEASE); | 302 | fuse_prepare_release(ff, flags, FUSE_RELEASE); |
| 303 | __set_bit(FR_FORCE, &ff->reserved_req->flags); | 303 | /* |
| 304 | __clear_bit(FR_BACKGROUND, &ff->reserved_req->flags); | 304 | * iput(NULL) is a no-op and since the refcount is 1 and everything's |
| 305 | fuse_request_send(ff->fc, ff->reserved_req); | 305 | * synchronous, we are fine with not doing igrab() here" |
| 306 | fuse_put_request(ff->fc, ff->reserved_req); | 306 | */ |
| 307 | kfree(ff); | 307 | fuse_file_put(ff, true); |
| 308 | } | 308 | } |
| 309 | EXPORT_SYMBOL_GPL(fuse_sync_release); | 309 | EXPORT_SYMBOL_GPL(fuse_sync_release); |
| 310 | 310 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 91307940c8ac..83f797271aef 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -732,7 +732,6 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, | |||
| 732 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir); | 732 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir); |
| 733 | 733 | ||
| 734 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); | 734 | struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); |
| 735 | struct fuse_file *fuse_file_get(struct fuse_file *ff); | ||
| 736 | void fuse_file_free(struct fuse_file *ff); | 735 | void fuse_file_free(struct fuse_file *ff); |
| 737 | void fuse_finish_open(struct inode *inode, struct file *file); | 736 | void fuse_finish_open(struct inode *inode, struct file *file); |
| 738 | 737 | ||
