summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2025-08-16 17:25:20 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-09-04 16:30:20 +0300
commit181feb41f0b268e6288bf9a7b984624d7fe2031d (patch)
treebdf8ba80c130ea43a9dc26c00181e3ef323a7d49 /include/linux
parent9a1963404cc2eef69d2f8a42861bdf63d087dd5d (diff)
downloadlinux-181feb41f0b268e6288bf9a7b984624d7fe2031d.tar.xz
NFS: Fix a race when updating an existing write
commit 76d2e3890fb169168c73f2e4f8375c7cc24a765e upstream. After nfs_lock_and_join_requests() tests for whether the request is still attached to the mapping, nothing prevents a call to nfs_inode_remove_request() from succeeding until we actually lock the page group. The reason is that whoever called nfs_inode_remove_request() doesn't necessarily have a lock on the page group head. So in order to avoid races, let's take the page group lock earlier in nfs_lock_and_join_requests(), and hold it across the removal of the request in nfs_inode_remove_request(). Reported-by: Jeff Layton <jlayton@kernel.org> Tested-by: Joe Quanaim <jdq@meta.com> Tested-by: Andrew Steffen <aksteffen@meta.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Fixes: bd37d6fce184 ("NFSv4: Convert nfs_lock_and_join_requests() to use nfs_page_find_head_request()") Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/nfs_page.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 3a0f7ebe5388..6a46069c5a36 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -162,6 +162,7 @@ extern void nfs_join_page_group(struct nfs_page *head,
extern int nfs_page_group_lock(struct nfs_page *);
extern void nfs_page_group_unlock(struct nfs_page *);
extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
+extern bool nfs_page_group_sync_on_bit_locked(struct nfs_page *, unsigned int);
extern int nfs_page_set_headlock(struct nfs_page *req);
extern void nfs_page_clear_headlock(struct nfs_page *req);
extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);