Skip to content

Commit bd37d6f

Browse files
committed
NFSv4: Convert nfs_lock_and_join_requests() to use nfs_page_find_head_request()
Hide the locking from nfs_lock_and_join_requests() so that we can separate out the requirements for swapcache pages. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
1 parent 7e8a30f commit bd37d6f

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

fs/nfs/write.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
154154
set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
155155
}
156156

157+
static struct nfs_page *
158+
nfs_page_private_request(struct page *page)
159+
{
160+
if (!PagePrivate(page))
161+
return NULL;
162+
return (struct nfs_page *)page_private(page);
163+
}
164+
157165
/*
158166
* nfs_page_find_head_request_locked - find head request associated with @page
159167
*
@@ -164,11 +172,10 @@ static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
164172
static struct nfs_page *
165173
nfs_page_find_head_request_locked(struct nfs_inode *nfsi, struct page *page)
166174
{
167-
struct nfs_page *req = NULL;
175+
struct nfs_page *req;
168176

169-
if (PagePrivate(page))
170-
req = (struct nfs_page *)page_private(page);
171-
else if (unlikely(PageSwapCache(page)))
177+
req = nfs_page_private_request(page);
178+
if (!req && unlikely(PageSwapCache(page)))
172179
req = nfs_page_search_commits_for_head_request_locked(nfsi,
173180
page);
174181

@@ -448,31 +455,29 @@ nfs_lock_and_join_requests(struct page *page)
448455
int ret;
449456

450457
try_again:
451-
if (!(PagePrivate(page) || PageSwapCache(page)))
452-
return NULL;
453-
spin_lock(&inode->i_lock);
454458
/*
455459
* A reference is taken only on the head request which acts as a
456460
* reference to the whole page group - the group will not be destroyed
457461
* until the head reference is released.
458462
*/
459-
head = nfs_page_find_head_request_locked(NFS_I(inode), page);
460-
461-
if (!head) {
462-
spin_unlock(&inode->i_lock);
463+
head = nfs_page_find_head_request(page);
464+
if (!head)
463465
return NULL;
464-
}
465466

466467
/* lock the page head first in order to avoid an ABBA inefficiency */
467468
if (!nfs_lock_request(head)) {
468-
spin_unlock(&inode->i_lock);
469469
ret = nfs_wait_on_request(head);
470470
nfs_release_request(head);
471471
if (ret < 0)
472472
return ERR_PTR(ret);
473473
goto try_again;
474474
}
475-
spin_unlock(&inode->i_lock);
475+
476+
/* Ensure that nobody removed the request before we locked it */
477+
if (head != nfs_page_private_request(page) && !PageSwapCache(page)) {
478+
nfs_unlock_and_release_request(head);
479+
goto try_again;
480+
}
476481

477482
ret = nfs_page_group_lock(head);
478483
if (ret < 0) {
@@ -559,7 +564,7 @@ nfs_lock_and_join_requests(struct page *page)
559564
return NULL;
560565
}
561566

562-
/* still holds ref on head from nfs_page_find_head_request_locked
567+
/* still holds ref on head from nfs_page_find_head_request
563568
* and still has lock on head from lock loop */
564569
return head;
565570
}

0 commit comments

Comments
 (0)