From 9784782e98d48f43c7e4224977263ad42e921575 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Mon, 20 Apr 2020 17:54:38 +0200 Subject: [PATCH] UPSTREAM: fuse: store fuse_conn in fuse_req Every fuse_req belongs to a fuse_conn. Right now, we always know which fuse_conn that is based on the respective device, but we want to allow multiple (sub)mounts per single connection, and then the corresponding filesystem is not going to be so trivial to obtain. Storing a pointer to the associated fuse_conn in every fuse_req will allow us to trivially find any request's superblock (and thus filesystem) even then. Change-Id: I60a5e891535ab5c172d3658c3b6f42f4804e2a21 Signed-off-by: Max Reitz Reviewed-by: Stefan Hajnoczi Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 13 +++++++------ fs/fuse/fuse_i.h | 3 +++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ad7a72cf6bfd..a5a5e8aa81e3 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -42,20 +42,21 @@ static struct fuse_dev *fuse_get_dev(struct file *file) return READ_ONCE(file->private_data); } -static void fuse_request_init(struct fuse_req *req) +static void fuse_request_init(struct fuse_conn *fc, struct fuse_req *req) { INIT_LIST_HEAD(&req->list); INIT_LIST_HEAD(&req->intr_entry); init_waitqueue_head(&req->waitq); refcount_set(&req->count, 1); __set_bit(FR_PENDING, &req->flags); + req->fc = fc; } -static struct fuse_req *fuse_request_alloc(gfp_t flags) +static struct fuse_req *fuse_request_alloc(struct fuse_conn *fc, gfp_t flags) { struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags); if (req) - fuse_request_init(req); + fuse_request_init(fc, req); return req; } @@ -127,7 +128,7 @@ static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background) if (fc->conn_error) goto out; - req = fuse_request_alloc(GFP_KERNEL); + req = fuse_request_alloc(fc, GFP_KERNEL); err = -ENOMEM; if (!req) { if (for_background) @@ -487,7 +488,7 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) if (args->force) { atomic_inc(&fc->num_waiting); - req = fuse_request_alloc(GFP_KERNEL | __GFP_NOFAIL); + req = fuse_request_alloc(fc, GFP_KERNEL | __GFP_NOFAIL); if (!args->nocreds) fuse_force_creds(fc, req); @@ -554,7 +555,7 @@ int fuse_simple_background(struct fuse_conn *fc, struct fuse_args *args, if (args->force) { WARN_ON(!args->nocreds); - req = fuse_request_alloc(gfp_flags); + req = fuse_request_alloc(fc, gfp_flags); if (!req) return -ENOMEM; __set_bit(FR_BACKGROUND, &req->flags); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index d92d289cd76d..89ce51ecf87d 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -394,6 +394,9 @@ struct fuse_req { /** virtio-fs's physically contiguous buffer for in and out args */ void *argbuf; #endif + + /** fuse_conn this request belongs to */ + struct fuse_conn *fc; }; struct fuse_iqueue;