aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2012-04-20 14:47:54 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-04-27 14:10:38 -0400
commitf453a54a01c7c0453ad9550906e3d2663dd486ac (patch)
tree1eac38e7e186ea0339066e7da417a20e0274b2c0
parentea2cf2282b4278461266013e9c002ee1c66700ff (diff)
NFS: create nfs_commit_completion_ops
Factors out the code that needs to change when directio starts using these code paths. Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/internal.h5
-rw-r--r--fs/nfs/nfs4filelayout.c12
-rw-r--r--fs/nfs/write.c31
-rw-r--r--include/linux/nfs_xdr.h9
4 files changed, 36 insertions, 21 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 145e9e7dc8ce..137f5cd71433 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -344,13 +344,12 @@ extern int nfs_initiate_commit(struct rpc_clnt *clnt,
344 int how); 344 int how);
345extern void nfs_init_commit(struct nfs_commit_data *data, 345extern void nfs_init_commit(struct nfs_commit_data *data,
346 struct list_head *head, 346 struct list_head *head,
347 struct pnfs_layout_segment *lseg); 347 struct pnfs_layout_segment *lseg,
348 struct nfs_commit_info *cinfo);
348void nfs_retry_commit(struct list_head *page_list, 349void nfs_retry_commit(struct list_head *page_list,
349 struct pnfs_layout_segment *lseg, 350 struct pnfs_layout_segment *lseg,
350 struct nfs_commit_info *cinfo); 351 struct nfs_commit_info *cinfo);
351void nfs_commit_clear_lock(struct nfs_inode *nfsi);
352void nfs_commitdata_release(struct nfs_commit_data *data); 352void nfs_commitdata_release(struct nfs_commit_data *data);
353void nfs_commit_release_pages(struct nfs_commit_data *data);
354void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, 353void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
355 struct nfs_commit_info *cinfo); 354 struct nfs_commit_info *cinfo);
356void nfs_request_remove_commit_list(struct nfs_page *req, 355void nfs_request_remove_commit_list(struct nfs_page *req,
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index fe2cb55ca6b1..26d1da486761 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -347,12 +347,8 @@ static void filelayout_commit_count_stats(struct rpc_task *task, void *data)
347static void filelayout_commit_release(void *calldata) 347static void filelayout_commit_release(void *calldata)
348{ 348{
349 struct nfs_commit_data *data = calldata; 349 struct nfs_commit_data *data = calldata;
350 struct nfs_commit_info cinfo;
351 350
352 nfs_commit_release_pages(data); 351 data->completion_ops->completion(data);
353 nfs_init_cinfo(&cinfo, data->inode, data->dreq);
354 if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
355 nfs_commit_clear_lock(NFS_I(data->inode));
356 put_lseg(data->lseg); 352 put_lseg(data->lseg);
357 nfs_commitdata_release(data); 353 nfs_commitdata_release(data);
358} 354}
@@ -1108,7 +1104,7 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
1108 nreq += alloc_ds_commits(cinfo, &list); 1104 nreq += alloc_ds_commits(cinfo, &list);
1109 1105
1110 if (nreq == 0) { 1106 if (nreq == 0) {
1111 nfs_commit_clear_lock(NFS_I(inode)); 1107 cinfo->completion_ops->error_cleanup(NFS_I(inode));
1112 goto out; 1108 goto out;
1113 } 1109 }
1114 1110
@@ -1117,14 +1113,14 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
1117 list_for_each_entry_safe(data, tmp, &list, pages) { 1113 list_for_each_entry_safe(data, tmp, &list, pages) {
1118 list_del_init(&data->pages); 1114 list_del_init(&data->pages);
1119 if (!data->lseg) { 1115 if (!data->lseg) {
1120 nfs_init_commit(data, mds_pages, NULL); 1116 nfs_init_commit(data, mds_pages, NULL, cinfo);
1121 nfs_initiate_commit(NFS_CLIENT(inode), data, 1117 nfs_initiate_commit(NFS_CLIENT(inode), data,
1122 data->mds_ops, how); 1118 data->mds_ops, how);
1123 } else { 1119 } else {
1124 struct pnfs_commit_bucket *buckets; 1120 struct pnfs_commit_bucket *buckets;
1125 1121
1126 buckets = cinfo->ds->buckets; 1122 buckets = cinfo->ds->buckets;
1127 nfs_init_commit(data, &buckets[data->ds_commit_index].committing, data->lseg); 1123 nfs_init_commit(data, &buckets[data->ds_commit_index].committing, data->lseg, cinfo);
1128 filelayout_initiate_commit(data, how); 1124 filelayout_initiate_commit(data, how);
1129 } 1125 }
1130 } 1126 }
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 18bf70055272..333d01d26292 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -46,6 +46,7 @@ static void nfs_redirty_request(struct nfs_page *req);
46static const struct rpc_call_ops nfs_write_common_ops; 46static const struct rpc_call_ops nfs_write_common_ops;
47static const struct rpc_call_ops nfs_commit_ops; 47static const struct rpc_call_ops nfs_commit_ops;
48static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; 48static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
49static const struct nfs_commit_completion_ops nfs_commit_completion_ops;
49 50
50static struct kmem_cache *nfs_wdata_cachep; 51static struct kmem_cache *nfs_wdata_cachep;
51static mempool_t *nfs_wdata_mempool; 52static mempool_t *nfs_wdata_mempool;
@@ -505,6 +506,7 @@ static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
505 cinfo->lock = &inode->i_lock; 506 cinfo->lock = &inode->i_lock;
506 cinfo->mds = &NFS_I(inode)->commit_info; 507 cinfo->mds = &NFS_I(inode)->commit_info;
507 cinfo->ds = pnfs_get_ds_info(inode); 508 cinfo->ds = pnfs_get_ds_info(inode);
509 cinfo->completion_ops = &nfs_commit_completion_ops;
508} 510}
509 511
510void nfs_init_cinfo(struct nfs_commit_info *cinfo, 512void nfs_init_cinfo(struct nfs_commit_info *cinfo,
@@ -1358,13 +1360,12 @@ static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
1358 return (ret < 0) ? ret : 1; 1360 return (ret < 0) ? ret : 1;
1359} 1361}
1360 1362
1361void nfs_commit_clear_lock(struct nfs_inode *nfsi) 1363static void nfs_commit_clear_lock(struct nfs_inode *nfsi)
1362{ 1364{
1363 clear_bit(NFS_INO_COMMIT, &nfsi->flags); 1365 clear_bit(NFS_INO_COMMIT, &nfsi->flags);
1364 smp_mb__after_clear_bit(); 1366 smp_mb__after_clear_bit();
1365 wake_up_bit(&nfsi->flags, NFS_INO_COMMIT); 1367 wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
1366} 1368}
1367EXPORT_SYMBOL_GPL(nfs_commit_clear_lock);
1368 1369
1369void nfs_commitdata_release(struct nfs_commit_data *data) 1370void nfs_commitdata_release(struct nfs_commit_data *data)
1370{ 1371{
@@ -1413,8 +1414,9 @@ EXPORT_SYMBOL_GPL(nfs_initiate_commit);
1413 * Set up the argument/result storage required for the RPC call. 1414 * Set up the argument/result storage required for the RPC call.
1414 */ 1415 */
1415void nfs_init_commit(struct nfs_commit_data *data, 1416void nfs_init_commit(struct nfs_commit_data *data,
1416 struct list_head *head, 1417 struct list_head *head,
1417 struct pnfs_layout_segment *lseg) 1418 struct pnfs_layout_segment *lseg,
1419 struct nfs_commit_info *cinfo)
1418{ 1420{
1419 struct nfs_page *first = nfs_list_entry(head->next); 1421 struct nfs_page *first = nfs_list_entry(head->next);
1420 struct inode *inode = first->wb_context->dentry->d_inode; 1422 struct inode *inode = first->wb_context->dentry->d_inode;
@@ -1428,6 +1430,7 @@ void nfs_init_commit(struct nfs_commit_data *data,
1428 data->cred = first->wb_context->cred; 1430 data->cred = first->wb_context->cred;
1429 data->lseg = lseg; /* reference transferred */ 1431 data->lseg = lseg; /* reference transferred */
1430 data->mds_ops = &nfs_commit_ops; 1432 data->mds_ops = &nfs_commit_ops;
1433 data->completion_ops = cinfo->completion_ops;
1431 1434
1432 data->args.fh = NFS_FH(data->inode); 1435 data->args.fh = NFS_FH(data->inode);
1433 /* Note: we always request a commit of the entire inode */ 1436 /* Note: we always request a commit of the entire inode */
@@ -1473,11 +1476,12 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
1473 goto out_bad; 1476 goto out_bad;
1474 1477
1475 /* Set up the argument struct */ 1478 /* Set up the argument struct */
1476 nfs_init_commit(data, head, NULL); 1479 nfs_init_commit(data, head, NULL, cinfo);
1480 atomic_inc(&cinfo->mds->rpcs_out);
1477 return nfs_initiate_commit(NFS_CLIENT(inode), data, data->mds_ops, how); 1481 return nfs_initiate_commit(NFS_CLIENT(inode), data, data->mds_ops, how);
1478 out_bad: 1482 out_bad:
1479 nfs_retry_commit(head, NULL, cinfo); 1483 nfs_retry_commit(head, NULL, cinfo);
1480 nfs_commit_clear_lock(NFS_I(inode)); 1484 cinfo->completion_ops->error_cleanup(NFS_I(inode));
1481 return -ENOMEM; 1485 return -ENOMEM;
1482} 1486}
1483 1487
@@ -1495,10 +1499,11 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1495 NFS_PROTO(data->inode)->commit_done(task, data); 1499 NFS_PROTO(data->inode)->commit_done(task, data);
1496} 1500}
1497 1501
1498void nfs_commit_release_pages(struct nfs_commit_data *data) 1502static void nfs_commit_release_pages(struct nfs_commit_data *data)
1499{ 1503{
1500 struct nfs_page *req; 1504 struct nfs_page *req;
1501 int status = data->task.tk_status; 1505 int status = data->task.tk_status;
1506 struct nfs_commit_info cinfo;
1502 1507
1503 while (!list_empty(&data->pages)) { 1508 while (!list_empty(&data->pages)) {
1504 req = nfs_list_entry(data->pages.next); 1509 req = nfs_list_entry(data->pages.next);
@@ -1531,15 +1536,16 @@ void nfs_commit_release_pages(struct nfs_commit_data *data)
1531 next: 1536 next:
1532 nfs_unlock_request(req); 1537 nfs_unlock_request(req);
1533 } 1538 }
1539 nfs_init_cinfo(&cinfo, data->inode, data->dreq);
1540 if (atomic_dec_and_test(&cinfo.mds->rpcs_out))
1541 nfs_commit_clear_lock(NFS_I(data->inode));
1534} 1542}
1535EXPORT_SYMBOL_GPL(nfs_commit_release_pages);
1536 1543
1537static void nfs_commit_release(void *calldata) 1544static void nfs_commit_release(void *calldata)
1538{ 1545{
1539 struct nfs_commit_data *data = calldata; 1546 struct nfs_commit_data *data = calldata;
1540 1547
1541 nfs_commit_release_pages(data); 1548 data->completion_ops->completion(data);
1542 nfs_commit_clear_lock(NFS_I(data->inode));
1543 nfs_commitdata_release(calldata); 1549 nfs_commitdata_release(calldata);
1544} 1550}
1545 1551
@@ -1549,6 +1555,11 @@ static const struct rpc_call_ops nfs_commit_ops = {
1549 .rpc_release = nfs_commit_release, 1555 .rpc_release = nfs_commit_release,
1550}; 1556};
1551 1557
1558static const struct nfs_commit_completion_ops nfs_commit_completion_ops = {
1559 .completion = nfs_commit_release_pages,
1560 .error_cleanup = nfs_commit_clear_lock,
1561};
1562
1552static int nfs_generic_commit_list(struct inode *inode, struct list_head *head, 1563static int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
1553 int how, struct nfs_commit_info *cinfo) 1564 int how, struct nfs_commit_info *cinfo)
1554{ 1565{
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 224e1e82670c..0e8b88ad9ae2 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1263,10 +1263,18 @@ struct nfs_mds_commit_info {
1263 struct list_head list; 1263 struct list_head list;
1264}; 1264};
1265 1265
1266struct nfs_commit_data;
1267struct nfs_inode;
1268struct nfs_commit_completion_ops {
1269 void (*error_cleanup) (struct nfs_inode *nfsi);
1270 void (*completion) (struct nfs_commit_data *data);
1271};
1272
1266struct nfs_commit_info { 1273struct nfs_commit_info {
1267 spinlock_t *lock; 1274 spinlock_t *lock;
1268 struct nfs_mds_commit_info *mds; 1275 struct nfs_mds_commit_info *mds;
1269 struct pnfs_ds_commit_info *ds; 1276 struct pnfs_ds_commit_info *ds;
1277 const struct nfs_commit_completion_ops *completion_ops;
1270}; 1278};
1271 1279
1272struct nfs_commit_data { 1280struct nfs_commit_data {
@@ -1285,6 +1293,7 @@ struct nfs_commit_data {
1285 struct nfs_client *ds_clp; /* pNFS data server */ 1293 struct nfs_client *ds_clp; /* pNFS data server */
1286 int ds_commit_index; 1294 int ds_commit_index;
1287 const struct rpc_call_ops *mds_ops; 1295 const struct rpc_call_ops *mds_ops;
1296 const struct nfs_commit_completion_ops *completion_ops;
1288 int (*commit_done_cb) (struct rpc_task *task, struct nfs_commit_data *data); 1297 int (*commit_done_cb) (struct rpc_task *task, struct nfs_commit_data *data);
1289}; 1298};
1290 1299