Obvious leak, which cannot detected unless you try to unload fuse module. Found accidentally searching for reasons why fuse_dev_find_request take 7% of cpu in profiles.
Also, make it in more optimal way, fget() is too expensive and well seen on profiles, there is lighter way relying on rcu protection. Signed-off-by: Alexey Kuznetsov <kuz...@virtuozzo.com> Acked-by:: Liu Kui <kui....@virtuozzo.com> --- fs/fuse/dev.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index f5594e4..1db40f0 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -19,6 +19,7 @@ #include <linux/slab.h> #include <linux/pipe_fs_i.h> #include <linux/swap.h> +#include <linux/fdtable.h> #include <linux/splice.h> #include <linux/sched.h> @@ -2678,16 +2679,29 @@ int fuse_dev_release(struct inode *inode, struct file *file) struct fuse_req *fuse_dev_find_request(int fd, u64 unique) { - struct file *f = fget(fd); - struct fuse_dev *fud = fuse_get_dev(f); - struct fuse_pqueue *fpq = &fud->pq; + struct file * file; + struct fuse_dev *fud; + struct fuse_pqueue *fpq; struct fuse_req *req = NULL; + rcu_read_lock(); + file = files_lookup_fd_rcu(current->files, fd); + if (!file) + goto out; + + if (file->f_op != &fuse_dev_operations) + goto out; + + fud = fuse_get_dev(file); + fpq = &fud->pq; + spin_lock(&fpq->lock); if (fpq->connected) req = request_find(&fud->pq, unique); spin_unlock(&fpq->lock); +out: + rcu_read_unlock(); return req; } EXPORT_SYMBOL_GPL(fuse_dev_find_request); -- 1.8.3.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel