]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.6.22-NFS_ALL.dif
- more strict values parser
[packages/kernel.git] / linux-2.6.22-NFS_ALL.dif
CommitLineData
8b272c0e
JR
1All of the above
2---
3 fs/lockd/host.c | 39 +
4 fs/lockd/mon.c | 2
5 fs/lockd/svc.c | 6
6 fs/nfs/Makefile | 4
7 fs/nfs/client.c | 28 -
8 fs/nfs/delegation.c | 186 +++--
9 fs/nfs/delegation.h | 26 -
10 fs/nfs/dir.c | 16
11 fs/nfs/direct.c | 34 +
12 fs/nfs/inode.c | 73 +-
13 fs/nfs/internal.h | 4
14 fs/nfs/mount_clnt.c | 169 +++--
15 fs/nfs/nfs2xdr.c | 6
16 fs/nfs/nfs3proc.c | 4
17 fs/nfs/nfs3xdr.c | 8
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 ++--
22 fs/nfs/nfsroot.c | 5
23 fs/nfs/pagelist.c | 60 +-
24 fs/nfs/read.c | 40 +
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
45 kernel/auditsc.c | 1
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(-)
61
62diff --git a/fs/lockd/host.c b/fs/lockd/host.c
63index 96070bf..572601e 100644
64--- a/fs/lockd/host.c
65+++ b/fs/lockd/host.c
66@@ -44,9 +44,8 @@ static struct nsm_handle * nsm_find(const struct sockaddr_in *sin,
67 */
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,
72- int hostname_len)
73+ int proto, int version, const char *hostname,
74+ int hostname_len, const struct sockaddr_in *ssin)
75 {
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;
80 int hash;
81
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",
88 hostname_len,
89@@ -91,6 +92,8 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
90 continue;
91 if (host->h_server != server)
92 continue;
93+ if (!nlm_cmp_addr(&host->h_saddr, ssin))
94+ continue;
95
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;
100 host->h_addr = *sin;
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)
107 */
108 nsm_unmonitor(host);
109
110- if ((clnt = host->h_rpcclnt) != NULL) {
111- if (atomic_read(&clnt->cl_users)) {
112- printk(KERN_WARNING
113- "lockd: active RPC handle\n");
114- clnt->cl_dead = 1;
115- } else {
116- rpc_destroy_client(host->h_rpcclnt);
117- }
118- }
119+ clnt = host->h_rpcclnt;
120+ if (clnt != NULL)
121+ rpc_shutdown_client(clnt);
122 kfree(host);
123 }
124
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)
128 {
129+ struct sockaddr_in ssin = {0};
130+
131 return nlm_lookup_host(0, sin, proto, version,
132- hostname, hostname_len);
133+ hostname, hostname_len, &ssin);
134 }
135
136 /*
137@@ -191,9 +191,12 @@ struct nlm_host *
138 nlmsvc_lookup_host(struct svc_rqst *rqstp,
139 const char *hostname, int hostname_len)
140 {
141+ struct sockaddr_in ssin = {0};
142+
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);
148 }
149
150 /*
151@@ -204,8 +207,9 @@ nlm_bind_host(struct nlm_host *host)
152 {
153 struct rpc_clnt *clnt;
154
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));
160
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,
171diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
172index 2102e2d..3353ed8 100644
173--- a/fs/lockd/mon.c
174+++ b/fs/lockd/mon.c
175@@ -61,6 +61,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
176 status);
177 else
178 status = 0;
179+ rpc_shutdown_client(clnt);
180 out:
181 return status;
182 }
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),
188 };
189
190 return rpc_create(&args);
191diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
192index 126b1bf..2680932 100644
193--- a/fs/lockd/svc.c
194+++ b/fs/lockd/svc.c
195@@ -123,9 +123,6 @@ lockd(struct svc_rqst *rqstp)
196 /* Process request with signals blocked, but allow SIGKILL. */
197 allow_signal(SIGKILL);
198
199- /* kick rpciod */
200- rpciod_up();
201-
202 dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");
203
204 if (!nlm_timeout)
205@@ -202,9 +199,6 @@ lockd(struct svc_rqst *rqstp)
206 /* Exit the RPC thread */
207 svc_exit_thread(rqstp);
208
209- /* release rpciod */
210- rpciod_down();
211-
212 /* Release module */
213 unlock_kernel();
214 module_put_and_exit(0);
215diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
216index f4580b4..b55cb23 100644
217--- a/fs/nfs/Makefile
218+++ b/fs/nfs/Makefile
219@@ -6,8 +6,8 @@ obj-$(CONFIG_NFS_FS) += nfs.o
220
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 \
230diff --git a/fs/nfs/client.c b/fs/nfs/client.c
231index 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,
235 int nfsversion)
236 {
237 struct nfs_client *clp;
238- int error;
239
240 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
241 goto error_0;
242
243- error = rpciod_up();
244- if (error < 0) {
245- dprintk("%s: couldn't start rpciod! Error = %d\n",
246- __FUNCTION__, error);
247- goto error_1;
248- }
249- __set_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
250-
251 if (nfsversion == 4) {
252 if (nfs_callback_up() < 0)
253 goto error_2;
254@@ -139,8 +130,6 @@ static struct nfs_client *nfs_alloc_client(const char *hostname,
255 #ifdef CONFIG_NFS_V4
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))
265 nfs_callback_down();
266 error_2:
267- rpciod_down();
268- __clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state);
269-error_1:
270 kfree(clp);
271 error_0:
272 return NULL;
273@@ -167,16 +153,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
274 #ifdef CONFIG_NFS_V4
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;
279-
280- sp = list_entry(clp->cl_unused.next,
281- struct nfs4_state_owner,
282- so_list);
283- list_del(&sp->so_list);
284- kfree(sp);
285- }
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);
290 #endif
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))
293 nfs_callback_down();
294
295- if (__test_and_clear_bit(NFS_CS_RPCIOD, &clp->cl_res_state))
296- rpciod_down();
297-
298 kfree(clp->cl_hostname);
299 kfree(clp);
300
301diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
302index 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)
306 kfree(delegation);
307 }
308
309+static void nfs_free_delegation_callback(struct rcu_head *head)
310+{
311+ struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
312+
313+ nfs_free_delegation(delegation);
314+}
315+
316 static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
317 {
318 struct inode *inode = state->inode;
319@@ -57,7 +64,7 @@ out_err:
320 return status;
321 }
322
323-static void nfs_delegation_claim_opens(struct inode *inode)
324+static void nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
325 {
326 struct nfs_inode *nfsi = NFS_I(inode);
327 struct nfs_open_context *ctx;
328@@ -72,9 +79,11 @@ again:
329 continue;
330 if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
331 continue;
332+ if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
333+ continue;
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);
338 if (err >= 0)
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;
343 int status = 0;
344
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);
348-
349 delegation = kmalloc(sizeof(*delegation), GFP_KERNEL);
350 if (delegation == NULL)
351 return -ENOMEM;
352@@ -131,10 +136,10 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
353 delegation->inode = inode;
354
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);
363 delegation = NULL;
364 } else {
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
367 status = -EIO;
368 }
369 }
370+
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);
375+
376 spin_unlock(&clp->cl_lock);
377 kfree(delegation);
378 return status;
379@@ -155,7 +166,7 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
380 int res = 0;
381
382 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid);
383- nfs_free_delegation(delegation);
384+ call_rcu(&delegation->rcu, nfs_free_delegation_callback);
385 return res;
386 }
387
388@@ -170,33 +181,55 @@ static void nfs_msync_inode(struct inode *inode)
389 /*
390 * Basic procedure for returning a delegation to the server
391 */
392-int __nfs_inode_return_delegation(struct inode *inode)
393+static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation)
394 {
395 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
396 struct nfs_inode *nfsi = NFS_I(inode);
397- struct nfs_delegation *delegation;
398- int res = 0;
399
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;
410- }
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);
417
418- if (delegation != NULL)
419- res = nfs_do_return_delegation(inode, delegation);
420- return res;
421+ return nfs_do_return_delegation(inode, delegation);
422+}
423+
424+static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid)
425+{
426+ struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
427+
428+ if (delegation == NULL)
429+ goto nomatch;
430+ if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data,
431+ sizeof(delegation->stateid.data)) != 0)
432+ goto nomatch;
433+ list_del_rcu(&delegation->super_list);
434+ nfsi->delegation_state = 0;
435+ rcu_assign_pointer(nfsi->delegation, NULL);
436+ return delegation;
437+nomatch:
438+ return NULL;
439+}
440+
441+int nfs_inode_return_delegation(struct inode *inode)
442+{
443+ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
444+ struct nfs_inode *nfsi = NFS_I(inode);
445+ struct nfs_delegation *delegation;
446+ int err = 0;
447+
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);
454+ }
455+ return err;
456 }
457
458 /*
459@@ -211,19 +244,23 @@ void nfs_return_all_delegations(struct super_block *sb)
460 if (clp == NULL)
461 return;
462 restart:
463- spin_lock(&clp->cl_lock);
464- list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
465+ rcu_read_lock();
466+ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
467 if (delegation->inode->i_sb != sb)
468 continue;
469 inode = igrab(delegation->inode);
470 if (inode == NULL)
471 continue;
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);
476+ rcu_read_unlock();
477+ if (delegation != NULL)
478+ __nfs_inode_return_delegation(inode, delegation);
479 iput(inode);
480 goto restart;
481 }
482- spin_unlock(&clp->cl_lock);
483+ rcu_read_unlock();
484 }
485
486 static int nfs_do_expire_all_delegations(void *ptr)
487@@ -234,22 +271,26 @@ static int nfs_do_expire_all_delegations(void *ptr)
488
489 allow_signal(SIGKILL);
490 restart:
491- spin_lock(&clp->cl_lock);
492 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
493 goto out;
494 if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
495 goto out;
496- list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
497+ rcu_read_lock();
498+ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
499 inode = igrab(delegation->inode);
500 if (inode == NULL)
501 continue;
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);
506+ rcu_read_unlock();
507+ if (delegation)
508+ __nfs_inode_return_delegation(inode, delegation);
509 iput(inode);
510 goto restart;
511 }
512+ rcu_read_unlock();
513 out:
514- spin_unlock(&clp->cl_lock);
515 nfs_put_client(clp);
516 module_put_and_exit(0);
517 }
518@@ -280,17 +321,21 @@ void nfs_handle_cb_pathdown(struct nfs_client *clp)
519 if (clp == NULL)
520 return;
521 restart:
522- spin_lock(&clp->cl_lock);
523- list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
524+ rcu_read_lock();
525+ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
526 inode = igrab(delegation->inode);
527 if (inode == NULL)
528 continue;
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);
533+ rcu_read_unlock();
534+ if (delegation != NULL)
535+ __nfs_inode_return_delegation(inode, delegation);
536 iput(inode);
537 goto restart;
538 }
539- spin_unlock(&clp->cl_lock);
540+ rcu_read_unlock();
541 }
542
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)
557 args->result = 0;
558- } else {
559- delegation = NULL;
560+ else
561 args->result = -ENOENT;
562- }
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
571 {
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) {
576+ rcu_read_lock();
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);
580 break;
581 }
582 }
583- spin_unlock(&clp->cl_lock);
584+ rcu_read_unlock();
585 return res;
586 }
587
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)
590 {
591 struct nfs_delegation *delegation;
592- spin_lock(&clp->cl_lock);
593- list_for_each_entry(delegation, &clp->cl_delegations, super_list)
594+ rcu_read_lock();
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);
598+ rcu_read_unlock();
599 }
600
601 /*
602@@ -399,39 +437,35 @@ void nfs_delegation_mark_reclaim(struct nfs_client *clp)
603 */
604 void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
605 {
606- struct nfs_delegation *delegation, *n;
607- LIST_HEAD(head);
608- spin_lock(&clp->cl_lock);
609- list_for_each_entry_safe(delegation, n, &clp->cl_delegations, super_list) {
610+ struct nfs_delegation *delegation;
611+restart:
612+ rcu_read_lock();
613+ list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
614 if ((delegation->flags & NFS_DELEGATION_NEED_RECLAIM) == 0)
615 continue;
616- list_move(&delegation->super_list, &head);
617- NFS_I(delegation->inode)->delegation = NULL;
618- NFS_I(delegation->inode)->delegation_state = 0;
619- }
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);
628+ rcu_read_unlock();
629+ if (delegation != NULL)
630+ call_rcu(&delegation->rcu, nfs_free_delegation_callback);
631+ goto restart;
632 }
633+ rcu_read_unlock();
634 }
635
636 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
637 {
638- struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
639 struct nfs_inode *nfsi = NFS_I(inode);
640 struct nfs_delegation *delegation;
641- int res = 0;
642+ int ret = 0;
643
644- if (nfsi->delegation_state == 0)
645- return 0;
646- spin_lock(&clp->cl_lock);
647- delegation = nfsi->delegation;
648+ rcu_read_lock();
649+ delegation = rcu_dereference(nfsi->delegation);
650 if (delegation != NULL) {
651 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data));
652- res = 1;
653+ ret = 1;
654 }
655- spin_unlock(&clp->cl_lock);
656- return res;
657+ rcu_read_unlock();
658+ return ret;
659 }
660diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
661index 2cfd4b2..5874ce7 100644
662--- a/fs/nfs/delegation.h
663+++ b/fs/nfs/delegation.h
664@@ -22,11 +22,12 @@ struct nfs_delegation {
665 long flags;
666 loff_t maxsize;
667 __u64 change_attr;
668+ struct rcu_head rcu;
669 };
670
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);
676
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);
679
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);
686
687 static inline int nfs_have_delegation(struct inode *inode, int flags)
688 {
689+ struct nfs_delegation *delegation;
690+ int ret = 0;
691+
692 flags &= FMODE_READ|FMODE_WRITE;
693- smp_rmb();
694- if ((NFS_I(inode)->delegation_state & flags) == flags)
695- return 1;
696- return 0;
697+ rcu_read_lock();
698+ delegation = rcu_dereference(NFS_I(inode)->delegation);
699+ if (delegation != NULL && (delegation->type & flags) == flags)
700+ ret = 1;
701+ rcu_read_unlock();
702+ return ret;
703 }
704
705-static inline int nfs_inode_return_delegation(struct inode *inode)
706-{
707- int err = 0;
708-
709- if (NFS_I(inode)->delegation != NULL)
710- err = __nfs_inode_return_delegation(inode);
711- return err;
712-}
713 #else
714 static inline int nfs_have_delegation(struct inode *inode, int flags)
715 {
716diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
717index c27258b..322141f 100644
718--- a/fs/nfs/dir.c
719+++ b/fs/nfs/dir.c
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;
722 }
723
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)
727 {
728 struct nfs_server *server = NFS_SERVER(dir);
729
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);
735 return 0;
736 }
737
738@@ -946,7 +945,7 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
739 res = ERR_PTR(error);
740 goto out_unlock;
741 }
742- error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr);
743+ error = nfs_reval_fsid(dir, &fattr);
744 if (error < 0) {
745 res = ERR_PTR(error);
746 goto out_unlock;
747@@ -1244,7 +1243,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
748 attr.ia_mode = mode;
749 attr.ia_valid = ATTR_MODE;
750
751- if (nd && (nd->flags & LOOKUP_CREATE))
752+ if ((nd->flags & LOOKUP_CREATE) != 0)
753 open_flags = nd->intent.open.flags;
754
755 lock_kernel();
756@@ -1535,7 +1534,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
757
758 lock_kernel();
759
760- page = alloc_page(GFP_KERNEL);
761+ page = alloc_page(GFP_HIGHUSER);
762 if (!page) {
763 unlock_kernel();
764 return -ENOMEM;
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;
768
769- spin_lock(&nfs_access_lru_lock);
770 restart:
771+ spin_lock(&nfs_access_lru_lock);
772 list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) {
773 struct inode *inode;
774
775@@ -1770,6 +1769,7 @@ remove_lru_entry:
776 clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags);
777 }
778 spin_unlock(&inode->i_lock);
779+ spin_unlock(&nfs_access_lru_lock);
780 iput(inode);
781 goto restart;
782 }
783diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
784index 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)
789 {
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;
794 unsigned int pgbase;
795 int result;
796@@ -295,9 +295,14 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
797 break;
798 }
799 if ((unsigned)result < data->npages) {
800- nfs_direct_release_pages(data->pagevec, result);
801- nfs_readdata_release(data);
802- break;
803+ bytes = result * PAGE_SIZE;
804+ if (bytes <= pgbase) {
805+ nfs_direct_release_pages(data->pagevec, result);
806+ nfs_readdata_release(data);
807+ break;
808+ }
809+ bytes -= pgbase;
810+ data->npages = result;
811 }
812
813 get_dreq(dreq);
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)
816 {
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;
821 unsigned int pgbase;
822 int result;
823@@ -630,9 +635,14 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
824 break;
825 }
826 if ((unsigned)result < data->npages) {
827- nfs_direct_release_pages(data->pagevec, result);
828- nfs_writedata_release(data);
829- break;
830+ bytes = result * PAGE_SIZE;
831+ if (bytes <= pgbase) {
832+ nfs_direct_release_pages(data->pagevec, result);
833+ nfs_writedata_release(data);
834+ break;
835+ }
836+ bytes -= pgbase;
837+ data->npages = result;
838 }
839
840 get_dreq(dreq);
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);
843
844 if (nr_segs != 1)
845- return -EINVAL;
846-
847- if (count < 0)
848 goto out;
849+
850 retval = -EFAULT;
851 if (!access_ok(VERIFY_WRITE, buf, count))
852 goto out;
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)
856 {
857- ssize_t retval;
858+ ssize_t retval = -EINVAL;
859 struct file *file = iocb->ki_filp;
860 struct address_space *mapping = file->f_mapping;
861 /* XXX: temporary */
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);
864
865 if (nr_segs != 1)
866- return -EINVAL;
867+ goto out;
868
869 retval = generic_write_checks(file, &pos, &count, 0);
870 if (retval)
871diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
872index bd9f5a8..3d9fccf 100644
873--- a/fs/nfs/inode.c
874+++ b/fs/nfs/inode.c
875@@ -461,14 +461,14 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
876
877 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
878 if (ctx != NULL) {
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);
885 ctx->state = NULL;
886 ctx->lockowner = current->files;
887 ctx->error = 0;
888 ctx->dir_cookie = 0;
889+ kref_init(&ctx->kref);
890 }
891 return ctx;
892 }
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)
895 {
896 if (ctx != NULL)
897- atomic_inc(&ctx->count);
898+ kref_get(&ctx->kref);
899 return ctx;
900 }
901
902-void put_nfs_open_context(struct nfs_open_context *ctx)
903+static void nfs_free_open_context(struct kref *kref)
904 {
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);
911- }
912- if (ctx->state != NULL)
913- nfs4_close_state(ctx->state, ctx->mode);
914- if (ctx->cred != NULL)
915- put_rpccred(ctx->cred);
916- dput(ctx->dentry);
917- mntput(ctx->vfsmnt);
918- kfree(ctx);
919+ struct nfs_open_context *ctx = container_of(kref,
920+ struct nfs_open_context, kref);
921+
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);
927 }
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);
934+ kfree(ctx);
935+}
936+
937+void put_nfs_open_context(struct nfs_open_context *ctx)
938+{
939+ kref_put(&ctx->kref, nfs_free_open_context);
940 }
941
942 /*
943@@ -961,8 +967,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
944 goto out_changed;
945
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;
953
954@@ -1066,8 +1072,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
955 invalid &= ~NFS_INO_INVALID_DATA;
956 if (data_stable)
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;
963
964 return 0;
965 out_changed:
966@@ -1103,27 +1111,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
967 */
968 void nfs4_clear_inode(struct inode *inode)
969 {
970- struct nfs_inode *nfsi = NFS_I(inode);
971-
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;
979-
980- state = list_entry(nfsi->open_states.next,
981- struct nfs4_state,
982- inode_states);
983- dprintk("%s(%s/%Ld): found unclaimed NFSv4 state %p\n",
984- __FUNCTION__,
985- inode->i_sb->s_id,
986- (long long)NFS_FILEID(inode),
987- state);
988- BUG_ON(atomic_read(&state->count) != 1);
989- nfs4_close_state(state, state->state);
990- }
991 }
992 #endif
993
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;
996
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);
1006- nfsi->ndirty = 0;
1007 nfsi->ncommit = 0;
1008 nfsi->npages = 0;
1009 nfs4_init_once(nfsi);
1010diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
1011index 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)
1015 /*
1016 * Calculate the number of 512byte blocks used.
1017 */
1018-static inline unsigned long nfs_calc_block_size(u64 tsize)
1019+static inline blkcnt_t nfs_calc_block_size(u64 tsize)
1020 {
1021- loff_t used = (tsize + 511) >> 9;
1022+ blkcnt_t used = (tsize + 511) >> 9;
1023 return (used > ULONG_MAX) ? ULONG_MAX : used;
1024 }
1025
1026diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
1027index ca5a266..8afd9f7 100644
1028--- a/fs/nfs/mount_clnt.c
1029+++ b/fs/nfs/mount_clnt.c
1030@@ -1,7 +1,5 @@
1031 /*
1032- * linux/fs/nfs/mount_clnt.c
1033- *
1034- * MOUNT client to support NFSroot.
1035+ * In-kernel MOUNT protocol client
1036 *
1037 * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
1038 */
1039@@ -18,33 +16,31 @@
1040 #include <linux/nfs_fs.h>
1041
1042 #ifdef RPC_DEBUG
1043-# define NFSDBG_FACILITY NFSDBG_ROOT
1044+# define NFSDBG_FACILITY NFSDBG_MOUNT
1045 #endif
1046
1047-/*
1048-#define MOUNT_PROGRAM 100005
1049-#define MOUNT_VERSION 1
1050-#define MOUNT_MNT 1
1051-#define MOUNT_UMNT 3
1052- */
1053-
1054-static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *,
1055- int, int);
1056 static struct rpc_program mnt_program;
1057
1058 struct mnt_fhstatus {
1059- unsigned int status;
1060- struct nfs_fh * fh;
1061+ u32 status;
1062+ struct nfs_fh *fh;
1063 };
1064
1065-/*
1066- * Obtain an NFS file handle for the given host and path
1067+/**
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
1076+ *
1077+ * Uses default timeout parameters specified by underlying transport.
1078 */
1079-int
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)
1084 {
1085- struct rpc_clnt *mnt_clnt;
1086 struct mnt_fhstatus result = {
1087 .fh = fh
1088 };
1089@@ -52,16 +48,25 @@ nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
1090 .rpc_argp = path,
1091 .rpc_resp = &result,
1092 };
1093- char hostname[32];
1094+ struct rpc_create_args args = {
1095+ .protocol = protocol,
1096+ .address = addr,
1097+ .addrsize = len,
1098+ .servername = hostname,
1099+ .program = &mnt_program,
1100+ .version = version,
1101+ .authflavor = RPC_AUTH_UNIX,
1102+ .flags = RPC_CLNT_CREATE_INTR,
1103+ };
1104+ struct rpc_clnt *mnt_clnt;
1105 int status;
1106
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);
1111
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;
1118
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];
1123
1124 status = rpc_call_sync(mnt_clnt, &msg, 0);
1125- return status < 0? status : (result.status? -EACCES : 0);
1126-}
1127+ rpc_shutdown_client(mnt_clnt);
1128
1129-static struct rpc_clnt *
1130-mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
1131- int protocol)
1132-{
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),
1143- };
1144+ if (status < 0)
1145+ goto out_call_err;
1146+ if (result.status != 0)
1147+ goto out_mnt_err;
1148+
1149+ dprintk("NFS: MNT request succeeded\n");
1150+ status = 0;
1151+
1152+out:
1153+ return status;
1154+
1155+out_clnt_err:
1156+ status = PTR_ERR(mnt_clnt);
1157+ dprintk("NFS: failed to create RPC client, status=%d\n", status);
1158+ goto out;
1159+
1160+out_call_err:
1161+ dprintk("NFS: failed to start MNT request, status=%d\n", status);
1162+ goto out;
1163
1164- return rpc_create(&args);
1165+out_mnt_err:
1166+ dprintk("NFS: MNT server returned result %d\n", result.status);
1167+ status = -EACCES;
1168+ goto out;
1169 }
1170
1171 /*
1172 * XDR encode/decode functions for MOUNT
1173 */
1174-static int
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,
1177+ const char *path)
1178 {
1179 p = xdr_encode_string(p, path);
1180
1181@@ -103,8 +114,8 @@ xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, const char *path)
1182 return 0;
1183 }
1184
1185-static int
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)
1189 {
1190 struct nfs_fh *fh = res->fh;
1191
1192@@ -115,8 +126,8 @@ xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
1193 return 0;
1194 }
1195
1196-static int
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)
1200 {
1201 struct nfs_fh *fh = res->fh;
1202
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)
1206
1207-static struct rpc_procinfo mnt_procedures[] = {
1208-[MNTPROC_MNT] = {
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[] = {
1217+ [MNTPROC_MNT] = {
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",
1225 },
1226 };
1227
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",
1245 },
1246 };
1247
1248
1249-static struct rpc_version mnt_version1 = {
1250- .number = 1,
1251- .nrprocs = 2,
1252- .procs = mnt_procedures
1253+static struct rpc_version mnt_version1 = {
1254+ .number = 1,
1255+ .nrprocs = 2,
1256+ .procs = mnt_procedures,
1257 };
1258
1259-static struct rpc_version mnt_version3 = {
1260- .number = 3,
1261- .nrprocs = 2,
1262- .procs = mnt3_procedures
1263+static struct rpc_version mnt_version3 = {
1264+ .number = 3,
1265+ .nrprocs = 2,
1266+ .procs = mnt3_procedures,
1267 };
1268
1269-static struct rpc_version * mnt_version[] = {
1270+static struct rpc_version *mnt_version[] = {
1271 NULL,
1272 &mnt_version1,
1273 NULL,
1274 &mnt_version3,
1275 };
1276
1277-static struct rpc_stat mnt_stats;
1278+static struct rpc_stat mnt_stats;
1279
1280-static struct rpc_program mnt_program = {
1281+static struct rpc_program mnt_program = {
1282 .name = "mount",
1283 .number = NFS_MNT_PROGRAM,
1284 .nrvers = ARRAY_SIZE(mnt_version),
1285diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
1286index 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)
1290 static int
1291 nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
1292 {
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)
1300 {
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;
1306
1307@@ -541,7 +541,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
1308 static int
1309 nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
1310 {
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;
1314
1315 p = xdr_encode_fhandle(p, args->fh);
1316diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
1317index 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);
1324- if (status == 0)
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);
1329 }
1330 if (status != 0)
1331diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
1332index 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
1336 static int
1337 nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
1338 {
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;
1343
1344@@ -458,7 +458,7 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
1345 static int
1346 nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
1347 {
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;
1352
1353@@ -643,7 +643,7 @@ static int
1354 nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
1355 struct nfs3_getaclargs *args)
1356 {
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;
1360
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)
1363 static int
1364 nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
1365 {
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;
1369
1370 p = xdr_encode_fhandle(p, args->fh);
1371diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
1372index 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;
1377 }
1378
1379+struct nfs_unique_id {
1380+ struct rb_node rb_node;
1381+ __u64 id;
1382+};
1383+
1384 /*
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.
1388 */
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;
1398
1399 struct rpc_cred *so_cred; /* Associated cred */
1400+
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
1408 int ls_flags;
1409 struct nfs_seqid_counter ls_seqid;
1410- u32 ls_id;
1411+ struct nfs_unique_id ls_id;
1412 nfs4_stateid ls_stateid;
1413 atomic_t ls_count;
1414 };
1415@@ -116,7 +123,10 @@ struct nfs4_lock_state {
1416 /* bits for nfs4_state->flags */
1417 enum {
1418 LK_STATE_IN_USE,
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 */
1424 };
1425
1426 struct nfs4_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 */
1430
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 */
1435
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) */
1444 atomic_t count;
1445 };
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 *);
1456
1457 /* nfs4state.c */
1458 struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp);
1459-extern u32 nfs4_alloc_lockowner_id(struct nfs_client *);
1460
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;
1472
1473 #else
1474
1475-#define nfs4_close_state(a, b) do { } while (0)
1476+#define nfs4_close_state(a, b, c) do { } while (0)
1477
1478 #endif /* CONFIG_NFS_V4 */
1479 #endif /* __LINUX_FS_NFS_NFS4_FS.H */
1480diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
1481index 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);
1489
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)
1493 }
1494
1495 struct nfs4_opendata {
1496- atomic_t count;
1497+ struct kref kref;
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;
1505+ struct path path;
1506 struct dentry *dir;
1507 struct nfs4_state_owner *owner;
1508+ struct nfs4_state *state;
1509 struct iattr attrs;
1510 unsigned long timestamp;
1511+ unsigned int rpc_done : 1;
1512 int rpc_status;
1513 int cancelled;
1514 };
1515
1516-static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
1517+
1518+static void nfs4_init_opendata_res(struct nfs4_opendata *p)
1519+{
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);
1525+}
1526+
1527+static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
1528 struct nfs4_state_owner *sp, int flags,
1529 const struct iattr *attrs)
1530 {
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)
1539 goto err_free;
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);
1544 p->dir = parent;
1545 p->owner = sp;
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;
1564 s[0] = jiffies;
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);
1571 return p;
1572 err_free:
1573 kfree(p);
1574@@ -282,27 +292,25 @@ err:
1575 return NULL;
1576 }
1577
1578-static void nfs4_opendata_free(struct nfs4_opendata *p)
1579+static void nfs4_opendata_free(struct kref *kref)
1580 {
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);
1584- dput(p->dir);
1585- dput(p->dentry);
1586- kfree(p);
1587- }
1588+ struct nfs4_opendata *p = container_of(kref,
1589+ struct nfs4_opendata, kref);
1590+
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);
1595+ dput(p->dir);
1596+ dput(p->path.dentry);
1597+ mntput(p->path.mnt);
1598+ kfree(p);
1599 }
1600
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)
1605 {
1606- struct rpc_task *task;
1607-
1608- if (!(task = rpc_new_task(clnt, RPC_TASK_ASYNC, tk_ops, calldata)))
1609- return -ENOMEM;
1610- rpc_execute(task);
1611- return 0;
1612+ if (p != NULL)
1613+ kref_put(&p->kref, nfs4_opendata_free);
1614 }
1615
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)
1618 return ret;
1619 }
1620
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)
1623+{
1624+ int ret = 0;
1625+ switch (mode & (FMODE_READ|FMODE_WRITE|O_EXCL)) {
1626+ case FMODE_READ:
1627+ ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0;
1628+ ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
1629+ break;
1630+ case FMODE_WRITE:
1631+ ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0;
1632+ ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
1633+ break;
1634+ case FMODE_READ|FMODE_WRITE:
1635+ ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
1636+ }
1637+ return ret;
1638+}
1639+
1640+static int can_open_delegated(struct nfs_delegation *delegation, mode_t open_flags)
1641+{
1642+ if ((delegation->type & open_flags) != open_flags)
1643+ return 0;
1644+ if (delegation->flags & NFS_DELEGATION_NEED_RECLAIM)
1645+ return 0;
1646+ return 1;
1647+}
1648+
1649+static void update_open_stateflags(struct nfs4_state *state, mode_t open_flags)
1650 {
1651 switch (open_flags) {
1652 case FMODE_WRITE:
1653@@ -328,41 +363,176 @@ static inline void update_open_stateflags(struct nfs4_state *state, mode_t open_
1654 case FMODE_READ|FMODE_WRITE:
1655 state->n_rdwr++;
1656 }
1657+ nfs4_state_set_mode_locked(state, state->state | open_flags);
1658 }
1659
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)
1662 {
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) {
1668+ case FMODE_READ:
1669+ set_bit(NFS_O_RDONLY_STATE, &state->flags);
1670+ break;
1671+ case FMODE_WRITE:
1672+ set_bit(NFS_O_WRONLY_STATE, &state->flags);
1673+ break;
1674+ case FMODE_READ|FMODE_WRITE:
1675+ set_bit(NFS_O_RDWR_STATE, &state->flags);
1676+ }
1677+}
1678+
1679+static void nfs_set_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
1680+{
1681+ write_seqlock(&state->seqlock);
1682+ nfs_set_open_stateid_locked(state, stateid, open_flags);
1683+ write_sequnlock(&state->seqlock);
1684+}
1685
1686+static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stateid, nfs4_stateid *deleg_stateid, int open_flags)
1687+{
1688 open_flags &= (FMODE_READ|FMODE_WRITE);
1689- /* Protect against nfs4_find_state_byowner() */
1690+ /*
1691+ * Protect the call to nfs4_state_set_mode_locked and
1692+ * serialise the stateid update
1693+ */
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);
1698+ }
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);
1709 }
1710
1711+static void nfs4_return_incompatible_delegation(struct inode *inode, mode_t open_flags)
1712+{
1713+ struct nfs_delegation *delegation;
1714+
1715+ rcu_read_lock();
1716+ delegation = rcu_dereference(NFS_I(inode)->delegation);
1717+ if (delegation == NULL || (delegation->type & open_flags) == open_flags) {
1718+ rcu_read_unlock();
1719+ return;
1720+ }
1721+ rcu_read_unlock();
1722+ nfs_inode_return_delegation(inode);
1723+}
1724+
1725+static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
1726+{
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;
1733+
1734+ rcu_read_lock();
1735+ delegation = rcu_dereference(nfsi->delegation);
1736+ for (;;) {
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;
1744+ }
1745+ spin_unlock(&state->owner->so_lock);
1746+ }
1747+ if (delegation == NULL)
1748+ break;
1749+ if (!can_open_delegated(delegation, open_mode))
1750+ break;
1751+ /* Save the delegation */
1752+ memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data));
1753+ rcu_read_unlock();
1754+ lock_kernel();
1755+ ret = _nfs4_do_access(state->inode, state->owner->so_cred, open_mode);
1756+ unlock_kernel();
1757+ if (ret != 0)
1758+ goto out;
1759+ ret = -EAGAIN;
1760+ rcu_read_lock();
1761+ delegation = rcu_dereference(nfsi->delegation);
1762+ /* If no delegation, try a cached open */
1763+ if (delegation == NULL)
1764+ continue;
1765+ /* Is the delegation still valid? */
1766+ if (memcmp(stateid.data, delegation->stateid.data, sizeof(stateid.data)) != 0)
1767+ continue;
1768+ rcu_read_unlock();
1769+ update_open_stateid(state, NULL, &stateid, open_mode);
1770+ goto out_return_state;
1771+ }
1772+ rcu_read_unlock();
1773+out:
1774+ return ERR_PTR(ret);
1775+out_return_state:
1776+ atomic_inc(&state->count);
1777+ return state;
1778+}
1779+
1780 static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
1781 {
1782 struct inode *inode;
1783 struct nfs4_state *state = NULL;
1784+ struct nfs_delegation *delegation;
1785+ nfs4_stateid *deleg_stateid = NULL;
1786+ int ret;
1787
1788- if (!(data->f_attr.valid & NFS_ATTR_FATTR))
1789+ if (!data->rpc_done) {
1790+ state = nfs4_try_open_cached(data);
1791 goto out;
1792+ }
1793+
1794+ ret = -EAGAIN;
1795+ if (!(data->f_attr.valid & NFS_ATTR_FATTR))
1796+ goto err;
1797 inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr);
1798+ ret = PTR_ERR(inode);
1799 if (IS_ERR(inode))
1800- goto out;
1801+ goto err;
1802+ ret = -ENOMEM;
1803 state = nfs4_get_open_state(inode, data->owner);
1804 if (state == NULL)
1805- goto put_inode;
1806- update_open_stateid(state, &data->o_res.stateid, data->o_arg.open_flags);
1807-put_inode:
1808+ goto err_put_inode;
1809+ if (data->o_res.delegation_type != 0) {
1810+ int delegation_flags = 0;
1811+
1812+ rcu_read_lock();
1813+ delegation = rcu_dereference(NFS_I(inode)->delegation);
1814+ if (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,
1820+ &data->o_res);
1821+ else
1822+ nfs_inode_reclaim_delegation(state->inode,
1823+ data->owner->so_cred,
1824+ &data->o_res);
1825+ }
1826+ rcu_read_lock();
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();
1832 iput(inode);
1833 out:
1834 return state;
1835+err_put_inode:
1836+ iput(inode);
1837+err:
1838+ return ERR_PTR(ret);
1839 }
1840
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);
1844 }
1845
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)
1848 {
1849+ struct nfs4_state *newstate;
1850 int ret;
1851
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);
1857 if (ret != 0)
1858 return ret;
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);
1865+ *res = newstate;
1866 return 0;
1867 }
1868
1869 static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *state)
1870 {
1871- nfs4_stateid stateid;
1872 struct nfs4_state *newstate;
1873- int mode = 0;
1874- int delegation = 0;
1875 int ret;
1876
1877 /* memory barrier prior to reading state->n_* */
1878+ clear_bit(NFS_DELEGATED_STATE, &state->flags);
1879 smp_rmb();
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);
1883 if (ret != 0)
1884 return ret;
1885- mode |= FMODE_READ|FMODE_WRITE;
1886- if (opendata->o_res.delegation_type != 0)
1887- delegation = opendata->o_res.delegation_type;
1888- smp_rmb();
1889+ if (newstate != state)
1890+ return -ESTALE;
1891 }
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);
1895 if (ret != 0)
1896 return ret;
1897- mode |= FMODE_WRITE;
1898- if (opendata->o_res.delegation_type != 0)
1899- delegation = opendata->o_res.delegation_type;
1900- smp_rmb();
1901+ if (newstate != state)
1902+ return -ESTALE;
1903 }
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);
1907 if (ret != 0)
1908 return ret;
1909- mode |= FMODE_READ;
1910+ if (newstate != state)
1911+ return -ESTALE;
1912 }
1913- clear_bit(NFS_DELEGATED_STATE, &state->flags);
1914- if (mode == 0)
1915- return 0;
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);
1930- else
1931- nfs_inode_reclaim_delegation(newstate->inode,
1932- opendata->owner->so_cred,
1933- &opendata->o_res);
1934- }
1935- nfs4_close_state(newstate, opendata->o_arg.open_flags);
1936+ /*
1937+ * We may have performed cached opens for all three recoveries.
1938+ * Check if we need to update the current stateid.
1939+ */
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);
1946 }
1947- if (newstate != state)
1948- return -ESTALE;
1949 return 0;
1950 }
1951
1952@@ -462,41 +619,37 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
1953 * OPEN_RECLAIM:
1954 * reclaim state on the server after a reboot.
1955 */
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)
1958 {
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;
1963 int status;
1964
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);
1970- return 0;
1971- }
1972- delegation_type = delegation->type;
1973- }
1974- opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL);
1975+ opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
1976 if (opendata == NULL)
1977 return -ENOMEM;
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);
1981+ rcu_read_lock();
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);
1990 return status;
1991 }
1992
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)
1995 {
1996 struct nfs_server *server = NFS_SERVER(state->inode);
1997 struct nfs4_exception exception = { };
1998 int err;
1999 do {
2000- err = _nfs4_do_open_reclaim(sp, state, dentry);
2001+ err = _nfs4_do_open_reclaim(ctx, state);
2002 if (err != -NFS4ERR_DELAY)
2003 break;
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);
2007 if (IS_ERR(ctx))
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);
2012 return ret;
2013 }
2014
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)
2017 {
2018 struct nfs4_state_owner *sp = state->owner;
2019 struct nfs4_opendata *opendata;
2020 int ret;
2021
2022- if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
2023- return 0;
2024- opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL);
2025+ opendata = nfs4_opendata_alloc(&ctx->path, sp, 0, NULL);
2026 if (opendata == NULL)
2027 return -ENOMEM;
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);
2035 return ret;
2036 }
2037
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)
2040 {
2041 struct nfs4_exception exception = { };
2042- struct nfs_server *server = NFS_SERVER(dentry->d_inode);
2043+ struct nfs_server *server = NFS_SERVER(state->inode);
2044 int err;
2045 do {
2046- err = _nfs4_open_delegation_recall(dentry, state);
2047+ err = _nfs4_open_delegation_recall(ctx, state, stateid);
2048 switch (err) {
2049 case 0:
2050 return err;
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;
2056 }
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);
2060 }
2061
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)
2065 goto out_free;
2066 /* In case of error, no cleanup! */
2067- if (data->rpc_status != 0)
2068+ if (!data->rpc_done)
2069 goto out_free;
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);
2076 out_free:
2077- nfs4_opendata_free(data);
2078+ nfs4_opendata_put(data);
2079 }
2080
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;
2084 int status;
2085
2086- atomic_inc(&data->count);
2087- /*
2088- * If rpc_run_task() ends up calling ->rpc_release(), we
2089- * want to ensure that it takes the 'error' code path.
2090- */
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);
2096 if (IS_ERR(task))
2097 return PTR_ERR(task);
2098@@ -653,13 +802,35 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
2099
2100 if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0)
2101 return;
2102+ /*
2103+ * Check if we still need to send an OPEN call, or if we can use
2104+ * a delegation instead.
2105+ */
2106+ if (data->state != NULL) {
2107+ struct nfs_delegation *delegation;
2108+
2109+ if (can_open_cached(data->state, data->o_arg.open_flags & (FMODE_READ|FMODE_WRITE|O_EXCL)))
2110+ goto out_no_action;
2111+ rcu_read_lock();
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;
2117+ }
2118+ rcu_read_unlock();
2119+ }
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);
2128+ return;
2129+out_no_action:
2130+ task->tk_action = NULL;
2131+
2132 }
2133
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;
2137 }
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);
2141 }
2142 nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid);
2143+ data->rpc_done = 1;
2144 }
2145
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)
2149 goto out_free;
2150 /* In case of error, no cleanup! */
2151- if (data->rpc_status != 0)
2152+ if (data->rpc_status != 0 || !data->rpc_done)
2153 goto out_free;
2154 /* In case we need an open_confirm, no cleanup! */
2155 if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
2156 goto out_free;
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);
2163 out_free:
2164- nfs4_opendata_free(data);
2165+ nfs4_opendata_put(data);
2166 }
2167
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;
2171 int status;
2172
2173- atomic_inc(&data->count);
2174- /*
2175- * If rpc_run_task() ends up calling ->rpc_release(), we
2176- * want to ensure that it takes the 'error' code path.
2177- */
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);
2184 if (IS_ERR(task))
2185 return PTR_ERR(task);
2186@@ -743,7 +915,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
2187 } else
2188 status = data->rpc_status;
2189 rpc_put_task(task);
2190- if (status != 0)
2191+ if (status != 0 || !data->rpc_done)
2192 return status;
2193
2194 if (o_arg->open_flags & O_CREAT) {
2195@@ -756,7 +928,6 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
2196 if (status != 0)
2197 return status;
2198 }
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);
2202 return 0;
2203@@ -772,6 +943,8 @@ static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openf
2204 mask |= MAY_READ;
2205 if (openflags & FMODE_WRITE)
2206 mask |= MAY_WRITE;
2207+ if (openflags & FMODE_EXEC)
2208+ mask |= MAY_EXEC;
2209 status = nfs_access_get_cached(inode, cred, &cache);
2210 if (status == 0)
2211 goto out;
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
2215 */
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)
2218 {
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);
2223 int ret;
2224
2225- if (delegation != NULL && !(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) {
2226- ret = _nfs4_do_access(inode, sp->so_cred, openflags);
2227- if (ret < 0)
2228- return ret;
2229- memcpy(&state->stateid, &delegation->stateid, sizeof(state->stateid));
2230- set_bit(NFS_DELEGATED_STATE, &state->flags);
2231- return 0;
2232- }
2233- opendata = nfs4_opendata_alloc(dentry, sp, openflags, NULL);
2234+ opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
2235 if (opendata == NULL)
2236 return -ENOMEM;
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);
2241- d_drop(dentry);
2242+ nfs4_drop_state_owner(state->owner);
2243+ d_drop(ctx->path.dentry);
2244 }
2245- nfs4_opendata_free(opendata);
2246+ nfs4_opendata_put(opendata);
2247 return ret;
2248 }
2249
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)
2252 {
2253- struct nfs_server *server = NFS_SERVER(dentry->d_inode);
2254+ struct nfs_server *server = NFS_SERVER(state->inode);
2255 struct nfs4_exception exception = { };
2256 int err;
2257
2258 do {
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);
2266 if (IS_ERR(ctx))
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);
2271 return ret;
2272 }
2273
2274 /*
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
2279 */
2280-static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred *cred, struct nfs4_state **res)
2281-{
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);
2289- int err;
2290-
2291- err = -ENOMEM;
2292- if (!(sp = nfs4_get_state_owner(server, cred))) {
2293- dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
2294- return err;
2295- }
2296- err = nfs4_recover_expired_lease(server);
2297- if (err != 0)
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;
2304- err = -ENOENT;
2305- if (delegation == NULL || (delegation->type & open_flags) != open_flags)
2306- goto out_err;
2307- err = -ENOMEM;
2308- state = nfs4_get_open_state(inode, sp);
2309- if (state == NULL)
2310- goto out_err;
2311-
2312- err = -ENOENT;
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);
2317- goto out_ok;
2318- } else if (state->state != 0)
2319- goto out_put_open_state;
2320-
2321- lock_kernel();
2322- err = _nfs4_do_access(inode, cred, open_flags);
2323- unlock_kernel();
2324- if (err != 0)
2325- goto out_put_open_state;
2326- set_bit(NFS_DELEGATED_STATE, &state->flags);
2327- update_open_stateid(state, &delegation->stateid, open_flags);
2328-out_ok:
2329- nfs4_put_state_owner(sp);
2330- up_read(&nfsi->rwsem);
2331- up_read(&clp->cl_sem);
2332- *res = state;
2333- return 0;
2334-out_put_open_state:
2335- nfs4_put_open_state(state);
2336-out_err:
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);
2343- return err;
2344-}
2345-
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)
2348 {
2349- struct nfs4_exception exception = { };
2350- struct nfs4_state *res = ERR_PTR(-EIO);
2351- int err;
2352+ if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_ACCESS) &&
2353+ !(sattr->ia_valid & ATTR_ATIME_SET))
2354+ sattr->ia_valid |= ATTR_ATIME;
2355
2356- do {
2357- err = _nfs4_open_delegated(inode, flags, cred, &res);
2358- if (err == 0)
2359- break;
2360- res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(inode),
2361- err, &exception));
2362- } while (exception.retry);
2363- return res;
2364+ if ((opendata->o_res.attrset[1] & FATTR4_WORD1_TIME_MODIFY) &&
2365+ !(sattr->ia_valid & ATTR_MTIME_SET))
2366+ sattr->ia_valid |= ATTR_MTIME;
2367 }
2368
2369 /*
2370 * Returns a referenced nfs4_state
2371 */
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)
2374 {
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;
2380- int status;
2381+ int status;
2382
2383 /* Protect against reboot recovery conflicts */
2384 status = -ENOMEM;
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);
2387 if (status != 0)
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);
2392 status = -ENOMEM;
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;
2397
2398+ if (path->dentry->d_inode != NULL)
2399+ opendata->state = nfs4_get_open_state(path->dentry->d_inode, sp);
2400+
2401 status = _nfs4_proc_open(opendata);
2402 if (status != 0)
2403- goto err_opendata_free;
2404+ goto err_opendata_put;
2405+
2406+ if (opendata->o_arg.open_flags & O_EXCL)
2407+ nfs4_exclusive_attrset(opendata, sattr);
2408
2409- status = -ENOMEM;
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);
2422 *res = state;
2423 return 0;
2424-err_opendata_free:
2425- nfs4_opendata_free(opendata);
2426+err_opendata_put:
2427+ nfs4_opendata_put(opendata);
2428 err_release_rwsem:
2429 up_read(&clp->cl_sem);
2430 err_put_state_owner:
2431@@ -1006,14 +1105,14 @@ out_err:
2432 }
2433
2434
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)
2437 {
2438 struct nfs4_exception exception = { };
2439 struct nfs4_state *res;
2440 int status;
2441
2442 do {
2443- status = _nfs4_do_open(dir, dentry, flags, sattr, cred, &res);
2444+ status = _nfs4_do_open(dir, path, flags, sattr, cred, &res);
2445 if (status == 0)
2446 break;
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...
2450 */
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;
2457 continue;
2458 }
2459@@ -1042,6 +1143,11 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry,
2460 exception.retry = 1;
2461 continue;
2462 }
2463+ if (status == -EAGAIN) {
2464+ /* We must have found a delegation */
2465+ exception.retry = 1;
2466+ continue;
2467+ }
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,
2472 }
2473
2474 struct nfs4_closedata {
2475+ struct path path;
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);
2485 kfree(calldata);
2486 }
2487
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) {
2491 case 0:
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);
2496 break;
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,
2501 };
2502- int mode = 0, old_mode;
2503+ int clear_rd, clear_wr, clear_rdwr;
2504+ int mode;
2505
2506 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
2507 return;
2508- /* Recalculate the new open mode in case someone reopened the file
2509- * while we were waiting in line to be scheduled.
2510- */
2511+
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);
2525+ }
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);
2530+ }
2531 }
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;
2539 return;
2540@@ -1209,19 +1321,21 @@ static const struct rpc_call_ops nfs4_close_ops = {
2541 *
2542 * NOTE: Caller must be holding the sp->so_owner semaphore!
2543 */
2544-int nfs4_do_close(struct inode *inode, struct nfs4_state *state)
2545+int nfs4_do_close(struct path *path, struct nfs4_state *state)
2546 {
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;
2553
2554 calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
2555 if (calldata == NULL)
2556 goto out;
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);
2573
2574- status = nfs4_call_async(server->client, &nfs4_close_ops, calldata);
2575- if (status == 0)
2576- goto out;
2577-
2578- nfs_free_seqid(calldata->arg.seqid);
2579+ task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata);
2580+ if (IS_ERR(task))
2581+ return PTR_ERR(task);
2582+ rpc_put_task(task);
2583+ return 0;
2584 out_free_calldata:
2585 kfree(calldata);
2586 out:
2587+ nfs4_put_open_state(state);
2588+ nfs4_put_state_owner(sp);
2589 return status;
2590 }
2591
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)
2594 {
2595 struct file *filp;
2596+ int ret;
2597
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);
2604+ if (ret < 0)
2605+ goto out_close;
2606+ }
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;
2611 ctx->state = state;
2612 return 0;
2613 }
2614- nfs4_close_state(state, nd->intent.open.flags);
2615- return PTR_ERR(filp);
2616+ ret = PTR_ERR(filp);
2617+out_close:
2618+ nfs4_close_state(path, state, nd->intent.open.flags);
2619+ return ret;
2620 }
2621
2622 struct dentry *
2623 nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
2624 {
2625+ struct path path = {
2626+ .mnt = nd->mnt,
2627+ .dentry = dentry,
2628+ };
2629 struct iattr attr;
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);
2634 if (IS_ERR(cred))
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);
2638 put_rpccred(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));
2643 if (res != NULL)
2644 dentry = res;
2645- nfs4_intent_set_file(nd, dentry, state);
2646+ nfs4_intent_set_file(nd, &path, state);
2647 return res;
2648 }
2649
2650 int
2651 nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
2652 {
2653+ struct path path = {
2654+ .mnt = nd->mnt,
2655+ .dentry = dentry,
2656+ };
2657 struct rpc_cred *cred;
2658 struct nfs4_state *state;
2659
2660 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
2661 if (IS_ERR(cred))
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);
2667 put_rpccred(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
2671 }
2672 }
2673 if (state->inode == dentry->d_inode) {
2674- nfs4_intent_set_file(nd, dentry, state);
2675+ nfs4_intent_set_file(nd, &path, state);
2676 return 1;
2677 }
2678- nfs4_close_state(state, openflags);
2679+ nfs4_close_state(&path, state, openflags);
2680 out_drop:
2681 d_drop(dentry);
2682 return 0;
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;
2689 return status;
2690 }
2691
2692@@ -1571,10 +1704,13 @@ static int nfs4_proc_lookupfh(struct nfs_server *server, struct nfs_fh *dirfh,
2693 struct nfs4_exception exception = { };
2694 int err;
2695 do {
2696- err = nfs4_handle_exception(server,
2697- _nfs4_proc_lookupfh(server, dirfh, name,
2698- fhandle, fattr),
2699- &exception);
2700+ err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
2701+ /* FIXME: !!!! */
2702+ if (err == -NFS4ERR_MOVED) {
2703+ err = -EREMOTE;
2704+ break;
2705+ }
2706+ err = nfs4_handle_exception(server, err, &exception);
2707 } while (exception.retry);
2708 return err;
2709 }
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)
2713 {
2714- int status;
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),
2719- .name = name,
2720- };
2721- struct nfs4_lookup_res res = {
2722- .server = server,
2723- .fattr = fattr,
2724- .fh = fhandle,
2725- };
2726- struct rpc_message msg = {
2727- .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP],
2728- .rpc_argp = &args,
2729- .rpc_resp = &res,
2730- };
2731-
2732- nfs_fattr_init(fattr);
2733+ int status;
2734
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)
2744 {
2745+ struct path path = {
2746+ .mnt = nd->mnt,
2747+ .dentry = dentry,
2748+ };
2749 struct nfs4_state *state;
2750 struct rpc_cred *cred;
2751 int status = 0;
2752@@ -1761,7 +1883,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2753 status = PTR_ERR(cred);
2754 goto out;
2755 }
2756- state = nfs4_do_open(dir, dentry, flags, sattr, cred);
2757+ state = nfs4_do_open(dir, &path, flags, sattr, cred);
2758 put_rpccred(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);
2763 if (status == 0)
2764 nfs_setattr_update_inode(state->inode, sattr);
2765+ nfs_post_op_update_inode(state->inode, &fattr);
2766 }
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);
2771 else
2772- nfs4_close_state(state, flags);
2773+ nfs4_close_state(&path, state, flags);
2774 out:
2775 return status;
2776 }
2777@@ -3008,7 +3131,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
2778 if (status != 0)
2779 goto out;
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);
2784 switch (status) {
2785 case 0:
2786@@ -3152,6 +3275,11 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
2787 {
2788 struct nfs4_unlockdata *data;
2789
2790+ /* Ensure this is an unlock - when canceling a lock, the
2791+ * canceled lock is passed in, and it won't be an unlock.
2792+ */
2793+ fl->fl_type = F_UNLCK;
2794+
2795 data = nfs4_alloc_unlockdata(fl, ctx, lsp, seqid);
2796 if (data == NULL) {
2797 nfs_free_seqid(seqid);
2798@@ -3222,7 +3350,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
2799 goto out_free;
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;
2804 p->lsp = lsp;
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);
2813 }
2814 nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid);
2815 out:
2816diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
2817index 8ed79d5..28551ae 100644
2818--- a/fs/nfs/nfs4state.c
2819+++ b/fs/nfs/nfs4state.c
2820@@ -38,12 +38,14 @@
2821 * subsequent patch.
2822 */
2823
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>
2834
2835@@ -69,33 +71,14 @@ static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
2836 return status;
2837 }
2838
2839-u32
2840-nfs4_alloc_lockowner_id(struct nfs_client *clp)
2841-{
2842- return clp->cl_lockowner_id ++;
2843-}
2844-
2845-static struct nfs4_state_owner *
2846-nfs4_client_grab_unused(struct nfs_client *clp, struct rpc_cred *cred)
2847-{
2848- struct nfs4_state_owner *sp = NULL;
2849-
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--;
2856- }
2857- return sp;
2858-}
2859-
2860 struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
2861 {
2862 struct nfs4_state_owner *sp;
2863+ struct rb_node *pos;
2864 struct rpc_cred *cred = NULL;
2865
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))
2870 continue;
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)
2874 {
2875 struct nfs4_state_owner *sp;
2876+ struct rb_node *pos;
2877
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);
2885 }
2886 return NULL;
2887 }
2888
2889+static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new,
2890+ __u64 minval, int maxbits)
2891+{
2892+ struct rb_node **p, *parent;
2893+ struct nfs_unique_id *pos;
2894+ __u64 mask = ~0ULL;
2895+
2896+ if (maxbits < 64)
2897+ mask = (1ULL << maxbits) - 1ULL;
2898+
2899+ /* Ensure distribution is more or less flat */
2900+ get_random_bytes(&new->id, sizeof(new->id));
2901+ new->id &= mask;
2902+ if (new->id < minval)
2903+ new->id += minval;
2904+retry:
2905+ p = &root->rb_node;
2906+ parent = NULL;
2907+
2908+ while (*p != NULL) {
2909+ parent = *p;
2910+ pos = rb_entry(parent, struct nfs_unique_id, rb_node);
2911+
2912+ if (new->id < pos->id)
2913+ p = &(*p)->rb_left;
2914+ else if (new->id > pos->id)
2915+ p = &(*p)->rb_right;
2916+ else
2917+ goto id_exists;
2918+ }
2919+ rb_link_node(&new->rb_node, parent, p);
2920+ rb_insert_color(&new->rb_node, root);
2921+ return;
2922+id_exists:
2923+ for (;;) {
2924+ new->id++;
2925+ if (new->id < minval || (new->id & mask) != new->id) {
2926+ new->id = minval;
2927+ break;
2928+ }
2929+ parent = rb_next(parent);
2930+ if (parent == NULL)
2931+ break;
2932+ pos = rb_entry(parent, struct nfs_unique_id, rb_node);
2933+ if (new->id < pos->id)
2934+ break;
2935+ }
2936+ goto retry;
2937+}
2938+
2939+static void nfs_free_unique_id(struct rb_root *root, struct nfs_unique_id *id)
2940+{
2941+ rb_erase(&id->rb_node, root);
2942+}
2943+
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)
2947 {
2948+ struct nfs_client *clp = server->nfs_client;
2949+ struct rb_node **p = &clp->cl_state_owners.rb_node,
2950+ *parent = NULL;
2951 struct nfs4_state_owner *sp, *res = NULL;
2952
2953- list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
2954- if (sp->so_cred != cred)
2955+ while (*p != NULL) {
2956+ parent = *p;
2957+ sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
2958+
2959+ if (server < sp->so_server) {
2960+ p = &parent->rb_left;
2961 continue;
2962- atomic_inc(&sp->so_count);
2963- /* Move to the head of the list */
2964- list_move(&sp->so_list, &clp->cl_state_owners);
2965- res = sp;
2966- break;
2967+ }
2968+ if (server > sp->so_server) {
2969+ p = &parent->rb_right;
2970+ continue;
2971+ }
2972+ if (cred < sp->so_cred)
2973+ p = &parent->rb_left;
2974+ else if (cred > sp->so_cred)
2975+ p = &parent->rb_right;
2976+ else {
2977+ atomic_inc(&sp->so_count);
2978+ res = sp;
2979+ break;
2980+ }
2981 }
2982 return res;
2983 }
2984
2985+static struct nfs4_state_owner *
2986+nfs4_insert_state_owner(struct nfs_client *clp, struct nfs4_state_owner *new)
2987+{
2988+ struct rb_node **p = &clp->cl_state_owners.rb_node,
2989+ *parent = NULL;
2990+ struct nfs4_state_owner *sp;
2991+
2992+ while (*p != NULL) {
2993+ parent = *p;
2994+ sp = rb_entry(parent, struct nfs4_state_owner, so_client_node);
2995+
2996+ if (new->so_server < sp->so_server) {
2997+ p = &parent->rb_left;
2998+ continue;
2999+ }
3000+ if (new->so_server > sp->so_server) {
3001+ p = &parent->rb_right;
3002+ continue;
3003+ }
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;
3008+ else {
3009+ atomic_inc(&sp->so_count);
3010+ return sp;
3011+ }
3012+ }
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);
3016+ return new;
3017+}
3018+
3019+static void
3020+nfs4_remove_state_owner(struct nfs_client *clp, struct nfs4_state_owner *sp)
3021+{
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);
3025+}
3026+
3027 /*
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)
3031 void
3032 nfs4_drop_state_owner(struct nfs4_state_owner *sp)
3033 {
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;
3040+
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);
3045+ }
3046 }
3047
3048 /*
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;
3052
3053- get_rpccred(cred);
3054- new = nfs4_alloc_state_owner();
3055 spin_lock(&clp->cl_lock);
3056- sp = nfs4_find_state_owner(clp, cred);
3057- if (sp == NULL)
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;
3064- sp = new;
3065- new = NULL;
3066- }
3067+ sp = nfs4_find_state_owner(server, cred);
3068 spin_unlock(&clp->cl_lock);
3069- kfree(new);
3070 if (sp != NULL)
3071 return sp;
3072- put_rpccred(cred);
3073- return NULL;
3074+ new = nfs4_alloc_state_owner();
3075+ if (new == NULL)
3076+ return NULL;
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);
3083+ if (sp == new)
3084+ get_rpccred(cred);
3085+ else
3086+ kfree(new);
3087+ return sp;
3088 }
3089
3090 /*
3091@@ -208,18 +308,7 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp)
3092
3093 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
3094 return;
3095- if (clp->cl_nunused >= OPENOWNER_POOL_SIZE)
3096- goto out_free;
3097- if (list_empty(&sp->so_list))
3098- goto out_free;
3099- list_move(&sp->so_list, &clp->cl_unused);
3100- clp->cl_nunused++;
3101- spin_unlock(&clp->cl_lock);
3102- put_rpccred(cred);
3103- cred = NULL;
3104- return;
3105-out_free:
3106- list_del(&sp->so_list);
3107+ nfs4_remove_state_owner(clp, sp);
3108 spin_unlock(&clp->cl_lock);
3109 put_rpccred(cred);
3110 kfree(sp);
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);
3116 return state;
3117 }
3118
3119@@ -263,13 +353,10 @@ __nfs4_find_state_byowner(struct inode *inode, struct nfs4_state_owner *owner)
3120 struct nfs4_state *state;
3121
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)
3126 continue;
3127- if (state->owner == owner) {
3128- atomic_inc(&state->count);
3129+ if (atomic_inc_not_zero(&state->count))
3130 return state;
3131- }
3132 }
3133 return NULL;
3134 }
3135@@ -341,16 +428,15 @@ void nfs4_put_open_state(struct nfs4_state *state)
3136 /*
3137 * Close the current file.
3138 */
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)
3141 {
3142- struct inode *inode = state->inode;
3143 struct nfs4_state_owner *owner = state->owner;
3144- int oldstate, newstate = 0;
3145+ int call_close = 0;
3146+ int newstate;
3147
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)) {
3153 case FMODE_READ:
3154 state->n_rdonly--;
3155@@ -361,24 +447,29 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
3156 case FMODE_READ|FMODE_WRITE:
3157 state->n_rdwr--;
3158 }
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);
3168+ }
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);
3173+ }
3174+ if (newstate == 0)
3175+ clear_bit(NFS_DELEGATED_STATE, &state->flags);
3176 }
3177- if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3178- nfs4_state_set_mode_locked(state, newstate);
3179- oldstate = newstate;
3180- }
3181- spin_unlock(&inode->i_lock);
3182+ nfs4_state_set_mode_locked(state, newstate);
3183 spin_unlock(&owner->so_lock);
3184
3185- if (oldstate != newstate && nfs4_do_close(inode, state) == 0)
3186- return;
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);
3192+ } else
3193+ nfs4_do_close(path, state);
3194 }
3195
3196 /*
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);
3205 return lsp;
3206 }
3207
3208+static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
3209+{
3210+ struct nfs_client *clp = lsp->ls_state->owner->so_client;
3211+
3212+ spin_lock(&clp->cl_lock);
3213+ nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id);
3214+ spin_unlock(&clp->cl_lock);
3215+ kfree(lsp);
3216+}
3217+
3218 /*
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_
3222 return NULL;
3223 }
3224 spin_unlock(&state->state_lock);
3225- kfree(new);
3226+ if (new != NULL)
3227+ nfs4_free_lock_state(new);
3228 return lsp;
3229 }
3230
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);
3235- kfree(lsp);
3236+ nfs4_free_lock_state(lsp);
3237 }
3238
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)
3242 {
3243 struct nfs4_lock_state *lsp;
3244+ int seq;
3245
3246- memcpy(dst, &state->stateid, sizeof(*dst));
3247+ do {
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)
3252 return;
3253
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()
3257 */
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)
3260 {
3261 switch (status) {
3262 case 0:
3263 break;
3264 case -NFS4ERR_BAD_SEQID:
3265+ if (seqid->sequence->flags & NFS_SEQID_CONFIRMED)
3266+ return;
3267+ printk(KERN_WARNING "NFS: v4 server returned a bad"
3268+ "sequence-id error on an"
3269+ "unconfirmed sequence %p!\n",
3270+ seqid->sequence);
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);
3277 }
3278- return nfs_increment_seqid(status, seqid);
3279+ nfs_increment_seqid(status, seqid);
3280 }
3281
3282 /*
3283@@ -596,7 +708,7 @@ void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
3284 */
3285 void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
3286 {
3287- return nfs_increment_seqid(status, seqid);
3288+ nfs_increment_seqid(status, seqid);
3289 }
3290
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)
3294 {
3295 struct nfs4_state_owner *sp;
3296+ struct rb_node *pos;
3297 struct nfs4_state *state;
3298 struct nfs4_lock_state *lock;
3299
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)
3316 {
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;
3322 int status = 0;
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);
3331 if (status < 0) {
3332 if (status == -NFS4ERR_NO_GRACE) {
3333diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
3334index 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);
3338 #endif
3339
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)
3343 */
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 \
3372+ (2)
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 + \
3383+ decode_ace_maxsz)
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 + \
3391 nfs4_name_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 + \
3396 nfs4_fattr_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 \
3406+ (0)
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 + \
3446- 11)
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 + \
3452- 4 + 5 + 2 + 3)
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 + \
3460 1 + 1 + 2 + 2 + \
3461 1 + 4 + 1 + 2 + \
3462- owner_id_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 + \
3468 2 + 2 + 1 + 2 + \
3469- owner_id_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 + \
3475 1 + 2 + 2 + 2 + \
3476- owner_id_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);
3482 encode_getfh_maxsz)
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 + \
3488 decode_getfh_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)
3504
3505 static struct {
3506 unsigned int mode;
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);
3517- WRITE32(4);
3518- WRITE32(args->lock_owner.id);
3519+ WRITE32(16);
3520+ WRITEMEM("lock id:", 8);
3521+ WRITE64(args->lock_owner.id);
3522 }
3523 else {
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
3526 {
3527 __be32 *p;
3528
3529- RESERVE_SPACE(40);
3530+ RESERVE_SPACE(52);
3531 WRITE32(OP_LOCKT);
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);
3536- WRITE32(4);
3537- WRITE32(args->lock_owner.id);
3538+ WRITE32(16);
3539+ WRITEMEM("lock id:", 8);
3540+ WRITE64(args->lock_owner.id);
3541
3542 return 0;
3543 }
3544@@ -886,10 +922,11 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
3545 WRITE32(OP_OPEN);
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);
3551- WRITE32(4);
3552- WRITE32(arg->id);
3553+ WRITE32(16);
3554+ WRITEMEM("open id:", 8);
3555+ WRITE64(arg->id);
3556 }
3557
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)
3560
3561 static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req)
3562 {
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
3569
3570 static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req)
3571 {
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;
3575 __be32 *p;
3576
3577@@ -1735,7 +1772,7 @@ out:
3578 */
3579 static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
3580 {
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 = {
3585 .nops = 2,
3586@@ -1795,7 +1832,7 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
3587 struct nfs_getaclargs *args)
3588 {
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 = {
3593 .nops = 2,
3594 };
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 = {
3597 .nops = 3,
3598 };
3599- struct rpc_auth *auth = req->rq_task->tk_auth;
3600+ struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
3601 int replen;
3602 int status;
3603
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)
3606 {
3607 __be32 *p;
3608- uint32_t bmlen;
3609+ uint32_t savewords, bmlen, i;
3610 int status;
3611
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)
3614 goto xdr_error;
3615
3616 READ_BUF(bmlen << 2);
3617- p += bmlen;
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;
3623+
3624 return decode_delegation(xdr, res);
3625 xdr_error:
3626 dprintk("%s: Bitmap too large! Length = %u\n", __FUNCTION__, bmlen);
3627diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
3628index 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);
3637 }
3638
3639
3640@@ -496,7 +496,8 @@ static int __init root_nfs_get_handle(void)
3641 NFS_MNT3_VERSION : NFS_MNT_VERSION;
3642
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);
3647 if (status < 0)
3648 printk(KERN_ERR "Root-NFS: Server returned error %d "
3649 "while mounting %s\n", status, nfs_path);
3650diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
3651index 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);
3660-
3661+ kref_init(&req->wb_kref);
3662 return req;
3663 }
3664
3665@@ -109,30 +108,31 @@ void nfs_unlock_request(struct nfs_page *req)
3666 }
3667
3668 /**
3669- * nfs_set_page_writeback_locked - Lock a request for writeback
3670+ * nfs_set_page_tag_locked - Tag a request as locked
3671 * @req:
3672 */
3673-int nfs_set_page_writeback_locked(struct nfs_page *req)
3674+static int nfs_set_page_tag_locked(struct nfs_page *req)
3675 {
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);
3678
3679 if (!nfs_lock_request(req))
3680 return 0;
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);
3683 return 1;
3684 }
3685
3686 /**
3687- * nfs_clear_page_writeback - Unlock request and wake up sleepers
3688+ * nfs_clear_page_tag_locked - Clear request tag and wake up sleepers
3689 */
3690-void nfs_clear_page_writeback(struct nfs_page *req)
3691+void nfs_clear_page_tag_locked(struct nfs_page *req)
3692 {
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);
3696
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);
3704 }
3705 nfs_unlock_request(req);
3706 }
3707@@ -160,11 +160,9 @@ void nfs_clear_request(struct nfs_page *req)
3708 *
3709 * Note: Should never be called with the spinlock held!
3710 */
3711-void
3712-nfs_release_request(struct nfs_page *req)
3713+static void nfs_free_request(struct kref *kref)
3714 {
3715- if (!atomic_dec_and_test(&req->wb_count))
3716- return;
3717+ struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
3718
3719 /* Release struct file or cached credential */
3720 nfs_clear_request(req);
3721@@ -172,6 +170,11 @@ nfs_release_request(struct nfs_page *req)
3722 nfs_page_free(req);
3723 }
3724
3725+void nfs_release_request(struct nfs_page *req)
3726+{
3727+ kref_put(&req->wb_kref, nfs_free_request);
3728+}
3729+
3730 static int nfs_wait_bit_interruptible(void *word)
3731 {
3732 int ret = 0;
3733@@ -193,7 +196,7 @@ static int nfs_wait_bit_interruptible(void *word)
3734 int
3735 nfs_wait_on_request(struct nfs_page *req)
3736 {
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);
3739 sigset_t oldmask;
3740 int ret = 0;
3741
3742@@ -379,20 +382,20 @@ void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
3743 /**
3744 * nfs_scan_list - Scan a list for matching requests
3745 * @nfsi: NFS inode
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
3751 *
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
3758 */
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)
3764 {
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;
3769
3770 for (;;) {
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);
3776 if (found <= 0)
3777 break;
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)
3781 goto out;
3782 idx_start = req->wb_index + 1;
3783- if (req->wb_list_head != head)
3784- continue;
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);
3791 res++;
3792+ if (res == INT_MAX)
3793+ goto out;
3794 }
3795 }
3796-
3797+ /* for latency reduction */
3798+ cond_resched_lock(&nfsi->vfs_inode.i_lock);
3799 }
3800 out:
3801 return res;
3802diff --git a/fs/nfs/read.c b/fs/nfs/read.c
3803index 7bd7cb9..6ae2e58 100644
3804--- a/fs/nfs/read.c
3805+++ b/fs/nfs/read.c
3806@@ -145,8 +145,8 @@ static void nfs_readpage_release(struct nfs_page *req)
3807 unlock_page(req->wb_page);
3808
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),
3814 req->wb_bytes,
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,
3818 int flags;
3819
3820 data->req = req;
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;
3824
3825 data->args.fh = NFS_FH(inode);
3826@@ -483,17 +483,19 @@ int nfs_readpage(struct file *file, struct page *page)
3827 */
3828 error = nfs_wb_page(inode, page);
3829 if (error)
3830- goto out_error;
3831+ goto out_unlock;
3832+ if (PageUptodate(page))
3833+ goto out_unlock;
3834
3835 error = -ESTALE;
3836 if (NFS_STALE(inode))
3837- goto out_error;
3838+ goto out_unlock;
3839
3840 if (file == NULL) {
3841 error = -EBADF;
3842 ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
3843 if (ctx == NULL)
3844- goto out_error;
3845+ goto out_unlock;
3846 } else
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)
3850
3851 put_nfs_open_context(ctx);
3852 return error;
3853-
3854-out_error:
3855+out_unlock:
3856 unlock_page(page);
3857 return error;
3858 }
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;
3862 unsigned int len;
3863+ int error;
3864+
3865+ error = nfs_wb_page(inode, page);
3866+ if (error)
3867+ goto out_unlock;
3868+ if (PageUptodate(page))
3869+ goto out_unlock;
3870
3871- nfs_wb_page(inode, page);
3872 len = nfs_page_length(page);
3873 if (len == 0)
3874 return nfs_return_empty_page(page);
3875+
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);
3881- }
3882+ if (IS_ERR(new))
3883+ goto out_error;
3884+
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);
3888 return 0;
3889+out_error:
3890+ error = PTR_ERR(new);
3891+ SetPageError(page);
3892+out_unlock:
3893+ unlock_page(page);
3894+ return error;
3895 }
3896
3897 int nfs_readpages(struct file *filp, struct address_space *mapping,
3898diff --git a/fs/nfs/super.c b/fs/nfs/super.c
3899index ca20d3c..a2b1af8 100644
3900--- a/fs/nfs/super.c
3901+++ b/fs/nfs/super.c
3902@@ -45,6 +45,7 @@
3903 #include <linux/inet.h>
3904 #include <linux/nfs_xdr.h>
3905 #include <linux/magic.h>
3906+#include <linux/parser.h>
3907
3908 #include <asm/system.h>
3909 #include <asm/uaccess.h>
3910@@ -57,6 +58,167 @@
3911
3912 #define NFSDBG_FACILITY NFSDBG_VFS
3913
3914+
3915+struct nfs_parsed_mount_data {
3916+ int flags;
3917+ int rsize, wsize;
3918+ int timeo, retrans;
3919+ int acregmin, acregmax,
3920+ acdirmin, acdirmax;
3921+ int namlen;
3922+ unsigned int bsize;
3923+ unsigned int auth_flavor_len;
3924+ rpc_authflavor_t auth_flavors[1];
3925+ char *client_address;
3926+
3927+ struct {
3928+ struct sockaddr_in address;
3929+ unsigned int program;
3930+ unsigned int version;
3931+ unsigned short port;
3932+ int protocol;
3933+ } mount_server;
3934+
3935+ struct {
3936+ struct sockaddr_in address;
3937+ char *hostname;
3938+ char *export_path;
3939+ unsigned int program;
3940+ int protocol;
3941+ } nfs_server;
3942+};
3943+
3944+enum {
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,
3950+ Opt_ac, Opt_noac,
3951+ Opt_lock, Opt_nolock,
3952+ Opt_v2, Opt_v3,
3953+ Opt_udp, Opt_tcp,
3954+ Opt_acl, Opt_noacl,
3955+ Opt_rdirplus, Opt_nordirplus,
3956+ Opt_sharecache, Opt_nosharecache,
3957+
3958+ /* Mount options that take integer arguments */
3959+ Opt_port,
3960+ Opt_rsize, Opt_wsize, Opt_bsize,
3961+ Opt_timeo, Opt_retrans,
3962+ Opt_acregmin, Opt_acregmax,
3963+ Opt_acdirmin, Opt_acdirmax,
3964+ Opt_actimeo,
3965+ Opt_namelen,
3966+ Opt_mountport,
3967+ Opt_mountprog, Opt_mountvers,
3968+ Opt_nfsprog, Opt_nfsvers,
3969+
3970+ /* Mount options that take string arguments */
3971+ Opt_sec, Opt_proto, Opt_mountproto,
3972+ Opt_addr, Opt_mounthost, Opt_clientaddr,
3973+
3974+ /* Mount options that are ignored */
3975+ Opt_userspace, Opt_deprecated,
3976+
3977+ Opt_err
3978+};
3979+
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" },
3991+ { Opt_ac, "ac" },
3992+ { Opt_noac, "noac" },
3993+ { Opt_lock, "lock" },
3994+ { Opt_nolock, "nolock" },
3995+ { Opt_v2, "v2" },
3996+ { Opt_v3, "v3" },
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" },
4005+
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" },
4025+
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" },
4032+
4033+ { Opt_err, NULL }
4034+};
4035+
4036+enum {
4037+ Opt_xprt_udp, Opt_xprt_tcp,
4038+
4039+ Opt_xprt_err
4040+};
4041+
4042+static match_table_t nfs_xprt_protocol_tokens = {
4043+ { Opt_xprt_udp, "udp" },
4044+ { Opt_xprt_tcp, "tcp" },
4045+
4046+ { Opt_xprt_err, NULL }
4047+};
4048+
4049+enum {
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,
4054+
4055+ Opt_sec_err
4056+};
4057+
4058+static match_table_t nfs_secflavor_tokens = {
4059+ { Opt_sec_none, "none" },
4060+ { Opt_sec_none, "null" },
4061+ { Opt_sec_sys, "sys" },
4062+
4063+ { Opt_sec_krb5, "krb5" },
4064+ { Opt_sec_krb5i, "krb5i" },
4065+ { Opt_sec_krb5p, "krb5p" },
4066+
4067+ { Opt_sec_lkey, "lkey" },
4068+ { Opt_sec_lkeyi, "lkeyi" },
4069+ { Opt_sec_lkeyp, "lkeyp" },
4070+
4071+ { Opt_sec_err, NULL }
4072+};
4073+
4074+
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" },
4082- { -1, "unknown" }
4083+ { UINT_MAX, "unknown" }
4084 };
4085 int i;
4086
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)
4090 break;
4091 }
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", ""},
4097 { 0, NULL, NULL }
4098 };
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)
4101 */
4102 static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
4103 {
4104+ struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
4105+ struct rpc_clnt *rpc;
4106+
4107 shrink_submounts(vfsmnt, &nfs_automount_list);
4108+
4109+ if (!(flags & MNT_FORCE))
4110+ return;
4111+ /* -EIO all pending I/O */
4112+ rpc = server->client_acl;
4113+ if (!IS_ERR(rpc))
4114+ rpc_killall_tasks(rpc);
4115+ rpc = server->client;
4116+ if (!IS_ERR(rpc))
4117+ rpc_killall_tasks(rpc);
4118 }
4119
4120 /*
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
4124 */
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)
4128 {
4129- if (data == NULL) {
4130- dprintk("%s: missing data argument\n", __FUNCTION__);
4131- return -EINVAL;
4132+ switch (addr->sa_family) {
4133+ case AF_INET: {
4134+ struct sockaddr_in *sa = (struct sockaddr_in *) addr;
4135+ if (sa->sin_addr.s_addr != INADDR_ANY)
4136+ return 1;
4137+ break;
4138+ }
4139 }
4140
4141- if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
4142- dprintk("%s: bad mount version\n", __FUNCTION__);
4143- return -EINVAL;
4144+ return 0;
4145+}
4146+
4147+/*
4148+ * Error-check and convert a string of mount options from user space into
4149+ * a data structure
4150+ */
4151+static int nfs_parse_mount_options(char *raw,
4152+ struct nfs_parsed_mount_data *mnt)
4153+{
4154+ char *p, *string;
4155+
4156+ if (!raw) {
4157+ dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
4158+ return 1;
4159 }
4160+ dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
4161
4162- switch (data->version) {
4163- case 1:
4164- data->namlen = 0;
4165- case 2:
4166- data->bsize = 0;
4167- case 3:
4168- if (data->flags & NFS_MOUNT_VER3) {
4169- dprintk("%s: mount structure version %d does not support NFSv3\n",
4170- __FUNCTION__,
4171- data->version);
4172- return -EINVAL;
4173+ while ((p = strsep(&raw, ",")) != NULL) {
4174+ substring_t args[MAX_OPT_ARGS];
4175+ int option, token;
4176+
4177+ if (!*p)
4178+ continue;
4179+
4180+ dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p);
4181+
4182+ token = match_token(p, nfs_mount_option_tokens, args);
4183+ switch (token) {
4184+ case Opt_soft:
4185+ mnt->flags |= NFS_MOUNT_SOFT;
4186+ break;
4187+ case Opt_hard:
4188+ mnt->flags &= ~NFS_MOUNT_SOFT;
4189+ break;
4190+ case Opt_intr:
4191+ mnt->flags |= NFS_MOUNT_INTR;
4192+ break;
4193+ case Opt_nointr:
4194+ mnt->flags &= ~NFS_MOUNT_INTR;
4195+ break;
4196+ case Opt_posix:
4197+ mnt->flags |= NFS_MOUNT_POSIX;
4198+ break;
4199+ case Opt_noposix:
4200+ mnt->flags &= ~NFS_MOUNT_POSIX;
4201+ break;
4202+ case Opt_cto:
4203+ mnt->flags &= ~NFS_MOUNT_NOCTO;
4204+ break;
4205+ case Opt_nocto:
4206+ mnt->flags |= NFS_MOUNT_NOCTO;
4207+ break;
4208+ case Opt_ac:
4209+ mnt->flags &= ~NFS_MOUNT_NOAC;
4210+ break;
4211+ case Opt_noac:
4212+ mnt->flags |= NFS_MOUNT_NOAC;
4213+ break;
4214+ case Opt_lock:
4215+ mnt->flags &= ~NFS_MOUNT_NONLM;
4216+ break;
4217+ case Opt_nolock:
4218+ mnt->flags |= NFS_MOUNT_NONLM;
4219+ break;
4220+ case Opt_v2:
4221+ mnt->flags &= ~NFS_MOUNT_VER3;
4222+ break;
4223+ case Opt_v3:
4224+ mnt->flags |= NFS_MOUNT_VER3;
4225+ break;
4226+ case Opt_udp:
4227+ mnt->flags &= ~NFS_MOUNT_TCP;
4228+ mnt->nfs_server.protocol = IPPROTO_UDP;
4229+ mnt->timeo = 7;
4230+ mnt->retrans = 5;
4231+ break;
4232+ case Opt_tcp:
4233+ mnt->flags |= NFS_MOUNT_TCP;
4234+ mnt->nfs_server.protocol = IPPROTO_TCP;
4235+ mnt->timeo = 600;
4236+ mnt->retrans = 2;
4237+ break;
4238+ case Opt_acl:
4239+ mnt->flags &= ~NFS_MOUNT_NOACL;
4240+ break;
4241+ case Opt_noacl:
4242+ mnt->flags |= NFS_MOUNT_NOACL;
4243+ break;
4244+ case Opt_rdirplus:
4245+ mnt->flags &= ~NFS_MOUNT_NORDIRPLUS;
4246+ break;
4247+ case Opt_nordirplus:
4248+ mnt->flags |= NFS_MOUNT_NORDIRPLUS;
4249+ break;
4250+ case Opt_sharecache:
4251+ mnt->flags &= ~NFS_MOUNT_UNSHARED;
4252+ break;
4253+ case Opt_nosharecache:
4254+ mnt->flags |= NFS_MOUNT_UNSHARED;
4255+ break;
4256+
4257+ case Opt_port:
4258+ if (match_int(args, &option))
4259+ return 0;
4260+ if (option < 0 || option > 65535)
4261+ return 0;
4262+ mnt->nfs_server.address.sin_port = htonl(option);
4263+ break;
4264+ case Opt_rsize:
4265+ if (match_int(args, &mnt->rsize))
4266+ return 0;
4267+ break;
4268+ case Opt_wsize:
4269+ if (match_int(args, &mnt->wsize))
4270+ return 0;
4271+ break;
4272+ case Opt_bsize:
4273+ if (match_int(args, &option))
4274+ return 0;
4275+ if (option < 0)
4276+ return 0;
4277+ mnt->bsize = option;
4278+ break;
4279+ case Opt_timeo:
4280+ if (match_int(args, &mnt->timeo))
4281+ return 0;
4282+ break;
4283+ case Opt_retrans:
4284+ if (match_int(args, &mnt->retrans))
4285+ return 0;
4286+ break;
4287+ case Opt_acregmin:
4288+ if (match_int(args, &mnt->acregmin))
4289+ return 0;
4290+ break;
4291+ case Opt_acregmax:
4292+ if (match_int(args, &mnt->acregmax))
4293+ return 0;
4294+ break;
4295+ case Opt_acdirmin:
4296+ if (match_int(args, &mnt->acdirmin))
4297+ return 0;
4298+ break;
4299+ case Opt_acdirmax:
4300+ if (match_int(args, &mnt->acdirmax))
4301+ return 0;
4302+ break;
4303+ case Opt_actimeo:
4304+ if (match_int(args, &option))
4305+ return 0;
4306+ if (option < 0)
4307+ return 0;
4308+ mnt->acregmin =
4309+ mnt->acregmax =
4310+ mnt->acdirmin =
4311+ mnt->acdirmax = option;
4312+ break;
4313+ case Opt_namelen:
4314+ if (match_int(args, &mnt->namlen))
4315+ return 0;
4316+ break;
4317+ case Opt_mountport:
4318+ if (match_int(args, &option))
4319+ return 0;
4320+ if (option < 0 || option > 65535)
4321+ return 0;
4322+ mnt->mount_server.port = option;
4323+ break;
4324+ case Opt_mountprog:
4325+ if (match_int(args, &option))
4326+ return 0;
4327+ if (option < 0)
4328+ return 0;
4329+ mnt->mount_server.program = option;
4330+ break;
4331+ case Opt_mountvers:
4332+ if (match_int(args, &option))
4333+ return 0;
4334+ if (option < 0)
4335+ return 0;
4336+ mnt->mount_server.version = option;
4337+ break;
4338+ case Opt_nfsprog:
4339+ if (match_int(args, &option))
4340+ return 0;
4341+ if (option < 0)
4342+ return 0;
4343+ mnt->nfs_server.program = option;
4344+ break;
4345+ case Opt_nfsvers:
4346+ if (match_int(args, &option))
4347+ return 0;
4348+ switch (option) {
4349+ case 2:
4350+ mnt->flags &= ~NFS_MOUNT_VER3;
4351+ break;
4352+ case 3:
4353+ mnt->flags |= NFS_MOUNT_VER3;
4354+ break;
4355+ default:
4356+ goto out_unrec_vers;
4357 }
4358- data->root.size = NFS2_FHSIZE;
4359- memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
4360- case 4:
4361- if (data->flags & NFS_MOUNT_SECFLAVOUR) {
4362- dprintk("%s: mount structure version %d does not support strong security\n",
4363- __FUNCTION__,
4364- data->version);
4365- return -EINVAL;
4366+ break;
4367+
4368+ case Opt_sec:
4369+ string = match_strdup(args);
4370+ if (string == NULL)
4371+ goto out_nomem;
4372+ token = match_token(string, nfs_secflavor_tokens, args);
4373+ kfree(string);
4374+
4375+ /*
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.
4379+ */
4380+ switch (token) {
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;
4385+ break;
4386+ case Opt_sec_sys:
4387+ mnt->flags &= ~NFS_MOUNT_SECFLAVOUR;
4388+ mnt->auth_flavor_len = 0;
4389+ mnt->auth_flavors[0] = RPC_AUTH_UNIX;
4390+ break;
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;
4395+ break;
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;
4400+ break;
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;
4405+ break;
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;
4410+ break;
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;
4415+ break;
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;
4420+ break;
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;
4425+ break;
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;
4430+ break;
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;
4435+ break;
4436+ default:
4437+ goto out_unrec_sec;
4438 }
4439- case 5:
4440- memset(data->context, 0, sizeof(data->context));
4441- }
4442+ break;
4443+ case Opt_proto:
4444+ string = match_strdup(args);
4445+ if (string == NULL)
4446+ goto out_nomem;
4447+ token = match_token(string,
4448+ nfs_xprt_protocol_tokens, args);
4449+ kfree(string);
4450+
4451+ switch (token) {
4452+ case Opt_udp:
4453+ mnt->flags &= ~NFS_MOUNT_TCP;
4454+ mnt->nfs_server.protocol = IPPROTO_UDP;
4455+ mnt->timeo = 7;
4456+ mnt->retrans = 5;
4457+ break;
4458+ case Opt_tcp:
4459+ mnt->flags |= NFS_MOUNT_TCP;
4460+ mnt->nfs_server.protocol = IPPROTO_TCP;
4461+ mnt->timeo = 600;
4462+ mnt->retrans = 2;
4463+ break;
4464+ default:
4465+ goto out_unrec_xprt;
4466+ }
4467+ break;
4468+ case Opt_mountproto:
4469+ string = match_strdup(args);
4470+ if (string == NULL)
4471+ goto out_nomem;
4472+ token = match_token(string,
4473+ nfs_xprt_protocol_tokens, args);
4474+ kfree(string);
4475+
4476+ switch (token) {
4477+ case Opt_udp:
4478+ mnt->mount_server.protocol = IPPROTO_UDP;
4479+ break;
4480+ case Opt_tcp:
4481+ mnt->mount_server.protocol = IPPROTO_TCP;
4482+ break;
4483+ default:
4484+ goto out_unrec_xprt;
4485+ }
4486+ break;
4487+ case Opt_addr:
4488+ string = match_strdup(args);
4489+ if (string == NULL)
4490+ goto out_nomem;
4491+ mnt->nfs_server.address.sin_family = AF_INET;
4492+ mnt->nfs_server.address.sin_addr.s_addr =
4493+ in_aton(string);
4494+ kfree(string);
4495+ break;
4496+ case Opt_clientaddr:
4497+ string = match_strdup(args);
4498+ if (string == NULL)
4499+ goto out_nomem;
4500+ mnt->client_address = string;
4501+ break;
4502+ case Opt_mounthost:
4503+ string = match_strdup(args);
4504+ if (string == NULL)
4505+ goto out_nomem;
4506+ mnt->mount_server.address.sin_family = AF_INET;
4507+ mnt->mount_server.address.sin_addr.s_addr =
4508+ in_aton(string);
4509+ kfree(string);
4510+ break;
4511
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:
4517+ break;
4518
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;
4524+ default:
4525+ goto out_unknown;
4526+ }
4527 }
4528-#endif /* CONFIG_NFS_V3 */
4529
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",
4533- __FUNCTION__);
4534- return -EINVAL;
4535+ return 1;
4536+
4537+out_nomem:
4538+ printk(KERN_INFO "NFS: not enough memory to parse option\n");
4539+ return 0;
4540+
4541+out_unrec_vers:
4542+ printk(KERN_INFO "NFS: unrecognized NFS version number\n");
4543+ return 0;
4544+
4545+out_unrec_xprt:
4546+ printk(KERN_INFO "NFS: unrecognized transport protocol\n");
4547+ return 0;
4548+
4549+out_unrec_sec:
4550+ printk(KERN_INFO "NFS: unrecognized security flavor\n");
4551+ return 0;
4552+
4553+out_unknown:
4554+ printk(KERN_INFO "NFS: unknown mount option: %s\n", p);
4555+ return 0;
4556+}
4557+
4558+/*
4559+ * Use the remote server's MOUNT service to request the NFS file handle
4560+ * corresponding to the provided path.
4561+ */
4562+static int nfs_try_mount(struct nfs_parsed_mount_data *args,
4563+ struct nfs_fh *root_fh)
4564+{
4565+ struct sockaddr_in sin;
4566+ int status;
4567+
4568+ if (args->mount_server.version == 0) {
4569+ if (args->flags & NFS_MOUNT_VER3)
4570+ args->mount_server.version = NFS_MNT3_VERSION;
4571+ else
4572+ args->mount_server.version = NFS_MNT_VERSION;
4573 }
4574
4575- /* Prepare the root filehandle */
4576- if (data->flags & NFS_MOUNT_VER3)
4577- mntfh->size = data->root.size;
4578+ /*
4579+ * Construct the mount server's address.
4580+ */
4581+ if (args->mount_server.address.sin_addr.s_addr != INADDR_ANY)
4582+ sin = args->mount_server.address;
4583 else
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);
4591+ if (status < 0)
4592+ goto out_err;
4593+ sin.sin_port = htons(status);
4594+ } else
4595+ sin.sin_port = htons(args->mount_server.port);
4596+
4597+ /*
4598+ * Now ask the mount server to map our export path
4599+ * to a file handle.
4600+ */
4601+ status = nfs_mount((struct sockaddr *) &sin,
4602+ sizeof(sin),
4603+ args->nfs_server.hostname,
4604+ args->nfs_server.export_path,
4605+ args->mount_server.version,
4606+ args->mount_server.protocol,
4607+ root_fh);
4608+ if (status < 0)
4609+ goto out_err;
4610+
4611+ return status;
4612
4613- if (mntfh->size > sizeof(mntfh->data)) {
4614- dprintk("%s: invalid root filehandle\n", __FUNCTION__);
4615- return -EINVAL;
4616+out_err:
4617+ dfprintk(MOUNT, "NFS: unable to contact server on host "
4618+ NIPQUAD_FMT "\n", NIPQUAD(sin.sin_addr.s_addr));
4619+ return status;
4620+}
4621+
4622+/*
4623+ * Validate the NFS2/NFS3 mount data
4624+ * - fills in the mount root filehandle
4625+ *
4626+ * For option strings, user space handles the following behaviors:
4627+ *
4628+ * + DNS: mapping server host name to IP address ("addr=" option)
4629+ *
4630+ * + failure mode: how to behave if a mount request can't be handled
4631+ * immediately ("fg/bg" option)
4632+ *
4633+ * + retry: how often to retry a mount request ("retry=" option)
4634+ *
4635+ * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
4636+ * mountproto=tcp after mountproto=udp, and so on
4637+ *
4638+ * XXX: as far as I can tell, changing the NFS program number is not
4639+ * supported in the NFS client.
4640+ */
4641+static int nfs_validate_mount_data(struct nfs_mount_data **options,
4642+ struct nfs_fh *mntfh,
4643+ const char *dev_name)
4644+{
4645+ struct nfs_mount_data *data = *options;
4646+
4647+ if (data == NULL)
4648+ goto out_no_data;
4649+
4650+ switch (data->version) {
4651+ case 1:
4652+ data->namlen = 0;
4653+ case 2:
4654+ data->bsize = 0;
4655+ case 3:
4656+ if (data->flags & NFS_MOUNT_VER3)
4657+ goto out_no_v3;
4658+ data->root.size = NFS2_FHSIZE;
4659+ memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
4660+ case 4:
4661+ if (data->flags & NFS_MOUNT_SECFLAVOUR)
4662+ goto out_no_sec;
4663+ case 5:
4664+ memset(data->context, 0, sizeof(data->context));
4665+ case 6:
4666+ if (data->flags & NFS_MOUNT_VER3)
4667+ mntfh->size = data->root.size;
4668+ else
4669+ mntfh->size = NFS2_FHSIZE;
4670+
4671+ if (mntfh->size > sizeof(mntfh->data))
4672+ goto out_invalid_fh;
4673+
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);
4678+ break;
4679+ default: {
4680+ unsigned int len;
4681+ char *c;
4682+ int status;
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,
4687+ .timeo = 600,
4688+ .retrans = 2,
4689+ .acregmin = 3,
4690+ .acregmax = 60,
4691+ .acdirmin = 30,
4692+ .acdirmax = 60,
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,
4697+ };
4698+
4699+ if (nfs_parse_mount_options((char *) *options, &args) == 0)
4700+ return -EINVAL;
4701+
4702+ data = kzalloc(sizeof(*data), GFP_KERNEL);
4703+ if (data == NULL)
4704+ return -ENOMEM;
4705+
4706+ /*
4707+ * NB: after this point, caller will free "data"
4708+ * if we return an error
4709+ */
4710+ *options = data;
4711+
4712+ c = strchr(dev_name, ':');
4713+ if (c == NULL)
4714+ return -EINVAL;
4715+ len = c - dev_name - 1;
4716+ if (len > sizeof(data->hostname))
4717+ return -EINVAL;
4718+ strncpy(data->hostname, dev_name, len);
4719+ args.nfs_server.hostname = data->hostname;
4720+
4721+ c++;
4722+ if (strlen(c) > NFS_MAXPATHLEN)
4723+ return -EINVAL;
4724+ args.nfs_server.export_path = c;
4725+
4726+ status = nfs_try_mount(&args, mntfh);
4727+ if (status)
4728+ return -EINVAL;
4729+
4730+ /*
4731+ * Translate to nfs_mount_data, which nfs_fill_super
4732+ * can deal with.
4733+ */
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];
4748+
4749+ break;
4750+ }
4751 }
4752
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;
4759+
4760+#ifndef CONFIG_NFS_V3
4761+ if (data->flags & NFS_MOUNT_VER3)
4762+ goto out_v3_not_compiled;
4763+#endif /* !CONFIG_NFS_V3 */
4764+
4765+ if (!nfs_verify_server_address((struct sockaddr *) &data->addr))
4766+ goto out_no_address;
4767
4768 return 0;
4769+
4770+out_no_data:
4771+ dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n");
4772+ return -EINVAL;
4773+
4774+out_no_v3:
4775+ dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n",
4776+ data->version);
4777+ return -EINVAL;
4778+
4779+out_no_sec:
4780+ dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
4781+ return -EINVAL;
4782+
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 */
4788+
4789+out_no_address:
4790+ dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
4791+ return -EINVAL;
4792+
4793+out_invalid_fh:
4794+ dfprintk(MOUNT, "NFS: invalid root filehandle\n");
4795+ return -EINVAL;
4796 }
4797
4798 /*
4799@@ -600,13 +1317,51 @@ static int nfs_compare_super(struct super_block *sb, void *data)
4800 {
4801 struct nfs_server *server = data, *old = NFS_SB(sb);
4802
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)
4807+ return 0;
4808+ /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
4809+ if (old->flags & NFS_MOUNT_UNSHARED)
4810 return 0;
4811 if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
4812 return 0;
4813 return 1;
4814 }
4815
4816+#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
4817+
4818+static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
4819+{
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;
4823+
4824+ if ((s->s_flags & NFS_MS_MASK) != (flags & NFS_MS_MASK))
4825+ goto Ebusy;
4826+ if (a->nfs_client != b->nfs_client)
4827+ goto Ebusy;
4828+ if (a->flags != b->flags)
4829+ goto Ebusy;
4830+ if (a->wsize != b->wsize)
4831+ goto Ebusy;
4832+ if (a->rsize != b->rsize)
4833+ goto Ebusy;
4834+ if (a->acregmin != b->acregmin)
4835+ goto Ebusy;
4836+ if (a->acregmax != b->acregmax)
4837+ goto Ebusy;
4838+ if (a->acdirmin != b->acdirmin)
4839+ goto Ebusy;
4840+ if (a->acdirmax != b->acdirmax)
4841+ goto Ebusy;
4842+ if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
4843+ goto Ebusy;
4844+ return 0;
4845+Ebusy:
4846+ return -EBUSY;
4847+}
4848+
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)
4851 {
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;
4857 int error;
4858
4859 /* Validate the mount data */
4860- error = nfs_validate_mount_data(data, &mntfh);
4861+ error = nfs_validate_mount_data(&data, &mntfh, dev_name);
4862 if (error < 0)
4863- return error;
4864+ goto out;
4865
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;
4871+ goto out;
4872 }
4873
4874+ if (server->flags & NFS_MOUNT_UNSHARED)
4875+ compare_super = NULL;
4876+
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);
4880 if (IS_ERR(s)) {
4881 error = PTR_ERR(s);
4882 goto out_err_nosb;
4883 }
4884
4885 if (s->s_fs_info != server) {
4886+ error = nfs_compare_mount_options(s, server, flags);
4887 nfs_free_server(server);
4888 server = NULL;
4889+ if (error < 0)
4890+ goto error_splat_super;
4891 }
4892
4893 if (!s->s_root) {
4894@@ -656,17 +1418,21 @@ static int nfs_get_sb(struct file_system_type *fs_type,
4895 s->s_flags |= MS_ACTIVE;
4896 mnt->mnt_sb = s;
4897 mnt->mnt_root = mntroot;
4898- return 0;
4899+ error = 0;
4900+
4901+out:
4902+ if (data != raw_data)
4903+ kfree(data);
4904+ return error;
4905
4906 out_err_nosb:
4907 nfs_free_server(server);
4908-out_err_noserver:
4909- return error;
4910+ goto out;
4911
4912 error_splat_super:
4913 up_write(&s->s_umount);
4914 deactivate_super(s);
4915- return error;
4916+ goto out;
4917 }
4918
4919 /*
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;
4925 int error;
4926
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;
4930 }
4931
4932+ if (server->flags & NFS_MOUNT_UNSHARED)
4933+ compare_super = NULL;
4934+
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);
4938 if (IS_ERR(s)) {
4939 error = PTR_ERR(s);
4940 goto out_err_nosb;
4941 }
4942
4943 if (s->s_fs_info != server) {
4944+ error = nfs_compare_mount_options(s, server, flags);
4945 nfs_free_server(server);
4946 server = NULL;
4947+ if (error < 0)
4948+ goto error_splat_super;
4949 }
4950
4951 if (!s->s_root) {
4952@@ -772,25 +1545,164 @@ static void nfs4_fill_super(struct super_block *sb)
4953 nfs_initialise_sb(sb);
4954 }
4955
4956-static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
4957+/*
4958+ * Validate NFSv4 mount options
4959+ */
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,
4964+ char **hostname,
4965+ char **mntpath,
4966+ char **ip_addr)
4967 {
4968- void *p = NULL;
4969-
4970- if (!src->len)
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);
4976- if (p == NULL)
4977- return ERR_PTR(-ENOMEM);
4978- }
4979- if (copy_from_user(dst, src->data, maxlen)) {
4980- kfree(p);
4981- return ERR_PTR(-EFAULT);
4982+ struct nfs4_mount_data *data = *options;
4983+ char *c;
4984+
4985+ if (data == NULL)
4986+ goto out_no_data;
4987+
4988+ switch (data->version) {
4989+ case 1:
4990+ if (data->host_addrlen != sizeof(*addr))
4991+ goto out_no_address;
4992+ if (copy_from_user(addr, data->host_addr, sizeof(*addr)))
4993+ return -EFAULT;
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;
4998+
4999+ switch (data->auth_flavourlen) {
5000+ case 0:
5001+ *authflavour = RPC_AUTH_UNIX;
5002+ break;
5003+ case 1:
5004+ if (copy_from_user(authflavour, data->auth_flavours,
5005+ sizeof(*authflavour)))
5006+ return -EFAULT;
5007+ break;
5008+ default:
5009+ goto out_inval_auth;
5010+ }
5011+
5012+ c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
5013+ if (IS_ERR(c))
5014+ return PTR_ERR(c);
5015+ *hostname = c;
5016+
5017+ c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
5018+ if (IS_ERR(c))
5019+ return PTR_ERR(c);
5020+ *mntpath = c;
5021+ dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *mntpath);
5022+
5023+ c = strndup_user(data->client_addr.data, 16);
5024+ if (IS_ERR(c))
5025+ return PTR_ERR(c);
5026+ *ip_addr = c;
5027+
5028+ break;
5029+ default: {
5030+ unsigned int len;
5031+ struct nfs_parsed_mount_data args = {
5032+ .rsize = NFS_MAX_FILE_IO_SIZE,
5033+ .wsize = NFS_MAX_FILE_IO_SIZE,
5034+ .timeo = 600,
5035+ .retrans = 2,
5036+ .acregmin = 3,
5037+ .acregmax = 60,
5038+ .acdirmin = 30,
5039+ .acdirmax = 60,
5040+ .nfs_server.protocol = IPPROTO_TCP,
5041+ };
5042+
5043+ if (nfs_parse_mount_options((char *) *options, &args) == 0)
5044+ return -EINVAL;
5045+
5046+ if (!nfs_verify_server_address((struct sockaddr *)
5047+ &args.nfs_server.address))
5048+ return -EINVAL;
5049+ *addr = args.nfs_server.address;
5050+
5051+ switch (args.auth_flavor_len) {
5052+ case 0:
5053+ *authflavour = RPC_AUTH_UNIX;
5054+ break;
5055+ case 1:
5056+ *authflavour = (rpc_authflavor_t) args.auth_flavors[0];
5057+ break;
5058+ default:
5059+ goto out_inval_auth;
5060+ }
5061+
5062+ /*
5063+ * Translate to nfs4_mount_data, which nfs4_fill_super
5064+ * can deal with.
5065+ */
5066+ data = kzalloc(sizeof(*data), GFP_KERNEL);
5067+ if (data == NULL)
5068+ return -ENOMEM;
5069+ *options = data;
5070+
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;
5082+
5083+ /*
5084+ * Split "dev_name" into "hostname:mntpath".
5085+ */
5086+ c = strchr(dev_name, ':');
5087+ if (c == NULL)
5088+ return -EINVAL;
5089+ /* while calculating len, pretend ':' is '\0' */
5090+ len = c - dev_name;
5091+ if (len > NFS4_MAXNAMLEN)
5092+ return -EINVAL;
5093+ *hostname = kzalloc(len, GFP_KERNEL);
5094+ if (*hostname == NULL)
5095+ return -ENOMEM;
5096+ strncpy(*hostname, dev_name, len - 1);
5097+
5098+ c++; /* step over the ':' */
5099+ len = strlen(c);
5100+ if (len > NFS4_MAXPATHLEN)
5101+ return -EINVAL;
5102+ *mntpath = kzalloc(len + 1, GFP_KERNEL);
5103+ if (*mntpath == NULL)
5104+ return -ENOMEM;
5105+ strncpy(*mntpath, c, len);
5106+
5107+ dprintk("MNTPATH: %s\n", *mntpath);
5108+
5109+ *ip_addr = args.client_address;
5110+
5111+ break;
5112+ }
5113 }
5114- dst[maxlen] = '\0';
5115- return dst;
5116+
5117+ return 0;
5118+
5119+out_no_data:
5120+ dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n");
5121+ return -EINVAL;
5122+
5123+out_inval_auth:
5124+ dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n",
5125+ data->auth_flavourlen);
5126+ return -EINVAL;
5127+
5128+out_no_address:
5129+ dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
5130+ return -EINVAL;
5131 }
5132
5133 /*
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];
5139- void *p;
5140+ char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL;
5141+ int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
5142 int error;
5143
5144- if (data == NULL) {
5145- dprintk("%s: missing data argument\n", __FUNCTION__);
5146- return -EINVAL;
5147- }
5148- if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
5149- dprintk("%s: bad mount version\n", __FUNCTION__);
5150- return -EINVAL;
5151- }
5152-
5153- /* We now require that the mount process passes the remote address */
5154- if (data->host_addrlen != sizeof(addr))
5155- return -EINVAL;
5156-
5157- if (copy_from_user(&addr, data->host_addr, sizeof(addr)))
5158- return -EFAULT;
5159-
5160- if (addr.sin_family != AF_INET ||
5161- addr.sin_addr.s_addr == INADDR_ANY
5162- ) {
5163- dprintk("%s: mount program didn't pass remote IP address!\n",
5164- __FUNCTION__);
5165- return -EINVAL;
5166- }
5167- /* RFC3530: The default port for NFS is 2049 */
5168- if (addr.sin_port == 0)
5169- addr.sin_port = htons(NFS_PORT);
5170-
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);
5177- error = -EINVAL;
5178- goto out_err_noserver;
5179- }
5180-
5181- if (copy_from_user(&authflavour, data->auth_flavours,
5182- sizeof(authflavour))) {
5183- error = -EFAULT;
5184- goto out_err_noserver;
5185- }
5186- }
5187-
5188- p = nfs_copy_user_string(NULL, &data->hostname, 256);
5189- if (IS_ERR(p))
5190- goto out_err;
5191- hostname = p;
5192-
5193- p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
5194- if (IS_ERR(p))
5195- goto out_err;
5196- mntpath = p;
5197-
5198- dprintk("MNTPATH: %s\n", mntpath);
5199-
5200- p = nfs_copy_user_string(ip_addr, &data->client_addr,
5201- sizeof(ip_addr) - 1);
5202- if (IS_ERR(p))
5203- goto out_err;
5204+ /* Validate the mount data */
5205+ error = nfs4_validate_mount_data(&data, dev_name, &addr, &authflavour,
5206+ &hostname, &mntpath, &ip_addr);
5207+ if (error < 0)
5208+ goto out;
5209
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;
5216+ goto out;
5217 }
5218
5219+ if (server->flags & NFS4_MOUNT_UNSHARED)
5220+ compare_super = NULL;
5221+
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);
5225 if (IS_ERR(s)) {
5226 error = PTR_ERR(s);
5227 goto out_free;
5228@@ -906,25 +1766,22 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
5229 s->s_flags |= MS_ACTIVE;
5230 mnt->mnt_sb = s;
5231 mnt->mnt_root = mntroot;
5232+ error = 0;
5233+
5234+out:
5235+ kfree(ip_addr);
5236 kfree(mntpath);
5237 kfree(hostname);
5238- return 0;
5239-
5240-out_err:
5241- error = PTR_ERR(p);
5242- goto out_err_noserver;
5243+ return error;
5244
5245 out_free:
5246 nfs_free_server(server);
5247-out_err_noserver:
5248- kfree(mntpath);
5249- kfree(hostname);
5250- return error;
5251+ goto out;
5252
5253 error_splat_super:
5254 up_write(&s->s_umount);
5255 deactivate_super(s);
5256- goto out_err_noserver;
5257+ goto out;
5258 }
5259
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;
5266 int error;
5267
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;
5271 }
5272
5273+ if (server->flags & NFS4_MOUNT_UNSHARED)
5274+ compare_super = NULL;
5275+
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);
5279 if (IS_ERR(s)) {
5280 error = PTR_ERR(s);
5281 goto out_err_nosb;
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;
5287 int error;
5288
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;
5292 }
5293
5294+ if (server->flags & NFS4_MOUNT_UNSHARED)
5295+ compare_super = NULL;
5296+
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);
5300 if (IS_ERR(s)) {
5301 error = PTR_ERR(s);
5302 goto out_err_nosb;
5303diff --git a/fs/nfs/write.c b/fs/nfs/write.c
5304index 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);
5310 if (req != NULL)
5311- atomic_inc(&req->wb_count);
5312+ kref_get(&req->wb_kref);
5313 }
5314 return req;
5315 }
5316
5317 static struct nfs_page *nfs_page_find_request(struct page *page)
5318 {
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;
5322
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);
5328 return req;
5329 }
5330
5331@@ -191,8 +191,6 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
5332 }
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);
5338 return 0;
5339 }
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,
5342 struct page *page)
5343 {
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;
5349 int ret;
5350
5351- spin_lock(req_lock);
5352+ spin_lock(&inode->i_lock);
5353 for(;;) {
5354 req = nfs_page_find_request_locked(page);
5355 if (req == NULL) {
5356- spin_unlock(req_lock);
5357+ spin_unlock(&inode->i_lock);
5358 return 1;
5359 }
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).
5364 */
5365- spin_unlock(req_lock);
5366+ spin_unlock(&inode->i_lock);
5367 ret = nfs_wait_on_request(req);
5368 nfs_release_request(req);
5369 if (ret != 0)
5370 return ret;
5371- spin_lock(req_lock);
5372+ spin_lock(&inode->i_lock);
5373 }
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);
5380 return 1;
5381 }
5382 if (nfs_set_page_writeback(page) != 0) {
5383- spin_unlock(req_lock);
5384+ spin_unlock(&inode->i_lock);
5385 BUG();
5386 }
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);
5394 return ret;
5395 }
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);
5399 nfsi->npages++;
5400- atomic_inc(&req->wb_count);
5401+ kref_get(&req->wb_kref);
5402 return 0;
5403 }
5404
5405@@ -409,12 +407,12 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
5406 */
5407 static void nfs_inode_remove_request(struct nfs_page *req)
5408 {
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);
5412
5413 BUG_ON (!NFS_WBACK_BUSY(req));
5414
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);
5422 nfsi->npages--;
5423 if (!nfsi->npages) {
5424- spin_unlock(&nfsi->req_lock);
5425+ spin_unlock(&inode->i_lock);
5426 nfs_end_data_update(inode);
5427 iput(inode);
5428 } else
5429- spin_unlock(&nfsi->req_lock);
5430+ spin_unlock(&inode->i_lock);
5431 nfs_clear_request(req);
5432 nfs_release_request(req);
5433 }
5434@@ -457,14 +455,16 @@ nfs_dirty_request(struct nfs_page *req)
5435 static void
5436 nfs_mark_request_commit(struct nfs_page *req)
5437 {
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);
5441
5442- spin_lock(&nfsi->req_lock);
5443- nfs_list_add_request(req, &nfsi->commit);
5444+ spin_lock(&inode->i_lock);
5445 nfsi->ncommit++;
5446 set_bit(PG_NEED_COMMIT, &(req)->wb_flags);
5447- spin_unlock(&nfsi->req_lock);
5448+ radix_tree_tag_set(&nfsi->nfs_page_tree,
5449+ req->wb_index,
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);
5454 }
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;
5457
5458 next = idx_start;
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)
5462 break;
5463
5464 next = req->wb_index + 1;
5465 BUG_ON(!NFS_WBACK_BUSY(req));
5466
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);
5475 if (error < 0)
5476 return error;
5477 res++;
5478@@ -577,10 +577,9 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, u
5479 int res = 0;
5480
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");
5488 }
5489 return res;
5490 }
5491@@ -603,7 +602,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
5492 {
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;
5497 pgoff_t rqend, end;
5498
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
5502 */
5503- spin_lock(&nfsi->req_lock);
5504+ spin_lock(&inode->i_lock);
5505 req = nfs_page_find_request_locked(page);
5506 if (req) {
5507 if (!nfs_lock_request_dontget(req)) {
5508 int error;
5509
5510- spin_unlock(&nfsi->req_lock);
5511+ spin_unlock(&inode->i_lock);
5512 error = nfs_wait_on_request(req);
5513 nfs_release_request(req);
5514 if (error < 0) {
5515@@ -629,7 +627,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
5516 }
5517 continue;
5518 }
5519- spin_unlock(&nfsi->req_lock);
5520+ spin_unlock(&inode->i_lock);
5521 if (new)
5522 nfs_release_request(new);
5523 break;
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);
5527 if (error) {
5528- spin_unlock(&nfsi->req_lock);
5529+ spin_unlock(&inode->i_lock);
5530 nfs_unlock_request(new);
5531 return ERR_PTR(error);
5532 }
5533- spin_unlock(&nfsi->req_lock);
5534+ spin_unlock(&inode->i_lock);
5535 return new;
5536 }
5537- spin_unlock(&nfsi->req_lock);
5538+ spin_unlock(&inode->i_lock);
5539
5540 new = nfs_create_request(ctx, inode, page, offset, bytes);
5541 if (IS_ERR(new))
5542@@ -751,12 +749,17 @@ int nfs_updatepage(struct file *file, struct page *page,
5543 static void nfs_writepage_release(struct nfs_page *req)
5544 {
5545
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);
5555 } else
5556 nfs_end_page_writeback(req->wb_page);
5557- nfs_clear_page_writeback(req);
5558+ nfs_clear_page_tag_locked(req);
5559 }
5560
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. */
5564
5565 data->req = req;
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;
5569
5570 data->args.fh = NFS_FH(inode);
5571@@ -885,7 +888,7 @@ out_bad:
5572 }
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);
5577 return -ENOMEM;
5578 }
5579
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);
5586 }
5587 return -ENOMEM;
5588 }
5589@@ -954,8 +957,8 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
5590 struct page *page = req->wb_page;
5591
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),
5597 req->wb_bytes,
5598 (long long)req_offset(req));
5599
5600@@ -970,9 +973,9 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
5601 }
5602
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;
5606
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");
5615 }
5616- spin_unlock(req_lock);
5617+ spin_unlock(&inode->i_lock);
5618 } else
5619 dprintk(" OK\n");
5620
5621@@ -1020,8 +1023,8 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
5622 page = req->wb_page;
5623
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),
5629 req->wb_bytes,
5630 (long long)req_offset(req));
5631
5632@@ -1039,12 +1042,14 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
5633 dprintk(" marked for commit\n");
5634 goto next;
5635 }
5636+ /* Set the PG_uptodate flag? */
5637+ nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
5638 dprintk(" OK\n");
5639 remove_request:
5640 nfs_end_page_writeback(page);
5641 nfs_inode_remove_request(req);
5642 next:
5643- nfs_clear_page_writeback(req);
5644+ nfs_clear_page_tag_locked(req);
5645 }
5646 }
5647
5648@@ -1157,7 +1162,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
5649
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;
5654
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);
5663 }
5664 return -ENOMEM;
5665 }
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);
5668
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),
5674 req->wb_bytes,
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,
5683+ req->wb_bytes);
5684 nfs_inode_remove_request(req);
5685 dprintk(" OK\n");
5686 goto next;
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);
5690 next:
5691- nfs_clear_page_writeback(req);
5692+ nfs_clear_page_tag_locked(req);
5693 }
5694 }
5695
5696@@ -1268,13 +1276,12 @@ static const struct rpc_call_ops nfs_commit_ops = {
5697
5698 int nfs_commit_inode(struct inode *inode, int how)
5699 {
5700- struct nfs_inode *nfsi = NFS_I(inode);
5701 LIST_HEAD(head);
5702 int res;
5703
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);
5709 if (res) {
5710 int error = nfs_commit_list(inode, &head, how);
5711 if (error < 0)
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)
5714 {
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;
5719 LIST_HEAD(head);
5720@@ -1314,7 +1320,7 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
5721 }
5722 }
5723 how &= ~FLUSH_NOCOMMIT;
5724- spin_lock(&nfsi->req_lock);
5725+ spin_lock(&inode->i_lock);
5726 do {
5727 ret = nfs_wait_on_requests_locked(inode, idx_start, npages);
5728 if (ret != 0)
5729@@ -1325,18 +1331,19 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
5730 if (pages == 0)
5731 break;
5732 if (how & FLUSH_INVALIDATE) {
5733- spin_unlock(&nfsi->req_lock);
5734+ spin_unlock(&inode->i_lock);
5735 nfs_cancel_commit_list(&head);
5736 ret = pages;
5737- spin_lock(&nfsi->req_lock);
5738+ spin_lock(&inode->i_lock);
5739 continue;
5740 }
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);
5747+
5748 } while (ret >= 0);
5749- spin_unlock(&nfsi->req_lock);
5750+ spin_unlock(&inode->i_lock);
5751 return ret;
5752 }
5753
5754@@ -1430,7 +1437,6 @@ int nfs_set_page_dirty(struct page *page)
5755 {
5756 struct address_space *mapping = page->mapping;
5757 struct inode *inode;
5758- spinlock_t *req_lock;
5759 struct nfs_page *req;
5760 int ret;
5761
5762@@ -1439,18 +1445,17 @@ int nfs_set_page_dirty(struct page *page)
5763 inode = mapping->host;
5764 if (!inode)
5765 goto out_raced;
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);
5770 if (req != NULL) {
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);
5776 return ret;
5777 }
5778 ret = __set_page_dirty_nobuffers(page);
5779- spin_unlock(req_lock);
5780+ spin_unlock(&inode->i_lock);
5781 return ret;
5782 out_raced:
5783 return !TestSetPageDirty(page);
5784diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
5785index 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],
5790 .rpc_argp = clp,
5791 };
5792- char clientname[16];
5793 int status;
5794
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;
5799
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;
5804-
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)
5809 goto out_err;
5810 }
5811
5812- /* Kick rpciod, put the call on the wire. */
5813- if (rpciod_up() != 0)
5814- goto out_clnt;
5815-
5816 /* the task holds a reference to the nfs4_client struct */
5817 atomic_inc(&clp->cl_count);
5818
5819 msg.rpc_cred = nfsd4_lookupcred(clp,0);
5820 if (IS_ERR(msg.rpc_cred))
5821- goto out_rpciod;
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);
5825
5826 if (status != 0) {
5827 dprintk("NFSD: asynchronous NFSPROC4_CB_NULL failed!\n");
5828- goto out_rpciod;
5829+ goto out_release_clp;
5830 }
5831 return;
5832
5833-out_rpciod:
5834+out_release_clp:
5835 atomic_dec(&clp->cl_count);
5836- rpciod_down();
5837-out_clnt:
5838 rpc_shutdown_client(cb->cb_client);
5839 out_err:
5840 cb->cb_client = NULL;
5841diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
5842index 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)
5846 if (clnt) {
5847 clp->cl_callback.cb_client = NULL;
5848 rpc_shutdown_client(clnt);
5849- rpciod_down();
5850 }
5851 }
5852
5853diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
5854index 05707e2..e2d1ce3 100644
5855--- a/include/linux/lockd/lockd.h
5856+++ b/include/linux/lockd/lockd.h
5857@@ -39,6 +39,7 @@
5858 struct nlm_host {
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 */
5865diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
5866index 7e7f33a..8726491 100644
5867--- a/include/linux/nfs4.h
5868+++ b/include/linux/nfs4.h
5869@@ -15,6 +15,7 @@
5870
5871 #include <linux/types.h>
5872
5873+#define NFS4_BITMAP_SIZE 2
5874 #define NFS4_VERIFIER_SIZE 8
5875 #define NFS4_STATEID_SIZE 16
5876 #define NFS4_FHSIZE 128
5877diff --git a/include/linux/nfs4_mount.h b/include/linux/nfs4_mount.h
5878index 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
5888
5889 #endif
5890diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
5891index 0543439..c098ae1 100644
5892--- a/include/linux/nfs_fs.h
5893+++ b/include/linux/nfs_fs.h
5894@@ -30,7 +30,9 @@
5895 #ifdef __KERNEL__
5896
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 {
5905
5906 struct nfs4_state;
5907 struct nfs_open_context {
5908- atomic_t count;
5909- struct vfsmount *vfsmnt;
5910- struct dentry *dentry;
5911+ struct kref kref;
5912+ struct path path;
5913 struct rpc_cred *cred;
5914 struct nfs4_state *state;
5915 fl_owner_t lockowner;
5916@@ -155,13 +156,9 @@ struct nfs_inode {
5917 /*
5918 * This is the list of dirty unwritten pages.
5919 */
5920- spinlock_t req_lock;
5921- struct list_head dirty;
5922- struct list_head commit;
5923 struct radix_tree_root nfs_page_tree;
5924
5925- unsigned int ndirty,
5926- ncommit,
5927+ unsigned long ncommit,
5928 npages;
5929
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 */
5936
5937 /*
5938 * Bit offsets in flags field
5939@@ -496,21 +494,18 @@ static inline void nfs3_forget_cached_acls(struct inode *inode)
5940
5941 /*
5942 * linux/fs/mount_clnt.c
5943- * (Used only by nfsroot module)
5944 */
5945-extern int nfsroot_mount(struct sockaddr_in *, char *, struct nfs_fh *,
5946- int, int);
5947+extern int nfs_mount(struct sockaddr *, size_t, char *, char *,
5948+ int, int, struct nfs_fh *);
5949
5950 /*
5951 * inline functions
5952 */
5953
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)
5957 {
5958- loff_t maxsz = (((loff_t) ULONG_MAX) << PAGE_CACHE_SHIFT) + PAGE_CACHE_SIZE - 1;
5959- if (size > maxsz)
5960- return maxsz;
5961+ if (size > (__u64) OFFSET_MAX - 1)
5962+ return OFFSET_MAX - 1;
5963 return (loff_t) size;
5964 }
5965
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
5972
5973 #ifdef __KERNEL__
5974diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
5975index 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;
5989
5990- u32 cl_lockowner_id;
5991+ struct rb_root cl_openowner_id;
5992+ struct rb_root cl_lockowner_id;
5993
5994 /*
5995 * The following rwsem ensures exclusive access to the server
5996@@ -44,9 +44,7 @@ struct nfs_client {
5997 struct rw_semaphore cl_sem;
5998
5999 struct list_head cl_delegations;
6000- struct list_head cl_state_owners;
6001- struct list_head cl_unused;
6002- int cl_nunused;
6003+ struct rb_root cl_state_owners;
6004 spinlock_t cl_lock;
6005
6006 unsigned long cl_lease_time;
6007diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
6008index 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 */
6017 int namlen; /* 2 */
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
6026
6027 #endif
6028diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
6029index bd193af..78e6079 100644
6030--- a/include/linux/nfs_page.h
6031+++ b/include/linux/nfs_page.h
6032@@ -16,12 +16,13 @@
6033 #include <linux/sunrpc/auth.h>
6034 #include <linux/nfs_xdr.h>
6035
6036-#include <asm/atomic.h>
6037+#include <linux/kref.h>
6038
6039 /*
6040 * Valid flags for the radix tree
6041 */
6042-#define NFS_PAGE_TAG_WRITEBACK 0
6043+#define NFS_PAGE_TAG_LOCKED 0
6044+#define NFS_PAGE_TAG_COMMIT 1
6045
6046 /*
6047 * Valid flags for a dirty buffer
6048@@ -33,8 +34,7 @@
6049
6050 struct nfs_inode;
6051 struct nfs_page {
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 */
6066 };
6067@@ -71,8 +71,8 @@ extern void nfs_clear_request(struct nfs_page *req);
6068 extern void nfs_release_request(struct nfs_page *req);
6069
6070
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);
6085
6086
6087 /*
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
6090 */
6091 static inline int
6092 nfs_lock_request_dontget(struct nfs_page *req)
6093@@ -98,14 +97,14 @@ nfs_lock_request_dontget(struct nfs_page *req)
6094 }
6095
6096 /*
6097- * Lock the page of an asynchronous request
6098+ * Lock the page of an asynchronous request and take a reference
6099 */
6100 static inline int
6101 nfs_lock_request(struct nfs_page *req)
6102 {
6103 if (test_and_set_bit(PG_BUSY, &req->wb_flags))
6104 return 0;
6105- atomic_inc(&req->wb_count);
6106+ kref_get(&req->wb_kref);
6107 return 1;
6108 }
6109
6110@@ -118,7 +117,6 @@ static inline void
6111 nfs_list_add_request(struct nfs_page *req, struct list_head *head)
6112 {
6113 list_add_tail(&req->wb_list, head);
6114- req->wb_list_head = head;
6115 }
6116
6117
6118@@ -132,7 +130,6 @@ nfs_list_remove_request(struct nfs_page *req)
6119 if (list_empty(&req->wb_list))
6120 return;
6121 list_del_init(&req->wb_list);
6122- req->wb_list_head = NULL;
6123 }
6124
6125 static inline struct nfs_page *
6126diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
6127index 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;
6132 int open_flags;
6133 __u64 clientid;
6134- __u32 id;
6135+ __u64 id;
6136 union {
6137 struct iattr * attrs; /* UNCHECKED, GUARDED */
6138 nfs4_verifier verifier; /* EXCLUSIVE */
6139@@ -144,6 +144,7 @@ struct nfs_openres {
6140 nfs4_stateid delegation;
6141 __u32 do_recall;
6142 __u64 maxsize;
6143+ __u32 attrset[NFS4_BITMAP_SIZE];
6144 };
6145
6146 /*
6147@@ -180,7 +181,7 @@ struct nfs_closeres {
6148 * */
6149 struct nfs_lowner {
6150 __u64 clientid;
6151- u32 id;
6152+ __u64 id;
6153 };
6154
6155 struct nfs_lock_args {
6156diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
6157index 534cdc7..7a69ca3 100644
6158--- a/include/linux/sunrpc/auth.h
6159+++ b/include/linux/sunrpc/auth.h
6160@@ -16,6 +16,7 @@
6161 #include <linux/sunrpc/xdr.h>
6162
6163 #include <asm/atomic.h>
6164+#include <linux/rcupdate.h>
6165
6166 /* size of the nodename buffer */
6167 #define UNX_MAXNODENAME 32
6168@@ -30,22 +31,28 @@ struct auth_cred {
6169 /*
6170 * Client user credentials
6171 */
6172+struct rpc_auth;
6173+struct rpc_credops;
6174 struct rpc_cred {
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;
6184 #ifdef RPC_DEBUG
6185 unsigned long cr_magic; /* 0x0f4aa4f0 */
6186 #endif
6187+ unsigned long cr_expire; /* when to gc */
6188+ unsigned long cr_flags; /* various flags */
6189+ atomic_t cr_count; /* ref count */
6190
6191 uid_t cr_uid;
6192
6193 /* per-flavor data */
6194 };
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
6200
6201 #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0
6202
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 */
6209+ spinlock_t lock;
6210 };
6211
6212+struct rpc_authops;
6213 struct rpc_auth {
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;
6218
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 *);
6227 };
6228
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;
6233-#endif
6234+extern const struct rpc_authops authunix_ops;
6235+extern const struct rpc_authops authnull_ops;
6236+
6237+void __init rpc_init_authunix(void);
6238+void __init rpcauth_init_module(void);
6239+void __exit rpcauth_remove_module(void);
6240
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 *);
6262
6263 static inline
6264 struct rpc_cred * get_rpccred(struct rpc_cred *cred)
6265diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
6266index 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;
6271 u32 gc_win;
6272 unsigned long gc_expiry;
6273+ struct rcu_head gc_rcu;
6274 };
6275
6276 struct gss_upcall_msg;
6277@@ -85,11 +86,6 @@ struct gss_cred {
6278 struct gss_upcall_msg *gc_upcall;
6279 };
6280
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
6285-
6286 #endif /* __KERNEL__ */
6287 #endif /* _LINUX_SUNRPC_AUTH_GSS_H */
6288
6289diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
6290index 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
6295 */
6296 struct rpc_clnt {
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() */
6314
6315 struct rpc_rtt * cl_rtt; /* RTO estimator data */
6316
6317@@ -98,6 +98,7 @@ struct rpc_create_args {
6318 int protocol;
6319 struct sockaddr *address;
6320 size_t addrsize;
6321+ struct sockaddr *saddress;
6322 struct rpc_timeout *timeout;
6323 char *servername;
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)
6336
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 *);
6345+
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 *);
6350
6351 void rpc_call_setup(struct rpc_task *, struct rpc_message *, int);
6352
6353@@ -132,20 +133,16 @@ int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg,
6354 void *calldata);
6355 int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
6356 int flags);
6357+struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
6358+ int flags);
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);
6368
6369-/*
6370- * Helper function for NFSroot support
6371- */
6372-int rpcb_getport_external(struct sockaddr_in *, __u32, __u32, int);
6373-
6374 #endif /* __KERNEL__ */
6375 #endif /* _LINUX_SUNRPC_CLNT_H */
6376diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
6377index 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;
6383 char *gm_name;
6384- struct gss_api_ops *gm_ops;
6385+ const struct gss_api_ops *gm_ops;
6386 /* pseudoflavors supported by this mechanism: */
6387 int gm_pf_num;
6388 struct pf_desc * gm_pfs;
6389diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
6390index 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 {
6394 void *private;
6395 struct list_head pipe;
6396 struct list_head in_upcall;
6397+ struct list_head in_downcall;
6398 int pipelen;
6399 int nreaders;
6400 int nwriters;
6401+ int nkern_readwriters;
6402 wait_queue_head_t waitq;
6403 #define RPC_PIPE_WAIT_FOR_OPEN 1
6404 int flags;
6405diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
6406index 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 */
6411 #endif
6412 };
6413-#define tk_auth tk_client->cl_auth
6414 #define tk_xprt tk_client->cl_xprt
6415
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))
6420
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)
6425-
6426 typedef void (*rpc_action)(struct rpc_task *);
6427
6428 struct rpc_call_ops {
6429diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
6430index 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;
6436
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 */
6440 };
6441diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
6442index 34f7590..d11cedd 100644
6443--- a/include/linux/sunrpc/xprt.h
6444+++ b/include/linux/sunrpc/xprt.h
6445@@ -17,6 +17,8 @@
6446 #include <linux/sunrpc/xdr.h>
6447 #include <linux/sunrpc/msg_prot.h>
6448
6449+#ifdef __KERNEL__
6450+
6451 extern unsigned int xprt_udp_slot_table_entries;
6452 extern unsigned int xprt_tcp_slot_table_entries;
6453
6454@@ -194,7 +196,13 @@ struct rpc_xprt {
6455 char * address_strings[RPC_DISPLAY_MAX];
6456 };
6457
6458-#ifdef __KERNEL__
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 */
6463+ size_t addrlen;
6464+ struct rpc_timeout * timeout; /* optional timeout parameters */
6465+};
6466
6467 /*
6468 * Transport operations used by ULPs
6469@@ -204,7 +212,7 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long
6470 /*
6471 * Generic internal transport functions
6472 */
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);
6479 /*
6480 * Socket transport setup operations
6481 */
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);
6488
6489diff --git a/kernel/auditsc.c b/kernel/auditsc.c
6490index 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;
6495 }
6496 }
6497+EXPORT_SYMBOL(__audit_inode_child);
6498
6499 /**
6500 * auditsc_get_stamp - get local copies of audit_context values
6501diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
6502index 9527f2b..74baf87 100644
6503--- a/net/sunrpc/auth.c
6504+++ b/net/sunrpc/auth.c
6505@@ -18,12 +18,16 @@
6506 # define RPCDBG_FACILITY RPCDBG_AUTH
6507 #endif
6508
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 */
6515 };
6516
6517+static LIST_HEAD(cred_unused);
6518+static unsigned long number_cred_unused;
6519+
6520 static u32
6521 pseudoflavor_to_flavor(u32 flavor) {
6522 if (flavor >= RPC_AUTH_MAXFLAVOR)
6523@@ -32,55 +36,67 @@ pseudoflavor_to_flavor(u32 flavor) {
6524 }
6525
6526 int
6527-rpcauth_register(struct rpc_authops *ops)
6528+rpcauth_register(const struct rpc_authops *ops)
6529 {
6530 rpc_authflavor_t flavor;
6531+ int ret = -EPERM;
6532
6533 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
6534 return -EINVAL;
6535- if (auth_flavors[flavor] != NULL)
6536- return -EPERM; /* what else? */
6537- auth_flavors[flavor] = ops;
6538- return 0;
6539+ spin_lock(&rpc_authflavor_lock);
6540+ if (auth_flavors[flavor] == NULL) {
6541+ auth_flavors[flavor] = ops;
6542+ ret = 0;
6543+ }
6544+ spin_unlock(&rpc_authflavor_lock);
6545+ return ret;
6546 }
6547
6548 int
6549-rpcauth_unregister(struct rpc_authops *ops)
6550+rpcauth_unregister(const struct rpc_authops *ops)
6551 {
6552 rpc_authflavor_t flavor;
6553+ int ret = -EPERM;
6554
6555 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
6556 return -EINVAL;
6557- if (auth_flavors[flavor] != ops)
6558- return -EPERM; /* what else? */
6559- auth_flavors[flavor] = NULL;
6560- return 0;
6561+ spin_lock(&rpc_authflavor_lock);
6562+ if (auth_flavors[flavor] == ops) {
6563+ auth_flavors[flavor] = NULL;
6564+ ret = 0;
6565+ }
6566+ spin_unlock(&rpc_authflavor_lock);
6567+ return ret;
6568 }
6569
6570 struct rpc_auth *
6571 rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
6572 {
6573 struct rpc_auth *auth;
6574- struct rpc_authops *ops;
6575+ const struct rpc_authops *ops;
6576 u32 flavor = pseudoflavor_to_flavor(pseudoflavor);
6577
6578 auth = ERR_PTR(-EINVAL);
6579 if (flavor >= RPC_AUTH_MAXFLAVOR)
6580 goto out;
6581
6582- /* FIXME - auth_flavors[] really needs an rw lock,
6583- * and module refcounting. */
6584 #ifdef CONFIG_KMOD
6585 if ((ops = auth_flavors[flavor]) == NULL)
6586 request_module("rpc-auth-%u", flavor);
6587 #endif
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);
6593 goto out;
6594+ }
6595+ spin_unlock(&rpc_authflavor_lock);
6596 auth = ops->create(clnt, pseudoflavor);
6597+ module_put(ops->owner);
6598 if (IS_ERR(auth))
6599 return auth;
6600 if (clnt->cl_auth)
6601- rpcauth_destroy(clnt->cl_auth);
6602+ rpcauth_release(clnt->cl_auth);
6603 clnt->cl_auth = auth;
6604
6605 out:
6606@@ -88,7 +104,7 @@ out:
6607 }
6608
6609 void
6610-rpcauth_destroy(struct rpc_auth *auth)
6611+rpcauth_release(struct rpc_auth *auth)
6612 {
6613 if (!atomic_dec_and_test(&auth->au_count))
6614 return;
6615@@ -97,11 +113,31 @@ rpcauth_destroy(struct rpc_auth *auth)
6616
6617 static DEFINE_SPINLOCK(rpc_credcache_lock);
6618
6619+static void
6620+rpcauth_unhash_cred_locked(struct rpc_cred *cred)
6621+{
6622+ hlist_del_rcu(&cred->cr_hash);
6623+ smp_mb__before_clear_bit();
6624+ clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
6625+}
6626+
6627+static void
6628+rpcauth_unhash_cred(struct rpc_cred *cred)
6629+{
6630+ spinlock_t *cache_lock;
6631+
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);
6637+}
6638+
6639 /*
6640 * Initialize RPC credential cache
6641 */
6642 int
6643-rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
6644+rpcauth_init_credcache(struct rpc_auth *auth)
6645 {
6646 struct rpc_cred_cache *new;
6647 int i;
6648@@ -111,8 +147,7 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
6649 return -ENOMEM;
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;
6656 return 0;
6657 }
6658@@ -121,13 +156,13 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
6659 * Destroy a list of credentials
6660 */
6661 static inline
6662-void rpcauth_destroy_credlist(struct hlist_head *head)
6663+void rpcauth_destroy_credlist(struct list_head *head)
6664 {
6665 struct rpc_cred *cred;
6666
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);
6673 put_rpccred(cred);
6674 }
6675 }
6676@@ -137,58 +172,95 @@ void rpcauth_destroy_credlist(struct hlist_head *head)
6677 * that are not referenced.
6678 */
6679 void
6680-rpcauth_free_credcache(struct rpc_auth *auth)
6681+rpcauth_clear_credcache(struct rpc_cred_cache *cache)
6682 {
6683- struct rpc_cred_cache *cache = auth->au_credcache;
6684- HLIST_HEAD(free);
6685- struct hlist_node *pos, *next;
6686+ LIST_HEAD(free);
6687+ struct hlist_head *head;
6688 struct rpc_cred *cred;
6689 int i;
6690
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--;
6705+ }
6706+ list_add_tail(&cred->cr_lru, &free);
6707+ rpcauth_unhash_cred_locked(cred);
6708 }
6709 }
6710+ spin_unlock(&cache->lock);
6711 spin_unlock(&rpc_credcache_lock);
6712 rpcauth_destroy_credlist(&free);
6713 }
6714
6715-static void
6716-rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist_head *free)
6717+/*
6718+ * Destroy the RPC credential cache
6719+ */
6720+void
6721+rpcauth_destroy_credcache(struct rpc_auth *auth)
6722 {
6723- if (atomic_read(&cred->cr_count) != 1)
6724- return;
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;
6731+
6732+ if (cache) {
6733+ auth->au_credcache = NULL;
6734+ rpcauth_clear_credcache(cache);
6735+ kfree(cache);
6736 }
6737 }
6738
6739 /*
6740 * Remove stale credentials. Avoid sleeping inside the loop.
6741 */
6742-static void
6743-rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free)
6744+static int
6745+rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
6746 {
6747- struct rpc_cred_cache *cache = auth->au_credcache;
6748- struct hlist_node *pos, *next;
6749- struct rpc_cred *cred;
6750- int i;
6751+ spinlock_t *cache_lock;
6752+ struct rpc_cred *cred;
6753
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)
6764+ continue;
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);
6771+ nr_to_scan--;
6772 }
6773+ spin_unlock(cache_lock);
6774+ if (nr_to_scan == 0)
6775+ break;
6776 }
6777- cache->nextgc = jiffies + cache->expire;
6778+ return nr_to_scan;
6779+}
6780+
6781+/*
6782+ * Run memory cache shrinker.
6783+ */
6784+static int
6785+rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
6786+{
6787+ LIST_HEAD(free);
6788+ int res;
6789+
6790+ if (list_empty(&cred_unused))
6791+ return 0;
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);
6797+ return res;
6798 }
6799
6800 /*
6801@@ -198,53 +270,56 @@ struct rpc_cred *
6802 rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
6803 int flags)
6804 {
6805+ LIST_HEAD(free);
6806 struct rpc_cred_cache *cache = auth->au_credcache;
6807- HLIST_HEAD(free);
6808- struct hlist_node *pos, *next;
6809- struct rpc_cred *new = NULL,
6810- *cred = NULL;
6811+ struct hlist_node *pos;
6812+ struct rpc_cred *cred = NULL,
6813+ *entry, *new;
6814 int nr = 0;
6815
6816 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
6817 nr = acred->uid & RPC_CREDCACHE_MASK;
6818-retry:
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);
6827- cred = entry;
6828- break;
6829+
6830+ rcu_read_lock();
6831+ hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
6832+ if (!entry->cr_ops->crmatch(acred, entry, flags))
6833+ continue;
6834+ spin_lock(&cache->lock);
6835+ if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) {
6836+ spin_unlock(&cache->lock);
6837+ continue;
6838 }
6839- rpcauth_prune_expired(auth, entry, &free);
6840- }
6841- if (new) {
6842- if (cred)
6843- hlist_add_head(&new->cr_hash, &free);
6844- else
6845- cred = new;
6846+ cred = get_rpccred(entry);
6847+ spin_unlock(&cache->lock);
6848+ break;
6849 }
6850- if (cred) {
6851- hlist_add_head(&cred->cr_hash, &cache->hashtable[nr]);
6852- get_rpccred(cred);
6853- }
6854- spin_unlock(&rpc_credcache_lock);
6855+ rcu_read_unlock();
6856
6857- rpcauth_destroy_credlist(&free);
6858+ if (cred != NULL)
6859+ goto found;
6860
6861- if (!cred) {
6862- new = auth->au_ops->crcreate(auth, acred, flags);
6863- if (!IS_ERR(new)) {
6864-#ifdef RPC_DEBUG
6865- new->cr_magic = RPCAUTH_CRED_MAGIC;
6866-#endif
6867- goto retry;
6868- } else
6869- cred = new;
6870- } else if ((cred->cr_flags & RPCAUTH_CRED_NEW)
6871+ new = auth->au_ops->crcreate(auth, acred, flags);
6872+ if (IS_ERR(new)) {
6873+ cred = new;
6874+ goto out;
6875+ }
6876+
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))
6880+ continue;
6881+ cred = get_rpccred(entry);
6882+ break;
6883+ }
6884+ if (cred == NULL) {
6885+ cred = new;
6886+ set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
6887+ hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]);
6888+ } else
6889+ list_add_tail(&new->cr_lru, &free);
6890+ spin_unlock(&cache->lock);
6891+found:
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);
6898 }
6899 }
6900-
6901- return (struct rpc_cred *) cred;
6902+ rpcauth_destroy_credlist(&free);
6903+out:
6904+ return cred;
6905 }
6906
6907 struct rpc_cred *
6908@@ -275,10 +351,27 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
6909 return ret;
6910 }
6911
6912+void
6913+rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
6914+ struct rpc_auth *auth, const struct rpc_credops *ops)
6915+{
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;
6922+#ifdef RPC_DEBUG
6923+ cred->cr_magic = RPCAUTH_CRED_MAGIC;
6924+#endif
6925+ cred->cr_uid = acred->uid;
6926+}
6927+EXPORT_SYMBOL(rpcauth_init_cred);
6928+
6929 struct rpc_cred *
6930 rpcauth_bindcred(struct rpc_task *task)
6931 {
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)
6938 int flags = 0;
6939
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)
6947 void
6948 rpcauth_holdcred(struct rpc_task *task)
6949 {
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);
6960+ }
6961 }
6962
6963 void
6964 put_rpccred(struct rpc_cred *cred)
6965 {
6966- cred->cr_expire = jiffies;
6967+ /* Fast path for unhashed credentials */
6968+ if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
6969+ goto need_lock;
6970+
6971 if (!atomic_dec_and_test(&cred->cr_count))
6972 return;
6973+ goto out_destroy;
6974+need_lock:
6975+ if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock))
6976+ return;
6977+ if (!list_empty(&cred->cr_lru)) {
6978+ number_cred_unused--;
6979+ list_del_init(&cred->cr_lru);
6980+ }
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);
6988+ return;
6989+ }
6990+ spin_unlock(&rpc_credcache_lock);
6991+out_destroy:
6992 cred->cr_ops->crdestroy(cred);
6993 }
6994
6995@@ -326,7 +442,7 @@ rpcauth_unbindcred(struct rpc_task *task)
6996 struct rpc_cred *cred = task->tk_msg.rpc_cred;
6997
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);
7001
7002 put_rpccred(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;
7006
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);
7010
7011 return cred->cr_ops->crmarshal(task, p);
7012 }
7013@@ -349,7 +465,7 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p)
7014 struct rpc_cred *cred = task->tk_msg.rpc_cred;
7015
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);
7019
7020 return cred->cr_ops->crvalidate(task, p);
7021 }
7022@@ -390,7 +506,7 @@ rpcauth_refreshcred(struct rpc_task *task)
7023 int err;
7024
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);
7028
7029 err = cred->cr_ops->crrefresh(task);
7030 if (err < 0)
7031@@ -401,17 +517,34 @@ rpcauth_refreshcred(struct rpc_task *task)
7032 void
7033 rpcauth_invalcred(struct rpc_task *task)
7034 {
7035+ struct rpc_cred *cred = task->tk_msg.rpc_cred;
7036+
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);
7044+ if (cred)
7045+ clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7046 }
7047
7048 int
7049 rpcauth_uptodatecred(struct rpc_task *task)
7050 {
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;
7054+
7055+ return cred == NULL ||
7056+ test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
7057+}
7058+
7059+
7060+static struct shrinker *rpc_cred_shrinker;
7061+
7062+void __init rpcauth_init_module(void)
7063+{
7064+ rpc_init_authunix();
7065+ rpc_cred_shrinker = set_shrinker(DEFAULT_SEEKS, rpcauth_cache_shrinker);
7066+}
7067+
7068+void __exit rpcauth_remove_module(void)
7069+{
7070+ if (rpc_cred_shrinker != NULL)
7071+ remove_shrinker(rpc_cred_shrinker);
7072 }
7073diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
7074index 4e4ccc5..17d460f 100644
7075--- a/net/sunrpc/auth_gss/auth_gss.c
7076+++ b/net/sunrpc/auth_gss/auth_gss.c
7077@@ -54,9 +54,10 @@
7078 #include <linux/sunrpc/gss_api.h>
7079 #include <asm/uaccess.h>
7080
7081-static struct rpc_authops authgss_ops;
7082+static const struct rpc_authops authgss_ops;
7083
7084-static struct rpc_credops gss_credops;
7085+static const struct rpc_credops gss_credops;
7086+static const struct rpc_credops gss_nullops;
7087
7088 #ifdef RPC_DEBUG
7089 # define RPCDBG_FACILITY RPCDBG_AUTH
7090@@ -64,7 +65,6 @@ static struct rpc_credops gss_credops;
7091
7092 #define NFS_NGROUPS 16
7093
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))
7101
7102-static DEFINE_RWLOCK(gss_ctx_lock);
7103-
7104 struct gss_auth {
7105+ struct kref kref;
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;
7112- spinlock_t lock;
7113 };
7114
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;
7118
7119 static inline struct gss_cl_ctx *
7120@@ -105,20 +102,24 @@ static inline void
7121 gss_put_ctx(struct gss_cl_ctx *ctx)
7122 {
7123 if (atomic_dec_and_test(&ctx->count))
7124- gss_destroy_ctx(ctx);
7125+ gss_free_ctx(ctx);
7126 }
7127
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.
7132+ */
7133 static void
7134 gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
7135 {
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);
7139+
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);
7148 if (old)
7149 gss_put_ctx(old);
7150 }
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);
7153 int res = 0;
7154
7155- read_lock(&gss_ctx_lock);
7156- if ((cred->cr_flags & RPCAUTH_CRED_UPTODATE) && gss_cred->gc_ctx)
7157+ rcu_read_lock();
7158+ if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) && gss_cred->gc_ctx)
7159 res = 1;
7160- read_unlock(&gss_ctx_lock);
7161+ rcu_read_unlock();
7162 return res;
7163 }
7164
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;
7168
7169- read_lock(&gss_ctx_lock);
7170+ rcu_read_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();
7175 return ctx;
7176 }
7177
7178@@ -269,10 +270,10 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
7179 }
7180
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)
7184 {
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)
7189 continue;
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)
7194 {
7195+ struct inode *inode = gss_auth->dentry->d_inode;
7196+ struct rpc_inode *rpci = RPC_I(inode);
7197 struct gss_upcall_msg *old;
7198
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);
7203 if (old == NULL) {
7204 atomic_inc(&gss_msg->count);
7205- list_add(&gss_msg->list, &gss_auth->upcalls);
7206+ list_add(&gss_msg->list, &rpci->in_downcall);
7207 } else
7208 gss_msg = old;
7209- spin_unlock(&gss_auth->lock);
7210+ spin_unlock(&inode->i_lock);
7211 return gss_msg;
7212 }
7213
7214 static void
7215 __gss_unhash_msg(struct gss_upcall_msg *gss_msg)
7216 {
7217- if (list_empty(&gss_msg->list))
7218- return;
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)
7224 {
7225 struct gss_auth *gss_auth = gss_msg->auth;
7226+ struct inode *inode = gss_auth->dentry->d_inode;
7227
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))
7232+ return;
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);
7237 }
7238
7239 static void
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;
7245
7246- BUG_ON(gss_msg == NULL);
7247+ spin_lock(&inode->i_lock);
7248 if (gss_msg->ctx)
7249 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx));
7250 else
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);
7258 }
7259
7260@@ -386,11 +391,12 @@ static inline int
7261 gss_refresh_upcall(struct rpc_task *task)
7262 {
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;
7271 int err = 0;
7272
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);
7276 goto out;
7277 }
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);
7285 } else
7286 err = gss_msg->msg.errno;
7287- spin_unlock(&gss_auth->lock);
7288+ spin_unlock(&inode->i_lock);
7289 gss_release_msg(gss_msg);
7290 out:
7291 dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n",
7292@@ -422,6 +428,7 @@ out:
7293 static inline int
7294 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
7295 {
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;
7299 DEFINE_WAIT(wait);
7300@@ -435,12 +442,11 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
7301 }
7302 for (;;) {
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);
7308 break;
7309 }
7310- spin_unlock(&gss_auth->lock);
7311+ spin_unlock(&inode->i_lock);
7312 if (signalled()) {
7313 err = -ERESTARTSYS;
7314 goto out_intr;
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));
7317 else
7318 err = gss_msg->msg.errno;
7319+ spin_unlock(&inode->i_lock);
7320 out_intr:
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;
7325 void *buf;
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;
7332 uid_t uid;
7333- int err = -EFBIG;
7334+ ssize_t err = -EFBIG;
7335
7336 if (mlen > MSG_BUF_MAXSIZE)
7337 goto out;
7338@@ -503,7 +509,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
7339 if (!buf)
7340 goto out;
7341
7342- clnt = RPC_I(filp->f_path.dentry->d_inode)->private;
7343+ clnt = RPC_I(inode)->private;
7344 err = -EFAULT;
7345 if (copy_from_user(buf, src, mlen))
7346 goto err;
7347@@ -519,43 +525,38 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
7348 ctx = gss_alloc_context();
7349 if (ctx == NULL)
7350 goto err;
7351- err = 0;
7352- gss_auth = container_of(clnt->cl_auth, struct gss_auth, rpc_auth);
7353- p = gss_fill_context(p, end, ctx, gss_auth->mech);
7354+
7355+ err = -ENOENT;
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);
7361+ goto err_put_ctx;
7362+ }
7363+ list_del_init(&gss_msg->list);
7364+ spin_unlock(&inode->i_lock);
7365+
7366+ p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
7367 if (IS_ERR(p)) {
7368 err = PTR_ERR(p);
7369- if (err != -EACCES)
7370- goto err_put_ctx;
7371- }
7372- spin_lock(&gss_auth->lock);
7373- gss_msg = __gss_find_upcall(gss_auth, uid);
7374- if (gss_msg) {
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);
7381- } else {
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);
7387- goto err_put_ctx;
7388- }
7389- gss_cred_set_ctx(cred, gss_get_ctx(ctx));
7390+ gss_msg->msg.errno = (err == -EACCES) ? -EACCES : -EAGAIN;
7391+ goto err_release_msg;
7392 }
7393- gss_put_ctx(ctx);
7394- kfree(buf);
7395- dprintk("RPC: gss_pipe_downcall returning length %Zu\n", mlen);
7396- return mlen;
7397+ gss_msg->ctx = gss_get_ctx(ctx);
7398+ err = mlen;
7399+
7400+err_release_msg:
7401+ spin_lock(&inode->i_lock);
7402+ __gss_unhash_msg(gss_msg);
7403+ spin_unlock(&inode->i_lock);
7404+ gss_release_msg(gss_msg);
7405 err_put_ctx:
7406 gss_put_ctx(ctx);
7407 err:
7408 kfree(buf);
7409 out:
7410- dprintk("RPC: gss_pipe_downcall returning %d\n", err);
7411+ dprintk("RPC: gss_pipe_downcall returning %Zd\n", err);
7412 return err;
7413 }
7414
7415@@ -563,27 +564,21 @@ static void
7416 gss_pipe_release(struct inode *inode)
7417 {
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;
7423
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)) {
7432
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);
7444 }
7445- spin_unlock(&gss_auth->lock);
7446+ spin_unlock(&inode->i_lock);
7447 }
7448
7449 static void
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)
7453 goto err_put_mech;
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);
7462-
7463- err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE);
7464- if (err)
7465- goto err_put_mech;
7466+ kref_init(&gss_auth->kref);
7467
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)
7471 goto err_put_mech;
7472 }
7473
7474+ err = rpcauth_init_credcache(auth);
7475+ if (err)
7476+ goto err_unlink_pipe;
7477+
7478 return auth;
7479+err_unlink_pipe:
7480+ rpc_unlink(gss_auth->dentry);
7481 err_put_mech:
7482 gss_mech_put(gss_auth->mech);
7483 err_free:
7484@@ -668,6 +664,25 @@ out_dec:
7485 }
7486
7487 static void
7488+gss_free(struct gss_auth *gss_auth)
7489+{
7490+ rpc_unlink(gss_auth->dentry);
7491+ gss_auth->dentry = NULL;
7492+ gss_mech_put(gss_auth->mech);
7493+
7494+ kfree(gss_auth);
7495+ module_put(THIS_MODULE);
7496+}
7497+
7498+static void
7499+gss_free_callback(struct kref *kref)
7500+{
7501+ struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
7502+
7503+ gss_free(gss_auth);
7504+}
7505+
7506+static void
7507 gss_destroy(struct rpc_auth *auth)
7508 {
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);
7513
7514+ rpcauth_destroy_credcache(auth);
7515+
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);
7521+}
7522
7523- rpcauth_free_credcache(auth);
7524- kfree(gss_auth);
7525- module_put(THIS_MODULE);
7526+/*
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.
7531+ */
7532+static int
7533+gss_destroying_context(struct rpc_cred *cred)
7534+{
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;
7538+
7539+ if (gss_cred->gc_ctx == NULL ||
7540+ gss_cred->gc_ctx->gc_proc == RPC_GSS_PROC_DESTROY)
7541+ return 0;
7542+
7543+ gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY;
7544+ cred->cr_ops = &gss_nullops;
7545+
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);
7549+
7550+ task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC);
7551+ if (!IS_ERR(task))
7552+ rpc_put_task(task);
7553+
7554+ put_rpccred(cred);
7555+ return 1;
7556 }
7557
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. */
7562 static void
7563-gss_destroy_ctx(struct gss_cl_ctx *ctx)
7564+gss_do_free_ctx(struct gss_cl_ctx *ctx)
7565 {
7566- dprintk("RPC: gss_destroy_ctx\n");
7567+ dprintk("RPC: gss_free_ctx\n");
7568
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)
7572 }
7573
7574 static void
7575-gss_destroy_cred(struct rpc_cred *rc)
7576+gss_free_ctx_callback(struct rcu_head *head)
7577 {
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);
7581+}
7582
7583- dprintk("RPC: gss_destroy_cred \n");
7584+static void
7585+gss_free_ctx(struct gss_cl_ctx *ctx)
7586+{
7587+ call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
7588+}
7589
7590- if (cred->gc_ctx)
7591- gss_put_ctx(cred->gc_ctx);
7592- kfree(cred);
7593+static void
7594+gss_free_cred(struct gss_cred *gss_cred)
7595+{
7596+ dprintk("RPC: gss_free_cred %p\n", gss_cred);
7597+ kfree(gss_cred);
7598+}
7599+
7600+static void
7601+gss_free_cred_callback(struct rcu_head *head)
7602+{
7603+ struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu);
7604+ gss_free_cred(gss_cred);
7605+}
7606+
7607+static void
7608+gss_destroy_cred(struct rpc_cred *cred)
7609+{
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;
7613+
7614+ if (gss_destroying_context(cred))
7615+ return;
7616+ rcu_assign_pointer(gss_cred->gc_ctx, NULL);
7617+ call_rcu(&cred->cr_rcu, gss_free_cred_callback);
7618+ if (ctx)
7619+ gss_put_ctx(ctx);
7620+ kref_put(&gss_auth->kref, gss_free_callback);
7621 }
7622
7623 /*
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)))
7626 goto out_err;
7627
7628- atomic_set(&cred->gc_count, 1);
7629- cred->gc_uid = acred->uid;
7630+ rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops);
7631 /*
7632 * Note: in order to force a call to call_refresh(), we deliberately
7633 * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
7634 */
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;
7642
7643 out_err:
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.
7647 */
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))
7650 goto out;
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);
7661 goto out_put_ctx;
7662@@ -855,6 +927,13 @@ gss_refresh(struct rpc_task *task)
7663 return 0;
7664 }
7665
7666+/* Dummy refresh routine: used only when destroying the context */
7667+static int
7668+gss_refresh_null(struct rpc_task *task)
7669+{
7670+ return -EACCES;
7671+}
7672+
7673 static __be32 *
7674 gss_validate(struct rpc_task *task, __be32 *p)
7675 {
7676@@ -883,12 +962,15 @@ gss_validate(struct rpc_task *task, __be32 *p)
7677
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;
7681- if (maj_stat)
7682+ clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
7683+ if (maj_stat) {
7684+ dprintk("RPC: %5u gss_validate: gss_verify_mic returned"
7685+ "error 0x%08x\n", task->tk_pid, maj_stat);
7686 goto out_bad;
7687+ }
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;
7692 gss_put_ctx(ctx);
7693 dprintk("RPC: %5u gss_validate: gss_verify_mic succeeded.\n",
7694 task->tk_pid);
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);
7701 else if (maj_stat)
7702 return status;
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);
7710 else if (maj_stat)
7711 return status;
7712
7713@@ -1123,7 +1205,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
7714
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)
7720 return status;
7721 return 0;
7722@@ -1148,7 +1230,7 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
7723
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)
7729 return status;
7730 if (ntohl(*(*p)++) != rqstp->rq_seqno)
7731@@ -1188,7 +1270,7 @@ gss_unwrap_resp(struct rpc_task *task,
7732 break;
7733 }
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);
7738 out_decode:
7739 status = decode(rqstp, p, obj);
7740@@ -1199,7 +1281,7 @@ out:
7741 return status;
7742 }
7743
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,
7748 #ifdef RPC_DEBUG
7749@@ -1211,7 +1293,7 @@ static struct rpc_authops authgss_ops = {
7750 .crcreate = gss_create_cred
7751 };
7752
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,
7760 };
7761
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,
7771+};
7772+
7773 static struct rpc_pipe_ops gss_upcall_ops = {
7774 .upcall = gss_pipe_upcall,
7775 .downcall = gss_pipe_downcall,
7776diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
7777index 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) {
7781 kfree(kctx);
7782 }
7783
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,
7789diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
7790index 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,
7794 return err;
7795 }
7796
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,
7802diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
7803index 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)
7807 static int
7808 nul_refresh(struct rpc_task *task)
7809 {
7810- task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
7811+ set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
7812 return 0;
7813 }
7814
7815@@ -101,7 +101,7 @@ nul_validate(struct rpc_task *task, __be32 *p)
7816 return p;
7817 }
7818
7819-struct rpc_authops authnull_ops = {
7820+const struct rpc_authops authnull_ops = {
7821 .owner = THIS_MODULE,
7822 .au_flavor = RPC_AUTH_NULL,
7823 #ifdef RPC_DEBUG
7824@@ -122,7 +122,7 @@ struct rpc_auth null_auth = {
7825 };
7826
7827 static
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 = {
7834
7835 static
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,
7843 #ifdef RPC_DEBUG
7844 .cr_magic = RPCAUTH_CRED_MAGIC,
7845 #endif
7846diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
7847index 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];
7852 };
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
7857-
7858-#define UNX_CRED_EXPIRE (60 * HZ)
7859
7860 #define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
7861
7862@@ -34,15 +29,14 @@ struct unx_cred {
7863
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;
7868
7869 static struct rpc_auth *
7870 unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
7871 {
7872 dprintk("RPC: creating UNIX authenticator for client %p\n",
7873 clnt);
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);
7877 return &unix_auth;
7878 }
7879
7880@@ -50,7 +44,7 @@ static void
7881 unx_destroy(struct rpc_auth *auth)
7882 {
7883 dprintk("RPC: destroying UNIX authenticator %p\n", auth);
7884- rpcauth_free_credcache(auth);
7885+ rpcauth_clear_credcache(auth->au_credcache);
7886 }
7887
7888 /*
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);
7892
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) {
7898 cred->uc_uid = 0;
7899 cred->uc_gid = 0;
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;
7903
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;
7910 }
7911- cred->uc_base.cr_ops = &unix_credops;
7912
7913- return (struct rpc_cred *) cred;
7914+ return &cred->uc_base;
7915+}
7916+
7917+static void
7918+unx_free_cred(struct unx_cred *unx_cred)
7919+{
7920+ dprintk("RPC: unx_free_cred %p\n", unx_cred);
7921+ kfree(unx_cred);
7922+}
7923+
7924+static void
7925+unx_free_cred_callback(struct rcu_head *head)
7926+{
7927+ struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
7928+ unx_free_cred(unx_cred);
7929 }
7930
7931 static void
7932 unx_destroy_cred(struct rpc_cred *cred)
7933 {
7934- kfree(cred);
7935+ call_rcu(&cred->cr_rcu, unx_free_cred_callback);
7936 }
7937
7938 /*
7939@@ -111,7 +117,7 @@ unx_destroy_cred(struct rpc_cred *cred)
7940 static int
7941 unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
7942 {
7943- struct unx_cred *cred = (struct unx_cred *) rcred;
7944+ struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
7945 int i;
7946
7947 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
7948@@ -142,7 +148,7 @@ static __be32 *
7949 unx_marshal(struct rpc_task *task, __be32 *p)
7950 {
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;
7955 int i;
7956
7957@@ -175,7 +181,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
7958 static int
7959 unx_refresh(struct rpc_task *task)
7960 {
7961- task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
7962+ set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
7963 return 0;
7964 }
7965
7966@@ -198,13 +204,18 @@ unx_validate(struct rpc_task *task, __be32 *p)
7967 printk("RPC: giant verf size: %u\n", size);
7968 return NULL;
7969 }
7970- task->tk_auth->au_rslack = (size >> 2) + 2;
7971+ task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2;
7972 p += (size >> 2);
7973
7974 return p;
7975 }
7976
7977-struct rpc_authops authunix_ops = {
7978+void __init rpc_init_authunix(void)
7979+{
7980+ spin_lock_init(&unix_cred_cache.lock);
7981+}
7982+
7983+const struct rpc_authops authunix_ops = {
7984 .owner = THIS_MODULE,
7985 .au_flavor = RPC_AUTH_UNIX,
7986 #ifdef RPC_DEBUG
7987@@ -218,7 +229,6 @@ struct rpc_authops authunix_ops = {
7988
7989 static
7990 struct rpc_cred_cache unix_cred_cache = {
7991- .expire = UNX_CRED_EXPIRE,
7992 };
7993
7994 static
7995@@ -232,7 +242,7 @@ struct rpc_auth unix_auth = {
7996 };
7997
7998 static
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,
8004diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
8005index d8fbee4..5d3fe7b 100644
8006--- a/net/sunrpc/clnt.c
8007+++ b/net/sunrpc/clnt.c
8008@@ -44,6 +44,12 @@
8009 dprintk("RPC: %5u %s (status %d)\n", t->tk_pid, \
8010 __FUNCTION__, t->tk_status)
8011
8012+/*
8013+ * All RPC clients are linked into this list
8014+ */
8015+static LIST_HEAD(all_clients);
8016+static DEFINE_SPINLOCK(rpc_client_lock);
8017+
8018 static DECLARE_WAIT_QUEUE_HEAD(destroy_wait);
8019
8020
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);
8024
8025+static int rpc_ping(struct rpc_clnt *clnt, int flags);
8026+
8027+static void rpc_register_client(struct rpc_clnt *clnt)
8028+{
8029+ spin_lock(&rpc_client_lock);
8030+ list_add(&clnt->cl_clients, &all_clients);
8031+ spin_unlock(&rpc_client_lock);
8032+}
8033+
8034+static void rpc_unregister_client(struct rpc_clnt *clnt)
8035+{
8036+ spin_lock(&rpc_client_lock);
8037+ list_del(&clnt->cl_clients);
8038+ spin_unlock(&rpc_client_lock);
8039+}
8040
8041 static int
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);
8046
8047+ err = rpciod_up();
8048+ if (err)
8049+ goto out_no_rpciod;
8050 err = -EINVAL;
8051 if (!xprt)
8052 goto out_no_xprt;
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);
8055 if (!clnt)
8056 goto out_err;
8057- atomic_set(&clnt->cl_users, 0);
8058- atomic_set(&clnt->cl_count, 1);
8059 clnt->cl_parent = clnt;
8060
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)
8064 goto out_no_stats;
8065 clnt->cl_program = program;
8066+ INIT_LIST_HEAD(&clnt->cl_tasks);
8067+ spin_lock_init(&clnt->cl_lock);
8068
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);
8074
8075+ kref_init(&clnt->cl_kref);
8076+
8077 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
8078 if (err < 0)
8079 goto out_no_path;
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);
8085 return clnt;
8086
8087 out_no_auth:
8088@@ -188,6 +215,8 @@ out_no_stats:
8089 out_err:
8090 xprt_put(xprt);
8091 out_no_xprt:
8092+ rpciod_down();
8093+out_no_rpciod:
8094 return ERR_PTR(err);
8095 }
8096
8097@@ -205,13 +234,32 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
8098 {
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
8107+ };
8108+ char servername[20];
8109
8110- xprt = xprt_create_transport(args->protocol, args->address,
8111- args->addrsize, args->timeout);
8112+ xprt = xprt_create_transport(&xprtargs);
8113 if (IS_ERR(xprt))
8114 return (struct rpc_clnt *)xprt;
8115
8116 /*
8117+ * If the caller chooses not to specify a hostname, whip
8118+ * up a string representation of the passed-in address.
8119+ */
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;
8126+ }
8127+
8128+ /*
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)
8133 clnt->cl_intr = 1;
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;
8140
8141@@ -268,24 +314,25 @@ rpc_clone_client(struct rpc_clnt *clnt)
8142 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
8143 if (!new)
8144 goto out_no_clnt;
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)
8155 goto out_no_stats;
8156+ kref_init(&new->cl_kref);
8157 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
8158 if (err != 0)
8159 goto out_no_path;
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;
8166- new->cl_dead = 0;
8167- rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
8168 if (new->cl_auth)
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);
8173+ rpciod_up();
8174 return new;
8175 out_no_path:
8176 rpc_free_iostats(new->cl_metrics);
8177@@ -298,86 +345,86 @@ out_no_clnt:
8178
8179 /*
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.
8184+ * requests.
8185 */
8186-int
8187-rpc_shutdown_client(struct rpc_clnt *clnt)
8188+void rpc_shutdown_client(struct rpc_clnt *clnt)
8189 {
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));
8193-
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);
8200+
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);
8205- }
8206-
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));
8210-#ifdef RPC_DEBUG
8211- rpc_show_tasks();
8212-#endif
8213- BUG();
8214+ list_empty(&clnt->cl_tasks), 1*HZ);
8215 }
8216
8217- return rpc_destroy_client(clnt);
8218+ rpc_release_client(clnt);
8219 }
8220
8221 /*
8222- * Delete an RPC client
8223+ * Free an RPC client
8224 */
8225-int
8226-rpc_destroy_client(struct rpc_clnt *clnt)
8227+static void
8228+rpc_free_client(struct kref *kref)
8229 {
8230- if (!atomic_dec_and_test(&clnt->cl_count))
8231- return 1;
8232- BUG_ON(atomic_read(&clnt->cl_users) != 0);
8233+ struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
8234
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;
8240- }
8241 if (!IS_ERR(clnt->cl_dentry)) {
8242 rpc_rmdir(clnt->cl_dentry);
8243 rpc_put_mount();
8244 }
8245 if (clnt->cl_parent != clnt) {
8246- rpc_destroy_client(clnt->cl_parent);
8247+ rpc_release_client(clnt->cl_parent);
8248 goto out_free;
8249 }
8250 if (clnt->cl_server != clnt->cl_inline_name)
8251 kfree(clnt->cl_server);
8252 out_free:
8253+ rpc_unregister_client(clnt);
8254 rpc_free_iostats(clnt->cl_metrics);
8255 clnt->cl_metrics = NULL;
8256 xprt_put(clnt->cl_xprt);
8257+ rpciod_down();
8258 kfree(clnt);
8259- return 0;
8260 }
8261
8262 /*
8263- * Release an RPC client
8264+ * Free an RPC client
8265+ */
8266+static void
8267+rpc_free_auth(struct kref *kref)
8268+{
8269+ struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
8270+
8271+ if (clnt->cl_auth == NULL) {
8272+ rpc_free_client(kref);
8273+ return;
8274+ }
8275+
8276+ /*
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.
8280+ */
8281+ kref_init(kref);
8282+ rpcauth_release(clnt->cl_auth);
8283+ clnt->cl_auth = NULL;
8284+ kref_put(kref, rpc_free_client);
8285+}
8286+
8287+/*
8288+ * Release reference to the RPC client
8289 */
8290 void
8291 rpc_release_client(struct rpc_clnt *clnt)
8292 {
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);
8296
8297- if (!atomic_dec_and_test(&clnt->cl_users))
8298- return;
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);
8305 }
8306
8307 /**
8308@@ -468,82 +515,96 @@ void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
8309 rpc_restore_sigmask(oldset);
8310 }
8311
8312-/*
8313- * New rpc_call implementation
8314+static
8315+struct rpc_task *rpc_do_run_task(struct rpc_clnt *clnt,
8316+ struct rpc_message *msg,
8317+ int flags,
8318+ const struct rpc_call_ops *ops,
8319+ void *data)
8320+{
8321+ struct rpc_task *task, *ret;
8322+ sigset_t oldset;
8323+
8324+ task = rpc_new_task(clnt, flags, ops, data);
8325+ if (task == NULL) {
8326+ rpc_release_calldata(ops, data);
8327+ return ERR_PTR(-ENOMEM);
8328+ }
8329+
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);
8337+ goto out;
8338+ }
8339+ }
8340+ atomic_inc(&task->tk_count);
8341+ rpc_execute(task);
8342+ ret = task;
8343+out:
8344+ rpc_restore_sigmask(&oldset);
8345+ return ret;
8346+}
8347+
8348+/**
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
8353 */
8354 int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
8355 {
8356 struct rpc_task *task;
8357- sigset_t oldset;
8358- int status;
8359-
8360- /* If this client is slain all further I/O fails */
8361- if (clnt->cl_dead)
8362- return -EIO;
8363+ int status;
8364
8365 BUG_ON(flags & RPC_TASK_ASYNC);
8366
8367- task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL);
8368- if (task == NULL)
8369- return -ENOMEM;
8370-
8371- /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
8372- rpc_task_sigmask(task, &oldset);
8373-
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);
8379- }
8380+ task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL);
8381+ if (IS_ERR(task))
8382+ return PTR_ERR(task);
8383 status = task->tk_status;
8384 rpc_put_task(task);
8385- rpc_restore_sigmask(&oldset);
8386 return status;
8387 }
8388
8389-/*
8390- * New rpc_call implementation
8391+/**
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
8398 */
8399 int
8400 rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
8401 const struct rpc_call_ops *tk_ops, void *data)
8402 {
8403 struct rpc_task *task;
8404- sigset_t oldset;
8405- int status;
8406-
8407- /* If this client is slain all further I/O fails */
8408- status = -EIO;
8409- if (clnt->cl_dead)
8410- goto out_release;
8411-
8412- flags |= RPC_TASK_ASYNC;
8413-
8414- /* Create/initialize a new RPC task */
8415- status = -ENOMEM;
8416- if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
8417- goto out_release;
8418-
8419- /* Mask signals on GSS_AUTH upcalls */
8420- rpc_task_sigmask(task, &oldset);
8421
8422- rpc_call_setup(task, msg, 0);
8423-
8424- /* Set up the call info struct and execute the task */
8425- status = task->tk_status;
8426- if (status == 0)
8427- rpc_execute(task);
8428- else
8429- rpc_put_task(task);
8430-
8431- rpc_restore_sigmask(&oldset);
8432- return status;
8433-out_release:
8434- rpc_release_calldata(tk_ops, data);
8435- return status;
8436+ task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data);
8437+ if (IS_ERR(task))
8438+ return PTR_ERR(task);
8439+ rpc_put_task(task);
8440+ return 0;
8441 }
8442
8443+/**
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
8449+ */
8450+struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
8451+ const struct rpc_call_ops *tk_ops,
8452+ void *data)
8453+{
8454+ return rpc_do_run_task(clnt, NULL, flags, tk_ops, data);
8455+}
8456+EXPORT_SYMBOL(rpc_run_task);
8457
8458 void
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)
8461 static void
8462 call_allocate(struct rpc_task *task)
8463 {
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
8471 * undefined results
8472 */
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);
8479 goto out_eio;
8480 }
8481 if ((len -= 3) < 0)
8482@@ -1283,7 +1344,8 @@ call_verify(struct rpc_task *task)
8483 p += 1; /* skip XID */
8484
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);
8489 goto out_garbage;
8490 }
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);
8494 break;
8495 default:
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);
8499 error = -EIO;
8500 }
8501 dprintk("RPC: %5u %s: call rejected %d\n",
8502@@ -1342,7 +1405,8 @@ call_verify(struct rpc_task *task)
8503 goto out_err;
8504 }
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 */
8510 }
8511 len = p - (__be32 *)iov->iov_base - 1;
8512@@ -1381,7 +1445,8 @@ call_verify(struct rpc_task *task)
8513 task->tk_pid, __FUNCTION__);
8514 break; /* retry */
8515 default:
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);
8519 /* Also retry */
8520 }
8521
8522@@ -1395,14 +1460,16 @@ out_garbage:
8523 out_retry:
8524 return ERR_PTR(-EAGAIN);
8525 }
8526- printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
8527 out_eio:
8528 error = -EIO;
8529 out_err:
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);
8534 out_overflow:
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,
8537+ __FUNCTION__);
8538 goto out_garbage;
8539 }
8540
8541@@ -1421,7 +1488,7 @@ static struct rpc_procinfo rpcproc_null = {
8542 .p_decode = rpcproc_decode_null,
8543 };
8544
8545-int rpc_ping(struct rpc_clnt *clnt, int flags)
8546+static int rpc_ping(struct rpc_clnt *clnt, int flags)
8547 {
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);
8552 return err;
8553 }
8554+
8555+struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags)
8556+{
8557+ struct rpc_message msg = {
8558+ .rpc_proc = &rpcproc_null,
8559+ .rpc_cred = cred,
8560+ };
8561+ return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL);
8562+}
8563+EXPORT_SYMBOL(rpc_call_null);
8564+
8565+#ifdef RPC_DEBUG
8566+void rpc_show_tasks(void)
8567+{
8568+ struct rpc_clnt *clnt;
8569+ struct rpc_task *t;
8570+
8571+ spin_lock(&rpc_client_lock);
8572+ if (list_empty(&all_clients))
8573+ goto out;
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))
8578+ continue;
8579+ spin_lock(&clnt->cl_lock);
8580+ list_for_each_entry(t, &clnt->cl_tasks, tk_task) {
8581+ const char *rpc_waitq = "none";
8582+
8583+ if (RPC_IS_QUEUED(t))
8584+ rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
8585+
8586+ printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
8587+ t->tk_pid,
8588+ (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
8589+ t->tk_flags, t->tk_status,
8590+ t->tk_client,
8591+ (t->tk_client ? t->tk_client->cl_prog : 0),
8592+ t->tk_rqstp, t->tk_timeout,
8593+ rpc_waitq,
8594+ t->tk_action, t->tk_ops);
8595+ }
8596+ spin_unlock(&clnt->cl_lock);
8597+ }
8598+out:
8599+ spin_unlock(&rpc_client_lock);
8600+}
8601+#endif
8602diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
8603index 5887457..22e25b5 100644
8604--- a/net/sunrpc/rpc_pipe.c
8605+++ b/net/sunrpc/rpc_pipe.c
8606@@ -14,7 +14,7 @@
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>
8613
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;
8618 if (clnt) {
8619- atomic_inc(&clnt->cl_users);
8620+ kref_get(&clnt->cl_kref);
8621 m->private = clnt;
8622 } else {
8623 single_release(inode, file);
8624@@ -448,6 +448,15 @@ void rpc_put_mount(void)
8625 simple_release_fs(&rpc_mount, &rpc_mount_count);
8626 }
8627
8628+static int rpc_delete_dentry(struct dentry *dentry)
8629+{
8630+ return 1;
8631+}
8632+
8633+static struct dentry_operations rpc_dentry_operations = {
8634+ .d_delete = rpc_delete_dentry,
8635+};
8636+
8637 static int
8638 rpc_lookup_parent(char *path, struct nameidata *nd)
8639 {
8640@@ -506,7 +515,7 @@ rpc_get_inode(struct super_block *sb, int mode)
8641 * FIXME: This probably has races.
8642 */
8643 static void
8644-rpc_depopulate(struct dentry *parent)
8645+rpc_depopulate(struct dentry *parent, int start, int eof)
8646 {
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)
8656+ continue;
8657 spin_lock(&dentry->d_lock);
8658 if (!d_unhashed(dentry)) {
8659 dget_locked(dentry);
8660@@ -533,11 +546,11 @@ repeat:
8661 if (n) {
8662 do {
8663 dentry = dvec[--n];
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);
8668- }
8669- inode_dir_notify(dir, DN_DELETE);
8670+ else if (S_ISDIR(dentry->d_inode->i_mode))
8671+ simple_rmdir(dir, dentry);
8672+ d_delete(dentry);
8673 dput(dentry);
8674 } while (n);
8675 goto repeat;
8676@@ -560,6 +573,7 @@ rpc_populate(struct dentry *parent,
8677 dentry = d_alloc_name(parent, files[i].name);
8678 if (!dentry)
8679 goto out_bad;
8680+ dentry->d_op = &rpc_dentry_operations;
8681 mode = files[i].mode;
8682 inode = rpc_get_inode(dir->i_sb, mode);
8683 if (!inode) {
8684@@ -574,6 +588,7 @@ rpc_populate(struct dentry *parent,
8685 if (S_ISDIR(mode))
8686 inc_nlink(dir);
8687 d_add(dentry, inode);
8688+ fsnotify_create(dir, dentry);
8689 }
8690 mutex_unlock(&dir->i_mutex);
8691 return 0;
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);
8695 inc_nlink(dir);
8696- inode_dir_notify(dir, DN_CREATE);
8697+ fsnotify_mkdir(dir, dentry);
8698 return 0;
8699 out_err:
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)
8703 {
8704 int error;
8705-
8706- shrink_dcache_parent(dentry);
8707- if (d_unhashed(dentry))
8708- return 0;
8709- if ((error = simple_rmdir(dir, dentry)) != 0)
8710- return error;
8711- if (!error) {
8712- inode_dir_notify(dir, DN_DELETE);
8713- d_drop(dentry);
8714- }
8715- return 0;
8716+ error = simple_rmdir(dir, dentry);
8717+ if (!error)
8718+ d_delete(dentry);
8719+ return error;
8720 }
8721
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)
8725 {
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);
8730 if (IS_ERR(dentry))
8731 goto out_err;
8732- if (dentry->d_inode) {
8733+ if (!dentry->d_inode)
8734+ dentry->d_op = &rpc_dentry_operations;
8735+ else if (exclusive) {
8736 dput(dentry);
8737 dentry = ERR_PTR(-EEXIST);
8738 goto out_err;
8739@@ -649,7 +659,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
8740
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);
8745 if (IS_ERR(dentry))
8746 rpc_release_path(nd);
8747 return dentry;
8748@@ -681,7 +691,7 @@ out:
8749 rpc_release_path(&nd);
8750 return dentry;
8751 err_depopulate:
8752- rpc_depopulate(dentry);
8753+ rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF);
8754 __rpc_rmdir(dir, dentry);
8755 err_dput:
8756 dput(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);
8764 dput(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;
8769
8770- dentry = rpc_lookup_create(parent, name, strlen(name));
8771+ dentry = rpc_lookup_create(parent, name, strlen(name), 0);
8772 if (IS_ERR(dentry))
8773 return dentry;
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) {
8780+ dput (dentry);
8781+ dentry = ERR_PTR(-EBUSY);
8782+ }
8783+ rpci->nkern_readwriters++;
8784+ goto out;
8785+ }
8786 inode = rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR);
8787 if (!inode)
8788 goto err_dput;
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;
8792 rpci->ops = ops;
8793- inode_dir_notify(dir, DN_CREATE);
8794+ rpci->nkern_readwriters = 1;
8795+ fsnotify_create(dir, dentry);
8796 dget(dentry);
8797 out:
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)) {
8804- d_drop(dentry);
8805- if (dentry->d_inode) {
8806- rpc_close_pipes(dentry->d_inode);
8807- error = simple_unlink(dir, dentry);
8808- }
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);
8813+ if (!error)
8814+ d_delete(dentry);
8815 }
8816 dput(dentry);
8817 mutex_unlock(&dir->i_mutex);
8818@@ -833,6 +853,7 @@ init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
8819 rpci->nreaders = 0;
8820 rpci->nwriters = 0;
8821 INIT_LIST_HEAD(&rpci->in_upcall);
8822+ INIT_LIST_HEAD(&rpci->in_downcall);
8823 INIT_LIST_HEAD(&rpci->pipe);
8824 rpci->pipelen = 0;
8825 init_waitqueue_head(&rpci->waitq);
8826diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
8827index 6c7aa8a..d1740db 100644
8828--- a/net/sunrpc/rpcb_clnt.c
8829+++ b/net/sunrpc/rpcb_clnt.c
8830@@ -12,6 +12,8 @@
8831 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
8832 */
8833
8834+#include <linux/module.h>
8835+
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,
8841 .version = version,
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),
8847 };
8848
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)
8851
8852 error = rpc_call_sync(rpcb_clnt, &msg, 0);
8853
8854+ rpc_shutdown_client(rpcb_clnt);
8855 if (error < 0)
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)
8859 return error;
8860 }
8861
8862-#ifdef CONFIG_ROOT_NFS
8863 /**
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
8870 *
8871 * Called from outside the RPC client in a synchronous task context.
8872+ * Uses default timeout parameters specified by underlying transport.
8873 *
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
8877 */
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)
8882 {
8883 struct rpcbind_args map = {
8884 .r_prog = prog,
8885@@ -277,15 +279,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog,
8886 char hostname[40];
8887 int status;
8888
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);
8893
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);
8899
8900 status = rpc_call_sync(rpcb_clnt, &msg, 0);
8901+ rpc_shutdown_client(rpcb_clnt);
8902
8903 if (status >= 0) {
8904 if (map.r_port != 0)
8905@@ -294,16 +297,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog,
8906 }
8907 return status;
8908 }
8909-#endif
8910+EXPORT_SYMBOL_GPL(rpcb_getport_sync);
8911
8912 /**
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
8916 *
8917 * This one can be called for an ongoing RPC request, and can be used in
8918 * an async (rpciod) context.
8919 */
8920-void rpcb_getport(struct rpc_task *task)
8921+void rpcb_getport_async(struct rpc_task *task)
8922 {
8923 struct rpc_clnt *clnt = task->tk_client;
8924 int bind_version;
8925@@ -314,17 +317,17 @@ void rpcb_getport(struct rpc_task *task)
8926 struct sockaddr addr;
8927 int status;
8928
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);
8935
8936 /* Autobind on cloned rpc clients is discouraged */
8937 BUG_ON(clnt->cl_parent != clnt);
8938
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",
8942- task->tk_pid);
8943+ dprintk("RPC: %5u %s: waiting for another binder\n",
8944+ task->tk_pid, __FUNCTION__);
8945 goto bailout_nowake;
8946 }
8947
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)) {
8951 status = 0;
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;
8956 }
8957
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;
8966 }
8967 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
8968
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);
8973
8974 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
8975 if (!map) {
8976 status = -ENOMEM;
8977- dprintk("RPC: %5u rpcb_getport no memory available\n",
8978- task->tk_pid);
8979+ dprintk("RPC: %5u %s: no memory available\n",
8980+ task->tk_pid, __FUNCTION__);
8981 goto bailout_nofree;
8982 }
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));
8992 goto bailout;
8993 }
8994
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)) {
8998 status = -EIO;
8999- dprintk("RPC: %5u rpcb_getport rpc_run_task failed\n",
9000- task->tk_pid);
9001+ dprintk("RPC: %5u %s: rpc_run_task failed\n",
9002+ task->tk_pid, __FUNCTION__);
9003 goto bailout_nofree;
9004 }
9005 rpc_put_task(child);
9006diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
9007index 944d753..2ac43c4 100644
9008--- a/net/sunrpc/sched.c
9009+++ b/net/sunrpc/sched.c
9010@@ -25,7 +25,6 @@
9011 #ifdef RPC_DEBUG
9012 #define RPCDBG_FACILITY RPCDBG_SCHED
9013 #define RPC_TASK_MAGIC_ID 0xf00baa
9014-static int rpc_task_id;
9015 #endif
9016
9017 /*
9018@@ -40,7 +39,6 @@ static mempool_t *rpc_task_mempool __read_mostly;
9019 static mempool_t *rpc_buffer_mempool __read_mostly;
9020
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);
9025
9026@@ -50,23 +48,13 @@ static void rpc_release_task(struct rpc_task *task);
9027 static RPC_WAITQ(delay_queue, "delayq");
9028
9029 /*
9030- * All RPC tasks are linked into this list
9031- */
9032-static LIST_HEAD(all_tasks);
9033-
9034-/*
9035 * rpciod-related stuff
9036 */
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;
9041
9042 /*
9043- * Spinlock for other critical sections of code.
9044- */
9045-static DEFINE_SPINLOCK(rpc_sched_lock);
9046-
9047-/*
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
9050 * rpc_run_timer().
9051@@ -267,18 +255,33 @@ static int rpc_wait_bit_interruptible(void *word)
9052 return 0;
9053 }
9054
9055+#ifdef RPC_DEBUG
9056+static void rpc_task_set_debuginfo(struct rpc_task *task)
9057+{
9058+ static atomic_t rpc_pid;
9059+
9060+ task->tk_magic = RPC_TASK_MAGIC_ID;
9061+ task->tk_pid = atomic_inc_return(&rpc_pid);
9062+}
9063+#else
9064+static inline void rpc_task_set_debuginfo(struct rpc_task *task)
9065+{
9066+}
9067+#endif
9068+
9069 static void rpc_set_active(struct rpc_task *task)
9070 {
9071+ struct rpc_clnt *clnt;
9072 if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
9073 return;
9074- spin_lock(&rpc_sched_lock);
9075-#ifdef RPC_DEBUG
9076- task->tk_magic = RPC_TASK_MAGIC_ID;
9077- task->tk_pid = rpc_task_id++;
9078-#endif
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);
9088+ }
9089 }
9090
9091 /*
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);
9097
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;
9102
9103 if (clnt) {
9104- atomic_inc(&clnt->cl_users);
9105+ kref_get(&clnt->cl_kref);
9106 if (clnt->cl_softrtry)
9107 task->tk_flags |= RPC_TASK_SOFT;
9108 if (!clnt->cl_intr)
9109@@ -860,9 +864,7 @@ static void rpc_free_task(struct rcu_head *rcu)
9110 }
9111
9112 /*
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.
9117 */
9118 struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
9119 {
9120@@ -870,7 +872,7 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
9121
9122 task = rpc_alloc_task();
9123 if (!task)
9124- goto cleanup;
9125+ goto out;
9126
9127 rpc_init_task(task, clnt, flags, tk_ops, calldata);
9128
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;
9131 out:
9132 return task;
9133-
9134-cleanup:
9135- /* Check whether to release the client */
9136- if (clnt) {
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);
9141- }
9142- goto out;
9143 }
9144
9145
9146@@ -920,11 +912,13 @@ static void rpc_release_task(struct rpc_task *task)
9147 #endif
9148 dprintk("RPC: %5u release task\n", task->tk_pid);
9149
9150- /* Remove from global task list */
9151- spin_lock(&rpc_sched_lock);
9152- list_del(&task->tk_task);
9153- spin_unlock(&rpc_sched_lock);
9154-
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);
9161+ }
9162 BUG_ON (RPC_IS_QUEUED(task));
9163
9164 /* Synchronously delete any running timer */
9165@@ -939,29 +933,6 @@ static void rpc_release_task(struct rpc_task *task)
9166 rpc_put_task(task);
9167 }
9168
9169-/**
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
9175- */
9176-struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
9177- const struct rpc_call_ops *ops,
9178- void *data)
9179-{
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);
9185- }
9186- atomic_inc(&task->tk_count);
9187- rpc_execute(task);
9188- return task;
9189-}
9190-EXPORT_SYMBOL(rpc_run_task);
9191-
9192 /*
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)
9197 {
9198 struct rpc_task *rovr;
9199- struct list_head *le;
9200
9201- dprintk("RPC: killing all tasks for client %p\n", clnt);
9202
9203+ if (list_empty(&clnt->cl_tasks))
9204+ return;
9205+ dprintk("RPC: killing all tasks for client %p\n", clnt);
9206 /*
9207 * Spin lock all_tasks to prevent changes...
9208 */
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))
9214 continue;
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);
9220 }
9221 }
9222- spin_unlock(&rpc_sched_lock);
9223-}
9224-
9225-static void rpciod_killall(void)
9226-{
9227- unsigned long flags;
9228-
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 "
9235- "to exit\n");
9236- yield();
9237- }
9238- }
9239-
9240- spin_lock_irqsave(&current->sighand->siglock, flags);
9241- recalc_sigpending();
9242- spin_unlock_irqrestore(&current->sighand->siglock, flags);
9243+ spin_unlock(&clnt->cl_lock);
9244 }
9245
9246 /*
9247@@ -1018,28 +970,27 @@ rpciod_up(void)
9248 struct workqueue_struct *wq;
9249 int error = 0;
9250
9251+ if (atomic_inc_not_zero(&rpciod_users))
9252+ return 0;
9253+
9254 mutex_lock(&rpciod_mutex);
9255- dprintk("RPC: rpciod_up: users %u\n", rpciod_users);
9256- rpciod_users++;
9257- if (rpciod_workqueue)
9258- goto out;
9259- /*
9260- * If there's no pid, we should be the first user.
9261- */
9262- if (rpciod_users > 1)
9263- printk(KERN_WARNING "rpciod_up: no workqueue, %u users??\n", rpciod_users);
9264+
9265+ /* Guard against races with rpciod_down() */
9266+ if (rpciod_workqueue != NULL)
9267+ goto out_ok;
9268 /*
9269 * Create the rpciod thread and wait for it to start.
9270 */
9271+ dprintk("RPC: creating workqueue rpciod\n");
9272 error = -ENOMEM;
9273 wq = create_workqueue("rpciod");
9274- if (wq == NULL) {
9275- printk(KERN_WARNING "rpciod_up: create workqueue failed, error=%d\n", error);
9276- rpciod_users--;
9277+ if (wq == NULL)
9278 goto out;
9279- }
9280+
9281 rpciod_workqueue = wq;
9282 error = 0;
9283+out_ok:
9284+ atomic_inc(&rpciod_users);
9285 out:
9286 mutex_unlock(&rpciod_mutex);
9287 return error;
9288@@ -1048,59 +999,19 @@ out:
9289 void
9290 rpciod_down(void)
9291 {
9292+ if (!atomic_dec_and_test(&rpciod_users))
9293+ return;
9294+
9295 mutex_lock(&rpciod_mutex);
9296- dprintk("RPC: rpciod_down sema %u\n", rpciod_users);
9297- if (rpciod_users) {
9298- if (--rpciod_users)
9299- goto out;
9300- } else
9301- printk(KERN_WARNING "rpciod_down: no users??\n");
9302+ dprintk("RPC: destroying workqueue rpciod\n");
9303
9304- if (!rpciod_workqueue) {
9305- dprintk("RPC: rpciod_down: Nothing to do!\n");
9306- goto out;
9307+ if (atomic_read(&rpciod_users) == 0 && rpciod_workqueue != NULL) {
9308+ destroy_workqueue(rpciod_workqueue);
9309+ rpciod_workqueue = NULL;
9310 }
9311- rpciod_killall();
9312-
9313- destroy_workqueue(rpciod_workqueue);
9314- rpciod_workqueue = NULL;
9315- out:
9316 mutex_unlock(&rpciod_mutex);
9317 }
9318
9319-#ifdef RPC_DEBUG
9320-void rpc_show_tasks(void)
9321-{
9322- struct list_head *le;
9323- struct rpc_task *t;
9324-
9325- spin_lock(&rpc_sched_lock);
9326- if (list_empty(&all_tasks)) {
9327- spin_unlock(&rpc_sched_lock);
9328- return;
9329- }
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";
9334-
9335- if (RPC_IS_QUEUED(t))
9336- rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
9337-
9338- printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
9339- t->tk_pid,
9340- (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
9341- t->tk_flags, t->tk_status,
9342- t->tk_client,
9343- (t->tk_client ? t->tk_client->cl_prog : 0),
9344- t->tk_rqstp, t->tk_timeout,
9345- rpc_waitq,
9346- t->tk_action, t->tk_ops);
9347- }
9348- spin_unlock(&rpc_sched_lock);
9349-}
9350-#endif
9351-
9352 void
9353 rpc_destroy_mempool(void)
9354 {
9355diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
9356index 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);
9367
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);
9383
9384@@ -156,6 +152,7 @@ init_sunrpc(void)
9385 cache_register(&ip_map_cache);
9386 cache_register(&unix_gid_cache);
9387 init_socket_xprt();
9388+ rpcauth_init_module();
9389 out:
9390 return err;
9391 }
9392@@ -163,6 +160,7 @@ out:
9393 static void __exit
9394 cleanup_sunrpc(void)
9395 {
9396+ rpcauth_remove_module();
9397 cleanup_socket_xprt();
9398 unregister_rpc_pipefs();
9399 rpc_destroy_mempool();
9400diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
9401index 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,
9407 };
9408+ struct sockaddr *sin;
9409 int len;
9410
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;
9415
9416+ /* Destination address in request is needed for binding the
9417+ * source address in RPC callbacks later.
9418+ */
9419+ sin = (struct sockaddr *)&svsk->sk_local;
9420+ switch (sin->sa_family) {
9421+ case AF_INET:
9422+ rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr;
9423+ break;
9424+ case AF_INET6:
9425+ rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr;
9426+ break;
9427+ }
9428+
9429 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
9430 svsk, iov[0].iov_base, iov[0].iov_len, len);
9431
9432@@ -1064,6 +1078,12 @@ svc_tcp_accept(struct svc_sock *svsk)
9433 goto failed;
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);
9440+ }
9441+ memcpy(&newsvsk->sk_local, sin, slen);
9442
9443 svc_sock_received(newsvsk);
9444
9445diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
9446index 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();
9452 } else
9453- schedule_work(&xprt->task_cleanup);
9454+ queue_work(rpciod_workqueue, &xprt->task_cleanup);
9455 }
9456
9457 /*
9458@@ -515,7 +515,7 @@ xprt_init_autodisconnect(unsigned long data)
9459 if (xprt_connecting(xprt))
9460 xprt_release_write(xprt, NULL);
9461 else
9462- schedule_work(&xprt->task_cleanup);
9463+ queue_work(rpciod_workqueue, &xprt->task_cleanup);
9464 return;
9465 out_abort:
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
9468
9469 /**
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
9476 *
9477 */
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)
9480 {
9481 struct rpc_xprt *xprt;
9482 struct rpc_rqst *req;
9483
9484- switch (proto) {
9485+ switch (args->proto) {
9486 case IPPROTO_UDP:
9487- xprt = xs_setup_udp(ap, size, to);
9488+ xprt = xs_setup_udp(args);
9489 break;
9490 case IPPROTO_TCP:
9491- xprt = xs_setup_tcp(ap, size, to);
9492+ xprt = xs_setup_tcp(args);
9493 break;
9494 default:
9495 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
9496- proto);
9497+ args->proto);
9498 return ERR_PTR(-EIO);
9499 }
9500 if (IS_ERR(xprt)) {
9501diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
9502index 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
9507 */
9508 struct delayed_work connect_worker;
9509+ struct sockaddr_storage addr;
9510 unsigned short port;
9511
9512 /*
9513@@ -653,8 +654,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
9514
9515 dprintk("RPC: xs_destroy xprt %p\n", xprt);
9516
9517- cancel_delayed_work(&transport->connect_worker);
9518- flush_scheduled_work();
9519+ cancel_rearming_delayed_work(&transport->connect_worker);
9520
9521 xprt_disconnect(xprt);
9522 xs_close(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);
9529 default:
9530 xprt_disconnect(xprt);
9531 }
9532@@ -1146,31 +1146,36 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
9533 sap->sin_port = htons(port);
9534 }
9535
9536-static int xs_bindresvport(struct sock_xprt *transport, struct socket *sock)
9537+static int xs_bind(struct sock_xprt *transport, struct socket *sock)
9538 {
9539 struct sockaddr_in myaddr = {
9540 .sin_family = AF_INET,
9541 };
9542+ struct sockaddr_in *sa;
9543 int err;
9544 unsigned short port = transport->port;
9545
9546+ if (!transport->xprt.resvport)
9547+ port = 0;
9548+ sa = (struct sockaddr_in *)&transport->addr;
9549+ myaddr.sin_addr = sa->sin_addr;
9550 do {
9551 myaddr.sin_port = htons(port);
9552 err = kernel_bind(sock, (struct sockaddr *) &myaddr,
9553 sizeof(myaddr));
9554+ if (!transport->xprt.resvport)
9555+ break;
9556 if (err == 0) {
9557 transport->port = port;
9558- dprintk("RPC: xs_bindresvport bound to port %u\n",
9559- port);
9560- return 0;
9561+ break;
9562 }
9563 if (port <= xprt_min_resvport)
9564 port = xprt_max_resvport;
9565 else
9566 port--;
9567 } while (err == -EADDRINUSE && port != transport->port);
9568-
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);
9572 return err;
9573 }
9574
9575@@ -1229,7 +1234,7 @@ static void xs_udp_connect_worker(struct work_struct *work)
9576 }
9577 xs_reclassify_socket(sock);
9578
9579- if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
9580+ if (xs_bind(transport, sock)) {
9581 sock_release(sock);
9582 goto out;
9583 }
9584@@ -1316,7 +1321,7 @@ static void xs_tcp_connect_worker(struct work_struct *work)
9585 }
9586 xs_reclassify_socket(sock);
9587
9588- if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
9589+ if (xs_bind(transport, sock)) {
9590 sock_release(sock);
9591 goto out;
9592 }
9593@@ -1410,18 +1415,16 @@ static void xs_connect(struct rpc_task *task)
9594 dprintk("RPC: xs_connect delayed xprt %p for %lu "
9595 "seconds\n",
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;
9605 } else {
9606 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
9607- schedule_delayed_work(&transport->connect_worker, 0);
9608-
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);
9614 }
9615 }
9616
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,
9637 };
9638
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)
9641 {
9642 struct rpc_xprt *xprt;
9643 struct sock_xprt *new;
9644
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);
9649 }
9650@@ -1532,8 +1535,10 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
9651 return ERR_PTR(-ENOMEM);
9652 }
9653
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();
9661
9662 return xprt;
9663@@ -1541,22 +1546,20 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
9664
9665 /**
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
9671 *
9672 */
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)
9675 {
9676 struct rpc_xprt *xprt;
9677 struct sock_xprt *transport;
9678
9679- xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
9680+ xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries);
9681 if (IS_ERR(xprt))
9682 return xprt;
9683 transport = container_of(xprt, struct sock_xprt, xprt);
9684
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);
9688
9689 xprt->prot = IPPROTO_UDP;
9690@@ -1572,8 +1575,8 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
9691
9692 xprt->ops = &xs_udp_ops;
9693
9694- if (to)
9695- xprt->timeout = *to;
9696+ if (args->timeout)
9697+ xprt->timeout = *args->timeout;
9698 else
9699 xprt_set_timeout(&xprt->timeout, 5, 5 * HZ);
9700
9701@@ -1586,22 +1589,20 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
9702
9703 /**
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
9709 *
9710 */
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)
9713 {
9714 struct rpc_xprt *xprt;
9715 struct sock_xprt *transport;
9716
9717- xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
9718+ xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
9719 if (IS_ERR(xprt))
9720 return xprt;
9721 transport = container_of(xprt, struct sock_xprt, xprt);
9722
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);
9726
9727 xprt->prot = IPPROTO_TCP;
9728@@ -1616,8 +1617,8 @@ struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_
9729
9730 xprt->ops = &xs_tcp_ops;
9731
9732- if (to)
9733- xprt->timeout = *to;
9734+ if (args->timeout)
9735+ xprt->timeout = *args->timeout;
9736 else
9737 xprt_set_timeout(&xprt->timeout, 2, 60 * HZ);
9738
This page took 1.075053 seconds and 4 git commands to generate.