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) unsigned int pos = 0; unsigned int len = nfs_page_length(req->wb_page); - nfs_page_group_lock(req, true); + nfs_page_group_lock(req, false); do { tmp = nfs_page_group_search_locked(req->wb_head, pos); @@ -478,10 +478,23 @@ try_again: return NULL; } - /* lock each request in the page group */ - ret = nfs_page_group_lock(head, false); - if (ret < 0) + /* holding inode lock, so always make a non-blocking call to try the + * page group lock */ + ret = nfs_page_group_lock(head, true); + if (ret < 0) { + spin_unlock(&inode->i_lock); + + if (!nonblock && ret == -EAGAIN) { + nfs_page_group_lock_wait(head); + nfs_release_request(head); + goto try_again; + } + + nfs_release_request(head); return ERR_PTR(ret); + } + + /* lock each request in the page group */ subreq = head; do { /* |