summaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2017-08-01 17:29:29 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2017-08-15 11:54:48 -0400
commit2ce209c42c01ca976ad680fea52a8e8b9a53643b (patch)
tree1728cf3caf2430e3a4cd944228b31f084f577115 /fs/nfs/write.c
parent8205b9ce030288e104a3024344f2a0a086231e36 (diff)
NFS: Wait for requests that are locked on the commit list
If a request is on the commit list, but is locked, we will currently skip it, which can lead to livelocking when the commit count doesn't reduce to zero. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 866702823869..5dd3b212376e 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1030,13 +1030,22 @@ int
1030nfs_scan_commit_list(struct list_head *src, struct list_head *dst, 1030nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
1031 struct nfs_commit_info *cinfo, int max) 1031 struct nfs_commit_info *cinfo, int max)
1032{ 1032{
1033 struct nfs_page *req, *tmp; 1033 struct nfs_page *req;
1034 int ret = 0; 1034 int ret = 0;
1035 1035
1036 list_for_each_entry_safe(req, tmp, src, wb_list) { 1036 while(!list_empty(src)) {
1037 if (!nfs_lock_request(req)) 1037 req = list_first_entry(src, struct nfs_page, wb_list);
1038 continue;
1039 kref_get(&req->wb_kref); 1038 kref_get(&req->wb_kref);
1039 if (!nfs_lock_request(req)) {
1040 int status;
1041 mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
1042 status = nfs_wait_on_request(req);
1043 nfs_release_request(req);
1044 mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
1045 if (status < 0)
1046 break;
1047 continue;
1048 }
1040 nfs_request_remove_commit_list(req, cinfo); 1049 nfs_request_remove_commit_list(req, cinfo);
1041 nfs_list_add_request(req, dst); 1050 nfs_list_add_request(req, dst);
1042 ret++; 1051 ret++;