diff options
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index c07462320f6b..54f7c0ffe5c3 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -48,11 +48,12 @@ static const struct rpc_call_ops nfs_commit_ops; | |||
48 | 48 | ||
49 | static struct kmem_cache *nfs_wdata_cachep; | 49 | static struct kmem_cache *nfs_wdata_cachep; |
50 | static mempool_t *nfs_wdata_mempool; | 50 | static mempool_t *nfs_wdata_mempool; |
51 | static struct kmem_cache *nfs_cdata_cachep; | ||
51 | static mempool_t *nfs_commit_mempool; | 52 | static mempool_t *nfs_commit_mempool; |
52 | 53 | ||
53 | struct nfs_write_data *nfs_commitdata_alloc(void) | 54 | struct nfs_commit_data *nfs_commitdata_alloc(void) |
54 | { | 55 | { |
55 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); | 56 | struct nfs_commit_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); |
56 | 57 | ||
57 | if (p) { | 58 | if (p) { |
58 | memset(p, 0, sizeof(*p)); | 59 | memset(p, 0, sizeof(*p)); |
@@ -62,10 +63,8 @@ struct nfs_write_data *nfs_commitdata_alloc(void) | |||
62 | } | 63 | } |
63 | EXPORT_SYMBOL_GPL(nfs_commitdata_alloc); | 64 | EXPORT_SYMBOL_GPL(nfs_commitdata_alloc); |
64 | 65 | ||
65 | void nfs_commit_free(struct nfs_write_data *p) | 66 | void nfs_commit_free(struct nfs_commit_data *p) |
66 | { | 67 | { |
67 | if (p && (p->pagevec != &p->page_array[0])) | ||
68 | kfree(p->pagevec); | ||
69 | mempool_free(p, nfs_commit_mempool); | 68 | mempool_free(p, nfs_commit_mempool); |
70 | } | 69 | } |
71 | EXPORT_SYMBOL_GPL(nfs_commit_free); | 70 | EXPORT_SYMBOL_GPL(nfs_commit_free); |
@@ -1179,6 +1178,13 @@ void nfs_write_prepare(struct rpc_task *task, void *calldata) | |||
1179 | NFS_PROTO(data->inode)->write_rpc_prepare(task, data); | 1178 | NFS_PROTO(data->inode)->write_rpc_prepare(task, data); |
1180 | } | 1179 | } |
1181 | 1180 | ||
1181 | void nfs_commit_prepare(struct rpc_task *task, void *calldata) | ||
1182 | { | ||
1183 | struct nfs_commit_data *data = calldata; | ||
1184 | |||
1185 | NFS_PROTO(data->inode)->commit_rpc_prepare(task, data); | ||
1186 | } | ||
1187 | |||
1182 | static const struct rpc_call_ops nfs_write_partial_ops = { | 1188 | static const struct rpc_call_ops nfs_write_partial_ops = { |
1183 | .rpc_call_prepare = nfs_write_prepare, | 1189 | .rpc_call_prepare = nfs_write_prepare, |
1184 | .rpc_call_done = nfs_writeback_done_partial, | 1190 | .rpc_call_done = nfs_writeback_done_partial, |
@@ -1355,16 +1361,14 @@ void nfs_commit_clear_lock(struct nfs_inode *nfsi) | |||
1355 | } | 1361 | } |
1356 | EXPORT_SYMBOL_GPL(nfs_commit_clear_lock); | 1362 | EXPORT_SYMBOL_GPL(nfs_commit_clear_lock); |
1357 | 1363 | ||
1358 | void nfs_commitdata_release(void *data) | 1364 | void nfs_commitdata_release(struct nfs_commit_data *data) |
1359 | { | 1365 | { |
1360 | struct nfs_write_data *wdata = data; | 1366 | put_nfs_open_context(data->context); |
1361 | 1367 | nfs_commit_free(data); | |
1362 | put_nfs_open_context(wdata->args.context); | ||
1363 | nfs_commit_free(wdata); | ||
1364 | } | 1368 | } |
1365 | EXPORT_SYMBOL_GPL(nfs_commitdata_release); | 1369 | EXPORT_SYMBOL_GPL(nfs_commitdata_release); |
1366 | 1370 | ||
1367 | int nfs_initiate_commit(struct nfs_write_data *data, struct rpc_clnt *clnt, | 1371 | int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data, |
1368 | const struct rpc_call_ops *call_ops, | 1372 | const struct rpc_call_ops *call_ops, |
1369 | int how) | 1373 | int how) |
1370 | { | 1374 | { |
@@ -1403,7 +1407,7 @@ EXPORT_SYMBOL_GPL(nfs_initiate_commit); | |||
1403 | /* | 1407 | /* |
1404 | * Set up the argument/result storage required for the RPC call. | 1408 | * Set up the argument/result storage required for the RPC call. |
1405 | */ | 1409 | */ |
1406 | void nfs_init_commit(struct nfs_write_data *data, | 1410 | void nfs_init_commit(struct nfs_commit_data *data, |
1407 | struct list_head *head, | 1411 | struct list_head *head, |
1408 | struct pnfs_layout_segment *lseg) | 1412 | struct pnfs_layout_segment *lseg) |
1409 | { | 1413 | { |
@@ -1424,8 +1428,7 @@ void nfs_init_commit(struct nfs_write_data *data, | |||
1424 | /* Note: we always request a commit of the entire inode */ | 1428 | /* Note: we always request a commit of the entire inode */ |
1425 | data->args.offset = 0; | 1429 | data->args.offset = 0; |
1426 | data->args.count = 0; | 1430 | data->args.count = 0; |
1427 | data->args.context = get_nfs_open_context(first->wb_context); | 1431 | data->context = get_nfs_open_context(first->wb_context); |
1428 | data->res.count = 0; | ||
1429 | data->res.fattr = &data->fattr; | 1432 | data->res.fattr = &data->fattr; |
1430 | data->res.verf = &data->verf; | 1433 | data->res.verf = &data->verf; |
1431 | nfs_fattr_init(&data->fattr); | 1434 | nfs_fattr_init(&data->fattr); |
@@ -1455,7 +1458,7 @@ EXPORT_SYMBOL_GPL(nfs_retry_commit); | |||
1455 | static int | 1458 | static int |
1456 | nfs_commit_list(struct inode *inode, struct list_head *head, int how) | 1459 | nfs_commit_list(struct inode *inode, struct list_head *head, int how) |
1457 | { | 1460 | { |
1458 | struct nfs_write_data *data; | 1461 | struct nfs_commit_data *data; |
1459 | 1462 | ||
1460 | data = nfs_commitdata_alloc(); | 1463 | data = nfs_commitdata_alloc(); |
1461 | 1464 | ||
@@ -1464,7 +1467,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how) | |||
1464 | 1467 | ||
1465 | /* Set up the argument struct */ | 1468 | /* Set up the argument struct */ |
1466 | nfs_init_commit(data, head, NULL); | 1469 | nfs_init_commit(data, head, NULL); |
1467 | return nfs_initiate_commit(data, NFS_CLIENT(inode), data->mds_ops, how); | 1470 | return nfs_initiate_commit(NFS_CLIENT(inode), data, data->mds_ops, how); |
1468 | out_bad: | 1471 | out_bad: |
1469 | nfs_retry_commit(head, NULL); | 1472 | nfs_retry_commit(head, NULL); |
1470 | nfs_commit_clear_lock(NFS_I(inode)); | 1473 | nfs_commit_clear_lock(NFS_I(inode)); |
@@ -1476,7 +1479,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how) | |||
1476 | */ | 1479 | */ |
1477 | static void nfs_commit_done(struct rpc_task *task, void *calldata) | 1480 | static void nfs_commit_done(struct rpc_task *task, void *calldata) |
1478 | { | 1481 | { |
1479 | struct nfs_write_data *data = calldata; | 1482 | struct nfs_commit_data *data = calldata; |
1480 | 1483 | ||
1481 | dprintk("NFS: %5u nfs_commit_done (status %d)\n", | 1484 | dprintk("NFS: %5u nfs_commit_done (status %d)\n", |
1482 | task->tk_pid, task->tk_status); | 1485 | task->tk_pid, task->tk_status); |
@@ -1485,7 +1488,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) | |||
1485 | NFS_PROTO(data->inode)->commit_done(task, data); | 1488 | NFS_PROTO(data->inode)->commit_done(task, data); |
1486 | } | 1489 | } |
1487 | 1490 | ||
1488 | void nfs_commit_release_pages(struct nfs_write_data *data) | 1491 | void nfs_commit_release_pages(struct nfs_commit_data *data) |
1489 | { | 1492 | { |
1490 | struct nfs_page *req; | 1493 | struct nfs_page *req; |
1491 | int status = data->task.tk_status; | 1494 | int status = data->task.tk_status; |
@@ -1526,7 +1529,7 @@ EXPORT_SYMBOL_GPL(nfs_commit_release_pages); | |||
1526 | 1529 | ||
1527 | static void nfs_commit_release(void *calldata) | 1530 | static void nfs_commit_release(void *calldata) |
1528 | { | 1531 | { |
1529 | struct nfs_write_data *data = calldata; | 1532 | struct nfs_commit_data *data = calldata; |
1530 | 1533 | ||
1531 | nfs_commit_release_pages(data); | 1534 | nfs_commit_release_pages(data); |
1532 | nfs_commit_clear_lock(NFS_I(data->inode)); | 1535 | nfs_commit_clear_lock(NFS_I(data->inode)); |
@@ -1534,7 +1537,7 @@ static void nfs_commit_release(void *calldata) | |||
1534 | } | 1537 | } |
1535 | 1538 | ||
1536 | static const struct rpc_call_ops nfs_commit_ops = { | 1539 | static const struct rpc_call_ops nfs_commit_ops = { |
1537 | .rpc_call_prepare = nfs_write_prepare, | 1540 | .rpc_call_prepare = nfs_commit_prepare, |
1538 | .rpc_call_done = nfs_commit_done, | 1541 | .rpc_call_done = nfs_commit_done, |
1539 | .rpc_release = nfs_commit_release, | 1542 | .rpc_release = nfs_commit_release, |
1540 | }; | 1543 | }; |
@@ -1753,6 +1756,13 @@ int __init nfs_init_writepagecache(void) | |||
1753 | if (nfs_wdata_mempool == NULL) | 1756 | if (nfs_wdata_mempool == NULL) |
1754 | return -ENOMEM; | 1757 | return -ENOMEM; |
1755 | 1758 | ||
1759 | nfs_cdata_cachep = kmem_cache_create("nfs_commit_data", | ||
1760 | sizeof(struct nfs_commit_data), | ||
1761 | 0, SLAB_HWCACHE_ALIGN, | ||
1762 | NULL); | ||
1763 | if (nfs_cdata_cachep == NULL) | ||
1764 | return -ENOMEM; | ||
1765 | |||
1756 | nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, | 1766 | nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, |
1757 | nfs_wdata_cachep); | 1767 | nfs_wdata_cachep); |
1758 | if (nfs_commit_mempool == NULL) | 1768 | if (nfs_commit_mempool == NULL) |