aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c98
1 files changed, 71 insertions, 27 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 9f9845859fc1..a34fae21fe10 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -25,6 +25,7 @@
25#include "delegation.h" 25#include "delegation.h"
26#include "internal.h" 26#include "internal.h"
27#include "iostat.h" 27#include "iostat.h"
28#include "nfs4_fs.h"
28 29
29#define NFSDBG_FACILITY NFSDBG_PAGECACHE 30#define NFSDBG_FACILITY NFSDBG_PAGECACHE
30 31
@@ -52,6 +53,7 @@ struct nfs_write_data *nfs_commitdata_alloc(void)
52 if (p) { 53 if (p) {
53 memset(p, 0, sizeof(*p)); 54 memset(p, 0, sizeof(*p));
54 INIT_LIST_HEAD(&p->pages); 55 INIT_LIST_HEAD(&p->pages);
56 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
55 } 57 }
56 return p; 58 return p;
57} 59}
@@ -71,6 +73,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
71 memset(p, 0, sizeof(*p)); 73 memset(p, 0, sizeof(*p));
72 INIT_LIST_HEAD(&p->pages); 74 INIT_LIST_HEAD(&p->pages);
73 p->npages = pagecount; 75 p->npages = pagecount;
76 p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
74 if (pagecount <= ARRAY_SIZE(p->page_array)) 77 if (pagecount <= ARRAY_SIZE(p->page_array))
75 p->pagevec = p->page_array; 78 p->pagevec = p->page_array;
76 else { 79 else {
@@ -84,17 +87,15 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
84 return p; 87 return p;
85} 88}
86 89
87static void nfs_writedata_free(struct nfs_write_data *p) 90void nfs_writedata_free(struct nfs_write_data *p)
88{ 91{
89 if (p && (p->pagevec != &p->page_array[0])) 92 if (p && (p->pagevec != &p->page_array[0]))
90 kfree(p->pagevec); 93 kfree(p->pagevec);
91 mempool_free(p, nfs_wdata_mempool); 94 mempool_free(p, nfs_wdata_mempool);
92} 95}
93 96
94void nfs_writedata_release(void *data) 97static void nfs_writedata_release(struct nfs_write_data *wdata)
95{ 98{
96 struct nfs_write_data *wdata = data;
97
98 put_nfs_open_context(wdata->args.context); 99 put_nfs_open_context(wdata->args.context);
99 nfs_writedata_free(wdata); 100 nfs_writedata_free(wdata);
100} 101}
@@ -199,8 +200,10 @@ static int nfs_set_page_writeback(struct page *page)
199 struct nfs_server *nfss = NFS_SERVER(inode); 200 struct nfs_server *nfss = NFS_SERVER(inode);
200 201
201 if (atomic_long_inc_return(&nfss->writeback) > 202 if (atomic_long_inc_return(&nfss->writeback) >
202 NFS_CONGESTION_ON_THRESH) 203 NFS_CONGESTION_ON_THRESH) {
203 set_bdi_congested(&nfss->backing_dev_info, WRITE); 204 set_bdi_congested(&nfss->backing_dev_info,
205 BLK_RW_ASYNC);
206 }
204 } 207 }
205 return ret; 208 return ret;
206} 209}
@@ -212,7 +215,7 @@ static void nfs_end_page_writeback(struct page *page)
212 215
213 end_page_writeback(page); 216 end_page_writeback(page);
214 if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) 217 if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
215 clear_bdi_congested(&nfss->backing_dev_info, WRITE); 218 clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
216} 219}
217 220
218/* 221/*
@@ -313,19 +316,34 @@ static int nfs_writepages_callback(struct page *page, struct writeback_control *
313int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) 316int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
314{ 317{
315 struct inode *inode = mapping->host; 318 struct inode *inode = mapping->host;
319 unsigned long *bitlock = &NFS_I(inode)->flags;
316 struct nfs_pageio_descriptor pgio; 320 struct nfs_pageio_descriptor pgio;
317 int err; 321 int err;
318 322
323 /* Stop dirtying of new pages while we sync */
324 err = wait_on_bit_lock(bitlock, NFS_INO_FLUSHING,
325 nfs_wait_bit_killable, TASK_KILLABLE);
326 if (err)
327 goto out_err;
328
319 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES); 329 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
320 330
321 nfs_pageio_init_write(&pgio, inode, wb_priority(wbc)); 331 nfs_pageio_init_write(&pgio, inode, wb_priority(wbc));
322 err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio); 332 err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
323 nfs_pageio_complete(&pgio); 333 nfs_pageio_complete(&pgio);
334
335 clear_bit_unlock(NFS_INO_FLUSHING, bitlock);
336 smp_mb__after_clear_bit();
337 wake_up_bit(bitlock, NFS_INO_FLUSHING);
338
324 if (err < 0) 339 if (err < 0)
325 return err; 340 goto out_err;
326 if (pgio.pg_error < 0) 341 err = pgio.pg_error;
327 return pgio.pg_error; 342 if (err < 0)
343 goto out_err;
328 return 0; 344 return 0;
345out_err:
346 return err;
329} 347}
330 348
331/* 349/*
@@ -404,7 +422,6 @@ nfs_mark_request_commit(struct nfs_page *req)
404 struct nfs_inode *nfsi = NFS_I(inode); 422 struct nfs_inode *nfsi = NFS_I(inode);
405 423
406 spin_lock(&inode->i_lock); 424 spin_lock(&inode->i_lock);
407 nfsi->ncommit++;
408 set_bit(PG_CLEAN, &(req)->wb_flags); 425 set_bit(PG_CLEAN, &(req)->wb_flags);
409 radix_tree_tag_set(&nfsi->nfs_page_tree, 426 radix_tree_tag_set(&nfsi->nfs_page_tree,
410 req->wb_index, 427 req->wb_index,
@@ -524,6 +541,12 @@ static void nfs_cancel_commit_list(struct list_head *head)
524} 541}
525 542
526#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 543#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
544static int
545nfs_need_commit(struct nfs_inode *nfsi)
546{
547 return radix_tree_tagged(&nfsi->nfs_page_tree, NFS_PAGE_TAG_COMMIT);
548}
549
527/* 550/*
528 * nfs_scan_commit - Scan an inode for commit requests 551 * nfs_scan_commit - Scan an inode for commit requests
529 * @inode: NFS inode to scan 552 * @inode: NFS inode to scan
@@ -538,16 +561,18 @@ static int
538nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages) 561nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages)
539{ 562{
540 struct nfs_inode *nfsi = NFS_I(inode); 563 struct nfs_inode *nfsi = NFS_I(inode);
541 int res = 0;
542 564
543 if (nfsi->ncommit != 0) { 565 if (!nfs_need_commit(nfsi))
544 res = nfs_scan_list(nfsi, dst, idx_start, npages, 566 return 0;
545 NFS_PAGE_TAG_COMMIT); 567
546 nfsi->ncommit -= res; 568 return nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT);
547 }
548 return res;
549} 569}
550#else 570#else
571static inline int nfs_need_commit(struct nfs_inode *nfsi)
572{
573 return 0;
574}
575
551static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages) 576static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages)
552{ 577{
553 return 0; 578 return 0;
@@ -820,7 +845,7 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
820 data->args.stable = NFS_UNSTABLE; 845 data->args.stable = NFS_UNSTABLE;
821 if (how & FLUSH_STABLE) { 846 if (how & FLUSH_STABLE) {
822 data->args.stable = NFS_DATA_SYNC; 847 data->args.stable = NFS_DATA_SYNC;
823 if (!NFS_I(inode)->ncommit) 848 if (!nfs_need_commit(NFS_I(inode)))
824 data->args.stable = NFS_FILE_SYNC; 849 data->args.stable = NFS_FILE_SYNC;
825 } 850 }
826 851
@@ -1026,7 +1051,23 @@ out:
1026 nfs_writedata_release(calldata); 1051 nfs_writedata_release(calldata);
1027} 1052}
1028 1053
1054#if defined(CONFIG_NFS_V4_1)
1055void nfs_write_prepare(struct rpc_task *task, void *calldata)
1056{
1057 struct nfs_write_data *data = calldata;
1058 struct nfs_client *clp = (NFS_SERVER(data->inode))->nfs_client;
1059
1060 if (nfs4_setup_sequence(clp, &data->args.seq_args,
1061 &data->res.seq_res, 1, task))
1062 return;
1063 rpc_call_start(task);
1064}
1065#endif /* CONFIG_NFS_V4_1 */
1066
1029static const struct rpc_call_ops nfs_write_partial_ops = { 1067static const struct rpc_call_ops nfs_write_partial_ops = {
1068#if defined(CONFIG_NFS_V4_1)
1069 .rpc_call_prepare = nfs_write_prepare,
1070#endif /* CONFIG_NFS_V4_1 */
1030 .rpc_call_done = nfs_writeback_done_partial, 1071 .rpc_call_done = nfs_writeback_done_partial,
1031 .rpc_release = nfs_writeback_release_partial, 1072 .rpc_release = nfs_writeback_release_partial,
1032}; 1073};
@@ -1089,6 +1130,9 @@ remove_request:
1089} 1130}
1090 1131
1091static const struct rpc_call_ops nfs_write_full_ops = { 1132static const struct rpc_call_ops nfs_write_full_ops = {
1133#if defined(CONFIG_NFS_V4_1)
1134 .rpc_call_prepare = nfs_write_prepare,
1135#endif /* CONFIG_NFS_V4_1 */
1092 .rpc_call_done = nfs_writeback_done_full, 1136 .rpc_call_done = nfs_writeback_done_full,
1093 .rpc_release = nfs_writeback_release_full, 1137 .rpc_release = nfs_writeback_release_full,
1094}; 1138};
@@ -1101,6 +1145,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1101{ 1145{
1102 struct nfs_writeargs *argp = &data->args; 1146 struct nfs_writeargs *argp = &data->args;
1103 struct nfs_writeres *resp = &data->res; 1147 struct nfs_writeres *resp = &data->res;
1148 struct nfs_server *server = NFS_SERVER(data->inode);
1104 int status; 1149 int status;
1105 1150
1106 dprintk("NFS: %5u nfs_writeback_done (status %d)\n", 1151 dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
@@ -1133,7 +1178,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1133 if (time_before(complain, jiffies)) { 1178 if (time_before(complain, jiffies)) {
1134 dprintk("NFS: faulty NFS server %s:" 1179 dprintk("NFS: faulty NFS server %s:"
1135 " (committed = %d) != (stable = %d)\n", 1180 " (committed = %d) != (stable = %d)\n",
1136 NFS_SERVER(data->inode)->nfs_client->cl_hostname, 1181 server->nfs_client->cl_hostname,
1137 resp->verf->committed, argp->stable); 1182 resp->verf->committed, argp->stable);
1138 complain = jiffies + 300 * HZ; 1183 complain = jiffies + 300 * HZ;
1139 } 1184 }
@@ -1159,7 +1204,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1159 */ 1204 */
1160 argp->stable = NFS_FILE_SYNC; 1205 argp->stable = NFS_FILE_SYNC;
1161 } 1206 }
1162 rpc_restart_call(task); 1207 nfs4_restart_rpc(task, server->nfs_client);
1163 return -EAGAIN; 1208 return -EAGAIN;
1164 } 1209 }
1165 if (time_before(complain, jiffies)) { 1210 if (time_before(complain, jiffies)) {
@@ -1171,6 +1216,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1171 /* Can't do anything about it except throw an error. */ 1216 /* Can't do anything about it except throw an error. */
1172 task->tk_status = -EIO; 1217 task->tk_status = -EIO;
1173 } 1218 }
1219 nfs4_sequence_free_slot(server->nfs_client, &data->res.seq_res);
1174 return 0; 1220 return 0;
1175} 1221}
1176 1222
@@ -1327,6 +1373,9 @@ static void nfs_commit_release(void *calldata)
1327} 1373}
1328 1374
1329static const struct rpc_call_ops nfs_commit_ops = { 1375static const struct rpc_call_ops nfs_commit_ops = {
1376#if defined(CONFIG_NFS_V4_1)
1377 .rpc_call_prepare = nfs_write_prepare,
1378#endif /* CONFIG_NFS_V4_1 */
1330 .rpc_call_done = nfs_commit_done, 1379 .rpc_call_done = nfs_commit_done,
1331 .rpc_release = nfs_commit_release, 1380 .rpc_release = nfs_commit_release,
1332}; 1381};
@@ -1425,18 +1474,13 @@ static int nfs_write_mapping(struct address_space *mapping, int how)
1425{ 1474{
1426 struct writeback_control wbc = { 1475 struct writeback_control wbc = {
1427 .bdi = mapping->backing_dev_info, 1476 .bdi = mapping->backing_dev_info,
1428 .sync_mode = WB_SYNC_NONE, 1477 .sync_mode = WB_SYNC_ALL,
1429 .nr_to_write = LONG_MAX, 1478 .nr_to_write = LONG_MAX,
1430 .range_start = 0, 1479 .range_start = 0,
1431 .range_end = LLONG_MAX, 1480 .range_end = LLONG_MAX,
1432 .for_writepages = 1, 1481 .for_writepages = 1,
1433 }; 1482 };
1434 int ret;
1435 1483
1436 ret = __nfs_write_mapping(mapping, &wbc, how);
1437 if (ret < 0)
1438 return ret;
1439 wbc.sync_mode = WB_SYNC_ALL;
1440 return __nfs_write_mapping(mapping, &wbc, how); 1484 return __nfs_write_mapping(mapping, &wbc, how);
1441} 1485}
1442 1486