aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Schumaker <Anna.Schumaker@netapp.com>2014-05-06 09:12:32 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-05-28 18:40:36 -0400
commit0eecb2145c1ce18e36617008424a93836ad0a3bd (patch)
tree469884c95d6e3c65383800e0c41b197d44851543
parenta4cdda59111f92000297e0d3edb1e0e08ba3549b (diff)
NFS: Create a common nfs_pgio_result_common function
Combining these functions will let me make a single nfs_rw_common_ops struct (see the next patch). Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/internal.h1
-rw-r--r--fs/nfs/pagelist.c23
-rw-r--r--fs/nfs/read.c25
-rw-r--r--fs/nfs/write.c51
-rw-r--r--include/linux/nfs_fs.h2
-rw-r--r--include/linux/nfs_page.h2
6 files changed, 54 insertions, 50 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 1959260f8c57..7c0ae364bdad 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -243,6 +243,7 @@ struct nfs_pgio_data *nfs_pgio_data_alloc(struct nfs_pgio_header *, unsigned int
243void nfs_pgio_data_release(struct nfs_pgio_data *); 243void nfs_pgio_data_release(struct nfs_pgio_data *);
244void nfs_pgio_prepare(struct rpc_task *, void *); 244void nfs_pgio_prepare(struct rpc_task *, void *);
245void nfs_pgio_release(void *); 245void nfs_pgio_release(void *);
246void nfs_pgio_result(struct rpc_task *, void *);
246 247
247static inline void nfs_iocounter_init(struct nfs_io_counter *c) 248static inline void nfs_iocounter_init(struct nfs_io_counter *c)
248{ 249{
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 0fa211d35e40..f74df87058b6 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -24,6 +24,8 @@
24#include "internal.h" 24#include "internal.h"
25#include "pnfs.h" 25#include "pnfs.h"
26 26
27#define NFSDBG_FACILITY NFSDBG_PAGECACHE
28
27static struct kmem_cache *nfs_page_cachep; 29static struct kmem_cache *nfs_page_cachep;
28 30
29static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount) 31static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
@@ -447,6 +449,27 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
447} 449}
448EXPORT_SYMBOL_GPL(nfs_pageio_init); 450EXPORT_SYMBOL_GPL(nfs_pageio_init);
449 451
452/**
453 * nfs_pgio_result - Basic pageio error handling
454 * @task: The task that ran
455 * @calldata: Pageio data to check
456 */
457void nfs_pgio_result(struct rpc_task *task, void *calldata)
458{
459 struct nfs_pgio_data *data = calldata;
460 struct inode *inode = data->header->inode;
461
462 dprintk("NFS: %s: %5u, (status %d)\n", __func__,
463 task->tk_pid, task->tk_status);
464
465 if (data->header->rw_ops->rw_done(task, data, inode) != 0)
466 return;
467 if (task->tk_status < 0)
468 nfs_set_pgio_error(data->header, task->tk_status, data->args.offset);
469 else
470 data->header->rw_ops->rw_result(task, data);
471}
472
450static bool nfs_match_open_context(const struct nfs_open_context *ctx1, 473static bool nfs_match_open_context(const struct nfs_open_context *ctx1,
451 const struct nfs_open_context *ctx2) 474 const struct nfs_open_context *ctx2)
452{ 475{
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index cfa15e828dd6..bc78bd248eb8 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -388,15 +388,10 @@ static const struct nfs_pageio_ops nfs_pageio_read_ops = {
388 * This is the callback from RPC telling us whether a reply was 388 * This is the callback from RPC telling us whether a reply was
389 * received or some error occurred (timeout or socket shutdown). 389 * received or some error occurred (timeout or socket shutdown).
390 */ 390 */
391int nfs_readpage_result(struct rpc_task *task, struct nfs_pgio_data *data) 391static int nfs_readpage_done(struct rpc_task *task, struct nfs_pgio_data *data,
392 struct inode *inode)
392{ 393{
393 struct inode *inode = data->header->inode; 394 int status = NFS_PROTO(inode)->read_done(task, data);
394 int status;
395
396 dprintk("NFS: %s: %5u, (status %d)\n", __func__, task->tk_pid,
397 task->tk_status);
398
399 status = NFS_PROTO(inode)->read_done(task, data);
400 if (status != 0) 395 if (status != 0)
401 return status; 396 return status;
402 397
@@ -429,17 +424,11 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_pgio_data *data
429 rpc_restart_call_prepare(task); 424 rpc_restart_call_prepare(task);
430} 425}
431 426
432static void nfs_readpage_result_common(struct rpc_task *task, void *calldata) 427static void nfs_readpage_result(struct rpc_task *task, struct nfs_pgio_data *data)
433{ 428{
434 struct nfs_pgio_data *data = calldata;
435 struct nfs_pgio_header *hdr = data->header; 429 struct nfs_pgio_header *hdr = data->header;
436 430
437 /* Note the only returns of nfs_readpage_result are 0 and -EAGAIN */ 431 if (data->res.eof) {
438 if (nfs_readpage_result(task, data) != 0)
439 return;
440 if (task->tk_status < 0)
441 nfs_set_pgio_error(hdr, task->tk_status, data->args.offset);
442 else if (data->res.eof) {
443 loff_t bound; 432 loff_t bound;
444 433
445 bound = data->args.offset + data->res.count; 434 bound = data->args.offset + data->res.count;
@@ -456,7 +445,7 @@ static void nfs_readpage_result_common(struct rpc_task *task, void *calldata)
456 445
457static const struct rpc_call_ops nfs_read_common_ops = { 446static const struct rpc_call_ops nfs_read_common_ops = {
458 .rpc_call_prepare = nfs_pgio_prepare, 447 .rpc_call_prepare = nfs_pgio_prepare,
459 .rpc_call_done = nfs_readpage_result_common, 448 .rpc_call_done = nfs_pgio_result,
460 .rpc_release = nfs_pgio_release, 449 .rpc_release = nfs_pgio_release,
461}; 450};
462 451
@@ -625,4 +614,6 @@ static const struct nfs_rw_ops nfs_rw_read_ops = {
625 .rw_mode = FMODE_READ, 614 .rw_mode = FMODE_READ,
626 .rw_alloc_header = nfs_readhdr_alloc, 615 .rw_alloc_header = nfs_readhdr_alloc,
627 .rw_free_header = nfs_readhdr_free, 616 .rw_free_header = nfs_readhdr_free,
617 .rw_done = nfs_readpage_done,
618 .rw_result = nfs_readpage_result,
628}; 619};
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index ae799c96ec2b..1d3e1d75c8c5 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1255,20 +1255,6 @@ void nfs_commit_prepare(struct rpc_task *task, void *calldata)
1255 NFS_PROTO(data->inode)->commit_rpc_prepare(task, data); 1255 NFS_PROTO(data->inode)->commit_rpc_prepare(task, data);
1256} 1256}
1257 1257
1258/*
1259 * Handle a write reply that flushes a whole page.
1260 *
1261 * FIXME: There is an inherent race with invalidate_inode_pages and
1262 * writebacks since the page->count is kept > 1 for as long
1263 * as the page has a write request pending.
1264 */
1265static void nfs_writeback_done_common(struct rpc_task *task, void *calldata)
1266{
1267 struct nfs_pgio_data *data = calldata;
1268
1269 nfs_writeback_done(task, data);
1270}
1271
1272static void nfs_writeback_release_common(struct nfs_pgio_data *data) 1258static void nfs_writeback_release_common(struct nfs_pgio_data *data)
1273{ 1259{
1274 struct nfs_pgio_header *hdr = data->header; 1260 struct nfs_pgio_header *hdr = data->header;
@@ -1288,7 +1274,7 @@ static void nfs_writeback_release_common(struct nfs_pgio_data *data)
1288 1274
1289static const struct rpc_call_ops nfs_write_common_ops = { 1275static const struct rpc_call_ops nfs_write_common_ops = {
1290 .rpc_call_prepare = nfs_pgio_prepare, 1276 .rpc_call_prepare = nfs_pgio_prepare,
1291 .rpc_call_done = nfs_writeback_done_common, 1277 .rpc_call_done = nfs_pgio_result,
1292 .rpc_release = nfs_pgio_release, 1278 .rpc_release = nfs_pgio_release,
1293}; 1279};
1294 1280
@@ -1320,16 +1306,11 @@ static int nfs_should_remove_suid(const struct inode *inode)
1320/* 1306/*
1321 * This function is called when the WRITE call is complete. 1307 * This function is called when the WRITE call is complete.
1322 */ 1308 */
1323void nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data) 1309static int nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data,
1310 struct inode *inode)
1324{ 1311{
1325 struct nfs_pgio_args *argp = &data->args;
1326 struct nfs_pgio_res *resp = &data->res;
1327 struct inode *inode = data->header->inode;
1328 int status; 1312 int status;
1329 1313
1330 dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
1331 task->tk_pid, task->tk_status);
1332
1333 /* 1314 /*
1334 * ->write_done will attempt to use post-op attributes to detect 1315 * ->write_done will attempt to use post-op attributes to detect
1335 * conflicting writes by other clients. A strict interpretation 1316 * conflicting writes by other clients. A strict interpretation
@@ -1339,11 +1320,11 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data)
1339 */ 1320 */
1340 status = NFS_PROTO(inode)->write_done(task, data); 1321 status = NFS_PROTO(inode)->write_done(task, data);
1341 if (status != 0) 1322 if (status != 0)
1342 return; 1323 return status;
1343 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, resp->count); 1324 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, data->res.count);
1344 1325
1345#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4) 1326#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
1346 if (resp->verf->committed < argp->stable && task->tk_status >= 0) { 1327 if (data->res.verf->committed < data->args.stable && task->tk_status >= 0) {
1347 /* We tried a write call, but the server did not 1328 /* We tried a write call, but the server did not
1348 * commit data to stable storage even though we 1329 * commit data to stable storage even though we
1349 * requested it. 1330 * requested it.
@@ -1359,25 +1340,31 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data)
1359 dprintk("NFS: faulty NFS server %s:" 1340 dprintk("NFS: faulty NFS server %s:"
1360 " (committed = %d) != (stable = %d)\n", 1341 " (committed = %d) != (stable = %d)\n",
1361 NFS_SERVER(inode)->nfs_client->cl_hostname, 1342 NFS_SERVER(inode)->nfs_client->cl_hostname,
1362 resp->verf->committed, argp->stable); 1343 data->res.verf->committed, data->args.stable);
1363 complain = jiffies + 300 * HZ; 1344 complain = jiffies + 300 * HZ;
1364 } 1345 }
1365 } 1346 }
1366#endif 1347#endif
1367 if (task->tk_status < 0) {
1368 nfs_set_pgio_error(data->header, task->tk_status, argp->offset);
1369 return;
1370 }
1371 1348
1372 /* Deal with the suid/sgid bit corner case */ 1349 /* Deal with the suid/sgid bit corner case */
1373 if (nfs_should_remove_suid(inode)) 1350 if (nfs_should_remove_suid(inode))
1374 nfs_mark_for_revalidate(inode); 1351 nfs_mark_for_revalidate(inode);
1352 return 0;
1353}
1354
1355/*
1356 * This function is called when the WRITE call is complete.
1357 */
1358static void nfs_writeback_result(struct rpc_task *task, struct nfs_pgio_data *data)
1359{
1360 struct nfs_pgio_args *argp = &data->args;
1361 struct nfs_pgio_res *resp = &data->res;
1375 1362
1376 if (resp->count < argp->count) { 1363 if (resp->count < argp->count) {
1377 static unsigned long complain; 1364 static unsigned long complain;
1378 1365
1379 /* This a short write! */ 1366 /* This a short write! */
1380 nfs_inc_stats(inode, NFSIOS_SHORTWRITE); 1367 nfs_inc_stats(data->header->inode, NFSIOS_SHORTWRITE);
1381 1368
1382 /* Has the server at least made some progress? */ 1369 /* Has the server at least made some progress? */
1383 if (resp->count == 0) { 1370 if (resp->count == 0) {
@@ -1911,4 +1898,6 @@ static const struct nfs_rw_ops nfs_rw_write_ops = {
1911 .rw_alloc_header = nfs_writehdr_alloc, 1898 .rw_alloc_header = nfs_writehdr_alloc,
1912 .rw_free_header = nfs_writehdr_free, 1899 .rw_free_header = nfs_writehdr_free,
1913 .rw_release = nfs_writeback_release_common, 1900 .rw_release = nfs_writeback_release_common,
1901 .rw_done = nfs_writeback_done,
1902 .rw_result = nfs_writeback_result,
1914}; 1903};
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 7e0db561d829..919576b8e2cf 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -520,7 +520,6 @@ extern int nfs_writepage(struct page *page, struct writeback_control *wbc);
520extern int nfs_writepages(struct address_space *, struct writeback_control *); 520extern int nfs_writepages(struct address_space *, struct writeback_control *);
521extern int nfs_flush_incompatible(struct file *file, struct page *page); 521extern int nfs_flush_incompatible(struct file *file, struct page *page);
522extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); 522extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
523extern void nfs_writeback_done(struct rpc_task *, struct nfs_pgio_data *);
524 523
525/* 524/*
526 * Try to write back everything synchronously (but check the 525 * Try to write back everything synchronously (but check the
@@ -553,7 +552,6 @@ nfs_have_writebacks(struct inode *inode)
553extern int nfs_readpage(struct file *, struct page *); 552extern int nfs_readpage(struct file *, struct page *);
554extern int nfs_readpages(struct file *, struct address_space *, 553extern int nfs_readpages(struct file *, struct address_space *,
555 struct list_head *, unsigned); 554 struct list_head *, unsigned);
556extern int nfs_readpage_result(struct rpc_task *, struct nfs_pgio_data *);
557extern int nfs_readpage_async(struct nfs_open_context *, struct inode *, 555extern int nfs_readpage_async(struct nfs_open_context *, struct inode *,
558 struct page *); 556 struct page *);
559 557
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index da00a4d6f470..01aa29c5ec42 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -57,6 +57,8 @@ struct nfs_rw_ops {
57 struct nfs_rw_header *(*rw_alloc_header)(void); 57 struct nfs_rw_header *(*rw_alloc_header)(void);
58 void (*rw_free_header)(struct nfs_rw_header *); 58 void (*rw_free_header)(struct nfs_rw_header *);
59 void (*rw_release)(struct nfs_pgio_data *); 59 void (*rw_release)(struct nfs_pgio_data *);
60 int (*rw_done)(struct rpc_task *, struct nfs_pgio_data *, struct inode *);
61 void (*rw_result)(struct rpc_task *, struct nfs_pgio_data *);
60}; 62};
61 63
62struct nfs_pageio_descriptor { 64struct nfs_pageio_descriptor {