aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/filelayout/filelayout.c
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-07-03 01:07:46 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-07-12 18:22:45 -0400
commit0b0bc6ea77ec8430626e8c2f6cbdfb767b168ac1 (patch)
tree6c53179ccbf38cc4c40c555443df07bdc7365472 /fs/nfs/filelayout/filelayout.c
parentc8a3292d246f3ed326698ed6acf3286c62b7bf11 (diff)
pnfs/filelayout: retry ds commit if nfs_commitdata_alloc fails
Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Tom Haynes <Thomas.Haynes@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/filelayout/filelayout.c')
-rw-r--r--fs/nfs/filelayout/filelayout.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index a928f92bcb10..2576d28bffc0 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -1237,15 +1237,33 @@ restart:
1237 spin_unlock(cinfo->lock); 1237 spin_unlock(cinfo->lock);
1238} 1238}
1239 1239
1240static void filelayout_retry_commit(struct nfs_commit_info *cinfo, int idx)
1241{
1242 struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
1243 struct pnfs_commit_bucket *bucket = fl_cinfo->buckets;
1244 struct pnfs_layout_segment *freeme;
1245 int i;
1246
1247 for (i = idx; i < fl_cinfo->nbuckets; i++, bucket++) {
1248 if (list_empty(&bucket->committing))
1249 continue;
1250 nfs_retry_commit(&bucket->committing, bucket->clseg, cinfo);
1251 spin_lock(cinfo->lock);
1252 freeme = bucket->clseg;
1253 bucket->clseg = NULL;
1254 spin_unlock(cinfo->lock);
1255 pnfs_put_lseg(freeme);
1256 }
1257}
1258
1240static unsigned int 1259static unsigned int
1241alloc_ds_commits(struct nfs_commit_info *cinfo, struct list_head *list) 1260alloc_ds_commits(struct nfs_commit_info *cinfo, struct list_head *list)
1242{ 1261{
1243 struct pnfs_ds_commit_info *fl_cinfo; 1262 struct pnfs_ds_commit_info *fl_cinfo;
1244 struct pnfs_commit_bucket *bucket; 1263 struct pnfs_commit_bucket *bucket;
1245 struct nfs_commit_data *data; 1264 struct nfs_commit_data *data;
1246 int i, j; 1265 int i;
1247 unsigned int nreq = 0; 1266 unsigned int nreq = 0;
1248 struct pnfs_layout_segment *freeme;
1249 1267
1250 fl_cinfo = cinfo->ds; 1268 fl_cinfo = cinfo->ds;
1251 bucket = fl_cinfo->buckets; 1269 bucket = fl_cinfo->buckets;
@@ -1265,16 +1283,7 @@ alloc_ds_commits(struct nfs_commit_info *cinfo, struct list_head *list)
1265 } 1283 }
1266 1284
1267 /* Clean up on error */ 1285 /* Clean up on error */
1268 for (j = i; j < fl_cinfo->nbuckets; j++, bucket++) { 1286 filelayout_retry_commit(cinfo, i);
1269 if (list_empty(&bucket->committing))
1270 continue;
1271 nfs_retry_commit(&bucket->committing, bucket->clseg, cinfo);
1272 spin_lock(cinfo->lock);
1273 freeme = bucket->clseg;
1274 bucket->clseg = NULL;
1275 spin_unlock(cinfo->lock);
1276 pnfs_put_lseg(freeme);
1277 }
1278 /* Caller will clean up entries put on list */ 1287 /* Caller will clean up entries put on list */
1279 return nreq; 1288 return nreq;
1280} 1289}
@@ -1294,8 +1303,12 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
1294 data->lseg = NULL; 1303 data->lseg = NULL;
1295 list_add(&data->pages, &list); 1304 list_add(&data->pages, &list);
1296 nreq++; 1305 nreq++;
1297 } else 1306 } else {
1298 nfs_retry_commit(mds_pages, NULL, cinfo); 1307 nfs_retry_commit(mds_pages, NULL, cinfo);
1308 filelayout_retry_commit(cinfo, 0);
1309 cinfo->completion_ops->error_cleanup(NFS_I(inode));
1310 return -ENOMEM;
1311 }
1299 } 1312 }
1300 1313
1301 nreq += alloc_ds_commits(cinfo, &list); 1314 nreq += alloc_ds_commits(cinfo, &list);