]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.6.22-NFS_ALL.dif
- typo
[packages/kernel.git] / linux-2.6.22-NFS_ALL.dif
1 All 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
62 diff --git a/fs/lockd/host.c b/fs/lockd/host.c
63 index 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,
171 diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
172 index 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);
191 diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
192 index 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);
215 diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
216 index f4580b4..b55cb23 100644
217 --- a/fs/nfs/Makefile
218 +++ b/fs/nfs/Makefile
219 @@ -6,8 +6,8 @@ obj-$(CONFIG_NFS_FS) += nfs.o
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 \
230 diff --git a/fs/nfs/client.c b/fs/nfs/client.c
231 index 881fa49..ccb4550 100644
232 --- a/fs/nfs/client.c
233 +++ b/fs/nfs/client.c
234 @@ -102,19 +102,10 @@ static struct nfs_client *nfs_alloc_client(const char *hostname,
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  
301 diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
302 index 7f37d1b..20ac403 100644
303 --- a/fs/nfs/delegation.c
304 +++ b/fs/nfs/delegation.c
305 @@ -27,6 +27,13 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
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  }
660 diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
661 index 2cfd4b2..5874ce7 100644
662 --- a/fs/nfs/delegation.h
663 +++ b/fs/nfs/delegation.h
664 @@ -22,11 +22,12 @@ struct nfs_delegation {
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  {
716 diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
717 index 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         }
783 diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
784 index 00eee87..a5c82b6 100644
785 --- a/fs/nfs/direct.c
786 +++ b/fs/nfs/direct.c
787 @@ -266,7 +266,7 @@ static const struct rpc_call_ops nfs_read_direct_ops = {
788  static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos)
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)
871 diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
872 index 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);
1010 diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
1011 index ad2b40d..76cf55d 100644
1012 --- a/fs/nfs/internal.h
1013 +++ b/fs/nfs/internal.h
1014 @@ -183,9 +183,9 @@ unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
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  
1026 diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
1027 index ca5a266..8afd9f7 100644
1028 --- a/fs/nfs/mount_clnt.c
1029 +++ b/fs/nfs/mount_clnt.c
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),
1285 diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
1286 index cd3ca7b..7fcc78f 100644
1287 --- a/fs/nfs/nfs2xdr.c
1288 +++ b/fs/nfs/nfs2xdr.c
1289 @@ -223,7 +223,7 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
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);
1316 diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
1317 index 45268d6..814d886 100644
1318 --- a/fs/nfs/nfs3proc.c
1319 +++ b/fs/nfs/nfs3proc.c
1320 @@ -335,9 +335,7 @@ again:
1321                  * not sure this buys us anything (and I'd have
1322                  * to revamp the NFSv3 XDR code) */
1323                 status = nfs3_proc_setattr(dentry, &fattr, sattr);
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)
1331 diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
1332 index b51df8e..b4647a2 100644
1333 --- a/fs/nfs/nfs3xdr.c
1334 +++ b/fs/nfs/nfs3xdr.c
1335 @@ -319,7 +319,7 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *arg
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);
1371 diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
1372 index cf3a17e..6c028e7 100644
1373 --- a/fs/nfs/nfs4_fs.h
1374 +++ b/fs/nfs/nfs4_fs.h
1375 @@ -70,19 +70,26 @@ static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status
1376                 seqid->flags |= NFS_SEQID_CONFIRMED;
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 */
1480 diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
1481 index 648e0ac..fee2da8 100644
1482 --- a/fs/nfs/nfs4proc.c
1483 +++ b/fs/nfs/nfs4proc.c
1484 @@ -65,6 +65,7 @@ static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *)
1485  static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
1486  static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
1487  static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
1488 +static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags);
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:
2816 diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
2817 index 8ed79d5..28551ae 100644
2818 --- a/fs/nfs/nfs4state.c
2819 +++ b/fs/nfs/nfs4state.c
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) {
3333 diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
3334 index 8003c91..c087384 100644
3335 --- a/fs/nfs/nfs4xdr.c
3336 +++ b/fs/nfs/nfs4xdr.c
3337 @@ -68,9 +68,10 @@ static int nfs4_stat_to_errno(int);
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);
3627 diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
3628 index 49d1008..3490322 100644
3629 --- a/fs/nfs/nfsroot.c
3630 +++ b/fs/nfs/nfsroot.c
3631 @@ -428,7 +428,7 @@ static int __init root_nfs_getport(int program, int version, int proto)
3632         printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
3633                 program, version, NIPQUAD(servaddr));
3634         set_sockaddr(&sin, servaddr, 0);
3635 -       return rpcb_getport_external(&sin, program, version, proto);
3636 +       return rpcb_getport_sync(&sin, program, version, proto);
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);
3650 diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
3651 index c5bb51a..f56dae5 100644
3652 --- a/fs/nfs/pagelist.c
3653 +++ b/fs/nfs/pagelist.c
3654 @@ -85,9 +85,8 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
3655         req->wb_offset  = offset;
3656         req->wb_pgbase  = offset;
3657         req->wb_bytes   = count;
3658 -       atomic_set(&req->wb_count, 1);
3659         req->wb_context = get_nfs_open_context(ctx);
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;
3802 diff --git a/fs/nfs/read.c b/fs/nfs/read.c
3803 index 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,
3898 diff --git a/fs/nfs/super.c b/fs/nfs/super.c
3899 index ca20d3c..a2b1af8 100644
3900 --- a/fs/nfs/super.c
3901 +++ b/fs/nfs/super.c
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;
5303 diff --git a/fs/nfs/write.c b/fs/nfs/write.c
5304 index af344a1..73ac992 100644
5305 --- a/fs/nfs/write.c
5306 +++ b/fs/nfs/write.c
5307 @@ -117,19 +117,19 @@ static struct nfs_page *nfs_page_find_request_locked(struct page *page)
5308         if (PagePrivate(page)) {
5309                 req = (struct nfs_page *)page_private(page);
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);
5784 diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
5785 index 864090e..5443c52 100644
5786 --- a/fs/nfsd/nfs4callback.c
5787 +++ b/fs/nfsd/nfs4callback.c
5788 @@ -394,7 +394,6 @@ nfsd4_probe_callback(struct nfs4_client *clp)
5789                 .rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
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;
5841 diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
5842 index 3cc8ce4..8c52913 100644
5843 --- a/fs/nfsd/nfs4state.c
5844 +++ b/fs/nfsd/nfs4state.c
5845 @@ -378,7 +378,6 @@ shutdown_callback_client(struct nfs4_client *clp)
5846         if (clnt) {
5847                 clp->cl_callback.cb_client = NULL;
5848                 rpc_shutdown_client(clnt);
5849 -               rpciod_down();
5850         }
5851  }
5852  
5853 diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
5854 index 05707e2..e2d1ce3 100644
5855 --- a/include/linux/lockd/lockd.h
5856 +++ b/include/linux/lockd/lockd.h
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 */
5865 diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
5866 index 7e7f33a..8726491 100644
5867 --- a/include/linux/nfs4.h
5868 +++ b/include/linux/nfs4.h
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
5877 diff --git a/include/linux/nfs4_mount.h b/include/linux/nfs4_mount.h
5878 index 26b4c83..a0dcf66 100644
5879 --- a/include/linux/nfs4_mount.h
5880 +++ b/include/linux/nfs4_mount.h
5881 @@ -65,6 +65,7 @@ struct nfs4_mount_data {
5882  #define NFS4_MOUNT_NOCTO       0x0010  /* 1 */
5883  #define NFS4_MOUNT_NOAC                0x0020  /* 1 */
5884  #define NFS4_MOUNT_STRICTLOCK  0x1000  /* 1 */
5885 -#define NFS4_MOUNT_FLAGMASK    0xFFFF
5886 +#define NFS4_MOUNT_UNSHARED    0x8000  /* 1 */
5887 +#define NFS4_MOUNT_FLAGMASK    0x9033
5888  
5889  #endif
5890 diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
5891 index 0543439..c098ae1 100644
5892 --- a/include/linux/nfs_fs.h
5893 +++ b/include/linux/nfs_fs.h
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__
5974 diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
5975 index 52b4378..0cac49b 100644
5976 --- a/include/linux/nfs_fs_sb.h
5977 +++ b/include/linux/nfs_fs_sb.h
5978 @@ -16,7 +16,6 @@ struct nfs_client {
5979  #define NFS_CS_INITING         1               /* busy initialising */
5980         int                     cl_nfsversion;  /* NFS protocol version */
5981         unsigned long           cl_res_state;   /* NFS resources state */
5982 -#define NFS_CS_RPCIOD          0               /* - rpciod started */
5983  #define NFS_CS_CALLBACK                1               /* - callback started */
5984  #define NFS_CS_IDMAP           2               /* - idmap started */
5985  #define NFS_CS_RENEWD          3               /* - renewd started */
5986 @@ -35,7 +34,8 @@ struct nfs_client {
5987         nfs4_verifier           cl_confirm;
5988         unsigned long           cl_state;
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;
6007 diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
6008 index cc8b9c5..a3ade89 100644
6009 --- a/include/linux/nfs_mount.h
6010 +++ b/include/linux/nfs_mount.h
6011 @@ -37,7 +37,7 @@ struct nfs_mount_data {
6012         int             acdirmin;               /* 1 */
6013         int             acdirmax;               /* 1 */
6014         struct sockaddr_in addr;                /* 1 */
6015 -       char            hostname[256];          /* 1 */
6016 +       char            hostname[NFS_MAXNAMLEN + 1];            /* 1 */
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
6028 diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
6029 index bd193af..78e6079 100644
6030 --- a/include/linux/nfs_page.h
6031 +++ b/include/linux/nfs_page.h
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 *
6126 diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
6127 index 10c26ed..38d7768 100644
6128 --- a/include/linux/nfs_xdr.h
6129 +++ b/include/linux/nfs_xdr.h
6130 @@ -119,7 +119,7 @@ struct nfs_openargs {
6131         struct nfs_seqid *      seqid;
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 {
6156 diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
6157 index 534cdc7..7a69ca3 100644
6158 --- a/include/linux/sunrpc/auth.h
6159 +++ b/include/linux/sunrpc/auth.h
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)
6265 diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
6266 index 2db2fbf..67658e1 100644
6267 --- a/include/linux/sunrpc/auth_gss.h
6268 +++ b/include/linux/sunrpc/auth_gss.h
6269 @@ -75,6 +75,7 @@ struct gss_cl_ctx {
6270         struct xdr_netobj       gc_wire_ctx;
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  
6289 diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
6290 index 6661142..c0d9d14 100644
6291 --- a/include/linux/sunrpc/clnt.h
6292 +++ b/include/linux/sunrpc/clnt.h
6293 @@ -24,8 +24,10 @@ struct rpc_inode;
6294   * The high-level client handle
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 */
6376 diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
6377 index 5eca9e4..bbac101 100644
6378 --- a/include/linux/sunrpc/gss_api.h
6379 +++ b/include/linux/sunrpc/gss_api.h
6380 @@ -77,7 +77,7 @@ struct gss_api_mech {
6381         struct module           *gm_owner;
6382         struct xdr_netobj       gm_oid;
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;
6389 diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
6390 index ad29376..51b977a 100644
6391 --- a/include/linux/sunrpc/rpc_pipe_fs.h
6392 +++ b/include/linux/sunrpc/rpc_pipe_fs.h
6393 @@ -23,9 +23,11 @@ struct rpc_inode {
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;
6405 diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
6406 index 2047fb2..8ea077d 100644
6407 --- a/include/linux/sunrpc/sched.h
6408 +++ b/include/linux/sunrpc/sched.h
6409 @@ -98,7 +98,6 @@ struct rpc_task {
6410         unsigned short          tk_pid;         /* debugging aid */
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 {
6429 diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
6430 index e21dd93..a53e0fa 100644
6431 --- a/include/linux/sunrpc/svcsock.h
6432 +++ b/include/linux/sunrpc/svcsock.h
6433 @@ -59,6 +59,7 @@ struct svc_sock {
6434         /* cache of various info for TCP sockets */
6435         void                    *sk_info_authunix;
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  };
6441 diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
6442 index 34f7590..d11cedd 100644
6443 --- a/include/linux/sunrpc/xprt.h
6444 +++ b/include/linux/sunrpc/xprt.h
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  
6489 diff --git a/kernel/auditsc.c b/kernel/auditsc.c
6490 index e36481e..ced6541 100644
6491 --- a/kernel/auditsc.c
6492 +++ b/kernel/auditsc.c
6493 @@ -1500,6 +1500,7 @@ add_names:
6494                         context->names[idx].ino = (unsigned long)-1;
6495         }
6496  }
6497 +EXPORT_SYMBOL(__audit_inode_child);
6498  
6499  /**
6500   * auditsc_get_stamp - get local copies of audit_context values
6501 diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
6502 index 9527f2b..74baf87 100644
6503 --- a/net/sunrpc/auth.c
6504 +++ b/net/sunrpc/auth.c
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  }
7073 diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
7074 index 4e4ccc5..17d460f 100644
7075 --- a/net/sunrpc/auth_gss/auth_gss.c
7076 +++ b/net/sunrpc/auth_gss/auth_gss.c
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,
7776 diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
7777 index 7b19432..71b9dae 100644
7778 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c
7779 +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
7780 @@ -201,7 +201,7 @@ gss_delete_sec_context_kerberos(void *internal_ctx) {
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,
7789 diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
7790 index 7e15aa6..577d590 100644
7791 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
7792 +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
7793 @@ -202,7 +202,7 @@ gss_get_mic_spkm3(struct gss_ctx    *ctx,
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,
7802 diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
7803 index 3df9fcc..537d0e8 100644
7804 --- a/net/sunrpc/auth_null.c
7805 +++ b/net/sunrpc/auth_null.c
7806 @@ -76,7 +76,7 @@ nul_marshal(struct rpc_task *task, __be32 *p)
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
7846 diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
7847 index 4e7733a..5ed91e5 100644
7848 --- a/net/sunrpc/auth_unix.c
7849 +++ b/net/sunrpc/auth_unix.c
7850 @@ -20,11 +20,6 @@ struct unx_cred {
7851         gid_t                   uc_gids[NFS_NGROUPS];
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,
8004 diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
8005 index d8fbee4..5d3fe7b 100644
8006 --- a/net/sunrpc/clnt.c
8007 +++ b/net/sunrpc/clnt.c
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
8602 diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
8603 index 5887457..22e25b5 100644
8604 --- a/net/sunrpc/rpc_pipe.c
8605 +++ b/net/sunrpc/rpc_pipe.c
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);
8826 diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
8827 index 6c7aa8a..d1740db 100644
8828 --- a/net/sunrpc/rpcb_clnt.c
8829 +++ b/net/sunrpc/rpcb_clnt.c
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);
9006 diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
9007 index 944d753..2ac43c4 100644
9008 --- a/net/sunrpc/sched.c
9009 +++ b/net/sunrpc/sched.c
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  {
9355 diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
9356 index 73075de..384c4ad 100644
9357 --- a/net/sunrpc/sunrpc_syms.c
9358 +++ b/net/sunrpc/sunrpc_syms.c
9359 @@ -28,15 +28,11 @@ EXPORT_SYMBOL(rpc_init_task);
9360  EXPORT_SYMBOL(rpc_sleep_on);
9361  EXPORT_SYMBOL(rpc_wake_up_next);
9362  EXPORT_SYMBOL(rpc_wake_up_task);
9363 -EXPORT_SYMBOL(rpciod_down);
9364 -EXPORT_SYMBOL(rpciod_up);
9365 -EXPORT_SYMBOL(rpc_new_task);
9366  EXPORT_SYMBOL(rpc_wake_up_status);
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();
9400 diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
9401 index 5baf48d..64b9b8c 100644
9402 --- a/net/sunrpc/svcsock.c
9403 +++ b/net/sunrpc/svcsock.c
9404 @@ -644,6 +644,7 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
9405         struct msghdr msg = {
9406                 .msg_flags      = MSG_DONTWAIT,
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  
9445 diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
9446 index 5b05b73..c8c2edc 100644
9447 --- a/net/sunrpc/xprt.c
9448 +++ b/net/sunrpc/xprt.c
9449 @@ -127,7 +127,7 @@ static void xprt_clear_locked(struct rpc_xprt *xprt)
9450                 clear_bit(XPRT_LOCKED, &xprt->state);
9451                 smp_mb__after_clear_bit();
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)) {
9501 diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
9502 index cc33c58..4ae7eed 100644
9503 --- a/net/sunrpc/xprtsock.c
9504 +++ b/net/sunrpc/xprtsock.c
9505 @@ -235,6 +235,7 @@ struct sock_xprt {
9506          * Connection of transports
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 0.939778 seconds and 3 git commands to generate.