8 fs/nfs/delegation.c | 186 +++--
9 fs/nfs/delegation.h | 26 -
11 fs/nfs/direct.c | 34 +
12 fs/nfs/inode.c | 73 +-
14 fs/nfs/mount_clnt.c | 169 +++--
18 fs/nfs/nfs4_fs.h | 40 +
19 fs/nfs/nfs4proc.c | 760 +++++++++++++---------
20 fs/nfs/nfs4state.c | 310 ++++++---
21 fs/nfs/nfs4xdr.c | 126 ++--
23 fs/nfs/pagelist.c | 60 +-
25 fs/nfs/super.c | 1189 +++++++++++++++++++++++++++++-----
26 fs/nfs/write.c | 149 ++--
27 fs/nfsd/nfs4callback.c | 18 -
28 fs/nfsd/nfs4state.c | 1
29 include/linux/lockd/lockd.h | 1
30 include/linux/nfs4.h | 1
31 include/linux/nfs4_mount.h | 3
32 include/linux/nfs_fs.h | 28 -
33 include/linux/nfs_fs_sb.h | 8
34 include/linux/nfs_mount.h | 3
35 include/linux/nfs_page.h | 25 -
36 include/linux/nfs_xdr.h | 5
37 include/linux/sunrpc/auth.h | 48 +
38 include/linux/sunrpc/auth_gss.h | 6
39 include/linux/sunrpc/clnt.h | 33 -
40 include/linux/sunrpc/gss_api.h | 2
41 include/linux/sunrpc/rpc_pipe_fs.h | 2
42 include/linux/sunrpc/sched.h | 6
43 include/linux/sunrpc/svcsock.h | 1
44 include/linux/sunrpc/xprt.h | 16
46 net/sunrpc/auth.c | 357 +++++++---
47 net/sunrpc/auth_gss/auth_gss.c | 339 ++++++----
48 net/sunrpc/auth_gss/gss_krb5_mech.c | 2
49 net/sunrpc/auth_gss/gss_spkm3_mech.c | 2
50 net/sunrpc/auth_null.c | 10
51 net/sunrpc/auth_unix.c | 54 +-
52 net/sunrpc/clnt.c | 367 +++++++---
53 net/sunrpc/rpc_pipe.c | 87 ++
54 net/sunrpc/rpcb_clnt.c | 65 +-
55 net/sunrpc/sched.c | 209 ++----
56 net/sunrpc/sunrpc_syms.c | 8
57 net/sunrpc/svcsock.c | 20 +
58 net/sunrpc/xprt.c | 19 -
59 net/sunrpc/xprtsock.c | 81 +-
60 57 files changed, 3305 insertions(+), 1807 deletions(-)
62 diff --git a/fs/lockd/host.c b/fs/lockd/host.c
63 index 96070bf..572601e 100644
66 @@ -44,9 +44,8 @@ static struct nsm_handle * nsm_find(const struct sockaddr_in *sin,
68 static struct nlm_host *
69 nlm_lookup_host(int server, const struct sockaddr_in *sin,
70 - int proto, int version,
71 - const char *hostname,
73 + int proto, int version, const char *hostname,
74 + int hostname_len, const struct sockaddr_in *ssin)
76 struct hlist_head *chain;
77 struct hlist_node *pos;
78 @@ -54,7 +53,9 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
79 struct nsm_handle *nsm = NULL;
82 - dprintk("lockd: nlm_lookup_host(%u.%u.%u.%u, p=%d, v=%d, my role=%s, name=%.*s)\n",
83 + dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT
84 + ", p=%d, v=%d, my role=%s, name=%.*s)\n",
85 + NIPQUAD(ssin->sin_addr.s_addr),
86 NIPQUAD(sin->sin_addr.s_addr), proto, version,
87 server? "server" : "client",
89 @@ -91,6 +92,8 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
91 if (host->h_server != server)
93 + if (!nlm_cmp_addr(&host->h_saddr, ssin))
96 /* Move to head of hash chain. */
97 hlist_del(&host->h_hash);
98 @@ -118,6 +121,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
99 host->h_name = nsm->sm_name;
101 host->h_addr.sin_port = 0; /* ouch! */
102 + host->h_saddr = *ssin;
103 host->h_version = version;
104 host->h_proto = proto;
105 host->h_rpcclnt = NULL;
106 @@ -161,15 +165,9 @@ nlm_destroy_host(struct nlm_host *host)
110 - if ((clnt = host->h_rpcclnt) != NULL) {
111 - if (atomic_read(&clnt->cl_users)) {
112 - printk(KERN_WARNING
113 - "lockd: active RPC handle\n");
116 - rpc_destroy_client(host->h_rpcclnt);
119 + clnt = host->h_rpcclnt;
121 + rpc_shutdown_client(clnt);
125 @@ -180,8 +178,10 @@ struct nlm_host *
126 nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version,
127 const char *hostname, int hostname_len)
129 + struct sockaddr_in ssin = {0};
131 return nlm_lookup_host(0, sin, proto, version,
132 - hostname, hostname_len);
133 + hostname, hostname_len, &ssin);
137 @@ -191,9 +191,12 @@ struct nlm_host *
138 nlmsvc_lookup_host(struct svc_rqst *rqstp,
139 const char *hostname, int hostname_len)
141 + struct sockaddr_in ssin = {0};
143 + ssin.sin_addr = rqstp->rq_daddr.addr;
144 return nlm_lookup_host(1, svc_addr_in(rqstp),
145 rqstp->rq_prot, rqstp->rq_vers,
146 - hostname, hostname_len);
147 + hostname, hostname_len, &ssin);
151 @@ -204,8 +207,9 @@ nlm_bind_host(struct nlm_host *host)
153 struct rpc_clnt *clnt;
155 - dprintk("lockd: nlm_bind_host(%08x)\n",
156 - (unsigned)ntohl(host->h_addr.sin_addr.s_addr));
157 + dprintk("lockd: nlm_bind_host("NIPQUAD_FMT"->"NIPQUAD_FMT")\n",
158 + NIPQUAD(host->h_saddr.sin_addr),
159 + NIPQUAD(host->h_addr.sin_addr));
161 /* Lock host handle */
162 mutex_lock(&host->h_mutex);
163 @@ -232,6 +236,7 @@ nlm_bind_host(struct nlm_host *host)
164 .protocol = host->h_proto,
165 .address = (struct sockaddr *)&host->h_addr,
166 .addrsize = sizeof(host->h_addr),
167 + .saddress = (struct sockaddr *)&host->h_saddr,
168 .timeout = &timeparms,
169 .servername = host->h_name,
170 .program = &nlm_program,
171 diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
172 index 2102e2d..3353ed8 100644
175 @@ -61,6 +61,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
179 + rpc_shutdown_client(clnt);
183 @@ -138,7 +139,6 @@ nsm_create(void)
184 .program = &nsm_program,
185 .version = SM_VERSION,
186 .authflavor = RPC_AUTH_NULL,
187 - .flags = (RPC_CLNT_CREATE_ONESHOT),
190 return rpc_create(&args);
191 diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
192 index 126b1bf..2680932 100644
195 @@ -123,9 +123,6 @@ lockd(struct svc_rqst *rqstp)
196 /* Process request with signals blocked, but allow SIGKILL. */
197 allow_signal(SIGKILL);
202 dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");
205 @@ -202,9 +199,6 @@ lockd(struct svc_rqst *rqstp)
206 /* Exit the RPC thread */
207 svc_exit_thread(rqstp);
209 - /* release rpciod */
214 module_put_and_exit(0);
215 diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
216 index f4580b4..b55cb23 100644
217 --- a/fs/nfs/Makefile
218 +++ b/fs/nfs/Makefile
219 @@ -6,8 +6,8 @@ obj-$(CONFIG_NFS_FS) += nfs.o
221 nfs-y := client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \
222 pagelist.o proc.o read.o symlink.o unlink.o \
223 - write.o namespace.o
224 -nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o
225 + write.o namespace.o mount_clnt.o
226 +nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
227 nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
228 nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
229 nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
230 diff --git a/fs/nfs/client.c b/fs/nfs/client.c
231 index 881fa49..ccb4550 100644
232 --- a/fs/nfs/client.c
233 +++ b/fs/nfs/client.c
234 @@ -102,19 +102,10 @@ static struct nfs_client *nfs_alloc_client(const char *hostname,
237 struct nfs_client *clp;
240 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
243 - error = rpciod_up();
245 - dprintk("%s: couldn't start rpciod! Error = %d\n",
246 - __FUNCTION__, error);
249 - __set_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
251 if (nfsversion == 4) {
252 if (nfs_callback_up() < 0)
254 @@ -139,8 +130,6 @@ static struct nfs_client *nfs_alloc_client(const char *hostname,
256 init_rwsem(&clp->cl_sem);
257 INIT_LIST_HEAD(&clp->cl_delegations);
258 - INIT_LIST_HEAD(&clp->cl_state_owners);
259 - INIT_LIST_HEAD(&clp->cl_unused);
260 spin_lock_init(&clp->cl_lock);
261 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
262 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
263 @@ -154,9 +143,6 @@ error_3:
264 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
268 - __clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
273 @@ -167,16 +153,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
275 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
276 nfs4_kill_renewd(clp);
277 - while (!list_empty(&clp->cl_unused)) {
278 - struct nfs4_state_owner *sp;
280 - sp = list_entry(clp->cl_unused.next,
281 - struct nfs4_state_owner,
283 - list_del(&sp->so_list);
286 - BUG_ON(!list_empty(&clp->cl_state_owners));
287 + BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners));
288 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
289 nfs_idmap_delete(clp);
291 @@ -198,9 +175,6 @@ static void nfs_free_client(struct nfs_client *clp)
292 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
295 - if (__test_and_clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state))
298 kfree(clp->cl_hostname);
301 diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
302 index 7f37d1b..20ac403 100644
303 --- a/fs/nfs/delegation.c
304 +++ b/fs/nfs/delegation.c
305 @@ -27,6 +27,13 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
309 +static void nfs_free_delegation_callback(struct rcu_head *head)
311 + struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
313 + nfs_free_delegation(delegation);
316 static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
318 struct inode *inode = state->inode;
319 @@ -57,7 +64,7 @@ out_err:
323 -static void nfs_delegation_claim_opens(struct inode *inode)
324 +static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
326 struct nfs_inode *nfsi = NFS_I(inode);
327 struct nfs_open_context *ctx;
328 @@ -72,9 +79,11 @@ again:
330 if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
332 + if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
334 get_nfs_open_context(ctx);
335 spin_unlock(&inode->i_lock);
336 - err = nfs4_open_delegation_recall(ctx->dentry, state);
337 + err = nfs4_open_delegation_recall(ctx, state, stateid);
339 err = nfs_delegation_claim_locks(ctx, state);
340 put_nfs_open_context(ctx);
341 @@ -115,10 +124,6 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
342 struct nfs_delegation *delegation;
345 - /* Ensure we first revalidate the attributes and page cache! */
346 - if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR)))
347 - __nfs_revalidate_inode(NFS_SERVER(inode), inode);
349 delegation = kmalloc(sizeof(*delegation), GFP_KERNEL);
350 if (delegation == NULL)
352 @@ -131,10 +136,10 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
353 delegation->inode = inode;
355 spin_lock(&clp->cl_lock);
356 - if (nfsi->delegation == NULL) {
357 - list_add(&delegation->super_list, &clp->cl_delegations);
358 - nfsi->delegation = delegation;
359 + if (rcu_dereference(nfsi->delegation) == NULL) {
360 + list_add_rcu(&delegation->super_list, &clp->cl_delegations);
361 nfsi->delegation_state = delegation->type;
362 + rcu_assign_pointer(nfsi->delegation, delegation);
365 if (memcmp(&delegation->stateid, &nfsi->delegation->stateid,
366 @@ -145,6 +150,12 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
371 + /* Ensure we revalidate the attributes and page cache! */
372 + spin_lock(&inode->i_lock);
373 + nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
374 + spin_unlock(&inode->i_lock);
376 spin_unlock(&clp->cl_lock);
379 @@ -155,7 +166,7 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
382 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid);
383 - nfs_free_delegation(delegation);
384 + call_rcu(&delegation->rcu, nfs_free_delegation_callback);
388 @@ -170,33 +181,55 @@ static void nfs_msync_inode(struct inode *inode)
390 * Basic procedure for returning a delegation to the server
392 -int __nfs_inode_return_delegation(struct inode *inode)
393 +static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation)
395 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
396 struct nfs_inode *nfsi = NFS_I(inode);
397 - struct nfs_delegation *delegation;
400 nfs_msync_inode(inode);
401 down_read(&clp->cl_sem);
402 /* Guard against new delegated open calls */
403 down_write(&nfsi->rwsem);
404 - spin_lock(&clp->cl_lock);
405 - delegation = nfsi->delegation;
406 - if (delegation != NULL) {
407 - list_del_init(&delegation->super_list);
408 - nfsi->delegation = NULL;
409 - nfsi->delegation_state = 0;
411 - spin_unlock(&clp->cl_lock);
412 - nfs_delegation_claim_opens(inode);
413 + nfs_delegation_claim_opens(inode, &delegation->stateid);
414 up_write(&nfsi->rwsem);
415 up_read(&clp->cl_sem);
416 nfs_msync_inode(inode);
418 - if (delegation != NULL)
419 - res = nfs_do_return_delegation(inode, delegation);
421 + return nfs_do_return_delegation(inode, delegation);
424 +static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid)
426 + struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
428 + if (delegation == NULL)
430 + if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data,
431 + sizeof(delegation->stateid.data)) != 0)
433 + list_del_rcu(&delegation->super_list);
434 + nfsi->delegation_state = 0;
435 + rcu_assign_pointer(nfsi->delegation, NULL);
441 +int nfs_inode_return_delegation(struct inode *inode)
443 + struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
444 + struct nfs_inode *nfsi = NFS_I(inode);
445 + struct nfs_delegation *delegation;
448 + if (rcu_dereference(nfsi->delegation) != NULL) {
449 + spin_lock(&clp->cl_lock);
450 + delegation = nfs_detach_delegation_locked(nfsi, NULL);
451 + spin_unlock(&clp->cl_lock);
452 + if (delegation != NULL)
453 + err = __nfs_inode_return_delegation(inode, delegation);
459 @@ -211,19 +244,23 @@ void nfs_return_all_delegations(struct super_block *sb)
463 - spin_lock(&clp->cl_lock);
464 - list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
466 + list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
467 if (delegation->inode->i_sb != sb)
469 inode = igrab(delegation->inode);
472 + spin_lock(&clp->cl_lock);
473 + delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
474 spin_unlock(&clp->cl_lock);
475 - nfs_inode_return_delegation(inode);
477 + if (delegation != NULL)
478 + __nfs_inode_return_delegation(inode, delegation);
482 - spin_unlock(&clp->cl_lock);
486 static int nfs_do_expire_all_delegations(void *ptr)
487 @@ -234,22 +271,26 @@ static int nfs_do_expire_all_delegations(void *ptr)
489 allow_signal(SIGKILL);
491 - spin_lock(&clp->cl_lock);
492 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
494 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
496 - list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
498 + list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
499 inode = igrab(delegation->inode);
502 + spin_lock(&clp->cl_lock);
503 + delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
504 spin_unlock(&clp->cl_lock);
505 - nfs_inode_return_delegation(inode);
508 + __nfs_inode_return_delegation(inode, delegation);
514 - spin_unlock(&clp->cl_lock);
516 module_put_and_exit(0);
518 @@ -280,17 +321,21 @@ void nfs_handle_cb_pathdown(struct nfs_client *clp)
522 - spin_lock(&clp->cl_lock);
523 - list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
525 + list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
526 inode = igrab(delegation->inode);
529 + spin_lock(&clp->cl_lock);
530 + delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
531 spin_unlock(&clp->cl_lock);
532 - nfs_inode_return_delegation(inode);
534 + if (delegation != NULL)
535 + __nfs_inode_return_delegation(inode, delegation);
539 - spin_unlock(&clp->cl_lock);
543 struct recall_threadargs {
544 @@ -316,21 +361,14 @@ static int recall_thread(void *data)
545 down_read(&clp->cl_sem);
546 down_write(&nfsi->rwsem);
547 spin_lock(&clp->cl_lock);
548 - delegation = nfsi->delegation;
549 - if (delegation != NULL && memcmp(delegation->stateid.data,
550 - args->stateid->data,
551 - sizeof(delegation->stateid.data)) == 0) {
552 - list_del_init(&delegation->super_list);
553 - nfsi->delegation = NULL;
554 - nfsi->delegation_state = 0;
555 + delegation = nfs_detach_delegation_locked(nfsi, args->stateid);
556 + if (delegation != NULL)
561 args->result = -ENOENT;
563 spin_unlock(&clp->cl_lock);
564 complete(&args->started);
565 - nfs_delegation_claim_opens(inode);
566 + nfs_delegation_claim_opens(inode, args->stateid);
567 up_write(&nfsi->rwsem);
568 up_read(&clp->cl_sem);
569 nfs_msync_inode(inode);
570 @@ -371,14 +409,14 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
572 struct nfs_delegation *delegation;
573 struct inode *res = NULL;
574 - spin_lock(&clp->cl_lock);
575 - list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
577 + list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
578 if (nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
579 res = igrab(delegation->inode);
583 - spin_unlock(&clp->cl_lock);
588 @@ -388,10 +426,10 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
589 void nfs_delegation_mark_reclaim(struct nfs_client *clp)
591 struct nfs_delegation *delegation;
592 - spin_lock(&clp->cl_lock);
593 - list_for_each_entry(delegation, &clp->cl_delegations, super_list)
595 + list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list)
596 delegation->flags |= NFS_DELEGATION_NEED_RECLAIM;
597 - spin_unlock(&clp->cl_lock);
602 @@ -399,39 +437,35 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp)
604 void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
606 - struct nfs_delegation *delegation, *n;
608 - spin_lock(&clp->cl_lock);
609 - list_for_each_entry_safe(delegation, n, &clp->cl_delegations, super_list) {
610 + struct nfs_delegation *delegation;
613 + list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
614 if ((delegation->flags & NFS_DELEGATION_NEED_RECLAIM) == 0)
616 - list_move(&delegation->super_list, &head);
617 - NFS_I(delegation->inode)->delegation = NULL;
618 - NFS_I(delegation->inode)->delegation_state = 0;
620 - spin_unlock(&clp->cl_lock);
621 - while(!list_empty(&head)) {
622 - delegation = list_entry(head.next, struct nfs_delegation, super_list);
623 - list_del(&delegation->super_list);
624 - nfs_free_delegation(delegation);
625 + spin_lock(&clp->cl_lock);
626 + delegation = nfs_detach_delegation_locked(NFS_I(delegation->inode), NULL);
627 + spin_unlock(&clp->cl_lock);
629 + if (delegation != NULL)
630 + call_rcu(&delegation->rcu, nfs_free_delegation_callback);
636 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
638 - struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
639 struct nfs_inode *nfsi = NFS_I(inode);
640 struct nfs_delegation *delegation;
644 - if (nfsi->delegation_state == 0)
646 - spin_lock(&clp->cl_lock);
647 - delegation = nfsi->delegation;
649 + delegation = rcu_dereference(nfsi->delegation);
650 if (delegation != NULL) {
651 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data));
655 - spin_unlock(&clp->cl_lock);
660 diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
661 index 2cfd4b2..5874ce7 100644
662 --- a/fs/nfs/delegation.h
663 +++ b/fs/nfs/delegation.h
664 @@ -22,11 +22,12 @@ struct nfs_delegation {
668 + struct rcu_head rcu;
671 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
672 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
673 -int __nfs_inode_return_delegation(struct inode *inode);
674 +int nfs_inode_return_delegation(struct inode *inode);
675 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
677 struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
678 @@ -39,27 +40,24 @@ void nfs_delegation_reap_unclaimed(struct nfs_client *clp);
680 /* NFSv4 delegation-related procedures */
681 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid);
682 -int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state);
683 +int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid);
684 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl);
685 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
687 static inline int nfs_have_delegation(struct inode *inode, int flags)
689 + struct nfs_delegation *delegation;
692 flags &= FMODE_READ|FMODE_WRITE;
694 - if ((NFS_I(inode)->delegation_state & flags) == flags)
698 + delegation = rcu_dereference(NFS_I(inode)->delegation);
699 + if (delegation != NULL && (delegation->type & flags) == flags)
705 -static inline int nfs_inode_return_delegation(struct inode *inode)
709 - if (NFS_I(inode)->delegation != NULL)
710 - err = __nfs_inode_return_delegation(inode);
714 static inline int nfs_have_delegation(struct inode *inode, int flags)
716 diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
717 index c27258b..322141f 100644
720 @@ -897,14 +897,13 @@ int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
721 return (nd->intent.open.flags & O_EXCL) != 0;
724 -static inline int nfs_reval_fsid(struct vfsmount *mnt, struct inode *dir,
725 - struct nfs_fh *fh, struct nfs_fattr *fattr)
726 +static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr)
728 struct nfs_server *server = NFS_SERVER(dir);
730 if (!nfs_fsid_equal(&server->fsid, &fattr->fsid))
731 - /* Revalidate fsid on root dir */
732 - return __nfs_revalidate_inode(server, mnt->mnt_root->d_inode);
733 + /* Revalidate fsid using the parent directory */
734 + return __nfs_revalidate_inode(server, dir);
738 @@ -946,7 +945,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
739 res = ERR_PTR(error);
742 - error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr);
743 + error = nfs_reval_fsid(dir, &fattr);
745 res = ERR_PTR(error);
747 @@ -1244,7 +1243,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
749 attr.ia_valid = ATTR_MODE;
751 - if (nd && (nd->flags & LOOKUP_CREATE))
752 + if ((nd->flags & LOOKUP_CREATE) != 0)
753 open_flags = nd->intent.open.flags;
756 @@ -1535,7 +1534,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
760 - page = alloc_page(GFP_KERNEL);
761 + page = alloc_page(GFP_HIGHUSER);
765 @@ -1744,8 +1743,8 @@ int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
766 struct nfs_inode *nfsi;
767 struct nfs_access_entry *cache;
769 - spin_lock(&nfs_access_lru_lock);
771 + spin_lock(&nfs_access_lru_lock);
772 list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) {
775 @@ -1770,6 +1769,7 @@ remove_lru_entry:
776 clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags);
778 spin_unlock(&inode->i_lock);
779 + spin_unlock(&nfs_access_lru_lock);
783 diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
784 index 00eee87..a5c82b6 100644
785 --- a/fs/nfs/direct.c
786 +++ b/fs/nfs/direct.c
787 @@ -266,7 +266,7 @@ static const struct rpc_call_ops nfs_read_direct_ops = {
788 static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos)
790 struct nfs_open_context *ctx = dreq->ctx;
791 - struct inode *inode = ctx->dentry->d_inode;
792 + struct inode *inode = ctx->path.dentry->d_inode;
793 size_t rsize = NFS_SERVER(inode)->rsize;
796 @@ -295,9 +295,14 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
799 if ((unsigned)result < data->npages) {
800 - nfs_direct_release_pages(data->pagevec, result);
801 - nfs_readdata_release(data);
803 + bytes = result * PAGE_SIZE;
804 + if (bytes <= pgbase) {
805 + nfs_direct_release_pages(data->pagevec, result);
806 + nfs_readdata_release(data);
810 + data->npages = result;
814 @@ -601,7 +606,7 @@ static const struct rpc_call_ops nfs_write_direct_ops = {
815 static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos, int sync)
817 struct nfs_open_context *ctx = dreq->ctx;
818 - struct inode *inode = ctx->dentry->d_inode;
819 + struct inode *inode = ctx->path.dentry->d_inode;
820 size_t wsize = NFS_SERVER(inode)->wsize;
823 @@ -630,9 +635,14 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
826 if ((unsigned)result < data->npages) {
827 - nfs_direct_release_pages(data->pagevec, result);
828 - nfs_writedata_release(data);
830 + bytes = result * PAGE_SIZE;
831 + if (bytes <= pgbase) {
832 + nfs_direct_release_pages(data->pagevec, result);
833 + nfs_writedata_release(data);
837 + data->npages = result;
841 @@ -763,10 +773,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
842 (unsigned long) count, (long long) pos);
851 if (!access_ok(VERIFY_WRITE, buf, count))
853 @@ -814,7 +822,7 @@ out:
854 ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
855 unsigned long nr_segs, loff_t pos)
858 + ssize_t retval = -EINVAL;
859 struct file *file = iocb->ki_filp;
860 struct address_space *mapping = file->f_mapping;
862 @@ -827,7 +835,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
863 (unsigned long) count, (long long) pos);
869 retval = generic_write_checks(file, &pos, &count, 0);
871 diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
872 index bd9f5a8..3d9fccf 100644
875 @@ -461,14 +461,14 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
877 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
879 - atomic_set(&ctx->count, 1);
880 - ctx->dentry = dget(dentry);
881 - ctx->vfsmnt = mntget(mnt);
882 + ctx->path.dentry = dget(dentry);
883 + ctx->path.mnt = mntget(mnt);
884 ctx->cred = get_rpccred(cred);
886 ctx->lockowner = current->files;
889 + kref_init(&ctx->kref);
893 @@ -476,27 +476,33 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
894 struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
897 - atomic_inc(&ctx->count);
898 + kref_get(&ctx->kref);
902 -void put_nfs_open_context(struct nfs_open_context *ctx)
903 +static void nfs_free_open_context(struct kref *kref)
905 - if (atomic_dec_and_test(&ctx->count)) {
906 - if (!list_empty(&ctx->list)) {
907 - struct inode *inode = ctx->dentry->d_inode;
908 - spin_lock(&inode->i_lock);
909 - list_del(&ctx->list);
910 - spin_unlock(&inode->i_lock);
912 - if (ctx->state != NULL)
913 - nfs4_close_state(ctx->state, ctx->mode);
914 - if (ctx->cred != NULL)
915 - put_rpccred(ctx->cred);
917 - mntput(ctx->vfsmnt);
919 + struct nfs_open_context *ctx = container_of(kref,
920 + struct nfs_open_context, kref);
922 + if (!list_empty(&ctx->list)) {
923 + struct inode *inode = ctx->path.dentry->d_inode;
924 + spin_lock(&inode->i_lock);
925 + list_del(&ctx->list);
926 + spin_unlock(&inode->i_lock);
928 + if (ctx->state != NULL)
929 + nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
930 + if (ctx->cred != NULL)
931 + put_rpccred(ctx->cred);
932 + dput(ctx->path.dentry);
933 + mntput(ctx->path.mnt);
937 +void put_nfs_open_context(struct nfs_open_context *ctx)
939 + kref_put(&ctx->kref, nfs_free_open_context);
943 @@ -961,8 +967,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
946 server = NFS_SERVER(inode);
947 - /* Update the fsid if and only if this is the root directory */
948 - if (inode == inode->i_sb->s_root->d_inode
949 + /* Update the fsid? */
950 + if (S_ISDIR(inode->i_mode)
951 && !nfs_fsid_equal(&server->fsid, &fattr->fsid))
952 server->fsid = fattr->fsid;
954 @@ -1066,8 +1072,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
955 invalid &= ~NFS_INO_INVALID_DATA;
957 invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
958 - if (!nfs_have_delegation(inode, FMODE_READ))
959 + if (!nfs_have_delegation(inode, FMODE_READ) ||
960 + (nfsi->cache_validity & NFS_INO_REVAL_FORCED))
961 nfsi->cache_validity |= invalid;
962 + nfsi->cache_validity &= ~NFS_INO_REVAL_FORCED;
966 @@ -1103,27 +1111,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
968 void nfs4_clear_inode(struct inode *inode)
970 - struct nfs_inode *nfsi = NFS_I(inode);
972 /* If we are holding a delegation, return it! */
973 nfs_inode_return_delegation(inode);
974 /* First call standard NFS clear_inode() code */
975 nfs_clear_inode(inode);
976 - /* Now clear out any remaining state */
977 - while (!list_empty(&nfsi->open_states)) {
978 - struct nfs4_state *state;
980 - state = list_entry(nfsi->open_states.next,
983 - dprintk("%s(%s/%Ld): found unclaimed NFSv4 state %p\n",
986 - (long long)NFS_FILEID(inode),
988 - BUG_ON(atomic_read(&state->count) != 1);
989 - nfs4_close_state(state, state->state);
994 @@ -1165,15 +1156,11 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
995 struct nfs_inode *nfsi = (struct nfs_inode *) foo;
997 inode_init_once(&nfsi->vfs_inode);
998 - spin_lock_init(&nfsi->req_lock);
999 - INIT_LIST_HEAD(&nfsi->dirty);
1000 - INIT_LIST_HEAD(&nfsi->commit);
1001 INIT_LIST_HEAD(&nfsi->open_files);
1002 INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
1003 INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
1004 INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
1005 atomic_set(&nfsi->data_updates, 0);
1009 nfs4_init_once(nfsi);
1010 diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
1011 index ad2b40d..76cf55d 100644
1012 --- a/fs/nfs/internal.h
1013 +++ b/fs/nfs/internal.h
1014 @@ -183,9 +183,9 @@ unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
1016 * Calculate the number of 512byte blocks used.
1018 -static inline unsigned long nfs_calc_block_size(u64 tsize)
1019 +static inline blkcnt_t nfs_calc_block_size(u64 tsize)
1021 - loff_t used = (tsize + 511) >> 9;
1022 + blkcnt_t used = (tsize + 511) >> 9;
1023 return (used > ULONG_MAX) ? ULONG_MAX : used;
1026 diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
1027 index ca5a266..8afd9f7 100644
1028 --- a/fs/nfs/mount_clnt.c
1029 +++ b/fs/nfs/mount_clnt.c
1032 - * linux/fs/nfs/mount_clnt.c
1034 - * MOUNT client to support NFSroot.
1035 + * In-kernel MOUNT protocol client
1037 * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
1040 #include <linux/nfs_fs.h>
1043 -# define NFSDBG_FACILITY NFSDBG_ROOT
1044 +# define NFSDBG_FACILITY NFSDBG_MOUNT
1048 -#define MOUNT_PROGRAM 100005
1049 -#define MOUNT_VERSION 1
1050 -#define MOUNT_MNT 1
1051 -#define MOUNT_UMNT 3
1054 -static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *,
1056 static struct rpc_program mnt_program;
1058 struct mnt_fhstatus {
1059 - unsigned int status;
1060 - struct nfs_fh * fh;
1062 + struct nfs_fh *fh;
1066 - * Obtain an NFS file handle for the given host and path
1068 + * nfs_mount - Obtain an NFS file handle for the given host and path
1069 + * @addr: pointer to server's address
1070 + * @len: size of server's address
1071 + * @hostname: name of server host, or NULL
1072 + * @path: pointer to string containing export path to mount
1073 + * @version: mount version to use for this request
1074 + * @protocol: transport protocol to use for thie request
1075 + * @fh: pointer to location to place returned file handle
1077 + * Uses default timeout parameters specified by underlying transport.
1080 -nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
1081 - int version, int protocol)
1082 +int nfs_mount(struct sockaddr *addr, size_t len, char *hostname, char *path,
1083 + int version, int protocol, struct nfs_fh *fh)
1085 - struct rpc_clnt *mnt_clnt;
1086 struct mnt_fhstatus result = {
1089 @@ -52,16 +48,25 @@ nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
1091 .rpc_resp = &result,
1093 - char hostname[32];
1094 + struct rpc_create_args args = {
1095 + .protocol = protocol,
1098 + .servername = hostname,
1099 + .program = &mnt_program,
1100 + .version = version,
1101 + .authflavor = RPC_AUTH_UNIX,
1102 + .flags = RPC_CLNT_CREATE_INTR,
1104 + struct rpc_clnt *mnt_clnt;
1107 - dprintk("NFS: nfs_mount(%08x:%s)\n",
1108 - (unsigned)ntohl(addr->sin_addr.s_addr), path);
1109 + dprintk("NFS: sending MNT request for %s:%s\n",
1110 + (hostname ? hostname : "server"), path);
1112 - sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr));
1113 - mnt_clnt = mnt_create(hostname, addr, version, protocol);
1114 + mnt_clnt = rpc_create(&args);
1115 if (IS_ERR(mnt_clnt))
1116 - return PTR_ERR(mnt_clnt);
1117 + goto out_clnt_err;
1119 if (version == NFS_MNT3_VERSION)
1120 msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
1121 @@ -69,33 +74,39 @@ nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
1122 msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT];
1124 status = rpc_call_sync(mnt_clnt, &msg, 0);
1125 - return status < 0? status : (result.status? -EACCES : 0);
1127 + rpc_shutdown_client(mnt_clnt);
1129 -static struct rpc_clnt *
1130 -mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
1133 - struct rpc_create_args args = {
1134 - .protocol = protocol,
1135 - .address = (struct sockaddr *)srvaddr,
1136 - .addrsize = sizeof(*srvaddr),
1137 - .servername = hostname,
1138 - .program = &mnt_program,
1139 - .version = version,
1140 - .authflavor = RPC_AUTH_UNIX,
1141 - .flags = (RPC_CLNT_CREATE_ONESHOT |
1142 - RPC_CLNT_CREATE_INTR),
1145 + goto out_call_err;
1146 + if (result.status != 0)
1149 + dprintk("NFS: MNT request succeeded\n");
1156 + status = PTR_ERR(mnt_clnt);
1157 + dprintk("NFS: failed to create RPC client, status=%d\n", status);
1161 + dprintk("NFS: failed to start MNT request, status=%d\n", status);
1164 - return rpc_create(&args);
1166 + dprintk("NFS: MNT server returned result %d\n", result.status);
1172 * XDR encode/decode functions for MOUNT
1175 -xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, const char *path)
1176 +static int xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p,
1179 p = xdr_encode_string(p, path);
1181 @@ -103,8 +114,8 @@ xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, const char *path)
1186 -xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
1187 +static int xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p,
1188 + struct mnt_fhstatus *res)
1190 struct nfs_fh *fh = res->fh;
1192 @@ -115,8 +126,8 @@ xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
1197 -xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
1198 +static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
1199 + struct mnt_fhstatus *res)
1201 struct nfs_fh *fh = res->fh;
1203 @@ -135,53 +146,53 @@ xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
1204 #define MNT_fhstatus_sz (1 + 8)
1205 #define MNT_fhstatus3_sz (1 + 16)
1207 -static struct rpc_procinfo mnt_procedures[] = {
1209 - .p_proc = MNTPROC_MNT,
1210 - .p_encode = (kxdrproc_t) xdr_encode_dirpath,
1211 - .p_decode = (kxdrproc_t) xdr_decode_fhstatus,
1212 - .p_arglen = MNT_dirpath_sz,
1213 - .p_replen = MNT_fhstatus_sz,
1214 - .p_statidx = MNTPROC_MNT,
1215 - .p_name = "MOUNT",
1216 +static struct rpc_procinfo mnt_procedures[] = {
1218 + .p_proc = MNTPROC_MNT,
1219 + .p_encode = (kxdrproc_t) xdr_encode_dirpath,
1220 + .p_decode = (kxdrproc_t) xdr_decode_fhstatus,
1221 + .p_arglen = MNT_dirpath_sz,
1222 + .p_replen = MNT_fhstatus_sz,
1223 + .p_statidx = MNTPROC_MNT,
1224 + .p_name = "MOUNT",
1228 static struct rpc_procinfo mnt3_procedures[] = {
1229 -[MOUNTPROC3_MNT] = {
1230 - .p_proc = MOUNTPROC3_MNT,
1231 - .p_encode = (kxdrproc_t) xdr_encode_dirpath,
1232 - .p_decode = (kxdrproc_t) xdr_decode_fhstatus3,
1233 - .p_arglen = MNT_dirpath_sz,
1234 - .p_replen = MNT_fhstatus3_sz,
1235 - .p_statidx = MOUNTPROC3_MNT,
1236 - .p_name = "MOUNT",
1237 + [MOUNTPROC3_MNT] = {
1238 + .p_proc = MOUNTPROC3_MNT,
1239 + .p_encode = (kxdrproc_t) xdr_encode_dirpath,
1240 + .p_decode = (kxdrproc_t) xdr_decode_fhstatus3,
1241 + .p_arglen = MNT_dirpath_sz,
1242 + .p_replen = MNT_fhstatus3_sz,
1243 + .p_statidx = MOUNTPROC3_MNT,
1244 + .p_name = "MOUNT",
1249 -static struct rpc_version mnt_version1 = {
1252 - .procs = mnt_procedures
1253 +static struct rpc_version mnt_version1 = {
1256 + .procs = mnt_procedures,
1259 -static struct rpc_version mnt_version3 = {
1262 - .procs = mnt3_procedures
1263 +static struct rpc_version mnt_version3 = {
1266 + .procs = mnt3_procedures,
1269 -static struct rpc_version * mnt_version[] = {
1270 +static struct rpc_version *mnt_version[] = {
1277 -static struct rpc_stat mnt_stats;
1278 +static struct rpc_stat mnt_stats;
1280 -static struct rpc_program mnt_program = {
1281 +static struct rpc_program mnt_program = {
1283 .number = NFS_MNT_PROGRAM,
1284 .nrvers = ARRAY_SIZE(mnt_version),
1285 diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
1286 index cd3ca7b..7fcc78f 100644
1287 --- a/fs/nfs/nfs2xdr.c
1288 +++ b/fs/nfs/nfs2xdr.c
1289 @@ -223,7 +223,7 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
1291 nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
1293 - struct rpc_auth *auth = req->rq_task->tk_auth;
1294 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1295 unsigned int replen;
1296 u32 offset = (u32)args->offset;
1297 u32 count = args->count;
1298 @@ -380,7 +380,7 @@ static int
1299 nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
1301 struct rpc_task *task = req->rq_task;
1302 - struct rpc_auth *auth = task->tk_auth;
1303 + struct rpc_auth *auth = task->tk_msg.rpc_cred->cr_auth;
1304 unsigned int replen;
1305 u32 count = args->count;
1307 @@ -541,7 +541,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
1309 nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
1311 - struct rpc_auth *auth = req->rq_task->tk_auth;
1312 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1313 unsigned int replen;
1315 p = xdr_encode_fhandle(p, args->fh);
1316 diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
1317 index 45268d6..814d886 100644
1318 --- a/fs/nfs/nfs3proc.c
1319 +++ b/fs/nfs/nfs3proc.c
1320 @@ -335,9 +335,7 @@ again:
1321 * not sure this buys us anything (and I'd have
1322 * to revamp the NFSv3 XDR code) */
1323 status = nfs3_proc_setattr(dentry, &fattr, sattr);
1325 - nfs_setattr_update_inode(dentry->d_inode, sattr);
1326 - nfs_refresh_inode(dentry->d_inode, &fattr);
1327 + nfs_post_op_update_inode(dentry->d_inode, &fattr);
1328 dprintk("NFS reply setattr (post-create): %d\n", status);
1331 diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
1332 index b51df8e..b4647a2 100644
1333 --- a/fs/nfs/nfs3xdr.c
1334 +++ b/fs/nfs/nfs3xdr.c
1335 @@ -319,7 +319,7 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *arg
1337 nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
1339 - struct rpc_auth *auth = req->rq_task->tk_auth;
1340 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1341 unsigned int replen;
1342 u32 count = args->count;
1344 @@ -458,7 +458,7 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
1346 nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
1348 - struct rpc_auth *auth = req->rq_task->tk_auth;
1349 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1350 unsigned int replen;
1351 u32 count = args->count;
1353 @@ -643,7 +643,7 @@ static int
1354 nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
1355 struct nfs3_getaclargs *args)
1357 - struct rpc_auth *auth = req->rq_task->tk_auth;
1358 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1359 unsigned int replen;
1361 p = xdr_encode_fhandle(p, args->fh);
1362 @@ -773,7 +773,7 @@ nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1364 nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
1366 - struct rpc_auth *auth = req->rq_task->tk_auth;
1367 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1368 unsigned int replen;
1370 p = xdr_encode_fhandle(p, args->fh);
1371 diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
1372 index cf3a17e..6c028e7 100644
1373 --- a/fs/nfs/nfs4_fs.h
1374 +++ b/fs/nfs/nfs4_fs.h
1375 @@ -70,19 +70,26 @@ static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status
1376 seqid->flags |= NFS_SEQID_CONFIRMED;
1379 +struct nfs_unique_id {
1380 + struct rb_node rb_node;
1385 * NFS4 state_owners and lock_owners are simply labels for ordered
1386 * sequences of RPC calls. Their sole purpose is to provide once-only
1387 * semantics by allowing the server to identify replayed requests.
1389 struct nfs4_state_owner {
1390 - spinlock_t so_lock;
1391 - struct list_head so_list; /* per-clientid list of state_owners */
1392 + struct nfs_unique_id so_owner_id;
1393 struct nfs_client *so_client;
1394 - u32 so_id; /* 32-bit identifier, unique */
1395 - atomic_t so_count;
1396 + struct nfs_server *so_server;
1397 + struct rb_node so_client_node;
1399 struct rpc_cred *so_cred; /* Associated cred */
1401 + spinlock_t so_lock;
1402 + atomic_t so_count;
1403 struct list_head so_states;
1404 struct list_head so_delegations;
1405 struct nfs_seqid_counter so_seqid;
1406 @@ -108,7 +115,7 @@ struct nfs4_lock_state {
1407 #define NFS_LOCK_INITIALIZED 1
1409 struct nfs_seqid_counter ls_seqid;
1411 + struct nfs_unique_id ls_id;
1412 nfs4_stateid ls_stateid;
1415 @@ -116,7 +123,10 @@ struct nfs4_lock_state {
1416 /* bits for nfs4_state->flags */
1419 - NFS_DELEGATED_STATE,
1420 + NFS_DELEGATED_STATE, /* Current stateid is delegation */
1421 + NFS_O_RDONLY_STATE, /* OPEN stateid has read-only state */
1422 + NFS_O_WRONLY_STATE, /* OPEN stateid has write-only state */
1423 + NFS_O_RDWR_STATE, /* OPEN stateid has read/write state */
1427 @@ -130,11 +140,14 @@ struct nfs4_state {
1428 unsigned long flags; /* Do we hold any locks? */
1429 spinlock_t state_lock; /* Protects the lock_states list */
1431 - nfs4_stateid stateid;
1432 + seqlock_t seqlock; /* Protects the stateid/open_stateid */
1433 + nfs4_stateid stateid; /* Current stateid: may be delegation */
1434 + nfs4_stateid open_stateid; /* OPEN stateid */
1436 - unsigned int n_rdonly;
1437 - unsigned int n_wronly;
1438 - unsigned int n_rdwr;
1439 + /* The following 3 fields are protected by owner->so_lock */
1440 + unsigned int n_rdonly; /* Number of read-only references */
1441 + unsigned int n_wronly; /* Number of write-only references */
1442 + unsigned int n_rdwr; /* Number of read/write references */
1443 int state; /* State on the server (R,W, or RW) */
1446 @@ -165,7 +178,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc
1447 extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
1448 extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
1449 extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
1450 -extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
1451 +extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
1452 extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
1453 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
1454 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
1455 @@ -189,14 +202,13 @@ extern void nfs4_renew_state(struct work_struct *);
1458 struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp);
1459 -extern u32 nfs4_alloc_lockowner_id(struct nfs_client *);
1461 extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
1462 extern void nfs4_put_state_owner(struct nfs4_state_owner *);
1463 extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
1464 extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
1465 extern void nfs4_put_open_state(struct nfs4_state *);
1466 -extern void nfs4_close_state(struct nfs4_state *, mode_t);
1467 +extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t);
1468 extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
1469 extern void nfs4_schedule_state_recovery(struct nfs_client *);
1470 extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
1471 @@ -222,7 +234,7 @@ extern struct svc_version nfs4_callback_version1;
1475 -#define nfs4_close_state(a, b) do { } while (0)
1476 +#define nfs4_close_state(a, b, c) do { } while (0)
1478 #endif /* CONFIG_NFS_V4 */
1479 #endif /* __LINUX_FS_NFS_NFS4_FS.H */
1480 diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
1481 index 648e0ac..fee2da8 100644
1482 --- a/fs/nfs/nfs4proc.c
1483 +++ b/fs/nfs/nfs4proc.c
1484 @@ -65,6 +65,7 @@ static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *)
1485 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
1486 static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
1487 static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
1488 +static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags);
1490 /* Prevent leaks of NFSv4 errors into userland */
1491 int nfs4_map_errors(int err)
1492 @@ -214,27 +215,39 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
1495 struct nfs4_opendata {
1498 struct nfs_openargs o_arg;
1499 struct nfs_openres o_res;
1500 struct nfs_open_confirmargs c_arg;
1501 struct nfs_open_confirmres c_res;
1502 struct nfs_fattr f_attr;
1503 struct nfs_fattr dir_attr;
1504 - struct dentry *dentry;
1507 struct nfs4_state_owner *owner;
1508 + struct nfs4_state *state;
1510 unsigned long timestamp;
1511 + unsigned int rpc_done : 1;
1516 -static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
1518 +static void nfs4_init_opendata_res(struct nfs4_opendata *p)
1520 + p->o_res.f_attr = &p->f_attr;
1521 + p->o_res.dir_attr = &p->dir_attr;
1522 + p->o_res.server = p->o_arg.server;
1523 + nfs_fattr_init(&p->f_attr);
1524 + nfs_fattr_init(&p->dir_attr);
1527 +static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
1528 struct nfs4_state_owner *sp, int flags,
1529 const struct iattr *attrs)
1531 - struct dentry *parent = dget_parent(dentry);
1532 + struct dentry *parent = dget_parent(path->dentry);
1533 struct inode *dir = parent->d_inode;
1534 struct nfs_server *server = NFS_SERVER(dir);
1535 struct nfs4_opendata *p;
1536 @@ -245,24 +258,19 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
1537 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
1538 if (p->o_arg.seqid == NULL)
1540 - atomic_set(&p->count, 1);
1541 - p->dentry = dget(dentry);
1542 + p->path.mnt = mntget(path->mnt);
1543 + p->path.dentry = dget(path->dentry);
1546 atomic_inc(&sp->so_count);
1547 p->o_arg.fh = NFS_FH(dir);
1548 p->o_arg.open_flags = flags,
1549 p->o_arg.clientid = server->nfs_client->cl_clientid;
1550 - p->o_arg.id = sp->so_id;
1551 - p->o_arg.name = &dentry->d_name;
1552 + p->o_arg.id = sp->so_owner_id.id;
1553 + p->o_arg.name = &p->path.dentry->d_name;
1554 p->o_arg.server = server;
1555 p->o_arg.bitmask = server->attr_bitmask;
1556 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
1557 - p->o_res.f_attr = &p->f_attr;
1558 - p->o_res.dir_attr = &p->dir_attr;
1559 - p->o_res.server = server;
1560 - nfs_fattr_init(&p->f_attr);
1561 - nfs_fattr_init(&p->dir_attr);
1562 if (flags & O_EXCL) {
1563 u32 *s = (u32 *) p->o_arg.u.verifier.data;
1565 @@ -274,6 +282,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
1566 p->c_arg.fh = &p->o_res.fh;
1567 p->c_arg.stateid = &p->o_res.stateid;
1568 p->c_arg.seqid = p->o_arg.seqid;
1569 + nfs4_init_opendata_res(p);
1570 + kref_init(&p->kref);
1574 @@ -282,27 +292,25 @@ err:
1578 -static void nfs4_opendata_free(struct nfs4_opendata *p)
1579 +static void nfs4_opendata_free(struct kref *kref)
1581 - if (p != NULL && atomic_dec_and_test(&p->count)) {
1582 - nfs_free_seqid(p->o_arg.seqid);
1583 - nfs4_put_state_owner(p->owner);
1588 + struct nfs4_opendata *p = container_of(kref,
1589 + struct nfs4_opendata, kref);
1591 + nfs_free_seqid(p->o_arg.seqid);
1592 + if (p->state != NULL)
1593 + nfs4_put_open_state(p->state);
1594 + nfs4_put_state_owner(p->owner);
1596 + dput(p->path.dentry);
1597 + mntput(p->path.mnt);
1601 -/* Helper for asynchronous RPC calls */
1602 -static int nfs4_call_async(struct rpc_clnt *clnt,
1603 - const struct rpc_call_ops *tk_ops, void *calldata)
1604 +static void nfs4_opendata_put(struct nfs4_opendata *p)
1606 - struct rpc_task *task;
1608 - if (!(task = rpc_new_task(clnt, RPC_TASK_ASYNC, tk_ops, calldata)))
1610 - rpc_execute(task);
1613 + kref_put(&p->kref, nfs4_opendata_free);
1616 static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task)
1617 @@ -316,7 +324,34 @@ static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task)
1621 -static inline void update_open_stateflags(struct nfs4_state *state, mode_t open_flags)
1622 +static int can_open_cached(struct nfs4_state *state, int mode)
1625 + switch (mode & (FMODE_READ|FMODE_WRITE|O_EXCL)) {
1627 + ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0;
1628 + ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
1631 + ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0;
1632 + ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
1634 + case FMODE_READ|FMODE_WRITE:
1635 + ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
1640 +static int can_open_delegated(struct nfs_delegation *delegation, mode_t open_flags)
1642 + if ((delegation->type & open_flags) != open_flags)
1644 + if (delegation->flags & NFS_DELEGATION_NEED_RECLAIM)
1649 +static void update_open_stateflags(struct nfs4_state *state, mode_t open_flags)
1651 switch (open_flags) {
1653 @@ -328,41 +363,176 @@ static inline void update_open_stateflags(struct nfs4_state *state, mode_t open_
1654 case FMODE_READ|FMODE_WRITE:
1657 + nfs4_state_set_mode_locked(state, state->state | open_flags);
1660 -static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
1661 +static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
1663 - struct inode *inode = state->inode;
1664 + if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
1665 + memcpy(state->stateid.data, stateid->data, sizeof(state->stateid.data));
1666 + memcpy(state->open_stateid.data, stateid->data, sizeof(state->open_stateid.data));
1667 + switch (open_flags) {
1669 + set_bit(NFS_O_RDONLY_STATE, &state->flags);
1672 + set_bit(NFS_O_WRONLY_STATE, &state->flags);
1674 + case FMODE_READ|FMODE_WRITE:
1675 + set_bit(NFS_O_RDWR_STATE, &state->flags);
1679 +static void nfs_set_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
1681 + write_seqlock(&state->seqlock);
1682 + nfs_set_open_stateid_locked(state, stateid, open_flags);
1683 + write_sequnlock(&state->seqlock);
1686 +static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stateid, nfs4_stateid *deleg_stateid, int open_flags)
1688 open_flags &= (FMODE_READ|FMODE_WRITE);
1689 - /* Protect against nfs4_find_state_byowner() */
1691 + * Protect the call to nfs4_state_set_mode_locked and
1692 + * serialise the stateid update
1694 + write_seqlock(&state->seqlock);
1695 + if (deleg_stateid != NULL) {
1696 + memcpy(state->stateid.data, deleg_stateid->data, sizeof(state->stateid.data));
1697 + set_bit(NFS_DELEGATED_STATE, &state->flags);
1699 + if (open_stateid != NULL)
1700 + nfs_set_open_stateid_locked(state, open_stateid, open_flags);
1701 + write_sequnlock(&state->seqlock);
1702 spin_lock(&state->owner->so_lock);
1703 - spin_lock(&inode->i_lock);
1704 - memcpy(&state->stateid, stateid, sizeof(state->stateid));
1705 update_open_stateflags(state, open_flags);
1706 - nfs4_state_set_mode_locked(state, state->state | open_flags);
1707 - spin_unlock(&inode->i_lock);
1708 spin_unlock(&state->owner->so_lock);
1711 +static void nfs4_return_incompatible_delegation(struct inode *inode, mode_t open_flags)
1713 + struct nfs_delegation *delegation;
1716 + delegation = rcu_dereference(NFS_I(inode)->delegation);
1717 + if (delegation == NULL || (delegation->type & open_flags) == open_flags) {
1718 + rcu_read_unlock();
1721 + rcu_read_unlock();
1722 + nfs_inode_return_delegation(inode);
1725 +static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
1727 + struct nfs4_state *state = opendata->state;
1728 + struct nfs_inode *nfsi = NFS_I(state->inode);
1729 + struct nfs_delegation *delegation;
1730 + int open_mode = opendata->o_arg.open_flags & (FMODE_READ|FMODE_WRITE|O_EXCL);
1731 + nfs4_stateid stateid;
1732 + int ret = -EAGAIN;
1735 + delegation = rcu_dereference(nfsi->delegation);
1737 + if (can_open_cached(state, open_mode)) {
1738 + spin_lock(&state->owner->so_lock);
1739 + if (can_open_cached(state, open_mode)) {
1740 + update_open_stateflags(state, open_mode);
1741 + spin_unlock(&state->owner->so_lock);
1742 + rcu_read_unlock();
1743 + goto out_return_state;
1745 + spin_unlock(&state->owner->so_lock);
1747 + if (delegation == NULL)
1749 + if (!can_open_delegated(delegation, open_mode))
1751 + /* Save the delegation */
1752 + memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data));
1753 + rcu_read_unlock();
1755 + ret = _nfs4_do_access(state->inode, state->owner->so_cred, open_mode);
1761 + delegation = rcu_dereference(nfsi->delegation);
1762 + /* If no delegation, try a cached open */
1763 + if (delegation == NULL)
1765 + /* Is the delegation still valid? */
1766 + if (memcmp(stateid.data, delegation->stateid.data, sizeof(stateid.data)) != 0)
1768 + rcu_read_unlock();
1769 + update_open_stateid(state, NULL, &stateid, open_mode);
1770 + goto out_return_state;
1772 + rcu_read_unlock();
1774 + return ERR_PTR(ret);
1776 + atomic_inc(&state->count);
1780 static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
1782 struct inode *inode;
1783 struct nfs4_state *state = NULL;
1784 + struct nfs_delegation *delegation;
1785 + nfs4_stateid *deleg_stateid = NULL;
1788 - if (!(data->f_attr.valid & NFS_ATTR_FATTR))
1789 + if (!data->rpc_done) {
1790 + state = nfs4_try_open_cached(data);
1795 + if (!(data->f_attr.valid & NFS_ATTR_FATTR))
1797 inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr);
1798 + ret = PTR_ERR(inode);
1803 state = nfs4_get_open_state(inode, data->owner);
1806 - update_open_stateid(state, &data->o_res.stateid, data->o_arg.open_flags);
1808 + goto err_put_inode;
1809 + if (data->o_res.delegation_type != 0) {
1810 + int delegation_flags = 0;
1813 + delegation = rcu_dereference(NFS_I(inode)->delegation);
1815 + delegation_flags = delegation->flags;
1816 + rcu_read_unlock();
1817 + if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM))
1818 + nfs_inode_set_delegation(state->inode,
1819 + data->owner->so_cred,
1822 + nfs_inode_reclaim_delegation(state->inode,
1823 + data->owner->so_cred,
1827 + delegation = rcu_dereference(NFS_I(inode)->delegation);
1828 + if (delegation != NULL)
1829 + deleg_stateid = &delegation->stateid;
1830 + update_open_stateid(state, &data->o_res.stateid, deleg_stateid, data->o_arg.open_flags);
1831 + rcu_read_unlock();
1838 + return ERR_PTR(ret);
1841 static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state)
1842 @@ -382,79 +552,66 @@ static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *
1843 return ERR_PTR(-ENOENT);
1846 -static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, nfs4_stateid *stateid)
1847 +static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, struct nfs4_state **res)
1849 + struct nfs4_state *newstate;
1852 opendata->o_arg.open_flags = openflags;
1853 + memset(&opendata->o_res, 0, sizeof(opendata->o_res));
1854 + memset(&opendata->c_res, 0, sizeof(opendata->c_res));
1855 + nfs4_init_opendata_res(opendata);
1856 ret = _nfs4_proc_open(opendata);
1859 - memcpy(stateid->data, opendata->o_res.stateid.data,
1860 - sizeof(stateid->data));
1861 + newstate = nfs4_opendata_to_nfs4_state(opendata);
1862 + if (IS_ERR(newstate))
1863 + return PTR_ERR(newstate);
1864 + nfs4_close_state(&opendata->path, newstate, openflags);
1869 static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *state)
1871 - nfs4_stateid stateid;
1872 struct nfs4_state *newstate;
1874 - int delegation = 0;
1877 /* memory barrier prior to reading state->n_* */
1878 + clear_bit(NFS_DELEGATED_STATE, &state->flags);
1880 if (state->n_rdwr != 0) {
1881 - ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &stateid);
1882 + ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &newstate);
1885 - mode |= FMODE_READ|FMODE_WRITE;
1886 - if (opendata->o_res.delegation_type != 0)
1887 - delegation = opendata->o_res.delegation_type;
1889 + if (newstate != state)
1892 if (state->n_wronly != 0) {
1893 - ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &stateid);
1894 + ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &newstate);
1897 - mode |= FMODE_WRITE;
1898 - if (opendata->o_res.delegation_type != 0)
1899 - delegation = opendata->o_res.delegation_type;
1901 + if (newstate != state)
1904 if (state->n_rdonly != 0) {
1905 - ret = nfs4_open_recover_helper(opendata, FMODE_READ, &stateid);
1906 + ret = nfs4_open_recover_helper(opendata, FMODE_READ, &newstate);
1909 - mode |= FMODE_READ;
1910 + if (newstate != state)
1913 - clear_bit(NFS_DELEGATED_STATE, &state->flags);
1916 - if (opendata->o_res.delegation_type == 0)
1917 - opendata->o_res.delegation_type = delegation;
1918 - opendata->o_arg.open_flags |= mode;
1919 - newstate = nfs4_opendata_to_nfs4_state(opendata);
1920 - if (newstate != NULL) {
1921 - if (opendata->o_res.delegation_type != 0) {
1922 - struct nfs_inode *nfsi = NFS_I(newstate->inode);
1923 - int delegation_flags = 0;
1924 - if (nfsi->delegation)
1925 - delegation_flags = nfsi->delegation->flags;
1926 - if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM))
1927 - nfs_inode_set_delegation(newstate->inode,
1928 - opendata->owner->so_cred,
1929 - &opendata->o_res);
1931 - nfs_inode_reclaim_delegation(newstate->inode,
1932 - opendata->owner->so_cred,
1933 - &opendata->o_res);
1935 - nfs4_close_state(newstate, opendata->o_arg.open_flags);
1937 + * We may have performed cached opens for all three recoveries.
1938 + * Check if we need to update the current stateid.
1940 + if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0 &&
1941 + memcmp(state->stateid.data, state->open_stateid.data, sizeof(state->stateid.data)) != 0) {
1942 + write_seqlock(&state->seqlock);
1943 + if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
1944 + memcpy(state->stateid.data, state->open_stateid.data, sizeof(state->stateid.data));
1945 + write_sequnlock(&state->seqlock);
1947 - if (newstate != state)
1952 @@ -462,41 +619,37 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1954 * reclaim state on the server after a reboot.
1956 -static int _nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
1957 +static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
1959 - struct nfs_delegation *delegation = NFS_I(state->inode)->delegation;
1960 + struct nfs_delegation *delegation;
1961 struct nfs4_opendata *opendata;
1962 int delegation_type = 0;
1965 - if (delegation != NULL) {
1966 - if (!(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) {
1967 - memcpy(&state->stateid, &delegation->stateid,
1968 - sizeof(state->stateid));
1969 - set_bit(NFS_DELEGATED_STATE, &state->flags);
1972 - delegation_type = delegation->type;
1974 - opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL);
1975 + opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
1976 if (opendata == NULL)
1978 opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS;
1979 opendata->o_arg.fh = NFS_FH(state->inode);
1980 nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh);
1982 + delegation = rcu_dereference(NFS_I(state->inode)->delegation);
1983 + if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0)
1984 + delegation_type = delegation->flags;
1985 + rcu_read_unlock();
1986 opendata->o_arg.u.delegation_type = delegation_type;
1987 status = nfs4_open_recover(opendata, state);
1988 - nfs4_opendata_free(opendata);
1989 + nfs4_opendata_put(opendata);
1993 -static int nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
1994 +static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
1996 struct nfs_server *server = NFS_SERVER(state->inode);
1997 struct nfs4_exception exception = { };
2000 - err = _nfs4_do_open_reclaim(sp, state, dentry);
2001 + err = _nfs4_do_open_reclaim(ctx, state);
2002 if (err != -NFS4ERR_DELAY)
2004 nfs4_handle_exception(server, err, &exception);
2005 @@ -512,37 +665,35 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
2006 ctx = nfs4_state_find_open_context(state);
2008 return PTR_ERR(ctx);
2009 - ret = nfs4_do_open_reclaim(sp, state, ctx->dentry);
2010 + ret = nfs4_do_open_reclaim(ctx, state);
2011 put_nfs_open_context(ctx);
2015 -static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
2016 +static int _nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
2018 struct nfs4_state_owner *sp = state->owner;
2019 struct nfs4_opendata *opendata;
2022 - if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
2024 - opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL);
2025 + opendata = nfs4_opendata_alloc(&ctx->path, sp, 0, NULL);
2026 if (opendata == NULL)
2028 opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR;
2029 - memcpy(opendata->o_arg.u.delegation.data, state->stateid.data,
2030 + memcpy(opendata->o_arg.u.delegation.data, stateid->data,
2031 sizeof(opendata->o_arg.u.delegation.data));
2032 ret = nfs4_open_recover(opendata, state);
2033 - nfs4_opendata_free(opendata);
2034 + nfs4_opendata_put(opendata);
2038 -int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
2039 +int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
2041 struct nfs4_exception exception = { };
2042 - struct nfs_server *server = NFS_SERVER(dentry->d_inode);
2043 + struct nfs_server *server = NFS_SERVER(state->inode);
2046 - err = _nfs4_open_delegation_recall(dentry, state);
2047 + err = _nfs4_open_delegation_recall(ctx, state, stateid);
2051 @@ -582,9 +733,10 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
2052 memcpy(data->o_res.stateid.data, data->c_res.stateid.data,
2053 sizeof(data->o_res.stateid.data));
2054 renew_lease(data->o_res.server, data->timestamp);
2055 + data->rpc_done = 1;
2057 - nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
2058 nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status);
2059 + nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
2062 static void nfs4_open_confirm_release(void *calldata)
2063 @@ -596,14 +748,14 @@ static void nfs4_open_confirm_release(void *calldata)
2064 if (data->cancelled == 0)
2066 /* In case of error, no cleanup! */
2067 - if (data->rpc_status != 0)
2068 + if (!data->rpc_done)
2070 nfs_confirm_seqid(&data->owner->so_seqid, 0);
2071 state = nfs4_opendata_to_nfs4_state(data);
2072 - if (state != NULL)
2073 - nfs4_close_state(state, data->o_arg.open_flags);
2074 + if (!IS_ERR(state))
2075 + nfs4_close_state(&data->path, state, data->o_arg.open_flags);
2077 - nfs4_opendata_free(data);
2078 + nfs4_opendata_put(data);
2081 static const struct rpc_call_ops nfs4_open_confirm_ops = {
2082 @@ -621,12 +773,9 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
2083 struct rpc_task *task;
2086 - atomic_inc(&data->count);
2088 - * If rpc_run_task() ends up calling ->rpc_release(), we
2089 - * want to ensure that it takes the 'error' code path.
2091 - data->rpc_status = -ENOMEM;
2092 + kref_get(&data->kref);
2093 + data->rpc_done = 0;
2094 + data->rpc_status = 0;
2095 task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_confirm_ops, data);
2097 return PTR_ERR(task);
2098 @@ -653,13 +802,35 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
2100 if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0)
2103 + * Check if we still need to send an OPEN call, or if we can use
2104 + * a delegation instead.
2106 + if (data->state != NULL) {
2107 + struct nfs_delegation *delegation;
2109 + if (can_open_cached(data->state, data->o_arg.open_flags & (FMODE_READ|FMODE_WRITE|O_EXCL)))
2110 + goto out_no_action;
2112 + delegation = rcu_dereference(NFS_I(data->state->inode)->delegation);
2113 + if (delegation != NULL &&
2114 + (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) == 0) {
2115 + rcu_read_unlock();
2116 + goto out_no_action;
2118 + rcu_read_unlock();
2120 /* Update sequence id. */
2121 - data->o_arg.id = sp->so_id;
2122 + data->o_arg.id = sp->so_owner_id.id;
2123 data->o_arg.clientid = sp->so_client->cl_clientid;
2124 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
2125 msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
2126 data->timestamp = jiffies;
2127 rpc_call_setup(task, &msg, 0);
2130 + task->tk_action = NULL;
2134 static void nfs4_open_done(struct rpc_task *task, void *calldata)
2135 @@ -683,8 +854,11 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
2136 data->rpc_status = -ENOTDIR;
2138 renew_lease(data->o_res.server, data->timestamp);
2139 + if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))
2140 + nfs_confirm_seqid(&data->owner->so_seqid, 0);
2142 nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid);
2143 + data->rpc_done = 1;
2146 static void nfs4_open_release(void *calldata)
2147 @@ -696,17 +870,17 @@ static void nfs4_open_release(void *calldata)
2148 if (data->cancelled == 0)
2150 /* In case of error, no cleanup! */
2151 - if (data->rpc_status != 0)
2152 + if (data->rpc_status != 0 || !data->rpc_done)
2154 /* In case we need an open_confirm, no cleanup! */
2155 if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
2157 nfs_confirm_seqid(&data->owner->so_seqid, 0);
2158 state = nfs4_opendata_to_nfs4_state(data);
2159 - if (state != NULL)
2160 - nfs4_close_state(state, data->o_arg.open_flags);
2161 + if (!IS_ERR(state))
2162 + nfs4_close_state(&data->path, state, data->o_arg.open_flags);
2164 - nfs4_opendata_free(data);
2165 + nfs4_opendata_put(data);
2168 static const struct rpc_call_ops nfs4_open_ops = {
2169 @@ -727,12 +901,10 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
2170 struct rpc_task *task;
2173 - atomic_inc(&data->count);
2175 - * If rpc_run_task() ends up calling ->rpc_release(), we
2176 - * want to ensure that it takes the 'error' code path.
2178 - data->rpc_status = -ENOMEM;
2179 + kref_get(&data->kref);
2180 + data->rpc_done = 0;
2181 + data->rpc_status = 0;
2182 + data->cancelled = 0;
2183 task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_ops, data);
2185 return PTR_ERR(task);
2186 @@ -743,7 +915,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
2188 status = data->rpc_status;
2191 + if (status != 0 || !data->rpc_done)
2194 if (o_arg->open_flags & O_CREAT) {
2195 @@ -756,7 +928,6 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
2199 - nfs_confirm_seqid(&data->owner->so_seqid, 0);
2200 if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
2201 return server->nfs_client->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
2203 @@ -772,6 +943,8 @@ static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openf
2205 if (openflags & FMODE_WRITE)
2207 + if (openflags & FMODE_EXEC)
2209 status = nfs_access_get_cached(inode, cred, &cache);
2212 @@ -811,43 +984,32 @@ static int nfs4_recover_expired_lease(struct nfs_server *server)
2213 * reclaim state on the server after a network partition.
2214 * Assumes caller holds the appropriate lock
2216 -static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
2217 +static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
2219 - struct inode *inode = state->inode;
2220 - struct nfs_delegation *delegation = NFS_I(inode)->delegation;
2221 struct nfs4_opendata *opendata;
2222 - int openflags = state->state & (FMODE_READ|FMODE_WRITE);
2225 - if (delegation != NULL && !(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) {
2226 - ret = _nfs4_do_access(inode, sp->so_cred, openflags);
2229 - memcpy(&state->stateid, &delegation->stateid, sizeof(state->stateid));
2230 - set_bit(NFS_DELEGATED_STATE, &state->flags);
2233 - opendata = nfs4_opendata_alloc(dentry, sp, openflags, NULL);
2234 + opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
2235 if (opendata == NULL)
2237 ret = nfs4_open_recover(opendata, state);
2238 if (ret == -ESTALE) {
2239 /* Invalidate the state owner so we don't ever use it again */
2240 - nfs4_drop_state_owner(sp);
2242 + nfs4_drop_state_owner(state->owner);
2243 + d_drop(ctx->path.dentry);
2245 - nfs4_opendata_free(opendata);
2246 + nfs4_opendata_put(opendata);
2250 -static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
2251 +static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
2253 - struct nfs_server *server = NFS_SERVER(dentry->d_inode);
2254 + struct nfs_server *server = NFS_SERVER(state->inode);
2255 struct nfs4_exception exception = { };
2259 - err = _nfs4_open_expired(sp, state, dentry);
2260 + err = _nfs4_open_expired(ctx, state);
2261 if (err == -NFS4ERR_DELAY)
2262 nfs4_handle_exception(server, err, &exception);
2263 } while (exception.retry);
2264 @@ -862,107 +1024,38 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
2265 ctx = nfs4_state_find_open_context(state);
2267 return PTR_ERR(ctx);
2268 - ret = nfs4_do_open_expired(sp, state, ctx->dentry);
2269 + ret = nfs4_do_open_expired(ctx, state);
2270 put_nfs_open_context(ctx);
2275 - * Returns a referenced nfs4_state if there is an open delegation on the file
2276 + * on an EXCLUSIVE create, the server should send back a bitmask with FATTR4-*
2277 + * fields corresponding to attributes that were used to store the verifier.
2278 + * Make sure we clobber those fields in the later setattr call
2280 -static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred *cred, struct nfs4_state **res)
2282 - struct nfs_delegation *delegation;
2283 - struct nfs_server *server = NFS_SERVER(inode);
2284 - struct nfs_client *clp = server->nfs_client;
2285 - struct nfs_inode *nfsi = NFS_I(inode);
2286 - struct nfs4_state_owner *sp = NULL;
2287 - struct nfs4_state *state = NULL;
2288 - int open_flags = flags & (FMODE_READ|FMODE_WRITE);
2292 - if (!(sp = nfs4_get_state_owner(server, cred))) {
2293 - dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
2296 - err = nfs4_recover_expired_lease(server);
2298 - goto out_put_state_owner;
2299 - /* Protect against reboot recovery - NOTE ORDER! */
2300 - down_read(&clp->cl_sem);
2301 - /* Protect against delegation recall */
2302 - down_read(&nfsi->rwsem);
2303 - delegation = NFS_I(inode)->delegation;
2305 - if (delegation == NULL || (delegation->type & open_flags) != open_flags)
2308 - state = nfs4_get_open_state(inode, sp);
2309 - if (state == NULL)
2313 - if ((state->state & open_flags) == open_flags) {
2314 - spin_lock(&inode->i_lock);
2315 - update_open_stateflags(state, open_flags);
2316 - spin_unlock(&inode->i_lock);
2318 - } else if (state->state != 0)
2319 - goto out_put_open_state;
2322 - err = _nfs4_do_access(inode, cred, open_flags);
2325 - goto out_put_open_state;
2326 - set_bit(NFS_DELEGATED_STATE, &state->flags);
2327 - update_open_stateid(state, &delegation->stateid, open_flags);
2329 - nfs4_put_state_owner(sp);
2330 - up_read(&nfsi->rwsem);
2331 - up_read(&clp->cl_sem);
2334 -out_put_open_state:
2335 - nfs4_put_open_state(state);
2337 - up_read(&nfsi->rwsem);
2338 - up_read(&clp->cl_sem);
2339 - if (err != -EACCES)
2340 - nfs_inode_return_delegation(inode);
2341 -out_put_state_owner:
2342 - nfs4_put_state_owner(sp);
2346 -static struct nfs4_state *nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred *cred)
2347 +static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct iattr *sattr)
2349 - struct nfs4_exception exception = { };
2350 - struct nfs4_state *res = ERR_PTR(-EIO);
2352 + if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_ACCESS) &&
2353 + !(sattr->ia_valid & ATTR_ATIME_SET))
2354 + sattr->ia_valid |= ATTR_ATIME;
2357 - err = _nfs4_open_delegated(inode, flags, cred, &res);
2360 - res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(inode),
2361 - err, &exception));
2362 - } while (exception.retry);
2364 + if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_MODIFY) &&
2365 + !(sattr->ia_valid & ATTR_MTIME_SET))
2366 + sattr->ia_valid |= ATTR_MTIME;
2370 * Returns a referenced nfs4_state
2372 -static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
2373 +static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
2375 struct nfs4_state_owner *sp;
2376 struct nfs4_state *state = NULL;
2377 struct nfs_server *server = NFS_SERVER(dir);
2378 struct nfs_client *clp = server->nfs_client;
2379 struct nfs4_opendata *opendata;
2383 /* Protect against reboot recovery conflicts */
2385 @@ -973,29 +1066,35 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
2386 status = nfs4_recover_expired_lease(server);
2388 goto err_put_state_owner;
2389 + if (path->dentry->d_inode != NULL)
2390 + nfs4_return_incompatible_delegation(path->dentry->d_inode, flags & (FMODE_READ|FMODE_WRITE));
2391 down_read(&clp->cl_sem);
2393 - opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
2394 + opendata = nfs4_opendata_alloc(path, sp, flags, sattr);
2395 if (opendata == NULL)
2396 goto err_release_rwsem;
2398 + if (path->dentry->d_inode != NULL)
2399 + opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp);
2401 status = _nfs4_proc_open(opendata);
2403 - goto err_opendata_free;
2404 + goto err_opendata_put;
2406 + if (opendata->o_arg.open_flags & O_EXCL)
2407 + nfs4_exclusive_attrset(opendata, sattr);
2410 state = nfs4_opendata_to_nfs4_state(opendata);
2411 - if (state == NULL)
2412 - goto err_opendata_free;
2413 - if (opendata->o_res.delegation_type != 0)
2414 - nfs_inode_set_delegation(state->inode, cred, &opendata->o_res);
2415 - nfs4_opendata_free(opendata);
2416 + status = PTR_ERR(state);
2417 + if (IS_ERR(state))
2418 + goto err_opendata_put;
2419 + nfs4_opendata_put(opendata);
2420 nfs4_put_state_owner(sp);
2421 up_read(&clp->cl_sem);
2425 - nfs4_opendata_free(opendata);
2427 + nfs4_opendata_put(opendata);
2429 up_read(&clp->cl_sem);
2430 err_put_state_owner:
2431 @@ -1006,14 +1105,14 @@ out_err:
2435 -static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred)
2436 +static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
2438 struct nfs4_exception exception = { };
2439 struct nfs4_state *res;
2443 - status = _nfs4_do_open(dir, dentry, flags, sattr, cred, &res);
2444 + status = _nfs4_do_open(dir, path, flags, sattr, cred, &res);
2447 /* NOTE: BAD_SEQID means the server and client disagree about the
2448 @@ -1028,7 +1127,9 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
2449 * the user though...
2451 if (status == -NFS4ERR_BAD_SEQID) {
2452 - printk(KERN_WARNING "NFS: v4 server returned a bad sequence-id error!\n");
2453 + printk(KERN_WARNING "NFS: v4 server %s "
2454 + " returned a bad sequence-id error!\n",
2455 + NFS_SERVER(dir)->nfs_client->cl_hostname);
2456 exception.retry = 1;
2459 @@ -1042,6 +1143,11 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
2460 exception.retry = 1;
2463 + if (status == -EAGAIN) {
2464 + /* We must have found a delegation */
2465 + exception.retry = 1;
2468 res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir),
2469 status, &exception));
2470 } while (exception.retry);
2471 @@ -1101,6 +1207,7 @@ static int nfs4_do_setattr(struct inode *inode, struct nfs_fattr *fattr,
2474 struct nfs4_closedata {
2476 struct inode *inode;
2477 struct nfs4_state *state;
2478 struct nfs_closeargs arg;
2479 @@ -1117,6 +1224,8 @@ static void nfs4_free_closedata(void *data)
2480 nfs4_put_open_state(calldata->state);
2481 nfs_free_seqid(calldata->arg.seqid);
2482 nfs4_put_state_owner(sp);
2483 + dput(calldata->path.dentry);
2484 + mntput(calldata->path.mnt);
2488 @@ -1134,8 +1243,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
2489 nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
2490 switch (task->tk_status) {
2492 - memcpy(&state->stateid, &calldata->res.stateid,
2493 - sizeof(state->stateid));
2494 + nfs_set_open_stateid(state, &calldata->res.stateid, calldata->arg.open_flags);
2495 renew_lease(server, calldata->timestamp);
2497 case -NFS4ERR_STALE_STATEID:
2498 @@ -1160,26 +1268,30 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2499 .rpc_resp = &calldata->res,
2500 .rpc_cred = state->owner->so_cred,
2502 - int mode = 0, old_mode;
2503 + int clear_rd, clear_wr, clear_rdwr;
2506 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
2508 - /* Recalculate the new open mode in case someone reopened the file
2509 - * while we were waiting in line to be scheduled.
2512 + mode = FMODE_READ|FMODE_WRITE;
2513 + clear_rd = clear_wr = clear_rdwr = 0;
2514 spin_lock(&state->owner->so_lock);
2515 - spin_lock(&calldata->inode->i_lock);
2516 - mode = old_mode = state->state;
2517 + /* Calculate the change in open mode */
2518 if (state->n_rdwr == 0) {
2519 - if (state->n_rdonly == 0)
2520 + if (state->n_rdonly == 0) {
2521 mode &= ~FMODE_READ;
2522 - if (state->n_wronly == 0)
2523 + clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags);
2524 + clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags);
2526 + if (state->n_wronly == 0) {
2527 mode &= ~FMODE_WRITE;
2528 + clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags);
2529 + clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags);
2532 - nfs4_state_set_mode_locked(state, mode);
2533 - spin_unlock(&calldata->inode->i_lock);
2534 spin_unlock(&state->owner->so_lock);
2535 - if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) {
2536 + if (!clear_rd && !clear_wr && !clear_rdwr) {
2537 /* Note: exit _without_ calling nfs4_close_done */
2538 task->tk_action = NULL;
2540 @@ -1209,19 +1321,21 @@ static const struct rpc_call_ops nfs4_close_ops = {
2542 * NOTE: Caller must be holding the sp->so_owner semaphore!
2544 -int nfs4_do_close(struct inode *inode, struct nfs4_state *state)
2545 +int nfs4_do_close(struct path *path, struct nfs4_state *state)
2547 - struct nfs_server *server = NFS_SERVER(inode);
2548 + struct nfs_server *server = NFS_SERVER(state->inode);
2549 struct nfs4_closedata *calldata;
2550 + struct nfs4_state_owner *sp = state->owner;
2551 + struct rpc_task *task;
2552 int status = -ENOMEM;
2554 calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
2555 if (calldata == NULL)
2557 - calldata->inode = inode;
2558 + calldata->inode = state->inode;
2559 calldata->state = state;
2560 - calldata->arg.fh = NFS_FH(inode);
2561 - calldata->arg.stateid = &state->stateid;
2562 + calldata->arg.fh = NFS_FH(state->inode);
2563 + calldata->arg.stateid = &state->open_stateid;
2564 /* Serialization for the sequence id */
2565 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
2566 if (calldata->arg.seqid == NULL)
2567 @@ -1229,36 +1343,55 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state)
2568 calldata->arg.bitmask = server->attr_bitmask;
2569 calldata->res.fattr = &calldata->fattr;
2570 calldata->res.server = server;
2571 + calldata->path.mnt = mntget(path->mnt);
2572 + calldata->path.dentry = dget(path->dentry);
2574 - status = nfs4_call_async(server->client, &nfs4_close_ops, calldata);
2578 - nfs_free_seqid(calldata->arg.seqid);
2579 + task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata);
2581 + return PTR_ERR(task);
2582 + rpc_put_task(task);
2587 + nfs4_put_open_state(state);
2588 + nfs4_put_state_owner(sp);
2592 -static int nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state)
2593 +static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state)
2598 - filp = lookup_instantiate_filp(nd, dentry, NULL);
2599 + /* If the open_intent is for execute, we have an extra check to make */
2600 + if (nd->intent.open.flags & FMODE_EXEC) {
2601 + ret = _nfs4_do_access(state->inode,
2602 + state->owner->so_cred,
2603 + nd->intent.open.flags);
2607 + filp = lookup_instantiate_filp(nd, path->dentry, NULL);
2608 if (!IS_ERR(filp)) {
2609 struct nfs_open_context *ctx;
2610 ctx = (struct nfs_open_context *)filp->private_data;
2614 - nfs4_close_state(state, nd->intent.open.flags);
2615 - return PTR_ERR(filp);
2616 + ret = PTR_ERR(filp);
2618 + nfs4_close_state(path, state, nd->intent.open.flags);
2623 nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
2625 + struct path path = {
2630 struct rpc_cred *cred;
2631 struct nfs4_state *state;
2632 @@ -1277,7 +1410,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
2633 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
2635 return (struct dentry *)cred;
2636 - state = nfs4_do_open(dir, dentry, nd->intent.open.flags, &attr, cred);
2637 + state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
2639 if (IS_ERR(state)) {
2640 if (PTR_ERR(state) == -ENOENT)
2641 @@ -1287,22 +1420,24 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
2642 res = d_add_unique(dentry, igrab(state->inode));
2645 - nfs4_intent_set_file(nd, dentry, state);
2646 + nfs4_intent_set_file(nd, &path, state);
2651 nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
2653 + struct path path = {
2657 struct rpc_cred *cred;
2658 struct nfs4_state *state;
2660 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
2662 return PTR_ERR(cred);
2663 - state = nfs4_open_delegated(dentry->d_inode, openflags, cred);
2664 - if (IS_ERR(state))
2665 - state = nfs4_do_open(dir, dentry, openflags, NULL, cred);
2666 + state = nfs4_do_open(dir, &path, openflags, NULL, cred);
2668 if (IS_ERR(state)) {
2669 switch (PTR_ERR(state)) {
2670 @@ -1318,10 +1453,10 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
2673 if (state->inode == dentry->d_inode) {
2674 - nfs4_intent_set_file(nd, dentry, state);
2675 + nfs4_intent_set_file(nd, &path, state);
2678 - nfs4_close_state(state, openflags);
2679 + nfs4_close_state(&path, state, openflags);
2683 @@ -1559,8 +1694,6 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
2684 dprintk("NFS call lookupfh %s\n", name->name);
2685 status = rpc_call_sync(server->client, &msg, 0);
2686 dprintk("NFS reply lookupfh: %d\n", status);
2687 - if (status == -NFS4ERR_MOVED)
2688 - status = -EREMOTE;
2692 @@ -1571,10 +1704,13 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
2693 struct nfs4_exception exception = { };
2696 - err = nfs4_handle_exception(server,
2697 - _nfs4_proc_lookupfh(server, dirfh, name,
2700 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
2702 + if (err == -NFS4ERR_MOVED) {
2706 + err = nfs4_handle_exception(server, err, &exception);
2707 } while (exception.retry);
2710 @@ -1582,28 +1718,10 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
2711 static int _nfs4_proc_lookup(struct inode *dir, struct qstr *name,
2712 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
2715 - struct nfs_server *server = NFS_SERVER(dir);
2716 - struct nfs4_lookup_arg args = {
2717 - .bitmask = server->attr_bitmask,
2718 - .dir_fh = NFS_FH(dir),
2721 - struct nfs4_lookup_res res = {
2726 - struct rpc_message msg = {
2727 - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
2728 - .rpc_argp = &args,
2732 - nfs_fattr_init(fattr);
2735 dprintk("NFS call lookup %s\n", name->name);
2736 - status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
2737 + status = _nfs4_proc_lookupfh(NFS_SERVER(dir), NFS_FH(dir), name, fhandle, fattr);
2738 if (status == -NFS4ERR_MOVED)
2739 status = nfs4_get_referral(dir, name, fattr, fhandle);
2740 dprintk("NFS reply lookup: %d\n", status);
2741 @@ -1752,6 +1870,10 @@ static int
2742 nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2743 int flags, struct nameidata *nd)
2745 + struct path path = {
2749 struct nfs4_state *state;
2750 struct rpc_cred *cred;
2752 @@ -1761,7 +1883,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2753 status = PTR_ERR(cred);
2756 - state = nfs4_do_open(dir, dentry, flags, sattr, cred);
2757 + state = nfs4_do_open(dir, &path, flags, sattr, cred);
2759 if (IS_ERR(state)) {
2760 status = PTR_ERR(state);
2761 @@ -1773,11 +1895,12 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2762 status = nfs4_do_setattr(state->inode, &fattr, sattr, state);
2764 nfs_setattr_update_inode(state->inode, sattr);
2765 + nfs_post_op_update_inode(state->inode, &fattr);
2767 - if (status == 0 && nd != NULL && (nd->flags & LOOKUP_OPEN))
2768 - status = nfs4_intent_set_file(nd, dentry, state);
2769 + if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
2770 + status = nfs4_intent_set_file(nd, &path, state);
2772 - nfs4_close_state(state, flags);
2773 + nfs4_close_state(&path, state, flags);
2777 @@ -3008,7 +3131,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
2780 lsp = request->fl_u.nfs4_fl.owner;
2781 - arg.lock_owner.id = lsp->ls_id;
2782 + arg.lock_owner.id = lsp->ls_id.id;
2783 status = rpc_call_sync(server->client, &msg, 0);
2786 @@ -3152,6 +3275,11 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
2788 struct nfs4_unlockdata *data;
2790 + /* Ensure this is an unlock - when canceling a lock, the
2791 + * canceled lock is passed in, and it won't be an unlock.
2793 + fl->fl_type = F_UNLCK;
2795 data = nfs4_alloc_unlockdata(fl, ctx, lsp, seqid);
2797 nfs_free_seqid(seqid);
2798 @@ -3222,7 +3350,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
2800 p->arg.lock_stateid = &lsp->ls_stateid;
2801 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
2802 - p->arg.lock_owner.id = lsp->ls_id;
2803 + p->arg.lock_owner.id = lsp->ls_id.id;
2805 atomic_inc(&lsp->ls_count);
2806 p->ctx = get_nfs_open_context(ctx);
2807 @@ -3285,7 +3413,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
2808 memcpy(data->lsp->ls_stateid.data, data->res.stateid.data,
2809 sizeof(data->lsp->ls_stateid.data));
2810 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
2811 - renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp);
2812 + renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp);
2814 nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid);
2816 diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
2817 index 8ed79d5..28551ae 100644
2818 --- a/fs/nfs/nfs4state.c
2819 +++ b/fs/nfs/nfs4state.c
2824 +#include <linux/kernel.h>
2825 #include <linux/slab.h>
2826 #include <linux/smp_lock.h>
2827 #include <linux/nfs_fs.h>
2828 #include <linux/nfs_idmap.h>
2829 #include <linux/kthread.h>
2830 #include <linux/module.h>
2831 +#include <linux/random.h>
2832 #include <linux/workqueue.h>
2833 #include <linux/bitops.h>
2835 @@ -69,33 +71,14 @@ static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
2840 -nfs4_alloc_lockowner_id(struct nfs_client *clp)
2842 - return clp->cl_lockowner_id ++;
2845 -static struct nfs4_state_owner *
2846 -nfs4_client_grab_unused(struct nfs_client *clp, struct rpc_cred *cred)
2848 - struct nfs4_state_owner *sp = NULL;
2850 - if (!list_empty(&clp->cl_unused)) {
2851 - sp = list_entry(clp->cl_unused.next, struct nfs4_state_owner, so_list);
2852 - atomic_inc(&sp->so_count);
2853 - sp->so_cred = cred;
2854 - list_move(&sp->so_list, &clp->cl_state_owners);
2855 - clp->cl_nunused--;
2860 struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
2862 struct nfs4_state_owner *sp;
2863 + struct rb_node *pos;
2864 struct rpc_cred *cred = NULL;
2866 - list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
2867 + for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
2868 + sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
2869 if (list_empty(&sp->so_states))
2871 cred = get_rpccred(sp->so_cred);
2872 @@ -107,32 +90,146 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
2873 static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
2875 struct nfs4_state_owner *sp;
2876 + struct rb_node *pos;
2878 - if (!list_empty(&clp->cl_state_owners)) {
2879 - sp = list_entry(clp->cl_state_owners.next,
2880 - struct nfs4_state_owner, so_list);
2881 + pos = rb_first(&clp->cl_state_owners);
2882 + if (pos != NULL) {
2883 + sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
2884 return get_rpccred(sp->so_cred);
2889 +static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new,
2890 + __u64 minval, int maxbits)
2892 + struct rb_node **p, *parent;
2893 + struct nfs_unique_id *pos;
2894 + __u64 mask = ~0ULL;
2897 + mask = (1ULL << maxbits) - 1ULL;
2899 + /* Ensure distribution is more or less flat */
2900 + get_random_bytes(&new->id, sizeof(new->id));
2902 + if (new->id < minval)
2903 + new->id += minval;
2905 + p = &root->rb_node;
2908 + while (*p != NULL) {
2910 + pos = rb_entry(parent, struct nfs_unique_id, rb_node);
2912 + if (new->id < pos->id)
2913 + p = &(*p)->rb_left;
2914 + else if (new->id > pos->id)
2915 + p = &(*p)->rb_right;
2919 + rb_link_node(&new->rb_node, parent, p);
2920 + rb_insert_color(&new->rb_node, root);
2925 + if (new->id < minval || (new->id & mask) != new->id) {
2929 + parent = rb_next(parent);
2930 + if (parent == NULL)
2932 + pos = rb_entry(parent, struct nfs_unique_id, rb_node);
2933 + if (new->id < pos->id)
2939 +static void nfs_free_unique_id(struct rb_root *root, struct nfs_unique_id *id)
2941 + rb_erase(&id->rb_node, root);
2944 static struct nfs4_state_owner *
2945 -nfs4_find_state_owner(struct nfs_client *clp, struct rpc_cred *cred)
2946 +nfs4_find_state_owner(struct nfs_server *server, struct rpc_cred *cred)
2948 + struct nfs_client *clp = server->nfs_client;
2949 + struct rb_node **p = &clp->cl_state_owners.rb_node,
2951 struct nfs4_state_owner *sp, *res = NULL;
2953 - list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
2954 - if (sp->so_cred != cred)
2955 + while (*p != NULL) {
2957 + sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
2959 + if (server < sp->so_server) {
2960 + p = &parent->rb_left;
2962 - atomic_inc(&sp->so_count);
2963 - /* Move to the head of the list */
2964 - list_move(&sp->so_list, &clp->cl_state_owners);
2968 + if (server > sp->so_server) {
2969 + p = &parent->rb_right;
2972 + if (cred < sp->so_cred)
2973 + p = &parent->rb_left;
2974 + else if (cred > sp->so_cred)
2975 + p = &parent->rb_right;
2977 + atomic_inc(&sp->so_count);
2985 +static struct nfs4_state_owner *
2986 +nfs4_insert_state_owner(struct nfs_client *clp, struct nfs4_state_owner *new)
2988 + struct rb_node **p = &clp->cl_state_owners.rb_node,
2990 + struct nfs4_state_owner *sp;
2992 + while (*p != NULL) {
2994 + sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
2996 + if (new->so_server < sp->so_server) {
2997 + p = &parent->rb_left;
3000 + if (new->so_server > sp->so_server) {
3001 + p = &parent->rb_right;
3004 + if (new->so_cred < sp->so_cred)
3005 + p = &parent->rb_left;
3006 + else if (new->so_cred > sp->so_cred)
3007 + p = &parent->rb_right;
3009 + atomic_inc(&sp->so_count);
3013 + nfs_alloc_unique_id(&clp->cl_openowner_id, &new->so_owner_id, 1, 64);
3014 + rb_link_node(&new->so_client_node, parent, p);
3015 + rb_insert_color(&new->so_client_node, &clp->cl_state_owners);
3020 +nfs4_remove_state_owner(struct nfs_client *clp, struct nfs4_state_owner *sp)
3022 + if (!RB_EMPTY_NODE(&sp->so_client_node))
3023 + rb_erase(&sp->so_client_node, &clp->cl_state_owners);
3024 + nfs_free_unique_id(&clp->cl_openowner_id, &sp->so_owner_id);
3028 * nfs4_alloc_state_owner(): this is called on the OPEN or CREATE path to
3029 * create a new state_owner.
3030 @@ -160,10 +257,14 @@ nfs4_alloc_state_owner(void)
3032 nfs4_drop_state_owner(struct nfs4_state_owner *sp)
3034 - struct nfs_client *clp = sp->so_client;
3035 - spin_lock(&clp->cl_lock);
3036 - list_del_init(&sp->so_list);
3037 - spin_unlock(&clp->cl_lock);
3038 + if (!RB_EMPTY_NODE(&sp->so_client_node)) {
3039 + struct nfs_client *clp = sp->so_client;
3041 + spin_lock(&clp->cl_lock);
3042 + rb_erase(&sp->so_client_node, &clp->cl_state_owners);
3043 + RB_CLEAR_NODE(&sp->so_client_node);
3044 + spin_unlock(&clp->cl_lock);
3049 @@ -175,26 +276,25 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
3050 struct nfs_client *clp = server->nfs_client;
3051 struct nfs4_state_owner *sp, *new;
3053 - get_rpccred(cred);
3054 - new = nfs4_alloc_state_owner();
3055 spin_lock(&clp->cl_lock);
3056 - sp = nfs4_find_state_owner(clp, cred);
3058 - sp = nfs4_client_grab_unused(clp, cred);
3059 - if (sp == NULL && new != NULL) {
3060 - list_add(&new->so_list, &clp->cl_state_owners);
3061 - new->so_client = clp;
3062 - new->so_id = nfs4_alloc_lockowner_id(clp);
3063 - new->so_cred = cred;
3067 + sp = nfs4_find_state_owner(server, cred);
3068 spin_unlock(&clp->cl_lock);
3072 - put_rpccred(cred);
3074 + new = nfs4_alloc_state_owner();
3077 + new->so_client = clp;
3078 + new->so_server = server;
3079 + new->so_cred = cred;
3080 + spin_lock(&clp->cl_lock);
3081 + sp = nfs4_insert_state_owner(clp, new);
3082 + spin_unlock(&clp->cl_lock);
3084 + get_rpccred(cred);
3091 @@ -208,18 +308,7 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp)
3093 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
3095 - if (clp->cl_nunused >= OPENOWNER_POOL_SIZE)
3097 - if (list_empty(&sp->so_list))
3099 - list_move(&sp->so_list, &clp->cl_unused);
3100 - clp->cl_nunused++;
3101 - spin_unlock(&clp->cl_lock);
3102 - put_rpccred(cred);
3106 - list_del(&sp->so_list);
3107 + nfs4_remove_state_owner(clp, sp);
3108 spin_unlock(&clp->cl_lock);
3111 @@ -236,6 +325,7 @@ nfs4_alloc_open_state(void)
3112 atomic_set(&state->count, 1);
3113 INIT_LIST_HEAD(&state->lock_states);
3114 spin_lock_init(&state->state_lock);
3115 + seqlock_init(&state->seqlock);
3119 @@ -263,13 +353,10 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
3120 struct nfs4_state *state;
3122 list_for_each_entry(state, &nfsi->open_states, inode_states) {
3123 - /* Is this in the process of being freed? */
3124 - if (state->state == 0)
3125 + if (state->owner != owner)
3127 - if (state->owner == owner) {
3128 - atomic_inc(&state->count);
3129 + if (atomic_inc_not_zero(&state->count))
3135 @@ -341,16 +428,15 @@ void nfs4_put_open_state(struct nfs4_state *state)
3137 * Close the current file.
3139 -void nfs4_close_state(struct nfs4_state *state, mode_t mode)
3140 +void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
3142 - struct inode *inode = state->inode;
3143 struct nfs4_state_owner *owner = state->owner;
3144 - int oldstate, newstate = 0;
3145 + int call_close = 0;
3148 atomic_inc(&owner->so_count);
3149 /* Protect against nfs4_find_state() */
3150 spin_lock(&owner->so_lock);
3151 - spin_lock(&inode->i_lock);
3152 switch (mode & (FMODE_READ | FMODE_WRITE)) {
3155 @@ -361,24 +447,29 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
3156 case FMODE_READ|FMODE_WRITE:
3159 - oldstate = newstate = state->state;
3160 + newstate = FMODE_READ|FMODE_WRITE;
3161 if (state->n_rdwr == 0) {
3162 - if (state->n_rdonly == 0)
3163 + if (state->n_rdonly == 0) {
3164 newstate &= ~FMODE_READ;
3165 - if (state->n_wronly == 0)
3166 + call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags);
3167 + call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
3169 + if (state->n_wronly == 0) {
3170 newstate &= ~FMODE_WRITE;
3171 + call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags);
3172 + call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
3174 + if (newstate == 0)
3175 + clear_bit(NFS_DELEGATED_STATE, &state->flags);
3177 - if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3178 - nfs4_state_set_mode_locked(state, newstate);
3179 - oldstate = newstate;
3181 - spin_unlock(&inode->i_lock);
3182 + nfs4_state_set_mode_locked(state, newstate);
3183 spin_unlock(&owner->so_lock);
3185 - if (oldstate != newstate && nfs4_do_close(inode, state) == 0)
3187 - nfs4_put_open_state(state);
3188 - nfs4_put_state_owner(owner);
3189 + if (!call_close) {
3190 + nfs4_put_open_state(state);
3191 + nfs4_put_state_owner(owner);
3193 + nfs4_do_close(path, state);
3197 @@ -415,12 +506,22 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
3198 atomic_set(&lsp->ls_count, 1);
3199 lsp->ls_owner = fl_owner;
3200 spin_lock(&clp->cl_lock);
3201 - lsp->ls_id = nfs4_alloc_lockowner_id(clp);
3202 + nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64);
3203 spin_unlock(&clp->cl_lock);
3204 INIT_LIST_HEAD(&lsp->ls_locks);
3208 +static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
3210 + struct nfs_client *clp = lsp->ls_state->owner->so_client;
3212 + spin_lock(&clp->cl_lock);
3213 + nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id);
3214 + spin_unlock(&clp->cl_lock);
3219 * Return a compatible lock_state. If no initialized lock_state structure
3220 * exists, return an uninitialized one.
3221 @@ -450,7 +551,8 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_
3224 spin_unlock(&state->state_lock);
3227 + nfs4_free_lock_state(new);
3231 @@ -471,7 +573,7 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
3232 if (list_empty(&state->lock_states))
3233 clear_bit(LK_STATE_IN_USE, &state->flags);
3234 spin_unlock(&state->state_lock);
3236 + nfs4_free_lock_state(lsp);
3239 static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
3240 @@ -513,8 +615,12 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
3241 void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
3243 struct nfs4_lock_state *lsp;
3246 - memcpy(dst, &state->stateid, sizeof(*dst));
3248 + seq = read_seqbegin(&state->seqlock);
3249 + memcpy(dst, &state->stateid, sizeof(*dst));
3250 + } while(read_seqretry(&state->seqlock, seq));
3251 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
3254 @@ -557,12 +663,18 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
3255 * failed with a seqid incrementing error -
3256 * see comments nfs_fs.h:seqid_mutating_error()
3258 -static inline void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
3259 +static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
3264 case -NFS4ERR_BAD_SEQID:
3265 + if (seqid->sequence->flags & NFS_SEQID_CONFIRMED)
3267 + printk(KERN_WARNING "NFS: v4 server returned a bad"
3268 + "sequence-id error on an"
3269 + "unconfirmed sequence %p!\n",
3271 case -NFS4ERR_STALE_CLIENTID:
3272 case -NFS4ERR_STALE_STATEID:
3273 case -NFS4ERR_BAD_STATEID:
3274 @@ -586,7 +698,7 @@ void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
3275 struct nfs4_state_owner, so_seqid);
3276 nfs4_drop_state_owner(sp);
3278 - return nfs_increment_seqid(status, seqid);
3279 + nfs_increment_seqid(status, seqid);
3283 @@ -596,7 +708,7 @@ void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
3285 void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
3287 - return nfs_increment_seqid(status, seqid);
3288 + nfs_increment_seqid(status, seqid);
3291 int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
3292 @@ -748,15 +860,21 @@ out_err:
3293 static void nfs4_state_mark_reclaim(struct nfs_client *clp)
3295 struct nfs4_state_owner *sp;
3296 + struct rb_node *pos;
3297 struct nfs4_state *state;
3298 struct nfs4_lock_state *lock;
3300 /* Reset all sequence ids to zero */
3301 - list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
3302 + for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
3303 + sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
3304 sp->so_seqid.counter = 0;
3305 sp->so_seqid.flags = 0;
3306 spin_lock(&sp->so_lock);
3307 list_for_each_entry(state, &sp->so_states, open_states) {
3308 + clear_bit(NFS_DELEGATED_STATE, &state->flags);
3309 + clear_bit(NFS_O_RDONLY_STATE, &state->flags);
3310 + clear_bit(NFS_O_WRONLY_STATE, &state->flags);
3311 + clear_bit(NFS_O_RDWR_STATE, &state->flags);
3312 list_for_each_entry(lock, &state->lock_states, ls_locks) {
3313 lock->ls_seqid.counter = 0;
3314 lock->ls_seqid.flags = 0;
3315 @@ -771,6 +889,7 @@ static int reclaimer(void *ptr)
3317 struct nfs_client *clp = ptr;
3318 struct nfs4_state_owner *sp;
3319 + struct rb_node *pos;
3320 struct nfs4_state_recovery_ops *ops;
3321 struct rpc_cred *cred;
3323 @@ -816,7 +935,8 @@ restart_loop:
3324 /* Mark all delegations for reclaim */
3325 nfs_delegation_mark_reclaim(clp);
3326 /* Note: list is protected by exclusive lock on cl->cl_sem */
3327 - list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
3328 + for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
3329 + sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
3330 status = nfs4_reclaim_open_state(ops, sp);
3332 if (status == -NFS4ERR_NO_GRACE) {
3333 diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
3334 index 8003c91..c087384 100644
3335 --- a/fs/nfs/nfs4xdr.c
3336 +++ b/fs/nfs/nfs4xdr.c
3337 @@ -68,9 +68,10 @@ static int nfs4_stat_to_errno(int);
3340 /* lock,open owner id:
3341 - * we currently use size 1 (u32) out of (NFS4_OPAQUE_LIMIT >> 2)
3342 + * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2)
3344 -#define owner_id_maxsz (1 + 1)
3345 +#define open_owner_id_maxsz (1 + 4)
3346 +#define lock_owner_id_maxsz (1 + 4)
3347 #define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))
3348 #define compound_decode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))
3349 #define op_encode_hdr_maxsz (1)
3350 @@ -87,9 +88,11 @@ static int nfs4_stat_to_errno(int);
3351 #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
3352 #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
3353 #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
3354 +#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
3355 +#define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
3356 /* This is based on getfattr, which uses the most attributes: */
3357 #define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
3358 - 3 + 3 + 3 + 2 * nfs4_name_maxsz))
3359 + 3 + 3 + 3 + nfs4_owner_maxsz + nfs4_group_maxsz))
3360 #define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
3361 nfs4_fattr_value_maxsz)
3362 #define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
3363 @@ -116,8 +119,27 @@ static int nfs4_stat_to_errno(int);
3364 3 + (NFS4_VERIFIER_SIZE >> 2))
3365 #define decode_setclientid_confirm_maxsz \
3366 (op_decode_hdr_maxsz)
3367 -#define encode_lookup_maxsz (op_encode_hdr_maxsz + \
3368 - 1 + ((3 + NFS4_FHSIZE) >> 2))
3369 +#define encode_lookup_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz)
3370 +#define decode_lookup_maxsz (op_decode_hdr_maxsz)
3371 +#define encode_share_access_maxsz \
3373 +#define encode_createmode_maxsz (1 + nfs4_fattr_maxsz)
3374 +#define encode_opentype_maxsz (1 + encode_createmode_maxsz)
3375 +#define encode_claim_null_maxsz (1 + nfs4_name_maxsz)
3376 +#define encode_open_maxsz (op_encode_hdr_maxsz + \
3377 + 2 + encode_share_access_maxsz + 2 + \
3378 + open_owner_id_maxsz + \
3379 + encode_opentype_maxsz + \
3380 + encode_claim_null_maxsz)
3381 +#define decode_ace_maxsz (3 + nfs4_owner_maxsz)
3382 +#define decode_delegation_maxsz (1 + XDR_QUADLEN(NFS4_STATEID_SIZE) + 1 + \
3384 +#define decode_change_info_maxsz (5)
3385 +#define decode_open_maxsz (op_decode_hdr_maxsz + \
3386 + XDR_QUADLEN(NFS4_STATEID_SIZE) + \
3387 + decode_change_info_maxsz + 1 + \
3388 + nfs4_fattr_bitmap_maxsz + \
3389 + decode_delegation_maxsz)
3390 #define encode_remove_maxsz (op_encode_hdr_maxsz + \
3392 #define encode_rename_maxsz (op_encode_hdr_maxsz + \
3393 @@ -134,9 +156,15 @@ static int nfs4_stat_to_errno(int);
3394 #define encode_create_maxsz (op_encode_hdr_maxsz + \
3395 2 + nfs4_name_maxsz + \
3397 -#define decode_create_maxsz (op_decode_hdr_maxsz + 8)
3398 +#define decode_create_maxsz (op_decode_hdr_maxsz + \
3399 + decode_change_info_maxsz + \
3400 + nfs4_fattr_bitmap_maxsz)
3401 #define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)
3402 #define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
3403 +#define encode_fs_locations_maxsz \
3404 + (encode_getattr_maxsz)
3405 +#define decode_fs_locations_maxsz \
3407 #define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
3408 #define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
3409 #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
3410 @@ -174,16 +202,21 @@ static int nfs4_stat_to_errno(int);
3411 op_decode_hdr_maxsz + 2 + \
3412 decode_getattr_maxsz)
3413 #define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
3414 - encode_putfh_maxsz + \
3415 - op_encode_hdr_maxsz + \
3416 - 13 + 3 + 2 + 64 + \
3417 - encode_getattr_maxsz + \
3418 - encode_getfh_maxsz)
3419 + encode_putfh_maxsz + \
3420 + encode_savefh_maxsz + \
3421 + encode_open_maxsz + \
3422 + encode_getfh_maxsz + \
3423 + encode_getattr_maxsz + \
3424 + encode_restorefh_maxsz + \
3425 + encode_getattr_maxsz)
3426 #define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
3427 - decode_putfh_maxsz + \
3428 - op_decode_hdr_maxsz + 4 + 5 + 2 + 3 + \
3429 - decode_getattr_maxsz + \
3430 - decode_getfh_maxsz)
3431 + decode_putfh_maxsz + \
3432 + decode_savefh_maxsz + \
3433 + decode_open_maxsz + \
3434 + decode_getfh_maxsz + \
3435 + decode_getattr_maxsz + \
3436 + decode_restorefh_maxsz + \
3437 + decode_getattr_maxsz)
3438 #define NFS4_enc_open_confirm_sz \
3439 (compound_encode_hdr_maxsz + \
3440 encode_putfh_maxsz + \
3441 @@ -193,12 +226,12 @@ static int nfs4_stat_to_errno(int);
3442 op_decode_hdr_maxsz + 4)
3443 #define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \
3444 encode_putfh_maxsz + \
3445 - op_encode_hdr_maxsz + \
3447 + encode_open_maxsz + \
3448 + encode_getattr_maxsz)
3449 #define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
3450 decode_putfh_maxsz + \
3451 - op_decode_hdr_maxsz + \
3453 + decode_open_maxsz + \
3454 + decode_getattr_maxsz)
3455 #define NFS4_enc_open_downgrade_sz \
3456 (compound_encode_hdr_maxsz + \
3457 encode_putfh_maxsz + \
3458 @@ -256,19 +289,19 @@ static int nfs4_stat_to_errno(int);
3459 op_encode_hdr_maxsz + \
3463 + lock_owner_id_maxsz)
3464 #define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \
3465 decode_putfh_maxsz + \
3466 decode_getattr_maxsz + \
3467 op_decode_hdr_maxsz + \
3470 + lock_owner_id_maxsz)
3471 #define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \
3472 encode_putfh_maxsz + \
3473 encode_getattr_maxsz + \
3474 op_encode_hdr_maxsz + \
3477 + lock_owner_id_maxsz)
3478 #define NFS4_dec_lockt_sz (NFS4_dec_lock_sz)
3479 #define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \
3480 encode_putfh_maxsz + \
3481 @@ -298,7 +331,7 @@ static int nfs4_stat_to_errno(int);
3483 #define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \
3484 decode_putfh_maxsz + \
3485 - op_decode_hdr_maxsz + \
3486 + decode_lookup_maxsz + \
3487 decode_getattr_maxsz + \
3489 #define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
3490 @@ -417,12 +450,13 @@ static int nfs4_stat_to_errno(int);
3491 #define NFS4_enc_fs_locations_sz \
3492 (compound_encode_hdr_maxsz + \
3493 encode_putfh_maxsz + \
3494 - encode_getattr_maxsz)
3495 + encode_lookup_maxsz + \
3496 + encode_fs_locations_maxsz)
3497 #define NFS4_dec_fs_locations_sz \
3498 (compound_decode_hdr_maxsz + \
3499 decode_putfh_maxsz + \
3500 - op_decode_hdr_maxsz + \
3501 - nfs4_fattr_bitmap_maxsz)
3502 + decode_lookup_maxsz + \
3503 + decode_fs_locations_maxsz)
3507 @@ -793,13 +827,14 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
3508 WRITE64(nfs4_lock_length(args->fl));
3509 WRITE32(args->new_lock_owner);
3510 if (args->new_lock_owner){
3511 - RESERVE_SPACE(4+NFS4_STATEID_SIZE+20);
3512 + RESERVE_SPACE(4+NFS4_STATEID_SIZE+32);
3513 WRITE32(args->open_seqid->sequence->counter);
3514 WRITEMEM(args->open_stateid->data, NFS4_STATEID_SIZE);
3515 WRITE32(args->lock_seqid->sequence->counter);
3516 WRITE64(args->lock_owner.clientid);
3518 - WRITE32(args->lock_owner.id);
3520 + WRITEMEM("lock id:", 8);
3521 + WRITE64(args->lock_owner.id);
3524 RESERVE_SPACE(NFS4_STATEID_SIZE+4);
3525 @@ -814,14 +849,15 @@ static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *arg
3529 - RESERVE_SPACE(40);
3530 + RESERVE_SPACE(52);
3532 WRITE32(nfs4_lock_type(args->fl, 0));
3533 WRITE64(args->fl->fl_start);
3534 WRITE64(nfs4_lock_length(args->fl));
3535 WRITE64(args->lock_owner.clientid);
3537 - WRITE32(args->lock_owner.id);
3539 + WRITEMEM("lock id:", 8);
3540 + WRITE64(args->lock_owner.id);
3544 @@ -886,10 +922,11 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
3546 WRITE32(arg->seqid->sequence->counter);
3547 encode_share_access(xdr, arg->open_flags);
3548 - RESERVE_SPACE(16);
3549 + RESERVE_SPACE(28);
3550 WRITE64(arg->clientid);
3554 + WRITEMEM("open id:", 8);
3558 static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
3559 @@ -1071,7 +1108,7 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)
3561 static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req)
3563 - struct rpc_auth *auth = req->rq_task->tk_auth;
3564 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
3565 uint32_t attrs[2] = {
3566 FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
3567 FATTR4_WORD1_MOUNTED_ON_FILEID,
3568 @@ -1117,7 +1154,7 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
3570 static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req)
3572 - struct rpc_auth *auth = req->rq_task->tk_auth;
3573 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
3574 unsigned int replen;
3577 @@ -1735,7 +1772,7 @@ out:
3579 static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
3581 - struct rpc_auth *auth = req->rq_task->tk_auth;
3582 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
3583 struct xdr_stream xdr;
3584 struct compound_hdr hdr = {
3586 @@ -1795,7 +1832,7 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
3587 struct nfs_getaclargs *args)
3589 struct xdr_stream xdr;
3590 - struct rpc_auth *auth = req->rq_task->tk_auth;
3591 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
3592 struct compound_hdr hdr = {
3595 @@ -2030,7 +2067,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
3596 struct compound_hdr hdr = {
3599 - struct rpc_auth *auth = req->rq_task->tk_auth;
3600 + struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
3604 @@ -3269,7 +3306,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3605 static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
3609 + uint32_t savewords, bmlen, i;
3612 status = decode_op_hdr(xdr, OP_OPEN);
3613 @@ -3287,7 +3324,12 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
3616 READ_BUF(bmlen << 2);
3618 + savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE);
3619 + for (i = 0; i < savewords; ++i)
3620 + READ32(res->attrset[i]);
3621 + for (; i < NFS4_BITMAP_SIZE; i++)
3622 + res->attrset[i] = 0;
3624 return decode_delegation(xdr, res);
3626 dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen);
3627 diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
3628 index 49d1008..3490322 100644
3629 --- a/fs/nfs/nfsroot.c
3630 +++ b/fs/nfs/nfsroot.c
3631 @@ -428,7 +428,7 @@ static int __init root_nfs_getport(int program, int version, int proto)
3632 printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
3633 program, version, NIPQUAD(servaddr));
3634 set_sockaddr(&sin, servaddr, 0);
3635 - return rpcb_getport_external(&sin, program, version, proto);
3636 + return rpcb_getport_sync(&sin, program, version, proto);
3640 @@ -496,7 +496,8 @@ static int __init root_nfs_get_handle(void)
3641 NFS_MNT3_VERSION : NFS_MNT_VERSION;
3643 set_sockaddr(&sin, servaddr, htons(mount_port));
3644 - status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol);
3645 + status = nfs_mount((struct sockaddr *) &sin, sizeof(sin), NULL,
3646 + nfs_path, version, protocol, &fh);
3648 printk(KERN_ERR "Root-NFS: Server returned error %d "
3649 "while mounting %s\n", status, nfs_path);
3650 diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
3651 index c5bb51a..f56dae5 100644
3652 --- a/fs/nfs/pagelist.c
3653 +++ b/fs/nfs/pagelist.c
3654 @@ -85,9 +85,8 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
3655 req->wb_offset = offset;
3656 req->wb_pgbase = offset;
3657 req->wb_bytes = count;
3658 - atomic_set(&req->wb_count, 1);
3659 req->wb_context = get_nfs_open_context(ctx);
3661 + kref_init(&req->wb_kref);
3665 @@ -109,30 +108,31 @@ void nfs_unlock_request(struct nfs_page *req)
3669 - * nfs_set_page_writeback_locked - Lock a request for writeback
3670 + * nfs_set_page_tag_locked - Tag a request as locked
3673 -int nfs_set_page_writeback_locked(struct nfs_page *req)
3674 +static int nfs_set_page_tag_locked(struct nfs_page *req)
3676 - struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode);
3677 + struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode);
3679 if (!nfs_lock_request(req))
3681 - radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_WRITEBACK);
3682 + radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
3687 - * nfs_clear_page_writeback - Unlock request and wake up sleepers
3688 + * nfs_clear_page_tag_locked - Clear request tag and wake up sleepers
3690 -void nfs_clear_page_writeback(struct nfs_page *req)
3691 +void nfs_clear_page_tag_locked(struct nfs_page *req)
3693 - struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode);
3694 + struct inode *inode = req->wb_context->path.dentry->d_inode;
3695 + struct nfs_inode *nfsi = NFS_I(inode);
3697 if (req->wb_page != NULL) {
3698 - spin_lock(&nfsi->req_lock);
3699 - radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_WRITEBACK);
3700 - spin_unlock(&nfsi->req_lock);
3701 + spin_lock(&inode->i_lock);
3702 + radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
3703 + spin_unlock(&inode->i_lock);
3705 nfs_unlock_request(req);
3707 @@ -160,11 +160,9 @@ void nfs_clear_request(struct nfs_page *req)
3709 * Note: Should never be called with the spinlock held!
3712 -nfs_release_request(struct nfs_page *req)
3713 +static void nfs_free_request(struct kref *kref)
3715 - if (!atomic_dec_and_test(&req->wb_count))
3717 + struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
3719 /* Release struct file or cached credential */
3720 nfs_clear_request(req);
3721 @@ -172,6 +170,11 @@ nfs_release_request(struct nfs_page *req)
3725 +void nfs_release_request(struct nfs_page *req)
3727 + kref_put(&req->wb_kref, nfs_free_request);
3730 static int nfs_wait_bit_interruptible(void *word)
3733 @@ -193,7 +196,7 @@ static int nfs_wait_bit_interruptible(void *word)
3735 nfs_wait_on_request(struct nfs_page *req)
3737 - struct rpc_clnt *clnt = NFS_CLIENT(req->wb_context->dentry->d_inode);
3738 + struct rpc_clnt *clnt = NFS_CLIENT(req->wb_context->path.dentry->d_inode);
3742 @@ -379,20 +382,20 @@ void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
3744 * nfs_scan_list - Scan a list for matching requests
3746 - * @head: One of the NFS inode request lists
3747 * @dst: Destination list
3748 * @idx_start: lower bound of page->index to scan
3749 * @npages: idx_start + npages sets the upper bound to scan.
3750 + * @tag: tag to scan for
3752 * Moves elements from one of the inode request lists.
3753 * If the number of requests is set to 0, the entire address_space
3754 * starting at index idx_start, is scanned.
3755 * The requests are *not* checked to ensure that they form a contiguous set.
3756 - * You must be holding the inode's req_lock when calling this function
3757 + * You must be holding the inode's i_lock when calling this function
3759 -int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head,
3760 +int nfs_scan_list(struct nfs_inode *nfsi,
3761 struct list_head *dst, pgoff_t idx_start,
3762 - unsigned int npages)
3763 + unsigned int npages, int tag)
3765 struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES];
3766 struct nfs_page *req;
3767 @@ -407,9 +410,9 @@ int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head,
3768 idx_end = idx_start + npages - 1;
3771 - found = radix_tree_gang_lookup(&nfsi->nfs_page_tree,
3772 + found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree,
3773 (void **)&pgvec[0], idx_start,
3774 - NFS_SCAN_MAXENTRIES);
3775 + NFS_SCAN_MAXENTRIES, tag);
3778 for (i = 0; i < found; i++) {
3779 @@ -417,15 +420,18 @@ int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head,
3780 if (req->wb_index > idx_end)
3782 idx_start = req->wb_index + 1;
3783 - if (req->wb_list_head != head)
3785 - if (nfs_set_page_writeback_locked(req)) {
3786 + if (nfs_set_page_tag_locked(req)) {
3787 nfs_list_remove_request(req);
3788 + radix_tree_tag_clear(&nfsi->nfs_page_tree,
3789 + req->wb_index, tag);
3790 nfs_list_add_request(req, dst);
3792 + if (res == INT_MAX)
3797 + /* for latency reduction */
3798 + cond_resched_lock(&nfsi->vfs_inode.i_lock);
3802 diff --git a/fs/nfs/read.c b/fs/nfs/read.c
3803 index 7bd7cb9..6ae2e58 100644
3806 @@ -145,8 +145,8 @@ static void nfs_readpage_release(struct nfs_page *req)
3807 unlock_page(req->wb_page);
3809 dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
3810 - req->wb_context->dentry->d_inode->i_sb->s_id,
3811 - (long long)NFS_FILEID(req->wb_context->dentry->d_inode),
3812 + req->wb_context->path.dentry->d_inode->i_sb->s_id,
3813 + (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
3815 (long long)req_offset(req));
3816 nfs_clear_request(req);
3817 @@ -164,7 +164,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
3821 - data->inode = inode = req->wb_context->dentry->d_inode;
3822 + data->inode = inode = req->wb_context->path.dentry->d_inode;
3823 data->cred = req->wb_context->cred;
3825 data->args.fh = NFS_FH(inode);
3826 @@ -483,17 +483,19 @@ int nfs_readpage(struct file *file, struct page *page)
3828 error = nfs_wb_page(inode, page);
3832 + if (PageUptodate(page))
3836 if (NFS_STALE(inode))
3842 ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
3847 ctx = get_nfs_open_context((struct nfs_open_context *)
3848 file->private_data);
3849 @@ -502,8 +504,7 @@ int nfs_readpage(struct file *file, struct page *page)
3851 put_nfs_open_context(ctx);
3859 @@ -520,21 +521,32 @@ readpage_async_filler(void *data, struct page *page)
3860 struct inode *inode = page->mapping->host;
3861 struct nfs_page *new;
3865 + error = nfs_wb_page(inode, page);
3868 + if (PageUptodate(page))
3871 - nfs_wb_page(inode, page);
3872 len = nfs_page_length(page);
3874 return nfs_return_empty_page(page);
3876 new = nfs_create_request(desc->ctx, inode, page, 0, len);
3877 - if (IS_ERR(new)) {
3878 - SetPageError(page);
3879 - unlock_page(page);
3880 - return PTR_ERR(new);
3885 if (len < PAGE_CACHE_SIZE)
3886 zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0);
3887 nfs_pageio_add_request(desc->pgio, new);
3890 + error = PTR_ERR(new);
3891 + SetPageError(page);
3893 + unlock_page(page);
3897 int nfs_readpages(struct file *filp, struct address_space *mapping,
3898 diff --git a/fs/nfs/super.c b/fs/nfs/super.c
3899 index ca20d3c..a2b1af8 100644
3900 --- a/fs/nfs/super.c
3901 +++ b/fs/nfs/super.c
3903 #include <linux/inet.h>
3904 #include <linux/nfs_xdr.h>
3905 #include <linux/magic.h>
3906 +#include <linux/parser.h>
3908 #include <asm/system.h>
3909 #include <asm/uaccess.h>
3912 #define NFSDBG_FACILITY NFSDBG_VFS
3915 +struct nfs_parsed_mount_data {
3918 + int timeo, retrans;
3919 + int acregmin, acregmax,
3920 + acdirmin, acdirmax;
3922 + unsigned int bsize;
3923 + unsigned int auth_flavor_len;
3924 + rpc_authflavor_t auth_flavors[1];
3925 + char *client_address;
3928 + struct sockaddr_in address;
3929 + unsigned int program;
3930 + unsigned int version;
3931 + unsigned short port;
3936 + struct sockaddr_in address;
3938 + char *export_path;
3939 + unsigned int program;
3945 + /* Mount options that take no arguments */
3946 + Opt_soft, Opt_hard,
3947 + Opt_intr, Opt_nointr,
3948 + Opt_posix, Opt_noposix,
3949 + Opt_cto, Opt_nocto,
3951 + Opt_lock, Opt_nolock,
3954 + Opt_acl, Opt_noacl,
3955 + Opt_rdirplus, Opt_nordirplus,
3956 + Opt_sharecache, Opt_nosharecache,
3958 + /* Mount options that take integer arguments */
3960 + Opt_rsize, Opt_wsize, Opt_bsize,
3961 + Opt_timeo, Opt_retrans,
3962 + Opt_acregmin, Opt_acregmax,
3963 + Opt_acdirmin, Opt_acdirmax,
3967 + Opt_mountprog, Opt_mountvers,
3968 + Opt_nfsprog, Opt_nfsvers,
3970 + /* Mount options that take string arguments */
3971 + Opt_sec, Opt_proto, Opt_mountproto,
3972 + Opt_addr, Opt_mounthost, Opt_clientaddr,
3974 + /* Mount options that are ignored */
3975 + Opt_userspace, Opt_deprecated,
3980 +static match_table_t nfs_mount_option_tokens = {
3981 + { Opt_userspace, "bg" },
3982 + { Opt_userspace, "fg" },
3983 + { Opt_soft, "soft" },
3984 + { Opt_hard, "hard" },
3985 + { Opt_intr, "intr" },
3986 + { Opt_nointr, "nointr" },
3987 + { Opt_posix, "posix" },
3988 + { Opt_noposix, "noposix" },
3989 + { Opt_cto, "cto" },
3990 + { Opt_nocto, "nocto" },
3992 + { Opt_noac, "noac" },
3993 + { Opt_lock, "lock" },
3994 + { Opt_nolock, "nolock" },
3997 + { Opt_udp, "udp" },
3998 + { Opt_tcp, "tcp" },
3999 + { Opt_acl, "acl" },
4000 + { Opt_noacl, "noacl" },
4001 + { Opt_rdirplus, "rdirplus" },
4002 + { Opt_nordirplus, "nordirplus" },
4003 + { Opt_sharecache, "sharecache" },
4004 + { Opt_nosharecache, "nosharecache" },
4006 + { Opt_port, "port=%u" },
4007 + { Opt_rsize, "rsize=%u" },
4008 + { Opt_wsize, "wsize=%u" },
4009 + { Opt_bsize, "bsize=%u" },
4010 + { Opt_timeo, "timeo=%u" },
4011 + { Opt_retrans, "retrans=%u" },
4012 + { Opt_acregmin, "acregmin=%u" },
4013 + { Opt_acregmax, "acregmax=%u" },
4014 + { Opt_acdirmin, "acdirmin=%u" },
4015 + { Opt_acdirmax, "acdirmax=%u" },
4016 + { Opt_actimeo, "actimeo=%u" },
4017 + { Opt_userspace, "retry=%u" },
4018 + { Opt_namelen, "namlen=%u" },
4019 + { Opt_mountport, "mountport=%u" },
4020 + { Opt_mountprog, "mountprog=%u" },
4021 + { Opt_mountvers, "mountvers=%u" },
4022 + { Opt_nfsprog, "nfsprog=%u" },
4023 + { Opt_nfsvers, "nfsvers=%u" },
4024 + { Opt_nfsvers, "vers=%u" },
4026 + { Opt_sec, "sec=%s" },
4027 + { Opt_proto, "proto=%s" },
4028 + { Opt_mountproto, "mountproto=%s" },
4029 + { Opt_addr, "addr=%s" },
4030 + { Opt_clientaddr, "clientaddr=%s" },
4031 + { Opt_mounthost, "mounthost=%s" },
4037 + Opt_xprt_udp, Opt_xprt_tcp,
4042 +static match_table_t nfs_xprt_protocol_tokens = {
4043 + { Opt_xprt_udp, "udp" },
4044 + { Opt_xprt_tcp, "tcp" },
4046 + { Opt_xprt_err, NULL }
4050 + Opt_sec_none, Opt_sec_sys,
4051 + Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
4052 + Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp,
4053 + Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp,
4058 +static match_table_t nfs_secflavor_tokens = {
4059 + { Opt_sec_none, "none" },
4060 + { Opt_sec_none, "null" },
4061 + { Opt_sec_sys, "sys" },
4063 + { Opt_sec_krb5, "krb5" },
4064 + { Opt_sec_krb5i, "krb5i" },
4065 + { Opt_sec_krb5p, "krb5p" },
4067 + { Opt_sec_lkey, "lkey" },
4068 + { Opt_sec_lkeyi, "lkeyi" },
4069 + { Opt_sec_lkeyp, "lkeyp" },
4071 + { Opt_sec_err, NULL }
4075 static void nfs_umount_begin(struct vfsmount *, int);
4076 static int nfs_statfs(struct dentry *, struct kstatfs *);
4077 static int nfs_show_options(struct seq_file *, struct vfsmount *);
4078 @@ -263,11 +425,11 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
4079 { RPC_AUTH_GSS_SPKM, "spkm" },
4080 { RPC_AUTH_GSS_SPKMI, "spkmi" },
4081 { RPC_AUTH_GSS_SPKMP, "spkmp" },
4083 + { UINT_MAX, "unknown" }
4087 - for (i=0; sec_flavours[i].flavour != -1; i++) {
4088 + for (i = 0; sec_flavours[i].flavour != UINT_MAX; i++) {
4089 if (sec_flavours[i].flavour == flavour)
4092 @@ -291,6 +453,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
4093 { NFS_MOUNT_NONLM, ",nolock", "" },
4094 { NFS_MOUNT_NOACL, ",noacl", "" },
4095 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
4096 + { NFS_MOUNT_UNSHARED, ",nosharecache", ""},
4099 const struct proc_nfs_info *nfs_infop;
4100 @@ -430,87 +593,641 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
4102 static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
4104 + struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
4105 + struct rpc_clnt *rpc;
4107 shrink_submounts(vfsmnt, &nfs_automount_list);
4109 + if (!(flags & MNT_FORCE))
4111 + /* -EIO all pending I/O */
4112 + rpc = server->client_acl;
4114 + rpc_killall_tasks(rpc);
4115 + rpc = server->client;
4117 + rpc_killall_tasks(rpc);
4121 - * Validate the NFS2/NFS3 mount data
4122 - * - fills in the mount root filehandle
4123 + * Sanity-check a server address provided by the mount command
4125 -static int nfs_validate_mount_data(struct nfs_mount_data *data,
4126 - struct nfs_fh *mntfh)
4127 +static int nfs_verify_server_address(struct sockaddr *addr)
4129 - if (data == NULL) {
4130 - dprintk("%s: missing data argument\n", __FUNCTION__);
4132 + switch (addr->sa_family) {
4134 + struct sockaddr_in *sa = (struct sockaddr_in *) addr;
4135 + if (sa->sin_addr.s_addr != INADDR_ANY)
4141 - if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
4142 - dprintk("%s: bad mount version\n", __FUNCTION__);
4148 + * Error-check and convert a string of mount options from user space into
4149 + * a data structure
4151 +static int nfs_parse_mount_options(char *raw,
4152 + struct nfs_parsed_mount_data *mnt)
4157 + dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
4160 + dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
4162 - switch (data->version) {
4168 - if (data->flags & NFS_MOUNT_VER3) {
4169 - dprintk("%s: mount structure version %d does not support NFSv3\n",
4173 + while ((p = strsep(&raw, ",")) != NULL) {
4174 + substring_t args[MAX_OPT_ARGS];
4175 + int option, token;
4180 + dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p);
4182 + token = match_token(p, nfs_mount_option_tokens, args);
4185 + mnt->flags |= NFS_MOUNT_SOFT;
4188 + mnt->flags &= ~NFS_MOUNT_SOFT;
4191 + mnt->flags |= NFS_MOUNT_INTR;
4194 + mnt->flags &= ~NFS_MOUNT_INTR;
4197 + mnt->flags |= NFS_MOUNT_POSIX;
4200 + mnt->flags &= ~NFS_MOUNT_POSIX;
4203 + mnt->flags &= ~NFS_MOUNT_NOCTO;
4206 + mnt->flags |= NFS_MOUNT_NOCTO;
4209 + mnt->flags &= ~NFS_MOUNT_NOAC;
4212 + mnt->flags |= NFS_MOUNT_NOAC;
4215 + mnt->flags &= ~NFS_MOUNT_NONLM;
4218 + mnt->flags |= NFS_MOUNT_NONLM;
4221 + mnt->flags &= ~NFS_MOUNT_VER3;
4224 + mnt->flags |= NFS_MOUNT_VER3;
4227 + mnt->flags &= ~NFS_MOUNT_TCP;
4228 + mnt->nfs_server.protocol = IPPROTO_UDP;
4233 + mnt->flags |= NFS_MOUNT_TCP;
4234 + mnt->nfs_server.protocol = IPPROTO_TCP;
4239 + mnt->flags &= ~NFS_MOUNT_NOACL;
4242 + mnt->flags |= NFS_MOUNT_NOACL;
4244 + case Opt_rdirplus:
4245 + mnt->flags &= ~NFS_MOUNT_NORDIRPLUS;
4247 + case Opt_nordirplus:
4248 + mnt->flags |= NFS_MOUNT_NORDIRPLUS;
4250 + case Opt_sharecache:
4251 + mnt->flags &= ~NFS_MOUNT_UNSHARED;
4253 + case Opt_nosharecache:
4254 + mnt->flags |= NFS_MOUNT_UNSHARED;
4258 + if (match_int(args, &option))
4260 + if (option < 0 || option > 65535)
4262 + mnt->nfs_server.address.sin_port = htonl(option);
4265 + if (match_int(args, &mnt->rsize))
4269 + if (match_int(args, &mnt->wsize))
4273 + if (match_int(args, &option))
4277 + mnt->bsize = option;
4280 + if (match_int(args, &mnt->timeo))
4284 + if (match_int(args, &mnt->retrans))
4287 + case Opt_acregmin:
4288 + if (match_int(args, &mnt->acregmin))
4291 + case Opt_acregmax:
4292 + if (match_int(args, &mnt->acregmax))
4295 + case Opt_acdirmin:
4296 + if (match_int(args, &mnt->acdirmin))
4299 + case Opt_acdirmax:
4300 + if (match_int(args, &mnt->acdirmax))
4304 + if (match_int(args, &option))
4311 + mnt->acdirmax = option;
4314 + if (match_int(args, &mnt->namlen))
4317 + case Opt_mountport:
4318 + if (match_int(args, &option))
4320 + if (option < 0 || option > 65535)
4322 + mnt->mount_server.port = option;
4324 + case Opt_mountprog:
4325 + if (match_int(args, &option))
4329 + mnt->mount_server.program = option;
4331 + case Opt_mountvers:
4332 + if (match_int(args, &option))
4336 + mnt->mount_server.version = option;
4339 + if (match_int(args, &option))
4343 + mnt->nfs_server.program = option;
4346 + if (match_int(args, &option))
4350 + mnt->flags &= ~NFS_MOUNT_VER3;
4353 + mnt->flags |= NFS_MOUNT_VER3;
4356 + goto out_unrec_vers;
4358 - data->root.size = NFS2_FHSIZE;
4359 - memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
4361 - if (data->flags & NFS_MOUNT_SECFLAVOUR) {
4362 - dprintk("%s: mount structure version %d does not support strong security\n",
4369 + string = match_strdup(args);
4370 + if (string == NULL)
4372 + token = match_token(string, nfs_secflavor_tokens, args);
4376 + * The flags setting is for v2/v3. The flavor_len
4377 + * setting is for v4. v2/v3 also need to know the
4378 + * difference between NULL and UNIX.
4381 + case Opt_sec_none:
4382 + mnt->flags &= ~NFS_MOUNT_SECFLAVOUR;
4383 + mnt->auth_flavor_len = 0;
4384 + mnt->auth_flavors[0] = RPC_AUTH_NULL;
4387 + mnt->flags &= ~NFS_MOUNT_SECFLAVOUR;
4388 + mnt->auth_flavor_len = 0;
4389 + mnt->auth_flavors[0] = RPC_AUTH_UNIX;
4391 + case Opt_sec_krb5:
4392 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4393 + mnt->auth_flavor_len = 1;
4394 + mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5;
4396 + case Opt_sec_krb5i:
4397 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4398 + mnt->auth_flavor_len = 1;
4399 + mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I;
4401 + case Opt_sec_krb5p:
4402 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4403 + mnt->auth_flavor_len = 1;
4404 + mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P;
4406 + case Opt_sec_lkey:
4407 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4408 + mnt->auth_flavor_len = 1;
4409 + mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY;
4411 + case Opt_sec_lkeyi:
4412 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4413 + mnt->auth_flavor_len = 1;
4414 + mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI;
4416 + case Opt_sec_lkeyp:
4417 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4418 + mnt->auth_flavor_len = 1;
4419 + mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP;
4421 + case Opt_sec_spkm:
4422 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4423 + mnt->auth_flavor_len = 1;
4424 + mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM;
4426 + case Opt_sec_spkmi:
4427 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4428 + mnt->auth_flavor_len = 1;
4429 + mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI;
4431 + case Opt_sec_spkmp:
4432 + mnt->flags |= NFS_MOUNT_SECFLAVOUR;
4433 + mnt->auth_flavor_len = 1;
4434 + mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP;
4437 + goto out_unrec_sec;
4440 - memset(data->context, 0, sizeof(data->context));
4444 + string = match_strdup(args);
4445 + if (string == NULL)
4447 + token = match_token(string,
4448 + nfs_xprt_protocol_tokens, args);
4453 + mnt->flags &= ~NFS_MOUNT_TCP;
4454 + mnt->nfs_server.protocol = IPPROTO_UDP;
4459 + mnt->flags |= NFS_MOUNT_TCP;
4460 + mnt->nfs_server.protocol = IPPROTO_TCP;
4465 + goto out_unrec_xprt;
4468 + case Opt_mountproto:
4469 + string = match_strdup(args);
4470 + if (string == NULL)
4472 + token = match_token(string,
4473 + nfs_xprt_protocol_tokens, args);
4478 + mnt->mount_server.protocol = IPPROTO_UDP;
4481 + mnt->mount_server.protocol = IPPROTO_TCP;
4484 + goto out_unrec_xprt;
4488 + string = match_strdup(args);
4489 + if (string == NULL)
4491 + mnt->nfs_server.address.sin_family = AF_INET;
4492 + mnt->nfs_server.address.sin_addr.s_addr =
4496 + case Opt_clientaddr:
4497 + string = match_strdup(args);
4498 + if (string == NULL)
4500 + mnt->client_address = string;
4502 + case Opt_mounthost:
4503 + string = match_strdup(args);
4504 + if (string == NULL)
4506 + mnt->mount_server.address.sin_family = AF_INET;
4507 + mnt->mount_server.address.sin_addr.s_addr =
4512 - /* Set the pseudoflavor */
4513 - if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
4514 - data->pseudoflavor = RPC_AUTH_UNIX;
4515 + case Opt_userspace:
4516 + case Opt_deprecated:
4519 -#ifndef CONFIG_NFS_V3
4520 - /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
4521 - if (data->flags & NFS_MOUNT_VER3) {
4522 - dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
4523 - return -EPROTONOSUPPORT;
4528 -#endif /* CONFIG_NFS_V3 */
4530 - /* We now require that the mount process passes the remote address */
4531 - if (data->addr.sin_addr.s_addr == INADDR_ANY) {
4532 - dprintk("%s: mount program didn't pass remote address!\n",
4538 + printk(KERN_INFO "NFS: not enough memory to parse option\n");
4542 + printk(KERN_INFO "NFS: unrecognized NFS version number\n");
4546 + printk(KERN_INFO "NFS: unrecognized transport protocol\n");
4550 + printk(KERN_INFO "NFS: unrecognized security flavor\n");
4554 + printk(KERN_INFO "NFS: unknown mount option: %s\n", p);
4559 + * Use the remote server's MOUNT service to request the NFS file handle
4560 + * corresponding to the provided path.
4562 +static int nfs_try_mount(struct nfs_parsed_mount_data *args,
4563 + struct nfs_fh *root_fh)
4565 + struct sockaddr_in sin;
4568 + if (args->mount_server.version == 0) {
4569 + if (args->flags & NFS_MOUNT_VER3)
4570 + args->mount_server.version = NFS_MNT3_VERSION;
4572 + args->mount_server.version = NFS_MNT_VERSION;
4575 - /* Prepare the root filehandle */
4576 - if (data->flags & NFS_MOUNT_VER3)
4577 - mntfh->size = data->root.size;
4579 + * Construct the mount server's address.
4581 + if (args->mount_server.address.sin_addr.s_addr != INADDR_ANY)
4582 + sin = args->mount_server.address;
4584 - mntfh->size = NFS2_FHSIZE;
4585 + sin = args->nfs_server.address;
4586 + if (args->mount_server.port == 0) {
4587 + status = rpcb_getport_sync(&sin,
4588 + args->mount_server.program,
4589 + args->mount_server.version,
4590 + args->mount_server.protocol);
4593 + sin.sin_port = htons(status);
4595 + sin.sin_port = htons(args->mount_server.port);
4598 + * Now ask the mount server to map our export path
4599 + * to a file handle.
4601 + status = nfs_mount((struct sockaddr *) &sin,
4603 + args->nfs_server.hostname,
4604 + args->nfs_server.export_path,
4605 + args->mount_server.version,
4606 + args->mount_server.protocol,
4613 - if (mntfh->size > sizeof(mntfh->data)) {
4614 - dprintk("%s: invalid root filehandle\n", __FUNCTION__);
4617 + dfprintk(MOUNT, "NFS: unable to contact server on host "
4618 + NIPQUAD_FMT "\n", NIPQUAD(sin.sin_addr.s_addr));
4623 + * Validate the NFS2/NFS3 mount data
4624 + * - fills in the mount root filehandle
4626 + * For option strings, user space handles the following behaviors:
4628 + * + DNS: mapping server host name to IP address ("addr=" option)
4630 + * + failure mode: how to behave if a mount request can't be handled
4631 + * immediately ("fg/bg" option)
4633 + * + retry: how often to retry a mount request ("retry=" option)
4635 + * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
4636 + * mountproto=tcp after mountproto=udp, and so on
4638 + * XXX: as far as I can tell, changing the NFS program number is not
4639 + * supported in the NFS client.
4641 +static int nfs_validate_mount_data(struct nfs_mount_data **options,
4642 + struct nfs_fh *mntfh,
4643 + const char *dev_name)
4645 + struct nfs_mount_data *data = *options;
4650 + switch (data->version) {
4656 + if (data->flags & NFS_MOUNT_VER3)
4658 + data->root.size = NFS2_FHSIZE;
4659 + memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
4661 + if (data->flags & NFS_MOUNT_SECFLAVOUR)
4664 + memset(data->context, 0, sizeof(data->context));
4666 + if (data->flags & NFS_MOUNT_VER3)
4667 + mntfh->size = data->root.size;
4669 + mntfh->size = NFS2_FHSIZE;
4671 + if (mntfh->size > sizeof(mntfh->data))
4672 + goto out_invalid_fh;
4674 + memcpy(mntfh->data, data->root.data, mntfh->size);
4675 + if (mntfh->size < sizeof(mntfh->data))
4676 + memset(mntfh->data + mntfh->size, 0,
4677 + sizeof(mntfh->data) - mntfh->size);
4683 + struct nfs_parsed_mount_data args = {
4684 + .flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP),
4685 + .rsize = NFS_MAX_FILE_IO_SIZE,
4686 + .wsize = NFS_MAX_FILE_IO_SIZE,
4693 + .mount_server.protocol = IPPROTO_UDP,
4694 + .mount_server.program = NFS_MNT_PROGRAM,
4695 + .nfs_server.protocol = IPPROTO_TCP,
4696 + .nfs_server.program = NFS_PROGRAM,
4699 + if (nfs_parse_mount_options((char *) *options, &args) == 0)
4702 + data = kzalloc(sizeof(*data), GFP_KERNEL);
4707 + * NB: after this point, caller will free "data"
4708 + * if we return an error
4712 + c = strchr(dev_name, ':');
4715 + len = c - dev_name - 1;
4716 + if (len > sizeof(data->hostname))
4718 + strncpy(data->hostname, dev_name, len);
4719 + args.nfs_server.hostname = data->hostname;
4722 + if (strlen(c) > NFS_MAXPATHLEN)
4724 + args.nfs_server.export_path = c;
4726 + status = nfs_try_mount(&args, mntfh);
4731 + * Translate to nfs_mount_data, which nfs_fill_super
4734 + data->version = 6;
4735 + data->flags = args.flags;
4736 + data->rsize = args.rsize;
4737 + data->wsize = args.wsize;
4738 + data->timeo = args.timeo;
4739 + data->retrans = args.retrans;
4740 + data->acregmin = args.acregmin;
4741 + data->acregmax = args.acregmax;
4742 + data->acdirmin = args.acdirmin;
4743 + data->acdirmax = args.acdirmax;
4744 + data->addr = args.nfs_server.address;
4745 + data->namlen = args.namlen;
4746 + data->bsize = args.bsize;
4747 + data->pseudoflavor = args.auth_flavors[0];
4753 - memcpy(mntfh->data, data->root.data, mntfh->size);
4754 - if (mntfh->size < sizeof(mntfh->data))
4755 - memset(mntfh->data + mntfh->size, 0,
4756 - sizeof(mntfh->data) - mntfh->size);
4757 + if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
4758 + data->pseudoflavor = RPC_AUTH_UNIX;
4760 +#ifndef CONFIG_NFS_V3
4761 + if (data->flags & NFS_MOUNT_VER3)
4762 + goto out_v3_not_compiled;
4763 +#endif /* !CONFIG_NFS_V3 */
4765 + if (!nfs_verify_server_address((struct sockaddr *) &data->addr))
4766 + goto out_no_address;
4771 + dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n");
4775 + dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n",
4780 + dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
4783 +#ifndef CONFIG_NFS_V3
4784 +out_v3_not_compiled:
4785 + dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n");
4786 + return -EPROTONOSUPPORT;
4787 +#endif /* !CONFIG_NFS_V3 */
4790 + dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
4794 + dfprintk(MOUNT, "NFS: invalid root filehandle\n");
4799 @@ -600,13 +1317,51 @@ static int nfs_compare_super(struct super_block *sb, void *data)
4801 struct nfs_server *server = data, *old = NFS_SB(sb);
4803 - if (old->nfs_client != server->nfs_client)
4804 + if (memcmp(&old->nfs_client->cl_addr,
4805 + &server->nfs_client->cl_addr,
4806 + sizeof(old->nfs_client->cl_addr)) != 0)
4808 + /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
4809 + if (old->flags & NFS_MOUNT_UNSHARED)
4811 if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
4816 +#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
4818 +static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
4820 + const struct nfs_server *a = s->s_fs_info;
4821 + const struct rpc_clnt *clnt_a = a->client;
4822 + const struct rpc_clnt *clnt_b = b->client;
4824 + if ((s->s_flags & NFS_MS_MASK) != (flags & NFS_MS_MASK))
4826 + if (a->nfs_client != b->nfs_client)
4828 + if (a->flags != b->flags)
4830 + if (a->wsize != b->wsize)
4832 + if (a->rsize != b->rsize)
4834 + if (a->acregmin != b->acregmin)
4836 + if (a->acregmax != b->acregmax)
4838 + if (a->acdirmin != b->acdirmin)
4840 + if (a->acdirmax != b->acdirmax)
4842 + if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
4849 static int nfs_get_sb(struct file_system_type *fs_type,
4850 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
4852 @@ -615,30 +1370,37 @@ static int nfs_get_sb(struct file_system_type *fs_type,
4853 struct nfs_fh mntfh;
4854 struct nfs_mount_data *data = raw_data;
4855 struct dentry *mntroot;
4856 + int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
4859 /* Validate the mount data */
4860 - error = nfs_validate_mount_data(data, &mntfh);
4861 + error = nfs_validate_mount_data(&data, &mntfh, dev_name);
4866 /* Get a volume representation */
4867 server = nfs_create_server(data, &mntfh);
4868 if (IS_ERR(server)) {
4869 error = PTR_ERR(server);
4870 - goto out_err_noserver;
4874 + if (server->flags & NFS_MOUNT_UNSHARED)
4875 + compare_super = NULL;
4877 /* Get a superblock - note that we may end up sharing one that already exists */
4878 - s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
4879 + s = sget(fs_type, compare_super, nfs_set_super, server);
4885 if (s->s_fs_info != server) {
4886 + error = nfs_compare_mount_options(s, server, flags);
4887 nfs_free_server(server);
4890 + goto error_splat_super;
4894 @@ -656,17 +1418,21 @@ static int nfs_get_sb(struct file_system_type *fs_type,
4895 s->s_flags |= MS_ACTIVE;
4897 mnt->mnt_root = mntroot;
4902 + if (data != raw_data)
4907 nfs_free_server(server);
4913 up_write(&s->s_umount);
4914 deactivate_super(s);
4920 @@ -691,6 +1457,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
4921 struct super_block *s;
4922 struct nfs_server *server;
4923 struct dentry *mntroot;
4924 + int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
4927 dprintk("--> nfs_xdev_get_sb()\n");
4928 @@ -702,16 +1469,22 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
4929 goto out_err_noserver;
4932 + if (server->flags & NFS_MOUNT_UNSHARED)
4933 + compare_super = NULL;
4935 /* Get a superblock - note that we may end up sharing one that already exists */
4936 - s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
4937 + s = sget(&nfs_fs_type, compare_super, nfs_set_super, server);
4943 if (s->s_fs_info != server) {
4944 + error = nfs_compare_mount_options(s, server, flags);
4945 nfs_free_server(server);
4948 + goto error_splat_super;
4952 @@ -772,25 +1545,164 @@ static void nfs4_fill_super(struct super_block *sb)
4953 nfs_initialise_sb(sb);
4956 -static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
4958 + * Validate NFSv4 mount options
4960 +static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
4961 + const char *dev_name,
4962 + struct sockaddr_in *addr,
4963 + rpc_authflavor_t *authflavour,
4971 - return ERR_PTR(-EINVAL);
4972 - if (src->len < maxlen)
4973 - maxlen = src->len;
4974 - if (dst == NULL) {
4975 - p = dst = kmalloc(maxlen + 1, GFP_KERNEL);
4977 - return ERR_PTR(-ENOMEM);
4979 - if (copy_from_user(dst, src->data, maxlen)) {
4981 - return ERR_PTR(-EFAULT);
4982 + struct nfs4_mount_data *data = *options;
4988 + switch (data->version) {
4990 + if (data->host_addrlen != sizeof(*addr))
4991 + goto out_no_address;
4992 + if (copy_from_user(addr, data->host_addr, sizeof(*addr)))
4994 + if (addr->sin_port == 0)
4995 + addr->sin_port = htons(NFS_PORT);
4996 + if (!nfs_verify_server_address((struct sockaddr *) addr))
4997 + goto out_no_address;
4999 + switch (data->auth_flavourlen) {
5001 + *authflavour = RPC_AUTH_UNIX;
5004 + if (copy_from_user(authflavour, data->auth_flavours,
5005 + sizeof(*authflavour)))
5009 + goto out_inval_auth;
5012 + c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
5014 + return PTR_ERR(c);
5017 + c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
5019 + return PTR_ERR(c);
5021 + dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *mntpath);
5023 + c = strndup_user(data->client_addr.data, 16);
5025 + return PTR_ERR(c);
5031 + struct nfs_parsed_mount_data args = {
5032 + .rsize = NFS_MAX_FILE_IO_SIZE,
5033 + .wsize = NFS_MAX_FILE_IO_SIZE,
5040 + .nfs_server.protocol = IPPROTO_TCP,
5043 + if (nfs_parse_mount_options((char *) *options, &args) == 0)
5046 + if (!nfs_verify_server_address((struct sockaddr *)
5047 + &args.nfs_server.address))
5049 + *addr = args.nfs_server.address;
5051 + switch (args.auth_flavor_len) {
5053 + *authflavour = RPC_AUTH_UNIX;
5056 + *authflavour = (rpc_authflavor_t) args.auth_flavors[0];
5059 + goto out_inval_auth;
5063 + * Translate to nfs4_mount_data, which nfs4_fill_super
5066 + data = kzalloc(sizeof(*data), GFP_KERNEL);
5071 + data->version = 1;
5072 + data->flags = args.flags & NFS4_MOUNT_FLAGMASK;
5073 + data->rsize = args.rsize;
5074 + data->wsize = args.wsize;
5075 + data->timeo = args.timeo;
5076 + data->retrans = args.retrans;
5077 + data->acregmin = args.acregmin;
5078 + data->acregmax = args.acregmax;
5079 + data->acdirmin = args.acdirmin;
5080 + data->acdirmax = args.acdirmax;
5081 + data->proto = args.nfs_server.protocol;
5084 + * Split "dev_name" into "hostname:mntpath".
5086 + c = strchr(dev_name, ':');
5089 + /* while calculating len, pretend ':' is '\0' */
5090 + len = c - dev_name;
5091 + if (len > NFS4_MAXNAMLEN)
5093 + *hostname = kzalloc(len, GFP_KERNEL);
5094 + if (*hostname == NULL)
5096 + strncpy(*hostname, dev_name, len - 1);
5098 + c++; /* step over the ':' */
5100 + if (len > NFS4_MAXPATHLEN)
5102 + *mntpath = kzalloc(len + 1, GFP_KERNEL);
5103 + if (*mntpath == NULL)
5105 + strncpy(*mntpath, c, len);
5107 + dprintk("MNTPATH: %s\n", *mntpath);
5109 + *ip_addr = args.client_address;
5114 - dst[maxlen] = '\0';
5120 + dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n");
5124 + dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n",
5125 + data->auth_flavourlen);
5129 + dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
5134 @@ -806,81 +1718,29 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
5135 rpc_authflavor_t authflavour;
5136 struct nfs_fh mntfh;
5137 struct dentry *mntroot;
5138 - char *mntpath = NULL, *hostname = NULL, ip_addr[16];
5140 + char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL;
5141 + int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
5144 - if (data == NULL) {
5145 - dprintk("%s: missing data argument\n", __FUNCTION__);
5148 - if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
5149 - dprintk("%s: bad mount version\n", __FUNCTION__);
5153 - /* We now require that the mount process passes the remote address */
5154 - if (data->host_addrlen != sizeof(addr))
5157 - if (copy_from_user(&addr, data->host_addr, sizeof(addr)))
5160 - if (addr.sin_family != AF_INET ||
5161 - addr.sin_addr.s_addr == INADDR_ANY
5163 - dprintk("%s: mount program didn't pass remote IP address!\n",
5167 - /* RFC3530: The default port for NFS is 2049 */
5168 - if (addr.sin_port == 0)
5169 - addr.sin_port = htons(NFS_PORT);
5171 - /* Grab the authentication type */
5172 - authflavour = RPC_AUTH_UNIX;
5173 - if (data->auth_flavourlen != 0) {
5174 - if (data->auth_flavourlen != 1) {
5175 - dprintk("%s: Invalid number of RPC auth flavours %d.\n",
5176 - __FUNCTION__, data->auth_flavourlen);
5178 - goto out_err_noserver;
5181 - if (copy_from_user(&authflavour, data->auth_flavours,
5182 - sizeof(authflavour))) {
5184 - goto out_err_noserver;
5188 - p = nfs_copy_user_string(NULL, &data->hostname, 256);
5193 - p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
5198 - dprintk("MNTPATH: %s\n", mntpath);
5200 - p = nfs_copy_user_string(ip_addr, &data->client_addr,
5201 - sizeof(ip_addr) - 1);
5204 + /* Validate the mount data */
5205 + error = nfs4_validate_mount_data(&data, dev_name, &addr, &authflavour,
5206 + &hostname, &mntpath, &ip_addr);
5210 /* Get a volume representation */
5211 server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
5212 authflavour, &mntfh);
5213 if (IS_ERR(server)) {
5214 error = PTR_ERR(server);
5215 - goto out_err_noserver;
5219 + if (server->flags & NFS4_MOUNT_UNSHARED)
5220 + compare_super = NULL;
5222 /* Get a superblock - note that we may end up sharing one that already exists */
5223 - s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
5224 + s = sget(fs_type, compare_super, nfs_set_super, server);
5228 @@ -906,25 +1766,22 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
5229 s->s_flags |= MS_ACTIVE;
5231 mnt->mnt_root = mntroot;
5241 - error = PTR_ERR(p);
5242 - goto out_err_noserver;
5246 nfs_free_server(server);
5254 up_write(&s->s_umount);
5255 deactivate_super(s);
5256 - goto out_err_noserver;
5260 static void nfs4_kill_super(struct super_block *sb)
5261 @@ -949,6 +1806,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
5262 struct super_block *s;
5263 struct nfs_server *server;
5264 struct dentry *mntroot;
5265 + int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
5268 dprintk("--> nfs4_xdev_get_sb()\n");
5269 @@ -960,8 +1818,11 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
5270 goto out_err_noserver;
5273 + if (server->flags & NFS4_MOUNT_UNSHARED)
5274 + compare_super = NULL;
5276 /* Get a superblock - note that we may end up sharing one that already exists */
5277 - s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
5278 + s = sget(&nfs_fs_type, compare_super, nfs_set_super, server);
5282 @@ -1016,6 +1877,7 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
5283 struct nfs_server *server;
5284 struct dentry *mntroot;
5285 struct nfs_fh mntfh;
5286 + int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
5289 dprintk("--> nfs4_referral_get_sb()\n");
5290 @@ -1027,8 +1889,11 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
5291 goto out_err_noserver;
5294 + if (server->flags & NFS4_MOUNT_UNSHARED)
5295 + compare_super = NULL;
5297 /* Get a superblock - note that we may end up sharing one that already exists */
5298 - s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
5299 + s = sget(&nfs_fs_type, compare_super, nfs_set_super, server);
5303 diff --git a/fs/nfs/write.c b/fs/nfs/write.c
5304 index af344a1..73ac992 100644
5305 --- a/fs/nfs/write.c
5306 +++ b/fs/nfs/write.c
5307 @@ -117,19 +117,19 @@ static struct nfs_page *nfs_page_find_request_locked(struct page *page)
5308 if (PagePrivate(page)) {
5309 req = (struct nfs_page *)page_private(page);
5311 - atomic_inc(&req->wb_count);
5312 + kref_get(&req->wb_kref);
5317 static struct nfs_page *nfs_page_find_request(struct page *page)
5319 + struct inode *inode = page->mapping->host;
5320 struct nfs_page *req = NULL;
5321 - spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
5323 - spin_lock(req_lock);
5324 + spin_lock(&inode->i_lock);
5325 req = nfs_page_find_request_locked(page);
5326 - spin_unlock(req_lock);
5327 + spin_unlock(&inode->i_lock);
5331 @@ -191,8 +191,6 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
5333 /* Update file length */
5334 nfs_grow_file(page, offset, count);
5335 - /* Set the PG_uptodate flag? */
5336 - nfs_mark_uptodate(page, offset, count);
5337 nfs_unlock_request(req);
5340 @@ -253,16 +251,16 @@ static void nfs_end_page_writeback(struct page *page)
5341 static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
5344 + struct inode *inode = page->mapping->host;
5345 + struct nfs_inode *nfsi = NFS_I(inode);
5346 struct nfs_page *req;
5347 - struct nfs_inode *nfsi = NFS_I(page->mapping->host);
5348 - spinlock_t *req_lock = &nfsi->req_lock;
5351 - spin_lock(req_lock);
5352 + spin_lock(&inode->i_lock);
5354 req = nfs_page_find_request_locked(page);
5356 - spin_unlock(req_lock);
5357 + spin_unlock(&inode->i_lock);
5360 if (nfs_lock_request_dontget(req))
5361 @@ -272,28 +270,28 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
5362 * succeed provided that someone hasn't already marked the
5363 * request as dirty (in which case we don't care).
5365 - spin_unlock(req_lock);
5366 + spin_unlock(&inode->i_lock);
5367 ret = nfs_wait_on_request(req);
5368 nfs_release_request(req);
5371 - spin_lock(req_lock);
5372 + spin_lock(&inode->i_lock);
5374 if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
5375 /* This request is marked for commit */
5376 - spin_unlock(req_lock);
5377 + spin_unlock(&inode->i_lock);
5378 nfs_unlock_request(req);
5379 nfs_pageio_complete(pgio);
5382 if (nfs_set_page_writeback(page) != 0) {
5383 - spin_unlock(req_lock);
5384 + spin_unlock(&inode->i_lock);
5387 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index,
5388 - NFS_PAGE_TAG_WRITEBACK);
5389 + NFS_PAGE_TAG_LOCKED);
5390 ret = test_bit(PG_NEED_FLUSH, &req->wb_flags);
5391 - spin_unlock(req_lock);
5392 + spin_unlock(&inode->i_lock);
5393 nfs_pageio_add_request(pgio, req);
5396 @@ -400,7 +398,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
5397 if (PageDirty(req->wb_page))
5398 set_bit(PG_NEED_FLUSH, &req->wb_flags);
5400 - atomic_inc(&req->wb_count);
5401 + kref_get(&req->wb_kref);
5405 @@ -409,12 +407,12 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
5407 static void nfs_inode_remove_request(struct nfs_page *req)
5409 - struct inode *inode = req->wb_context->dentry->d_inode;
5410 + struct inode *inode = req->wb_context->path.dentry->d_inode;
5411 struct nfs_inode *nfsi = NFS_I(inode);
5413 BUG_ON (!NFS_WBACK_BUSY(req));
5415 - spin_lock(&nfsi->req_lock);
5416 + spin_lock(&inode->i_lock);
5417 set_page_private(req->wb_page, 0);
5418 ClearPagePrivate(req->wb_page);
5419 radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
5420 @@ -422,11 +420,11 @@ static void nfs_inode_remove_request(struct nfs_page *req)
5421 __set_page_dirty_nobuffers(req->wb_page);
5423 if (!nfsi->npages) {
5424 - spin_unlock(&nfsi->req_lock);
5425 + spin_unlock(&inode->i_lock);
5426 nfs_end_data_update(inode);
5429 - spin_unlock(&nfsi->req_lock);
5430 + spin_unlock(&inode->i_lock);
5431 nfs_clear_request(req);
5432 nfs_release_request(req);
5434 @@ -457,14 +455,16 @@ nfs_dirty_request(struct nfs_page *req)
5436 nfs_mark_request_commit(struct nfs_page *req)
5438 - struct inode *inode = req->wb_context->dentry->d_inode;
5439 + struct inode *inode = req->wb_context->path.dentry->d_inode;
5440 struct nfs_inode *nfsi = NFS_I(inode);
5442 - spin_lock(&nfsi->req_lock);
5443 - nfs_list_add_request(req, &nfsi->commit);
5444 + spin_lock(&inode->i_lock);
5446 set_bit(PG_NEED_COMMIT, &(req)->wb_flags);
5447 - spin_unlock(&nfsi->req_lock);
5448 + radix_tree_tag_set(&nfsi->nfs_page_tree,
5450 + NFS_PAGE_TAG_COMMIT);
5451 + spin_unlock(&inode->i_lock);
5452 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
5453 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
5455 @@ -526,18 +526,18 @@ static int nfs_wait_on_requests_locked(struct inode *inode, pgoff_t idx_start, u
5456 idx_end = idx_start + npages - 1;
5459 - while (radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, (void **)&req, next, 1, NFS_PAGE_TAG_WRITEBACK)) {
5460 + while (radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, (void **)&req, next, 1, NFS_PAGE_TAG_LOCKED)) {
5461 if (req->wb_index > idx_end)
5464 next = req->wb_index + 1;
5465 BUG_ON(!NFS_WBACK_BUSY(req));
5467 - atomic_inc(&req->wb_count);
5468 - spin_unlock(&nfsi->req_lock);
5469 + kref_get(&req->wb_kref);
5470 + spin_unlock(&inode->i_lock);
5471 error = nfs_wait_on_request(req);
5472 nfs_release_request(req);
5473 - spin_lock(&nfsi->req_lock);
5474 + spin_lock(&inode->i_lock);
5478 @@ -577,10 +577,9 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, u
5481 if (nfsi->ncommit != 0) {
5482 - res = nfs_scan_list(nfsi, &nfsi->commit, dst, idx_start, npages);
5483 + res = nfs_scan_list(nfsi, dst, idx_start, npages,
5484 + NFS_PAGE_TAG_COMMIT);
5485 nfsi->ncommit -= res;
5486 - if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit))
5487 - printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n");
5491 @@ -603,7 +602,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
5493 struct address_space *mapping = page->mapping;
5494 struct inode *inode = mapping->host;
5495 - struct nfs_inode *nfsi = NFS_I(inode);
5496 struct nfs_page *req, *new = NULL;
5499 @@ -613,13 +611,13 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
5500 /* Loop over all inode entries and see if we find
5501 * A request for the page we wish to update
5503 - spin_lock(&nfsi->req_lock);
5504 + spin_lock(&inode->i_lock);
5505 req = nfs_page_find_request_locked(page);
5507 if (!nfs_lock_request_dontget(req)) {
5510 - spin_unlock(&nfsi->req_lock);
5511 + spin_unlock(&inode->i_lock);
5512 error = nfs_wait_on_request(req);
5513 nfs_release_request(req);
5515 @@ -629,7 +627,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
5519 - spin_unlock(&nfsi->req_lock);
5520 + spin_unlock(&inode->i_lock);
5522 nfs_release_request(new);
5524 @@ -640,14 +638,14 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
5525 nfs_lock_request_dontget(new);
5526 error = nfs_inode_add_request(inode, new);
5528 - spin_unlock(&nfsi->req_lock);
5529 + spin_unlock(&inode->i_lock);
5530 nfs_unlock_request(new);
5531 return ERR_PTR(error);
5533 - spin_unlock(&nfsi->req_lock);
5534 + spin_unlock(&inode->i_lock);
5537 - spin_unlock(&nfsi->req_lock);
5538 + spin_unlock(&inode->i_lock);
5540 new = nfs_create_request(ctx, inode, page, offset, bytes);
5542 @@ -751,12 +749,17 @@ int nfs_updatepage(struct file *file, struct page *page,
5543 static void nfs_writepage_release(struct nfs_page *req)
5546 - if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
5547 + if (PageError(req->wb_page)) {
5548 + nfs_end_page_writeback(req->wb_page);
5549 + nfs_inode_remove_request(req);
5550 + } else if (!nfs_reschedule_unstable_write(req)) {
5551 + /* Set the PG_uptodate flag */
5552 + nfs_mark_uptodate(req->wb_page, req->wb_pgbase, req->wb_bytes);
5553 nfs_end_page_writeback(req->wb_page);
5554 nfs_inode_remove_request(req);
5556 nfs_end_page_writeback(req->wb_page);
5557 - nfs_clear_page_writeback(req);
5558 + nfs_clear_page_tag_locked(req);
5561 static inline int flush_task_priority(int how)
5562 @@ -786,7 +789,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
5563 * NB: take care not to mess about with data->commit et al. */
5566 - data->inode = inode = req->wb_context->dentry->d_inode;
5567 + data->inode = inode = req->wb_context->path.dentry->d_inode;
5568 data->cred = req->wb_context->cred;
5570 data->args.fh = NFS_FH(inode);
5571 @@ -885,7 +888,7 @@ out_bad:
5573 nfs_redirty_request(req);
5574 nfs_end_page_writeback(req->wb_page);
5575 - nfs_clear_page_writeback(req);
5576 + nfs_clear_page_tag_locked(req);
5580 @@ -928,7 +931,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
5581 nfs_list_remove_request(req);
5582 nfs_redirty_request(req);
5583 nfs_end_page_writeback(req->wb_page);
5584 - nfs_clear_page_writeback(req);
5585 + nfs_clear_page_tag_locked(req);
5589 @@ -954,8 +957,8 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
5590 struct page *page = req->wb_page;
5592 dprintk("NFS: write (%s/%Ld %d@%Ld)",
5593 - req->wb_context->dentry->d_inode->i_sb->s_id,
5594 - (long long)NFS_FILEID(req->wb_context->dentry->d_inode),
5595 + req->wb_context->path.dentry->d_inode->i_sb->s_id,
5596 + (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
5598 (long long)req_offset(req));
5600 @@ -970,9 +973,9 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
5603 if (nfs_write_need_commit(data)) {
5604 - spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
5605 + struct inode *inode = page->mapping->host;
5607 - spin_lock(req_lock);
5608 + spin_lock(&inode->i_lock);
5609 if (test_bit(PG_NEED_RESCHED, &req->wb_flags)) {
5610 /* Do nothing we need to resend the writes */
5611 } else if (!test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) {
5612 @@ -983,7 +986,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
5613 clear_bit(PG_NEED_COMMIT, &req->wb_flags);
5614 dprintk(" server reboot detected\n");
5616 - spin_unlock(req_lock);
5617 + spin_unlock(&inode->i_lock);
5621 @@ -1020,8 +1023,8 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
5622 page = req->wb_page;
5624 dprintk("NFS: write (%s/%Ld %d@%Ld)",
5625 - req->wb_context->dentry->d_inode->i_sb->s_id,
5626 - (long long)NFS_FILEID(req->wb_context->dentry->d_inode),
5627 + req->wb_context->path.dentry->d_inode->i_sb->s_id,
5628 + (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
5630 (long long)req_offset(req));
5632 @@ -1039,12 +1042,14 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
5633 dprintk(" marked for commit\n");
5636 + /* Set the PG_uptodate flag? */
5637 + nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
5640 nfs_end_page_writeback(page);
5641 nfs_inode_remove_request(req);
5643 - nfs_clear_page_writeback(req);
5644 + nfs_clear_page_tag_locked(req);
5648 @@ -1157,7 +1162,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
5650 list_splice_init(head, &data->pages);
5651 first = nfs_list_entry(data->pages.next);
5652 - inode = first->wb_context->dentry->d_inode;
5653 + inode = first->wb_context->path.dentry->d_inode;
5655 data->inode = inode;
5656 data->cred = first->wb_context->cred;
5657 @@ -1207,7 +1212,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
5658 nfs_list_remove_request(req);
5659 nfs_mark_request_commit(req);
5660 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
5661 - nfs_clear_page_writeback(req);
5662 + nfs_clear_page_tag_locked(req);
5666 @@ -1234,8 +1239,8 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
5667 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
5669 dprintk("NFS: commit (%s/%Ld %d@%Ld)",
5670 - req->wb_context->dentry->d_inode->i_sb->s_id,
5671 - (long long)NFS_FILEID(req->wb_context->dentry->d_inode),
5672 + req->wb_context->path.dentry->d_inode->i_sb->s_id,
5673 + (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
5675 (long long)req_offset(req));
5676 if (task->tk_status < 0) {
5677 @@ -1249,6 +1254,9 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
5678 * returned by the server against all stored verfs. */
5679 if (!memcmp(req->wb_verf.verifier, data->verf.verifier, sizeof(data->verf.verifier))) {
5680 /* We have a match */
5681 + /* Set the PG_uptodate flag */
5682 + nfs_mark_uptodate(req->wb_page, req->wb_pgbase,
5684 nfs_inode_remove_request(req);
5687 @@ -1257,7 +1265,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
5688 dprintk(" mismatch\n");
5689 nfs_redirty_request(req);
5691 - nfs_clear_page_writeback(req);
5692 + nfs_clear_page_tag_locked(req);
5696 @@ -1268,13 +1276,12 @@ static const struct rpc_call_ops nfs_commit_ops = {
5698 int nfs_commit_inode(struct inode *inode, int how)
5700 - struct nfs_inode *nfsi = NFS_I(inode);
5704 - spin_lock(&nfsi->req_lock);
5705 + spin_lock(&inode->i_lock);
5706 res = nfs_scan_commit(inode, &head, 0, 0);
5707 - spin_unlock(&nfsi->req_lock);
5708 + spin_unlock(&inode->i_lock);
5710 int error = nfs_commit_list(inode, &head, how);
5712 @@ -1292,7 +1299,6 @@ static inline int nfs_commit_list(struct inode *inode, struct list_head *head, i
5713 long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how)
5715 struct inode *inode = mapping->host;
5716 - struct nfs_inode *nfsi = NFS_I(inode);
5717 pgoff_t idx_start, idx_end;
5718 unsigned int npages = 0;
5720 @@ -1314,7 +1320,7 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
5723 how &= ~FLUSH_NOCOMMIT;
5724 - spin_lock(&nfsi->req_lock);
5725 + spin_lock(&inode->i_lock);
5727 ret = nfs_wait_on_requests_locked(inode, idx_start, npages);
5729 @@ -1325,18 +1331,19 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
5732 if (how & FLUSH_INVALIDATE) {
5733 - spin_unlock(&nfsi->req_lock);
5734 + spin_unlock(&inode->i_lock);
5735 nfs_cancel_commit_list(&head);
5737 - spin_lock(&nfsi->req_lock);
5738 + spin_lock(&inode->i_lock);
5741 pages += nfs_scan_commit(inode, &head, 0, 0);
5742 - spin_unlock(&nfsi->req_lock);
5743 + spin_unlock(&inode->i_lock);
5744 ret = nfs_commit_list(inode, &head, how);
5745 - spin_lock(&nfsi->req_lock);
5746 + spin_lock(&inode->i_lock);
5749 - spin_unlock(&nfsi->req_lock);
5750 + spin_unlock(&inode->i_lock);
5754 @@ -1430,7 +1437,6 @@ int nfs_set_page_dirty(struct page *page)
5756 struct address_space *mapping = page->mapping;
5757 struct inode *inode;
5758 - spinlock_t *req_lock;
5759 struct nfs_page *req;
5762 @@ -1439,18 +1445,17 @@ int nfs_set_page_dirty(struct page *page)
5763 inode = mapping->host;
5766 - req_lock = &NFS_I(inode)->req_lock;
5767 - spin_lock(req_lock);
5768 + spin_lock(&inode->i_lock);
5769 req = nfs_page_find_request_locked(page);
5771 /* Mark any existing write requests for flushing */
5772 ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags);
5773 - spin_unlock(req_lock);
5774 + spin_unlock(&inode->i_lock);
5775 nfs_release_request(req);
5778 ret = __set_page_dirty_nobuffers(page);
5779 - spin_unlock(req_lock);
5780 + spin_unlock(&inode->i_lock);
5783 return !TestSetPageDirty(page);
5784 diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
5785 index 864090e..5443c52 100644
5786 --- a/fs/nfsd/nfs4callback.c
5787 +++ b/fs/nfsd/nfs4callback.c
5788 @@ -394,7 +394,6 @@ nfsd4_probe_callback(struct nfs4_client *clp)
5789 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
5792 - char clientname[16];
5795 if (atomic_read(&cb->cb_set))
5796 @@ -417,11 +416,6 @@ nfsd4_probe_callback(struct nfs4_client *clp)
5797 memset(program->stats, 0, sizeof(cb->cb_stat));
5798 program->stats->program = program;
5800 - /* Just here to make some printk's more useful: */
5801 - snprintf(clientname, sizeof(clientname),
5802 - "%u.%u.%u.%u", NIPQUAD(addr.sin_addr));
5803 - args.servername = clientname;
5805 /* Create RPC client */
5806 cb->cb_client = rpc_create(&args);
5807 if (IS_ERR(cb->cb_client)) {
5808 @@ -429,29 +423,23 @@ nfsd4_probe_callback(struct nfs4_client *clp)
5812 - /* Kick rpciod, put the call on the wire. */
5813 - if (rpciod_up() != 0)
5816 /* the task holds a reference to the nfs4_client struct */
5817 atomic_inc(&clp->cl_count);
5819 msg.rpc_cred = nfsd4_lookupcred(clp,0);
5820 if (IS_ERR(msg.rpc_cred))
5822 + goto out_release_clp;
5823 status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL);
5824 put_rpccred(msg.rpc_cred);
5827 dprintk("NFSD: asynchronous NFSPROC4_CB_NULL failed!\n");
5829 + goto out_release_clp;
5835 atomic_dec(&clp->cl_count);
5838 rpc_shutdown_client(cb->cb_client);
5840 cb->cb_client = NULL;
5841 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
5842 index 3cc8ce4..8c52913 100644
5843 --- a/fs/nfsd/nfs4state.c
5844 +++ b/fs/nfsd/nfs4state.c
5845 @@ -378,7 +378,6 @@ shutdown_callback_client(struct nfs4_client *clp)
5847 clp->cl_callback.cb_client = NULL;
5848 rpc_shutdown_client(clnt);
5853 diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
5854 index 05707e2..e2d1ce3 100644
5855 --- a/include/linux/lockd/lockd.h
5856 +++ b/include/linux/lockd/lockd.h
5859 struct hlist_node h_hash; /* doubly linked list */
5860 struct sockaddr_in h_addr; /* peer address */
5861 + struct sockaddr_in h_saddr; /* our address (optional) */
5862 struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */
5863 char * h_name; /* remote hostname */
5864 u32 h_version; /* interface version */
5865 diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
5866 index 7e7f33a..8726491 100644
5867 --- a/include/linux/nfs4.h
5868 +++ b/include/linux/nfs4.h
5871 #include <linux/types.h>
5873 +#define NFS4_BITMAP_SIZE 2
5874 #define NFS4_VERIFIER_SIZE 8
5875 #define NFS4_STATEID_SIZE 16
5876 #define NFS4_FHSIZE 128
5877 diff --git a/include/linux/nfs4_mount.h b/include/linux/nfs4_mount.h
5878 index 26b4c83..a0dcf66 100644
5879 --- a/include/linux/nfs4_mount.h
5880 +++ b/include/linux/nfs4_mount.h
5881 @@ -65,6 +65,7 @@ struct nfs4_mount_data {
5882 #define NFS4_MOUNT_NOCTO 0x0010 /* 1 */
5883 #define NFS4_MOUNT_NOAC 0x0020 /* 1 */
5884 #define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */
5885 -#define NFS4_MOUNT_FLAGMASK 0xFFFF
5886 +#define NFS4_MOUNT_UNSHARED 0x8000 /* 1 */
5887 +#define NFS4_MOUNT_FLAGMASK 0x9033
5890 diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
5891 index 0543439..c098ae1 100644
5892 --- a/include/linux/nfs_fs.h
5893 +++ b/include/linux/nfs_fs.h
5897 #include <linux/in.h>
5898 +#include <linux/kref.h>
5899 #include <linux/mm.h>
5900 +#include <linux/namei.h>
5901 #include <linux/pagemap.h>
5902 #include <linux/rbtree.h>
5903 #include <linux/rwsem.h>
5904 @@ -69,9 +71,8 @@ struct nfs_access_entry {
5907 struct nfs_open_context {
5909 - struct vfsmount *vfsmnt;
5910 - struct dentry *dentry;
5913 struct rpc_cred *cred;
5914 struct nfs4_state *state;
5915 fl_owner_t lockowner;
5916 @@ -155,13 +156,9 @@ struct nfs_inode {
5918 * This is the list of dirty unwritten pages.
5920 - spinlock_t req_lock;
5921 - struct list_head dirty;
5922 - struct list_head commit;
5923 struct radix_tree_root nfs_page_tree;
5925 - unsigned int ndirty,
5927 + unsigned long ncommit,
5930 /* Open contexts for shared mmap writes */
5931 @@ -187,6 +184,7 @@ struct nfs_inode {
5932 #define NFS_INO_INVALID_ACCESS 0x0008 /* cached access cred invalid */
5933 #define NFS_INO_INVALID_ACL 0x0010 /* cached acls are invalid */
5934 #define NFS_INO_REVAL_PAGECACHE 0x0020 /* must revalidate pagecache */
5935 +#define NFS_INO_REVAL_FORCED 0x0040 /* force revalidation ignoring a delegation */
5938 * Bit offsets in flags field
5939 @@ -496,21 +494,18 @@ static inline void nfs3_forget_cached_acls(struct inode *inode)
5942 * linux/fs/mount_clnt.c
5943 - * (Used only by nfsroot module)
5945 -extern int nfsroot_mount(struct sockaddr_in *, char *, struct nfs_fh *,
5947 +extern int nfs_mount(struct sockaddr *, size_t, char *, char *,
5948 + int, int, struct nfs_fh *);
5954 -static inline loff_t
5955 -nfs_size_to_loff_t(__u64 size)
5956 +static inline loff_t nfs_size_to_loff_t(__u64 size)
5958 - loff_t maxsz = (((loff_t) ULONG_MAX) << PAGE_CACHE_SHIFT) + PAGE_CACHE_SIZE - 1;
5961 + if (size > (__u64) OFFSET_MAX - 1)
5962 + return OFFSET_MAX - 1;
5963 return (loff_t) size;
5966 @@ -557,6 +552,7 @@ extern void * nfs_root_data(void);
5967 #define NFSDBG_ROOT 0x0080
5968 #define NFSDBG_CALLBACK 0x0100
5969 #define NFSDBG_CLIENT 0x0200
5970 +#define NFSDBG_MOUNT 0x0400
5971 #define NFSDBG_ALL 0xFFFF
5974 diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
5975 index 52b4378..0cac49b 100644
5976 --- a/include/linux/nfs_fs_sb.h
5977 +++ b/include/linux/nfs_fs_sb.h
5978 @@ -16,7 +16,6 @@ struct nfs_client {
5979 #define NFS_CS_INITING 1 /* busy initialising */
5980 int cl_nfsversion; /* NFS protocol version */
5981 unsigned long cl_res_state; /* NFS resources state */
5982 -#define NFS_CS_RPCIOD 0 /* - rpciod started */
5983 #define NFS_CS_CALLBACK 1 /* - callback started */
5984 #define NFS_CS_IDMAP 2 /* - idmap started */
5985 #define NFS_CS_RENEWD 3 /* - renewd started */
5986 @@ -35,7 +34,8 @@ struct nfs_client {
5987 nfs4_verifier cl_confirm;
5988 unsigned long cl_state;
5990 - u32 cl_lockowner_id;
5991 + struct rb_root cl_openowner_id;
5992 + struct rb_root cl_lockowner_id;
5995 * The following rwsem ensures exclusive access to the server
5996 @@ -44,9 +44,7 @@ struct nfs_client {
5997 struct rw_semaphore cl_sem;
5999 struct list_head cl_delegations;
6000 - struct list_head cl_state_owners;
6001 - struct list_head cl_unused;
6003 + struct rb_root cl_state_owners;
6006 unsigned long cl_lease_time;
6007 diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
6008 index cc8b9c5..a3ade89 100644
6009 --- a/include/linux/nfs_mount.h
6010 +++ b/include/linux/nfs_mount.h
6011 @@ -37,7 +37,7 @@ struct nfs_mount_data {
6012 int acdirmin; /* 1 */
6013 int acdirmax; /* 1 */
6014 struct sockaddr_in addr; /* 1 */
6015 - char hostname[256]; /* 1 */
6016 + char hostname[NFS_MAXNAMLEN + 1]; /* 1 */
6018 unsigned int bsize; /* 3 */
6019 struct nfs3_fh root; /* 4 */
6020 @@ -62,6 +62,7 @@ struct nfs_mount_data {
6021 #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */
6022 #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
6023 #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
6024 +#define NFS_MOUNT_UNSHARED 0x8000 /* 5 */
6025 #define NFS_MOUNT_FLAGMASK 0xFFFF
6028 diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
6029 index bd193af..78e6079 100644
6030 --- a/include/linux/nfs_page.h
6031 +++ b/include/linux/nfs_page.h
6033 #include <linux/sunrpc/auth.h>
6034 #include <linux/nfs_xdr.h>
6036 -#include <asm/atomic.h>
6037 +#include <linux/kref.h>
6040 * Valid flags for the radix tree
6042 -#define NFS_PAGE_TAG_WRITEBACK 0
6043 +#define NFS_PAGE_TAG_LOCKED 0
6044 +#define NFS_PAGE_TAG_COMMIT 1
6047 * Valid flags for a dirty buffer
6052 - struct list_head wb_list, /* Defines state of page: */
6053 - *wb_list_head; /* read/write/commit */
6054 + struct list_head wb_list; /* Defines state of page: */
6055 struct page *wb_page; /* page to read in/write out */
6056 struct nfs_open_context *wb_context; /* File state context info */
6057 atomic_t wb_complete; /* i/os we're waiting for */
6058 @@ -42,7 +42,7 @@ struct nfs_page {
6059 unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */
6060 wb_pgbase, /* Start of page data */
6061 wb_bytes; /* Length of request */
6062 - atomic_t wb_count; /* reference count */
6063 + struct kref wb_kref; /* reference count */
6064 unsigned long wb_flags;
6065 struct nfs_writeverf wb_verf; /* Commit cookie */
6067 @@ -71,8 +71,8 @@ extern void nfs_clear_request(struct nfs_page *req);
6068 extern void nfs_release_request(struct nfs_page *req);
6071 -extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head, struct list_head *dst,
6072 - pgoff_t idx_start, unsigned int npages);
6073 +extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *dst,
6074 + pgoff_t idx_start, unsigned int npages, int tag);
6075 extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
6076 struct inode *inode,
6077 int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int),
6078 @@ -84,12 +84,11 @@ extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
6079 extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
6080 extern int nfs_wait_on_request(struct nfs_page *);
6081 extern void nfs_unlock_request(struct nfs_page *req);
6082 -extern int nfs_set_page_writeback_locked(struct nfs_page *req);
6083 -extern void nfs_clear_page_writeback(struct nfs_page *req);
6084 +extern void nfs_clear_page_tag_locked(struct nfs_page *req);
6088 - * Lock the page of an asynchronous request without incrementing the wb_count
6089 + * Lock the page of an asynchronous request without getting a new reference
6092 nfs_lock_request_dontget(struct nfs_page *req)
6093 @@ -98,14 +97,14 @@ nfs_lock_request_dontget(struct nfs_page *req)
6097 - * Lock the page of an asynchronous request
6098 + * Lock the page of an asynchronous request and take a reference
6101 nfs_lock_request(struct nfs_page *req)
6103 if (test_and_set_bit(PG_BUSY, &req->wb_flags))
6105 - atomic_inc(&req->wb_count);
6106 + kref_get(&req->wb_kref);
6110 @@ -118,7 +117,6 @@ static inline void
6111 nfs_list_add_request(struct nfs_page *req, struct list_head *head)
6113 list_add_tail(&req->wb_list, head);
6114 - req->wb_list_head = head;
6118 @@ -132,7 +130,6 @@ nfs_list_remove_request(struct nfs_page *req)
6119 if (list_empty(&req->wb_list))
6121 list_del_init(&req->wb_list);
6122 - req->wb_list_head = NULL;
6125 static inline struct nfs_page *
6126 diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
6127 index 10c26ed..38d7768 100644
6128 --- a/include/linux/nfs_xdr.h
6129 +++ b/include/linux/nfs_xdr.h
6130 @@ -119,7 +119,7 @@ struct nfs_openargs {
6131 struct nfs_seqid * seqid;
6137 struct iattr * attrs; /* UNCHECKED, GUARDED */
6138 nfs4_verifier verifier; /* EXCLUSIVE */
6139 @@ -144,6 +144,7 @@ struct nfs_openres {
6140 nfs4_stateid delegation;
6143 + __u32 attrset[NFS4_BITMAP_SIZE];
6147 @@ -180,7 +181,7 @@ struct nfs_closeres {
6155 struct nfs_lock_args {
6156 diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
6157 index 534cdc7..7a69ca3 100644
6158 --- a/include/linux/sunrpc/auth.h
6159 +++ b/include/linux/sunrpc/auth.h
6161 #include <linux/sunrpc/xdr.h>
6163 #include <asm/atomic.h>
6164 +#include <linux/rcupdate.h>
6166 /* size of the nodename buffer */
6167 #define UNX_MAXNODENAME 32
6168 @@ -30,22 +31,28 @@ struct auth_cred {
6170 * Client user credentials
6173 +struct rpc_credops;
6175 struct hlist_node cr_hash; /* hash chain */
6176 - struct rpc_credops * cr_ops;
6177 - unsigned long cr_expire; /* when to gc */
6178 - atomic_t cr_count; /* ref count */
6179 - unsigned short cr_flags; /* various flags */
6180 + struct list_head cr_lru; /* lru garbage collection */
6181 + struct rcu_head cr_rcu;
6182 + struct rpc_auth * cr_auth;
6183 + const struct rpc_credops *cr_ops;
6185 unsigned long cr_magic; /* 0x0f4aa4f0 */
6187 + unsigned long cr_expire; /* when to gc */
6188 + unsigned long cr_flags; /* various flags */
6189 + atomic_t cr_count; /* ref count */
6193 /* per-flavor data */
6195 -#define RPCAUTH_CRED_NEW 0x0001
6196 -#define RPCAUTH_CRED_UPTODATE 0x0002
6197 +#define RPCAUTH_CRED_NEW 0
6198 +#define RPCAUTH_CRED_UPTODATE 1
6199 +#define RPCAUTH_CRED_HASHED 2
6201 #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0
6203 @@ -56,10 +63,10 @@ struct rpc_cred {
6204 #define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1)
6205 struct rpc_cred_cache {
6206 struct hlist_head hashtable[RPC_CREDCACHE_NR];
6207 - unsigned long nextgc; /* next garbage collection */
6208 - unsigned long expire; /* cache expiry interval */
6212 +struct rpc_authops;
6214 unsigned int au_cslack; /* call cred size estimate */
6215 /* guess at number of u32's auth adds before
6216 @@ -69,7 +76,7 @@ struct rpc_auth {
6217 unsigned int au_verfsize;
6219 unsigned int au_flags; /* various flags */
6220 - struct rpc_authops * au_ops; /* operations */
6221 + const struct rpc_authops *au_ops; /* operations */
6222 rpc_authflavor_t au_flavor; /* pseudoflavor (note may
6223 * differ from the flavor in
6224 * au_ops->au_flavor in gss
6225 @@ -115,17 +122,19 @@ struct rpc_credops {
6226 void *, __be32 *, void *);
6229 -extern struct rpc_authops authunix_ops;
6230 -extern struct rpc_authops authnull_ops;
6231 -#ifdef CONFIG_SUNRPC_SECURE
6232 -extern struct rpc_authops authdes_ops;
6234 +extern const struct rpc_authops authunix_ops;
6235 +extern const struct rpc_authops authnull_ops;
6237 +void __init rpc_init_authunix(void);
6238 +void __init rpcauth_init_module(void);
6239 +void __exit rpcauth_remove_module(void);
6241 -int rpcauth_register(struct rpc_authops *);
6242 -int rpcauth_unregister(struct rpc_authops *);
6243 +int rpcauth_register(const struct rpc_authops *);
6244 +int rpcauth_unregister(const struct rpc_authops *);
6245 struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
6246 -void rpcauth_destroy(struct rpc_auth *);
6247 +void rpcauth_release(struct rpc_auth *);
6248 struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
6249 +void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
6250 struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
6251 struct rpc_cred * rpcauth_bindcred(struct rpc_task *);
6252 void rpcauth_holdcred(struct rpc_task *);
6253 @@ -138,8 +147,9 @@ int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
6254 int rpcauth_refreshcred(struct rpc_task *);
6255 void rpcauth_invalcred(struct rpc_task *);
6256 int rpcauth_uptodatecred(struct rpc_task *);
6257 -int rpcauth_init_credcache(struct rpc_auth *, unsigned long);
6258 -void rpcauth_free_credcache(struct rpc_auth *);
6259 +int rpcauth_init_credcache(struct rpc_auth *);
6260 +void rpcauth_destroy_credcache(struct rpc_auth *);
6261 +void rpcauth_clear_credcache(struct rpc_cred_cache *);
6264 struct rpc_cred * get_rpccred(struct rpc_cred *cred)
6265 diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
6266 index 2db2fbf..67658e1 100644
6267 --- a/include/linux/sunrpc/auth_gss.h
6268 +++ b/include/linux/sunrpc/auth_gss.h
6269 @@ -75,6 +75,7 @@ struct gss_cl_ctx {
6270 struct xdr_netobj gc_wire_ctx;
6272 unsigned long gc_expiry;
6273 + struct rcu_head gc_rcu;
6276 struct gss_upcall_msg;
6277 @@ -85,11 +86,6 @@ struct gss_cred {
6278 struct gss_upcall_msg *gc_upcall;
6281 -#define gc_uid gc_base.cr_uid
6282 -#define gc_count gc_base.cr_count
6283 -#define gc_flags gc_base.cr_flags
6284 -#define gc_expire gc_base.cr_expire
6286 #endif /* __KERNEL__ */
6287 #endif /* _LINUX_SUNRPC_AUTH_GSS_H */
6289 diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
6290 index 6661142..c0d9d14 100644
6291 --- a/include/linux/sunrpc/clnt.h
6292 +++ b/include/linux/sunrpc/clnt.h
6293 @@ -24,8 +24,10 @@ struct rpc_inode;
6294 * The high-level client handle
6297 - atomic_t cl_count; /* Number of clones */
6298 - atomic_t cl_users; /* number of references */
6299 + struct kref cl_kref; /* Number of references */
6300 + struct list_head cl_clients; /* Global list of clients */
6301 + struct list_head cl_tasks; /* List of tasks */
6302 + spinlock_t cl_lock; /* spinlock */
6303 struct rpc_xprt * cl_xprt; /* transport */
6304 struct rpc_procinfo * cl_procinfo; /* procedure info */
6305 u32 cl_prog, /* RPC program number */
6306 @@ -41,9 +43,7 @@ struct rpc_clnt {
6307 unsigned int cl_softrtry : 1,/* soft timeouts */
6308 cl_intr : 1,/* interruptible */
6309 cl_discrtry : 1,/* disconnect before retry */
6310 - cl_autobind : 1,/* use getport() */
6311 - cl_oneshot : 1,/* dispose after use */
6312 - cl_dead : 1;/* abandoned */
6313 + cl_autobind : 1;/* use getport() */
6315 struct rpc_rtt * cl_rtt; /* RTO estimator data */
6317 @@ -98,6 +98,7 @@ struct rpc_create_args {
6319 struct sockaddr *address;
6321 + struct sockaddr *saddress;
6322 struct rpc_timeout *timeout;
6324 struct rpc_program *program;
6325 @@ -110,20 +111,20 @@ struct rpc_create_args {
6326 #define RPC_CLNT_CREATE_HARDRTRY (1UL << 0)
6327 #define RPC_CLNT_CREATE_INTR (1UL << 1)
6328 #define RPC_CLNT_CREATE_AUTOBIND (1UL << 2)
6329 -#define RPC_CLNT_CREATE_ONESHOT (1UL << 3)
6330 -#define RPC_CLNT_CREATE_NONPRIVPORT (1UL << 4)
6331 -#define RPC_CLNT_CREATE_NOPING (1UL << 5)
6332 -#define RPC_CLNT_CREATE_DISCRTRY (1UL << 6)
6333 +#define RPC_CLNT_CREATE_NONPRIVPORT (1UL << 3)
6334 +#define RPC_CLNT_CREATE_NOPING (1UL << 4)
6335 +#define RPC_CLNT_CREATE_DISCRTRY (1UL << 5)
6337 struct rpc_clnt *rpc_create(struct rpc_create_args *args);
6338 struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
6339 struct rpc_program *, int);
6340 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
6341 -int rpc_shutdown_client(struct rpc_clnt *);
6342 -int rpc_destroy_client(struct rpc_clnt *);
6343 +void rpc_shutdown_client(struct rpc_clnt *);
6344 void rpc_release_client(struct rpc_clnt *);
6346 int rpcb_register(u32, u32, int, unsigned short, int *);
6347 -void rpcb_getport(struct rpc_task *);
6348 +int rpcb_getport_sync(struct sockaddr_in *, __u32, __u32, int);
6349 +void rpcb_getport_async(struct rpc_task *);
6351 void rpc_call_setup(struct rpc_task *, struct rpc_message *, int);
6353 @@ -132,20 +133,16 @@ int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg,
6355 int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
6357 +struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
6359 void rpc_restart_call(struct rpc_task *);
6360 void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
6361 void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
6362 void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
6363 size_t rpc_max_payload(struct rpc_clnt *);
6364 void rpc_force_rebind(struct rpc_clnt *);
6365 -int rpc_ping(struct rpc_clnt *clnt, int flags);
6366 size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
6367 char * rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
6370 - * Helper function for NFSroot support
6372 -int rpcb_getport_external(struct sockaddr_in *, __u32, __u32, int);
6374 #endif /* __KERNEL__ */
6375 #endif /* _LINUX_SUNRPC_CLNT_H */
6376 diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
6377 index 5eca9e4..bbac101 100644
6378 --- a/include/linux/sunrpc/gss_api.h
6379 +++ b/include/linux/sunrpc/gss_api.h
6380 @@ -77,7 +77,7 @@ struct gss_api_mech {
6381 struct module *gm_owner;
6382 struct xdr_netobj gm_oid;
6384 - struct gss_api_ops *gm_ops;
6385 + const struct gss_api_ops *gm_ops;
6386 /* pseudoflavors supported by this mechanism: */
6388 struct pf_desc * gm_pfs;
6389 diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
6390 index ad29376..51b977a 100644
6391 --- a/include/linux/sunrpc/rpc_pipe_fs.h
6392 +++ b/include/linux/sunrpc/rpc_pipe_fs.h
6393 @@ -23,9 +23,11 @@ struct rpc_inode {
6395 struct list_head pipe;
6396 struct list_head in_upcall;
6397 + struct list_head in_downcall;
6401 + int nkern_readwriters;
6402 wait_queue_head_t waitq;
6403 #define RPC_PIPE_WAIT_FOR_OPEN 1
6405 diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
6406 index 2047fb2..8ea077d 100644
6407 --- a/include/linux/sunrpc/sched.h
6408 +++ b/include/linux/sunrpc/sched.h
6409 @@ -98,7 +98,6 @@ struct rpc_task {
6410 unsigned short tk_pid; /* debugging aid */
6413 -#define tk_auth tk_client->cl_auth
6414 #define tk_xprt tk_client->cl_xprt
6416 /* support walking a list of tasks on a wait queue */
6417 @@ -110,11 +109,6 @@ struct rpc_task {
6418 if (!list_empty(head) && \
6419 ((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1))
6421 -/* .. and walking list of all tasks */
6422 -#define alltask_for_each(task, pos, head) \
6423 - list_for_each(pos, head) \
6424 - if ((task=list_entry(pos, struct rpc_task, tk_task)),1)
6426 typedef void (*rpc_action)(struct rpc_task *);
6428 struct rpc_call_ops {
6429 diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
6430 index e21dd93..a53e0fa 100644
6431 --- a/include/linux/sunrpc/svcsock.h
6432 +++ b/include/linux/sunrpc/svcsock.h
6433 @@ -59,6 +59,7 @@ struct svc_sock {
6434 /* cache of various info for TCP sockets */
6435 void *sk_info_authunix;
6437 + struct sockaddr_storage sk_local; /* local address */
6438 struct sockaddr_storage sk_remote; /* remote peer's address */
6439 int sk_remotelen; /* length of address */
6441 diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
6442 index 34f7590..d11cedd 100644
6443 --- a/include/linux/sunrpc/xprt.h
6444 +++ b/include/linux/sunrpc/xprt.h
6446 #include <linux/sunrpc/xdr.h>
6447 #include <linux/sunrpc/msg_prot.h>
6451 extern unsigned int xprt_udp_slot_table_entries;
6452 extern unsigned int xprt_tcp_slot_table_entries;
6454 @@ -194,7 +196,13 @@ struct rpc_xprt {
6455 char * address_strings[RPC_DISPLAY_MAX];
6459 +struct rpc_xprtsock_create {
6460 + int proto; /* IPPROTO_UDP or IPPROTO_TCP */
6461 + struct sockaddr * srcaddr; /* optional local address */
6462 + struct sockaddr * dstaddr; /* remote peer address */
6464 + struct rpc_timeout * timeout; /* optional timeout parameters */
6468 * Transport operations used by ULPs
6469 @@ -204,7 +212,7 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long
6471 * Generic internal transport functions
6473 -struct rpc_xprt * xprt_create_transport(int proto, struct sockaddr *addr, size_t size, struct rpc_timeout *toparms);
6474 +struct rpc_xprt * xprt_create_transport(struct rpc_xprtsock_create *args);
6475 void xprt_connect(struct rpc_task *task);
6476 void xprt_reserve(struct rpc_task *task);
6477 int xprt_reserve_xprt(struct rpc_task *task);
6478 @@ -242,8 +250,8 @@ void xprt_disconnect(struct rpc_xprt *xprt);
6480 * Socket transport setup operations
6482 -struct rpc_xprt * xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to);
6483 -struct rpc_xprt * xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to);
6484 +struct rpc_xprt * xs_setup_udp(struct rpc_xprtsock_create *args);
6485 +struct rpc_xprt * xs_setup_tcp(struct rpc_xprtsock_create *args);
6486 int init_socket_xprt(void);
6487 void cleanup_socket_xprt(void);
6489 diff --git a/kernel/auditsc.c b/kernel/auditsc.c
6490 index e36481e..ced6541 100644
6491 --- a/kernel/auditsc.c
6492 +++ b/kernel/auditsc.c
6493 @@ -1500,6 +1500,7 @@ add_names:
6494 context->names[idx].ino = (unsigned long)-1;
6497 +EXPORT_SYMBOL(__audit_inode_child);
6500 * auditsc_get_stamp - get local copies of audit_context values
6501 diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
6502 index 9527f2b..74baf87 100644
6503 --- a/net/sunrpc/auth.c
6504 +++ b/net/sunrpc/auth.c
6506 # define RPCDBG_FACILITY RPCDBG_AUTH
6509 -static struct rpc_authops * auth_flavors[RPC_AUTH_MAXFLAVOR] = {
6510 +static DEFINE_SPINLOCK(rpc_authflavor_lock);
6511 +static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
6512 &authnull_ops, /* AUTH_NULL */
6513 &authunix_ops, /* AUTH_UNIX */
6514 NULL, /* others can be loadable modules */
6517 +static LIST_HEAD(cred_unused);
6518 +static unsigned long number_cred_unused;
6521 pseudoflavor_to_flavor(u32 flavor) {
6522 if (flavor >= RPC_AUTH_MAXFLAVOR)
6523 @@ -32,55 +36,67 @@ pseudoflavor_to_flavor(u32 flavor) {
6527 -rpcauth_register(struct rpc_authops *ops)
6528 +rpcauth_register(const struct rpc_authops *ops)
6530 rpc_authflavor_t flavor;
6533 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
6535 - if (auth_flavors[flavor] != NULL)
6536 - return -EPERM; /* what else? */
6537 - auth_flavors[flavor] = ops;
6539 + spin_lock(&rpc_authflavor_lock);
6540 + if (auth_flavors[flavor] == NULL) {
6541 + auth_flavors[flavor] = ops;
6544 + spin_unlock(&rpc_authflavor_lock);
6549 -rpcauth_unregister(struct rpc_authops *ops)
6550 +rpcauth_unregister(const struct rpc_authops *ops)
6552 rpc_authflavor_t flavor;
6555 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
6557 - if (auth_flavors[flavor] != ops)
6558 - return -EPERM; /* what else? */
6559 - auth_flavors[flavor] = NULL;
6561 + spin_lock(&rpc_authflavor_lock);
6562 + if (auth_flavors[flavor] == ops) {
6563 + auth_flavors[flavor] = NULL;
6566 + spin_unlock(&rpc_authflavor_lock);
6571 rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
6573 struct rpc_auth *auth;
6574 - struct rpc_authops *ops;
6575 + const struct rpc_authops *ops;
6576 u32 flavor = pseudoflavor_to_flavor(pseudoflavor);
6578 auth = ERR_PTR(-EINVAL);
6579 if (flavor >= RPC_AUTH_MAXFLAVOR)
6582 - /* FIXME - auth_flavors[] really needs an rw lock,
6583 - * and module refcounting. */
6585 if ((ops = auth_flavors[flavor]) == NULL)
6586 request_module("rpc-auth-%u", flavor);
6588 - if ((ops = auth_flavors[flavor]) == NULL)
6589 + spin_lock(&rpc_authflavor_lock);
6590 + ops = auth_flavors[flavor];
6591 + if (ops == NULL || !try_module_get(ops->owner)) {
6592 + spin_unlock(&rpc_authflavor_lock);
6595 + spin_unlock(&rpc_authflavor_lock);
6596 auth = ops->create(clnt, pseudoflavor);
6597 + module_put(ops->owner);
6601 - rpcauth_destroy(clnt->cl_auth);
6602 + rpcauth_release(clnt->cl_auth);
6603 clnt->cl_auth = auth;
6606 @@ -88,7 +104,7 @@ out:
6610 -rpcauth_destroy(struct rpc_auth *auth)
6611 +rpcauth_release(struct rpc_auth *auth)
6613 if (!atomic_dec_and_test(&auth->au_count))
6615 @@ -97,11 +113,31 @@ rpcauth_destroy(struct rpc_auth *auth)
6617 static DEFINE_SPINLOCK(rpc_credcache_lock);
6620 +rpcauth_unhash_cred_locked(struct rpc_cred *cred)
6622 + hlist_del_rcu(&cred->cr_hash);
6623 + smp_mb__before_clear_bit();
6624 + clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
6628 +rpcauth_unhash_cred(struct rpc_cred *cred)
6630 + spinlock_t *cache_lock;
6632 + cache_lock = &cred->cr_auth->au_credcache->lock;
6633 + spin_lock(cache_lock);
6634 + if (atomic_read(&cred->cr_count) == 0)
6635 + rpcauth_unhash_cred_locked(cred);
6636 + spin_unlock(cache_lock);
6640 * Initialize RPC credential cache
6643 -rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
6644 +rpcauth_init_credcache(struct rpc_auth *auth)
6646 struct rpc_cred_cache *new;
6648 @@ -111,8 +147,7 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
6650 for (i = 0; i < RPC_CREDCACHE_NR; i++)
6651 INIT_HLIST_HEAD(&new->hashtable[i]);
6652 - new->expire = expire;
6653 - new->nextgc = jiffies + (expire >> 1);
6654 + spin_lock_init(&new->lock);
6655 auth->au_credcache = new;
6658 @@ -121,13 +156,13 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
6659 * Destroy a list of credentials
6662 -void rpcauth_destroy_credlist(struct hlist_head *head)
6663 +void rpcauth_destroy_credlist(struct list_head *head)
6665 struct rpc_cred *cred;
6667 - while (!hlist_empty(head)) {
6668 - cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
6669 - hlist_del_init(&cred->cr_hash);
6670 + while (!list_empty(head)) {
6671 + cred = list_entry(head->next, struct rpc_cred, cr_lru);
6672 + list_del_init(&cred->cr_lru);
6676 @@ -137,58 +172,95 @@ void rpcauth_destroy_credlist(struct hlist_head *head)
6677 * that are not referenced.
6680 -rpcauth_free_credcache(struct rpc_auth *auth)
6681 +rpcauth_clear_credcache(struct rpc_cred_cache *cache)
6683 - struct rpc_cred_cache *cache = auth->au_credcache;
6685 - struct hlist_node *pos, *next;
6687 + struct hlist_head *head;
6688 struct rpc_cred *cred;
6691 spin_lock(&rpc_credcache_lock);
6692 + spin_lock(&cache->lock);
6693 for (i = 0; i < RPC_CREDCACHE_NR; i++) {
6694 - hlist_for_each_safe(pos, next, &cache->hashtable[i]) {
6695 - cred = hlist_entry(pos, struct rpc_cred, cr_hash);
6696 - __hlist_del(&cred->cr_hash);
6697 - hlist_add_head(&cred->cr_hash, &free);
6698 + head = &cache->hashtable[i];
6699 + while (!hlist_empty(head)) {
6700 + cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
6701 + get_rpccred(cred);
6702 + if (!list_empty(&cred->cr_lru)) {
6703 + list_del(&cred->cr_lru);
6704 + number_cred_unused--;
6706 + list_add_tail(&cred->cr_lru, &free);
6707 + rpcauth_unhash_cred_locked(cred);
6710 + spin_unlock(&cache->lock);
6711 spin_unlock(&rpc_credcache_lock);
6712 rpcauth_destroy_credlist(&free);
6716 -rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist_head *free)
6718 + * Destroy the RPC credential cache
6721 +rpcauth_destroy_credcache(struct rpc_auth *auth)
6723 - if (atomic_read(&cred->cr_count) != 1)
6725 - if (time_after(jiffies, cred->cr_expire + auth->au_credcache->expire))
6726 - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
6727 - if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) {
6728 - __hlist_del(&cred->cr_hash);
6729 - hlist_add_head(&cred->cr_hash, free);
6730 + struct rpc_cred_cache *cache = auth->au_credcache;
6733 + auth->au_credcache = NULL;
6734 + rpcauth_clear_credcache(cache);
6740 * Remove stale credentials. Avoid sleeping inside the loop.
6743 -rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free)
6745 +rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
6747 - struct rpc_cred_cache *cache = auth->au_credcache;
6748 - struct hlist_node *pos, *next;
6749 - struct rpc_cred *cred;
6751 + spinlock_t *cache_lock;
6752 + struct rpc_cred *cred;
6754 - dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth);
6755 - for (i = 0; i < RPC_CREDCACHE_NR; i++) {
6756 - hlist_for_each_safe(pos, next, &cache->hashtable[i]) {
6757 - cred = hlist_entry(pos, struct rpc_cred, cr_hash);
6758 - rpcauth_prune_expired(auth, cred, free);
6759 + while (!list_empty(&cred_unused)) {
6760 + cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru);
6761 + list_del_init(&cred->cr_lru);
6762 + number_cred_unused--;
6763 + if (atomic_read(&cred->cr_count) != 0)
6765 + cache_lock = &cred->cr_auth->au_credcache->lock;
6766 + spin_lock(cache_lock);
6767 + if (atomic_read(&cred->cr_count) == 0) {
6768 + get_rpccred(cred);
6769 + list_add_tail(&cred->cr_lru, free);
6770 + rpcauth_unhash_cred_locked(cred);
6773 + spin_unlock(cache_lock);
6774 + if (nr_to_scan == 0)
6777 - cache->nextgc = jiffies + cache->expire;
6778 + return nr_to_scan;
6782 + * Run memory cache shrinker.
6785 +rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
6790 + if (list_empty(&cred_unused))
6792 + spin_lock(&rpc_credcache_lock);
6793 + nr_to_scan = rpcauth_prune_expired(&free, nr_to_scan);
6794 + res = (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
6795 + spin_unlock(&rpc_credcache_lock);
6796 + rpcauth_destroy_credlist(&free);
6801 @@ -198,53 +270,56 @@ struct rpc_cred *
6802 rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
6806 struct rpc_cred_cache *cache = auth->au_credcache;
6808 - struct hlist_node *pos, *next;
6809 - struct rpc_cred *new = NULL,
6811 + struct hlist_node *pos;
6812 + struct rpc_cred *cred = NULL,
6816 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
6817 nr = acred->uid & RPC_CREDCACHE_MASK;
6819 - spin_lock(&rpc_credcache_lock);
6820 - if (time_before(cache->nextgc, jiffies))
6821 - rpcauth_gc_credcache(auth, &free);
6822 - hlist_for_each_safe(pos, next, &cache->hashtable[nr]) {
6823 - struct rpc_cred *entry;
6824 - entry = hlist_entry(pos, struct rpc_cred, cr_hash);
6825 - if (entry->cr_ops->crmatch(acred, entry, flags)) {
6826 - hlist_del(&entry->cr_hash);
6831 + hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
6832 + if (!entry->cr_ops->crmatch(acred, entry, flags))
6834 + spin_lock(&cache->lock);
6835 + if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) {
6836 + spin_unlock(&cache->lock);
6839 - rpcauth_prune_expired(auth, entry, &free);
6843 - hlist_add_head(&new->cr_hash, &free);
6846 + cred = get_rpccred(entry);
6847 + spin_unlock(&cache->lock);
6851 - hlist_add_head(&cred->cr_hash, &cache->hashtable[nr]);
6852 - get_rpccred(cred);
6854 - spin_unlock(&rpc_credcache_lock);
6855 + rcu_read_unlock();
6857 - rpcauth_destroy_credlist(&free);
6862 - new = auth->au_ops->crcreate(auth, acred, flags);
6863 - if (!IS_ERR(new)) {
6865 - new->cr_magic = RPCAUTH_CRED_MAGIC;
6870 - } else if ((cred->cr_flags & RPCAUTH_CRED_NEW)
6871 + new = auth->au_ops->crcreate(auth, acred, flags);
6872 + if (IS_ERR(new)) {
6877 + spin_lock(&cache->lock);
6878 + hlist_for_each_entry(entry, pos, &cache->hashtable[nr], cr_hash) {
6879 + if (!entry->cr_ops->crmatch(acred, entry, flags))
6881 + cred = get_rpccred(entry);
6884 + if (cred == NULL) {
6886 + set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
6887 + hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]);
6889 + list_add_tail(&new->cr_lru, &free);
6890 + spin_unlock(&cache->lock);
6892 + if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)
6893 && cred->cr_ops->cr_init != NULL
6894 && !(flags & RPCAUTH_LOOKUP_NEW)) {
6895 int res = cred->cr_ops->cr_init(auth, cred);
6896 @@ -253,8 +328,9 @@ retry:
6897 cred = ERR_PTR(res);
6901 - return (struct rpc_cred *) cred;
6902 + rpcauth_destroy_credlist(&free);
6908 @@ -275,10 +351,27 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
6913 +rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
6914 + struct rpc_auth *auth, const struct rpc_credops *ops)
6916 + INIT_HLIST_NODE(&cred->cr_hash);
6917 + INIT_LIST_HEAD(&cred->cr_lru);
6918 + atomic_set(&cred->cr_count, 1);
6919 + cred->cr_auth = auth;
6920 + cred->cr_ops = ops;
6921 + cred->cr_expire = jiffies;
6923 + cred->cr_magic = RPCAUTH_CRED_MAGIC;
6925 + cred->cr_uid = acred->uid;
6927 +EXPORT_SYMBOL(rpcauth_init_cred);
6930 rpcauth_bindcred(struct rpc_task *task)
6932 - struct rpc_auth *auth = task->tk_auth;
6933 + struct rpc_auth *auth = task->tk_client->cl_auth;
6934 struct auth_cred acred = {
6935 .uid = current->fsuid,
6936 .gid = current->fsgid,
6937 @@ -288,7 +381,7 @@ rpcauth_bindcred(struct rpc_task *task)
6940 dprintk("RPC: %5u looking up %s cred\n",
6941 - task->tk_pid, task->tk_auth->au_ops->au_name);
6942 + task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
6943 get_group_info(acred.group_info);
6944 if (task->tk_flags & RPC_TASK_ROOTCREDS)
6945 flags |= RPCAUTH_LOOKUP_ROOTCREDS;
6946 @@ -304,19 +397,42 @@ rpcauth_bindcred(struct rpc_task *task)
6948 rpcauth_holdcred(struct rpc_task *task)
6950 - dprintk("RPC: %5u holding %s cred %p\n",
6951 - task->tk_pid, task->tk_auth->au_ops->au_name,
6952 - task->tk_msg.rpc_cred);
6953 - if (task->tk_msg.rpc_cred)
6954 - get_rpccred(task->tk_msg.rpc_cred);
6955 + struct rpc_cred *cred = task->tk_msg.rpc_cred;
6956 + if (cred != NULL) {
6957 + get_rpccred(cred);
6958 + dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid,
6959 + cred->cr_auth->au_ops->au_name, cred);
6964 put_rpccred(struct rpc_cred *cred)
6966 - cred->cr_expire = jiffies;
6967 + /* Fast path for unhashed credentials */
6968 + if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
6971 if (!atomic_dec_and_test(&cred->cr_count))
6975 + if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock))
6977 + if (!list_empty(&cred->cr_lru)) {
6978 + number_cred_unused--;
6979 + list_del_init(&cred->cr_lru);
6981 + if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
6982 + rpcauth_unhash_cred(cred);
6983 + else if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) {
6984 + cred->cr_expire = jiffies;
6985 + list_add_tail(&cred->cr_lru, &cred_unused);
6986 + number_cred_unused++;
6987 + spin_unlock(&rpc_credcache_lock);
6990 + spin_unlock(&rpc_credcache_lock);
6992 cred->cr_ops->crdestroy(cred);
6995 @@ -326,7 +442,7 @@ rpcauth_unbindcred(struct rpc_task *task)
6996 struct rpc_cred *cred = task->tk_msg.rpc_cred;
6998 dprintk("RPC: %5u releasing %s cred %p\n",
6999 - task->tk_pid, task->tk_auth->au_ops->au_name, cred);
7000 + task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
7003 task->tk_msg.rpc_cred = NULL;
7004 @@ -338,7 +454,7 @@ rpcauth_marshcred(struct rpc_task *task, __be32 *p)
7005 struct rpc_cred *cred = task->tk_msg.rpc_cred;
7007 dprintk("RPC: %5u marshaling %s cred %p\n",
7008 - task->tk_pid, task->tk_auth->au_ops->au_name, cred);
7009 + task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
7011 return cred->cr_ops->crmarshal(task, p);
7013 @@ -349,7 +465,7 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p)
7014 struct rpc_cred *cred = task->tk_msg.rpc_cred;
7016 dprintk("RPC: %5u validating %s cred %p\n",
7017 - task->tk_pid, task->tk_auth->au_ops->au_name, cred);
7018 + task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
7020 return cred->cr_ops->crvalidate(task, p);
7022 @@ -390,7 +506,7 @@ rpcauth_refreshcred(struct rpc_task *task)
7025 dprintk("RPC: %5u refreshing %s cred %p\n",
7026 - task->tk_pid, task->tk_auth->au_ops->au_name, cred);
7027 + task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
7029 err = cred->cr_ops->crrefresh(task);
7031 @@ -401,17 +517,34 @@ rpcauth_refreshcred(struct rpc_task *task)
7033 rpcauth_invalcred(struct rpc_task *task)
7035 + struct rpc_cred *cred = task->tk_msg.rpc_cred;
7037 dprintk("RPC: %5u invalidating %s cred %p\n",
7038 - task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred);
7039 - spin_lock(&rpc_credcache_lock);
7040 - if (task->tk_msg.rpc_cred)
7041 - task->tk_msg.rpc_cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
7042 - spin_unlock(&rpc_credcache_lock);
7043 + task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
7045 + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7049 rpcauth_uptodatecred(struct rpc_task *task)
7051 - return !(task->tk_msg.rpc_cred) ||
7052 - (task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE);
7053 + struct rpc_cred *cred = task->tk_msg.rpc_cred;
7055 + return cred == NULL ||
7056 + test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
7060 +static struct shrinker *rpc_cred_shrinker;
7062 +void __init rpcauth_init_module(void)
7064 + rpc_init_authunix();
7065 + rpc_cred_shrinker = set_shrinker(DEFAULT_SEEKS, rpcauth_cache_shrinker);
7068 +void __exit rpcauth_remove_module(void)
7070 + if (rpc_cred_shrinker != NULL)
7071 + remove_shrinker(rpc_cred_shrinker);
7073 diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
7074 index 4e4ccc5..17d460f 100644
7075 --- a/net/sunrpc/auth_gss/auth_gss.c
7076 +++ b/net/sunrpc/auth_gss/auth_gss.c
7078 #include <linux/sunrpc/gss_api.h>
7079 #include <asm/uaccess.h>
7081 -static struct rpc_authops authgss_ops;
7082 +static const struct rpc_authops authgss_ops;
7084 -static struct rpc_credops gss_credops;
7085 +static const struct rpc_credops gss_credops;
7086 +static const struct rpc_credops gss_nullops;
7089 # define RPCDBG_FACILITY RPCDBG_AUTH
7090 @@ -64,7 +65,6 @@ static struct rpc_credops gss_credops;
7092 #define NFS_NGROUPS 16
7094 -#define GSS_CRED_EXPIRE (60 * HZ) /* XXX: reasonable? */
7095 #define GSS_CRED_SLACK 1024 /* XXX: unused */
7096 /* length of a krb5 verifier (48), plus data added before arguments when
7097 * using integrity (two 4-byte integers): */
7098 @@ -79,19 +79,16 @@ static struct rpc_credops gss_credops;
7099 /* dump the buffer in `emacs-hexl' style */
7100 #define isprint(c) ((c > 0x1f) && (c < 0x7f))
7102 -static DEFINE_RWLOCK(gss_ctx_lock);
7106 struct rpc_auth rpc_auth;
7107 struct gss_api_mech *mech;
7108 enum rpc_gss_svc service;
7109 - struct list_head upcalls;
7110 struct rpc_clnt *client;
7111 struct dentry *dentry;
7115 -static void gss_destroy_ctx(struct gss_cl_ctx *);
7116 +static void gss_free_ctx(struct gss_cl_ctx *);
7117 static struct rpc_pipe_ops gss_upcall_ops;
7119 static inline struct gss_cl_ctx *
7120 @@ -105,20 +102,24 @@ static inline void
7121 gss_put_ctx(struct gss_cl_ctx *ctx)
7123 if (atomic_dec_and_test(&ctx->count))
7124 - gss_destroy_ctx(ctx);
7125 + gss_free_ctx(ctx);
7128 +/* gss_cred_set_ctx:
7129 + * called by gss_upcall_callback and gss_create_upcall in order
7130 + * to set the gss context. The actual exchange of an old context
7131 + * and a new one is protected by the inode->i_lock.
7134 gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
7136 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
7137 struct gss_cl_ctx *old;
7138 - write_lock(&gss_ctx_lock);
7140 old = gss_cred->gc_ctx;
7141 - gss_cred->gc_ctx = ctx;
7142 - cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
7143 - cred->cr_flags &= ~RPCAUTH_CRED_NEW;
7144 - write_unlock(&gss_ctx_lock);
7145 + rcu_assign_pointer(gss_cred->gc_ctx, ctx);
7146 + set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7147 + clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
7151 @@ -129,10 +130,10 @@ gss_cred_is_uptodate_ctx(struct rpc_cred *cred)
7152 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
7155 - read_lock(&gss_ctx_lock);
7156 - if ((cred->cr_flags & RPCAUTH_CRED_UPTODATE) && gss_cred->gc_ctx)
7158 + if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) && gss_cred->gc_ctx)
7160 - read_unlock(&gss_ctx_lock);
7161 + rcu_read_unlock();
7165 @@ -171,10 +172,10 @@ gss_cred_get_ctx(struct rpc_cred *cred)
7166 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
7167 struct gss_cl_ctx *ctx = NULL;
7169 - read_lock(&gss_ctx_lock);
7171 if (gss_cred->gc_ctx)
7172 ctx = gss_get_ctx(gss_cred->gc_ctx);
7173 - read_unlock(&gss_ctx_lock);
7174 + rcu_read_unlock();
7178 @@ -269,10 +270,10 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
7181 static struct gss_upcall_msg *
7182 -__gss_find_upcall(struct gss_auth *gss_auth, uid_t uid)
7183 +__gss_find_upcall(struct rpc_inode *rpci, uid_t uid)
7185 struct gss_upcall_msg *pos;
7186 - list_for_each_entry(pos, &gss_auth->upcalls, list) {
7187 + list_for_each_entry(pos, &rpci->in_downcall, list) {
7188 if (pos->uid != uid)
7190 atomic_inc(&pos->count);
7191 @@ -290,24 +291,24 @@ __gss_find_upcall(struct gss_auth *gss_auth, uid_t uid)
7192 static inline struct gss_upcall_msg *
7193 gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg)
7195 + struct inode *inode = gss_auth->dentry->d_inode;
7196 + struct rpc_inode *rpci = RPC_I(inode);
7197 struct gss_upcall_msg *old;
7199 - spin_lock(&gss_auth->lock);
7200 - old = __gss_find_upcall(gss_auth, gss_msg->uid);
7201 + spin_lock(&inode->i_lock);
7202 + old = __gss_find_upcall(rpci, gss_msg->uid);
7204 atomic_inc(&gss_msg->count);
7205 - list_add(&gss_msg->list, &gss_auth->upcalls);
7206 + list_add(&gss_msg->list, &rpci->in_downcall);
7209 - spin_unlock(&gss_auth->lock);
7210 + spin_unlock(&inode->i_lock);
7215 __gss_unhash_msg(struct gss_upcall_msg *gss_msg)
7217 - if (list_empty(&gss_msg->list))
7219 list_del_init(&gss_msg->list);
7220 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
7221 wake_up_all(&gss_msg->waitqueue);
7222 @@ -318,10 +319,14 @@ static void
7223 gss_unhash_msg(struct gss_upcall_msg *gss_msg)
7225 struct gss_auth *gss_auth = gss_msg->auth;
7226 + struct inode *inode = gss_auth->dentry->d_inode;
7228 - spin_lock(&gss_auth->lock);
7229 - __gss_unhash_msg(gss_msg);
7230 - spin_unlock(&gss_auth->lock);
7231 + if (list_empty(&gss_msg->list))
7233 + spin_lock(&inode->i_lock);
7234 + if (!list_empty(&gss_msg->list))
7235 + __gss_unhash_msg(gss_msg);
7236 + spin_unlock(&inode->i_lock);
7240 @@ -330,16 +335,16 @@ gss_upcall_callback(struct rpc_task *task)
7241 struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred,
7242 struct gss_cred, gc_base);
7243 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
7244 + struct inode *inode = gss_msg->auth->dentry->d_inode;
7246 - BUG_ON(gss_msg == NULL);
7247 + spin_lock(&inode->i_lock);
7249 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx));
7251 task->tk_status = gss_msg->msg.errno;
7252 - spin_lock(&gss_msg->auth->lock);
7253 gss_cred->gc_upcall = NULL;
7254 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
7255 - spin_unlock(&gss_msg->auth->lock);
7256 + spin_unlock(&inode->i_lock);
7257 gss_release_msg(gss_msg);
7260 @@ -386,11 +391,12 @@ static inline int
7261 gss_refresh_upcall(struct rpc_task *task)
7263 struct rpc_cred *cred = task->tk_msg.rpc_cred;
7264 - struct gss_auth *gss_auth = container_of(task->tk_client->cl_auth,
7265 + struct gss_auth *gss_auth = container_of(cred->cr_auth,
7266 struct gss_auth, rpc_auth);
7267 struct gss_cred *gss_cred = container_of(cred,
7268 struct gss_cred, gc_base);
7269 struct gss_upcall_msg *gss_msg;
7270 + struct inode *inode = gss_auth->dentry->d_inode;
7273 dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
7274 @@ -400,7 +406,7 @@ gss_refresh_upcall(struct rpc_task *task)
7275 err = PTR_ERR(gss_msg);
7278 - spin_lock(&gss_auth->lock);
7279 + spin_lock(&inode->i_lock);
7280 if (gss_cred->gc_upcall != NULL)
7281 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL);
7282 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
7283 @@ -411,7 +417,7 @@ gss_refresh_upcall(struct rpc_task *task)
7284 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL);
7286 err = gss_msg->msg.errno;
7287 - spin_unlock(&gss_auth->lock);
7288 + spin_unlock(&inode->i_lock);
7289 gss_release_msg(gss_msg);
7291 dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n",
7292 @@ -422,6 +428,7 @@ out:
7294 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
7296 + struct inode *inode = gss_auth->dentry->d_inode;
7297 struct rpc_cred *cred = &gss_cred->gc_base;
7298 struct gss_upcall_msg *gss_msg;
7300 @@ -435,12 +442,11 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
7303 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE);
7304 - spin_lock(&gss_auth->lock);
7305 + spin_lock(&inode->i_lock);
7306 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
7307 - spin_unlock(&gss_auth->lock);
7310 - spin_unlock(&gss_auth->lock);
7311 + spin_unlock(&inode->i_lock);
7315 @@ -451,6 +457,7 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
7316 gss_cred_set_ctx(cred, gss_get_ctx(gss_msg->ctx));
7318 err = gss_msg->msg.errno;
7319 + spin_unlock(&inode->i_lock);
7321 finish_wait(&gss_msg->waitqueue, &wait);
7322 gss_release_msg(gss_msg);
7323 @@ -489,12 +496,11 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
7324 const void *p, *end;
7326 struct rpc_clnt *clnt;
7327 - struct gss_auth *gss_auth;
7328 - struct rpc_cred *cred;
7329 struct gss_upcall_msg *gss_msg;
7330 + struct inode *inode = filp->f_path.dentry->d_inode;
7331 struct gss_cl_ctx *ctx;
7334 + ssize_t err = -EFBIG;
7336 if (mlen > MSG_BUF_MAXSIZE)
7338 @@ -503,7 +509,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
7342 - clnt = RPC_I(filp->f_path.dentry->d_inode)->private;
7343 + clnt = RPC_I(inode)->private;
7345 if (copy_from_user(buf, src, mlen))
7347 @@ -519,43 +525,38 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
7348 ctx = gss_alloc_context();
7352 - gss_auth = container_of(clnt->cl_auth, struct gss_auth, rpc_auth);
7353 - p = gss_fill_context(p, end, ctx, gss_auth->mech);
7356 + /* Find a matching upcall */
7357 + spin_lock(&inode->i_lock);
7358 + gss_msg = __gss_find_upcall(RPC_I(inode), uid);
7359 + if (gss_msg == NULL) {
7360 + spin_unlock(&inode->i_lock);
7363 + list_del_init(&gss_msg->list);
7364 + spin_unlock(&inode->i_lock);
7366 + p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
7369 - if (err != -EACCES)
7372 - spin_lock(&gss_auth->lock);
7373 - gss_msg = __gss_find_upcall(gss_auth, uid);
7375 - if (err == 0 && gss_msg->ctx == NULL)
7376 - gss_msg->ctx = gss_get_ctx(ctx);
7377 - gss_msg->msg.errno = err;
7378 - __gss_unhash_msg(gss_msg);
7379 - spin_unlock(&gss_auth->lock);
7380 - gss_release_msg(gss_msg);
7382 - struct auth_cred acred = { .uid = uid };
7383 - spin_unlock(&gss_auth->lock);
7384 - cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW);
7385 - if (IS_ERR(cred)) {
7386 - err = PTR_ERR(cred);
7389 - gss_cred_set_ctx(cred, gss_get_ctx(ctx));
7390 + gss_msg->msg.errno = (err == -EACCES) ? -EACCES : -EAGAIN;
7391 + goto err_release_msg;
7395 - dprintk("RPC: gss_pipe_downcall returning length %Zu\n", mlen);
7397 + gss_msg->ctx = gss_get_ctx(ctx);
7401 + spin_lock(&inode->i_lock);
7402 + __gss_unhash_msg(gss_msg);
7403 + spin_unlock(&inode->i_lock);
7404 + gss_release_msg(gss_msg);
7410 - dprintk("RPC: gss_pipe_downcall returning %d\n", err);
7411 + dprintk("RPC: gss_pipe_downcall returning %Zd\n", err);
7415 @@ -563,27 +564,21 @@ static void
7416 gss_pipe_release(struct inode *inode)
7418 struct rpc_inode *rpci = RPC_I(inode);
7419 - struct rpc_clnt *clnt;
7420 - struct rpc_auth *auth;
7421 - struct gss_auth *gss_auth;
7422 + struct gss_upcall_msg *gss_msg;
7424 - clnt = rpci->private;
7425 - auth = clnt->cl_auth;
7426 - gss_auth = container_of(auth, struct gss_auth, rpc_auth);
7427 - spin_lock(&gss_auth->lock);
7428 - while (!list_empty(&gss_auth->upcalls)) {
7429 - struct gss_upcall_msg *gss_msg;
7430 + spin_lock(&inode->i_lock);
7431 + while (!list_empty(&rpci->in_downcall)) {
7433 - gss_msg = list_entry(gss_auth->upcalls.next,
7434 + gss_msg = list_entry(rpci->in_downcall.next,
7435 struct gss_upcall_msg, list);
7436 gss_msg->msg.errno = -EPIPE;
7437 atomic_inc(&gss_msg->count);
7438 __gss_unhash_msg(gss_msg);
7439 - spin_unlock(&gss_auth->lock);
7440 + spin_unlock(&inode->i_lock);
7441 gss_release_msg(gss_msg);
7442 - spin_lock(&gss_auth->lock);
7443 + spin_lock(&inode->i_lock);
7445 - spin_unlock(&gss_auth->lock);
7446 + spin_unlock(&inode->i_lock);
7450 @@ -637,18 +632,13 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
7451 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
7452 if (gss_auth->service == 0)
7454 - INIT_LIST_HEAD(&gss_auth->upcalls);
7455 - spin_lock_init(&gss_auth->lock);
7456 auth = &gss_auth->rpc_auth;
7457 auth->au_cslack = GSS_CRED_SLACK >> 2;
7458 auth->au_rslack = GSS_VERF_SLACK >> 2;
7459 auth->au_ops = &authgss_ops;
7460 auth->au_flavor = flavor;
7461 atomic_set(&auth->au_count, 1);
7463 - err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE);
7465 - goto err_put_mech;
7466 + kref_init(&gss_auth->kref);
7468 gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name,
7469 clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
7470 @@ -657,7 +647,13 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
7474 + err = rpcauth_init_credcache(auth);
7476 + goto err_unlink_pipe;
7480 + rpc_unlink(gss_auth->dentry);
7482 gss_mech_put(gss_auth->mech);
7484 @@ -668,6 +664,25 @@ out_dec:
7488 +gss_free(struct gss_auth *gss_auth)
7490 + rpc_unlink(gss_auth->dentry);
7491 + gss_auth->dentry = NULL;
7492 + gss_mech_put(gss_auth->mech);
7495 + module_put(THIS_MODULE);
7499 +gss_free_callback(struct kref *kref)
7501 + struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
7503 + gss_free(gss_auth);
7507 gss_destroy(struct rpc_auth *auth)
7509 struct gss_auth *gss_auth;
7510 @@ -675,23 +690,51 @@ gss_destroy(struct rpc_auth *auth)
7511 dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
7512 auth, auth->au_flavor);
7514 + rpcauth_destroy_credcache(auth);
7516 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
7517 - rpc_unlink(gss_auth->dentry);
7518 - gss_auth->dentry = NULL;
7519 - gss_mech_put(gss_auth->mech);
7520 + kref_put(&gss_auth->kref, gss_free_callback);
7523 - rpcauth_free_credcache(auth);
7525 - module_put(THIS_MODULE);
7527 + * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
7528 + * to the server with the GSS control procedure field set to
7529 + * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
7530 + * all RPCSEC_GSS state associated with that context.
7533 +gss_destroying_context(struct rpc_cred *cred)
7535 + struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
7536 + struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
7537 + struct rpc_task *task;
7539 + if (gss_cred->gc_ctx == NULL ||
7540 + gss_cred->gc_ctx->gc_proc == RPC_GSS_PROC_DESTROY)
7543 + gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY;
7544 + cred->cr_ops = &gss_nullops;
7546 + /* Take a reference to ensure the cred will be destroyed either
7547 + * by the RPC call or by the put_rpccred() below */
7548 + get_rpccred(cred);
7550 + task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC);
7551 + if (!IS_ERR(task))
7552 + rpc_put_task(task);
7554 + put_rpccred(cred);
7558 -/* gss_destroy_cred (and gss_destroy_ctx) are used to clean up after failure
7559 +/* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
7560 * to create a new cred or context, so they check that things have been
7561 * allocated before freeing them. */
7563 -gss_destroy_ctx(struct gss_cl_ctx *ctx)
7564 +gss_do_free_ctx(struct gss_cl_ctx *ctx)
7566 - dprintk("RPC: gss_destroy_ctx\n");
7567 + dprintk("RPC: gss_free_ctx\n");
7569 if (ctx->gc_gss_ctx)
7570 gss_delete_sec_context(&ctx->gc_gss_ctx);
7571 @@ -701,15 +744,46 @@ gss_destroy_ctx(struct gss_cl_ctx *ctx)
7575 -gss_destroy_cred(struct rpc_cred *rc)
7576 +gss_free_ctx_callback(struct rcu_head *head)
7578 - struct gss_cred *cred = container_of(rc, struct gss_cred, gc_base);
7579 + struct gss_cl_ctx *ctx = container_of(head, struct gss_cl_ctx, gc_rcu);
7580 + gss_do_free_ctx(ctx);
7583 - dprintk("RPC: gss_destroy_cred \n");
7585 +gss_free_ctx(struct gss_cl_ctx *ctx)
7587 + call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
7591 - gss_put_ctx(cred->gc_ctx);
7594 +gss_free_cred(struct gss_cred *gss_cred)
7596 + dprintk("RPC: gss_free_cred %p\n", gss_cred);
7601 +gss_free_cred_callback(struct rcu_head *head)
7603 + struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu);
7604 + gss_free_cred(gss_cred);
7608 +gss_destroy_cred(struct rpc_cred *cred)
7610 + struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
7611 + struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
7612 + struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
7614 + if (gss_destroying_context(cred))
7616 + rcu_assign_pointer(gss_cred->gc_ctx, NULL);
7617 + call_rcu(&cred->cr_rcu, gss_free_cred_callback);
7620 + kref_put(&gss_auth->kref, gss_free_callback);
7624 @@ -734,16 +808,14 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
7625 if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL)))
7628 - atomic_set(&cred->gc_count, 1);
7629 - cred->gc_uid = acred->uid;
7630 + rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops);
7632 * Note: in order to force a call to call_refresh(), we deliberately
7633 * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
7635 - cred->gc_flags = 0;
7636 - cred->gc_base.cr_ops = &gss_credops;
7637 - cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
7638 + cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
7639 cred->gc_service = gss_auth->service;
7640 + kref_get(&gss_auth->kref);
7641 return &cred->gc_base;
7644 @@ -774,7 +846,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
7645 * we don't really care if the credential has expired or not,
7646 * since the caller should be prepared to reinitialise it.
7648 - if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW))
7649 + if ((flags & RPCAUTH_LOOKUP_NEW) && test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
7651 /* Don't match with creds that have expired. */
7652 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
7653 @@ -830,7 +902,7 @@ gss_marshal(struct rpc_task *task, __be32 *p)
7654 mic.data = (u8 *)(p + 1);
7655 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
7656 if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
7657 - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
7658 + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7659 } else if (maj_stat != 0) {
7660 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
7662 @@ -855,6 +927,13 @@ gss_refresh(struct rpc_task *task)
7666 +/* Dummy refresh routine: used only when destroying the context */
7668 +gss_refresh_null(struct rpc_task *task)
7674 gss_validate(struct rpc_task *task, __be32 *p)
7676 @@ -883,12 +962,15 @@ gss_validate(struct rpc_task *task, __be32 *p)
7678 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
7679 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
7680 - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
7682 + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7684 + dprintk("RPC: %5u gss_validate: gss_verify_mic returned"
7685 + "error 0x%08x\n", task->tk_pid, maj_stat);
7688 /* We leave it to unwrap to calculate au_rslack. For now we just
7689 * calculate the length of the verifier: */
7690 - task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2;
7691 + cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
7693 dprintk("RPC: %5u gss_validate: gss_verify_mic succeeded.\n",
7695 @@ -937,7 +1019,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
7696 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
7697 status = -EIO; /* XXX? */
7698 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
7699 - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
7700 + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7703 q = xdr_encode_opaque(p, NULL, mic.len);
7704 @@ -1036,7 +1118,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
7705 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
7706 * done anyway, so it's safe to put the request on the wire: */
7707 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
7708 - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
7709 + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7713 @@ -1123,7 +1205,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
7715 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
7716 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
7717 - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
7718 + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7719 if (maj_stat != GSS_S_COMPLETE)
7722 @@ -1148,7 +1230,7 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
7724 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
7725 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
7726 - cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
7727 + clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7728 if (maj_stat != GSS_S_COMPLETE)
7730 if (ntohl(*(*p)++) != rqstp->rq_seqno)
7731 @@ -1188,7 +1270,7 @@ gss_unwrap_resp(struct rpc_task *task,
7734 /* take into account extra slack for integrity and privacy cases: */
7735 - task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp)
7736 + cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp)
7737 + (savedlen - head->iov_len);
7739 status = decode(rqstp, p, obj);
7740 @@ -1199,7 +1281,7 @@ out:
7744 -static struct rpc_authops authgss_ops = {
7745 +static const struct rpc_authops authgss_ops = {
7746 .owner = THIS_MODULE,
7747 .au_flavor = RPC_AUTH_GSS,
7749 @@ -1211,7 +1293,7 @@ static struct rpc_authops authgss_ops = {
7750 .crcreate = gss_create_cred
7753 -static struct rpc_credops gss_credops = {
7754 +static const struct rpc_credops gss_credops = {
7755 .cr_name = "AUTH_GSS",
7756 .crdestroy = gss_destroy_cred,
7757 .cr_init = gss_cred_init,
7758 @@ -1223,6 +1305,17 @@ static struct rpc_credops gss_credops = {
7759 .crunwrap_resp = gss_unwrap_resp,
7762 +static const struct rpc_credops gss_nullops = {
7763 + .cr_name = "AUTH_GSS",
7764 + .crdestroy = gss_destroy_cred,
7765 + .crmatch = gss_match,
7766 + .crmarshal = gss_marshal,
7767 + .crrefresh = gss_refresh_null,
7768 + .crvalidate = gss_validate,
7769 + .crwrap_req = gss_wrap_req,
7770 + .crunwrap_resp = gss_unwrap_resp,
7773 static struct rpc_pipe_ops gss_upcall_ops = {
7774 .upcall = gss_pipe_upcall,
7775 .downcall = gss_pipe_downcall,
7776 diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
7777 index 7b19432..71b9dae 100644
7778 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c
7779 +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
7780 @@ -201,7 +201,7 @@ gss_delete_sec_context_kerberos(void *internal_ctx) {
7784 -static struct gss_api_ops gss_kerberos_ops = {
7785 +static const struct gss_api_ops gss_kerberos_ops = {
7786 .gss_import_sec_context = gss_import_sec_context_kerberos,
7787 .gss_get_mic = gss_get_mic_kerberos,
7788 .gss_verify_mic = gss_verify_mic_kerberos,
7789 diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
7790 index 7e15aa6..577d590 100644
7791 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
7792 +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
7793 @@ -202,7 +202,7 @@ gss_get_mic_spkm3(struct gss_ctx *ctx,
7797 -static struct gss_api_ops gss_spkm3_ops = {
7798 +static const struct gss_api_ops gss_spkm3_ops = {
7799 .gss_import_sec_context = gss_import_sec_context_spkm3,
7800 .gss_get_mic = gss_get_mic_spkm3,
7801 .gss_verify_mic = gss_verify_mic_spkm3,
7802 diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
7803 index 3df9fcc..537d0e8 100644
7804 --- a/net/sunrpc/auth_null.c
7805 +++ b/net/sunrpc/auth_null.c
7806 @@ -76,7 +76,7 @@ nul_marshal(struct rpc_task *task, __be32 *p)
7808 nul_refresh(struct rpc_task *task)
7810 - task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
7811 + set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
7815 @@ -101,7 +101,7 @@ nul_validate(struct rpc_task *task, __be32 *p)
7819 -struct rpc_authops authnull_ops = {
7820 +const struct rpc_authops authnull_ops = {
7821 .owner = THIS_MODULE,
7822 .au_flavor = RPC_AUTH_NULL,
7824 @@ -122,7 +122,7 @@ struct rpc_auth null_auth = {
7828 -struct rpc_credops null_credops = {
7829 +const struct rpc_credops null_credops = {
7830 .cr_name = "AUTH_NULL",
7831 .crdestroy = nul_destroy_cred,
7832 .crmatch = nul_match,
7833 @@ -133,9 +133,11 @@ struct rpc_credops null_credops = {
7836 struct rpc_cred null_cred = {
7837 + .cr_lru = LIST_HEAD_INIT(null_cred.cr_lru),
7838 + .cr_auth = &null_auth,
7839 .cr_ops = &null_credops,
7840 .cr_count = ATOMIC_INIT(1),
7841 - .cr_flags = RPCAUTH_CRED_UPTODATE,
7842 + .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE,
7844 .cr_magic = RPCAUTH_CRED_MAGIC,
7846 diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
7847 index 4e7733a..5ed91e5 100644
7848 --- a/net/sunrpc/auth_unix.c
7849 +++ b/net/sunrpc/auth_unix.c
7850 @@ -20,11 +20,6 @@ struct unx_cred {
7851 gid_t uc_gids[NFS_NGROUPS];
7853 #define uc_uid uc_base.cr_uid
7854 -#define uc_count uc_base.cr_count
7855 -#define uc_flags uc_base.cr_flags
7856 -#define uc_expire uc_base.cr_expire
7858 -#define UNX_CRED_EXPIRE (60 * HZ)
7860 #define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
7862 @@ -34,15 +29,14 @@ struct unx_cred {
7864 static struct rpc_auth unix_auth;
7865 static struct rpc_cred_cache unix_cred_cache;
7866 -static struct rpc_credops unix_credops;
7867 +static const struct rpc_credops unix_credops;
7869 static struct rpc_auth *
7870 unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
7872 dprintk("RPC: creating UNIX authenticator for client %p\n",
7874 - if (atomic_inc_return(&unix_auth.au_count) == 0)
7875 - unix_cred_cache.nextgc = jiffies + (unix_cred_cache.expire >> 1);
7876 + atomic_inc(&unix_auth.au_count);
7880 @@ -50,7 +44,7 @@ static void
7881 unx_destroy(struct rpc_auth *auth)
7883 dprintk("RPC: destroying UNIX authenticator %p\n", auth);
7884 - rpcauth_free_credcache(auth);
7885 + rpcauth_clear_credcache(auth->au_credcache);
7889 @@ -74,8 +68,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
7890 if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL)))
7891 return ERR_PTR(-ENOMEM);
7893 - atomic_set(&cred->uc_count, 1);
7894 - cred->uc_flags = RPCAUTH_CRED_UPTODATE;
7895 + rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
7896 + cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
7897 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
7900 @@ -85,22 +79,34 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
7901 if (groups > NFS_NGROUPS)
7902 groups = NFS_NGROUPS;
7904 - cred->uc_uid = acred->uid;
7905 cred->uc_gid = acred->gid;
7906 for (i = 0; i < groups; i++)
7907 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
7908 if (i < NFS_NGROUPS)
7909 cred->uc_gids[i] = NOGROUP;
7911 - cred->uc_base.cr_ops = &unix_credops;
7913 - return (struct rpc_cred *) cred;
7914 + return &cred->uc_base;
7918 +unx_free_cred(struct unx_cred *unx_cred)
7920 + dprintk("RPC: unx_free_cred %p\n", unx_cred);
7925 +unx_free_cred_callback(struct rcu_head *head)
7927 + struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
7928 + unx_free_cred(unx_cred);
7932 unx_destroy_cred(struct rpc_cred *cred)
7935 + call_rcu(&cred->cr_rcu, unx_free_cred_callback);
7939 @@ -111,7 +117,7 @@ unx_destroy_cred(struct rpc_cred *cred)
7941 unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
7943 - struct unx_cred *cred = (struct unx_cred *) rcred;
7944 + struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
7947 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
7948 @@ -142,7 +148,7 @@ static __be32 *
7949 unx_marshal(struct rpc_task *task, __be32 *p)
7951 struct rpc_clnt *clnt = task->tk_client;
7952 - struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
7953 + struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base);
7954 __be32 *base, *hold;
7957 @@ -175,7 +181,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
7959 unx_refresh(struct rpc_task *task)
7961 - task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
7962 + set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
7966 @@ -198,13 +204,18 @@ unx_validate(struct rpc_task *task, __be32 *p)
7967 printk("RPC: giant verf size: %u\n", size);
7970 - task->tk_auth->au_rslack = (size >> 2) + 2;
7971 + task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2;
7977 -struct rpc_authops authunix_ops = {
7978 +void __init rpc_init_authunix(void)
7980 + spin_lock_init(&unix_cred_cache.lock);
7983 +const struct rpc_authops authunix_ops = {
7984 .owner = THIS_MODULE,
7985 .au_flavor = RPC_AUTH_UNIX,
7987 @@ -218,7 +229,6 @@ struct rpc_authops authunix_ops = {
7990 struct rpc_cred_cache unix_cred_cache = {
7991 - .expire = UNX_CRED_EXPIRE,
7995 @@ -232,7 +242,7 @@ struct rpc_auth unix_auth = {
7999 -struct rpc_credops unix_credops = {
8000 +const struct rpc_credops unix_credops = {
8001 .cr_name = "AUTH_UNIX",
8002 .crdestroy = unx_destroy_cred,
8003 .crmatch = unx_match,
8004 diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
8005 index d8fbee4..5d3fe7b 100644
8006 --- a/net/sunrpc/clnt.c
8007 +++ b/net/sunrpc/clnt.c
8009 dprintk("RPC: %5u %s (status %d)\n", t->tk_pid, \
8010 __FUNCTION__, t->tk_status)
8013 + * All RPC clients are linked into this list
8015 +static LIST_HEAD(all_clients);
8016 +static DEFINE_SPINLOCK(rpc_client_lock);
8018 static DECLARE_WAIT_QUEUE_HEAD(destroy_wait);
8021 @@ -66,6 +72,21 @@ static void call_connect_status(struct rpc_task *task);
8022 static __be32 * call_header(struct rpc_task *task);
8023 static __be32 * call_verify(struct rpc_task *task);
8025 +static int rpc_ping(struct rpc_clnt *clnt, int flags);
8027 +static void rpc_register_client(struct rpc_clnt *clnt)
8029 + spin_lock(&rpc_client_lock);
8030 + list_add(&clnt->cl_clients, &all_clients);
8031 + spin_unlock(&rpc_client_lock);
8034 +static void rpc_unregister_client(struct rpc_clnt *clnt)
8036 + spin_lock(&rpc_client_lock);
8037 + list_del(&clnt->cl_clients);
8038 + spin_unlock(&rpc_client_lock);
8042 rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
8043 @@ -111,6 +132,9 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
8044 dprintk("RPC: creating %s client for %s (xprt %p)\n",
8045 program->name, servname, xprt);
8047 + err = rpciod_up();
8049 + goto out_no_rpciod;
8053 @@ -121,8 +145,6 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
8054 clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
8057 - atomic_set(&clnt->cl_users, 0);
8058 - atomic_set(&clnt->cl_count, 1);
8059 clnt->cl_parent = clnt;
8061 clnt->cl_server = clnt->cl_inline_name;
8062 @@ -148,6 +170,8 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
8063 if (clnt->cl_metrics == NULL)
8065 clnt->cl_program = program;
8066 + INIT_LIST_HEAD(&clnt->cl_tasks);
8067 + spin_lock_init(&clnt->cl_lock);
8069 if (!xprt_bound(clnt->cl_xprt))
8070 clnt->cl_autobind = 1;
8071 @@ -155,6 +179,8 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
8072 clnt->cl_rtt = &clnt->cl_rtt_default;
8073 rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval);
8075 + kref_init(&clnt->cl_kref);
8077 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
8080 @@ -172,6 +198,7 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
8081 if (clnt->cl_nodelen > UNX_MAXNODENAME)
8082 clnt->cl_nodelen = UNX_MAXNODENAME;
8083 memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
8084 + rpc_register_client(clnt);
8088 @@ -188,6 +215,8 @@ out_no_stats:
8094 return ERR_PTR(err);
8097 @@ -205,13 +234,32 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
8099 struct rpc_xprt *xprt;
8100 struct rpc_clnt *clnt;
8101 + struct rpc_xprtsock_create xprtargs = {
8102 + .proto = args->protocol,
8103 + .srcaddr = args->saddress,
8104 + .dstaddr = args->address,
8105 + .addrlen = args->addrsize,
8106 + .timeout = args->timeout
8108 + char servername[20];
8110 - xprt = xprt_create_transport(args->protocol, args->address,
8111 - args->addrsize, args->timeout);
8112 + xprt = xprt_create_transport(&xprtargs);
8114 return (struct rpc_clnt *)xprt;
8117 + * If the caller chooses not to specify a hostname, whip
8118 + * up a string representation of the passed-in address.
8120 + if (args->servername == NULL) {
8121 + struct sockaddr_in *addr =
8122 + (struct sockaddr_in *) &args->address;
8123 + snprintf(servername, sizeof(servername), NIPQUAD_FMT,
8124 + NIPQUAD(addr->sin_addr.s_addr));
8125 + args->servername = servername;
8129 * By default, kernel RPC client connects from a reserved port.
8130 * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters,
8131 * but it is always enabled for rpciod, which handles the connect
8132 @@ -245,8 +293,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
8134 if (args->flags & RPC_CLNT_CREATE_AUTOBIND)
8135 clnt->cl_autobind = 1;
8136 - if (args->flags & RPC_CLNT_CREATE_ONESHOT)
8137 - clnt->cl_oneshot = 1;
8138 if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
8139 clnt->cl_discrtry = 1;
8141 @@ -268,24 +314,25 @@ rpc_clone_client(struct rpc_clnt *clnt)
8142 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
8145 - atomic_set(&new->cl_count, 1);
8146 - atomic_set(&new->cl_users, 0);
8147 + new->cl_parent = clnt;
8148 + /* Turn off autobind on clones */
8149 + new->cl_autobind = 0;
8150 + INIT_LIST_HEAD(&new->cl_tasks);
8151 + spin_lock_init(&new->cl_lock);
8152 + rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
8153 new->cl_metrics = rpc_alloc_iostats(clnt);
8154 if (new->cl_metrics == NULL)
8156 + kref_init(&new->cl_kref);
8157 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
8160 - new->cl_parent = clnt;
8161 - atomic_inc(&clnt->cl_count);
8162 - new->cl_xprt = xprt_get(clnt->cl_xprt);
8163 - /* Turn off autobind on clones */
8164 - new->cl_autobind = 0;
8165 - new->cl_oneshot = 0;
8167 - rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
8169 atomic_inc(&new->cl_auth->au_count);
8170 + xprt_get(clnt->cl_xprt);
8171 + kref_get(&clnt->cl_kref);
8172 + rpc_register_client(new);
8176 rpc_free_iostats(new->cl_metrics);
8177 @@ -298,86 +345,86 @@ out_no_clnt:
8180 * Properly shut down an RPC client, terminating all outstanding
8181 - * requests. Note that we must be certain that cl_oneshot and
8182 - * cl_dead are cleared, or else the client would be destroyed
8183 - * when the last task releases it.
8187 -rpc_shutdown_client(struct rpc_clnt *clnt)
8188 +void rpc_shutdown_client(struct rpc_clnt *clnt)
8190 - dprintk("RPC: shutting down %s client for %s, tasks=%d\n",
8191 - clnt->cl_protname, clnt->cl_server,
8192 - atomic_read(&clnt->cl_users));
8194 - while (atomic_read(&clnt->cl_users) > 0) {
8195 - /* Don't let rpc_release_client destroy us */
8196 - clnt->cl_oneshot = 0;
8197 - clnt->cl_dead = 0;
8198 + dprintk("RPC: shutting down %s client for %s\n",
8199 + clnt->cl_protname, clnt->cl_server);
8201 + while (!list_empty(&clnt->cl_tasks)) {
8202 rpc_killall_tasks(clnt);
8203 wait_event_timeout(destroy_wait,
8204 - !atomic_read(&clnt->cl_users), 1*HZ);
8207 - if (atomic_read(&clnt->cl_users) < 0) {
8208 - printk(KERN_ERR "RPC: rpc_shutdown_client clnt %p tasks=%d\n",
8209 - clnt, atomic_read(&clnt->cl_users));
8214 + list_empty(&clnt->cl_tasks), 1*HZ);
8217 - return rpc_destroy_client(clnt);
8218 + rpc_release_client(clnt);
8222 - * Delete an RPC client
8223 + * Free an RPC client
8226 -rpc_destroy_client(struct rpc_clnt *clnt)
8228 +rpc_free_client(struct kref *kref)
8230 - if (!atomic_dec_and_test(&clnt->cl_count))
8232 - BUG_ON(atomic_read(&clnt->cl_users) != 0);
8233 + struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
8235 dprintk("RPC: destroying %s client for %s\n",
8236 clnt->cl_protname, clnt->cl_server);
8237 - if (clnt->cl_auth) {
8238 - rpcauth_destroy(clnt->cl_auth);
8239 - clnt->cl_auth = NULL;
8241 if (!IS_ERR(clnt->cl_dentry)) {
8242 rpc_rmdir(clnt->cl_dentry);
8245 if (clnt->cl_parent != clnt) {
8246 - rpc_destroy_client(clnt->cl_parent);
8247 + rpc_release_client(clnt->cl_parent);
8250 if (clnt->cl_server != clnt->cl_inline_name)
8251 kfree(clnt->cl_server);
8253 + rpc_unregister_client(clnt);
8254 rpc_free_iostats(clnt->cl_metrics);
8255 clnt->cl_metrics = NULL;
8256 xprt_put(clnt->cl_xprt);
8263 - * Release an RPC client
8264 + * Free an RPC client
8267 +rpc_free_auth(struct kref *kref)
8269 + struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
8271 + if (clnt->cl_auth == NULL) {
8272 + rpc_free_client(kref);
8277 + * Note: RPCSEC_GSS may need to send NULL RPC calls in order to
8278 + * release remaining GSS contexts. This mechanism ensures
8279 + * that it can do so safely.
8282 + rpcauth_release(clnt->cl_auth);
8283 + clnt->cl_auth = NULL;
8284 + kref_put(kref, rpc_free_client);
8288 + * Release reference to the RPC client
8291 rpc_release_client(struct rpc_clnt *clnt)
8293 - dprintk("RPC: rpc_release_client(%p, %d)\n",
8294 - clnt, atomic_read(&clnt->cl_users));
8295 + dprintk("RPC: rpc_release_client(%p)\n", clnt);
8297 - if (!atomic_dec_and_test(&clnt->cl_users))
8299 - wake_up(&destroy_wait);
8300 - if (clnt->cl_oneshot || clnt->cl_dead)
8301 - rpc_destroy_client(clnt);
8302 + if (list_empty(&clnt->cl_tasks))
8303 + wake_up(&destroy_wait);
8304 + kref_put(&clnt->cl_kref, rpc_free_auth);
8308 @@ -468,82 +515,96 @@ void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
8309 rpc_restore_sigmask(oldset);
8313 - * New rpc_call implementation
8315 +struct rpc_task *rpc_do_run_task(struct rpc_clnt *clnt,
8316 + struct rpc_message *msg,
8318 + const struct rpc_call_ops *ops,
8321 + struct rpc_task *task, *ret;
8324 + task = rpc_new_task(clnt, flags, ops, data);
8325 + if (task == NULL) {
8326 + rpc_release_calldata(ops, data);
8327 + return ERR_PTR(-ENOMEM);
8330 + /* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */
8331 + rpc_task_sigmask(task, &oldset);
8332 + if (msg != NULL) {
8333 + rpc_call_setup(task, msg, 0);
8334 + if (task->tk_status != 0) {
8335 + ret = ERR_PTR(task->tk_status);
8336 + rpc_put_task(task);
8340 + atomic_inc(&task->tk_count);
8341 + rpc_execute(task);
8344 + rpc_restore_sigmask(&oldset);
8349 + * rpc_call_sync - Perform a synchronous RPC call
8350 + * @clnt: pointer to RPC client
8351 + * @msg: RPC call parameters
8352 + * @flags: RPC call flags
8354 int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
8356 struct rpc_task *task;
8360 - /* If this client is slain all further I/O fails */
8361 - if (clnt->cl_dead)
8365 BUG_ON(flags & RPC_TASK_ASYNC);
8367 - task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL);
8371 - /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
8372 - rpc_task_sigmask(task, &oldset);
8374 - /* Set up the call info struct and execute the task */
8375 - rpc_call_setup(task, msg, 0);
8376 - if (task->tk_status == 0) {
8377 - atomic_inc(&task->tk_count);
8378 - rpc_execute(task);
8380 + task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL);
8382 + return PTR_ERR(task);
8383 status = task->tk_status;
8385 - rpc_restore_sigmask(&oldset);
8390 - * New rpc_call implementation
8392 + * rpc_call_async - Perform an asynchronous RPC call
8393 + * @clnt: pointer to RPC client
8394 + * @msg: RPC call parameters
8395 + * @flags: RPC call flags
8396 + * @ops: RPC call ops
8397 + * @data: user call data
8400 rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
8401 const struct rpc_call_ops *tk_ops, void *data)
8403 struct rpc_task *task;
8407 - /* If this client is slain all further I/O fails */
8409 - if (clnt->cl_dead)
8412 - flags |= RPC_TASK_ASYNC;
8414 - /* Create/initialize a new RPC task */
8416 - if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
8419 - /* Mask signals on GSS_AUTH upcalls */
8420 - rpc_task_sigmask(task, &oldset);
8422 - rpc_call_setup(task, msg, 0);
8424 - /* Set up the call info struct and execute the task */
8425 - status = task->tk_status;
8427 - rpc_execute(task);
8429 - rpc_put_task(task);
8431 - rpc_restore_sigmask(&oldset);
8434 - rpc_release_calldata(tk_ops, data);
8436 + task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data);
8438 + return PTR_ERR(task);
8439 + rpc_put_task(task);
8444 + * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
8445 + * @clnt: pointer to RPC client
8446 + * @flags: RPC flags
8447 + * @ops: RPC call ops
8448 + * @data: user call data
8450 +struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
8451 + const struct rpc_call_ops *tk_ops,
8454 + return rpc_do_run_task(clnt, NULL, flags, tk_ops, data);
8456 +EXPORT_SYMBOL(rpc_run_task);
8459 rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
8460 @@ -745,7 +806,7 @@ call_reserveresult(struct rpc_task *task)
8462 call_allocate(struct rpc_task *task)
8464 - unsigned int slack = task->tk_auth->au_cslack;
8465 + unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack;
8466 struct rpc_rqst *req = task->tk_rqstp;
8467 struct rpc_xprt *xprt = task->tk_xprt;
8468 struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
8469 @@ -1273,9 +1334,9 @@ call_verify(struct rpc_task *task)
8470 * - if it isn't pointer subtraction in the NFS client may give
8473 - printk(KERN_WARNING
8474 - "call_verify: XDR representation not a multiple of"
8475 - " 4 bytes: 0x%x\n", task->tk_rqstp->rq_rcv_buf.len);
8476 + dprintk("RPC: %5u %s: XDR representation not a multiple of"
8477 + " 4 bytes: 0x%x\n", task->tk_pid, __FUNCTION__,
8478 + task->tk_rqstp->rq_rcv_buf.len);
8482 @@ -1283,7 +1344,8 @@ call_verify(struct rpc_task *task)
8483 p += 1; /* skip XID */
8485 if ((n = ntohl(*p++)) != RPC_REPLY) {
8486 - printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n);
8487 + dprintk("RPC: %5u %s: not an RPC reply: %x\n",
8488 + task->tk_pid, __FUNCTION__, n);
8491 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
8492 @@ -1334,7 +1396,8 @@ call_verify(struct rpc_task *task)
8493 "authentication.\n", task->tk_client->cl_server);
8496 - printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n);
8497 + dprintk("RPC: %5u %s: unknown auth error: %x\n",
8498 + task->tk_pid, __FUNCTION__, n);
8501 dprintk("RPC: %5u %s: call rejected %d\n",
8502 @@ -1342,7 +1405,8 @@ call_verify(struct rpc_task *task)
8505 if (!(p = rpcauth_checkverf(task, p))) {
8506 - printk(KERN_WARNING "call_verify: auth check failed\n");
8507 + dprintk("RPC: %5u %s: auth check failed\n",
8508 + task->tk_pid, __FUNCTION__);
8509 goto out_garbage; /* bad verifier, retry */
8511 len = p - (__be32 *)iov->iov_base - 1;
8512 @@ -1381,7 +1445,8 @@ call_verify(struct rpc_task *task)
8513 task->tk_pid, __FUNCTION__);
8516 - printk(KERN_WARNING "call_verify: server accept status: %x\n", n);
8517 + dprintk("RPC: %5u %s: server accept status: %x\n",
8518 + task->tk_pid, __FUNCTION__, n);
8522 @@ -1395,14 +1460,16 @@ out_garbage:
8524 return ERR_PTR(-EAGAIN);
8526 - printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
8530 rpc_exit(task, error);
8531 + dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,
8532 + __FUNCTION__, error);
8533 return ERR_PTR(error);
8535 - printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
8536 + dprintk("RPC: %5u %s: server reply was truncated.\n", task->tk_pid,
8541 @@ -1421,7 +1488,7 @@ static struct rpc_procinfo rpcproc_null = {
8542 .p_decode = rpcproc_decode_null,
8545 -int rpc_ping(struct rpc_clnt *clnt, int flags)
8546 +static int rpc_ping(struct rpc_clnt *clnt, int flags)
8548 struct rpc_message msg = {
8549 .rpc_proc = &rpcproc_null,
8550 @@ -1432,3 +1499,51 @@ int rpc_ping(struct rpc_clnt *clnt, int flags)
8551 put_rpccred(msg.rpc_cred);
8555 +struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags)
8557 + struct rpc_message msg = {
8558 + .rpc_proc = &rpcproc_null,
8561 + return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL);
8563 +EXPORT_SYMBOL(rpc_call_null);
8566 +void rpc_show_tasks(void)
8568 + struct rpc_clnt *clnt;
8569 + struct rpc_task *t;
8571 + spin_lock(&rpc_client_lock);
8572 + if (list_empty(&all_clients))
8574 + printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
8575 + "-rpcwait -action- ---ops--\n");
8576 + list_for_each_entry(clnt, &all_clients, cl_clients) {
8577 + if (list_empty(&clnt->cl_tasks))
8579 + spin_lock(&clnt->cl_lock);
8580 + list_for_each_entry(t, &clnt->cl_tasks, tk_task) {
8581 + const char *rpc_waitq = "none";
8583 + if (RPC_IS_QUEUED(t))
8584 + rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
8586 + printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
8588 + (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
8589 + t->tk_flags, t->tk_status,
8591 + (t->tk_client ? t->tk_client->cl_prog : 0),
8592 + t->tk_rqstp, t->tk_timeout,
8594 + t->tk_action, t->tk_ops);
8596 + spin_unlock(&clnt->cl_lock);
8599 + spin_unlock(&rpc_client_lock);
8602 diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
8603 index 5887457..22e25b5 100644
8604 --- a/net/sunrpc/rpc_pipe.c
8605 +++ b/net/sunrpc/rpc_pipe.c
8607 #include <linux/pagemap.h>
8608 #include <linux/mount.h>
8609 #include <linux/namei.h>
8610 -#include <linux/dnotify.h>
8611 +#include <linux/fsnotify.h>
8612 #include <linux/kernel.h>
8614 #include <asm/ioctls.h>
8615 @@ -344,7 +344,7 @@ rpc_info_open(struct inode *inode, struct file *file)
8616 mutex_lock(&inode->i_mutex);
8617 clnt = RPC_I(inode)->private;
8619 - atomic_inc(&clnt->cl_users);
8620 + kref_get(&clnt->cl_kref);
8623 single_release(inode, file);
8624 @@ -448,6 +448,15 @@ void rpc_put_mount(void)
8625 simple_release_fs(&rpc_mount, &rpc_mount_count);
8628 +static int rpc_delete_dentry(struct dentry *dentry)
8633 +static struct dentry_operations rpc_dentry_operations = {
8634 + .d_delete = rpc_delete_dentry,
8638 rpc_lookup_parent(char *path, struct nameidata *nd)
8640 @@ -506,7 +515,7 @@ rpc_get_inode(struct super_block *sb, int mode)
8641 * FIXME: This probably has races.
8644 -rpc_depopulate(struct dentry *parent)
8645 +rpc_depopulate(struct dentry *parent, int start, int eof)
8647 struct inode *dir = parent->d_inode;
8648 struct list_head *pos, *next;
8649 @@ -518,6 +527,10 @@ repeat:
8650 spin_lock(&dcache_lock);
8651 list_for_each_safe(pos, next, &parent->d_subdirs) {
8652 dentry = list_entry(pos, struct dentry, d_u.d_child);
8653 + if (!dentry->d_inode ||
8654 + dentry->d_inode->i_ino < start ||
8655 + dentry->d_inode->i_ino >= eof)
8657 spin_lock(&dentry->d_lock);
8658 if (!d_unhashed(dentry)) {
8659 dget_locked(dentry);
8660 @@ -533,11 +546,11 @@ repeat:
8664 - if (dentry->d_inode) {
8665 - rpc_close_pipes(dentry->d_inode);
8666 + if (S_ISREG(dentry->d_inode->i_mode))
8667 simple_unlink(dir, dentry);
8669 - inode_dir_notify(dir, DN_DELETE);
8670 + else if (S_ISDIR(dentry->d_inode->i_mode))
8671 + simple_rmdir(dir, dentry);
8676 @@ -560,6 +573,7 @@ rpc_populate(struct dentry *parent,
8677 dentry = d_alloc_name(parent, files[i].name);
8680 + dentry->d_op = &rpc_dentry_operations;
8681 mode = files[i].mode;
8682 inode = rpc_get_inode(dir->i_sb, mode);
8684 @@ -574,6 +588,7 @@ rpc_populate(struct dentry *parent,
8687 d_add(dentry, inode);
8688 + fsnotify_create(dir, dentry);
8690 mutex_unlock(&dir->i_mutex);
8692 @@ -595,7 +610,7 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry)
8693 inode->i_ino = iunique(dir->i_sb, 100);
8694 d_instantiate(dentry, inode);
8696 - inode_dir_notify(dir, DN_CREATE);
8697 + fsnotify_mkdir(dir, dentry);
8700 printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n",
8701 @@ -607,21 +622,14 @@ static int
8702 __rpc_rmdir(struct inode *dir, struct dentry *dentry)
8706 - shrink_dcache_parent(dentry);
8707 - if (d_unhashed(dentry))
8709 - if ((error = simple_rmdir(dir, dentry)) != 0)
8712 - inode_dir_notify(dir, DN_DELETE);
8716 + error = simple_rmdir(dir, dentry);
8722 static struct dentry *
8723 -rpc_lookup_create(struct dentry *parent, const char *name, int len)
8724 +rpc_lookup_create(struct dentry *parent, const char *name, int len, int exclusive)
8726 struct inode *dir = parent->d_inode;
8727 struct dentry *dentry;
8728 @@ -630,7 +638,9 @@ rpc_lookup_create(struct dentry *parent, const char *name, int len)
8729 dentry = lookup_one_len(name, parent, len);
8732 - if (dentry->d_inode) {
8733 + if (!dentry->d_inode)
8734 + dentry->d_op = &rpc_dentry_operations;
8735 + else if (exclusive) {
8737 dentry = ERR_PTR(-EEXIST);
8739 @@ -649,7 +659,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
8741 if ((error = rpc_lookup_parent(path, nd)) != 0)
8742 return ERR_PTR(error);
8743 - dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len);
8744 + dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len, 1);
8746 rpc_release_path(nd);
8748 @@ -681,7 +691,7 @@ out:
8749 rpc_release_path(&nd);
8752 - rpc_depopulate(dentry);
8753 + rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF);
8754 __rpc_rmdir(dir, dentry);
8757 @@ -701,7 +711,7 @@ rpc_rmdir(struct dentry *dentry)
8758 parent = dget_parent(dentry);
8759 dir = parent->d_inode;
8760 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
8761 - rpc_depopulate(dentry);
8762 + rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF);
8763 error = __rpc_rmdir(dir, dentry);
8765 mutex_unlock(&dir->i_mutex);
8766 @@ -716,10 +726,21 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
8767 struct inode *dir, *inode;
8768 struct rpc_inode *rpci;
8770 - dentry = rpc_lookup_create(parent, name, strlen(name));
8771 + dentry = rpc_lookup_create(parent, name, strlen(name), 0);
8774 dir = parent->d_inode;
8775 + if (dentry->d_inode) {
8776 + rpci = RPC_I(dentry->d_inode);
8777 + if (rpci->private != private ||
8778 + rpci->ops != ops ||
8779 + rpci->flags != flags) {
8781 + dentry = ERR_PTR(-EBUSY);
8783 + rpci->nkern_readwriters++;
8786 inode = rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR);
8789 @@ -730,7 +751,8 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
8790 rpci->private = private;
8791 rpci->flags = flags;
8793 - inode_dir_notify(dir, DN_CREATE);
8794 + rpci->nkern_readwriters = 1;
8795 + fsnotify_create(dir, dentry);
8798 mutex_unlock(&dir->i_mutex);
8799 @@ -754,13 +776,11 @@ rpc_unlink(struct dentry *dentry)
8800 parent = dget_parent(dentry);
8801 dir = parent->d_inode;
8802 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
8803 - if (!d_unhashed(dentry)) {
8805 - if (dentry->d_inode) {
8806 - rpc_close_pipes(dentry->d_inode);
8807 - error = simple_unlink(dir, dentry);
8809 - inode_dir_notify(dir, DN_DELETE);
8810 + if (--RPC_I(dentry->d_inode)->nkern_readwriters == 0) {
8811 + rpc_close_pipes(dentry->d_inode);
8812 + error = simple_unlink(dir, dentry);
8817 mutex_unlock(&dir->i_mutex);
8818 @@ -833,6 +853,7 @@ init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
8821 INIT_LIST_HEAD(&rpci->in_upcall);
8822 + INIT_LIST_HEAD(&rpci->in_downcall);
8823 INIT_LIST_HEAD(&rpci->pipe);
8825 init_waitqueue_head(&rpci->waitq);
8826 diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
8827 index 6c7aa8a..d1740db 100644
8828 --- a/net/sunrpc/rpcb_clnt.c
8829 +++ b/net/sunrpc/rpcb_clnt.c
8831 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
8834 +#include <linux/module.h>
8836 #include <linux/types.h>
8837 #include <linux/socket.h>
8838 #include <linux/kernel.h>
8839 @@ -184,8 +186,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
8840 .program = &rpcb_program,
8842 .authflavor = RPC_AUTH_UNIX,
8843 - .flags = (RPC_CLNT_CREATE_ONESHOT |
8844 - RPC_CLNT_CREATE_NOPING),
8845 + .flags = (RPC_CLNT_CREATE_NOPING |
8846 + RPC_CLNT_CREATE_INTR),
8849 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
8850 @@ -238,6 +240,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
8852 error = rpc_call_sync(rpcb_clnt, &msg, 0);
8854 + rpc_shutdown_client(rpcb_clnt);
8856 printk(KERN_WARNING "RPC: failed to contact local rpcbind "
8857 "server (errno %d).\n", -error);
8858 @@ -246,21 +249,20 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
8862 -#ifdef CONFIG_ROOT_NFS
8864 - * rpcb_getport_external - obtain the port for an RPC service on a given host
8865 + * rpcb_getport_sync - obtain the port for an RPC service on a given host
8866 * @sin: address of remote peer
8867 * @prog: RPC program number to bind
8868 * @vers: RPC version number to bind
8869 * @prot: transport protocol to use to make this request
8871 * Called from outside the RPC client in a synchronous task context.
8872 + * Uses default timeout parameters specified by underlying transport.
8874 - * For now, this supports only version 2 queries, but is used only by
8875 - * mount_clnt for NFS_ROOT.
8876 + * XXX: Needs to support IPv6, and rpcbind versions 3 and 4
8878 -int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog,
8879 - __u32 vers, int prot)
8880 +int rpcb_getport_sync(struct sockaddr_in *sin, __u32 prog,
8881 + __u32 vers, int prot)
8883 struct rpcbind_args map = {
8885 @@ -277,15 +279,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog,
8889 - dprintk("RPC: rpcb_getport_external(%u.%u.%u.%u, %u, %u, %d)\n",
8890 - NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
8891 + dprintk("RPC: %s(" NIPQUAD_FMT ", %u, %u, %d)\n",
8892 + __FUNCTION__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
8894 - sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
8895 + sprintf(hostname, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
8896 rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0);
8897 if (IS_ERR(rpcb_clnt))
8898 return PTR_ERR(rpcb_clnt);
8900 status = rpc_call_sync(rpcb_clnt, &msg, 0);
8901 + rpc_shutdown_client(rpcb_clnt);
8904 if (map.r_port != 0)
8905 @@ -294,16 +297,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog,
8910 +EXPORT_SYMBOL_GPL(rpcb_getport_sync);
8913 - * rpcb_getport - obtain the port for a given RPC service on a given host
8914 + * rpcb_getport_async - obtain the port for a given RPC service on a given host
8915 * @task: task that is waiting for portmapper request
8917 * This one can be called for an ongoing RPC request, and can be used in
8918 * an async (rpciod) context.
8920 -void rpcb_getport(struct rpc_task *task)
8921 +void rpcb_getport_async(struct rpc_task *task)
8923 struct rpc_clnt *clnt = task->tk_client;
8925 @@ -314,17 +317,17 @@ void rpcb_getport(struct rpc_task *task)
8926 struct sockaddr addr;
8929 - dprintk("RPC: %5u rpcb_getport(%s, %u, %u, %d)\n",
8930 - task->tk_pid, clnt->cl_server,
8931 - clnt->cl_prog, clnt->cl_vers, xprt->prot);
8932 + dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
8933 + task->tk_pid, __FUNCTION__,
8934 + clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
8936 /* Autobind on cloned rpc clients is discouraged */
8937 BUG_ON(clnt->cl_parent != clnt);
8939 if (xprt_test_and_set_binding(xprt)) {
8940 status = -EACCES; /* tell caller to check again */
8941 - dprintk("RPC: %5u rpcb_getport waiting for another binder\n",
8943 + dprintk("RPC: %5u %s: waiting for another binder\n",
8944 + task->tk_pid, __FUNCTION__);
8945 goto bailout_nowake;
8948 @@ -335,27 +338,28 @@ void rpcb_getport(struct rpc_task *task)
8949 /* Someone else may have bound if we slept */
8950 if (xprt_bound(xprt)) {
8952 - dprintk("RPC: %5u rpcb_getport already bound\n", task->tk_pid);
8953 + dprintk("RPC: %5u %s: already bound\n",
8954 + task->tk_pid, __FUNCTION__);
8955 goto bailout_nofree;
8958 if (rpcb_next_version[xprt->bind_index].rpc_proc == NULL) {
8959 xprt->bind_index = 0;
8960 status = -EACCES; /* tell caller to try again later */
8961 - dprintk("RPC: %5u rpcb_getport no more getport versions "
8962 - "available\n", task->tk_pid);
8963 + dprintk("RPC: %5u %s: no more getport versions available\n",
8964 + task->tk_pid, __FUNCTION__);
8965 goto bailout_nofree;
8967 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
8969 - dprintk("RPC: %5u rpcb_getport trying rpcbind version %u\n",
8970 - task->tk_pid, bind_version);
8971 + dprintk("RPC: %5u %s: trying rpcbind version %u\n",
8972 + task->tk_pid, __FUNCTION__, bind_version);
8974 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
8977 - dprintk("RPC: %5u rpcb_getport no memory available\n",
8979 + dprintk("RPC: %5u %s: no memory available\n",
8980 + task->tk_pid, __FUNCTION__);
8981 goto bailout_nofree;
8983 map->r_prog = clnt->cl_prog;
8984 @@ -373,16 +377,17 @@ void rpcb_getport(struct rpc_task *task)
8985 rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0);
8986 if (IS_ERR(rpcb_clnt)) {
8987 status = PTR_ERR(rpcb_clnt);
8988 - dprintk("RPC: %5u rpcb_getport rpcb_create failed, error %ld\n",
8989 - task->tk_pid, PTR_ERR(rpcb_clnt));
8990 + dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
8991 + task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt));
8995 child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map);
8996 + rpc_release_client(rpcb_clnt);
8997 if (IS_ERR(child)) {
8999 - dprintk("RPC: %5u rpcb_getport rpc_run_task failed\n",
9001 + dprintk("RPC: %5u %s: rpc_run_task failed\n",
9002 + task->tk_pid, __FUNCTION__);
9003 goto bailout_nofree;
9005 rpc_put_task(child);
9006 diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
9007 index 944d753..2ac43c4 100644
9008 --- a/net/sunrpc/sched.c
9009 +++ b/net/sunrpc/sched.c
9012 #define RPCDBG_FACILITY RPCDBG_SCHED
9013 #define RPC_TASK_MAGIC_ID 0xf00baa
9014 -static int rpc_task_id;
9018 @@ -40,7 +39,6 @@ static mempool_t *rpc_task_mempool __read_mostly;
9019 static mempool_t *rpc_buffer_mempool __read_mostly;
9021 static void __rpc_default_timer(struct rpc_task *task);
9022 -static void rpciod_killall(void);
9023 static void rpc_async_schedule(struct work_struct *);
9024 static void rpc_release_task(struct rpc_task *task);
9026 @@ -50,23 +48,13 @@ static void rpc_release_task(struct rpc_task *task);
9027 static RPC_WAITQ(delay_queue, "delayq");
9030 - * All RPC tasks are linked into this list
9032 -static LIST_HEAD(all_tasks);
9035 * rpciod-related stuff
9037 static DEFINE_MUTEX(rpciod_mutex);
9038 -static unsigned int rpciod_users;
9039 +static atomic_t rpciod_users = ATOMIC_INIT(0);
9040 struct workqueue_struct *rpciod_workqueue;
9043 - * Spinlock for other critical sections of code.
9045 -static DEFINE_SPINLOCK(rpc_sched_lock);
9048 * Disable the timer for a given RPC task. Should be called with
9049 * queue->lock and bh_disabled in order to avoid races within
9051 @@ -267,18 +255,33 @@ static int rpc_wait_bit_interruptible(void *word)
9056 +static void rpc_task_set_debuginfo(struct rpc_task *task)
9058 + static atomic_t rpc_pid;
9060 + task->tk_magic = RPC_TASK_MAGIC_ID;
9061 + task->tk_pid = atomic_inc_return(&rpc_pid);
9064 +static inline void rpc_task_set_debuginfo(struct rpc_task *task)
9069 static void rpc_set_active(struct rpc_task *task)
9071 + struct rpc_clnt *clnt;
9072 if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
9074 - spin_lock(&rpc_sched_lock);
9076 - task->tk_magic = RPC_TASK_MAGIC_ID;
9077 - task->tk_pid = rpc_task_id++;
9079 + rpc_task_set_debuginfo(task);
9080 /* Add to global list of all tasks */
9081 - list_add_tail(&task->tk_task, &all_tasks);
9082 - spin_unlock(&rpc_sched_lock);
9083 + clnt = task->tk_client;
9084 + if (clnt != NULL) {
9085 + spin_lock(&clnt->cl_lock);
9086 + list_add_tail(&task->tk_task, &clnt->cl_tasks);
9087 + spin_unlock(&clnt->cl_lock);
9092 @@ -818,6 +821,7 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
9093 if (tk_ops->rpc_call_prepare != NULL)
9094 task->tk_action = rpc_prepare_task;
9095 task->tk_calldata = calldata;
9096 + INIT_LIST_HEAD(&task->tk_task);
9098 /* Initialize retry counters */
9099 task->tk_garb_retry = 2;
9100 @@ -830,7 +834,7 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
9101 task->tk_workqueue = rpciod_workqueue;
9104 - atomic_inc(&clnt->cl_users);
9105 + kref_get(&clnt->cl_kref);
9106 if (clnt->cl_softrtry)
9107 task->tk_flags |= RPC_TASK_SOFT;
9109 @@ -860,9 +864,7 @@ static void rpc_free_task(struct rcu_head *rcu)
9113 - * Create a new task for the specified client. We have to
9114 - * clean up after an allocation failure, as the client may
9115 - * have specified "oneshot".
9116 + * Create a new task for the specified client.
9118 struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
9120 @@ -870,7 +872,7 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
9122 task = rpc_alloc_task();
9127 rpc_init_task(task, clnt, flags, tk_ops, calldata);
9129 @@ -878,16 +880,6 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
9130 task->tk_flags |= RPC_TASK_DYNAMIC;
9135 - /* Check whether to release the client */
9137 - printk("rpc_new_task: failed, users=%d, oneshot=%d\n",
9138 - atomic_read(&clnt->cl_users), clnt->cl_oneshot);
9139 - atomic_inc(&clnt->cl_users); /* pretend we were used ... */
9140 - rpc_release_client(clnt);
9146 @@ -920,11 +912,13 @@ static void rpc_release_task(struct rpc_task *task)
9148 dprintk("RPC: %5u release task\n", task->tk_pid);
9150 - /* Remove from global task list */
9151 - spin_lock(&rpc_sched_lock);
9152 - list_del(&task->tk_task);
9153 - spin_unlock(&rpc_sched_lock);
9155 + if (!list_empty(&task->tk_task)) {
9156 + struct rpc_clnt *clnt = task->tk_client;
9157 + /* Remove from client task list */
9158 + spin_lock(&clnt->cl_lock);
9159 + list_del(&task->tk_task);
9160 + spin_unlock(&clnt->cl_lock);
9162 BUG_ON (RPC_IS_QUEUED(task));
9164 /* Synchronously delete any running timer */
9165 @@ -939,29 +933,6 @@ static void rpc_release_task(struct rpc_task *task)
9170 - * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
9171 - * @clnt: pointer to RPC client
9172 - * @flags: RPC flags
9173 - * @ops: RPC call ops
9174 - * @data: user call data
9176 -struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
9177 - const struct rpc_call_ops *ops,
9180 - struct rpc_task *task;
9181 - task = rpc_new_task(clnt, flags, ops, data);
9182 - if (task == NULL) {
9183 - rpc_release_calldata(ops, data);
9184 - return ERR_PTR(-ENOMEM);
9186 - atomic_inc(&task->tk_count);
9187 - rpc_execute(task);
9190 -EXPORT_SYMBOL(rpc_run_task);
9193 * Kill all tasks for the given client.
9194 * XXX: kill their descendants as well?
9195 @@ -969,44 +940,25 @@ EXPORT_SYMBOL(rpc_run_task);
9196 void rpc_killall_tasks(struct rpc_clnt *clnt)
9198 struct rpc_task *rovr;
9199 - struct list_head *le;
9201 - dprintk("RPC: killing all tasks for client %p\n", clnt);
9203 + if (list_empty(&clnt->cl_tasks))
9205 + dprintk("RPC: killing all tasks for client %p\n", clnt);
9207 * Spin lock all_tasks to prevent changes...
9209 - spin_lock(&rpc_sched_lock);
9210 - alltask_for_each(rovr, le, &all_tasks) {
9211 + spin_lock(&clnt->cl_lock);
9212 + list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
9213 if (! RPC_IS_ACTIVATED(rovr))
9215 - if (!clnt || rovr->tk_client == clnt) {
9216 + if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
9217 rovr->tk_flags |= RPC_TASK_KILLED;
9218 rpc_exit(rovr, -EIO);
9219 rpc_wake_up_task(rovr);
9222 - spin_unlock(&rpc_sched_lock);
9225 -static void rpciod_killall(void)
9227 - unsigned long flags;
9229 - while (!list_empty(&all_tasks)) {
9230 - clear_thread_flag(TIF_SIGPENDING);
9231 - rpc_killall_tasks(NULL);
9232 - flush_workqueue(rpciod_workqueue);
9233 - if (!list_empty(&all_tasks)) {
9234 - dprintk("RPC: rpciod_killall: waiting for tasks "
9240 - spin_lock_irqsave(¤t->sighand->siglock, flags);
9241 - recalc_sigpending();
9242 - spin_unlock_irqrestore(¤t->sighand->siglock, flags);
9243 + spin_unlock(&clnt->cl_lock);
9247 @@ -1018,28 +970,27 @@ rpciod_up(void)
9248 struct workqueue_struct *wq;
9251 + if (atomic_inc_not_zero(&rpciod_users))
9254 mutex_lock(&rpciod_mutex);
9255 - dprintk("RPC: rpciod_up: users %u\n", rpciod_users);
9257 - if (rpciod_workqueue)
9260 - * If there's no pid, we should be the first user.
9262 - if (rpciod_users > 1)
9263 - printk(KERN_WARNING "rpciod_up: no workqueue, %u users??\n", rpciod_users);
9265 + /* Guard against races with rpciod_down() */
9266 + if (rpciod_workqueue != NULL)
9269 * Create the rpciod thread and wait for it to start.
9271 + dprintk("RPC: creating workqueue rpciod\n");
9273 wq = create_workqueue("rpciod");
9275 - printk(KERN_WARNING "rpciod_up: create workqueue failed, error=%d\n", error);
9281 rpciod_workqueue = wq;
9284 + atomic_inc(&rpciod_users);
9286 mutex_unlock(&rpciod_mutex);
9288 @@ -1048,59 +999,19 @@ out:
9292 + if (!atomic_dec_and_test(&rpciod_users))
9295 mutex_lock(&rpciod_mutex);
9296 - dprintk("RPC: rpciod_down sema %u\n", rpciod_users);
9297 - if (rpciod_users) {
9298 - if (--rpciod_users)
9301 - printk(KERN_WARNING "rpciod_down: no users??\n");
9302 + dprintk("RPC: destroying workqueue rpciod\n");
9304 - if (!rpciod_workqueue) {
9305 - dprintk("RPC: rpciod_down: Nothing to do!\n");
9307 + if (atomic_read(&rpciod_users) == 0 && rpciod_workqueue != NULL) {
9308 + destroy_workqueue(rpciod_workqueue);
9309 + rpciod_workqueue = NULL;
9313 - destroy_workqueue(rpciod_workqueue);
9314 - rpciod_workqueue = NULL;
9316 mutex_unlock(&rpciod_mutex);
9320 -void rpc_show_tasks(void)
9322 - struct list_head *le;
9323 - struct rpc_task *t;
9325 - spin_lock(&rpc_sched_lock);
9326 - if (list_empty(&all_tasks)) {
9327 - spin_unlock(&rpc_sched_lock);
9330 - printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
9331 - "-rpcwait -action- ---ops--\n");
9332 - alltask_for_each(t, le, &all_tasks) {
9333 - const char *rpc_waitq = "none";
9335 - if (RPC_IS_QUEUED(t))
9336 - rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
9338 - printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
9340 - (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
9341 - t->tk_flags, t->tk_status,
9343 - (t->tk_client ? t->tk_client->cl_prog : 0),
9344 - t->tk_rqstp, t->tk_timeout,
9346 - t->tk_action, t->tk_ops);
9348 - spin_unlock(&rpc_sched_lock);
9353 rpc_destroy_mempool(void)
9355 diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
9356 index 73075de..384c4ad 100644
9357 --- a/net/sunrpc/sunrpc_syms.c
9358 +++ b/net/sunrpc/sunrpc_syms.c
9359 @@ -28,15 +28,11 @@ EXPORT_SYMBOL(rpc_init_task);
9360 EXPORT_SYMBOL(rpc_sleep_on);
9361 EXPORT_SYMBOL(rpc_wake_up_next);
9362 EXPORT_SYMBOL(rpc_wake_up_task);
9363 -EXPORT_SYMBOL(rpciod_down);
9364 -EXPORT_SYMBOL(rpciod_up);
9365 -EXPORT_SYMBOL(rpc_new_task);
9366 EXPORT_SYMBOL(rpc_wake_up_status);
9368 /* RPC client functions */
9369 EXPORT_SYMBOL(rpc_clone_client);
9370 EXPORT_SYMBOL(rpc_bind_new_program);
9371 -EXPORT_SYMBOL(rpc_destroy_client);
9372 EXPORT_SYMBOL(rpc_shutdown_client);
9373 EXPORT_SYMBOL(rpc_killall_tasks);
9374 EXPORT_SYMBOL(rpc_call_sync);
9375 @@ -61,7 +57,7 @@ EXPORT_SYMBOL(rpcauth_unregister);
9376 EXPORT_SYMBOL(rpcauth_create);
9377 EXPORT_SYMBOL(rpcauth_lookupcred);
9378 EXPORT_SYMBOL(rpcauth_lookup_credcache);
9379 -EXPORT_SYMBOL(rpcauth_free_credcache);
9380 +EXPORT_SYMBOL(rpcauth_destroy_credcache);
9381 EXPORT_SYMBOL(rpcauth_init_credcache);
9382 EXPORT_SYMBOL(put_rpccred);
9384 @@ -156,6 +152,7 @@ init_sunrpc(void)
9385 cache_register(&ip_map_cache);
9386 cache_register(&unix_gid_cache);
9388 + rpcauth_init_module();
9392 @@ -163,6 +160,7 @@ out:
9394 cleanup_sunrpc(void)
9396 + rpcauth_remove_module();
9397 cleanup_socket_xprt();
9398 unregister_rpc_pipefs();
9399 rpc_destroy_mempool();
9400 diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
9401 index 5baf48d..64b9b8c 100644
9402 --- a/net/sunrpc/svcsock.c
9403 +++ b/net/sunrpc/svcsock.c
9404 @@ -644,6 +644,7 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
9405 struct msghdr msg = {
9406 .msg_flags = MSG_DONTWAIT,
9408 + struct sockaddr *sin;
9411 len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen,
9412 @@ -654,6 +655,19 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
9413 memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen);
9414 rqstp->rq_addrlen = svsk->sk_remotelen;
9416 + /* Destination address in request is needed for binding the
9417 + * source address in RPC callbacks later.
9419 + sin = (struct sockaddr *)&svsk->sk_local;
9420 + switch (sin->sa_family) {
9422 + rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr;
9425 + rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr;
9429 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
9430 svsk, iov[0].iov_base, iov[0].iov_len, len);
9432 @@ -1064,6 +1078,12 @@ svc_tcp_accept(struct svc_sock *svsk)
9434 memcpy(&newsvsk->sk_remote, sin, slen);
9435 newsvsk->sk_remotelen = slen;
9436 + err = kernel_getsockname(newsock, sin, &slen);
9437 + if (unlikely(err < 0)) {
9438 + dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err);
9439 + slen = offsetof(struct sockaddr, sa_data);
9441 + memcpy(&newsvsk->sk_local, sin, slen);
9443 svc_sock_received(newsvsk);
9445 diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
9446 index 5b05b73..c8c2edc 100644
9447 --- a/net/sunrpc/xprt.c
9448 +++ b/net/sunrpc/xprt.c
9449 @@ -127,7 +127,7 @@ static void xprt_clear_locked(struct rpc_xprt *xprt)
9450 clear_bit(XPRT_LOCKED, &xprt->state);
9451 smp_mb__after_clear_bit();
9453 - schedule_work(&xprt->task_cleanup);
9454 + queue_work(rpciod_workqueue, &xprt->task_cleanup);
9458 @@ -515,7 +515,7 @@ xprt_init_autodisconnect(unsigned long data)
9459 if (xprt_connecting(xprt))
9460 xprt_release_write(xprt, NULL);
9462 - schedule_work(&xprt->task_cleanup);
9463 + queue_work(rpciod_workqueue, &xprt->task_cleanup);
9466 spin_unlock(&xprt->transport_lock);
9467 @@ -886,27 +886,24 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
9470 * xprt_create_transport - create an RPC transport
9471 - * @proto: requested transport protocol
9472 - * @ap: remote peer address
9473 - * @size: length of address
9474 - * @to: timeout parameters
9475 + * @args: rpc transport creation arguments
9478 -struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to)
9479 +struct rpc_xprt *xprt_create_transport(struct rpc_xprtsock_create *args)
9481 struct rpc_xprt *xprt;
9482 struct rpc_rqst *req;
9485 + switch (args->proto) {
9487 - xprt = xs_setup_udp(ap, size, to);
9488 + xprt = xs_setup_udp(args);
9491 - xprt = xs_setup_tcp(ap, size, to);
9492 + xprt = xs_setup_tcp(args);
9495 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
9498 return ERR_PTR(-EIO);
9501 diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
9502 index cc33c58..4ae7eed 100644
9503 --- a/net/sunrpc/xprtsock.c
9504 +++ b/net/sunrpc/xprtsock.c
9505 @@ -235,6 +235,7 @@ struct sock_xprt {
9506 * Connection of transports
9508 struct delayed_work connect_worker;
9509 + struct sockaddr_storage addr;
9510 unsigned short port;
9513 @@ -653,8 +654,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
9515 dprintk("RPC: xs_destroy xprt %p\n", xprt);
9517 - cancel_delayed_work(&transport->connect_worker);
9518 - flush_scheduled_work();
9519 + cancel_rearming_delayed_work(&transport->connect_worker);
9521 xprt_disconnect(xprt);
9523 @@ -1001,7 +1001,7 @@ static void xs_tcp_state_change(struct sock *sk)
9524 /* Try to schedule an autoclose RPC calls */
9525 set_bit(XPRT_CLOSE_WAIT, &xprt->state);
9526 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
9527 - schedule_work(&xprt->task_cleanup);
9528 + queue_work(rpciod_workqueue, &xprt->task_cleanup);
9530 xprt_disconnect(xprt);
9532 @@ -1146,31 +1146,36 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
9533 sap->sin_port = htons(port);
9536 -static int xs_bindresvport(struct sock_xprt *transport, struct socket *sock)
9537 +static int xs_bind(struct sock_xprt *transport, struct socket *sock)
9539 struct sockaddr_in myaddr = {
9540 .sin_family = AF_INET,
9542 + struct sockaddr_in *sa;
9544 unsigned short port = transport->port;
9546 + if (!transport->xprt.resvport)
9548 + sa = (struct sockaddr_in *)&transport->addr;
9549 + myaddr.sin_addr = sa->sin_addr;
9551 myaddr.sin_port = htons(port);
9552 err = kernel_bind(sock, (struct sockaddr *) &myaddr,
9554 + if (!transport->xprt.resvport)
9557 transport->port = port;
9558 - dprintk("RPC: xs_bindresvport bound to port %u\n",
9563 if (port <= xprt_min_resvport)
9564 port = xprt_max_resvport;
9567 } while (err == -EADDRINUSE && port != transport->port);
9569 - dprintk("RPC: can't bind to reserved port (%d).\n", -err);
9570 + dprintk("RPC: xs_bind "NIPQUAD_FMT":%u: %s (%d)\n",
9571 + NIPQUAD(myaddr.sin_addr), port, err ? "failed" : "ok", err);
9575 @@ -1229,7 +1234,7 @@ static void xs_udp_connect_worker(struct work_struct *work)
9577 xs_reclassify_socket(sock);
9579 - if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
9580 + if (xs_bind(transport, sock)) {
9584 @@ -1316,7 +1321,7 @@ static void xs_tcp_connect_worker(struct work_struct *work)
9586 xs_reclassify_socket(sock);
9588 - if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
9589 + if (xs_bind(transport, sock)) {
9593 @@ -1410,18 +1415,16 @@ static void xs_connect(struct rpc_task *task)
9594 dprintk("RPC: xs_connect delayed xprt %p for %lu "
9596 xprt, xprt->reestablish_timeout / HZ);
9597 - schedule_delayed_work(&transport->connect_worker,
9598 - xprt->reestablish_timeout);
9599 + queue_delayed_work(rpciod_workqueue,
9600 + &transport->connect_worker,
9601 + xprt->reestablish_timeout);
9602 xprt->reestablish_timeout <<= 1;
9603 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
9604 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
9606 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
9607 - schedule_delayed_work(&transport->connect_worker, 0);
9609 - /* flush_scheduled_work can sleep... */
9610 - if (!RPC_IS_ASYNC(task))
9611 - flush_scheduled_work();
9612 + queue_delayed_work(rpciod_workqueue,
9613 + &transport->connect_worker, 0);
9617 @@ -1476,7 +1479,7 @@ static struct rpc_xprt_ops xs_udp_ops = {
9618 .set_buffer_size = xs_udp_set_buffer_size,
9619 .reserve_xprt = xprt_reserve_xprt_cong,
9620 .release_xprt = xprt_release_xprt_cong,
9621 - .rpcbind = rpcb_getport,
9622 + .rpcbind = rpcb_getport_async,
9623 .set_port = xs_set_port,
9624 .connect = xs_connect,
9625 .buf_alloc = rpc_malloc,
9626 @@ -1493,7 +1496,7 @@ static struct rpc_xprt_ops xs_udp_ops = {
9627 static struct rpc_xprt_ops xs_tcp_ops = {
9628 .reserve_xprt = xprt_reserve_xprt,
9629 .release_xprt = xs_tcp_release_xprt,
9630 - .rpcbind = rpcb_getport,
9631 + .rpcbind = rpcb_getport_async,
9632 .set_port = xs_set_port,
9633 .connect = xs_connect,
9634 .buf_alloc = rpc_malloc,
9635 @@ -1505,12 +1508,12 @@ static struct rpc_xprt_ops xs_tcp_ops = {
9636 .print_stats = xs_tcp_print_stats,
9639 -static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, unsigned int slot_table_size)
9640 +static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, unsigned int slot_table_size)
9642 struct rpc_xprt *xprt;
9643 struct sock_xprt *new;
9645 - if (addrlen > sizeof(xprt->addr)) {
9646 + if (args->addrlen > sizeof(xprt->addr)) {
9647 dprintk("RPC: xs_setup_xprt: address too large\n");
9648 return ERR_PTR(-EBADF);
9650 @@ -1532,8 +1535,10 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
9651 return ERR_PTR(-ENOMEM);
9654 - memcpy(&xprt->addr, addr, addrlen);
9655 - xprt->addrlen = addrlen;
9656 + memcpy(&xprt->addr, args->dstaddr, args->addrlen);
9657 + xprt->addrlen = args->addrlen;
9658 + if (args->srcaddr)
9659 + memcpy(&new->addr, args->srcaddr, args->addrlen);
9660 new->port = xs_get_random_port();
9663 @@ -1541,22 +1546,20 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
9666 * xs_setup_udp - Set up transport to use a UDP socket
9667 - * @addr: address of remote server
9668 - * @addrlen: length of address in bytes
9669 - * @to: timeout parameters
9670 + * @args: rpc transport creation arguments
9673 -struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
9674 +struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args)
9676 struct rpc_xprt *xprt;
9677 struct sock_xprt *transport;
9679 - xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
9680 + xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries);
9683 transport = container_of(xprt, struct sock_xprt, xprt);
9685 - if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
9686 + if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0)
9687 xprt_set_bound(xprt);
9689 xprt->prot = IPPROTO_UDP;
9690 @@ -1572,8 +1575,8 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
9692 xprt->ops = &xs_udp_ops;
9695 - xprt->timeout = *to;
9696 + if (args->timeout)
9697 + xprt->timeout = *args->timeout;
9699 xprt_set_timeout(&xprt->timeout, 5, 5 * HZ);
9701 @@ -1586,22 +1589,20 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
9704 * xs_setup_tcp - Set up transport to use a TCP socket
9705 - * @addr: address of remote server
9706 - * @addrlen: length of address in bytes
9707 - * @to: timeout parameters
9708 + * @args: rpc transport creation arguments
9711 -struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
9712 +struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args)
9714 struct rpc_xprt *xprt;
9715 struct sock_xprt *transport;
9717 - xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
9718 + xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
9721 transport = container_of(xprt, struct sock_xprt, xprt);
9723 - if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
9724 + if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0)
9725 xprt_set_bound(xprt);
9727 xprt->prot = IPPROTO_TCP;
9728 @@ -1616,8 +1617,8 @@ struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_
9730 xprt->ops = &xs_tcp_ops;
9733 - xprt->timeout = *to;
9734 + if (args->timeout)
9735 + xprt->timeout = *args->timeout;
9737 xprt_set_timeout(&xprt->timeout, 2, 60 * HZ);