aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/lockd/clntproc.c9
-rw-r--r--fs/lockd/svclock.c4
-rw-r--r--fs/nfs/client.c18
-rw-r--r--fs/nfs/dir.c37
-rw-r--r--fs/nfs/direct.c8
-rw-r--r--fs/nfs/getroot.c11
-rw-r--r--fs/nfs/inode.c50
-rw-r--r--fs/nfs/internal.h4
-rw-r--r--fs/nfs/nfs3proc.c24
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4namespace.c16
-rw-r--r--fs/nfs/nfs4proc.c60
-rw-r--r--fs/nfs/nfs4xdr.c2
-rw-r--r--fs/nfs/proc.c30
-rw-r--r--fs/nfs/read.c109
-rw-r--r--fs/nfs/super.c2
-rw-r--r--fs/nfs/write.c91
17 files changed, 134 insertions, 343 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 0b4acc1c5e7d..a5c019e1a447 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -361,7 +361,6 @@ static int __nlm_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *
361{ 361{
362 struct nlm_host *host = req->a_host; 362 struct nlm_host *host = req->a_host;
363 struct rpc_clnt *clnt; 363 struct rpc_clnt *clnt;
364 int status = -ENOLCK;
365 364
366 dprintk("lockd: call procedure %d on %s (async)\n", 365 dprintk("lockd: call procedure %d on %s (async)\n",
367 (int)proc, host->h_name); 366 (int)proc, host->h_name);
@@ -373,12 +372,10 @@ static int __nlm_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *
373 msg->rpc_proc = &clnt->cl_procinfo[proc]; 372 msg->rpc_proc = &clnt->cl_procinfo[proc];
374 373
375 /* bootstrap and kick off the async RPC call */ 374 /* bootstrap and kick off the async RPC call */
376 status = rpc_call_async(clnt, msg, RPC_TASK_ASYNC, tk_ops, req); 375 return rpc_call_async(clnt, msg, RPC_TASK_ASYNC, tk_ops, req);
377 if (status == 0)
378 return 0;
379out_err: 376out_err:
380 nlm_release_call(req); 377 tk_ops->rpc_release(req);
381 return status; 378 return -ENOLCK;
382} 379}
383 380
384int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops) 381int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index c7db0a5bccdc..cf51f849e76c 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -593,9 +593,7 @@ callback:
593 593
594 /* Call the client */ 594 /* Call the client */
595 kref_get(&block->b_count); 595 kref_get(&block->b_count);
596 if (nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, 596 nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, &nlmsvc_grant_ops);
597 &nlmsvc_grant_ops) < 0)
598 nlmsvc_release_block(block);
599} 597}
600 598
601/* 599/*
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ae9f36e393cf..2190e6c2792e 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -394,7 +394,8 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
394static int nfs_create_rpc_client(struct nfs_client *clp, int proto, 394static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
395 unsigned int timeo, 395 unsigned int timeo,
396 unsigned int retrans, 396 unsigned int retrans,
397 rpc_authflavor_t flavor) 397 rpc_authflavor_t flavor,
398 int flags)
398{ 399{
399 struct rpc_timeout timeparms; 400 struct rpc_timeout timeparms;
400 struct rpc_clnt *clnt = NULL; 401 struct rpc_clnt *clnt = NULL;
@@ -407,6 +408,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
407 .program = &nfs_program, 408 .program = &nfs_program,
408 .version = clp->rpc_ops->version, 409 .version = clp->rpc_ops->version,
409 .authflavor = flavor, 410 .authflavor = flavor,
411 .flags = flags,
410 }; 412 };
411 413
412 if (!IS_ERR(clp->cl_rpcclient)) 414 if (!IS_ERR(clp->cl_rpcclient))
@@ -548,7 +550,7 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *
548 * - RFC 2623, sec 2.3.2 550 * - RFC 2623, sec 2.3.2
549 */ 551 */
550 error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans, 552 error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans,
551 RPC_AUTH_UNIX); 553 RPC_AUTH_UNIX, 0);
552 if (error < 0) 554 if (error < 0)
553 goto error; 555 goto error;
554 nfs_mark_client_ready(clp, NFS_CS_READY); 556 nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -868,7 +870,8 @@ static int nfs4_init_client(struct nfs_client *clp,
868 /* Check NFS protocol revision and initialize RPC op vector */ 870 /* Check NFS protocol revision and initialize RPC op vector */
869 clp->rpc_ops = &nfs_v4_clientops; 871 clp->rpc_ops = &nfs_v4_clientops;
870 872
871 error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour); 873 error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour,
874 RPC_CLNT_CREATE_DISCRTRY);
872 if (error < 0) 875 if (error < 0)
873 goto error; 876 goto error;
874 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); 877 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
@@ -1030,7 +1033,7 @@ error:
1030 * Create an NFS4 referral server record 1033 * Create an NFS4 referral server record
1031 */ 1034 */
1032struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, 1035struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1033 struct nfs_fh *fh) 1036 struct nfs_fh *mntfh)
1034{ 1037{
1035 struct nfs_client *parent_client; 1038 struct nfs_client *parent_client;
1036 struct nfs_server *server, *parent_server; 1039 struct nfs_server *server, *parent_server;
@@ -1069,8 +1072,13 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1069 BUG_ON(!server->nfs_client->rpc_ops); 1072 BUG_ON(!server->nfs_client->rpc_ops);
1070 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1073 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1071 1074
1075 /* Probe the root fh to retrieve its FSID and filehandle */
1076 error = nfs4_path_walk(server, mntfh, data->mnt_path);
1077 if (error < 0)
1078 goto error;
1079
1072 /* probe the filesystem info for this server filesystem */ 1080 /* probe the filesystem info for this server filesystem */
1073 error = nfs_probe_fsinfo(server, fh, &fattr); 1081 error = nfs_probe_fsinfo(server, mntfh, &fattr);
1074 if (error < 0) 1082 if (error < 0)
1075 goto error; 1083 goto error;
1076 1084
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f03a770bacb0..92d8ec859e22 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -637,7 +637,7 @@ int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
637 * In the case it has, we assume that the dentries are untrustworthy 637 * In the case it has, we assume that the dentries are untrustworthy
638 * and may need to be looked up again. 638 * and may need to be looked up again.
639 */ 639 */
640static inline int nfs_check_verifier(struct inode *dir, struct dentry *dentry) 640static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
641{ 641{
642 if (IS_ROOT(dentry)) 642 if (IS_ROOT(dentry))
643 return 1; 643 return 1;
@@ -652,6 +652,12 @@ static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
652 dentry->d_fsdata = (void *)verf; 652 dentry->d_fsdata = (void *)verf;
653} 653}
654 654
655static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf)
656{
657 if (time_after(verf, (unsigned long)dentry->d_fsdata))
658 nfs_set_verifier(dentry, verf);
659}
660
655/* 661/*
656 * Whenever an NFS operation succeeds, we know that the dentry 662 * Whenever an NFS operation succeeds, we know that the dentry
657 * is valid, so we update the revalidation timestamp. 663 * is valid, so we update the revalidation timestamp.
@@ -785,7 +791,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
785 goto out_bad; 791 goto out_bad;
786 792
787 nfs_renew_times(dentry); 793 nfs_renew_times(dentry);
788 nfs_set_verifier(dentry, verifier); 794 nfs_refresh_verifier(dentry, verifier);
789 out_valid: 795 out_valid:
790 unlock_kernel(); 796 unlock_kernel();
791 dput(parent); 797 dput(parent);
@@ -1085,7 +1091,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1085 verifier = nfs_save_change_attribute(dir); 1091 verifier = nfs_save_change_attribute(dir);
1086 ret = nfs4_open_revalidate(dir, dentry, openflags, nd); 1092 ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
1087 if (!ret) 1093 if (!ret)
1088 nfs_set_verifier(dentry, verifier); 1094 nfs_refresh_verifier(dentry, verifier);
1089 unlock_kernel(); 1095 unlock_kernel();
1090out: 1096out:
1091 dput(parent); 1097 dput(parent);
@@ -1123,8 +1129,21 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
1123 } 1129 }
1124 name.hash = full_name_hash(name.name, name.len); 1130 name.hash = full_name_hash(name.name, name.len);
1125 dentry = d_lookup(parent, &name); 1131 dentry = d_lookup(parent, &name);
1126 if (dentry != NULL) 1132 if (dentry != NULL) {
1127 return dentry; 1133 /* Is this a positive dentry that matches the readdir info? */
1134 if (dentry->d_inode != NULL &&
1135 (NFS_FILEID(dentry->d_inode) == entry->ino ||
1136 d_mountpoint(dentry))) {
1137 if (!desc->plus || entry->fh->size == 0)
1138 return dentry;
1139 if (nfs_compare_fh(NFS_FH(dentry->d_inode),
1140 entry->fh) == 0)
1141 goto out_renew;
1142 }
1143 /* No, so d_drop to allow one to be created */
1144 d_drop(dentry);
1145 dput(dentry);
1146 }
1128 if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) 1147 if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR))
1129 return NULL; 1148 return NULL;
1130 /* Note: caller is already holding the dir->i_mutex! */ 1149 /* Note: caller is already holding the dir->i_mutex! */
@@ -1149,6 +1168,10 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
1149 nfs_renew_times(dentry); 1168 nfs_renew_times(dentry);
1150 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1169 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1151 return dentry; 1170 return dentry;
1171out_renew:
1172 nfs_renew_times(dentry);
1173 nfs_refresh_verifier(dentry, nfs_save_change_attribute(dir));
1174 return dentry;
1152} 1175}
1153 1176
1154/* 1177/*
@@ -1443,6 +1466,8 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
1443 if (atomic_read(&dentry->d_count) > 1) { 1466 if (atomic_read(&dentry->d_count) > 1) {
1444 spin_unlock(&dentry->d_lock); 1467 spin_unlock(&dentry->d_lock);
1445 spin_unlock(&dcache_lock); 1468 spin_unlock(&dcache_lock);
1469 /* Start asynchronous writeout of the inode */
1470 write_inode_now(dentry->d_inode, 0);
1446 error = nfs_sillyrename(dir, dentry); 1471 error = nfs_sillyrename(dir, dentry);
1447 unlock_kernel(); 1472 unlock_kernel();
1448 return error; 1473 return error;
@@ -1684,7 +1709,7 @@ out:
1684 if (!error) { 1709 if (!error) {
1685 d_move(old_dentry, new_dentry); 1710 d_move(old_dentry, new_dentry);
1686 nfs_renew_times(new_dentry); 1711 nfs_renew_times(new_dentry);
1687 nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir)); 1712 nfs_refresh_verifier(new_dentry, nfs_save_change_attribute(new_dir));
1688 } 1713 }
1689 1714
1690 /* new dentry created? */ 1715 /* new dentry created? */
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index bd21d7fde650..b1c98ea39b72 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -309,7 +309,8 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
309 309
310 rpc_execute(&data->task); 310 rpc_execute(&data->task);
311 311
312 dfprintk(VFS, "NFS: %5u initiated direct read call (req %s/%Ld, %zu bytes @ offset %Lu)\n", 312 dprintk("NFS: %5u initiated direct read call "
313 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
313 data->task.tk_pid, 314 data->task.tk_pid,
314 inode->i_sb->s_id, 315 inode->i_sb->s_id,
315 (long long)NFS_FILEID(inode), 316 (long long)NFS_FILEID(inode),
@@ -639,7 +640,8 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
639 640
640 rpc_execute(&data->task); 641 rpc_execute(&data->task);
641 642
642 dfprintk(VFS, "NFS: %5u initiated direct write call (req %s/%Ld, %zu bytes @ offset %Lu)\n", 643 dprintk("NFS: %5u initiated direct write call "
644 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
643 data->task.tk_pid, 645 data->task.tk_pid,
644 inode->i_sb->s_id, 646 inode->i_sb->s_id,
645 (long long)NFS_FILEID(inode), 647 (long long)NFS_FILEID(inode),
@@ -797,7 +799,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
797 const char __user *buf = iov[0].iov_base; 799 const char __user *buf = iov[0].iov_base;
798 size_t count = iov[0].iov_len; 800 size_t count = iov[0].iov_len;
799 801
800 dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", 802 dprintk("nfs: direct write(%s/%s, %lu@%Ld)\n",
801 file->f_path.dentry->d_parent->d_name.name, 803 file->f_path.dentry->d_parent->d_name.name,
802 file->f_path.dentry->d_name.name, 804 file->f_path.dentry->d_name.name,
803 (unsigned long) count, (long long) pos); 805 (unsigned long) count, (long long) pos);
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 8391bd7a83ce..6ef268f7c300 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -135,17 +135,15 @@ int nfs4_path_walk(struct nfs_server *server,
135 struct nfs_fh lastfh; 135 struct nfs_fh lastfh;
136 struct qstr name; 136 struct qstr name;
137 int ret; 137 int ret;
138 //int referral_count = 0;
139 138
140 dprintk("--> nfs4_path_walk(,,%s)\n", path); 139 dprintk("--> nfs4_path_walk(,,%s)\n", path);
141 140
142 fsinfo.fattr = &fattr; 141 fsinfo.fattr = &fattr;
143 nfs_fattr_init(&fattr); 142 nfs_fattr_init(&fattr);
144 143
145 if (*path++ != '/') { 144 /* Eat leading slashes */
146 dprintk("nfs4_get_root: Path does not begin with a slash\n"); 145 while (*path == '/')
147 return -EINVAL; 146 path++;
148 }
149 147
150 /* Start by getting the root filehandle from the server */ 148 /* Start by getting the root filehandle from the server */
151 ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo); 149 ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
@@ -160,6 +158,7 @@ int nfs4_path_walk(struct nfs_server *server,
160 return -ENOTDIR; 158 return -ENOTDIR;
161 } 159 }
162 160
161 /* FIXME: It is quite valid for the server to return a referral here */
163 if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { 162 if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
164 printk(KERN_ERR "nfs4_get_root:" 163 printk(KERN_ERR "nfs4_get_root:"
165 " getroot obtained referral\n"); 164 " getroot obtained referral\n");
@@ -187,6 +186,7 @@ eat_dot_dir:
187 goto eat_dot_dir; 186 goto eat_dot_dir;
188 } 187 }
189 188
189 /* FIXME: Why shouldn't the user be able to use ".." in the path? */
190 if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2]) 190 if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2])
191 ) { 191 ) {
192 printk(KERN_ERR "nfs4_get_root:" 192 printk(KERN_ERR "nfs4_get_root:"
@@ -212,6 +212,7 @@ eat_dot_dir:
212 return -ENOTDIR; 212 return -ENOTDIR;
213 } 213 }
214 214
215 /* FIXME: Referrals are quite valid here too */
215 if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) { 216 if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
216 printk(KERN_ERR "nfs4_get_root:" 217 printk(KERN_ERR "nfs4_get_root:"
217 " lookupfh obtained referral\n"); 218 " lookupfh obtained referral\n");
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index d83498282837..af53c02f473b 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -65,13 +65,18 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
65 65
66int nfs_write_inode(struct inode *inode, int sync) 66int nfs_write_inode(struct inode *inode, int sync)
67{ 67{
68 int flags = sync ? FLUSH_SYNC : 0;
69 int ret; 68 int ret;
70 69
71 ret = nfs_commit_inode(inode, flags); 70 if (sync) {
72 if (ret < 0) 71 ret = filemap_fdatawait(inode->i_mapping);
73 return ret; 72 if (ret == 0)
74 return 0; 73 ret = nfs_commit_inode(inode, FLUSH_SYNC);
74 } else
75 ret = nfs_commit_inode(inode, 0);
76 if (ret >= 0)
77 return 0;
78 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
79 return ret;
75} 80}
76 81
77void nfs_clear_inode(struct inode *inode) 82void nfs_clear_inode(struct inode *inode)
@@ -235,6 +240,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
235 240
236 if (inode->i_state & I_NEW) { 241 if (inode->i_state & I_NEW) {
237 struct nfs_inode *nfsi = NFS_I(inode); 242 struct nfs_inode *nfsi = NFS_I(inode);
243 unsigned long now = jiffies;
238 244
239 /* We set i_ino for the few things that still rely on it, 245 /* We set i_ino for the few things that still rely on it,
240 * such as stat(2) */ 246 * such as stat(2) */
@@ -271,7 +277,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
271 init_special_inode(inode, inode->i_mode, fattr->rdev); 277 init_special_inode(inode, inode->i_mode, fattr->rdev);
272 278
273 nfsi->read_cache_jiffies = fattr->time_start; 279 nfsi->read_cache_jiffies = fattr->time_start;
274 nfsi->last_updated = jiffies; 280 nfsi->last_updated = now;
281 nfsi->cache_change_attribute = now;
275 inode->i_atime = fattr->atime; 282 inode->i_atime = fattr->atime;
276 inode->i_mtime = fattr->mtime; 283 inode->i_mtime = fattr->mtime;
277 inode->i_ctime = fattr->ctime; 284 inode->i_ctime = fattr->ctime;
@@ -290,7 +297,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
290 inode->i_blocks = fattr->du.nfs2.blocks; 297 inode->i_blocks = fattr->du.nfs2.blocks;
291 } 298 }
292 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 299 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
293 nfsi->attrtimeo_timestamp = jiffies; 300 nfsi->attrtimeo_timestamp = now;
294 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); 301 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
295 nfsi->access_cache = RB_ROOT; 302 nfsi->access_cache = RB_ROOT;
296 303
@@ -783,20 +790,21 @@ void nfs_end_data_update(struct inode *inode)
783static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) 790static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
784{ 791{
785 struct nfs_inode *nfsi = NFS_I(inode); 792 struct nfs_inode *nfsi = NFS_I(inode);
793 unsigned long now = jiffies;
786 794
787 /* If we have atomic WCC data, we may update some attributes */ 795 /* If we have atomic WCC data, we may update some attributes */
788 if ((fattr->valid & NFS_ATTR_WCC) != 0) { 796 if ((fattr->valid & NFS_ATTR_WCC) != 0) {
789 if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) { 797 if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
790 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 798 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
791 nfsi->cache_change_attribute = jiffies; 799 nfsi->cache_change_attribute = now;
792 } 800 }
793 if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { 801 if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
794 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 802 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
795 nfsi->cache_change_attribute = jiffies; 803 nfsi->cache_change_attribute = now;
796 } 804 }
797 if (inode->i_size == fattr->pre_size && nfsi->npages == 0) { 805 if (inode->i_size == fattr->pre_size && nfsi->npages == 0) {
798 inode->i_size = fattr->size; 806 inode->i_size = fattr->size;
799 nfsi->cache_change_attribute = jiffies; 807 nfsi->cache_change_attribute = now;
800 } 808 }
801 } 809 }
802} 810}
@@ -934,6 +942,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
934 struct nfs_inode *nfsi = NFS_I(inode); 942 struct nfs_inode *nfsi = NFS_I(inode);
935 loff_t cur_isize, new_isize; 943 loff_t cur_isize, new_isize;
936 unsigned int invalid = 0; 944 unsigned int invalid = 0;
945 unsigned long now = jiffies;
937 int data_stable; 946 int data_stable;
938 947
939 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", 948 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
@@ -959,7 +968,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
959 * Update the read time so we don't revalidate too often. 968 * Update the read time so we don't revalidate too often.
960 */ 969 */
961 nfsi->read_cache_jiffies = fattr->time_start; 970 nfsi->read_cache_jiffies = fattr->time_start;
962 nfsi->last_updated = jiffies; 971 nfsi->last_updated = now;
972
973 /* Fix a wraparound issue with nfsi->cache_change_attribute */
974 if (time_before(now, nfsi->cache_change_attribute))
975 nfsi->cache_change_attribute = now - 600*HZ;
963 976
964 /* Are we racing with known updates of the metadata on the server? */ 977 /* Are we racing with known updates of the metadata on the server? */
965 data_stable = nfs_verify_change_attribute(inode, fattr->time_start); 978 data_stable = nfs_verify_change_attribute(inode, fattr->time_start);
@@ -985,7 +998,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
985 inode->i_size = new_isize; 998 inode->i_size = new_isize;
986 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 999 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
987 } 1000 }
988 nfsi->cache_change_attribute = jiffies; 1001 nfsi->cache_change_attribute = now;
989 dprintk("NFS: isize change on server for file %s/%ld\n", 1002 dprintk("NFS: isize change on server for file %s/%ld\n",
990 inode->i_sb->s_id, inode->i_ino); 1003 inode->i_sb->s_id, inode->i_ino);
991 } 1004 }
@@ -996,14 +1009,14 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
996 dprintk("NFS: mtime change on server for file %s/%ld\n", 1009 dprintk("NFS: mtime change on server for file %s/%ld\n",
997 inode->i_sb->s_id, inode->i_ino); 1010 inode->i_sb->s_id, inode->i_ino);
998 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1011 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
999 nfsi->cache_change_attribute = jiffies; 1012 nfsi->cache_change_attribute = now;
1000 } 1013 }
1001 1014
1002 /* If ctime has changed we should definitely clear access+acl caches */ 1015 /* If ctime has changed we should definitely clear access+acl caches */
1003 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { 1016 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
1004 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1017 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1005 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1018 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1006 nfsi->cache_change_attribute = jiffies; 1019 nfsi->cache_change_attribute = now;
1007 } 1020 }
1008 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1021 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1009 1022
@@ -1032,18 +1045,18 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1032 inode->i_sb->s_id, inode->i_ino); 1045 inode->i_sb->s_id, inode->i_ino);
1033 nfsi->change_attr = fattr->change_attr; 1046 nfsi->change_attr = fattr->change_attr;
1034 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1047 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1035 nfsi->cache_change_attribute = jiffies; 1048 nfsi->cache_change_attribute = now;
1036 } 1049 }
1037 1050
1038 /* Update attrtimeo value if we're out of the unstable period */ 1051 /* Update attrtimeo value if we're out of the unstable period */
1039 if (invalid & NFS_INO_INVALID_ATTR) { 1052 if (invalid & NFS_INO_INVALID_ATTR) {
1040 nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); 1053 nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
1041 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 1054 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
1042 nfsi->attrtimeo_timestamp = jiffies; 1055 nfsi->attrtimeo_timestamp = now;
1043 } else if (time_after(jiffies, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) { 1056 } else if (time_after(now, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) {
1044 if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode)) 1057 if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
1045 nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode); 1058 nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
1046 nfsi->attrtimeo_timestamp = jiffies; 1059 nfsi->attrtimeo_timestamp = now;
1047 } 1060 }
1048 /* Don't invalidate the data if we were to blame */ 1061 /* Don't invalidate the data if we were to blame */
1049 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) 1062 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
@@ -1122,7 +1135,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
1122 return NULL; 1135 return NULL;
1123 nfsi->flags = 0UL; 1136 nfsi->flags = 0UL;
1124 nfsi->cache_validity = 0UL; 1137 nfsi->cache_validity = 0UL;
1125 nfsi->cache_change_attribute = jiffies;
1126#ifdef CONFIG_NFS_V3_ACL 1138#ifdef CONFIG_NFS_V3_ACL
1127 nfsi->acl_access = ERR_PTR(-EAGAIN); 1139 nfsi->acl_access = ERR_PTR(-EAGAIN);
1128 nfsi->acl_default = ERR_PTR(-EAGAIN); 1140 nfsi->acl_default = ERR_PTR(-EAGAIN);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index a28f6ce2e131..6610f2b02077 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -107,10 +107,6 @@ extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
107/* nfs4proc.c */ 107/* nfs4proc.c */
108#ifdef CONFIG_NFS_V4 108#ifdef CONFIG_NFS_V4
109extern struct rpc_procinfo nfs4_procedures[]; 109extern struct rpc_procinfo nfs4_procedures[];
110
111extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
112 struct nfs4_fs_locations *fs_locations,
113 struct page *page);
114#endif 110#endif
115 111
116/* dir.c */ 112/* dir.c */
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index acd8fe9762d3..7d0371e2bad5 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -253,29 +253,6 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
253 return status; 253 return status;
254} 254}
255 255
256static int nfs3_proc_read(struct nfs_read_data *rdata)
257{
258 int flags = rdata->flags;
259 struct inode * inode = rdata->inode;
260 struct nfs_fattr * fattr = rdata->res.fattr;
261 struct rpc_message msg = {
262 .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
263 .rpc_argp = &rdata->args,
264 .rpc_resp = &rdata->res,
265 .rpc_cred = rdata->cred,
266 };
267 int status;
268
269 dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
270 (long long) rdata->args.offset);
271 nfs_fattr_init(fattr);
272 status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
273 if (status >= 0)
274 nfs_refresh_inode(inode, fattr);
275 dprintk("NFS reply read: %d\n", status);
276 return status;
277}
278
279/* 256/*
280 * Create a regular file. 257 * Create a regular file.
281 * For now, we don't implement O_EXCL. 258 * For now, we don't implement O_EXCL.
@@ -855,7 +832,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
855 .lookup = nfs3_proc_lookup, 832 .lookup = nfs3_proc_lookup,
856 .access = nfs3_proc_access, 833 .access = nfs3_proc_access,
857 .readlink = nfs3_proc_readlink, 834 .readlink = nfs3_proc_readlink,
858 .read = nfs3_proc_read,
859 .create = nfs3_proc_create, 835 .create = nfs3_proc_create,
860 .remove = nfs3_proc_remove, 836 .remove = nfs3_proc_remove,
861 .unlink_setup = nfs3_proc_unlink_setup, 837 .unlink_setup = nfs3_proc_unlink_setup,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index e2341766c4f0..cf3a17eb5c09 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -169,7 +169,7 @@ extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
169extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); 169extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
170extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); 170extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
171extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); 171extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
172extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry, 172extern int nfs4_proc_fs_locations(struct inode *dir, struct qstr *name,
173 struct nfs4_fs_locations *fs_locations, struct page *page); 173 struct nfs4_fs_locations *fs_locations, struct page *page);
174 174
175extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; 175extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index b872779d7cd5..dd5fef20c702 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -16,6 +16,7 @@
16#include <linux/vfs.h> 16#include <linux/vfs.h>
17#include <linux/inet.h> 17#include <linux/inet.h>
18#include "internal.h" 18#include "internal.h"
19#include "nfs4_fs.h"
19 20
20#define NFSDBG_FACILITY NFSDBG_VFS 21#define NFSDBG_FACILITY NFSDBG_VFS
21 22
@@ -130,7 +131,6 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
130 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor, 131 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor,
131 }; 132 };
132 char *page = NULL, *page2 = NULL; 133 char *page = NULL, *page2 = NULL;
133 char *devname;
134 int loc, s, error; 134 int loc, s, error;
135 135
136 if (locations == NULL || locations->nlocations <= 0) 136 if (locations == NULL || locations->nlocations <= 0)
@@ -154,12 +154,6 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
154 goto out; 154 goto out;
155 } 155 }
156 156
157 devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
158 if (IS_ERR(devname)) {
159 mnt = (struct vfsmount *)devname;
160 goto out;
161 }
162
163 loc = 0; 157 loc = 0;
164 while (loc < locations->nlocations && IS_ERR(mnt)) { 158 while (loc < locations->nlocations && IS_ERR(mnt)) {
165 const struct nfs4_fs_location *location = &locations->locations[loc]; 159 const struct nfs4_fs_location *location = &locations->locations[loc];
@@ -194,7 +188,11 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
194 addr.sin_port = htons(NFS_PORT); 188 addr.sin_port = htons(NFS_PORT);
195 mountdata.addr = &addr; 189 mountdata.addr = &addr;
196 190
197 mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, devname, &mountdata); 191 snprintf(page, PAGE_SIZE, "%s:%s",
192 mountdata.hostname,
193 mountdata.mnt_path);
194
195 mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, page, &mountdata);
198 if (!IS_ERR(mnt)) { 196 if (!IS_ERR(mnt)) {
199 break; 197 break;
200 } 198 }
@@ -242,7 +240,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr
242 dprintk("%s: getting locations for %s/%s\n", 240 dprintk("%s: getting locations for %s/%s\n",
243 __FUNCTION__, parent->d_name.name, dentry->d_name.name); 241 __FUNCTION__, parent->d_name.name, dentry->d_name.name);
244 242
245 err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page); 243 err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page);
246 dput(parent); 244 dput(parent);
247 if (err != 0 || 245 if (err != 0 ||
248 fs_locations->nlocations <= 0 || 246 fs_locations->nlocations <= 0 ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1daee65b517e..f52cf5c33c6c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1140,7 +1140,6 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1140 break; 1140 break;
1141 case -NFS4ERR_STALE_STATEID: 1141 case -NFS4ERR_STALE_STATEID:
1142 case -NFS4ERR_EXPIRED: 1142 case -NFS4ERR_EXPIRED:
1143 nfs4_schedule_state_recovery(server->nfs_client);
1144 break; 1143 break;
1145 default: 1144 default:
1146 if (nfs4_async_handle_error(task, server) == -EAGAIN) { 1145 if (nfs4_async_handle_error(task, server) == -EAGAIN) {
@@ -1424,7 +1423,6 @@ static int nfs4_get_referral(struct inode *dir, struct qstr *name, struct nfs_fa
1424 int status = -ENOMEM; 1423 int status = -ENOMEM;
1425 struct page *page = NULL; 1424 struct page *page = NULL;
1426 struct nfs4_fs_locations *locations = NULL; 1425 struct nfs4_fs_locations *locations = NULL;
1427 struct dentry dentry = {};
1428 1426
1429 page = alloc_page(GFP_KERNEL); 1427 page = alloc_page(GFP_KERNEL);
1430 if (page == NULL) 1428 if (page == NULL)
@@ -1433,9 +1431,7 @@ static int nfs4_get_referral(struct inode *dir, struct qstr *name, struct nfs_fa
1433 if (locations == NULL) 1431 if (locations == NULL)
1434 goto out; 1432 goto out;
1435 1433
1436 dentry.d_name.name = name->name; 1434 status = nfs4_proc_fs_locations(dir, name, locations, page);
1437 dentry.d_name.len = name->len;
1438 status = nfs4_proc_fs_locations(dir, &dentry, locations, page);
1439 if (status != 0) 1435 if (status != 0)
1440 goto out; 1436 goto out;
1441 /* Make sure server returned a different fsid for the referral */ 1437 /* Make sure server returned a different fsid for the referral */
@@ -1737,44 +1733,6 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
1737 return err; 1733 return err;
1738} 1734}
1739 1735
1740static int _nfs4_proc_read(struct nfs_read_data *rdata)
1741{
1742 int flags = rdata->flags;
1743 struct inode *inode = rdata->inode;
1744 struct nfs_fattr *fattr = rdata->res.fattr;
1745 struct nfs_server *server = NFS_SERVER(inode);
1746 struct rpc_message msg = {
1747 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
1748 .rpc_argp = &rdata->args,
1749 .rpc_resp = &rdata->res,
1750 .rpc_cred = rdata->cred,
1751 };
1752 unsigned long timestamp = jiffies;
1753 int status;
1754
1755 dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
1756 (long long) rdata->args.offset);
1757
1758 nfs_fattr_init(fattr);
1759 status = rpc_call_sync(server->client, &msg, flags);
1760 if (!status)
1761 renew_lease(server, timestamp);
1762 dprintk("NFS reply read: %d\n", status);
1763 return status;
1764}
1765
1766static int nfs4_proc_read(struct nfs_read_data *rdata)
1767{
1768 struct nfs4_exception exception = { };
1769 int err;
1770 do {
1771 err = nfs4_handle_exception(NFS_SERVER(rdata->inode),
1772 _nfs4_proc_read(rdata),
1773 &exception);
1774 } while (exception.retry);
1775 return err;
1776}
1777
1778/* 1736/*
1779 * Got race? 1737 * Got race?
1780 * We will need to arrange for the VFS layer to provide an atomic open. 1738 * We will need to arrange for the VFS layer to provide an atomic open.
@@ -2753,11 +2711,15 @@ static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp)
2753 2711
2754 might_sleep(); 2712 might_sleep();
2755 2713
2714 rwsem_acquire(&clp->cl_sem.dep_map, 0, 0, _RET_IP_);
2715
2756 rpc_clnt_sigmask(clnt, &oldset); 2716 rpc_clnt_sigmask(clnt, &oldset);
2757 res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, 2717 res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER,
2758 nfs4_wait_bit_interruptible, 2718 nfs4_wait_bit_interruptible,
2759 TASK_INTERRUPTIBLE); 2719 TASK_INTERRUPTIBLE);
2760 rpc_clnt_sigunmask(clnt, &oldset); 2720 rpc_clnt_sigunmask(clnt, &oldset);
2721
2722 rwsem_release(&clp->cl_sem.dep_map, 1, _RET_IP_);
2761 return res; 2723 return res;
2762} 2724}
2763 2725
@@ -2996,7 +2958,6 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
2996 switch (err) { 2958 switch (err) {
2997 case -NFS4ERR_STALE_STATEID: 2959 case -NFS4ERR_STALE_STATEID:
2998 case -NFS4ERR_EXPIRED: 2960 case -NFS4ERR_EXPIRED:
2999 nfs4_schedule_state_recovery(server->nfs_client);
3000 case 0: 2961 case 0:
3001 return 0; 2962 return 0;
3002 } 2963 }
@@ -3150,12 +3111,10 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3150 break; 3111 break;
3151 case -NFS4ERR_STALE_STATEID: 3112 case -NFS4ERR_STALE_STATEID:
3152 case -NFS4ERR_EXPIRED: 3113 case -NFS4ERR_EXPIRED:
3153 nfs4_schedule_state_recovery(calldata->server->nfs_client);
3154 break; 3114 break;
3155 default: 3115 default:
3156 if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) { 3116 if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN)
3157 rpc_restart_call(task); 3117 rpc_restart_call(task);
3158 }
3159 } 3118 }
3160} 3119}
3161 3120
@@ -3585,7 +3544,7 @@ ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
3585 return len; 3544 return len;
3586} 3545}
3587 3546
3588int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry, 3547int nfs4_proc_fs_locations(struct inode *dir, struct qstr *name,
3589 struct nfs4_fs_locations *fs_locations, struct page *page) 3548 struct nfs4_fs_locations *fs_locations, struct page *page)
3590{ 3549{
3591 struct nfs_server *server = NFS_SERVER(dir); 3550 struct nfs_server *server = NFS_SERVER(dir);
@@ -3595,7 +3554,7 @@ int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
3595 }; 3554 };
3596 struct nfs4_fs_locations_arg args = { 3555 struct nfs4_fs_locations_arg args = {
3597 .dir_fh = NFS_FH(dir), 3556 .dir_fh = NFS_FH(dir),
3598 .name = &dentry->d_name, 3557 .name = name,
3599 .page = page, 3558 .page = page,
3600 .bitmask = bitmask, 3559 .bitmask = bitmask,
3601 }; 3560 };
@@ -3607,7 +3566,7 @@ int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
3607 int status; 3566 int status;
3608 3567
3609 dprintk("%s: start\n", __FUNCTION__); 3568 dprintk("%s: start\n", __FUNCTION__);
3610 fs_locations->fattr.valid = 0; 3569 nfs_fattr_init(&fs_locations->fattr);
3611 fs_locations->server = server; 3570 fs_locations->server = server;
3612 fs_locations->nlocations = 0; 3571 fs_locations->nlocations = 0;
3613 status = rpc_call_sync(server->client, &msg, 0); 3572 status = rpc_call_sync(server->client, &msg, 0);
@@ -3646,7 +3605,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
3646 .lookup = nfs4_proc_lookup, 3605 .lookup = nfs4_proc_lookup,
3647 .access = nfs4_proc_access, 3606 .access = nfs4_proc_access,
3648 .readlink = nfs4_proc_readlink, 3607 .readlink = nfs4_proc_readlink,
3649 .read = nfs4_proc_read,
3650 .create = nfs4_proc_create, 3608 .create = nfs4_proc_create,
3651 .remove = nfs4_proc_remove, 3609 .remove = nfs4_proc_remove,
3652 .unlink_setup = nfs4_proc_unlink_setup, 3610 .unlink_setup = nfs4_proc_unlink_setup,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 0cf3fa312a33..f02d522fd788 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -387,8 +387,10 @@ static int nfs4_stat_to_errno(int);
387 decode_putfh_maxsz + \ 387 decode_putfh_maxsz + \
388 op_decode_hdr_maxsz + 12) 388 op_decode_hdr_maxsz + 12)
389#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ 389#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
390 encode_putfh_maxsz + \
390 encode_getattr_maxsz) 391 encode_getattr_maxsz)
391#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \ 392#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
393 decode_putfh_maxsz + \
392 decode_getattr_maxsz) 394 decode_getattr_maxsz)
393#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ 395#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
394 encode_putfh_maxsz + \ 396 encode_putfh_maxsz + \
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 560536ad74a4..1dcf56de9482 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -186,35 +186,6 @@ static int nfs_proc_readlink(struct inode *inode, struct page *page,
186 return status; 186 return status;
187} 187}
188 188
189static int nfs_proc_read(struct nfs_read_data *rdata)
190{
191 int flags = rdata->flags;
192 struct inode * inode = rdata->inode;
193 struct nfs_fattr * fattr = rdata->res.fattr;
194 struct rpc_message msg = {
195 .rpc_proc = &nfs_procedures[NFSPROC_READ],
196 .rpc_argp = &rdata->args,
197 .rpc_resp = &rdata->res,
198 .rpc_cred = rdata->cred,
199 };
200 int status;
201
202 dprintk("NFS call read %d @ %Ld\n", rdata->args.count,
203 (long long) rdata->args.offset);
204 nfs_fattr_init(fattr);
205 status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
206 if (status >= 0) {
207 nfs_refresh_inode(inode, fattr);
208 /* Emulate the eof flag, which isn't normally needed in NFSv2
209 * as it is guaranteed to always return the file attributes
210 */
211 if (rdata->args.offset + rdata->args.count >= fattr->size)
212 rdata->res.eof = 1;
213 }
214 dprintk("NFS reply read: %d\n", status);
215 return status;
216}
217
218static int 189static int
219nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 190nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
220 int flags, struct nameidata *nd) 191 int flags, struct nameidata *nd)
@@ -666,7 +637,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
666 .lookup = nfs_proc_lookup, 637 .lookup = nfs_proc_lookup,
667 .access = NULL, /* access */ 638 .access = NULL, /* access */
668 .readlink = nfs_proc_readlink, 639 .readlink = nfs_proc_readlink,
669 .read = nfs_proc_read,
670 .create = nfs_proc_create, 640 .create = nfs_proc_create,
671 .remove = nfs_proc_remove, 641 .remove = nfs_proc_remove,
672 .unlink_setup = nfs_proc_unlink_setup, 642 .unlink_setup = nfs_proc_unlink_setup,
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index a9c26521a9e2..6ab4d5a9edf2 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -5,14 +5,6 @@
5 * 5 *
6 * Partial copy of Linus' read cache modifications to fs/nfs/file.c 6 * Partial copy of Linus' read cache modifications to fs/nfs/file.c
7 * modified for async RPC by okir@monad.swb.de 7 * modified for async RPC by okir@monad.swb.de
8 *
9 * We do an ugly hack here in order to return proper error codes to the
10 * user program when a read request failed: since generic_file_read
11 * only checks the return value of inode->i_op->readpage() which is always 0
12 * for async RPC, we set the error bit of the page to 1 when an error occurs,
13 * and make nfs_readpage transmit requests synchronously when encountering this.
14 * This is only a small problem, though, since we now retry all operations
15 * within the RPC code when root squashing is suspected.
16 */ 8 */
17 9
18#include <linux/time.h> 10#include <linux/time.h>
@@ -122,93 +114,6 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data)
122 } 114 }
123} 115}
124 116
125/*
126 * Read a page synchronously.
127 */
128static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
129 struct page *page)
130{
131 unsigned int rsize = NFS_SERVER(inode)->rsize;
132 unsigned int count = PAGE_CACHE_SIZE;
133 int result = -ENOMEM;
134 struct nfs_read_data *rdata;
135
136 rdata = nfs_readdata_alloc(count);
137 if (!rdata)
138 goto out_unlock;
139
140 memset(rdata, 0, sizeof(*rdata));
141 rdata->flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
142 rdata->cred = ctx->cred;
143 rdata->inode = inode;
144 INIT_LIST_HEAD(&rdata->pages);
145 rdata->args.fh = NFS_FH(inode);
146 rdata->args.context = ctx;
147 rdata->args.pages = &page;
148 rdata->args.pgbase = 0UL;
149 rdata->args.count = rsize;
150 rdata->res.fattr = &rdata->fattr;
151
152 dprintk("NFS: nfs_readpage_sync(%p)\n", page);
153
154 /*
155 * This works now because the socket layer never tries to DMA
156 * into this buffer directly.
157 */
158 do {
159 if (count < rsize)
160 rdata->args.count = count;
161 rdata->res.count = rdata->args.count;
162 rdata->args.offset = page_offset(page) + rdata->args.pgbase;
163
164 dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n",
165 NFS_SERVER(inode)->nfs_client->cl_hostname,
166 inode->i_sb->s_id,
167 (long long)NFS_FILEID(inode),
168 (unsigned long long)rdata->args.pgbase,
169 rdata->args.count);
170
171 lock_kernel();
172 result = NFS_PROTO(inode)->read(rdata);
173 unlock_kernel();
174
175 /*
176 * Even if we had a partial success we can't mark the page
177 * cache valid.
178 */
179 if (result < 0) {
180 if (result == -EISDIR)
181 result = -EINVAL;
182 goto io_error;
183 }
184 count -= result;
185 rdata->args.pgbase += result;
186 nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, result);
187
188 /* Note: result == 0 should only happen if we're caching
189 * a write that extends the file and punches a hole.
190 */
191 if (rdata->res.eof != 0 || result == 0)
192 break;
193 } while (count);
194 spin_lock(&inode->i_lock);
195 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
196 spin_unlock(&inode->i_lock);
197
198 if (rdata->res.eof || rdata->res.count == rdata->args.count) {
199 SetPageUptodate(page);
200 if (rdata->res.eof && count != 0)
201 memclear_highpage_flush(page, rdata->args.pgbase, count);
202 }
203 result = 0;
204
205io_error:
206 nfs_readdata_free(rdata);
207out_unlock:
208 unlock_page(page);
209 return result;
210}
211
212static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, 117static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
213 struct page *page) 118 struct page *page)
214{ 119{
@@ -278,7 +183,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
278 183
279 data->task.tk_cookie = (unsigned long)inode; 184 data->task.tk_cookie = (unsigned long)inode;
280 185
281 dprintk("NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n", 186 dprintk("NFS: %5u initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n",
282 data->task.tk_pid, 187 data->task.tk_pid,
283 inode->i_sb->s_id, 188 inode->i_sb->s_id,
284 (long long)NFS_FILEID(inode), 189 (long long)NFS_FILEID(inode),
@@ -452,7 +357,7 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data)
452{ 357{
453 int status; 358 int status;
454 359
455 dprintk("%s: %4d, (status %d)\n", __FUNCTION__, task->tk_pid, 360 dprintk("NFS: %s: %5u, (status %d)\n", __FUNCTION__, task->tk_pid,
456 task->tk_status); 361 task->tk_status);
457 362
458 status = NFS_PROTO(data->inode)->read_done(task, data); 363 status = NFS_PROTO(data->inode)->read_done(task, data);
@@ -621,15 +526,9 @@ int nfs_readpage(struct file *file, struct page *page)
621 } else 526 } else
622 ctx = get_nfs_open_context((struct nfs_open_context *) 527 ctx = get_nfs_open_context((struct nfs_open_context *)
623 file->private_data); 528 file->private_data);
624 if (!IS_SYNC(inode)) {
625 error = nfs_readpage_async(ctx, inode, page);
626 goto out;
627 }
628 529
629 error = nfs_readpage_sync(ctx, inode, page); 530 error = nfs_readpage_async(ctx, inode, page);
630 if (error < 0 && IS_SWAPFILE(inode)) 531
631 printk("Aiee.. nfs swap-in of page failed!\n");
632out:
633 put_nfs_open_context(ctx); 532 put_nfs_open_context(ctx);
634 return error; 533 return error;
635 534
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index baa28860ad27..bb516a2cfbaf 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1045,7 +1045,7 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
1045 nfs4_fill_super(s); 1045 nfs4_fill_super(s);
1046 } 1046 }
1047 1047
1048 mntroot = nfs4_get_root(s, data->fh); 1048 mntroot = nfs4_get_root(s, &mntfh);
1049 if (IS_ERR(mntroot)) { 1049 if (IS_ERR(mntroot)) {
1050 error = PTR_ERR(mntroot); 1050 error = PTR_ERR(mntroot);
1051 goto error_splat_super; 1051 goto error_splat_super;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 345492e78643..febdade91670 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1,47 +1,7 @@
1/* 1/*
2 * linux/fs/nfs/write.c 2 * linux/fs/nfs/write.c
3 * 3 *
4 * Writing file data over NFS. 4 * Write file data over NFS.
5 *
6 * We do it like this: When a (user) process wishes to write data to an
7 * NFS file, a write request is allocated that contains the RPC task data
8 * plus some info on the page to be written, and added to the inode's
9 * write chain. If the process writes past the end of the page, an async
10 * RPC call to write the page is scheduled immediately; otherwise, the call
11 * is delayed for a few seconds.
12 *
13 * Just like readahead, no async I/O is performed if wsize < PAGE_SIZE.
14 *
15 * Write requests are kept on the inode's writeback list. Each entry in
16 * that list references the page (portion) to be written. When the
17 * cache timeout has expired, the RPC task is woken up, and tries to
18 * lock the page. As soon as it manages to do so, the request is moved
19 * from the writeback list to the writelock list.
20 *
21 * Note: we must make sure never to confuse the inode passed in the
22 * write_page request with the one in page->inode. As far as I understand
23 * it, these are different when doing a swap-out.
24 *
25 * To understand everything that goes on here and in the NFS read code,
26 * one should be aware that a page is locked in exactly one of the following
27 * cases:
28 *
29 * - A write request is in progress.
30 * - A user process is in generic_file_write/nfs_update_page
31 * - A user process is in generic_file_read
32 *
33 * Also note that because of the way pages are invalidated in
34 * nfs_revalidate_inode, the following assertions hold:
35 *
36 * - If a page is dirty, there will be no read requests (a page will
37 * not be re-read unless invalidated by nfs_revalidate_inode).
38 * - If the page is not uptodate, there will be no pending write
39 * requests, and no process will be in nfs_update_page.
40 *
41 * FIXME: Interaction with the vmscan routines is not optimal yet.
42 * Either vmscan must be made nfs-savvy, or we need a different page
43 * reclaim concept that supports something like FS-independent
44 * buffer_heads with a b_ops-> field.
45 * 5 *
46 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
47 */ 7 */
@@ -79,7 +39,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context*,
79 unsigned int, unsigned int); 39 unsigned int, unsigned int);
80static void nfs_mark_request_dirty(struct nfs_page *req); 40static void nfs_mark_request_dirty(struct nfs_page *req);
81static int nfs_wait_on_write_congestion(struct address_space *, int); 41static int nfs_wait_on_write_congestion(struct address_space *, int);
82static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int);
83static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); 42static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how);
84static const struct rpc_call_ops nfs_write_partial_ops; 43static const struct rpc_call_ops nfs_write_partial_ops;
85static const struct rpc_call_ops nfs_write_full_ops; 44static const struct rpc_call_ops nfs_write_full_ops;
@@ -194,6 +153,13 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c
194 i_size_write(inode, end); 153 i_size_write(inode, end);
195} 154}
196 155
156/* A writeback failed: mark the page as bad, and invalidate the page cache */
157static void nfs_set_pageerror(struct page *page)
158{
159 SetPageError(page);
160 nfs_zap_mapping(page->mapping->host, page->mapping);
161}
162
197/* We can set the PG_uptodate flag if we see that a write request 163/* We can set the PG_uptodate flag if we see that a write request
198 * covers the full page. 164 * covers the full page.
199 */ 165 */
@@ -323,7 +289,7 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc
323 err = 0; 289 err = 0;
324out: 290out:
325 if (!wbc->for_writepages) 291 if (!wbc->for_writepages)
326 nfs_flush_mapping(page->mapping, wbc, wb_priority(wbc)); 292 nfs_flush_mapping(page->mapping, wbc, FLUSH_STABLE|wb_priority(wbc));
327 return err; 293 return err;
328} 294}
329 295
@@ -360,14 +326,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
360 if (err < 0) 326 if (err < 0)
361 goto out; 327 goto out;
362 nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); 328 nfs_add_stats(inode, NFSIOS_WRITEPAGES, err);
363 if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { 329 err = 0;
364 err = nfs_wait_on_requests(inode, 0, 0);
365 if (err < 0)
366 goto out;
367 }
368 err = nfs_commit_inode(inode, wb_priority(wbc));
369 if (err > 0)
370 err = 0;
371out: 330out:
372 clear_bit(BDI_write_congested, &bdi->state); 331 clear_bit(BDI_write_congested, &bdi->state);
373 wake_up_all(&nfs_write_congestion); 332 wake_up_all(&nfs_write_congestion);
@@ -516,17 +475,6 @@ static int nfs_wait_on_requests_locked(struct inode *inode, unsigned long idx_st
516 return res; 475 return res;
517} 476}
518 477
519static int nfs_wait_on_requests(struct inode *inode, unsigned long idx_start, unsigned int npages)
520{
521 struct nfs_inode *nfsi = NFS_I(inode);
522 int ret;
523
524 spin_lock(&nfsi->req_lock);
525 ret = nfs_wait_on_requests_locked(inode, idx_start, npages);
526 spin_unlock(&nfsi->req_lock);
527 return ret;
528}
529
530static void nfs_cancel_dirty_list(struct list_head *head) 478static void nfs_cancel_dirty_list(struct list_head *head)
531{ 479{
532 struct nfs_page *req; 480 struct nfs_page *req;
@@ -773,7 +721,7 @@ int nfs_updatepage(struct file *file, struct page *page,
773 dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", 721 dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
774 status, (long long)i_size_read(inode)); 722 status, (long long)i_size_read(inode));
775 if (status < 0) 723 if (status < 0)
776 ClearPageUptodate(page); 724 nfs_set_pageerror(page);
777 return status; 725 return status;
778} 726}
779 727
@@ -852,7 +800,8 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
852 data->task.tk_priority = flush_task_priority(how); 800 data->task.tk_priority = flush_task_priority(how);
853 data->task.tk_cookie = (unsigned long)inode; 801 data->task.tk_cookie = (unsigned long)inode;
854 802
855 dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n", 803 dprintk("NFS: %5u initiated write call "
804 "(req %s/%Ld, %u bytes @ offset %Lu)\n",
856 data->task.tk_pid, 805 data->task.tk_pid,
857 inode->i_sb->s_id, 806 inode->i_sb->s_id,
858 (long long)NFS_FILEID(inode), 807 (long long)NFS_FILEID(inode),
@@ -1034,8 +983,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
1034 return; 983 return;
1035 984
1036 if (task->tk_status < 0) { 985 if (task->tk_status < 0) {
1037 ClearPageUptodate(page); 986 nfs_set_pageerror(page);
1038 SetPageError(page);
1039 req->wb_context->error = task->tk_status; 987 req->wb_context->error = task->tk_status;
1040 dprintk(", error = %d\n", task->tk_status); 988 dprintk(", error = %d\n", task->tk_status);
1041 } else { 989 } else {
@@ -1092,8 +1040,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1092 (long long)req_offset(req)); 1040 (long long)req_offset(req));
1093 1041
1094 if (task->tk_status < 0) { 1042 if (task->tk_status < 0) {
1095 ClearPageUptodate(page); 1043 nfs_set_pageerror(page);
1096 SetPageError(page);
1097 req->wb_context->error = task->tk_status; 1044 req->wb_context->error = task->tk_status;
1098 end_page_writeback(page); 1045 end_page_writeback(page);
1099 nfs_inode_remove_request(req); 1046 nfs_inode_remove_request(req);
@@ -1134,7 +1081,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1134 struct nfs_writeres *resp = &data->res; 1081 struct nfs_writeres *resp = &data->res;
1135 int status; 1082 int status;
1136 1083
1137 dprintk("NFS: %4d nfs_writeback_done (status %d)\n", 1084 dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
1138 task->tk_pid, task->tk_status); 1085 task->tk_pid, task->tk_status);
1139 1086
1140 /* 1087 /*
@@ -1250,7 +1197,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1250 data->task.tk_priority = flush_task_priority(how); 1197 data->task.tk_priority = flush_task_priority(how);
1251 data->task.tk_cookie = (unsigned long)inode; 1198 data->task.tk_cookie = (unsigned long)inode;
1252 1199
1253 dprintk("NFS: %4d initiated commit call\n", data->task.tk_pid); 1200 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
1254} 1201}
1255 1202
1256/* 1203/*
@@ -1291,7 +1238,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1291 struct nfs_write_data *data = calldata; 1238 struct nfs_write_data *data = calldata;
1292 struct nfs_page *req; 1239 struct nfs_page *req;
1293 1240
1294 dprintk("NFS: %4d nfs_commit_done (status %d)\n", 1241 dprintk("NFS: %5u nfs_commit_done (status %d)\n",
1295 task->tk_pid, task->tk_status); 1242 task->tk_pid, task->tk_status);
1296 1243
1297 /* Call the NFS version-specific code */ 1244 /* Call the NFS version-specific code */
@@ -1516,6 +1463,8 @@ int nfs_wb_page_priority(struct inode *inode, struct page *page, int how)
1516 if (ret < 0) 1463 if (ret < 0)
1517 goto out; 1464 goto out;
1518 } 1465 }
1466 if (!PagePrivate(page))
1467 return 0;
1519 ret = nfs_sync_mapping_wait(page->mapping, &wbc, how); 1468 ret = nfs_sync_mapping_wait(page->mapping, &wbc, how);
1520 if (ret >= 0) 1469 if (ret >= 0)
1521 return 0; 1470 return 0;