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 /fs/nfs/write.c | |
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>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 31 |
1 files changed, 21 insertions, 10 deletions
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 | { |