aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 09:44:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 09:44:06 -0400
commitef78cc75f11ba3b085b105209cbfc6666ee10499 (patch)
tree1820dbd8ebb422b0a5751981cdfb6a2ecd30e20b /fs/nfs
parent1442d1678ca7e53574fd403ba7bee6f4125d920c (diff)
parent940aab490215424a269f93d2eba2794fc8b3e269 (diff)
Merge branch 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (26 commits) Check validity of cl_rpcclient in nfs_server_list_show NFS: Get rid of the nfs_rdata_mempool NFS: Don't rely on PageError in nfs_readpage_release_partial NFS: Get rid of unnecessary calls to ClearPageError() in read code NFS: Get rid of nfs_restart_rpc() NFS: Get rid of the unused nfs_write_data->flags field NFS: Get rid of the unused nfs_read_data->flags field NFSv4: Translate NFS4ERR_BADNAME into ENOENT when applied to a lookup NFS: Remove the unused "lookupfh()" version of nfs4_proc_lookup() NFS: Use the inode->i_version to cache NFSv4 change attribute information SUNRPC: Remove unnecessary export of rpc_sockaddr2uaddr SUNRPC: Fix rpc_sockaddr2uaddr nfs/super.c: local functions should be static pnfsblock: fix writeback deadlock pnfsblock: fix NULL pointer dereference pnfs: recoalesce when ld read pagelist fails pnfs: recoalesce when ld write pagelist fails pnfs: make _set_lo_fail generic pnfsblock: add missing rpc_put_mount and path_put SUNRPC/NFS: make rpc pipe upcall generic ...
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/blocklayout/blocklayout.c58
-rw-r--r--fs/nfs/blocklayout/blocklayout.h4
-rw-r--r--fs/nfs/blocklayout/blocklayoutdev.c35
-rw-r--r--fs/nfs/client.c4
-rw-r--r--fs/nfs/delegation.c2
-rw-r--r--fs/nfs/fscache-index.c4
-rw-r--r--fs/nfs/idmap.c25
-rw-r--r--fs/nfs/inode.c16
-rw-r--r--fs/nfs/internal.h10
-rw-r--r--fs/nfs/nfs4filelayout.c33
-rw-r--r--fs/nfs/nfs4proc.c93
-rw-r--r--fs/nfs/pnfs.c52
-rw-r--r--fs/nfs/pnfs.h5
-rw-r--r--fs/nfs/read.c40
-rw-r--r--fs/nfs/super.c17
-rw-r--r--fs/nfs/unlink.c4
-rw-r--r--fs/nfs/write.c73
17 files changed, 202 insertions, 273 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 9561c8fc8bd..281ae95932c 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -176,17 +176,6 @@ retry:
176 return bio; 176 return bio;
177} 177}
178 178
179static void bl_set_lo_fail(struct pnfs_layout_segment *lseg)
180{
181 if (lseg->pls_range.iomode == IOMODE_RW) {
182 dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
183 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
184 } else {
185 dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
186 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
187 }
188}
189
190/* This is basically copied from mpage_end_io_read */ 179/* This is basically copied from mpage_end_io_read */
191static void bl_end_io_read(struct bio *bio, int err) 180static void bl_end_io_read(struct bio *bio, int err)
192{ 181{
@@ -206,7 +195,7 @@ static void bl_end_io_read(struct bio *bio, int err)
206 if (!uptodate) { 195 if (!uptodate) {
207 if (!rdata->pnfs_error) 196 if (!rdata->pnfs_error)
208 rdata->pnfs_error = -EIO; 197 rdata->pnfs_error = -EIO;
209 bl_set_lo_fail(rdata->lseg); 198 pnfs_set_lo_fail(rdata->lseg);
210 } 199 }
211 bio_put(bio); 200 bio_put(bio);
212 put_parallel(par); 201 put_parallel(par);
@@ -303,6 +292,7 @@ bl_read_pagelist(struct nfs_read_data *rdata)
303 bl_end_io_read, par); 292 bl_end_io_read, par);
304 if (IS_ERR(bio)) { 293 if (IS_ERR(bio)) {
305 rdata->pnfs_error = PTR_ERR(bio); 294 rdata->pnfs_error = PTR_ERR(bio);
295 bio = NULL;
306 goto out; 296 goto out;
307 } 297 }
308 } 298 }
@@ -370,7 +360,7 @@ static void bl_end_io_write_zero(struct bio *bio, int err)
370 if (!uptodate) { 360 if (!uptodate) {
371 if (!wdata->pnfs_error) 361 if (!wdata->pnfs_error)
372 wdata->pnfs_error = -EIO; 362 wdata->pnfs_error = -EIO;
373 bl_set_lo_fail(wdata->lseg); 363 pnfs_set_lo_fail(wdata->lseg);
374 } 364 }
375 bio_put(bio); 365 bio_put(bio);
376 put_parallel(par); 366 put_parallel(par);
@@ -386,7 +376,7 @@ static void bl_end_io_write(struct bio *bio, int err)
386 if (!uptodate) { 376 if (!uptodate) {
387 if (!wdata->pnfs_error) 377 if (!wdata->pnfs_error)
388 wdata->pnfs_error = -EIO; 378 wdata->pnfs_error = -EIO;
389 bl_set_lo_fail(wdata->lseg); 379 pnfs_set_lo_fail(wdata->lseg);
390 } 380 }
391 bio_put(bio); 381 bio_put(bio);
392 put_parallel(par); 382 put_parallel(par);
@@ -543,6 +533,11 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
543fill_invalid_ext: 533fill_invalid_ext:
544 dprintk("%s need to zero %d pages\n", __func__, npg_zero); 534 dprintk("%s need to zero %d pages\n", __func__, npg_zero);
545 for (;npg_zero > 0; npg_zero--) { 535 for (;npg_zero > 0; npg_zero--) {
536 if (bl_is_sector_init(be->be_inval, isect)) {
537 dprintk("isect %llu already init\n",
538 (unsigned long long)isect);
539 goto next_page;
540 }
546 /* page ref released in bl_end_io_write_zero */ 541 /* page ref released in bl_end_io_write_zero */
547 index = isect >> PAGE_CACHE_SECTOR_SHIFT; 542 index = isect >> PAGE_CACHE_SECTOR_SHIFT;
548 dprintk("%s zero %dth page: index %lu isect %llu\n", 543 dprintk("%s zero %dth page: index %lu isect %llu\n",
@@ -562,8 +557,7 @@ fill_invalid_ext:
562 * PageUptodate: It was read before 557 * PageUptodate: It was read before
563 * sector_initialized: already written out 558 * sector_initialized: already written out
564 */ 559 */
565 if (PageDirty(page) || PageWriteback(page) || 560 if (PageDirty(page) || PageWriteback(page)) {
566 bl_is_sector_init(be->be_inval, isect)) {
567 print_page(page); 561 print_page(page);
568 unlock_page(page); 562 unlock_page(page);
569 page_cache_release(page); 563 page_cache_release(page);
@@ -592,6 +586,7 @@ fill_invalid_ext:
592 bl_end_io_write_zero, par); 586 bl_end_io_write_zero, par);
593 if (IS_ERR(bio)) { 587 if (IS_ERR(bio)) {
594 wdata->pnfs_error = PTR_ERR(bio); 588 wdata->pnfs_error = PTR_ERR(bio);
589 bio = NULL;
595 goto out; 590 goto out;
596 } 591 }
597 /* FIXME: This should be done in bi_end_io */ 592 /* FIXME: This should be done in bi_end_io */
@@ -640,6 +635,7 @@ next_page:
640 bl_end_io_write, par); 635 bl_end_io_write, par);
641 if (IS_ERR(bio)) { 636 if (IS_ERR(bio)) {
642 wdata->pnfs_error = PTR_ERR(bio); 637 wdata->pnfs_error = PTR_ERR(bio);
638 bio = NULL;
643 goto out; 639 goto out;
644 } 640 }
645 isect += PAGE_CACHE_SECTORS; 641 isect += PAGE_CACHE_SECTORS;
@@ -805,7 +801,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
805 struct nfs4_deviceid *d_id) 801 struct nfs4_deviceid *d_id)
806{ 802{
807 struct pnfs_device *dev; 803 struct pnfs_device *dev;
808 struct pnfs_block_dev *rv = NULL; 804 struct pnfs_block_dev *rv;
809 u32 max_resp_sz; 805 u32 max_resp_sz;
810 int max_pages; 806 int max_pages;
811 struct page **pages = NULL; 807 struct page **pages = NULL;
@@ -823,18 +819,20 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
823 dev = kmalloc(sizeof(*dev), GFP_NOFS); 819 dev = kmalloc(sizeof(*dev), GFP_NOFS);
824 if (!dev) { 820 if (!dev) {
825 dprintk("%s kmalloc failed\n", __func__); 821 dprintk("%s kmalloc failed\n", __func__);
826 return NULL; 822 return ERR_PTR(-ENOMEM);
827 } 823 }
828 824
829 pages = kzalloc(max_pages * sizeof(struct page *), GFP_NOFS); 825 pages = kzalloc(max_pages * sizeof(struct page *), GFP_NOFS);
830 if (pages == NULL) { 826 if (pages == NULL) {
831 kfree(dev); 827 kfree(dev);
832 return NULL; 828 return ERR_PTR(-ENOMEM);
833 } 829 }
834 for (i = 0; i < max_pages; i++) { 830 for (i = 0; i < max_pages; i++) {
835 pages[i] = alloc_page(GFP_NOFS); 831 pages[i] = alloc_page(GFP_NOFS);
836 if (!pages[i]) 832 if (!pages[i]) {
833 rv = ERR_PTR(-ENOMEM);
837 goto out_free; 834 goto out_free;
835 }
838 } 836 }
839 837
840 memcpy(&dev->dev_id, d_id, sizeof(*d_id)); 838 memcpy(&dev->dev_id, d_id, sizeof(*d_id));
@@ -847,8 +845,10 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
847 dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data); 845 dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data);
848 rc = nfs4_proc_getdeviceinfo(server, dev); 846 rc = nfs4_proc_getdeviceinfo(server, dev);
849 dprintk("%s getdevice info returns %d\n", __func__, rc); 847 dprintk("%s getdevice info returns %d\n", __func__, rc);
850 if (rc) 848 if (rc) {
849 rv = ERR_PTR(rc);
851 goto out_free; 850 goto out_free;
851 }
852 852
853 rv = nfs4_blk_decode_device(server, dev); 853 rv = nfs4_blk_decode_device(server, dev);
854 out_free: 854 out_free:
@@ -866,7 +866,7 @@ bl_set_layoutdriver(struct nfs_server *server, const struct nfs_fh *fh)
866 struct pnfs_devicelist *dlist = NULL; 866 struct pnfs_devicelist *dlist = NULL;
867 struct pnfs_block_dev *bdev; 867 struct pnfs_block_dev *bdev;
868 LIST_HEAD(block_disklist); 868 LIST_HEAD(block_disklist);
869 int status = 0, i; 869 int status, i;
870 870
871 dprintk("%s enter\n", __func__); 871 dprintk("%s enter\n", __func__);
872 872
@@ -898,8 +898,8 @@ bl_set_layoutdriver(struct nfs_server *server, const struct nfs_fh *fh)
898 for (i = 0; i < dlist->num_devs; i++) { 898 for (i = 0; i < dlist->num_devs; i++) {
899 bdev = nfs4_blk_get_deviceinfo(server, fh, 899 bdev = nfs4_blk_get_deviceinfo(server, fh,
900 &dlist->dev_id[i]); 900 &dlist->dev_id[i]);
901 if (!bdev) { 901 if (IS_ERR(bdev)) {
902 status = -ENODEV; 902 status = PTR_ERR(bdev);
903 goto out_error; 903 goto out_error;
904 } 904 }
905 spin_lock(&b_mt_id->bm_lock); 905 spin_lock(&b_mt_id->bm_lock);
@@ -960,7 +960,7 @@ static struct pnfs_layoutdriver_type blocklayout_type = {
960}; 960};
961 961
962static const struct rpc_pipe_ops bl_upcall_ops = { 962static const struct rpc_pipe_ops bl_upcall_ops = {
963 .upcall = bl_pipe_upcall, 963 .upcall = rpc_pipe_generic_upcall,
964 .downcall = bl_pipe_downcall, 964 .downcall = bl_pipe_downcall,
965 .destroy_msg = bl_pipe_destroy_msg, 965 .destroy_msg = bl_pipe_destroy_msg,
966}; 966};
@@ -989,17 +989,20 @@ static int __init nfs4blocklayout_init(void)
989 mnt, 989 mnt,
990 NFS_PIPE_DIRNAME, 0, &path); 990 NFS_PIPE_DIRNAME, 0, &path);
991 if (ret) 991 if (ret)
992 goto out_remove; 992 goto out_putrpc;
993 993
994 bl_device_pipe = rpc_mkpipe(path.dentry, "blocklayout", NULL, 994 bl_device_pipe = rpc_mkpipe(path.dentry, "blocklayout", NULL,
995 &bl_upcall_ops, 0); 995 &bl_upcall_ops, 0);
996 path_put(&path);
996 if (IS_ERR(bl_device_pipe)) { 997 if (IS_ERR(bl_device_pipe)) {
997 ret = PTR_ERR(bl_device_pipe); 998 ret = PTR_ERR(bl_device_pipe);
998 goto out_remove; 999 goto out_putrpc;
999 } 1000 }
1000out: 1001out:
1001 return ret; 1002 return ret;
1002 1003
1004out_putrpc:
1005 rpc_put_mount();
1003out_remove: 1006out_remove:
1004 pnfs_unregister_layoutdriver(&blocklayout_type); 1007 pnfs_unregister_layoutdriver(&blocklayout_type);
1005 return ret; 1008 return ret;
@@ -1012,6 +1015,7 @@ static void __exit nfs4blocklayout_exit(void)
1012 1015
1013 pnfs_unregister_layoutdriver(&blocklayout_type); 1016 pnfs_unregister_layoutdriver(&blocklayout_type);
1014 rpc_unlink(bl_device_pipe); 1017 rpc_unlink(bl_device_pipe);
1018 rpc_put_mount();
1015} 1019}
1016 1020
1017MODULE_ALIAS("nfs-layouttype4-3"); 1021MODULE_ALIAS("nfs-layouttype4-3");
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index f27d827960a..42acf7ef599 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -150,7 +150,7 @@ BLK_LSEG2EXT(struct pnfs_layout_segment *lseg)
150} 150}
151 151
152struct bl_dev_msg { 152struct bl_dev_msg {
153 int status; 153 int32_t status;
154 uint32_t major, minor; 154 uint32_t major, minor;
155}; 155};
156 156
@@ -169,8 +169,6 @@ extern wait_queue_head_t bl_wq;
169#define BL_DEVICE_REQUEST_ERR 0x2 /* User level process fails */ 169#define BL_DEVICE_REQUEST_ERR 0x2 /* User level process fails */
170 170
171/* blocklayoutdev.c */ 171/* blocklayoutdev.c */
172ssize_t bl_pipe_upcall(struct file *, struct rpc_pipe_msg *,
173 char __user *, size_t);
174ssize_t bl_pipe_downcall(struct file *, const char __user *, size_t); 172ssize_t bl_pipe_downcall(struct file *, const char __user *, size_t);
175void bl_pipe_destroy_msg(struct rpc_pipe_msg *); 173void bl_pipe_destroy_msg(struct rpc_pipe_msg *);
176struct block_device *nfs4_blkdev_get(dev_t dev); 174struct block_device *nfs4_blkdev_get(dev_t dev);
diff --git a/fs/nfs/blocklayout/blocklayoutdev.c b/fs/nfs/blocklayout/blocklayoutdev.c
index a83b393fb01..d08ba9107fd 100644
--- a/fs/nfs/blocklayout/blocklayoutdev.c
+++ b/fs/nfs/blocklayout/blocklayoutdev.c
@@ -79,28 +79,6 @@ int nfs4_blkdev_put(struct block_device *bdev)
79 return blkdev_put(bdev, FMODE_READ); 79 return blkdev_put(bdev, FMODE_READ);
80} 80}
81 81
82/*
83 * Shouldn't there be a rpc_generic_upcall() to do this for us?
84 */
85ssize_t bl_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
86 char __user *dst, size_t buflen)
87{
88 char *data = (char *)msg->data + msg->copied;
89 size_t mlen = min(msg->len - msg->copied, buflen);
90 unsigned long left;
91
92 left = copy_to_user(dst, data, mlen);
93 if (left == mlen) {
94 msg->errno = -EFAULT;
95 return -EFAULT;
96 }
97
98 mlen -= left;
99 msg->copied += mlen;
100 msg->errno = 0;
101 return mlen;
102}
103
104static struct bl_dev_msg bl_mount_reply; 82static struct bl_dev_msg bl_mount_reply;
105 83
106ssize_t bl_pipe_downcall(struct file *filp, const char __user *src, 84ssize_t bl_pipe_downcall(struct file *filp, const char __user *src,
@@ -131,7 +109,7 @@ struct pnfs_block_dev *
131nfs4_blk_decode_device(struct nfs_server *server, 109nfs4_blk_decode_device(struct nfs_server *server,
132 struct pnfs_device *dev) 110 struct pnfs_device *dev)
133{ 111{
134 struct pnfs_block_dev *rv = NULL; 112 struct pnfs_block_dev *rv;
135 struct block_device *bd = NULL; 113 struct block_device *bd = NULL;
136 struct rpc_pipe_msg msg; 114 struct rpc_pipe_msg msg;
137 struct bl_msg_hdr bl_msg = { 115 struct bl_msg_hdr bl_msg = {
@@ -141,7 +119,7 @@ nfs4_blk_decode_device(struct nfs_server *server,
141 uint8_t *dataptr; 119 uint8_t *dataptr;
142 DECLARE_WAITQUEUE(wq, current); 120 DECLARE_WAITQUEUE(wq, current);
143 struct bl_dev_msg *reply = &bl_mount_reply; 121 struct bl_dev_msg *reply = &bl_mount_reply;
144 int offset, len, i; 122 int offset, len, i, rc;
145 123
146 dprintk("%s CREATING PIPEFS MESSAGE\n", __func__); 124 dprintk("%s CREATING PIPEFS MESSAGE\n", __func__);
147 dprintk("%s: deviceid: %s, mincount: %d\n", __func__, dev->dev_id.data, 125 dprintk("%s: deviceid: %s, mincount: %d\n", __func__, dev->dev_id.data,
@@ -168,8 +146,10 @@ nfs4_blk_decode_device(struct nfs_server *server,
168 146
169 dprintk("%s CALLING USERSPACE DAEMON\n", __func__); 147 dprintk("%s CALLING USERSPACE DAEMON\n", __func__);
170 add_wait_queue(&bl_wq, &wq); 148 add_wait_queue(&bl_wq, &wq);
171 if (rpc_queue_upcall(bl_device_pipe->d_inode, &msg) < 0) { 149 rc = rpc_queue_upcall(bl_device_pipe->d_inode, &msg);
150 if (rc < 0) {
172 remove_wait_queue(&bl_wq, &wq); 151 remove_wait_queue(&bl_wq, &wq);
152 rv = ERR_PTR(rc);
173 goto out; 153 goto out;
174 } 154 }
175 155
@@ -187,8 +167,9 @@ nfs4_blk_decode_device(struct nfs_server *server,
187 167
188 bd = nfs4_blkdev_get(MKDEV(reply->major, reply->minor)); 168 bd = nfs4_blkdev_get(MKDEV(reply->major, reply->minor));
189 if (IS_ERR(bd)) { 169 if (IS_ERR(bd)) {
190 dprintk("%s failed to open device : %ld\n", 170 rc = PTR_ERR(bd);
191 __func__, PTR_ERR(bd)); 171 dprintk("%s failed to open device : %d\n", __func__, rc);
172 rv = ERR_PTR(rc);
192 goto out; 173 goto out;
193 } 174 }
194 175
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index b4e41dd4d0f..873bf00d51a 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1868,6 +1868,10 @@ static int nfs_server_list_show(struct seq_file *m, void *v)
1868 /* display one transport per line on subsequent lines */ 1868 /* display one transport per line on subsequent lines */
1869 clp = list_entry(v, struct nfs_client, cl_share_link); 1869 clp = list_entry(v, struct nfs_client, cl_share_link);
1870 1870
1871 /* Check if the client is initialized */
1872 if (clp->cl_cons_state != NFS_CS_READY)
1873 return 0;
1874
1871 seq_printf(m, "v%u %s %s %3d %s\n", 1875 seq_printf(m, "v%u %s %s %3d %s\n",
1872 clp->rpc_ops->version, 1876 clp->rpc_ops->version,
1873 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR), 1877 rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 321a66bc384..7f265406980 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -240,7 +240,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
240 sizeof(delegation->stateid.data)); 240 sizeof(delegation->stateid.data));
241 delegation->type = res->delegation_type; 241 delegation->type = res->delegation_type;
242 delegation->maxsize = res->maxsize; 242 delegation->maxsize = res->maxsize;
243 delegation->change_attr = nfsi->change_attr; 243 delegation->change_attr = inode->i_version;
244 delegation->cred = get_rpccred(cred); 244 delegation->cred = get_rpccred(cred);
245 delegation->inode = inode; 245 delegation->inode = inode;
246 delegation->flags = 1<<NFS_DELEGATION_REFERENCED; 246 delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
index 5b1006480bc..7cf2c4699b0 100644
--- a/fs/nfs/fscache-index.c
+++ b/fs/nfs/fscache-index.c
@@ -212,7 +212,7 @@ static uint16_t nfs_fscache_inode_get_aux(const void *cookie_netfs_data,
212 auxdata.ctime = nfsi->vfs_inode.i_ctime; 212 auxdata.ctime = nfsi->vfs_inode.i_ctime;
213 213
214 if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) 214 if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
215 auxdata.change_attr = nfsi->change_attr; 215 auxdata.change_attr = nfsi->vfs_inode.i_version;
216 216
217 if (bufmax > sizeof(auxdata)) 217 if (bufmax > sizeof(auxdata))
218 bufmax = sizeof(auxdata); 218 bufmax = sizeof(auxdata);
@@ -244,7 +244,7 @@ enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
244 auxdata.ctime = nfsi->vfs_inode.i_ctime; 244 auxdata.ctime = nfsi->vfs_inode.i_ctime;
245 245
246 if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) 246 if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
247 auxdata.change_attr = nfsi->change_attr; 247 auxdata.change_attr = nfsi->vfs_inode.i_version;
248 248
249 if (memcmp(data, &auxdata, datalen) != 0) 249 if (memcmp(data, &auxdata, datalen) != 0)
250 return FSCACHE_CHECKAUX_OBSOLETE; 250 return FSCACHE_CHECKAUX_OBSOLETE;
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index f20801ae0a1..47d1c6ff2d8 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -336,8 +336,6 @@ struct idmap {
336 struct idmap_hashtable idmap_group_hash; 336 struct idmap_hashtable idmap_group_hash;
337}; 337};
338 338
339static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *,
340 char __user *, size_t);
341static ssize_t idmap_pipe_downcall(struct file *, const char __user *, 339static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
342 size_t); 340 size_t);
343static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); 341static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
@@ -345,7 +343,7 @@ static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
345static unsigned int fnvhash32(const void *, size_t); 343static unsigned int fnvhash32(const void *, size_t);
346 344
347static const struct rpc_pipe_ops idmap_upcall_ops = { 345static const struct rpc_pipe_ops idmap_upcall_ops = {
348 .upcall = idmap_pipe_upcall, 346 .upcall = rpc_pipe_generic_upcall,
349 .downcall = idmap_pipe_downcall, 347 .downcall = idmap_pipe_downcall,
350 .destroy_msg = idmap_pipe_destroy_msg, 348 .destroy_msg = idmap_pipe_destroy_msg,
351}; 349};
@@ -595,27 +593,6 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
595 return ret; 593 return ret;
596} 594}
597 595
598/* RPC pipefs upcall/downcall routines */
599static ssize_t
600idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
601 char __user *dst, size_t buflen)
602{
603 char *data = (char *)msg->data + msg->copied;
604 size_t mlen = min(msg->len, buflen);
605 unsigned long left;
606
607 left = copy_to_user(dst, data, mlen);
608 if (left == mlen) {
609 msg->errno = -EFAULT;
610 return -EFAULT;
611 }
612
613 mlen -= left;
614 msg->copied += mlen;
615 msg->errno = 0;
616 return mlen;
617}
618
619static ssize_t 596static ssize_t
620idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) 597idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
621{ 598{
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index fe1203797b2..4dc6d078f10 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -318,7 +318,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
318 memset(&inode->i_atime, 0, sizeof(inode->i_atime)); 318 memset(&inode->i_atime, 0, sizeof(inode->i_atime));
319 memset(&inode->i_mtime, 0, sizeof(inode->i_mtime)); 319 memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
320 memset(&inode->i_ctime, 0, sizeof(inode->i_ctime)); 320 memset(&inode->i_ctime, 0, sizeof(inode->i_ctime));
321 nfsi->change_attr = 0; 321 inode->i_version = 0;
322 inode->i_size = 0; 322 inode->i_size = 0;
323 inode->i_nlink = 0; 323 inode->i_nlink = 0;
324 inode->i_uid = -2; 324 inode->i_uid = -2;
@@ -344,7 +344,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
344 | NFS_INO_INVALID_ACCESS 344 | NFS_INO_INVALID_ACCESS
345 | NFS_INO_INVALID_ACL; 345 | NFS_INO_INVALID_ACL;
346 if (fattr->valid & NFS_ATTR_FATTR_CHANGE) 346 if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
347 nfsi->change_attr = fattr->change_attr; 347 inode->i_version = fattr->change_attr;
348 else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) 348 else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR))
349 nfsi->cache_validity |= NFS_INO_INVALID_ATTR 349 nfsi->cache_validity |= NFS_INO_INVALID_ATTR
350 | NFS_INO_INVALID_DATA; 350 | NFS_INO_INVALID_DATA;
@@ -897,8 +897,8 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
897 897
898 if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE) 898 if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
899 && (fattr->valid & NFS_ATTR_FATTR_CHANGE) 899 && (fattr->valid & NFS_ATTR_FATTR_CHANGE)
900 && nfsi->change_attr == fattr->pre_change_attr) { 900 && inode->i_version == fattr->pre_change_attr) {
901 nfsi->change_attr = fattr->change_attr; 901 inode->i_version = fattr->change_attr;
902 if (S_ISDIR(inode->i_mode)) 902 if (S_ISDIR(inode->i_mode))
903 nfsi->cache_validity |= NFS_INO_INVALID_DATA; 903 nfsi->cache_validity |= NFS_INO_INVALID_DATA;
904 ret |= NFS_INO_INVALID_ATTR; 904 ret |= NFS_INO_INVALID_ATTR;
@@ -952,7 +952,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
952 return -EIO; 952 return -EIO;
953 953
954 if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && 954 if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
955 nfsi->change_attr != fattr->change_attr) 955 inode->i_version != fattr->change_attr)
956 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; 956 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
957 957
958 /* Verify a few of the more important attributes */ 958 /* Verify a few of the more important attributes */
@@ -1163,7 +1163,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
1163 } 1163 }
1164 if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && 1164 if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 &&
1165 (fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) { 1165 (fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) {
1166 fattr->pre_change_attr = NFS_I(inode)->change_attr; 1166 fattr->pre_change_attr = inode->i_version;
1167 fattr->valid |= NFS_ATTR_FATTR_PRECHANGE; 1167 fattr->valid |= NFS_ATTR_FATTR_PRECHANGE;
1168 } 1168 }
1169 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 && 1169 if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 &&
@@ -1244,13 +1244,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1244 1244
1245 /* More cache consistency checks */ 1245 /* More cache consistency checks */
1246 if (fattr->valid & NFS_ATTR_FATTR_CHANGE) { 1246 if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
1247 if (nfsi->change_attr != fattr->change_attr) { 1247 if (inode->i_version != fattr->change_attr) {
1248 dprintk("NFS: change_attr change on server for file %s/%ld\n", 1248 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1249 inode->i_sb->s_id, inode->i_ino); 1249 inode->i_sb->s_id, inode->i_ino);
1250 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1250 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1251 if (S_ISDIR(inode->i_mode)) 1251 if (S_ISDIR(inode->i_mode))
1252 nfs_force_lookup_revalidate(inode); 1252 nfs_force_lookup_revalidate(inode);
1253 nfsi->change_attr = fattr->change_attr; 1253 inode->i_version = fattr->change_attr;
1254 } 1254 }
1255 } else if (server->caps & NFS_CAP_CHANGE_ATTR) 1255 } else if (server->caps & NFS_CAP_CHANGE_ATTR)
1256 invalid |= save_cache_validity; 1256 invalid |= save_cache_validity;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index ab12913dd47..c1a1bd8ddf1 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -457,13 +457,3 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
457 PAGE_SIZE - 1) >> PAGE_SHIFT; 457 PAGE_SIZE - 1) >> PAGE_SHIFT;
458} 458}
459 459
460/*
461 * Helper for restarting RPC calls in the possible presence of NFSv4.1
462 * sessions.
463 */
464static inline int nfs_restart_rpc(struct rpc_task *task, const struct nfs_client *clp)
465{
466 if (nfs4_has_session(clp))
467 return rpc_restart_call_prepare(task);
468 return rpc_restart_call(task);
469}
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index e8915d4840a..09119418402 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -77,19 +77,6 @@ filelayout_get_dserver_offset(struct pnfs_layout_segment *lseg, loff_t offset)
77 BUG(); 77 BUG();
78} 78}
79 79
80/* For data server errors we don't recover from */
81static void
82filelayout_set_lo_fail(struct pnfs_layout_segment *lseg)
83{
84 if (lseg->pls_range.iomode == IOMODE_RW) {
85 dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
86 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
87 } else {
88 dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
89 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
90 }
91}
92
93static int filelayout_async_handle_error(struct rpc_task *task, 80static int filelayout_async_handle_error(struct rpc_task *task,
94 struct nfs4_state *state, 81 struct nfs4_state *state,
95 struct nfs_client *clp, 82 struct nfs_client *clp,
@@ -135,7 +122,6 @@ static int filelayout_async_handle_error(struct rpc_task *task,
135static int filelayout_read_done_cb(struct rpc_task *task, 122static int filelayout_read_done_cb(struct rpc_task *task,
136 struct nfs_read_data *data) 123 struct nfs_read_data *data)
137{ 124{
138 struct nfs_client *clp = data->ds_clp;
139 int reset = 0; 125 int reset = 0;
140 126
141 dprintk("%s DS read\n", __func__); 127 dprintk("%s DS read\n", __func__);
@@ -145,11 +131,10 @@ static int filelayout_read_done_cb(struct rpc_task *task,
145 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 131 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
146 __func__, data->ds_clp, data->ds_clp->cl_session); 132 __func__, data->ds_clp, data->ds_clp->cl_session);
147 if (reset) { 133 if (reset) {
148 filelayout_set_lo_fail(data->lseg); 134 pnfs_set_lo_fail(data->lseg);
149 nfs4_reset_read(task, data); 135 nfs4_reset_read(task, data);
150 clp = NFS_SERVER(data->inode)->nfs_client;
151 } 136 }
152 nfs_restart_rpc(task, clp); 137 rpc_restart_call_prepare(task);
153 return -EAGAIN; 138 return -EAGAIN;
154 } 139 }
155 140
@@ -216,17 +201,13 @@ static int filelayout_write_done_cb(struct rpc_task *task,
216 201
217 if (filelayout_async_handle_error(task, data->args.context->state, 202 if (filelayout_async_handle_error(task, data->args.context->state,
218 data->ds_clp, &reset) == -EAGAIN) { 203 data->ds_clp, &reset) == -EAGAIN) {
219 struct nfs_client *clp;
220
221 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 204 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
222 __func__, data->ds_clp, data->ds_clp->cl_session); 205 __func__, data->ds_clp, data->ds_clp->cl_session);
223 if (reset) { 206 if (reset) {
224 filelayout_set_lo_fail(data->lseg); 207 pnfs_set_lo_fail(data->lseg);
225 nfs4_reset_write(task, data); 208 nfs4_reset_write(task, data);
226 clp = NFS_SERVER(data->inode)->nfs_client; 209 }
227 } else 210 rpc_restart_call_prepare(task);
228 clp = data->ds_clp;
229 nfs_restart_rpc(task, clp);
230 return -EAGAIN; 211 return -EAGAIN;
231 } 212 }
232 213
@@ -256,9 +237,9 @@ static int filelayout_commit_done_cb(struct rpc_task *task,
256 __func__, data->ds_clp, data->ds_clp->cl_session); 237 __func__, data->ds_clp, data->ds_clp->cl_session);
257 if (reset) { 238 if (reset) {
258 prepare_to_resend_writes(data); 239 prepare_to_resend_writes(data);
259 filelayout_set_lo_fail(data->lseg); 240 pnfs_set_lo_fail(data->lseg);
260 } else 241 } else
261 nfs_restart_rpc(task, data->ds_clp); 242 rpc_restart_call_prepare(task);
262 return -EAGAIN; 243 return -EAGAIN;
263 } 244 }
264 245
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4700fae1ada..d2ae413c986 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -73,9 +73,6 @@ static int _nfs4_proc_open(struct nfs4_opendata *data);
73static int _nfs4_recover_proc_open(struct nfs4_opendata *data); 73static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
74static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 74static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
75static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 75static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
76static int _nfs4_proc_lookup(struct rpc_clnt *client, struct inode *dir,
77 const struct qstr *name, struct nfs_fh *fhandle,
78 struct nfs_fattr *fattr);
79static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 76static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
80static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, 77static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
81 struct nfs_fattr *fattr, struct iattr *sattr, 78 struct nfs_fattr *fattr, struct iattr *sattr,
@@ -753,9 +750,9 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
753 750
754 spin_lock(&dir->i_lock); 751 spin_lock(&dir->i_lock);
755 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA; 752 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA;
756 if (!cinfo->atomic || cinfo->before != nfsi->change_attr) 753 if (!cinfo->atomic || cinfo->before != dir->i_version)
757 nfs_force_lookup_revalidate(dir); 754 nfs_force_lookup_revalidate(dir);
758 nfsi->change_attr = cinfo->after; 755 dir->i_version = cinfo->after;
759 spin_unlock(&dir->i_lock); 756 spin_unlock(&dir->i_lock);
760} 757}
761 758
@@ -1596,8 +1593,14 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1596 int status; 1593 int status;
1597 1594
1598 status = nfs4_run_open_task(data, 0); 1595 status = nfs4_run_open_task(data, 0);
1599 if (status != 0 || !data->rpc_done) 1596 if (!data->rpc_done)
1597 return status;
1598 if (status != 0) {
1599 if (status == -NFS4ERR_BADNAME &&
1600 !(o_arg->open_flags & O_CREAT))
1601 return -ENOENT;
1600 return status; 1602 return status;
1603 }
1601 1604
1602 if (o_arg->open_flags & O_CREAT) { 1605 if (o_arg->open_flags & O_CREAT) {
1603 update_changeattr(dir, &o_res->cinfo); 1606 update_changeattr(dir, &o_res->cinfo);
@@ -2408,14 +2411,15 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
2408 return status; 2411 return status;
2409} 2412}
2410 2413
2411static int _nfs4_proc_lookupfh(struct rpc_clnt *clnt, struct nfs_server *server, 2414static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
2412 const struct nfs_fh *dirfh, const struct qstr *name, 2415 const struct qstr *name, struct nfs_fh *fhandle,
2413 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 2416 struct nfs_fattr *fattr)
2414{ 2417{
2418 struct nfs_server *server = NFS_SERVER(dir);
2415 int status; 2419 int status;
2416 struct nfs4_lookup_arg args = { 2420 struct nfs4_lookup_arg args = {
2417 .bitmask = server->attr_bitmask, 2421 .bitmask = server->attr_bitmask,
2418 .dir_fh = dirfh, 2422 .dir_fh = NFS_FH(dir),
2419 .name = name, 2423 .name = name,
2420 }; 2424 };
2421 struct nfs4_lookup_res res = { 2425 struct nfs4_lookup_res res = {
@@ -2431,40 +2435,8 @@ static int _nfs4_proc_lookupfh(struct rpc_clnt *clnt, struct nfs_server *server,
2431 2435
2432 nfs_fattr_init(fattr); 2436 nfs_fattr_init(fattr);
2433 2437
2434 dprintk("NFS call lookupfh %s\n", name->name);
2435 status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0);
2436 dprintk("NFS reply lookupfh: %d\n", status);
2437 return status;
2438}
2439
2440static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
2441 struct qstr *name, struct nfs_fh *fhandle,
2442 struct nfs_fattr *fattr)
2443{
2444 struct nfs4_exception exception = { };
2445 int err;
2446 do {
2447 err = _nfs4_proc_lookupfh(server->client, server, dirfh, name, fhandle, fattr);
2448 /* FIXME: !!!! */
2449 if (err == -NFS4ERR_MOVED) {
2450 err = -EREMOTE;
2451 break;
2452 }
2453 err = nfs4_handle_exception(server, err, &exception);
2454 } while (exception.retry);
2455 return err;
2456}
2457
2458static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
2459 const struct qstr *name, struct nfs_fh *fhandle,
2460 struct nfs_fattr *fattr)
2461{
2462 int status;
2463
2464 dprintk("NFS call lookup %s\n", name->name); 2438 dprintk("NFS call lookup %s\n", name->name);
2465 status = _nfs4_proc_lookupfh(clnt, NFS_SERVER(dir), NFS_FH(dir), name, fhandle, fattr); 2439 status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0);
2466 if (status == -NFS4ERR_MOVED)
2467 status = nfs4_get_referral(dir, name, fattr, fhandle);
2468 dprintk("NFS reply lookup: %d\n", status); 2440 dprintk("NFS reply lookup: %d\n", status);
2469 return status; 2441 return status;
2470} 2442}
@@ -2485,11 +2457,20 @@ static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qst
2485 struct nfs4_exception exception = { }; 2457 struct nfs4_exception exception = { };
2486 int err; 2458 int err;
2487 do { 2459 do {
2488 err = nfs4_handle_exception(NFS_SERVER(dir), 2460 int status;
2489 _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr), 2461
2490 &exception); 2462 status = _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr);
2491 if (err == -EPERM) 2463 switch (status) {
2464 case -NFS4ERR_BADNAME:
2465 return -ENOENT;
2466 case -NFS4ERR_MOVED:
2467 err = nfs4_get_referral(dir, name, fattr, fhandle);
2468 break;
2469 case -NFS4ERR_WRONGSEC:
2492 nfs_fixup_secinfo_attributes(fattr, fhandle); 2470 nfs_fixup_secinfo_attributes(fattr, fhandle);
2471 }
2472 err = nfs4_handle_exception(NFS_SERVER(dir),
2473 status, &exception);
2493 } while (exception.retry); 2474 } while (exception.retry);
2494 return err; 2475 return err;
2495} 2476}
@@ -3210,7 +3191,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data)
3210 struct nfs_server *server = NFS_SERVER(data->inode); 3191 struct nfs_server *server = NFS_SERVER(data->inode);
3211 3192
3212 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3193 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
3213 nfs_restart_rpc(task, server->nfs_client); 3194 rpc_restart_call_prepare(task);
3214 return -EAGAIN; 3195 return -EAGAIN;
3215 } 3196 }
3216 3197
@@ -3260,7 +3241,7 @@ static int nfs4_write_done_cb(struct rpc_task *task, struct nfs_write_data *data
3260 struct inode *inode = data->inode; 3241 struct inode *inode = data->inode;
3261 3242
3262 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 3243 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3263 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3244 rpc_restart_call_prepare(task);
3264 return -EAGAIN; 3245 return -EAGAIN;
3265 } 3246 }
3266 if (task->tk_status >= 0) { 3247 if (task->tk_status >= 0) {
@@ -3317,7 +3298,7 @@ static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_write_data *dat
3317 struct inode *inode = data->inode; 3298 struct inode *inode = data->inode;
3318 3299
3319 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 3300 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
3320 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3301 rpc_restart_call_prepare(task);
3321 return -EAGAIN; 3302 return -EAGAIN;
3322 } 3303 }
3323 nfs_refresh_inode(inode, data->res.fattr); 3304 nfs_refresh_inode(inode, data->res.fattr);
@@ -3857,7 +3838,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
3857 default: 3838 default:
3858 if (nfs4_async_handle_error(task, data->res.server, NULL) == 3839 if (nfs4_async_handle_error(task, data->res.server, NULL) ==
3859 -EAGAIN) { 3840 -EAGAIN) {
3860 nfs_restart_rpc(task, data->res.server->nfs_client); 3841 rpc_restart_call_prepare(task);
3861 return; 3842 return;
3862 } 3843 }
3863 } 3844 }
@@ -4111,8 +4092,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
4111 break; 4092 break;
4112 default: 4093 default:
4113 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 4094 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
4114 nfs_restart_rpc(task, 4095 rpc_restart_call_prepare(task);
4115 calldata->server->nfs_client);
4116 } 4096 }
4117} 4097}
4118 4098
@@ -4945,7 +4925,7 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4945 task->tk_status = 0; 4925 task->tk_status = 0;
4946 /* fall through */ 4926 /* fall through */
4947 case -NFS4ERR_RETRY_UNCACHED_REP: 4927 case -NFS4ERR_RETRY_UNCACHED_REP:
4948 nfs_restart_rpc(task, data->clp); 4928 rpc_restart_call_prepare(task);
4949 return; 4929 return;
4950 } 4930 }
4951 dprintk("<-- %s\n", __func__); 4931 dprintk("<-- %s\n", __func__);
@@ -5786,7 +5766,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
5786 5766
5787 server = NFS_SERVER(lrp->args.inode); 5767 server = NFS_SERVER(lrp->args.inode);
5788 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { 5768 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
5789 nfs_restart_rpc(task, lrp->clp); 5769 rpc_restart_call_prepare(task);
5790 return; 5770 return;
5791 } 5771 }
5792 spin_lock(&lo->plh_inode->i_lock); 5772 spin_lock(&lo->plh_inode->i_lock);
@@ -5957,7 +5937,7 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
5957 } 5937 }
5958 5938
5959 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { 5939 if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
5960 nfs_restart_rpc(task, server->nfs_client); 5940 rpc_restart_call_prepare(task);
5961 return; 5941 return;
5962 } 5942 }
5963 5943
@@ -6270,7 +6250,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
6270 .getroot = nfs4_proc_get_root, 6250 .getroot = nfs4_proc_get_root,
6271 .getattr = nfs4_proc_getattr, 6251 .getattr = nfs4_proc_getattr,
6272 .setattr = nfs4_proc_setattr, 6252 .setattr = nfs4_proc_setattr,
6273 .lookupfh = nfs4_proc_lookupfh,
6274 .lookup = nfs4_proc_lookup, 6253 .lookup = nfs4_proc_lookup,
6275 .access = nfs4_proc_access, 6254 .access = nfs4_proc_access,
6276 .readlink = nfs4_proc_readlink, 6255 .readlink = nfs4_proc_readlink,
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index e550e8836c3..ee73d9a4f70 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1168,23 +1168,17 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);
1168/* 1168/*
1169 * Called by non rpc-based layout drivers 1169 * Called by non rpc-based layout drivers
1170 */ 1170 */
1171int 1171void pnfs_ld_write_done(struct nfs_write_data *data)
1172pnfs_ld_write_done(struct nfs_write_data *data)
1173{ 1172{
1174 int status; 1173 if (likely(!data->pnfs_error)) {
1175
1176 if (!data->pnfs_error) {
1177 pnfs_set_layoutcommit(data); 1174 pnfs_set_layoutcommit(data);
1178 data->mds_ops->rpc_call_done(&data->task, data); 1175 data->mds_ops->rpc_call_done(&data->task, data);
1179 data->mds_ops->rpc_release(data); 1176 } else {
1180 return 0; 1177 put_lseg(data->lseg);
1178 data->lseg = NULL;
1179 dprintk("pnfs write error = %d\n", data->pnfs_error);
1181 } 1180 }
1182 1181 data->mds_ops->rpc_release(data);
1183 dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__,
1184 data->pnfs_error);
1185 status = nfs_initiate_write(data, NFS_CLIENT(data->inode),
1186 data->mds_ops, NFS_FILE_SYNC);
1187 return status ? : -EAGAIN;
1188} 1182}
1189EXPORT_SYMBOL_GPL(pnfs_ld_write_done); 1183EXPORT_SYMBOL_GPL(pnfs_ld_write_done);
1190 1184
@@ -1268,23 +1262,17 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
1268/* 1262/*
1269 * Called by non rpc-based layout drivers 1263 * Called by non rpc-based layout drivers
1270 */ 1264 */
1271int 1265void pnfs_ld_read_done(struct nfs_read_data *data)
1272pnfs_ld_read_done(struct nfs_read_data *data)
1273{ 1266{
1274 int status; 1267 if (likely(!data->pnfs_error)) {
1275
1276 if (!data->pnfs_error) {
1277 __nfs4_read_done_cb(data); 1268 __nfs4_read_done_cb(data);
1278 data->mds_ops->rpc_call_done(&data->task, data); 1269 data->mds_ops->rpc_call_done(&data->task, data);
1279 data->mds_ops->rpc_release(data); 1270 } else {
1280 return 0; 1271 put_lseg(data->lseg);
1272 data->lseg = NULL;
1273 dprintk("pnfs write error = %d\n", data->pnfs_error);
1281 } 1274 }
1282 1275 data->mds_ops->rpc_release(data);
1283 dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__,
1284 data->pnfs_error);
1285 status = nfs_initiate_read(data, NFS_CLIENT(data->inode),
1286 data->mds_ops);
1287 return status ? : -EAGAIN;
1288} 1276}
1289EXPORT_SYMBOL_GPL(pnfs_ld_read_done); 1277EXPORT_SYMBOL_GPL(pnfs_ld_read_done);
1290 1278
@@ -1381,6 +1369,18 @@ static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
1381 } 1369 }
1382} 1370}
1383 1371
1372void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg)
1373{
1374 if (lseg->pls_range.iomode == IOMODE_RW) {
1375 dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
1376 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
1377 } else {
1378 dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
1379 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
1380 }
1381}
1382EXPORT_SYMBOL_GPL(pnfs_set_lo_fail);
1383
1384void 1384void
1385pnfs_set_layoutcommit(struct nfs_write_data *wdata) 1385pnfs_set_layoutcommit(struct nfs_write_data *wdata)
1386{ 1386{
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 01cbfd54f3c..1509530cb11 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -178,6 +178,7 @@ int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
178void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *); 178void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *);
179int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc); 179int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
180bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); 180bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
181void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg);
181int pnfs_layout_process(struct nfs4_layoutget *lgp); 182int pnfs_layout_process(struct nfs4_layoutget *lgp);
182void pnfs_free_lseg_list(struct list_head *tmp_list); 183void pnfs_free_lseg_list(struct list_head *tmp_list);
183void pnfs_destroy_layout(struct nfs_inode *); 184void pnfs_destroy_layout(struct nfs_inode *);
@@ -200,8 +201,8 @@ void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
200void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data); 201void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
201int pnfs_layoutcommit_inode(struct inode *inode, bool sync); 202int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
202int _pnfs_return_layout(struct inode *); 203int _pnfs_return_layout(struct inode *);
203int pnfs_ld_write_done(struct nfs_write_data *); 204void pnfs_ld_write_done(struct nfs_write_data *);
204int pnfs_ld_read_done(struct nfs_read_data *); 205void pnfs_ld_read_done(struct nfs_read_data *);
205struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino, 206struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
206 struct nfs_open_context *ctx, 207 struct nfs_open_context *ctx,
207 loff_t pos, 208 loff_t pos,
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 2171c043ab0..8b48ec63f72 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -35,16 +35,13 @@ static const struct rpc_call_ops nfs_read_partial_ops;
35static const struct rpc_call_ops nfs_read_full_ops; 35static const struct rpc_call_ops nfs_read_full_ops;
36 36
37static struct kmem_cache *nfs_rdata_cachep; 37static struct kmem_cache *nfs_rdata_cachep;
38static mempool_t *nfs_rdata_mempool;
39
40#define MIN_POOL_READ (32)
41 38
42struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) 39struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
43{ 40{
44 struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_KERNEL); 41 struct nfs_read_data *p;
45 42
43 p = kmem_cache_zalloc(nfs_rdata_cachep, GFP_KERNEL);
46 if (p) { 44 if (p) {
47 memset(p, 0, sizeof(*p));
48 INIT_LIST_HEAD(&p->pages); 45 INIT_LIST_HEAD(&p->pages);
49 p->npages = pagecount; 46 p->npages = pagecount;
50 if (pagecount <= ARRAY_SIZE(p->page_array)) 47 if (pagecount <= ARRAY_SIZE(p->page_array))
@@ -52,7 +49,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
52 else { 49 else {
53 p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL); 50 p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
54 if (!p->pagevec) { 51 if (!p->pagevec) {
55 mempool_free(p, nfs_rdata_mempool); 52 kmem_cache_free(nfs_rdata_cachep, p);
56 p = NULL; 53 p = NULL;
57 } 54 }
58 } 55 }
@@ -64,7 +61,7 @@ void nfs_readdata_free(struct nfs_read_data *p)
64{ 61{
65 if (p && (p->pagevec != &p->page_array[0])) 62 if (p && (p->pagevec != &p->page_array[0]))
66 kfree(p->pagevec); 63 kfree(p->pagevec);
67 mempool_free(p, nfs_rdata_mempool); 64 kmem_cache_free(nfs_rdata_cachep, p);
68} 65}
69 66
70void nfs_readdata_release(struct nfs_read_data *rdata) 67void nfs_readdata_release(struct nfs_read_data *rdata)
@@ -276,7 +273,6 @@ nfs_async_read_error(struct list_head *head)
276 while (!list_empty(head)) { 273 while (!list_empty(head)) {
277 req = nfs_list_entry(head->next); 274 req = nfs_list_entry(head->next);
278 nfs_list_remove_request(req); 275 nfs_list_remove_request(req);
279 SetPageError(req->wb_page);
280 nfs_readpage_release(req); 276 nfs_readpage_release(req);
281 } 277 }
282} 278}
@@ -322,7 +318,6 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc, struct list_head
322 offset += len; 318 offset += len;
323 } while(nbytes != 0); 319 } while(nbytes != 0);
324 atomic_set(&req->wb_complete, requests); 320 atomic_set(&req->wb_complete, requests);
325 ClearPageError(page);
326 desc->pg_rpc_callops = &nfs_read_partial_ops; 321 desc->pg_rpc_callops = &nfs_read_partial_ops;
327 return ret; 322 return ret;
328out_bad: 323out_bad:
@@ -331,7 +326,6 @@ out_bad:
331 list_del(&data->list); 326 list_del(&data->list);
332 nfs_readdata_free(data); 327 nfs_readdata_free(data);
333 } 328 }
334 SetPageError(page);
335 nfs_readpage_release(req); 329 nfs_readpage_release(req);
336 return -ENOMEM; 330 return -ENOMEM;
337} 331}
@@ -357,7 +351,6 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc, struct list_head *
357 req = nfs_list_entry(head->next); 351 req = nfs_list_entry(head->next);
358 nfs_list_remove_request(req); 352 nfs_list_remove_request(req);
359 nfs_list_add_request(req, &data->pages); 353 nfs_list_add_request(req, &data->pages);
360 ClearPageError(req->wb_page);
361 *pages++ = req->wb_page; 354 *pages++ = req->wb_page;
362 } 355 }
363 req = nfs_list_entry(data->pages.next); 356 req = nfs_list_entry(data->pages.next);
@@ -435,7 +428,7 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
435 argp->offset += resp->count; 428 argp->offset += resp->count;
436 argp->pgbase += resp->count; 429 argp->pgbase += resp->count;
437 argp->count -= resp->count; 430 argp->count -= resp->count;
438 nfs_restart_rpc(task, NFS_SERVER(data->inode)->nfs_client); 431 rpc_restart_call_prepare(task);
439} 432}
440 433
441/* 434/*
@@ -462,10 +455,10 @@ static void nfs_readpage_release_partial(void *calldata)
462 int status = data->task.tk_status; 455 int status = data->task.tk_status;
463 456
464 if (status < 0) 457 if (status < 0)
465 SetPageError(page); 458 set_bit(PG_PARTIAL_READ_FAILED, &req->wb_flags);
466 459
467 if (atomic_dec_and_test(&req->wb_complete)) { 460 if (atomic_dec_and_test(&req->wb_complete)) {
468 if (!PageError(page)) 461 if (!test_bit(PG_PARTIAL_READ_FAILED, &req->wb_flags))
469 SetPageUptodate(page); 462 SetPageUptodate(page);
470 nfs_readpage_release(req); 463 nfs_readpage_release(req);
471 } 464 }
@@ -541,13 +534,23 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata)
541static void nfs_readpage_release_full(void *calldata) 534static void nfs_readpage_release_full(void *calldata)
542{ 535{
543 struct nfs_read_data *data = calldata; 536 struct nfs_read_data *data = calldata;
537 struct nfs_pageio_descriptor pgio;
544 538
539 if (data->pnfs_error) {
540 nfs_pageio_init_read_mds(&pgio, data->inode);
541 pgio.pg_recoalesce = 1;
542 }
545 while (!list_empty(&data->pages)) { 543 while (!list_empty(&data->pages)) {
546 struct nfs_page *req = nfs_list_entry(data->pages.next); 544 struct nfs_page *req = nfs_list_entry(data->pages.next);
547 545
548 nfs_list_remove_request(req); 546 nfs_list_remove_request(req);
549 nfs_readpage_release(req); 547 if (!data->pnfs_error)
548 nfs_readpage_release(req);
549 else
550 nfs_pageio_add_request(&pgio, req);
550 } 551 }
552 if (data->pnfs_error)
553 nfs_pageio_complete(&pgio);
551 nfs_readdata_release(calldata); 554 nfs_readdata_release(calldata);
552} 555}
553 556
@@ -648,7 +651,6 @@ readpage_async_filler(void *data, struct page *page)
648 return 0; 651 return 0;
649out_error: 652out_error:
650 error = PTR_ERR(new); 653 error = PTR_ERR(new);
651 SetPageError(page);
652out_unlock: 654out_unlock:
653 unlock_page(page); 655 unlock_page(page);
654 return error; 656 return error;
@@ -711,16 +713,10 @@ int __init nfs_init_readpagecache(void)
711 if (nfs_rdata_cachep == NULL) 713 if (nfs_rdata_cachep == NULL)
712 return -ENOMEM; 714 return -ENOMEM;
713 715
714 nfs_rdata_mempool = mempool_create_slab_pool(MIN_POOL_READ,
715 nfs_rdata_cachep);
716 if (nfs_rdata_mempool == NULL)
717 return -ENOMEM;
718
719 return 0; 716 return 0;
720} 717}
721 718
722void nfs_destroy_readpagecache(void) 719void nfs_destroy_readpagecache(void)
723{ 720{
724 mempool_destroy(nfs_rdata_mempool);
725 kmem_cache_destroy(nfs_rdata_cachep); 721 kmem_cache_destroy(nfs_rdata_cachep);
726} 722}
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 5b19b6aabe1..480b3b6bf71 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -733,18 +733,22 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
733 733
734 return 0; 734 return 0;
735} 735}
736
737#ifdef CONFIG_NFS_V4
736#ifdef CONFIG_NFS_V4_1 738#ifdef CONFIG_NFS_V4_1
737void show_sessions(struct seq_file *m, struct nfs_server *server) 739static void show_sessions(struct seq_file *m, struct nfs_server *server)
738{ 740{
739 if (nfs4_has_session(server->nfs_client)) 741 if (nfs4_has_session(server->nfs_client))
740 seq_printf(m, ",sessions"); 742 seq_printf(m, ",sessions");
741} 743}
742#else 744#else
743void show_sessions(struct seq_file *m, struct nfs_server *server) {} 745static void show_sessions(struct seq_file *m, struct nfs_server *server) {}
746#endif
744#endif 747#endif
745 748
749#ifdef CONFIG_NFS_V4
746#ifdef CONFIG_NFS_V4_1 750#ifdef CONFIG_NFS_V4_1
747void show_pnfs(struct seq_file *m, struct nfs_server *server) 751static void show_pnfs(struct seq_file *m, struct nfs_server *server)
748{ 752{
749 seq_printf(m, ",pnfs="); 753 seq_printf(m, ",pnfs=");
750 if (server->pnfs_curr_ld) 754 if (server->pnfs_curr_ld)
@@ -752,9 +756,10 @@ void show_pnfs(struct seq_file *m, struct nfs_server *server)
752 else 756 else
753 seq_printf(m, "not configured"); 757 seq_printf(m, "not configured");
754} 758}
755#else /* CONFIG_NFS_V4_1 */ 759#else
756void show_pnfs(struct seq_file *m, struct nfs_server *server) {} 760static void show_pnfs(struct seq_file *m, struct nfs_server *server) {}
757#endif /* CONFIG_NFS_V4_1 */ 761#endif
762#endif
758 763
759static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) 764static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt)
760{ 765{
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index b2fbbde58e4..4f9319a2e56 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -87,7 +87,7 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
87 struct inode *dir = data->dir; 87 struct inode *dir = data->dir;
88 88
89 if (!NFS_PROTO(dir)->unlink_done(task, dir)) 89 if (!NFS_PROTO(dir)->unlink_done(task, dir))
90 nfs_restart_rpc(task, NFS_SERVER(dir)->nfs_client); 90 rpc_restart_call_prepare(task);
91} 91}
92 92
93/** 93/**
@@ -369,7 +369,7 @@ static void nfs_async_rename_done(struct rpc_task *task, void *calldata)
369 struct dentry *new_dentry = data->new_dentry; 369 struct dentry *new_dentry = data->new_dentry;
370 370
371 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) { 371 if (!NFS_PROTO(old_dir)->rename_done(task, old_dir, new_dir)) {
372 nfs_restart_rpc(task, NFS_SERVER(old_dir)->nfs_client); 372 rpc_restart_call_prepare(task);
373 return; 373 return;
374 } 374 }
375 375
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index c9bd2a6b7d4..2219c88d96b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -390,7 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
390 error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); 390 error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req);
391 BUG_ON(error); 391 BUG_ON(error);
392 if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE)) 392 if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE))
393 nfsi->change_attr++; 393 inode->i_version++;
394 set_bit(PG_MAPPED, &req->wb_flags); 394 set_bit(PG_MAPPED, &req->wb_flags);
395 SetPagePrivate(req->wb_page); 395 SetPagePrivate(req->wb_page);
396 set_page_private(req->wb_page, (unsigned long)req); 396 set_page_private(req->wb_page, (unsigned long)req);
@@ -428,7 +428,6 @@ static void
428nfs_mark_request_dirty(struct nfs_page *req) 428nfs_mark_request_dirty(struct nfs_page *req)
429{ 429{
430 __set_page_dirty_nobuffers(req->wb_page); 430 __set_page_dirty_nobuffers(req->wb_page);
431 __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC);
432} 431}
433 432
434#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 433#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -762,6 +761,8 @@ int nfs_updatepage(struct file *file, struct page *page,
762 status = nfs_writepage_setup(ctx, page, offset, count); 761 status = nfs_writepage_setup(ctx, page, offset, count);
763 if (status < 0) 762 if (status < 0)
764 nfs_set_pageerror(page); 763 nfs_set_pageerror(page);
764 else
765 __set_page_dirty_nobuffers(page);
765 766
766 dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", 767 dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n",
767 status, (long long)i_size_read(inode)); 768 status, (long long)i_size_read(inode));
@@ -1010,7 +1011,6 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc, struct list_head *r
1010 req = nfs_list_entry(head->next); 1011 req = nfs_list_entry(head->next);
1011 nfs_list_remove_request(req); 1012 nfs_list_remove_request(req);
1012 nfs_list_add_request(req, &data->pages); 1013 nfs_list_add_request(req, &data->pages);
1013 ClearPageError(req->wb_page);
1014 *pages++ = req->wb_page; 1014 *pages++ = req->wb_page;
1015 } 1015 }
1016 req = nfs_list_entry(data->pages.next); 1016 req = nfs_list_entry(data->pages.next);
@@ -1165,7 +1165,13 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1165static void nfs_writeback_release_full(void *calldata) 1165static void nfs_writeback_release_full(void *calldata)
1166{ 1166{
1167 struct nfs_write_data *data = calldata; 1167 struct nfs_write_data *data = calldata;
1168 int status = data->task.tk_status; 1168 int ret, status = data->task.tk_status;
1169 struct nfs_pageio_descriptor pgio;
1170
1171 if (data->pnfs_error) {
1172 nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE);
1173 pgio.pg_recoalesce = 1;
1174 }
1169 1175
1170 /* Update attributes as result of writeback. */ 1176 /* Update attributes as result of writeback. */
1171 while (!list_empty(&data->pages)) { 1177 while (!list_empty(&data->pages)) {
@@ -1181,6 +1187,11 @@ static void nfs_writeback_release_full(void *calldata)
1181 req->wb_bytes, 1187 req->wb_bytes,
1182 (long long)req_offset(req)); 1188 (long long)req_offset(req));
1183 1189
1190 if (data->pnfs_error) {
1191 dprintk(", pnfs error = %d\n", data->pnfs_error);
1192 goto next;
1193 }
1194
1184 if (status < 0) { 1195 if (status < 0) {
1185 nfs_set_pageerror(page); 1196 nfs_set_pageerror(page);
1186 nfs_context_set_write_error(req->wb_context, status); 1197 nfs_context_set_write_error(req->wb_context, status);
@@ -1200,7 +1211,19 @@ remove_request:
1200 next: 1211 next:
1201 nfs_clear_page_tag_locked(req); 1212 nfs_clear_page_tag_locked(req);
1202 nfs_end_page_writeback(page); 1213 nfs_end_page_writeback(page);
1214 if (data->pnfs_error) {
1215 lock_page(page);
1216 nfs_pageio_cond_complete(&pgio, page->index);
1217 ret = nfs_page_async_flush(&pgio, page, 0);
1218 if (ret) {
1219 nfs_set_pageerror(page);
1220 dprintk("rewrite to MDS error = %d\n", ret);
1221 }
1222 unlock_page(page);
1223 }
1203 } 1224 }
1225 if (data->pnfs_error)
1226 nfs_pageio_complete(&pgio);
1204 nfs_writedata_release(calldata); 1227 nfs_writedata_release(calldata);
1205} 1228}
1206 1229
@@ -1281,7 +1304,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1281 */ 1304 */
1282 argp->stable = NFS_FILE_SYNC; 1305 argp->stable = NFS_FILE_SYNC;
1283 } 1306 }
1284 nfs_restart_rpc(task, server->nfs_client); 1307 rpc_restart_call_prepare(task);
1285 return; 1308 return;
1286 } 1309 }
1287 if (time_before(complain, jiffies)) { 1310 if (time_before(complain, jiffies)) {
@@ -1553,6 +1576,10 @@ static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_contr
1553 int flags = FLUSH_SYNC; 1576 int flags = FLUSH_SYNC;
1554 int ret = 0; 1577 int ret = 0;
1555 1578
1579 /* no commits means nothing needs to be done */
1580 if (!nfsi->ncommit)
1581 return ret;
1582
1556 if (wbc->sync_mode == WB_SYNC_NONE) { 1583 if (wbc->sync_mode == WB_SYNC_NONE) {
1557 /* Don't commit yet if this is a non-blocking flush and there 1584 /* Don't commit yet if this is a non-blocking flush and there
1558 * are a lot of outstanding writes for this mapping. 1585 * are a lot of outstanding writes for this mapping.
@@ -1686,34 +1713,20 @@ out_error:
1686int nfs_migrate_page(struct address_space *mapping, struct page *newpage, 1713int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
1687 struct page *page) 1714 struct page *page)
1688{ 1715{
1689 struct nfs_page *req; 1716 /*
1690 int ret; 1717 * If PagePrivate is set, then the page is currently associated with
1718 * an in-progress read or write request. Don't try to migrate it.
1719 *
1720 * FIXME: we could do this in principle, but we'll need a way to ensure
1721 * that we can safely release the inode reference while holding
1722 * the page lock.
1723 */
1724 if (PagePrivate(page))
1725 return -EBUSY;
1691 1726
1692 nfs_fscache_release_page(page, GFP_KERNEL); 1727 nfs_fscache_release_page(page, GFP_KERNEL);
1693 1728
1694 req = nfs_find_and_lock_request(page, false); 1729 return migrate_page(mapping, newpage, page);
1695 ret = PTR_ERR(req);
1696 if (IS_ERR(req))
1697 goto out;
1698
1699 ret = migrate_page(mapping, newpage, page);
1700 if (!req)
1701 goto out;
1702 if (ret)
1703 goto out_unlock;
1704 page_cache_get(newpage);
1705 spin_lock(&mapping->host->i_lock);
1706 req->wb_page = newpage;
1707 SetPagePrivate(newpage);
1708 set_page_private(newpage, (unsigned long)req);
1709 ClearPagePrivate(page);
1710 set_page_private(page, 0);
1711 spin_unlock(&mapping->host->i_lock);
1712 page_cache_release(page);
1713out_unlock:
1714 nfs_clear_page_tag_locked(req);
1715out:
1716 return ret;
1717} 1730}
1718#endif 1731#endif
1719 1732