aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig4
-rw-r--r--fs/dcache.c164
-rw-r--r--fs/lockd/clntproc.c10
-rw-r--r--fs/lockd/host.c51
-rw-r--r--fs/lockd/mon.c41
-rw-r--r--fs/nfs/Makefile6
-rw-r--r--fs/nfs/callback.c31
-rw-r--r--fs/nfs/callback.h7
-rw-r--r--fs/nfs/callback_proc.c13
-rw-r--r--fs/nfs/client.c1448
-rw-r--r--fs/nfs/delegation.c35
-rw-r--r--fs/nfs/delegation.h10
-rw-r--r--fs/nfs/dir.c338
-rw-r--r--fs/nfs/file.c4
-rw-r--r--fs/nfs/getroot.c311
-rw-r--r--fs/nfs/idmap.c45
-rw-r--r--fs/nfs/inode.c46
-rw-r--r--fs/nfs/internal.h105
-rw-r--r--fs/nfs/mount_clnt.c30
-rw-r--r--fs/nfs/namespace.c34
-rw-r--r--fs/nfs/nfs2xdr.c21
-rw-r--r--fs/nfs/nfs3proc.c42
-rw-r--r--fs/nfs/nfs3xdr.c7
-rw-r--r--fs/nfs/nfs4_fs.h78
-rw-r--r--fs/nfs/nfs4namespace.c118
-rw-r--r--fs/nfs/nfs4proc.c218
-rw-r--r--fs/nfs/nfs4renewd.c20
-rw-r--r--fs/nfs/nfs4state.c174
-rw-r--r--fs/nfs/nfs4xdr.c50
-rw-r--r--fs/nfs/proc.c41
-rw-r--r--fs/nfs/read.c21
-rw-r--r--fs/nfs/super.c1411
-rw-r--r--fs/nfs/write.c11
-rw-r--r--fs/nfsd/nfs4callback.c66
34 files changed, 3326 insertions, 1685 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 530581628311..a27002668bd3 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1471,8 +1471,8 @@ config NFS_V4
1471 If unsure, say N. 1471 If unsure, say N.
1472 1472
1473config NFS_DIRECTIO 1473config NFS_DIRECTIO
1474 bool "Allow direct I/O on NFS files (EXPERIMENTAL)" 1474 bool "Allow direct I/O on NFS files"
1475 depends on NFS_FS && EXPERIMENTAL 1475 depends on NFS_FS
1476 help 1476 help
1477 This option enables applications to perform uncached I/O on files 1477 This option enables applications to perform uncached I/O on files
1478 in NFS file systems using the O_DIRECT open() flag. When O_DIRECT 1478 in NFS file systems using the O_DIRECT open() flag. When O_DIRECT
diff --git a/fs/dcache.c b/fs/dcache.c
index 1b4a3a34ec57..17b392a2049e 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -828,17 +828,19 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
828 * (or otherwise set) by the caller to indicate that it is now 828 * (or otherwise set) by the caller to indicate that it is now
829 * in use by the dcache. 829 * in use by the dcache.
830 */ 830 */
831struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) 831static struct dentry *__d_instantiate_unique(struct dentry *entry,
832 struct inode *inode)
832{ 833{
833 struct dentry *alias; 834 struct dentry *alias;
834 int len = entry->d_name.len; 835 int len = entry->d_name.len;
835 const char *name = entry->d_name.name; 836 const char *name = entry->d_name.name;
836 unsigned int hash = entry->d_name.hash; 837 unsigned int hash = entry->d_name.hash;
837 838
838 BUG_ON(!list_empty(&entry->d_alias)); 839 if (!inode) {
839 spin_lock(&dcache_lock); 840 entry->d_inode = NULL;
840 if (!inode) 841 return NULL;
841 goto do_negative; 842 }
843
842 list_for_each_entry(alias, &inode->i_dentry, d_alias) { 844 list_for_each_entry(alias, &inode->i_dentry, d_alias) {
843 struct qstr *qstr = &alias->d_name; 845 struct qstr *qstr = &alias->d_name;
844 846
@@ -851,19 +853,35 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
851 if (memcmp(qstr->name, name, len)) 853 if (memcmp(qstr->name, name, len))
852 continue; 854 continue;
853 dget_locked(alias); 855 dget_locked(alias);
854 spin_unlock(&dcache_lock);
855 BUG_ON(!d_unhashed(alias));
856 iput(inode);
857 return alias; 856 return alias;
858 } 857 }
858
859 list_add(&entry->d_alias, &inode->i_dentry); 859 list_add(&entry->d_alias, &inode->i_dentry);
860do_negative:
861 entry->d_inode = inode; 860 entry->d_inode = inode;
862 fsnotify_d_instantiate(entry, inode); 861 fsnotify_d_instantiate(entry, inode);
863 spin_unlock(&dcache_lock);
864 security_d_instantiate(entry, inode);
865 return NULL; 862 return NULL;
866} 863}
864
865struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
866{
867 struct dentry *result;
868
869 BUG_ON(!list_empty(&entry->d_alias));
870
871 spin_lock(&dcache_lock);
872 result = __d_instantiate_unique(entry, inode);
873 spin_unlock(&dcache_lock);
874
875 if (!result) {
876 security_d_instantiate(entry, inode);
877 return NULL;
878 }
879
880 BUG_ON(!d_unhashed(result));
881 iput(inode);
882 return result;
883}
884
867EXPORT_SYMBOL(d_instantiate_unique); 885EXPORT_SYMBOL(d_instantiate_unique);
868 886
869/** 887/**
@@ -1235,6 +1253,11 @@ static void __d_rehash(struct dentry * entry, struct hlist_head *list)
1235 hlist_add_head_rcu(&entry->d_hash, list); 1253 hlist_add_head_rcu(&entry->d_hash, list);
1236} 1254}
1237 1255
1256static void _d_rehash(struct dentry * entry)
1257{
1258 __d_rehash(entry, d_hash(entry->d_parent, entry->d_name.hash));
1259}
1260
1238/** 1261/**
1239 * d_rehash - add an entry back to the hash 1262 * d_rehash - add an entry back to the hash
1240 * @entry: dentry to add to the hash 1263 * @entry: dentry to add to the hash
@@ -1244,11 +1267,9 @@ static void __d_rehash(struct dentry * entry, struct hlist_head *list)
1244 1267
1245void d_rehash(struct dentry * entry) 1268void d_rehash(struct dentry * entry)
1246{ 1269{
1247 struct hlist_head *list = d_hash(entry->d_parent, entry->d_name.hash);
1248
1249 spin_lock(&dcache_lock); 1270 spin_lock(&dcache_lock);
1250 spin_lock(&entry->d_lock); 1271 spin_lock(&entry->d_lock);
1251 __d_rehash(entry, list); 1272 _d_rehash(entry);
1252 spin_unlock(&entry->d_lock); 1273 spin_unlock(&entry->d_lock);
1253 spin_unlock(&dcache_lock); 1274 spin_unlock(&dcache_lock);
1254} 1275}
@@ -1386,6 +1407,120 @@ already_unhashed:
1386 spin_unlock(&dcache_lock); 1407 spin_unlock(&dcache_lock);
1387} 1408}
1388 1409
1410/*
1411 * Prepare an anonymous dentry for life in the superblock's dentry tree as a
1412 * named dentry in place of the dentry to be replaced.
1413 */
1414static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
1415{
1416 struct dentry *dparent, *aparent;
1417
1418 switch_names(dentry, anon);
1419 do_switch(dentry->d_name.len, anon->d_name.len);
1420 do_switch(dentry->d_name.hash, anon->d_name.hash);
1421
1422 dparent = dentry->d_parent;
1423 aparent = anon->d_parent;
1424
1425 dentry->d_parent = (aparent == anon) ? dentry : aparent;
1426 list_del(&dentry->d_u.d_child);
1427 if (!IS_ROOT(dentry))
1428 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
1429 else
1430 INIT_LIST_HEAD(&dentry->d_u.d_child);
1431
1432 anon->d_parent = (dparent == dentry) ? anon : dparent;
1433 list_del(&anon->d_u.d_child);
1434 if (!IS_ROOT(anon))
1435 list_add(&anon->d_u.d_child, &anon->d_parent->d_subdirs);
1436 else
1437 INIT_LIST_HEAD(&anon->d_u.d_child);
1438
1439 anon->d_flags &= ~DCACHE_DISCONNECTED;
1440}
1441
1442/**
1443 * d_materialise_unique - introduce an inode into the tree
1444 * @dentry: candidate dentry
1445 * @inode: inode to bind to the dentry, to which aliases may be attached
1446 *
1447 * Introduces an dentry into the tree, substituting an extant disconnected
1448 * root directory alias in its place if there is one
1449 */
1450struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
1451{
1452 struct dentry *alias, *actual;
1453
1454 BUG_ON(!d_unhashed(dentry));
1455
1456 spin_lock(&dcache_lock);
1457
1458 if (!inode) {
1459 actual = dentry;
1460 dentry->d_inode = NULL;
1461 goto found_lock;
1462 }
1463
1464 /* See if a disconnected directory already exists as an anonymous root
1465 * that we should splice into the tree instead */
1466 if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) {
1467 spin_lock(&alias->d_lock);
1468
1469 /* Is this a mountpoint that we could splice into our tree? */
1470 if (IS_ROOT(alias))
1471 goto connect_mountpoint;
1472
1473 if (alias->d_name.len == dentry->d_name.len &&
1474 alias->d_parent == dentry->d_parent &&
1475 memcmp(alias->d_name.name,
1476 dentry->d_name.name,
1477 dentry->d_name.len) == 0)
1478 goto replace_with_alias;
1479
1480 spin_unlock(&alias->d_lock);
1481
1482 /* Doh! Seem to be aliasing directories for some reason... */
1483 dput(alias);
1484 }
1485
1486 /* Add a unique reference */
1487 actual = __d_instantiate_unique(dentry, inode);
1488 if (!actual)
1489 actual = dentry;
1490 else if (unlikely(!d_unhashed(actual)))
1491 goto shouldnt_be_hashed;
1492
1493found_lock:
1494 spin_lock(&actual->d_lock);
1495found:
1496 _d_rehash(actual);
1497 spin_unlock(&actual->d_lock);
1498 spin_unlock(&dcache_lock);
1499
1500 if (actual == dentry) {
1501 security_d_instantiate(dentry, inode);
1502 return NULL;
1503 }
1504
1505 iput(inode);
1506 return actual;
1507
1508 /* Convert the anonymous/root alias into an ordinary dentry */
1509connect_mountpoint:
1510 __d_materialise_dentry(dentry, alias);
1511
1512 /* Replace the candidate dentry with the alias in the tree */
1513replace_with_alias:
1514 __d_drop(alias);
1515 actual = alias;
1516 goto found;
1517
1518shouldnt_be_hashed:
1519 spin_unlock(&dcache_lock);
1520 BUG();
1521 goto shouldnt_be_hashed;
1522}
1523
1389/** 1524/**
1390 * d_path - return the path of a dentry 1525 * d_path - return the path of a dentry
1391 * @dentry: dentry to report 1526 * @dentry: dentry to report
@@ -1784,6 +1919,7 @@ EXPORT_SYMBOL(d_instantiate);
1784EXPORT_SYMBOL(d_invalidate); 1919EXPORT_SYMBOL(d_invalidate);
1785EXPORT_SYMBOL(d_lookup); 1920EXPORT_SYMBOL(d_lookup);
1786EXPORT_SYMBOL(d_move); 1921EXPORT_SYMBOL(d_move);
1922EXPORT_SYMBOL_GPL(d_materialise_unique);
1787EXPORT_SYMBOL(d_path); 1923EXPORT_SYMBOL(d_path);
1788EXPORT_SYMBOL(d_prune_aliases); 1924EXPORT_SYMBOL(d_prune_aliases);
1789EXPORT_SYMBOL(d_rehash); 1925EXPORT_SYMBOL(d_rehash);
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 89ba0df14c22..50dbb67ae0c4 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -151,11 +151,13 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req)
151int 151int
152nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) 152nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
153{ 153{
154 struct rpc_clnt *client = NFS_CLIENT(inode);
155 struct sockaddr_in addr;
154 struct nlm_host *host; 156 struct nlm_host *host;
155 struct nlm_rqst *call; 157 struct nlm_rqst *call;
156 sigset_t oldset; 158 sigset_t oldset;
157 unsigned long flags; 159 unsigned long flags;
158 int status, proto, vers; 160 int status, vers;
159 161
160 vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1; 162 vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1;
161 if (NFS_PROTO(inode)->version > 3) { 163 if (NFS_PROTO(inode)->version > 3) {
@@ -163,10 +165,8 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
163 return -ENOLCK; 165 return -ENOLCK;
164 } 166 }
165 167
166 /* Retrieve transport protocol from NFS client */ 168 rpc_peeraddr(client, (struct sockaddr *) &addr, sizeof(addr));
167 proto = NFS_CLIENT(inode)->cl_xprt->prot; 169 host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers);
168
169 host = nlmclnt_lookup_host(NFS_ADDR(inode), proto, vers);
170 if (host == NULL) 170 if (host == NULL)
171 return -ENOLCK; 171 return -ENOLCK;
172 172
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 38b0e8a1aec0..703fb038c813 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -26,7 +26,6 @@
26#define NLM_HOST_REBIND (60 * HZ) 26#define NLM_HOST_REBIND (60 * HZ)
27#define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) 27#define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ)
28#define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) 28#define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ)
29#define NLM_HOST_ADDR(sv) (&(sv)->s_nlmclnt->cl_xprt->addr)
30 29
31static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; 30static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH];
32static unsigned long next_gc; 31static unsigned long next_gc;
@@ -167,7 +166,6 @@ struct rpc_clnt *
167nlm_bind_host(struct nlm_host *host) 166nlm_bind_host(struct nlm_host *host)
168{ 167{
169 struct rpc_clnt *clnt; 168 struct rpc_clnt *clnt;
170 struct rpc_xprt *xprt;
171 169
172 dprintk("lockd: nlm_bind_host(%08x)\n", 170 dprintk("lockd: nlm_bind_host(%08x)\n",
173 (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); 171 (unsigned)ntohl(host->h_addr.sin_addr.s_addr));
@@ -179,7 +177,6 @@ nlm_bind_host(struct nlm_host *host)
179 * RPC rebind is required 177 * RPC rebind is required
180 */ 178 */
181 if ((clnt = host->h_rpcclnt) != NULL) { 179 if ((clnt = host->h_rpcclnt) != NULL) {
182 xprt = clnt->cl_xprt;
183 if (time_after_eq(jiffies, host->h_nextrebind)) { 180 if (time_after_eq(jiffies, host->h_nextrebind)) {
184 rpc_force_rebind(clnt); 181 rpc_force_rebind(clnt);
185 host->h_nextrebind = jiffies + NLM_HOST_REBIND; 182 host->h_nextrebind = jiffies + NLM_HOST_REBIND;
@@ -187,31 +184,37 @@ nlm_bind_host(struct nlm_host *host)
187 host->h_nextrebind - jiffies); 184 host->h_nextrebind - jiffies);
188 } 185 }
189 } else { 186 } else {
190 xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL); 187 unsigned long increment = nlmsvc_timeout * HZ;
191 if (IS_ERR(xprt)) 188 struct rpc_timeout timeparms = {
192 goto forgetit; 189 .to_initval = increment,
193 190 .to_increment = increment,
194 xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout); 191 .to_maxval = increment * 6UL,
195 xprt->resvport = 1; /* NLM requires a reserved port */ 192 .to_retries = 5U,
196 193 };
197 /* Existing NLM servers accept AUTH_UNIX only */ 194 struct rpc_create_args args = {
198 clnt = rpc_new_client(xprt, host->h_name, &nlm_program, 195 .protocol = host->h_proto,
199 host->h_version, RPC_AUTH_UNIX); 196 .address = (struct sockaddr *)&host->h_addr,
200 if (IS_ERR(clnt)) 197 .addrsize = sizeof(host->h_addr),
201 goto forgetit; 198 .timeout = &timeparms,
202 clnt->cl_autobind = 1; /* turn on pmap queries */ 199 .servername = host->h_name,
203 clnt->cl_softrtry = 1; /* All queries are soft */ 200 .program = &nlm_program,
204 201 .version = host->h_version,
205 host->h_rpcclnt = clnt; 202 .authflavor = RPC_AUTH_UNIX,
203 .flags = (RPC_CLNT_CREATE_HARDRTRY |
204 RPC_CLNT_CREATE_AUTOBIND),
205 };
206
207 clnt = rpc_create(&args);
208 if (!IS_ERR(clnt))
209 host->h_rpcclnt = clnt;
210 else {
211 printk("lockd: couldn't create RPC handle for %s\n", host->h_name);
212 clnt = NULL;
213 }
206 } 214 }
207 215
208 mutex_unlock(&host->h_mutex); 216 mutex_unlock(&host->h_mutex);
209 return clnt; 217 return clnt;
210
211forgetit:
212 printk("lockd: couldn't create RPC handle for %s\n", host->h_name);
213 mutex_unlock(&host->h_mutex);
214 return NULL;
215} 218}
216 219
217/* 220/*
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 3fc683f46b3e..5954dcb497e4 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -109,30 +109,23 @@ nsm_unmonitor(struct nlm_host *host)
109static struct rpc_clnt * 109static struct rpc_clnt *
110nsm_create(void) 110nsm_create(void)
111{ 111{
112 struct rpc_xprt *xprt; 112 struct sockaddr_in sin = {
113 struct rpc_clnt *clnt; 113 .sin_family = AF_INET,
114 struct sockaddr_in sin; 114 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
115 115 .sin_port = 0,
116 sin.sin_family = AF_INET; 116 };
117 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 117 struct rpc_create_args args = {
118 sin.sin_port = 0; 118 .protocol = IPPROTO_UDP,
119 119 .address = (struct sockaddr *)&sin,
120 xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL); 120 .addrsize = sizeof(sin),
121 if (IS_ERR(xprt)) 121 .servername = "localhost",
122 return (struct rpc_clnt *)xprt; 122 .program = &nsm_program,
123 xprt->resvport = 1; /* NSM requires a reserved port */ 123 .version = SM_VERSION,
124 124 .authflavor = RPC_AUTH_NULL,
125 clnt = rpc_create_client(xprt, "localhost", 125 .flags = (RPC_CLNT_CREATE_ONESHOT),
126 &nsm_program, SM_VERSION, 126 };
127 RPC_AUTH_NULL); 127
128 if (IS_ERR(clnt)) 128 return rpc_create(&args);
129 goto out_err;
130 clnt->cl_softrtry = 1;
131 clnt->cl_oneshot = 1;
132 return clnt;
133
134out_err:
135 return clnt;
136} 129}
137 130
138/* 131/*
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 0b572a0c1967..f4580b44eef4 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -4,9 +4,9 @@
4 4
5obj-$(CONFIG_NFS_FS) += nfs.o 5obj-$(CONFIG_NFS_FS) += nfs.o
6 6
7nfs-y := dir.o file.o inode.o super.o nfs2xdr.o pagelist.o \ 7nfs-y := client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \
8 proc.o read.o symlink.o unlink.o write.o \ 8 pagelist.o proc.o read.o symlink.o unlink.o \
9 namespace.o 9 write.o namespace.o
10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o 10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o
11nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o 11nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
12nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o 12nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index fe0a6b8ac149..a3ee11364db0 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -19,6 +19,7 @@
19 19
20#include "nfs4_fs.h" 20#include "nfs4_fs.h"
21#include "callback.h" 21#include "callback.h"
22#include "internal.h"
22 23
23#define NFSDBG_FACILITY NFSDBG_CALLBACK 24#define NFSDBG_FACILITY NFSDBG_CALLBACK
24 25
@@ -36,6 +37,21 @@ static struct svc_program nfs4_callback_program;
36 37
37unsigned int nfs_callback_set_tcpport; 38unsigned int nfs_callback_set_tcpport;
38unsigned short nfs_callback_tcpport; 39unsigned short nfs_callback_tcpport;
40static const int nfs_set_port_min = 0;
41static const int nfs_set_port_max = 65535;
42
43static int param_set_port(const char *val, struct kernel_param *kp)
44{
45 char *endp;
46 int num = simple_strtol(val, &endp, 0);
47 if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max)
48 return -EINVAL;
49 *((int *)kp->arg) = num;
50 return 0;
51}
52
53module_param_call(callback_tcpport, param_set_port, param_get_int,
54 &nfs_callback_set_tcpport, 0644);
39 55
40/* 56/*
41 * This is the callback kernel thread. 57 * This is the callback kernel thread.
@@ -134,10 +150,8 @@ out_err:
134/* 150/*
135 * Kill the server process if it is not already up. 151 * Kill the server process if it is not already up.
136 */ 152 */
137int nfs_callback_down(void) 153void nfs_callback_down(void)
138{ 154{
139 int ret = 0;
140
141 lock_kernel(); 155 lock_kernel();
142 mutex_lock(&nfs_callback_mutex); 156 mutex_lock(&nfs_callback_mutex);
143 nfs_callback_info.users--; 157 nfs_callback_info.users--;
@@ -149,20 +163,19 @@ int nfs_callback_down(void)
149 } while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0); 163 } while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0);
150 mutex_unlock(&nfs_callback_mutex); 164 mutex_unlock(&nfs_callback_mutex);
151 unlock_kernel(); 165 unlock_kernel();
152 return ret;
153} 166}
154 167
155static int nfs_callback_authenticate(struct svc_rqst *rqstp) 168static int nfs_callback_authenticate(struct svc_rqst *rqstp)
156{ 169{
157 struct in_addr *addr = &rqstp->rq_addr.sin_addr; 170 struct sockaddr_in *addr = &rqstp->rq_addr;
158 struct nfs4_client *clp; 171 struct nfs_client *clp;
159 172
160 /* Don't talk to strangers */ 173 /* Don't talk to strangers */
161 clp = nfs4_find_client(addr); 174 clp = nfs_find_client(addr, 4);
162 if (clp == NULL) 175 if (clp == NULL)
163 return SVC_DROP; 176 return SVC_DROP;
164 dprintk("%s: %u.%u.%u.%u NFSv4 callback!\n", __FUNCTION__, NIPQUAD(addr)); 177 dprintk("%s: %u.%u.%u.%u NFSv4 callback!\n", __FUNCTION__, NIPQUAD(addr->sin_addr));
165 nfs4_put_client(clp); 178 nfs_put_client(clp);
166 switch (rqstp->rq_authop->flavour) { 179 switch (rqstp->rq_authop->flavour) {
167 case RPC_AUTH_NULL: 180 case RPC_AUTH_NULL:
168 if (rqstp->rq_proc != CB_NULL) 181 if (rqstp->rq_proc != CB_NULL)
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index b252e7fe53a5..5676163d26e8 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -62,8 +62,13 @@ struct cb_recallargs {
62extern unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); 62extern unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
63extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy); 63extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
64 64
65#ifdef CONFIG_NFS_V4
65extern int nfs_callback_up(void); 66extern int nfs_callback_up(void);
66extern int nfs_callback_down(void); 67extern void nfs_callback_down(void);
68#else
69#define nfs_callback_up() (0)
70#define nfs_callback_down() do {} while(0)
71#endif
67 72
68extern unsigned int nfs_callback_set_tcpport; 73extern unsigned int nfs_callback_set_tcpport;
69extern unsigned short nfs_callback_tcpport; 74extern unsigned short nfs_callback_tcpport;
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 7719483ecdfc..97cf8f71451f 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -10,19 +10,20 @@
10#include "nfs4_fs.h" 10#include "nfs4_fs.h"
11#include "callback.h" 11#include "callback.h"
12#include "delegation.h" 12#include "delegation.h"
13#include "internal.h"
13 14
14#define NFSDBG_FACILITY NFSDBG_CALLBACK 15#define NFSDBG_FACILITY NFSDBG_CALLBACK
15 16
16unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res) 17unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res)
17{ 18{
18 struct nfs4_client *clp; 19 struct nfs_client *clp;
19 struct nfs_delegation *delegation; 20 struct nfs_delegation *delegation;
20 struct nfs_inode *nfsi; 21 struct nfs_inode *nfsi;
21 struct inode *inode; 22 struct inode *inode;
22 23
23 res->bitmap[0] = res->bitmap[1] = 0; 24 res->bitmap[0] = res->bitmap[1] = 0;
24 res->status = htonl(NFS4ERR_BADHANDLE); 25 res->status = htonl(NFS4ERR_BADHANDLE);
25 clp = nfs4_find_client(&args->addr->sin_addr); 26 clp = nfs_find_client(args->addr, 4);
26 if (clp == NULL) 27 if (clp == NULL)
27 goto out; 28 goto out;
28 inode = nfs_delegation_find_inode(clp, &args->fh); 29 inode = nfs_delegation_find_inode(clp, &args->fh);
@@ -48,7 +49,7 @@ out_iput:
48 up_read(&nfsi->rwsem); 49 up_read(&nfsi->rwsem);
49 iput(inode); 50 iput(inode);
50out_putclient: 51out_putclient:
51 nfs4_put_client(clp); 52 nfs_put_client(clp);
52out: 53out:
53 dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status)); 54 dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res->status));
54 return res->status; 55 return res->status;
@@ -56,12 +57,12 @@ out:
56 57
57unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy) 58unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
58{ 59{
59 struct nfs4_client *clp; 60 struct nfs_client *clp;
60 struct inode *inode; 61 struct inode *inode;
61 unsigned res; 62 unsigned res;
62 63
63 res = htonl(NFS4ERR_BADHANDLE); 64 res = htonl(NFS4ERR_BADHANDLE);
64 clp = nfs4_find_client(&args->addr->sin_addr); 65 clp = nfs_find_client(args->addr, 4);
65 if (clp == NULL) 66 if (clp == NULL)
66 goto out; 67 goto out;
67 inode = nfs_delegation_find_inode(clp, &args->fh); 68 inode = nfs_delegation_find_inode(clp, &args->fh);
@@ -80,7 +81,7 @@ unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
80 } 81 }
81 iput(inode); 82 iput(inode);
82out_putclient: 83out_putclient:
83 nfs4_put_client(clp); 84 nfs_put_client(clp);
84out: 85out:
85 dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res)); 86 dprintk("%s: exit with status = %d\n", __FUNCTION__, ntohl(res));
86 return res; 87 return res;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
new file mode 100644
index 000000000000..ec1938d4b814
--- /dev/null
+++ b/fs/nfs/client.c
@@ -0,0 +1,1448 @@
1/* client.c: NFS client sharing and management code
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12
13#include <linux/config.h>
14#include <linux/module.h>
15#include <linux/init.h>
16
17#include <linux/time.h>
18#include <linux/kernel.h>
19#include <linux/mm.h>
20#include <linux/string.h>
21#include <linux/stat.h>
22#include <linux/errno.h>
23#include <linux/unistd.h>
24#include <linux/sunrpc/clnt.h>
25#include <linux/sunrpc/stats.h>
26#include <linux/sunrpc/metrics.h>
27#include <linux/nfs_fs.h>
28#include <linux/nfs_mount.h>
29#include <linux/nfs4_mount.h>
30#include <linux/lockd/bind.h>
31#include <linux/smp_lock.h>
32#include <linux/seq_file.h>
33#include <linux/mount.h>
34#include <linux/nfs_idmap.h>
35#include <linux/vfs.h>
36#include <linux/inet.h>
37#include <linux/nfs_xdr.h>
38
39#include <asm/system.h>
40
41#include "nfs4_fs.h"
42#include "callback.h"
43#include "delegation.h"
44#include "iostat.h"
45#include "internal.h"
46
47#define NFSDBG_FACILITY NFSDBG_CLIENT
48
49static DEFINE_SPINLOCK(nfs_client_lock);
50static LIST_HEAD(nfs_client_list);
51static LIST_HEAD(nfs_volume_list);
52static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
53
54/*
55 * RPC cruft for NFS
56 */
57static struct rpc_version *nfs_version[5] = {
58 [2] = &nfs_version2,
59#ifdef CONFIG_NFS_V3
60 [3] = &nfs_version3,
61#endif
62#ifdef CONFIG_NFS_V4
63 [4] = &nfs_version4,
64#endif
65};
66
67struct rpc_program nfs_program = {
68 .name = "nfs",
69 .number = NFS_PROGRAM,
70 .nrvers = ARRAY_SIZE(nfs_version),
71 .version = nfs_version,
72 .stats = &nfs_rpcstat,
73 .pipe_dir_name = "/nfs",
74};
75
76struct rpc_stat nfs_rpcstat = {
77 .program = &nfs_program
78};
79
80
81#ifdef CONFIG_NFS_V3_ACL
82static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
83static struct rpc_version * nfsacl_version[] = {
84 [3] = &nfsacl_version3,
85};
86
87struct rpc_program nfsacl_program = {
88 .name = "nfsacl",
89 .number = NFS_ACL_PROGRAM,
90 .nrvers = ARRAY_SIZE(nfsacl_version),
91 .version = nfsacl_version,
92 .stats = &nfsacl_rpcstat,
93};
94#endif /* CONFIG_NFS_V3_ACL */
95
96/*
97 * Allocate a shared client record
98 *
99 * Since these are allocated/deallocated very rarely, we don't
100 * bother putting them in a slab cache...
101 */
102static struct nfs_client *nfs_alloc_client(const char *hostname,
103 const struct sockaddr_in *addr,
104 int nfsversion)
105{
106 struct nfs_client *clp;
107 int error;
108
109 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
110 goto error_0;
111
112 error = rpciod_up();
113 if (error < 0) {
114 dprintk("%s: couldn't start rpciod! Error = %d\n",
115 __FUNCTION__, error);
116 goto error_1;
117 }
118 __set_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
119
120 if (nfsversion == 4) {
121 if (nfs_callback_up() < 0)
122 goto error_2;
123 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
124 }
125
126 atomic_set(&clp->cl_count, 1);
127 clp->cl_cons_state = NFS_CS_INITING;
128
129 clp->cl_nfsversion = nfsversion;
130 memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr));
131
132 if (hostname) {
133 clp->cl_hostname = kstrdup(hostname, GFP_KERNEL);
134 if (!clp->cl_hostname)
135 goto error_3;
136 }
137
138 INIT_LIST_HEAD(&clp->cl_superblocks);
139 clp->cl_rpcclient = ERR_PTR(-EINVAL);
140
141#ifdef CONFIG_NFS_V4
142 init_rwsem(&clp->cl_sem);
143 INIT_LIST_HEAD(&clp->cl_delegations);
144 INIT_LIST_HEAD(&clp->cl_state_owners);
145 INIT_LIST_HEAD(&clp->cl_unused);
146 spin_lock_init(&clp->cl_lock);
147 INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
148 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
149 clp->cl_boot_time = CURRENT_TIME;
150 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
151#endif
152
153 return clp;
154
155error_3:
156 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
157 nfs_callback_down();
158error_2:
159 rpciod_down();
160 __clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
161error_1:
162 kfree(clp);
163error_0:
164 return NULL;
165}
166
167static void nfs4_shutdown_client(struct nfs_client *clp)
168{
169#ifdef CONFIG_NFS_V4
170 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
171 nfs4_kill_renewd(clp);
172 while (!list_empty(&clp->cl_unused)) {
173 struct nfs4_state_owner *sp;
174
175 sp = list_entry(clp->cl_unused.next,
176 struct nfs4_state_owner,
177 so_list);
178 list_del(&sp->so_list);
179 kfree(sp);
180 }
181 BUG_ON(!list_empty(&clp->cl_state_owners));
182 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
183 nfs_idmap_delete(clp);
184#endif
185}
186
187/*
188 * Destroy a shared client record
189 */
190static void nfs_free_client(struct nfs_client *clp)
191{
192 dprintk("--> nfs_free_client(%d)\n", clp->cl_nfsversion);
193
194 nfs4_shutdown_client(clp);
195
196 /* -EIO all pending I/O */
197 if (!IS_ERR(clp->cl_rpcclient))
198 rpc_shutdown_client(clp->cl_rpcclient);
199
200 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
201 nfs_callback_down();
202
203 if (__test_and_clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state))
204 rpciod_down();
205
206 kfree(clp->cl_hostname);
207 kfree(clp);
208
209 dprintk("<-- nfs_free_client()\n");
210}
211
212/*
213 * Release a reference to a shared client record
214 */
215void nfs_put_client(struct nfs_client *clp)
216{
217 if (!clp)
218 return;
219
220 dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count));
221
222 if (atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock)) {
223 list_del(&clp->cl_share_link);
224 spin_unlock(&nfs_client_lock);
225
226 BUG_ON(!list_empty(&clp->cl_superblocks));
227
228 nfs_free_client(clp);
229 }
230}
231
232/*
233 * Find a client by address
234 * - caller must hold nfs_client_lock
235 */
236static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion)
237{
238 struct nfs_client *clp;
239
240 list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
241 /* Different NFS versions cannot share the same nfs_client */
242 if (clp->cl_nfsversion != nfsversion)
243 continue;
244
245 if (memcmp(&clp->cl_addr.sin_addr, &addr->sin_addr,
246 sizeof(clp->cl_addr.sin_addr)) != 0)
247 continue;
248
249 if (clp->cl_addr.sin_port == addr->sin_port)
250 goto found;
251 }
252
253 return NULL;
254
255found:
256 atomic_inc(&clp->cl_count);
257 return clp;
258}
259
260/*
261 * Find a client by IP address and protocol version
262 * - returns NULL if no such client
263 */
264struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion)
265{
266 struct nfs_client *clp;
267
268 spin_lock(&nfs_client_lock);
269 clp = __nfs_find_client(addr, nfsversion);
270 spin_unlock(&nfs_client_lock);
271
272 BUG_ON(clp && clp->cl_cons_state == 0);
273
274 return clp;
275}
276
277/*
278 * Look up a client by IP address and protocol version
279 * - creates a new record if one doesn't yet exist
280 */
281static struct nfs_client *nfs_get_client(const char *hostname,
282 const struct sockaddr_in *addr,
283 int nfsversion)
284{
285 struct nfs_client *clp, *new = NULL;
286 int error;
287
288 dprintk("--> nfs_get_client(%s,"NIPQUAD_FMT":%d,%d)\n",
289 hostname ?: "", NIPQUAD(addr->sin_addr),
290 addr->sin_port, nfsversion);
291
292 /* see if the client already exists */
293 do {
294 spin_lock(&nfs_client_lock);
295
296 clp = __nfs_find_client(addr, nfsversion);
297 if (clp)
298 goto found_client;
299 if (new)
300 goto install_client;
301
302 spin_unlock(&nfs_client_lock);
303
304 new = nfs_alloc_client(hostname, addr, nfsversion);
305 } while (new);
306
307 return ERR_PTR(-ENOMEM);
308
309 /* install a new client and return with it unready */
310install_client:
311 clp = new;
312 list_add(&clp->cl_share_link, &nfs_client_list);
313 spin_unlock(&nfs_client_lock);
314 dprintk("--> nfs_get_client() = %p [new]\n", clp);
315 return clp;
316
317 /* found an existing client
318 * - make sure it's ready before returning
319 */
320found_client:
321 spin_unlock(&nfs_client_lock);
322
323 if (new)
324 nfs_free_client(new);
325
326 if (clp->cl_cons_state == NFS_CS_INITING) {
327 DECLARE_WAITQUEUE(myself, current);
328
329 add_wait_queue(&nfs_client_active_wq, &myself);
330
331 for (;;) {
332 set_current_state(TASK_INTERRUPTIBLE);
333 if (signal_pending(current) ||
334 clp->cl_cons_state > NFS_CS_READY)
335 break;
336 schedule();
337 }
338
339 remove_wait_queue(&nfs_client_active_wq, &myself);
340
341 if (signal_pending(current)) {
342 nfs_put_client(clp);
343 return ERR_PTR(-ERESTARTSYS);
344 }
345 }
346
347 if (clp->cl_cons_state < NFS_CS_READY) {
348 error = clp->cl_cons_state;
349 nfs_put_client(clp);
350 return ERR_PTR(error);
351 }
352
353 BUG_ON(clp->cl_cons_state != NFS_CS_READY);
354
355 dprintk("--> nfs_get_client() = %p [share]\n", clp);
356 return clp;
357}
358
359/*
360 * Mark a server as ready or failed
361 */
362static void nfs_mark_client_ready(struct nfs_client *clp, int state)
363{
364 clp->cl_cons_state = state;
365 wake_up_all(&nfs_client_active_wq);
366}
367
368/*
369 * Initialise the timeout values for a connection
370 */
371static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
372 unsigned int timeo, unsigned int retrans)
373{
374 to->to_initval = timeo * HZ / 10;
375 to->to_retries = retrans;
376 if (!to->to_retries)
377 to->to_retries = 2;
378
379 switch (proto) {
380 case IPPROTO_TCP:
381 if (!to->to_initval)
382 to->to_initval = 60 * HZ;
383 if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
384 to->to_initval = NFS_MAX_TCP_TIMEOUT;
385 to->to_increment = to->to_initval;
386 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
387 to->to_exponential = 0;
388 break;
389 case IPPROTO_UDP:
390 default:
391 if (!to->to_initval)
392 to->to_initval = 11 * HZ / 10;
393 if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
394 to->to_initval = NFS_MAX_UDP_TIMEOUT;
395 to->to_maxval = NFS_MAX_UDP_TIMEOUT;
396 to->to_exponential = 1;
397 break;
398 }
399}
400
401/*
402 * Create an RPC client handle
403 */
404static int nfs_create_rpc_client(struct nfs_client *clp, int proto,
405 unsigned int timeo,
406 unsigned int retrans,
407 rpc_authflavor_t flavor)
408{
409 struct rpc_timeout timeparms;
410 struct rpc_clnt *clnt = NULL;
411 struct rpc_create_args args = {
412 .protocol = proto,
413 .address = (struct sockaddr *)&clp->cl_addr,
414 .addrsize = sizeof(clp->cl_addr),
415 .timeout = &timeparms,
416 .servername = clp->cl_hostname,
417 .program = &nfs_program,
418 .version = clp->rpc_ops->version,
419 .authflavor = flavor,
420 };
421
422 if (!IS_ERR(clp->cl_rpcclient))
423 return 0;
424
425 nfs_init_timeout_values(&timeparms, proto, timeo, retrans);
426 clp->retrans_timeo = timeparms.to_initval;
427 clp->retrans_count = timeparms.to_retries;
428
429 clnt = rpc_create(&args);
430 if (IS_ERR(clnt)) {
431 dprintk("%s: cannot create RPC client. Error = %ld\n",
432 __FUNCTION__, PTR_ERR(clnt));
433 return PTR_ERR(clnt);
434 }
435
436 clp->cl_rpcclient = clnt;
437 return 0;
438}
439
440/*
441 * Version 2 or 3 client destruction
442 */
443static void nfs_destroy_server(struct nfs_server *server)
444{
445 if (!IS_ERR(server->client_acl))
446 rpc_shutdown_client(server->client_acl);
447
448 if (!(server->flags & NFS_MOUNT_NONLM))
449 lockd_down(); /* release rpc.lockd */
450}
451
452/*
453 * Version 2 or 3 lockd setup
454 */
455static int nfs_start_lockd(struct nfs_server *server)
456{
457 int error = 0;
458
459 if (server->nfs_client->cl_nfsversion > 3)
460 goto out;
461 if (server->flags & NFS_MOUNT_NONLM)
462 goto out;
463 error = lockd_up();
464 if (error < 0)
465 server->flags |= NFS_MOUNT_NONLM;
466 else
467 server->destroy = nfs_destroy_server;
468out:
469 return error;
470}
471
472/*
473 * Initialise an NFSv3 ACL client connection
474 */
475#ifdef CONFIG_NFS_V3_ACL
476static void nfs_init_server_aclclient(struct nfs_server *server)
477{
478 if (server->nfs_client->cl_nfsversion != 3)
479 goto out_noacl;
480 if (server->flags & NFS_MOUNT_NOACL)
481 goto out_noacl;
482
483 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
484 if (IS_ERR(server->client_acl))
485 goto out_noacl;
486
487 /* No errors! Assume that Sun nfsacls are supported */
488 server->caps |= NFS_CAP_ACLS;
489 return;
490
491out_noacl:
492 server->caps &= ~NFS_CAP_ACLS;
493}
494#else
495static inline void nfs_init_server_aclclient(struct nfs_server *server)
496{
497 server->flags &= ~NFS_MOUNT_NOACL;
498 server->caps &= ~NFS_CAP_ACLS;
499}
500#endif
501
502/*
503 * Create a general RPC client
504 */
505static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t pseudoflavour)
506{
507 struct nfs_client *clp = server->nfs_client;
508
509 server->client = rpc_clone_client(clp->cl_rpcclient);
510 if (IS_ERR(server->client)) {
511 dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__);
512 return PTR_ERR(server->client);
513 }
514
515 if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {
516 struct rpc_auth *auth;
517
518 auth = rpcauth_create(pseudoflavour, server->client);
519 if (IS_ERR(auth)) {
520 dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
521 return PTR_ERR(auth);
522 }
523 }
524 server->client->cl_softrtry = 0;
525 if (server->flags & NFS_MOUNT_SOFT)
526 server->client->cl_softrtry = 1;
527
528 server->client->cl_intr = 0;
529 if (server->flags & NFS4_MOUNT_INTR)
530 server->client->cl_intr = 1;
531
532 return 0;
533}
534
535/*
536 * Initialise an NFS2 or NFS3 client
537 */
538static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data)
539{
540 int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
541 int error;
542
543 if (clp->cl_cons_state == NFS_CS_READY) {
544 /* the client is already initialised */
545 dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp);
546 return 0;
547 }
548
549 /* Check NFS protocol revision and initialize RPC op vector */
550 clp->rpc_ops = &nfs_v2_clientops;
551#ifdef CONFIG_NFS_V3
552 if (clp->cl_nfsversion == 3)
553 clp->rpc_ops = &nfs_v3_clientops;
554#endif
555 /*
556 * Create a client RPC handle for doing FSSTAT with UNIX auth only
557 * - RFC 2623, sec 2.3.2
558 */
559 error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans,
560 RPC_AUTH_UNIX);
561 if (error < 0)
562 goto error;
563 nfs_mark_client_ready(clp, NFS_CS_READY);
564 return 0;
565
566error:
567 nfs_mark_client_ready(clp, error);
568 dprintk("<-- nfs_init_client() = xerror %d\n", error);
569 return error;
570}
571
572/*
573 * Create a version 2 or 3 client
574 */
575static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data)
576{
577 struct nfs_client *clp;
578 int error, nfsvers = 2;
579
580 dprintk("--> nfs_init_server()\n");
581
582#ifdef CONFIG_NFS_V3
583 if (data->flags & NFS_MOUNT_VER3)
584 nfsvers = 3;
585#endif
586
587 /* Allocate or find a client reference we can use */
588 clp = nfs_get_client(data->hostname, &data->addr, nfsvers);
589 if (IS_ERR(clp)) {
590 dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
591 return PTR_ERR(clp);
592 }
593
594 error = nfs_init_client(clp, data);
595 if (error < 0)
596 goto error;
597
598 server->nfs_client = clp;
599
600 /* Initialise the client representation from the mount data */
601 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
602
603 if (data->rsize)
604 server->rsize = nfs_block_size(data->rsize, NULL);
605 if (data->wsize)
606 server->wsize = nfs_block_size(data->wsize, NULL);
607
608 server->acregmin = data->acregmin * HZ;
609 server->acregmax = data->acregmax * HZ;
610 server->acdirmin = data->acdirmin * HZ;
611 server->acdirmax = data->acdirmax * HZ;
612
613 /* Start lockd here, before we might error out */
614 error = nfs_start_lockd(server);
615 if (error < 0)
616 goto error;
617
618 error = nfs_init_server_rpcclient(server, data->pseudoflavor);
619 if (error < 0)
620 goto error;
621
622 server->namelen = data->namlen;
623 /* Create a client RPC handle for the NFSv3 ACL management interface */
624 nfs_init_server_aclclient(server);
625 if (clp->cl_nfsversion == 3) {
626 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
627 server->namelen = NFS3_MAXNAMLEN;
628 server->caps |= NFS_CAP_READDIRPLUS;
629 } else {
630 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
631 server->namelen = NFS2_MAXNAMLEN;
632 }
633
634 dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
635 return 0;
636
637error:
638 server->nfs_client = NULL;
639 nfs_put_client(clp);
640 dprintk("<-- nfs_init_server() = xerror %d\n", error);
641 return error;
642}
643
644/*
645 * Load up the server record from information gained in an fsinfo record
646 */
647static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *fsinfo)
648{
649 unsigned long max_rpc_payload;
650
651 /* Work out a lot of parameters */
652 if (server->rsize == 0)
653 server->rsize = nfs_block_size(fsinfo->rtpref, NULL);
654 if (server->wsize == 0)
655 server->wsize = nfs_block_size(fsinfo->wtpref, NULL);
656
657 if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)
658 server->rsize = nfs_block_size(fsinfo->rtmax, NULL);
659 if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
660 server->wsize = nfs_block_size(fsinfo->wtmax, NULL);
661
662 max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
663 if (server->rsize > max_rpc_payload)
664 server->rsize = max_rpc_payload;
665 if (server->rsize > NFS_MAX_FILE_IO_SIZE)
666 server->rsize = NFS_MAX_FILE_IO_SIZE;
667 server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
668 server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
669
670 if (server->wsize > max_rpc_payload)
671 server->wsize = max_rpc_payload;
672 if (server->wsize > NFS_MAX_FILE_IO_SIZE)
673 server->wsize = NFS_MAX_FILE_IO_SIZE;
674 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
675 server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
676
677 server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);
678 if (server->dtsize > PAGE_CACHE_SIZE)
679 server->dtsize = PAGE_CACHE_SIZE;
680 if (server->dtsize > server->rsize)
681 server->dtsize = server->rsize;
682
683 if (server->flags & NFS_MOUNT_NOAC) {
684 server->acregmin = server->acregmax = 0;
685 server->acdirmin = server->acdirmax = 0;
686 }
687
688 server->maxfilesize = fsinfo->maxfilesize;
689
690 /* We're airborne Set socket buffersize */
691 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
692}
693
694/*
695 * Probe filesystem information, including the FSID on v2/v3
696 */
697static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
698{
699 struct nfs_fsinfo fsinfo;
700 struct nfs_client *clp = server->nfs_client;
701 int error;
702
703 dprintk("--> nfs_probe_fsinfo()\n");
704
705 if (clp->rpc_ops->set_capabilities != NULL) {
706 error = clp->rpc_ops->set_capabilities(server, mntfh);
707 if (error < 0)
708 goto out_error;
709 }
710
711 fsinfo.fattr = fattr;
712 nfs_fattr_init(fattr);
713 error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
714 if (error < 0)
715 goto out_error;
716
717 nfs_server_set_fsinfo(server, &fsinfo);
718
719 /* Get some general file system info */
720 if (server->namelen == 0) {
721 struct nfs_pathconf pathinfo;
722
723 pathinfo.fattr = fattr;
724 nfs_fattr_init(fattr);
725
726 if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)
727 server->namelen = pathinfo.max_namelen;
728 }
729
730 dprintk("<-- nfs_probe_fsinfo() = 0\n");
731 return 0;
732
733out_error:
734 dprintk("nfs_probe_fsinfo: error = %d\n", -error);
735 return error;
736}
737
738/*
739 * Copy useful information when duplicating a server record
740 */
741static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
742{
743 target->flags = source->flags;
744 target->acregmin = source->acregmin;
745 target->acregmax = source->acregmax;
746 target->acdirmin = source->acdirmin;
747 target->acdirmax = source->acdirmax;
748 target->caps = source->caps;
749}
750
751/*
752 * Allocate and initialise a server record
753 */
754static struct nfs_server *nfs_alloc_server(void)
755{
756 struct nfs_server *server;
757
758 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
759 if (!server)
760 return NULL;
761
762 server->client = server->client_acl = ERR_PTR(-EINVAL);
763
764 /* Zero out the NFS state stuff */
765 INIT_LIST_HEAD(&server->client_link);
766 INIT_LIST_HEAD(&server->master_link);
767
768 server->io_stats = nfs_alloc_iostats();
769 if (!server->io_stats) {
770 kfree(server);
771 return NULL;
772 }
773
774 return server;
775}
776
777/*
778 * Free up a server record
779 */
780void nfs_free_server(struct nfs_server *server)
781{
782 dprintk("--> nfs_free_server()\n");
783
784 spin_lock(&nfs_client_lock);
785 list_del(&server->client_link);
786 list_del(&server->master_link);
787 spin_unlock(&nfs_client_lock);
788
789 if (server->destroy != NULL)
790 server->destroy(server);
791 if (!IS_ERR(server->client))
792 rpc_shutdown_client(server->client);
793
794 nfs_put_client(server->nfs_client);
795
796 nfs_free_iostats(server->io_stats);
797 kfree(server);
798 nfs_release_automount_timer();
799 dprintk("<-- nfs_free_server()\n");
800}
801
802/*
803 * Create a version 2 or 3 volume record
804 * - keyed on server and FSID
805 */
806struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
807 struct nfs_fh *mntfh)
808{
809 struct nfs_server *server;
810 struct nfs_fattr fattr;
811 int error;
812
813 server = nfs_alloc_server();
814 if (!server)
815 return ERR_PTR(-ENOMEM);
816
817 /* Get a client representation */
818 error = nfs_init_server(server, data);
819 if (error < 0)
820 goto error;
821
822 BUG_ON(!server->nfs_client);
823 BUG_ON(!server->nfs_client->rpc_ops);
824 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
825
826 /* Probe the root fh to retrieve its FSID */
827 error = nfs_probe_fsinfo(server, mntfh, &fattr);
828 if (error < 0)
829 goto error;
830 if (!(fattr.valid & NFS_ATTR_FATTR)) {
831 error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
832 if (error < 0) {
833 dprintk("nfs_create_server: getattr error = %d\n", -error);
834 goto error;
835 }
836 }
837 memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
838
839 dprintk("Server FSID: %llx:%llx\n",
840 (unsigned long long) server->fsid.major,
841 (unsigned long long) server->fsid.minor);
842
843 BUG_ON(!server->nfs_client);
844 BUG_ON(!server->nfs_client->rpc_ops);
845 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
846
847 spin_lock(&nfs_client_lock);
848 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
849 list_add_tail(&server->master_link, &nfs_volume_list);
850 spin_unlock(&nfs_client_lock);
851
852 server->mount_time = jiffies;
853 return server;
854
855error:
856 nfs_free_server(server);
857 return ERR_PTR(error);
858}
859
860#ifdef CONFIG_NFS_V4
861/*
862 * Initialise an NFS4 client record
863 */
864static int nfs4_init_client(struct nfs_client *clp,
865 int proto, int timeo, int retrans,
866 rpc_authflavor_t authflavour)
867{
868 int error;
869
870 if (clp->cl_cons_state == NFS_CS_READY) {
871 /* the client is initialised already */
872 dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);
873 return 0;
874 }
875
876 /* Check NFS protocol revision and initialize RPC op vector */
877 clp->rpc_ops = &nfs_v4_clientops;
878
879 error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour);
880 if (error < 0)
881 goto error;
882
883 error = nfs_idmap_new(clp);
884 if (error < 0) {
885 dprintk("%s: failed to create idmapper. Error = %d\n",
886 __FUNCTION__, error);
887 goto error;
888 }
889 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
890
891 nfs_mark_client_ready(clp, NFS_CS_READY);
892 return 0;
893
894error:
895 nfs_mark_client_ready(clp, error);
896 dprintk("<-- nfs4_init_client() = xerror %d\n", error);
897 return error;
898}
899
900/*
901 * Set up an NFS4 client
902 */
903static int nfs4_set_client(struct nfs_server *server,
904 const char *hostname, const struct sockaddr_in *addr,
905 rpc_authflavor_t authflavour,
906 int proto, int timeo, int retrans)
907{
908 struct nfs_client *clp;
909 int error;
910
911 dprintk("--> nfs4_set_client()\n");
912
913 /* Allocate or find a client reference we can use */
914 clp = nfs_get_client(hostname, addr, 4);
915 if (IS_ERR(clp)) {
916 error = PTR_ERR(clp);
917 goto error;
918 }
919 error = nfs4_init_client(clp, proto, timeo, retrans, authflavour);
920 if (error < 0)
921 goto error_put;
922
923 server->nfs_client = clp;
924 dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp);
925 return 0;
926
927error_put:
928 nfs_put_client(clp);
929error:
930 dprintk("<-- nfs4_set_client() = xerror %d\n", error);
931 return error;
932}
933
934/*
935 * Create a version 4 volume record
936 */
937static int nfs4_init_server(struct nfs_server *server,
938 const struct nfs4_mount_data *data, rpc_authflavor_t authflavour)
939{
940 int error;
941
942 dprintk("--> nfs4_init_server()\n");
943
944 /* Initialise the client representation from the mount data */
945 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
946 server->caps |= NFS_CAP_ATOMIC_OPEN;
947
948 if (data->rsize)
949 server->rsize = nfs_block_size(data->rsize, NULL);
950 if (data->wsize)
951 server->wsize = nfs_block_size(data->wsize, NULL);
952
953 server->acregmin = data->acregmin * HZ;
954 server->acregmax = data->acregmax * HZ;
955 server->acdirmin = data->acdirmin * HZ;
956 server->acdirmax = data->acdirmax * HZ;
957
958 error = nfs_init_server_rpcclient(server, authflavour);
959
960 /* Done */
961 dprintk("<-- nfs4_init_server() = %d\n", error);
962 return error;
963}
964
965/*
966 * Create a version 4 volume record
967 * - keyed on server and FSID
968 */
969struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
970 const char *hostname,
971 const struct sockaddr_in *addr,
972 const char *mntpath,
973 const char *ip_addr,
974 rpc_authflavor_t authflavour,
975 struct nfs_fh *mntfh)
976{
977 struct nfs_fattr fattr;
978 struct nfs_server *server;
979 int error;
980
981 dprintk("--> nfs4_create_server()\n");
982
983 server = nfs_alloc_server();
984 if (!server)
985 return ERR_PTR(-ENOMEM);
986
987 /* Get a client record */
988 error = nfs4_set_client(server, hostname, addr, authflavour,
989 data->proto, data->timeo, data->retrans);
990 if (error < 0)
991 goto error;
992
993 /* set up the general RPC client */
994 error = nfs4_init_server(server, data, authflavour);
995 if (error < 0)
996 goto error;
997
998 BUG_ON(!server->nfs_client);
999 BUG_ON(!server->nfs_client->rpc_ops);
1000 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1001
1002 /* Probe the root fh to retrieve its FSID */
1003 error = nfs4_path_walk(server, mntfh, mntpath);
1004 if (error < 0)
1005 goto error;
1006
1007 dprintk("Server FSID: %llx:%llx\n",
1008 (unsigned long long) server->fsid.major,
1009 (unsigned long long) server->fsid.minor);
1010 dprintk("Mount FH: %d\n", mntfh->size);
1011
1012 error = nfs_probe_fsinfo(server, mntfh, &fattr);
1013 if (error < 0)
1014 goto error;
1015
1016 BUG_ON(!server->nfs_client);
1017 BUG_ON(!server->nfs_client->rpc_ops);
1018 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1019
1020 spin_lock(&nfs_client_lock);
1021 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1022 list_add_tail(&server->master_link, &nfs_volume_list);
1023 spin_unlock(&nfs_client_lock);
1024
1025 server->mount_time = jiffies;
1026 dprintk("<-- nfs4_create_server() = %p\n", server);
1027 return server;
1028
1029error:
1030 nfs_free_server(server);
1031 dprintk("<-- nfs4_create_server() = error %d\n", error);
1032 return ERR_PTR(error);
1033}
1034
1035/*
1036 * Create an NFS4 referral server record
1037 */
1038struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1039 struct nfs_fh *fh)
1040{
1041 struct nfs_client *parent_client;
1042 struct nfs_server *server, *parent_server;
1043 struct nfs_fattr fattr;
1044 int error;
1045
1046 dprintk("--> nfs4_create_referral_server()\n");
1047
1048 server = nfs_alloc_server();
1049 if (!server)
1050 return ERR_PTR(-ENOMEM);
1051
1052 parent_server = NFS_SB(data->sb);
1053 parent_client = parent_server->nfs_client;
1054
1055 /* Get a client representation.
1056 * Note: NFSv4 always uses TCP, */
1057 error = nfs4_set_client(server, data->hostname, data->addr,
1058 data->authflavor,
1059 parent_server->client->cl_xprt->prot,
1060 parent_client->retrans_timeo,
1061 parent_client->retrans_count);
1062 if (error < 0)
1063 goto error;
1064
1065 /* Initialise the client representation from the parent server */
1066 nfs_server_copy_userdata(server, parent_server);
1067 server->caps |= NFS_CAP_ATOMIC_OPEN;
1068
1069 error = nfs_init_server_rpcclient(server, data->authflavor);
1070 if (error < 0)
1071 goto error;
1072
1073 BUG_ON(!server->nfs_client);
1074 BUG_ON(!server->nfs_client->rpc_ops);
1075 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1076
1077 /* probe the filesystem info for this server filesystem */
1078 error = nfs_probe_fsinfo(server, fh, &fattr);
1079 if (error < 0)
1080 goto error;
1081
1082 dprintk("Referral FSID: %llx:%llx\n",
1083 (unsigned long long) server->fsid.major,
1084 (unsigned long long) server->fsid.minor);
1085
1086 spin_lock(&nfs_client_lock);
1087 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1088 list_add_tail(&server->master_link, &nfs_volume_list);
1089 spin_unlock(&nfs_client_lock);
1090
1091 server->mount_time = jiffies;
1092
1093 dprintk("<-- nfs_create_referral_server() = %p\n", server);
1094 return server;
1095
1096error:
1097 nfs_free_server(server);
1098 dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
1099 return ERR_PTR(error);
1100}
1101
1102#endif /* CONFIG_NFS_V4 */
1103
1104/*
1105 * Clone an NFS2, NFS3 or NFS4 server record
1106 */
1107struct nfs_server *nfs_clone_server(struct nfs_server *source,
1108 struct nfs_fh *fh,
1109 struct nfs_fattr *fattr)
1110{
1111 struct nfs_server *server;
1112 struct nfs_fattr fattr_fsinfo;
1113 int error;
1114
1115 dprintk("--> nfs_clone_server(,%llx:%llx,)\n",
1116 (unsigned long long) fattr->fsid.major,
1117 (unsigned long long) fattr->fsid.minor);
1118
1119 server = nfs_alloc_server();
1120 if (!server)
1121 return ERR_PTR(-ENOMEM);
1122
1123 /* Copy data from the source */
1124 server->nfs_client = source->nfs_client;
1125 atomic_inc(&server->nfs_client->cl_count);
1126 nfs_server_copy_userdata(server, source);
1127
1128 server->fsid = fattr->fsid;
1129
1130 error = nfs_init_server_rpcclient(server, source->client->cl_auth->au_flavor);
1131 if (error < 0)
1132 goto out_free_server;
1133 if (!IS_ERR(source->client_acl))
1134 nfs_init_server_aclclient(server);
1135
1136 /* probe the filesystem info for this server filesystem */
1137 error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo);
1138 if (error < 0)
1139 goto out_free_server;
1140
1141 dprintk("Cloned FSID: %llx:%llx\n",
1142 (unsigned long long) server->fsid.major,
1143 (unsigned long long) server->fsid.minor);
1144
1145 error = nfs_start_lockd(server);
1146 if (error < 0)
1147 goto out_free_server;
1148
1149 spin_lock(&nfs_client_lock);
1150 list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
1151 list_add_tail(&server->master_link, &nfs_volume_list);
1152 spin_unlock(&nfs_client_lock);
1153
1154 server->mount_time = jiffies;
1155
1156 dprintk("<-- nfs_clone_server() = %p\n", server);
1157 return server;
1158
1159out_free_server:
1160 nfs_free_server(server);
1161 dprintk("<-- nfs_clone_server() = error %d\n", error);
1162 return ERR_PTR(error);
1163}
1164
1165#ifdef CONFIG_PROC_FS
1166static struct proc_dir_entry *proc_fs_nfs;
1167
1168static int nfs_server_list_open(struct inode *inode, struct file *file);
1169static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
1170static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
1171static void nfs_server_list_stop(struct seq_file *p, void *v);
1172static int nfs_server_list_show(struct seq_file *m, void *v);
1173
1174static struct seq_operations nfs_server_list_ops = {
1175 .start = nfs_server_list_start,
1176 .next = nfs_server_list_next,
1177 .stop = nfs_server_list_stop,
1178 .show = nfs_server_list_show,
1179};
1180
1181static struct file_operations nfs_server_list_fops = {
1182 .open = nfs_server_list_open,
1183 .read = seq_read,
1184 .llseek = seq_lseek,
1185 .release = seq_release,
1186};
1187
1188static int nfs_volume_list_open(struct inode *inode, struct file *file);
1189static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
1190static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
1191static void nfs_volume_list_stop(struct seq_file *p, void *v);
1192static int nfs_volume_list_show(struct seq_file *m, void *v);
1193
1194static struct seq_operations nfs_volume_list_ops = {
1195 .start = nfs_volume_list_start,
1196 .next = nfs_volume_list_next,
1197 .stop = nfs_volume_list_stop,
1198 .show = nfs_volume_list_show,
1199};
1200
1201static struct file_operations nfs_volume_list_fops = {
1202 .open = nfs_volume_list_open,
1203 .read = seq_read,
1204 .llseek = seq_lseek,
1205 .release = seq_release,
1206};
1207
1208/*
1209 * open "/proc/fs/nfsfs/servers" which provides a summary of servers with which
1210 * we're dealing
1211 */
1212static int nfs_server_list_open(struct inode *inode, struct file *file)
1213{
1214 struct seq_file *m;
1215 int ret;
1216
1217 ret = seq_open(file, &nfs_server_list_ops);
1218 if (ret < 0)
1219 return ret;
1220
1221 m = file->private_data;
1222 m->private = PDE(inode)->data;
1223
1224 return 0;
1225}
1226
1227/*
1228 * set up the iterator to start reading from the server list and return the first item
1229 */
1230static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
1231{
1232 struct list_head *_p;
1233 loff_t pos = *_pos;
1234
1235 /* lock the list against modification */
1236 spin_lock(&nfs_client_lock);
1237
1238 /* allow for the header line */
1239 if (!pos)
1240 return SEQ_START_TOKEN;
1241 pos--;
1242
1243 /* find the n'th element in the list */
1244 list_for_each(_p, &nfs_client_list)
1245 if (!pos--)
1246 break;
1247
1248 return _p != &nfs_client_list ? _p : NULL;
1249}
1250
1251/*
1252 * move to next server
1253 */
1254static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
1255{
1256 struct list_head *_p;
1257
1258 (*pos)++;
1259
1260 _p = v;
1261 _p = (v == SEQ_START_TOKEN) ? nfs_client_list.next : _p->next;
1262
1263 return _p != &nfs_client_list ? _p : NULL;
1264}
1265
1266/*
1267 * clean up after reading from the transports list
1268 */
1269static void nfs_server_list_stop(struct seq_file *p, void *v)
1270{
1271 spin_unlock(&nfs_client_lock);
1272}
1273
1274/*
1275 * display a header line followed by a load of call lines
1276 */
1277static int nfs_server_list_show(struct seq_file *m, void *v)
1278{
1279 struct nfs_client *clp;
1280
1281 /* display header on line 1 */
1282 if (v == SEQ_START_TOKEN) {
1283 seq_puts(m, "NV SERVER PORT USE HOSTNAME\n");
1284 return 0;
1285 }
1286
1287 /* display one transport per line on subsequent lines */
1288 clp = list_entry(v, struct nfs_client, cl_share_link);
1289
1290 seq_printf(m, "v%d %02x%02x%02x%02x %4hx %3d %s\n",
1291 clp->cl_nfsversion,
1292 NIPQUAD(clp->cl_addr.sin_addr),
1293 ntohs(clp->cl_addr.sin_port),
1294 atomic_read(&clp->cl_count),
1295 clp->cl_hostname);
1296
1297 return 0;
1298}
1299
1300/*
1301 * open "/proc/fs/nfsfs/volumes" which provides a summary of extant volumes
1302 */
1303static int nfs_volume_list_open(struct inode *inode, struct file *file)
1304{
1305 struct seq_file *m;
1306 int ret;
1307
1308 ret = seq_open(file, &nfs_volume_list_ops);
1309 if (ret < 0)
1310 return ret;
1311
1312 m = file->private_data;
1313 m->private = PDE(inode)->data;
1314
1315 return 0;
1316}
1317
1318/*
1319 * set up the iterator to start reading from the volume list and return the first item
1320 */
1321static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
1322{
1323 struct list_head *_p;
1324 loff_t pos = *_pos;
1325
1326 /* lock the list against modification */
1327 spin_lock(&nfs_client_lock);
1328
1329 /* allow for the header line */
1330 if (!pos)
1331 return SEQ_START_TOKEN;
1332 pos--;
1333
1334 /* find the n'th element in the list */
1335 list_for_each(_p, &nfs_volume_list)
1336 if (!pos--)
1337 break;
1338
1339 return _p != &nfs_volume_list ? _p : NULL;
1340}
1341
1342/*
1343 * move to next volume
1344 */
1345static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
1346{
1347 struct list_head *_p;
1348
1349 (*pos)++;
1350
1351 _p = v;
1352 _p = (v == SEQ_START_TOKEN) ? nfs_volume_list.next : _p->next;
1353
1354 return _p != &nfs_volume_list ? _p : NULL;
1355}
1356
1357/*
1358 * clean up after reading from the transports list
1359 */
1360static void nfs_volume_list_stop(struct seq_file *p, void *v)
1361{
1362 spin_unlock(&nfs_client_lock);
1363}
1364
1365/*
1366 * display a header line followed by a load of call lines
1367 */
1368static int nfs_volume_list_show(struct seq_file *m, void *v)
1369{
1370 struct nfs_server *server;
1371 struct nfs_client *clp;
1372 char dev[8], fsid[17];
1373
1374 /* display header on line 1 */
1375 if (v == SEQ_START_TOKEN) {
1376 seq_puts(m, "NV SERVER PORT DEV FSID\n");
1377 return 0;
1378 }
1379 /* display one transport per line on subsequent lines */
1380 server = list_entry(v, struct nfs_server, master_link);
1381 clp = server->nfs_client;
1382
1383 snprintf(dev, 8, "%u:%u",
1384 MAJOR(server->s_dev), MINOR(server->s_dev));
1385
1386 snprintf(fsid, 17, "%llx:%llx",
1387 (unsigned long long) server->fsid.major,
1388 (unsigned long long) server->fsid.minor);
1389
1390 seq_printf(m, "v%d %02x%02x%02x%02x %4hx %-7s %-17s\n",
1391 clp->cl_nfsversion,
1392 NIPQUAD(clp->cl_addr.sin_addr),
1393 ntohs(clp->cl_addr.sin_port),
1394 dev,
1395 fsid);
1396
1397 return 0;
1398}
1399
1400/*
1401 * initialise the /proc/fs/nfsfs/ directory
1402 */
1403int __init nfs_fs_proc_init(void)
1404{
1405 struct proc_dir_entry *p;
1406
1407 proc_fs_nfs = proc_mkdir("nfsfs", proc_root_fs);
1408 if (!proc_fs_nfs)
1409 goto error_0;
1410
1411 proc_fs_nfs->owner = THIS_MODULE;
1412
1413 /* a file of servers with which we're dealing */
1414 p = create_proc_entry("servers", S_IFREG|S_IRUGO, proc_fs_nfs);
1415 if (!p)
1416 goto error_1;
1417
1418 p->proc_fops = &nfs_server_list_fops;
1419 p->owner = THIS_MODULE;
1420
1421 /* a file of volumes that we have mounted */
1422 p = create_proc_entry("volumes", S_IFREG|S_IRUGO, proc_fs_nfs);
1423 if (!p)
1424 goto error_2;
1425
1426 p->proc_fops = &nfs_volume_list_fops;
1427 p->owner = THIS_MODULE;
1428 return 0;
1429
1430error_2:
1431 remove_proc_entry("servers", proc_fs_nfs);
1432error_1:
1433 remove_proc_entry("nfsfs", proc_root_fs);
1434error_0:
1435 return -ENOMEM;
1436}
1437
1438/*
1439 * clean up the /proc/fs/nfsfs/ directory
1440 */
1441void nfs_fs_proc_exit(void)
1442{
1443 remove_proc_entry("volumes", proc_fs_nfs);
1444 remove_proc_entry("servers", proc_fs_nfs);
1445 remove_proc_entry("nfsfs", proc_root_fs);
1446}
1447
1448#endif /* CONFIG_PROC_FS */
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 9540a316c05e..57133678db16 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -18,6 +18,7 @@
18 18
19#include "nfs4_fs.h" 19#include "nfs4_fs.h"
20#include "delegation.h" 20#include "delegation.h"
21#include "internal.h"
21 22
22static struct nfs_delegation *nfs_alloc_delegation(void) 23static struct nfs_delegation *nfs_alloc_delegation(void)
23{ 24{
@@ -52,7 +53,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
52 case -NFS4ERR_EXPIRED: 53 case -NFS4ERR_EXPIRED:
53 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 54 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
54 case -NFS4ERR_STALE_CLIENTID: 55 case -NFS4ERR_STALE_CLIENTID:
55 nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs4_state); 56 nfs4_schedule_state_recovery(NFS_SERVER(inode)->nfs_client);
56 goto out_err; 57 goto out_err;
57 } 58 }
58 } 59 }
@@ -114,7 +115,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st
114 */ 115 */
115int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) 116int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
116{ 117{
117 struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; 118 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
118 struct nfs_inode *nfsi = NFS_I(inode); 119 struct nfs_inode *nfsi = NFS_I(inode);
119 struct nfs_delegation *delegation; 120 struct nfs_delegation *delegation;
120 int status = 0; 121 int status = 0;
@@ -145,7 +146,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
145 sizeof(delegation->stateid)) != 0 || 146 sizeof(delegation->stateid)) != 0 ||
146 delegation->type != nfsi->delegation->type) { 147 delegation->type != nfsi->delegation->type) {
147 printk("%s: server %u.%u.%u.%u, handed out a duplicate delegation!\n", 148 printk("%s: server %u.%u.%u.%u, handed out a duplicate delegation!\n",
148 __FUNCTION__, NIPQUAD(clp->cl_addr)); 149 __FUNCTION__, NIPQUAD(clp->cl_addr.sin_addr));
149 status = -EIO; 150 status = -EIO;
150 } 151 }
151 } 152 }
@@ -176,7 +177,7 @@ static void nfs_msync_inode(struct inode *inode)
176 */ 177 */
177int __nfs_inode_return_delegation(struct inode *inode) 178int __nfs_inode_return_delegation(struct inode *inode)
178{ 179{
179 struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; 180 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
180 struct nfs_inode *nfsi = NFS_I(inode); 181 struct nfs_inode *nfsi = NFS_I(inode);
181 struct nfs_delegation *delegation; 182 struct nfs_delegation *delegation;
182 int res = 0; 183 int res = 0;
@@ -208,7 +209,7 @@ int __nfs_inode_return_delegation(struct inode *inode)
208 */ 209 */
209void nfs_return_all_delegations(struct super_block *sb) 210void nfs_return_all_delegations(struct super_block *sb)
210{ 211{
211 struct nfs4_client *clp = NFS_SB(sb)->nfs4_state; 212 struct nfs_client *clp = NFS_SB(sb)->nfs_client;
212 struct nfs_delegation *delegation; 213 struct nfs_delegation *delegation;
213 struct inode *inode; 214 struct inode *inode;
214 215
@@ -232,7 +233,7 @@ restart:
232 233
233int nfs_do_expire_all_delegations(void *ptr) 234int nfs_do_expire_all_delegations(void *ptr)
234{ 235{
235 struct nfs4_client *clp = ptr; 236 struct nfs_client *clp = ptr;
236 struct nfs_delegation *delegation; 237 struct nfs_delegation *delegation;
237 struct inode *inode; 238 struct inode *inode;
238 239
@@ -254,11 +255,11 @@ restart:
254 } 255 }
255out: 256out:
256 spin_unlock(&clp->cl_lock); 257 spin_unlock(&clp->cl_lock);
257 nfs4_put_client(clp); 258 nfs_put_client(clp);
258 module_put_and_exit(0); 259 module_put_and_exit(0);
259} 260}
260 261
261void nfs_expire_all_delegations(struct nfs4_client *clp) 262void nfs_expire_all_delegations(struct nfs_client *clp)
262{ 263{
263 struct task_struct *task; 264 struct task_struct *task;
264 265
@@ -266,17 +267,17 @@ void nfs_expire_all_delegations(struct nfs4_client *clp)
266 atomic_inc(&clp->cl_count); 267 atomic_inc(&clp->cl_count);
267 task = kthread_run(nfs_do_expire_all_delegations, clp, 268 task = kthread_run(nfs_do_expire_all_delegations, clp,
268 "%u.%u.%u.%u-delegreturn", 269 "%u.%u.%u.%u-delegreturn",
269 NIPQUAD(clp->cl_addr)); 270 NIPQUAD(clp->cl_addr.sin_addr));
270 if (!IS_ERR(task)) 271 if (!IS_ERR(task))
271 return; 272 return;
272 nfs4_put_client(clp); 273 nfs_put_client(clp);
273 module_put(THIS_MODULE); 274 module_put(THIS_MODULE);
274} 275}
275 276
276/* 277/*
277 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. 278 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
278 */ 279 */
279void nfs_handle_cb_pathdown(struct nfs4_client *clp) 280void nfs_handle_cb_pathdown(struct nfs_client *clp)
280{ 281{
281 struct nfs_delegation *delegation; 282 struct nfs_delegation *delegation;
282 struct inode *inode; 283 struct inode *inode;
@@ -299,7 +300,7 @@ restart:
299 300
300struct recall_threadargs { 301struct recall_threadargs {
301 struct inode *inode; 302 struct inode *inode;
302 struct nfs4_client *clp; 303 struct nfs_client *clp;
303 const nfs4_stateid *stateid; 304 const nfs4_stateid *stateid;
304 305
305 struct completion started; 306 struct completion started;
@@ -310,7 +311,7 @@ static int recall_thread(void *data)
310{ 311{
311 struct recall_threadargs *args = (struct recall_threadargs *)data; 312 struct recall_threadargs *args = (struct recall_threadargs *)data;
312 struct inode *inode = igrab(args->inode); 313 struct inode *inode = igrab(args->inode);
313 struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; 314 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
314 struct nfs_inode *nfsi = NFS_I(inode); 315 struct nfs_inode *nfsi = NFS_I(inode);
315 struct nfs_delegation *delegation; 316 struct nfs_delegation *delegation;
316 317
@@ -371,7 +372,7 @@ out_module_put:
371/* 372/*
372 * Retrieve the inode associated with a delegation 373 * Retrieve the inode associated with a delegation
373 */ 374 */
374struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle) 375struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle)
375{ 376{
376 struct nfs_delegation *delegation; 377 struct nfs_delegation *delegation;
377 struct inode *res = NULL; 378 struct inode *res = NULL;
@@ -389,7 +390,7 @@ struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nf
389/* 390/*
390 * Mark all delegations as needing to be reclaimed 391 * Mark all delegations as needing to be reclaimed
391 */ 392 */
392void nfs_delegation_mark_reclaim(struct nfs4_client *clp) 393void nfs_delegation_mark_reclaim(struct nfs_client *clp)
393{ 394{
394 struct nfs_delegation *delegation; 395 struct nfs_delegation *delegation;
395 spin_lock(&clp->cl_lock); 396 spin_lock(&clp->cl_lock);
@@ -401,7 +402,7 @@ void nfs_delegation_mark_reclaim(struct nfs4_client *clp)
401/* 402/*
402 * Reap all unclaimed delegations after reboot recovery is done 403 * Reap all unclaimed delegations after reboot recovery is done
403 */ 404 */
404void nfs_delegation_reap_unclaimed(struct nfs4_client *clp) 405void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
405{ 406{
406 struct nfs_delegation *delegation, *n; 407 struct nfs_delegation *delegation, *n;
407 LIST_HEAD(head); 408 LIST_HEAD(head);
@@ -423,7 +424,7 @@ void nfs_delegation_reap_unclaimed(struct nfs4_client *clp)
423 424
424int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode) 425int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
425{ 426{
426 struct nfs4_client *clp = NFS_SERVER(inode)->nfs4_state; 427 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
427 struct nfs_inode *nfsi = NFS_I(inode); 428 struct nfs_inode *nfsi = NFS_I(inode);
428 struct nfs_delegation *delegation; 429 struct nfs_delegation *delegation;
429 int res = 0; 430 int res = 0;
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 3858694652fa..2cfd4b24c7fe 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -29,13 +29,13 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st
29int __nfs_inode_return_delegation(struct inode *inode); 29int __nfs_inode_return_delegation(struct inode *inode);
30int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid); 30int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
31 31
32struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle); 32struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
33void nfs_return_all_delegations(struct super_block *sb); 33void nfs_return_all_delegations(struct super_block *sb);
34void nfs_expire_all_delegations(struct nfs4_client *clp); 34void nfs_expire_all_delegations(struct nfs_client *clp);
35void nfs_handle_cb_pathdown(struct nfs4_client *clp); 35void nfs_handle_cb_pathdown(struct nfs_client *clp);
36 36
37void nfs_delegation_mark_reclaim(struct nfs4_client *clp); 37void nfs_delegation_mark_reclaim(struct nfs_client *clp);
38void nfs_delegation_reap_unclaimed(struct nfs4_client *clp); 38void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
39 39
40/* NFSv4 delegation-related procedures */ 40/* NFSv4 delegation-related procedures */
41int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid); 41int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e7ffb4deb3e5..3419c2da9ba9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -30,7 +30,9 @@
30#include <linux/nfs_mount.h> 30#include <linux/nfs_mount.h>
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
33#include <linux/pagevec.h>
33#include <linux/namei.h> 34#include <linux/namei.h>
35#include <linux/mount.h>
34 36
35#include "nfs4_fs.h" 37#include "nfs4_fs.h"
36#include "delegation.h" 38#include "delegation.h"
@@ -870,14 +872,14 @@ int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
870 return (nd->intent.open.flags & O_EXCL) != 0; 872 return (nd->intent.open.flags & O_EXCL) != 0;
871} 873}
872 874
873static inline int nfs_reval_fsid(struct inode *dir, 875static inline int nfs_reval_fsid(struct vfsmount *mnt, struct inode *dir,
874 struct nfs_fh *fh, struct nfs_fattr *fattr) 876 struct nfs_fh *fh, struct nfs_fattr *fattr)
875{ 877{
876 struct nfs_server *server = NFS_SERVER(dir); 878 struct nfs_server *server = NFS_SERVER(dir);
877 879
878 if (!nfs_fsid_equal(&server->fsid, &fattr->fsid)) 880 if (!nfs_fsid_equal(&server->fsid, &fattr->fsid))
879 /* Revalidate fsid on root dir */ 881 /* Revalidate fsid on root dir */
880 return __nfs_revalidate_inode(server, dir->i_sb->s_root->d_inode); 882 return __nfs_revalidate_inode(server, mnt->mnt_root->d_inode);
881 return 0; 883 return 0;
882} 884}
883 885
@@ -902,9 +904,15 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
902 904
903 lock_kernel(); 905 lock_kernel();
904 906
905 /* If we're doing an exclusive create, optimize away the lookup */ 907 /*
906 if (nfs_is_exclusive_create(dir, nd)) 908 * If we're doing an exclusive create, optimize away the lookup
907 goto no_entry; 909 * but don't hash the dentry.
910 */
911 if (nfs_is_exclusive_create(dir, nd)) {
912 d_instantiate(dentry, NULL);
913 res = NULL;
914 goto out_unlock;
915 }
908 916
909 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); 917 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
910 if (error == -ENOENT) 918 if (error == -ENOENT)
@@ -913,7 +921,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
913 res = ERR_PTR(error); 921 res = ERR_PTR(error);
914 goto out_unlock; 922 goto out_unlock;
915 } 923 }
916 error = nfs_reval_fsid(dir, &fhandle, &fattr); 924 error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr);
917 if (error < 0) { 925 if (error < 0) {
918 res = ERR_PTR(error); 926 res = ERR_PTR(error);
919 goto out_unlock; 927 goto out_unlock;
@@ -922,8 +930,9 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
922 res = (struct dentry *)inode; 930 res = (struct dentry *)inode;
923 if (IS_ERR(res)) 931 if (IS_ERR(res))
924 goto out_unlock; 932 goto out_unlock;
933
925no_entry: 934no_entry:
926 res = d_add_unique(dentry, inode); 935 res = d_materialise_unique(dentry, inode);
927 if (res != NULL) 936 if (res != NULL)
928 dentry = res; 937 dentry = res;
929 nfs_renew_times(dentry); 938 nfs_renew_times(dentry);
@@ -1117,11 +1126,13 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
1117 dput(dentry); 1126 dput(dentry);
1118 return NULL; 1127 return NULL;
1119 } 1128 }
1120 alias = d_add_unique(dentry, inode); 1129
1130 alias = d_materialise_unique(dentry, inode);
1121 if (alias != NULL) { 1131 if (alias != NULL) {
1122 dput(dentry); 1132 dput(dentry);
1123 dentry = alias; 1133 dentry = alias;
1124 } 1134 }
1135
1125 nfs_renew_times(dentry); 1136 nfs_renew_times(dentry);
1126 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1137 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1127 return dentry; 1138 return dentry;
@@ -1143,23 +1154,22 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
1143 struct inode *dir = dentry->d_parent->d_inode; 1154 struct inode *dir = dentry->d_parent->d_inode;
1144 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1155 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
1145 if (error) 1156 if (error)
1146 goto out_err; 1157 return error;
1147 } 1158 }
1148 if (!(fattr->valid & NFS_ATTR_FATTR)) { 1159 if (!(fattr->valid & NFS_ATTR_FATTR)) {
1149 struct nfs_server *server = NFS_SB(dentry->d_sb); 1160 struct nfs_server *server = NFS_SB(dentry->d_sb);
1150 error = server->rpc_ops->getattr(server, fhandle, fattr); 1161 error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr);
1151 if (error < 0) 1162 if (error < 0)
1152 goto out_err; 1163 return error;
1153 } 1164 }
1154 inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1165 inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
1155 error = PTR_ERR(inode); 1166 error = PTR_ERR(inode);
1156 if (IS_ERR(inode)) 1167 if (IS_ERR(inode))
1157 goto out_err; 1168 return error;
1158 d_instantiate(dentry, inode); 1169 d_instantiate(dentry, inode);
1170 if (d_unhashed(dentry))
1171 d_rehash(dentry);
1159 return 0; 1172 return 0;
1160out_err:
1161 d_drop(dentry);
1162 return error;
1163} 1173}
1164 1174
1165/* 1175/*
@@ -1440,48 +1450,82 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
1440 return error; 1450 return error;
1441} 1451}
1442 1452
1443static int 1453/*
1444nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) 1454 * To create a symbolic link, most file systems instantiate a new inode,
1455 * add a page to it containing the path, then write it out to the disk
1456 * using prepare_write/commit_write.
1457 *
1458 * Unfortunately the NFS client can't create the in-core inode first
1459 * because it needs a file handle to create an in-core inode (see
1460 * fs/nfs/inode.c:nfs_fhget). We only have a file handle *after* the
1461 * symlink request has completed on the server.
1462 *
1463 * So instead we allocate a raw page, copy the symname into it, then do
1464 * the SYMLINK request with the page as the buffer. If it succeeds, we
1465 * now have a new file handle and can instantiate an in-core NFS inode
1466 * and move the raw page into its mapping.
1467 */
1468static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1445{ 1469{
1470 struct pagevec lru_pvec;
1471 struct page *page;
1472 char *kaddr;
1446 struct iattr attr; 1473 struct iattr attr;
1447 struct nfs_fattr sym_attr; 1474 unsigned int pathlen = strlen(symname);
1448 struct nfs_fh sym_fh;
1449 struct qstr qsymname;
1450 int error; 1475 int error;
1451 1476
1452 dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, 1477 dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id,
1453 dir->i_ino, dentry->d_name.name, symname); 1478 dir->i_ino, dentry->d_name.name, symname);
1454 1479
1455#ifdef NFS_PARANOIA 1480 if (pathlen > PAGE_SIZE)
1456if (dentry->d_inode) 1481 return -ENAMETOOLONG;
1457printk("nfs_proc_symlink: %s/%s not negative!\n",
1458dentry->d_parent->d_name.name, dentry->d_name.name);
1459#endif
1460 /*
1461 * Fill in the sattr for the call.
1462 * Note: SunOS 4.1.2 crashes if the mode isn't initialized!
1463 */
1464 attr.ia_valid = ATTR_MODE;
1465 attr.ia_mode = S_IFLNK | S_IRWXUGO;
1466 1482
1467 qsymname.name = symname; 1483 attr.ia_mode = S_IFLNK | S_IRWXUGO;
1468 qsymname.len = strlen(symname); 1484 attr.ia_valid = ATTR_MODE;
1469 1485
1470 lock_kernel(); 1486 lock_kernel();
1487
1488 page = alloc_page(GFP_KERNEL);
1489 if (!page) {
1490 unlock_kernel();
1491 return -ENOMEM;
1492 }
1493
1494 kaddr = kmap_atomic(page, KM_USER0);
1495 memcpy(kaddr, symname, pathlen);
1496 if (pathlen < PAGE_SIZE)
1497 memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
1498 kunmap_atomic(kaddr, KM_USER0);
1499
1471 nfs_begin_data_update(dir); 1500 nfs_begin_data_update(dir);
1472 error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname, 1501 error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
1473 &attr, &sym_fh, &sym_attr);
1474 nfs_end_data_update(dir); 1502 nfs_end_data_update(dir);
1475 if (!error) { 1503 if (error != 0) {
1476 error = nfs_instantiate(dentry, &sym_fh, &sym_attr); 1504 dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n",
1477 } else { 1505 dir->i_sb->s_id, dir->i_ino,
1478 if (error == -EEXIST) 1506 dentry->d_name.name, symname, error);
1479 printk("nfs_proc_symlink: %s/%s already exists??\n",
1480 dentry->d_parent->d_name.name, dentry->d_name.name);
1481 d_drop(dentry); 1507 d_drop(dentry);
1508 __free_page(page);
1509 unlock_kernel();
1510 return error;
1482 } 1511 }
1512
1513 /*
1514 * No big deal if we can't add this page to the page cache here.
1515 * READLINK will get the missing page from the server if needed.
1516 */
1517 pagevec_init(&lru_pvec, 0);
1518 if (!add_to_page_cache(page, dentry->d_inode->i_mapping, 0,
1519 GFP_KERNEL)) {
1520 if (!pagevec_add(&lru_pvec, page))
1521 __pagevec_lru_add(&lru_pvec);
1522 SetPageUptodate(page);
1523 unlock_page(page);
1524 } else
1525 __free_page(page);
1526
1483 unlock_kernel(); 1527 unlock_kernel();
1484 return error; 1528 return 0;
1485} 1529}
1486 1530
1487static int 1531static int
@@ -1638,35 +1682,211 @@ out:
1638 return error; 1682 return error;
1639} 1683}
1640 1684
1685static DEFINE_SPINLOCK(nfs_access_lru_lock);
1686static LIST_HEAD(nfs_access_lru_list);
1687static atomic_long_t nfs_access_nr_entries;
1688
1689static void nfs_access_free_entry(struct nfs_access_entry *entry)
1690{
1691 put_rpccred(entry->cred);
1692 kfree(entry);
1693 smp_mb__before_atomic_dec();
1694 atomic_long_dec(&nfs_access_nr_entries);
1695 smp_mb__after_atomic_dec();
1696}
1697
1698int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
1699{
1700 LIST_HEAD(head);
1701 struct nfs_inode *nfsi;
1702 struct nfs_access_entry *cache;
1703
1704 spin_lock(&nfs_access_lru_lock);
1705restart:
1706 list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) {
1707 struct inode *inode;
1708
1709 if (nr_to_scan-- == 0)
1710 break;
1711 inode = igrab(&nfsi->vfs_inode);
1712 if (inode == NULL)
1713 continue;
1714 spin_lock(&inode->i_lock);
1715 if (list_empty(&nfsi->access_cache_entry_lru))
1716 goto remove_lru_entry;
1717 cache = list_entry(nfsi->access_cache_entry_lru.next,
1718 struct nfs_access_entry, lru);
1719 list_move(&cache->lru, &head);
1720 rb_erase(&cache->rb_node, &nfsi->access_cache);
1721 if (!list_empty(&nfsi->access_cache_entry_lru))
1722 list_move_tail(&nfsi->access_cache_inode_lru,
1723 &nfs_access_lru_list);
1724 else {
1725remove_lru_entry:
1726 list_del_init(&nfsi->access_cache_inode_lru);
1727 clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags);
1728 }
1729 spin_unlock(&inode->i_lock);
1730 iput(inode);
1731 goto restart;
1732 }
1733 spin_unlock(&nfs_access_lru_lock);
1734 while (!list_empty(&head)) {
1735 cache = list_entry(head.next, struct nfs_access_entry, lru);
1736 list_del(&cache->lru);
1737 nfs_access_free_entry(cache);
1738 }
1739 return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure;
1740}
1741
1742static void __nfs_access_zap_cache(struct inode *inode)
1743{
1744 struct nfs_inode *nfsi = NFS_I(inode);
1745 struct rb_root *root_node = &nfsi->access_cache;
1746 struct rb_node *n, *dispose = NULL;
1747 struct nfs_access_entry *entry;
1748
1749 /* Unhook entries from the cache */
1750 while ((n = rb_first(root_node)) != NULL) {
1751 entry = rb_entry(n, struct nfs_access_entry, rb_node);
1752 rb_erase(n, root_node);
1753 list_del(&entry->lru);
1754 n->rb_left = dispose;
1755 dispose = n;
1756 }
1757 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
1758 spin_unlock(&inode->i_lock);
1759
1760 /* Now kill them all! */
1761 while (dispose != NULL) {
1762 n = dispose;
1763 dispose = n->rb_left;
1764 nfs_access_free_entry(rb_entry(n, struct nfs_access_entry, rb_node));
1765 }
1766}
1767
1768void nfs_access_zap_cache(struct inode *inode)
1769{
1770 /* Remove from global LRU init */
1771 if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_FLAGS(inode))) {
1772 spin_lock(&nfs_access_lru_lock);
1773 list_del_init(&NFS_I(inode)->access_cache_inode_lru);
1774 spin_unlock(&nfs_access_lru_lock);
1775 }
1776
1777 spin_lock(&inode->i_lock);
1778 /* This will release the spinlock */
1779 __nfs_access_zap_cache(inode);
1780}
1781
1782static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
1783{
1784 struct rb_node *n = NFS_I(inode)->access_cache.rb_node;
1785 struct nfs_access_entry *entry;
1786
1787 while (n != NULL) {
1788 entry = rb_entry(n, struct nfs_access_entry, rb_node);
1789
1790 if (cred < entry->cred)
1791 n = n->rb_left;
1792 else if (cred > entry->cred)
1793 n = n->rb_right;
1794 else
1795 return entry;
1796 }
1797 return NULL;
1798}
1799
1641int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res) 1800int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
1642{ 1801{
1643 struct nfs_inode *nfsi = NFS_I(inode); 1802 struct nfs_inode *nfsi = NFS_I(inode);
1644 struct nfs_access_entry *cache = &nfsi->cache_access; 1803 struct nfs_access_entry *cache;
1804 int err = -ENOENT;
1645 1805
1646 if (cache->cred != cred 1806 spin_lock(&inode->i_lock);
1647 || time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)) 1807 if (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)
1648 || (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)) 1808 goto out_zap;
1649 return -ENOENT; 1809 cache = nfs_access_search_rbtree(inode, cred);
1650 memcpy(res, cache, sizeof(*res)); 1810 if (cache == NULL)
1651 return 0; 1811 goto out;
1812 if (time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)))
1813 goto out_stale;
1814 res->jiffies = cache->jiffies;
1815 res->cred = cache->cred;
1816 res->mask = cache->mask;
1817 list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru);
1818 err = 0;
1819out:
1820 spin_unlock(&inode->i_lock);
1821 return err;
1822out_stale:
1823 rb_erase(&cache->rb_node, &nfsi->access_cache);
1824 list_del(&cache->lru);
1825 spin_unlock(&inode->i_lock);
1826 nfs_access_free_entry(cache);
1827 return -ENOENT;
1828out_zap:
1829 /* This will release the spinlock */
1830 __nfs_access_zap_cache(inode);
1831 return -ENOENT;
1652} 1832}
1653 1833
1654void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) 1834static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set)
1655{ 1835{
1656 struct nfs_inode *nfsi = NFS_I(inode); 1836 struct nfs_inode *nfsi = NFS_I(inode);
1657 struct nfs_access_entry *cache = &nfsi->cache_access; 1837 struct rb_root *root_node = &nfsi->access_cache;
1838 struct rb_node **p = &root_node->rb_node;
1839 struct rb_node *parent = NULL;
1840 struct nfs_access_entry *entry;
1658 1841
1659 if (cache->cred != set->cred) {
1660 if (cache->cred)
1661 put_rpccred(cache->cred);
1662 cache->cred = get_rpccred(set->cred);
1663 }
1664 /* FIXME: replace current access_cache BKL reliance with inode->i_lock */
1665 spin_lock(&inode->i_lock); 1842 spin_lock(&inode->i_lock);
1666 nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS; 1843 while (*p != NULL) {
1844 parent = *p;
1845 entry = rb_entry(parent, struct nfs_access_entry, rb_node);
1846
1847 if (set->cred < entry->cred)
1848 p = &parent->rb_left;
1849 else if (set->cred > entry->cred)
1850 p = &parent->rb_right;
1851 else
1852 goto found;
1853 }
1854 rb_link_node(&set->rb_node, parent, p);
1855 rb_insert_color(&set->rb_node, root_node);
1856 list_add_tail(&set->lru, &nfsi->access_cache_entry_lru);
1667 spin_unlock(&inode->i_lock); 1857 spin_unlock(&inode->i_lock);
1858 return;
1859found:
1860 rb_replace_node(parent, &set->rb_node, root_node);
1861 list_add_tail(&set->lru, &nfsi->access_cache_entry_lru);
1862 list_del(&entry->lru);
1863 spin_unlock(&inode->i_lock);
1864 nfs_access_free_entry(entry);
1865}
1866
1867void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
1868{
1869 struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
1870 if (cache == NULL)
1871 return;
1872 RB_CLEAR_NODE(&cache->rb_node);
1668 cache->jiffies = set->jiffies; 1873 cache->jiffies = set->jiffies;
1874 cache->cred = get_rpccred(set->cred);
1669 cache->mask = set->mask; 1875 cache->mask = set->mask;
1876
1877 nfs_access_add_rbtree(inode, cache);
1878
1879 /* Update accounting */
1880 smp_mb__before_atomic_inc();
1881 atomic_long_inc(&nfs_access_nr_entries);
1882 smp_mb__after_atomic_inc();
1883
1884 /* Add inode to global LRU list */
1885 if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_FLAGS(inode))) {
1886 spin_lock(&nfs_access_lru_lock);
1887 list_add_tail(&NFS_I(inode)->access_cache_inode_lru, &nfs_access_lru_list);
1888 spin_unlock(&nfs_access_lru_lock);
1889 }
1670} 1890}
1671 1891
1672static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) 1892static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 48e892880d5b..be997d649127 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -111,7 +111,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
111 111
112 nfs_inc_stats(inode, NFSIOS_VFSOPEN); 112 nfs_inc_stats(inode, NFSIOS_VFSOPEN);
113 lock_kernel(); 113 lock_kernel();
114 res = NFS_SERVER(inode)->rpc_ops->file_open(inode, filp); 114 res = NFS_PROTO(inode)->file_open(inode, filp);
115 unlock_kernel(); 115 unlock_kernel();
116 return res; 116 return res;
117} 117}
@@ -157,7 +157,7 @@ force_reval:
157static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) 157static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
158{ 158{
159 /* origin == SEEK_END => we must revalidate the cached file length */ 159 /* origin == SEEK_END => we must revalidate the cached file length */
160 if (origin == 2) { 160 if (origin == SEEK_END) {
161 struct inode *inode = filp->f_mapping->host; 161 struct inode *inode = filp->f_mapping->host;
162 int retval = nfs_revalidate_file_size(inode, filp); 162 int retval = nfs_revalidate_file_size(inode, filp);
163 if (retval < 0) 163 if (retval < 0)
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
new file mode 100644
index 000000000000..76b08ae9ed82
--- /dev/null
+++ b/fs/nfs/getroot.c
@@ -0,0 +1,311 @@
1/* getroot.c: get the root dentry for an NFS mount
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/init.h>
15
16#include <linux/time.h>
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/string.h>
20#include <linux/stat.h>
21#include <linux/errno.h>
22#include <linux/unistd.h>
23#include <linux/sunrpc/clnt.h>
24#include <linux/sunrpc/stats.h>
25#include <linux/nfs_fs.h>
26#include <linux/nfs_mount.h>
27#include <linux/nfs4_mount.h>
28#include <linux/lockd/bind.h>
29#include <linux/smp_lock.h>
30#include <linux/seq_file.h>
31#include <linux/mount.h>
32#include <linux/nfs_idmap.h>
33#include <linux/vfs.h>
34#include <linux/namei.h>
35#include <linux/namespace.h>
36#include <linux/security.h>
37
38#include <asm/system.h>
39#include <asm/uaccess.h>
40
41#include "nfs4_fs.h"
42#include "delegation.h"
43#include "internal.h"
44
45#define NFSDBG_FACILITY NFSDBG_CLIENT
46#define NFS_PARANOIA 1
47
48/*
49 * get an NFS2/NFS3 root dentry from the root filehandle
50 */
51struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
52{
53 struct nfs_server *server = NFS_SB(sb);
54 struct nfs_fsinfo fsinfo;
55 struct nfs_fattr fattr;
56 struct dentry *mntroot;
57 struct inode *inode;
58 int error;
59
60 /* create a dummy root dentry with dummy inode for this superblock */
61 if (!sb->s_root) {
62 struct nfs_fh dummyfh;
63 struct dentry *root;
64 struct inode *iroot;
65
66 memset(&dummyfh, 0, sizeof(dummyfh));
67 memset(&fattr, 0, sizeof(fattr));
68 nfs_fattr_init(&fattr);
69 fattr.valid = NFS_ATTR_FATTR;
70 fattr.type = NFDIR;
71 fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
72 fattr.nlink = 2;
73
74 iroot = nfs_fhget(sb, &dummyfh, &fattr);
75 if (IS_ERR(iroot))
76 return ERR_PTR(PTR_ERR(iroot));
77
78 root = d_alloc_root(iroot);
79 if (!root) {
80 iput(iroot);
81 return ERR_PTR(-ENOMEM);
82 }
83
84 sb->s_root = root;
85 }
86
87 /* get the actual root for this mount */
88 fsinfo.fattr = &fattr;
89
90 error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
91 if (error < 0) {
92 dprintk("nfs_get_root: getattr error = %d\n", -error);
93 return ERR_PTR(error);
94 }
95
96 inode = nfs_fhget(sb, mntfh, fsinfo.fattr);
97 if (IS_ERR(inode)) {
98 dprintk("nfs_get_root: get root inode failed\n");
99 return ERR_PTR(PTR_ERR(inode));
100 }
101
102 /* root dentries normally start off anonymous and get spliced in later
103 * if the dentry tree reaches them; however if the dentry already
104 * exists, we'll pick it up at this point and use it as the root
105 */
106 mntroot = d_alloc_anon(inode);
107 if (!mntroot) {
108 iput(inode);
109 dprintk("nfs_get_root: get root dentry failed\n");
110 return ERR_PTR(-ENOMEM);
111 }
112
113 security_d_instantiate(mntroot, inode);
114
115 if (!mntroot->d_op)
116 mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops;
117
118 return mntroot;
119}
120
121#ifdef CONFIG_NFS_V4
122
123/*
124 * Do a simple pathwalk from the root FH of the server to the nominated target
125 * of the mountpoint
126 * - give error on symlinks
127 * - give error on ".." occurring in the path
128 * - follow traversals
129 */
130int nfs4_path_walk(struct nfs_server *server,
131 struct nfs_fh *mntfh,
132 const char *path)
133{
134 struct nfs_fsinfo fsinfo;
135 struct nfs_fattr fattr;
136 struct nfs_fh lastfh;
137 struct qstr name;
138 int ret;
139 //int referral_count = 0;
140
141 dprintk("--> nfs4_path_walk(,,%s)\n", path);
142
143 fsinfo.fattr = &fattr;
144 nfs_fattr_init(&fattr);
145
146 if (*path++ != '/') {
147 dprintk("nfs4_get_root: Path does not begin with a slash\n");
148 return -EINVAL;
149 }
150
151 /* Start by getting the root filehandle from the server */
152 ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
153 if (ret < 0) {
154 dprintk("nfs4_get_root: getroot error = %d\n", -ret);
155 return ret;
156 }
157
158 if (fattr.type != NFDIR) {
159 printk(KERN_ERR "nfs4_get_root:"
160 " getroot encountered non-directory\n");
161 return -ENOTDIR;
162 }
163
164 if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
165 printk(KERN_ERR "nfs4_get_root:"
166 " getroot obtained referral\n");
167 return -EREMOTE;
168 }
169
170next_component:
171 dprintk("Next: %s\n", path);
172
173 /* extract the next bit of the path */
174 if (!*path)
175 goto path_walk_complete;
176
177 name.name = path;
178 while (*path && *path != '/')
179 path++;
180 name.len = path - (const char *) name.name;
181
182eat_dot_dir:
183 while (*path == '/')
184 path++;
185
186 if (path[0] == '.' && (path[1] == '/' || !path[1])) {
187 path += 2;
188 goto eat_dot_dir;
189 }
190
191 if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2])
192 ) {
193 printk(KERN_ERR "nfs4_get_root:"
194 " Mount path contains reference to \"..\"\n");
195 return -EINVAL;
196 }
197
198 /* lookup the next FH in the sequence */
199 memcpy(&lastfh, mntfh, sizeof(lastfh));
200
201 dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path);
202
203 ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name,
204 mntfh, &fattr);
205 if (ret < 0) {
206 dprintk("nfs4_get_root: getroot error = %d\n", -ret);
207 return ret;
208 }
209
210 if (fattr.type != NFDIR) {
211 printk(KERN_ERR "nfs4_get_root:"
212 " lookupfh encountered non-directory\n");
213 return -ENOTDIR;
214 }
215
216 if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
217 printk(KERN_ERR "nfs4_get_root:"
218 " lookupfh obtained referral\n");
219 return -EREMOTE;
220 }
221
222 goto next_component;
223
224path_walk_complete:
225 memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
226 dprintk("<-- nfs4_path_walk() = 0\n");
227 return 0;
228}
229
230/*
231 * get an NFS4 root dentry from the root filehandle
232 */
233struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
234{
235 struct nfs_server *server = NFS_SB(sb);
236 struct nfs_fattr fattr;
237 struct dentry *mntroot;
238 struct inode *inode;
239 int error;
240
241 dprintk("--> nfs4_get_root()\n");
242
243 /* create a dummy root dentry with dummy inode for this superblock */
244 if (!sb->s_root) {
245 struct nfs_fh dummyfh;
246 struct dentry *root;
247 struct inode *iroot;
248
249 memset(&dummyfh, 0, sizeof(dummyfh));
250 memset(&fattr, 0, sizeof(fattr));
251 nfs_fattr_init(&fattr);
252 fattr.valid = NFS_ATTR_FATTR;
253 fattr.type = NFDIR;
254 fattr.mode = S_IFDIR | S_IRUSR | S_IWUSR;
255 fattr.nlink = 2;
256
257 iroot = nfs_fhget(sb, &dummyfh, &fattr);
258 if (IS_ERR(iroot))
259 return ERR_PTR(PTR_ERR(iroot));
260
261 root = d_alloc_root(iroot);
262 if (!root) {
263 iput(iroot);
264 return ERR_PTR(-ENOMEM);
265 }
266
267 sb->s_root = root;
268 }
269
270 /* get the info about the server and filesystem */
271 error = nfs4_server_capabilities(server, mntfh);
272 if (error < 0) {
273 dprintk("nfs_get_root: getcaps error = %d\n",
274 -error);
275 return ERR_PTR(error);
276 }
277
278 /* get the actual root for this mount */
279 error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
280 if (error < 0) {
281 dprintk("nfs_get_root: getattr error = %d\n", -error);
282 return ERR_PTR(error);
283 }
284
285 inode = nfs_fhget(sb, mntfh, &fattr);
286 if (IS_ERR(inode)) {
287 dprintk("nfs_get_root: get root inode failed\n");
288 return ERR_PTR(PTR_ERR(inode));
289 }
290
291 /* root dentries normally start off anonymous and get spliced in later
292 * if the dentry tree reaches them; however if the dentry already
293 * exists, we'll pick it up at this point and use it as the root
294 */
295 mntroot = d_alloc_anon(inode);
296 if (!mntroot) {
297 iput(inode);
298 dprintk("nfs_get_root: get root dentry failed\n");
299 return ERR_PTR(-ENOMEM);
300 }
301
302 security_d_instantiate(mntroot, inode);
303
304 if (!mntroot->d_op)
305 mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops;
306
307 dprintk("<-- nfs4_get_root()\n");
308 return mntroot;
309}
310
311#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 07a5dd57646e..82ad7110a1c0 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -57,6 +57,20 @@
57/* Default cache timeout is 10 minutes */ 57/* Default cache timeout is 10 minutes */
58unsigned int nfs_idmap_cache_timeout = 600 * HZ; 58unsigned int nfs_idmap_cache_timeout = 600 * HZ;
59 59
60static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
61{
62 char *endp;
63 int num = simple_strtol(val, &endp, 0);
64 int jif = num * HZ;
65 if (endp == val || *endp || num < 0 || jif < num)
66 return -EINVAL;
67 *((int *)kp->arg) = jif;
68 return 0;
69}
70
71module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int,
72 &nfs_idmap_cache_timeout, 0644);
73
60struct idmap_hashent { 74struct idmap_hashent {
61 unsigned long ih_expires; 75 unsigned long ih_expires;
62 __u32 ih_id; 76 __u32 ih_id;
@@ -70,7 +84,6 @@ struct idmap_hashtable {
70}; 84};
71 85
72struct idmap { 86struct idmap {
73 char idmap_path[48];
74 struct dentry *idmap_dentry; 87 struct dentry *idmap_dentry;
75 wait_queue_head_t idmap_wq; 88 wait_queue_head_t idmap_wq;
76 struct idmap_msg idmap_im; 89 struct idmap_msg idmap_im;
@@ -94,24 +107,23 @@ static struct rpc_pipe_ops idmap_upcall_ops = {
94 .destroy_msg = idmap_pipe_destroy_msg, 107 .destroy_msg = idmap_pipe_destroy_msg,
95}; 108};
96 109
97void 110int
98nfs_idmap_new(struct nfs4_client *clp) 111nfs_idmap_new(struct nfs_client *clp)
99{ 112{
100 struct idmap *idmap; 113 struct idmap *idmap;
114 int error;
101 115
102 if (clp->cl_idmap != NULL) 116 BUG_ON(clp->cl_idmap != NULL);
103 return;
104 if ((idmap = kzalloc(sizeof(*idmap), GFP_KERNEL)) == NULL)
105 return;
106 117
107 snprintf(idmap->idmap_path, sizeof(idmap->idmap_path), 118 if ((idmap = kzalloc(sizeof(*idmap), GFP_KERNEL)) == NULL)
108 "%s/idmap", clp->cl_rpcclient->cl_pathname); 119 return -ENOMEM;
109 120
110 idmap->idmap_dentry = rpc_mkpipe(idmap->idmap_path, 121 idmap->idmap_dentry = rpc_mkpipe(clp->cl_rpcclient->cl_dentry, "idmap",
111 idmap, &idmap_upcall_ops, 0); 122 idmap, &idmap_upcall_ops, 0);
112 if (IS_ERR(idmap->idmap_dentry)) { 123 if (IS_ERR(idmap->idmap_dentry)) {
124 error = PTR_ERR(idmap->idmap_dentry);
113 kfree(idmap); 125 kfree(idmap);
114 return; 126 return error;
115 } 127 }
116 128
117 mutex_init(&idmap->idmap_lock); 129 mutex_init(&idmap->idmap_lock);
@@ -121,10 +133,11 @@ nfs_idmap_new(struct nfs4_client *clp)
121 idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP; 133 idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP;
122 134
123 clp->cl_idmap = idmap; 135 clp->cl_idmap = idmap;
136 return 0;
124} 137}
125 138
126void 139void
127nfs_idmap_delete(struct nfs4_client *clp) 140nfs_idmap_delete(struct nfs_client *clp)
128{ 141{
129 struct idmap *idmap = clp->cl_idmap; 142 struct idmap *idmap = clp->cl_idmap;
130 143
@@ -477,27 +490,27 @@ static unsigned int fnvhash32(const void *buf, size_t buflen)
477 return (hash); 490 return (hash);
478} 491}
479 492
480int nfs_map_name_to_uid(struct nfs4_client *clp, const char *name, size_t namelen, __u32 *uid) 493int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid)
481{ 494{
482 struct idmap *idmap = clp->cl_idmap; 495 struct idmap *idmap = clp->cl_idmap;
483 496
484 return nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid); 497 return nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid);
485} 498}
486 499
487int nfs_map_group_to_gid(struct nfs4_client *clp, const char *name, size_t namelen, __u32 *uid) 500int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid)
488{ 501{
489 struct idmap *idmap = clp->cl_idmap; 502 struct idmap *idmap = clp->cl_idmap;
490 503
491 return nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, uid); 504 return nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, uid);
492} 505}
493 506
494int nfs_map_uid_to_name(struct nfs4_client *clp, __u32 uid, char *buf) 507int nfs_map_uid_to_name(struct nfs_client *clp, __u32 uid, char *buf)
495{ 508{
496 struct idmap *idmap = clp->cl_idmap; 509 struct idmap *idmap = clp->cl_idmap;
497 510
498 return nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); 511 return nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf);
499} 512}
500int nfs_map_gid_to_group(struct nfs4_client *clp, __u32 uid, char *buf) 513int nfs_map_gid_to_group(struct nfs_client *clp, __u32 uid, char *buf)
501{ 514{
502 struct idmap *idmap = clp->cl_idmap; 515 struct idmap *idmap = clp->cl_idmap;
503 516
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index d349fb2245da..e8c143d182c4 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -76,19 +76,14 @@ int nfs_write_inode(struct inode *inode, int sync)
76 76
77void nfs_clear_inode(struct inode *inode) 77void nfs_clear_inode(struct inode *inode)
78{ 78{
79 struct nfs_inode *nfsi = NFS_I(inode);
80 struct rpc_cred *cred;
81
82 /* 79 /*
83 * The following should never happen... 80 * The following should never happen...
84 */ 81 */
85 BUG_ON(nfs_have_writebacks(inode)); 82 BUG_ON(nfs_have_writebacks(inode));
86 BUG_ON (!list_empty(&nfsi->open_files)); 83 BUG_ON(!list_empty(&NFS_I(inode)->open_files));
84 BUG_ON(atomic_read(&NFS_I(inode)->data_updates) != 0);
87 nfs_zap_acl_cache(inode); 85 nfs_zap_acl_cache(inode);
88 cred = nfsi->cache_access.cred; 86 nfs_access_zap_cache(inode);
89 if (cred)
90 put_rpccred(cred);
91 BUG_ON(atomic_read(&nfsi->data_updates) != 0);
92} 87}
93 88
94/** 89/**
@@ -242,13 +237,13 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
242 /* Why so? Because we want revalidate for devices/FIFOs, and 237 /* Why so? Because we want revalidate for devices/FIFOs, and
243 * that's precisely what we have in nfs_file_inode_operations. 238 * that's precisely what we have in nfs_file_inode_operations.
244 */ 239 */
245 inode->i_op = NFS_SB(sb)->rpc_ops->file_inode_ops; 240 inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops;
246 if (S_ISREG(inode->i_mode)) { 241 if (S_ISREG(inode->i_mode)) {
247 inode->i_fop = &nfs_file_operations; 242 inode->i_fop = &nfs_file_operations;
248 inode->i_data.a_ops = &nfs_file_aops; 243 inode->i_data.a_ops = &nfs_file_aops;
249 inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; 244 inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info;
250 } else if (S_ISDIR(inode->i_mode)) { 245 } else if (S_ISDIR(inode->i_mode)) {
251 inode->i_op = NFS_SB(sb)->rpc_ops->dir_inode_ops; 246 inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
252 inode->i_fop = &nfs_dir_operations; 247 inode->i_fop = &nfs_dir_operations;
253 if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) 248 if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)
254 && fattr->size <= NFS_LIMIT_READDIRPLUS) 249 && fattr->size <= NFS_LIMIT_READDIRPLUS)
@@ -290,7 +285,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
290 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); 285 nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
291 nfsi->attrtimeo_timestamp = jiffies; 286 nfsi->attrtimeo_timestamp = jiffies;
292 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); 287 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
293 nfsi->cache_access.cred = NULL; 288 nfsi->access_cache = RB_ROOT;
294 289
295 unlock_new_inode(inode); 290 unlock_new_inode(inode);
296 } else 291 } else
@@ -722,13 +717,11 @@ void nfs_end_data_update(struct inode *inode)
722{ 717{
723 struct nfs_inode *nfsi = NFS_I(inode); 718 struct nfs_inode *nfsi = NFS_I(inode);
724 719
725 if (!nfs_have_delegation(inode, FMODE_READ)) { 720 /* Directories: invalidate page cache */
726 /* Directories and symlinks: invalidate page cache */ 721 if (S_ISDIR(inode->i_mode)) {
727 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) { 722 spin_lock(&inode->i_lock);
728 spin_lock(&inode->i_lock); 723 nfsi->cache_validity |= NFS_INO_INVALID_DATA;
729 nfsi->cache_validity |= NFS_INO_INVALID_DATA; 724 spin_unlock(&inode->i_lock);
730 spin_unlock(&inode->i_lock);
731 }
732 } 725 }
733 nfsi->cache_change_attribute = jiffies; 726 nfsi->cache_change_attribute = jiffies;
734 atomic_dec(&nfsi->data_updates); 727 atomic_dec(&nfsi->data_updates);
@@ -847,6 +840,12 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
847 * 840 *
848 * After an operation that has changed the inode metadata, mark the 841 * After an operation that has changed the inode metadata, mark the
849 * attribute cache as being invalid, then try to update it. 842 * attribute cache as being invalid, then try to update it.
843 *
844 * NB: if the server didn't return any post op attributes, this
845 * function will force the retrieval of attributes before the next
846 * NFS request. Thus it should be used only for operations that
847 * are expected to change one or more attributes, to avoid
848 * unnecessary NFS requests and trips through nfs_update_inode().
850 */ 849 */
851int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) 850int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
852{ 851{
@@ -1025,7 +1024,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1025 out_fileid: 1024 out_fileid:
1026 printk(KERN_ERR "NFS: server %s error: fileid changed\n" 1025 printk(KERN_ERR "NFS: server %s error: fileid changed\n"
1027 "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", 1026 "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
1028 NFS_SERVER(inode)->hostname, inode->i_sb->s_id, 1027 NFS_SERVER(inode)->nfs_client->cl_hostname, inode->i_sb->s_id,
1029 (long long)nfsi->fileid, (long long)fattr->fileid); 1028 (long long)nfsi->fileid, (long long)fattr->fileid);
1030 goto out_err; 1029 goto out_err;
1031} 1030}
@@ -1109,6 +1108,8 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
1109 INIT_LIST_HEAD(&nfsi->dirty); 1108 INIT_LIST_HEAD(&nfsi->dirty);
1110 INIT_LIST_HEAD(&nfsi->commit); 1109 INIT_LIST_HEAD(&nfsi->commit);
1111 INIT_LIST_HEAD(&nfsi->open_files); 1110 INIT_LIST_HEAD(&nfsi->open_files);
1111 INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
1112 INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
1112 INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); 1113 INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
1113 atomic_set(&nfsi->data_updates, 0); 1114 atomic_set(&nfsi->data_updates, 0);
1114 nfsi->ndirty = 0; 1115 nfsi->ndirty = 0;
@@ -1144,6 +1145,10 @@ static int __init init_nfs_fs(void)
1144{ 1145{
1145 int err; 1146 int err;
1146 1147
1148 err = nfs_fs_proc_init();
1149 if (err)
1150 goto out5;
1151
1147 err = nfs_init_nfspagecache(); 1152 err = nfs_init_nfspagecache();
1148 if (err) 1153 if (err)
1149 goto out4; 1154 goto out4;
@@ -1184,6 +1189,8 @@ out2:
1184out3: 1189out3:
1185 nfs_destroy_nfspagecache(); 1190 nfs_destroy_nfspagecache();
1186out4: 1191out4:
1192 nfs_fs_proc_exit();
1193out5:
1187 return err; 1194 return err;
1188} 1195}
1189 1196
@@ -1198,6 +1205,7 @@ static void __exit exit_nfs_fs(void)
1198 rpc_proc_unregister("nfs"); 1205 rpc_proc_unregister("nfs");
1199#endif 1206#endif
1200 unregister_nfs_fs(); 1207 unregister_nfs_fs();
1208 nfs_fs_proc_exit();
1201} 1209}
1202 1210
1203/* Not quite true; I just maintain it */ 1211/* Not quite true; I just maintain it */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e4f4e5def0fc..bea0b016bd70 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -4,6 +4,18 @@
4 4
5#include <linux/mount.h> 5#include <linux/mount.h>
6 6
7struct nfs_string;
8struct nfs_mount_data;
9struct nfs4_mount_data;
10
11/* Maximum number of readahead requests
12 * FIXME: this should really be a sysctl so that users may tune it to suit
13 * their needs. People that do NFS over a slow network, might for
14 * instance want to reduce it to something closer to 1 for improved
15 * interactive response.
16 */
17#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
18
7struct nfs_clone_mount { 19struct nfs_clone_mount {
8 const struct super_block *sb; 20 const struct super_block *sb;
9 const struct dentry *dentry; 21 const struct dentry *dentry;
@@ -15,7 +27,40 @@ struct nfs_clone_mount {
15 rpc_authflavor_t authflavor; 27 rpc_authflavor_t authflavor;
16}; 28};
17 29
18/* namespace-nfs4.c */ 30/* client.c */
31extern struct rpc_program nfs_program;
32
33extern void nfs_put_client(struct nfs_client *);
34extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
35extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *,
36 struct nfs_fh *);
37extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *,
38 const char *,
39 const struct sockaddr_in *,
40 const char *,
41 const char *,
42 rpc_authflavor_t,
43 struct nfs_fh *);
44extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
45 struct nfs_fh *);
46extern void nfs_free_server(struct nfs_server *server);
47extern struct nfs_server *nfs_clone_server(struct nfs_server *,
48 struct nfs_fh *,
49 struct nfs_fattr *);
50#ifdef CONFIG_PROC_FS
51extern int __init nfs_fs_proc_init(void);
52extern void nfs_fs_proc_exit(void);
53#else
54static inline int nfs_fs_proc_init(void)
55{
56 return 0;
57}
58static inline void nfs_fs_proc_exit(void)
59{
60}
61#endif
62
63/* nfs4namespace.c */
19#ifdef CONFIG_NFS_V4 64#ifdef CONFIG_NFS_V4
20extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry); 65extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry);
21#else 66#else
@@ -46,6 +91,7 @@ extern void nfs_destroy_directcache(void);
46#endif 91#endif
47 92
48/* nfs2xdr.c */ 93/* nfs2xdr.c */
94extern int nfs_stat_to_errno(int);
49extern struct rpc_procinfo nfs_procedures[]; 95extern struct rpc_procinfo nfs_procedures[];
50extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int); 96extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
51 97
@@ -54,8 +100,9 @@ extern struct rpc_procinfo nfs3_procedures[];
54extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int); 100extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
55 101
56/* nfs4xdr.c */ 102/* nfs4xdr.c */
57extern int nfs_stat_to_errno(int); 103#ifdef CONFIG_NFS_V4
58extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); 104extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
105#endif
59 106
60/* nfs4proc.c */ 107/* nfs4proc.c */
61#ifdef CONFIG_NFS_V4 108#ifdef CONFIG_NFS_V4
@@ -66,6 +113,9 @@ extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
66 struct page *page); 113 struct page *page);
67#endif 114#endif
68 115
116/* dir.c */
117extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask);
118
69/* inode.c */ 119/* inode.c */
70extern struct inode *nfs_alloc_inode(struct super_block *sb); 120extern struct inode *nfs_alloc_inode(struct super_block *sb);
71extern void nfs_destroy_inode(struct inode *); 121extern void nfs_destroy_inode(struct inode *);
@@ -76,10 +126,10 @@ extern void nfs4_clear_inode(struct inode *);
76#endif 126#endif
77 127
78/* super.c */ 128/* super.c */
79extern struct file_system_type nfs_referral_nfs4_fs_type; 129extern struct file_system_type nfs_xdev_fs_type;
80extern struct file_system_type clone_nfs_fs_type;
81#ifdef CONFIG_NFS_V4 130#ifdef CONFIG_NFS_V4
82extern struct file_system_type clone_nfs4_fs_type; 131extern struct file_system_type nfs4_xdev_fs_type;
132extern struct file_system_type nfs4_referral_fs_type;
83#endif 133#endif
84 134
85extern struct rpc_stat nfs_rpcstat; 135extern struct rpc_stat nfs_rpcstat;
@@ -88,30 +138,30 @@ extern int __init register_nfs_fs(void);
88extern void __exit unregister_nfs_fs(void); 138extern void __exit unregister_nfs_fs(void);
89 139
90/* namespace.c */ 140/* namespace.c */
91extern char *nfs_path(const char *base, const struct dentry *dentry, 141extern char *nfs_path(const char *base,
142 const struct dentry *droot,
143 const struct dentry *dentry,
92 char *buffer, ssize_t buflen); 144 char *buffer, ssize_t buflen);
93 145
94/* 146/* getroot.c */
95 * Determine the mount path as a string 147extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *);
96 */
97static inline char *
98nfs4_path(const struct dentry *dentry, char *buffer, ssize_t buflen)
99{
100#ifdef CONFIG_NFS_V4 148#ifdef CONFIG_NFS_V4
101 return nfs_path(NFS_SB(dentry->d_sb)->mnt_path, dentry, buffer, buflen); 149extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *);
102#else 150
103 return NULL; 151extern int nfs4_path_walk(struct nfs_server *server,
152 struct nfs_fh *mntfh,
153 const char *path);
104#endif 154#endif
105}
106 155
107/* 156/*
108 * Determine the device name as a string 157 * Determine the device name as a string
109 */ 158 */
110static inline char *nfs_devname(const struct vfsmount *mnt_parent, 159static inline char *nfs_devname(const struct vfsmount *mnt_parent,
111 const struct dentry *dentry, 160 const struct dentry *dentry,
112 char *buffer, ssize_t buflen) 161 char *buffer, ssize_t buflen)
113{ 162{
114 return nfs_path(mnt_parent->mnt_devname, dentry, buffer, buflen); 163 return nfs_path(mnt_parent->mnt_devname, mnt_parent->mnt_root,
164 dentry, buffer, buflen);
115} 165}
116 166
117/* 167/*
@@ -167,20 +217,3 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
167 if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) 217 if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
168 sb->s_maxbytes = MAX_LFS_FILESIZE; 218 sb->s_maxbytes = MAX_LFS_FILESIZE;
169} 219}
170
171/*
172 * Check if the string represents a "valid" IPv4 address
173 */
174static inline int valid_ipaddr4(const char *buf)
175{
176 int rc, count, in[4];
177
178 rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
179 if (rc != 4)
180 return -EINVAL;
181 for (count = 0; count < 4; count++) {
182 if (in[count] > 255)
183 return -EINVAL;
184 }
185 return 0;
186}
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 445abb4d4214..d507b021207f 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -14,7 +14,6 @@
14#include <linux/net.h> 14#include <linux/net.h>
15#include <linux/in.h> 15#include <linux/in.h>
16#include <linux/sunrpc/clnt.h> 16#include <linux/sunrpc/clnt.h>
17#include <linux/sunrpc/xprt.h>
18#include <linux/sunrpc/sched.h> 17#include <linux/sunrpc/sched.h>
19#include <linux/nfs_fs.h> 18#include <linux/nfs_fs.h>
20 19
@@ -77,22 +76,19 @@ static struct rpc_clnt *
77mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version, 76mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
78 int protocol) 77 int protocol)
79{ 78{
80 struct rpc_xprt *xprt; 79 struct rpc_create_args args = {
81 struct rpc_clnt *clnt; 80 .protocol = protocol,
82 81 .address = (struct sockaddr *)srvaddr,
83 xprt = xprt_create_proto(protocol, srvaddr, NULL); 82 .addrsize = sizeof(*srvaddr),
84 if (IS_ERR(xprt)) 83 .servername = hostname,
85 return (struct rpc_clnt *)xprt; 84 .program = &mnt_program,
86 85 .version = version,
87 clnt = rpc_create_client(xprt, hostname, 86 .authflavor = RPC_AUTH_UNIX,
88 &mnt_program, version, 87 .flags = (RPC_CLNT_CREATE_ONESHOT |
89 RPC_AUTH_UNIX); 88 RPC_CLNT_CREATE_INTR),
90 if (!IS_ERR(clnt)) { 89 };
91 clnt->cl_softrtry = 1; 90
92 clnt->cl_oneshot = 1; 91 return rpc_create(&args);
93 clnt->cl_intr = 1;
94 }
95 return clnt;
96} 92}
97 93
98/* 94/*
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 86b3169c8cac..77b00684894d 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -2,6 +2,7 @@
2 * linux/fs/nfs/namespace.c 2 * linux/fs/nfs/namespace.c
3 * 3 *
4 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com> 4 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com>
5 * - Modified by David Howells <dhowells@redhat.com>
5 * 6 *
6 * NFS namespace 7 * NFS namespace
7 */ 8 */
@@ -28,6 +29,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
28/* 29/*
29 * nfs_path - reconstruct the path given an arbitrary dentry 30 * nfs_path - reconstruct the path given an arbitrary dentry
30 * @base - arbitrary string to prepend to the path 31 * @base - arbitrary string to prepend to the path
32 * @droot - pointer to root dentry for mountpoint
31 * @dentry - pointer to dentry 33 * @dentry - pointer to dentry
32 * @buffer - result buffer 34 * @buffer - result buffer
33 * @buflen - length of buffer 35 * @buflen - length of buffer
@@ -38,7 +40,9 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
38 * This is mainly for use in figuring out the path on the 40 * This is mainly for use in figuring out the path on the
39 * server side when automounting on top of an existing partition. 41 * server side when automounting on top of an existing partition.
40 */ 42 */
41char *nfs_path(const char *base, const struct dentry *dentry, 43char *nfs_path(const char *base,
44 const struct dentry *droot,
45 const struct dentry *dentry,
42 char *buffer, ssize_t buflen) 46 char *buffer, ssize_t buflen)
43{ 47{
44 char *end = buffer+buflen; 48 char *end = buffer+buflen;
@@ -47,7 +51,7 @@ char *nfs_path(const char *base, const struct dentry *dentry,
47 *--end = '\0'; 51 *--end = '\0';
48 buflen--; 52 buflen--;
49 spin_lock(&dcache_lock); 53 spin_lock(&dcache_lock);
50 while (!IS_ROOT(dentry)) { 54 while (!IS_ROOT(dentry) && dentry != droot) {
51 namelen = dentry->d_name.len; 55 namelen = dentry->d_name.len;
52 buflen -= namelen + 1; 56 buflen -= namelen + 1;
53 if (buflen < 0) 57 if (buflen < 0)
@@ -96,15 +100,18 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
96 struct nfs_fattr fattr; 100 struct nfs_fattr fattr;
97 int err; 101 int err;
98 102
103 dprintk("--> nfs_follow_mountpoint()\n");
104
99 BUG_ON(IS_ROOT(dentry)); 105 BUG_ON(IS_ROOT(dentry));
100 dprintk("%s: enter\n", __FUNCTION__); 106 dprintk("%s: enter\n", __FUNCTION__);
101 dput(nd->dentry); 107 dput(nd->dentry);
102 nd->dentry = dget(dentry); 108 nd->dentry = dget(dentry);
103 if (d_mountpoint(nd->dentry)) 109
104 goto out_follow;
105 /* Look it up again */ 110 /* Look it up again */
106 parent = dget_parent(nd->dentry); 111 parent = dget_parent(nd->dentry);
107 err = server->rpc_ops->lookup(parent->d_inode, &nd->dentry->d_name, &fh, &fattr); 112 err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
113 &nd->dentry->d_name,
114 &fh, &fattr);
108 dput(parent); 115 dput(parent);
109 if (err != 0) 116 if (err != 0)
110 goto out_err; 117 goto out_err;
@@ -132,6 +139,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
132 schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); 139 schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
133out: 140out:
134 dprintk("%s: done, returned %d\n", __FUNCTION__, err); 141 dprintk("%s: done, returned %d\n", __FUNCTION__, err);
142
143 dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
135 return ERR_PTR(err); 144 return ERR_PTR(err);
136out_err: 145out_err:
137 path_release(nd); 146 path_release(nd);
@@ -172,22 +181,23 @@ void nfs_release_automount_timer(void)
172/* 181/*
173 * Clone a mountpoint of the appropriate type 182 * Clone a mountpoint of the appropriate type
174 */ 183 */
175static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, char *devname, 184static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
185 const char *devname,
176 struct nfs_clone_mount *mountdata) 186 struct nfs_clone_mount *mountdata)
177{ 187{
178#ifdef CONFIG_NFS_V4 188#ifdef CONFIG_NFS_V4
179 struct vfsmount *mnt = NULL; 189 struct vfsmount *mnt = NULL;
180 switch (server->rpc_ops->version) { 190 switch (server->nfs_client->cl_nfsversion) {
181 case 2: 191 case 2:
182 case 3: 192 case 3:
183 mnt = vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); 193 mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
184 break; 194 break;
185 case 4: 195 case 4:
186 mnt = vfs_kern_mount(&clone_nfs4_fs_type, 0, devname, mountdata); 196 mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata);
187 } 197 }
188 return mnt; 198 return mnt;
189#else 199#else
190 return vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata); 200 return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
191#endif 201#endif
192} 202}
193 203
@@ -213,6 +223,8 @@ struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent,
213 char *page = (char *) __get_free_page(GFP_USER); 223 char *page = (char *) __get_free_page(GFP_USER);
214 char *devname; 224 char *devname;
215 225
226 dprintk("--> nfs_do_submount()\n");
227
216 dprintk("%s: submounting on %s/%s\n", __FUNCTION__, 228 dprintk("%s: submounting on %s/%s\n", __FUNCTION__,
217 dentry->d_parent->d_name.name, 229 dentry->d_parent->d_name.name,
218 dentry->d_name.name); 230 dentry->d_name.name);
@@ -227,5 +239,7 @@ free_page:
227 free_page((unsigned long)page); 239 free_page((unsigned long)page);
228out: 240out:
229 dprintk("%s: done\n", __FUNCTION__); 241 dprintk("%s: done\n", __FUNCTION__);
242
243 dprintk("<-- nfs_do_submount() = %p\n", mnt);
230 return mnt; 244 return mnt;
231} 245}
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 67391eef6b93..b49501fc0a79 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -51,7 +51,7 @@
51#define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz) 51#define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz)
52#define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz) 52#define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz)
53#define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz) 53#define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz)
54#define NFS_symlinkargs_sz (NFS_diropargs_sz+NFS_path_sz+NFS_sattr_sz) 54#define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz)
55#define NFS_readdirargs_sz (NFS_fhandle_sz+2) 55#define NFS_readdirargs_sz (NFS_fhandle_sz+2)
56 56
57#define NFS_attrstat_sz (1+NFS_fattr_sz) 57#define NFS_attrstat_sz (1+NFS_fattr_sz)
@@ -351,11 +351,26 @@ nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args)
351static int 351static int
352nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args) 352nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args)
353{ 353{
354 struct xdr_buf *sndbuf = &req->rq_snd_buf;
355 size_t pad;
356
354 p = xdr_encode_fhandle(p, args->fromfh); 357 p = xdr_encode_fhandle(p, args->fromfh);
355 p = xdr_encode_array(p, args->fromname, args->fromlen); 358 p = xdr_encode_array(p, args->fromname, args->fromlen);
356 p = xdr_encode_array(p, args->topath, args->tolen); 359 *p++ = htonl(args->pathlen);
360 sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
361
362 xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen);
363
364 /*
365 * xdr_encode_pages may have added a few bytes to ensure the
366 * pathname ends on a 4-byte boundary. Start encoding the
367 * attributes after the pad bytes.
368 */
369 pad = sndbuf->tail->iov_len;
370 if (pad > 0)
371 p++;
357 p = xdr_encode_sattr(p, args->sattr); 372 p = xdr_encode_sattr(p, args->sattr);
358 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); 373 sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad;
359 return 0; 374 return 0;
360} 375}
361 376
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 7143b1f82cea..f8688eaa0001 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -81,7 +81,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
81} 81}
82 82
83/* 83/*
84 * Bare-bones access to getattr: this is for nfs_read_super. 84 * Bare-bones access to getattr: this is for nfs_get_root/nfs_get_sb
85 */ 85 */
86static int 86static int
87nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, 87nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -90,8 +90,8 @@ nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
90 int status; 90 int status;
91 91
92 status = do_proc_get_root(server->client, fhandle, info); 92 status = do_proc_get_root(server->client, fhandle, info);
93 if (status && server->client_sys != server->client) 93 if (status && server->nfs_client->cl_rpcclient != server->client)
94 status = do_proc_get_root(server->client_sys, fhandle, info); 94 status = do_proc_get_root(server->nfs_client->cl_rpcclient, fhandle, info);
95 return status; 95 return status;
96} 96}
97 97
@@ -544,23 +544,23 @@ nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
544} 544}
545 545
546static int 546static int
547nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, 547nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
548 struct iattr *sattr, struct nfs_fh *fhandle, 548 unsigned int len, struct iattr *sattr)
549 struct nfs_fattr *fattr)
550{ 549{
551 struct nfs_fattr dir_attr; 550 struct nfs_fh fhandle;
551 struct nfs_fattr fattr, dir_attr;
552 struct nfs3_symlinkargs arg = { 552 struct nfs3_symlinkargs arg = {
553 .fromfh = NFS_FH(dir), 553 .fromfh = NFS_FH(dir),
554 .fromname = name->name, 554 .fromname = dentry->d_name.name,
555 .fromlen = name->len, 555 .fromlen = dentry->d_name.len,
556 .topath = path->name, 556 .pages = &page,
557 .tolen = path->len, 557 .pathlen = len,
558 .sattr = sattr 558 .sattr = sattr
559 }; 559 };
560 struct nfs3_diropres res = { 560 struct nfs3_diropres res = {
561 .dir_attr = &dir_attr, 561 .dir_attr = &dir_attr,
562 .fh = fhandle, 562 .fh = &fhandle,
563 .fattr = fattr 563 .fattr = &fattr
564 }; 564 };
565 struct rpc_message msg = { 565 struct rpc_message msg = {
566 .rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK], 566 .rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK],
@@ -569,13 +569,19 @@ nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
569 }; 569 };
570 int status; 570 int status;
571 571
572 if (path->len > NFS3_MAXPATHLEN) 572 if (len > NFS3_MAXPATHLEN)
573 return -ENAMETOOLONG; 573 return -ENAMETOOLONG;
574 dprintk("NFS call symlink %s -> %s\n", name->name, path->name); 574
575 dprintk("NFS call symlink %s\n", dentry->d_name.name);
576
575 nfs_fattr_init(&dir_attr); 577 nfs_fattr_init(&dir_attr);
576 nfs_fattr_init(fattr); 578 nfs_fattr_init(&fattr);
577 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 579 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
578 nfs_post_op_update_inode(dir, &dir_attr); 580 nfs_post_op_update_inode(dir, &dir_attr);
581 if (status != 0)
582 goto out;
583 status = nfs_instantiate(dentry, &fhandle, &fattr);
584out:
579 dprintk("NFS reply symlink: %d\n", status); 585 dprintk("NFS reply symlink: %d\n", status);
580 return status; 586 return status;
581} 587}
@@ -785,7 +791,7 @@ nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
785 791
786 dprintk("NFS call fsinfo\n"); 792 dprintk("NFS call fsinfo\n");
787 nfs_fattr_init(info->fattr); 793 nfs_fattr_init(info->fattr);
788 status = rpc_call_sync(server->client_sys, &msg, 0); 794 status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
789 dprintk("NFS reply fsinfo: %d\n", status); 795 dprintk("NFS reply fsinfo: %d\n", status);
790 return status; 796 return status;
791} 797}
@@ -886,7 +892,7 @@ nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
886 return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl); 892 return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl);
887} 893}
888 894
889struct nfs_rpc_ops nfs_v3_clientops = { 895const struct nfs_rpc_ops nfs_v3_clientops = {
890 .version = 3, /* protocol version */ 896 .version = 3, /* protocol version */
891 .dentry_ops = &nfs_dentry_operations, 897 .dentry_ops = &nfs_dentry_operations,
892 .dir_inode_ops = &nfs3_dir_inode_operations, 898 .dir_inode_ops = &nfs3_dir_inode_operations,
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 0250269e9753..16556fa4effb 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -56,7 +56,7 @@
56#define NFS3_writeargs_sz (NFS3_fh_sz+5) 56#define NFS3_writeargs_sz (NFS3_fh_sz+5)
57#define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) 57#define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
58#define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) 58#define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
59#define NFS3_symlinkargs_sz (NFS3_diropargs_sz+NFS3_path_sz+NFS3_sattr_sz) 59#define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
60#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) 60#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
61#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) 61#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
62#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) 62#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
@@ -398,8 +398,11 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_symlinkargs *args
398 p = xdr_encode_fhandle(p, args->fromfh); 398 p = xdr_encode_fhandle(p, args->fromfh);
399 p = xdr_encode_array(p, args->fromname, args->fromlen); 399 p = xdr_encode_array(p, args->fromname, args->fromlen);
400 p = xdr_encode_sattr(p, args->sattr); 400 p = xdr_encode_sattr(p, args->sattr);
401 p = xdr_encode_array(p, args->topath, args->tolen); 401 *p++ = htonl(args->pathlen);
402 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); 402 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
403
404 /* Copy the page */
405 xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen);
403 return 0; 406 return 0;
404} 407}
405 408
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 9a102860df37..61095fe4b5ca 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -43,55 +43,6 @@ enum nfs4_client_state {
43}; 43};
44 44
45/* 45/*
46 * The nfs4_client identifies our client state to the server.
47 */
48struct nfs4_client {
49 struct list_head cl_servers; /* Global list of servers */
50 struct in_addr cl_addr; /* Server identifier */
51 u64 cl_clientid; /* constant */
52 nfs4_verifier cl_confirm;
53 unsigned long cl_state;
54
55 u32 cl_lockowner_id;
56
57 /*
58 * The following rwsem ensures exclusive access to the server
59 * while we recover the state following a lease expiration.
60 */
61 struct rw_semaphore cl_sem;
62
63 struct list_head cl_delegations;
64 struct list_head cl_state_owners;
65 struct list_head cl_unused;
66 int cl_nunused;
67 spinlock_t cl_lock;
68 atomic_t cl_count;
69
70 struct rpc_clnt * cl_rpcclient;
71
72 struct list_head cl_superblocks; /* List of nfs_server structs */
73
74 unsigned long cl_lease_time;
75 unsigned long cl_last_renewal;
76 struct work_struct cl_renewd;
77 struct work_struct cl_recoverd;
78
79 struct rpc_wait_queue cl_rpcwaitq;
80
81 /* used for the setclientid verifier */
82 struct timespec cl_boot_time;
83
84 /* idmapper */
85 struct idmap * cl_idmap;
86
87 /* Our own IP address, as a null-terminated string.
88 * This is used to generate the clientid, and the callback address.
89 */
90 char cl_ipaddr[16];
91 unsigned char cl_id_uniquifier;
92};
93
94/*
95 * struct rpc_sequence ensures that RPC calls are sent in the exact 46 * struct rpc_sequence ensures that RPC calls are sent in the exact
96 * order that they appear on the list. 47 * order that they appear on the list.
97 */ 48 */
@@ -127,7 +78,7 @@ static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status
127struct nfs4_state_owner { 78struct nfs4_state_owner {
128 spinlock_t so_lock; 79 spinlock_t so_lock;
129 struct list_head so_list; /* per-clientid list of state_owners */ 80 struct list_head so_list; /* per-clientid list of state_owners */
130 struct nfs4_client *so_client; 81 struct nfs_client *so_client;
131 u32 so_id; /* 32-bit identifier, unique */ 82 u32 so_id; /* 32-bit identifier, unique */
132 atomic_t so_count; 83 atomic_t so_count;
133 84
@@ -210,10 +161,10 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
210 161
211/* nfs4proc.c */ 162/* nfs4proc.c */
212extern int nfs4_map_errors(int err); 163extern int nfs4_map_errors(int err);
213extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short, struct rpc_cred *); 164extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
214extern int nfs4_proc_setclientid_confirm(struct nfs4_client *, struct rpc_cred *); 165extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
215extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *); 166extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
216extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *); 167extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
217extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); 168extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
218extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); 169extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
219extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); 170extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
@@ -231,19 +182,14 @@ extern const u32 nfs4_fsinfo_bitmap[2];
231extern const u32 nfs4_fs_locations_bitmap[2]; 182extern const u32 nfs4_fs_locations_bitmap[2];
232 183
233/* nfs4renewd.c */ 184/* nfs4renewd.c */
234extern void nfs4_schedule_state_renewal(struct nfs4_client *); 185extern void nfs4_schedule_state_renewal(struct nfs_client *);
235extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); 186extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
236extern void nfs4_kill_renewd(struct nfs4_client *); 187extern void nfs4_kill_renewd(struct nfs_client *);
237extern void nfs4_renew_state(void *); 188extern void nfs4_renew_state(void *);
238 189
239/* nfs4state.c */ 190/* nfs4state.c */
240extern void init_nfsv4_state(struct nfs_server *); 191struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp);
241extern void destroy_nfsv4_state(struct nfs_server *); 192extern u32 nfs4_alloc_lockowner_id(struct nfs_client *);
242extern struct nfs4_client *nfs4_get_client(struct in_addr *);
243extern void nfs4_put_client(struct nfs4_client *clp);
244extern struct nfs4_client *nfs4_find_client(struct in_addr *);
245struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp);
246extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
247 193
248extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); 194extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
249extern void nfs4_put_state_owner(struct nfs4_state_owner *); 195extern void nfs4_put_state_owner(struct nfs4_state_owner *);
@@ -252,7 +198,7 @@ extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state
252extern void nfs4_put_open_state(struct nfs4_state *); 198extern void nfs4_put_open_state(struct nfs4_state *);
253extern void nfs4_close_state(struct nfs4_state *, mode_t); 199extern void nfs4_close_state(struct nfs4_state *, mode_t);
254extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t); 200extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
255extern void nfs4_schedule_state_recovery(struct nfs4_client *); 201extern void nfs4_schedule_state_recovery(struct nfs_client *);
256extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 202extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
257extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 203extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
258extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); 204extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
@@ -276,10 +222,6 @@ extern struct svc_version nfs4_callback_version1;
276 222
277#else 223#else
278 224
279#define init_nfsv4_state(server) do { } while (0)
280#define destroy_nfsv4_state(server) do { } while (0)
281#define nfs4_put_state_owner(inode, owner) do { } while (0)
282#define nfs4_put_open_state(state) do { } while (0)
283#define nfs4_close_state(a, b) do { } while (0) 225#define nfs4_close_state(a, b) do { } while (0)
284 226
285#endif /* CONFIG_NFS_V4 */ 227#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index ea38d27b74e6..24e47f3bbd17 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -2,6 +2,7 @@
2 * linux/fs/nfs/nfs4namespace.c 2 * linux/fs/nfs/nfs4namespace.c
3 * 3 *
4 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com> 4 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com>
5 * - Modified by David Howells <dhowells@redhat.com>
5 * 6 *
6 * NFSv4 namespace 7 * NFSv4 namespace
7 */ 8 */
@@ -23,7 +24,7 @@
23/* 24/*
24 * Check if fs_root is valid 25 * Check if fs_root is valid
25 */ 26 */
26static inline char *nfs4_pathname_string(struct nfs4_pathname *pathname, 27static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname,
27 char *buffer, ssize_t buflen) 28 char *buffer, ssize_t buflen)
28{ 29{
29 char *end = buffer + buflen; 30 char *end = buffer + buflen;
@@ -34,7 +35,7 @@ static inline char *nfs4_pathname_string(struct nfs4_pathname *pathname,
34 35
35 n = pathname->ncomponents; 36 n = pathname->ncomponents;
36 while (--n >= 0) { 37 while (--n >= 0) {
37 struct nfs4_string *component = &pathname->components[n]; 38 const struct nfs4_string *component = &pathname->components[n];
38 buflen -= component->len + 1; 39 buflen -= component->len + 1;
39 if (buflen < 0) 40 if (buflen < 0)
40 goto Elong; 41 goto Elong;
@@ -47,6 +48,68 @@ Elong:
47 return ERR_PTR(-ENAMETOOLONG); 48 return ERR_PTR(-ENAMETOOLONG);
48} 49}
49 50
51/*
52 * Determine the mount path as a string
53 */
54static char *nfs4_path(const struct vfsmount *mnt_parent,
55 const struct dentry *dentry,
56 char *buffer, ssize_t buflen)
57{
58 const char *srvpath;
59
60 srvpath = strchr(mnt_parent->mnt_devname, ':');
61 if (srvpath)
62 srvpath++;
63 else
64 srvpath = mnt_parent->mnt_devname;
65
66 return nfs_path(srvpath, mnt_parent->mnt_root, dentry, buffer, buflen);
67}
68
69/*
70 * Check that fs_locations::fs_root [RFC3530 6.3] is a prefix for what we
71 * believe to be the server path to this dentry
72 */
73static int nfs4_validate_fspath(const struct vfsmount *mnt_parent,
74 const struct dentry *dentry,
75 const struct nfs4_fs_locations *locations,
76 char *page, char *page2)
77{
78 const char *path, *fs_path;
79
80 path = nfs4_path(mnt_parent, dentry, page, PAGE_SIZE);
81 if (IS_ERR(path))
82 return PTR_ERR(path);
83
84 fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE);
85 if (IS_ERR(fs_path))
86 return PTR_ERR(fs_path);
87
88 if (strncmp(path, fs_path, strlen(fs_path)) != 0) {
89 dprintk("%s: path %s does not begin with fsroot %s\n",
90 __FUNCTION__, path, fs_path);
91 return -ENOENT;
92 }
93
94 return 0;
95}
96
97/*
98 * Check if the string represents a "valid" IPv4 address
99 */
100static inline int valid_ipaddr4(const char *buf)
101{
102 int rc, count, in[4];
103
104 rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
105 if (rc != 4)
106 return -EINVAL;
107 for (count = 0; count < 4; count++) {
108 if (in[count] > 255)
109 return -EINVAL;
110 }
111 return 0;
112}
50 113
51/** 114/**
52 * nfs_follow_referral - set up mountpoint when hitting a referral on moved error 115 * nfs_follow_referral - set up mountpoint when hitting a referral on moved error
@@ -60,7 +123,7 @@ Elong:
60 */ 123 */
61static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent, 124static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
62 const struct dentry *dentry, 125 const struct dentry *dentry,
63 struct nfs4_fs_locations *locations) 126 const struct nfs4_fs_locations *locations)
64{ 127{
65 struct vfsmount *mnt = ERR_PTR(-ENOENT); 128 struct vfsmount *mnt = ERR_PTR(-ENOENT);
66 struct nfs_clone_mount mountdata = { 129 struct nfs_clone_mount mountdata = {
@@ -68,10 +131,9 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
68 .dentry = dentry, 131 .dentry = dentry,
69 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor, 132 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor,
70 }; 133 };
71 char *page, *page2; 134 char *page = NULL, *page2 = NULL;
72 char *path, *fs_path;
73 char *devname; 135 char *devname;
74 int loc, s; 136 int loc, s, error;
75 137
76 if (locations == NULL || locations->nlocations <= 0) 138 if (locations == NULL || locations->nlocations <= 0)
77 goto out; 139 goto out;
@@ -79,36 +141,30 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
79 dprintk("%s: referral at %s/%s\n", __FUNCTION__, 141 dprintk("%s: referral at %s/%s\n", __FUNCTION__,
80 dentry->d_parent->d_name.name, dentry->d_name.name); 142 dentry->d_parent->d_name.name, dentry->d_name.name);
81 143
82 /* Ensure fs path is a prefix of current dentry path */
83 page = (char *) __get_free_page(GFP_USER); 144 page = (char *) __get_free_page(GFP_USER);
84 if (page == NULL) 145 if (!page)
85 goto out; 146 goto out;
147
86 page2 = (char *) __get_free_page(GFP_USER); 148 page2 = (char *) __get_free_page(GFP_USER);
87 if (page2 == NULL) 149 if (!page2)
88 goto out; 150 goto out;
89 151
90 path = nfs4_path(dentry, page, PAGE_SIZE); 152 /* Ensure fs path is a prefix of current dentry path */
91 if (IS_ERR(path)) 153 error = nfs4_validate_fspath(mnt_parent, dentry, locations, page, page2);
92 goto out_free; 154 if (error < 0) {
93 155 mnt = ERR_PTR(error);
94 fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE); 156 goto out;
95 if (IS_ERR(fs_path))
96 goto out_free;
97
98 if (strncmp(path, fs_path, strlen(fs_path)) != 0) {
99 dprintk("%s: path %s does not begin with fsroot %s\n", __FUNCTION__, path, fs_path);
100 goto out_free;
101 } 157 }
102 158
103 devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE); 159 devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
104 if (IS_ERR(devname)) { 160 if (IS_ERR(devname)) {
105 mnt = (struct vfsmount *)devname; 161 mnt = (struct vfsmount *)devname;
106 goto out_free; 162 goto out;
107 } 163 }
108 164
109 loc = 0; 165 loc = 0;
110 while (loc < locations->nlocations && IS_ERR(mnt)) { 166 while (loc < locations->nlocations && IS_ERR(mnt)) {
111 struct nfs4_fs_location *location = &locations->locations[loc]; 167 const struct nfs4_fs_location *location = &locations->locations[loc];
112 char *mnt_path; 168 char *mnt_path;
113 169
114 if (location == NULL || location->nservers <= 0 || 170 if (location == NULL || location->nservers <= 0 ||
@@ -140,7 +196,7 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
140 addr.sin_port = htons(NFS_PORT); 196 addr.sin_port = htons(NFS_PORT);
141 mountdata.addr = &addr; 197 mountdata.addr = &addr;
142 198
143 mnt = vfs_kern_mount(&nfs_referral_nfs4_fs_type, 0, devname, &mountdata); 199 mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, devname, &mountdata);
144 if (!IS_ERR(mnt)) { 200 if (!IS_ERR(mnt)) {
145 break; 201 break;
146 } 202 }
@@ -149,10 +205,9 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
149 loc++; 205 loc++;
150 } 206 }
151 207
152out_free:
153 free_page((unsigned long)page);
154 free_page((unsigned long)page2);
155out: 208out:
209 free_page((unsigned long) page);
210 free_page((unsigned long) page2);
156 dprintk("%s: done\n", __FUNCTION__); 211 dprintk("%s: done\n", __FUNCTION__);
157 return mnt; 212 return mnt;
158} 213}
@@ -165,7 +220,7 @@ out:
165 */ 220 */
166struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry) 221struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
167{ 222{
168 struct vfsmount *mnt = ERR_PTR(-ENOENT); 223 struct vfsmount *mnt = ERR_PTR(-ENOMEM);
169 struct dentry *parent; 224 struct dentry *parent;
170 struct nfs4_fs_locations *fs_locations = NULL; 225 struct nfs4_fs_locations *fs_locations = NULL;
171 struct page *page; 226 struct page *page;
@@ -183,11 +238,16 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr
183 goto out_free; 238 goto out_free;
184 239
185 /* Get locations */ 240 /* Get locations */
241 mnt = ERR_PTR(-ENOENT);
242
186 parent = dget_parent(dentry); 243 parent = dget_parent(dentry);
187 dprintk("%s: getting locations for %s/%s\n", __FUNCTION__, parent->d_name.name, dentry->d_name.name); 244 dprintk("%s: getting locations for %s/%s\n",
245 __FUNCTION__, parent->d_name.name, dentry->d_name.name);
246
188 err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page); 247 err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page);
189 dput(parent); 248 dput(parent);
190 if (err != 0 || fs_locations->nlocations <= 0 || 249 if (err != 0 ||
250 fs_locations->nlocations <= 0 ||
191 fs_locations->fs_path.ncomponents <= 0) 251 fs_locations->fs_path.ncomponents <= 0)
192 goto out_free; 252 goto out_free;
193 253
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index b14145b7b87f..47c7e6e3910d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -55,7 +55,7 @@
55 55
56#define NFSDBG_FACILITY NFSDBG_PROC 56#define NFSDBG_FACILITY NFSDBG_PROC
57 57
58#define NFS4_POLL_RETRY_MIN (1*HZ) 58#define NFS4_POLL_RETRY_MIN (HZ/10)
59#define NFS4_POLL_RETRY_MAX (15*HZ) 59#define NFS4_POLL_RETRY_MAX (15*HZ)
60 60
61struct nfs4_opendata; 61struct nfs4_opendata;
@@ -64,7 +64,7 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
64static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); 64static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
65static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); 65static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
66static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); 66static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
67static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp); 67static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
68 68
69/* Prevent leaks of NFSv4 errors into userland */ 69/* Prevent leaks of NFSv4 errors into userland */
70int nfs4_map_errors(int err) 70int nfs4_map_errors(int err)
@@ -195,7 +195,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
195 195
196static void renew_lease(const struct nfs_server *server, unsigned long timestamp) 196static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
197{ 197{
198 struct nfs4_client *clp = server->nfs4_state; 198 struct nfs_client *clp = server->nfs_client;
199 spin_lock(&clp->cl_lock); 199 spin_lock(&clp->cl_lock);
200 if (time_before(clp->cl_last_renewal,timestamp)) 200 if (time_before(clp->cl_last_renewal,timestamp))
201 clp->cl_last_renewal = timestamp; 201 clp->cl_last_renewal = timestamp;
@@ -252,7 +252,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
252 atomic_inc(&sp->so_count); 252 atomic_inc(&sp->so_count);
253 p->o_arg.fh = NFS_FH(dir); 253 p->o_arg.fh = NFS_FH(dir);
254 p->o_arg.open_flags = flags, 254 p->o_arg.open_flags = flags,
255 p->o_arg.clientid = server->nfs4_state->cl_clientid; 255 p->o_arg.clientid = server->nfs_client->cl_clientid;
256 p->o_arg.id = sp->so_id; 256 p->o_arg.id = sp->so_id;
257 p->o_arg.name = &dentry->d_name; 257 p->o_arg.name = &dentry->d_name;
258 p->o_arg.server = server; 258 p->o_arg.server = server;
@@ -550,7 +550,7 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
550 case -NFS4ERR_STALE_STATEID: 550 case -NFS4ERR_STALE_STATEID:
551 case -NFS4ERR_EXPIRED: 551 case -NFS4ERR_EXPIRED:
552 /* Don't recall a delegation if it was lost */ 552 /* Don't recall a delegation if it was lost */
553 nfs4_schedule_state_recovery(server->nfs4_state); 553 nfs4_schedule_state_recovery(server->nfs_client);
554 return err; 554 return err;
555 } 555 }
556 err = nfs4_handle_exception(server, err, &exception); 556 err = nfs4_handle_exception(server, err, &exception);
@@ -758,7 +758,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
758 } 758 }
759 nfs_confirm_seqid(&data->owner->so_seqid, 0); 759 nfs_confirm_seqid(&data->owner->so_seqid, 0);
760 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) 760 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
761 return server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); 761 return server->nfs_client->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
762 return 0; 762 return 0;
763} 763}
764 764
@@ -792,11 +792,18 @@ out:
792 792
793int nfs4_recover_expired_lease(struct nfs_server *server) 793int nfs4_recover_expired_lease(struct nfs_server *server)
794{ 794{
795 struct nfs4_client *clp = server->nfs4_state; 795 struct nfs_client *clp = server->nfs_client;
796 int ret;
796 797
797 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) 798 for (;;) {
799 ret = nfs4_wait_clnt_recover(server->client, clp);
800 if (ret != 0)
801 return ret;
802 if (!test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
803 break;
798 nfs4_schedule_state_recovery(clp); 804 nfs4_schedule_state_recovery(clp);
799 return nfs4_wait_clnt_recover(server->client, clp); 805 }
806 return 0;
800} 807}
801 808
802/* 809/*
@@ -867,7 +874,7 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
867{ 874{
868 struct nfs_delegation *delegation; 875 struct nfs_delegation *delegation;
869 struct nfs_server *server = NFS_SERVER(inode); 876 struct nfs_server *server = NFS_SERVER(inode);
870 struct nfs4_client *clp = server->nfs4_state; 877 struct nfs_client *clp = server->nfs_client;
871 struct nfs_inode *nfsi = NFS_I(inode); 878 struct nfs_inode *nfsi = NFS_I(inode);
872 struct nfs4_state_owner *sp = NULL; 879 struct nfs4_state_owner *sp = NULL;
873 struct nfs4_state *state = NULL; 880 struct nfs4_state *state = NULL;
@@ -953,7 +960,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
953 struct nfs4_state_owner *sp; 960 struct nfs4_state_owner *sp;
954 struct nfs4_state *state = NULL; 961 struct nfs4_state *state = NULL;
955 struct nfs_server *server = NFS_SERVER(dir); 962 struct nfs_server *server = NFS_SERVER(dir);
956 struct nfs4_client *clp = server->nfs4_state; 963 struct nfs_client *clp = server->nfs_client;
957 struct nfs4_opendata *opendata; 964 struct nfs4_opendata *opendata;
958 int status; 965 int status;
959 966
@@ -1133,7 +1140,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1133 break; 1140 break;
1134 case -NFS4ERR_STALE_STATEID: 1141 case -NFS4ERR_STALE_STATEID:
1135 case -NFS4ERR_EXPIRED: 1142 case -NFS4ERR_EXPIRED:
1136 nfs4_schedule_state_recovery(server->nfs4_state); 1143 nfs4_schedule_state_recovery(server->nfs_client);
1137 break; 1144 break;
1138 default: 1145 default:
1139 if (nfs4_async_handle_error(task, server) == -EAGAIN) { 1146 if (nfs4_async_handle_error(task, server) == -EAGAIN) {
@@ -1268,7 +1275,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
1268 BUG_ON(nd->intent.open.flags & O_CREAT); 1275 BUG_ON(nd->intent.open.flags & O_CREAT);
1269 } 1276 }
1270 1277
1271 cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); 1278 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
1272 if (IS_ERR(cred)) 1279 if (IS_ERR(cred))
1273 return (struct dentry *)cred; 1280 return (struct dentry *)cred;
1274 state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred); 1281 state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
@@ -1291,7 +1298,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
1291 struct rpc_cred *cred; 1298 struct rpc_cred *cred;
1292 struct nfs4_state *state; 1299 struct nfs4_state *state;
1293 1300
1294 cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); 1301 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
1295 if (IS_ERR(cred)) 1302 if (IS_ERR(cred))
1296 return PTR_ERR(cred); 1303 return PTR_ERR(cred);
1297 state = nfs4_open_delegated(dentry->d_inode, openflags, cred); 1304 state = nfs4_open_delegated(dentry->d_inode, openflags, cred);
@@ -1393,70 +1400,19 @@ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
1393 return err; 1400 return err;
1394} 1401}
1395 1402
1403/*
1404 * get the file handle for the "/" directory on the server
1405 */
1396static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, 1406static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
1397 struct nfs_fsinfo *info) 1407 struct nfs_fsinfo *info)
1398{ 1408{
1399 struct nfs_fattr * fattr = info->fattr;
1400 unsigned char * p;
1401 struct qstr q;
1402 struct nfs4_lookup_arg args = {
1403 .dir_fh = fhandle,
1404 .name = &q,
1405 .bitmask = nfs4_fattr_bitmap,
1406 };
1407 struct nfs4_lookup_res res = {
1408 .server = server,
1409 .fattr = fattr,
1410 .fh = fhandle,
1411 };
1412 struct rpc_message msg = {
1413 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
1414 .rpc_argp = &args,
1415 .rpc_resp = &res,
1416 };
1417 int status; 1409 int status;
1418 1410
1419 /*
1420 * Now we do a separate LOOKUP for each component of the mount path.
1421 * The LOOKUPs are done separately so that we can conveniently
1422 * catch an ERR_WRONGSEC if it occurs along the way...
1423 */
1424 status = nfs4_lookup_root(server, fhandle, info); 1411 status = nfs4_lookup_root(server, fhandle, info);
1425 if (status)
1426 goto out;
1427
1428 p = server->mnt_path;
1429 for (;;) {
1430 struct nfs4_exception exception = { };
1431
1432 while (*p == '/')
1433 p++;
1434 if (!*p)
1435 break;
1436 q.name = p;
1437 while (*p && (*p != '/'))
1438 p++;
1439 q.len = p - q.name;
1440
1441 do {
1442 nfs_fattr_init(fattr);
1443 status = nfs4_handle_exception(server,
1444 rpc_call_sync(server->client, &msg, 0),
1445 &exception);
1446 } while (exception.retry);
1447 if (status == 0)
1448 continue;
1449 if (status == -ENOENT) {
1450 printk(KERN_NOTICE "NFS: mount path %s does not exist!\n", server->mnt_path);
1451 printk(KERN_NOTICE "NFS: suggestion: try mounting '/' instead.\n");
1452 }
1453 break;
1454 }
1455 if (status == 0) 1412 if (status == 0)
1456 status = nfs4_server_capabilities(server, fhandle); 1413 status = nfs4_server_capabilities(server, fhandle);
1457 if (status == 0) 1414 if (status == 0)
1458 status = nfs4_do_fsinfo(server, fhandle, info); 1415 status = nfs4_do_fsinfo(server, fhandle, info);
1459out:
1460 return nfs4_map_errors(status); 1416 return nfs4_map_errors(status);
1461} 1417}
1462 1418
@@ -1565,7 +1521,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
1565 1521
1566 nfs_fattr_init(fattr); 1522 nfs_fattr_init(fattr);
1567 1523
1568 cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0); 1524 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
1569 if (IS_ERR(cred)) 1525 if (IS_ERR(cred))
1570 return PTR_ERR(cred); 1526 return PTR_ERR(cred);
1571 1527
@@ -1583,6 +1539,52 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
1583 return status; 1539 return status;
1584} 1540}
1585 1541
1542static int _nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
1543 struct qstr *name, struct nfs_fh *fhandle,
1544 struct nfs_fattr *fattr)
1545{
1546 int status;
1547 struct nfs4_lookup_arg args = {
1548 .bitmask = server->attr_bitmask,
1549 .dir_fh = dirfh,
1550 .name = name,
1551 };
1552 struct nfs4_lookup_res res = {
1553 .server = server,
1554 .fattr = fattr,
1555 .fh = fhandle,
1556 };
1557 struct rpc_message msg = {
1558 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
1559 .rpc_argp = &args,
1560 .rpc_resp = &res,
1561 };
1562
1563 nfs_fattr_init(fattr);
1564
1565 dprintk("NFS call lookupfh %s\n", name->name);
1566 status = rpc_call_sync(server->client, &msg, 0);
1567 dprintk("NFS reply lookupfh: %d\n", status);
1568 if (status == -NFS4ERR_MOVED)
1569 status = -EREMOTE;
1570 return status;
1571}
1572
1573static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
1574 struct qstr *name, struct nfs_fh *fhandle,
1575 struct nfs_fattr *fattr)
1576{
1577 struct nfs4_exception exception = { };
1578 int err;
1579 do {
1580 err = nfs4_handle_exception(server,
1581 _nfs4_proc_lookupfh(server, dirfh, name,
1582 fhandle, fattr),
1583 &exception);
1584 } while (exception.retry);
1585 return err;
1586}
1587
1586static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name, 1588static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name,
1587 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 1589 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
1588{ 1590{
@@ -1881,7 +1883,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1881 struct rpc_cred *cred; 1883 struct rpc_cred *cred;
1882 int status = 0; 1884 int status = 0;
1883 1885
1884 cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); 1886 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
1885 if (IS_ERR(cred)) { 1887 if (IS_ERR(cred)) {
1886 status = PTR_ERR(cred); 1888 status = PTR_ERR(cred);
1887 goto out; 1889 goto out;
@@ -2089,24 +2091,24 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n
2089 return err; 2091 return err;
2090} 2092}
2091 2093
2092static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name, 2094static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
2093 struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle, 2095 struct page *page, unsigned int len, struct iattr *sattr)
2094 struct nfs_fattr *fattr)
2095{ 2096{
2096 struct nfs_server *server = NFS_SERVER(dir); 2097 struct nfs_server *server = NFS_SERVER(dir);
2097 struct nfs_fattr dir_fattr; 2098 struct nfs_fh fhandle;
2099 struct nfs_fattr fattr, dir_fattr;
2098 struct nfs4_create_arg arg = { 2100 struct nfs4_create_arg arg = {
2099 .dir_fh = NFS_FH(dir), 2101 .dir_fh = NFS_FH(dir),
2100 .server = server, 2102 .server = server,
2101 .name = name, 2103 .name = &dentry->d_name,
2102 .attrs = sattr, 2104 .attrs = sattr,
2103 .ftype = NF4LNK, 2105 .ftype = NF4LNK,
2104 .bitmask = server->attr_bitmask, 2106 .bitmask = server->attr_bitmask,
2105 }; 2107 };
2106 struct nfs4_create_res res = { 2108 struct nfs4_create_res res = {
2107 .server = server, 2109 .server = server,
2108 .fh = fhandle, 2110 .fh = &fhandle,
2109 .fattr = fattr, 2111 .fattr = &fattr,
2110 .dir_fattr = &dir_fattr, 2112 .dir_fattr = &dir_fattr,
2111 }; 2113 };
2112 struct rpc_message msg = { 2114 struct rpc_message msg = {
@@ -2116,29 +2118,32 @@ static int _nfs4_proc_symlink(struct inode *dir, struct qstr *name,
2116 }; 2118 };
2117 int status; 2119 int status;
2118 2120
2119 if (path->len > NFS4_MAXPATHLEN) 2121 if (len > NFS4_MAXPATHLEN)
2120 return -ENAMETOOLONG; 2122 return -ENAMETOOLONG;
2121 arg.u.symlink = path; 2123
2122 nfs_fattr_init(fattr); 2124 arg.u.symlink.pages = &page;
2125 arg.u.symlink.len = len;
2126 nfs_fattr_init(&fattr);
2123 nfs_fattr_init(&dir_fattr); 2127 nfs_fattr_init(&dir_fattr);
2124 2128
2125 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 2129 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
2126 if (!status) 2130 if (!status) {
2127 update_changeattr(dir, &res.dir_cinfo); 2131 update_changeattr(dir, &res.dir_cinfo);
2128 nfs_post_op_update_inode(dir, res.dir_fattr); 2132 nfs_post_op_update_inode(dir, res.dir_fattr);
2133 status = nfs_instantiate(dentry, &fhandle, &fattr);
2134 }
2129 return status; 2135 return status;
2130} 2136}
2131 2137
2132static int nfs4_proc_symlink(struct inode *dir, struct qstr *name, 2138static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
2133 struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle, 2139 struct page *page, unsigned int len, struct iattr *sattr)
2134 struct nfs_fattr *fattr)
2135{ 2140{
2136 struct nfs4_exception exception = { }; 2141 struct nfs4_exception exception = { };
2137 int err; 2142 int err;
2138 do { 2143 do {
2139 err = nfs4_handle_exception(NFS_SERVER(dir), 2144 err = nfs4_handle_exception(NFS_SERVER(dir),
2140 _nfs4_proc_symlink(dir, name, path, sattr, 2145 _nfs4_proc_symlink(dir, dentry, page,
2141 fhandle, fattr), 2146 len, sattr),
2142 &exception); 2147 &exception);
2143 } while (exception.retry); 2148 } while (exception.retry);
2144 return err; 2149 return err;
@@ -2521,7 +2526,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
2521 */ 2526 */
2522static void nfs4_renew_done(struct rpc_task *task, void *data) 2527static void nfs4_renew_done(struct rpc_task *task, void *data)
2523{ 2528{
2524 struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; 2529 struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp;
2525 unsigned long timestamp = (unsigned long)data; 2530 unsigned long timestamp = (unsigned long)data;
2526 2531
2527 if (task->tk_status < 0) { 2532 if (task->tk_status < 0) {
@@ -2543,7 +2548,7 @@ static const struct rpc_call_ops nfs4_renew_ops = {
2543 .rpc_call_done = nfs4_renew_done, 2548 .rpc_call_done = nfs4_renew_done,
2544}; 2549};
2545 2550
2546int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred) 2551int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
2547{ 2552{
2548 struct rpc_message msg = { 2553 struct rpc_message msg = {
2549 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 2554 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2555,7 +2560,7 @@ int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred)
2555 &nfs4_renew_ops, (void *)jiffies); 2560 &nfs4_renew_ops, (void *)jiffies);
2556} 2561}
2557 2562
2558int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred) 2563int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
2559{ 2564{
2560 struct rpc_message msg = { 2565 struct rpc_message msg = {
2561 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], 2566 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -2770,7 +2775,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
2770 return -EOPNOTSUPP; 2775 return -EOPNOTSUPP;
2771 nfs_inode_return_delegation(inode); 2776 nfs_inode_return_delegation(inode);
2772 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); 2777 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
2773 ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0); 2778 ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
2774 if (ret == 0) 2779 if (ret == 0)
2775 nfs4_write_cached_acl(inode, buf, buflen); 2780 nfs4_write_cached_acl(inode, buf, buflen);
2776 return ret; 2781 return ret;
@@ -2791,7 +2796,7 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
2791static int 2796static int
2792nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) 2797nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
2793{ 2798{
2794 struct nfs4_client *clp = server->nfs4_state; 2799 struct nfs_client *clp = server->nfs_client;
2795 2800
2796 if (!clp || task->tk_status >= 0) 2801 if (!clp || task->tk_status >= 0)
2797 return 0; 2802 return 0;
@@ -2828,7 +2833,7 @@ static int nfs4_wait_bit_interruptible(void *word)
2828 return 0; 2833 return 0;
2829} 2834}
2830 2835
2831static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp) 2836static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp)
2832{ 2837{
2833 sigset_t oldset; 2838 sigset_t oldset;
2834 int res; 2839 int res;
@@ -2871,7 +2876,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
2871 */ 2876 */
2872int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) 2877int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
2873{ 2878{
2874 struct nfs4_client *clp = server->nfs4_state; 2879 struct nfs_client *clp = server->nfs_client;
2875 int ret = errorcode; 2880 int ret = errorcode;
2876 2881
2877 exception->retry = 0; 2882 exception->retry = 0;
@@ -2886,6 +2891,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
2886 if (ret == 0) 2891 if (ret == 0)
2887 exception->retry = 1; 2892 exception->retry = 1;
2888 break; 2893 break;
2894 case -NFS4ERR_FILE_OPEN:
2889 case -NFS4ERR_GRACE: 2895 case -NFS4ERR_GRACE:
2890 case -NFS4ERR_DELAY: 2896 case -NFS4ERR_DELAY:
2891 ret = nfs4_delay(server->client, &exception->timeout); 2897 ret = nfs4_delay(server->client, &exception->timeout);
@@ -2898,7 +2904,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
2898 return nfs4_map_errors(ret); 2904 return nfs4_map_errors(ret);
2899} 2905}
2900 2906
2901int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) 2907int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
2902{ 2908{
2903 nfs4_verifier sc_verifier; 2909 nfs4_verifier sc_verifier;
2904 struct nfs4_setclientid setclientid = { 2910 struct nfs4_setclientid setclientid = {
@@ -2922,7 +2928,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
2922 for(;;) { 2928 for(;;) {
2923 setclientid.sc_name_len = scnprintf(setclientid.sc_name, 2929 setclientid.sc_name_len = scnprintf(setclientid.sc_name,
2924 sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", 2930 sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u",
2925 clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), 2931 clp->cl_ipaddr, NIPQUAD(clp->cl_addr.sin_addr),
2926 cred->cr_ops->cr_name, 2932 cred->cr_ops->cr_name,
2927 clp->cl_id_uniquifier); 2933 clp->cl_id_uniquifier);
2928 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, 2934 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
@@ -2945,7 +2951,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p
2945 return status; 2951 return status;
2946} 2952}
2947 2953
2948static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) 2954static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
2949{ 2955{
2950 struct nfs_fsinfo fsinfo; 2956 struct nfs_fsinfo fsinfo;
2951 struct rpc_message msg = { 2957 struct rpc_message msg = {
@@ -2969,7 +2975,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cr
2969 return status; 2975 return status;
2970} 2976}
2971 2977
2972int nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) 2978int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
2973{ 2979{
2974 long timeout; 2980 long timeout;
2975 int err; 2981 int err;
@@ -3077,7 +3083,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
3077 switch (err) { 3083 switch (err) {
3078 case -NFS4ERR_STALE_STATEID: 3084 case -NFS4ERR_STALE_STATEID:
3079 case -NFS4ERR_EXPIRED: 3085 case -NFS4ERR_EXPIRED:
3080 nfs4_schedule_state_recovery(server->nfs4_state); 3086 nfs4_schedule_state_recovery(server->nfs_client);
3081 case 0: 3087 case 0:
3082 return 0; 3088 return 0;
3083 } 3089 }
@@ -3106,7 +3112,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3106{ 3112{
3107 struct inode *inode = state->inode; 3113 struct inode *inode = state->inode;
3108 struct nfs_server *server = NFS_SERVER(inode); 3114 struct nfs_server *server = NFS_SERVER(inode);
3109 struct nfs4_client *clp = server->nfs4_state; 3115 struct nfs_client *clp = server->nfs_client;
3110 struct nfs_lockt_args arg = { 3116 struct nfs_lockt_args arg = {
3111 .fh = NFS_FH(inode), 3117 .fh = NFS_FH(inode),
3112 .fl = request, 3118 .fl = request,
@@ -3231,7 +3237,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3231 break; 3237 break;
3232 case -NFS4ERR_STALE_STATEID: 3238 case -NFS4ERR_STALE_STATEID:
3233 case -NFS4ERR_EXPIRED: 3239 case -NFS4ERR_EXPIRED:
3234 nfs4_schedule_state_recovery(calldata->server->nfs4_state); 3240 nfs4_schedule_state_recovery(calldata->server->nfs_client);
3235 break; 3241 break;
3236 default: 3242 default:
3237 if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) { 3243 if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) {
@@ -3343,7 +3349,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
3343 if (p->arg.lock_seqid == NULL) 3349 if (p->arg.lock_seqid == NULL)
3344 goto out_free; 3350 goto out_free;
3345 p->arg.lock_stateid = &lsp->ls_stateid; 3351 p->arg.lock_stateid = &lsp->ls_stateid;
3346 p->arg.lock_owner.clientid = server->nfs4_state->cl_clientid; 3352 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
3347 p->arg.lock_owner.id = lsp->ls_id; 3353 p->arg.lock_owner.id = lsp->ls_id;
3348 p->lsp = lsp; 3354 p->lsp = lsp;
3349 atomic_inc(&lsp->ls_count); 3355 atomic_inc(&lsp->ls_count);
@@ -3513,7 +3519,7 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
3513 3519
3514static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 3520static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
3515{ 3521{
3516 struct nfs4_client *clp = state->owner->so_client; 3522 struct nfs_client *clp = state->owner->so_client;
3517 unsigned char fl_flags = request->fl_flags; 3523 unsigned char fl_flags = request->fl_flags;
3518 int status; 3524 int status;
3519 3525
@@ -3715,7 +3721,7 @@ static struct inode_operations nfs4_file_inode_operations = {
3715 .listxattr = nfs4_listxattr, 3721 .listxattr = nfs4_listxattr,
3716}; 3722};
3717 3723
3718struct nfs_rpc_ops nfs_v4_clientops = { 3724const struct nfs_rpc_ops nfs_v4_clientops = {
3719 .version = 4, /* protocol version */ 3725 .version = 4, /* protocol version */
3720 .dentry_ops = &nfs4_dentry_operations, 3726 .dentry_ops = &nfs4_dentry_operations,
3721 .dir_inode_ops = &nfs4_dir_inode_operations, 3727 .dir_inode_ops = &nfs4_dir_inode_operations,
@@ -3723,6 +3729,7 @@ struct nfs_rpc_ops nfs_v4_clientops = {
3723 .getroot = nfs4_proc_get_root, 3729 .getroot = nfs4_proc_get_root,
3724 .getattr = nfs4_proc_getattr, 3730 .getattr = nfs4_proc_getattr,
3725 .setattr = nfs4_proc_setattr, 3731 .setattr = nfs4_proc_setattr,
3732 .lookupfh = nfs4_proc_lookupfh,
3726 .lookup = nfs4_proc_lookup, 3733 .lookup = nfs4_proc_lookup,
3727 .access = nfs4_proc_access, 3734 .access = nfs4_proc_access,
3728 .readlink = nfs4_proc_readlink, 3735 .readlink = nfs4_proc_readlink,
@@ -3743,6 +3750,7 @@ struct nfs_rpc_ops nfs_v4_clientops = {
3743 .statfs = nfs4_proc_statfs, 3750 .statfs = nfs4_proc_statfs,
3744 .fsinfo = nfs4_proc_fsinfo, 3751 .fsinfo = nfs4_proc_fsinfo,
3745 .pathconf = nfs4_proc_pathconf, 3752 .pathconf = nfs4_proc_pathconf,
3753 .set_capabilities = nfs4_server_capabilities,
3746 .decode_dirent = nfs4_decode_dirent, 3754 .decode_dirent = nfs4_decode_dirent,
3747 .read_setup = nfs4_proc_read_setup, 3755 .read_setup = nfs4_proc_read_setup,
3748 .read_done = nfs4_read_done, 3756 .read_done = nfs4_read_done,
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 5d764d8e6d8a..7b6df1852e75 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -61,7 +61,7 @@
61void 61void
62nfs4_renew_state(void *data) 62nfs4_renew_state(void *data)
63{ 63{
64 struct nfs4_client *clp = (struct nfs4_client *)data; 64 struct nfs_client *clp = (struct nfs_client *)data;
65 struct rpc_cred *cred; 65 struct rpc_cred *cred;
66 long lease, timeout; 66 long lease, timeout;
67 unsigned long last, now; 67 unsigned long last, now;
@@ -108,7 +108,7 @@ out:
108 108
109/* Must be called with clp->cl_sem locked for writes */ 109/* Must be called with clp->cl_sem locked for writes */
110void 110void
111nfs4_schedule_state_renewal(struct nfs4_client *clp) 111nfs4_schedule_state_renewal(struct nfs_client *clp)
112{ 112{
113 long timeout; 113 long timeout;
114 114
@@ -121,32 +121,20 @@ nfs4_schedule_state_renewal(struct nfs4_client *clp)
121 __FUNCTION__, (timeout + HZ - 1) / HZ); 121 __FUNCTION__, (timeout + HZ - 1) / HZ);
122 cancel_delayed_work(&clp->cl_renewd); 122 cancel_delayed_work(&clp->cl_renewd);
123 schedule_delayed_work(&clp->cl_renewd, timeout); 123 schedule_delayed_work(&clp->cl_renewd, timeout);
124 set_bit(NFS_CS_RENEWD, &clp->cl_res_state);
124 spin_unlock(&clp->cl_lock); 125 spin_unlock(&clp->cl_lock);
125} 126}
126 127
127void 128void
128nfs4_renewd_prepare_shutdown(struct nfs_server *server) 129nfs4_renewd_prepare_shutdown(struct nfs_server *server)
129{ 130{
130 struct nfs4_client *clp = server->nfs4_state;
131
132 if (!clp)
133 return;
134 flush_scheduled_work(); 131 flush_scheduled_work();
135 down_write(&clp->cl_sem);
136 if (!list_empty(&server->nfs4_siblings))
137 list_del_init(&server->nfs4_siblings);
138 up_write(&clp->cl_sem);
139} 132}
140 133
141/* Must be called with clp->cl_sem locked for writes */
142void 134void
143nfs4_kill_renewd(struct nfs4_client *clp) 135nfs4_kill_renewd(struct nfs_client *clp)
144{ 136{
145 down_read(&clp->cl_sem); 137 down_read(&clp->cl_sem);
146 if (!list_empty(&clp->cl_superblocks)) {
147 up_read(&clp->cl_sem);
148 return;
149 }
150 cancel_delayed_work(&clp->cl_renewd); 138 cancel_delayed_work(&clp->cl_renewd);
151 up_read(&clp->cl_sem); 139 up_read(&clp->cl_sem);
152 flush_scheduled_work(); 140 flush_scheduled_work();
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 090a36b07a22..5fffbdfa971f 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -50,149 +50,15 @@
50#include "nfs4_fs.h" 50#include "nfs4_fs.h"
51#include "callback.h" 51#include "callback.h"
52#include "delegation.h" 52#include "delegation.h"
53#include "internal.h"
53 54
54#define OPENOWNER_POOL_SIZE 8 55#define OPENOWNER_POOL_SIZE 8
55 56
56const nfs4_stateid zero_stateid; 57const nfs4_stateid zero_stateid;
57 58
58static DEFINE_SPINLOCK(state_spinlock);
59static LIST_HEAD(nfs4_clientid_list); 59static LIST_HEAD(nfs4_clientid_list);
60 60
61void 61static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
62init_nfsv4_state(struct nfs_server *server)
63{
64 server->nfs4_state = NULL;
65 INIT_LIST_HEAD(&server->nfs4_siblings);
66}
67
68void
69destroy_nfsv4_state(struct nfs_server *server)
70{
71 kfree(server->mnt_path);
72 server->mnt_path = NULL;
73 if (server->nfs4_state) {
74 nfs4_put_client(server->nfs4_state);
75 server->nfs4_state = NULL;
76 }
77}
78
79/*
80 * nfs4_get_client(): returns an empty client structure
81 * nfs4_put_client(): drops reference to client structure
82 *
83 * Since these are allocated/deallocated very rarely, we don't
84 * bother putting them in a slab cache...
85 */
86static struct nfs4_client *
87nfs4_alloc_client(struct in_addr *addr)
88{
89 struct nfs4_client *clp;
90
91 if (nfs_callback_up() < 0)
92 return NULL;
93 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) {
94 nfs_callback_down();
95 return NULL;
96 }
97 memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr));
98 init_rwsem(&clp->cl_sem);
99 INIT_LIST_HEAD(&clp->cl_delegations);
100 INIT_LIST_HEAD(&clp->cl_state_owners);
101 INIT_LIST_HEAD(&clp->cl_unused);
102 spin_lock_init(&clp->cl_lock);
103 atomic_set(&clp->cl_count, 1);
104 INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
105 INIT_LIST_HEAD(&clp->cl_superblocks);
106 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
107 clp->cl_rpcclient = ERR_PTR(-EINVAL);
108 clp->cl_boot_time = CURRENT_TIME;
109 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
110 return clp;
111}
112
113static void
114nfs4_free_client(struct nfs4_client *clp)
115{
116 struct nfs4_state_owner *sp;
117
118 while (!list_empty(&clp->cl_unused)) {
119 sp = list_entry(clp->cl_unused.next,
120 struct nfs4_state_owner,
121 so_list);
122 list_del(&sp->so_list);
123 kfree(sp);
124 }
125 BUG_ON(!list_empty(&clp->cl_state_owners));
126 nfs_idmap_delete(clp);
127 if (!IS_ERR(clp->cl_rpcclient))
128 rpc_shutdown_client(clp->cl_rpcclient);
129 kfree(clp);
130 nfs_callback_down();
131}
132
133static struct nfs4_client *__nfs4_find_client(struct in_addr *addr)
134{
135 struct nfs4_client *clp;
136 list_for_each_entry(clp, &nfs4_clientid_list, cl_servers) {
137 if (memcmp(&clp->cl_addr, addr, sizeof(clp->cl_addr)) == 0) {
138 atomic_inc(&clp->cl_count);
139 return clp;
140 }
141 }
142 return NULL;
143}
144
145struct nfs4_client *nfs4_find_client(struct in_addr *addr)
146{
147 struct nfs4_client *clp;
148 spin_lock(&state_spinlock);
149 clp = __nfs4_find_client(addr);
150 spin_unlock(&state_spinlock);
151 return clp;
152}
153
154struct nfs4_client *
155nfs4_get_client(struct in_addr *addr)
156{
157 struct nfs4_client *clp, *new = NULL;
158
159 spin_lock(&state_spinlock);
160 for (;;) {
161 clp = __nfs4_find_client(addr);
162 if (clp != NULL)
163 break;
164 clp = new;
165 if (clp != NULL) {
166 list_add(&clp->cl_servers, &nfs4_clientid_list);
167 new = NULL;
168 break;
169 }
170 spin_unlock(&state_spinlock);
171 new = nfs4_alloc_client(addr);
172 spin_lock(&state_spinlock);
173 if (new == NULL)
174 break;
175 }
176 spin_unlock(&state_spinlock);
177 if (new)
178 nfs4_free_client(new);
179 return clp;
180}
181
182void
183nfs4_put_client(struct nfs4_client *clp)
184{
185 if (!atomic_dec_and_lock(&clp->cl_count, &state_spinlock))
186 return;
187 list_del(&clp->cl_servers);
188 spin_unlock(&state_spinlock);
189 BUG_ON(!list_empty(&clp->cl_superblocks));
190 rpc_wake_up(&clp->cl_rpcwaitq);
191 nfs4_kill_renewd(clp);
192 nfs4_free_client(clp);
193}
194
195static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred)
196{ 62{
197 int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, 63 int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK,
198 nfs_callback_tcpport, cred); 64 nfs_callback_tcpport, cred);
@@ -204,13 +70,13 @@ static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred)
204} 70}
205 71
206u32 72u32
207nfs4_alloc_lockowner_id(struct nfs4_client *clp) 73nfs4_alloc_lockowner_id(struct nfs_client *clp)
208{ 74{
209 return clp->cl_lockowner_id ++; 75 return clp->cl_lockowner_id ++;
210} 76}
211 77
212static struct nfs4_state_owner * 78static struct nfs4_state_owner *
213nfs4_client_grab_unused(struct nfs4_client *clp, struct rpc_cred *cred) 79nfs4_client_grab_unused(struct nfs_client *clp, struct rpc_cred *cred)
214{ 80{
215 struct nfs4_state_owner *sp = NULL; 81 struct nfs4_state_owner *sp = NULL;
216 82
@@ -224,7 +90,7 @@ nfs4_client_grab_unused(struct nfs4_client *clp, struct rpc_cred *cred)
224 return sp; 90 return sp;
225} 91}
226 92
227struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp) 93struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
228{ 94{
229 struct nfs4_state_owner *sp; 95 struct nfs4_state_owner *sp;
230 struct rpc_cred *cred = NULL; 96 struct rpc_cred *cred = NULL;
@@ -238,7 +104,7 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp)
238 return cred; 104 return cred;
239} 105}
240 106
241struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp) 107struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
242{ 108{
243 struct nfs4_state_owner *sp; 109 struct nfs4_state_owner *sp;
244 110
@@ -251,7 +117,7 @@ struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp)
251} 117}
252 118
253static struct nfs4_state_owner * 119static struct nfs4_state_owner *
254nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) 120nfs4_find_state_owner(struct nfs_client *clp, struct rpc_cred *cred)
255{ 121{
256 struct nfs4_state_owner *sp, *res = NULL; 122 struct nfs4_state_owner *sp, *res = NULL;
257 123
@@ -294,7 +160,7 @@ nfs4_alloc_state_owner(void)
294void 160void
295nfs4_drop_state_owner(struct nfs4_state_owner *sp) 161nfs4_drop_state_owner(struct nfs4_state_owner *sp)
296{ 162{
297 struct nfs4_client *clp = sp->so_client; 163 struct nfs_client *clp = sp->so_client;
298 spin_lock(&clp->cl_lock); 164 spin_lock(&clp->cl_lock);
299 list_del_init(&sp->so_list); 165 list_del_init(&sp->so_list);
300 spin_unlock(&clp->cl_lock); 166 spin_unlock(&clp->cl_lock);
@@ -306,7 +172,7 @@ nfs4_drop_state_owner(struct nfs4_state_owner *sp)
306 */ 172 */
307struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) 173struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred)
308{ 174{
309 struct nfs4_client *clp = server->nfs4_state; 175 struct nfs_client *clp = server->nfs_client;
310 struct nfs4_state_owner *sp, *new; 176 struct nfs4_state_owner *sp, *new;
311 177
312 get_rpccred(cred); 178 get_rpccred(cred);
@@ -337,7 +203,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
337 */ 203 */
338void nfs4_put_state_owner(struct nfs4_state_owner *sp) 204void nfs4_put_state_owner(struct nfs4_state_owner *sp)
339{ 205{
340 struct nfs4_client *clp = sp->so_client; 206 struct nfs_client *clp = sp->so_client;
341 struct rpc_cred *cred = sp->so_cred; 207 struct rpc_cred *cred = sp->so_cred;
342 208
343 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) 209 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
@@ -540,7 +406,7 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
540static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner) 406static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
541{ 407{
542 struct nfs4_lock_state *lsp; 408 struct nfs4_lock_state *lsp;
543 struct nfs4_client *clp = state->owner->so_client; 409 struct nfs_client *clp = state->owner->so_client;
544 410
545 lsp = kzalloc(sizeof(*lsp), GFP_KERNEL); 411 lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
546 if (lsp == NULL) 412 if (lsp == NULL)
@@ -752,7 +618,7 @@ out:
752 618
753static int reclaimer(void *); 619static int reclaimer(void *);
754 620
755static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) 621static inline void nfs4_clear_recover_bit(struct nfs_client *clp)
756{ 622{
757 smp_mb__before_clear_bit(); 623 smp_mb__before_clear_bit();
758 clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); 624 clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state);
@@ -764,25 +630,25 @@ static inline void nfs4_clear_recover_bit(struct nfs4_client *clp)
764/* 630/*
765 * State recovery routine 631 * State recovery routine
766 */ 632 */
767static void nfs4_recover_state(struct nfs4_client *clp) 633static void nfs4_recover_state(struct nfs_client *clp)
768{ 634{
769 struct task_struct *task; 635 struct task_struct *task;
770 636
771 __module_get(THIS_MODULE); 637 __module_get(THIS_MODULE);
772 atomic_inc(&clp->cl_count); 638 atomic_inc(&clp->cl_count);
773 task = kthread_run(reclaimer, clp, "%u.%u.%u.%u-reclaim", 639 task = kthread_run(reclaimer, clp, "%u.%u.%u.%u-reclaim",
774 NIPQUAD(clp->cl_addr)); 640 NIPQUAD(clp->cl_addr.sin_addr));
775 if (!IS_ERR(task)) 641 if (!IS_ERR(task))
776 return; 642 return;
777 nfs4_clear_recover_bit(clp); 643 nfs4_clear_recover_bit(clp);
778 nfs4_put_client(clp); 644 nfs_put_client(clp);
779 module_put(THIS_MODULE); 645 module_put(THIS_MODULE);
780} 646}
781 647
782/* 648/*
783 * Schedule a state recovery attempt 649 * Schedule a state recovery attempt
784 */ 650 */
785void nfs4_schedule_state_recovery(struct nfs4_client *clp) 651void nfs4_schedule_state_recovery(struct nfs_client *clp)
786{ 652{
787 if (!clp) 653 if (!clp)
788 return; 654 return;
@@ -879,7 +745,7 @@ out_err:
879 return status; 745 return status;
880} 746}
881 747
882static void nfs4_state_mark_reclaim(struct nfs4_client *clp) 748static void nfs4_state_mark_reclaim(struct nfs_client *clp)
883{ 749{
884 struct nfs4_state_owner *sp; 750 struct nfs4_state_owner *sp;
885 struct nfs4_state *state; 751 struct nfs4_state *state;
@@ -903,7 +769,7 @@ static void nfs4_state_mark_reclaim(struct nfs4_client *clp)
903 769
904static int reclaimer(void *ptr) 770static int reclaimer(void *ptr)
905{ 771{
906 struct nfs4_client *clp = ptr; 772 struct nfs_client *clp = ptr;
907 struct nfs4_state_owner *sp; 773 struct nfs4_state_owner *sp;
908 struct nfs4_state_recovery_ops *ops; 774 struct nfs4_state_recovery_ops *ops;
909 struct rpc_cred *cred; 775 struct rpc_cred *cred;
@@ -970,12 +836,12 @@ out:
970 if (status == -NFS4ERR_CB_PATH_DOWN) 836 if (status == -NFS4ERR_CB_PATH_DOWN)
971 nfs_handle_cb_pathdown(clp); 837 nfs_handle_cb_pathdown(clp);
972 nfs4_clear_recover_bit(clp); 838 nfs4_clear_recover_bit(clp);
973 nfs4_put_client(clp); 839 nfs_put_client(clp);
974 module_put_and_exit(0); 840 module_put_and_exit(0);
975 return 0; 841 return 0;
976out_error: 842out_error:
977 printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n", 843 printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n",
978 NIPQUAD(clp->cl_addr.s_addr), -status); 844 NIPQUAD(clp->cl_addr.sin_addr), -status);
979 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 845 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
980 goto out; 846 goto out;
981} 847}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 730ec8fb31c6..3dd413f52da1 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -58,7 +58,7 @@
58/* Mapping from NFS error code to "errno" error code. */ 58/* Mapping from NFS error code to "errno" error code. */
59#define errno_NFSERR_IO EIO 59#define errno_NFSERR_IO EIO
60 60
61static int nfs_stat_to_errno(int); 61static int nfs4_stat_to_errno(int);
62 62
63/* NFSv4 COMPOUND tags are only wanted for debugging purposes */ 63/* NFSv4 COMPOUND tags are only wanted for debugging purposes */
64#ifdef DEBUG 64#ifdef DEBUG
@@ -128,7 +128,7 @@ static int nfs_stat_to_errno(int);
128#define decode_link_maxsz (op_decode_hdr_maxsz + 5) 128#define decode_link_maxsz (op_decode_hdr_maxsz + 5)
129#define encode_symlink_maxsz (op_encode_hdr_maxsz + \ 129#define encode_symlink_maxsz (op_encode_hdr_maxsz + \
130 1 + nfs4_name_maxsz + \ 130 1 + nfs4_name_maxsz + \
131 nfs4_path_maxsz + \ 131 1 + \
132 nfs4_fattr_maxsz) 132 nfs4_fattr_maxsz)
133#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) 133#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8)
134#define encode_create_maxsz (op_encode_hdr_maxsz + \ 134#define encode_create_maxsz (op_encode_hdr_maxsz + \
@@ -529,7 +529,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
529 if (iap->ia_valid & ATTR_MODE) 529 if (iap->ia_valid & ATTR_MODE)
530 len += 4; 530 len += 4;
531 if (iap->ia_valid & ATTR_UID) { 531 if (iap->ia_valid & ATTR_UID) {
532 owner_namelen = nfs_map_uid_to_name(server->nfs4_state, iap->ia_uid, owner_name); 532 owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name);
533 if (owner_namelen < 0) { 533 if (owner_namelen < 0) {
534 printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n", 534 printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n",
535 iap->ia_uid); 535 iap->ia_uid);
@@ -541,7 +541,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
541 len += 4 + (XDR_QUADLEN(owner_namelen) << 2); 541 len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
542 } 542 }
543 if (iap->ia_valid & ATTR_GID) { 543 if (iap->ia_valid & ATTR_GID) {
544 owner_grouplen = nfs_map_gid_to_group(server->nfs4_state, iap->ia_gid, owner_group); 544 owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group);
545 if (owner_grouplen < 0) { 545 if (owner_grouplen < 0) {
546 printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n", 546 printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n",
547 iap->ia_gid); 547 iap->ia_gid);
@@ -673,9 +673,9 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *c
673 673
674 switch (create->ftype) { 674 switch (create->ftype) {
675 case NF4LNK: 675 case NF4LNK:
676 RESERVE_SPACE(4 + create->u.symlink->len); 676 RESERVE_SPACE(4);
677 WRITE32(create->u.symlink->len); 677 WRITE32(create->u.symlink.len);
678 WRITEMEM(create->u.symlink->name, create->u.symlink->len); 678 xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len);
679 break; 679 break;
680 680
681 case NF4BLK: case NF4CHR: 681 case NF4BLK: case NF4CHR:
@@ -1160,7 +1160,7 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, con
1160 return 0; 1160 return 0;
1161} 1161}
1162 1162
1163static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client_stateid) 1163static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid)
1164{ 1164{
1165 uint32_t *p; 1165 uint32_t *p;
1166 1166
@@ -1246,7 +1246,7 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien
1246 return 0; 1246 return 0;
1247} 1247}
1248 1248
1249static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_client *client_state) 1249static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state)
1250{ 1250{
1251 uint32_t *p; 1251 uint32_t *p;
1252 1252
@@ -1945,7 +1945,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const str
1945/* 1945/*
1946 * a RENEW request 1946 * a RENEW request
1947 */ 1947 */
1948static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) 1948static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp)
1949{ 1949{
1950 struct xdr_stream xdr; 1950 struct xdr_stream xdr;
1951 struct compound_hdr hdr = { 1951 struct compound_hdr hdr = {
@@ -1975,7 +1975,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nf
1975/* 1975/*
1976 * a SETCLIENTID_CONFIRM request 1976 * a SETCLIENTID_CONFIRM request
1977 */ 1977 */
1978static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs4_client *clp) 1978static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp)
1979{ 1979{
1980 struct xdr_stream xdr; 1980 struct xdr_stream xdr;
1981 struct compound_hdr hdr = { 1981 struct compound_hdr hdr = {
@@ -2127,12 +2127,12 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
2127 } 2127 }
2128 READ32(nfserr); 2128 READ32(nfserr);
2129 if (nfserr != NFS_OK) 2129 if (nfserr != NFS_OK)
2130 return -nfs_stat_to_errno(nfserr); 2130 return -nfs4_stat_to_errno(nfserr);
2131 return 0; 2131 return 0;
2132} 2132}
2133 2133
2134/* Dummy routine */ 2134/* Dummy routine */
2135static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs4_client *clp) 2135static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp)
2136{ 2136{
2137 uint32_t *p; 2137 uint32_t *p;
2138 unsigned int strlen; 2138 unsigned int strlen;
@@ -2636,7 +2636,7 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t
2636 return 0; 2636 return 0;
2637} 2637}
2638 2638
2639static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *uid) 2639static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *uid)
2640{ 2640{
2641 uint32_t len, *p; 2641 uint32_t len, *p;
2642 2642
@@ -2660,7 +2660,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
2660 return 0; 2660 return 0;
2661} 2661}
2662 2662
2663static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_client *clp, int32_t *gid) 2663static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *gid)
2664{ 2664{
2665 uint32_t len, *p; 2665 uint32_t len, *p;
2666 2666
@@ -3051,9 +3051,9 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
3051 fattr->mode |= fmode; 3051 fattr->mode |= fmode;
3052 if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0) 3052 if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0)
3053 goto xdr_error; 3053 goto xdr_error;
3054 if ((status = decode_attr_owner(xdr, bitmap, server->nfs4_state, &fattr->uid)) != 0) 3054 if ((status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid)) != 0)
3055 goto xdr_error; 3055 goto xdr_error;
3056 if ((status = decode_attr_group(xdr, bitmap, server->nfs4_state, &fattr->gid)) != 0) 3056 if ((status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid)) != 0)
3057 goto xdr_error; 3057 goto xdr_error;
3058 if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0) 3058 if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0)
3059 goto xdr_error; 3059 goto xdr_error;
@@ -3254,7 +3254,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3254 if (decode_space_limit(xdr, &res->maxsize) < 0) 3254 if (decode_space_limit(xdr, &res->maxsize) < 0)
3255 return -EIO; 3255 return -EIO;
3256 } 3256 }
3257 return decode_ace(xdr, NULL, res->server->nfs4_state); 3257 return decode_ace(xdr, NULL, res->server->nfs_client);
3258} 3258}
3259 3259
3260static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) 3260static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
@@ -3565,7 +3565,7 @@ static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
3565 return 0; 3565 return 0;
3566} 3566}
3567 3567
3568static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp) 3568static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
3569{ 3569{
3570 uint32_t *p; 3570 uint32_t *p;
3571 uint32_t opnum; 3571 uint32_t opnum;
@@ -3598,7 +3598,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp)
3598 READ_BUF(len); 3598 READ_BUF(len);
3599 return -NFSERR_CLID_INUSE; 3599 return -NFSERR_CLID_INUSE;
3600 } else 3600 } else
3601 return -nfs_stat_to_errno(nfserr); 3601 return -nfs4_stat_to_errno(nfserr);
3602 3602
3603 return 0; 3603 return 0;
3604} 3604}
@@ -4256,7 +4256,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsi
4256 if (!status) 4256 if (!status)
4257 status = decode_fsinfo(&xdr, fsinfo); 4257 status = decode_fsinfo(&xdr, fsinfo);
4258 if (!status) 4258 if (!status)
4259 status = -nfs_stat_to_errno(hdr.status); 4259 status = -nfs4_stat_to_errno(hdr.status);
4260 return status; 4260 return status;
4261} 4261}
4262 4262
@@ -4335,7 +4335,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
4335 * a SETCLIENTID request 4335 * a SETCLIENTID request
4336 */ 4336 */
4337static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p, 4337static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
4338 struct nfs4_client *clp) 4338 struct nfs_client *clp)
4339{ 4339{
4340 struct xdr_stream xdr; 4340 struct xdr_stream xdr;
4341 struct compound_hdr hdr; 4341 struct compound_hdr hdr;
@@ -4346,7 +4346,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
4346 if (!status) 4346 if (!status)
4347 status = decode_setclientid(&xdr, clp); 4347 status = decode_setclientid(&xdr, clp);
4348 if (!status) 4348 if (!status)
4349 status = -nfs_stat_to_errno(hdr.status); 4349 status = -nfs4_stat_to_errno(hdr.status);
4350 return status; 4350 return status;
4351} 4351}
4352 4352
@@ -4368,7 +4368,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s
4368 if (!status) 4368 if (!status)
4369 status = decode_fsinfo(&xdr, fsinfo); 4369 status = decode_fsinfo(&xdr, fsinfo);
4370 if (!status) 4370 if (!status)
4371 status = -nfs_stat_to_errno(hdr.status); 4371 status = -nfs4_stat_to_errno(hdr.status);
4372 return status; 4372 return status;
4373} 4373}
4374 4374
@@ -4521,7 +4521,7 @@ static struct {
4521 * This one is used jointly by NFSv2 and NFSv3. 4521 * This one is used jointly by NFSv2 and NFSv3.
4522 */ 4522 */
4523static int 4523static int
4524nfs_stat_to_errno(int stat) 4524nfs4_stat_to_errno(int stat)
4525{ 4525{
4526 int i; 4526 int i;
4527 for (i = 0; nfs_errtbl[i].stat != -1; i++) { 4527 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index b3899ea3229e..630e50647bbb 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -66,14 +66,14 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
66 66
67 dprintk("%s: call getattr\n", __FUNCTION__); 67 dprintk("%s: call getattr\n", __FUNCTION__);
68 nfs_fattr_init(fattr); 68 nfs_fattr_init(fattr);
69 status = rpc_call_sync(server->client_sys, &msg, 0); 69 status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
70 dprintk("%s: reply getattr: %d\n", __FUNCTION__, status); 70 dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
71 if (status) 71 if (status)
72 return status; 72 return status;
73 dprintk("%s: call statfs\n", __FUNCTION__); 73 dprintk("%s: call statfs\n", __FUNCTION__);
74 msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS]; 74 msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS];
75 msg.rpc_resp = &fsinfo; 75 msg.rpc_resp = &fsinfo;
76 status = rpc_call_sync(server->client_sys, &msg, 0); 76 status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
77 dprintk("%s: reply statfs: %d\n", __FUNCTION__, status); 77 dprintk("%s: reply statfs: %d\n", __FUNCTION__, status);
78 if (status) 78 if (status)
79 return status; 79 return status;
@@ -425,16 +425,17 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
425} 425}
426 426
427static int 427static int
428nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, 428nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
429 struct iattr *sattr, struct nfs_fh *fhandle, 429 unsigned int len, struct iattr *sattr)
430 struct nfs_fattr *fattr)
431{ 430{
431 struct nfs_fh fhandle;
432 struct nfs_fattr fattr;
432 struct nfs_symlinkargs arg = { 433 struct nfs_symlinkargs arg = {
433 .fromfh = NFS_FH(dir), 434 .fromfh = NFS_FH(dir),
434 .fromname = name->name, 435 .fromname = dentry->d_name.name,
435 .fromlen = name->len, 436 .fromlen = dentry->d_name.len,
436 .topath = path->name, 437 .pages = &page,
437 .tolen = path->len, 438 .pathlen = len,
438 .sattr = sattr 439 .sattr = sattr
439 }; 440 };
440 struct rpc_message msg = { 441 struct rpc_message msg = {
@@ -443,13 +444,25 @@ nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
443 }; 444 };
444 int status; 445 int status;
445 446
446 if (path->len > NFS2_MAXPATHLEN) 447 if (len > NFS2_MAXPATHLEN)
447 return -ENAMETOOLONG; 448 return -ENAMETOOLONG;
448 dprintk("NFS call symlink %s -> %s\n", name->name, path->name); 449
449 nfs_fattr_init(fattr); 450 dprintk("NFS call symlink %s\n", dentry->d_name.name);
450 fhandle->size = 0; 451
451 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 452 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
452 nfs_mark_for_revalidate(dir); 453 nfs_mark_for_revalidate(dir);
454
455 /*
456 * V2 SYMLINK requests don't return any attributes. Setting the
457 * filehandle size to zero indicates to nfs_instantiate that it
458 * should fill in the data with a LOOKUP call on the wire.
459 */
460 if (status == 0) {
461 nfs_fattr_init(&fattr);
462 fhandle.size = 0;
463 status = nfs_instantiate(dentry, &fhandle, &fattr);
464 }
465
453 dprintk("NFS reply symlink: %d\n", status); 466 dprintk("NFS reply symlink: %d\n", status);
454 return status; 467 return status;
455} 468}
@@ -671,7 +684,7 @@ nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
671} 684}
672 685
673 686
674struct nfs_rpc_ops nfs_v2_clientops = { 687const struct nfs_rpc_ops nfs_v2_clientops = {
675 .version = 2, /* protocol version */ 688 .version = 2, /* protocol version */
676 .dentry_ops = &nfs_dentry_operations, 689 .dentry_ops = &nfs_dentry_operations,
677 .dir_inode_ops = &nfs_dir_inode_operations, 690 .dir_inode_ops = &nfs_dir_inode_operations,
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index f0aff824a291..69f1549da2b9 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -171,7 +171,7 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
171 rdata->args.offset = page_offset(page) + rdata->args.pgbase; 171 rdata->args.offset = page_offset(page) + rdata->args.pgbase;
172 172
173 dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n", 173 dprintk("NFS: nfs_proc_read(%s, (%s/%Ld), %Lu, %u)\n",
174 NFS_SERVER(inode)->hostname, 174 NFS_SERVER(inode)->nfs_client->cl_hostname,
175 inode->i_sb->s_id, 175 inode->i_sb->s_id,
176 (long long)NFS_FILEID(inode), 176 (long long)NFS_FILEID(inode),
177 (unsigned long long)rdata->args.pgbase, 177 (unsigned long long)rdata->args.pgbase,
@@ -568,8 +568,13 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data)
568 568
569 nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); 569 nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count);
570 570
571 /* Is this a short read? */ 571 if (task->tk_status < 0) {
572 if (task->tk_status >= 0 && resp->count < argp->count && !resp->eof) { 572 if (task->tk_status == -ESTALE) {
573 set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode));
574 nfs_mark_for_revalidate(data->inode);
575 }
576 } else if (resp->count < argp->count && !resp->eof) {
577 /* This is a short read! */
573 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); 578 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
574 /* Has the server at least made some progress? */ 579 /* Has the server at least made some progress? */
575 if (resp->count != 0) { 580 if (resp->count != 0) {
@@ -616,6 +621,10 @@ int nfs_readpage(struct file *file, struct page *page)
616 if (error) 621 if (error)
617 goto out_error; 622 goto out_error;
618 623
624 error = -ESTALE;
625 if (NFS_STALE(inode))
626 goto out_error;
627
619 if (file == NULL) { 628 if (file == NULL) {
620 ctx = nfs_find_open_context(inode, NULL, FMODE_READ); 629 ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
621 if (ctx == NULL) 630 if (ctx == NULL)
@@ -678,7 +687,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
678 }; 687 };
679 struct inode *inode = mapping->host; 688 struct inode *inode = mapping->host;
680 struct nfs_server *server = NFS_SERVER(inode); 689 struct nfs_server *server = NFS_SERVER(inode);
681 int ret; 690 int ret = -ESTALE;
682 691
683 dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", 692 dprintk("NFS: nfs_readpages (%s/%Ld %d)\n",
684 inode->i_sb->s_id, 693 inode->i_sb->s_id,
@@ -686,6 +695,9 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
686 nr_pages); 695 nr_pages);
687 nfs_inc_stats(inode, NFSIOS_VFSREADPAGES); 696 nfs_inc_stats(inode, NFSIOS_VFSREADPAGES);
688 697
698 if (NFS_STALE(inode))
699 goto out;
700
689 if (filp == NULL) { 701 if (filp == NULL) {
690 desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ); 702 desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
691 if (desc.ctx == NULL) 703 if (desc.ctx == NULL)
@@ -701,6 +713,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
701 ret = err; 713 ret = err;
702 } 714 }
703 put_nfs_open_context(desc.ctx); 715 put_nfs_open_context(desc.ctx);
716out:
704 return ret; 717 return ret;
705} 718}
706 719
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index e8a9bee74d9d..b99113b0f65f 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -13,6 +13,11 @@
13 * 13 *
14 * Split from inode.c by David Howells <dhowells@redhat.com> 14 * Split from inode.c by David Howells <dhowells@redhat.com>
15 * 15 *
16 * - superblocks are indexed on server only - all inodes, dentries, etc. associated with a
17 * particular server are held in the same superblock
18 * - NFS superblocks can have several effective roots to the dentry tree
19 * - directory type roots are spliced into the tree when a path from one root reaches the root
20 * of another (see nfs_lookup())
16 */ 21 */
17 22
18#include <linux/config.h> 23#include <linux/config.h>
@@ -52,66 +57,12 @@
52 57
53#define NFSDBG_FACILITY NFSDBG_VFS 58#define NFSDBG_FACILITY NFSDBG_VFS
54 59
55/* Maximum number of readahead requests
56 * FIXME: this should really be a sysctl so that users may tune it to suit
57 * their needs. People that do NFS over a slow network, might for
58 * instance want to reduce it to something closer to 1 for improved
59 * interactive response.
60 */
61#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
62
63/*
64 * RPC cruft for NFS
65 */
66static struct rpc_version * nfs_version[] = {
67 NULL,
68 NULL,
69 &nfs_version2,
70#if defined(CONFIG_NFS_V3)
71 &nfs_version3,
72#elif defined(CONFIG_NFS_V4)
73 NULL,
74#endif
75#if defined(CONFIG_NFS_V4)
76 &nfs_version4,
77#endif
78};
79
80static struct rpc_program nfs_program = {
81 .name = "nfs",
82 .number = NFS_PROGRAM,
83 .nrvers = ARRAY_SIZE(nfs_version),
84 .version = nfs_version,
85 .stats = &nfs_rpcstat,
86 .pipe_dir_name = "/nfs",
87};
88
89struct rpc_stat nfs_rpcstat = {
90 .program = &nfs_program
91};
92
93
94#ifdef CONFIG_NFS_V3_ACL
95static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
96static struct rpc_version * nfsacl_version[] = {
97 [3] = &nfsacl_version3,
98};
99
100struct rpc_program nfsacl_program = {
101 .name = "nfsacl",
102 .number = NFS_ACL_PROGRAM,
103 .nrvers = ARRAY_SIZE(nfsacl_version),
104 .version = nfsacl_version,
105 .stats = &nfsacl_rpcstat,
106};
107#endif /* CONFIG_NFS_V3_ACL */
108
109static void nfs_umount_begin(struct vfsmount *, int); 60static void nfs_umount_begin(struct vfsmount *, int);
110static int nfs_statfs(struct dentry *, struct kstatfs *); 61static int nfs_statfs(struct dentry *, struct kstatfs *);
111static int nfs_show_options(struct seq_file *, struct vfsmount *); 62static int nfs_show_options(struct seq_file *, struct vfsmount *);
112static int nfs_show_stats(struct seq_file *, struct vfsmount *); 63static int nfs_show_stats(struct seq_file *, struct vfsmount *);
113static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); 64static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
114static int nfs_clone_nfs_sb(struct file_system_type *fs_type, 65static int nfs_xdev_get_sb(struct file_system_type *fs_type,
115 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); 66 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
116static void nfs_kill_super(struct super_block *); 67static void nfs_kill_super(struct super_block *);
117 68
@@ -123,10 +74,10 @@ static struct file_system_type nfs_fs_type = {
123 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 74 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
124}; 75};
125 76
126struct file_system_type clone_nfs_fs_type = { 77struct file_system_type nfs_xdev_fs_type = {
127 .owner = THIS_MODULE, 78 .owner = THIS_MODULE,
128 .name = "nfs", 79 .name = "nfs",
129 .get_sb = nfs_clone_nfs_sb, 80 .get_sb = nfs_xdev_get_sb,
130 .kill_sb = nfs_kill_super, 81 .kill_sb = nfs_kill_super,
131 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 82 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
132}; 83};
@@ -145,10 +96,10 @@ static struct super_operations nfs_sops = {
145#ifdef CONFIG_NFS_V4 96#ifdef CONFIG_NFS_V4
146static int nfs4_get_sb(struct file_system_type *fs_type, 97static int nfs4_get_sb(struct file_system_type *fs_type,
147 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); 98 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
148static int nfs_clone_nfs4_sb(struct file_system_type *fs_type, 99static int nfs4_xdev_get_sb(struct file_system_type *fs_type,
149 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); 100 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
150static int nfs_referral_nfs4_sb(struct file_system_type *fs_type, 101static int nfs4_referral_get_sb(struct file_system_type *fs_type,
151 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); 102 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
152static void nfs4_kill_super(struct super_block *sb); 103static void nfs4_kill_super(struct super_block *sb);
153 104
154static struct file_system_type nfs4_fs_type = { 105static struct file_system_type nfs4_fs_type = {
@@ -159,18 +110,18 @@ static struct file_system_type nfs4_fs_type = {
159 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 110 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
160}; 111};
161 112
162struct file_system_type clone_nfs4_fs_type = { 113struct file_system_type nfs4_xdev_fs_type = {
163 .owner = THIS_MODULE, 114 .owner = THIS_MODULE,
164 .name = "nfs4", 115 .name = "nfs4",
165 .get_sb = nfs_clone_nfs4_sb, 116 .get_sb = nfs4_xdev_get_sb,
166 .kill_sb = nfs4_kill_super, 117 .kill_sb = nfs4_kill_super,
167 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 118 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
168}; 119};
169 120
170struct file_system_type nfs_referral_nfs4_fs_type = { 121struct file_system_type nfs4_referral_fs_type = {
171 .owner = THIS_MODULE, 122 .owner = THIS_MODULE,
172 .name = "nfs4", 123 .name = "nfs4",
173 .get_sb = nfs_referral_nfs4_sb, 124 .get_sb = nfs4_referral_get_sb,
174 .kill_sb = nfs4_kill_super, 125 .kill_sb = nfs4_kill_super,
175 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 126 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
176}; 127};
@@ -187,39 +138,7 @@ static struct super_operations nfs4_sops = {
187}; 138};
188#endif 139#endif
189 140
190#ifdef CONFIG_NFS_V4 141static struct shrinker *acl_shrinker;
191static const int nfs_set_port_min = 0;
192static const int nfs_set_port_max = 65535;
193
194static int param_set_port(const char *val, struct kernel_param *kp)
195{
196 char *endp;
197 int num = simple_strtol(val, &endp, 0);
198 if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max)
199 return -EINVAL;
200 *((int *)kp->arg) = num;
201 return 0;
202}
203
204module_param_call(callback_tcpport, param_set_port, param_get_int,
205 &nfs_callback_set_tcpport, 0644);
206#endif
207
208#ifdef CONFIG_NFS_V4
209static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
210{
211 char *endp;
212 int num = simple_strtol(val, &endp, 0);
213 int jif = num * HZ;
214 if (endp == val || *endp || num < 0 || jif < num)
215 return -EINVAL;
216 *((int *)kp->arg) = jif;
217 return 0;
218}
219
220module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int,
221 &nfs_idmap_cache_timeout, 0644);
222#endif
223 142
224/* 143/*
225 * Register the NFS filesystems 144 * Register the NFS filesystems
@@ -240,6 +159,7 @@ int __init register_nfs_fs(void)
240 if (ret < 0) 159 if (ret < 0)
241 goto error_2; 160 goto error_2;
242#endif 161#endif
162 acl_shrinker = set_shrinker(DEFAULT_SEEKS, nfs_access_cache_shrinker);
243 return 0; 163 return 0;
244 164
245#ifdef CONFIG_NFS_V4 165#ifdef CONFIG_NFS_V4
@@ -257,6 +177,8 @@ error_0:
257 */ 177 */
258void __exit unregister_nfs_fs(void) 178void __exit unregister_nfs_fs(void)
259{ 179{
180 if (acl_shrinker != NULL)
181 remove_shrinker(acl_shrinker);
260#ifdef CONFIG_NFS_V4 182#ifdef CONFIG_NFS_V4
261 unregister_filesystem(&nfs4_fs_type); 183 unregister_filesystem(&nfs4_fs_type);
262 nfs_unregister_sysctl(); 184 nfs_unregister_sysctl();
@@ -269,11 +191,10 @@ void __exit unregister_nfs_fs(void)
269 */ 191 */
270static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) 192static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
271{ 193{
272 struct super_block *sb = dentry->d_sb; 194 struct nfs_server *server = NFS_SB(dentry->d_sb);
273 struct nfs_server *server = NFS_SB(sb);
274 unsigned char blockbits; 195 unsigned char blockbits;
275 unsigned long blockres; 196 unsigned long blockres;
276 struct nfs_fh *rootfh = NFS_FH(sb->s_root->d_inode); 197 struct nfs_fh *fh = NFS_FH(dentry->d_inode);
277 struct nfs_fattr fattr; 198 struct nfs_fattr fattr;
278 struct nfs_fsstat res = { 199 struct nfs_fsstat res = {
279 .fattr = &fattr, 200 .fattr = &fattr,
@@ -282,7 +203,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
282 203
283 lock_kernel(); 204 lock_kernel();
284 205
285 error = server->rpc_ops->statfs(server, rootfh, &res); 206 error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
286 buf->f_type = NFS_SUPER_MAGIC; 207 buf->f_type = NFS_SUPER_MAGIC;
287 if (error < 0) 208 if (error < 0)
288 goto out_err; 209 goto out_err;
@@ -292,7 +213,7 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
292 * case where f_frsize != f_bsize. Eventually we want to 213 * case where f_frsize != f_bsize. Eventually we want to
293 * report the value of wtmult in this field. 214 * report the value of wtmult in this field.
294 */ 215 */
295 buf->f_frsize = sb->s_blocksize; 216 buf->f_frsize = dentry->d_sb->s_blocksize;
296 217
297 /* 218 /*
298 * On most *nix systems, f_blocks, f_bfree, and f_bavail 219 * On most *nix systems, f_blocks, f_bfree, and f_bavail
@@ -301,8 +222,8 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
301 * thus historically Linux's sys_statfs reports these 222 * thus historically Linux's sys_statfs reports these
302 * fields in units of f_bsize. 223 * fields in units of f_bsize.
303 */ 224 */
304 buf->f_bsize = sb->s_blocksize; 225 buf->f_bsize = dentry->d_sb->s_blocksize;
305 blockbits = sb->s_blocksize_bits; 226 blockbits = dentry->d_sb->s_blocksize_bits;
306 blockres = (1 << blockbits) - 1; 227 blockres = (1 << blockbits) - 1;
307 buf->f_blocks = (res.tbytes + blockres) >> blockbits; 228 buf->f_blocks = (res.tbytes + blockres) >> blockbits;
308 buf->f_bfree = (res.fbytes + blockres) >> blockbits; 229 buf->f_bfree = (res.fbytes + blockres) >> blockbits;
@@ -323,9 +244,12 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
323 244
324} 245}
325 246
247/*
248 * Map the security flavour number to a name
249 */
326static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) 250static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
327{ 251{
328 static struct { 252 static const struct {
329 rpc_authflavor_t flavour; 253 rpc_authflavor_t flavour;
330 const char *str; 254 const char *str;
331 } sec_flavours[] = { 255 } sec_flavours[] = {
@@ -356,10 +280,10 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
356 */ 280 */
357static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults) 281static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults)
358{ 282{
359 static struct proc_nfs_info { 283 static const struct proc_nfs_info {
360 int flag; 284 int flag;
361 char *str; 285 const char *str;
362 char *nostr; 286 const char *nostr;
363 } nfs_info[] = { 287 } nfs_info[] = {
364 { NFS_MOUNT_SOFT, ",soft", ",hard" }, 288 { NFS_MOUNT_SOFT, ",soft", ",hard" },
365 { NFS_MOUNT_INTR, ",intr", "" }, 289 { NFS_MOUNT_INTR, ",intr", "" },
@@ -369,11 +293,12 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
369 { NFS_MOUNT_NOACL, ",noacl", "" }, 293 { NFS_MOUNT_NOACL, ",noacl", "" },
370 { 0, NULL, NULL } 294 { 0, NULL, NULL }
371 }; 295 };
372 struct proc_nfs_info *nfs_infop; 296 const struct proc_nfs_info *nfs_infop;
297 struct nfs_client *clp = nfss->nfs_client;
373 char buf[12]; 298 char buf[12];
374 char *proto; 299 const char *proto;
375 300
376 seq_printf(m, ",vers=%d", nfss->rpc_ops->version); 301 seq_printf(m, ",vers=%d", clp->rpc_ops->version);
377 seq_printf(m, ",rsize=%d", nfss->rsize); 302 seq_printf(m, ",rsize=%d", nfss->rsize);
378 seq_printf(m, ",wsize=%d", nfss->wsize); 303 seq_printf(m, ",wsize=%d", nfss->wsize);
379 if (nfss->acregmin != 3*HZ || showdefaults) 304 if (nfss->acregmin != 3*HZ || showdefaults)
@@ -402,8 +327,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
402 proto = buf; 327 proto = buf;
403 } 328 }
404 seq_printf(m, ",proto=%s", proto); 329 seq_printf(m, ",proto=%s", proto);
405 seq_printf(m, ",timeo=%lu", 10U * nfss->retrans_timeo / HZ); 330 seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ);
406 seq_printf(m, ",retrans=%u", nfss->retrans_count); 331 seq_printf(m, ",retrans=%u", clp->retrans_count);
407 seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); 332 seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
408} 333}
409 334
@@ -417,7 +342,7 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
417 nfs_show_mount_options(m, nfss, 0); 342 nfs_show_mount_options(m, nfss, 0);
418 343
419 seq_puts(m, ",addr="); 344 seq_puts(m, ",addr=");
420 seq_escape(m, nfss->hostname, " \t\n\\"); 345 seq_escape(m, nfss->nfs_client->cl_hostname, " \t\n\\");
421 346
422 return 0; 347 return 0;
423} 348}
@@ -454,7 +379,7 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
454 seq_printf(m, ",namelen=%d", nfss->namelen); 379 seq_printf(m, ",namelen=%d", nfss->namelen);
455 380
456#ifdef CONFIG_NFS_V4 381#ifdef CONFIG_NFS_V4
457 if (nfss->rpc_ops->version == 4) { 382 if (nfss->nfs_client->cl_nfsversion == 4) {
458 seq_printf(m, "\n\tnfsv4:\t"); 383 seq_printf(m, "\n\tnfsv4:\t");
459 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); 384 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
460 seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); 385 seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
@@ -501,782 +426,353 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
501 426
502/* 427/*
503 * Begin unmount by attempting to remove all automounted mountpoints we added 428 * Begin unmount by attempting to remove all automounted mountpoints we added
504 * in response to traversals 429 * in response to xdev traversals and referrals
505 */ 430 */
506static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) 431static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
507{ 432{
508 struct nfs_server *server;
509 struct rpc_clnt *rpc;
510
511 shrink_submounts(vfsmnt, &nfs_automount_list); 433 shrink_submounts(vfsmnt, &nfs_automount_list);
512 if (!(flags & MNT_FORCE))
513 return;
514 /* -EIO all pending I/O */
515 server = NFS_SB(vfsmnt->mnt_sb);
516 rpc = server->client;
517 if (!IS_ERR(rpc))
518 rpc_killall_tasks(rpc);
519 rpc = server->client_acl;
520 if (!IS_ERR(rpc))
521 rpc_killall_tasks(rpc);
522} 434}
523 435
524/* 436/*
525 * Obtain the root inode of the file system. 437 * Validate the NFS2/NFS3 mount data
438 * - fills in the mount root filehandle
526 */ 439 */
527static struct inode * 440static int nfs_validate_mount_data(struct nfs_mount_data *data,
528nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo) 441 struct nfs_fh *mntfh)
529{ 442{
530 struct nfs_server *server = NFS_SB(sb); 443 if (data == NULL) {
531 int error; 444 dprintk("%s: missing data argument\n", __FUNCTION__);
532 445 return -EINVAL;
533 error = server->rpc_ops->getroot(server, rootfh, fsinfo);
534 if (error < 0) {
535 dprintk("nfs_get_root: getattr error = %d\n", -error);
536 return ERR_PTR(error);
537 } 446 }
538 447
539 server->fsid = fsinfo->fattr->fsid; 448 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
540 return nfs_fhget(sb, rootfh, fsinfo->fattr); 449 dprintk("%s: bad mount version\n", __FUNCTION__);
541} 450 return -EINVAL;
542 451 }
543/*
544 * Do NFS version-independent mount processing, and sanity checking
545 */
546static int
547nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
548{
549 struct nfs_server *server;
550 struct inode *root_inode;
551 struct nfs_fattr fattr;
552 struct nfs_fsinfo fsinfo = {
553 .fattr = &fattr,
554 };
555 struct nfs_pathconf pathinfo = {
556 .fattr = &fattr,
557 };
558 int no_root_error = 0;
559 unsigned long max_rpc_payload;
560
561 /* We probably want something more informative here */
562 snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
563
564 server = NFS_SB(sb);
565 452
566 sb->s_magic = NFS_SUPER_MAGIC; 453 switch (data->version) {
454 case 1:
455 data->namlen = 0;
456 case 2:
457 data->bsize = 0;
458 case 3:
459 if (data->flags & NFS_MOUNT_VER3) {
460 dprintk("%s: mount structure version %d does not support NFSv3\n",
461 __FUNCTION__,
462 data->version);
463 return -EINVAL;
464 }
465 data->root.size = NFS2_FHSIZE;
466 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
467 case 4:
468 if (data->flags & NFS_MOUNT_SECFLAVOUR) {
469 dprintk("%s: mount structure version %d does not support strong security\n",
470 __FUNCTION__,
471 data->version);
472 return -EINVAL;
473 }
474 case 5:
475 memset(data->context, 0, sizeof(data->context));
476 }
567 477
568 server->io_stats = nfs_alloc_iostats(); 478 /* Set the pseudoflavor */
569 if (server->io_stats == NULL) 479 if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
570 return -ENOMEM; 480 data->pseudoflavor = RPC_AUTH_UNIX;
571 481
572 root_inode = nfs_get_root(sb, &server->fh, &fsinfo); 482#ifndef CONFIG_NFS_V3
573 /* Did getting the root inode fail? */ 483 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
574 if (IS_ERR(root_inode)) { 484 if (data->flags & NFS_MOUNT_VER3) {
575 no_root_error = PTR_ERR(root_inode); 485 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
576 goto out_no_root; 486 return -EPROTONOSUPPORT;
577 }
578 sb->s_root = d_alloc_root(root_inode);
579 if (!sb->s_root) {
580 no_root_error = -ENOMEM;
581 goto out_no_root;
582 } 487 }
583 sb->s_root->d_op = server->rpc_ops->dentry_ops; 488#endif /* CONFIG_NFS_V3 */
584
585 /* mount time stamp, in seconds */
586 server->mount_time = jiffies;
587
588 /* Get some general file system info */
589 if (server->namelen == 0 &&
590 server->rpc_ops->pathconf(server, &server->fh, &pathinfo) >= 0)
591 server->namelen = pathinfo.max_namelen;
592 /* Work out a lot of parameters */
593 if (server->rsize == 0)
594 server->rsize = nfs_block_size(fsinfo.rtpref, NULL);
595 if (server->wsize == 0)
596 server->wsize = nfs_block_size(fsinfo.wtpref, NULL);
597
598 if (fsinfo.rtmax >= 512 && server->rsize > fsinfo.rtmax)
599 server->rsize = nfs_block_size(fsinfo.rtmax, NULL);
600 if (fsinfo.wtmax >= 512 && server->wsize > fsinfo.wtmax)
601 server->wsize = nfs_block_size(fsinfo.wtmax, NULL);
602
603 max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
604 if (server->rsize > max_rpc_payload)
605 server->rsize = max_rpc_payload;
606 if (server->rsize > NFS_MAX_FILE_IO_SIZE)
607 server->rsize = NFS_MAX_FILE_IO_SIZE;
608 server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
609
610 if (server->wsize > max_rpc_payload)
611 server->wsize = max_rpc_payload;
612 if (server->wsize > NFS_MAX_FILE_IO_SIZE)
613 server->wsize = NFS_MAX_FILE_IO_SIZE;
614 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
615 489
616 if (sb->s_blocksize == 0) 490 /* We now require that the mount process passes the remote address */
617 sb->s_blocksize = nfs_block_bits(server->wsize, 491 if (data->addr.sin_addr.s_addr == INADDR_ANY) {
618 &sb->s_blocksize_bits); 492 dprintk("%s: mount program didn't pass remote address!\n",
619 server->wtmult = nfs_block_bits(fsinfo.wtmult, NULL); 493 __FUNCTION__);
620 494 return -EINVAL;
621 server->dtsize = nfs_block_size(fsinfo.dtpref, NULL);
622 if (server->dtsize > PAGE_CACHE_SIZE)
623 server->dtsize = PAGE_CACHE_SIZE;
624 if (server->dtsize > server->rsize)
625 server->dtsize = server->rsize;
626
627 if (server->flags & NFS_MOUNT_NOAC) {
628 server->acregmin = server->acregmax = 0;
629 server->acdirmin = server->acdirmax = 0;
630 sb->s_flags |= MS_SYNCHRONOUS;
631 } 495 }
632 server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
633 496
634 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize); 497 /* Prepare the root filehandle */
498 if (data->flags & NFS_MOUNT_VER3)
499 mntfh->size = data->root.size;
500 else
501 mntfh->size = NFS2_FHSIZE;
502
503 if (mntfh->size > sizeof(mntfh->data)) {
504 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
505 return -EINVAL;
506 }
635 507
636 server->client->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0; 508 memcpy(mntfh->data, data->root.data, mntfh->size);
637 server->client->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0; 509 if (mntfh->size < sizeof(mntfh->data))
510 memset(mntfh->data + mntfh->size, 0,
511 sizeof(mntfh->data) - mntfh->size);
638 512
639 /* We're airborne Set socket buffersize */
640 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
641 return 0; 513 return 0;
642 /* Yargs. It didn't work out. */
643out_no_root:
644 dprintk("nfs_sb_init: get root inode failed: errno %d\n", -no_root_error);
645 if (!IS_ERR(root_inode))
646 iput(root_inode);
647 return no_root_error;
648} 514}
649 515
650/* 516/*
651 * Initialise the timeout values for a connection 517 * Initialise the common bits of the superblock
652 */ 518 */
653static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans) 519static inline void nfs_initialise_sb(struct super_block *sb)
654{ 520{
655 to->to_initval = timeo * HZ / 10; 521 struct nfs_server *server = NFS_SB(sb);
656 to->to_retries = retrans;
657 if (!to->to_retries)
658 to->to_retries = 2;
659
660 switch (proto) {
661 case IPPROTO_TCP:
662 if (!to->to_initval)
663 to->to_initval = 60 * HZ;
664 if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
665 to->to_initval = NFS_MAX_TCP_TIMEOUT;
666 to->to_increment = to->to_initval;
667 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
668 to->to_exponential = 0;
669 break;
670 case IPPROTO_UDP:
671 default:
672 if (!to->to_initval)
673 to->to_initval = 11 * HZ / 10;
674 if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
675 to->to_initval = NFS_MAX_UDP_TIMEOUT;
676 to->to_maxval = NFS_MAX_UDP_TIMEOUT;
677 to->to_exponential = 1;
678 break;
679 }
680}
681 522
682/* 523 sb->s_magic = NFS_SUPER_MAGIC;
683 * Create an RPC client handle.
684 */
685static struct rpc_clnt *
686nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
687{
688 struct rpc_timeout timeparms;
689 struct rpc_xprt *xprt = NULL;
690 struct rpc_clnt *clnt = NULL;
691 int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
692
693 nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
694
695 server->retrans_timeo = timeparms.to_initval;
696 server->retrans_count = timeparms.to_retries;
697
698 /* create transport and client */
699 xprt = xprt_create_proto(proto, &server->addr, &timeparms);
700 if (IS_ERR(xprt)) {
701 dprintk("%s: cannot create RPC transport. Error = %ld\n",
702 __FUNCTION__, PTR_ERR(xprt));
703 return (struct rpc_clnt *)xprt;
704 }
705 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
706 server->rpc_ops->version, data->pseudoflavor);
707 if (IS_ERR(clnt)) {
708 dprintk("%s: cannot create RPC client. Error = %ld\n",
709 __FUNCTION__, PTR_ERR(xprt));
710 goto out_fail;
711 }
712 524
713 clnt->cl_intr = 1; 525 /* We probably want something more informative here */
714 clnt->cl_softrtry = 1; 526 snprintf(sb->s_id, sizeof(sb->s_id),
527 "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
528
529 if (sb->s_blocksize == 0)
530 sb->s_blocksize = nfs_block_bits(server->wsize,
531 &sb->s_blocksize_bits);
715 532
716 return clnt; 533 if (server->flags & NFS_MOUNT_NOAC)
534 sb->s_flags |= MS_SYNCHRONOUS;
717 535
718out_fail: 536 nfs_super_set_maxbytes(sb, server->maxfilesize);
719 return clnt;
720} 537}
721 538
722/* 539/*
723 * Clone a server record 540 * Finish setting up an NFS2/3 superblock
724 */ 541 */
725static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_clone_mount *data) 542static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data)
726{ 543{
727 struct nfs_server *server = NFS_SB(sb); 544 struct nfs_server *server = NFS_SB(sb);
728 struct nfs_server *parent = NFS_SB(data->sb);
729 struct inode *root_inode;
730 struct nfs_fsinfo fsinfo;
731 void *err = ERR_PTR(-ENOMEM);
732
733 sb->s_op = data->sb->s_op;
734 sb->s_blocksize = data->sb->s_blocksize;
735 sb->s_blocksize_bits = data->sb->s_blocksize_bits;
736 sb->s_maxbytes = data->sb->s_maxbytes;
737
738 server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
739 server->io_stats = nfs_alloc_iostats();
740 if (server->io_stats == NULL)
741 goto out;
742
743 server->client = rpc_clone_client(parent->client);
744 if (IS_ERR((err = server->client)))
745 goto out;
746
747 if (!IS_ERR(parent->client_sys)) {
748 server->client_sys = rpc_clone_client(parent->client_sys);
749 if (IS_ERR((err = server->client_sys)))
750 goto out;
751 }
752 if (!IS_ERR(parent->client_acl)) {
753 server->client_acl = rpc_clone_client(parent->client_acl);
754 if (IS_ERR((err = server->client_acl)))
755 goto out;
756 }
757 root_inode = nfs_fhget(sb, data->fh, data->fattr);
758 if (!root_inode)
759 goto out;
760 sb->s_root = d_alloc_root(root_inode);
761 if (!sb->s_root)
762 goto out_put_root;
763 fsinfo.fattr = data->fattr;
764 if (NFS_PROTO(root_inode)->fsinfo(server, data->fh, &fsinfo) == 0)
765 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize);
766 sb->s_root->d_op = server->rpc_ops->dentry_ops;
767 sb->s_flags |= MS_ACTIVE;
768 return server;
769out_put_root:
770 iput(root_inode);
771out:
772 return err;
773}
774 545
775/* 546 sb->s_blocksize_bits = 0;
776 * Copy an existing superblock and attach revised data 547 sb->s_blocksize = 0;
777 */ 548 if (data->bsize)
778static int nfs_clone_generic_sb(struct nfs_clone_mount *data, 549 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
779 struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *),
780 struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *),
781 struct vfsmount *mnt)
782{
783 struct nfs_server *server;
784 struct nfs_server *parent = NFS_SB(data->sb);
785 struct super_block *sb = ERR_PTR(-EINVAL);
786 char *hostname;
787 int error = -ENOMEM;
788 int len;
789
790 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
791 if (server == NULL)
792 goto out_err;
793 memcpy(server, parent, sizeof(*server));
794 hostname = (data->hostname != NULL) ? data->hostname : parent->hostname;
795 len = strlen(hostname) + 1;
796 server->hostname = kmalloc(len, GFP_KERNEL);
797 if (server->hostname == NULL)
798 goto free_server;
799 memcpy(server->hostname, hostname, len);
800 error = rpciod_up();
801 if (error != 0)
802 goto free_hostname;
803
804 sb = fill_sb(server, data);
805 if (IS_ERR(sb)) {
806 error = PTR_ERR(sb);
807 goto kill_rpciod;
808 }
809
810 if (sb->s_root)
811 goto out_rpciod_down;
812 550
813 server = fill_server(sb, data); 551 if (server->flags & NFS_MOUNT_VER3) {
814 if (IS_ERR(server)) { 552 /* The VFS shouldn't apply the umask to mode bits. We will do
815 error = PTR_ERR(server); 553 * so ourselves when necessary.
816 goto out_deactivate; 554 */
555 sb->s_flags |= MS_POSIXACL;
556 sb->s_time_gran = 1;
817 } 557 }
818 return simple_set_mnt(mnt, sb); 558
819out_deactivate: 559 sb->s_op = &nfs_sops;
820 up_write(&sb->s_umount); 560 nfs_initialise_sb(sb);
821 deactivate_super(sb);
822 return error;
823out_rpciod_down:
824 rpciod_down();
825 kfree(server->hostname);
826 kfree(server);
827 return simple_set_mnt(mnt, sb);
828kill_rpciod:
829 rpciod_down();
830free_hostname:
831 kfree(server->hostname);
832free_server:
833 kfree(server);
834out_err:
835 return error;
836} 561}
837 562
838/* 563/*
839 * Set up an NFS2/3 superblock 564 * Finish setting up a cloned NFS2/3 superblock
840 *
841 * The way this works is that the mount process passes a structure
842 * in the data argument which contains the server's IP address
843 * and the root file handle obtained from the server's mount
844 * daemon. We stash these away in the private superblock fields.
845 */ 565 */
846static int 566static void nfs_clone_super(struct super_block *sb,
847nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) 567 const struct super_block *old_sb)
848{ 568{
849 struct nfs_server *server; 569 struct nfs_server *server = NFS_SB(sb);
850 rpc_authflavor_t authflavor;
851 570
852 server = NFS_SB(sb); 571 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
853 sb->s_blocksize_bits = 0; 572 sb->s_blocksize = old_sb->s_blocksize;
854 sb->s_blocksize = 0; 573 sb->s_maxbytes = old_sb->s_maxbytes;
855 if (data->bsize)
856 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
857 if (data->rsize)
858 server->rsize = nfs_block_size(data->rsize, NULL);
859 if (data->wsize)
860 server->wsize = nfs_block_size(data->wsize, NULL);
861 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
862
863 server->acregmin = data->acregmin*HZ;
864 server->acregmax = data->acregmax*HZ;
865 server->acdirmin = data->acdirmin*HZ;
866 server->acdirmax = data->acdirmax*HZ;
867
868 /* Start lockd here, before we might error out */
869 if (!(server->flags & NFS_MOUNT_NONLM))
870 lockd_up();
871
872 server->namelen = data->namlen;
873 server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL);
874 if (!server->hostname)
875 return -ENOMEM;
876 strcpy(server->hostname, data->hostname);
877
878 /* Check NFS protocol revision and initialize RPC op vector
879 * and file handle pool. */
880#ifdef CONFIG_NFS_V3
881 if (server->flags & NFS_MOUNT_VER3) {
882 server->rpc_ops = &nfs_v3_clientops;
883 server->caps |= NFS_CAP_READDIRPLUS;
884 } else {
885 server->rpc_ops = &nfs_v2_clientops;
886 }
887#else
888 server->rpc_ops = &nfs_v2_clientops;
889#endif
890 574
891 /* Fill in pseudoflavor for mount version < 5 */
892 if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
893 data->pseudoflavor = RPC_AUTH_UNIX;
894 authflavor = data->pseudoflavor; /* save for sb_init() */
895 /* XXX maybe we want to add a server->pseudoflavor field */
896
897 /* Create RPC client handles */
898 server->client = nfs_create_client(server, data);
899 if (IS_ERR(server->client))
900 return PTR_ERR(server->client);
901 /* RFC 2623, sec 2.3.2 */
902 if (authflavor != RPC_AUTH_UNIX) {
903 struct rpc_auth *auth;
904
905 server->client_sys = rpc_clone_client(server->client);
906 if (IS_ERR(server->client_sys))
907 return PTR_ERR(server->client_sys);
908 auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys);
909 if (IS_ERR(auth))
910 return PTR_ERR(auth);
911 } else {
912 atomic_inc(&server->client->cl_count);
913 server->client_sys = server->client;
914 }
915 if (server->flags & NFS_MOUNT_VER3) { 575 if (server->flags & NFS_MOUNT_VER3) {
916#ifdef CONFIG_NFS_V3_ACL 576 /* The VFS shouldn't apply the umask to mode bits. We will do
917 if (!(server->flags & NFS_MOUNT_NOACL)) { 577 * so ourselves when necessary.
918 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
919 /* No errors! Assume that Sun nfsacls are supported */
920 if (!IS_ERR(server->client_acl))
921 server->caps |= NFS_CAP_ACLS;
922 }
923#else
924 server->flags &= ~NFS_MOUNT_NOACL;
925#endif /* CONFIG_NFS_V3_ACL */
926 /*
927 * The VFS shouldn't apply the umask to mode bits. We will
928 * do so ourselves when necessary.
929 */ 578 */
930 sb->s_flags |= MS_POSIXACL; 579 sb->s_flags |= MS_POSIXACL;
931 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
932 server->namelen = NFS3_MAXNAMLEN;
933 sb->s_time_gran = 1; 580 sb->s_time_gran = 1;
934 } else {
935 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
936 server->namelen = NFS2_MAXNAMLEN;
937 } 581 }
938 582
939 sb->s_op = &nfs_sops; 583 sb->s_op = old_sb->s_op;
940 return nfs_sb_init(sb, authflavor); 584 nfs_initialise_sb(sb);
941} 585}
942 586
943static int nfs_set_super(struct super_block *s, void *data) 587static int nfs_set_super(struct super_block *s, void *_server)
944{ 588{
945 s->s_fs_info = data; 589 struct nfs_server *server = _server;
946 return set_anon_super(s, data); 590 int ret;
591
592 s->s_fs_info = server;
593 ret = set_anon_super(s, server);
594 if (ret == 0)
595 server->s_dev = s->s_dev;
596 return ret;
947} 597}
948 598
949static int nfs_compare_super(struct super_block *sb, void *data) 599static int nfs_compare_super(struct super_block *sb, void *data)
950{ 600{
951 struct nfs_server *server = data; 601 struct nfs_server *server = data, *old = NFS_SB(sb);
952 struct nfs_server *old = NFS_SB(sb);
953 602
954 if (old->addr.sin_addr.s_addr != server->addr.sin_addr.s_addr) 603 if (old->nfs_client != server->nfs_client)
955 return 0; 604 return 0;
956 if (old->addr.sin_port != server->addr.sin_port) 605 if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
957 return 0; 606 return 0;
958 return !nfs_compare_fh(&old->fh, &server->fh); 607 return 1;
959} 608}
960 609
961static int nfs_get_sb(struct file_system_type *fs_type, 610static int nfs_get_sb(struct file_system_type *fs_type,
962 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 611 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
963{ 612{
964 int error;
965 struct nfs_server *server = NULL; 613 struct nfs_server *server = NULL;
966 struct super_block *s; 614 struct super_block *s;
967 struct nfs_fh *root; 615 struct nfs_fh mntfh;
968 struct nfs_mount_data *data = raw_data; 616 struct nfs_mount_data *data = raw_data;
617 struct dentry *mntroot;
618 int error;
969 619
970 error = -EINVAL; 620 /* Validate the mount data */
971 if (data == NULL) { 621 error = nfs_validate_mount_data(data, &mntfh);
972 dprintk("%s: missing data argument\n", __FUNCTION__); 622 if (error < 0)
973 goto out_err_noserver; 623 return error;
974 }
975 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
976 dprintk("%s: bad mount version\n", __FUNCTION__);
977 goto out_err_noserver;
978 }
979 switch (data->version) {
980 case 1:
981 data->namlen = 0;
982 case 2:
983 data->bsize = 0;
984 case 3:
985 if (data->flags & NFS_MOUNT_VER3) {
986 dprintk("%s: mount structure version %d does not support NFSv3\n",
987 __FUNCTION__,
988 data->version);
989 goto out_err_noserver;
990 }
991 data->root.size = NFS2_FHSIZE;
992 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
993 case 4:
994 if (data->flags & NFS_MOUNT_SECFLAVOUR) {
995 dprintk("%s: mount structure version %d does not support strong security\n",
996 __FUNCTION__,
997 data->version);
998 goto out_err_noserver;
999 }
1000 case 5:
1001 memset(data->context, 0, sizeof(data->context));
1002 }
1003#ifndef CONFIG_NFS_V3
1004 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
1005 error = -EPROTONOSUPPORT;
1006 if (data->flags & NFS_MOUNT_VER3) {
1007 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
1008 goto out_err_noserver;
1009 }
1010#endif /* CONFIG_NFS_V3 */
1011 624
1012 error = -ENOMEM; 625 /* Get a volume representation */
1013 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); 626 server = nfs_create_server(data, &mntfh);
1014 if (!server) 627 if (IS_ERR(server)) {
628 error = PTR_ERR(server);
1015 goto out_err_noserver; 629 goto out_err_noserver;
1016 /* Zero out the NFS state stuff */
1017 init_nfsv4_state(server);
1018 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1019
1020 root = &server->fh;
1021 if (data->flags & NFS_MOUNT_VER3)
1022 root->size = data->root.size;
1023 else
1024 root->size = NFS2_FHSIZE;
1025 error = -EINVAL;
1026 if (root->size > sizeof(root->data)) {
1027 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
1028 goto out_err;
1029 }
1030 memcpy(root->data, data->root.data, root->size);
1031
1032 /* We now require that the mount process passes the remote address */
1033 memcpy(&server->addr, &data->addr, sizeof(server->addr));
1034 if (server->addr.sin_addr.s_addr == INADDR_ANY) {
1035 dprintk("%s: mount program didn't pass remote address!\n",
1036 __FUNCTION__);
1037 goto out_err;
1038 }
1039
1040 /* Fire up rpciod if not yet running */
1041 error = rpciod_up();
1042 if (error < 0) {
1043 dprintk("%s: couldn't start rpciod! Error = %d\n",
1044 __FUNCTION__, error);
1045 goto out_err;
1046 } 630 }
1047 631
632 /* Get a superblock - note that we may end up sharing one that already exists */
1048 s = sget(fs_type, nfs_compare_super, nfs_set_super, server); 633 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1049 if (IS_ERR(s)) { 634 if (IS_ERR(s)) {
1050 error = PTR_ERR(s); 635 error = PTR_ERR(s);
1051 goto out_err_rpciod; 636 goto out_err_nosb;
1052 } 637 }
1053 638
1054 if (s->s_root) 639 if (s->s_fs_info != server) {
1055 goto out_rpciod_down; 640 nfs_free_server(server);
641 server = NULL;
642 }
1056 643
1057 s->s_flags = flags; 644 if (!s->s_root) {
645 /* initial superblock/root creation */
646 s->s_flags = flags;
647 nfs_fill_super(s, data);
648 }
1058 649
1059 error = nfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0); 650 mntroot = nfs_get_root(s, &mntfh);
1060 if (error) { 651 if (IS_ERR(mntroot)) {
1061 up_write(&s->s_umount); 652 error = PTR_ERR(mntroot);
1062 deactivate_super(s); 653 goto error_splat_super;
1063 return error;
1064 } 654 }
1065 s->s_flags |= MS_ACTIVE;
1066 return simple_set_mnt(mnt, s);
1067 655
1068out_rpciod_down: 656 s->s_flags |= MS_ACTIVE;
1069 rpciod_down(); 657 mnt->mnt_sb = s;
1070 kfree(server); 658 mnt->mnt_root = mntroot;
1071 return simple_set_mnt(mnt, s); 659 return 0;
1072 660
1073out_err_rpciod: 661out_err_nosb:
1074 rpciod_down(); 662 nfs_free_server(server);
1075out_err:
1076 kfree(server);
1077out_err_noserver: 663out_err_noserver:
1078 return error; 664 return error;
665
666error_splat_super:
667 up_write(&s->s_umount);
668 deactivate_super(s);
669 return error;
1079} 670}
1080 671
672/*
673 * Destroy an NFS2/3 superblock
674 */
1081static void nfs_kill_super(struct super_block *s) 675static void nfs_kill_super(struct super_block *s)
1082{ 676{
1083 struct nfs_server *server = NFS_SB(s); 677 struct nfs_server *server = NFS_SB(s);
1084 678
1085 kill_anon_super(s); 679 kill_anon_super(s);
1086 680 nfs_free_server(server);
1087 if (!IS_ERR(server->client))
1088 rpc_shutdown_client(server->client);
1089 if (!IS_ERR(server->client_sys))
1090 rpc_shutdown_client(server->client_sys);
1091 if (!IS_ERR(server->client_acl))
1092 rpc_shutdown_client(server->client_acl);
1093
1094 if (!(server->flags & NFS_MOUNT_NONLM))
1095 lockd_down(); /* release rpc.lockd */
1096
1097 rpciod_down(); /* release rpciod */
1098
1099 nfs_free_iostats(server->io_stats);
1100 kfree(server->hostname);
1101 kfree(server);
1102 nfs_release_automount_timer();
1103}
1104
1105static struct super_block *nfs_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data)
1106{
1107 struct super_block *sb;
1108
1109 server->fsid = data->fattr->fsid;
1110 nfs_copy_fh(&server->fh, data->fh);
1111 sb = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
1112 if (!IS_ERR(sb) && sb->s_root == NULL && !(server->flags & NFS_MOUNT_NONLM))
1113 lockd_up();
1114 return sb;
1115} 681}
1116 682
1117static int nfs_clone_nfs_sb(struct file_system_type *fs_type, 683/*
1118 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 684 * Clone an NFS2/3 server record on xdev traversal (FSID-change)
685 */
686static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
687 const char *dev_name, void *raw_data,
688 struct vfsmount *mnt)
1119{ 689{
1120 struct nfs_clone_mount *data = raw_data; 690 struct nfs_clone_mount *data = raw_data;
1121 return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server, mnt); 691 struct super_block *s;
1122} 692 struct nfs_server *server;
693 struct dentry *mntroot;
694 int error;
1123 695
1124#ifdef CONFIG_NFS_V4 696 dprintk("--> nfs_xdev_get_sb()\n");
1125static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
1126 struct rpc_timeout *timeparms, int proto, rpc_authflavor_t flavor)
1127{
1128 struct nfs4_client *clp;
1129 struct rpc_xprt *xprt = NULL;
1130 struct rpc_clnt *clnt = NULL;
1131 int err = -EIO;
1132
1133 clp = nfs4_get_client(&server->addr.sin_addr);
1134 if (!clp) {
1135 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
1136 return ERR_PTR(err);
1137 }
1138 697
1139 /* Now create transport and client */ 698 /* create a new volume representation */
1140 down_write(&clp->cl_sem); 699 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
1141 if (IS_ERR(clp->cl_rpcclient)) { 700 if (IS_ERR(server)) {
1142 xprt = xprt_create_proto(proto, &server->addr, timeparms); 701 error = PTR_ERR(server);
1143 if (IS_ERR(xprt)) { 702 goto out_err_noserver;
1144 up_write(&clp->cl_sem);
1145 err = PTR_ERR(xprt);
1146 dprintk("%s: cannot create RPC transport. Error = %d\n",
1147 __FUNCTION__, err);
1148 goto out_fail;
1149 }
1150 /* Bind to a reserved port! */
1151 xprt->resvport = 1;
1152 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
1153 server->rpc_ops->version, flavor);
1154 if (IS_ERR(clnt)) {
1155 up_write(&clp->cl_sem);
1156 err = PTR_ERR(clnt);
1157 dprintk("%s: cannot create RPC client. Error = %d\n",
1158 __FUNCTION__, err);
1159 goto out_fail;
1160 }
1161 clnt->cl_intr = 1;
1162 clnt->cl_softrtry = 1;
1163 clp->cl_rpcclient = clnt;
1164 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
1165 nfs_idmap_new(clp);
1166 }
1167 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
1168 clnt = rpc_clone_client(clp->cl_rpcclient);
1169 if (!IS_ERR(clnt))
1170 server->nfs4_state = clp;
1171 up_write(&clp->cl_sem);
1172 clp = NULL;
1173
1174 if (IS_ERR(clnt)) {
1175 dprintk("%s: cannot create RPC client. Error = %d\n",
1176 __FUNCTION__, err);
1177 return clnt;
1178 } 703 }
1179 704
1180 if (server->nfs4_state->cl_idmap == NULL) { 705 /* Get a superblock - note that we may end up sharing one that already exists */
1181 dprintk("%s: failed to create idmapper.\n", __FUNCTION__); 706 s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
1182 return ERR_PTR(-ENOMEM); 707 if (IS_ERR(s)) {
708 error = PTR_ERR(s);
709 goto out_err_nosb;
1183 } 710 }
1184 711
1185 if (clnt->cl_auth->au_flavor != flavor) { 712 if (s->s_fs_info != server) {
1186 struct rpc_auth *auth; 713 nfs_free_server(server);
1187 714 server = NULL;
1188 auth = rpcauth_create(flavor, clnt);
1189 if (IS_ERR(auth)) {
1190 dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
1191 return (struct rpc_clnt *)auth;
1192 }
1193 } 715 }
1194 return clnt;
1195
1196 out_fail:
1197 if (clp)
1198 nfs4_put_client(clp);
1199 return ERR_PTR(err);
1200}
1201
1202/*
1203 * Set up an NFS4 superblock
1204 */
1205static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent)
1206{
1207 struct nfs_server *server;
1208 struct rpc_timeout timeparms;
1209 rpc_authflavor_t authflavour;
1210 int err = -EIO;
1211 716
1212 sb->s_blocksize_bits = 0; 717 if (!s->s_root) {
1213 sb->s_blocksize = 0; 718 /* initial superblock/root creation */
1214 server = NFS_SB(sb); 719 s->s_flags = flags;
1215 if (data->rsize != 0) 720 nfs_clone_super(s, data->sb);
1216 server->rsize = nfs_block_size(data->rsize, NULL); 721 }
1217 if (data->wsize != 0)
1218 server->wsize = nfs_block_size(data->wsize, NULL);
1219 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
1220 server->caps = NFS_CAP_ATOMIC_OPEN;
1221 722
1222 server->acregmin = data->acregmin*HZ; 723 mntroot = nfs_get_root(s, data->fh);
1223 server->acregmax = data->acregmax*HZ; 724 if (IS_ERR(mntroot)) {
1224 server->acdirmin = data->acdirmin*HZ; 725 error = PTR_ERR(mntroot);
1225 server->acdirmax = data->acdirmax*HZ; 726 goto error_splat_super;
727 }
1226 728
1227 server->rpc_ops = &nfs_v4_clientops; 729 s->s_flags |= MS_ACTIVE;
730 mnt->mnt_sb = s;
731 mnt->mnt_root = mntroot;
1228 732
1229 nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans); 733 dprintk("<-- nfs_xdev_get_sb() = 0\n");
734 return 0;
1230 735
1231 server->retrans_timeo = timeparms.to_initval; 736out_err_nosb:
1232 server->retrans_count = timeparms.to_retries; 737 nfs_free_server(server);
738out_err_noserver:
739 dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error);
740 return error;
1233 741
1234 /* Now create transport and client */ 742error_splat_super:
1235 authflavour = RPC_AUTH_UNIX; 743 up_write(&s->s_umount);
1236 if (data->auth_flavourlen != 0) { 744 deactivate_super(s);
1237 if (data->auth_flavourlen != 1) { 745 dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
1238 dprintk("%s: Invalid number of RPC auth flavours %d.\n", 746 return error;
1239 __FUNCTION__, data->auth_flavourlen); 747}
1240 err = -EINVAL;
1241 goto out_fail;
1242 }
1243 if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {
1244 err = -EFAULT;
1245 goto out_fail;
1246 }
1247 }
1248 748
1249 server->client = nfs4_create_client(server, &timeparms, data->proto, authflavour); 749#ifdef CONFIG_NFS_V4
1250 if (IS_ERR(server->client)) {
1251 err = PTR_ERR(server->client);
1252 dprintk("%s: cannot create RPC client. Error = %d\n",
1253 __FUNCTION__, err);
1254 goto out_fail;
1255 }
1256 750
751/*
752 * Finish setting up a cloned NFS4 superblock
753 */
754static void nfs4_clone_super(struct super_block *sb,
755 const struct super_block *old_sb)
756{
757 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
758 sb->s_blocksize = old_sb->s_blocksize;
759 sb->s_maxbytes = old_sb->s_maxbytes;
1257 sb->s_time_gran = 1; 760 sb->s_time_gran = 1;
1258 761 sb->s_op = old_sb->s_op;
1259 sb->s_op = &nfs4_sops; 762 nfs_initialise_sb(sb);
1260 err = nfs_sb_init(sb, authflavour);
1261
1262 out_fail:
1263 return err;
1264} 763}
1265 764
1266static int nfs4_compare_super(struct super_block *sb, void *data) 765/*
766 * Set up an NFS4 superblock
767 */
768static void nfs4_fill_super(struct super_block *sb)
1267{ 769{
1268 struct nfs_server *server = data; 770 sb->s_time_gran = 1;
1269 struct nfs_server *old = NFS_SB(sb); 771 sb->s_op = &nfs4_sops;
1270 772 nfs_initialise_sb(sb);
1271 if (strcmp(server->hostname, old->hostname) != 0)
1272 return 0;
1273 if (strcmp(server->mnt_path, old->mnt_path) != 0)
1274 return 0;
1275 return 1;
1276} 773}
1277 774
1278static void * 775static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
1279nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
1280{ 776{
1281 void *p = NULL; 777 void *p = NULL;
1282 778
@@ -1297,14 +793,22 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
1297 return dst; 793 return dst;
1298} 794}
1299 795
796/*
797 * Get the superblock for an NFS4 mountpoint
798 */
1300static int nfs4_get_sb(struct file_system_type *fs_type, 799static int nfs4_get_sb(struct file_system_type *fs_type,
1301 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 800 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1302{ 801{
1303 int error;
1304 struct nfs_server *server;
1305 struct super_block *s;
1306 struct nfs4_mount_data *data = raw_data; 802 struct nfs4_mount_data *data = raw_data;
803 struct super_block *s;
804 struct nfs_server *server;
805 struct sockaddr_in addr;
806 rpc_authflavor_t authflavour;
807 struct nfs_fh mntfh;
808 struct dentry *mntroot;
809 char *mntpath = NULL, *hostname = NULL, ip_addr[16];
1307 void *p; 810 void *p;
811 int error;
1308 812
1309 if (data == NULL) { 813 if (data == NULL) {
1310 dprintk("%s: missing data argument\n", __FUNCTION__); 814 dprintk("%s: missing data argument\n", __FUNCTION__);
@@ -1315,84 +819,112 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
1315 return -EINVAL; 819 return -EINVAL;
1316 } 820 }
1317 821
1318 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); 822 /* We now require that the mount process passes the remote address */
1319 if (!server) 823 if (data->host_addrlen != sizeof(addr))
1320 return -ENOMEM; 824 return -EINVAL;
1321 /* Zero out the NFS state stuff */ 825
1322 init_nfsv4_state(server); 826 if (copy_from_user(&addr, data->host_addr, sizeof(addr)))
1323 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 827 return -EFAULT;
828
829 if (addr.sin_family != AF_INET ||
830 addr.sin_addr.s_addr == INADDR_ANY
831 ) {
832 dprintk("%s: mount program didn't pass remote IP address!\n",
833 __FUNCTION__);
834 return -EINVAL;
835 }
836 /* RFC3530: The default port for NFS is 2049 */
837 if (addr.sin_port == 0)
838 addr.sin_port = NFS_PORT;
839
840 /* Grab the authentication type */
841 authflavour = RPC_AUTH_UNIX;
842 if (data->auth_flavourlen != 0) {
843 if (data->auth_flavourlen != 1) {
844 dprintk("%s: Invalid number of RPC auth flavours %d.\n",
845 __FUNCTION__, data->auth_flavourlen);
846 error = -EINVAL;
847 goto out_err_noserver;
848 }
849
850 if (copy_from_user(&authflavour, data->auth_flavours,
851 sizeof(authflavour))) {
852 error = -EFAULT;
853 goto out_err_noserver;
854 }
855 }
1324 856
1325 p = nfs_copy_user_string(NULL, &data->hostname, 256); 857 p = nfs_copy_user_string(NULL, &data->hostname, 256);
1326 if (IS_ERR(p)) 858 if (IS_ERR(p))
1327 goto out_err; 859 goto out_err;
1328 server->hostname = p; 860 hostname = p;
1329 861
1330 p = nfs_copy_user_string(NULL, &data->mnt_path, 1024); 862 p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
1331 if (IS_ERR(p)) 863 if (IS_ERR(p))
1332 goto out_err; 864 goto out_err;
1333 server->mnt_path = p; 865 mntpath = p;
866
867 dprintk("MNTPATH: %s\n", mntpath);
1334 868
1335 p = nfs_copy_user_string(server->ip_addr, &data->client_addr, 869 p = nfs_copy_user_string(ip_addr, &data->client_addr,
1336 sizeof(server->ip_addr) - 1); 870 sizeof(ip_addr) - 1);
1337 if (IS_ERR(p)) 871 if (IS_ERR(p))
1338 goto out_err; 872 goto out_err;
1339 873
1340 /* We now require that the mount process passes the remote address */ 874 /* Get a volume representation */
1341 if (data->host_addrlen != sizeof(server->addr)) { 875 server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
1342 error = -EINVAL; 876 authflavour, &mntfh);
1343 goto out_free; 877 if (IS_ERR(server)) {
1344 } 878 error = PTR_ERR(server);
1345 if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) { 879 goto out_err_noserver;
1346 error = -EFAULT;
1347 goto out_free;
1348 }
1349 if (server->addr.sin_family != AF_INET ||
1350 server->addr.sin_addr.s_addr == INADDR_ANY) {
1351 dprintk("%s: mount program didn't pass remote IP address!\n",
1352 __FUNCTION__);
1353 error = -EINVAL;
1354 goto out_free;
1355 }
1356
1357 /* Fire up rpciod if not yet running */
1358 error = rpciod_up();
1359 if (error < 0) {
1360 dprintk("%s: couldn't start rpciod! Error = %d\n",
1361 __FUNCTION__, error);
1362 goto out_free;
1363 } 880 }
1364 881
1365 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); 882 /* Get a superblock - note that we may end up sharing one that already exists */
1366 883 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1367 if (IS_ERR(s)) { 884 if (IS_ERR(s)) {
1368 error = PTR_ERR(s); 885 error = PTR_ERR(s);
1369 goto out_free; 886 goto out_free;
1370 } 887 }
1371 888
1372 if (s->s_root) { 889 if (s->s_fs_info != server) {
1373 kfree(server->mnt_path); 890 nfs_free_server(server);
1374 kfree(server->hostname); 891 server = NULL;
1375 kfree(server);
1376 return simple_set_mnt(mnt, s);
1377 } 892 }
1378 893
1379 s->s_flags = flags; 894 if (!s->s_root) {
895 /* initial superblock/root creation */
896 s->s_flags = flags;
897 nfs4_fill_super(s);
898 }
1380 899
1381 error = nfs4_fill_super(s, data, flags & MS_SILENT ? 1 : 0); 900 mntroot = nfs4_get_root(s, &mntfh);
1382 if (error) { 901 if (IS_ERR(mntroot)) {
1383 up_write(&s->s_umount); 902 error = PTR_ERR(mntroot);
1384 deactivate_super(s); 903 goto error_splat_super;
1385 return error;
1386 } 904 }
905
1387 s->s_flags |= MS_ACTIVE; 906 s->s_flags |= MS_ACTIVE;
1388 return simple_set_mnt(mnt, s); 907 mnt->mnt_sb = s;
908 mnt->mnt_root = mntroot;
909 kfree(mntpath);
910 kfree(hostname);
911 return 0;
912
1389out_err: 913out_err:
1390 error = PTR_ERR(p); 914 error = PTR_ERR(p);
915 goto out_err_noserver;
916
1391out_free: 917out_free:
1392 kfree(server->mnt_path); 918 nfs_free_server(server);
1393 kfree(server->hostname); 919out_err_noserver:
1394 kfree(server); 920 kfree(mntpath);
921 kfree(hostname);
1395 return error; 922 return error;
923
924error_splat_super:
925 up_write(&s->s_umount);
926 deactivate_super(s);
927 goto out_err_noserver;
1396} 928}
1397 929
1398static void nfs4_kill_super(struct super_block *sb) 930static void nfs4_kill_super(struct super_block *sb)
@@ -1403,135 +935,140 @@ static void nfs4_kill_super(struct super_block *sb)
1403 kill_anon_super(sb); 935 kill_anon_super(sb);
1404 936
1405 nfs4_renewd_prepare_shutdown(server); 937 nfs4_renewd_prepare_shutdown(server);
938 nfs_free_server(server);
939}
940
941/*
942 * Clone an NFS4 server record on xdev traversal (FSID-change)
943 */
944static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
945 const char *dev_name, void *raw_data,
946 struct vfsmount *mnt)
947{
948 struct nfs_clone_mount *data = raw_data;
949 struct super_block *s;
950 struct nfs_server *server;
951 struct dentry *mntroot;
952 int error;
953
954 dprintk("--> nfs4_xdev_get_sb()\n");
955
956 /* create a new volume representation */
957 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
958 if (IS_ERR(server)) {
959 error = PTR_ERR(server);
960 goto out_err_noserver;
961 }
962
963 /* Get a superblock - note that we may end up sharing one that already exists */
964 s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
965 if (IS_ERR(s)) {
966 error = PTR_ERR(s);
967 goto out_err_nosb;
968 }
1406 969
1407 if (server->client != NULL && !IS_ERR(server->client)) 970 if (s->s_fs_info != server) {
1408 rpc_shutdown_client(server->client); 971 nfs_free_server(server);
972 server = NULL;
973 }
1409 974
1410 destroy_nfsv4_state(server); 975 if (!s->s_root) {
976 /* initial superblock/root creation */
977 s->s_flags = flags;
978 nfs4_clone_super(s, data->sb);
979 }
980
981 mntroot = nfs4_get_root(s, data->fh);
982 if (IS_ERR(mntroot)) {
983 error = PTR_ERR(mntroot);
984 goto error_splat_super;
985 }
1411 986
1412 rpciod_down(); 987 s->s_flags |= MS_ACTIVE;
988 mnt->mnt_sb = s;
989 mnt->mnt_root = mntroot;
990
991 dprintk("<-- nfs4_xdev_get_sb() = 0\n");
992 return 0;
993
994out_err_nosb:
995 nfs_free_server(server);
996out_err_noserver:
997 dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error);
998 return error;
1413 999
1414 nfs_free_iostats(server->io_stats); 1000error_splat_super:
1415 kfree(server->hostname); 1001 up_write(&s->s_umount);
1416 kfree(server); 1002 deactivate_super(s);
1417 nfs_release_automount_timer(); 1003 dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
1004 return error;
1418} 1005}
1419 1006
1420/* 1007/*
1421 * Constructs the SERVER-side path 1008 * Create an NFS4 server record on referral traversal
1422 */ 1009 */
1423static inline char *nfs4_dup_path(const struct dentry *dentry) 1010static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
1011 const char *dev_name, void *raw_data,
1012 struct vfsmount *mnt)
1424{ 1013{
1425 char *page = (char *) __get_free_page(GFP_USER); 1014 struct nfs_clone_mount *data = raw_data;
1426 char *path; 1015 struct super_block *s;
1016 struct nfs_server *server;
1017 struct dentry *mntroot;
1018 struct nfs_fh mntfh;
1019 int error;
1427 1020
1428 path = nfs4_path(dentry, page, PAGE_SIZE); 1021 dprintk("--> nfs4_referral_get_sb()\n");
1429 if (!IS_ERR(path)) {
1430 int len = PAGE_SIZE + page - path;
1431 char *tmp = path;
1432 1022
1433 path = kmalloc(len, GFP_KERNEL); 1023 /* create a new volume representation */
1434 if (path) 1024 server = nfs4_create_referral_server(data, &mntfh);
1435 memcpy(path, tmp, len); 1025 if (IS_ERR(server)) {
1436 else 1026 error = PTR_ERR(server);
1437 path = ERR_PTR(-ENOMEM); 1027 goto out_err_noserver;
1438 } 1028 }
1439 free_page((unsigned long)page);
1440 return path;
1441}
1442 1029
1443static struct super_block *nfs4_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data) 1030 /* Get a superblock - note that we may end up sharing one that already exists */
1444{ 1031 s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
1445 const struct dentry *dentry = data->dentry; 1032 if (IS_ERR(s)) {
1446 struct nfs4_client *clp = server->nfs4_state; 1033 error = PTR_ERR(s);
1447 struct super_block *sb; 1034 goto out_err_nosb;
1448
1449 server->fsid = data->fattr->fsid;
1450 nfs_copy_fh(&server->fh, data->fh);
1451 server->mnt_path = nfs4_dup_path(dentry);
1452 if (IS_ERR(server->mnt_path)) {
1453 sb = (struct super_block *)server->mnt_path;
1454 goto err;
1455 } 1035 }
1456 sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server);
1457 if (IS_ERR(sb) || sb->s_root)
1458 goto free_path;
1459 nfs4_server_capabilities(server, &server->fh);
1460
1461 down_write(&clp->cl_sem);
1462 atomic_inc(&clp->cl_count);
1463 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
1464 up_write(&clp->cl_sem);
1465 return sb;
1466free_path:
1467 kfree(server->mnt_path);
1468err:
1469 server->mnt_path = NULL;
1470 return sb;
1471}
1472 1036
1473static int nfs_clone_nfs4_sb(struct file_system_type *fs_type, 1037 if (s->s_fs_info != server) {
1474 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 1038 nfs_free_server(server);
1475{ 1039 server = NULL;
1476 struct nfs_clone_mount *data = raw_data; 1040 }
1477 return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server, mnt);
1478}
1479 1041
1480static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data) 1042 if (!s->s_root) {
1481{ 1043 /* initial superblock/root creation */
1482 struct super_block *sb = ERR_PTR(-ENOMEM); 1044 s->s_flags = flags;
1483 int len; 1045 nfs4_fill_super(s);
1484 1046 }
1485 len = strlen(data->mnt_path) + 1;
1486 server->mnt_path = kmalloc(len, GFP_KERNEL);
1487 if (server->mnt_path == NULL)
1488 goto err;
1489 memcpy(server->mnt_path, data->mnt_path, len);
1490 memcpy(&server->addr, data->addr, sizeof(struct sockaddr_in));
1491
1492 sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server);
1493 if (IS_ERR(sb) || sb->s_root)
1494 goto free_path;
1495 return sb;
1496free_path:
1497 kfree(server->mnt_path);
1498err:
1499 server->mnt_path = NULL;
1500 return sb;
1501}
1502 1047
1503static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data) 1048 mntroot = nfs4_get_root(s, data->fh);
1504{ 1049 if (IS_ERR(mntroot)) {
1505 struct nfs_server *server = NFS_SB(sb); 1050 error = PTR_ERR(mntroot);
1506 struct rpc_timeout timeparms; 1051 goto error_splat_super;
1507 int proto, timeo, retrans; 1052 }
1508 void *err;
1509
1510 proto = IPPROTO_TCP;
1511 /* Since we are following a referral and there may be alternatives,
1512 set the timeouts and retries to low values */
1513 timeo = 2;
1514 retrans = 1;
1515 nfs_init_timeout_values(&timeparms, proto, timeo, retrans);
1516
1517 server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor);
1518 if (IS_ERR((err = server->client)))
1519 goto out_err;
1520 1053
1521 sb->s_time_gran = 1; 1054 s->s_flags |= MS_ACTIVE;
1522 sb->s_op = &nfs4_sops; 1055 mnt->mnt_sb = s;
1523 err = ERR_PTR(nfs_sb_init(sb, data->authflavor)); 1056 mnt->mnt_root = mntroot;
1524 if (!IS_ERR(err))
1525 return server;
1526out_err:
1527 return (struct nfs_server *)err;
1528}
1529 1057
1530static int nfs_referral_nfs4_sb(struct file_system_type *fs_type, 1058 dprintk("<-- nfs4_referral_get_sb() = 0\n");
1531 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) 1059 return 0;
1532{ 1060
1533 struct nfs_clone_mount *data = raw_data; 1061out_err_nosb:
1534 return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server, mnt); 1062 nfs_free_server(server);
1063out_err_noserver:
1064 dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
1065 return error;
1066
1067error_splat_super:
1068 up_write(&s->s_umount);
1069 deactivate_super(s);
1070 dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
1071 return error;
1535} 1072}
1536 1073
1537#endif 1074#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 7084ac9a6455..c12effb46fe5 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -396,6 +396,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
396out: 396out:
397 clear_bit(BDI_write_congested, &bdi->state); 397 clear_bit(BDI_write_congested, &bdi->state);
398 wake_up_all(&nfs_write_congestion); 398 wake_up_all(&nfs_write_congestion);
399 writeback_congestion_end();
399 return err; 400 return err;
400} 401}
401 402
@@ -1252,7 +1253,13 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1252 dprintk("NFS: %4d nfs_writeback_done (status %d)\n", 1253 dprintk("NFS: %4d nfs_writeback_done (status %d)\n",
1253 task->tk_pid, task->tk_status); 1254 task->tk_pid, task->tk_status);
1254 1255
1255 /* Call the NFS version-specific code */ 1256 /*
1257 * ->write_done will attempt to use post-op attributes to detect
1258 * conflicting writes by other clients. A strict interpretation
1259 * of close-to-open would allow us to continue caching even if
1260 * another writer had changed the file, but some applications
1261 * depend on tighter cache coherency when writing.
1262 */
1256 status = NFS_PROTO(data->inode)->write_done(task, data); 1263 status = NFS_PROTO(data->inode)->write_done(task, data);
1257 if (status != 0) 1264 if (status != 0)
1258 return status; 1265 return status;
@@ -1273,7 +1280,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1273 if (time_before(complain, jiffies)) { 1280 if (time_before(complain, jiffies)) {
1274 dprintk("NFS: faulty NFS server %s:" 1281 dprintk("NFS: faulty NFS server %s:"
1275 " (committed = %d) != (stable = %d)\n", 1282 " (committed = %d) != (stable = %d)\n",
1276 NFS_SERVER(data->inode)->hostname, 1283 NFS_SERVER(data->inode)->nfs_client->cl_hostname,
1277 resp->verf->committed, argp->stable); 1284 resp->verf->committed, argp->stable);
1278 complain = jiffies + 300 * HZ; 1285 complain = jiffies + 300 * HZ;
1279 } 1286 }
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 54b37b1d2e3a..8583d99ee740 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -375,16 +375,28 @@ nfsd4_probe_callback(struct nfs4_client *clp)
375{ 375{
376 struct sockaddr_in addr; 376 struct sockaddr_in addr;
377 struct nfs4_callback *cb = &clp->cl_callback; 377 struct nfs4_callback *cb = &clp->cl_callback;
378 struct rpc_timeout timeparms; 378 struct rpc_timeout timeparms = {
379 struct rpc_xprt * xprt; 379 .to_initval = (NFSD_LEASE_TIME/4) * HZ,
380 .to_retries = 5,
381 .to_maxval = (NFSD_LEASE_TIME/2) * HZ,
382 .to_exponential = 1,
383 };
380 struct rpc_program * program = &cb->cb_program; 384 struct rpc_program * program = &cb->cb_program;
381 struct rpc_stat * stat = &cb->cb_stat; 385 struct rpc_create_args args = {
382 struct rpc_clnt * clnt; 386 .protocol = IPPROTO_TCP,
387 .address = (struct sockaddr *)&addr,
388 .addrsize = sizeof(addr),
389 .timeout = &timeparms,
390 .servername = clp->cl_name.data,
391 .program = program,
392 .version = nfs_cb_version[1]->number,
393 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
394 .flags = (RPC_CLNT_CREATE_NOPING),
395 };
383 struct rpc_message msg = { 396 struct rpc_message msg = {
384 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], 397 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
385 .rpc_argp = clp, 398 .rpc_argp = clp,
386 }; 399 };
387 char hostname[32];
388 int status; 400 int status;
389 401
390 if (atomic_read(&cb->cb_set)) 402 if (atomic_read(&cb->cb_set))
@@ -396,51 +408,27 @@ nfsd4_probe_callback(struct nfs4_client *clp)
396 addr.sin_port = htons(cb->cb_port); 408 addr.sin_port = htons(cb->cb_port);
397 addr.sin_addr.s_addr = htonl(cb->cb_addr); 409 addr.sin_addr.s_addr = htonl(cb->cb_addr);
398 410
399 /* Initialize timeout */
400 timeparms.to_initval = (NFSD_LEASE_TIME/4) * HZ;
401 timeparms.to_retries = 0;
402 timeparms.to_maxval = (NFSD_LEASE_TIME/2) * HZ;
403 timeparms.to_exponential = 1;
404
405 /* Create RPC transport */
406 xprt = xprt_create_proto(IPPROTO_TCP, &addr, &timeparms);
407 if (IS_ERR(xprt)) {
408 dprintk("NFSD: couldn't create callback transport!\n");
409 goto out_err;
410 }
411
412 /* Initialize rpc_program */ 411 /* Initialize rpc_program */
413 program->name = "nfs4_cb"; 412 program->name = "nfs4_cb";
414 program->number = cb->cb_prog; 413 program->number = cb->cb_prog;
415 program->nrvers = ARRAY_SIZE(nfs_cb_version); 414 program->nrvers = ARRAY_SIZE(nfs_cb_version);
416 program->version = nfs_cb_version; 415 program->version = nfs_cb_version;
417 program->stats = stat; 416 program->stats = &cb->cb_stat;
418 417
419 /* Initialize rpc_stat */ 418 /* Initialize rpc_stat */
420 memset(stat, 0, sizeof(struct rpc_stat)); 419 memset(program->stats, 0, sizeof(cb->cb_stat));
421 stat->program = program; 420 program->stats->program = program;
422 421
423 /* Create RPC client 422 /* Create RPC client */
424 * 423 cb->cb_client = rpc_create(&args);
425 * XXX AUTH_UNIX only - need AUTH_GSS.... 424 if (!cb->cb_client) {
426 */
427 sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
428 clnt = rpc_new_client(xprt, hostname, program, 1, RPC_AUTH_UNIX);
429 if (IS_ERR(clnt)) {
430 dprintk("NFSD: couldn't create callback client\n"); 425 dprintk("NFSD: couldn't create callback client\n");
431 goto out_err; 426 goto out_err;
432 } 427 }
433 clnt->cl_intr = 0;
434 clnt->cl_softrtry = 1;
435 428
436 /* Kick rpciod, put the call on the wire. */ 429 /* Kick rpciod, put the call on the wire. */
437 430 if (rpciod_up() != 0)
438 if (rpciod_up() != 0) {
439 dprintk("nfsd: couldn't start rpciod for callbacks!\n");
440 goto out_clnt; 431 goto out_clnt;
441 }
442
443 cb->cb_client = clnt;
444 432
445 /* the task holds a reference to the nfs4_client struct */ 433 /* the task holds a reference to the nfs4_client struct */
446 atomic_inc(&clp->cl_count); 434 atomic_inc(&clp->cl_count);
@@ -448,7 +436,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
448 msg.rpc_cred = nfsd4_lookupcred(clp,0); 436 msg.rpc_cred = nfsd4_lookupcred(clp,0);
449 if (IS_ERR(msg.rpc_cred)) 437 if (IS_ERR(msg.rpc_cred))
450 goto out_rpciod; 438 goto out_rpciod;
451 status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); 439 status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL);
452 put_rpccred(msg.rpc_cred); 440 put_rpccred(msg.rpc_cred);
453 441
454 if (status != 0) { 442 if (status != 0) {
@@ -462,7 +450,7 @@ out_rpciod:
462 rpciod_down(); 450 rpciod_down();
463 cb->cb_client = NULL; 451 cb->cb_client = NULL;
464out_clnt: 452out_clnt:
465 rpc_shutdown_client(clnt); 453 rpc_shutdown_client(cb->cb_client);
466out_err: 454out_err:
467 dprintk("NFSD: warning: no callback path to client %.*s\n", 455 dprintk("NFSD: warning: no callback path to client %.*s\n",
468 (int)clp->cl_name.len, clp->cl_name.data); 456 (int)clp->cl_name.len, clp->cl_name.data);