diff options
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e3b5cf28bdc5..175d5d073ccf 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -241,7 +241,7 @@ static bool nfs_page_group_covers_page(struct nfs_page *req) | |||
241 | unsigned int pos = 0; | 241 | unsigned int pos = 0; |
242 | unsigned int len = nfs_page_length(req->wb_page); | 242 | unsigned int len = nfs_page_length(req->wb_page); |
243 | 243 | ||
244 | nfs_page_group_lock(req, true); | 244 | nfs_page_group_lock(req, false); |
245 | 245 | ||
246 | do { | 246 | do { |
247 | tmp = nfs_page_group_search_locked(req->wb_head, pos); | 247 | tmp = nfs_page_group_search_locked(req->wb_head, pos); |
@@ -478,10 +478,23 @@ try_again: | |||
478 | return NULL; | 478 | return NULL; |
479 | } | 479 | } |
480 | 480 | ||
481 | /* lock each request in the page group */ | 481 | /* holding inode lock, so always make a non-blocking call to try the |
482 | ret = nfs_page_group_lock(head, false); | 482 | * page group lock */ |
483 | if (ret < 0) | 483 | ret = nfs_page_group_lock(head, true); |
484 | if (ret < 0) { | ||
485 | spin_unlock(&inode->i_lock); | ||
486 | |||
487 | if (!nonblock && ret == -EAGAIN) { | ||
488 | nfs_page_group_lock_wait(head); | ||
489 | nfs_release_request(head); | ||
490 | goto try_again; | ||
491 | } | ||
492 | |||
493 | nfs_release_request(head); | ||
484 | return ERR_PTR(ret); | 494 | return ERR_PTR(ret); |
495 | } | ||
496 | |||
497 | /* lock each request in the page group */ | ||
485 | subreq = head; | 498 | subreq = head; |
486 | do { | 499 | do { |
487 | /* | 500 | /* |