diff options
author | Fred Isaman <iisaman@netapp.com> | 2012-04-20 14:47:54 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-04-27 14:10:38 -0400 |
commit | f453a54a01c7c0453ad9550906e3d2663dd486ac (patch) | |
tree | 1eac38e7e186ea0339066e7da417a20e0274b2c0 | |
parent | ea2cf2282b4278461266013e9c002ee1c66700ff (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.h | 5 | ||||
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 12 | ||||
-rw-r--r-- | fs/nfs/write.c | 31 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 9 |
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); |
345 | extern void nfs_init_commit(struct nfs_commit_data *data, | 345 | extern 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); | ||
348 | void nfs_retry_commit(struct list_head *page_list, | 349 | void 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); |
351 | void nfs_commit_clear_lock(struct nfs_inode *nfsi); | ||
352 | void nfs_commitdata_release(struct nfs_commit_data *data); | 352 | void nfs_commitdata_release(struct nfs_commit_data *data); |
353 | void nfs_commit_release_pages(struct nfs_commit_data *data); | ||
354 | void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, | 353 | void 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); |
356 | void nfs_request_remove_commit_list(struct nfs_page *req, | 355 | void 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) | |||
347 | static void filelayout_commit_release(void *calldata) | 347 | static 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); | |||
46 | static const struct rpc_call_ops nfs_write_common_ops; | 46 | static const struct rpc_call_ops nfs_write_common_ops; |
47 | static const struct rpc_call_ops nfs_commit_ops; | 47 | static const struct rpc_call_ops nfs_commit_ops; |
48 | static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; | 48 | static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; |
49 | static const struct nfs_commit_completion_ops nfs_commit_completion_ops; | ||
49 | 50 | ||
50 | static struct kmem_cache *nfs_wdata_cachep; | 51 | static struct kmem_cache *nfs_wdata_cachep; |
51 | static mempool_t *nfs_wdata_mempool; | 52 | static 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 | ||
510 | void nfs_init_cinfo(struct nfs_commit_info *cinfo, | 512 | void 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 | ||
1361 | void nfs_commit_clear_lock(struct nfs_inode *nfsi) | 1363 | static 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 | } |
1367 | EXPORT_SYMBOL_GPL(nfs_commit_clear_lock); | ||
1368 | 1369 | ||
1369 | void nfs_commitdata_release(struct nfs_commit_data *data) | 1370 | void 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 | */ |
1415 | void nfs_init_commit(struct nfs_commit_data *data, | 1416 | void 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 | ||
1498 | void nfs_commit_release_pages(struct nfs_commit_data *data) | 1502 | static 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 | } |
1535 | EXPORT_SYMBOL_GPL(nfs_commit_release_pages); | ||
1536 | 1543 | ||
1537 | static void nfs_commit_release(void *calldata) | 1544 | static 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 | ||
1558 | static 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 | |||
1552 | static int nfs_generic_commit_list(struct inode *inode, struct list_head *head, | 1563 | static 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 | ||
1266 | struct nfs_commit_data; | ||
1267 | struct nfs_inode; | ||
1268 | struct nfs_commit_completion_ops { | ||
1269 | void (*error_cleanup) (struct nfs_inode *nfsi); | ||
1270 | void (*completion) (struct nfs_commit_data *data); | ||
1271 | }; | ||
1272 | |||
1266 | struct nfs_commit_info { | 1273 | struct 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 | ||
1272 | struct nfs_commit_data { | 1280 | struct 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 | ||