summaryrefslogtreecommitdiff
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2024-07-01 07:26:50 +0200
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2024-07-08 13:47:51 -0400
commit9eb7c484db1ae993648fc9b9d48a295f4d99afb8 (patch)
treec4af8274edc2b3dd2dc6ad846be076636e90c00d /fs/nfs/write.c
parent02e61ec1e2c1da136bbf7f6bbabc46733c53b035 (diff)
nfs: simplify nfs_folio_find_and_lock_request
nfs_folio_find_and_lock_request and the nfs_page_group_lock_head helper called by it spend quite some effort to deal with head vs subrequests. But given that only the head request can be stashed in the folio private data, non of that is required. Fold the locking logic from nfs_page_group_lock_head into nfs_folio_find_and_lock_request and simplify the result based on the invariant that we always find the head request in the folio private data. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index a56bb49af55a..69336bca26f5 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -197,28 +197,32 @@ static struct nfs_page *nfs_folio_find_head_request(struct folio *folio)
static struct nfs_page *nfs_folio_find_and_lock_request(struct folio *folio)
{
struct inode *inode = folio->mapping->host;
- struct nfs_page *req, *head;
+ struct nfs_page *head;
int ret;
- for (;;) {
- req = nfs_folio_find_head_request(folio);
- if (!req)
- return req;
- head = nfs_page_group_lock_head(req);
- if (head != req)
- nfs_release_request(req);
- if (IS_ERR(head))
- return head;
- ret = nfs_cancel_remove_inode(head, inode);
- if (ret < 0) {
- nfs_unlock_and_release_request(head);
+retry:
+ head = nfs_folio_find_head_request(folio);
+ if (!head)
+ return NULL;
+
+ while (!nfs_lock_request(head)) {
+ ret = nfs_wait_on_request(head);
+ if (ret < 0)
return ERR_PTR(ret);
- }
- /* Ensure that nobody removed the request before we locked it */
- if (head == folio->private)
- break;
+ }
+
+ /* Ensure that nobody removed the request before we locked it */
+ if (head != folio->private) {
nfs_unlock_and_release_request(head);
+ goto retry;
}
+
+ ret = nfs_cancel_remove_inode(head, inode);
+ if (ret < 0) {
+ nfs_unlock_and_release_request(head);
+ return ERR_PTR(ret);
+ }
+
return head;
}