From a6e033c41cc9f0ec105f5d208b0a820118e2bda8 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Tue, 14 Jun 2022 12:19:02 +0900 Subject: [PATCH] 9p: fix EBADF errors in cached mode cached operations sometimes need to do invalid operations (e.g. read on a write only file) Historic fscache had added a "writeback fid" for this, but the conversion to new fscache somehow lost usage of it: use the writeback fid instead of normal one. Note that the way this works (writeback fid being linked to inode) means we might use overprivileged fid for some operations, e.g. write as root when we shouldn't. Ideally we should keep both fids handy, and only use the writeback fid when really required e.g. reads to a write-only file to fill in the page cache (read-modify-write); but this is the situation we've always had and this commit only fixes an issue we've had for too long. Fixes: eb497943fa21 ("9p: Convert to using the netfs helper lib to do reads and caching") [unfortunately won't apply cleanly due to netfs name changes] Cc: stable@vger.kernel.org Cc: David Howells Reported-By: Christian Schoenebeck Signed-off-by: Dominique Martinet --- fs/9p/vfs_addr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index a8f512b44a851d..7f924e671e3ebc 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -58,7 +58,17 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq) */ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file) { - struct p9_fid *fid = file->private_data; + struct inode *inode = file_inode(file); + struct v9fs_inode *v9inode = V9FS_I(inode); + struct p9_fid *fid = v9inode->writeback_fid; + + /* If there is no writeback fid this file only ever has had + * read-only opens, so we can use file's fid which should + * always be set instead */ + if (!fid) + fid = file->private_data; + + BUG_ON(!fid); refcount_inc(&fid->count); rreq->netfs_priv = fid;