aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-12-30 16:51:43 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-12-30 16:51:43 -0500
commit08cc36cbd1ee7d86422713bb21551eed1326b894 (patch)
tree52cc683387f903b34a7f6f798dcdbae385b58db8 /fs
parent3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff)
parent46f72f57d279688c4524df78edb5738db730eeef (diff)
Merge branch 'devel' into next
Diffstat (limited to 'fs')
-rw-r--r--fs/lockd/clntlock.c23
-rw-r--r--fs/lockd/host.c10
-rw-r--r--fs/lockd/svc.c6
-rw-r--r--fs/nfs/callback.c36
-rw-r--r--fs/nfs/client.c95
-rw-r--r--fs/nfs/delegation.c260
-rw-r--r--fs/nfs/delegation.h33
-rw-r--r--fs/nfs/dir.c24
-rw-r--r--fs/nfs/inode.c13
-rw-r--r--fs/nfs/internal.h14
-rw-r--r--fs/nfs/mount_clnt.c34
-rw-r--r--fs/nfs/nfs4_fs.h32
-rw-r--r--fs/nfs/nfs4proc.c431
-rw-r--r--fs/nfs/nfs4renewd.c22
-rw-r--r--fs/nfs/nfs4state.c415
-rw-r--r--fs/nfs/nfs4xdr.c1235
-rw-r--r--fs/nfs/nfsroot.c27
-rw-r--r--fs/nfs/read.c6
-rw-r--r--fs/nfs/super.c44
-rw-r--r--fs/nfs_common/nfsacl.c4
-rw-r--r--fs/nfsd/nfs4callback.c9
-rw-r--r--fs/nfsd/nfs4state.c12
22 files changed, 1492 insertions, 1293 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 8307dd64bf46..1f3b0fc0d351 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -14,6 +14,7 @@
14#include <linux/sunrpc/svc.h> 14#include <linux/sunrpc/svc.h>
15#include <linux/lockd/lockd.h> 15#include <linux/lockd/lockd.h>
16#include <linux/smp_lock.h> 16#include <linux/smp_lock.h>
17#include <linux/kthread.h>
17 18
18#define NLMDBG_FACILITY NLMDBG_CLIENT 19#define NLMDBG_FACILITY NLMDBG_CLIENT
19 20
@@ -60,7 +61,7 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init)
60 61
61 host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, 62 host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen,
62 nlm_init->protocol, nlm_version, 63 nlm_init->protocol, nlm_version,
63 nlm_init->hostname); 64 nlm_init->hostname, nlm_init->noresvport);
64 if (host == NULL) { 65 if (host == NULL) {
65 lockd_down(); 66 lockd_down();
66 return ERR_PTR(-ENOLCK); 67 return ERR_PTR(-ENOLCK);
@@ -191,11 +192,15 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock)
191void 192void
192nlmclnt_recovery(struct nlm_host *host) 193nlmclnt_recovery(struct nlm_host *host)
193{ 194{
195 struct task_struct *task;
196
194 if (!host->h_reclaiming++) { 197 if (!host->h_reclaiming++) {
195 nlm_get_host(host); 198 nlm_get_host(host);
196 __module_get(THIS_MODULE); 199 task = kthread_run(reclaimer, host, "%s-reclaim", host->h_name);
197 if (kernel_thread(reclaimer, host, CLONE_FS | CLONE_FILES) < 0) 200 if (IS_ERR(task))
198 module_put(THIS_MODULE); 201 printk(KERN_ERR "lockd: unable to spawn reclaimer "
202 "thread. Locks for %s won't be reclaimed! "
203 "(%ld)\n", host->h_name, PTR_ERR(task));
199 } 204 }
200} 205}
201 206
@@ -207,7 +212,6 @@ reclaimer(void *ptr)
207 struct file_lock *fl, *next; 212 struct file_lock *fl, *next;
208 u32 nsmstate; 213 u32 nsmstate;
209 214
210 daemonize("%s-reclaim", host->h_name);
211 allow_signal(SIGKILL); 215 allow_signal(SIGKILL);
212 216
213 down_write(&host->h_rwsem); 217 down_write(&host->h_rwsem);
@@ -233,7 +237,12 @@ restart:
233 list_for_each_entry_safe(fl, next, &host->h_reclaim, fl_u.nfs_fl.list) { 237 list_for_each_entry_safe(fl, next, &host->h_reclaim, fl_u.nfs_fl.list) {
234 list_del_init(&fl->fl_u.nfs_fl.list); 238 list_del_init(&fl->fl_u.nfs_fl.list);
235 239
236 /* Why are we leaking memory here? --okir */ 240 /*
241 * sending this thread a SIGKILL will result in any unreclaimed
242 * locks being removed from the h_granted list. This means that
243 * the kernel will not attempt to reclaim them again if a new
244 * reclaimer thread is spawned for this host.
245 */
237 if (signalled()) 246 if (signalled())
238 continue; 247 continue;
239 if (nlmclnt_reclaim(host, fl) != 0) 248 if (nlmclnt_reclaim(host, fl) != 0)
@@ -261,5 +270,5 @@ restart:
261 nlm_release_host(host); 270 nlm_release_host(host);
262 lockd_down(); 271 lockd_down();
263 unlock_kernel(); 272 unlock_kernel();
264 module_put_and_exit(0); 273 return 0;
265} 274}
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index e05d04416037..abdebf76b820 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -48,6 +48,7 @@ struct nlm_lookup_host_info {
48 const size_t hostname_len; /* it's length */ 48 const size_t hostname_len; /* it's length */
49 const struct sockaddr *src_sap; /* our address (optional) */ 49 const struct sockaddr *src_sap; /* our address (optional) */
50 const size_t src_len; /* it's length */ 50 const size_t src_len; /* it's length */
51 const int noresvport; /* use non-priv port */
51}; 52};
52 53
53/* 54/*
@@ -222,6 +223,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni)
222 host->h_nsmstate = 0; /* real NSM state */ 223 host->h_nsmstate = 0; /* real NSM state */
223 host->h_nsmhandle = nsm; 224 host->h_nsmhandle = nsm;
224 host->h_server = ni->server; 225 host->h_server = ni->server;
226 host->h_noresvport = ni->noresvport;
225 hlist_add_head(&host->h_hash, chain); 227 hlist_add_head(&host->h_hash, chain);
226 INIT_LIST_HEAD(&host->h_lockowners); 228 INIT_LIST_HEAD(&host->h_lockowners);
227 spin_lock_init(&host->h_lock); 229 spin_lock_init(&host->h_lock);
@@ -272,6 +274,7 @@ nlm_destroy_host(struct nlm_host *host)
272 * @protocol: transport protocol to use 274 * @protocol: transport protocol to use
273 * @version: NLM protocol version 275 * @version: NLM protocol version
274 * @hostname: '\0'-terminated hostname of server 276 * @hostname: '\0'-terminated hostname of server
277 * @noresvport: 1 if non-privileged port should be used
275 * 278 *
276 * Returns an nlm_host structure that matches the passed-in 279 * Returns an nlm_host structure that matches the passed-in
277 * [server address, transport protocol, NLM version, server hostname]. 280 * [server address, transport protocol, NLM version, server hostname].
@@ -281,7 +284,9 @@ nlm_destroy_host(struct nlm_host *host)
281struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, 284struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
282 const size_t salen, 285 const size_t salen,
283 const unsigned short protocol, 286 const unsigned short protocol,
284 const u32 version, const char *hostname) 287 const u32 version,
288 const char *hostname,
289 int noresvport)
285{ 290{
286 const struct sockaddr source = { 291 const struct sockaddr source = {
287 .sa_family = AF_UNSPEC, 292 .sa_family = AF_UNSPEC,
@@ -296,6 +301,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
296 .hostname_len = strlen(hostname), 301 .hostname_len = strlen(hostname),
297 .src_sap = &source, 302 .src_sap = &source,
298 .src_len = sizeof(source), 303 .src_len = sizeof(source),
304 .noresvport = noresvport,
299 }; 305 };
300 306
301 dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, 307 dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__,
@@ -417,6 +423,8 @@ nlm_bind_host(struct nlm_host *host)
417 */ 423 */
418 if (!host->h_server) 424 if (!host->h_server)
419 args.flags |= RPC_CLNT_CREATE_HARDRTRY; 425 args.flags |= RPC_CLNT_CREATE_HARDRTRY;
426 if (host->h_noresvport)
427 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
420 428
421 clnt = rpc_create(&args); 429 clnt = rpc_create(&args);
422 if (!IS_ERR(clnt)) 430 if (!IS_ERR(clnt))
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 56b076736b56..252d80163d02 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -45,7 +45,7 @@
45static struct svc_program nlmsvc_program; 45static struct svc_program nlmsvc_program;
46 46
47struct nlmsvc_binding * nlmsvc_ops; 47struct nlmsvc_binding * nlmsvc_ops;
48EXPORT_SYMBOL(nlmsvc_ops); 48EXPORT_SYMBOL_GPL(nlmsvc_ops);
49 49
50static DEFINE_MUTEX(nlmsvc_mutex); 50static DEFINE_MUTEX(nlmsvc_mutex);
51static unsigned int nlmsvc_users; 51static unsigned int nlmsvc_users;
@@ -300,7 +300,7 @@ out:
300 mutex_unlock(&nlmsvc_mutex); 300 mutex_unlock(&nlmsvc_mutex);
301 return error; 301 return error;
302} 302}
303EXPORT_SYMBOL(lockd_up); 303EXPORT_SYMBOL_GPL(lockd_up);
304 304
305/* 305/*
306 * Decrement the user count and bring down lockd if we're the last. 306 * Decrement the user count and bring down lockd if we're the last.
@@ -329,7 +329,7 @@ lockd_down(void)
329out: 329out:
330 mutex_unlock(&nlmsvc_mutex); 330 mutex_unlock(&nlmsvc_mutex);
331} 331}
332EXPORT_SYMBOL(lockd_down); 332EXPORT_SYMBOL_GPL(lockd_down);
333 333
334#ifdef CONFIG_SYSCTL 334#ifdef CONFIG_SYSCTL
335 335
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index c2e9cfd9e5a4..3e634f2a1083 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -16,6 +16,7 @@
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/freezer.h> 17#include <linux/freezer.h>
18#include <linux/kthread.h> 18#include <linux/kthread.h>
19#include <linux/sunrpc/svcauth_gss.h>
19 20
20#include <net/inet_sock.h> 21#include <net/inet_sock.h>
21 22
@@ -182,10 +183,34 @@ void nfs_callback_down(void)
182 mutex_unlock(&nfs_callback_mutex); 183 mutex_unlock(&nfs_callback_mutex);
183} 184}
184 185
186static int check_gss_callback_principal(struct nfs_client *clp,
187 struct svc_rqst *rqstp)
188{
189 struct rpc_clnt *r = clp->cl_rpcclient;
190 char *p = svc_gss_principal(rqstp);
191
192 /*
193 * It might just be a normal user principal, in which case
194 * userspace won't bother to tell us the name at all.
195 */
196 if (p == NULL)
197 return SVC_DENIED;
198
199 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */
200
201 if (memcmp(p, "nfs@", 4) != 0)
202 return SVC_DENIED;
203 p += 4;
204 if (strcmp(p, r->cl_server) != 0)
205 return SVC_DENIED;
206 return SVC_OK;
207}
208
185static int nfs_callback_authenticate(struct svc_rqst *rqstp) 209static int nfs_callback_authenticate(struct svc_rqst *rqstp)
186{ 210{
187 struct nfs_client *clp; 211 struct nfs_client *clp;
188 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); 212 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
213 int ret = SVC_OK;
189 214
190 /* Don't talk to strangers */ 215 /* Don't talk to strangers */
191 clp = nfs_find_client(svc_addr(rqstp), 4); 216 clp = nfs_find_client(svc_addr(rqstp), 4);
@@ -194,21 +219,22 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp)
194 219
195 dprintk("%s: %s NFSv4 callback!\n", __func__, 220 dprintk("%s: %s NFSv4 callback!\n", __func__,
196 svc_print_addr(rqstp, buf, sizeof(buf))); 221 svc_print_addr(rqstp, buf, sizeof(buf)));
197 nfs_put_client(clp);
198 222
199 switch (rqstp->rq_authop->flavour) { 223 switch (rqstp->rq_authop->flavour) {
200 case RPC_AUTH_NULL: 224 case RPC_AUTH_NULL:
201 if (rqstp->rq_proc != CB_NULL) 225 if (rqstp->rq_proc != CB_NULL)
202 return SVC_DENIED; 226 ret = SVC_DENIED;
203 break; 227 break;
204 case RPC_AUTH_UNIX: 228 case RPC_AUTH_UNIX:
205 break; 229 break;
206 case RPC_AUTH_GSS: 230 case RPC_AUTH_GSS:
207 /* FIXME: RPCSEC_GSS handling? */ 231 ret = check_gss_callback_principal(clp, rqstp);
232 break;
208 default: 233 default:
209 return SVC_DENIED; 234 ret = SVC_DENIED;
210 } 235 }
211 return SVC_OK; 236 nfs_put_client(clp);
237 return ret;
212} 238}
213 239
214/* 240/*
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 7547600b6174..9b728f3565a1 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -143,7 +143,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
143 clp->cl_proto = cl_init->proto; 143 clp->cl_proto = cl_init->proto;
144 144
145#ifdef CONFIG_NFS_V4 145#ifdef CONFIG_NFS_V4
146 init_rwsem(&clp->cl_sem);
147 INIT_LIST_HEAD(&clp->cl_delegations); 146 INIT_LIST_HEAD(&clp->cl_delegations);
148 spin_lock_init(&clp->cl_lock); 147 spin_lock_init(&clp->cl_lock);
149 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); 148 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
@@ -224,31 +223,54 @@ void nfs_put_client(struct nfs_client *clp)
224 } 223 }
225} 224}
226 225
227static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, 226#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
228 const struct sockaddr_in *sa2) 227static const struct in6_addr *nfs_map_ipv4_addr(const struct sockaddr *sa, struct in6_addr *addr_mapped)
229{ 228{
230 return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr; 229 switch (sa->sa_family) {
230 default:
231 return NULL;
232 case AF_INET6:
233 return &((const struct sockaddr_in6 *)sa)->sin6_addr;
234 break;
235 case AF_INET:
236 ipv6_addr_set_v4mapped(((const struct sockaddr_in *)sa)->sin_addr.s_addr,
237 addr_mapped);
238 return addr_mapped;
239 }
231} 240}
232 241
233static int nfs_sockaddr_match_ipaddr6(const struct sockaddr_in6 *sa1, 242static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
234 const struct sockaddr_in6 *sa2) 243 const struct sockaddr *sa2)
244{
245 const struct in6_addr *addr1;
246 const struct in6_addr *addr2;
247 struct in6_addr addr1_mapped;
248 struct in6_addr addr2_mapped;
249
250 addr1 = nfs_map_ipv4_addr(sa1, &addr1_mapped);
251 if (likely(addr1 != NULL)) {
252 addr2 = nfs_map_ipv4_addr(sa2, &addr2_mapped);
253 if (likely(addr2 != NULL))
254 return ipv6_addr_equal(addr1, addr2);
255 }
256 return 0;
257}
258#else
259static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1,
260 const struct sockaddr_in *sa2)
235{ 261{
236 return ipv6_addr_equal(&sa1->sin6_addr, &sa2->sin6_addr); 262 return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr;
237} 263}
238 264
239static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, 265static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
240 const struct sockaddr *sa2) 266 const struct sockaddr *sa2)
241{ 267{
242 switch (sa1->sa_family) { 268 if (unlikely(sa1->sa_family != AF_INET || sa2->sa_family != AF_INET))
243 case AF_INET: 269 return 0;
244 return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, 270 return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1,
245 (const struct sockaddr_in *)sa2); 271 (const struct sockaddr_in *)sa2);
246 case AF_INET6:
247 return nfs_sockaddr_match_ipaddr6((const struct sockaddr_in6 *)sa1,
248 (const struct sockaddr_in6 *)sa2);
249 }
250 BUG();
251} 272}
273#endif
252 274
253/* 275/*
254 * Find a client by IP address and protocol version 276 * Find a client by IP address and protocol version
@@ -270,8 +292,6 @@ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
270 if (clp->rpc_ops->version != nfsversion) 292 if (clp->rpc_ops->version != nfsversion)
271 continue; 293 continue;
272 294
273 if (addr->sa_family != clap->sa_family)
274 continue;
275 /* Match only the IP address, not the port number */ 295 /* Match only the IP address, not the port number */
276 if (!nfs_sockaddr_match_ipaddr(addr, clap)) 296 if (!nfs_sockaddr_match_ipaddr(addr, clap))
277 continue; 297 continue;
@@ -305,8 +325,6 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp)
305 if (clp->rpc_ops->version != nfsvers) 325 if (clp->rpc_ops->version != nfsvers)
306 continue; 326 continue;
307 327
308 if (sap->sa_family != clap->sa_family)
309 continue;
310 /* Match only the IP address, not the port number */ 328 /* Match only the IP address, not the port number */
311 if (!nfs_sockaddr_match_ipaddr(sap, clap)) 329 if (!nfs_sockaddr_match_ipaddr(sap, clap))
312 continue; 330 continue;
@@ -470,7 +488,7 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
470static int nfs_create_rpc_client(struct nfs_client *clp, 488static int nfs_create_rpc_client(struct nfs_client *clp,
471 const struct rpc_timeout *timeparms, 489 const struct rpc_timeout *timeparms,
472 rpc_authflavor_t flavor, 490 rpc_authflavor_t flavor,
473 int flags) 491 int discrtry, int noresvport)
474{ 492{
475 struct rpc_clnt *clnt = NULL; 493 struct rpc_clnt *clnt = NULL;
476 struct rpc_create_args args = { 494 struct rpc_create_args args = {
@@ -482,9 +500,13 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
482 .program = &nfs_program, 500 .program = &nfs_program,
483 .version = clp->rpc_ops->version, 501 .version = clp->rpc_ops->version,
484 .authflavor = flavor, 502 .authflavor = flavor,
485 .flags = flags,
486 }; 503 };
487 504
505 if (discrtry)
506 args.flags |= RPC_CLNT_CREATE_DISCRTRY;
507 if (noresvport)
508 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
509
488 if (!IS_ERR(clp->cl_rpcclient)) 510 if (!IS_ERR(clp->cl_rpcclient))
489 return 0; 511 return 0;
490 512
@@ -522,6 +544,8 @@ static int nfs_start_lockd(struct nfs_server *server)
522 .protocol = server->flags & NFS_MOUNT_TCP ? 544 .protocol = server->flags & NFS_MOUNT_TCP ?
523 IPPROTO_TCP : IPPROTO_UDP, 545 IPPROTO_TCP : IPPROTO_UDP,
524 .nfs_version = clp->rpc_ops->version, 546 .nfs_version = clp->rpc_ops->version,
547 .noresvport = server->flags & NFS_MOUNT_NORESVPORT ?
548 1 : 0,
525 }; 549 };
526 550
527 if (nlm_init.nfs_version > 3) 551 if (nlm_init.nfs_version > 3)
@@ -623,7 +647,8 @@ static int nfs_init_client(struct nfs_client *clp,
623 * Create a client RPC handle for doing FSSTAT with UNIX auth only 647 * Create a client RPC handle for doing FSSTAT with UNIX auth only
624 * - RFC 2623, sec 2.3.2 648 * - RFC 2623, sec 2.3.2
625 */ 649 */
626 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 0); 650 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX,
651 0, data->flags & NFS_MOUNT_NORESVPORT);
627 if (error < 0) 652 if (error < 0)
628 goto error; 653 goto error;
629 nfs_mark_client_ready(clp, NFS_CS_READY); 654 nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -965,7 +990,8 @@ error:
965static int nfs4_init_client(struct nfs_client *clp, 990static int nfs4_init_client(struct nfs_client *clp,
966 const struct rpc_timeout *timeparms, 991 const struct rpc_timeout *timeparms,
967 const char *ip_addr, 992 const char *ip_addr,
968 rpc_authflavor_t authflavour) 993 rpc_authflavor_t authflavour,
994 int flags)
969{ 995{
970 int error; 996 int error;
971 997
@@ -979,7 +1005,7 @@ static int nfs4_init_client(struct nfs_client *clp,
979 clp->rpc_ops = &nfs_v4_clientops; 1005 clp->rpc_ops = &nfs_v4_clientops;
980 1006
981 error = nfs_create_rpc_client(clp, timeparms, authflavour, 1007 error = nfs_create_rpc_client(clp, timeparms, authflavour,
982 RPC_CLNT_CREATE_DISCRTRY); 1008 1, flags & NFS_MOUNT_NORESVPORT);
983 if (error < 0) 1009 if (error < 0)
984 goto error; 1010 goto error;
985 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); 1011 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
@@ -1030,7 +1056,8 @@ static int nfs4_set_client(struct nfs_server *server,
1030 error = PTR_ERR(clp); 1056 error = PTR_ERR(clp);
1031 goto error; 1057 goto error;
1032 } 1058 }
1033 error = nfs4_init_client(clp, timeparms, ip_addr, authflavour); 1059 error = nfs4_init_client(clp, timeparms, ip_addr, authflavour,
1060 server->flags);
1034 if (error < 0) 1061 if (error < 0)
1035 goto error_put; 1062 goto error_put;
1036 1063
@@ -1059,6 +1086,10 @@ static int nfs4_init_server(struct nfs_server *server,
1059 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, 1086 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
1060 data->timeo, data->retrans); 1087 data->timeo, data->retrans);
1061 1088
1089 /* Initialise the client representation from the mount data */
1090 server->flags = data->flags;
1091 server->caps |= NFS_CAP_ATOMIC_OPEN;
1092
1062 /* Get a client record */ 1093 /* Get a client record */
1063 error = nfs4_set_client(server, 1094 error = nfs4_set_client(server,
1064 data->nfs_server.hostname, 1095 data->nfs_server.hostname,
@@ -1071,10 +1102,6 @@ static int nfs4_init_server(struct nfs_server *server,
1071 if (error < 0) 1102 if (error < 0)
1072 goto error; 1103 goto error;
1073 1104
1074 /* Initialise the client representation from the mount data */
1075 server->flags = data->flags;
1076 server->caps |= NFS_CAP_ATOMIC_OPEN;
1077
1078 if (data->rsize) 1105 if (data->rsize)
1079 server->rsize = nfs_block_size(data->rsize, NULL); 1106 server->rsize = nfs_block_size(data->rsize, NULL);
1080 if (data->wsize) 1107 if (data->wsize)
@@ -1177,6 +1204,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1177 parent_server = NFS_SB(data->sb); 1204 parent_server = NFS_SB(data->sb);
1178 parent_client = parent_server->nfs_client; 1205 parent_client = parent_server->nfs_client;
1179 1206
1207 /* Initialise the client representation from the parent server */
1208 nfs_server_copy_userdata(server, parent_server);
1209 server->caps |= NFS_CAP_ATOMIC_OPEN;
1210
1180 /* Get a client representation. 1211 /* Get a client representation.
1181 * Note: NFSv4 always uses TCP, */ 1212 * Note: NFSv4 always uses TCP, */
1182 error = nfs4_set_client(server, data->hostname, 1213 error = nfs4_set_client(server, data->hostname,
@@ -1189,10 +1220,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1189 if (error < 0) 1220 if (error < 0)
1190 goto error; 1221 goto error;
1191 1222
1192 /* Initialise the client representation from the parent server */
1193 nfs_server_copy_userdata(server, parent_server);
1194 server->caps |= NFS_CAP_ATOMIC_OPEN;
1195
1196 error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor); 1223 error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor);
1197 if (error < 0) 1224 if (error < 0)
1198 goto error; 1225 goto error;
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index cc563cfa6940..968225a88015 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -43,6 +43,27 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
43 put_rpccred(cred); 43 put_rpccred(cred);
44} 44}
45 45
46void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
47{
48 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
49}
50
51int nfs_have_delegation(struct inode *inode, fmode_t flags)
52{
53 struct nfs_delegation *delegation;
54 int ret = 0;
55
56 flags &= FMODE_READ|FMODE_WRITE;
57 rcu_read_lock();
58 delegation = rcu_dereference(NFS_I(inode)->delegation);
59 if (delegation != NULL && (delegation->type & flags) == flags) {
60 nfs_mark_delegation_referenced(delegation);
61 ret = 1;
62 }
63 rcu_read_unlock();
64 return ret;
65}
66
46static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) 67static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
47{ 68{
48 struct inode *inode = state->inode; 69 struct inode *inode = state->inode;
@@ -119,7 +140,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st
119 delegation->maxsize = res->maxsize; 140 delegation->maxsize = res->maxsize;
120 oldcred = delegation->cred; 141 oldcred = delegation->cred;
121 delegation->cred = get_rpccred(cred); 142 delegation->cred = get_rpccred(cred);
122 delegation->flags &= ~NFS_DELEGATION_NEED_RECLAIM; 143 clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
123 NFS_I(inode)->delegation_state = delegation->type; 144 NFS_I(inode)->delegation_state = delegation->type;
124 smp_wmb(); 145 smp_wmb();
125 put_rpccred(oldcred); 146 put_rpccred(oldcred);
@@ -134,19 +155,35 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
134 return res; 155 return res;
135} 156}
136 157
158static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
159{
160 struct inode *inode = NULL;
161
162 spin_lock(&delegation->lock);
163 if (delegation->inode != NULL)
164 inode = igrab(delegation->inode);
165 spin_unlock(&delegation->lock);
166 return inode;
167}
168
137static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid) 169static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid)
138{ 170{
139 struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation); 171 struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
140 172
141 if (delegation == NULL) 173 if (delegation == NULL)
142 goto nomatch; 174 goto nomatch;
175 spin_lock(&delegation->lock);
143 if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data, 176 if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data,
144 sizeof(delegation->stateid.data)) != 0) 177 sizeof(delegation->stateid.data)) != 0)
145 goto nomatch; 178 goto nomatch_unlock;
146 list_del_rcu(&delegation->super_list); 179 list_del_rcu(&delegation->super_list);
180 delegation->inode = NULL;
147 nfsi->delegation_state = 0; 181 nfsi->delegation_state = 0;
148 rcu_assign_pointer(nfsi->delegation, NULL); 182 rcu_assign_pointer(nfsi->delegation, NULL);
183 spin_unlock(&delegation->lock);
149 return delegation; 184 return delegation;
185nomatch_unlock:
186 spin_unlock(&delegation->lock);
150nomatch: 187nomatch:
151 return NULL; 188 return NULL;
152} 189}
@@ -172,6 +209,8 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
172 delegation->change_attr = nfsi->change_attr; 209 delegation->change_attr = nfsi->change_attr;
173 delegation->cred = get_rpccred(cred); 210 delegation->cred = get_rpccred(cred);
174 delegation->inode = inode; 211 delegation->inode = inode;
212 delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
213 spin_lock_init(&delegation->lock);
175 214
176 spin_lock(&clp->cl_lock); 215 spin_lock(&clp->cl_lock);
177 if (rcu_dereference(nfsi->delegation) != NULL) { 216 if (rcu_dereference(nfsi->delegation) != NULL) {
@@ -226,22 +265,47 @@ static void nfs_msync_inode(struct inode *inode)
226 */ 265 */
227static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation) 266static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation)
228{ 267{
229 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
230 struct nfs_inode *nfsi = NFS_I(inode); 268 struct nfs_inode *nfsi = NFS_I(inode);
231 269
232 nfs_msync_inode(inode); 270 nfs_msync_inode(inode);
233 down_read(&clp->cl_sem);
234 /* Guard against new delegated open calls */ 271 /* Guard against new delegated open calls */
235 down_write(&nfsi->rwsem); 272 down_write(&nfsi->rwsem);
236 nfs_delegation_claim_opens(inode, &delegation->stateid); 273 nfs_delegation_claim_opens(inode, &delegation->stateid);
237 up_write(&nfsi->rwsem); 274 up_write(&nfsi->rwsem);
238 up_read(&clp->cl_sem);
239 nfs_msync_inode(inode); 275 nfs_msync_inode(inode);
240 276
241 return nfs_do_return_delegation(inode, delegation, 1); 277 return nfs_do_return_delegation(inode, delegation, 1);
242} 278}
243 279
244/* 280/*
281 * Return all delegations that have been marked for return
282 */
283void nfs_client_return_marked_delegations(struct nfs_client *clp)
284{
285 struct nfs_delegation *delegation;
286 struct inode *inode;
287
288restart:
289 rcu_read_lock();
290 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
291 if (!test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
292 continue;
293 inode = nfs_delegation_grab_inode(delegation);
294 if (inode == NULL)
295 continue;
296 spin_lock(&clp->cl_lock);
297 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
298 spin_unlock(&clp->cl_lock);
299 rcu_read_unlock();
300 if (delegation != NULL)
301 __nfs_inode_return_delegation(inode, delegation);
302 iput(inode);
303 goto restart;
304 }
305 rcu_read_unlock();
306}
307
308/*
245 * This function returns the delegation without reclaiming opens 309 * This function returns the delegation without reclaiming opens
246 * or protecting against delegation reclaims. 310 * or protecting against delegation reclaims.
247 * It is therefore really only safe to be called from 311 * It is therefore really only safe to be called from
@@ -279,83 +343,55 @@ int nfs_inode_return_delegation(struct inode *inode)
279 return err; 343 return err;
280} 344}
281 345
346static void nfs_mark_return_delegation(struct nfs_client *clp, struct nfs_delegation *delegation)
347{
348 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
349 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
350}
351
282/* 352/*
283 * Return all delegations associated to a super block 353 * Return all delegations associated to a super block
284 */ 354 */
285void nfs_return_all_delegations(struct super_block *sb) 355void nfs_super_return_all_delegations(struct super_block *sb)
286{ 356{
287 struct nfs_client *clp = NFS_SB(sb)->nfs_client; 357 struct nfs_client *clp = NFS_SB(sb)->nfs_client;
288 struct nfs_delegation *delegation; 358 struct nfs_delegation *delegation;
289 struct inode *inode;
290 359
291 if (clp == NULL) 360 if (clp == NULL)
292 return; 361 return;
293restart:
294 rcu_read_lock(); 362 rcu_read_lock();
295 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 363 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
296 if (delegation->inode->i_sb != sb) 364 spin_lock(&delegation->lock);
297 continue; 365 if (delegation->inode != NULL && delegation->inode->i_sb == sb)
298 inode = igrab(delegation->inode); 366 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
299 if (inode == NULL) 367 spin_unlock(&delegation->lock);
300 continue;
301 spin_lock(&clp->cl_lock);
302 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
303 spin_unlock(&clp->cl_lock);
304 rcu_read_unlock();
305 if (delegation != NULL)
306 __nfs_inode_return_delegation(inode, delegation);
307 iput(inode);
308 goto restart;
309 } 368 }
310 rcu_read_unlock(); 369 rcu_read_unlock();
370 nfs_client_return_marked_delegations(clp);
311} 371}
312 372
313static int nfs_do_expire_all_delegations(void *ptr) 373static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
314{ 374{
315 struct nfs_client *clp = ptr;
316 struct nfs_delegation *delegation; 375 struct nfs_delegation *delegation;
317 struct inode *inode;
318 376
319 allow_signal(SIGKILL);
320restart:
321 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
322 goto out;
323 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
324 goto out;
325 rcu_read_lock(); 377 rcu_read_lock();
326 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 378 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
327 inode = igrab(delegation->inode); 379 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
328 if (inode == NULL) 380 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
329 continue;
330 spin_lock(&clp->cl_lock);
331 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
332 spin_unlock(&clp->cl_lock);
333 rcu_read_unlock();
334 if (delegation)
335 __nfs_inode_return_delegation(inode, delegation);
336 iput(inode);
337 goto restart;
338 } 381 }
339 rcu_read_unlock(); 382 rcu_read_unlock();
340out: 383}
341 nfs_put_client(clp); 384
342 module_put_and_exit(0); 385static void nfs_delegation_run_state_manager(struct nfs_client *clp)
386{
387 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
388 nfs4_schedule_state_manager(clp);
343} 389}
344 390
345void nfs_expire_all_delegations(struct nfs_client *clp) 391void nfs_expire_all_delegations(struct nfs_client *clp)
346{ 392{
347 struct task_struct *task; 393 nfs_client_mark_return_all_delegations(clp);
348 394 nfs_delegation_run_state_manager(clp);
349 __module_get(THIS_MODULE);
350 atomic_inc(&clp->cl_count);
351 task = kthread_run(nfs_do_expire_all_delegations, clp,
352 "%s-delegreturn",
353 rpc_peeraddr2str(clp->cl_rpcclient,
354 RPC_DISPLAY_ADDR));
355 if (!IS_ERR(task))
356 return;
357 nfs_put_client(clp);
358 module_put(THIS_MODULE);
359} 395}
360 396
361/* 397/*
@@ -363,68 +399,29 @@ void nfs_expire_all_delegations(struct nfs_client *clp)
363 */ 399 */
364void nfs_handle_cb_pathdown(struct nfs_client *clp) 400void nfs_handle_cb_pathdown(struct nfs_client *clp)
365{ 401{
366 struct nfs_delegation *delegation;
367 struct inode *inode;
368
369 if (clp == NULL) 402 if (clp == NULL)
370 return; 403 return;
371restart: 404 nfs_client_mark_return_all_delegations(clp);
405}
406
407static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *clp)
408{
409 struct nfs_delegation *delegation;
410
372 rcu_read_lock(); 411 rcu_read_lock();
373 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 412 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
374 inode = igrab(delegation->inode); 413 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
375 if (inode == NULL)
376 continue; 414 continue;
377 spin_lock(&clp->cl_lock); 415 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
378 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL); 416 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
379 spin_unlock(&clp->cl_lock);
380 rcu_read_unlock();
381 if (delegation != NULL)
382 __nfs_inode_return_delegation(inode, delegation);
383 iput(inode);
384 goto restart;
385 } 417 }
386 rcu_read_unlock(); 418 rcu_read_unlock();
387} 419}
388 420
389struct recall_threadargs { 421void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
390 struct inode *inode;
391 struct nfs_client *clp;
392 const nfs4_stateid *stateid;
393
394 struct completion started;
395 int result;
396};
397
398static int recall_thread(void *data)
399{ 422{
400 struct recall_threadargs *args = (struct recall_threadargs *)data; 423 nfs_client_mark_return_unreferenced_delegations(clp);
401 struct inode *inode = igrab(args->inode); 424 nfs_delegation_run_state_manager(clp);
402 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
403 struct nfs_inode *nfsi = NFS_I(inode);
404 struct nfs_delegation *delegation;
405
406 daemonize("nfsv4-delegreturn");
407
408 nfs_msync_inode(inode);
409 down_read(&clp->cl_sem);
410 down_write(&nfsi->rwsem);
411 spin_lock(&clp->cl_lock);
412 delegation = nfs_detach_delegation_locked(nfsi, args->stateid);
413 if (delegation != NULL)
414 args->result = 0;
415 else
416 args->result = -ENOENT;
417 spin_unlock(&clp->cl_lock);
418 complete(&args->started);
419 nfs_delegation_claim_opens(inode, args->stateid);
420 up_write(&nfsi->rwsem);
421 up_read(&clp->cl_sem);
422 nfs_msync_inode(inode);
423
424 if (delegation != NULL)
425 nfs_do_return_delegation(inode, delegation, 1);
426 iput(inode);
427 module_put_and_exit(0);
428} 425}
429 426
430/* 427/*
@@ -432,22 +429,20 @@ static int recall_thread(void *data)
432 */ 429 */
433int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid) 430int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid)
434{ 431{
435 struct recall_threadargs data = { 432 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
436 .inode = inode, 433 struct nfs_delegation *delegation;
437 .stateid = stateid,
438 };
439 int status;
440 434
441 init_completion(&data.started); 435 rcu_read_lock();
442 __module_get(THIS_MODULE); 436 delegation = rcu_dereference(NFS_I(inode)->delegation);
443 status = kernel_thread(recall_thread, &data, CLONE_KERNEL); 437 if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data,
444 if (status < 0) 438 sizeof(delegation->stateid.data)) != 0) {
445 goto out_module_put; 439 rcu_read_unlock();
446 wait_for_completion(&data.started); 440 return -ENOENT;
447 return data.result; 441 }
448out_module_put: 442 nfs_mark_return_delegation(clp, delegation);
449 module_put(THIS_MODULE); 443 rcu_read_unlock();
450 return status; 444 nfs_delegation_run_state_manager(clp);
445 return 0;
451} 446}
452 447
453/* 448/*
@@ -459,10 +454,14 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
459 struct inode *res = NULL; 454 struct inode *res = NULL;
460 rcu_read_lock(); 455 rcu_read_lock();
461 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 456 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
462 if (nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { 457 spin_lock(&delegation->lock);
458 if (delegation->inode != NULL &&
459 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
463 res = igrab(delegation->inode); 460 res = igrab(delegation->inode);
464 break;
465 } 461 }
462 spin_unlock(&delegation->lock);
463 if (res != NULL)
464 break;
466 } 465 }
467 rcu_read_unlock(); 466 rcu_read_unlock();
468 return res; 467 return res;
@@ -476,7 +475,7 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp)
476 struct nfs_delegation *delegation; 475 struct nfs_delegation *delegation;
477 rcu_read_lock(); 476 rcu_read_lock();
478 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) 477 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list)
479 delegation->flags |= NFS_DELEGATION_NEED_RECLAIM; 478 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
480 rcu_read_unlock(); 479 rcu_read_unlock();
481} 480}
482 481
@@ -486,17 +485,22 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp)
486void nfs_delegation_reap_unclaimed(struct nfs_client *clp) 485void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
487{ 486{
488 struct nfs_delegation *delegation; 487 struct nfs_delegation *delegation;
488 struct inode *inode;
489restart: 489restart:
490 rcu_read_lock(); 490 rcu_read_lock();
491 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 491 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
492 if ((delegation->flags & NFS_DELEGATION_NEED_RECLAIM) == 0) 492 if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0)
493 continue;
494 inode = nfs_delegation_grab_inode(delegation);
495 if (inode == NULL)
493 continue; 496 continue;
494 spin_lock(&clp->cl_lock); 497 spin_lock(&clp->cl_lock);
495 delegation = nfs_detach_delegation_locked(NFS_I(delegation->inode), NULL); 498 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
496 spin_unlock(&clp->cl_lock); 499 spin_unlock(&clp->cl_lock);
497 rcu_read_unlock(); 500 rcu_read_unlock();
498 if (delegation != NULL) 501 if (delegation != NULL)
499 nfs_free_delegation(delegation); 502 nfs_free_delegation(delegation);
503 iput(inode);
500 goto restart; 504 goto restart;
501 } 505 }
502 rcu_read_unlock(); 506 rcu_read_unlock();
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index f1c5e2a5d88e..09f383795174 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -17,14 +17,20 @@ struct nfs_delegation {
17 struct rpc_cred *cred; 17 struct rpc_cred *cred;
18 struct inode *inode; 18 struct inode *inode;
19 nfs4_stateid stateid; 19 nfs4_stateid stateid;
20 int type; 20 fmode_t type;
21#define NFS_DELEGATION_NEED_RECLAIM 1
22 long flags;
23 loff_t maxsize; 21 loff_t maxsize;
24 __u64 change_attr; 22 __u64 change_attr;
23 unsigned long flags;
24 spinlock_t lock;
25 struct rcu_head rcu; 25 struct rcu_head rcu;
26}; 26};
27 27
28enum {
29 NFS_DELEGATION_NEED_RECLAIM = 0,
30 NFS_DELEGATION_RETURN,
31 NFS_DELEGATION_REFERENCED,
32};
33
28int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); 34int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
29void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); 35void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
30int nfs_inode_return_delegation(struct inode *inode); 36int nfs_inode_return_delegation(struct inode *inode);
@@ -32,9 +38,11 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s
32void nfs_inode_return_delegation_noreclaim(struct inode *inode); 38void nfs_inode_return_delegation_noreclaim(struct inode *inode);
33 39
34struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); 40struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
35void nfs_return_all_delegations(struct super_block *sb); 41void nfs_super_return_all_delegations(struct super_block *sb);
36void nfs_expire_all_delegations(struct nfs_client *clp); 42void nfs_expire_all_delegations(struct nfs_client *clp);
43void nfs_expire_unreferenced_delegations(struct nfs_client *clp);
37void nfs_handle_cb_pathdown(struct nfs_client *clp); 44void nfs_handle_cb_pathdown(struct nfs_client *clp);
45void nfs_client_return_marked_delegations(struct nfs_client *clp);
38 46
39void nfs_delegation_mark_reclaim(struct nfs_client *clp); 47void nfs_delegation_mark_reclaim(struct nfs_client *clp);
40void nfs_delegation_reap_unclaimed(struct nfs_client *clp); 48void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
@@ -45,22 +53,11 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
45int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl); 53int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
46int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode); 54int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
47 55
48static inline int nfs_have_delegation(struct inode *inode, int flags) 56void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
49{ 57int nfs_have_delegation(struct inode *inode, fmode_t flags);
50 struct nfs_delegation *delegation;
51 int ret = 0;
52
53 flags &= FMODE_READ|FMODE_WRITE;
54 rcu_read_lock();
55 delegation = rcu_dereference(NFS_I(inode)->delegation);
56 if (delegation != NULL && (delegation->type & flags) == flags)
57 ret = 1;
58 rcu_read_unlock();
59 return ret;
60}
61 58
62#else 59#else
63static inline int nfs_have_delegation(struct inode *inode, int flags) 60static inline int nfs_have_delegation(struct inode *inode, fmode_t flags)
64{ 61{
65 return 0; 62 return 0;
66} 63}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 3e64b98f3a93..e35c8199f82f 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -799,6 +799,9 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
799 goto out_bad; 799 goto out_bad;
800 } 800 }
801 801
802 if (nfs_have_delegation(inode, FMODE_READ))
803 goto out_set_verifier;
804
802 /* Force a full look up iff the parent directory has changed */ 805 /* Force a full look up iff the parent directory has changed */
803 if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) { 806 if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) {
804 if (nfs_lookup_verify_inode(inode, nd)) 807 if (nfs_lookup_verify_inode(inode, nd))
@@ -817,6 +820,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
817 if ((error = nfs_refresh_inode(inode, &fattr)) != 0) 820 if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
818 goto out_bad; 821 goto out_bad;
819 822
823out_set_verifier:
820 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 824 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
821 out_valid: 825 out_valid:
822 dput(parent); 826 dput(parent);
@@ -973,7 +977,7 @@ struct dentry_operations nfs4_dentry_operations = {
973 * Use intent information to determine whether we need to substitute 977 * Use intent information to determine whether we need to substitute
974 * the NFSv4-style stateful OPEN for the LOOKUP call 978 * the NFSv4-style stateful OPEN for the LOOKUP call
975 */ 979 */
976static int is_atomic_open(struct inode *dir, struct nameidata *nd) 980static int is_atomic_open(struct nameidata *nd)
977{ 981{
978 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) 982 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
979 return 0; 983 return 0;
@@ -996,7 +1000,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
996 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1000 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
997 1001
998 /* Check that we are indeed trying to open this file */ 1002 /* Check that we are indeed trying to open this file */
999 if (!is_atomic_open(dir, nd)) 1003 if (!is_atomic_open(nd))
1000 goto no_open; 1004 goto no_open;
1001 1005
1002 if (dentry->d_name.len > NFS_SERVER(dir)->namelen) { 1006 if (dentry->d_name.len > NFS_SERVER(dir)->namelen) {
@@ -1047,10 +1051,10 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1047 struct inode *dir; 1051 struct inode *dir;
1048 int openflags, ret = 0; 1052 int openflags, ret = 0;
1049 1053
1054 if (!is_atomic_open(nd))
1055 goto no_open;
1050 parent = dget_parent(dentry); 1056 parent = dget_parent(dentry);
1051 dir = parent->d_inode; 1057 dir = parent->d_inode;
1052 if (!is_atomic_open(dir, nd))
1053 goto no_open;
1054 /* We can't create new files in nfs_open_revalidate(), so we 1058 /* We can't create new files in nfs_open_revalidate(), so we
1055 * optimize away revalidation of negative dentries. 1059 * optimize away revalidation of negative dentries.
1056 */ 1060 */
@@ -1062,11 +1066,11 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1062 1066
1063 /* NFS only supports OPEN on regular files */ 1067 /* NFS only supports OPEN on regular files */
1064 if (!S_ISREG(inode->i_mode)) 1068 if (!S_ISREG(inode->i_mode))
1065 goto no_open; 1069 goto no_open_dput;
1066 openflags = nd->intent.open.flags; 1070 openflags = nd->intent.open.flags;
1067 /* We cannot do exclusive creation on a positive dentry */ 1071 /* We cannot do exclusive creation on a positive dentry */
1068 if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) 1072 if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
1069 goto no_open; 1073 goto no_open_dput;
1070 /* We can't create new files, or truncate existing ones here */ 1074 /* We can't create new files, or truncate existing ones here */
1071 openflags &= ~(O_CREAT|O_TRUNC); 1075 openflags &= ~(O_CREAT|O_TRUNC);
1072 1076
@@ -1081,10 +1085,9 @@ out:
1081 if (!ret) 1085 if (!ret)
1082 d_drop(dentry); 1086 d_drop(dentry);
1083 return ret; 1087 return ret;
1084no_open: 1088no_open_dput:
1085 dput(parent); 1089 dput(parent);
1086 if (inode != NULL && nfs_have_delegation(inode, FMODE_READ)) 1090no_open:
1087 return 1;
1088 return nfs_lookup_revalidate(dentry, nd); 1091 return nfs_lookup_revalidate(dentry, nd);
1089} 1092}
1090#endif /* CONFIG_NFSV4 */ 1093#endif /* CONFIG_NFSV4 */
@@ -1794,7 +1797,8 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
1794 cache = nfs_access_search_rbtree(inode, cred); 1797 cache = nfs_access_search_rbtree(inode, cred);
1795 if (cache == NULL) 1798 if (cache == NULL)
1796 goto out; 1799 goto out;
1797 if (!time_in_range(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo)) 1800 if (!nfs_have_delegation(inode, FMODE_READ) &&
1801 !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
1798 goto out_stale; 1802 goto out_stale;
1799 res->jiffies = cache->jiffies; 1803 res->jiffies = cache->jiffies;
1800 res->cred = cache->cred; 1804 res->cred = cache->cred;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index d22eb383e1cf..0c381686171e 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -592,7 +592,7 @@ static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context
592/* 592/*
593 * Given an inode, search for an open context with the desired characteristics 593 * Given an inode, search for an open context with the desired characteristics
594 */ 594 */
595struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode) 595struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode)
596{ 596{
597 struct nfs_inode *nfsi = NFS_I(inode); 597 struct nfs_inode *nfsi = NFS_I(inode);
598 struct nfs_open_context *pos, *ctx = NULL; 598 struct nfs_open_context *pos, *ctx = NULL;
@@ -712,14 +712,7 @@ int nfs_attribute_timeout(struct inode *inode)
712 712
713 if (nfs_have_delegation(inode, FMODE_READ)) 713 if (nfs_have_delegation(inode, FMODE_READ))
714 return 0; 714 return 0;
715 /* 715 return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
716 * Special case: if the attribute timeout is set to 0, then always
717 * treat the cache as having expired (unless holding
718 * a delegation).
719 */
720 if (nfsi->attrtimeo == 0)
721 return 1;
722 return !time_in_range(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
723} 716}
724 717
725/** 718/**
@@ -1182,7 +1175,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1182 nfsi->attrtimeo_timestamp = now; 1175 nfsi->attrtimeo_timestamp = now;
1183 nfsi->attr_gencount = nfs_inc_attr_generation_counter(); 1176 nfsi->attr_gencount = nfs_inc_attr_generation_counter();
1184 } else { 1177 } else {
1185 if (!time_in_range(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) { 1178 if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
1186 if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode)) 1179 if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
1187 nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode); 1180 nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
1188 nfsi->attrtimeo_timestamp = now; 1181 nfsi->attrtimeo_timestamp = now;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index d212ee41caf2..340ede8f608f 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -63,6 +63,20 @@ struct nfs_parsed_mount_data {
63 struct security_mnt_opts lsm_opts; 63 struct security_mnt_opts lsm_opts;
64}; 64};
65 65
66/* mount_clnt.c */
67struct nfs_mount_request {
68 struct sockaddr *sap;
69 size_t salen;
70 char *hostname;
71 char *dirpath;
72 u32 version;
73 unsigned short protocol;
74 struct nfs_fh *fh;
75 int noresvport;
76};
77
78extern int nfs_mount(struct nfs_mount_request *info);
79
66/* client.c */ 80/* client.c */
67extern struct rpc_program nfs_program; 81extern struct rpc_program nfs_program;
68 82
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 086a6830d785..ca905a5bb1ba 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -29,47 +29,43 @@ struct mnt_fhstatus {
29 29
30/** 30/**
31 * nfs_mount - Obtain an NFS file handle for the given host and path 31 * nfs_mount - Obtain an NFS file handle for the given host and path
32 * @addr: pointer to server's address 32 * @info: pointer to mount request arguments
33 * @len: size of server's address
34 * @hostname: name of server host, or NULL
35 * @path: pointer to string containing export path to mount
36 * @version: mount version to use for this request
37 * @protocol: transport protocol to use for thie request
38 * @fh: pointer to location to place returned file handle
39 * 33 *
40 * Uses default timeout parameters specified by underlying transport. 34 * Uses default timeout parameters specified by underlying transport.
41 */ 35 */
42int nfs_mount(struct sockaddr *addr, size_t len, char *hostname, char *path, 36int nfs_mount(struct nfs_mount_request *info)
43 int version, int protocol, struct nfs_fh *fh)
44{ 37{
45 struct mnt_fhstatus result = { 38 struct mnt_fhstatus result = {
46 .fh = fh 39 .fh = info->fh
47 }; 40 };
48 struct rpc_message msg = { 41 struct rpc_message msg = {
49 .rpc_argp = path, 42 .rpc_argp = info->dirpath,
50 .rpc_resp = &result, 43 .rpc_resp = &result,
51 }; 44 };
52 struct rpc_create_args args = { 45 struct rpc_create_args args = {
53 .protocol = protocol, 46 .protocol = info->protocol,
54 .address = addr, 47 .address = info->sap,
55 .addrsize = len, 48 .addrsize = info->salen,
56 .servername = hostname, 49 .servername = info->hostname,
57 .program = &mnt_program, 50 .program = &mnt_program,
58 .version = version, 51 .version = info->version,
59 .authflavor = RPC_AUTH_UNIX, 52 .authflavor = RPC_AUTH_UNIX,
60 .flags = 0,
61 }; 53 };
62 struct rpc_clnt *mnt_clnt; 54 struct rpc_clnt *mnt_clnt;
63 int status; 55 int status;
64 56
65 dprintk("NFS: sending MNT request for %s:%s\n", 57 dprintk("NFS: sending MNT request for %s:%s\n",
66 (hostname ? hostname : "server"), path); 58 (info->hostname ? info->hostname : "server"),
59 info->dirpath);
60
61 if (info->noresvport)
62 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
67 63
68 mnt_clnt = rpc_create(&args); 64 mnt_clnt = rpc_create(&args);
69 if (IS_ERR(mnt_clnt)) 65 if (IS_ERR(mnt_clnt))
70 goto out_clnt_err; 66 goto out_clnt_err;
71 67
72 if (version == NFS_MNT3_VERSION) 68 if (info->version == NFS_MNT3_VERSION)
73 msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT]; 69 msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
74 else 70 else
75 msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT]; 71 msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT];
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ea790645fda6..4e4d33204376 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -38,8 +38,12 @@ struct idmap;
38 ((err) != NFSERR_NOFILEHANDLE)) 38 ((err) != NFSERR_NOFILEHANDLE))
39 39
40enum nfs4_client_state { 40enum nfs4_client_state {
41 NFS4CLNT_STATE_RECOVER = 0, 41 NFS4CLNT_MANAGER_RUNNING = 0,
42 NFS4CLNT_CHECK_LEASE,
42 NFS4CLNT_LEASE_EXPIRED, 43 NFS4CLNT_LEASE_EXPIRED,
44 NFS4CLNT_RECLAIM_REBOOT,
45 NFS4CLNT_RECLAIM_NOGRACE,
46 NFS4CLNT_DELEGRETURN,
43}; 47};
44 48
45/* 49/*
@@ -90,12 +94,18 @@ struct nfs4_state_owner {
90 94
91 spinlock_t so_lock; 95 spinlock_t so_lock;
92 atomic_t so_count; 96 atomic_t so_count;
97 unsigned long so_flags;
93 struct list_head so_states; 98 struct list_head so_states;
94 struct list_head so_delegations; 99 struct list_head so_delegations;
95 struct nfs_seqid_counter so_seqid; 100 struct nfs_seqid_counter so_seqid;
96 struct rpc_sequence so_sequence; 101 struct rpc_sequence so_sequence;
97}; 102};
98 103
104enum {
105 NFS_OWNER_RECLAIM_REBOOT,
106 NFS_OWNER_RECLAIM_NOGRACE
107};
108
99/* 109/*
100 * struct nfs4_state maintains the client-side state for a given 110 * struct nfs4_state maintains the client-side state for a given
101 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK). 111 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
@@ -128,6 +138,8 @@ enum {
128 NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */ 138 NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */
129 NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */ 139 NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */
130 NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */ 140 NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */
141 NFS_STATE_RECLAIM_REBOOT, /* OPEN stateid server rebooted */
142 NFS_STATE_RECLAIM_NOGRACE, /* OPEN stateid needs to recover state */
131}; 143};
132 144
133struct nfs4_state { 145struct nfs4_state {
@@ -149,7 +161,7 @@ struct nfs4_state {
149 unsigned int n_rdonly; /* Number of read-only references */ 161 unsigned int n_rdonly; /* Number of read-only references */
150 unsigned int n_wronly; /* Number of write-only references */ 162 unsigned int n_wronly; /* Number of write-only references */
151 unsigned int n_rdwr; /* Number of read/write references */ 163 unsigned int n_rdwr; /* Number of read/write references */
152 int state; /* State on the server (R,W, or RW) */ 164 fmode_t state; /* State on the server (R,W, or RW) */
153 atomic_t count; 165 atomic_t count;
154}; 166};
155 167
@@ -157,9 +169,12 @@ struct nfs4_state {
157struct nfs4_exception { 169struct nfs4_exception {
158 long timeout; 170 long timeout;
159 int retry; 171 int retry;
172 struct nfs4_state *state;
160}; 173};
161 174
162struct nfs4_state_recovery_ops { 175struct nfs4_state_recovery_ops {
176 int owner_flag_bit;
177 int state_flag_bit;
163 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *); 178 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
164 int (*recover_lock)(struct nfs4_state *, struct file_lock *); 179 int (*recover_lock)(struct nfs4_state *, struct file_lock *);
165}; 180};
@@ -174,7 +189,6 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
174 189
175 190
176/* nfs4proc.c */ 191/* nfs4proc.c */
177extern int nfs4_map_errors(int err);
178extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *); 192extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
179extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *); 193extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
180extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); 194extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
@@ -187,7 +201,7 @@ extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
187 struct nfs4_fs_locations *fs_locations, struct page *page); 201 struct nfs4_fs_locations *fs_locations, struct page *page);
188 202
189extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; 203extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
190extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops; 204extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops;
191 205
192extern const u32 nfs4_fattr_bitmap[2]; 206extern const u32 nfs4_fattr_bitmap[2];
193extern const u32 nfs4_statfs_bitmap[2]; 207extern const u32 nfs4_statfs_bitmap[2];
@@ -202,16 +216,18 @@ extern void nfs4_kill_renewd(struct nfs_client *);
202extern void nfs4_renew_state(struct work_struct *); 216extern void nfs4_renew_state(struct work_struct *);
203 217
204/* nfs4state.c */ 218/* nfs4state.c */
205struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); 219struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
206 220
207extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); 221extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
208extern void nfs4_put_state_owner(struct nfs4_state_owner *); 222extern void nfs4_put_state_owner(struct nfs4_state_owner *);
209extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); 223extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
210extern void nfs4_put_open_state(struct nfs4_state *); 224extern void nfs4_put_open_state(struct nfs4_state *);
211extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t); 225extern void nfs4_close_state(struct path *, struct nfs4_state *, fmode_t);
212extern void nfs4_close_sync(struct path *, struct nfs4_state *, mode_t); 226extern void nfs4_close_sync(struct path *, struct nfs4_state *, fmode_t);
213extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t); 227extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
214extern void nfs4_schedule_state_recovery(struct nfs_client *); 228extern void nfs4_schedule_state_recovery(struct nfs_client *);
229extern void nfs4_schedule_state_manager(struct nfs_client *);
230extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
215extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); 231extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
216extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 232extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
217extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); 233extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 83e700a2b0c0..8dde84b988d9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -62,14 +62,12 @@
62struct nfs4_opendata; 62struct nfs4_opendata;
63static int _nfs4_proc_open(struct nfs4_opendata *data); 63static int _nfs4_proc_open(struct nfs4_opendata *data);
64static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 64static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
65static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); 65static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
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 nfs_client *clp);
68static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 66static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
69static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 67static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
70 68
71/* Prevent leaks of NFSv4 errors into userland */ 69/* Prevent leaks of NFSv4 errors into userland */
72int nfs4_map_errors(int err) 70static int nfs4_map_errors(int err)
73{ 71{
74 if (err < -1000) { 72 if (err < -1000) {
75 dprintk("%s could not handle NFSv4 error %d\n", 73 dprintk("%s could not handle NFSv4 error %d\n",
@@ -195,6 +193,83 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
195 kunmap_atomic(start, KM_USER0); 193 kunmap_atomic(start, KM_USER0);
196} 194}
197 195
196static int nfs4_wait_bit_killable(void *word)
197{
198 if (fatal_signal_pending(current))
199 return -ERESTARTSYS;
200 schedule();
201 return 0;
202}
203
204static int nfs4_wait_clnt_recover(struct nfs_client *clp)
205{
206 int res;
207
208 might_sleep();
209
210 res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING,
211 nfs4_wait_bit_killable, TASK_KILLABLE);
212 return res;
213}
214
215static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
216{
217 int res = 0;
218
219 might_sleep();
220
221 if (*timeout <= 0)
222 *timeout = NFS4_POLL_RETRY_MIN;
223 if (*timeout > NFS4_POLL_RETRY_MAX)
224 *timeout = NFS4_POLL_RETRY_MAX;
225 schedule_timeout_killable(*timeout);
226 if (fatal_signal_pending(current))
227 res = -ERESTARTSYS;
228 *timeout <<= 1;
229 return res;
230}
231
232/* This is the error handling routine for processes that are allowed
233 * to sleep.
234 */
235static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
236{
237 struct nfs_client *clp = server->nfs_client;
238 struct nfs4_state *state = exception->state;
239 int ret = errorcode;
240
241 exception->retry = 0;
242 switch(errorcode) {
243 case 0:
244 return 0;
245 case -NFS4ERR_ADMIN_REVOKED:
246 case -NFS4ERR_BAD_STATEID:
247 case -NFS4ERR_OPENMODE:
248 if (state == NULL)
249 break;
250 nfs4_state_mark_reclaim_nograce(clp, state);
251 case -NFS4ERR_STALE_CLIENTID:
252 case -NFS4ERR_STALE_STATEID:
253 case -NFS4ERR_EXPIRED:
254 nfs4_schedule_state_recovery(clp);
255 ret = nfs4_wait_clnt_recover(clp);
256 if (ret == 0)
257 exception->retry = 1;
258 break;
259 case -NFS4ERR_FILE_OPEN:
260 case -NFS4ERR_GRACE:
261 case -NFS4ERR_DELAY:
262 ret = nfs4_delay(server->client, &exception->timeout);
263 if (ret != 0)
264 break;
265 case -NFS4ERR_OLD_STATEID:
266 exception->retry = 1;
267 }
268 /* We failed to handle the error */
269 return nfs4_map_errors(ret);
270}
271
272
198static void renew_lease(const struct nfs_server *server, unsigned long timestamp) 273static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
199{ 274{
200 struct nfs_client *clp = server->nfs_client; 275 struct nfs_client *clp = server->nfs_client;
@@ -248,7 +323,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
248} 323}
249 324
250static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path, 325static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
251 struct nfs4_state_owner *sp, int flags, 326 struct nfs4_state_owner *sp, fmode_t fmode, int flags,
252 const struct iattr *attrs) 327 const struct iattr *attrs)
253{ 328{
254 struct dentry *parent = dget_parent(path->dentry); 329 struct dentry *parent = dget_parent(path->dentry);
@@ -268,7 +343,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
268 p->owner = sp; 343 p->owner = sp;
269 atomic_inc(&sp->so_count); 344 atomic_inc(&sp->so_count);
270 p->o_arg.fh = NFS_FH(dir); 345 p->o_arg.fh = NFS_FH(dir);
271 p->o_arg.open_flags = flags, 346 p->o_arg.open_flags = flags;
347 p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
272 p->o_arg.clientid = server->nfs_client->cl_clientid; 348 p->o_arg.clientid = server->nfs_client->cl_clientid;
273 p->o_arg.id = sp->so_owner_id.id; 349 p->o_arg.id = sp->so_owner_id.id;
274 p->o_arg.name = &p->path.dentry->d_name; 350 p->o_arg.name = &p->path.dentry->d_name;
@@ -324,10 +400,13 @@ static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task)
324 return ret; 400 return ret;
325} 401}
326 402
327static int can_open_cached(struct nfs4_state *state, int mode) 403static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode)
328{ 404{
329 int ret = 0; 405 int ret = 0;
330 switch (mode & (FMODE_READ|FMODE_WRITE|O_EXCL)) { 406
407 if (open_mode & O_EXCL)
408 goto out;
409 switch (mode & (FMODE_READ|FMODE_WRITE)) {
331 case FMODE_READ: 410 case FMODE_READ:
332 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0; 411 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0;
333 break; 412 break;
@@ -337,21 +416,23 @@ static int can_open_cached(struct nfs4_state *state, int mode)
337 case FMODE_READ|FMODE_WRITE: 416 case FMODE_READ|FMODE_WRITE:
338 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; 417 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
339 } 418 }
419out:
340 return ret; 420 return ret;
341} 421}
342 422
343static int can_open_delegated(struct nfs_delegation *delegation, mode_t open_flags) 423static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode)
344{ 424{
345 if ((delegation->type & open_flags) != open_flags) 425 if ((delegation->type & fmode) != fmode)
346 return 0; 426 return 0;
347 if (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) 427 if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags))
348 return 0; 428 return 0;
429 nfs_mark_delegation_referenced(delegation);
349 return 1; 430 return 1;
350} 431}
351 432
352static void update_open_stateflags(struct nfs4_state *state, mode_t open_flags) 433static void update_open_stateflags(struct nfs4_state *state, fmode_t fmode)
353{ 434{
354 switch (open_flags) { 435 switch (fmode) {
355 case FMODE_WRITE: 436 case FMODE_WRITE:
356 state->n_wronly++; 437 state->n_wronly++;
357 break; 438 break;
@@ -361,15 +442,15 @@ static void update_open_stateflags(struct nfs4_state *state, mode_t open_flags)
361 case FMODE_READ|FMODE_WRITE: 442 case FMODE_READ|FMODE_WRITE:
362 state->n_rdwr++; 443 state->n_rdwr++;
363 } 444 }
364 nfs4_state_set_mode_locked(state, state->state | open_flags); 445 nfs4_state_set_mode_locked(state, state->state | fmode);
365} 446}
366 447
367static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags) 448static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *stateid, fmode_t fmode)
368{ 449{
369 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) 450 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
370 memcpy(state->stateid.data, stateid->data, sizeof(state->stateid.data)); 451 memcpy(state->stateid.data, stateid->data, sizeof(state->stateid.data));
371 memcpy(state->open_stateid.data, stateid->data, sizeof(state->open_stateid.data)); 452 memcpy(state->open_stateid.data, stateid->data, sizeof(state->open_stateid.data));
372 switch (open_flags) { 453 switch (fmode) {
373 case FMODE_READ: 454 case FMODE_READ:
374 set_bit(NFS_O_RDONLY_STATE, &state->flags); 455 set_bit(NFS_O_RDONLY_STATE, &state->flags);
375 break; 456 break;
@@ -381,16 +462,15 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *
381 } 462 }
382} 463}
383 464
384static void nfs_set_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags) 465static void nfs_set_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, fmode_t fmode)
385{ 466{
386 write_seqlock(&state->seqlock); 467 write_seqlock(&state->seqlock);
387 nfs_set_open_stateid_locked(state, stateid, open_flags); 468 nfs_set_open_stateid_locked(state, stateid, fmode);
388 write_sequnlock(&state->seqlock); 469 write_sequnlock(&state->seqlock);
389} 470}
390 471
391static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stateid, nfs4_stateid *deleg_stateid, int open_flags) 472static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stateid, const nfs4_stateid *deleg_stateid, fmode_t fmode)
392{ 473{
393 open_flags &= (FMODE_READ|FMODE_WRITE);
394 /* 474 /*
395 * Protect the call to nfs4_state_set_mode_locked and 475 * Protect the call to nfs4_state_set_mode_locked and
396 * serialise the stateid update 476 * serialise the stateid update
@@ -401,20 +481,60 @@ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_sta
401 set_bit(NFS_DELEGATED_STATE, &state->flags); 481 set_bit(NFS_DELEGATED_STATE, &state->flags);
402 } 482 }
403 if (open_stateid != NULL) 483 if (open_stateid != NULL)
404 nfs_set_open_stateid_locked(state, open_stateid, open_flags); 484 nfs_set_open_stateid_locked(state, open_stateid, fmode);
405 write_sequnlock(&state->seqlock); 485 write_sequnlock(&state->seqlock);
406 spin_lock(&state->owner->so_lock); 486 spin_lock(&state->owner->so_lock);
407 update_open_stateflags(state, open_flags); 487 update_open_stateflags(state, fmode);
408 spin_unlock(&state->owner->so_lock); 488 spin_unlock(&state->owner->so_lock);
409} 489}
410 490
411static void nfs4_return_incompatible_delegation(struct inode *inode, mode_t open_flags) 491static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stateid, nfs4_stateid *delegation, fmode_t fmode)
492{
493 struct nfs_inode *nfsi = NFS_I(state->inode);
494 struct nfs_delegation *deleg_cur;
495 int ret = 0;
496
497 fmode &= (FMODE_READ|FMODE_WRITE);
498
499 rcu_read_lock();
500 deleg_cur = rcu_dereference(nfsi->delegation);
501 if (deleg_cur == NULL)
502 goto no_delegation;
503
504 spin_lock(&deleg_cur->lock);
505 if (nfsi->delegation != deleg_cur ||
506 (deleg_cur->type & fmode) != fmode)
507 goto no_delegation_unlock;
508
509 if (delegation == NULL)
510 delegation = &deleg_cur->stateid;
511 else if (memcmp(deleg_cur->stateid.data, delegation->data, NFS4_STATEID_SIZE) != 0)
512 goto no_delegation_unlock;
513
514 nfs_mark_delegation_referenced(deleg_cur);
515 __update_open_stateid(state, open_stateid, &deleg_cur->stateid, fmode);
516 ret = 1;
517no_delegation_unlock:
518 spin_unlock(&deleg_cur->lock);
519no_delegation:
520 rcu_read_unlock();
521
522 if (!ret && open_stateid != NULL) {
523 __update_open_stateid(state, open_stateid, NULL, fmode);
524 ret = 1;
525 }
526
527 return ret;
528}
529
530
531static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmode)
412{ 532{
413 struct nfs_delegation *delegation; 533 struct nfs_delegation *delegation;
414 534
415 rcu_read_lock(); 535 rcu_read_lock();
416 delegation = rcu_dereference(NFS_I(inode)->delegation); 536 delegation = rcu_dereference(NFS_I(inode)->delegation);
417 if (delegation == NULL || (delegation->type & open_flags) == open_flags) { 537 if (delegation == NULL || (delegation->type & fmode) == fmode) {
418 rcu_read_unlock(); 538 rcu_read_unlock();
419 return; 539 return;
420 } 540 }
@@ -427,27 +547,28 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
427 struct nfs4_state *state = opendata->state; 547 struct nfs4_state *state = opendata->state;
428 struct nfs_inode *nfsi = NFS_I(state->inode); 548 struct nfs_inode *nfsi = NFS_I(state->inode);
429 struct nfs_delegation *delegation; 549 struct nfs_delegation *delegation;
430 int open_mode = opendata->o_arg.open_flags & (FMODE_READ|FMODE_WRITE|O_EXCL); 550 int open_mode = opendata->o_arg.open_flags & O_EXCL;
551 fmode_t fmode = opendata->o_arg.fmode;
431 nfs4_stateid stateid; 552 nfs4_stateid stateid;
432 int ret = -EAGAIN; 553 int ret = -EAGAIN;
433 554
434 rcu_read_lock();
435 delegation = rcu_dereference(nfsi->delegation);
436 for (;;) { 555 for (;;) {
437 if (can_open_cached(state, open_mode)) { 556 if (can_open_cached(state, fmode, open_mode)) {
438 spin_lock(&state->owner->so_lock); 557 spin_lock(&state->owner->so_lock);
439 if (can_open_cached(state, open_mode)) { 558 if (can_open_cached(state, fmode, open_mode)) {
440 update_open_stateflags(state, open_mode); 559 update_open_stateflags(state, fmode);
441 spin_unlock(&state->owner->so_lock); 560 spin_unlock(&state->owner->so_lock);
442 rcu_read_unlock();
443 goto out_return_state; 561 goto out_return_state;
444 } 562 }
445 spin_unlock(&state->owner->so_lock); 563 spin_unlock(&state->owner->so_lock);
446 } 564 }
447 if (delegation == NULL) 565 rcu_read_lock();
448 break; 566 delegation = rcu_dereference(nfsi->delegation);
449 if (!can_open_delegated(delegation, open_mode)) 567 if (delegation == NULL ||
568 !can_open_delegated(delegation, fmode)) {
569 rcu_read_unlock();
450 break; 570 break;
571 }
451 /* Save the delegation */ 572 /* Save the delegation */
452 memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data)); 573 memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data));
453 rcu_read_unlock(); 574 rcu_read_unlock();
@@ -455,19 +576,11 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
455 if (ret != 0) 576 if (ret != 0)
456 goto out; 577 goto out;
457 ret = -EAGAIN; 578 ret = -EAGAIN;
458 rcu_read_lock(); 579
459 delegation = rcu_dereference(nfsi->delegation); 580 /* Try to update the stateid using the delegation */
460 /* If no delegation, try a cached open */ 581 if (update_open_stateid(state, NULL, &stateid, fmode))
461 if (delegation == NULL) 582 goto out_return_state;
462 continue;
463 /* Is the delegation still valid? */
464 if (memcmp(stateid.data, delegation->stateid.data, sizeof(stateid.data)) != 0)
465 continue;
466 rcu_read_unlock();
467 update_open_stateid(state, NULL, &stateid, open_mode);
468 goto out_return_state;
469 } 583 }
470 rcu_read_unlock();
471out: 584out:
472 return ERR_PTR(ret); 585 return ERR_PTR(ret);
473out_return_state: 586out_return_state:
@@ -480,7 +593,6 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
480 struct inode *inode; 593 struct inode *inode;
481 struct nfs4_state *state = NULL; 594 struct nfs4_state *state = NULL;
482 struct nfs_delegation *delegation; 595 struct nfs_delegation *delegation;
483 nfs4_stateid *deleg_stateid = NULL;
484 int ret; 596 int ret;
485 597
486 if (!data->rpc_done) { 598 if (!data->rpc_done) {
@@ -507,7 +619,7 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
507 if (delegation) 619 if (delegation)
508 delegation_flags = delegation->flags; 620 delegation_flags = delegation->flags;
509 rcu_read_unlock(); 621 rcu_read_unlock();
510 if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM)) 622 if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
511 nfs_inode_set_delegation(state->inode, 623 nfs_inode_set_delegation(state->inode,
512 data->owner->so_cred, 624 data->owner->so_cred,
513 &data->o_res); 625 &data->o_res);
@@ -516,12 +628,9 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
516 data->owner->so_cred, 628 data->owner->so_cred,
517 &data->o_res); 629 &data->o_res);
518 } 630 }
519 rcu_read_lock(); 631
520 delegation = rcu_dereference(NFS_I(inode)->delegation); 632 update_open_stateid(state, &data->o_res.stateid, NULL,
521 if (delegation != NULL) 633 data->o_arg.fmode);
522 deleg_stateid = &delegation->stateid;
523 update_open_stateid(state, &data->o_res.stateid, deleg_stateid, data->o_arg.open_flags);
524 rcu_read_unlock();
525 iput(inode); 634 iput(inode);
526out: 635out:
527 return state; 636 return state;
@@ -552,7 +661,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
552{ 661{
553 struct nfs4_opendata *opendata; 662 struct nfs4_opendata *opendata;
554 663
555 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL); 664 opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL);
556 if (opendata == NULL) 665 if (opendata == NULL)
557 return ERR_PTR(-ENOMEM); 666 return ERR_PTR(-ENOMEM);
558 opendata->state = state; 667 opendata->state = state;
@@ -560,12 +669,13 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
560 return opendata; 669 return opendata;
561} 670}
562 671
563static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res) 672static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmode, struct nfs4_state **res)
564{ 673{
565 struct nfs4_state *newstate; 674 struct nfs4_state *newstate;
566 int ret; 675 int ret;
567 676
568 opendata->o_arg.open_flags = openflags; 677 opendata->o_arg.open_flags = 0;
678 opendata->o_arg.fmode = fmode;
569 memset(&opendata->o_res, 0, sizeof(opendata->o_res)); 679 memset(&opendata->o_res, 0, sizeof(opendata->o_res));
570 memset(&opendata->c_res, 0, sizeof(opendata->c_res)); 680 memset(&opendata->c_res, 0, sizeof(opendata->c_res));
571 nfs4_init_opendata_res(opendata); 681 nfs4_init_opendata_res(opendata);
@@ -575,7 +685,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openf
575 newstate = nfs4_opendata_to_nfs4_state(opendata); 685 newstate = nfs4_opendata_to_nfs4_state(opendata);
576 if (IS_ERR(newstate)) 686 if (IS_ERR(newstate))
577 return PTR_ERR(newstate); 687 return PTR_ERR(newstate);
578 nfs4_close_state(&opendata->path, newstate, openflags); 688 nfs4_close_state(&opendata->path, newstate, fmode);
579 *res = newstate; 689 *res = newstate;
580 return 0; 690 return 0;
581} 691}
@@ -631,7 +741,7 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
631{ 741{
632 struct nfs_delegation *delegation; 742 struct nfs_delegation *delegation;
633 struct nfs4_opendata *opendata; 743 struct nfs4_opendata *opendata;
634 int delegation_type = 0; 744 fmode_t delegation_type = 0;
635 int status; 745 int status;
636 746
637 opendata = nfs4_open_recoverdata_alloc(ctx, state); 747 opendata = nfs4_open_recoverdata_alloc(ctx, state);
@@ -641,7 +751,7 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
641 opendata->o_arg.fh = NFS_FH(state->inode); 751 opendata->o_arg.fh = NFS_FH(state->inode);
642 rcu_read_lock(); 752 rcu_read_lock();
643 delegation = rcu_dereference(NFS_I(state->inode)->delegation); 753 delegation = rcu_dereference(NFS_I(state->inode)->delegation);
644 if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0) 754 if (delegation != NULL && test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) != 0)
645 delegation_type = delegation->type; 755 delegation_type = delegation->type;
646 rcu_read_unlock(); 756 rcu_read_unlock();
647 opendata->o_arg.u.delegation_type = delegation_type; 757 opendata->o_arg.u.delegation_type = delegation_type;
@@ -744,7 +854,7 @@ static void nfs4_open_confirm_release(void *calldata)
744 goto out_free; 854 goto out_free;
745 state = nfs4_opendata_to_nfs4_state(data); 855 state = nfs4_opendata_to_nfs4_state(data);
746 if (!IS_ERR(state)) 856 if (!IS_ERR(state))
747 nfs4_close_state(&data->path, state, data->o_arg.open_flags); 857 nfs4_close_state(&data->path, state, data->o_arg.fmode);
748out_free: 858out_free:
749 nfs4_opendata_put(data); 859 nfs4_opendata_put(data);
750} 860}
@@ -808,12 +918,12 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
808 if (data->state != NULL) { 918 if (data->state != NULL) {
809 struct nfs_delegation *delegation; 919 struct nfs_delegation *delegation;
810 920
811 if (can_open_cached(data->state, data->o_arg.open_flags & (FMODE_READ|FMODE_WRITE|O_EXCL))) 921 if (can_open_cached(data->state, data->o_arg.fmode, data->o_arg.open_flags))
812 goto out_no_action; 922 goto out_no_action;
813 rcu_read_lock(); 923 rcu_read_lock();
814 delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); 924 delegation = rcu_dereference(NFS_I(data->state->inode)->delegation);
815 if (delegation != NULL && 925 if (delegation != NULL &&
816 (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) == 0) { 926 test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0) {
817 rcu_read_unlock(); 927 rcu_read_unlock();
818 goto out_no_action; 928 goto out_no_action;
819 } 929 }
@@ -877,7 +987,7 @@ static void nfs4_open_release(void *calldata)
877 goto out_free; 987 goto out_free;
878 state = nfs4_opendata_to_nfs4_state(data); 988 state = nfs4_opendata_to_nfs4_state(data);
879 if (!IS_ERR(state)) 989 if (!IS_ERR(state))
880 nfs4_close_state(&data->path, state, data->o_arg.open_flags); 990 nfs4_close_state(&data->path, state, data->o_arg.fmode);
881out_free: 991out_free:
882 nfs4_opendata_put(data); 992 nfs4_opendata_put(data);
883} 993}
@@ -955,10 +1065,11 @@ static int nfs4_recover_expired_lease(struct nfs_server *server)
955 int ret; 1065 int ret;
956 1066
957 for (;;) { 1067 for (;;) {
958 ret = nfs4_wait_clnt_recover(server->client, clp); 1068 ret = nfs4_wait_clnt_recover(clp);
959 if (ret != 0) 1069 if (ret != 0)
960 return ret; 1070 return ret;
961 if (!test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) 1071 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) &&
1072 !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state))
962 break; 1073 break;
963 nfs4_schedule_state_recovery(clp); 1074 nfs4_schedule_state_recovery(clp);
964 } 1075 }
@@ -993,8 +1104,9 @@ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4
993 1104
994 do { 1105 do {
995 err = _nfs4_open_expired(ctx, state); 1106 err = _nfs4_open_expired(ctx, state);
996 if (err == -NFS4ERR_DELAY) 1107 if (err != -NFS4ERR_DELAY)
997 nfs4_handle_exception(server, err, &exception); 1108 break;
1109 nfs4_handle_exception(server, err, &exception);
998 } while (exception.retry); 1110 } while (exception.retry);
999 return err; 1111 return err;
1000} 1112}
@@ -1031,12 +1143,11 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
1031/* 1143/*
1032 * Returns a referenced nfs4_state 1144 * Returns a referenced nfs4_state
1033 */ 1145 */
1034static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res) 1146static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
1035{ 1147{
1036 struct nfs4_state_owner *sp; 1148 struct nfs4_state_owner *sp;
1037 struct nfs4_state *state = NULL; 1149 struct nfs4_state *state = NULL;
1038 struct nfs_server *server = NFS_SERVER(dir); 1150 struct nfs_server *server = NFS_SERVER(dir);
1039 struct nfs_client *clp = server->nfs_client;
1040 struct nfs4_opendata *opendata; 1151 struct nfs4_opendata *opendata;
1041 int status; 1152 int status;
1042 1153
@@ -1050,12 +1161,11 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
1050 if (status != 0) 1161 if (status != 0)
1051 goto err_put_state_owner; 1162 goto err_put_state_owner;
1052 if (path->dentry->d_inode != NULL) 1163 if (path->dentry->d_inode != NULL)
1053 nfs4_return_incompatible_delegation(path->dentry->d_inode, flags & (FMODE_READ|FMODE_WRITE)); 1164 nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode);
1054 down_read(&clp->cl_sem);
1055 status = -ENOMEM; 1165 status = -ENOMEM;
1056 opendata = nfs4_opendata_alloc(path, sp, flags, sattr); 1166 opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr);
1057 if (opendata == NULL) 1167 if (opendata == NULL)
1058 goto err_release_rwsem; 1168 goto err_put_state_owner;
1059 1169
1060 if (path->dentry->d_inode != NULL) 1170 if (path->dentry->d_inode != NULL)
1061 opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp); 1171 opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp);
@@ -1073,13 +1183,10 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
1073 goto err_opendata_put; 1183 goto err_opendata_put;
1074 nfs4_opendata_put(opendata); 1184 nfs4_opendata_put(opendata);
1075 nfs4_put_state_owner(sp); 1185 nfs4_put_state_owner(sp);
1076 up_read(&clp->cl_sem);
1077 *res = state; 1186 *res = state;
1078 return 0; 1187 return 0;
1079err_opendata_put: 1188err_opendata_put:
1080 nfs4_opendata_put(opendata); 1189 nfs4_opendata_put(opendata);
1081err_release_rwsem:
1082 up_read(&clp->cl_sem);
1083err_put_state_owner: 1190err_put_state_owner:
1084 nfs4_put_state_owner(sp); 1191 nfs4_put_state_owner(sp);
1085out_err: 1192out_err:
@@ -1088,14 +1195,14 @@ out_err:
1088} 1195}
1089 1196
1090 1197
1091static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred) 1198static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred)
1092{ 1199{
1093 struct nfs4_exception exception = { }; 1200 struct nfs4_exception exception = { };
1094 struct nfs4_state *res; 1201 struct nfs4_state *res;
1095 int status; 1202 int status;
1096 1203
1097 do { 1204 do {
1098 status = _nfs4_do_open(dir, path, flags, sattr, cred, &res); 1205 status = _nfs4_do_open(dir, path, fmode, flags, sattr, cred, &res);
1099 if (status == 0) 1206 if (status == 0)
1100 break; 1207 break;
1101 /* NOTE: BAD_SEQID means the server and client disagree about the 1208 /* NOTE: BAD_SEQID means the server and client disagree about the
@@ -1230,10 +1337,13 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1230 renew_lease(server, calldata->timestamp); 1337 renew_lease(server, calldata->timestamp);
1231 break; 1338 break;
1232 case -NFS4ERR_STALE_STATEID: 1339 case -NFS4ERR_STALE_STATEID:
1340 case -NFS4ERR_OLD_STATEID:
1341 case -NFS4ERR_BAD_STATEID:
1233 case -NFS4ERR_EXPIRED: 1342 case -NFS4ERR_EXPIRED:
1234 break; 1343 if (calldata->arg.fmode == 0)
1344 break;
1235 default: 1345 default:
1236 if (nfs4_async_handle_error(task, server) == -EAGAIN) { 1346 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) {
1237 rpc_restart_call(task); 1347 rpc_restart_call(task);
1238 return; 1348 return;
1239 } 1349 }
@@ -1272,10 +1382,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1272 nfs_fattr_init(calldata->res.fattr); 1382 nfs_fattr_init(calldata->res.fattr);
1273 if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) { 1383 if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) {
1274 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; 1384 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1275 calldata->arg.open_flags = FMODE_READ; 1385 calldata->arg.fmode = FMODE_READ;
1276 } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) { 1386 } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) {
1277 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; 1387 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1278 calldata->arg.open_flags = FMODE_WRITE; 1388 calldata->arg.fmode = FMODE_WRITE;
1279 } 1389 }
1280 calldata->timestamp = jiffies; 1390 calldata->timestamp = jiffies;
1281 rpc_call_start(task); 1391 rpc_call_start(task);
@@ -1328,6 +1438,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1328 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1438 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
1329 if (calldata->arg.seqid == NULL) 1439 if (calldata->arg.seqid == NULL)
1330 goto out_free_calldata; 1440 goto out_free_calldata;
1441 calldata->arg.fmode = 0;
1331 calldata->arg.bitmask = server->attr_bitmask; 1442 calldata->arg.bitmask = server->attr_bitmask;
1332 calldata->res.fattr = &calldata->fattr; 1443 calldata->res.fattr = &calldata->fattr;
1333 calldata->res.seqid = calldata->arg.seqid; 1444 calldata->res.seqid = calldata->arg.seqid;
@@ -1354,13 +1465,13 @@ out:
1354 return status; 1465 return status;
1355} 1466}
1356 1467
1357static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state) 1468static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state, fmode_t fmode)
1358{ 1469{
1359 struct file *filp; 1470 struct file *filp;
1360 int ret; 1471 int ret;
1361 1472
1362 /* If the open_intent is for execute, we have an extra check to make */ 1473 /* If the open_intent is for execute, we have an extra check to make */
1363 if (nd->intent.open.flags & FMODE_EXEC) { 1474 if (fmode & FMODE_EXEC) {
1364 ret = nfs_may_open(state->inode, 1475 ret = nfs_may_open(state->inode,
1365 state->owner->so_cred, 1476 state->owner->so_cred,
1366 nd->intent.open.flags); 1477 nd->intent.open.flags);
@@ -1376,7 +1487,7 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
1376 } 1487 }
1377 ret = PTR_ERR(filp); 1488 ret = PTR_ERR(filp);
1378out_close: 1489out_close:
1379 nfs4_close_sync(path, state, nd->intent.open.flags); 1490 nfs4_close_sync(path, state, fmode & (FMODE_READ|FMODE_WRITE));
1380 return ret; 1491 return ret;
1381} 1492}
1382 1493
@@ -1392,6 +1503,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
1392 struct rpc_cred *cred; 1503 struct rpc_cred *cred;
1393 struct nfs4_state *state; 1504 struct nfs4_state *state;
1394 struct dentry *res; 1505 struct dentry *res;
1506 fmode_t fmode = nd->intent.open.flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
1395 1507
1396 if (nd->flags & LOOKUP_CREATE) { 1508 if (nd->flags & LOOKUP_CREATE) {
1397 attr.ia_mode = nd->intent.open.create_mode; 1509 attr.ia_mode = nd->intent.open.create_mode;
@@ -1409,7 +1521,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
1409 parent = dentry->d_parent; 1521 parent = dentry->d_parent;
1410 /* Protect against concurrent sillydeletes */ 1522 /* Protect against concurrent sillydeletes */
1411 nfs_block_sillyrename(parent); 1523 nfs_block_sillyrename(parent);
1412 state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred); 1524 state = nfs4_do_open(dir, &path, fmode, nd->intent.open.flags, &attr, cred);
1413 put_rpccred(cred); 1525 put_rpccred(cred);
1414 if (IS_ERR(state)) { 1526 if (IS_ERR(state)) {
1415 if (PTR_ERR(state) == -ENOENT) { 1527 if (PTR_ERR(state) == -ENOENT) {
@@ -1424,7 +1536,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
1424 path.dentry = res; 1536 path.dentry = res;
1425 nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir)); 1537 nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
1426 nfs_unblock_sillyrename(parent); 1538 nfs_unblock_sillyrename(parent);
1427 nfs4_intent_set_file(nd, &path, state); 1539 nfs4_intent_set_file(nd, &path, state, fmode);
1428 return res; 1540 return res;
1429} 1541}
1430 1542
@@ -1437,11 +1549,12 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
1437 }; 1549 };
1438 struct rpc_cred *cred; 1550 struct rpc_cred *cred;
1439 struct nfs4_state *state; 1551 struct nfs4_state *state;
1552 fmode_t fmode = openflags & (FMODE_READ | FMODE_WRITE);
1440 1553
1441 cred = rpc_lookup_cred(); 1554 cred = rpc_lookup_cred();
1442 if (IS_ERR(cred)) 1555 if (IS_ERR(cred))
1443 return PTR_ERR(cred); 1556 return PTR_ERR(cred);
1444 state = nfs4_do_open(dir, &path, openflags, NULL, cred); 1557 state = nfs4_do_open(dir, &path, fmode, openflags, NULL, cred);
1445 put_rpccred(cred); 1558 put_rpccred(cred);
1446 if (IS_ERR(state)) { 1559 if (IS_ERR(state)) {
1447 switch (PTR_ERR(state)) { 1560 switch (PTR_ERR(state)) {
@@ -1458,10 +1571,10 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
1458 } 1571 }
1459 if (state->inode == dentry->d_inode) { 1572 if (state->inode == dentry->d_inode) {
1460 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1573 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1461 nfs4_intent_set_file(nd, &path, state); 1574 nfs4_intent_set_file(nd, &path, state, fmode);
1462 return 1; 1575 return 1;
1463 } 1576 }
1464 nfs4_close_sync(&path, state, openflags); 1577 nfs4_close_sync(&path, state, fmode);
1465out_drop: 1578out_drop:
1466 d_drop(dentry); 1579 d_drop(dentry);
1467 return 0; 1580 return 0;
@@ -1887,6 +2000,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1887 }; 2000 };
1888 struct nfs4_state *state; 2001 struct nfs4_state *state;
1889 struct rpc_cred *cred; 2002 struct rpc_cred *cred;
2003 fmode_t fmode = flags & (FMODE_READ | FMODE_WRITE);
1890 int status = 0; 2004 int status = 0;
1891 2005
1892 cred = rpc_lookup_cred(); 2006 cred = rpc_lookup_cred();
@@ -1894,7 +2008,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1894 status = PTR_ERR(cred); 2008 status = PTR_ERR(cred);
1895 goto out; 2009 goto out;
1896 } 2010 }
1897 state = nfs4_do_open(dir, &path, flags, sattr, cred); 2011 state = nfs4_do_open(dir, &path, fmode, flags, sattr, cred);
1898 d_drop(dentry); 2012 d_drop(dentry);
1899 if (IS_ERR(state)) { 2013 if (IS_ERR(state)) {
1900 status = PTR_ERR(state); 2014 status = PTR_ERR(state);
@@ -1910,9 +2024,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1910 nfs_post_op_update_inode(state->inode, &fattr); 2024 nfs_post_op_update_inode(state->inode, &fattr);
1911 } 2025 }
1912 if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0) 2026 if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
1913 status = nfs4_intent_set_file(nd, &path, state); 2027 status = nfs4_intent_set_file(nd, &path, state, fmode);
1914 else 2028 else
1915 nfs4_close_sync(&path, state, flags); 2029 nfs4_close_sync(&path, state, fmode);
1916out_putcred: 2030out_putcred:
1917 put_rpccred(cred); 2031 put_rpccred(cred);
1918out: 2032out:
@@ -1974,7 +2088,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
1974{ 2088{
1975 struct nfs_removeres *res = task->tk_msg.rpc_resp; 2089 struct nfs_removeres *res = task->tk_msg.rpc_resp;
1976 2090
1977 if (nfs4_async_handle_error(task, res->server) == -EAGAIN) 2091 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
1978 return 0; 2092 return 0;
1979 update_changeattr(dir, &res->cinfo); 2093 update_changeattr(dir, &res->cinfo);
1980 nfs_post_op_update_inode(dir, &res->dir_attr); 2094 nfs_post_op_update_inode(dir, &res->dir_attr);
@@ -2402,7 +2516,7 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2402{ 2516{
2403 struct nfs_server *server = NFS_SERVER(data->inode); 2517 struct nfs_server *server = NFS_SERVER(data->inode);
2404 2518
2405 if (nfs4_async_handle_error(task, server) == -EAGAIN) { 2519 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
2406 rpc_restart_call(task); 2520 rpc_restart_call(task);
2407 return -EAGAIN; 2521 return -EAGAIN;
2408 } 2522 }
@@ -2423,7 +2537,7 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2423{ 2537{
2424 struct inode *inode = data->inode; 2538 struct inode *inode = data->inode;
2425 2539
2426 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2540 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
2427 rpc_restart_call(task); 2541 rpc_restart_call(task);
2428 return -EAGAIN; 2542 return -EAGAIN;
2429 } 2543 }
@@ -2449,7 +2563,7 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
2449{ 2563{
2450 struct inode *inode = data->inode; 2564 struct inode *inode = data->inode;
2451 2565
2452 if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { 2566 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
2453 rpc_restart_call(task); 2567 rpc_restart_call(task);
2454 return -EAGAIN; 2568 return -EAGAIN;
2455 } 2569 }
@@ -2742,19 +2856,25 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
2742} 2856}
2743 2857
2744static int 2858static int
2745nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) 2859nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
2746{ 2860{
2747 struct nfs_client *clp = server->nfs_client; 2861 struct nfs_client *clp = server->nfs_client;
2748 2862
2749 if (!clp || task->tk_status >= 0) 2863 if (!clp || task->tk_status >= 0)
2750 return 0; 2864 return 0;
2751 switch(task->tk_status) { 2865 switch(task->tk_status) {
2866 case -NFS4ERR_ADMIN_REVOKED:
2867 case -NFS4ERR_BAD_STATEID:
2868 case -NFS4ERR_OPENMODE:
2869 if (state == NULL)
2870 break;
2871 nfs4_state_mark_reclaim_nograce(clp, state);
2752 case -NFS4ERR_STALE_CLIENTID: 2872 case -NFS4ERR_STALE_CLIENTID:
2753 case -NFS4ERR_STALE_STATEID: 2873 case -NFS4ERR_STALE_STATEID:
2754 case -NFS4ERR_EXPIRED: 2874 case -NFS4ERR_EXPIRED:
2755 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); 2875 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
2756 nfs4_schedule_state_recovery(clp); 2876 nfs4_schedule_state_recovery(clp);
2757 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) 2877 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
2758 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); 2878 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
2759 task->tk_status = 0; 2879 task->tk_status = 0;
2760 return -EAGAIN; 2880 return -EAGAIN;
@@ -2772,79 +2892,6 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
2772 return 0; 2892 return 0;
2773} 2893}
2774 2894
2775static int nfs4_wait_bit_killable(void *word)
2776{
2777 if (fatal_signal_pending(current))
2778 return -ERESTARTSYS;
2779 schedule();
2780 return 0;
2781}
2782
2783static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp)
2784{
2785 int res;
2786
2787 might_sleep();
2788
2789 rwsem_acquire(&clp->cl_sem.dep_map, 0, 0, _RET_IP_);
2790
2791 res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER,
2792 nfs4_wait_bit_killable, TASK_KILLABLE);
2793
2794 rwsem_release(&clp->cl_sem.dep_map, 1, _RET_IP_);
2795 return res;
2796}
2797
2798static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
2799{
2800 int res = 0;
2801
2802 might_sleep();
2803
2804 if (*timeout <= 0)
2805 *timeout = NFS4_POLL_RETRY_MIN;
2806 if (*timeout > NFS4_POLL_RETRY_MAX)
2807 *timeout = NFS4_POLL_RETRY_MAX;
2808 schedule_timeout_killable(*timeout);
2809 if (fatal_signal_pending(current))
2810 res = -ERESTARTSYS;
2811 *timeout <<= 1;
2812 return res;
2813}
2814
2815/* This is the error handling routine for processes that are allowed
2816 * to sleep.
2817 */
2818static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
2819{
2820 struct nfs_client *clp = server->nfs_client;
2821 int ret = errorcode;
2822
2823 exception->retry = 0;
2824 switch(errorcode) {
2825 case 0:
2826 return 0;
2827 case -NFS4ERR_STALE_CLIENTID:
2828 case -NFS4ERR_STALE_STATEID:
2829 case -NFS4ERR_EXPIRED:
2830 nfs4_schedule_state_recovery(clp);
2831 ret = nfs4_wait_clnt_recover(server->client, clp);
2832 if (ret == 0)
2833 exception->retry = 1;
2834 break;
2835 case -NFS4ERR_FILE_OPEN:
2836 case -NFS4ERR_GRACE:
2837 case -NFS4ERR_DELAY:
2838 ret = nfs4_delay(server->client, &exception->timeout);
2839 if (ret != 0)
2840 break;
2841 case -NFS4ERR_OLD_STATEID:
2842 exception->retry = 1;
2843 }
2844 /* We failed to handle the error */
2845 return nfs4_map_errors(ret);
2846}
2847
2848int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) 2895int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
2849{ 2896{
2850 nfs4_verifier sc_verifier; 2897 nfs4_verifier sc_verifier;
@@ -2916,7 +2963,6 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre
2916 spin_lock(&clp->cl_lock); 2963 spin_lock(&clp->cl_lock);
2917 clp->cl_lease_time = fsinfo.lease_time * HZ; 2964 clp->cl_lease_time = fsinfo.lease_time * HZ;
2918 clp->cl_last_renewal = now; 2965 clp->cl_last_renewal = now;
2919 clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
2920 spin_unlock(&clp->cl_lock); 2966 spin_unlock(&clp->cl_lock);
2921 } 2967 }
2922 return status; 2968 return status;
@@ -3074,7 +3120,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3074 struct nfs4_lock_state *lsp; 3120 struct nfs4_lock_state *lsp;
3075 int status; 3121 int status;
3076 3122
3077 down_read(&clp->cl_sem);
3078 arg.lock_owner.clientid = clp->cl_clientid; 3123 arg.lock_owner.clientid = clp->cl_clientid;
3079 status = nfs4_set_lock_state(state, request); 3124 status = nfs4_set_lock_state(state, request);
3080 if (status != 0) 3125 if (status != 0)
@@ -3091,7 +3136,6 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
3091 } 3136 }
3092 request->fl_ops->fl_release_private(request); 3137 request->fl_ops->fl_release_private(request);
3093out: 3138out:
3094 up_read(&clp->cl_sem);
3095 return status; 3139 return status;
3096} 3140}
3097 3141
@@ -3181,11 +3225,13 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3181 sizeof(calldata->lsp->ls_stateid.data)); 3225 sizeof(calldata->lsp->ls_stateid.data));
3182 renew_lease(calldata->server, calldata->timestamp); 3226 renew_lease(calldata->server, calldata->timestamp);
3183 break; 3227 break;
3228 case -NFS4ERR_BAD_STATEID:
3229 case -NFS4ERR_OLD_STATEID:
3184 case -NFS4ERR_STALE_STATEID: 3230 case -NFS4ERR_STALE_STATEID:
3185 case -NFS4ERR_EXPIRED: 3231 case -NFS4ERR_EXPIRED:
3186 break; 3232 break;
3187 default: 3233 default:
3188 if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) 3234 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
3189 rpc_restart_call(task); 3235 rpc_restart_call(task);
3190 } 3236 }
3191} 3237}
@@ -3248,6 +3294,7 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
3248 3294
3249static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) 3295static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
3250{ 3296{
3297 struct nfs_inode *nfsi = NFS_I(state->inode);
3251 struct nfs_seqid *seqid; 3298 struct nfs_seqid *seqid;
3252 struct nfs4_lock_state *lsp; 3299 struct nfs4_lock_state *lsp;
3253 struct rpc_task *task; 3300 struct rpc_task *task;
@@ -3257,8 +3304,12 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
3257 status = nfs4_set_lock_state(state, request); 3304 status = nfs4_set_lock_state(state, request);
3258 /* Unlock _before_ we do the RPC call */ 3305 /* Unlock _before_ we do the RPC call */
3259 request->fl_flags |= FL_EXISTS; 3306 request->fl_flags |= FL_EXISTS;
3260 if (do_vfs_lock(request->fl_file, request) == -ENOENT) 3307 down_read(&nfsi->rwsem);
3308 if (do_vfs_lock(request->fl_file, request) == -ENOENT) {
3309 up_read(&nfsi->rwsem);
3261 goto out; 3310 goto out;
3311 }
3312 up_read(&nfsi->rwsem);
3262 if (status != 0) 3313 if (status != 0)
3263 goto out; 3314 goto out;
3264 /* Is this a delegated lock? */ 3315 /* Is this a delegated lock? */
@@ -3484,7 +3535,7 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
3484 3535
3485static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 3536static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
3486{ 3537{
3487 struct nfs_client *clp = state->owner->so_client; 3538 struct nfs_inode *nfsi = NFS_I(state->inode);
3488 unsigned char fl_flags = request->fl_flags; 3539 unsigned char fl_flags = request->fl_flags;
3489 int status; 3540 int status;
3490 3541
@@ -3496,19 +3547,13 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
3496 status = do_vfs_lock(request->fl_file, request); 3547 status = do_vfs_lock(request->fl_file, request);
3497 if (status < 0) 3548 if (status < 0)
3498 goto out; 3549 goto out;
3499 down_read(&clp->cl_sem); 3550 down_read(&nfsi->rwsem);
3500 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { 3551 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3501 struct nfs_inode *nfsi = NFS_I(state->inode);
3502 /* Yes: cache locks! */ 3552 /* Yes: cache locks! */
3503 down_read(&nfsi->rwsem);
3504 /* ...but avoid races with delegation recall... */ 3553 /* ...but avoid races with delegation recall... */
3505 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { 3554 request->fl_flags = fl_flags & ~FL_SLEEP;
3506 request->fl_flags = fl_flags & ~FL_SLEEP; 3555 status = do_vfs_lock(request->fl_file, request);
3507 status = do_vfs_lock(request->fl_file, request); 3556 goto out_unlock;
3508 up_read(&nfsi->rwsem);
3509 goto out_unlock;
3510 }
3511 up_read(&nfsi->rwsem);
3512 } 3557 }
3513 status = _nfs4_do_setlk(state, cmd, request, 0); 3558 status = _nfs4_do_setlk(state, cmd, request, 0);
3514 if (status != 0) 3559 if (status != 0)
@@ -3518,7 +3563,7 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
3518 if (do_vfs_lock(request->fl_file, request) < 0) 3563 if (do_vfs_lock(request->fl_file, request) < 0)
3519 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__); 3564 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__);
3520out_unlock: 3565out_unlock:
3521 up_read(&clp->cl_sem); 3566 up_read(&nfsi->rwsem);
3522out: 3567out:
3523 request->fl_flags = fl_flags; 3568 request->fl_flags = fl_flags;
3524 return status; 3569 return status;
@@ -3664,11 +3709,15 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
3664} 3709}
3665 3710
3666struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { 3711struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
3712 .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
3713 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
3667 .recover_open = nfs4_open_reclaim, 3714 .recover_open = nfs4_open_reclaim,
3668 .recover_lock = nfs4_lock_reclaim, 3715 .recover_lock = nfs4_lock_reclaim,
3669}; 3716};
3670 3717
3671struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops = { 3718struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops = {
3719 .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE,
3720 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
3672 .recover_open = nfs4_open_expired, 3721 .recover_open = nfs4_open_expired,
3673 .recover_lock = nfs4_lock_expired, 3722 .recover_lock = nfs4_lock_expired,
3674}; 3723};
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 3305acbbe2ae..f524e932ff7b 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -65,7 +65,6 @@ nfs4_renew_state(struct work_struct *work)
65 long lease, timeout; 65 long lease, timeout;
66 unsigned long last, now; 66 unsigned long last, now;
67 67
68 down_read(&clp->cl_sem);
69 dprintk("%s: start\n", __func__); 68 dprintk("%s: start\n", __func__);
70 /* Are there any active superblocks? */ 69 /* Are there any active superblocks? */
71 if (list_empty(&clp->cl_superblocks)) 70 if (list_empty(&clp->cl_superblocks))
@@ -77,17 +76,19 @@ nfs4_renew_state(struct work_struct *work)
77 timeout = (2 * lease) / 3 + (long)last - (long)now; 76 timeout = (2 * lease) / 3 + (long)last - (long)now;
78 /* Are we close to a lease timeout? */ 77 /* Are we close to a lease timeout? */
79 if (time_after(now, last + lease/3)) { 78 if (time_after(now, last + lease/3)) {
80 cred = nfs4_get_renew_cred(clp); 79 cred = nfs4_get_renew_cred_locked(clp);
80 spin_unlock(&clp->cl_lock);
81 if (cred == NULL) { 81 if (cred == NULL) {
82 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 82 if (list_empty(&clp->cl_delegations)) {
83 spin_unlock(&clp->cl_lock); 83 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
84 goto out;
85 }
84 nfs_expire_all_delegations(clp); 86 nfs_expire_all_delegations(clp);
85 goto out; 87 } else {
88 /* Queue an asynchronous RENEW. */
89 nfs4_proc_async_renew(clp, cred);
90 put_rpccred(cred);
86 } 91 }
87 spin_unlock(&clp->cl_lock);
88 /* Queue an asynchronous RENEW. */
89 nfs4_proc_async_renew(clp, cred);
90 put_rpccred(cred);
91 timeout = (2 * lease) / 3; 92 timeout = (2 * lease) / 3;
92 spin_lock(&clp->cl_lock); 93 spin_lock(&clp->cl_lock);
93 } else 94 } else
@@ -100,12 +101,11 @@ nfs4_renew_state(struct work_struct *work)
100 cancel_delayed_work(&clp->cl_renewd); 101 cancel_delayed_work(&clp->cl_renewd);
101 schedule_delayed_work(&clp->cl_renewd, timeout); 102 schedule_delayed_work(&clp->cl_renewd, timeout);
102 spin_unlock(&clp->cl_lock); 103 spin_unlock(&clp->cl_lock);
104 nfs_expire_unreferenced_delegations(clp);
103out: 105out:
104 up_read(&clp->cl_sem);
105 dprintk("%s: done\n", __func__); 106 dprintk("%s: done\n", __func__);
106} 107}
107 108
108/* Must be called with clp->cl_sem locked for writes */
109void 109void
110nfs4_schedule_state_renewal(struct nfs_client *clp) 110nfs4_schedule_state_renewal(struct nfs_client *clp)
111{ 111{
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 401ef8b28f97..2022fe47966f 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -71,14 +71,12 @@ static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
71 return status; 71 return status;
72} 72}
73 73
74static struct rpc_cred *nfs4_get_machine_cred(struct nfs_client *clp) 74static struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
75{ 75{
76 struct rpc_cred *cred = NULL; 76 struct rpc_cred *cred = NULL;
77 77
78 spin_lock(&clp->cl_lock);
79 if (clp->cl_machine_cred != NULL) 78 if (clp->cl_machine_cred != NULL)
80 cred = get_rpccred(clp->cl_machine_cred); 79 cred = get_rpccred(clp->cl_machine_cred);
81 spin_unlock(&clp->cl_lock);
82 return cred; 80 return cred;
83} 81}
84 82
@@ -94,7 +92,7 @@ static void nfs4_clear_machine_cred(struct nfs_client *clp)
94 put_rpccred(cred); 92 put_rpccred(cred);
95} 93}
96 94
97struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp) 95struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
98{ 96{
99 struct nfs4_state_owner *sp; 97 struct nfs4_state_owner *sp;
100 struct rb_node *pos; 98 struct rb_node *pos;
@@ -110,13 +108,24 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
110 return cred; 108 return cred;
111} 109}
112 110
111static struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
112{
113 struct rpc_cred *cred;
114
115 spin_lock(&clp->cl_lock);
116 cred = nfs4_get_renew_cred_locked(clp);
117 spin_unlock(&clp->cl_lock);
118 return cred;
119}
120
113static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) 121static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
114{ 122{
115 struct nfs4_state_owner *sp; 123 struct nfs4_state_owner *sp;
116 struct rb_node *pos; 124 struct rb_node *pos;
117 struct rpc_cred *cred; 125 struct rpc_cred *cred;
118 126
119 cred = nfs4_get_machine_cred(clp); 127 spin_lock(&clp->cl_lock);
128 cred = nfs4_get_machine_cred_locked(clp);
120 if (cred != NULL) 129 if (cred != NULL)
121 goto out; 130 goto out;
122 pos = rb_first(&clp->cl_state_owners); 131 pos = rb_first(&clp->cl_state_owners);
@@ -125,6 +134,7 @@ static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
125 cred = get_rpccred(sp->so_cred); 134 cred = get_rpccred(sp->so_cred);
126 } 135 }
127out: 136out:
137 spin_unlock(&clp->cl_lock);
128 return cred; 138 return cred;
129} 139}
130 140
@@ -295,10 +305,6 @@ nfs4_drop_state_owner(struct nfs4_state_owner *sp)
295 } 305 }
296} 306}
297 307
298/*
299 * Note: must be called with clp->cl_sem held in order to prevent races
300 * with reboot recovery!
301 */
302struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) 308struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred)
303{ 309{
304 struct nfs_client *clp = server->nfs_client; 310 struct nfs_client *clp = server->nfs_client;
@@ -327,10 +333,6 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
327 return sp; 333 return sp;
328} 334}
329 335
330/*
331 * Must be called with clp->cl_sem held in order to avoid races
332 * with state recovery...
333 */
334void nfs4_put_state_owner(struct nfs4_state_owner *sp) 336void nfs4_put_state_owner(struct nfs4_state_owner *sp)
335{ 337{
336 struct nfs_client *clp = sp->so_client; 338 struct nfs_client *clp = sp->so_client;
@@ -361,18 +363,18 @@ nfs4_alloc_open_state(void)
361} 363}
362 364
363void 365void
364nfs4_state_set_mode_locked(struct nfs4_state *state, mode_t mode) 366nfs4_state_set_mode_locked(struct nfs4_state *state, fmode_t fmode)
365{ 367{
366 if (state->state == mode) 368 if (state->state == fmode)
367 return; 369 return;
368 /* NB! List reordering - see the reclaim code for why. */ 370 /* NB! List reordering - see the reclaim code for why. */
369 if ((mode & FMODE_WRITE) != (state->state & FMODE_WRITE)) { 371 if ((fmode & FMODE_WRITE) != (state->state & FMODE_WRITE)) {
370 if (mode & FMODE_WRITE) 372 if (fmode & FMODE_WRITE)
371 list_move(&state->open_states, &state->owner->so_states); 373 list_move(&state->open_states, &state->owner->so_states);
372 else 374 else
373 list_move_tail(&state->open_states, &state->owner->so_states); 375 list_move_tail(&state->open_states, &state->owner->so_states);
374 } 376 }
375 state->state = mode; 377 state->state = fmode;
376} 378}
377 379
378static struct nfs4_state * 380static struct nfs4_state *
@@ -432,10 +434,6 @@ out:
432 return state; 434 return state;
433} 435}
434 436
435/*
436 * Beware! Caller must be holding exactly one
437 * reference to clp->cl_sem!
438 */
439void nfs4_put_open_state(struct nfs4_state *state) 437void nfs4_put_open_state(struct nfs4_state *state)
440{ 438{
441 struct inode *inode = state->inode; 439 struct inode *inode = state->inode;
@@ -456,16 +454,16 @@ void nfs4_put_open_state(struct nfs4_state *state)
456/* 454/*
457 * Close the current file. 455 * Close the current file.
458 */ 456 */
459static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mode, int wait) 457static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fmode, int wait)
460{ 458{
461 struct nfs4_state_owner *owner = state->owner; 459 struct nfs4_state_owner *owner = state->owner;
462 int call_close = 0; 460 int call_close = 0;
463 int newstate; 461 fmode_t newstate;
464 462
465 atomic_inc(&owner->so_count); 463 atomic_inc(&owner->so_count);
466 /* Protect against nfs4_find_state() */ 464 /* Protect against nfs4_find_state() */
467 spin_lock(&owner->so_lock); 465 spin_lock(&owner->so_lock);
468 switch (mode & (FMODE_READ | FMODE_WRITE)) { 466 switch (fmode & (FMODE_READ | FMODE_WRITE)) {
469 case FMODE_READ: 467 case FMODE_READ:
470 state->n_rdonly--; 468 state->n_rdonly--;
471 break; 469 break;
@@ -500,14 +498,14 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mod
500 nfs4_do_close(path, state, wait); 498 nfs4_do_close(path, state, wait);
501} 499}
502 500
503void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode) 501void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode)
504{ 502{
505 __nfs4_close(path, state, mode, 0); 503 __nfs4_close(path, state, fmode, 0);
506} 504}
507 505
508void nfs4_close_sync(struct path *path, struct nfs4_state *state, mode_t mode) 506void nfs4_close_sync(struct path *path, struct nfs4_state *state, fmode_t fmode)
509{ 507{
510 __nfs4_close(path, state, mode, 1); 508 __nfs4_close(path, state, fmode, 1);
511} 509}
512 510
513/* 511/*
@@ -568,7 +566,6 @@ static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
568 * Return a compatible lock_state. If no initialized lock_state structure 566 * Return a compatible lock_state. If no initialized lock_state structure
569 * exists, return an uninitialized one. 567 * exists, return an uninitialized one.
570 * 568 *
571 * The caller must be holding clp->cl_sem
572 */ 569 */
573static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) 570static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
574{ 571{
@@ -770,32 +767,34 @@ unlock:
770 return status; 767 return status;
771} 768}
772 769
773static int reclaimer(void *); 770static int nfs4_run_state_manager(void *);
774 771
775static inline void nfs4_clear_recover_bit(struct nfs_client *clp) 772static void nfs4_clear_state_manager_bit(struct nfs_client *clp)
776{ 773{
777 smp_mb__before_clear_bit(); 774 smp_mb__before_clear_bit();
778 clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); 775 clear_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state);
779 smp_mb__after_clear_bit(); 776 smp_mb__after_clear_bit();
780 wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER); 777 wake_up_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING);
781 rpc_wake_up(&clp->cl_rpcwaitq); 778 rpc_wake_up(&clp->cl_rpcwaitq);
782} 779}
783 780
784/* 781/*
785 * State recovery routine 782 * Schedule the nfs_client asynchronous state management routine
786 */ 783 */
787static void nfs4_recover_state(struct nfs_client *clp) 784void nfs4_schedule_state_manager(struct nfs_client *clp)
788{ 785{
789 struct task_struct *task; 786 struct task_struct *task;
790 787
788 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
789 return;
791 __module_get(THIS_MODULE); 790 __module_get(THIS_MODULE);
792 atomic_inc(&clp->cl_count); 791 atomic_inc(&clp->cl_count);
793 task = kthread_run(reclaimer, clp, "%s-reclaim", 792 task = kthread_run(nfs4_run_state_manager, clp, "%s-manager",
794 rpc_peeraddr2str(clp->cl_rpcclient, 793 rpc_peeraddr2str(clp->cl_rpcclient,
795 RPC_DISPLAY_ADDR)); 794 RPC_DISPLAY_ADDR));
796 if (!IS_ERR(task)) 795 if (!IS_ERR(task))
797 return; 796 return;
798 nfs4_clear_recover_bit(clp); 797 nfs4_clear_state_manager_bit(clp);
799 nfs_put_client(clp); 798 nfs_put_client(clp);
800 module_put(THIS_MODULE); 799 module_put(THIS_MODULE);
801} 800}
@@ -807,16 +806,42 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp)
807{ 806{
808 if (!clp) 807 if (!clp)
809 return; 808 return;
810 if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) 809 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
811 nfs4_recover_state(clp); 810 set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
811 nfs4_schedule_state_manager(clp);
812} 812}
813 813
814static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state) 814static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
815{
816
817 set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
818 /* Don't recover state that expired before the reboot */
819 if (test_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags)) {
820 clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
821 return 0;
822 }
823 set_bit(NFS_OWNER_RECLAIM_REBOOT, &state->owner->so_flags);
824 set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
825 return 1;
826}
827
828int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state)
829{
830 set_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags);
831 clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
832 set_bit(NFS_OWNER_RECLAIM_NOGRACE, &state->owner->so_flags);
833 set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
834 return 1;
835}
836
837static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)
815{ 838{
816 struct inode *inode = state->inode; 839 struct inode *inode = state->inode;
840 struct nfs_inode *nfsi = NFS_I(inode);
817 struct file_lock *fl; 841 struct file_lock *fl;
818 int status = 0; 842 int status = 0;
819 843
844 down_write(&nfsi->rwsem);
820 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 845 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
821 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) 846 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
822 continue; 847 continue;
@@ -839,12 +864,14 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
839 goto out_err; 864 goto out_err;
840 } 865 }
841 } 866 }
867 up_write(&nfsi->rwsem);
842 return 0; 868 return 0;
843out_err: 869out_err:
870 up_write(&nfsi->rwsem);
844 return status; 871 return status;
845} 872}
846 873
847static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct nfs4_state_owner *sp) 874static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs4_state_recovery_ops *ops)
848{ 875{
849 struct nfs4_state *state; 876 struct nfs4_state *state;
850 struct nfs4_lock_state *lock; 877 struct nfs4_lock_state *lock;
@@ -858,28 +885,34 @@ static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct n
858 * recovering after a network partition or a reboot from a 885 * recovering after a network partition or a reboot from a
859 * server that doesn't support a grace period. 886 * server that doesn't support a grace period.
860 */ 887 */
888restart:
889 spin_lock(&sp->so_lock);
861 list_for_each_entry(state, &sp->so_states, open_states) { 890 list_for_each_entry(state, &sp->so_states, open_states) {
891 if (!test_and_clear_bit(ops->state_flag_bit, &state->flags))
892 continue;
862 if (state->state == 0) 893 if (state->state == 0)
863 continue; 894 continue;
895 atomic_inc(&state->count);
896 spin_unlock(&sp->so_lock);
864 status = ops->recover_open(sp, state); 897 status = ops->recover_open(sp, state);
865 if (status >= 0) { 898 if (status >= 0) {
866 status = nfs4_reclaim_locks(ops, state); 899 status = nfs4_reclaim_locks(state, ops);
867 if (status < 0) 900 if (status >= 0) {
868 goto out_err; 901 list_for_each_entry(lock, &state->lock_states, ls_locks) {
869 list_for_each_entry(lock, &state->lock_states, ls_locks) { 902 if (!(lock->ls_flags & NFS_LOCK_INITIALIZED))
870 if (!(lock->ls_flags & NFS_LOCK_INITIALIZED)) 903 printk("%s: Lock reclaim failed!\n",
871 printk("%s: Lock reclaim failed!\n",
872 __func__); 904 __func__);
905 }
906 nfs4_put_open_state(state);
907 goto restart;
873 } 908 }
874 continue;
875 } 909 }
876 switch (status) { 910 switch (status) {
877 default: 911 default:
878 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", 912 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
879 __func__, status); 913 __func__, status);
880 case -ENOENT: 914 case -ENOENT:
881 case -NFS4ERR_RECLAIM_BAD: 915 case -ESTALE:
882 case -NFS4ERR_RECLAIM_CONFLICT:
883 /* 916 /*
884 * Open state on this file cannot be recovered 917 * Open state on this file cannot be recovered
885 * All we can do is revert to using the zero stateid. 918 * All we can do is revert to using the zero stateid.
@@ -889,84 +922,176 @@ static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct n
889 /* Mark the file as being 'closed' */ 922 /* Mark the file as being 'closed' */
890 state->state = 0; 923 state->state = 0;
891 break; 924 break;
925 case -NFS4ERR_RECLAIM_BAD:
926 case -NFS4ERR_RECLAIM_CONFLICT:
927 nfs4_state_mark_reclaim_nograce(sp->so_client, state);
928 break;
892 case -NFS4ERR_EXPIRED: 929 case -NFS4ERR_EXPIRED:
893 case -NFS4ERR_NO_GRACE: 930 case -NFS4ERR_NO_GRACE:
931 nfs4_state_mark_reclaim_nograce(sp->so_client, state);
894 case -NFS4ERR_STALE_CLIENTID: 932 case -NFS4ERR_STALE_CLIENTID:
895 goto out_err; 933 goto out_err;
896 } 934 }
935 nfs4_put_open_state(state);
936 goto restart;
897 } 937 }
938 spin_unlock(&sp->so_lock);
898 return 0; 939 return 0;
899out_err: 940out_err:
941 nfs4_put_open_state(state);
900 return status; 942 return status;
901} 943}
902 944
903static void nfs4_state_mark_reclaim(struct nfs_client *clp) 945static void nfs4_clear_open_state(struct nfs4_state *state)
946{
947 struct nfs4_lock_state *lock;
948
949 clear_bit(NFS_DELEGATED_STATE, &state->flags);
950 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
951 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
952 clear_bit(NFS_O_RDWR_STATE, &state->flags);
953 list_for_each_entry(lock, &state->lock_states, ls_locks) {
954 lock->ls_seqid.flags = 0;
955 lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
956 }
957}
958
959static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp, int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state))
904{ 960{
905 struct nfs4_state_owner *sp; 961 struct nfs4_state_owner *sp;
906 struct rb_node *pos; 962 struct rb_node *pos;
907 struct nfs4_state *state; 963 struct nfs4_state *state;
908 struct nfs4_lock_state *lock;
909 964
910 /* Reset all sequence ids to zero */ 965 /* Reset all sequence ids to zero */
911 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 966 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
912 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 967 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
913 sp->so_seqid.counter = 0;
914 sp->so_seqid.flags = 0; 968 sp->so_seqid.flags = 0;
915 spin_lock(&sp->so_lock); 969 spin_lock(&sp->so_lock);
916 list_for_each_entry(state, &sp->so_states, open_states) { 970 list_for_each_entry(state, &sp->so_states, open_states) {
917 clear_bit(NFS_DELEGATED_STATE, &state->flags); 971 if (mark_reclaim(clp, state))
918 clear_bit(NFS_O_RDONLY_STATE, &state->flags); 972 nfs4_clear_open_state(state);
919 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
920 clear_bit(NFS_O_RDWR_STATE, &state->flags);
921 list_for_each_entry(lock, &state->lock_states, ls_locks) {
922 lock->ls_seqid.counter = 0;
923 lock->ls_seqid.flags = 0;
924 lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
925 }
926 } 973 }
927 spin_unlock(&sp->so_lock); 974 spin_unlock(&sp->so_lock);
928 } 975 }
929} 976}
930 977
931static int reclaimer(void *ptr) 978static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
979{
980 /* Mark all delegations for reclaim */
981 nfs_delegation_mark_reclaim(clp);
982 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
983}
984
985static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
932{ 986{
933 struct nfs_client *clp = ptr;
934 struct nfs4_state_owner *sp; 987 struct nfs4_state_owner *sp;
935 struct rb_node *pos; 988 struct rb_node *pos;
936 struct nfs4_state_recovery_ops *ops; 989 struct nfs4_state *state;
937 struct rpc_cred *cred; 990
991 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
992 return;
993
994 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
995 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
996 spin_lock(&sp->so_lock);
997 list_for_each_entry(state, &sp->so_states, open_states) {
998 if (!test_and_clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags))
999 continue;
1000 nfs4_state_mark_reclaim_nograce(clp, state);
1001 }
1002 spin_unlock(&sp->so_lock);
1003 }
1004
1005 nfs_delegation_reap_unclaimed(clp);
1006}
1007
1008static void nfs_delegation_clear_all(struct nfs_client *clp)
1009{
1010 nfs_delegation_mark_reclaim(clp);
1011 nfs_delegation_reap_unclaimed(clp);
1012}
1013
1014static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp)
1015{
1016 nfs_delegation_clear_all(clp);
1017 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce);
1018}
1019
1020static void nfs4_state_end_reclaim_nograce(struct nfs_client *clp)
1021{
1022 clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1023}
1024
1025static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1026{
1027 switch (error) {
1028 case -NFS4ERR_CB_PATH_DOWN:
1029 nfs_handle_cb_pathdown(clp);
1030 break;
1031 case -NFS4ERR_STALE_CLIENTID:
1032 case -NFS4ERR_LEASE_MOVED:
1033 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1034 nfs4_state_start_reclaim_reboot(clp);
1035 break;
1036 case -NFS4ERR_EXPIRED:
1037 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1038 nfs4_state_start_reclaim_nograce(clp);
1039 }
1040}
1041
1042static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops)
1043{
1044 struct rb_node *pos;
938 int status = 0; 1045 int status = 0;
939 1046
940 allow_signal(SIGKILL); 1047restart:
1048 spin_lock(&clp->cl_lock);
1049 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
1050 struct nfs4_state_owner *sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
1051 if (!test_and_clear_bit(ops->owner_flag_bit, &sp->so_flags))
1052 continue;
1053 atomic_inc(&sp->so_count);
1054 spin_unlock(&clp->cl_lock);
1055 status = nfs4_reclaim_open_state(sp, ops);
1056 if (status < 0) {
1057 set_bit(ops->owner_flag_bit, &sp->so_flags);
1058 nfs4_put_state_owner(sp);
1059 nfs4_recovery_handle_error(clp, status);
1060 return status;
1061 }
1062 nfs4_put_state_owner(sp);
1063 goto restart;
1064 }
1065 spin_unlock(&clp->cl_lock);
1066 return status;
1067}
941 1068
942 /* Ensure exclusive access to NFSv4 state */ 1069static int nfs4_check_lease(struct nfs_client *clp)
943 down_write(&clp->cl_sem); 1070{
944 /* Are there any NFS mounts out there? */ 1071 struct rpc_cred *cred;
945 if (list_empty(&clp->cl_superblocks)) 1072 int status = -NFS4ERR_EXPIRED;
946 goto out; 1073
947restart_loop: 1074 /* Is the client already known to have an expired lease? */
948 ops = &nfs4_network_partition_recovery_ops; 1075 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
949 /* Are there any open files on this volume? */ 1076 return 0;
950 cred = nfs4_get_renew_cred(clp); 1077 cred = nfs4_get_renew_cred(clp);
951 if (cred != NULL) { 1078 if (cred == NULL) {
952 /* Yes there are: try to renew the old lease */ 1079 cred = nfs4_get_setclientid_cred(clp);
953 status = nfs4_proc_renew(clp, cred); 1080 if (cred == NULL)
954 put_rpccred(cred); 1081 goto out;
955 switch (status) {
956 case 0:
957 case -NFS4ERR_CB_PATH_DOWN:
958 goto out;
959 case -NFS4ERR_STALE_CLIENTID:
960 case -NFS4ERR_LEASE_MOVED:
961 ops = &nfs4_reboot_recovery_ops;
962 }
963 } else {
964 /* "reboot" to ensure we clear all state on the server */
965 clp->cl_boot_time = CURRENT_TIME;
966 } 1082 }
967 /* We're going to have to re-establish a clientid */ 1083 status = nfs4_proc_renew(clp, cred);
968 nfs4_state_mark_reclaim(clp); 1084 put_rpccred(cred);
969 status = -ENOENT; 1085out:
1086 nfs4_recovery_handle_error(clp, status);
1087 return status;
1088}
1089
1090static int nfs4_reclaim_lease(struct nfs_client *clp)
1091{
1092 struct rpc_cred *cred;
1093 int status = -ENOENT;
1094
970 cred = nfs4_get_setclientid_cred(clp); 1095 cred = nfs4_get_setclientid_cred(clp);
971 if (cred != NULL) { 1096 if (cred != NULL) {
972 status = nfs4_init_client(clp, cred); 1097 status = nfs4_init_client(clp, cred);
@@ -974,42 +1099,90 @@ restart_loop:
974 /* Handle case where the user hasn't set up machine creds */ 1099 /* Handle case where the user hasn't set up machine creds */
975 if (status == -EACCES && cred == clp->cl_machine_cred) { 1100 if (status == -EACCES && cred == clp->cl_machine_cred) {
976 nfs4_clear_machine_cred(clp); 1101 nfs4_clear_machine_cred(clp);
977 goto restart_loop; 1102 status = -EAGAIN;
978 } 1103 }
979 } 1104 }
980 if (status) 1105 return status;
981 goto out_error; 1106}
982 /* Mark all delegations for reclaim */ 1107
983 nfs_delegation_mark_reclaim(clp); 1108static void nfs4_state_manager(struct nfs_client *clp)
984 /* Note: list is protected by exclusive lock on cl->cl_sem */ 1109{
985 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1110 int status = 0;
986 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1111
987 status = nfs4_reclaim_open_state(ops, sp); 1112 /* Ensure exclusive access to NFSv4 state */
988 if (status < 0) { 1113 for(;;) {
989 if (status == -NFS4ERR_NO_GRACE) { 1114 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
990 ops = &nfs4_network_partition_recovery_ops; 1115 /* We're going to have to re-establish a clientid */
991 status = nfs4_reclaim_open_state(ops, sp); 1116 status = nfs4_reclaim_lease(clp);
1117 if (status) {
1118 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1119 if (status == -EAGAIN)
1120 continue;
1121 goto out_error;
992 } 1122 }
1123 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1124 }
1125
1126 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
1127 status = nfs4_check_lease(clp);
1128 if (status != 0)
1129 continue;
1130 }
1131
1132 /* First recover reboot state... */
1133 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
1134 status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops);
993 if (status == -NFS4ERR_STALE_CLIENTID) 1135 if (status == -NFS4ERR_STALE_CLIENTID)
994 goto restart_loop; 1136 continue;
995 if (status == -NFS4ERR_EXPIRED) 1137 nfs4_state_end_reclaim_reboot(clp);
996 goto restart_loop; 1138 continue;
1139 }
1140
1141 /* Now recover expired state... */
1142 if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
1143 status = nfs4_do_reclaim(clp, &nfs4_nograce_recovery_ops);
1144 if (status < 0) {
1145 set_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1146 if (status == -NFS4ERR_STALE_CLIENTID)
1147 continue;
1148 if (status == -NFS4ERR_EXPIRED)
1149 continue;
1150 goto out_error;
1151 } else
1152 nfs4_state_end_reclaim_nograce(clp);
1153 continue;
997 } 1154 }
1155
1156 if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) {
1157 nfs_client_return_marked_delegations(clp);
1158 continue;
1159 }
1160
1161 nfs4_clear_state_manager_bit(clp);
1162 /* Did we race with an attempt to give us more work? */
1163 if (clp->cl_state == 0)
1164 break;
1165 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
1166 break;
998 } 1167 }
999 nfs_delegation_reap_unclaimed(clp); 1168 return;
1000out: 1169out_error:
1001 up_write(&clp->cl_sem); 1170 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
1002 if (status == -NFS4ERR_CB_PATH_DOWN) 1171 " with error %d\n", clp->cl_hostname, -status);
1003 nfs_handle_cb_pathdown(clp); 1172 if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1004 nfs4_clear_recover_bit(clp); 1173 nfs4_state_end_reclaim_reboot(clp);
1174 nfs4_clear_state_manager_bit(clp);
1175}
1176
1177static int nfs4_run_state_manager(void *ptr)
1178{
1179 struct nfs_client *clp = ptr;
1180
1181 allow_signal(SIGKILL);
1182 nfs4_state_manager(clp);
1005 nfs_put_client(clp); 1183 nfs_put_client(clp);
1006 module_put_and_exit(0); 1184 module_put_and_exit(0);
1007 return 0; 1185 return 0;
1008out_error:
1009 printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %s"
1010 " with error %d\n", clp->cl_hostname, -status);
1011 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1012 goto out;
1013} 1186}
1014 1187
1015/* 1188/*
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index b916297d2334..d1e4c8f8a0a9 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Kendrick Smith <kmsmith@umich.edu> 9 * Kendrick Smith <kmsmith@umich.edu>
10 * Andy Adamson <andros@umich.edu> 10 * Andy Adamson <andros@umich.edu>
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -67,7 +67,7 @@ static int nfs4_stat_to_errno(int);
67#define NFS4_MAXTAGLEN 0 67#define NFS4_MAXTAGLEN 0
68#endif 68#endif
69 69
70/* lock,open owner id: 70/* lock,open owner id:
71 * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2) 71 * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2)
72 */ 72 */
73#define open_owner_id_maxsz (1 + 4) 73#define open_owner_id_maxsz (1 + 4)
@@ -541,6 +541,7 @@ static struct {
541struct compound_hdr { 541struct compound_hdr {
542 int32_t status; 542 int32_t status;
543 uint32_t nops; 543 uint32_t nops;
544 __be32 * nops_p;
544 uint32_t taglen; 545 uint32_t taglen;
545 char * tag; 546 char * tag;
546}; 547};
@@ -578,7 +579,7 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *
578 xdr_encode_opaque(p, str, len); 579 xdr_encode_opaque(p, str, len);
579} 580}
580 581
581static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) 582static void encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
582{ 583{
583 __be32 *p; 584 __be32 *p;
584 585
@@ -588,8 +589,13 @@ static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
588 WRITE32(hdr->taglen); 589 WRITE32(hdr->taglen);
589 WRITEMEM(hdr->tag, hdr->taglen); 590 WRITEMEM(hdr->tag, hdr->taglen);
590 WRITE32(NFS4_MINOR_VERSION); 591 WRITE32(NFS4_MINOR_VERSION);
592 hdr->nops_p = p;
591 WRITE32(hdr->nops); 593 WRITE32(hdr->nops);
592 return 0; 594}
595
596static void encode_nops(struct compound_hdr *hdr)
597{
598 *hdr->nops_p = htonl(hdr->nops);
593} 599}
594 600
595static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf) 601static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf)
@@ -601,7 +607,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
601 xdr_encode_opaque_fixed(p, verf->data, NFS4_VERIFIER_SIZE); 607 xdr_encode_opaque_fixed(p, verf->data, NFS4_VERIFIER_SIZE);
602} 608}
603 609
604static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server) 610static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server)
605{ 611{
606 char owner_name[IDMAP_NAMESZ]; 612 char owner_name[IDMAP_NAMESZ];
607 char owner_group[IDMAP_NAMESZ]; 613 char owner_group[IDMAP_NAMESZ];
@@ -612,7 +618,6 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
612 int len; 618 int len;
613 uint32_t bmval0 = 0; 619 uint32_t bmval0 = 0;
614 uint32_t bmval1 = 0; 620 uint32_t bmval1 = 0;
615 int status;
616 621
617 /* 622 /*
618 * We reserve enough space to write the entire attribute buffer at once. 623 * We reserve enough space to write the entire attribute buffer at once.
@@ -709,7 +714,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
709 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET; 714 bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
710 WRITE32(NFS4_SET_TO_SERVER_TIME); 715 WRITE32(NFS4_SET_TO_SERVER_TIME);
711 } 716 }
712 717
713 /* 718 /*
714 * Now we backfill the bitmap and the attribute buffer length. 719 * Now we backfill the bitmap and the attribute buffer length.
715 */ 720 */
@@ -723,23 +728,20 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
723 *q++ = htonl(bmval1); 728 *q++ = htonl(bmval1);
724 *q++ = htonl(len); 729 *q++ = htonl(len);
725 730
726 status = 0;
727/* out: */ 731/* out: */
728 return status;
729} 732}
730 733
731static int encode_access(struct xdr_stream *xdr, u32 access) 734static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hdr *hdr)
732{ 735{
733 __be32 *p; 736 __be32 *p;
734 737
735 RESERVE_SPACE(8); 738 RESERVE_SPACE(8);
736 WRITE32(OP_ACCESS); 739 WRITE32(OP_ACCESS);
737 WRITE32(access); 740 WRITE32(access);
738 741 hdr->nops++;
739 return 0;
740} 742}
741 743
742static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg) 744static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
743{ 745{
744 __be32 *p; 746 __be32 *p;
745 747
@@ -747,26 +749,24 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
747 WRITE32(OP_CLOSE); 749 WRITE32(OP_CLOSE);
748 WRITE32(arg->seqid->sequence->counter); 750 WRITE32(arg->seqid->sequence->counter);
749 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); 751 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
750 752 hdr->nops++;
751 return 0;
752} 753}
753 754
754static int encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args) 755static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
755{ 756{
756 __be32 *p; 757 __be32 *p;
757
758 RESERVE_SPACE(16);
759 WRITE32(OP_COMMIT);
760 WRITE64(args->offset);
761 WRITE32(args->count);
762 758
763 return 0; 759 RESERVE_SPACE(16);
760 WRITE32(OP_COMMIT);
761 WRITE64(args->offset);
762 WRITE32(args->count);
763 hdr->nops++;
764} 764}
765 765
766static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create) 766static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr)
767{ 767{
768 __be32 *p; 768 __be32 *p;
769 769
770 RESERVE_SPACE(8); 770 RESERVE_SPACE(8);
771 WRITE32(OP_CREATE); 771 WRITE32(OP_CREATE);
772 WRITE32(create->ftype); 772 WRITE32(create->ftype);
@@ -791,64 +791,62 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *c
791 RESERVE_SPACE(4 + create->name->len); 791 RESERVE_SPACE(4 + create->name->len);
792 WRITE32(create->name->len); 792 WRITE32(create->name->len);
793 WRITEMEM(create->name->name, create->name->len); 793 WRITEMEM(create->name->name, create->name->len);
794 hdr->nops++;
794 795
795 return encode_attrs(xdr, create->attrs, create->server); 796 encode_attrs(xdr, create->attrs, create->server);
796} 797}
797 798
798static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap) 799static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr)
799{ 800{
800 __be32 *p; 801 __be32 *p;
801 802
802 RESERVE_SPACE(12); 803 RESERVE_SPACE(12);
803 WRITE32(OP_GETATTR); 804 WRITE32(OP_GETATTR);
804 WRITE32(1); 805 WRITE32(1);
805 WRITE32(bitmap); 806 WRITE32(bitmap);
806 return 0; 807 hdr->nops++;
807} 808}
808 809
809static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1) 810static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr)
810{ 811{
811 __be32 *p; 812 __be32 *p;
812 813
813 RESERVE_SPACE(16); 814 RESERVE_SPACE(16);
814 WRITE32(OP_GETATTR); 815 WRITE32(OP_GETATTR);
815 WRITE32(2); 816 WRITE32(2);
816 WRITE32(bm0); 817 WRITE32(bm0);
817 WRITE32(bm1); 818 WRITE32(bm1);
818 return 0; 819 hdr->nops++;
819} 820}
820 821
821static int encode_getfattr(struct xdr_stream *xdr, const u32* bitmask) 822static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
822{ 823{
823 return encode_getattr_two(xdr, 824 encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0],
824 bitmask[0] & nfs4_fattr_bitmap[0], 825 bitmask[1] & nfs4_fattr_bitmap[1], hdr);
825 bitmask[1] & nfs4_fattr_bitmap[1]);
826} 826}
827 827
828static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask) 828static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
829{ 829{
830 return encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0], 830 encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0],
831 bitmask[1] & nfs4_fsinfo_bitmap[1]); 831 bitmask[1] & nfs4_fsinfo_bitmap[1], hdr);
832} 832}
833 833
834static int encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask) 834static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
835{ 835{
836 return encode_getattr_two(xdr, 836 encode_getattr_two(xdr, bitmask[0] & nfs4_fs_locations_bitmap[0],
837 bitmask[0] & nfs4_fs_locations_bitmap[0], 837 bitmask[1] & nfs4_fs_locations_bitmap[1], hdr);
838 bitmask[1] & nfs4_fs_locations_bitmap[1]);
839} 838}
840 839
841static int encode_getfh(struct xdr_stream *xdr) 840static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
842{ 841{
843 __be32 *p; 842 __be32 *p;
844 843
845 RESERVE_SPACE(4); 844 RESERVE_SPACE(4);
846 WRITE32(OP_GETFH); 845 WRITE32(OP_GETFH);
847 846 hdr->nops++;
848 return 0;
849} 847}
850 848
851static int encode_link(struct xdr_stream *xdr, const struct qstr *name) 849static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
852{ 850{
853 __be32 *p; 851 __be32 *p;
854 852
@@ -856,8 +854,7 @@ static int encode_link(struct xdr_stream *xdr, const struct qstr *name)
856 WRITE32(OP_LINK); 854 WRITE32(OP_LINK);
857 WRITE32(name->len); 855 WRITE32(name->len);
858 WRITEMEM(name->name, name->len); 856 WRITEMEM(name->name, name->len);
859 857 hdr->nops++;
860 return 0;
861} 858}
862 859
863static inline int nfs4_lock_type(struct file_lock *fl, int block) 860static inline int nfs4_lock_type(struct file_lock *fl, int block)
@@ -878,7 +875,7 @@ static inline uint64_t nfs4_lock_length(struct file_lock *fl)
878 * opcode,type,reclaim,offset,length,new_lock_owner = 32 875 * opcode,type,reclaim,offset,length,new_lock_owner = 32
879 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 876 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
880 */ 877 */
881static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args) 878static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args, struct compound_hdr *hdr)
882{ 879{
883 __be32 *p; 880 __be32 *p;
884 881
@@ -904,11 +901,10 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
904 WRITEMEM(args->lock_stateid->data, NFS4_STATEID_SIZE); 901 WRITEMEM(args->lock_stateid->data, NFS4_STATEID_SIZE);
905 WRITE32(args->lock_seqid->sequence->counter); 902 WRITE32(args->lock_seqid->sequence->counter);
906 } 903 }
907 904 hdr->nops++;
908 return 0;
909} 905}
910 906
911static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args) 907static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr)
912{ 908{
913 __be32 *p; 909 __be32 *p;
914 910
@@ -921,11 +917,10 @@ static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *arg
921 WRITE32(16); 917 WRITE32(16);
922 WRITEMEM("lock id:", 8); 918 WRITEMEM("lock id:", 8);
923 WRITE64(args->lock_owner.id); 919 WRITE64(args->lock_owner.id);
924 920 hdr->nops++;
925 return 0;
926} 921}
927 922
928static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args) 923static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr)
929{ 924{
930 __be32 *p; 925 __be32 *p;
931 926
@@ -936,11 +931,10 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *arg
936 WRITEMEM(args->stateid->data, NFS4_STATEID_SIZE); 931 WRITEMEM(args->stateid->data, NFS4_STATEID_SIZE);
937 WRITE64(args->fl->fl_start); 932 WRITE64(args->fl->fl_start);
938 WRITE64(nfs4_lock_length(args->fl)); 933 WRITE64(nfs4_lock_length(args->fl));
939 934 hdr->nops++;
940 return 0;
941} 935}
942 936
943static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name) 937static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
944{ 938{
945 int len = name->len; 939 int len = name->len;
946 __be32 *p; 940 __be32 *p;
@@ -949,27 +943,26 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
949 WRITE32(OP_LOOKUP); 943 WRITE32(OP_LOOKUP);
950 WRITE32(len); 944 WRITE32(len);
951 WRITEMEM(name->name, len); 945 WRITEMEM(name->name, len);
952 946 hdr->nops++;
953 return 0;
954} 947}
955 948
956static void encode_share_access(struct xdr_stream *xdr, int open_flags) 949static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode)
957{ 950{
958 __be32 *p; 951 __be32 *p;
959 952
960 RESERVE_SPACE(8); 953 RESERVE_SPACE(8);
961 switch (open_flags & (FMODE_READ|FMODE_WRITE)) { 954 switch (fmode & (FMODE_READ|FMODE_WRITE)) {
962 case FMODE_READ: 955 case FMODE_READ:
963 WRITE32(NFS4_SHARE_ACCESS_READ); 956 WRITE32(NFS4_SHARE_ACCESS_READ);
964 break; 957 break;
965 case FMODE_WRITE: 958 case FMODE_WRITE:
966 WRITE32(NFS4_SHARE_ACCESS_WRITE); 959 WRITE32(NFS4_SHARE_ACCESS_WRITE);
967 break; 960 break;
968 case FMODE_READ|FMODE_WRITE: 961 case FMODE_READ|FMODE_WRITE:
969 WRITE32(NFS4_SHARE_ACCESS_BOTH); 962 WRITE32(NFS4_SHARE_ACCESS_BOTH);
970 break; 963 break;
971 default: 964 default:
972 BUG(); 965 WRITE32(0);
973 } 966 }
974 WRITE32(0); /* for linux, share_deny = 0 always */ 967 WRITE32(0); /* for linux, share_deny = 0 always */
975} 968}
@@ -984,7 +977,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
984 RESERVE_SPACE(8); 977 RESERVE_SPACE(8);
985 WRITE32(OP_OPEN); 978 WRITE32(OP_OPEN);
986 WRITE32(arg->seqid->sequence->counter); 979 WRITE32(arg->seqid->sequence->counter);
987 encode_share_access(xdr, arg->open_flags); 980 encode_share_access(xdr, arg->fmode);
988 RESERVE_SPACE(28); 981 RESERVE_SPACE(28);
989 WRITE64(arg->clientid); 982 WRITE64(arg->clientid);
990 WRITE32(16); 983 WRITE32(16);
@@ -998,13 +991,13 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
998 991
999 RESERVE_SPACE(4); 992 RESERVE_SPACE(4);
1000 switch(arg->open_flags & O_EXCL) { 993 switch(arg->open_flags & O_EXCL) {
1001 case 0: 994 case 0:
1002 WRITE32(NFS4_CREATE_UNCHECKED); 995 WRITE32(NFS4_CREATE_UNCHECKED);
1003 encode_attrs(xdr, arg->u.attrs, arg->server); 996 encode_attrs(xdr, arg->u.attrs, arg->server);
1004 break; 997 break;
1005 default: 998 default:
1006 WRITE32(NFS4_CREATE_EXCLUSIVE); 999 WRITE32(NFS4_CREATE_EXCLUSIVE);
1007 encode_nfs4_verifier(xdr, &arg->u.verifier); 1000 encode_nfs4_verifier(xdr, &arg->u.verifier);
1008 } 1001 }
1009} 1002}
1010 1003
@@ -1014,33 +1007,33 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a
1014 1007
1015 RESERVE_SPACE(4); 1008 RESERVE_SPACE(4);
1016 switch (arg->open_flags & O_CREAT) { 1009 switch (arg->open_flags & O_CREAT) {
1017 case 0: 1010 case 0:
1018 WRITE32(NFS4_OPEN_NOCREATE); 1011 WRITE32(NFS4_OPEN_NOCREATE);
1019 break; 1012 break;
1020 default: 1013 default:
1021 BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL); 1014 BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
1022 WRITE32(NFS4_OPEN_CREATE); 1015 WRITE32(NFS4_OPEN_CREATE);
1023 encode_createmode(xdr, arg); 1016 encode_createmode(xdr, arg);
1024 } 1017 }
1025} 1018}
1026 1019
1027static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation_type) 1020static inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delegation_type)
1028{ 1021{
1029 __be32 *p; 1022 __be32 *p;
1030 1023
1031 RESERVE_SPACE(4); 1024 RESERVE_SPACE(4);
1032 switch (delegation_type) { 1025 switch (delegation_type) {
1033 case 0: 1026 case 0:
1034 WRITE32(NFS4_OPEN_DELEGATE_NONE); 1027 WRITE32(NFS4_OPEN_DELEGATE_NONE);
1035 break; 1028 break;
1036 case FMODE_READ: 1029 case FMODE_READ:
1037 WRITE32(NFS4_OPEN_DELEGATE_READ); 1030 WRITE32(NFS4_OPEN_DELEGATE_READ);
1038 break; 1031 break;
1039 case FMODE_WRITE|FMODE_READ: 1032 case FMODE_WRITE|FMODE_READ:
1040 WRITE32(NFS4_OPEN_DELEGATE_WRITE); 1033 WRITE32(NFS4_OPEN_DELEGATE_WRITE);
1041 break; 1034 break;
1042 default: 1035 default:
1043 BUG(); 1036 BUG();
1044 } 1037 }
1045} 1038}
1046 1039
@@ -1053,7 +1046,7 @@ static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *
1053 encode_string(xdr, name->len, name->name); 1046 encode_string(xdr, name->len, name->name);
1054} 1047}
1055 1048
1056static inline void encode_claim_previous(struct xdr_stream *xdr, int type) 1049static inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type)
1057{ 1050{
1058 __be32 *p; 1051 __be32 *p;
1059 1052
@@ -1072,27 +1065,27 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc
1072 encode_string(xdr, name->len, name->name); 1065 encode_string(xdr, name->len, name->name);
1073} 1066}
1074 1067
1075static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg) 1068static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr)
1076{ 1069{
1077 encode_openhdr(xdr, arg); 1070 encode_openhdr(xdr, arg);
1078 encode_opentype(xdr, arg); 1071 encode_opentype(xdr, arg);
1079 switch (arg->claim) { 1072 switch (arg->claim) {
1080 case NFS4_OPEN_CLAIM_NULL: 1073 case NFS4_OPEN_CLAIM_NULL:
1081 encode_claim_null(xdr, arg->name); 1074 encode_claim_null(xdr, arg->name);
1082 break; 1075 break;
1083 case NFS4_OPEN_CLAIM_PREVIOUS: 1076 case NFS4_OPEN_CLAIM_PREVIOUS:
1084 encode_claim_previous(xdr, arg->u.delegation_type); 1077 encode_claim_previous(xdr, arg->u.delegation_type);
1085 break; 1078 break;
1086 case NFS4_OPEN_CLAIM_DELEGATE_CUR: 1079 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
1087 encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation); 1080 encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
1088 break; 1081 break;
1089 default: 1082 default:
1090 BUG(); 1083 BUG();
1091 } 1084 }
1092 return 0; 1085 hdr->nops++;
1093} 1086}
1094 1087
1095static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg) 1088static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr)
1096{ 1089{
1097 __be32 *p; 1090 __be32 *p;
1098 1091
@@ -1100,11 +1093,10 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
1100 WRITE32(OP_OPEN_CONFIRM); 1093 WRITE32(OP_OPEN_CONFIRM);
1101 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); 1094 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
1102 WRITE32(arg->seqid->sequence->counter); 1095 WRITE32(arg->seqid->sequence->counter);
1103 1096 hdr->nops++;
1104 return 0;
1105} 1097}
1106 1098
1107static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg) 1099static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
1108{ 1100{
1109 __be32 *p; 1101 __be32 *p;
1110 1102
@@ -1112,12 +1104,12 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
1112 WRITE32(OP_OPEN_DOWNGRADE); 1104 WRITE32(OP_OPEN_DOWNGRADE);
1113 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); 1105 WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
1114 WRITE32(arg->seqid->sequence->counter); 1106 WRITE32(arg->seqid->sequence->counter);
1115 encode_share_access(xdr, arg->open_flags); 1107 encode_share_access(xdr, arg->fmode);
1116 return 0; 1108 hdr->nops++;
1117} 1109}
1118 1110
1119static int 1111static void
1120encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh) 1112encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hdr *hdr)
1121{ 1113{
1122 int len = fh->size; 1114 int len = fh->size;
1123 __be32 *p; 1115 __be32 *p;
@@ -1126,18 +1118,16 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh)
1126 WRITE32(OP_PUTFH); 1118 WRITE32(OP_PUTFH);
1127 WRITE32(len); 1119 WRITE32(len);
1128 WRITEMEM(fh->data, len); 1120 WRITEMEM(fh->data, len);
1129 1121 hdr->nops++;
1130 return 0;
1131} 1122}
1132 1123
1133static int encode_putrootfh(struct xdr_stream *xdr) 1124static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1134{ 1125{
1135 __be32 *p; 1126 __be32 *p;
1136
1137 RESERVE_SPACE(4);
1138 WRITE32(OP_PUTROOTFH);
1139 1127
1140 return 0; 1128 RESERVE_SPACE(4);
1129 WRITE32(OP_PUTROOTFH);
1130 hdr->nops++;
1141} 1131}
1142 1132
1143static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx) 1133static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
@@ -1153,7 +1143,7 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context
1153 WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE); 1143 WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE);
1154} 1144}
1155 1145
1156static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args) 1146static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr)
1157{ 1147{
1158 __be32 *p; 1148 __be32 *p;
1159 1149
@@ -1165,11 +1155,10 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)
1165 RESERVE_SPACE(12); 1155 RESERVE_SPACE(12);
1166 WRITE64(args->offset); 1156 WRITE64(args->offset);
1167 WRITE32(args->count); 1157 WRITE32(args->count);
1168 1158 hdr->nops++;
1169 return 0;
1170} 1159}
1171 1160
1172static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req) 1161static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
1173{ 1162{
1174 uint32_t attrs[2] = { 1163 uint32_t attrs[2] = {
1175 FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID, 1164 FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
@@ -1191,6 +1180,7 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1191 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; 1180 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1192 WRITE32(attrs[0] & readdir->bitmask[0]); 1181 WRITE32(attrs[0] & readdir->bitmask[0]);
1193 WRITE32(attrs[1] & readdir->bitmask[1]); 1182 WRITE32(attrs[1] & readdir->bitmask[1]);
1183 hdr->nops++;
1194 dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", 1184 dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n",
1195 __func__, 1185 __func__,
1196 (unsigned long long)readdir->cookie, 1186 (unsigned long long)readdir->cookie,
@@ -1198,21 +1188,18 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1198 ((u32 *)readdir->verifier.data)[1], 1188 ((u32 *)readdir->verifier.data)[1],
1199 attrs[0] & readdir->bitmask[0], 1189 attrs[0] & readdir->bitmask[0],
1200 attrs[1] & readdir->bitmask[1]); 1190 attrs[1] & readdir->bitmask[1]);
1201
1202 return 0;
1203} 1191}
1204 1192
1205static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req) 1193static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr)
1206{ 1194{
1207 __be32 *p; 1195 __be32 *p;
1208 1196
1209 RESERVE_SPACE(4); 1197 RESERVE_SPACE(4);
1210 WRITE32(OP_READLINK); 1198 WRITE32(OP_READLINK);
1211 1199 hdr->nops++;
1212 return 0;
1213} 1200}
1214 1201
1215static int encode_remove(struct xdr_stream *xdr, const struct qstr *name) 1202static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
1216{ 1203{
1217 __be32 *p; 1204 __be32 *p;
1218 1205
@@ -1220,11 +1207,10 @@ static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)
1220 WRITE32(OP_REMOVE); 1207 WRITE32(OP_REMOVE);
1221 WRITE32(name->len); 1208 WRITE32(name->len);
1222 WRITEMEM(name->name, name->len); 1209 WRITEMEM(name->name, name->len);
1223 1210 hdr->nops++;
1224 return 0;
1225} 1211}
1226 1212
1227static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname) 1213static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr)
1228{ 1214{
1229 __be32 *p; 1215 __be32 *p;
1230 1216
@@ -1232,38 +1218,35 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, con
1232 WRITE32(OP_RENAME); 1218 WRITE32(OP_RENAME);
1233 WRITE32(oldname->len); 1219 WRITE32(oldname->len);
1234 WRITEMEM(oldname->name, oldname->len); 1220 WRITEMEM(oldname->name, oldname->len);
1235 1221
1236 RESERVE_SPACE(4 + newname->len); 1222 RESERVE_SPACE(4 + newname->len);
1237 WRITE32(newname->len); 1223 WRITE32(newname->len);
1238 WRITEMEM(newname->name, newname->len); 1224 WRITEMEM(newname->name, newname->len);
1239 1225 hdr->nops++;
1240 return 0;
1241} 1226}
1242 1227
1243static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid) 1228static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid, struct compound_hdr *hdr)
1244{ 1229{
1245 __be32 *p; 1230 __be32 *p;
1246 1231
1247 RESERVE_SPACE(12); 1232 RESERVE_SPACE(12);
1248 WRITE32(OP_RENEW); 1233 WRITE32(OP_RENEW);
1249 WRITE64(client_stateid->cl_clientid); 1234 WRITE64(client_stateid->cl_clientid);
1250 1235 hdr->nops++;
1251 return 0;
1252} 1236}
1253 1237
1254static int 1238static void
1255encode_restorefh(struct xdr_stream *xdr) 1239encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1256{ 1240{
1257 __be32 *p; 1241 __be32 *p;
1258 1242
1259 RESERVE_SPACE(4); 1243 RESERVE_SPACE(4);
1260 WRITE32(OP_RESTOREFH); 1244 WRITE32(OP_RESTOREFH);
1261 1245 hdr->nops++;
1262 return 0;
1263} 1246}
1264 1247
1265static int 1248static int
1266encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg) 1249encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr)
1267{ 1250{
1268 __be32 *p; 1251 __be32 *p;
1269 1252
@@ -1278,36 +1261,32 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
1278 RESERVE_SPACE(4); 1261 RESERVE_SPACE(4);
1279 WRITE32(arg->acl_len); 1262 WRITE32(arg->acl_len);
1280 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); 1263 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
1264 hdr->nops++;
1281 return 0; 1265 return 0;
1282} 1266}
1283 1267
1284static int 1268static void
1285encode_savefh(struct xdr_stream *xdr) 1269encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1286{ 1270{
1287 __be32 *p; 1271 __be32 *p;
1288 1272
1289 RESERVE_SPACE(4); 1273 RESERVE_SPACE(4);
1290 WRITE32(OP_SAVEFH); 1274 WRITE32(OP_SAVEFH);
1291 1275 hdr->nops++;
1292 return 0;
1293} 1276}
1294 1277
1295static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server) 1278static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr)
1296{ 1279{
1297 int status;
1298 __be32 *p; 1280 __be32 *p;
1299
1300 RESERVE_SPACE(4+NFS4_STATEID_SIZE);
1301 WRITE32(OP_SETATTR);
1302 WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE);
1303 1281
1304 if ((status = encode_attrs(xdr, arg->iap, server))) 1282 RESERVE_SPACE(4+NFS4_STATEID_SIZE);
1305 return status; 1283 WRITE32(OP_SETATTR);
1306 1284 WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE);
1307 return 0; 1285 hdr->nops++;
1286 encode_attrs(xdr, arg->iap, server);
1308} 1287}
1309 1288
1310static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid) 1289static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
1311{ 1290{
1312 __be32 *p; 1291 __be32 *p;
1313 1292
@@ -1322,23 +1301,21 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien
1322 encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr); 1301 encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
1323 RESERVE_SPACE(4); 1302 RESERVE_SPACE(4);
1324 WRITE32(setclientid->sc_cb_ident); 1303 WRITE32(setclientid->sc_cb_ident);
1325 1304 hdr->nops++;
1326 return 0;
1327} 1305}
1328 1306
1329static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state) 1307static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr)
1330{ 1308{
1331 __be32 *p; 1309 __be32 *p;
1332
1333 RESERVE_SPACE(12 + NFS4_VERIFIER_SIZE);
1334 WRITE32(OP_SETCLIENTID_CONFIRM);
1335 WRITE64(client_state->cl_clientid);
1336 WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
1337 1310
1338 return 0; 1311 RESERVE_SPACE(12 + NFS4_VERIFIER_SIZE);
1312 WRITE32(OP_SETCLIENTID_CONFIRM);
1313 WRITE64(client_state->cl_clientid);
1314 WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
1315 hdr->nops++;
1339} 1316}
1340 1317
1341static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args) 1318static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
1342{ 1319{
1343 __be32 *p; 1320 __be32 *p;
1344 1321
@@ -1353,11 +1330,10 @@ static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args
1353 WRITE32(args->count); 1330 WRITE32(args->count);
1354 1331
1355 xdr_write_pages(xdr, args->pages, args->pgbase, args->count); 1332 xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1356 1333 hdr->nops++;
1357 return 0;
1358} 1334}
1359 1335
1360static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid) 1336static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr)
1361{ 1337{
1362 __be32 *p; 1338 __be32 *p;
1363 1339
@@ -1365,8 +1341,7 @@ static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *statei
1365 1341
1366 WRITE32(OP_DELEGRETURN); 1342 WRITE32(OP_DELEGRETURN);
1367 WRITEMEM(stateid->data, NFS4_STATEID_SIZE); 1343 WRITEMEM(stateid->data, NFS4_STATEID_SIZE);
1368 return 0; 1344 hdr->nops++;
1369
1370} 1345}
1371/* 1346/*
1372 * END OF "GENERIC" ENCODE ROUTINES. 1347 * END OF "GENERIC" ENCODE ROUTINES.
@@ -1379,21 +1354,16 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs
1379{ 1354{
1380 struct xdr_stream xdr; 1355 struct xdr_stream xdr;
1381 struct compound_hdr hdr = { 1356 struct compound_hdr hdr = {
1382 .nops = 3, 1357 .nops = 0,
1383 }; 1358 };
1384 int status;
1385 1359
1386 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1360 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1387 encode_compound_hdr(&xdr, &hdr); 1361 encode_compound_hdr(&xdr, &hdr);
1388 status = encode_putfh(&xdr, args->fh); 1362 encode_putfh(&xdr, args->fh, &hdr);
1389 if (status != 0) 1363 encode_access(&xdr, args->access, &hdr);
1390 goto out; 1364 encode_getfattr(&xdr, args->bitmask, &hdr);
1391 status = encode_access(&xdr, args->access); 1365 encode_nops(&hdr);
1392 if (status != 0) 1366 return 0;
1393 goto out;
1394 status = encode_getfattr(&xdr, args->bitmask);
1395out:
1396 return status;
1397} 1367}
1398 1368
1399/* 1369/*
@@ -1403,21 +1373,17 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs
1403{ 1373{
1404 struct xdr_stream xdr; 1374 struct xdr_stream xdr;
1405 struct compound_hdr hdr = { 1375 struct compound_hdr hdr = {
1406 .nops = 4, 1376 .nops = 0,
1407 }; 1377 };
1408 int status;
1409 1378
1410 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1379 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1411 encode_compound_hdr(&xdr, &hdr); 1380 encode_compound_hdr(&xdr, &hdr);
1412 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) 1381 encode_putfh(&xdr, args->dir_fh, &hdr);
1413 goto out; 1382 encode_lookup(&xdr, args->name, &hdr);
1414 if ((status = encode_lookup(&xdr, args->name)) != 0) 1383 encode_getfh(&xdr, &hdr);
1415 goto out; 1384 encode_getfattr(&xdr, args->bitmask, &hdr);
1416 if ((status = encode_getfh(&xdr)) != 0) 1385 encode_nops(&hdr);
1417 goto out; 1386 return 0;
1418 status = encode_getfattr(&xdr, args->bitmask);
1419out:
1420 return status;
1421} 1387}
1422 1388
1423/* 1389/*
@@ -1427,18 +1393,16 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc
1427{ 1393{
1428 struct xdr_stream xdr; 1394 struct xdr_stream xdr;
1429 struct compound_hdr hdr = { 1395 struct compound_hdr hdr = {
1430 .nops = 3, 1396 .nops = 0,
1431 }; 1397 };
1432 int status;
1433 1398
1434 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1399 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1435 encode_compound_hdr(&xdr, &hdr); 1400 encode_compound_hdr(&xdr, &hdr);
1436 if ((status = encode_putrootfh(&xdr)) != 0) 1401 encode_putrootfh(&xdr, &hdr);
1437 goto out; 1402 encode_getfh(&xdr, &hdr);
1438 if ((status = encode_getfh(&xdr)) == 0) 1403 encode_getfattr(&xdr, args->bitmask, &hdr);
1439 status = encode_getfattr(&xdr, args->bitmask); 1404 encode_nops(&hdr);
1440out: 1405 return 0;
1441 return status;
1442} 1406}
1443 1407
1444/* 1408/*
@@ -1448,19 +1412,16 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
1448{ 1412{
1449 struct xdr_stream xdr; 1413 struct xdr_stream xdr;
1450 struct compound_hdr hdr = { 1414 struct compound_hdr hdr = {
1451 .nops = 3, 1415 .nops = 0,
1452 }; 1416 };
1453 int status;
1454 1417
1455 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1418 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1456 encode_compound_hdr(&xdr, &hdr); 1419 encode_compound_hdr(&xdr, &hdr);
1457 if ((status = encode_putfh(&xdr, args->fh)) != 0) 1420 encode_putfh(&xdr, args->fh, &hdr);
1458 goto out; 1421 encode_remove(&xdr, &args->name, &hdr);
1459 if ((status = encode_remove(&xdr, &args->name)) != 0) 1422 encode_getfattr(&xdr, args->bitmask, &hdr);
1460 goto out; 1423 encode_nops(&hdr);
1461 status = encode_getfattr(&xdr, args->bitmask); 1424 return 0;
1462out:
1463 return status;
1464} 1425}
1465 1426
1466/* 1427/*
@@ -1470,27 +1431,20 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs
1470{ 1431{
1471 struct xdr_stream xdr; 1432 struct xdr_stream xdr;
1472 struct compound_hdr hdr = { 1433 struct compound_hdr hdr = {
1473 .nops = 7, 1434 .nops = 0,
1474 }; 1435 };
1475 int status;
1476 1436
1477 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1437 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1478 encode_compound_hdr(&xdr, &hdr); 1438 encode_compound_hdr(&xdr, &hdr);
1479 if ((status = encode_putfh(&xdr, args->old_dir)) != 0) 1439 encode_putfh(&xdr, args->old_dir, &hdr);
1480 goto out; 1440 encode_savefh(&xdr, &hdr);
1481 if ((status = encode_savefh(&xdr)) != 0) 1441 encode_putfh(&xdr, args->new_dir, &hdr);
1482 goto out; 1442 encode_rename(&xdr, args->old_name, args->new_name, &hdr);
1483 if ((status = encode_putfh(&xdr, args->new_dir)) != 0) 1443 encode_getfattr(&xdr, args->bitmask, &hdr);
1484 goto out; 1444 encode_restorefh(&xdr, &hdr);
1485 if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0) 1445 encode_getfattr(&xdr, args->bitmask, &hdr);
1486 goto out; 1446 encode_nops(&hdr);
1487 if ((status = encode_getfattr(&xdr, args->bitmask)) != 0) 1447 return 0;
1488 goto out;
1489 if ((status = encode_restorefh(&xdr)) != 0)
1490 goto out;
1491 status = encode_getfattr(&xdr, args->bitmask);
1492out:
1493 return status;
1494} 1448}
1495 1449
1496/* 1450/*
@@ -1500,27 +1454,20 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_
1500{ 1454{
1501 struct xdr_stream xdr; 1455 struct xdr_stream xdr;
1502 struct compound_hdr hdr = { 1456 struct compound_hdr hdr = {
1503 .nops = 7, 1457 .nops = 0,
1504 }; 1458 };
1505 int status;
1506 1459
1507 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1460 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1508 encode_compound_hdr(&xdr, &hdr); 1461 encode_compound_hdr(&xdr, &hdr);
1509 if ((status = encode_putfh(&xdr, args->fh)) != 0) 1462 encode_putfh(&xdr, args->fh, &hdr);
1510 goto out; 1463 encode_savefh(&xdr, &hdr);
1511 if ((status = encode_savefh(&xdr)) != 0) 1464 encode_putfh(&xdr, args->dir_fh, &hdr);
1512 goto out; 1465 encode_link(&xdr, args->name, &hdr);
1513 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) 1466 encode_getfattr(&xdr, args->bitmask, &hdr);
1514 goto out; 1467 encode_restorefh(&xdr, &hdr);
1515 if ((status = encode_link(&xdr, args->name)) != 0) 1468 encode_getfattr(&xdr, args->bitmask, &hdr);
1516 goto out; 1469 encode_nops(&hdr);
1517 if ((status = encode_getfattr(&xdr, args->bitmask)) != 0) 1470 return 0;
1518 goto out;
1519 if ((status = encode_restorefh(&xdr)) != 0)
1520 goto out;
1521 status = encode_getfattr(&xdr, args->bitmask);
1522out:
1523 return status;
1524} 1471}
1525 1472
1526/* 1473/*
@@ -1530,27 +1477,20 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs
1530{ 1477{
1531 struct xdr_stream xdr; 1478 struct xdr_stream xdr;
1532 struct compound_hdr hdr = { 1479 struct compound_hdr hdr = {
1533 .nops = 7, 1480 .nops = 0,
1534 }; 1481 };
1535 int status;
1536 1482
1537 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1483 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1538 encode_compound_hdr(&xdr, &hdr); 1484 encode_compound_hdr(&xdr, &hdr);
1539 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) 1485 encode_putfh(&xdr, args->dir_fh, &hdr);
1540 goto out; 1486 encode_savefh(&xdr, &hdr);
1541 if ((status = encode_savefh(&xdr)) != 0) 1487 encode_create(&xdr, args, &hdr);
1542 goto out; 1488 encode_getfh(&xdr, &hdr);
1543 if ((status = encode_create(&xdr, args)) != 0) 1489 encode_getfattr(&xdr, args->bitmask, &hdr);
1544 goto out; 1490 encode_restorefh(&xdr, &hdr);
1545 if ((status = encode_getfh(&xdr)) != 0) 1491 encode_getfattr(&xdr, args->bitmask, &hdr);
1546 goto out; 1492 encode_nops(&hdr);
1547 if ((status = encode_getfattr(&xdr, args->bitmask)) != 0) 1493 return 0;
1548 goto out;
1549 if ((status = encode_restorefh(&xdr)) != 0)
1550 goto out;
1551 status = encode_getfattr(&xdr, args->bitmask);
1552out:
1553 return status;
1554} 1494}
1555 1495
1556/* 1496/*
@@ -1568,15 +1508,15 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf
1568{ 1508{
1569 struct xdr_stream xdr; 1509 struct xdr_stream xdr;
1570 struct compound_hdr hdr = { 1510 struct compound_hdr hdr = {
1571 .nops = 2, 1511 .nops = 0,
1572 }; 1512 };
1573 int status;
1574 1513
1575 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1514 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1576 encode_compound_hdr(&xdr, &hdr); 1515 encode_compound_hdr(&xdr, &hdr);
1577 if ((status = encode_putfh(&xdr, args->fh)) == 0) 1516 encode_putfh(&xdr, args->fh, &hdr);
1578 status = encode_getfattr(&xdr, args->bitmask); 1517 encode_getfattr(&xdr, args->bitmask, &hdr);
1579 return status; 1518 encode_nops(&hdr);
1519 return 0;
1580} 1520}
1581 1521
1582/* 1522/*
@@ -1584,23 +1524,18 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf
1584 */ 1524 */
1585static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args) 1525static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
1586{ 1526{
1587 struct xdr_stream xdr; 1527 struct xdr_stream xdr;
1588 struct compound_hdr hdr = { 1528 struct compound_hdr hdr = {
1589 .nops = 3, 1529 .nops = 0,
1590 }; 1530 };
1591 int status; 1531
1592 1532 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1593 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1533 encode_compound_hdr(&xdr, &hdr);
1594 encode_compound_hdr(&xdr, &hdr); 1534 encode_putfh(&xdr, args->fh, &hdr);
1595 status = encode_putfh(&xdr, args->fh); 1535 encode_close(&xdr, args, &hdr);
1596 if(status) 1536 encode_getfattr(&xdr, args->bitmask, &hdr);
1597 goto out; 1537 encode_nops(&hdr);
1598 status = encode_close(&xdr, args); 1538 return 0;
1599 if (status != 0)
1600 goto out;
1601 status = encode_getfattr(&xdr, args->bitmask);
1602out:
1603 return status;
1604} 1539}
1605 1540
1606/* 1541/*
@@ -1610,33 +1545,20 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg
1610{ 1545{
1611 struct xdr_stream xdr; 1546 struct xdr_stream xdr;
1612 struct compound_hdr hdr = { 1547 struct compound_hdr hdr = {
1613 .nops = 7, 1548 .nops = 0,
1614 }; 1549 };
1615 int status;
1616 1550
1617 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1551 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1618 encode_compound_hdr(&xdr, &hdr); 1552 encode_compound_hdr(&xdr, &hdr);
1619 status = encode_putfh(&xdr, args->fh); 1553 encode_putfh(&xdr, args->fh, &hdr);
1620 if (status) 1554 encode_savefh(&xdr, &hdr);
1621 goto out; 1555 encode_open(&xdr, args, &hdr);
1622 status = encode_savefh(&xdr); 1556 encode_getfh(&xdr, &hdr);
1623 if (status) 1557 encode_getfattr(&xdr, args->bitmask, &hdr);
1624 goto out; 1558 encode_restorefh(&xdr, &hdr);
1625 status = encode_open(&xdr, args); 1559 encode_getfattr(&xdr, args->bitmask, &hdr);
1626 if (status) 1560 encode_nops(&hdr);
1627 goto out; 1561 return 0;
1628 status = encode_getfh(&xdr);
1629 if (status)
1630 goto out;
1631 status = encode_getfattr(&xdr, args->bitmask);
1632 if (status)
1633 goto out;
1634 status = encode_restorefh(&xdr);
1635 if (status)
1636 goto out;
1637 status = encode_getfattr(&xdr, args->bitmask);
1638out:
1639 return status;
1640} 1562}
1641 1563
1642/* 1564/*
@@ -1646,18 +1568,15 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs
1646{ 1568{
1647 struct xdr_stream xdr; 1569 struct xdr_stream xdr;
1648 struct compound_hdr hdr = { 1570 struct compound_hdr hdr = {
1649 .nops = 2, 1571 .nops = 0,
1650 }; 1572 };
1651 int status;
1652 1573
1653 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1574 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1654 encode_compound_hdr(&xdr, &hdr); 1575 encode_compound_hdr(&xdr, &hdr);
1655 status = encode_putfh(&xdr, args->fh); 1576 encode_putfh(&xdr, args->fh, &hdr);
1656 if(status) 1577 encode_open_confirm(&xdr, args, &hdr);
1657 goto out; 1578 encode_nops(&hdr);
1658 status = encode_open_confirm(&xdr, args); 1579 return 0;
1659out:
1660 return status;
1661} 1580}
1662 1581
1663/* 1582/*
@@ -1667,21 +1586,16 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_
1667{ 1586{
1668 struct xdr_stream xdr; 1587 struct xdr_stream xdr;
1669 struct compound_hdr hdr = { 1588 struct compound_hdr hdr = {
1670 .nops = 3, 1589 .nops = 0,
1671 }; 1590 };
1672 int status;
1673 1591
1674 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1592 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1675 encode_compound_hdr(&xdr, &hdr); 1593 encode_compound_hdr(&xdr, &hdr);
1676 status = encode_putfh(&xdr, args->fh); 1594 encode_putfh(&xdr, args->fh, &hdr);
1677 if (status) 1595 encode_open(&xdr, args, &hdr);
1678 goto out; 1596 encode_getfattr(&xdr, args->bitmask, &hdr);
1679 status = encode_open(&xdr, args); 1597 encode_nops(&hdr);
1680 if (status) 1598 return 0;
1681 goto out;
1682 status = encode_getfattr(&xdr, args->bitmask);
1683out:
1684 return status;
1685} 1599}
1686 1600
1687/* 1601/*
@@ -1691,21 +1605,16 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n
1691{ 1605{
1692 struct xdr_stream xdr; 1606 struct xdr_stream xdr;
1693 struct compound_hdr hdr = { 1607 struct compound_hdr hdr = {
1694 .nops = 3, 1608 .nops = 0,
1695 }; 1609 };
1696 int status;
1697 1610
1698 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1611 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1699 encode_compound_hdr(&xdr, &hdr); 1612 encode_compound_hdr(&xdr, &hdr);
1700 status = encode_putfh(&xdr, args->fh); 1613 encode_putfh(&xdr, args->fh, &hdr);
1701 if (status) 1614 encode_open_downgrade(&xdr, args, &hdr);
1702 goto out; 1615 encode_getfattr(&xdr, args->bitmask, &hdr);
1703 status = encode_open_downgrade(&xdr, args); 1616 encode_nops(&hdr);
1704 if (status != 0) 1617 return 0;
1705 goto out;
1706 status = encode_getfattr(&xdr, args->bitmask);
1707out:
1708 return status;
1709} 1618}
1710 1619
1711/* 1620/*
@@ -1715,18 +1624,15 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar
1715{ 1624{
1716 struct xdr_stream xdr; 1625 struct xdr_stream xdr;
1717 struct compound_hdr hdr = { 1626 struct compound_hdr hdr = {
1718 .nops = 2, 1627 .nops = 0,
1719 }; 1628 };
1720 int status;
1721 1629
1722 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1630 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1723 encode_compound_hdr(&xdr, &hdr); 1631 encode_compound_hdr(&xdr, &hdr);
1724 status = encode_putfh(&xdr, args->fh); 1632 encode_putfh(&xdr, args->fh, &hdr);
1725 if(status) 1633 encode_lock(&xdr, args, &hdr);
1726 goto out; 1634 encode_nops(&hdr);
1727 status = encode_lock(&xdr, args); 1635 return 0;
1728out:
1729 return status;
1730} 1636}
1731 1637
1732/* 1638/*
@@ -1736,18 +1642,15 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_
1736{ 1642{
1737 struct xdr_stream xdr; 1643 struct xdr_stream xdr;
1738 struct compound_hdr hdr = { 1644 struct compound_hdr hdr = {
1739 .nops = 2, 1645 .nops = 0,
1740 }; 1646 };
1741 int status;
1742 1647
1743 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1648 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1744 encode_compound_hdr(&xdr, &hdr); 1649 encode_compound_hdr(&xdr, &hdr);
1745 status = encode_putfh(&xdr, args->fh); 1650 encode_putfh(&xdr, args->fh, &hdr);
1746 if(status) 1651 encode_lockt(&xdr, args, &hdr);
1747 goto out; 1652 encode_nops(&hdr);
1748 status = encode_lockt(&xdr, args); 1653 return 0;
1749out:
1750 return status;
1751} 1654}
1752 1655
1753/* 1656/*
@@ -1757,18 +1660,15 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_
1757{ 1660{
1758 struct xdr_stream xdr; 1661 struct xdr_stream xdr;
1759 struct compound_hdr hdr = { 1662 struct compound_hdr hdr = {
1760 .nops = 2, 1663 .nops = 0,
1761 }; 1664 };
1762 int status;
1763 1665
1764 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1666 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1765 encode_compound_hdr(&xdr, &hdr); 1667 encode_compound_hdr(&xdr, &hdr);
1766 status = encode_putfh(&xdr, args->fh); 1668 encode_putfh(&xdr, args->fh, &hdr);
1767 if(status) 1669 encode_locku(&xdr, args, &hdr);
1768 goto out; 1670 encode_nops(&hdr);
1769 status = encode_locku(&xdr, args); 1671 return 0;
1770out:
1771 return status;
1772} 1672}
1773 1673
1774/* 1674/*
@@ -1778,18 +1678,15 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
1778{ 1678{
1779 struct xdr_stream xdr; 1679 struct xdr_stream xdr;
1780 struct compound_hdr hdr = { 1680 struct compound_hdr hdr = {
1781 .nops = 2, 1681 .nops = 0,
1782 }; 1682 };
1783 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 1683 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1784 unsigned int replen; 1684 unsigned int replen;
1785 int status;
1786 1685
1787 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1686 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1788 encode_compound_hdr(&xdr, &hdr); 1687 encode_compound_hdr(&xdr, &hdr);
1789 status = encode_putfh(&xdr, args->fh); 1688 encode_putfh(&xdr, args->fh, &hdr);
1790 if(status) 1689 encode_readlink(&xdr, args, req, &hdr);
1791 goto out;
1792 status = encode_readlink(&xdr, args, req);
1793 1690
1794 /* set up reply kvec 1691 /* set up reply kvec
1795 * toplevel_status + taglen + rescount + OP_PUTFH + status 1692 * toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -1798,9 +1695,8 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
1798 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2; 1695 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2;
1799 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 1696 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
1800 args->pgbase, args->pglen); 1697 args->pgbase, args->pglen);
1801 1698 encode_nops(&hdr);
1802out: 1699 return 0;
1803 return status;
1804} 1700}
1805 1701
1806/* 1702/*
@@ -1810,18 +1706,15 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
1810{ 1706{
1811 struct xdr_stream xdr; 1707 struct xdr_stream xdr;
1812 struct compound_hdr hdr = { 1708 struct compound_hdr hdr = {
1813 .nops = 2, 1709 .nops = 0,
1814 }; 1710 };
1815 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 1711 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1816 int replen; 1712 int replen;
1817 int status;
1818 1713
1819 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1714 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1820 encode_compound_hdr(&xdr, &hdr); 1715 encode_compound_hdr(&xdr, &hdr);
1821 status = encode_putfh(&xdr, args->fh); 1716 encode_putfh(&xdr, args->fh, &hdr);
1822 if(status) 1717 encode_readdir(&xdr, args, req, &hdr);
1823 goto out;
1824 status = encode_readdir(&xdr, args, req);
1825 1718
1826 /* set up reply kvec 1719 /* set up reply kvec
1827 * toplevel_status + taglen + rescount + OP_PUTFH + status 1720 * toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -1833,9 +1726,8 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
1833 dprintk("%s: inlined page args = (%u, %p, %u, %u)\n", 1726 dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
1834 __func__, replen, args->pages, 1727 __func__, replen, args->pages,
1835 args->pgbase, args->count); 1728 args->pgbase, args->count);
1836 1729 encode_nops(&hdr);
1837out: 1730 return 0;
1838 return status;
1839} 1731}
1840 1732
1841/* 1733/*
@@ -1846,18 +1738,14 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg
1846 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 1738 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1847 struct xdr_stream xdr; 1739 struct xdr_stream xdr;
1848 struct compound_hdr hdr = { 1740 struct compound_hdr hdr = {
1849 .nops = 2, 1741 .nops = 0,
1850 }; 1742 };
1851 int replen, status; 1743 int replen;
1852 1744
1853 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1745 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1854 encode_compound_hdr(&xdr, &hdr); 1746 encode_compound_hdr(&xdr, &hdr);
1855 status = encode_putfh(&xdr, args->fh); 1747 encode_putfh(&xdr, args->fh, &hdr);
1856 if (status) 1748 encode_read(&xdr, args, &hdr);
1857 goto out;
1858 status = encode_read(&xdr, args);
1859 if (status)
1860 goto out;
1861 1749
1862 /* set up reply kvec 1750 /* set up reply kvec
1863 * toplevel status + taglen=0 + rescount + OP_PUTFH + status 1751 * toplevel status + taglen=0 + rescount + OP_PUTFH + status
@@ -1867,33 +1755,27 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg
1867 xdr_inline_pages(&req->rq_rcv_buf, replen, 1755 xdr_inline_pages(&req->rq_rcv_buf, replen,
1868 args->pages, args->pgbase, args->count); 1756 args->pages, args->pgbase, args->count);
1869 req->rq_rcv_buf.flags |= XDRBUF_READ; 1757 req->rq_rcv_buf.flags |= XDRBUF_READ;
1870out: 1758 encode_nops(&hdr);
1871 return status; 1759 return 0;
1872} 1760}
1873 1761
1874/* 1762/*
1875 * Encode an SETATTR request 1763 * Encode an SETATTR request
1876 */ 1764 */
1877static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args) 1765static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args)
1878
1879{ 1766{
1880 struct xdr_stream xdr; 1767 struct xdr_stream xdr;
1881 struct compound_hdr hdr = { 1768 struct compound_hdr hdr = {
1882 .nops = 3, 1769 .nops = 0,
1883 }; 1770 };
1884 int status; 1771
1885 1772 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1886 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1773 encode_compound_hdr(&xdr, &hdr);
1887 encode_compound_hdr(&xdr, &hdr); 1774 encode_putfh(&xdr, args->fh, &hdr);
1888 status = encode_putfh(&xdr, args->fh); 1775 encode_setattr(&xdr, args, args->server, &hdr);
1889 if(status) 1776 encode_getfattr(&xdr, args->bitmask, &hdr);
1890 goto out; 1777 encode_nops(&hdr);
1891 status = encode_setattr(&xdr, args, args->server); 1778 return 0;
1892 if(status)
1893 goto out;
1894 status = encode_getfattr(&xdr, args->bitmask);
1895out:
1896 return status;
1897} 1779}
1898 1780
1899/* 1781/*
@@ -1906,22 +1788,21 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
1906 struct xdr_stream xdr; 1788 struct xdr_stream xdr;
1907 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 1789 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1908 struct compound_hdr hdr = { 1790 struct compound_hdr hdr = {
1909 .nops = 2, 1791 .nops = 0,
1910 }; 1792 };
1911 int replen, status; 1793 int replen;
1912 1794
1913 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1795 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1914 encode_compound_hdr(&xdr, &hdr); 1796 encode_compound_hdr(&xdr, &hdr);
1915 status = encode_putfh(&xdr, args->fh); 1797 encode_putfh(&xdr, args->fh, &hdr);
1916 if (status) 1798 encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
1917 goto out; 1799
1918 status = encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0);
1919 /* set up reply buffer: */ 1800 /* set up reply buffer: */
1920 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2; 1801 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
1921 xdr_inline_pages(&req->rq_rcv_buf, replen, 1802 xdr_inline_pages(&req->rq_rcv_buf, replen,
1922 args->acl_pages, args->acl_pgbase, args->acl_len); 1803 args->acl_pages, args->acl_pgbase, args->acl_len);
1923out: 1804 encode_nops(&hdr);
1924 return status; 1805 return 0;
1925} 1806}
1926 1807
1927/* 1808/*
@@ -1931,22 +1812,17 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea
1931{ 1812{
1932 struct xdr_stream xdr; 1813 struct xdr_stream xdr;
1933 struct compound_hdr hdr = { 1814 struct compound_hdr hdr = {
1934 .nops = 3, 1815 .nops = 0,
1935 }; 1816 };
1936 int status;
1937 1817
1938 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1818 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1939 encode_compound_hdr(&xdr, &hdr); 1819 encode_compound_hdr(&xdr, &hdr);
1940 status = encode_putfh(&xdr, args->fh); 1820 encode_putfh(&xdr, args->fh, &hdr);
1941 if (status) 1821 encode_write(&xdr, args, &hdr);
1942 goto out;
1943 status = encode_write(&xdr, args);
1944 if (status)
1945 goto out;
1946 req->rq_snd_buf.flags |= XDRBUF_WRITE; 1822 req->rq_snd_buf.flags |= XDRBUF_WRITE;
1947 status = encode_getfattr(&xdr, args->bitmask); 1823 encode_getfattr(&xdr, args->bitmask, &hdr);
1948out: 1824 encode_nops(&hdr);
1949 return status; 1825 return 0;
1950} 1826}
1951 1827
1952/* 1828/*
@@ -1956,21 +1832,16 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write
1956{ 1832{
1957 struct xdr_stream xdr; 1833 struct xdr_stream xdr;
1958 struct compound_hdr hdr = { 1834 struct compound_hdr hdr = {
1959 .nops = 3, 1835 .nops = 0,
1960 }; 1836 };
1961 int status;
1962 1837
1963 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1838 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1964 encode_compound_hdr(&xdr, &hdr); 1839 encode_compound_hdr(&xdr, &hdr);
1965 status = encode_putfh(&xdr, args->fh); 1840 encode_putfh(&xdr, args->fh, &hdr);
1966 if (status) 1841 encode_commit(&xdr, args, &hdr);
1967 goto out; 1842 encode_getfattr(&xdr, args->bitmask, &hdr);
1968 status = encode_commit(&xdr, args); 1843 encode_nops(&hdr);
1969 if (status) 1844 return 0;
1970 goto out;
1971 status = encode_getfattr(&xdr, args->bitmask);
1972out:
1973 return status;
1974} 1845}
1975 1846
1976/* 1847/*
@@ -1980,16 +1851,15 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin
1980{ 1851{
1981 struct xdr_stream xdr; 1852 struct xdr_stream xdr;
1982 struct compound_hdr hdr = { 1853 struct compound_hdr hdr = {
1983 .nops = 2, 1854 .nops = 0,
1984 }; 1855 };
1985 int status;
1986 1856
1987 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1857 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1988 encode_compound_hdr(&xdr, &hdr); 1858 encode_compound_hdr(&xdr, &hdr);
1989 status = encode_putfh(&xdr, args->fh); 1859 encode_putfh(&xdr, args->fh, &hdr);
1990 if (!status) 1860 encode_fsinfo(&xdr, args->bitmask, &hdr);
1991 status = encode_fsinfo(&xdr, args->bitmask); 1861 encode_nops(&hdr);
1992 return status; 1862 return 0;
1993} 1863}
1994 1864
1995/* 1865/*
@@ -1999,17 +1869,16 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n
1999{ 1869{
2000 struct xdr_stream xdr; 1870 struct xdr_stream xdr;
2001 struct compound_hdr hdr = { 1871 struct compound_hdr hdr = {
2002 .nops = 2, 1872 .nops = 0,
2003 }; 1873 };
2004 int status;
2005 1874
2006 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1875 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2007 encode_compound_hdr(&xdr, &hdr); 1876 encode_compound_hdr(&xdr, &hdr);
2008 status = encode_putfh(&xdr, args->fh); 1877 encode_putfh(&xdr, args->fh, &hdr);
2009 if (!status) 1878 encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
2010 status = encode_getattr_one(&xdr, 1879 &hdr);
2011 args->bitmask[0] & nfs4_pathconf_bitmap[0]); 1880 encode_nops(&hdr);
2012 return status; 1881 return 0;
2013} 1882}
2014 1883
2015/* 1884/*
@@ -2019,18 +1888,16 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
2019{ 1888{
2020 struct xdr_stream xdr; 1889 struct xdr_stream xdr;
2021 struct compound_hdr hdr = { 1890 struct compound_hdr hdr = {
2022 .nops = 2, 1891 .nops = 0,
2023 }; 1892 };
2024 int status;
2025 1893
2026 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1894 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2027 encode_compound_hdr(&xdr, &hdr); 1895 encode_compound_hdr(&xdr, &hdr);
2028 status = encode_putfh(&xdr, args->fh); 1896 encode_putfh(&xdr, args->fh, &hdr);
2029 if (status == 0) 1897 encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
2030 status = encode_getattr_two(&xdr, 1898 args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
2031 args->bitmask[0] & nfs4_statfs_bitmap[0], 1899 encode_nops(&hdr);
2032 args->bitmask[1] & nfs4_statfs_bitmap[1]); 1900 return 0;
2033 return status;
2034} 1901}
2035 1902
2036/* 1903/*
@@ -2040,19 +1907,18 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struc
2040{ 1907{
2041 struct xdr_stream xdr; 1908 struct xdr_stream xdr;
2042 struct compound_hdr hdr = { 1909 struct compound_hdr hdr = {
2043 .nops = 2, 1910 .nops = 0,
2044 }; 1911 };
2045 int status;
2046 1912
2047 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1913 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2048 encode_compound_hdr(&xdr, &hdr); 1914 encode_compound_hdr(&xdr, &hdr);
2049 status = encode_putfh(&xdr, fhandle); 1915 encode_putfh(&xdr, fhandle, &hdr);
2050 if (status == 0) 1916 encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
2051 status = encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS| 1917 FATTR4_WORD0_LINK_SUPPORT|
2052 FATTR4_WORD0_LINK_SUPPORT| 1918 FATTR4_WORD0_SYMLINK_SUPPORT|
2053 FATTR4_WORD0_SYMLINK_SUPPORT| 1919 FATTR4_WORD0_ACLSUPPORT, &hdr);
2054 FATTR4_WORD0_ACLSUPPORT); 1920 encode_nops(&hdr);
2055 return status; 1921 return 0;
2056} 1922}
2057 1923
2058/* 1924/*
@@ -2062,12 +1928,14 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client
2062{ 1928{
2063 struct xdr_stream xdr; 1929 struct xdr_stream xdr;
2064 struct compound_hdr hdr = { 1930 struct compound_hdr hdr = {
2065 .nops = 1, 1931 .nops = 0,
2066 }; 1932 };
2067 1933
2068 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1934 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2069 encode_compound_hdr(&xdr, &hdr); 1935 encode_compound_hdr(&xdr, &hdr);
2070 return encode_renew(&xdr, clp); 1936 encode_renew(&xdr, clp, &hdr);
1937 encode_nops(&hdr);
1938 return 0;
2071} 1939}
2072 1940
2073/* 1941/*
@@ -2077,12 +1945,14 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4
2077{ 1945{
2078 struct xdr_stream xdr; 1946 struct xdr_stream xdr;
2079 struct compound_hdr hdr = { 1947 struct compound_hdr hdr = {
2080 .nops = 1, 1948 .nops = 0,
2081 }; 1949 };
2082 1950
2083 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1951 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2084 encode_compound_hdr(&xdr, &hdr); 1952 encode_compound_hdr(&xdr, &hdr);
2085 return encode_setclientid(&xdr, sc); 1953 encode_setclientid(&xdr, sc, &hdr);
1954 encode_nops(&hdr);
1955 return 0;
2086} 1956}
2087 1957
2088/* 1958/*
@@ -2092,19 +1962,17 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
2092{ 1962{
2093 struct xdr_stream xdr; 1963 struct xdr_stream xdr;
2094 struct compound_hdr hdr = { 1964 struct compound_hdr hdr = {
2095 .nops = 3, 1965 .nops = 0,
2096 }; 1966 };
2097 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; 1967 const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
2098 int status;
2099 1968
2100 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1969 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2101 encode_compound_hdr(&xdr, &hdr); 1970 encode_compound_hdr(&xdr, &hdr);
2102 status = encode_setclientid_confirm(&xdr, clp); 1971 encode_setclientid_confirm(&xdr, clp, &hdr);
2103 if (!status) 1972 encode_putrootfh(&xdr, &hdr);
2104 status = encode_putrootfh(&xdr); 1973 encode_fsinfo(&xdr, lease_bitmap, &hdr);
2105 if (!status) 1974 encode_nops(&hdr);
2106 status = encode_fsinfo(&xdr, lease_bitmap); 1975 return 0;
2107 return status;
2108} 1976}
2109 1977
2110/* 1978/*
@@ -2114,21 +1982,16 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc
2114{ 1982{
2115 struct xdr_stream xdr; 1983 struct xdr_stream xdr;
2116 struct compound_hdr hdr = { 1984 struct compound_hdr hdr = {
2117 .nops = 3, 1985 .nops = 0,
2118 }; 1986 };
2119 int status;
2120 1987
2121 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 1988 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2122 encode_compound_hdr(&xdr, &hdr); 1989 encode_compound_hdr(&xdr, &hdr);
2123 status = encode_putfh(&xdr, args->fhandle); 1990 encode_putfh(&xdr, args->fhandle, &hdr);
2124 if (status != 0) 1991 encode_delegreturn(&xdr, args->stateid, &hdr);
2125 goto out; 1992 encode_getfattr(&xdr, args->bitmask, &hdr);
2126 status = encode_delegreturn(&xdr, args->stateid); 1993 encode_nops(&hdr);
2127 if (status != 0) 1994 return 0;
2128 goto out;
2129 status = encode_getfattr(&xdr, args->bitmask);
2130out:
2131 return status;
2132} 1995}
2133 1996
2134/* 1997/*
@@ -2138,20 +2001,17 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
2138{ 2001{
2139 struct xdr_stream xdr; 2002 struct xdr_stream xdr;
2140 struct compound_hdr hdr = { 2003 struct compound_hdr hdr = {
2141 .nops = 3, 2004 .nops = 0,
2142 }; 2005 };
2143 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; 2006 struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
2144 int replen; 2007 int replen;
2145 int status;
2146 2008
2147 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 2009 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2148 encode_compound_hdr(&xdr, &hdr); 2010 encode_compound_hdr(&xdr, &hdr);
2149 if ((status = encode_putfh(&xdr, args->dir_fh)) != 0) 2011 encode_putfh(&xdr, args->dir_fh, &hdr);
2150 goto out; 2012 encode_lookup(&xdr, args->name, &hdr);
2151 if ((status = encode_lookup(&xdr, args->name)) != 0) 2013 encode_fs_locations(&xdr, args->bitmask, &hdr);
2152 goto out; 2014
2153 if ((status = encode_fs_locations(&xdr, args->bitmask)) != 0)
2154 goto out;
2155 /* set up reply 2015 /* set up reply
2156 * toplevel_status + OP_PUTFH + status 2016 * toplevel_status + OP_PUTFH + status
2157 * + OP_LOOKUP + status + OP_GETATTR + status = 7 2017 * + OP_LOOKUP + status + OP_GETATTR + status = 7
@@ -2159,8 +2019,8 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
2159 replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2; 2019 replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
2160 xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page, 2020 xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
2161 0, PAGE_SIZE); 2021 0, PAGE_SIZE);
2162out: 2022 encode_nops(&hdr);
2163 return status; 2023 return 0;
2164} 2024}
2165 2025
2166/* 2026/*
@@ -2217,11 +2077,13 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
2217 READ_BUF(8); 2077 READ_BUF(8);
2218 READ32(hdr->status); 2078 READ32(hdr->status);
2219 READ32(hdr->taglen); 2079 READ32(hdr->taglen);
2220 2080
2221 READ_BUF(hdr->taglen + 4); 2081 READ_BUF(hdr->taglen + 4);
2222 hdr->tag = (char *)p; 2082 hdr->tag = (char *)p;
2223 p += XDR_QUADLEN(hdr->taglen); 2083 p += XDR_QUADLEN(hdr->taglen);
2224 READ32(hdr->nops); 2084 READ32(hdr->nops);
2085 if (unlikely(hdr->nops < 1))
2086 return nfs4_stat_to_errno(hdr->status);
2225 return 0; 2087 return 0;
2226} 2088}
2227 2089
@@ -3047,8 +2909,7 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
3047static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) 2909static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
3048{ 2910{
3049 __be32 *savep; 2911 __be32 *savep;
3050 uint32_t attrlen, 2912 uint32_t attrlen, bitmap[2] = {0};
3051 bitmap[2] = {0};
3052 int status; 2913 int status;
3053 2914
3054 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 2915 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
@@ -3070,14 +2931,13 @@ xdr_error:
3070 dprintk("%s: xdr returned %d!\n", __func__, -status); 2931 dprintk("%s: xdr returned %d!\n", __func__, -status);
3071 return status; 2932 return status;
3072} 2933}
3073 2934
3074static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) 2935static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
3075{ 2936{
3076 __be32 *savep; 2937 __be32 *savep;
3077 uint32_t attrlen, 2938 uint32_t attrlen, bitmap[2] = {0};
3078 bitmap[2] = {0};
3079 int status; 2939 int status;
3080 2940
3081 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 2941 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3082 goto xdr_error; 2942 goto xdr_error;
3083 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 2943 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
@@ -3107,10 +2967,9 @@ xdr_error:
3107static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) 2967static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf)
3108{ 2968{
3109 __be32 *savep; 2969 __be32 *savep;
3110 uint32_t attrlen, 2970 uint32_t attrlen, bitmap[2] = {0};
3111 bitmap[2] = {0};
3112 int status; 2971 int status;
3113 2972
3114 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 2973 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3115 goto xdr_error; 2974 goto xdr_error;
3116 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 2975 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
@@ -3256,7 +3115,7 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
3256static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) 3115static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
3257{ 3116{
3258 int status; 3117 int status;
3259 3118
3260 status = decode_op_hdr(xdr, OP_LINK); 3119 status = decode_op_hdr(xdr, OP_LINK);
3261 if (status) 3120 if (status)
3262 return status; 3121 return status;
@@ -3344,27 +3203,27 @@ static int decode_lookup(struct xdr_stream *xdr)
3344/* This is too sick! */ 3203/* This is too sick! */
3345static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) 3204static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
3346{ 3205{
3347 __be32 *p; 3206 __be32 *p;
3348 uint32_t limit_type, nblocks, blocksize; 3207 uint32_t limit_type, nblocks, blocksize;
3349 3208
3350 READ_BUF(12); 3209 READ_BUF(12);
3351 READ32(limit_type); 3210 READ32(limit_type);
3352 switch (limit_type) { 3211 switch (limit_type) {
3353 case 1: 3212 case 1:
3354 READ64(*maxsize); 3213 READ64(*maxsize);
3355 break; 3214 break;
3356 case 2: 3215 case 2:
3357 READ32(nblocks); 3216 READ32(nblocks);
3358 READ32(blocksize); 3217 READ32(blocksize);
3359 *maxsize = (uint64_t)nblocks * (uint64_t)blocksize; 3218 *maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
3360 } 3219 }
3361 return 0; 3220 return 0;
3362} 3221}
3363 3222
3364static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) 3223static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3365{ 3224{
3366 __be32 *p; 3225 __be32 *p;
3367 uint32_t delegation_type; 3226 uint32_t delegation_type;
3368 3227
3369 READ_BUF(4); 3228 READ_BUF(4);
3370 READ32(delegation_type); 3229 READ32(delegation_type);
@@ -3375,13 +3234,14 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3375 READ_BUF(NFS4_STATEID_SIZE+4); 3234 READ_BUF(NFS4_STATEID_SIZE+4);
3376 COPYMEM(res->delegation.data, NFS4_STATEID_SIZE); 3235 COPYMEM(res->delegation.data, NFS4_STATEID_SIZE);
3377 READ32(res->do_recall); 3236 READ32(res->do_recall);
3237
3378 switch (delegation_type) { 3238 switch (delegation_type) {
3379 case NFS4_OPEN_DELEGATE_READ: 3239 case NFS4_OPEN_DELEGATE_READ:
3380 res->delegation_type = FMODE_READ; 3240 res->delegation_type = FMODE_READ;
3381 break; 3241 break;
3382 case NFS4_OPEN_DELEGATE_WRITE: 3242 case NFS4_OPEN_DELEGATE_WRITE:
3383 res->delegation_type = FMODE_WRITE|FMODE_READ; 3243 res->delegation_type = FMODE_WRITE|FMODE_READ;
3384 if (decode_space_limit(xdr, &res->maxsize) < 0) 3244 if (decode_space_limit(xdr, &res->maxsize) < 0)
3385 return -EIO; 3245 return -EIO;
3386 } 3246 }
3387 return decode_ace(xdr, NULL, res->server->nfs_client); 3247 return decode_ace(xdr, NULL, res->server->nfs_client);
@@ -3389,27 +3249,27 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3389 3249
3390static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) 3250static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
3391{ 3251{
3392 __be32 *p; 3252 __be32 *p;
3393 uint32_t savewords, bmlen, i; 3253 uint32_t savewords, bmlen, i;
3394 int status; 3254 int status;
3395 3255
3396 status = decode_op_hdr(xdr, OP_OPEN); 3256 status = decode_op_hdr(xdr, OP_OPEN);
3397 if (status != -EIO) 3257 if (status != -EIO)
3398 nfs_increment_open_seqid(status, res->seqid); 3258 nfs_increment_open_seqid(status, res->seqid);
3399 if (status) 3259 if (status)
3400 return status; 3260 return status;
3401 READ_BUF(NFS4_STATEID_SIZE); 3261 READ_BUF(NFS4_STATEID_SIZE);
3402 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); 3262 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3403 3263
3404 decode_change_info(xdr, &res->cinfo); 3264 decode_change_info(xdr, &res->cinfo);
3405 3265
3406 READ_BUF(8); 3266 READ_BUF(8);
3407 READ32(res->rflags); 3267 READ32(res->rflags);
3408 READ32(bmlen); 3268 READ32(bmlen);
3409 if (bmlen > 10) 3269 if (bmlen > 10)
3410 goto xdr_error; 3270 goto xdr_error;
3411 3271
3412 READ_BUF(bmlen << 2); 3272 READ_BUF(bmlen << 2);
3413 savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); 3273 savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE);
3414 for (i = 0; i < savewords; ++i) 3274 for (i = 0; i < savewords; ++i)
3415 READ32(res->attrset[i]); 3275 READ32(res->attrset[i]);
@@ -3424,17 +3284,17 @@ xdr_error:
3424 3284
3425static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) 3285static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res)
3426{ 3286{
3427 __be32 *p; 3287 __be32 *p;
3428 int status; 3288 int status;
3429 3289
3430 status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); 3290 status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
3431 if (status != -EIO) 3291 if (status != -EIO)
3432 nfs_increment_open_seqid(status, res->seqid); 3292 nfs_increment_open_seqid(status, res->seqid);
3433 if (status) 3293 if (status)
3434 return status; 3294 return status;
3435 READ_BUF(NFS4_STATEID_SIZE); 3295 READ_BUF(NFS4_STATEID_SIZE);
3436 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); 3296 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3437 return 0; 3297 return 0;
3438} 3298}
3439 3299
3440static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res) 3300static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res)
@@ -3562,7 +3422,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3562 dprintk("NFS: readdir reply truncated!\n"); 3422 dprintk("NFS: readdir reply truncated!\n");
3563 entry[1] = 1; 3423 entry[1] = 1;
3564 } 3424 }
3565out: 3425out:
3566 kunmap_atomic(kaddr, KM_USER0); 3426 kunmap_atomic(kaddr, KM_USER0);
3567 return 0; 3427 return 0;
3568short_pkt: 3428short_pkt:
@@ -3718,7 +3578,6 @@ static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
3718 uint32_t bmlen; 3578 uint32_t bmlen;
3719 int status; 3579 int status;
3720 3580
3721
3722 status = decode_op_hdr(xdr, OP_SETATTR); 3581 status = decode_op_hdr(xdr, OP_SETATTR);
3723 if (status) 3582 if (status)
3724 return status; 3583 return status;
@@ -3738,7 +3597,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
3738 READ32(opnum); 3597 READ32(opnum);
3739 if (opnum != OP_SETCLIENTID) { 3598 if (opnum != OP_SETCLIENTID) {
3740 dprintk("nfs: decode_setclientid: Server returned operation" 3599 dprintk("nfs: decode_setclientid: Server returned operation"
3741 " %d\n", opnum); 3600 " %d\n", opnum);
3742 return -EIO; 3601 return -EIO;
3743 } 3602 }
3744 READ32(nfserr); 3603 READ32(nfserr);
@@ -3792,34 +3651,34 @@ static int decode_delegreturn(struct xdr_stream *xdr)
3792} 3651}
3793 3652
3794/* 3653/*
3654 * END OF "GENERIC" DECODE ROUTINES.
3655 */
3656
3657/*
3795 * Decode OPEN_DOWNGRADE response 3658 * Decode OPEN_DOWNGRADE response
3796 */ 3659 */
3797static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res) 3660static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
3798{ 3661{
3799 struct xdr_stream xdr; 3662 struct xdr_stream xdr;
3800 struct compound_hdr hdr; 3663 struct compound_hdr hdr;
3801 int status; 3664 int status;
3802 3665
3803 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3666 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3804 status = decode_compound_hdr(&xdr, &hdr); 3667 status = decode_compound_hdr(&xdr, &hdr);
3805 if (status) 3668 if (status)
3806 goto out; 3669 goto out;
3807 status = decode_putfh(&xdr); 3670 status = decode_putfh(&xdr);
3808 if (status) 3671 if (status)
3809 goto out; 3672 goto out;
3810 status = decode_open_downgrade(&xdr, res); 3673 status = decode_open_downgrade(&xdr, res);
3811 if (status != 0) 3674 if (status != 0)
3812 goto out; 3675 goto out;
3813 decode_getfattr(&xdr, res->fattr, res->server); 3676 decode_getfattr(&xdr, res->fattr, res->server);
3814out: 3677out:
3815 return status; 3678 return status;
3816} 3679}
3817 3680
3818/* 3681/*
3819 * END OF "GENERIC" DECODE ROUTINES.
3820 */
3821
3822/*
3823 * Decode ACCESS response 3682 * Decode ACCESS response
3824 */ 3683 */
3825static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_accessres *res) 3684static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_accessres *res)
@@ -3827,7 +3686,7 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac
3827 struct xdr_stream xdr; 3686 struct xdr_stream xdr;
3828 struct compound_hdr hdr; 3687 struct compound_hdr hdr;
3829 int status; 3688 int status;
3830 3689
3831 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3690 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3832 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 3691 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3833 goto out; 3692 goto out;
@@ -3850,7 +3709,7 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo
3850 struct xdr_stream xdr; 3709 struct xdr_stream xdr;
3851 struct compound_hdr hdr; 3710 struct compound_hdr hdr;
3852 int status; 3711 int status;
3853 3712
3854 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3713 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3855 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 3714 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3856 goto out; 3715 goto out;
@@ -3873,7 +3732,7 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf
3873 struct xdr_stream xdr; 3732 struct xdr_stream xdr;
3874 struct compound_hdr hdr; 3733 struct compound_hdr hdr;
3875 int status; 3734 int status;
3876 3735
3877 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3736 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3878 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 3737 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3879 goto out; 3738 goto out;
@@ -3893,7 +3752,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem
3893 struct xdr_stream xdr; 3752 struct xdr_stream xdr;
3894 struct compound_hdr hdr; 3753 struct compound_hdr hdr;
3895 int status; 3754 int status;
3896 3755
3897 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3756 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3898 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 3757 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3899 goto out; 3758 goto out;
@@ -3914,7 +3773,7 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re
3914 struct xdr_stream xdr; 3773 struct xdr_stream xdr;
3915 struct compound_hdr hdr; 3774 struct compound_hdr hdr;
3916 int status; 3775 int status;
3917 3776
3918 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3777 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3919 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 3778 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3920 goto out; 3779 goto out;
@@ -3944,7 +3803,7 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link
3944 struct xdr_stream xdr; 3803 struct xdr_stream xdr;
3945 struct compound_hdr hdr; 3804 struct compound_hdr hdr;
3946 int status; 3805 int status;
3947 3806
3948 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3807 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3949 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 3808 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3950 goto out; 3809 goto out;
@@ -3977,7 +3836,7 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr
3977 struct xdr_stream xdr; 3836 struct xdr_stream xdr;
3978 struct compound_hdr hdr; 3837 struct compound_hdr hdr;
3979 int status; 3838 int status;
3980 3839
3981 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3840 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3982 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0) 3841 if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3983 goto out; 3842 goto out;
@@ -4014,7 +3873,7 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g
4014 struct xdr_stream xdr; 3873 struct xdr_stream xdr;
4015 struct compound_hdr hdr; 3874 struct compound_hdr hdr;
4016 int status; 3875 int status;
4017 3876
4018 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3877 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4019 status = decode_compound_hdr(&xdr, &hdr); 3878 status = decode_compound_hdr(&xdr, &hdr);
4020 if (status) 3879 if (status)
@@ -4025,7 +3884,6 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g
4025 status = decode_getfattr(&xdr, res->fattr, res->server); 3884 status = decode_getfattr(&xdr, res->fattr, res->server);
4026out: 3885out:
4027 return status; 3886 return status;
4028
4029} 3887}
4030 3888
4031/* 3889/*
@@ -4034,21 +3892,20 @@ out:
4034static int 3892static int
4035nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args) 3893nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args)
4036{ 3894{
4037 struct xdr_stream xdr; 3895 struct xdr_stream xdr;
4038 struct compound_hdr hdr = { 3896 struct compound_hdr hdr = {
4039 .nops = 2, 3897 .nops = 0,
4040 }; 3898 };
4041 int status; 3899 int status;
4042 3900
4043 xdr_init_encode(&xdr, &req->rq_snd_buf, p); 3901 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
4044 encode_compound_hdr(&xdr, &hdr); 3902 encode_compound_hdr(&xdr, &hdr);
4045 status = encode_putfh(&xdr, args->fh); 3903 encode_putfh(&xdr, args->fh, &hdr);
4046 if (status) 3904 status = encode_setacl(&xdr, args, &hdr);
4047 goto out; 3905 encode_nops(&hdr);
4048 status = encode_setacl(&xdr, args); 3906 return status;
4049out:
4050 return status;
4051} 3907}
3908
4052/* 3909/*
4053 * Decode SETACL response 3910 * Decode SETACL response
4054 */ 3911 */
@@ -4099,18 +3956,18 @@ out:
4099 */ 3956 */
4100static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res) 3957static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
4101{ 3958{
4102 struct xdr_stream xdr; 3959 struct xdr_stream xdr;
4103 struct compound_hdr hdr; 3960 struct compound_hdr hdr;
4104 int status; 3961 int status;
4105 3962
4106 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3963 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4107 status = decode_compound_hdr(&xdr, &hdr); 3964 status = decode_compound_hdr(&xdr, &hdr);
4108 if (status) 3965 if (status)
4109 goto out; 3966 goto out;
4110 status = decode_putfh(&xdr); 3967 status = decode_putfh(&xdr);
4111 if (status) 3968 if (status)
4112 goto out; 3969 goto out;
4113 status = decode_close(&xdr, res); 3970 status = decode_close(&xdr, res);
4114 if (status != 0) 3971 if (status != 0)
4115 goto out; 3972 goto out;
4116 /* 3973 /*
@@ -4121,7 +3978,7 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos
4121 */ 3978 */
4122 decode_getfattr(&xdr, res->fattr, res->server); 3979 decode_getfattr(&xdr, res->fattr, res->server);
4123out: 3980out:
4124 return status; 3981 return status;
4125} 3982}
4126 3983
4127/* 3984/*
@@ -4129,23 +3986,23 @@ out:
4129 */ 3986 */
4130static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res) 3987static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
4131{ 3988{
4132 struct xdr_stream xdr; 3989 struct xdr_stream xdr;
4133 struct compound_hdr hdr; 3990 struct compound_hdr hdr;
4134 int status; 3991 int status;
4135 3992
4136 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 3993 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4137 status = decode_compound_hdr(&xdr, &hdr); 3994 status = decode_compound_hdr(&xdr, &hdr);
4138 if (status) 3995 if (status)
4139 goto out; 3996 goto out;
4140 status = decode_putfh(&xdr); 3997 status = decode_putfh(&xdr);
4141 if (status) 3998 if (status)
4142 goto out; 3999 goto out;
4143 status = decode_savefh(&xdr); 4000 status = decode_savefh(&xdr);
4001 if (status)
4002 goto out;
4003 status = decode_open(&xdr, res);
4144 if (status) 4004 if (status)
4145 goto out; 4005 goto out;
4146 status = decode_open(&xdr, res);
4147 if (status)
4148 goto out;
4149 if (decode_getfh(&xdr, &res->fh) != 0) 4006 if (decode_getfh(&xdr, &res->fh) != 0)
4150 goto out; 4007 goto out;
4151 if (decode_getfattr(&xdr, res->f_attr, res->server) != 0) 4008 if (decode_getfattr(&xdr, res->f_attr, res->server) != 0)
@@ -4154,7 +4011,7 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr
4154 goto out; 4011 goto out;
4155 decode_getfattr(&xdr, res->dir_attr, res->server); 4012 decode_getfattr(&xdr, res->dir_attr, res->server);
4156out: 4013out:
4157 return status; 4014 return status;
4158} 4015}
4159 4016
4160/* 4017/*
@@ -4162,20 +4019,20 @@ out:
4162 */ 4019 */
4163static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res) 4020static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res)
4164{ 4021{
4165 struct xdr_stream xdr; 4022 struct xdr_stream xdr;
4166 struct compound_hdr hdr; 4023 struct compound_hdr hdr;
4167 int status; 4024 int status;
4168 4025
4169 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4026 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4170 status = decode_compound_hdr(&xdr, &hdr); 4027 status = decode_compound_hdr(&xdr, &hdr);
4171 if (status) 4028 if (status)
4172 goto out; 4029 goto out;
4173 status = decode_putfh(&xdr); 4030 status = decode_putfh(&xdr);
4174 if (status) 4031 if (status)
4175 goto out; 4032 goto out;
4176 status = decode_open_confirm(&xdr, res); 4033 status = decode_open_confirm(&xdr, res);
4177out: 4034out:
4178 return status; 4035 return status;
4179} 4036}
4180 4037
4181/* 4038/*
@@ -4183,23 +4040,23 @@ out:
4183 */ 4040 */
4184static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res) 4041static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
4185{ 4042{
4186 struct xdr_stream xdr; 4043 struct xdr_stream xdr;
4187 struct compound_hdr hdr; 4044 struct compound_hdr hdr;
4188 int status; 4045 int status;
4189 4046
4190 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4047 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4191 status = decode_compound_hdr(&xdr, &hdr); 4048 status = decode_compound_hdr(&xdr, &hdr);
4192 if (status) 4049 if (status)
4193 goto out; 4050 goto out;
4194 status = decode_putfh(&xdr); 4051 status = decode_putfh(&xdr);
4195 if (status) 4052 if (status)
4196 goto out; 4053 goto out;
4197 status = decode_open(&xdr, res); 4054 status = decode_open(&xdr, res);
4198 if (status) 4055 if (status)
4199 goto out; 4056 goto out;
4200 decode_getfattr(&xdr, res->f_attr, res->server); 4057 decode_getfattr(&xdr, res->f_attr, res->server);
4201out: 4058out:
4202 return status; 4059 return status;
4203} 4060}
4204 4061
4205/* 4062/*
@@ -4207,25 +4064,25 @@ out:
4207 */ 4064 */
4208static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res) 4065static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res)
4209{ 4066{
4210 struct xdr_stream xdr; 4067 struct xdr_stream xdr;
4211 struct compound_hdr hdr; 4068 struct compound_hdr hdr;
4212 int status; 4069 int status;
4213 4070
4214 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 4071 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4215 status = decode_compound_hdr(&xdr, &hdr); 4072 status = decode_compound_hdr(&xdr, &hdr);
4216 if (status) 4073 if (status)
4217 goto out; 4074 goto out;
4218 status = decode_putfh(&xdr); 4075 status = decode_putfh(&xdr);
4219 if (status) 4076 if (status)
4220 goto out; 4077 goto out;
4221 status = decode_setattr(&xdr, res); 4078 status = decode_setattr(&xdr, res);
4222 if (status) 4079 if (status)
4223 goto out; 4080 goto out;
4224 status = decode_getfattr(&xdr, res->fattr, res->server); 4081 status = decode_getfattr(&xdr, res->fattr, res->server);
4225 if (status == NFS4ERR_DELAY) 4082 if (status == NFS4ERR_DELAY)
4226 status = 0; 4083 status = 0;
4227out: 4084out:
4228 return status; 4085 return status;
4229} 4086}
4230 4087
4231/* 4088/*
@@ -4421,8 +4278,6 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf
4421 status = decode_putfh(&xdr); 4278 status = decode_putfh(&xdr);
4422 if (!status) 4279 if (!status)
4423 status = decode_fsinfo(&xdr, fsinfo); 4280 status = decode_fsinfo(&xdr, fsinfo);
4424 if (!status)
4425 status = nfs4_stat_to_errno(hdr.status);
4426 return status; 4281 return status;
4427} 4282}
4428 4283
@@ -4511,8 +4366,6 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
4511 status = decode_compound_hdr(&xdr, &hdr); 4366 status = decode_compound_hdr(&xdr, &hdr);
4512 if (!status) 4367 if (!status)
4513 status = decode_setclientid(&xdr, clp); 4368 status = decode_setclientid(&xdr, clp);
4514 if (!status)
4515 status = nfs4_stat_to_errno(hdr.status);
4516 return status; 4369 return status;
4517} 4370}
4518 4371
@@ -4533,8 +4386,6 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
4533 status = decode_putrootfh(&xdr); 4386 status = decode_putrootfh(&xdr);
4534 if (!status) 4387 if (!status)
4535 status = decode_fsinfo(&xdr, fsinfo); 4388 status = decode_fsinfo(&xdr, fsinfo);
4536 if (!status)
4537 status = nfs4_stat_to_errno(hdr.status);
4538 return status; 4389 return status;
4539} 4390}
4540 4391
@@ -4715,7 +4566,7 @@ nfs4_stat_to_errno(int stat)
4715 .p_replen = NFS4_##restype##_sz, \ 4566 .p_replen = NFS4_##restype##_sz, \
4716 .p_statidx = NFSPROC4_CLNT_##proc, \ 4567 .p_statidx = NFSPROC4_CLNT_##proc, \
4717 .p_name = #proc, \ 4568 .p_name = #proc, \
4718 } 4569}
4719 4570
4720struct rpc_procinfo nfs4_procedures[] = { 4571struct rpc_procinfo nfs4_procedures[] = {
4721 PROC(READ, enc_read, dec_read), 4572 PROC(READ, enc_read, dec_read),
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index d74d16ce0d49..d9ef602fbc5a 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -86,6 +86,8 @@
86#include <net/ipconfig.h> 86#include <net/ipconfig.h>
87#include <linux/parser.h> 87#include <linux/parser.h>
88 88
89#include "internal.h"
90
89/* Define this to allow debugging output */ 91/* Define this to allow debugging output */
90#undef NFSROOT_DEBUG 92#undef NFSROOT_DEBUG
91#define NFSDBG_FACILITY NFSDBG_ROOT 93#define NFSDBG_FACILITY NFSDBG_ROOT
@@ -100,7 +102,7 @@ static char nfs_root_name[256] __initdata = "";
100static __be32 servaddr __initdata = 0; 102static __be32 servaddr __initdata = 0;
101 103
102/* Name of directory to mount */ 104/* Name of directory to mount */
103static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, }; 105static char nfs_export_path[NFS_MAXPATHLEN] __initdata = { 0, };
104 106
105/* NFS-related data */ 107/* NFS-related data */
106static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */ 108static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */
@@ -312,7 +314,7 @@ static int __init root_nfs_name(char *name)
312 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n"); 314 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
313 return -1; 315 return -1;
314 } 316 }
315 sprintf(nfs_path, buf, cp); 317 sprintf(nfs_export_path, buf, cp);
316 318
317 return 1; 319 return 1;
318} 320}
@@ -340,7 +342,7 @@ static int __init root_nfs_addr(void)
340static void __init root_nfs_print(void) 342static void __init root_nfs_print(void)
341{ 343{
342 printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n", 344 printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
343 nfs_path, nfs_data.hostname); 345 nfs_export_path, nfs_data.hostname);
344 printk(KERN_NOTICE "Root-NFS: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n", 346 printk(KERN_NOTICE "Root-NFS: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
345 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans); 347 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
346 printk(KERN_NOTICE "Root-NFS: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n", 348 printk(KERN_NOTICE "Root-NFS: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
@@ -485,18 +487,23 @@ static int __init root_nfs_get_handle(void)
485{ 487{
486 struct nfs_fh fh; 488 struct nfs_fh fh;
487 struct sockaddr_in sin; 489 struct sockaddr_in sin;
490 struct nfs_mount_request request = {
491 .sap = (struct sockaddr *)&sin,
492 .salen = sizeof(sin),
493 .dirpath = nfs_export_path,
494 .version = (nfs_data.flags & NFS_MOUNT_VER3) ?
495 NFS_MNT3_VERSION : NFS_MNT_VERSION,
496 .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
497 XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP,
498 .fh = &fh,
499 };
488 int status; 500 int status;
489 int protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
490 XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP;
491 int version = (nfs_data.flags & NFS_MOUNT_VER3) ?
492 NFS_MNT3_VERSION : NFS_MNT_VERSION;
493 501
494 set_sockaddr(&sin, servaddr, htons(mount_port)); 502 set_sockaddr(&sin, servaddr, htons(mount_port));
495 status = nfs_mount((struct sockaddr *) &sin, sizeof(sin), NULL, 503 status = nfs_mount(&request);
496 nfs_path, version, protocol, &fh);
497 if (status < 0) 504 if (status < 0)
498 printk(KERN_ERR "Root-NFS: Server returned error %d " 505 printk(KERN_ERR "Root-NFS: Server returned error %d "
499 "while mounting %s\n", status, nfs_path); 506 "while mounting %s\n", status, nfs_export_path);
500 else { 507 else {
501 nfs_data.root.size = fh.size; 508 nfs_data.root.size = fh.size;
502 memcpy(nfs_data.root.data, fh.data, fh.size); 509 memcpy(nfs_data.root.data, fh.data, fh.size);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 40d17987d0e8..f856004bb7fa 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -533,12 +533,6 @@ readpage_async_filler(void *data, struct page *page)
533 unsigned int len; 533 unsigned int len;
534 int error; 534 int error;
535 535
536 error = nfs_wb_page(inode, page);
537 if (error)
538 goto out_unlock;
539 if (PageUptodate(page))
540 goto out_unlock;
541
542 len = nfs_page_length(page); 536 len = nfs_page_length(page);
543 if (len == 0) 537 if (len == 0)
544 return nfs_return_empty_page(page); 538 return nfs_return_empty_page(page);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index bb0313ac9e1f..d6686f4786dc 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -75,6 +75,7 @@ enum {
75 Opt_acl, Opt_noacl, 75 Opt_acl, Opt_noacl,
76 Opt_rdirplus, Opt_nordirplus, 76 Opt_rdirplus, Opt_nordirplus,
77 Opt_sharecache, Opt_nosharecache, 77 Opt_sharecache, Opt_nosharecache,
78 Opt_resvport, Opt_noresvport,
78 79
79 /* Mount options that take integer arguments */ 80 /* Mount options that take integer arguments */
80 Opt_port, 81 Opt_port,
@@ -129,6 +130,8 @@ static const match_table_t nfs_mount_option_tokens = {
129 { Opt_nordirplus, "nordirplus" }, 130 { Opt_nordirplus, "nordirplus" },
130 { Opt_sharecache, "sharecache" }, 131 { Opt_sharecache, "sharecache" },
131 { Opt_nosharecache, "nosharecache" }, 132 { Opt_nosharecache, "nosharecache" },
133 { Opt_resvport, "resvport" },
134 { Opt_noresvport, "noresvport" },
132 135
133 { Opt_port, "port=%u" }, 136 { Opt_port, "port=%u" },
134 { Opt_rsize, "rsize=%u" }, 137 { Opt_rsize, "rsize=%u" },
@@ -512,7 +515,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
512 { NFS_MOUNT_NONLM, ",nolock", "" }, 515 { NFS_MOUNT_NONLM, ",nolock", "" },
513 { NFS_MOUNT_NOACL, ",noacl", "" }, 516 { NFS_MOUNT_NOACL, ",noacl", "" },
514 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" }, 517 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
515 { NFS_MOUNT_UNSHARED, ",nosharecache", ""}, 518 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
519 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
516 { 0, NULL, NULL } 520 { 0, NULL, NULL }
517 }; 521 };
518 const struct proc_nfs_info *nfs_infop; 522 const struct proc_nfs_info *nfs_infop;
@@ -1033,6 +1037,12 @@ static int nfs_parse_mount_options(char *raw,
1033 case Opt_nosharecache: 1037 case Opt_nosharecache:
1034 mnt->flags |= NFS_MOUNT_UNSHARED; 1038 mnt->flags |= NFS_MOUNT_UNSHARED;
1035 break; 1039 break;
1040 case Opt_resvport:
1041 mnt->flags &= ~NFS_MOUNT_NORESVPORT;
1042 break;
1043 case Opt_noresvport:
1044 mnt->flags |= NFS_MOUNT_NORESVPORT;
1045 break;
1036 1046
1037 /* 1047 /*
1038 * options that take numeric values 1048 * options that take numeric values
@@ -1327,8 +1337,14 @@ out_security_failure:
1327static int nfs_try_mount(struct nfs_parsed_mount_data *args, 1337static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1328 struct nfs_fh *root_fh) 1338 struct nfs_fh *root_fh)
1329{ 1339{
1330 struct sockaddr *sap = (struct sockaddr *)&args->mount_server.address; 1340 struct nfs_mount_request request = {
1331 char *hostname; 1341 .sap = (struct sockaddr *)
1342 &args->mount_server.address,
1343 .dirpath = args->nfs_server.export_path,
1344 .protocol = args->mount_server.protocol,
1345 .fh = root_fh,
1346 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1347 };
1332 int status; 1348 int status;
1333 1349
1334 if (args->mount_server.version == 0) { 1350 if (args->mount_server.version == 0) {
@@ -1337,42 +1353,38 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1337 else 1353 else
1338 args->mount_server.version = NFS_MNT_VERSION; 1354 args->mount_server.version = NFS_MNT_VERSION;
1339 } 1355 }
1356 request.version = args->mount_server.version;
1340 1357
1341 if (args->mount_server.hostname) 1358 if (args->mount_server.hostname)
1342 hostname = args->mount_server.hostname; 1359 request.hostname = args->mount_server.hostname;
1343 else 1360 else
1344 hostname = args->nfs_server.hostname; 1361 request.hostname = args->nfs_server.hostname;
1345 1362
1346 /* 1363 /*
1347 * Construct the mount server's address. 1364 * Construct the mount server's address.
1348 */ 1365 */
1349 if (args->mount_server.address.ss_family == AF_UNSPEC) { 1366 if (args->mount_server.address.ss_family == AF_UNSPEC) {
1350 memcpy(sap, &args->nfs_server.address, 1367 memcpy(request.sap, &args->nfs_server.address,
1351 args->nfs_server.addrlen); 1368 args->nfs_server.addrlen);
1352 args->mount_server.addrlen = args->nfs_server.addrlen; 1369 args->mount_server.addrlen = args->nfs_server.addrlen;
1353 } 1370 }
1371 request.salen = args->mount_server.addrlen;
1354 1372
1355 /* 1373 /*
1356 * autobind will be used if mount_server.port == 0 1374 * autobind will be used if mount_server.port == 0
1357 */ 1375 */
1358 nfs_set_port(sap, args->mount_server.port); 1376 nfs_set_port(request.sap, args->mount_server.port);
1359 1377
1360 /* 1378 /*
1361 * Now ask the mount server to map our export path 1379 * Now ask the mount server to map our export path
1362 * to a file handle. 1380 * to a file handle.
1363 */ 1381 */
1364 status = nfs_mount(sap, 1382 status = nfs_mount(&request);
1365 args->mount_server.addrlen,
1366 hostname,
1367 args->nfs_server.export_path,
1368 args->mount_server.version,
1369 args->mount_server.protocol,
1370 root_fh);
1371 if (status == 0) 1383 if (status == 0)
1372 return 0; 1384 return 0;
1373 1385
1374 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", 1386 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
1375 hostname, status); 1387 request.hostname, status);
1376 return status; 1388 return status;
1377} 1389}
1378 1390
@@ -2419,7 +2431,7 @@ static void nfs4_kill_super(struct super_block *sb)
2419{ 2431{
2420 struct nfs_server *server = NFS_SB(sb); 2432 struct nfs_server *server = NFS_SB(sb);
2421 2433
2422 nfs_return_all_delegations(sb); 2434 nfs_super_return_all_delegations(sb);
2423 kill_anon_super(sb); 2435 kill_anon_super(sb);
2424 2436
2425 nfs4_renewd_prepare_shutdown(server); 2437 nfs4_renewd_prepare_shutdown(server);
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
index c11f5375d7c1..04133aacb1e5 100644
--- a/fs/nfs_common/nfsacl.c
+++ b/fs/nfs_common/nfsacl.c
@@ -29,8 +29,8 @@
29 29
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31 31
32EXPORT_SYMBOL(nfsacl_encode); 32EXPORT_SYMBOL_GPL(nfsacl_encode);
33EXPORT_SYMBOL(nfsacl_decode); 33EXPORT_SYMBOL_GPL(nfsacl_decode);
34 34
35struct nfsacl_encode_desc { 35struct nfsacl_encode_desc {
36 struct xdr_array2_desc desc; 36 struct xdr_array2_desc desc;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 094747a1227c..6d7d8c02c197 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -358,6 +358,7 @@ static struct rpc_program cb_program = {
358 .nrvers = ARRAY_SIZE(nfs_cb_version), 358 .nrvers = ARRAY_SIZE(nfs_cb_version),
359 .version = nfs_cb_version, 359 .version = nfs_cb_version,
360 .stats = &cb_stats, 360 .stats = &cb_stats,
361 .pipe_dir_name = "/nfsd4_cb",
361}; 362};
362 363
363/* Reference counting, callback cleanup, etc., all look racy as heck. 364/* Reference counting, callback cleanup, etc., all look racy as heck.
@@ -382,8 +383,9 @@ static int do_probe_callback(void *data)
382 .program = &cb_program, 383 .program = &cb_program,
383 .prognumber = cb->cb_prog, 384 .prognumber = cb->cb_prog,
384 .version = nfs_cb_version[1]->number, 385 .version = nfs_cb_version[1]->number,
385 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ 386 .authflavor = clp->cl_flavor,
386 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET), 387 .flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
388 .client_name = clp->cl_principal,
387 }; 389 };
388 struct rpc_message msg = { 390 struct rpc_message msg = {
389 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL], 391 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
@@ -392,6 +394,11 @@ static int do_probe_callback(void *data)
392 struct rpc_clnt *client; 394 struct rpc_clnt *client;
393 int status; 395 int status;
394 396
397 if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) {
398 status = nfserr_cb_path_down;
399 goto out_err;
400 }
401
395 /* Initialize address */ 402 /* Initialize address */
396 memset(&addr, 0, sizeof(addr)); 403 memset(&addr, 0, sizeof(addr));
397 addr.sin_family = AF_INET; 404 addr.sin_family = AF_INET;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index bf4cd46a5a11..13e0e074dbb8 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -54,6 +54,7 @@
54#include <linux/mutex.h> 54#include <linux/mutex.h>
55#include <linux/lockd/bind.h> 55#include <linux/lockd/bind.h>
56#include <linux/module.h> 56#include <linux/module.h>
57#include <linux/sunrpc/svcauth_gss.h>
57 58
58#define NFSDDBG_FACILITY NFSDDBG_PROC 59#define NFSDDBG_FACILITY NFSDDBG_PROC
59 60
@@ -377,6 +378,7 @@ free_client(struct nfs4_client *clp)
377 shutdown_callback_client(clp); 378 shutdown_callback_client(clp);
378 if (clp->cl_cred.cr_group_info) 379 if (clp->cl_cred.cr_group_info)
379 put_group_info(clp->cl_cred.cr_group_info); 380 put_group_info(clp->cl_cred.cr_group_info);
381 kfree(clp->cl_principal);
380 kfree(clp->cl_name.data); 382 kfree(clp->cl_name.data);
381 kfree(clp); 383 kfree(clp);
382} 384}
@@ -696,6 +698,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
696 unsigned int strhashval; 698 unsigned int strhashval;
697 struct nfs4_client *conf, *unconf, *new; 699 struct nfs4_client *conf, *unconf, *new;
698 __be32 status; 700 __be32 status;
701 char *princ;
699 char dname[HEXDIR_LEN]; 702 char dname[HEXDIR_LEN];
700 703
701 if (!check_name(clname)) 704 if (!check_name(clname))
@@ -783,6 +786,15 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
783 } 786 }
784 copy_verf(new, &clverifier); 787 copy_verf(new, &clverifier);
785 new->cl_addr = sin->sin_addr.s_addr; 788 new->cl_addr = sin->sin_addr.s_addr;
789 new->cl_flavor = rqstp->rq_flavor;
790 princ = svc_gss_principal(rqstp);
791 if (princ) {
792 new->cl_principal = kstrdup(princ, GFP_KERNEL);
793 if (new->cl_principal == NULL) {
794 free_client(new);
795 goto out;
796 }
797 }
786 copy_cred(&new->cl_cred, &rqstp->rq_cred); 798 copy_cred(&new->cl_cred, &rqstp->rq_cred);
787 gen_confirm(new); 799 gen_confirm(new);
788 gen_callback(new, setclid); 800 gen_callback(new, setclid);