diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-13 20:13:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-13 20:13:19 -0400 |
commit | 06b8ab55289345ab191bf4bf0e4acc6d4bdf293d (patch) | |
tree | 9af9215097e26c026f30a58c6ca3092ec15d1e1e /fs/nfs/write.c | |
parent | dc1cc85133120e49c223f36aa77d398b8abac727 (diff) | |
parent | 71a6ec8ac587418ceb6b420def1ca44b334c1ff7 (diff) |
Merge tag 'nfs-for-3.17-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust:
"Highlights include:
- stable fix for a bug in nfs3_list_one_acl()
- speed up NFS path walks by supporting LOOKUP_RCU
- more read/write code cleanups
- pNFS fixes for layout return on close
- fixes for the RCU handling in the rpcsec_gss code
- more NFS/RDMA fixes"
* tag 'nfs-for-3.17-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (79 commits)
nfs: reject changes to resvport and sharecache during remount
NFS: Avoid infinite loop when RELEASE_LOCKOWNER getting expired error
SUNRPC: remove all refcounting of groupinfo from rpcauth_lookupcred
NFS: fix two problems in lookup_revalidate in RCU-walk
NFS: allow lockless access to access_cache
NFS: teach nfs_lookup_verify_inode to handle LOOKUP_RCU
NFS: teach nfs_neg_need_reval to understand LOOKUP_RCU
NFS: support RCU_WALK in nfs_permission()
sunrpc/auth: allow lockless (rcu) lookup of credential cache.
NFS: prepare for RCU-walk support but pushing tests later in code.
NFS: nfs4_lookup_revalidate: only evaluate parent if it will be used.
NFS: add checks for returned value of try_module_get()
nfs: clear_request_commit while holding i_lock
pnfs: add pnfs_put_lseg_async
pnfs: find swapped pages on pnfs commit lists too
nfs: fix comment and add warn_on for PG_INODE_REF
nfs: check wait_on_bit_lock err in page_group_lock
sunrpc: remove "ec" argument from encrypt_v2 operation
sunrpc: clean up sparse endianness warnings in gss_krb5_wrap.c
sunrpc: clean up sparse endianness warnings in gss_krb5_seal.c
...
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 150 |
1 files changed, 79 insertions, 71 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 962c9ee758be..e3b5cf28bdc5 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -47,6 +47,8 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; | |||
47 | static const struct nfs_commit_completion_ops nfs_commit_completion_ops; | 47 | static const struct nfs_commit_completion_ops nfs_commit_completion_ops; |
48 | static const struct nfs_rw_ops nfs_rw_write_ops; | 48 | static const struct nfs_rw_ops nfs_rw_write_ops; |
49 | static void nfs_clear_request_commit(struct nfs_page *req); | 49 | static void nfs_clear_request_commit(struct nfs_page *req); |
50 | static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, | ||
51 | struct inode *inode); | ||
50 | 52 | ||
51 | static struct kmem_cache *nfs_wdata_cachep; | 53 | static struct kmem_cache *nfs_wdata_cachep; |
52 | static mempool_t *nfs_wdata_mempool; | 54 | static mempool_t *nfs_wdata_mempool; |
@@ -71,18 +73,18 @@ void nfs_commit_free(struct nfs_commit_data *p) | |||
71 | } | 73 | } |
72 | EXPORT_SYMBOL_GPL(nfs_commit_free); | 74 | EXPORT_SYMBOL_GPL(nfs_commit_free); |
73 | 75 | ||
74 | static struct nfs_rw_header *nfs_writehdr_alloc(void) | 76 | static struct nfs_pgio_header *nfs_writehdr_alloc(void) |
75 | { | 77 | { |
76 | struct nfs_rw_header *p = mempool_alloc(nfs_wdata_mempool, GFP_NOIO); | 78 | struct nfs_pgio_header *p = mempool_alloc(nfs_wdata_mempool, GFP_NOIO); |
77 | 79 | ||
78 | if (p) | 80 | if (p) |
79 | memset(p, 0, sizeof(*p)); | 81 | memset(p, 0, sizeof(*p)); |
80 | return p; | 82 | return p; |
81 | } | 83 | } |
82 | 84 | ||
83 | static void nfs_writehdr_free(struct nfs_rw_header *whdr) | 85 | static void nfs_writehdr_free(struct nfs_pgio_header *hdr) |
84 | { | 86 | { |
85 | mempool_free(whdr, nfs_wdata_mempool); | 87 | mempool_free(hdr, nfs_wdata_mempool); |
86 | } | 88 | } |
87 | 89 | ||
88 | static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) | 90 | static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) |
@@ -93,6 +95,38 @@ static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) | |||
93 | } | 95 | } |
94 | 96 | ||
95 | /* | 97 | /* |
98 | * nfs_page_search_commits_for_head_request_locked | ||
99 | * | ||
100 | * Search through commit lists on @inode for the head request for @page. | ||
101 | * Must be called while holding the inode (which is cinfo) lock. | ||
102 | * | ||
103 | * Returns the head request if found, or NULL if not found. | ||
104 | */ | ||
105 | static struct nfs_page * | ||
106 | nfs_page_search_commits_for_head_request_locked(struct nfs_inode *nfsi, | ||
107 | struct page *page) | ||
108 | { | ||
109 | struct nfs_page *freq, *t; | ||
110 | struct nfs_commit_info cinfo; | ||
111 | struct inode *inode = &nfsi->vfs_inode; | ||
112 | |||
113 | nfs_init_cinfo_from_inode(&cinfo, inode); | ||
114 | |||
115 | /* search through pnfs commit lists */ | ||
116 | freq = pnfs_search_commit_reqs(inode, &cinfo, page); | ||
117 | if (freq) | ||
118 | return freq->wb_head; | ||
119 | |||
120 | /* Linearly search the commit list for the correct request */ | ||
121 | list_for_each_entry_safe(freq, t, &cinfo.mds->list, wb_list) { | ||
122 | if (freq->wb_page == page) | ||
123 | return freq->wb_head; | ||
124 | } | ||
125 | |||
126 | return NULL; | ||
127 | } | ||
128 | |||
129 | /* | ||
96 | * nfs_page_find_head_request_locked - find head request associated with @page | 130 | * nfs_page_find_head_request_locked - find head request associated with @page |
97 | * | 131 | * |
98 | * must be called while holding the inode lock. | 132 | * must be called while holding the inode lock. |
@@ -106,21 +140,12 @@ nfs_page_find_head_request_locked(struct nfs_inode *nfsi, struct page *page) | |||
106 | 140 | ||
107 | if (PagePrivate(page)) | 141 | if (PagePrivate(page)) |
108 | req = (struct nfs_page *)page_private(page); | 142 | req = (struct nfs_page *)page_private(page); |
109 | else if (unlikely(PageSwapCache(page))) { | 143 | else if (unlikely(PageSwapCache(page))) |
110 | struct nfs_page *freq, *t; | 144 | req = nfs_page_search_commits_for_head_request_locked(nfsi, |
111 | 145 | page); | |
112 | /* Linearly search the commit list for the correct req */ | ||
113 | list_for_each_entry_safe(freq, t, &nfsi->commit_info.list, wb_list) { | ||
114 | if (freq->wb_page == page) { | ||
115 | req = freq->wb_head; | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | 146 | ||
121 | if (req) { | 147 | if (req) { |
122 | WARN_ON_ONCE(req->wb_head != req); | 148 | WARN_ON_ONCE(req->wb_head != req); |
123 | |||
124 | kref_get(&req->wb_kref); | 149 | kref_get(&req->wb_kref); |
125 | } | 150 | } |
126 | 151 | ||
@@ -216,7 +241,7 @@ static bool nfs_page_group_covers_page(struct nfs_page *req) | |||
216 | unsigned int pos = 0; | 241 | unsigned int pos = 0; |
217 | unsigned int len = nfs_page_length(req->wb_page); | 242 | unsigned int len = nfs_page_length(req->wb_page); |
218 | 243 | ||
219 | nfs_page_group_lock(req); | 244 | nfs_page_group_lock(req, true); |
220 | 245 | ||
221 | do { | 246 | do { |
222 | tmp = nfs_page_group_search_locked(req->wb_head, pos); | 247 | tmp = nfs_page_group_search_locked(req->wb_head, pos); |
@@ -379,8 +404,6 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, | |||
379 | subreq->wb_head = subreq; | 404 | subreq->wb_head = subreq; |
380 | subreq->wb_this_page = subreq; | 405 | subreq->wb_this_page = subreq; |
381 | 406 | ||
382 | nfs_clear_request_commit(subreq); | ||
383 | |||
384 | /* subreq is now totally disconnected from page group or any | 407 | /* subreq is now totally disconnected from page group or any |
385 | * write / commit lists. last chance to wake any waiters */ | 408 | * write / commit lists. last chance to wake any waiters */ |
386 | nfs_unlock_request(subreq); | 409 | nfs_unlock_request(subreq); |
@@ -456,7 +479,9 @@ try_again: | |||
456 | } | 479 | } |
457 | 480 | ||
458 | /* lock each request in the page group */ | 481 | /* lock each request in the page group */ |
459 | nfs_page_group_lock(head); | 482 | ret = nfs_page_group_lock(head, false); |
483 | if (ret < 0) | ||
484 | return ERR_PTR(ret); | ||
460 | subreq = head; | 485 | subreq = head; |
461 | do { | 486 | do { |
462 | /* | 487 | /* |
@@ -488,7 +513,7 @@ try_again: | |||
488 | * Commit list removal accounting is done after locks are dropped */ | 513 | * Commit list removal accounting is done after locks are dropped */ |
489 | subreq = head; | 514 | subreq = head; |
490 | do { | 515 | do { |
491 | nfs_list_remove_request(subreq); | 516 | nfs_clear_request_commit(subreq); |
492 | subreq = subreq->wb_this_page; | 517 | subreq = subreq->wb_this_page; |
493 | } while (subreq != head); | 518 | } while (subreq != head); |
494 | 519 | ||
@@ -518,15 +543,11 @@ try_again: | |||
518 | 543 | ||
519 | nfs_page_group_unlock(head); | 544 | nfs_page_group_unlock(head); |
520 | 545 | ||
521 | /* drop lock to clear_request_commit the head req and clean up | 546 | /* drop lock to clean uprequests on destroy list */ |
522 | * requests on destroy list */ | ||
523 | spin_unlock(&inode->i_lock); | 547 | spin_unlock(&inode->i_lock); |
524 | 548 | ||
525 | nfs_destroy_unlinked_subrequests(destroy_list, head); | 549 | nfs_destroy_unlinked_subrequests(destroy_list, head); |
526 | 550 | ||
527 | /* clean up commit list state */ | ||
528 | nfs_clear_request_commit(head); | ||
529 | |||
530 | /* still holds ref on head from nfs_page_find_head_request_locked | 551 | /* still holds ref on head from nfs_page_find_head_request_locked |
531 | * and still has lock on head from lock loop */ | 552 | * and still has lock on head from lock loop */ |
532 | return head; | 553 | return head; |
@@ -705,6 +726,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
705 | 726 | ||
706 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) | 727 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) |
707 | nfs_release_request(req); | 728 | nfs_release_request(req); |
729 | else | ||
730 | WARN_ON_ONCE(1); | ||
708 | } | 731 | } |
709 | 732 | ||
710 | static void | 733 | static void |
@@ -808,6 +831,7 @@ nfs_clear_page_commit(struct page *page) | |||
808 | dec_bdi_stat(page_file_mapping(page)->backing_dev_info, BDI_RECLAIMABLE); | 831 | dec_bdi_stat(page_file_mapping(page)->backing_dev_info, BDI_RECLAIMABLE); |
809 | } | 832 | } |
810 | 833 | ||
834 | /* Called holding inode (/cinfo) lock */ | ||
811 | static void | 835 | static void |
812 | nfs_clear_request_commit(struct nfs_page *req) | 836 | nfs_clear_request_commit(struct nfs_page *req) |
813 | { | 837 | { |
@@ -817,20 +841,17 @@ nfs_clear_request_commit(struct nfs_page *req) | |||
817 | 841 | ||
818 | nfs_init_cinfo_from_inode(&cinfo, inode); | 842 | nfs_init_cinfo_from_inode(&cinfo, inode); |
819 | if (!pnfs_clear_request_commit(req, &cinfo)) { | 843 | if (!pnfs_clear_request_commit(req, &cinfo)) { |
820 | spin_lock(cinfo.lock); | ||
821 | nfs_request_remove_commit_list(req, &cinfo); | 844 | nfs_request_remove_commit_list(req, &cinfo); |
822 | spin_unlock(cinfo.lock); | ||
823 | } | 845 | } |
824 | nfs_clear_page_commit(req->wb_page); | 846 | nfs_clear_page_commit(req->wb_page); |
825 | } | 847 | } |
826 | } | 848 | } |
827 | 849 | ||
828 | static inline | 850 | int nfs_write_need_commit(struct nfs_pgio_header *hdr) |
829 | int nfs_write_need_commit(struct nfs_pgio_data *data) | ||
830 | { | 851 | { |
831 | if (data->verf.committed == NFS_DATA_SYNC) | 852 | if (hdr->verf.committed == NFS_DATA_SYNC) |
832 | return data->header->lseg == NULL; | 853 | return hdr->lseg == NULL; |
833 | return data->verf.committed != NFS_FILE_SYNC; | 854 | return hdr->verf.committed != NFS_FILE_SYNC; |
834 | } | 855 | } |
835 | 856 | ||
836 | #else | 857 | #else |
@@ -856,8 +877,7 @@ nfs_clear_request_commit(struct nfs_page *req) | |||
856 | { | 877 | { |
857 | } | 878 | } |
858 | 879 | ||
859 | static inline | 880 | int nfs_write_need_commit(struct nfs_pgio_header *hdr) |
860 | int nfs_write_need_commit(struct nfs_pgio_data *data) | ||
861 | { | 881 | { |
862 | return 0; | 882 | return 0; |
863 | } | 883 | } |
@@ -883,11 +903,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr) | |||
883 | nfs_context_set_write_error(req->wb_context, hdr->error); | 903 | nfs_context_set_write_error(req->wb_context, hdr->error); |
884 | goto remove_req; | 904 | goto remove_req; |
885 | } | 905 | } |
886 | if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags)) { | 906 | if (nfs_write_need_commit(hdr)) { |
887 | nfs_mark_request_dirty(req); | ||
888 | goto next; | ||
889 | } | ||
890 | if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) { | ||
891 | memcpy(&req->wb_verf, &hdr->verf.verifier, sizeof(req->wb_verf)); | 907 | memcpy(&req->wb_verf, &hdr->verf.verifier, sizeof(req->wb_verf)); |
892 | nfs_mark_request_commit(req, hdr->lseg, &cinfo); | 908 | nfs_mark_request_commit(req, hdr->lseg, &cinfo); |
893 | goto next; | 909 | goto next; |
@@ -1038,9 +1054,9 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, | |||
1038 | else | 1054 | else |
1039 | req->wb_bytes = rqend - req->wb_offset; | 1055 | req->wb_bytes = rqend - req->wb_offset; |
1040 | out_unlock: | 1056 | out_unlock: |
1041 | spin_unlock(&inode->i_lock); | ||
1042 | if (req) | 1057 | if (req) |
1043 | nfs_clear_request_commit(req); | 1058 | nfs_clear_request_commit(req); |
1059 | spin_unlock(&inode->i_lock); | ||
1044 | return req; | 1060 | return req; |
1045 | out_flushme: | 1061 | out_flushme: |
1046 | spin_unlock(&inode->i_lock); | 1062 | spin_unlock(&inode->i_lock); |
@@ -1241,17 +1257,18 @@ static int flush_task_priority(int how) | |||
1241 | return RPC_PRIORITY_NORMAL; | 1257 | return RPC_PRIORITY_NORMAL; |
1242 | } | 1258 | } |
1243 | 1259 | ||
1244 | static void nfs_initiate_write(struct nfs_pgio_data *data, struct rpc_message *msg, | 1260 | static void nfs_initiate_write(struct nfs_pgio_header *hdr, |
1261 | struct rpc_message *msg, | ||
1245 | struct rpc_task_setup *task_setup_data, int how) | 1262 | struct rpc_task_setup *task_setup_data, int how) |
1246 | { | 1263 | { |
1247 | struct inode *inode = data->header->inode; | 1264 | struct inode *inode = hdr->inode; |
1248 | int priority = flush_task_priority(how); | 1265 | int priority = flush_task_priority(how); |
1249 | 1266 | ||
1250 | task_setup_data->priority = priority; | 1267 | task_setup_data->priority = priority; |
1251 | NFS_PROTO(inode)->write_setup(data, msg); | 1268 | NFS_PROTO(inode)->write_setup(hdr, msg); |
1252 | 1269 | ||
1253 | nfs4_state_protect_write(NFS_SERVER(inode)->nfs_client, | 1270 | nfs4_state_protect_write(NFS_SERVER(inode)->nfs_client, |
1254 | &task_setup_data->rpc_client, msg, data); | 1271 | &task_setup_data->rpc_client, msg, hdr); |
1255 | } | 1272 | } |
1256 | 1273 | ||
1257 | /* If a nfs_flush_* function fails, it should remove reqs from @head and | 1274 | /* If a nfs_flush_* function fails, it should remove reqs from @head and |
@@ -1313,21 +1330,9 @@ void nfs_commit_prepare(struct rpc_task *task, void *calldata) | |||
1313 | NFS_PROTO(data->inode)->commit_rpc_prepare(task, data); | 1330 | NFS_PROTO(data->inode)->commit_rpc_prepare(task, data); |
1314 | } | 1331 | } |
1315 | 1332 | ||
1316 | static void nfs_writeback_release_common(struct nfs_pgio_data *data) | 1333 | static void nfs_writeback_release_common(struct nfs_pgio_header *hdr) |
1317 | { | 1334 | { |
1318 | struct nfs_pgio_header *hdr = data->header; | 1335 | /* do nothing! */ |
1319 | int status = data->task.tk_status; | ||
1320 | |||
1321 | if ((status >= 0) && nfs_write_need_commit(data)) { | ||
1322 | spin_lock(&hdr->lock); | ||
1323 | if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags)) | ||
1324 | ; /* Do nothing */ | ||
1325 | else if (!test_and_set_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) | ||
1326 | memcpy(&hdr->verf, &data->verf, sizeof(hdr->verf)); | ||
1327 | else if (memcmp(&hdr->verf, &data->verf, sizeof(hdr->verf))) | ||
1328 | set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags); | ||
1329 | spin_unlock(&hdr->lock); | ||
1330 | } | ||
1331 | } | 1336 | } |
1332 | 1337 | ||
1333 | /* | 1338 | /* |
@@ -1358,7 +1363,8 @@ static int nfs_should_remove_suid(const struct inode *inode) | |||
1358 | /* | 1363 | /* |
1359 | * This function is called when the WRITE call is complete. | 1364 | * This function is called when the WRITE call is complete. |
1360 | */ | 1365 | */ |
1361 | static int nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data, | 1366 | static int nfs_writeback_done(struct rpc_task *task, |
1367 | struct nfs_pgio_header *hdr, | ||
1362 | struct inode *inode) | 1368 | struct inode *inode) |
1363 | { | 1369 | { |
1364 | int status; | 1370 | int status; |
@@ -1370,13 +1376,14 @@ static int nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data, | |||
1370 | * another writer had changed the file, but some applications | 1376 | * another writer had changed the file, but some applications |
1371 | * depend on tighter cache coherency when writing. | 1377 | * depend on tighter cache coherency when writing. |
1372 | */ | 1378 | */ |
1373 | status = NFS_PROTO(inode)->write_done(task, data); | 1379 | status = NFS_PROTO(inode)->write_done(task, hdr); |
1374 | if (status != 0) | 1380 | if (status != 0) |
1375 | return status; | 1381 | return status; |
1376 | nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, data->res.count); | 1382 | nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count); |
1377 | 1383 | ||
1378 | #if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4) | 1384 | #if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4) |
1379 | if (data->res.verf->committed < data->args.stable && task->tk_status >= 0) { | 1385 | if (hdr->res.verf->committed < hdr->args.stable && |
1386 | task->tk_status >= 0) { | ||
1380 | /* We tried a write call, but the server did not | 1387 | /* We tried a write call, but the server did not |
1381 | * commit data to stable storage even though we | 1388 | * commit data to stable storage even though we |
1382 | * requested it. | 1389 | * requested it. |
@@ -1392,7 +1399,7 @@ static int nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data, | |||
1392 | dprintk("NFS: faulty NFS server %s:" | 1399 | dprintk("NFS: faulty NFS server %s:" |
1393 | " (committed = %d) != (stable = %d)\n", | 1400 | " (committed = %d) != (stable = %d)\n", |
1394 | NFS_SERVER(inode)->nfs_client->cl_hostname, | 1401 | NFS_SERVER(inode)->nfs_client->cl_hostname, |
1395 | data->res.verf->committed, data->args.stable); | 1402 | hdr->res.verf->committed, hdr->args.stable); |
1396 | complain = jiffies + 300 * HZ; | 1403 | complain = jiffies + 300 * HZ; |
1397 | } | 1404 | } |
1398 | } | 1405 | } |
@@ -1407,16 +1414,17 @@ static int nfs_writeback_done(struct rpc_task *task, struct nfs_pgio_data *data, | |||
1407 | /* | 1414 | /* |
1408 | * This function is called when the WRITE call is complete. | 1415 | * This function is called when the WRITE call is complete. |
1409 | */ | 1416 | */ |
1410 | static void nfs_writeback_result(struct rpc_task *task, struct nfs_pgio_data *data) | 1417 | static void nfs_writeback_result(struct rpc_task *task, |
1418 | struct nfs_pgio_header *hdr) | ||
1411 | { | 1419 | { |
1412 | struct nfs_pgio_args *argp = &data->args; | 1420 | struct nfs_pgio_args *argp = &hdr->args; |
1413 | struct nfs_pgio_res *resp = &data->res; | 1421 | struct nfs_pgio_res *resp = &hdr->res; |
1414 | 1422 | ||
1415 | if (resp->count < argp->count) { | 1423 | if (resp->count < argp->count) { |
1416 | static unsigned long complain; | 1424 | static unsigned long complain; |
1417 | 1425 | ||
1418 | /* This a short write! */ | 1426 | /* This a short write! */ |
1419 | nfs_inc_stats(data->header->inode, NFSIOS_SHORTWRITE); | 1427 | nfs_inc_stats(hdr->inode, NFSIOS_SHORTWRITE); |
1420 | 1428 | ||
1421 | /* Has the server at least made some progress? */ | 1429 | /* Has the server at least made some progress? */ |
1422 | if (resp->count == 0) { | 1430 | if (resp->count == 0) { |
@@ -1426,14 +1434,14 @@ static void nfs_writeback_result(struct rpc_task *task, struct nfs_pgio_data *da | |||
1426 | argp->count); | 1434 | argp->count); |
1427 | complain = jiffies + 300 * HZ; | 1435 | complain = jiffies + 300 * HZ; |
1428 | } | 1436 | } |
1429 | nfs_set_pgio_error(data->header, -EIO, argp->offset); | 1437 | nfs_set_pgio_error(hdr, -EIO, argp->offset); |
1430 | task->tk_status = -EIO; | 1438 | task->tk_status = -EIO; |
1431 | return; | 1439 | return; |
1432 | } | 1440 | } |
1433 | /* Was this an NFSv2 write or an NFSv3 stable write? */ | 1441 | /* Was this an NFSv2 write or an NFSv3 stable write? */ |
1434 | if (resp->verf->committed != NFS_UNSTABLE) { | 1442 | if (resp->verf->committed != NFS_UNSTABLE) { |
1435 | /* Resend from where the server left off */ | 1443 | /* Resend from where the server left off */ |
1436 | data->mds_offset += resp->count; | 1444 | hdr->mds_offset += resp->count; |
1437 | argp->offset += resp->count; | 1445 | argp->offset += resp->count; |
1438 | argp->pgbase += resp->count; | 1446 | argp->pgbase += resp->count; |
1439 | argp->count -= resp->count; | 1447 | argp->count -= resp->count; |
@@ -1884,7 +1892,7 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage, | |||
1884 | int __init nfs_init_writepagecache(void) | 1892 | int __init nfs_init_writepagecache(void) |
1885 | { | 1893 | { |
1886 | nfs_wdata_cachep = kmem_cache_create("nfs_write_data", | 1894 | nfs_wdata_cachep = kmem_cache_create("nfs_write_data", |
1887 | sizeof(struct nfs_rw_header), | 1895 | sizeof(struct nfs_pgio_header), |
1888 | 0, SLAB_HWCACHE_ALIGN, | 1896 | 0, SLAB_HWCACHE_ALIGN, |
1889 | NULL); | 1897 | NULL); |
1890 | if (nfs_wdata_cachep == NULL) | 1898 | if (nfs_wdata_cachep == NULL) |