aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-24 14:01:02 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-24 14:01:02 -0400
commit233607dbbc823caf685e778cabc49fb7f679900b (patch)
tree13840137ee10788061cbec60fcfe8ea4c274558e
parent3dc5063786b273f1aee545844f6bd4e9651ebffe (diff)
parentb48633bd086d21f4a2a5bea96c7e6c7ba58eb60c (diff)
Merge branch 'devel'
-rw-r--r--fs/Kconfig70
-rw-r--r--fs/lockd/clntproc.c184
-rw-r--r--fs/lockd/host.c20
-rw-r--r--fs/lockd/mon.c113
-rw-r--r--fs/lockd/svc.c12
-rw-r--r--fs/nfs/Makefile3
-rw-r--r--fs/nfs/client.c23
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/direct.c88
-rw-r--r--fs/nfs/file.c18
-rw-r--r--fs/nfs/inode.c45
-rw-r--r--fs/nfs/internal.h13
-rw-r--r--fs/nfs/namespace.c2
-rw-r--r--fs/nfs/nfs2xdr.c113
-rw-r--r--fs/nfs/nfs3xdr.c71
-rw-r--r--fs/nfs/nfs4proc.c39
-rw-r--r--fs/nfs/nfs4state.c49
-rw-r--r--fs/nfs/nfs4xdr.c147
-rw-r--r--fs/nfs/read.c94
-rw-r--r--fs/nfs/super.c147
-rw-r--r--fs/nfs/unlink.c2
-rw-r--r--fs/nfs/write.c207
-rw-r--r--include/linux/lockd/lockd.h18
-rw-r--r--include/linux/lockd/sm_inter.h1
-rw-r--r--include/linux/nfs_fs.h5
-rw-r--r--include/linux/nfs_fs_sb.h10
-rw-r--r--include/linux/nfs_xdr.h10
-rw-r--r--include/linux/sunrpc/auth.h17
-rw-r--r--include/linux/sunrpc/auth_gss.h1
-rw-r--r--include/linux/sunrpc/clnt.h9
-rw-r--r--include/linux/sunrpc/sched.h41
-rw-r--r--include/linux/sunrpc/xprt.h10
-rw-r--r--net/sunrpc/Makefile2
-rw-r--r--net/sunrpc/auth.c71
-rw-r--r--net/sunrpc/auth_generic.c177
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c105
-rw-r--r--net/sunrpc/auth_null.c3
-rw-r--r--net/sunrpc/auth_unix.c59
-rw-r--r--net/sunrpc/clnt.c50
-rw-r--r--net/sunrpc/rpcb_clnt.c2
-rw-r--r--net/sunrpc/sched.c264
-rw-r--r--net/sunrpc/xprt.c80
-rw-r--r--net/sunrpc/xprtsock.c82
43 files changed, 1583 insertions, 896 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 8b18a8758677..48ca1e1316d9 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1664,30 +1664,6 @@ config NFS_V4
1664 1664
1665 If unsure, say N. 1665 If unsure, say N.
1666 1666
1667config NFS_DIRECTIO
1668 bool "Allow direct I/O on NFS files"
1669 depends on NFS_FS
1670 help
1671 This option enables applications to perform uncached I/O on files
1672 in NFS file systems using the O_DIRECT open() flag. When O_DIRECT
1673 is set for a file, its data is not cached in the system's page
1674 cache. Data is moved to and from user-level application buffers
1675 directly. Unlike local disk-based file systems, NFS O_DIRECT has
1676 no alignment restrictions.
1677
1678 Unless your program is designed to use O_DIRECT properly, you are
1679 much better off allowing the NFS client to manage data caching for
1680 you. Misusing O_DIRECT can cause poor server performance or network
1681 storms. This kernel build option defaults OFF to avoid exposing
1682 system administrators unwittingly to a potentially hazardous
1683 feature.
1684
1685 For more details on NFS O_DIRECT, see fs/nfs/direct.c.
1686
1687 If unsure, say N. This reduces the size of the NFS client, and
1688 causes open() to return EINVAL if a file residing in NFS is
1689 opened with the O_DIRECT flag.
1690
1691config NFSD 1667config NFSD
1692 tristate "NFS server support" 1668 tristate "NFS server support"
1693 depends on INET 1669 depends on INET
@@ -1808,15 +1784,33 @@ config SUNRPC_XPRT_RDMA
1808 tristate 1784 tristate
1809 depends on SUNRPC && INFINIBAND && EXPERIMENTAL 1785 depends on SUNRPC && INFINIBAND && EXPERIMENTAL
1810 default SUNRPC && INFINIBAND 1786 default SUNRPC && INFINIBAND
1787 help
1788 This option enables an RPC client transport capability that
1789 allows the NFS client to mount servers via an RDMA-enabled
1790 transport.
1791
1792 To compile RPC client RDMA transport support as a module,
1793 choose M here: the module will be called xprtrdma.
1794
1795 If unsure, say N.
1811 1796
1812config SUNRPC_BIND34 1797config SUNRPC_BIND34
1813 bool "Support for rpcbind versions 3 & 4 (EXPERIMENTAL)" 1798 bool "Support for rpcbind versions 3 & 4 (EXPERIMENTAL)"
1814 depends on SUNRPC && EXPERIMENTAL 1799 depends on SUNRPC && EXPERIMENTAL
1800 default n
1815 help 1801 help
1816 Provides kernel support for querying rpcbind servers via versions 3 1802 RPC requests over IPv6 networks require support for larger
1817 and 4 of the rpcbind protocol. The kernel automatically falls back 1803 addresses when performing an RPC bind. Sun added support for
1818 to version 2 if a remote rpcbind service does not support versions 1804 IPv6 addressing by creating two new versions of the rpcbind
1819 3 or 4. 1805 protocol (RFC 1833).
1806
1807 This option enables support in the kernel RPC client for
1808 querying rpcbind servers via versions 3 and 4 of the rpcbind
1809 protocol. The kernel automatically falls back to version 2
1810 if a remote rpcbind service does not support versions 3 or 4.
1811 By themselves, these new versions do not provide support for
1812 RPC over IPv6, but the new protocol versions are necessary to
1813 support it.
1820 1814
1821 If unsure, say N to get traditional behavior (version 2 rpcbind 1815 If unsure, say N to get traditional behavior (version 2 rpcbind
1822 requests only). 1816 requests only).
@@ -1830,12 +1824,13 @@ config RPCSEC_GSS_KRB5
1830 select CRYPTO_DES 1824 select CRYPTO_DES
1831 select CRYPTO_CBC 1825 select CRYPTO_CBC
1832 help 1826 help
1833 Provides for secure RPC calls by means of a gss-api 1827 Choose Y here to enable Secure RPC using the Kerberos version 5
1834 mechanism based on Kerberos V5. This is required for 1828 GSS-API mechanism (RFC 1964).
1835 NFSv4.
1836 1829
1837 Note: Requires an auxiliary userspace daemon which may be found on 1830 Secure RPC calls with Kerberos require an auxiliary user-space
1838 http://www.citi.umich.edu/projects/nfsv4/ 1831 daemon which may be found in the Linux nfs-utils package
1832 available from http://linux-nfs.org/. In addition, user-space
1833 Kerberos support should be installed.
1839 1834
1840 If unsure, say N. 1835 If unsure, say N.
1841 1836
@@ -1849,11 +1844,12 @@ config RPCSEC_GSS_SPKM3
1849 select CRYPTO_CAST5 1844 select CRYPTO_CAST5
1850 select CRYPTO_CBC 1845 select CRYPTO_CBC
1851 help 1846 help
1852 Provides for secure RPC calls by means of a gss-api 1847 Choose Y here to enable Secure RPC using the SPKM3 public key
1853 mechanism based on the SPKM3 public-key mechanism. 1848 GSS-API mechansim (RFC 2025).
1854 1849
1855 Note: Requires an auxiliary userspace daemon which may be found on 1850 Secure RPC calls with SPKM3 require an auxiliary userspace
1856 http://www.citi.umich.edu/projects/nfsv4/ 1851 daemon which may be found in the Linux nfs-utils package
1852 available from http://linux-nfs.org/.
1857 1853
1858 If unsure, say N. 1854 If unsure, say N.
1859 1855
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index b6b74a60e1eb..40b16f23e49a 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -155,8 +155,6 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req)
155int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl) 155int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
156{ 156{
157 struct nlm_rqst *call; 157 struct nlm_rqst *call;
158 sigset_t oldset;
159 unsigned long flags;
160 int status; 158 int status;
161 159
162 nlm_get_host(host); 160 nlm_get_host(host);
@@ -168,22 +166,6 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
168 /* Set up the argument struct */ 166 /* Set up the argument struct */
169 nlmclnt_setlockargs(call, fl); 167 nlmclnt_setlockargs(call, fl);
170 168
171 /* Keep the old signal mask */
172 spin_lock_irqsave(&current->sighand->siglock, flags);
173 oldset = current->blocked;
174
175 /* If we're cleaning up locks because the process is exiting,
176 * perform the RPC call asynchronously. */
177 if ((IS_SETLK(cmd) || IS_SETLKW(cmd))
178 && fl->fl_type == F_UNLCK
179 && (current->flags & PF_EXITING)) {
180 sigfillset(&current->blocked); /* Mask all signals */
181 recalc_sigpending();
182
183 call->a_flags = RPC_TASK_ASYNC;
184 }
185 spin_unlock_irqrestore(&current->sighand->siglock, flags);
186
187 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) { 169 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) {
188 if (fl->fl_type != F_UNLCK) { 170 if (fl->fl_type != F_UNLCK) {
189 call->a_args.block = IS_SETLKW(cmd) ? 1 : 0; 171 call->a_args.block = IS_SETLKW(cmd) ? 1 : 0;
@@ -198,11 +180,6 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
198 fl->fl_ops->fl_release_private(fl); 180 fl->fl_ops->fl_release_private(fl);
199 fl->fl_ops = NULL; 181 fl->fl_ops = NULL;
200 182
201 spin_lock_irqsave(&current->sighand->siglock, flags);
202 current->blocked = oldset;
203 recalc_sigpending();
204 spin_unlock_irqrestore(&current->sighand->siglock, flags);
205
206 dprintk("lockd: clnt proc returns %d\n", status); 183 dprintk("lockd: clnt proc returns %d\n", status);
207 return status; 184 return status;
208} 185}
@@ -221,6 +198,7 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host)
221 for(;;) { 198 for(;;) {
222 call = kzalloc(sizeof(*call), GFP_KERNEL); 199 call = kzalloc(sizeof(*call), GFP_KERNEL);
223 if (call != NULL) { 200 if (call != NULL) {
201 atomic_set(&call->a_count, 1);
224 locks_init_lock(&call->a_args.lock.fl); 202 locks_init_lock(&call->a_args.lock.fl);
225 locks_init_lock(&call->a_res.lock.fl); 203 locks_init_lock(&call->a_res.lock.fl);
226 call->a_host = host; 204 call->a_host = host;
@@ -237,6 +215,8 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host)
237 215
238void nlm_release_call(struct nlm_rqst *call) 216void nlm_release_call(struct nlm_rqst *call)
239{ 217{
218 if (!atomic_dec_and_test(&call->a_count))
219 return;
240 nlm_release_host(call->a_host); 220 nlm_release_host(call->a_host);
241 nlmclnt_release_lockargs(call); 221 nlmclnt_release_lockargs(call);
242 kfree(call); 222 kfree(call);
@@ -267,7 +247,7 @@ static int nlm_wait_on_grace(wait_queue_head_t *queue)
267 * Generic NLM call 247 * Generic NLM call
268 */ 248 */
269static int 249static int
270nlmclnt_call(struct nlm_rqst *req, u32 proc) 250nlmclnt_call(struct rpc_cred *cred, struct nlm_rqst *req, u32 proc)
271{ 251{
272 struct nlm_host *host = req->a_host; 252 struct nlm_host *host = req->a_host;
273 struct rpc_clnt *clnt; 253 struct rpc_clnt *clnt;
@@ -276,6 +256,7 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
276 struct rpc_message msg = { 256 struct rpc_message msg = {
277 .rpc_argp = argp, 257 .rpc_argp = argp,
278 .rpc_resp = resp, 258 .rpc_resp = resp,
259 .rpc_cred = cred,
279 }; 260 };
280 int status; 261 int status;
281 262
@@ -343,10 +324,16 @@ in_grace_period:
343/* 324/*
344 * Generic NLM call, async version. 325 * Generic NLM call, async version.
345 */ 326 */
346static int __nlm_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *msg, const struct rpc_call_ops *tk_ops) 327static struct rpc_task *__nlm_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *msg, const struct rpc_call_ops *tk_ops)
347{ 328{
348 struct nlm_host *host = req->a_host; 329 struct nlm_host *host = req->a_host;
349 struct rpc_clnt *clnt; 330 struct rpc_clnt *clnt;
331 struct rpc_task_setup task_setup_data = {
332 .rpc_message = msg,
333 .callback_ops = tk_ops,
334 .callback_data = req,
335 .flags = RPC_TASK_ASYNC,
336 };
350 337
351 dprintk("lockd: call procedure %d on %s (async)\n", 338 dprintk("lockd: call procedure %d on %s (async)\n",
352 (int)proc, host->h_name); 339 (int)proc, host->h_name);
@@ -356,21 +343,36 @@ static int __nlm_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *
356 if (clnt == NULL) 343 if (clnt == NULL)
357 goto out_err; 344 goto out_err;
358 msg->rpc_proc = &clnt->cl_procinfo[proc]; 345 msg->rpc_proc = &clnt->cl_procinfo[proc];
346 task_setup_data.rpc_client = clnt;
359 347
360 /* bootstrap and kick off the async RPC call */ 348 /* bootstrap and kick off the async RPC call */
361 return rpc_call_async(clnt, msg, RPC_TASK_ASYNC, tk_ops, req); 349 return rpc_run_task(&task_setup_data);
362out_err: 350out_err:
363 tk_ops->rpc_release(req); 351 tk_ops->rpc_release(req);
364 return -ENOLCK; 352 return ERR_PTR(-ENOLCK);
365} 353}
366 354
355static int nlm_do_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *msg, const struct rpc_call_ops *tk_ops)
356{
357 struct rpc_task *task;
358
359 task = __nlm_async_call(req, proc, msg, tk_ops);
360 if (IS_ERR(task))
361 return PTR_ERR(task);
362 rpc_put_task(task);
363 return 0;
364}
365
366/*
367 * NLM asynchronous call.
368 */
367int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops) 369int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
368{ 370{
369 struct rpc_message msg = { 371 struct rpc_message msg = {
370 .rpc_argp = &req->a_args, 372 .rpc_argp = &req->a_args,
371 .rpc_resp = &req->a_res, 373 .rpc_resp = &req->a_res,
372 }; 374 };
373 return __nlm_async_call(req, proc, &msg, tk_ops); 375 return nlm_do_async_call(req, proc, &msg, tk_ops);
374} 376}
375 377
376int nlm_async_reply(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops) 378int nlm_async_reply(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
@@ -378,7 +380,33 @@ int nlm_async_reply(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *t
378 struct rpc_message msg = { 380 struct rpc_message msg = {
379 .rpc_argp = &req->a_res, 381 .rpc_argp = &req->a_res,
380 }; 382 };
381 return __nlm_async_call(req, proc, &msg, tk_ops); 383 return nlm_do_async_call(req, proc, &msg, tk_ops);
384}
385
386/*
387 * NLM client asynchronous call.
388 *
389 * Note that although the calls are asynchronous, and are therefore
390 * guaranteed to complete, we still always attempt to wait for
391 * completion in order to be able to correctly track the lock
392 * state.
393 */
394static int nlmclnt_async_call(struct rpc_cred *cred, struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
395{
396 struct rpc_message msg = {
397 .rpc_argp = &req->a_args,
398 .rpc_resp = &req->a_res,
399 .rpc_cred = cred,
400 };
401 struct rpc_task *task;
402 int err;
403
404 task = __nlm_async_call(req, proc, &msg, tk_ops);
405 if (IS_ERR(task))
406 return PTR_ERR(task);
407 err = rpc_wait_for_completion_task(task);
408 rpc_put_task(task);
409 return err;
382} 410}
383 411
384/* 412/*
@@ -389,7 +417,7 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl)
389{ 417{
390 int status; 418 int status;
391 419
392 status = nlmclnt_call(req, NLMPROC_TEST); 420 status = nlmclnt_call(nfs_file_cred(fl->fl_file), req, NLMPROC_TEST);
393 if (status < 0) 421 if (status < 0)
394 goto out; 422 goto out;
395 423
@@ -480,10 +508,12 @@ static int do_vfs_lock(struct file_lock *fl)
480static int 508static int
481nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) 509nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
482{ 510{
511 struct rpc_cred *cred = nfs_file_cred(fl->fl_file);
483 struct nlm_host *host = req->a_host; 512 struct nlm_host *host = req->a_host;
484 struct nlm_res *resp = &req->a_res; 513 struct nlm_res *resp = &req->a_res;
485 struct nlm_wait *block = NULL; 514 struct nlm_wait *block = NULL;
486 unsigned char fl_flags = fl->fl_flags; 515 unsigned char fl_flags = fl->fl_flags;
516 unsigned char fl_type;
487 int status = -ENOLCK; 517 int status = -ENOLCK;
488 518
489 if (nsm_monitor(host) < 0) { 519 if (nsm_monitor(host) < 0) {
@@ -493,18 +523,22 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
493 } 523 }
494 fl->fl_flags |= FL_ACCESS; 524 fl->fl_flags |= FL_ACCESS;
495 status = do_vfs_lock(fl); 525 status = do_vfs_lock(fl);
526 fl->fl_flags = fl_flags;
496 if (status < 0) 527 if (status < 0)
497 goto out; 528 goto out;
498 529
499 block = nlmclnt_prepare_block(host, fl); 530 block = nlmclnt_prepare_block(host, fl);
500again: 531again:
532 /*
533 * Initialise resp->status to a valid non-zero value,
534 * since 0 == nlm_lck_granted
535 */
536 resp->status = nlm_lck_blocked;
501 for(;;) { 537 for(;;) {
502 /* Reboot protection */ 538 /* Reboot protection */
503 fl->fl_u.nfs_fl.state = host->h_state; 539 fl->fl_u.nfs_fl.state = host->h_state;
504 status = nlmclnt_call(req, NLMPROC_LOCK); 540 status = nlmclnt_call(cred, req, NLMPROC_LOCK);
505 if (status < 0) 541 if (status < 0)
506 goto out_unblock;
507 if (!req->a_args.block)
508 break; 542 break;
509 /* Did a reclaimer thread notify us of a server reboot? */ 543 /* Did a reclaimer thread notify us of a server reboot? */
510 if (resp->status == nlm_lck_denied_grace_period) 544 if (resp->status == nlm_lck_denied_grace_period)
@@ -513,15 +547,22 @@ again:
513 break; 547 break;
514 /* Wait on an NLM blocking lock */ 548 /* Wait on an NLM blocking lock */
515 status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); 549 status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
516 /* if we were interrupted. Send a CANCEL request to the server
517 * and exit
518 */
519 if (status < 0) 550 if (status < 0)
520 goto out_unblock; 551 break;
521 if (resp->status != nlm_lck_blocked) 552 if (resp->status != nlm_lck_blocked)
522 break; 553 break;
523 } 554 }
524 555
556 /* if we were interrupted while blocking, then cancel the lock request
557 * and exit
558 */
559 if (resp->status == nlm_lck_blocked) {
560 if (!req->a_args.block)
561 goto out_unlock;
562 if (nlmclnt_cancel(host, req->a_args.block, fl) == 0)
563 goto out_unblock;
564 }
565
525 if (resp->status == nlm_granted) { 566 if (resp->status == nlm_granted) {
526 down_read(&host->h_rwsem); 567 down_read(&host->h_rwsem);
527 /* Check whether or not the server has rebooted */ 568 /* Check whether or not the server has rebooted */
@@ -530,20 +571,34 @@ again:
530 goto again; 571 goto again;
531 } 572 }
532 /* Ensure the resulting lock will get added to granted list */ 573 /* Ensure the resulting lock will get added to granted list */
533 fl->fl_flags = fl_flags | FL_SLEEP; 574 fl->fl_flags |= FL_SLEEP;
534 if (do_vfs_lock(fl) < 0) 575 if (do_vfs_lock(fl) < 0)
535 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__); 576 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
536 up_read(&host->h_rwsem); 577 up_read(&host->h_rwsem);
578 fl->fl_flags = fl_flags;
579 status = 0;
537 } 580 }
581 if (status < 0)
582 goto out_unlock;
538 status = nlm_stat_to_errno(resp->status); 583 status = nlm_stat_to_errno(resp->status);
539out_unblock: 584out_unblock:
540 nlmclnt_finish_block(block); 585 nlmclnt_finish_block(block);
541 /* Cancel the blocked request if it is still pending */
542 if (resp->status == nlm_lck_blocked)
543 nlmclnt_cancel(host, req->a_args.block, fl);
544out: 586out:
545 nlm_release_call(req); 587 nlm_release_call(req);
588 return status;
589out_unlock:
590 /* Fatal error: ensure that we remove the lock altogether */
591 dprintk("lockd: lock attempt ended in fatal error.\n"
592 " Attempting to unlock.\n");
593 nlmclnt_finish_block(block);
594 fl_type = fl->fl_type;
595 fl->fl_type = F_UNLCK;
596 down_read(&host->h_rwsem);
597 do_vfs_lock(fl);
598 up_read(&host->h_rwsem);
599 fl->fl_type = fl_type;
546 fl->fl_flags = fl_flags; 600 fl->fl_flags = fl_flags;
601 nlmclnt_async_call(cred, req, NLMPROC_UNLOCK, &nlmclnt_unlock_ops);
547 return status; 602 return status;
548} 603}
549 604
@@ -567,8 +622,8 @@ nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl)
567 nlmclnt_setlockargs(req, fl); 622 nlmclnt_setlockargs(req, fl);
568 req->a_args.reclaim = 1; 623 req->a_args.reclaim = 1;
569 624
570 if ((status = nlmclnt_call(req, NLMPROC_LOCK)) >= 0 625 status = nlmclnt_call(nfs_file_cred(fl->fl_file), req, NLMPROC_LOCK);
571 && req->a_res.status == nlm_granted) 626 if (status >= 0 && req->a_res.status == nlm_granted)
572 return 0; 627 return 0;
573 628
574 printk(KERN_WARNING "lockd: failed to reclaim lock for pid %d " 629 printk(KERN_WARNING "lockd: failed to reclaim lock for pid %d "
@@ -598,7 +653,8 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
598{ 653{
599 struct nlm_host *host = req->a_host; 654 struct nlm_host *host = req->a_host;
600 struct nlm_res *resp = &req->a_res; 655 struct nlm_res *resp = &req->a_res;
601 int status = 0; 656 int status;
657 unsigned char fl_flags = fl->fl_flags;
602 658
603 /* 659 /*
604 * Note: the server is supposed to either grant us the unlock 660 * Note: the server is supposed to either grant us the unlock
@@ -607,16 +663,17 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
607 */ 663 */
608 fl->fl_flags |= FL_EXISTS; 664 fl->fl_flags |= FL_EXISTS;
609 down_read(&host->h_rwsem); 665 down_read(&host->h_rwsem);
610 if (do_vfs_lock(fl) == -ENOENT) { 666 status = do_vfs_lock(fl);
611 up_read(&host->h_rwsem); 667 up_read(&host->h_rwsem);
668 fl->fl_flags = fl_flags;
669 if (status == -ENOENT) {
670 status = 0;
612 goto out; 671 goto out;
613 } 672 }
614 up_read(&host->h_rwsem);
615
616 if (req->a_flags & RPC_TASK_ASYNC)
617 return nlm_async_call(req, NLMPROC_UNLOCK, &nlmclnt_unlock_ops);
618 673
619 status = nlmclnt_call(req, NLMPROC_UNLOCK); 674 atomic_inc(&req->a_count);
675 status = nlmclnt_async_call(nfs_file_cred(fl->fl_file), req,
676 NLMPROC_UNLOCK, &nlmclnt_unlock_ops);
620 if (status < 0) 677 if (status < 0)
621 goto out; 678 goto out;
622 679
@@ -671,16 +728,10 @@ static const struct rpc_call_ops nlmclnt_unlock_ops = {
671static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl) 728static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl)
672{ 729{
673 struct nlm_rqst *req; 730 struct nlm_rqst *req;
674 unsigned long flags; 731 int status;
675 sigset_t oldset;
676 int status;
677 732
678 /* Block all signals while setting up call */ 733 dprintk("lockd: blocking lock attempt was interrupted by a signal.\n"
679 spin_lock_irqsave(&current->sighand->siglock, flags); 734 " Attempting to cancel lock.\n");
680 oldset = current->blocked;
681 sigfillset(&current->blocked);
682 recalc_sigpending();
683 spin_unlock_irqrestore(&current->sighand->siglock, flags);
684 735
685 req = nlm_alloc_call(nlm_get_host(host)); 736 req = nlm_alloc_call(nlm_get_host(host));
686 if (!req) 737 if (!req)
@@ -690,13 +741,12 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl
690 nlmclnt_setlockargs(req, fl); 741 nlmclnt_setlockargs(req, fl);
691 req->a_args.block = block; 742 req->a_args.block = block;
692 743
693 status = nlm_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops); 744 atomic_inc(&req->a_count);
694 745 status = nlmclnt_async_call(nfs_file_cred(fl->fl_file), req,
695 spin_lock_irqsave(&current->sighand->siglock, flags); 746 NLMPROC_CANCEL, &nlmclnt_cancel_ops);
696 current->blocked = oldset; 747 if (status == 0 && req->a_res.status == nlm_lck_denied)
697 recalc_sigpending(); 748 status = -ENOLCK;
698 spin_unlock_irqrestore(&current->sighand->siglock, flags); 749 nlm_release_call(req);
699
700 return status; 750 return status;
701} 751}
702 752
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index f1ef49fff118..f23750db1650 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -42,11 +42,12 @@ static struct nsm_handle * nsm_find(const struct sockaddr_in *sin,
42/* 42/*
43 * Common host lookup routine for server & client 43 * Common host lookup routine for server & client
44 */ 44 */
45static struct nlm_host * 45static struct nlm_host *nlm_lookup_host(int server,
46nlm_lookup_host(int server, const struct sockaddr_in *sin, 46 const struct sockaddr_in *sin,
47 int proto, int version, const char *hostname, 47 int proto, u32 version,
48 unsigned int hostname_len, 48 const char *hostname,
49 const struct sockaddr_in *ssin) 49 unsigned int hostname_len,
50 const struct sockaddr_in *ssin)
50{ 51{
51 struct hlist_head *chain; 52 struct hlist_head *chain;
52 struct hlist_node *pos; 53 struct hlist_node *pos;
@@ -55,7 +56,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin,
55 int hash; 56 int hash;
56 57
57 dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT 58 dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT
58 ", p=%d, v=%d, my role=%s, name=%.*s)\n", 59 ", p=%d, v=%u, my role=%s, name=%.*s)\n",
59 NIPQUAD(ssin->sin_addr.s_addr), 60 NIPQUAD(ssin->sin_addr.s_addr),
60 NIPQUAD(sin->sin_addr.s_addr), proto, version, 61 NIPQUAD(sin->sin_addr.s_addr), proto, version,
61 server? "server" : "client", 62 server? "server" : "client",
@@ -175,9 +176,10 @@ nlm_destroy_host(struct nlm_host *host)
175/* 176/*
176 * Find an NLM server handle in the cache. If there is none, create it. 177 * Find an NLM server handle in the cache. If there is none, create it.
177 */ 178 */
178struct nlm_host * 179struct nlm_host *nlmclnt_lookup_host(const struct sockaddr_in *sin,
179nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, 180 int proto, u32 version,
180 const char *hostname, unsigned int hostname_len) 181 const char *hostname,
182 unsigned int hostname_len)
181{ 183{
182 struct sockaddr_in ssin = {0}; 184 struct sockaddr_in ssin = {0};
183 185
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 908b23fadd05..e4d563543b11 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -18,6 +18,8 @@
18 18
19#define NLMDBG_FACILITY NLMDBG_MONITOR 19#define NLMDBG_FACILITY NLMDBG_MONITOR
20 20
21#define XDR_ADDRBUF_LEN (20)
22
21static struct rpc_clnt * nsm_create(void); 23static struct rpc_clnt * nsm_create(void);
22 24
23static struct rpc_program nsm_program; 25static struct rpc_program nsm_program;
@@ -147,28 +149,55 @@ nsm_create(void)
147 149
148/* 150/*
149 * XDR functions for NSM. 151 * XDR functions for NSM.
152 *
153 * See http://www.opengroup.org/ for details on the Network
154 * Status Monitor wire protocol.
150 */ 155 */
151 156
152static __be32 * 157static __be32 *xdr_encode_nsm_string(__be32 *p, char *string)
153xdr_encode_common(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
154{ 158{
155 char buffer[20], *name; 159 size_t len = strlen(string);
156 160
157 /* 161 if (len > SM_MAXSTRLEN)
158 * Use the dotted-quad IP address of the remote host as 162 len = SM_MAXSTRLEN;
159 * identifier. Linux statd always looks up the canonical 163 return xdr_encode_opaque(p, string, len);
160 * hostname first for whatever remote hostname it receives, 164}
161 * so this works alright. 165
162 */ 166/*
163 if (nsm_use_hostnames) { 167 * "mon_name" specifies the host to be monitored.
164 name = argp->mon_name; 168 *
165 } else { 169 * Linux uses a text version of the IP address of the remote
166 sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr)); 170 * host as the host identifier (the "mon_name" argument).
171 *
172 * Linux statd always looks up the canonical hostname first for
173 * whatever remote hostname it receives, so this works alright.
174 */
175static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
176{
177 char buffer[XDR_ADDRBUF_LEN + 1];
178 char *name = argp->mon_name;
179
180 if (!nsm_use_hostnames) {
181 snprintf(buffer, XDR_ADDRBUF_LEN,
182 NIPQUAD_FMT, NIPQUAD(argp->addr));
167 name = buffer; 183 name = buffer;
168 } 184 }
169 if (!(p = xdr_encode_string(p, name)) 185
170 || !(p = xdr_encode_string(p, utsname()->nodename))) 186 return xdr_encode_nsm_string(p, name);
187}
188
189/*
190 * The "my_id" argument specifies the hostname and RPC procedure
191 * to be called when the status manager receives notification
192 * (via the SM_NOTIFY call) that the state of host "mon_name"
193 * has changed.
194 */
195static __be32 *xdr_encode_my_id(__be32 *p, struct nsm_args *argp)
196{
197 p = xdr_encode_nsm_string(p, utsname()->nodename);
198 if (!p)
171 return ERR_PTR(-EIO); 199 return ERR_PTR(-EIO);
200
172 *p++ = htonl(argp->prog); 201 *p++ = htonl(argp->prog);
173 *p++ = htonl(argp->vers); 202 *p++ = htonl(argp->vers);
174 *p++ = htonl(argp->proc); 203 *p++ = htonl(argp->proc);
@@ -176,18 +205,48 @@ xdr_encode_common(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
176 return p; 205 return p;
177} 206}
178 207
179static int 208/*
180xdr_encode_mon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) 209 * The "mon_id" argument specifies the non-private arguments
210 * of an SM_MON or SM_UNMON call.
211 */
212static __be32 *xdr_encode_mon_id(__be32 *p, struct nsm_args *argp)
181{ 213{
182 p = xdr_encode_common(rqstp, p, argp); 214 p = xdr_encode_mon_name(p, argp);
183 if (IS_ERR(p)) 215 if (!p)
184 return PTR_ERR(p); 216 return ERR_PTR(-EIO);
185 217
186 /* Surprise - there may even be room for an IPv6 address now */ 218 return xdr_encode_my_id(p, argp);
219}
220
221/*
222 * The "priv" argument may contain private information required
223 * by the SM_MON call. This information will be supplied in the
224 * SM_NOTIFY call.
225 *
226 * Linux provides the raw IP address of the monitored host,
227 * left in network byte order.
228 */
229static __be32 *xdr_encode_priv(__be32 *p, struct nsm_args *argp)
230{
187 *p++ = argp->addr; 231 *p++ = argp->addr;
188 *p++ = 0; 232 *p++ = 0;
189 *p++ = 0; 233 *p++ = 0;
190 *p++ = 0; 234 *p++ = 0;
235
236 return p;
237}
238
239static int
240xdr_encode_mon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
241{
242 p = xdr_encode_mon_id(p, argp);
243 if (IS_ERR(p))
244 return PTR_ERR(p);
245
246 p = xdr_encode_priv(p, argp);
247 if (IS_ERR(p))
248 return PTR_ERR(p);
249
191 rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); 250 rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p);
192 return 0; 251 return 0;
193} 252}
@@ -195,7 +254,7 @@ xdr_encode_mon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
195static int 254static int
196xdr_encode_unmon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp) 255xdr_encode_unmon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
197{ 256{
198 p = xdr_encode_common(rqstp, p, argp); 257 p = xdr_encode_mon_id(p, argp);
199 if (IS_ERR(p)) 258 if (IS_ERR(p))
200 return PTR_ERR(p); 259 return PTR_ERR(p);
201 rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p); 260 rqstp->rq_slen = xdr_adjust_iovec(rqstp->rq_svec, p);
@@ -220,9 +279,11 @@ xdr_decode_stat(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp)
220} 279}
221 280
222#define SM_my_name_sz (1+XDR_QUADLEN(SM_MAXSTRLEN)) 281#define SM_my_name_sz (1+XDR_QUADLEN(SM_MAXSTRLEN))
223#define SM_my_id_sz (3+1+SM_my_name_sz) 282#define SM_my_id_sz (SM_my_name_sz+3)
224#define SM_mon_id_sz (1+XDR_QUADLEN(20)+SM_my_id_sz) 283#define SM_mon_name_sz (1+XDR_QUADLEN(SM_MAXSTRLEN))
225#define SM_mon_sz (SM_mon_id_sz+4) 284#define SM_mon_id_sz (SM_mon_name_sz+SM_my_id_sz)
285#define SM_priv_sz (XDR_QUADLEN(SM_PRIV_SIZE))
286#define SM_mon_sz (SM_mon_id_sz+SM_priv_sz)
226#define SM_monres_sz 2 287#define SM_monres_sz 2
227#define SM_unmonres_sz 1 288#define SM_unmonres_sz 1
228 289
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 1ed8bd4de941..38c2f0b1dd7d 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -74,7 +74,9 @@ static const unsigned long nlm_timeout_min = 3;
74static const unsigned long nlm_timeout_max = 20; 74static const unsigned long nlm_timeout_max = 20;
75static const int nlm_port_min = 0, nlm_port_max = 65535; 75static const int nlm_port_min = 0, nlm_port_max = 65535;
76 76
77#ifdef CONFIG_SYSCTL
77static struct ctl_table_header * nlm_sysctl_table; 78static struct ctl_table_header * nlm_sysctl_table;
79#endif
78 80
79static unsigned long get_lockd_grace_period(void) 81static unsigned long get_lockd_grace_period(void)
80{ 82{
@@ -359,6 +361,8 @@ out:
359} 361}
360EXPORT_SYMBOL(lockd_down); 362EXPORT_SYMBOL(lockd_down);
361 363
364#ifdef CONFIG_SYSCTL
365
362/* 366/*
363 * Sysctl parameters (same as module parameters, different interface). 367 * Sysctl parameters (same as module parameters, different interface).
364 */ 368 */
@@ -443,6 +447,8 @@ static ctl_table nlm_sysctl_root[] = {
443 { .ctl_name = 0 } 447 { .ctl_name = 0 }
444}; 448};
445 449
450#endif /* CONFIG_SYSCTL */
451
446/* 452/*
447 * Module (and sysfs) parameters. 453 * Module (and sysfs) parameters.
448 */ 454 */
@@ -516,15 +522,21 @@ module_param(nsm_use_hostnames, bool, 0644);
516 522
517static int __init init_nlm(void) 523static int __init init_nlm(void)
518{ 524{
525#ifdef CONFIG_SYSCTL
519 nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root); 526 nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
520 return nlm_sysctl_table ? 0 : -ENOMEM; 527 return nlm_sysctl_table ? 0 : -ENOMEM;
528#else
529 return 0;
530#endif
521} 531}
522 532
523static void __exit exit_nlm(void) 533static void __exit exit_nlm(void)
524{ 534{
525 /* FIXME: delete all NLM clients */ 535 /* FIXME: delete all NLM clients */
526 nlm_shutdown_hosts(); 536 nlm_shutdown_hosts();
537#ifdef CONFIG_SYSCTL
527 unregister_sysctl_table(nlm_sysctl_table); 538 unregister_sysctl_table(nlm_sysctl_table);
539#endif
528} 540}
529 541
530module_init(init_nlm); 542module_init(init_nlm);
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index df0f41e09885..ac6170c594a3 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -5,7 +5,7 @@
5obj-$(CONFIG_NFS_FS) += nfs.o 5obj-$(CONFIG_NFS_FS) += nfs.o
6 6
7nfs-y := client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \ 7nfs-y := client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \
8 pagelist.o proc.o read.o symlink.o unlink.o \ 8 direct.o pagelist.o proc.o read.o symlink.o unlink.o \
9 write.o namespace.o mount_clnt.o 9 write.o namespace.o mount_clnt.o
10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o 10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
11nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o 11nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
@@ -14,5 +14,4 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
14 delegation.o idmap.o \ 14 delegation.o idmap.o \
15 callback.o callback_xdr.o callback_proc.o \ 15 callback.o callback_xdr.o callback_proc.o \
16 nfs4namespace.o 16 nfs4namespace.o
17nfs-$(CONFIG_NFS_DIRECTIO) += direct.o
18nfs-$(CONFIG_SYSCTL) += sysctl.o 17nfs-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index c5c0175898f6..f2f3b284e6dd 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -112,6 +112,7 @@ struct nfs_client_initdata {
112static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) 112static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
113{ 113{
114 struct nfs_client *clp; 114 struct nfs_client *clp;
115 struct rpc_cred *cred;
115 116
116 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) 117 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
117 goto error_0; 118 goto error_0;
@@ -150,6 +151,9 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
150 clp->cl_boot_time = CURRENT_TIME; 151 clp->cl_boot_time = CURRENT_TIME;
151 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; 152 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
152#endif 153#endif
154 cred = rpc_lookup_machine_cred();
155 if (!IS_ERR(cred))
156 clp->cl_machine_cred = cred;
153 157
154 return clp; 158 return clp;
155 159
@@ -170,6 +174,8 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
170 BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners)); 174 BUG_ON(!RB_EMPTY_ROOT(&clp->cl_state_owners));
171 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state)) 175 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
172 nfs_idmap_delete(clp); 176 nfs_idmap_delete(clp);
177
178 rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
173#endif 179#endif
174} 180}
175 181
@@ -189,6 +195,9 @@ static void nfs_free_client(struct nfs_client *clp)
189 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) 195 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
190 nfs_callback_down(); 196 nfs_callback_down();
191 197
198 if (clp->cl_machine_cred != NULL)
199 put_rpccred(clp->cl_machine_cred);
200
192 kfree(clp->cl_hostname); 201 kfree(clp->cl_hostname);
193 kfree(clp); 202 kfree(clp);
194 203
@@ -680,10 +689,22 @@ static int nfs_init_server(struct nfs_server *server,
680 if (error < 0) 689 if (error < 0)
681 goto error; 690 goto error;
682 691
692 server->port = data->nfs_server.port;
693
683 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); 694 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
684 if (error < 0) 695 if (error < 0)
685 goto error; 696 goto error;
686 697
698 /* Preserve the values of mount_server-related mount options */
699 if (data->mount_server.addrlen) {
700 memcpy(&server->mountd_address, &data->mount_server.address,
701 data->mount_server.addrlen);
702 server->mountd_addrlen = data->mount_server.addrlen;
703 }
704 server->mountd_version = data->mount_server.version;
705 server->mountd_port = data->mount_server.port;
706 server->mountd_protocol = data->mount_server.protocol;
707
687 server->namelen = data->namlen; 708 server->namelen = data->namlen;
688 /* Create a client RPC handle for the NFSv3 ACL management interface */ 709 /* Create a client RPC handle for the NFSv3 ACL management interface */
689 nfs_init_server_aclclient(server); 710 nfs_init_server_aclclient(server);
@@ -1062,6 +1083,8 @@ static int nfs4_init_server(struct nfs_server *server,
1062 server->acdirmin = data->acdirmin * HZ; 1083 server->acdirmin = data->acdirmin * HZ;
1063 server->acdirmax = data->acdirmax * HZ; 1084 server->acdirmax = data->acdirmax * HZ;
1064 1085
1086 server->port = data->nfs_server.port;
1087
1065 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]); 1088 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
1066 1089
1067error: 1090error:
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index d9e30ac2798d..f288b3ecab4a 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1967,7 +1967,7 @@ force_lookup:
1967 if (!NFS_PROTO(inode)->access) 1967 if (!NFS_PROTO(inode)->access)
1968 goto out_notsup; 1968 goto out_notsup;
1969 1969
1970 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); 1970 cred = rpc_lookup_cred();
1971 if (!IS_ERR(cred)) { 1971 if (!IS_ERR(cred)) {
1972 res = nfs_do_access(inode, cred, mask); 1972 res = nfs_do_access(inode, cred, mask);
1973 put_rpccred(cred); 1973 put_rpccred(cred);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 16844f98f50e..4757a2b326a1 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -229,14 +229,20 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq)
229static void nfs_direct_read_result(struct rpc_task *task, void *calldata) 229static void nfs_direct_read_result(struct rpc_task *task, void *calldata)
230{ 230{
231 struct nfs_read_data *data = calldata; 231 struct nfs_read_data *data = calldata;
232 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
233 232
234 if (nfs_readpage_result(task, data) != 0) 233 nfs_readpage_result(task, data);
235 return; 234}
235
236static void nfs_direct_read_release(void *calldata)
237{
238
239 struct nfs_read_data *data = calldata;
240 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
241 int status = data->task.tk_status;
236 242
237 spin_lock(&dreq->lock); 243 spin_lock(&dreq->lock);
238 if (unlikely(task->tk_status < 0)) { 244 if (unlikely(status < 0)) {
239 dreq->error = task->tk_status; 245 dreq->error = status;
240 spin_unlock(&dreq->lock); 246 spin_unlock(&dreq->lock);
241 } else { 247 } else {
242 dreq->count += data->res.count; 248 dreq->count += data->res.count;
@@ -249,11 +255,12 @@ static void nfs_direct_read_result(struct rpc_task *task, void *calldata)
249 255
250 if (put_dreq(dreq)) 256 if (put_dreq(dreq))
251 nfs_direct_complete(dreq); 257 nfs_direct_complete(dreq);
258 nfs_readdata_release(calldata);
252} 259}
253 260
254static const struct rpc_call_ops nfs_read_direct_ops = { 261static const struct rpc_call_ops nfs_read_direct_ops = {
255 .rpc_call_done = nfs_direct_read_result, 262 .rpc_call_done = nfs_direct_read_result,
256 .rpc_release = nfs_readdata_release, 263 .rpc_release = nfs_direct_read_release,
257}; 264};
258 265
259/* 266/*
@@ -280,6 +287,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
280 .rpc_client = NFS_CLIENT(inode), 287 .rpc_client = NFS_CLIENT(inode),
281 .rpc_message = &msg, 288 .rpc_message = &msg,
282 .callback_ops = &nfs_read_direct_ops, 289 .callback_ops = &nfs_read_direct_ops,
290 .workqueue = nfsiod_workqueue,
283 .flags = RPC_TASK_ASYNC, 291 .flags = RPC_TASK_ASYNC,
284 }; 292 };
285 unsigned int pgbase; 293 unsigned int pgbase;
@@ -323,7 +331,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
323 data->inode = inode; 331 data->inode = inode;
324 data->cred = msg.rpc_cred; 332 data->cred = msg.rpc_cred;
325 data->args.fh = NFS_FH(inode); 333 data->args.fh = NFS_FH(inode);
326 data->args.context = ctx; 334 data->args.context = get_nfs_open_context(ctx);
327 data->args.offset = pos; 335 data->args.offset = pos;
328 data->args.pgbase = pgbase; 336 data->args.pgbase = pgbase;
329 data->args.pages = data->pagevec; 337 data->args.pages = data->pagevec;
@@ -339,8 +347,9 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
339 NFS_PROTO(inode)->read_setup(data, &msg); 347 NFS_PROTO(inode)->read_setup(data, &msg);
340 348
341 task = rpc_run_task(&task_setup_data); 349 task = rpc_run_task(&task_setup_data);
342 if (!IS_ERR(task)) 350 if (IS_ERR(task))
343 rpc_put_task(task); 351 break;
352 rpc_put_task(task);
344 353
345 dprintk("NFS: %5u initiated direct read call " 354 dprintk("NFS: %5u initiated direct read call "
346 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 355 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
@@ -446,6 +455,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
446 struct rpc_task_setup task_setup_data = { 455 struct rpc_task_setup task_setup_data = {
447 .rpc_client = NFS_CLIENT(inode), 456 .rpc_client = NFS_CLIENT(inode),
448 .callback_ops = &nfs_write_direct_ops, 457 .callback_ops = &nfs_write_direct_ops,
458 .workqueue = nfsiod_workqueue,
449 .flags = RPC_TASK_ASYNC, 459 .flags = RPC_TASK_ASYNC,
450 }; 460 };
451 461
@@ -499,27 +509,34 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
499static void nfs_direct_commit_result(struct rpc_task *task, void *calldata) 509static void nfs_direct_commit_result(struct rpc_task *task, void *calldata)
500{ 510{
501 struct nfs_write_data *data = calldata; 511 struct nfs_write_data *data = calldata;
502 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
503 512
504 /* Call the NFS version-specific code */ 513 /* Call the NFS version-specific code */
505 if (NFS_PROTO(data->inode)->commit_done(task, data) != 0) 514 NFS_PROTO(data->inode)->commit_done(task, data);
506 return; 515}
507 if (unlikely(task->tk_status < 0)) { 516
517static void nfs_direct_commit_release(void *calldata)
518{
519 struct nfs_write_data *data = calldata;
520 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
521 int status = data->task.tk_status;
522
523 if (status < 0) {
508 dprintk("NFS: %5u commit failed with error %d.\n", 524 dprintk("NFS: %5u commit failed with error %d.\n",
509 task->tk_pid, task->tk_status); 525 data->task.tk_pid, status);
510 dreq->flags = NFS_ODIRECT_RESCHED_WRITES; 526 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
511 } else if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) { 527 } else if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) {
512 dprintk("NFS: %5u commit verify failed\n", task->tk_pid); 528 dprintk("NFS: %5u commit verify failed\n", data->task.tk_pid);
513 dreq->flags = NFS_ODIRECT_RESCHED_WRITES; 529 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
514 } 530 }
515 531
516 dprintk("NFS: %5u commit returned %d\n", task->tk_pid, task->tk_status); 532 dprintk("NFS: %5u commit returned %d\n", data->task.tk_pid, status);
517 nfs_direct_write_complete(dreq, data->inode); 533 nfs_direct_write_complete(dreq, data->inode);
534 nfs_commitdata_release(calldata);
518} 535}
519 536
520static const struct rpc_call_ops nfs_commit_direct_ops = { 537static const struct rpc_call_ops nfs_commit_direct_ops = {
521 .rpc_call_done = nfs_direct_commit_result, 538 .rpc_call_done = nfs_direct_commit_result,
522 .rpc_release = nfs_commit_release, 539 .rpc_release = nfs_direct_commit_release,
523}; 540};
524 541
525static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) 542static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
@@ -537,6 +554,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
537 .rpc_message = &msg, 554 .rpc_message = &msg,
538 .callback_ops = &nfs_commit_direct_ops, 555 .callback_ops = &nfs_commit_direct_ops,
539 .callback_data = data, 556 .callback_data = data,
557 .workqueue = nfsiod_workqueue,
540 .flags = RPC_TASK_ASYNC, 558 .flags = RPC_TASK_ASYNC,
541 }; 559 };
542 560
@@ -546,6 +564,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
546 data->args.fh = NFS_FH(data->inode); 564 data->args.fh = NFS_FH(data->inode);
547 data->args.offset = 0; 565 data->args.offset = 0;
548 data->args.count = 0; 566 data->args.count = 0;
567 data->args.context = get_nfs_open_context(dreq->ctx);
549 data->res.count = 0; 568 data->res.count = 0;
550 data->res.fattr = &data->fattr; 569 data->res.fattr = &data->fattr;
551 data->res.verf = &data->verf; 570 data->res.verf = &data->verf;
@@ -585,7 +604,7 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
585 604
586static void nfs_alloc_commit_data(struct nfs_direct_req *dreq) 605static void nfs_alloc_commit_data(struct nfs_direct_req *dreq)
587{ 606{
588 dreq->commit_data = nfs_commit_alloc(); 607 dreq->commit_data = nfs_commitdata_alloc();
589 if (dreq->commit_data != NULL) 608 if (dreq->commit_data != NULL)
590 dreq->commit_data->req = (struct nfs_page *) dreq; 609 dreq->commit_data->req = (struct nfs_page *) dreq;
591} 610}
@@ -606,11 +625,20 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
606static void nfs_direct_write_result(struct rpc_task *task, void *calldata) 625static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
607{ 626{
608 struct nfs_write_data *data = calldata; 627 struct nfs_write_data *data = calldata;
609 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
610 int status = task->tk_status;
611 628
612 if (nfs_writeback_done(task, data) != 0) 629 if (nfs_writeback_done(task, data) != 0)
613 return; 630 return;
631}
632
633/*
634 * NB: Return the value of the first error return code. Subsequent
635 * errors after the first one are ignored.
636 */
637static void nfs_direct_write_release(void *calldata)
638{
639 struct nfs_write_data *data = calldata;
640 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
641 int status = data->task.tk_status;
614 642
615 spin_lock(&dreq->lock); 643 spin_lock(&dreq->lock);
616 644
@@ -632,23 +660,13 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
632 break; 660 break;
633 case NFS_ODIRECT_DO_COMMIT: 661 case NFS_ODIRECT_DO_COMMIT:
634 if (memcmp(&dreq->verf, &data->verf, sizeof(dreq->verf))) { 662 if (memcmp(&dreq->verf, &data->verf, sizeof(dreq->verf))) {
635 dprintk("NFS: %5u write verify failed\n", task->tk_pid); 663 dprintk("NFS: %5u write verify failed\n", data->task.tk_pid);
636 dreq->flags = NFS_ODIRECT_RESCHED_WRITES; 664 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
637 } 665 }
638 } 666 }
639 } 667 }
640out_unlock: 668out_unlock:
641 spin_unlock(&dreq->lock); 669 spin_unlock(&dreq->lock);
642}
643
644/*
645 * NB: Return the value of the first error return code. Subsequent
646 * errors after the first one are ignored.
647 */
648static void nfs_direct_write_release(void *calldata)
649{
650 struct nfs_write_data *data = calldata;
651 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
652 670
653 if (put_dreq(dreq)) 671 if (put_dreq(dreq))
654 nfs_direct_write_complete(dreq, data->inode); 672 nfs_direct_write_complete(dreq, data->inode);
@@ -682,6 +700,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
682 .rpc_client = NFS_CLIENT(inode), 700 .rpc_client = NFS_CLIENT(inode),
683 .rpc_message = &msg, 701 .rpc_message = &msg,
684 .callback_ops = &nfs_write_direct_ops, 702 .callback_ops = &nfs_write_direct_ops,
703 .workqueue = nfsiod_workqueue,
685 .flags = RPC_TASK_ASYNC, 704 .flags = RPC_TASK_ASYNC,
686 }; 705 };
687 size_t wsize = NFS_SERVER(inode)->wsize; 706 size_t wsize = NFS_SERVER(inode)->wsize;
@@ -728,7 +747,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
728 data->inode = inode; 747 data->inode = inode;
729 data->cred = msg.rpc_cred; 748 data->cred = msg.rpc_cred;
730 data->args.fh = NFS_FH(inode); 749 data->args.fh = NFS_FH(inode);
731 data->args.context = ctx; 750 data->args.context = get_nfs_open_context(ctx);
732 data->args.offset = pos; 751 data->args.offset = pos;
733 data->args.pgbase = pgbase; 752 data->args.pgbase = pgbase;
734 data->args.pages = data->pagevec; 753 data->args.pages = data->pagevec;
@@ -745,8 +764,9 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
745 NFS_PROTO(inode)->write_setup(data, &msg); 764 NFS_PROTO(inode)->write_setup(data, &msg);
746 765
747 task = rpc_run_task(&task_setup_data); 766 task = rpc_run_task(&task_setup_data);
748 if (!IS_ERR(task)) 767 if (IS_ERR(task))
749 rpc_put_task(task); 768 break;
769 rpc_put_task(task);
750 770
751 dprintk("NFS: %5u initiated direct write call " 771 dprintk("NFS: %5u initiated direct write call "
752 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 772 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 5d2e9d9a4e28..3536b01164f9 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -238,10 +238,8 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
238 ssize_t result; 238 ssize_t result;
239 size_t count = iov_length(iov, nr_segs); 239 size_t count = iov_length(iov, nr_segs);
240 240
241#ifdef CONFIG_NFS_DIRECTIO
242 if (iocb->ki_filp->f_flags & O_DIRECT) 241 if (iocb->ki_filp->f_flags & O_DIRECT)
243 return nfs_file_direct_read(iocb, iov, nr_segs, pos); 242 return nfs_file_direct_read(iocb, iov, nr_segs, pos);
244#endif
245 243
246 dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", 244 dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n",
247 dentry->d_parent->d_name.name, dentry->d_name.name, 245 dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -387,9 +385,7 @@ const struct address_space_operations nfs_file_aops = {
387 .write_end = nfs_write_end, 385 .write_end = nfs_write_end,
388 .invalidatepage = nfs_invalidate_page, 386 .invalidatepage = nfs_invalidate_page,
389 .releasepage = nfs_release_page, 387 .releasepage = nfs_release_page,
390#ifdef CONFIG_NFS_DIRECTIO
391 .direct_IO = nfs_direct_IO, 388 .direct_IO = nfs_direct_IO,
392#endif
393 .launder_page = nfs_launder_page, 389 .launder_page = nfs_launder_page,
394}; 390};
395 391
@@ -447,10 +443,8 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
447 ssize_t result; 443 ssize_t result;
448 size_t count = iov_length(iov, nr_segs); 444 size_t count = iov_length(iov, nr_segs);
449 445
450#ifdef CONFIG_NFS_DIRECTIO
451 if (iocb->ki_filp->f_flags & O_DIRECT) 446 if (iocb->ki_filp->f_flags & O_DIRECT)
452 return nfs_file_direct_write(iocb, iov, nr_segs, pos); 447 return nfs_file_direct_write(iocb, iov, nr_segs, pos);
453#endif
454 448
455 dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n", 449 dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n",
456 dentry->d_parent->d_name.name, dentry->d_name.name, 450 dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -576,17 +570,9 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
576 570
577 lock_kernel(); 571 lock_kernel();
578 /* Use local locking if mounted with "-onolock" */ 572 /* Use local locking if mounted with "-onolock" */
579 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) { 573 if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
580 status = NFS_PROTO(inode)->lock(filp, cmd, fl); 574 status = NFS_PROTO(inode)->lock(filp, cmd, fl);
581 /* If we were signalled we still need to ensure that 575 else
582 * we clean up any state on the server. We therefore
583 * record the lock call as having succeeded in order to
584 * ensure that locks_remove_posix() cleans it out when
585 * the process exits.
586 */
587 if (status == -EINTR || status == -ERESTARTSYS)
588 do_vfs_lock(filp, fl);
589 } else
590 status = do_vfs_lock(filp, fl); 576 status = do_vfs_lock(filp, fl);
591 unlock_kernel(); 577 unlock_kernel();
592 if (status < 0) 578 if (status < 0)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6f88d7c77ac9..5cb3345eb694 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -523,8 +523,12 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
523 523
524static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait) 524static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait)
525{ 525{
526 struct inode *inode = ctx->path.dentry->d_inode; 526 struct inode *inode;
527 527
528 if (ctx == NULL)
529 return;
530
531 inode = ctx->path.dentry->d_inode;
528 if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock)) 532 if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock))
529 return; 533 return;
530 list_del(&ctx->list); 534 list_del(&ctx->list);
@@ -610,7 +614,7 @@ int nfs_open(struct inode *inode, struct file *filp)
610 struct nfs_open_context *ctx; 614 struct nfs_open_context *ctx;
611 struct rpc_cred *cred; 615 struct rpc_cred *cred;
612 616
613 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); 617 cred = rpc_lookup_cred();
614 if (IS_ERR(cred)) 618 if (IS_ERR(cred))
615 return PTR_ERR(cred); 619 return PTR_ERR(cred);
616 ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred); 620 ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred);
@@ -1218,6 +1222,36 @@ static void nfs_destroy_inodecache(void)
1218 kmem_cache_destroy(nfs_inode_cachep); 1222 kmem_cache_destroy(nfs_inode_cachep);
1219} 1223}
1220 1224
1225struct workqueue_struct *nfsiod_workqueue;
1226
1227/*
1228 * start up the nfsiod workqueue
1229 */
1230static int nfsiod_start(void)
1231{
1232 struct workqueue_struct *wq;
1233 dprintk("RPC: creating workqueue nfsiod\n");
1234 wq = create_singlethread_workqueue("nfsiod");
1235 if (wq == NULL)
1236 return -ENOMEM;
1237 nfsiod_workqueue = wq;
1238 return 0;
1239}
1240
1241/*
1242 * Destroy the nfsiod workqueue
1243 */
1244static void nfsiod_stop(void)
1245{
1246 struct workqueue_struct *wq;
1247
1248 wq = nfsiod_workqueue;
1249 if (wq == NULL)
1250 return;
1251 nfsiod_workqueue = NULL;
1252 destroy_workqueue(wq);
1253}
1254
1221/* 1255/*
1222 * Initialize NFS 1256 * Initialize NFS
1223 */ 1257 */
@@ -1225,6 +1259,10 @@ static int __init init_nfs_fs(void)
1225{ 1259{
1226 int err; 1260 int err;
1227 1261
1262 err = nfsiod_start();
1263 if (err)
1264 goto out6;
1265
1228 err = nfs_fs_proc_init(); 1266 err = nfs_fs_proc_init();
1229 if (err) 1267 if (err)
1230 goto out5; 1268 goto out5;
@@ -1271,6 +1309,8 @@ out3:
1271out4: 1309out4:
1272 nfs_fs_proc_exit(); 1310 nfs_fs_proc_exit();
1273out5: 1311out5:
1312 nfsiod_stop();
1313out6:
1274 return err; 1314 return err;
1275} 1315}
1276 1316
@@ -1286,6 +1326,7 @@ static void __exit exit_nfs_fs(void)
1286#endif 1326#endif
1287 unregister_nfs_fs(); 1327 unregister_nfs_fs();
1288 nfs_fs_proc_exit(); 1328 nfs_fs_proc_exit();
1329 nfsiod_stop();
1289} 1330}
1290 1331
1291/* Not quite true; I just maintain it */ 1332/* Not quite true; I just maintain it */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 931992763e68..04ae867dddba 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -46,9 +46,9 @@ struct nfs_parsed_mount_data {
46 struct sockaddr_storage address; 46 struct sockaddr_storage address;
47 size_t addrlen; 47 size_t addrlen;
48 char *hostname; 48 char *hostname;
49 unsigned int version; 49 u32 version;
50 unsigned short port; 50 unsigned short port;
51 int protocol; 51 unsigned short protocol;
52 } mount_server; 52 } mount_server;
53 53
54 struct { 54 struct {
@@ -56,7 +56,8 @@ struct nfs_parsed_mount_data {
56 size_t addrlen; 56 size_t addrlen;
57 char *hostname; 57 char *hostname;
58 char *export_path; 58 char *export_path;
59 int protocol; 59 unsigned short port;
60 unsigned short protocol;
60 } nfs_server; 61 } nfs_server;
61 62
62 struct security_mnt_opts lsm_opts; 63 struct security_mnt_opts lsm_opts;
@@ -115,13 +116,8 @@ extern void nfs_destroy_readpagecache(void);
115extern int __init nfs_init_writepagecache(void); 116extern int __init nfs_init_writepagecache(void);
116extern void nfs_destroy_writepagecache(void); 117extern void nfs_destroy_writepagecache(void);
117 118
118#ifdef CONFIG_NFS_DIRECTIO
119extern int __init nfs_init_directcache(void); 119extern int __init nfs_init_directcache(void);
120extern void nfs_destroy_directcache(void); 120extern void nfs_destroy_directcache(void);
121#else
122#define nfs_init_directcache() (0)
123#define nfs_destroy_directcache() do {} while(0)
124#endif
125 121
126/* nfs2xdr.c */ 122/* nfs2xdr.c */
127extern int nfs_stat_to_errno(int); 123extern int nfs_stat_to_errno(int);
@@ -146,6 +142,7 @@ extern struct rpc_procinfo nfs4_procedures[];
146extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask); 142extern int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask);
147 143
148/* inode.c */ 144/* inode.c */
145extern struct workqueue_struct *nfsiod_workqueue;
149extern struct inode *nfs_alloc_inode(struct super_block *sb); 146extern struct inode *nfs_alloc_inode(struct super_block *sb);
150extern void nfs_destroy_inode(struct inode *); 147extern void nfs_destroy_inode(struct inode *);
151extern int nfs_write_inode(struct inode *,int); 148extern int nfs_write_inode(struct inode *,int);
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 607f6eb9cdb5..af4d0f1e402c 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -20,7 +20,7 @@
20 20
21static void nfs_expire_automounts(struct work_struct *work); 21static void nfs_expire_automounts(struct work_struct *work);
22 22
23LIST_HEAD(nfs_automount_list); 23static LIST_HEAD(nfs_automount_list);
24static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); 24static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts);
25int nfs_mountpoint_expiry_timeout = 500 * HZ; 25int nfs_mountpoint_expiry_timeout = 500 * HZ;
26 26
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 1f7ea675e0c5..28bab67d1519 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -267,7 +267,7 @@ nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
267 int status; 267 int status;
268 268
269 if ((status = ntohl(*p++))) 269 if ((status = ntohl(*p++)))
270 return -nfs_stat_to_errno(status); 270 return nfs_stat_to_errno(status);
271 p = xdr_decode_fattr(p, res->fattr); 271 p = xdr_decode_fattr(p, res->fattr);
272 272
273 count = ntohl(*p++); 273 count = ntohl(*p++);
@@ -428,11 +428,11 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
428 size_t hdrlen; 428 size_t hdrlen;
429 unsigned int pglen, recvd; 429 unsigned int pglen, recvd;
430 u32 len; 430 u32 len;
431 int status, nr; 431 int status, nr = 0;
432 __be32 *end, *entry, *kaddr; 432 __be32 *end, *entry, *kaddr;
433 433
434 if ((status = ntohl(*p++))) 434 if ((status = ntohl(*p++)))
435 return -nfs_stat_to_errno(status); 435 return nfs_stat_to_errno(status);
436 436
437 hdrlen = (u8 *) p - (u8 *) iov->iov_base; 437 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
438 if (iov->iov_len < hdrlen) { 438 if (iov->iov_len < hdrlen) {
@@ -452,7 +452,12 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
452 kaddr = p = kmap_atomic(*page, KM_USER0); 452 kaddr = p = kmap_atomic(*page, KM_USER0);
453 end = (__be32 *)((char *)p + pglen); 453 end = (__be32 *)((char *)p + pglen);
454 entry = p; 454 entry = p;
455 for (nr = 0; *p++; nr++) { 455
456 /* Make sure the packet actually has a value_follows and EOF entry */
457 if ((entry + 1) > end)
458 goto short_pkt;
459
460 for (; *p++; nr++) {
456 if (p + 2 > end) 461 if (p + 2 > end)
457 goto short_pkt; 462 goto short_pkt;
458 p++; /* fileid */ 463 p++; /* fileid */
@@ -467,18 +472,32 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
467 goto short_pkt; 472 goto short_pkt;
468 entry = p; 473 entry = p;
469 } 474 }
470 if (!nr && (entry[0] != 0 || entry[1] == 0)) 475
471 goto short_pkt; 476 /*
477 * Apparently some server sends responses that are a valid size, but
478 * contain no entries, and have value_follows==0 and EOF==0. For
479 * those, just set the EOF marker.
480 */
481 if (!nr && entry[1] == 0) {
482 dprintk("NFS: readdir reply truncated!\n");
483 entry[1] = 1;
484 }
472 out: 485 out:
473 kunmap_atomic(kaddr, KM_USER0); 486 kunmap_atomic(kaddr, KM_USER0);
474 return nr; 487 return nr;
475 short_pkt: 488 short_pkt:
489 /*
490 * When we get a short packet there are 2 possibilities. We can
491 * return an error, or fix up the response to look like a valid
492 * response and return what we have so far. If there are no
493 * entries and the packet was short, then return -EIO. If there
494 * are valid entries in the response, return them and pretend that
495 * the call was successful, but incomplete. The caller can retry the
496 * readdir starting at the last cookie.
497 */
476 entry[0] = entry[1] = 0; 498 entry[0] = entry[1] = 0;
477 /* truncate listing ? */ 499 if (!nr)
478 if (!nr) { 500 nr = -errno_NFSERR_IO;
479 dprintk("NFS: readdir reply truncated!\n");
480 entry[1] = 1;
481 }
482 goto out; 501 goto out;
483err_unmap: 502err_unmap:
484 nr = -errno_NFSERR_IO; 503 nr = -errno_NFSERR_IO;
@@ -518,7 +537,7 @@ nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
518 int status; 537 int status;
519 538
520 if ((status = ntohl(*p++)) != 0) 539 if ((status = ntohl(*p++)) != 0)
521 status = -nfs_stat_to_errno(status); 540 status = nfs_stat_to_errno(status);
522 return status; 541 return status;
523} 542}
524 543
@@ -532,7 +551,7 @@ nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
532 int status; 551 int status;
533 552
534 if ((status = ntohl(*p++))) 553 if ((status = ntohl(*p++)))
535 return -nfs_stat_to_errno(status); 554 return nfs_stat_to_errno(status);
536 xdr_decode_fattr(p, fattr); 555 xdr_decode_fattr(p, fattr);
537 return 0; 556 return 0;
538} 557}
@@ -547,7 +566,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
547 int status; 566 int status;
548 567
549 if ((status = ntohl(*p++))) 568 if ((status = ntohl(*p++)))
550 return -nfs_stat_to_errno(status); 569 return nfs_stat_to_errno(status);
551 p = xdr_decode_fhandle(p, res->fh); 570 p = xdr_decode_fhandle(p, res->fh);
552 xdr_decode_fattr(p, res->fattr); 571 xdr_decode_fattr(p, res->fattr);
553 return 0; 572 return 0;
@@ -585,7 +604,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
585 int status; 604 int status;
586 605
587 if ((status = ntohl(*p++))) 606 if ((status = ntohl(*p++)))
588 return -nfs_stat_to_errno(status); 607 return nfs_stat_to_errno(status);
589 /* Convert length of symlink */ 608 /* Convert length of symlink */
590 len = ntohl(*p++); 609 len = ntohl(*p++);
591 if (len >= rcvbuf->page_len) { 610 if (len >= rcvbuf->page_len) {
@@ -634,7 +653,7 @@ nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
634 int status; 653 int status;
635 654
636 if ((status = ntohl(*p++))) 655 if ((status = ntohl(*p++)))
637 return -nfs_stat_to_errno(status); 656 return nfs_stat_to_errno(status);
638 657
639 res->tsize = ntohl(*p++); 658 res->tsize = ntohl(*p++);
640 res->bsize = ntohl(*p++); 659 res->bsize = ntohl(*p++);
@@ -653,39 +672,39 @@ static struct {
653 int errno; 672 int errno;
654} nfs_errtbl[] = { 673} nfs_errtbl[] = {
655 { NFS_OK, 0 }, 674 { NFS_OK, 0 },
656 { NFSERR_PERM, EPERM }, 675 { NFSERR_PERM, -EPERM },
657 { NFSERR_NOENT, ENOENT }, 676 { NFSERR_NOENT, -ENOENT },
658 { NFSERR_IO, errno_NFSERR_IO }, 677 { NFSERR_IO, -errno_NFSERR_IO},
659 { NFSERR_NXIO, ENXIO }, 678 { NFSERR_NXIO, -ENXIO },
660/* { NFSERR_EAGAIN, EAGAIN }, */ 679/* { NFSERR_EAGAIN, -EAGAIN }, */
661 { NFSERR_ACCES, EACCES }, 680 { NFSERR_ACCES, -EACCES },
662 { NFSERR_EXIST, EEXIST }, 681 { NFSERR_EXIST, -EEXIST },
663 { NFSERR_XDEV, EXDEV }, 682 { NFSERR_XDEV, -EXDEV },
664 { NFSERR_NODEV, ENODEV }, 683 { NFSERR_NODEV, -ENODEV },
665 { NFSERR_NOTDIR, ENOTDIR }, 684 { NFSERR_NOTDIR, -ENOTDIR },
666 { NFSERR_ISDIR, EISDIR }, 685 { NFSERR_ISDIR, -EISDIR },
667 { NFSERR_INVAL, EINVAL }, 686 { NFSERR_INVAL, -EINVAL },
668 { NFSERR_FBIG, EFBIG }, 687 { NFSERR_FBIG, -EFBIG },
669 { NFSERR_NOSPC, ENOSPC }, 688 { NFSERR_NOSPC, -ENOSPC },
670 { NFSERR_ROFS, EROFS }, 689 { NFSERR_ROFS, -EROFS },
671 { NFSERR_MLINK, EMLINK }, 690 { NFSERR_MLINK, -EMLINK },
672 { NFSERR_NAMETOOLONG, ENAMETOOLONG }, 691 { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
673 { NFSERR_NOTEMPTY, ENOTEMPTY }, 692 { NFSERR_NOTEMPTY, -ENOTEMPTY },
674 { NFSERR_DQUOT, EDQUOT }, 693 { NFSERR_DQUOT, -EDQUOT },
675 { NFSERR_STALE, ESTALE }, 694 { NFSERR_STALE, -ESTALE },
676 { NFSERR_REMOTE, EREMOTE }, 695 { NFSERR_REMOTE, -EREMOTE },
677#ifdef EWFLUSH 696#ifdef EWFLUSH
678 { NFSERR_WFLUSH, EWFLUSH }, 697 { NFSERR_WFLUSH, -EWFLUSH },
679#endif 698#endif
680 { NFSERR_BADHANDLE, EBADHANDLE }, 699 { NFSERR_BADHANDLE, -EBADHANDLE },
681 { NFSERR_NOT_SYNC, ENOTSYNC }, 700 { NFSERR_NOT_SYNC, -ENOTSYNC },
682 { NFSERR_BAD_COOKIE, EBADCOOKIE }, 701 { NFSERR_BAD_COOKIE, -EBADCOOKIE },
683 { NFSERR_NOTSUPP, ENOTSUPP }, 702 { NFSERR_NOTSUPP, -ENOTSUPP },
684 { NFSERR_TOOSMALL, ETOOSMALL }, 703 { NFSERR_TOOSMALL, -ETOOSMALL },
685 { NFSERR_SERVERFAULT, ESERVERFAULT }, 704 { NFSERR_SERVERFAULT, -ESERVERFAULT },
686 { NFSERR_BADTYPE, EBADTYPE }, 705 { NFSERR_BADTYPE, -EBADTYPE },
687 { NFSERR_JUKEBOX, EJUKEBOX }, 706 { NFSERR_JUKEBOX, -EJUKEBOX },
688 { -1, EIO } 707 { -1, -EIO }
689}; 708};
690 709
691/* 710/*
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 3917e2fa4e40..11cdddec1432 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -508,14 +508,14 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
508 struct page **page; 508 struct page **page;
509 size_t hdrlen; 509 size_t hdrlen;
510 u32 len, recvd, pglen; 510 u32 len, recvd, pglen;
511 int status, nr; 511 int status, nr = 0;
512 __be32 *entry, *end, *kaddr; 512 __be32 *entry, *end, *kaddr;
513 513
514 status = ntohl(*p++); 514 status = ntohl(*p++);
515 /* Decode post_op_attrs */ 515 /* Decode post_op_attrs */
516 p = xdr_decode_post_op_attr(p, res->dir_attr); 516 p = xdr_decode_post_op_attr(p, res->dir_attr);
517 if (status) 517 if (status)
518 return -nfs_stat_to_errno(status); 518 return nfs_stat_to_errno(status);
519 /* Decode verifier cookie */ 519 /* Decode verifier cookie */
520 if (res->verf) { 520 if (res->verf) {
521 res->verf[0] = *p++; 521 res->verf[0] = *p++;
@@ -542,7 +542,12 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
542 kaddr = p = kmap_atomic(*page, KM_USER0); 542 kaddr = p = kmap_atomic(*page, KM_USER0);
543 end = (__be32 *)((char *)p + pglen); 543 end = (__be32 *)((char *)p + pglen);
544 entry = p; 544 entry = p;
545 for (nr = 0; *p++; nr++) { 545
546 /* Make sure the packet actually has a value_follows and EOF entry */
547 if ((entry + 1) > end)
548 goto short_pkt;
549
550 for (; *p++; nr++) {
546 if (p + 3 > end) 551 if (p + 3 > end)
547 goto short_pkt; 552 goto short_pkt;
548 p += 2; /* inode # */ 553 p += 2; /* inode # */
@@ -581,18 +586,32 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
581 goto short_pkt; 586 goto short_pkt;
582 entry = p; 587 entry = p;
583 } 588 }
584 if (!nr && (entry[0] != 0 || entry[1] == 0)) 589
585 goto short_pkt; 590 /*
591 * Apparently some server sends responses that are a valid size, but
592 * contain no entries, and have value_follows==0 and EOF==0. For
593 * those, just set the EOF marker.
594 */
595 if (!nr && entry[1] == 0) {
596 dprintk("NFS: readdir reply truncated!\n");
597 entry[1] = 1;
598 }
586 out: 599 out:
587 kunmap_atomic(kaddr, KM_USER0); 600 kunmap_atomic(kaddr, KM_USER0);
588 return nr; 601 return nr;
589 short_pkt: 602 short_pkt:
603 /*
604 * When we get a short packet there are 2 possibilities. We can
605 * return an error, or fix up the response to look like a valid
606 * response and return what we have so far. If there are no
607 * entries and the packet was short, then return -EIO. If there
608 * are valid entries in the response, return them and pretend that
609 * the call was successful, but incomplete. The caller can retry the
610 * readdir starting at the last cookie.
611 */
590 entry[0] = entry[1] = 0; 612 entry[0] = entry[1] = 0;
591 /* truncate listing ? */ 613 if (!nr)
592 if (!nr) { 614 nr = -errno_NFSERR_IO;
593 dprintk("NFS: readdir reply truncated!\n");
594 entry[1] = 1;
595 }
596 goto out; 615 goto out;
597err_unmap: 616err_unmap:
598 nr = -errno_NFSERR_IO; 617 nr = -errno_NFSERR_IO;
@@ -732,7 +751,7 @@ nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
732 int status; 751 int status;
733 752
734 if ((status = ntohl(*p++))) 753 if ((status = ntohl(*p++)))
735 return -nfs_stat_to_errno(status); 754 return nfs_stat_to_errno(status);
736 xdr_decode_fattr(p, fattr); 755 xdr_decode_fattr(p, fattr);
737 return 0; 756 return 0;
738} 757}
@@ -747,7 +766,7 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
747 int status; 766 int status;
748 767
749 if ((status = ntohl(*p++))) 768 if ((status = ntohl(*p++)))
750 status = -nfs_stat_to_errno(status); 769 status = nfs_stat_to_errno(status);
751 xdr_decode_wcc_data(p, fattr); 770 xdr_decode_wcc_data(p, fattr);
752 return status; 771 return status;
753} 772}
@@ -767,7 +786,7 @@ nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
767 int status; 786 int status;
768 787
769 if ((status = ntohl(*p++))) { 788 if ((status = ntohl(*p++))) {
770 status = -nfs_stat_to_errno(status); 789 status = nfs_stat_to_errno(status);
771 } else { 790 } else {
772 if (!(p = xdr_decode_fhandle(p, res->fh))) 791 if (!(p = xdr_decode_fhandle(p, res->fh)))
773 return -errno_NFSERR_IO; 792 return -errno_NFSERR_IO;
@@ -787,7 +806,7 @@ nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
787 806
788 p = xdr_decode_post_op_attr(p, res->fattr); 807 p = xdr_decode_post_op_attr(p, res->fattr);
789 if (status) 808 if (status)
790 return -nfs_stat_to_errno(status); 809 return nfs_stat_to_errno(status);
791 res->access = ntohl(*p++); 810 res->access = ntohl(*p++);
792 return 0; 811 return 0;
793} 812}
@@ -824,7 +843,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
824 p = xdr_decode_post_op_attr(p, fattr); 843 p = xdr_decode_post_op_attr(p, fattr);
825 844
826 if (status != 0) 845 if (status != 0)
827 return -nfs_stat_to_errno(status); 846 return nfs_stat_to_errno(status);
828 847
829 /* Convert length of symlink */ 848 /* Convert length of symlink */
830 len = ntohl(*p++); 849 len = ntohl(*p++);
@@ -872,7 +891,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
872 p = xdr_decode_post_op_attr(p, res->fattr); 891 p = xdr_decode_post_op_attr(p, res->fattr);
873 892
874 if (status != 0) 893 if (status != 0)
875 return -nfs_stat_to_errno(status); 894 return nfs_stat_to_errno(status);
876 895
877 /* Decode reply count and EOF flag. NFSv3 is somewhat redundant 896 /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
878 * in that it puts the count both in the res struct and in the 897 * in that it puts the count both in the res struct and in the
@@ -922,7 +941,7 @@ nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
922 p = xdr_decode_wcc_data(p, res->fattr); 941 p = xdr_decode_wcc_data(p, res->fattr);
923 942
924 if (status != 0) 943 if (status != 0)
925 return -nfs_stat_to_errno(status); 944 return nfs_stat_to_errno(status);
926 945
927 res->count = ntohl(*p++); 946 res->count = ntohl(*p++);
928 res->verf->committed = (enum nfs3_stable_how)ntohl(*p++); 947 res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
@@ -953,7 +972,7 @@ nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
953 res->fattr->valid = 0; 972 res->fattr->valid = 0;
954 } 973 }
955 } else { 974 } else {
956 status = -nfs_stat_to_errno(status); 975 status = nfs_stat_to_errno(status);
957 } 976 }
958 p = xdr_decode_wcc_data(p, res->dir_attr); 977 p = xdr_decode_wcc_data(p, res->dir_attr);
959 return status; 978 return status;
@@ -968,7 +987,7 @@ nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs3_renameres *res)
968 int status; 987 int status;
969 988
970 if ((status = ntohl(*p++)) != 0) 989 if ((status = ntohl(*p++)) != 0)
971 status = -nfs_stat_to_errno(status); 990 status = nfs_stat_to_errno(status);
972 p = xdr_decode_wcc_data(p, res->fromattr); 991 p = xdr_decode_wcc_data(p, res->fromattr);
973 p = xdr_decode_wcc_data(p, res->toattr); 992 p = xdr_decode_wcc_data(p, res->toattr);
974 return status; 993 return status;
@@ -983,7 +1002,7 @@ nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
983 int status; 1002 int status;
984 1003
985 if ((status = ntohl(*p++)) != 0) 1004 if ((status = ntohl(*p++)) != 0)
986 status = -nfs_stat_to_errno(status); 1005 status = nfs_stat_to_errno(status);
987 p = xdr_decode_post_op_attr(p, res->fattr); 1006 p = xdr_decode_post_op_attr(p, res->fattr);
988 p = xdr_decode_wcc_data(p, res->dir_attr); 1007 p = xdr_decode_wcc_data(p, res->dir_attr);
989 return status; 1008 return status;
@@ -1001,7 +1020,7 @@ nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
1001 1020
1002 p = xdr_decode_post_op_attr(p, res->fattr); 1021 p = xdr_decode_post_op_attr(p, res->fattr);
1003 if (status != 0) 1022 if (status != 0)
1004 return -nfs_stat_to_errno(status); 1023 return nfs_stat_to_errno(status);
1005 1024
1006 p = xdr_decode_hyper(p, &res->tbytes); 1025 p = xdr_decode_hyper(p, &res->tbytes);
1007 p = xdr_decode_hyper(p, &res->fbytes); 1026 p = xdr_decode_hyper(p, &res->fbytes);
@@ -1026,7 +1045,7 @@ nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
1026 1045
1027 p = xdr_decode_post_op_attr(p, res->fattr); 1046 p = xdr_decode_post_op_attr(p, res->fattr);
1028 if (status != 0) 1047 if (status != 0)
1029 return -nfs_stat_to_errno(status); 1048 return nfs_stat_to_errno(status);
1030 1049
1031 res->rtmax = ntohl(*p++); 1050 res->rtmax = ntohl(*p++);
1032 res->rtpref = ntohl(*p++); 1051 res->rtpref = ntohl(*p++);
@@ -1054,7 +1073,7 @@ nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
1054 1073
1055 p = xdr_decode_post_op_attr(p, res->fattr); 1074 p = xdr_decode_post_op_attr(p, res->fattr);
1056 if (status != 0) 1075 if (status != 0)
1057 return -nfs_stat_to_errno(status); 1076 return nfs_stat_to_errno(status);
1058 res->max_link = ntohl(*p++); 1077 res->max_link = ntohl(*p++);
1059 res->max_namelen = ntohl(*p++); 1078 res->max_namelen = ntohl(*p++);
1060 1079
@@ -1073,7 +1092,7 @@ nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1073 status = ntohl(*p++); 1092 status = ntohl(*p++);
1074 p = xdr_decode_wcc_data(p, res->fattr); 1093 p = xdr_decode_wcc_data(p, res->fattr);
1075 if (status != 0) 1094 if (status != 0)
1076 return -nfs_stat_to_errno(status); 1095 return nfs_stat_to_errno(status);
1077 1096
1078 res->verf->verifier[0] = *p++; 1097 res->verf->verifier[0] = *p++;
1079 res->verf->verifier[1] = *p++; 1098 res->verf->verifier[1] = *p++;
@@ -1095,7 +1114,7 @@ nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
1095 int err, base; 1114 int err, base;
1096 1115
1097 if (status != 0) 1116 if (status != 0)
1098 return -nfs_stat_to_errno(status); 1117 return nfs_stat_to_errno(status);
1099 p = xdr_decode_post_op_attr(p, res->fattr); 1118 p = xdr_decode_post_op_attr(p, res->fattr);
1100 res->mask = ntohl(*p++); 1119 res->mask = ntohl(*p++);
1101 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) 1120 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
@@ -1122,7 +1141,7 @@ nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1122 int status = ntohl(*p++); 1141 int status = ntohl(*p++);
1123 1142
1124 if (status) 1143 if (status)
1125 return -nfs_stat_to_errno(status); 1144 return nfs_stat_to_errno(status);
1126 xdr_decode_post_op_attr(p, fattr); 1145 xdr_decode_post_op_attr(p, fattr);
1127 return 0; 1146 return 0;
1128} 1147}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 7ce07862c2fb..dbc09271af02 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -51,6 +51,7 @@
51 51
52#include "nfs4_fs.h" 52#include "nfs4_fs.h"
53#include "delegation.h" 53#include "delegation.h"
54#include "internal.h"
54#include "iostat.h" 55#include "iostat.h"
55 56
56#define NFSDBG_FACILITY NFSDBG_PROC 57#define NFSDBG_FACILITY NFSDBG_PROC
@@ -239,6 +240,8 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
239{ 240{
240 p->o_res.f_attr = &p->f_attr; 241 p->o_res.f_attr = &p->f_attr;
241 p->o_res.dir_attr = &p->dir_attr; 242 p->o_res.dir_attr = &p->dir_attr;
243 p->o_res.seqid = p->o_arg.seqid;
244 p->c_res.seqid = p->c_arg.seqid;
242 p->o_res.server = p->o_arg.server; 245 p->o_res.server = p->o_arg.server;
243 nfs_fattr_init(&p->f_attr); 246 nfs_fattr_init(&p->f_attr);
244 nfs_fattr_init(&p->dir_attr); 247 nfs_fattr_init(&p->dir_attr);
@@ -729,7 +732,6 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
729 renew_lease(data->o_res.server, data->timestamp); 732 renew_lease(data->o_res.server, data->timestamp);
730 data->rpc_done = 1; 733 data->rpc_done = 1;
731 } 734 }
732 nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
733} 735}
734 736
735static void nfs4_open_confirm_release(void *calldata) 737static void nfs4_open_confirm_release(void *calldata)
@@ -773,6 +775,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
773 .rpc_message = &msg, 775 .rpc_message = &msg,
774 .callback_ops = &nfs4_open_confirm_ops, 776 .callback_ops = &nfs4_open_confirm_ops,
775 .callback_data = data, 777 .callback_data = data,
778 .workqueue = nfsiod_workqueue,
776 .flags = RPC_TASK_ASYNC, 779 .flags = RPC_TASK_ASYNC,
777 }; 780 };
778 int status; 781 int status;
@@ -858,7 +861,6 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
858 if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)) 861 if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))
859 nfs_confirm_seqid(&data->owner->so_seqid, 0); 862 nfs_confirm_seqid(&data->owner->so_seqid, 0);
860 } 863 }
861 nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid);
862 data->rpc_done = 1; 864 data->rpc_done = 1;
863} 865}
864 866
@@ -910,6 +912,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
910 .rpc_message = &msg, 912 .rpc_message = &msg,
911 .callback_ops = &nfs4_open_ops, 913 .callback_ops = &nfs4_open_ops,
912 .callback_data = data, 914 .callback_data = data,
915 .workqueue = nfsiod_workqueue,
913 .flags = RPC_TASK_ASYNC, 916 .flags = RPC_TASK_ASYNC,
914 }; 917 };
915 int status; 918 int status;
@@ -979,11 +982,8 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
979 if (IS_ERR(opendata)) 982 if (IS_ERR(opendata))
980 return PTR_ERR(opendata); 983 return PTR_ERR(opendata);
981 ret = nfs4_open_recover(opendata, state); 984 ret = nfs4_open_recover(opendata, state);
982 if (ret == -ESTALE) { 985 if (ret == -ESTALE)
983 /* Invalidate the state owner so we don't ever use it again */
984 nfs4_drop_state_owner(state->owner);
985 d_drop(ctx->path.dentry); 986 d_drop(ctx->path.dentry);
986 }
987 nfs4_opendata_put(opendata); 987 nfs4_opendata_put(opendata);
988 return ret; 988 return ret;
989} 989}
@@ -1226,7 +1226,6 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1226 /* hmm. we are done with the inode, and in the process of freeing 1226 /* hmm. we are done with the inode, and in the process of freeing
1227 * the state_owner. we keep this around to process errors 1227 * the state_owner. we keep this around to process errors
1228 */ 1228 */
1229 nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
1230 switch (task->tk_status) { 1229 switch (task->tk_status) {
1231 case 0: 1230 case 0:
1232 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1231 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
@@ -1315,6 +1314,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1315 .rpc_client = server->client, 1314 .rpc_client = server->client,
1316 .rpc_message = &msg, 1315 .rpc_message = &msg,
1317 .callback_ops = &nfs4_close_ops, 1316 .callback_ops = &nfs4_close_ops,
1317 .workqueue = nfsiod_workqueue,
1318 .flags = RPC_TASK_ASYNC, 1318 .flags = RPC_TASK_ASYNC,
1319 }; 1319 };
1320 int status = -ENOMEM; 1320 int status = -ENOMEM;
@@ -1332,6 +1332,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1332 goto out_free_calldata; 1332 goto out_free_calldata;
1333 calldata->arg.bitmask = server->attr_bitmask; 1333 calldata->arg.bitmask = server->attr_bitmask;
1334 calldata->res.fattr = &calldata->fattr; 1334 calldata->res.fattr = &calldata->fattr;
1335 calldata->res.seqid = calldata->arg.seqid;
1335 calldata->res.server = server; 1336 calldata->res.server = server;
1336 calldata->path.mnt = mntget(path->mnt); 1337 calldata->path.mnt = mntget(path->mnt);
1337 calldata->path.dentry = dget(path->dentry); 1338 calldata->path.dentry = dget(path->dentry);
@@ -1404,7 +1405,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
1404 BUG_ON(nd->intent.open.flags & O_CREAT); 1405 BUG_ON(nd->intent.open.flags & O_CREAT);
1405 } 1406 }
1406 1407
1407 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); 1408 cred = rpc_lookup_cred();
1408 if (IS_ERR(cred)) 1409 if (IS_ERR(cred))
1409 return (struct dentry *)cred; 1410 return (struct dentry *)cred;
1410 parent = dentry->d_parent; 1411 parent = dentry->d_parent;
@@ -1439,7 +1440,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
1439 struct rpc_cred *cred; 1440 struct rpc_cred *cred;
1440 struct nfs4_state *state; 1441 struct nfs4_state *state;
1441 1442
1442 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); 1443 cred = rpc_lookup_cred();
1443 if (IS_ERR(cred)) 1444 if (IS_ERR(cred))
1444 return PTR_ERR(cred); 1445 return PTR_ERR(cred);
1445 state = nfs4_do_open(dir, &path, openflags, NULL, cred); 1446 state = nfs4_do_open(dir, &path, openflags, NULL, cred);
@@ -1656,7 +1657,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
1656 1657
1657 nfs_fattr_init(fattr); 1658 nfs_fattr_init(fattr);
1658 1659
1659 cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); 1660 cred = rpc_lookup_cred();
1660 if (IS_ERR(cred)) 1661 if (IS_ERR(cred))
1661 return PTR_ERR(cred); 1662 return PTR_ERR(cred);
1662 1663
@@ -1892,7 +1893,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
1892 struct rpc_cred *cred; 1893 struct rpc_cred *cred;
1893 int status = 0; 1894 int status = 0;
1894 1895
1895 cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); 1896 cred = rpc_lookup_cred();
1896 if (IS_ERR(cred)) { 1897 if (IS_ERR(cred)) {
1897 status = PTR_ERR(cred); 1898 status = PTR_ERR(cred);
1898 goto out; 1899 goto out;
@@ -2761,10 +2762,10 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
2761 case -NFS4ERR_STALE_CLIENTID: 2762 case -NFS4ERR_STALE_CLIENTID:
2762 case -NFS4ERR_STALE_STATEID: 2763 case -NFS4ERR_STALE_STATEID:
2763 case -NFS4ERR_EXPIRED: 2764 case -NFS4ERR_EXPIRED:
2764 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL); 2765 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
2765 nfs4_schedule_state_recovery(clp); 2766 nfs4_schedule_state_recovery(clp);
2766 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) 2767 if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
2767 rpc_wake_up_task(task); 2768 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
2768 task->tk_status = 0; 2769 task->tk_status = 0;
2769 return -EAGAIN; 2770 return -EAGAIN;
2770 case -NFS4ERR_DELAY: 2771 case -NFS4ERR_DELAY:
@@ -2884,7 +2885,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
2884 RPC_DISPLAY_ADDR), 2885 RPC_DISPLAY_ADDR),
2885 rpc_peeraddr2str(clp->cl_rpcclient, 2886 rpc_peeraddr2str(clp->cl_rpcclient,
2886 RPC_DISPLAY_PROTO), 2887 RPC_DISPLAY_PROTO),
2887 cred->cr_ops->cr_name, 2888 clp->cl_rpcclient->cl_auth->au_ops->au_name,
2888 clp->cl_id_uniquifier); 2889 clp->cl_id_uniquifier);
2889 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, 2890 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
2890 sizeof(setclientid.sc_netid), 2891 sizeof(setclientid.sc_netid),
@@ -3158,6 +3159,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
3158 p->arg.fh = NFS_FH(inode); 3159 p->arg.fh = NFS_FH(inode);
3159 p->arg.fl = &p->fl; 3160 p->arg.fl = &p->fl;
3160 p->arg.seqid = seqid; 3161 p->arg.seqid = seqid;
3162 p->res.seqid = seqid;
3161 p->arg.stateid = &lsp->ls_stateid; 3163 p->arg.stateid = &lsp->ls_stateid;
3162 p->lsp = lsp; 3164 p->lsp = lsp;
3163 atomic_inc(&lsp->ls_count); 3165 atomic_inc(&lsp->ls_count);
@@ -3183,7 +3185,6 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3183 3185
3184 if (RPC_ASSASSINATED(task)) 3186 if (RPC_ASSASSINATED(task))
3185 return; 3187 return;
3186 nfs_increment_lock_seqid(task->tk_status, calldata->arg.seqid);
3187 switch (task->tk_status) { 3188 switch (task->tk_status) {
3188 case 0: 3189 case 0:
3189 memcpy(calldata->lsp->ls_stateid.data, 3190 memcpy(calldata->lsp->ls_stateid.data,
@@ -3235,6 +3236,7 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
3235 .rpc_client = NFS_CLIENT(lsp->ls_state->inode), 3236 .rpc_client = NFS_CLIENT(lsp->ls_state->inode),
3236 .rpc_message = &msg, 3237 .rpc_message = &msg,
3237 .callback_ops = &nfs4_locku_ops, 3238 .callback_ops = &nfs4_locku_ops,
3239 .workqueue = nfsiod_workqueue,
3238 .flags = RPC_TASK_ASYNC, 3240 .flags = RPC_TASK_ASYNC,
3239 }; 3241 };
3240 3242
@@ -3261,6 +3263,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
3261 struct nfs4_lock_state *lsp; 3263 struct nfs4_lock_state *lsp;
3262 struct rpc_task *task; 3264 struct rpc_task *task;
3263 int status = 0; 3265 int status = 0;
3266 unsigned char fl_flags = request->fl_flags;
3264 3267
3265 status = nfs4_set_lock_state(state, request); 3268 status = nfs4_set_lock_state(state, request);
3266 /* Unlock _before_ we do the RPC call */ 3269 /* Unlock _before_ we do the RPC call */
@@ -3284,6 +3287,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
3284 status = nfs4_wait_for_completion_rpc_task(task); 3287 status = nfs4_wait_for_completion_rpc_task(task);
3285 rpc_put_task(task); 3288 rpc_put_task(task);
3286out: 3289out:
3290 request->fl_flags = fl_flags;
3287 return status; 3291 return status;
3288} 3292}
3289 3293
@@ -3320,6 +3324,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
3320 p->arg.lock_stateid = &lsp->ls_stateid; 3324 p->arg.lock_stateid = &lsp->ls_stateid;
3321 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid; 3325 p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
3322 p->arg.lock_owner.id = lsp->ls_id.id; 3326 p->arg.lock_owner.id = lsp->ls_id.id;
3327 p->res.lock_seqid = p->arg.lock_seqid;
3323 p->lsp = lsp; 3328 p->lsp = lsp;
3324 atomic_inc(&lsp->ls_count); 3329 atomic_inc(&lsp->ls_count);
3325 p->ctx = get_nfs_open_context(ctx); 3330 p->ctx = get_nfs_open_context(ctx);
@@ -3346,6 +3351,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3346 return; 3351 return;
3347 data->arg.open_stateid = &state->stateid; 3352 data->arg.open_stateid = &state->stateid;
3348 data->arg.new_lock_owner = 1; 3353 data->arg.new_lock_owner = 1;
3354 data->res.open_seqid = data->arg.open_seqid;
3349 } else 3355 } else
3350 data->arg.new_lock_owner = 0; 3356 data->arg.new_lock_owner = 0;
3351 data->timestamp = jiffies; 3357 data->timestamp = jiffies;
@@ -3363,7 +3369,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3363 if (RPC_ASSASSINATED(task)) 3369 if (RPC_ASSASSINATED(task))
3364 goto out; 3370 goto out;
3365 if (data->arg.new_lock_owner != 0) { 3371 if (data->arg.new_lock_owner != 0) {
3366 nfs_increment_open_seqid(data->rpc_status, data->arg.open_seqid);
3367 if (data->rpc_status == 0) 3372 if (data->rpc_status == 0)
3368 nfs_confirm_seqid(&data->lsp->ls_seqid, 0); 3373 nfs_confirm_seqid(&data->lsp->ls_seqid, 0);
3369 else 3374 else
@@ -3375,7 +3380,6 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3375 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; 3380 data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
3376 renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp); 3381 renew_lease(NFS_SERVER(data->ctx->path.dentry->d_inode), data->timestamp);
3377 } 3382 }
3378 nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid);
3379out: 3383out:
3380 dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status); 3384 dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status);
3381} 3385}
@@ -3419,6 +3423,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
3419 .rpc_client = NFS_CLIENT(state->inode), 3423 .rpc_client = NFS_CLIENT(state->inode),
3420 .rpc_message = &msg, 3424 .rpc_message = &msg,
3421 .callback_ops = &nfs4_lock_ops, 3425 .callback_ops = &nfs4_lock_ops,
3426 .workqueue = nfsiod_workqueue,
3422 .flags = RPC_TASK_ASYNC, 3427 .flags = RPC_TASK_ASYNC,
3423 }; 3428 };
3424 int ret; 3429 int ret;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index b962397004c1..46eb624e4f16 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -71,6 +71,29 @@ static int nfs4_init_client(struct nfs_client *clp, struct rpc_cred *cred)
71 return status; 71 return status;
72} 72}
73 73
74static struct rpc_cred *nfs4_get_machine_cred(struct nfs_client *clp)
75{
76 struct rpc_cred *cred = NULL;
77
78 spin_lock(&clp->cl_lock);
79 if (clp->cl_machine_cred != NULL)
80 cred = get_rpccred(clp->cl_machine_cred);
81 spin_unlock(&clp->cl_lock);
82 return cred;
83}
84
85static void nfs4_clear_machine_cred(struct nfs_client *clp)
86{
87 struct rpc_cred *cred;
88
89 spin_lock(&clp->cl_lock);
90 cred = clp->cl_machine_cred;
91 clp->cl_machine_cred = NULL;
92 spin_unlock(&clp->cl_lock);
93 if (cred != NULL)
94 put_rpccred(cred);
95}
96
74struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp) 97struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
75{ 98{
76 struct nfs4_state_owner *sp; 99 struct nfs4_state_owner *sp;
@@ -91,13 +114,18 @@ static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
91{ 114{
92 struct nfs4_state_owner *sp; 115 struct nfs4_state_owner *sp;
93 struct rb_node *pos; 116 struct rb_node *pos;
117 struct rpc_cred *cred;
94 118
119 cred = nfs4_get_machine_cred(clp);
120 if (cred != NULL)
121 goto out;
95 pos = rb_first(&clp->cl_state_owners); 122 pos = rb_first(&clp->cl_state_owners);
96 if (pos != NULL) { 123 if (pos != NULL) {
97 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 124 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
98 return get_rpccred(sp->so_cred); 125 cred = get_rpccred(sp->so_cred);
99 } 126 }
100 return NULL; 127out:
128 return cred;
101} 129}
102 130
103static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new, 131static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new,
@@ -292,8 +320,10 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
292 spin_unlock(&clp->cl_lock); 320 spin_unlock(&clp->cl_lock);
293 if (sp == new) 321 if (sp == new)
294 get_rpccred(cred); 322 get_rpccred(cred);
295 else 323 else {
324 rpc_destroy_wait_queue(&new->so_sequence.wait);
296 kfree(new); 325 kfree(new);
326 }
297 return sp; 327 return sp;
298} 328}
299 329
@@ -310,6 +340,7 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp)
310 return; 340 return;
311 nfs4_remove_state_owner(clp, sp); 341 nfs4_remove_state_owner(clp, sp);
312 spin_unlock(&clp->cl_lock); 342 spin_unlock(&clp->cl_lock);
343 rpc_destroy_wait_queue(&sp->so_sequence.wait);
313 put_rpccred(cred); 344 put_rpccred(cred);
314 kfree(sp); 345 kfree(sp);
315} 346}
@@ -529,6 +560,7 @@ static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
529 spin_lock(&clp->cl_lock); 560 spin_lock(&clp->cl_lock);
530 nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id); 561 nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id);
531 spin_unlock(&clp->cl_lock); 562 spin_unlock(&clp->cl_lock);
563 rpc_destroy_wait_queue(&lsp->ls_sequence.wait);
532 kfree(lsp); 564 kfree(lsp);
533} 565}
534 566
@@ -731,7 +763,7 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
731 list_add_tail(&seqid->list, &sequence->list); 763 list_add_tail(&seqid->list, &sequence->list);
732 if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid) 764 if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid)
733 goto unlock; 765 goto unlock;
734 rpc_sleep_on(&sequence->wait, task, NULL, NULL); 766 rpc_sleep_on(&sequence->wait, task, NULL);
735 status = -EAGAIN; 767 status = -EAGAIN;
736unlock: 768unlock:
737 spin_unlock(&sequence->lock); 769 spin_unlock(&sequence->lock);
@@ -920,10 +952,10 @@ restart_loop:
920 if (cred != NULL) { 952 if (cred != NULL) {
921 /* Yes there are: try to renew the old lease */ 953 /* Yes there are: try to renew the old lease */
922 status = nfs4_proc_renew(clp, cred); 954 status = nfs4_proc_renew(clp, cred);
955 put_rpccred(cred);
923 switch (status) { 956 switch (status) {
924 case 0: 957 case 0:
925 case -NFS4ERR_CB_PATH_DOWN: 958 case -NFS4ERR_CB_PATH_DOWN:
926 put_rpccred(cred);
927 goto out; 959 goto out;
928 case -NFS4ERR_STALE_CLIENTID: 960 case -NFS4ERR_STALE_CLIENTID:
929 case -NFS4ERR_LEASE_MOVED: 961 case -NFS4ERR_LEASE_MOVED:
@@ -932,14 +964,19 @@ restart_loop:
932 } else { 964 } else {
933 /* "reboot" to ensure we clear all state on the server */ 965 /* "reboot" to ensure we clear all state on the server */
934 clp->cl_boot_time = CURRENT_TIME; 966 clp->cl_boot_time = CURRENT_TIME;
935 cred = nfs4_get_setclientid_cred(clp);
936 } 967 }
937 /* We're going to have to re-establish a clientid */ 968 /* We're going to have to re-establish a clientid */
938 nfs4_state_mark_reclaim(clp); 969 nfs4_state_mark_reclaim(clp);
939 status = -ENOENT; 970 status = -ENOENT;
971 cred = nfs4_get_setclientid_cred(clp);
940 if (cred != NULL) { 972 if (cred != NULL) {
941 status = nfs4_init_client(clp, cred); 973 status = nfs4_init_client(clp, cred);
942 put_rpccred(cred); 974 put_rpccred(cred);
975 /* Handle case where the user hasn't set up machine creds */
976 if (status == -EACCES && cred == clp->cl_machine_cred) {
977 nfs4_clear_machine_cred(clp);
978 goto restart_loop;
979 }
943 } 980 }
944 if (status) 981 if (status)
945 goto out_error; 982 goto out_error;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index db1ed9c46ede..5a2d64927b35 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -110,7 +110,7 @@ static int nfs4_stat_to_errno(int);
110#define decode_savefh_maxsz (op_decode_hdr_maxsz) 110#define decode_savefh_maxsz (op_decode_hdr_maxsz)
111#define encode_restorefh_maxsz (op_encode_hdr_maxsz) 111#define encode_restorefh_maxsz (op_encode_hdr_maxsz)
112#define decode_restorefh_maxsz (op_decode_hdr_maxsz) 112#define decode_restorefh_maxsz (op_decode_hdr_maxsz)
113#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2) 113#define encode_fsinfo_maxsz (encode_getattr_maxsz)
114#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11) 114#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + 11)
115#define encode_renew_maxsz (op_encode_hdr_maxsz + 3) 115#define encode_renew_maxsz (op_encode_hdr_maxsz + 3)
116#define decode_renew_maxsz (op_decode_hdr_maxsz) 116#define decode_renew_maxsz (op_decode_hdr_maxsz)
@@ -1191,8 +1191,8 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1191 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; 1191 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1192 WRITE32(attrs[0] & readdir->bitmask[0]); 1192 WRITE32(attrs[0] & readdir->bitmask[0]);
1193 WRITE32(attrs[1] & readdir->bitmask[1]); 1193 WRITE32(attrs[1] & readdir->bitmask[1]);
1194 dprintk("%s: cookie = %Lu, verifier = 0x%x%x, bitmap = 0x%x%x\n", 1194 dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n",
1195 __FUNCTION__, 1195 __func__,
1196 (unsigned long long)readdir->cookie, 1196 (unsigned long long)readdir->cookie,
1197 ((u32 *)readdir->verifier.data)[0], 1197 ((u32 *)readdir->verifier.data)[0],
1198 ((u32 *)readdir->verifier.data)[1], 1198 ((u32 *)readdir->verifier.data)[1],
@@ -2241,7 +2241,7 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
2241 } 2241 }
2242 READ32(nfserr); 2242 READ32(nfserr);
2243 if (nfserr != NFS_OK) 2243 if (nfserr != NFS_OK)
2244 return -nfs4_stat_to_errno(nfserr); 2244 return nfs4_stat_to_errno(nfserr);
2245 return 0; 2245 return 0;
2246} 2246}
2247 2247
@@ -2291,7 +2291,7 @@ static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint3
2291 bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; 2291 bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS;
2292 } else 2292 } else
2293 bitmask[0] = bitmask[1] = 0; 2293 bitmask[0] = bitmask[1] = 0;
2294 dprintk("%s: bitmask=0x%x%x\n", __FUNCTION__, bitmask[0], bitmask[1]); 2294 dprintk("%s: bitmask=%08x:%08x\n", __func__, bitmask[0], bitmask[1]);
2295 return 0; 2295 return 0;
2296} 2296}
2297 2297
@@ -3005,6 +3005,8 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
3005 int status; 3005 int status;
3006 3006
3007 status = decode_op_hdr(xdr, OP_CLOSE); 3007 status = decode_op_hdr(xdr, OP_CLOSE);
3008 if (status != -EIO)
3009 nfs_increment_open_seqid(status, res->seqid);
3008 if (status) 3010 if (status)
3009 return status; 3011 return status;
3010 READ_BUF(NFS4_STATEID_SIZE); 3012 READ_BUF(NFS4_STATEID_SIZE);
@@ -3296,11 +3298,17 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
3296 int status; 3298 int status;
3297 3299
3298 status = decode_op_hdr(xdr, OP_LOCK); 3300 status = decode_op_hdr(xdr, OP_LOCK);
3301 if (status == -EIO)
3302 goto out;
3299 if (status == 0) { 3303 if (status == 0) {
3300 READ_BUF(NFS4_STATEID_SIZE); 3304 READ_BUF(NFS4_STATEID_SIZE);
3301 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); 3305 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3302 } else if (status == -NFS4ERR_DENIED) 3306 } else if (status == -NFS4ERR_DENIED)
3303 return decode_lock_denied(xdr, NULL); 3307 status = decode_lock_denied(xdr, NULL);
3308 if (res->open_seqid != NULL)
3309 nfs_increment_open_seqid(status, res->open_seqid);
3310 nfs_increment_lock_seqid(status, res->lock_seqid);
3311out:
3304 return status; 3312 return status;
3305} 3313}
3306 3314
@@ -3319,6 +3327,8 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
3319 int status; 3327 int status;
3320 3328
3321 status = decode_op_hdr(xdr, OP_LOCKU); 3329 status = decode_op_hdr(xdr, OP_LOCKU);
3330 if (status != -EIO)
3331 nfs_increment_lock_seqid(status, res->seqid);
3322 if (status == 0) { 3332 if (status == 0) {
3323 READ_BUF(NFS4_STATEID_SIZE); 3333 READ_BUF(NFS4_STATEID_SIZE);
3324 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); 3334 COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
@@ -3384,6 +3394,8 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
3384 int status; 3394 int status;
3385 3395
3386 status = decode_op_hdr(xdr, OP_OPEN); 3396 status = decode_op_hdr(xdr, OP_OPEN);
3397 if (status != -EIO)
3398 nfs_increment_open_seqid(status, res->seqid);
3387 if (status) 3399 if (status)
3388 return status; 3400 return status;
3389 READ_BUF(NFS4_STATEID_SIZE); 3401 READ_BUF(NFS4_STATEID_SIZE);
@@ -3416,6 +3428,8 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre
3416 int status; 3428 int status;
3417 3429
3418 status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); 3430 status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
3431 if (status != -EIO)
3432 nfs_increment_open_seqid(status, res->seqid);
3419 if (status) 3433 if (status)
3420 return status; 3434 return status;
3421 READ_BUF(NFS4_STATEID_SIZE); 3435 READ_BUF(NFS4_STATEID_SIZE);
@@ -3429,6 +3443,8 @@ static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *re
3429 int status; 3443 int status;
3430 3444
3431 status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE); 3445 status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE);
3446 if (status != -EIO)
3447 nfs_increment_open_seqid(status, res->seqid);
3432 if (status) 3448 if (status)
3433 return status; 3449 return status;
3434 READ_BUF(NFS4_STATEID_SIZE); 3450 READ_BUF(NFS4_STATEID_SIZE);
@@ -3481,7 +3497,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3481 size_t hdrlen; 3497 size_t hdrlen;
3482 u32 recvd, pglen = rcvbuf->page_len; 3498 u32 recvd, pglen = rcvbuf->page_len;
3483 __be32 *end, *entry, *p, *kaddr; 3499 __be32 *end, *entry, *p, *kaddr;
3484 unsigned int nr; 3500 unsigned int nr = 0;
3485 int status; 3501 int status;
3486 3502
3487 status = decode_op_hdr(xdr, OP_READDIR); 3503 status = decode_op_hdr(xdr, OP_READDIR);
@@ -3489,8 +3505,8 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3489 return status; 3505 return status;
3490 READ_BUF(8); 3506 READ_BUF(8);
3491 COPYMEM(readdir->verifier.data, 8); 3507 COPYMEM(readdir->verifier.data, 8);
3492 dprintk("%s: verifier = 0x%x%x\n", 3508 dprintk("%s: verifier = %08x:%08x\n",
3493 __FUNCTION__, 3509 __func__,
3494 ((u32 *)readdir->verifier.data)[0], 3510 ((u32 *)readdir->verifier.data)[0],
3495 ((u32 *)readdir->verifier.data)[1]); 3511 ((u32 *)readdir->verifier.data)[1]);
3496 3512
@@ -3505,7 +3521,12 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3505 kaddr = p = kmap_atomic(page, KM_USER0); 3521 kaddr = p = kmap_atomic(page, KM_USER0);
3506 end = p + ((pglen + readdir->pgbase) >> 2); 3522 end = p + ((pglen + readdir->pgbase) >> 2);
3507 entry = p; 3523 entry = p;
3508 for (nr = 0; *p++; nr++) { 3524
3525 /* Make sure the packet actually has a value_follows and EOF entry */
3526 if ((entry + 1) > end)
3527 goto short_pkt;
3528
3529 for (; *p++; nr++) {
3509 u32 len, attrlen, xlen; 3530 u32 len, attrlen, xlen;
3510 if (end - p < 3) 3531 if (end - p < 3)
3511 goto short_pkt; 3532 goto short_pkt;
@@ -3532,20 +3553,32 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3532 p += attrlen; /* attributes */ 3553 p += attrlen; /* attributes */
3533 entry = p; 3554 entry = p;
3534 } 3555 }
3535 if (!nr && (entry[0] != 0 || entry[1] == 0)) 3556 /*
3536 goto short_pkt; 3557 * Apparently some server sends responses that are a valid size, but
3558 * contain no entries, and have value_follows==0 and EOF==0. For
3559 * those, just set the EOF marker.
3560 */
3561 if (!nr && entry[1] == 0) {
3562 dprintk("NFS: readdir reply truncated!\n");
3563 entry[1] = 1;
3564 }
3537out: 3565out:
3538 kunmap_atomic(kaddr, KM_USER0); 3566 kunmap_atomic(kaddr, KM_USER0);
3539 return 0; 3567 return 0;
3540short_pkt: 3568short_pkt:
3569 /*
3570 * When we get a short packet there are 2 possibilities. We can
3571 * return an error, or fix up the response to look like a valid
3572 * response and return what we have so far. If there are no
3573 * entries and the packet was short, then return -EIO. If there
3574 * are valid entries in the response, return them and pretend that
3575 * the call was successful, but incomplete. The caller can retry the
3576 * readdir starting at the last cookie.
3577 */
3541 dprintk("%s: short packet at entry %d\n", __FUNCTION__, nr); 3578 dprintk("%s: short packet at entry %d\n", __FUNCTION__, nr);
3542 entry[0] = entry[1] = 0; 3579 entry[0] = entry[1] = 0;
3543 /* truncate listing ? */ 3580 if (nr)
3544 if (!nr) { 3581 goto out;
3545 dprintk("NFS: readdir reply truncated!\n");
3546 entry[1] = 1;
3547 }
3548 goto out;
3549err_unmap: 3582err_unmap:
3550 kunmap_atomic(kaddr, KM_USER0); 3583 kunmap_atomic(kaddr, KM_USER0);
3551 return -errno_NFSERR_IO; 3584 return -errno_NFSERR_IO;
@@ -3727,7 +3760,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
3727 READ_BUF(len); 3760 READ_BUF(len);
3728 return -NFSERR_CLID_INUSE; 3761 return -NFSERR_CLID_INUSE;
3729 } else 3762 } else
3730 return -nfs4_stat_to_errno(nfserr); 3763 return nfs4_stat_to_errno(nfserr);
3731 3764
3732 return 0; 3765 return 0;
3733} 3766}
@@ -4389,7 +4422,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf
4389 if (!status) 4422 if (!status)
4390 status = decode_fsinfo(&xdr, fsinfo); 4423 status = decode_fsinfo(&xdr, fsinfo);
4391 if (!status) 4424 if (!status)
4392 status = -nfs4_stat_to_errno(hdr.status); 4425 status = nfs4_stat_to_errno(hdr.status);
4393 return status; 4426 return status;
4394} 4427}
4395 4428
@@ -4479,7 +4512,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
4479 if (!status) 4512 if (!status)
4480 status = decode_setclientid(&xdr, clp); 4513 status = decode_setclientid(&xdr, clp);
4481 if (!status) 4514 if (!status)
4482 status = -nfs4_stat_to_errno(hdr.status); 4515 status = nfs4_stat_to_errno(hdr.status);
4483 return status; 4516 return status;
4484} 4517}
4485 4518
@@ -4501,7 +4534,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
4501 if (!status) 4534 if (!status)
4502 status = decode_fsinfo(&xdr, fsinfo); 4535 status = decode_fsinfo(&xdr, fsinfo);
4503 if (!status) 4536 if (!status)
4504 status = -nfs4_stat_to_errno(hdr.status); 4537 status = nfs4_stat_to_errno(hdr.status);
4505 return status; 4538 return status;
4506} 4539}
4507 4540
@@ -4611,42 +4644,42 @@ static struct {
4611 int errno; 4644 int errno;
4612} nfs_errtbl[] = { 4645} nfs_errtbl[] = {
4613 { NFS4_OK, 0 }, 4646 { NFS4_OK, 0 },
4614 { NFS4ERR_PERM, EPERM }, 4647 { NFS4ERR_PERM, -EPERM },
4615 { NFS4ERR_NOENT, ENOENT }, 4648 { NFS4ERR_NOENT, -ENOENT },
4616 { NFS4ERR_IO, errno_NFSERR_IO }, 4649 { NFS4ERR_IO, -errno_NFSERR_IO},
4617 { NFS4ERR_NXIO, ENXIO }, 4650 { NFS4ERR_NXIO, -ENXIO },
4618 { NFS4ERR_ACCESS, EACCES }, 4651 { NFS4ERR_ACCESS, -EACCES },
4619 { NFS4ERR_EXIST, EEXIST }, 4652 { NFS4ERR_EXIST, -EEXIST },
4620 { NFS4ERR_XDEV, EXDEV }, 4653 { NFS4ERR_XDEV, -EXDEV },
4621 { NFS4ERR_NOTDIR, ENOTDIR }, 4654 { NFS4ERR_NOTDIR, -ENOTDIR },
4622 { NFS4ERR_ISDIR, EISDIR }, 4655 { NFS4ERR_ISDIR, -EISDIR },
4623 { NFS4ERR_INVAL, EINVAL }, 4656 { NFS4ERR_INVAL, -EINVAL },
4624 { NFS4ERR_FBIG, EFBIG }, 4657 { NFS4ERR_FBIG, -EFBIG },
4625 { NFS4ERR_NOSPC, ENOSPC }, 4658 { NFS4ERR_NOSPC, -ENOSPC },
4626 { NFS4ERR_ROFS, EROFS }, 4659 { NFS4ERR_ROFS, -EROFS },
4627 { NFS4ERR_MLINK, EMLINK }, 4660 { NFS4ERR_MLINK, -EMLINK },
4628 { NFS4ERR_NAMETOOLONG, ENAMETOOLONG }, 4661 { NFS4ERR_NAMETOOLONG, -ENAMETOOLONG },
4629 { NFS4ERR_NOTEMPTY, ENOTEMPTY }, 4662 { NFS4ERR_NOTEMPTY, -ENOTEMPTY },
4630 { NFS4ERR_DQUOT, EDQUOT }, 4663 { NFS4ERR_DQUOT, -EDQUOT },
4631 { NFS4ERR_STALE, ESTALE }, 4664 { NFS4ERR_STALE, -ESTALE },
4632 { NFS4ERR_BADHANDLE, EBADHANDLE }, 4665 { NFS4ERR_BADHANDLE, -EBADHANDLE },
4633 { NFS4ERR_BADOWNER, EINVAL }, 4666 { NFS4ERR_BADOWNER, -EINVAL },
4634 { NFS4ERR_BADNAME, EINVAL }, 4667 { NFS4ERR_BADNAME, -EINVAL },
4635 { NFS4ERR_BAD_COOKIE, EBADCOOKIE }, 4668 { NFS4ERR_BAD_COOKIE, -EBADCOOKIE },
4636 { NFS4ERR_NOTSUPP, ENOTSUPP }, 4669 { NFS4ERR_NOTSUPP, -ENOTSUPP },
4637 { NFS4ERR_TOOSMALL, ETOOSMALL }, 4670 { NFS4ERR_TOOSMALL, -ETOOSMALL },
4638 { NFS4ERR_SERVERFAULT, ESERVERFAULT }, 4671 { NFS4ERR_SERVERFAULT, -ESERVERFAULT },
4639 { NFS4ERR_BADTYPE, EBADTYPE }, 4672 { NFS4ERR_BADTYPE, -EBADTYPE },
4640 { NFS4ERR_LOCKED, EAGAIN }, 4673 { NFS4ERR_LOCKED, -EAGAIN },
4641 { NFS4ERR_RESOURCE, EREMOTEIO }, 4674 { NFS4ERR_RESOURCE, -EREMOTEIO },
4642 { NFS4ERR_SYMLINK, ELOOP }, 4675 { NFS4ERR_SYMLINK, -ELOOP },
4643 { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP }, 4676 { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP },
4644 { NFS4ERR_DEADLOCK, EDEADLK }, 4677 { NFS4ERR_DEADLOCK, -EDEADLK },
4645 { NFS4ERR_WRONGSEC, EPERM }, /* FIXME: this needs 4678 { NFS4ERR_WRONGSEC, -EPERM }, /* FIXME: this needs
4646 * to be handled by a 4679 * to be handled by a
4647 * middle-layer. 4680 * middle-layer.
4648 */ 4681 */
4649 { -1, EIO } 4682 { -1, -EIO }
4650}; 4683};
4651 4684
4652/* 4685/*
@@ -4663,14 +4696,14 @@ nfs4_stat_to_errno(int stat)
4663 } 4696 }
4664 if (stat <= 10000 || stat > 10100) { 4697 if (stat <= 10000 || stat > 10100) {
4665 /* The server is looney tunes. */ 4698 /* The server is looney tunes. */
4666 return ESERVERFAULT; 4699 return -ESERVERFAULT;
4667 } 4700 }
4668 /* If we cannot translate the error, the recovery routines should 4701 /* If we cannot translate the error, the recovery routines should
4669 * handle it. 4702 * handle it.
4670 * Note: remaining NFSv4 error codes have values > 10000, so should 4703 * Note: remaining NFSv4 error codes have values > 10000, so should
4671 * not conflict with native Linux error codes. 4704 * not conflict with native Linux error codes.
4672 */ 4705 */
4673 return stat; 4706 return -stat;
4674} 4707}
4675 4708
4676#define PROC(proc, argtype, restype) \ 4709#define PROC(proc, argtype, restype) \
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 5a70be589bbe..16f57e0af999 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -58,22 +58,19 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
58 return p; 58 return p;
59} 59}
60 60
61static void nfs_readdata_rcu_free(struct rcu_head *head) 61static void nfs_readdata_free(struct nfs_read_data *p)
62{ 62{
63 struct nfs_read_data *p = container_of(head, struct nfs_read_data, task.u.tk_rcu);
64 if (p && (p->pagevec != &p->page_array[0])) 63 if (p && (p->pagevec != &p->page_array[0]))
65 kfree(p->pagevec); 64 kfree(p->pagevec);
66 mempool_free(p, nfs_rdata_mempool); 65 mempool_free(p, nfs_rdata_mempool);
67} 66}
68 67
69static void nfs_readdata_free(struct nfs_read_data *rdata)
70{
71 call_rcu_bh(&rdata->task.u.tk_rcu, nfs_readdata_rcu_free);
72}
73
74void nfs_readdata_release(void *data) 68void nfs_readdata_release(void *data)
75{ 69{
76 nfs_readdata_free(data); 70 struct nfs_read_data *rdata = data;
71
72 put_nfs_open_context(rdata->args.context);
73 nfs_readdata_free(rdata);
77} 74}
78 75
79static 76static
@@ -156,7 +153,7 @@ static void nfs_readpage_release(struct nfs_page *req)
156/* 153/*
157 * Set up the NFS read request struct 154 * Set up the NFS read request struct
158 */ 155 */
159static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, 156static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
160 const struct rpc_call_ops *call_ops, 157 const struct rpc_call_ops *call_ops,
161 unsigned int count, unsigned int offset) 158 unsigned int count, unsigned int offset)
162{ 159{
@@ -174,6 +171,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
174 .rpc_message = &msg, 171 .rpc_message = &msg,
175 .callback_ops = call_ops, 172 .callback_ops = call_ops,
176 .callback_data = data, 173 .callback_data = data,
174 .workqueue = nfsiod_workqueue,
177 .flags = RPC_TASK_ASYNC | swap_flags, 175 .flags = RPC_TASK_ASYNC | swap_flags,
178 }; 176 };
179 177
@@ -186,7 +184,7 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
186 data->args.pgbase = req->wb_pgbase + offset; 184 data->args.pgbase = req->wb_pgbase + offset;
187 data->args.pages = data->pagevec; 185 data->args.pages = data->pagevec;
188 data->args.count = count; 186 data->args.count = count;
189 data->args.context = req->wb_context; 187 data->args.context = get_nfs_open_context(req->wb_context);
190 188
191 data->res.fattr = &data->fattr; 189 data->res.fattr = &data->fattr;
192 data->res.count = count; 190 data->res.count = count;
@@ -204,8 +202,10 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
204 (unsigned long long)data->args.offset); 202 (unsigned long long)data->args.offset);
205 203
206 task = rpc_run_task(&task_setup_data); 204 task = rpc_run_task(&task_setup_data);
207 if (!IS_ERR(task)) 205 if (IS_ERR(task))
208 rpc_put_task(task); 206 return PTR_ERR(task);
207 rpc_put_task(task);
208 return 0;
209} 209}
210 210
211static void 211static void
@@ -242,6 +242,7 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
242 size_t rsize = NFS_SERVER(inode)->rsize, nbytes; 242 size_t rsize = NFS_SERVER(inode)->rsize, nbytes;
243 unsigned int offset; 243 unsigned int offset;
244 int requests = 0; 244 int requests = 0;
245 int ret = 0;
245 LIST_HEAD(list); 246 LIST_HEAD(list);
246 247
247 nfs_list_remove_request(req); 248 nfs_list_remove_request(req);
@@ -253,7 +254,6 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
253 data = nfs_readdata_alloc(1); 254 data = nfs_readdata_alloc(1);
254 if (!data) 255 if (!data)
255 goto out_bad; 256 goto out_bad;
256 INIT_LIST_HEAD(&data->pages);
257 list_add(&data->pages, &list); 257 list_add(&data->pages, &list);
258 requests++; 258 requests++;
259 nbytes -= len; 259 nbytes -= len;
@@ -264,6 +264,8 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
264 offset = 0; 264 offset = 0;
265 nbytes = count; 265 nbytes = count;
266 do { 266 do {
267 int ret2;
268
267 data = list_entry(list.next, struct nfs_read_data, pages); 269 data = list_entry(list.next, struct nfs_read_data, pages);
268 list_del_init(&data->pages); 270 list_del_init(&data->pages);
269 271
@@ -271,13 +273,15 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
271 273
272 if (nbytes < rsize) 274 if (nbytes < rsize)
273 rsize = nbytes; 275 rsize = nbytes;
274 nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, 276 ret2 = nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
275 rsize, offset); 277 rsize, offset);
278 if (ret == 0)
279 ret = ret2;
276 offset += rsize; 280 offset += rsize;
277 nbytes -= rsize; 281 nbytes -= rsize;
278 } while (nbytes != 0); 282 } while (nbytes != 0);
279 283
280 return 0; 284 return ret;
281 285
282out_bad: 286out_bad:
283 while (!list_empty(&list)) { 287 while (!list_empty(&list)) {
@@ -295,12 +299,12 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
295 struct nfs_page *req; 299 struct nfs_page *req;
296 struct page **pages; 300 struct page **pages;
297 struct nfs_read_data *data; 301 struct nfs_read_data *data;
302 int ret = -ENOMEM;
298 303
299 data = nfs_readdata_alloc(npages); 304 data = nfs_readdata_alloc(npages);
300 if (!data) 305 if (!data)
301 goto out_bad; 306 goto out_bad;
302 307
303 INIT_LIST_HEAD(&data->pages);
304 pages = data->pagevec; 308 pages = data->pagevec;
305 while (!list_empty(head)) { 309 while (!list_empty(head)) {
306 req = nfs_list_entry(head->next); 310 req = nfs_list_entry(head->next);
@@ -311,11 +315,10 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
311 } 315 }
312 req = nfs_list_entry(data->pages.next); 316 req = nfs_list_entry(data->pages.next);
313 317
314 nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0); 318 return nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0);
315 return 0;
316out_bad: 319out_bad:
317 nfs_async_read_error(head); 320 nfs_async_read_error(head);
318 return -ENOMEM; 321 return ret;
319} 322}
320 323
321/* 324/*
@@ -342,26 +345,25 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data)
342 return 0; 345 return 0;
343} 346}
344 347
345static int nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data) 348static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data)
346{ 349{
347 struct nfs_readargs *argp = &data->args; 350 struct nfs_readargs *argp = &data->args;
348 struct nfs_readres *resp = &data->res; 351 struct nfs_readres *resp = &data->res;
349 352
350 if (resp->eof || resp->count == argp->count) 353 if (resp->eof || resp->count == argp->count)
351 return 0; 354 return;
352 355
353 /* This is a short read! */ 356 /* This is a short read! */
354 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); 357 nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
355 /* Has the server at least made some progress? */ 358 /* Has the server at least made some progress? */
356 if (resp->count == 0) 359 if (resp->count == 0)
357 return 0; 360 return;
358 361
359 /* Yes, so retry the read at the end of the data */ 362 /* Yes, so retry the read at the end of the data */
360 argp->offset += resp->count; 363 argp->offset += resp->count;
361 argp->pgbase += resp->count; 364 argp->pgbase += resp->count;
362 argp->count -= resp->count; 365 argp->count -= resp->count;
363 rpc_restart_call(task); 366 rpc_restart_call(task);
364 return -EAGAIN;
365} 367}
366 368
367/* 369/*
@@ -370,29 +372,37 @@ static int nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data)
370static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata) 372static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata)
371{ 373{
372 struct nfs_read_data *data = calldata; 374 struct nfs_read_data *data = calldata;
373 struct nfs_page *req = data->req;
374 struct page *page = req->wb_page;
375 375
376 if (nfs_readpage_result(task, data) != 0) 376 if (nfs_readpage_result(task, data) != 0)
377 return; 377 return;
378 if (task->tk_status < 0)
379 return;
378 380
379 if (likely(task->tk_status >= 0)) { 381 nfs_readpage_truncate_uninitialised_page(data);
380 nfs_readpage_truncate_uninitialised_page(data); 382 nfs_readpage_retry(task, data);
381 if (nfs_readpage_retry(task, data) != 0) 383}
382 return; 384
383 } 385static void nfs_readpage_release_partial(void *calldata)
384 if (unlikely(task->tk_status < 0)) 386{
387 struct nfs_read_data *data = calldata;
388 struct nfs_page *req = data->req;
389 struct page *page = req->wb_page;
390 int status = data->task.tk_status;
391
392 if (status < 0)
385 SetPageError(page); 393 SetPageError(page);
394
386 if (atomic_dec_and_test(&req->wb_complete)) { 395 if (atomic_dec_and_test(&req->wb_complete)) {
387 if (!PageError(page)) 396 if (!PageError(page))
388 SetPageUptodate(page); 397 SetPageUptodate(page);
389 nfs_readpage_release(req); 398 nfs_readpage_release(req);
390 } 399 }
400 nfs_readdata_release(calldata);
391} 401}
392 402
393static const struct rpc_call_ops nfs_read_partial_ops = { 403static const struct rpc_call_ops nfs_read_partial_ops = {
394 .rpc_call_done = nfs_readpage_result_partial, 404 .rpc_call_done = nfs_readpage_result_partial,
395 .rpc_release = nfs_readdata_release, 405 .rpc_release = nfs_readpage_release_partial,
396}; 406};
397 407
398static void nfs_readpage_set_pages_uptodate(struct nfs_read_data *data) 408static void nfs_readpage_set_pages_uptodate(struct nfs_read_data *data)
@@ -427,29 +437,35 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata)
427 437
428 if (nfs_readpage_result(task, data) != 0) 438 if (nfs_readpage_result(task, data) != 0)
429 return; 439 return;
440 if (task->tk_status < 0)
441 return;
430 /* 442 /*
431 * Note: nfs_readpage_retry may change the values of 443 * Note: nfs_readpage_retry may change the values of
432 * data->args. In the multi-page case, we therefore need 444 * data->args. In the multi-page case, we therefore need
433 * to ensure that we call nfs_readpage_set_pages_uptodate() 445 * to ensure that we call nfs_readpage_set_pages_uptodate()
434 * first. 446 * first.
435 */ 447 */
436 if (likely(task->tk_status >= 0)) { 448 nfs_readpage_truncate_uninitialised_page(data);
437 nfs_readpage_truncate_uninitialised_page(data); 449 nfs_readpage_set_pages_uptodate(data);
438 nfs_readpage_set_pages_uptodate(data); 450 nfs_readpage_retry(task, data);
439 if (nfs_readpage_retry(task, data) != 0) 451}
440 return; 452
441 } 453static void nfs_readpage_release_full(void *calldata)
454{
455 struct nfs_read_data *data = calldata;
456
442 while (!list_empty(&data->pages)) { 457 while (!list_empty(&data->pages)) {
443 struct nfs_page *req = nfs_list_entry(data->pages.next); 458 struct nfs_page *req = nfs_list_entry(data->pages.next);
444 459
445 nfs_list_remove_request(req); 460 nfs_list_remove_request(req);
446 nfs_readpage_release(req); 461 nfs_readpage_release(req);
447 } 462 }
463 nfs_readdata_release(calldata);
448} 464}
449 465
450static const struct rpc_call_ops nfs_read_full_ops = { 466static const struct rpc_call_ops nfs_read_full_ops = {
451 .rpc_call_done = nfs_readpage_result_full, 467 .rpc_call_done = nfs_readpage_result_full,
452 .rpc_release = nfs_readdata_release, 468 .rpc_release = nfs_readpage_release_full,
453}; 469};
454 470
455/* 471/*
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f9219024f31a..20a1cb1810fe 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -441,10 +441,52 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
441 return sec_flavours[i].str; 441 return sec_flavours[i].str;
442} 442}
443 443
444static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
445 int showdefaults)
446{
447 struct sockaddr *sap = (struct sockaddr *)&nfss->mountd_address;
448
449 switch (sap->sa_family) {
450 case AF_INET: {
451 struct sockaddr_in *sin = (struct sockaddr_in *)sap;
452 seq_printf(m, ",mountaddr=" NIPQUAD_FMT,
453 NIPQUAD(sin->sin_addr.s_addr));
454 break;
455 }
456 case AF_INET6: {
457 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
458 seq_printf(m, ",mountaddr=" NIP6_FMT,
459 NIP6(sin6->sin6_addr));
460 break;
461 }
462 default:
463 if (showdefaults)
464 seq_printf(m, ",mountaddr=unspecified");
465 }
466
467 if (nfss->mountd_version || showdefaults)
468 seq_printf(m, ",mountvers=%u", nfss->mountd_version);
469 if (nfss->mountd_port || showdefaults)
470 seq_printf(m, ",mountport=%u", nfss->mountd_port);
471
472 switch (nfss->mountd_protocol) {
473 case IPPROTO_UDP:
474 seq_printf(m, ",mountproto=udp");
475 break;
476 case IPPROTO_TCP:
477 seq_printf(m, ",mountproto=tcp");
478 break;
479 default:
480 if (showdefaults)
481 seq_printf(m, ",mountproto=auto");
482 }
483}
484
444/* 485/*
445 * Describe the mount options in force on this server representation 486 * Describe the mount options in force on this server representation
446 */ 487 */
447static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults) 488static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
489 int showdefaults)
448{ 490{
449 static const struct proc_nfs_info { 491 static const struct proc_nfs_info {
450 int flag; 492 int flag;
@@ -452,6 +494,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
452 const char *nostr; 494 const char *nostr;
453 } nfs_info[] = { 495 } nfs_info[] = {
454 { NFS_MOUNT_SOFT, ",soft", ",hard" }, 496 { NFS_MOUNT_SOFT, ",soft", ",hard" },
497 { NFS_MOUNT_INTR, ",intr", ",nointr" },
498 { NFS_MOUNT_POSIX, ",posix", "" },
455 { NFS_MOUNT_NOCTO, ",nocto", "" }, 499 { NFS_MOUNT_NOCTO, ",nocto", "" },
456 { NFS_MOUNT_NOAC, ",noac", "" }, 500 { NFS_MOUNT_NOAC, ",noac", "" },
457 { NFS_MOUNT_NONLM, ",nolock", "" }, 501 { NFS_MOUNT_NONLM, ",nolock", "" },
@@ -462,18 +506,22 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
462 }; 506 };
463 const struct proc_nfs_info *nfs_infop; 507 const struct proc_nfs_info *nfs_infop;
464 struct nfs_client *clp = nfss->nfs_client; 508 struct nfs_client *clp = nfss->nfs_client;
465 509 u32 version = clp->rpc_ops->version;
466 seq_printf(m, ",vers=%d", clp->rpc_ops->version); 510
467 seq_printf(m, ",rsize=%d", nfss->rsize); 511 seq_printf(m, ",vers=%u", version);
468 seq_printf(m, ",wsize=%d", nfss->wsize); 512 seq_printf(m, ",rsize=%u", nfss->rsize);
513 seq_printf(m, ",wsize=%u", nfss->wsize);
514 if (nfss->bsize != 0)
515 seq_printf(m, ",bsize=%u", nfss->bsize);
516 seq_printf(m, ",namlen=%u", nfss->namelen);
469 if (nfss->acregmin != 3*HZ || showdefaults) 517 if (nfss->acregmin != 3*HZ || showdefaults)
470 seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ); 518 seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ);
471 if (nfss->acregmax != 60*HZ || showdefaults) 519 if (nfss->acregmax != 60*HZ || showdefaults)
472 seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ); 520 seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ);
473 if (nfss->acdirmin != 30*HZ || showdefaults) 521 if (nfss->acdirmin != 30*HZ || showdefaults)
474 seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ); 522 seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ);
475 if (nfss->acdirmax != 60*HZ || showdefaults) 523 if (nfss->acdirmax != 60*HZ || showdefaults)
476 seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ); 524 seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ);
477 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { 525 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
478 if (nfss->flags & nfs_infop->flag) 526 if (nfss->flags & nfs_infop->flag)
479 seq_puts(m, nfs_infop->str); 527 seq_puts(m, nfs_infop->str);
@@ -482,9 +530,24 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
482 } 530 }
483 seq_printf(m, ",proto=%s", 531 seq_printf(m, ",proto=%s",
484 rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); 532 rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO));
533 if (version == 4) {
534 if (nfss->port != NFS_PORT)
535 seq_printf(m, ",port=%u", nfss->port);
536 } else
537 if (nfss->port)
538 seq_printf(m, ",port=%u", nfss->port);
539
485 seq_printf(m, ",timeo=%lu", 10U * nfss->client->cl_timeout->to_initval / HZ); 540 seq_printf(m, ",timeo=%lu", 10U * nfss->client->cl_timeout->to_initval / HZ);
486 seq_printf(m, ",retrans=%u", nfss->client->cl_timeout->to_retries); 541 seq_printf(m, ",retrans=%u", nfss->client->cl_timeout->to_retries);
487 seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); 542 seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
543
544 if (version != 4)
545 nfs_show_mountd_options(m, nfss, showdefaults);
546
547#ifdef CONFIG_NFS_V4
548 if (clp->rpc_ops->version == 4)
549 seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
550#endif
488} 551}
489 552
490/* 553/*
@@ -529,10 +592,10 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
529 592
530 seq_printf(m, "\n\tcaps:\t"); 593 seq_printf(m, "\n\tcaps:\t");
531 seq_printf(m, "caps=0x%x", nfss->caps); 594 seq_printf(m, "caps=0x%x", nfss->caps);
532 seq_printf(m, ",wtmult=%d", nfss->wtmult); 595 seq_printf(m, ",wtmult=%u", nfss->wtmult);
533 seq_printf(m, ",dtsize=%d", nfss->dtsize); 596 seq_printf(m, ",dtsize=%u", nfss->dtsize);
534 seq_printf(m, ",bsize=%d", nfss->bsize); 597 seq_printf(m, ",bsize=%u", nfss->bsize);
535 seq_printf(m, ",namelen=%d", nfss->namelen); 598 seq_printf(m, ",namlen=%u", nfss->namelen);
536 599
537#ifdef CONFIG_NFS_V4 600#ifdef CONFIG_NFS_V4
538 if (nfss->nfs_client->rpc_ops->version == 4) { 601 if (nfss->nfs_client->rpc_ops->version == 4) {
@@ -546,9 +609,9 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
546 /* 609 /*
547 * Display security flavor in effect for this mount 610 * Display security flavor in effect for this mount
548 */ 611 */
549 seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor); 612 seq_printf(m, "\n\tsec:\tflavor=%u", auth->au_ops->au_flavor);
550 if (auth->au_flavor) 613 if (auth->au_flavor)
551 seq_printf(m, ",pseudoflavor=%d", auth->au_flavor); 614 seq_printf(m, ",pseudoflavor=%u", auth->au_flavor);
552 615
553 /* 616 /*
554 * Display superblock I/O counters 617 * Display superblock I/O counters
@@ -683,7 +746,6 @@ static int nfs_parse_mount_options(char *raw,
683 struct nfs_parsed_mount_data *mnt) 746 struct nfs_parsed_mount_data *mnt)
684{ 747{
685 char *p, *string, *secdata; 748 char *p, *string, *secdata;
686 unsigned short port = 0;
687 int rc; 749 int rc;
688 750
689 if (!raw) { 751 if (!raw) {
@@ -798,7 +860,7 @@ static int nfs_parse_mount_options(char *raw,
798 return 0; 860 return 0;
799 if (option < 0 || option > 65535) 861 if (option < 0 || option > 65535)
800 return 0; 862 return 0;
801 port = option; 863 mnt->nfs_server.port = option;
802 break; 864 break;
803 case Opt_rsize: 865 case Opt_rsize:
804 if (match_int(args, &mnt->rsize)) 866 if (match_int(args, &mnt->rsize))
@@ -1048,7 +1110,8 @@ static int nfs_parse_mount_options(char *raw,
1048 } 1110 }
1049 } 1111 }
1050 1112
1051 nfs_set_port((struct sockaddr *)&mnt->nfs_server.address, port); 1113 nfs_set_port((struct sockaddr *)&mnt->nfs_server.address,
1114 mnt->nfs_server.port);
1052 1115
1053 return 1; 1116 return 1;
1054 1117
@@ -1169,7 +1232,9 @@ static int nfs_validate_mount_data(void *options,
1169 args->acregmax = 60; 1232 args->acregmax = 60;
1170 args->acdirmin = 30; 1233 args->acdirmin = 30;
1171 args->acdirmax = 60; 1234 args->acdirmax = 60;
1235 args->mount_server.port = 0; /* autobind unless user sets port */
1172 args->mount_server.protocol = XPRT_TRANSPORT_UDP; 1236 args->mount_server.protocol = XPRT_TRANSPORT_UDP;
1237 args->nfs_server.port = 0; /* autobind unless user sets port */
1173 args->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1238 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1174 1239
1175 switch (data->version) { 1240 switch (data->version) {
@@ -1208,7 +1273,6 @@ static int nfs_validate_mount_data(void *options,
1208 args->flags = data->flags; 1273 args->flags = data->flags;
1209 args->rsize = data->rsize; 1274 args->rsize = data->rsize;
1210 args->wsize = data->wsize; 1275 args->wsize = data->wsize;
1211 args->flags = data->flags;
1212 args->timeo = data->timeo; 1276 args->timeo = data->timeo;
1213 args->retrans = data->retrans; 1277 args->retrans = data->retrans;
1214 args->acregmin = data->acregmin; 1278 args->acregmin = data->acregmin;
@@ -1230,6 +1294,8 @@ static int nfs_validate_mount_data(void *options,
1230 args->namlen = data->namlen; 1294 args->namlen = data->namlen;
1231 args->bsize = data->bsize; 1295 args->bsize = data->bsize;
1232 args->auth_flavors[0] = data->pseudoflavor; 1296 args->auth_flavors[0] = data->pseudoflavor;
1297 if (!args->nfs_server.hostname)
1298 goto out_nomem;
1233 1299
1234 /* 1300 /*
1235 * The legacy version 6 binary mount data from userspace has a 1301 * The legacy version 6 binary mount data from userspace has a
@@ -1276,6 +1342,8 @@ static int nfs_validate_mount_data(void *options,
1276 len = c - dev_name; 1342 len = c - dev_name;
1277 /* N.B. caller will free nfs_server.hostname in all cases */ 1343 /* N.B. caller will free nfs_server.hostname in all cases */
1278 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); 1344 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
1345 if (!args->nfs_server.hostname)
1346 goto out_nomem;
1279 1347
1280 c++; 1348 c++;
1281 if (strlen(c) > NFS_MAXPATHLEN) 1349 if (strlen(c) > NFS_MAXPATHLEN)
@@ -1319,6 +1387,10 @@ out_v3_not_compiled:
1319 return -EPROTONOSUPPORT; 1387 return -EPROTONOSUPPORT;
1320#endif /* !CONFIG_NFS_V3 */ 1388#endif /* !CONFIG_NFS_V3 */
1321 1389
1390out_nomem:
1391 dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
1392 return -ENOMEM;
1393
1322out_no_address: 1394out_no_address:
1323 dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); 1395 dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
1324 return -EINVAL; 1396 return -EINVAL;
@@ -1706,28 +1778,6 @@ static void nfs4_fill_super(struct super_block *sb)
1706} 1778}
1707 1779
1708/* 1780/*
1709 * If the user didn't specify a port, set the port number to
1710 * the NFS version 4 default port.
1711 */
1712static void nfs4_default_port(struct sockaddr *sap)
1713{
1714 switch (sap->sa_family) {
1715 case AF_INET: {
1716 struct sockaddr_in *ap = (struct sockaddr_in *)sap;
1717 if (ap->sin_port == 0)
1718 ap->sin_port = htons(NFS_PORT);
1719 break;
1720 }
1721 case AF_INET6: {
1722 struct sockaddr_in6 *ap = (struct sockaddr_in6 *)sap;
1723 if (ap->sin6_port == 0)
1724 ap->sin6_port = htons(NFS_PORT);
1725 break;
1726 }
1727 }
1728}
1729
1730/*
1731 * Validate NFSv4 mount options 1781 * Validate NFSv4 mount options
1732 */ 1782 */
1733static int nfs4_validate_mount_data(void *options, 1783static int nfs4_validate_mount_data(void *options,
@@ -1751,6 +1801,7 @@ static int nfs4_validate_mount_data(void *options,
1751 args->acregmax = 60; 1801 args->acregmax = 60;
1752 args->acdirmin = 30; 1802 args->acdirmin = 30;
1753 args->acdirmax = 60; 1803 args->acdirmax = 60;
1804 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
1754 args->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1805 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1755 1806
1756 switch (data->version) { 1807 switch (data->version) {
@@ -1767,9 +1818,6 @@ static int nfs4_validate_mount_data(void *options,
1767 &args->nfs_server.address)) 1818 &args->nfs_server.address))
1768 goto out_no_address; 1819 goto out_no_address;
1769 1820
1770 nfs4_default_port((struct sockaddr *)
1771 &args->nfs_server.address);
1772
1773 switch (data->auth_flavourlen) { 1821 switch (data->auth_flavourlen) {
1774 case 0: 1822 case 0:
1775 args->auth_flavors[0] = RPC_AUTH_UNIX; 1823 args->auth_flavors[0] = RPC_AUTH_UNIX;
@@ -1827,9 +1875,6 @@ static int nfs4_validate_mount_data(void *options,
1827 &args->nfs_server.address)) 1875 &args->nfs_server.address))
1828 return -EINVAL; 1876 return -EINVAL;
1829 1877
1830 nfs4_default_port((struct sockaddr *)
1831 &args->nfs_server.address);
1832
1833 switch (args->auth_flavor_len) { 1878 switch (args->auth_flavor_len) {
1834 case 0: 1879 case 0:
1835 args->auth_flavors[0] = RPC_AUTH_UNIX; 1880 args->auth_flavors[0] = RPC_AUTH_UNIX;
@@ -1852,12 +1897,16 @@ static int nfs4_validate_mount_data(void *options,
1852 return -ENAMETOOLONG; 1897 return -ENAMETOOLONG;
1853 /* N.B. caller will free nfs_server.hostname in all cases */ 1898 /* N.B. caller will free nfs_server.hostname in all cases */
1854 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); 1899 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
1900 if (!args->nfs_server.hostname)
1901 goto out_nomem;
1855 1902
1856 c++; /* step over the ':' */ 1903 c++; /* step over the ':' */
1857 len = strlen(c); 1904 len = strlen(c);
1858 if (len > NFS4_MAXPATHLEN) 1905 if (len > NFS4_MAXPATHLEN)
1859 return -ENAMETOOLONG; 1906 return -ENAMETOOLONG;
1860 args->nfs_server.export_path = kstrndup(c, len, GFP_KERNEL); 1907 args->nfs_server.export_path = kstrndup(c, len, GFP_KERNEL);
1908 if (!args->nfs_server.export_path)
1909 goto out_nomem;
1861 1910
1862 dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path); 1911 dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path);
1863 1912
@@ -1879,6 +1928,10 @@ out_inval_auth:
1879 data->auth_flavourlen); 1928 data->auth_flavourlen);
1880 return -EINVAL; 1929 return -EINVAL;
1881 1930
1931out_nomem:
1932 dfprintk(MOUNT, "NFS4: not enough memory to handle mount options\n");
1933 return -ENOMEM;
1934
1882out_no_address: 1935out_no_address:
1883 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 1936 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
1884 return -EINVAL; 1937 return -EINVAL;
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 757415363422..3adf8b266461 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -234,7 +234,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry)
234 if (data == NULL) 234 if (data == NULL)
235 goto out; 235 goto out;
236 236
237 data->cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0); 237 data->cred = rpc_lookup_cred();
238 if (IS_ERR(data->cred)) { 238 if (IS_ERR(data->cred)) {
239 status = PTR_ERR(data->cred); 239 status = PTR_ERR(data->cred);
240 goto out_free; 240 goto out_free;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index bed63416a55b..1ade11d1ba07 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -48,7 +48,7 @@ static struct kmem_cache *nfs_wdata_cachep;
48static mempool_t *nfs_wdata_mempool; 48static mempool_t *nfs_wdata_mempool;
49static mempool_t *nfs_commit_mempool; 49static mempool_t *nfs_commit_mempool;
50 50
51struct nfs_write_data *nfs_commit_alloc(void) 51struct nfs_write_data *nfs_commitdata_alloc(void)
52{ 52{
53 struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); 53 struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS);
54 54
@@ -59,19 +59,13 @@ struct nfs_write_data *nfs_commit_alloc(void)
59 return p; 59 return p;
60} 60}
61 61
62static void nfs_commit_rcu_free(struct rcu_head *head) 62void nfs_commit_free(struct nfs_write_data *p)
63{ 63{
64 struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu);
65 if (p && (p->pagevec != &p->page_array[0])) 64 if (p && (p->pagevec != &p->page_array[0]))
66 kfree(p->pagevec); 65 kfree(p->pagevec);
67 mempool_free(p, nfs_commit_mempool); 66 mempool_free(p, nfs_commit_mempool);
68} 67}
69 68
70void nfs_commit_free(struct nfs_write_data *wdata)
71{
72 call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free);
73}
74
75struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) 69struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
76{ 70{
77 struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); 71 struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS);
@@ -93,21 +87,18 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
93 return p; 87 return p;
94} 88}
95 89
96static void nfs_writedata_rcu_free(struct rcu_head *head) 90static void nfs_writedata_free(struct nfs_write_data *p)
97{ 91{
98 struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu);
99 if (p && (p->pagevec != &p->page_array[0])) 92 if (p && (p->pagevec != &p->page_array[0]))
100 kfree(p->pagevec); 93 kfree(p->pagevec);
101 mempool_free(p, nfs_wdata_mempool); 94 mempool_free(p, nfs_wdata_mempool);
102} 95}
103 96
104static void nfs_writedata_free(struct nfs_write_data *wdata) 97void nfs_writedata_release(void *data)
105{ 98{
106 call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free); 99 struct nfs_write_data *wdata = data;
107}
108 100
109void nfs_writedata_release(void *wdata) 101 put_nfs_open_context(wdata->args.context);
110{
111 nfs_writedata_free(wdata); 102 nfs_writedata_free(wdata);
112} 103}
113 104
@@ -291,8 +282,6 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
291 spin_unlock(&inode->i_lock); 282 spin_unlock(&inode->i_lock);
292 if (!nfs_pageio_add_request(pgio, req)) { 283 if (!nfs_pageio_add_request(pgio, req)) {
293 nfs_redirty_request(req); 284 nfs_redirty_request(req);
294 nfs_end_page_writeback(page);
295 nfs_clear_page_tag_locked(req);
296 return pgio->pg_error; 285 return pgio->pg_error;
297 } 286 }
298 return 0; 287 return 0;
@@ -366,15 +355,13 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
366/* 355/*
367 * Insert a write request into an inode 356 * Insert a write request into an inode
368 */ 357 */
369static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) 358static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
370{ 359{
371 struct nfs_inode *nfsi = NFS_I(inode); 360 struct nfs_inode *nfsi = NFS_I(inode);
372 int error; 361 int error;
373 362
374 error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req); 363 error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req);
375 BUG_ON(error == -EEXIST); 364 BUG_ON(error);
376 if (error)
377 return error;
378 if (!nfsi->npages) { 365 if (!nfsi->npages) {
379 igrab(inode); 366 igrab(inode);
380 if (nfs_have_delegation(inode, FMODE_WRITE)) 367 if (nfs_have_delegation(inode, FMODE_WRITE))
@@ -384,8 +371,8 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
384 set_page_private(req->wb_page, (unsigned long)req); 371 set_page_private(req->wb_page, (unsigned long)req);
385 nfsi->npages++; 372 nfsi->npages++;
386 kref_get(&req->wb_kref); 373 kref_get(&req->wb_kref);
387 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); 374 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index,
388 return 0; 375 NFS_PAGE_TAG_LOCKED);
389} 376}
390 377
391/* 378/*
@@ -413,7 +400,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
413} 400}
414 401
415static void 402static void
416nfs_redirty_request(struct nfs_page *req) 403nfs_mark_request_dirty(struct nfs_page *req)
417{ 404{
418 __set_page_dirty_nobuffers(req->wb_page); 405 __set_page_dirty_nobuffers(req->wb_page);
419} 406}
@@ -467,7 +454,7 @@ int nfs_reschedule_unstable_write(struct nfs_page *req)
467 return 1; 454 return 1;
468 } 455 }
469 if (test_and_clear_bit(PG_NEED_RESCHED, &req->wb_flags)) { 456 if (test_and_clear_bit(PG_NEED_RESCHED, &req->wb_flags)) {
470 nfs_redirty_request(req); 457 nfs_mark_request_dirty(req);
471 return 1; 458 return 1;
472 } 459 }
473 return 0; 460 return 0;
@@ -597,6 +584,13 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
597 /* Loop over all inode entries and see if we find 584 /* Loop over all inode entries and see if we find
598 * A request for the page we wish to update 585 * A request for the page we wish to update
599 */ 586 */
587 if (new) {
588 if (radix_tree_preload(GFP_NOFS)) {
589 nfs_release_request(new);
590 return ERR_PTR(-ENOMEM);
591 }
592 }
593
600 spin_lock(&inode->i_lock); 594 spin_lock(&inode->i_lock);
601 req = nfs_page_find_request_locked(page); 595 req = nfs_page_find_request_locked(page);
602 if (req) { 596 if (req) {
@@ -607,28 +601,27 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
607 error = nfs_wait_on_request(req); 601 error = nfs_wait_on_request(req);
608 nfs_release_request(req); 602 nfs_release_request(req);
609 if (error < 0) { 603 if (error < 0) {
610 if (new) 604 if (new) {
605 radix_tree_preload_end();
611 nfs_release_request(new); 606 nfs_release_request(new);
607 }
612 return ERR_PTR(error); 608 return ERR_PTR(error);
613 } 609 }
614 continue; 610 continue;
615 } 611 }
616 spin_unlock(&inode->i_lock); 612 spin_unlock(&inode->i_lock);
617 if (new) 613 if (new) {
614 radix_tree_preload_end();
618 nfs_release_request(new); 615 nfs_release_request(new);
616 }
619 break; 617 break;
620 } 618 }
621 619
622 if (new) { 620 if (new) {
623 int error;
624 nfs_lock_request_dontget(new); 621 nfs_lock_request_dontget(new);
625 error = nfs_inode_add_request(inode, new); 622 nfs_inode_add_request(inode, new);
626 if (error) {
627 spin_unlock(&inode->i_lock);
628 nfs_unlock_request(new);
629 return ERR_PTR(error);
630 }
631 spin_unlock(&inode->i_lock); 623 spin_unlock(&inode->i_lock);
624 radix_tree_preload_end();
632 req = new; 625 req = new;
633 goto zero_page; 626 goto zero_page;
634 } 627 }
@@ -785,7 +778,7 @@ static int flush_task_priority(int how)
785/* 778/*
786 * Set up the argument/result storage required for the RPC call. 779 * Set up the argument/result storage required for the RPC call.
787 */ 780 */
788static void nfs_write_rpcsetup(struct nfs_page *req, 781static int nfs_write_rpcsetup(struct nfs_page *req,
789 struct nfs_write_data *data, 782 struct nfs_write_data *data,
790 const struct rpc_call_ops *call_ops, 783 const struct rpc_call_ops *call_ops,
791 unsigned int count, unsigned int offset, 784 unsigned int count, unsigned int offset,
@@ -806,6 +799,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
806 .rpc_message = &msg, 799 .rpc_message = &msg,
807 .callback_ops = call_ops, 800 .callback_ops = call_ops,
808 .callback_data = data, 801 .callback_data = data,
802 .workqueue = nfsiod_workqueue,
809 .flags = flags, 803 .flags = flags,
810 .priority = priority, 804 .priority = priority,
811 }; 805 };
@@ -822,7 +816,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
822 data->args.pgbase = req->wb_pgbase + offset; 816 data->args.pgbase = req->wb_pgbase + offset;
823 data->args.pages = data->pagevec; 817 data->args.pages = data->pagevec;
824 data->args.count = count; 818 data->args.count = count;
825 data->args.context = req->wb_context; 819 data->args.context = get_nfs_open_context(req->wb_context);
826 data->args.stable = NFS_UNSTABLE; 820 data->args.stable = NFS_UNSTABLE;
827 if (how & FLUSH_STABLE) { 821 if (how & FLUSH_STABLE) {
828 data->args.stable = NFS_DATA_SYNC; 822 data->args.stable = NFS_DATA_SYNC;
@@ -847,8 +841,21 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
847 (unsigned long long)data->args.offset); 841 (unsigned long long)data->args.offset);
848 842
849 task = rpc_run_task(&task_setup_data); 843 task = rpc_run_task(&task_setup_data);
850 if (!IS_ERR(task)) 844 if (IS_ERR(task))
851 rpc_put_task(task); 845 return PTR_ERR(task);
846 rpc_put_task(task);
847 return 0;
848}
849
850/* If a nfs_flush_* function fails, it should remove reqs from @head and
851 * call this on each, which will prepare them to be retried on next
852 * writeback using standard nfs.
853 */
854static void nfs_redirty_request(struct nfs_page *req)
855{
856 nfs_mark_request_dirty(req);
857 nfs_end_page_writeback(req->wb_page);
858 nfs_clear_page_tag_locked(req);
852} 859}
853 860
854/* 861/*
@@ -863,6 +870,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
863 size_t wsize = NFS_SERVER(inode)->wsize, nbytes; 870 size_t wsize = NFS_SERVER(inode)->wsize, nbytes;
864 unsigned int offset; 871 unsigned int offset;
865 int requests = 0; 872 int requests = 0;
873 int ret = 0;
866 LIST_HEAD(list); 874 LIST_HEAD(list);
867 875
868 nfs_list_remove_request(req); 876 nfs_list_remove_request(req);
@@ -884,6 +892,8 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
884 offset = 0; 892 offset = 0;
885 nbytes = count; 893 nbytes = count;
886 do { 894 do {
895 int ret2;
896
887 data = list_entry(list.next, struct nfs_write_data, pages); 897 data = list_entry(list.next, struct nfs_write_data, pages);
888 list_del_init(&data->pages); 898 list_del_init(&data->pages);
889 899
@@ -891,13 +901,15 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
891 901
892 if (nbytes < wsize) 902 if (nbytes < wsize)
893 wsize = nbytes; 903 wsize = nbytes;
894 nfs_write_rpcsetup(req, data, &nfs_write_partial_ops, 904 ret2 = nfs_write_rpcsetup(req, data, &nfs_write_partial_ops,
895 wsize, offset, how); 905 wsize, offset, how);
906 if (ret == 0)
907 ret = ret2;
896 offset += wsize; 908 offset += wsize;
897 nbytes -= wsize; 909 nbytes -= wsize;
898 } while (nbytes != 0); 910 } while (nbytes != 0);
899 911
900 return 0; 912 return ret;
901 913
902out_bad: 914out_bad:
903 while (!list_empty(&list)) { 915 while (!list_empty(&list)) {
@@ -906,8 +918,6 @@ out_bad:
906 nfs_writedata_release(data); 918 nfs_writedata_release(data);
907 } 919 }
908 nfs_redirty_request(req); 920 nfs_redirty_request(req);
909 nfs_end_page_writeback(req->wb_page);
910 nfs_clear_page_tag_locked(req);
911 return -ENOMEM; 921 return -ENOMEM;
912} 922}
913 923
@@ -940,16 +950,12 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
940 req = nfs_list_entry(data->pages.next); 950 req = nfs_list_entry(data->pages.next);
941 951
942 /* Set up the argument struct */ 952 /* Set up the argument struct */
943 nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how); 953 return nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how);
944
945 return 0;
946 out_bad: 954 out_bad:
947 while (!list_empty(head)) { 955 while (!list_empty(head)) {
948 req = nfs_list_entry(head->next); 956 req = nfs_list_entry(head->next);
949 nfs_list_remove_request(req); 957 nfs_list_remove_request(req);
950 nfs_redirty_request(req); 958 nfs_redirty_request(req);
951 nfs_end_page_writeback(req->wb_page);
952 nfs_clear_page_tag_locked(req);
953 } 959 }
954 return -ENOMEM; 960 return -ENOMEM;
955} 961}
@@ -972,7 +978,6 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
972{ 978{
973 struct nfs_write_data *data = calldata; 979 struct nfs_write_data *data = calldata;
974 struct nfs_page *req = data->req; 980 struct nfs_page *req = data->req;
975 struct page *page = req->wb_page;
976 981
977 dprintk("NFS: write (%s/%Ld %d@%Ld)", 982 dprintk("NFS: write (%s/%Ld %d@%Ld)",
978 req->wb_context->path.dentry->d_inode->i_sb->s_id, 983 req->wb_context->path.dentry->d_inode->i_sb->s_id,
@@ -980,13 +985,20 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
980 req->wb_bytes, 985 req->wb_bytes,
981 (long long)req_offset(req)); 986 (long long)req_offset(req));
982 987
983 if (nfs_writeback_done(task, data) != 0) 988 nfs_writeback_done(task, data);
984 return; 989}
985 990
986 if (task->tk_status < 0) { 991static void nfs_writeback_release_partial(void *calldata)
992{
993 struct nfs_write_data *data = calldata;
994 struct nfs_page *req = data->req;
995 struct page *page = req->wb_page;
996 int status = data->task.tk_status;
997
998 if (status < 0) {
987 nfs_set_pageerror(page); 999 nfs_set_pageerror(page);
988 nfs_context_set_write_error(req->wb_context, task->tk_status); 1000 nfs_context_set_write_error(req->wb_context, status);
989 dprintk(", error = %d\n", task->tk_status); 1001 dprintk(", error = %d\n", status);
990 goto out; 1002 goto out;
991 } 1003 }
992 1004
@@ -1011,11 +1023,12 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
1011out: 1023out:
1012 if (atomic_dec_and_test(&req->wb_complete)) 1024 if (atomic_dec_and_test(&req->wb_complete))
1013 nfs_writepage_release(req); 1025 nfs_writepage_release(req);
1026 nfs_writedata_release(calldata);
1014} 1027}
1015 1028
1016static const struct rpc_call_ops nfs_write_partial_ops = { 1029static const struct rpc_call_ops nfs_write_partial_ops = {
1017 .rpc_call_done = nfs_writeback_done_partial, 1030 .rpc_call_done = nfs_writeback_done_partial,
1018 .rpc_release = nfs_writedata_release, 1031 .rpc_release = nfs_writeback_release_partial,
1019}; 1032};
1020 1033
1021/* 1034/*
@@ -1028,17 +1041,21 @@ static const struct rpc_call_ops nfs_write_partial_ops = {
1028static void nfs_writeback_done_full(struct rpc_task *task, void *calldata) 1041static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1029{ 1042{
1030 struct nfs_write_data *data = calldata; 1043 struct nfs_write_data *data = calldata;
1031 struct nfs_page *req;
1032 struct page *page;
1033 1044
1034 if (nfs_writeback_done(task, data) != 0) 1045 nfs_writeback_done(task, data);
1035 return; 1046}
1047
1048static void nfs_writeback_release_full(void *calldata)
1049{
1050 struct nfs_write_data *data = calldata;
1051 int status = data->task.tk_status;
1036 1052
1037 /* Update attributes as result of writeback. */ 1053 /* Update attributes as result of writeback. */
1038 while (!list_empty(&data->pages)) { 1054 while (!list_empty(&data->pages)) {
1039 req = nfs_list_entry(data->pages.next); 1055 struct nfs_page *req = nfs_list_entry(data->pages.next);
1056 struct page *page = req->wb_page;
1057
1040 nfs_list_remove_request(req); 1058 nfs_list_remove_request(req);
1041 page = req->wb_page;
1042 1059
1043 dprintk("NFS: write (%s/%Ld %d@%Ld)", 1060 dprintk("NFS: write (%s/%Ld %d@%Ld)",
1044 req->wb_context->path.dentry->d_inode->i_sb->s_id, 1061 req->wb_context->path.dentry->d_inode->i_sb->s_id,
@@ -1046,10 +1063,10 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1046 req->wb_bytes, 1063 req->wb_bytes,
1047 (long long)req_offset(req)); 1064 (long long)req_offset(req));
1048 1065
1049 if (task->tk_status < 0) { 1066 if (status < 0) {
1050 nfs_set_pageerror(page); 1067 nfs_set_pageerror(page);
1051 nfs_context_set_write_error(req->wb_context, task->tk_status); 1068 nfs_context_set_write_error(req->wb_context, status);
1052 dprintk(", error = %d\n", task->tk_status); 1069 dprintk(", error = %d\n", status);
1053 goto remove_request; 1070 goto remove_request;
1054 } 1071 }
1055 1072
@@ -1069,11 +1086,12 @@ remove_request:
1069 next: 1086 next:
1070 nfs_clear_page_tag_locked(req); 1087 nfs_clear_page_tag_locked(req);
1071 } 1088 }
1089 nfs_writedata_release(calldata);
1072} 1090}
1073 1091
1074static const struct rpc_call_ops nfs_write_full_ops = { 1092static const struct rpc_call_ops nfs_write_full_ops = {
1075 .rpc_call_done = nfs_writeback_done_full, 1093 .rpc_call_done = nfs_writeback_done_full,
1076 .rpc_release = nfs_writedata_release, 1094 .rpc_release = nfs_writeback_release_full,
1077}; 1095};
1078 1096
1079 1097
@@ -1159,15 +1177,18 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1159 1177
1160 1178
1161#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1179#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
1162void nfs_commit_release(void *wdata) 1180void nfs_commitdata_release(void *data)
1163{ 1181{
1182 struct nfs_write_data *wdata = data;
1183
1184 put_nfs_open_context(wdata->args.context);
1164 nfs_commit_free(wdata); 1185 nfs_commit_free(wdata);
1165} 1186}
1166 1187
1167/* 1188/*
1168 * Set up the argument/result storage required for the RPC call. 1189 * Set up the argument/result storage required for the RPC call.
1169 */ 1190 */
1170static void nfs_commit_rpcsetup(struct list_head *head, 1191static int nfs_commit_rpcsetup(struct list_head *head,
1171 struct nfs_write_data *data, 1192 struct nfs_write_data *data,
1172 int how) 1193 int how)
1173{ 1194{
@@ -1187,6 +1208,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1187 .rpc_message = &msg, 1208 .rpc_message = &msg,
1188 .callback_ops = &nfs_commit_ops, 1209 .callback_ops = &nfs_commit_ops,
1189 .callback_data = data, 1210 .callback_data = data,
1211 .workqueue = nfsiod_workqueue,
1190 .flags = flags, 1212 .flags = flags,
1191 .priority = priority, 1213 .priority = priority,
1192 }; 1214 };
@@ -1203,6 +1225,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1203 /* Note: we always request a commit of the entire inode */ 1225 /* Note: we always request a commit of the entire inode */
1204 data->args.offset = 0; 1226 data->args.offset = 0;
1205 data->args.count = 0; 1227 data->args.count = 0;
1228 data->args.context = get_nfs_open_context(first->wb_context);
1206 data->res.count = 0; 1229 data->res.count = 0;
1207 data->res.fattr = &data->fattr; 1230 data->res.fattr = &data->fattr;
1208 data->res.verf = &data->verf; 1231 data->res.verf = &data->verf;
@@ -1214,8 +1237,10 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1214 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); 1237 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
1215 1238
1216 task = rpc_run_task(&task_setup_data); 1239 task = rpc_run_task(&task_setup_data);
1217 if (!IS_ERR(task)) 1240 if (IS_ERR(task))
1218 rpc_put_task(task); 1241 return PTR_ERR(task);
1242 rpc_put_task(task);
1243 return 0;
1219} 1244}
1220 1245
1221/* 1246/*
@@ -1227,15 +1252,13 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1227 struct nfs_write_data *data; 1252 struct nfs_write_data *data;
1228 struct nfs_page *req; 1253 struct nfs_page *req;
1229 1254
1230 data = nfs_commit_alloc(); 1255 data = nfs_commitdata_alloc();
1231 1256
1232 if (!data) 1257 if (!data)
1233 goto out_bad; 1258 goto out_bad;
1234 1259
1235 /* Set up the argument struct */ 1260 /* Set up the argument struct */
1236 nfs_commit_rpcsetup(head, data, how); 1261 return nfs_commit_rpcsetup(head, data, how);
1237
1238 return 0;
1239 out_bad: 1262 out_bad:
1240 while (!list_empty(head)) { 1263 while (!list_empty(head)) {
1241 req = nfs_list_entry(head->next); 1264 req = nfs_list_entry(head->next);
@@ -1255,7 +1278,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1255static void nfs_commit_done(struct rpc_task *task, void *calldata) 1278static void nfs_commit_done(struct rpc_task *task, void *calldata)
1256{ 1279{
1257 struct nfs_write_data *data = calldata; 1280 struct nfs_write_data *data = calldata;
1258 struct nfs_page *req;
1259 1281
1260 dprintk("NFS: %5u nfs_commit_done (status %d)\n", 1282 dprintk("NFS: %5u nfs_commit_done (status %d)\n",
1261 task->tk_pid, task->tk_status); 1283 task->tk_pid, task->tk_status);
@@ -1263,6 +1285,13 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1263 /* Call the NFS version-specific code */ 1285 /* Call the NFS version-specific code */
1264 if (NFS_PROTO(data->inode)->commit_done(task, data) != 0) 1286 if (NFS_PROTO(data->inode)->commit_done(task, data) != 0)
1265 return; 1287 return;
1288}
1289
1290static void nfs_commit_release(void *calldata)
1291{
1292 struct nfs_write_data *data = calldata;
1293 struct nfs_page *req;
1294 int status = data->task.tk_status;
1266 1295
1267 while (!list_empty(&data->pages)) { 1296 while (!list_empty(&data->pages)) {
1268 req = nfs_list_entry(data->pages.next); 1297 req = nfs_list_entry(data->pages.next);
@@ -1277,10 +1306,10 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1277 (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), 1306 (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
1278 req->wb_bytes, 1307 req->wb_bytes,
1279 (long long)req_offset(req)); 1308 (long long)req_offset(req));
1280 if (task->tk_status < 0) { 1309 if (status < 0) {
1281 nfs_context_set_write_error(req->wb_context, task->tk_status); 1310 nfs_context_set_write_error(req->wb_context, status);
1282 nfs_inode_remove_request(req); 1311 nfs_inode_remove_request(req);
1283 dprintk(", error = %d\n", task->tk_status); 1312 dprintk(", error = %d\n", status);
1284 goto next; 1313 goto next;
1285 } 1314 }
1286 1315
@@ -1297,10 +1326,11 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1297 } 1326 }
1298 /* We have a mismatch. Write the page again */ 1327 /* We have a mismatch. Write the page again */
1299 dprintk(" mismatch\n"); 1328 dprintk(" mismatch\n");
1300 nfs_redirty_request(req); 1329 nfs_mark_request_dirty(req);
1301 next: 1330 next:
1302 nfs_clear_page_tag_locked(req); 1331 nfs_clear_page_tag_locked(req);
1303 } 1332 }
1333 nfs_commitdata_release(calldata);
1304} 1334}
1305 1335
1306static const struct rpc_call_ops nfs_commit_ops = { 1336static const struct rpc_call_ops nfs_commit_ops = {
@@ -1487,18 +1517,19 @@ static int nfs_wb_page_priority(struct inode *inode, struct page *page,
1487 }; 1517 };
1488 int ret; 1518 int ret;
1489 1519
1490 BUG_ON(!PageLocked(page)); 1520 do {
1491 if (clear_page_dirty_for_io(page)) { 1521 if (clear_page_dirty_for_io(page)) {
1492 ret = nfs_writepage_locked(page, &wbc); 1522 ret = nfs_writepage_locked(page, &wbc);
1523 if (ret < 0)
1524 goto out_error;
1525 } else if (!PagePrivate(page))
1526 break;
1527 ret = nfs_sync_mapping_wait(page->mapping, &wbc, how);
1493 if (ret < 0) 1528 if (ret < 0)
1494 goto out; 1529 goto out_error;
1495 } 1530 } while (PagePrivate(page));
1496 if (!PagePrivate(page)) 1531 return 0;
1497 return 0; 1532out_error:
1498 ret = nfs_sync_mapping_wait(page->mapping, &wbc, how);
1499 if (ret >= 0)
1500 return 0;
1501out:
1502 __mark_inode_dirty(inode, I_DIRTY_PAGES); 1533 __mark_inode_dirty(inode, I_DIRTY_PAGES);
1503 return ret; 1534 return ret;
1504} 1535}
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 4babb2a129ac..94649a8da014 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -91,6 +91,7 @@ struct nlm_wait;
91 */ 91 */
92#define NLMCLNT_OHSIZE ((__NEW_UTS_LEN) + 10u) 92#define NLMCLNT_OHSIZE ((__NEW_UTS_LEN) + 10u)
93struct nlm_rqst { 93struct nlm_rqst {
94 atomic_t a_count;
94 unsigned int a_flags; /* initial RPC task flags */ 95 unsigned int a_flags; /* initial RPC task flags */
95 struct nlm_host * a_host; /* host handle */ 96 struct nlm_host * a_host; /* host handle */
96 struct nlm_args a_args; /* arguments */ 97 struct nlm_args a_args; /* arguments */
@@ -173,8 +174,10 @@ void nlmclnt_next_cookie(struct nlm_cookie *);
173/* 174/*
174 * Host cache 175 * Host cache
175 */ 176 */
176struct nlm_host *nlmclnt_lookup_host(const struct sockaddr_in *, int, int, 177struct nlm_host *nlmclnt_lookup_host(const struct sockaddr_in *sin,
177 const char *, unsigned int); 178 int proto, u32 version,
179 const char *hostname,
180 unsigned int hostname_len);
178struct nlm_host *nlmsvc_lookup_host(struct svc_rqst *, const char *, 181struct nlm_host *nlmsvc_lookup_host(struct svc_rqst *, const char *,
179 unsigned int); 182 unsigned int);
180struct rpc_clnt * nlm_bind_host(struct nlm_host *); 183struct rpc_clnt * nlm_bind_host(struct nlm_host *);
@@ -217,8 +220,7 @@ void nlmsvc_mark_resources(void);
217void nlmsvc_free_host_resources(struct nlm_host *); 220void nlmsvc_free_host_resources(struct nlm_host *);
218void nlmsvc_invalidate_all(void); 221void nlmsvc_invalidate_all(void);
219 222
220static __inline__ struct inode * 223static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
221nlmsvc_file_inode(struct nlm_file *file)
222{ 224{
223 return file->f_file->f_path.dentry->d_inode; 225 return file->f_file->f_path.dentry->d_inode;
224} 226}
@@ -226,8 +228,8 @@ nlmsvc_file_inode(struct nlm_file *file)
226/* 228/*
227 * Compare two host addresses (needs modifying for ipv6) 229 * Compare two host addresses (needs modifying for ipv6)
228 */ 230 */
229static __inline__ int 231static inline int nlm_cmp_addr(const struct sockaddr_in *sin1,
230nlm_cmp_addr(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2) 232 const struct sockaddr_in *sin2)
231{ 233{
232 return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr; 234 return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
233} 235}
@@ -236,8 +238,8 @@ nlm_cmp_addr(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
236 * Compare two NLM locks. 238 * Compare two NLM locks.
237 * When the second lock is of type F_UNLCK, this acts like a wildcard. 239 * When the second lock is of type F_UNLCK, this acts like a wildcard.
238 */ 240 */
239static __inline__ int 241static inline int nlm_compare_locks(const struct file_lock *fl1,
240nlm_compare_locks(const struct file_lock *fl1, const struct file_lock *fl2) 242 const struct file_lock *fl2)
241{ 243{
242 return fl1->fl_pid == fl2->fl_pid 244 return fl1->fl_pid == fl2->fl_pid
243 && fl1->fl_owner == fl2->fl_owner 245 && fl1->fl_owner == fl2->fl_owner
diff --git a/include/linux/lockd/sm_inter.h b/include/linux/lockd/sm_inter.h
index 22a645828f26..5a5448bdb17d 100644
--- a/include/linux/lockd/sm_inter.h
+++ b/include/linux/lockd/sm_inter.h
@@ -19,6 +19,7 @@
19#define SM_NOTIFY 6 19#define SM_NOTIFY 6
20 20
21#define SM_MAXSTRLEN 1024 21#define SM_MAXSTRLEN 1024
22#define SM_PRIV_SIZE 16
22 23
23/* 24/*
24 * Arguments for all calls to statd 25 * Arguments for all calls to statd
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index f4a0e4c218df..27d6a8d98cef 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -430,7 +430,6 @@ extern void nfs_unregister_sysctl(void);
430/* 430/*
431 * linux/fs/nfs/namespace.c 431 * linux/fs/nfs/namespace.c
432 */ 432 */
433extern struct list_head nfs_automount_list;
434extern const struct inode_operations nfs_mountpoint_inode_operations; 433extern const struct inode_operations nfs_mountpoint_inode_operations;
435extern const struct inode_operations nfs_referral_inode_operations; 434extern const struct inode_operations nfs_referral_inode_operations;
436extern int nfs_mountpoint_expiry_timeout; 435extern int nfs_mountpoint_expiry_timeout;
@@ -466,9 +465,9 @@ extern int nfs_wb_page(struct inode *inode, struct page* page);
466extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); 465extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
467#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 466#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
468extern int nfs_commit_inode(struct inode *, int); 467extern int nfs_commit_inode(struct inode *, int);
469extern struct nfs_write_data *nfs_commit_alloc(void); 468extern struct nfs_write_data *nfs_commitdata_alloc(void);
470extern void nfs_commit_free(struct nfs_write_data *wdata); 469extern void nfs_commit_free(struct nfs_write_data *wdata);
471extern void nfs_commit_release(void *wdata); 470extern void nfs_commitdata_release(void *wdata);
472#else 471#else
473static inline int 472static inline int
474nfs_commit_inode(struct inode *inode, int how) 473nfs_commit_inode(struct inode *inode, int how)
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 3423c6761bf7..c9beacd16c00 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -32,6 +32,8 @@ struct nfs_client {
32 const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ 32 const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */
33 int cl_proto; /* Network transport protocol */ 33 int cl_proto; /* Network transport protocol */
34 34
35 struct rpc_cred *cl_machine_cred;
36
35#ifdef CONFIG_NFS_V4 37#ifdef CONFIG_NFS_V4
36 u64 cl_clientid; /* constant */ 38 u64 cl_clientid; /* constant */
37 nfs4_verifier cl_confirm; 39 nfs4_verifier cl_confirm;
@@ -93,6 +95,7 @@ struct nfs_server {
93 unsigned int wpages; /* write size (in pages) */ 95 unsigned int wpages; /* write size (in pages) */
94 unsigned int wtmult; /* server disk block size */ 96 unsigned int wtmult; /* server disk block size */
95 unsigned int dtsize; /* readdir size */ 97 unsigned int dtsize; /* readdir size */
98 unsigned short port; /* "port=" setting */
96 unsigned int bsize; /* server block size */ 99 unsigned int bsize; /* server block size */
97 unsigned int acregmin; /* attr cache timeouts */ 100 unsigned int acregmin; /* attr cache timeouts */
98 unsigned int acregmax; 101 unsigned int acregmax;
@@ -117,6 +120,13 @@ struct nfs_server {
117 120
118 atomic_t active; /* Keep trace of any activity to this server */ 121 atomic_t active; /* Keep trace of any activity to this server */
119 wait_queue_head_t active_wq; /* Wait for any activity to stop */ 122 wait_queue_head_t active_wq; /* Wait for any activity to stop */
123
124 /* mountd-related mount options */
125 struct sockaddr_storage mountd_address;
126 size_t mountd_addrlen;
127 u32 mountd_version;
128 unsigned short mountd_port;
129 unsigned short mountd_protocol;
120}; 130};
121 131
122/* Server capabilities */ 132/* Server capabilities */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index f301d0b8babc..24263bb8e0be 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -140,6 +140,7 @@ struct nfs_openres {
140 __u32 rflags; 140 __u32 rflags;
141 struct nfs_fattr * f_attr; 141 struct nfs_fattr * f_attr;
142 struct nfs_fattr * dir_attr; 142 struct nfs_fattr * dir_attr;
143 struct nfs_seqid * seqid;
143 const struct nfs_server *server; 144 const struct nfs_server *server;
144 int delegation_type; 145 int delegation_type;
145 nfs4_stateid delegation; 146 nfs4_stateid delegation;
@@ -159,6 +160,7 @@ struct nfs_open_confirmargs {
159 160
160struct nfs_open_confirmres { 161struct nfs_open_confirmres {
161 nfs4_stateid stateid; 162 nfs4_stateid stateid;
163 struct nfs_seqid * seqid;
162}; 164};
163 165
164/* 166/*
@@ -175,6 +177,7 @@ struct nfs_closeargs {
175struct nfs_closeres { 177struct nfs_closeres {
176 nfs4_stateid stateid; 178 nfs4_stateid stateid;
177 struct nfs_fattr * fattr; 179 struct nfs_fattr * fattr;
180 struct nfs_seqid * seqid;
178 const struct nfs_server *server; 181 const struct nfs_server *server;
179}; 182};
180/* 183/*
@@ -199,7 +202,9 @@ struct nfs_lock_args {
199}; 202};
200 203
201struct nfs_lock_res { 204struct nfs_lock_res {
202 nfs4_stateid stateid; 205 nfs4_stateid stateid;
206 struct nfs_seqid * lock_seqid;
207 struct nfs_seqid * open_seqid;
203}; 208};
204 209
205struct nfs_locku_args { 210struct nfs_locku_args {
@@ -210,7 +215,8 @@ struct nfs_locku_args {
210}; 215};
211 216
212struct nfs_locku_res { 217struct nfs_locku_res {
213 nfs4_stateid stateid; 218 nfs4_stateid stateid;
219 struct nfs_seqid * seqid;
214}; 220};
215 221
216struct nfs_lockt_args { 222struct nfs_lockt_args {
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 7a69ca3bebaf..3f632182d8eb 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -26,6 +26,7 @@ struct auth_cred {
26 uid_t uid; 26 uid_t uid;
27 gid_t gid; 27 gid_t gid;
28 struct group_info *group_info; 28 struct group_info *group_info;
29 unsigned char machine_cred : 1;
29}; 30};
30 31
31/* 32/*
@@ -59,8 +60,8 @@ struct rpc_cred {
59/* 60/*
60 * Client authentication handle 61 * Client authentication handle
61 */ 62 */
62#define RPC_CREDCACHE_NR 8 63#define RPC_CREDCACHE_HASHBITS 4
63#define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1) 64#define RPC_CREDCACHE_NR (1 << RPC_CREDCACHE_HASHBITS)
64struct rpc_cred_cache { 65struct rpc_cred_cache {
65 struct hlist_head hashtable[RPC_CREDCACHE_NR]; 66 struct hlist_head hashtable[RPC_CREDCACHE_NR];
66 spinlock_t lock; 67 spinlock_t lock;
@@ -89,7 +90,6 @@ struct rpc_auth {
89 90
90/* Flags for rpcauth_lookupcred() */ 91/* Flags for rpcauth_lookupcred() */
91#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */ 92#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */
92#define RPCAUTH_LOOKUP_ROOTCREDS 0x02 /* This really ought to go! */
93 93
94/* 94/*
95 * Client authentication ops 95 * Client authentication ops
@@ -97,9 +97,7 @@ struct rpc_auth {
97struct rpc_authops { 97struct rpc_authops {
98 struct module *owner; 98 struct module *owner;
99 rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */ 99 rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */
100#ifdef RPC_DEBUG
101 char * au_name; 100 char * au_name;
102#endif
103 struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t); 101 struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t);
104 void (*destroy)(struct rpc_auth *); 102 void (*destroy)(struct rpc_auth *);
105 103
@@ -113,6 +111,7 @@ struct rpc_credops {
113 void (*crdestroy)(struct rpc_cred *); 111 void (*crdestroy)(struct rpc_cred *);
114 112
115 int (*crmatch)(struct auth_cred *, struct rpc_cred *, int); 113 int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
114 void (*crbind)(struct rpc_task *, struct rpc_cred *);
116 __be32 * (*crmarshal)(struct rpc_task *, __be32 *); 115 __be32 * (*crmarshal)(struct rpc_task *, __be32 *);
117 int (*crrefresh)(struct rpc_task *); 116 int (*crrefresh)(struct rpc_task *);
118 __be32 * (*crvalidate)(struct rpc_task *, __be32 *); 117 __be32 * (*crvalidate)(struct rpc_task *, __be32 *);
@@ -126,9 +125,13 @@ extern const struct rpc_authops authunix_ops;
126extern const struct rpc_authops authnull_ops; 125extern const struct rpc_authops authnull_ops;
127 126
128void __init rpc_init_authunix(void); 127void __init rpc_init_authunix(void);
128void __init rpc_init_generic_auth(void);
129void __init rpcauth_init_module(void); 129void __init rpcauth_init_module(void);
130void __exit rpcauth_remove_module(void); 130void __exit rpcauth_remove_module(void);
131void __exit rpc_destroy_generic_auth(void);
131 132
133struct rpc_cred * rpc_lookup_cred(void);
134struct rpc_cred * rpc_lookup_machine_cred(void);
132int rpcauth_register(const struct rpc_authops *); 135int rpcauth_register(const struct rpc_authops *);
133int rpcauth_unregister(const struct rpc_authops *); 136int rpcauth_unregister(const struct rpc_authops *);
134struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); 137struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
@@ -136,8 +139,8 @@ void rpcauth_release(struct rpc_auth *);
136struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); 139struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
137void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); 140void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
138struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); 141struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
139struct rpc_cred * rpcauth_bindcred(struct rpc_task *); 142void rpcauth_bindcred(struct rpc_task *, struct rpc_cred *, int);
140void rpcauth_holdcred(struct rpc_task *); 143void rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *);
141void put_rpccred(struct rpc_cred *); 144void put_rpccred(struct rpc_cred *);
142void rpcauth_unbindcred(struct rpc_task *); 145void rpcauth_unbindcred(struct rpc_task *);
143__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *); 146__be32 * rpcauth_marshcred(struct rpc_task *, __be32 *);
diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
index 67658e17a375..fec6899bf355 100644
--- a/include/linux/sunrpc/auth_gss.h
+++ b/include/linux/sunrpc/auth_gss.h
@@ -84,6 +84,7 @@ struct gss_cred {
84 enum rpc_gss_svc gc_service; 84 enum rpc_gss_svc gc_service;
85 struct gss_cl_ctx *gc_ctx; 85 struct gss_cl_ctx *gc_ctx;
86 struct gss_upcall_msg *gc_upcall; 86 struct gss_upcall_msg *gc_upcall;
87 unsigned char gc_machine_cred : 1;
87}; 88};
88 89
89#endif /* __KERNEL__ */ 90#endif /* __KERNEL__ */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 129a86e25d29..6fff7f82ef12 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -127,11 +127,12 @@ int rpcb_getport_sync(struct sockaddr_in *, u32, u32, int);
127void rpcb_getport_async(struct rpc_task *); 127void rpcb_getport_async(struct rpc_task *);
128 128
129void rpc_call_start(struct rpc_task *); 129void rpc_call_start(struct rpc_task *);
130int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, 130int rpc_call_async(struct rpc_clnt *clnt,
131 int flags, const struct rpc_call_ops *tk_ops, 131 const struct rpc_message *msg, int flags,
132 const struct rpc_call_ops *tk_ops,
132 void *calldata); 133 void *calldata);
133int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, 134int rpc_call_sync(struct rpc_clnt *clnt,
134 int flags); 135 const struct rpc_message *msg, int flags);
135struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, 136struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
136 int flags); 137 int flags);
137void rpc_restart_call(struct rpc_task *); 138void rpc_restart_call(struct rpc_task *);
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index f689f02e6793..d1a5c8c1a0f1 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -11,7 +11,6 @@
11 11
12#include <linux/timer.h> 12#include <linux/timer.h>
13#include <linux/sunrpc/types.h> 13#include <linux/sunrpc/types.h>
14#include <linux/rcupdate.h>
15#include <linux/spinlock.h> 14#include <linux/spinlock.h>
16#include <linux/wait.h> 15#include <linux/wait.h>
17#include <linux/workqueue.h> 16#include <linux/workqueue.h>
@@ -33,7 +32,8 @@ struct rpc_wait_queue;
33struct rpc_wait { 32struct rpc_wait {
34 struct list_head list; /* wait queue links */ 33 struct list_head list; /* wait queue links */
35 struct list_head links; /* Links to related tasks */ 34 struct list_head links; /* Links to related tasks */
36 struct rpc_wait_queue * rpc_waitq; /* RPC wait queue we're on */ 35 struct list_head timer_list; /* Timer list */
36 unsigned long expires;
37}; 37};
38 38
39/* 39/*
@@ -57,33 +57,25 @@ struct rpc_task {
57 __u8 tk_cred_retry; 57 __u8 tk_cred_retry;
58 58
59 /* 59 /*
60 * timeout_fn to be executed by timer bottom half
61 * callback to be executed after waking up 60 * callback to be executed after waking up
62 * action next procedure for async tasks 61 * action next procedure for async tasks
63 * tk_ops caller callbacks 62 * tk_ops caller callbacks
64 */ 63 */
65 void (*tk_timeout_fn)(struct rpc_task *);
66 void (*tk_callback)(struct rpc_task *); 64 void (*tk_callback)(struct rpc_task *);
67 void (*tk_action)(struct rpc_task *); 65 void (*tk_action)(struct rpc_task *);
68 const struct rpc_call_ops *tk_ops; 66 const struct rpc_call_ops *tk_ops;
69 void * tk_calldata; 67 void * tk_calldata;
70 68
71 /*
72 * tk_timer is used for async processing by the RPC scheduling
73 * primitives. You should not access this directly unless
74 * you have a pathological interest in kernel oopses.
75 */
76 struct timer_list tk_timer; /* kernel timer */
77 unsigned long tk_timeout; /* timeout for rpc_sleep() */ 69 unsigned long tk_timeout; /* timeout for rpc_sleep() */
78 unsigned short tk_flags; /* misc flags */ 70 unsigned short tk_flags; /* misc flags */
79 unsigned long tk_runstate; /* Task run status */ 71 unsigned long tk_runstate; /* Task run status */
80 struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could 72 struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could
81 * be any workqueue 73 * be any workqueue
82 */ 74 */
75 struct rpc_wait_queue *tk_waitqueue; /* RPC wait queue we're on */
83 union { 76 union {
84 struct work_struct tk_work; /* Async task work queue */ 77 struct work_struct tk_work; /* Async task work queue */
85 struct rpc_wait tk_wait; /* RPC wait */ 78 struct rpc_wait tk_wait; /* RPC wait */
86 struct rcu_head tk_rcu; /* for task deletion */
87 } u; 79 } u;
88 80
89 unsigned short tk_timeouts; /* maj timeouts */ 81 unsigned short tk_timeouts; /* maj timeouts */
@@ -123,6 +115,7 @@ struct rpc_task_setup {
123 const struct rpc_message *rpc_message; 115 const struct rpc_message *rpc_message;
124 const struct rpc_call_ops *callback_ops; 116 const struct rpc_call_ops *callback_ops;
125 void *callback_data; 117 void *callback_data;
118 struct workqueue_struct *workqueue;
126 unsigned short flags; 119 unsigned short flags;
127 signed char priority; 120 signed char priority;
128}; 121};
@@ -147,9 +140,7 @@ struct rpc_task_setup {
147 140
148#define RPC_TASK_RUNNING 0 141#define RPC_TASK_RUNNING 0
149#define RPC_TASK_QUEUED 1 142#define RPC_TASK_QUEUED 1
150#define RPC_TASK_WAKEUP 2 143#define RPC_TASK_ACTIVE 2
151#define RPC_TASK_HAS_TIMER 3
152#define RPC_TASK_ACTIVE 4
153 144
154#define RPC_IS_RUNNING(t) test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate) 145#define RPC_IS_RUNNING(t) test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
155#define rpc_set_running(t) set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate) 146#define rpc_set_running(t) set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
@@ -171,15 +162,6 @@ struct rpc_task_setup {
171 smp_mb__after_clear_bit(); \ 162 smp_mb__after_clear_bit(); \
172 } while (0) 163 } while (0)
173 164
174#define rpc_start_wakeup(t) \
175 (test_and_set_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate) == 0)
176#define rpc_finish_wakeup(t) \
177 do { \
178 smp_mb__before_clear_bit(); \
179 clear_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate); \
180 smp_mb__after_clear_bit(); \
181 } while (0)
182
183#define RPC_IS_ACTIVATED(t) test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate) 165#define RPC_IS_ACTIVATED(t) test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)
184 166
185/* 167/*
@@ -192,6 +174,12 @@ struct rpc_task_setup {
192#define RPC_PRIORITY_HIGH (1) 174#define RPC_PRIORITY_HIGH (1)
193#define RPC_NR_PRIORITY (1 + RPC_PRIORITY_HIGH - RPC_PRIORITY_LOW) 175#define RPC_NR_PRIORITY (1 + RPC_PRIORITY_HIGH - RPC_PRIORITY_LOW)
194 176
177struct rpc_timer {
178 struct timer_list timer;
179 struct list_head list;
180 unsigned long expires;
181};
182
195/* 183/*
196 * RPC synchronization objects 184 * RPC synchronization objects
197 */ 185 */
@@ -204,6 +192,7 @@ struct rpc_wait_queue {
204 unsigned char count; /* # task groups remaining serviced so far */ 192 unsigned char count; /* # task groups remaining serviced so far */
205 unsigned char nr; /* # tasks remaining for cookie */ 193 unsigned char nr; /* # tasks remaining for cookie */
206 unsigned short qlen; /* total # tasks waiting in queue */ 194 unsigned short qlen; /* total # tasks waiting in queue */
195 struct rpc_timer timer_list;
207#ifdef RPC_DEBUG 196#ifdef RPC_DEBUG
208 const char * name; 197 const char * name;
209#endif 198#endif
@@ -229,9 +218,11 @@ void rpc_killall_tasks(struct rpc_clnt *);
229void rpc_execute(struct rpc_task *); 218void rpc_execute(struct rpc_task *);
230void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *); 219void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
231void rpc_init_wait_queue(struct rpc_wait_queue *, const char *); 220void rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
221void rpc_destroy_wait_queue(struct rpc_wait_queue *);
232void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, 222void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *,
233 rpc_action action, rpc_action timer); 223 rpc_action action);
234void rpc_wake_up_task(struct rpc_task *); 224void rpc_wake_up_queued_task(struct rpc_wait_queue *,
225 struct rpc_task *);
235void rpc_wake_up(struct rpc_wait_queue *); 226void rpc_wake_up(struct rpc_wait_queue *);
236struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *); 227struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *);
237void rpc_wake_up_status(struct rpc_wait_queue *, int); 228void rpc_wake_up_status(struct rpc_wait_queue *, int);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index b3ff9a815e6f..4d80a118d538 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -86,6 +86,10 @@ struct rpc_rqst {
86 unsigned long rq_majortimeo; /* major timeout alarm */ 86 unsigned long rq_majortimeo; /* major timeout alarm */
87 unsigned long rq_timeout; /* Current timeout value */ 87 unsigned long rq_timeout; /* Current timeout value */
88 unsigned int rq_retries; /* # of retries */ 88 unsigned int rq_retries; /* # of retries */
89 unsigned int rq_connect_cookie;
90 /* A cookie used to track the
91 state of the transport
92 connection */
89 93
90 /* 94 /*
91 * Partial send handling 95 * Partial send handling
@@ -152,6 +156,9 @@ struct rpc_xprt {
152 unsigned long connect_timeout, 156 unsigned long connect_timeout,
153 bind_timeout, 157 bind_timeout,
154 reestablish_timeout; 158 reestablish_timeout;
159 unsigned int connect_cookie; /* A cookie that gets bumped
160 every time the transport
161 is reconnected */
155 162
156 /* 163 /*
157 * Disconnection of idle transports 164 * Disconnection of idle transports
@@ -232,7 +239,7 @@ int xprt_unregister_transport(struct xprt_class *type);
232void xprt_set_retrans_timeout_def(struct rpc_task *task); 239void xprt_set_retrans_timeout_def(struct rpc_task *task);
233void xprt_set_retrans_timeout_rtt(struct rpc_task *task); 240void xprt_set_retrans_timeout_rtt(struct rpc_task *task);
234void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status); 241void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
235void xprt_wait_for_buffer_space(struct rpc_task *task); 242void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action);
236void xprt_write_space(struct rpc_xprt *xprt); 243void xprt_write_space(struct rpc_xprt *xprt);
237void xprt_update_rtt(struct rpc_task *task); 244void xprt_update_rtt(struct rpc_task *task);
238void xprt_adjust_cwnd(struct rpc_task *task, int result); 245void xprt_adjust_cwnd(struct rpc_task *task, int result);
@@ -241,6 +248,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied);
241void xprt_release_rqst_cong(struct rpc_task *task); 248void xprt_release_rqst_cong(struct rpc_task *task);
242void xprt_disconnect_done(struct rpc_xprt *xprt); 249void xprt_disconnect_done(struct rpc_xprt *xprt);
243void xprt_force_disconnect(struct rpc_xprt *xprt); 250void xprt_force_disconnect(struct rpc_xprt *xprt);
251void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie);
244 252
245/* 253/*
246 * Reserved bit positions in xprt->state 254 * Reserved bit positions in xprt->state
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index 92e1dbe50947..5369aa369b35 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
8obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/ 8obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/
9 9
10sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \ 10sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
11 auth.o auth_null.o auth_unix.o \ 11 auth.o auth_null.o auth_unix.o auth_generic.o \
12 svc.o svcsock.o svcauth.o svcauth_unix.o \ 12 svc.o svcsock.o svcauth.o svcauth_unix.o \
13 rpcb_clnt.o timer.o xdr.o \ 13 rpcb_clnt.o timer.o xdr.o \
14 sunrpc_syms.o cache.o rpc_pipe.o \ 14 sunrpc_syms.o cache.o rpc_pipe.o \
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index eca941ce298b..6bfea9ed6869 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/hash.h>
14#include <linux/sunrpc/clnt.h> 15#include <linux/sunrpc/clnt.h>
15#include <linux/spinlock.h> 16#include <linux/spinlock.h>
16 17
@@ -219,6 +220,9 @@ rpcauth_destroy_credcache(struct rpc_auth *auth)
219} 220}
220EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache); 221EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache);
221 222
223
224#define RPC_AUTH_EXPIRY_MORATORIUM (60 * HZ)
225
222/* 226/*
223 * Remove stale credentials. Avoid sleeping inside the loop. 227 * Remove stale credentials. Avoid sleeping inside the loop.
224 */ 228 */
@@ -227,6 +231,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
227{ 231{
228 spinlock_t *cache_lock; 232 spinlock_t *cache_lock;
229 struct rpc_cred *cred; 233 struct rpc_cred *cred;
234 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM;
230 235
231 while (!list_empty(&cred_unused)) { 236 while (!list_empty(&cred_unused)) {
232 cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru); 237 cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru);
@@ -234,6 +239,10 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
234 number_cred_unused--; 239 number_cred_unused--;
235 if (atomic_read(&cred->cr_count) != 0) 240 if (atomic_read(&cred->cr_count) != 0)
236 continue; 241 continue;
242 /* Enforce a 5 second garbage collection moratorium */
243 if (time_in_range(cred->cr_expire, expired, jiffies) &&
244 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0)
245 continue;
237 cache_lock = &cred->cr_auth->au_credcache->lock; 246 cache_lock = &cred->cr_auth->au_credcache->lock;
238 spin_lock(cache_lock); 247 spin_lock(cache_lock);
239 if (atomic_read(&cred->cr_count) == 0) { 248 if (atomic_read(&cred->cr_count) == 0) {
@@ -280,10 +289,9 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
280 struct hlist_node *pos; 289 struct hlist_node *pos;
281 struct rpc_cred *cred = NULL, 290 struct rpc_cred *cred = NULL,
282 *entry, *new; 291 *entry, *new;
283 int nr = 0; 292 unsigned int nr;
284 293
285 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) 294 nr = hash_long(acred->uid, RPC_CREDCACHE_HASHBITS);
286 nr = acred->uid & RPC_CREDCACHE_MASK;
287 295
288 rcu_read_lock(); 296 rcu_read_lock();
289 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { 297 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
@@ -356,7 +364,6 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
356 put_group_info(acred.group_info); 364 put_group_info(acred.group_info);
357 return ret; 365 return ret;
358} 366}
359EXPORT_SYMBOL_GPL(rpcauth_lookupcred);
360 367
361void 368void
362rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, 369rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
@@ -375,41 +382,58 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
375} 382}
376EXPORT_SYMBOL_GPL(rpcauth_init_cred); 383EXPORT_SYMBOL_GPL(rpcauth_init_cred);
377 384
378struct rpc_cred * 385void
379rpcauth_bindcred(struct rpc_task *task) 386rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred)
387{
388 task->tk_msg.rpc_cred = get_rpccred(cred);
389 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid,
390 cred->cr_auth->au_ops->au_name, cred);
391}
392EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred);
393
394static void
395rpcauth_bind_root_cred(struct rpc_task *task)
380{ 396{
381 struct rpc_auth *auth = task->tk_client->cl_auth; 397 struct rpc_auth *auth = task->tk_client->cl_auth;
382 struct auth_cred acred = { 398 struct auth_cred acred = {
383 .uid = current->fsuid, 399 .uid = 0,
384 .gid = current->fsgid, 400 .gid = 0,
385 .group_info = current->group_info,
386 }; 401 };
387 struct rpc_cred *ret; 402 struct rpc_cred *ret;
388 int flags = 0;
389 403
390 dprintk("RPC: %5u looking up %s cred\n", 404 dprintk("RPC: %5u looking up %s cred\n",
391 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name); 405 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
392 get_group_info(acred.group_info); 406 ret = auth->au_ops->lookup_cred(auth, &acred, 0);
393 if (task->tk_flags & RPC_TASK_ROOTCREDS) 407 if (!IS_ERR(ret))
394 flags |= RPCAUTH_LOOKUP_ROOTCREDS; 408 task->tk_msg.rpc_cred = ret;
395 ret = auth->au_ops->lookup_cred(auth, &acred, flags); 409 else
410 task->tk_status = PTR_ERR(ret);
411}
412
413static void
414rpcauth_bind_new_cred(struct rpc_task *task)
415{
416 struct rpc_auth *auth = task->tk_client->cl_auth;
417 struct rpc_cred *ret;
418
419 dprintk("RPC: %5u looking up %s cred\n",
420 task->tk_pid, auth->au_ops->au_name);
421 ret = rpcauth_lookupcred(auth, 0);
396 if (!IS_ERR(ret)) 422 if (!IS_ERR(ret))
397 task->tk_msg.rpc_cred = ret; 423 task->tk_msg.rpc_cred = ret;
398 else 424 else
399 task->tk_status = PTR_ERR(ret); 425 task->tk_status = PTR_ERR(ret);
400 put_group_info(acred.group_info);
401 return ret;
402} 426}
403 427
404void 428void
405rpcauth_holdcred(struct rpc_task *task) 429rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
406{ 430{
407 struct rpc_cred *cred = task->tk_msg.rpc_cred; 431 if (cred != NULL)
408 if (cred != NULL) { 432 cred->cr_ops->crbind(task, cred);
409 get_rpccred(cred); 433 else if (flags & RPC_TASK_ROOTCREDS)
410 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid, 434 rpcauth_bind_root_cred(task);
411 cred->cr_auth->au_ops->au_name, cred); 435 else
412 } 436 rpcauth_bind_new_cred(task);
413} 437}
414 438
415void 439void
@@ -550,6 +574,7 @@ static struct shrinker rpc_cred_shrinker = {
550void __init rpcauth_init_module(void) 574void __init rpcauth_init_module(void)
551{ 575{
552 rpc_init_authunix(); 576 rpc_init_authunix();
577 rpc_init_generic_auth();
553 register_shrinker(&rpc_cred_shrinker); 578 register_shrinker(&rpc_cred_shrinker);
554} 579}
555 580
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
new file mode 100644
index 000000000000..d927d9f57412
--- /dev/null
+++ b/net/sunrpc/auth_generic.c
@@ -0,0 +1,177 @@
1/*
2 * Generic RPC credential
3 *
4 * Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com>
5 */
6
7#include <linux/err.h>
8#include <linux/types.h>
9#include <linux/module.h>
10#include <linux/sched.h>
11#include <linux/sunrpc/auth.h>
12#include <linux/sunrpc/clnt.h>
13#include <linux/sunrpc/debug.h>
14#include <linux/sunrpc/sched.h>
15
16#ifdef RPC_DEBUG
17# define RPCDBG_FACILITY RPCDBG_AUTH
18#endif
19
20#define RPC_ANONYMOUS_USERID ((uid_t)-2)
21#define RPC_ANONYMOUS_GROUPID ((gid_t)-2)
22
23struct generic_cred {
24 struct rpc_cred gc_base;
25 struct auth_cred acred;
26};
27
28static struct rpc_auth generic_auth;
29static struct rpc_cred_cache generic_cred_cache;
30static const struct rpc_credops generic_credops;
31
32/*
33 * Public call interface
34 */
35struct rpc_cred *rpc_lookup_cred(void)
36{
37 return rpcauth_lookupcred(&generic_auth, 0);
38}
39EXPORT_SYMBOL_GPL(rpc_lookup_cred);
40
41/*
42 * Public call interface for looking up machine creds.
43 */
44struct rpc_cred *rpc_lookup_machine_cred(void)
45{
46 struct auth_cred acred = {
47 .uid = RPC_ANONYMOUS_USERID,
48 .gid = RPC_ANONYMOUS_GROUPID,
49 .machine_cred = 1,
50 };
51
52 dprintk("RPC: looking up machine cred\n");
53 return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0);
54}
55EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);
56
57static void
58generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred)
59{
60 struct rpc_auth *auth = task->tk_client->cl_auth;
61 struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred;
62 struct rpc_cred *ret;
63
64 ret = auth->au_ops->lookup_cred(auth, acred, 0);
65 if (!IS_ERR(ret))
66 task->tk_msg.rpc_cred = ret;
67 else
68 task->tk_status = PTR_ERR(ret);
69}
70
71/*
72 * Lookup generic creds for current process
73 */
74static struct rpc_cred *
75generic_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
76{
77 return rpcauth_lookup_credcache(&generic_auth, acred, flags);
78}
79
80static struct rpc_cred *
81generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
82{
83 struct generic_cred *gcred;
84
85 gcred = kmalloc(sizeof(*gcred), GFP_KERNEL);
86 if (gcred == NULL)
87 return ERR_PTR(-ENOMEM);
88
89 rpcauth_init_cred(&gcred->gc_base, acred, &generic_auth, &generic_credops);
90 gcred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
91
92 gcred->acred.uid = acred->uid;
93 gcred->acred.gid = acred->gid;
94 gcred->acred.group_info = acred->group_info;
95 if (gcred->acred.group_info != NULL)
96 get_group_info(gcred->acred.group_info);
97 gcred->acred.machine_cred = acred->machine_cred;
98
99 dprintk("RPC: allocated %s cred %p for uid %d gid %d\n",
100 gcred->acred.machine_cred ? "machine" : "generic",
101 gcred, acred->uid, acred->gid);
102 return &gcred->gc_base;
103}
104
105static void
106generic_free_cred(struct rpc_cred *cred)
107{
108 struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
109
110 dprintk("RPC: generic_free_cred %p\n", gcred);
111 if (gcred->acred.group_info != NULL)
112 put_group_info(gcred->acred.group_info);
113 kfree(gcred);
114}
115
116static void
117generic_free_cred_callback(struct rcu_head *head)
118{
119 struct rpc_cred *cred = container_of(head, struct rpc_cred, cr_rcu);
120 generic_free_cred(cred);
121}
122
123static void
124generic_destroy_cred(struct rpc_cred *cred)
125{
126 call_rcu(&cred->cr_rcu, generic_free_cred_callback);
127}
128
129/*
130 * Match credentials against current process creds.
131 */
132static int
133generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
134{
135 struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
136
137 if (gcred->acred.uid != acred->uid ||
138 gcred->acred.gid != acred->gid ||
139 gcred->acred.group_info != acred->group_info ||
140 gcred->acred.machine_cred != acred->machine_cred)
141 return 0;
142 return 1;
143}
144
145void __init rpc_init_generic_auth(void)
146{
147 spin_lock_init(&generic_cred_cache.lock);
148}
149
150void __exit rpc_destroy_generic_auth(void)
151{
152 rpcauth_clear_credcache(&generic_cred_cache);
153}
154
155static struct rpc_cred_cache generic_cred_cache = {
156 {{ NULL, },},
157};
158
159static const struct rpc_authops generic_auth_ops = {
160 .owner = THIS_MODULE,
161 .au_name = "Generic",
162 .lookup_cred = generic_lookup_cred,
163 .crcreate = generic_create_cred,
164};
165
166static struct rpc_auth generic_auth = {
167 .au_ops = &generic_auth_ops,
168 .au_count = ATOMIC_INIT(0),
169 .au_credcache = &generic_cred_cache,
170};
171
172static const struct rpc_credops generic_credops = {
173 .cr_name = "Generic cred",
174 .crdestroy = generic_destroy_cred,
175 .crbind = generic_bind_cred,
176 .crmatch = generic_match,
177};
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 5828e5c060ca..cc12d5f5d5da 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -114,27 +114,14 @@ static void
114gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) 114gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
115{ 115{
116 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 116 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
117 struct gss_cl_ctx *old;
118 117
119 old = gss_cred->gc_ctx; 118 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
119 return;
120 gss_get_ctx(ctx);
120 rcu_assign_pointer(gss_cred->gc_ctx, ctx); 121 rcu_assign_pointer(gss_cred->gc_ctx, ctx);
121 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 122 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
123 smp_mb__before_clear_bit();
122 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); 124 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
123 if (old)
124 gss_put_ctx(old);
125}
126
127static int
128gss_cred_is_uptodate_ctx(struct rpc_cred *cred)
129{
130 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
131 int res = 0;
132
133 rcu_read_lock();
134 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) && gss_cred->gc_ctx)
135 res = 1;
136 rcu_read_unlock();
137 return res;
138} 125}
139 126
140static const void * 127static const void *
@@ -266,6 +253,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
266 BUG_ON(!list_empty(&gss_msg->list)); 253 BUG_ON(!list_empty(&gss_msg->list));
267 if (gss_msg->ctx != NULL) 254 if (gss_msg->ctx != NULL)
268 gss_put_ctx(gss_msg->ctx); 255 gss_put_ctx(gss_msg->ctx);
256 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
269 kfree(gss_msg); 257 kfree(gss_msg);
270} 258}
271 259
@@ -339,7 +327,7 @@ gss_upcall_callback(struct rpc_task *task)
339 327
340 spin_lock(&inode->i_lock); 328 spin_lock(&inode->i_lock);
341 if (gss_msg->ctx) 329 if (gss_msg->ctx)
342 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx)); 330 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_msg->ctx);
343 else 331 else
344 task->tk_status = gss_msg->msg.errno; 332 task->tk_status = gss_msg->msg.errno;
345 gss_cred->gc_upcall = NULL; 333 gss_cred->gc_upcall = NULL;
@@ -370,9 +358,16 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid)
370static struct gss_upcall_msg * 358static struct gss_upcall_msg *
371gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cred *cred) 359gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cred *cred)
372{ 360{
361 struct gss_cred *gss_cred = container_of(cred,
362 struct gss_cred, gc_base);
373 struct gss_upcall_msg *gss_new, *gss_msg; 363 struct gss_upcall_msg *gss_new, *gss_msg;
364 uid_t uid = cred->cr_uid;
374 365
375 gss_new = gss_alloc_msg(gss_auth, cred->cr_uid); 366 /* Special case: rpc.gssd assumes that uid == 0 implies machine creds */
367 if (gss_cred->gc_machine_cred != 0)
368 uid = 0;
369
370 gss_new = gss_alloc_msg(gss_auth, uid);
376 if (gss_new == NULL) 371 if (gss_new == NULL)
377 return ERR_PTR(-ENOMEM); 372 return ERR_PTR(-ENOMEM);
378 gss_msg = gss_add_msg(gss_auth, gss_new); 373 gss_msg = gss_add_msg(gss_auth, gss_new);
@@ -408,13 +403,17 @@ gss_refresh_upcall(struct rpc_task *task)
408 } 403 }
409 spin_lock(&inode->i_lock); 404 spin_lock(&inode->i_lock);
410 if (gss_cred->gc_upcall != NULL) 405 if (gss_cred->gc_upcall != NULL)
411 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL); 406 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL);
412 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { 407 else if (gss_msg->ctx != NULL) {
408 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_msg->ctx);
409 gss_cred->gc_upcall = NULL;
410 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
411 } else if (gss_msg->msg.errno >= 0) {
413 task->tk_timeout = 0; 412 task->tk_timeout = 0;
414 gss_cred->gc_upcall = gss_msg; 413 gss_cred->gc_upcall = gss_msg;
415 /* gss_upcall_callback will release the reference to gss_upcall_msg */ 414 /* gss_upcall_callback will release the reference to gss_upcall_msg */
416 atomic_inc(&gss_msg->count); 415 atomic_inc(&gss_msg->count);
417 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL); 416 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback);
418 } else 417 } else
419 err = gss_msg->msg.errno; 418 err = gss_msg->msg.errno;
420 spin_unlock(&inode->i_lock); 419 spin_unlock(&inode->i_lock);
@@ -454,7 +453,7 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
454 schedule(); 453 schedule();
455 } 454 }
456 if (gss_msg->ctx) 455 if (gss_msg->ctx)
457 gss_cred_set_ctx(cred, gss_get_ctx(gss_msg->ctx)); 456 gss_cred_set_ctx(cred, gss_msg->ctx);
458 else 457 else
459 err = gss_msg->msg.errno; 458 err = gss_msg->msg.errno;
460 spin_unlock(&inode->i_lock); 459 spin_unlock(&inode->i_lock);
@@ -709,7 +708,7 @@ gss_destroying_context(struct rpc_cred *cred)
709 struct rpc_task *task; 708 struct rpc_task *task;
710 709
711 if (gss_cred->gc_ctx == NULL || 710 if (gss_cred->gc_ctx == NULL ||
712 gss_cred->gc_ctx->gc_proc == RPC_GSS_PROC_DESTROY) 711 test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
713 return 0; 712 return 0;
714 713
715 gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY; 714 gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY;
@@ -719,7 +718,7 @@ gss_destroying_context(struct rpc_cred *cred)
719 * by the RPC call or by the put_rpccred() below */ 718 * by the RPC call or by the put_rpccred() below */
720 get_rpccred(cred); 719 get_rpccred(cred);
721 720
722 task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC); 721 task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC|RPC_TASK_SOFT);
723 if (!IS_ERR(task)) 722 if (!IS_ERR(task))
724 rpc_put_task(task); 723 rpc_put_task(task);
725 724
@@ -817,6 +816,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
817 */ 816 */
818 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; 817 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
819 cred->gc_service = gss_auth->service; 818 cred->gc_service = gss_auth->service;
819 cred->gc_machine_cred = acred->machine_cred;
820 kref_get(&gss_auth->kref); 820 kref_get(&gss_auth->kref);
821 return &cred->gc_base; 821 return &cred->gc_base;
822 822
@@ -843,17 +843,16 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
843{ 843{
844 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 844 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
845 845
846 /* 846 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
847 * If the searchflags have set RPCAUTH_LOOKUP_NEW, then
848 * we don't really care if the credential has expired or not,
849 * since the caller should be prepared to reinitialise it.
850 */
851 if ((flags & RPCAUTH_LOOKUP_NEW) && test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
852 goto out; 847 goto out;
853 /* Don't match with creds that have expired. */ 848 /* Don't match with creds that have expired. */
854 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) 849 if (time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
850 return 0;
851 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags))
855 return 0; 852 return 0;
856out: 853out:
854 if (acred->machine_cred != gss_cred->gc_machine_cred)
855 return 0;
857 return (rc->cr_uid == acred->uid); 856 return (rc->cr_uid == acred->uid);
858} 857}
859 858
@@ -917,16 +916,48 @@ out_put_ctx:
917 return NULL; 916 return NULL;
918} 917}
919 918
919static int gss_renew_cred(struct rpc_task *task)
920{
921 struct rpc_cred *oldcred = task->tk_msg.rpc_cred;
922 struct gss_cred *gss_cred = container_of(oldcred,
923 struct gss_cred,
924 gc_base);
925 struct rpc_auth *auth = oldcred->cr_auth;
926 struct auth_cred acred = {
927 .uid = oldcred->cr_uid,
928 .machine_cred = gss_cred->gc_machine_cred,
929 };
930 struct rpc_cred *new;
931
932 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
933 if (IS_ERR(new))
934 return PTR_ERR(new);
935 task->tk_msg.rpc_cred = new;
936 put_rpccred(oldcred);
937 return 0;
938}
939
920/* 940/*
921* Refresh credentials. XXX - finish 941* Refresh credentials. XXX - finish
922*/ 942*/
923static int 943static int
924gss_refresh(struct rpc_task *task) 944gss_refresh(struct rpc_task *task)
925{ 945{
946 struct rpc_cred *cred = task->tk_msg.rpc_cred;
947 int ret = 0;
948
949 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
950 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) {
951 ret = gss_renew_cred(task);
952 if (ret < 0)
953 goto out;
954 cred = task->tk_msg.rpc_cred;
955 }
926 956
927 if (!gss_cred_is_uptodate_ctx(task->tk_msg.rpc_cred)) 957 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
928 return gss_refresh_upcall(task); 958 ret = gss_refresh_upcall(task);
929 return 0; 959out:
960 return ret;
930} 961}
931 962
932/* Dummy refresh routine: used only when destroying the context */ 963/* Dummy refresh routine: used only when destroying the context */
@@ -1286,9 +1317,7 @@ out:
1286static const struct rpc_authops authgss_ops = { 1317static const struct rpc_authops authgss_ops = {
1287 .owner = THIS_MODULE, 1318 .owner = THIS_MODULE,
1288 .au_flavor = RPC_AUTH_GSS, 1319 .au_flavor = RPC_AUTH_GSS,
1289#ifdef RPC_DEBUG
1290 .au_name = "RPCSEC_GSS", 1320 .au_name = "RPCSEC_GSS",
1291#endif
1292 .create = gss_create, 1321 .create = gss_create,
1293 .destroy = gss_destroy, 1322 .destroy = gss_destroy,
1294 .lookup_cred = gss_lookup_cred, 1323 .lookup_cred = gss_lookup_cred,
@@ -1299,6 +1328,7 @@ static const struct rpc_credops gss_credops = {
1299 .cr_name = "AUTH_GSS", 1328 .cr_name = "AUTH_GSS",
1300 .crdestroy = gss_destroy_cred, 1329 .crdestroy = gss_destroy_cred,
1301 .cr_init = gss_cred_init, 1330 .cr_init = gss_cred_init,
1331 .crbind = rpcauth_generic_bind_cred,
1302 .crmatch = gss_match, 1332 .crmatch = gss_match,
1303 .crmarshal = gss_marshal, 1333 .crmarshal = gss_marshal,
1304 .crrefresh = gss_refresh, 1334 .crrefresh = gss_refresh,
@@ -1310,6 +1340,7 @@ static const struct rpc_credops gss_credops = {
1310static const struct rpc_credops gss_nullops = { 1340static const struct rpc_credops gss_nullops = {
1311 .cr_name = "AUTH_GSS", 1341 .cr_name = "AUTH_GSS",
1312 .crdestroy = gss_destroy_cred, 1342 .crdestroy = gss_destroy_cred,
1343 .crbind = rpcauth_generic_bind_cred,
1313 .crmatch = gss_match, 1344 .crmatch = gss_match,
1314 .crmarshal = gss_marshal, 1345 .crmarshal = gss_marshal,
1315 .crrefresh = gss_refresh_null, 1346 .crrefresh = gss_refresh_null,
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 537d0e8589dd..c70dd7f5258e 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -104,9 +104,7 @@ nul_validate(struct rpc_task *task, __be32 *p)
104const struct rpc_authops authnull_ops = { 104const struct rpc_authops authnull_ops = {
105 .owner = THIS_MODULE, 105 .owner = THIS_MODULE,
106 .au_flavor = RPC_AUTH_NULL, 106 .au_flavor = RPC_AUTH_NULL,
107#ifdef RPC_DEBUG
108 .au_name = "NULL", 107 .au_name = "NULL",
109#endif
110 .create = nul_create, 108 .create = nul_create,
111 .destroy = nul_destroy, 109 .destroy = nul_destroy,
112 .lookup_cred = nul_lookup_cred, 110 .lookup_cred = nul_lookup_cred,
@@ -125,6 +123,7 @@ static
125const struct rpc_credops null_credops = { 123const struct rpc_credops null_credops = {
126 .cr_name = "AUTH_NULL", 124 .cr_name = "AUTH_NULL",
127 .crdestroy = nul_destroy_cred, 125 .crdestroy = nul_destroy_cred,
126 .crbind = rpcauth_generic_bind_cred,
128 .crmatch = nul_match, 127 .crmatch = nul_match,
129 .crmarshal = nul_marshal, 128 .crmarshal = nul_marshal,
130 .crrefresh = nul_refresh, 129 .crrefresh = nul_refresh,
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 5ed91e5bcee4..44920b90bdc4 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -60,7 +60,8 @@ static struct rpc_cred *
60unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) 60unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
61{ 61{
62 struct unx_cred *cred; 62 struct unx_cred *cred;
63 int i; 63 unsigned int groups = 0;
64 unsigned int i;
64 65
65 dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", 66 dprintk("RPC: allocating UNIX cred for uid %d gid %d\n",
66 acred->uid, acred->gid); 67 acred->uid, acred->gid);
@@ -70,21 +71,17 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
70 71
71 rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); 72 rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
72 cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; 73 cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
73 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { 74
74 cred->uc_uid = 0; 75 if (acred->group_info != NULL)
75 cred->uc_gid = 0; 76 groups = acred->group_info->ngroups;
76 cred->uc_gids[0] = NOGROUP; 77 if (groups > NFS_NGROUPS)
77 } else { 78 groups = NFS_NGROUPS;
78 int groups = acred->group_info->ngroups; 79
79 if (groups > NFS_NGROUPS) 80 cred->uc_gid = acred->gid;
80 groups = NFS_NGROUPS; 81 for (i = 0; i < groups; i++)
81 82 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
82 cred->uc_gid = acred->gid; 83 if (i < NFS_NGROUPS)
83 for (i = 0; i < groups; i++) 84 cred->uc_gids[i] = NOGROUP;
84 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
85 if (i < NFS_NGROUPS)
86 cred->uc_gids[i] = NOGROUP;
87 }
88 85
89 return &cred->uc_base; 86 return &cred->uc_base;
90} 87}
@@ -118,26 +115,21 @@ static int
118unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) 115unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
119{ 116{
120 struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base); 117 struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
121 int i; 118 unsigned int groups = 0;
119 unsigned int i;
122 120
123 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
124 int groups;
125 121
126 if (cred->uc_uid != acred->uid 122 if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid)
127 || cred->uc_gid != acred->gid) 123 return 0;
128 return 0;
129 124
125 if (acred->group_info != NULL)
130 groups = acred->group_info->ngroups; 126 groups = acred->group_info->ngroups;
131 if (groups > NFS_NGROUPS) 127 if (groups > NFS_NGROUPS)
132 groups = NFS_NGROUPS; 128 groups = NFS_NGROUPS;
133 for (i = 0; i < groups ; i++) 129 for (i = 0; i < groups ; i++)
134 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i)) 130 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
135 return 0; 131 return 0;
136 return 1; 132 return 1;
137 }
138 return (cred->uc_uid == 0
139 && cred->uc_gid == 0
140 && cred->uc_gids[0] == (gid_t) NOGROUP);
141} 133}
142 134
143/* 135/*
@@ -218,9 +210,7 @@ void __init rpc_init_authunix(void)
218const struct rpc_authops authunix_ops = { 210const struct rpc_authops authunix_ops = {
219 .owner = THIS_MODULE, 211 .owner = THIS_MODULE,
220 .au_flavor = RPC_AUTH_UNIX, 212 .au_flavor = RPC_AUTH_UNIX,
221#ifdef RPC_DEBUG
222 .au_name = "UNIX", 213 .au_name = "UNIX",
223#endif
224 .create = unx_create, 214 .create = unx_create,
225 .destroy = unx_destroy, 215 .destroy = unx_destroy,
226 .lookup_cred = unx_lookup_cred, 216 .lookup_cred = unx_lookup_cred,
@@ -245,6 +235,7 @@ static
245const struct rpc_credops unix_credops = { 235const struct rpc_credops unix_credops = {
246 .cr_name = "AUTH_UNIX", 236 .cr_name = "AUTH_UNIX",
247 .crdestroy = unx_destroy_cred, 237 .crdestroy = unx_destroy_cred,
238 .crbind = rpcauth_generic_bind_cred,
248 .crmatch = unx_match, 239 .crmatch = unx_match,
249 .crmarshal = unx_marshal, 240 .crmarshal = unx_marshal,
250 .crrefresh = unx_refresh, 241 .crrefresh = unx_refresh,
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 7b96ff38002f..8945307556ec 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -544,7 +544,7 @@ EXPORT_SYMBOL_GPL(rpc_run_task);
544 * @msg: RPC call parameters 544 * @msg: RPC call parameters
545 * @flags: RPC call flags 545 * @flags: RPC call flags
546 */ 546 */
547int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) 547int rpc_call_sync(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags)
548{ 548{
549 struct rpc_task *task; 549 struct rpc_task *task;
550 struct rpc_task_setup task_setup_data = { 550 struct rpc_task_setup task_setup_data = {
@@ -575,7 +575,7 @@ EXPORT_SYMBOL_GPL(rpc_call_sync);
575 * @data: user call data 575 * @data: user call data
576 */ 576 */
577int 577int
578rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, 578rpc_call_async(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags,
579 const struct rpc_call_ops *tk_ops, void *data) 579 const struct rpc_call_ops *tk_ops, void *data)
580{ 580{
581 struct rpc_task *task; 581 struct rpc_task *task;
@@ -1062,7 +1062,7 @@ call_transmit(struct rpc_task *task)
1062 if (task->tk_msg.rpc_proc->p_decode != NULL) 1062 if (task->tk_msg.rpc_proc->p_decode != NULL)
1063 return; 1063 return;
1064 task->tk_action = rpc_exit_task; 1064 task->tk_action = rpc_exit_task;
1065 rpc_wake_up_task(task); 1065 rpc_wake_up_queued_task(&task->tk_xprt->pending, task);
1066} 1066}
1067 1067
1068/* 1068/*
@@ -1116,7 +1116,8 @@ call_status(struct rpc_task *task)
1116 case -ETIMEDOUT: 1116 case -ETIMEDOUT:
1117 task->tk_action = call_timeout; 1117 task->tk_action = call_timeout;
1118 if (task->tk_client->cl_discrtry) 1118 if (task->tk_client->cl_discrtry)
1119 xprt_force_disconnect(task->tk_xprt); 1119 xprt_conditional_disconnect(task->tk_xprt,
1120 req->rq_connect_cookie);
1120 break; 1121 break;
1121 case -ECONNREFUSED: 1122 case -ECONNREFUSED:
1122 case -ENOTCONN: 1123 case -ENOTCONN:
@@ -1168,6 +1169,11 @@ call_timeout(struct rpc_task *task)
1168 clnt->cl_protname, clnt->cl_server); 1169 clnt->cl_protname, clnt->cl_server);
1169 } 1170 }
1170 rpc_force_rebind(clnt); 1171 rpc_force_rebind(clnt);
1172 /*
1173 * Did our request time out due to an RPCSEC_GSS out-of-sequence
1174 * event? RFC2203 requires the server to drop all such requests.
1175 */
1176 rpcauth_invalcred(task);
1171 1177
1172retry: 1178retry:
1173 clnt->cl_stats->rpcretrans++; 1179 clnt->cl_stats->rpcretrans++;
@@ -1195,18 +1201,6 @@ call_decode(struct rpc_task *task)
1195 task->tk_flags &= ~RPC_CALL_MAJORSEEN; 1201 task->tk_flags &= ~RPC_CALL_MAJORSEEN;
1196 } 1202 }
1197 1203
1198 if (task->tk_status < 12) {
1199 if (!RPC_IS_SOFT(task)) {
1200 task->tk_action = call_bind;
1201 clnt->cl_stats->rpcretrans++;
1202 goto out_retry;
1203 }
1204 dprintk("RPC: %s: too small RPC reply size (%d bytes)\n",
1205 clnt->cl_protname, task->tk_status);
1206 task->tk_action = call_timeout;
1207 goto out_retry;
1208 }
1209
1210 /* 1204 /*
1211 * Ensure that we see all writes made by xprt_complete_rqst() 1205 * Ensure that we see all writes made by xprt_complete_rqst()
1212 * before it changed req->rq_received. 1206 * before it changed req->rq_received.
@@ -1218,6 +1212,18 @@ call_decode(struct rpc_task *task)
1218 WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf, 1212 WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf,
1219 sizeof(req->rq_rcv_buf)) != 0); 1213 sizeof(req->rq_rcv_buf)) != 0);
1220 1214
1215 if (req->rq_rcv_buf.len < 12) {
1216 if (!RPC_IS_SOFT(task)) {
1217 task->tk_action = call_bind;
1218 clnt->cl_stats->rpcretrans++;
1219 goto out_retry;
1220 }
1221 dprintk("RPC: %s: too small RPC reply size (%d bytes)\n",
1222 clnt->cl_protname, task->tk_status);
1223 task->tk_action = call_timeout;
1224 goto out_retry;
1225 }
1226
1221 /* Verify the RPC header */ 1227 /* Verify the RPC header */
1222 p = call_verify(task); 1228 p = call_verify(task);
1223 if (IS_ERR(p)) { 1229 if (IS_ERR(p)) {
@@ -1236,10 +1242,14 @@ call_decode(struct rpc_task *task)
1236 task->tk_status); 1242 task->tk_status);
1237 return; 1243 return;
1238out_retry: 1244out_retry:
1239 req->rq_received = req->rq_private_buf.len = 0;
1240 task->tk_status = 0; 1245 task->tk_status = 0;
1241 if (task->tk_client->cl_discrtry) 1246 /* Note: call_verify() may have freed the RPC slot */
1242 xprt_force_disconnect(task->tk_xprt); 1247 if (task->tk_rqstp == req) {
1248 req->rq_received = req->rq_rcv_buf.len = 0;
1249 if (task->tk_client->cl_discrtry)
1250 xprt_conditional_disconnect(task->tk_xprt,
1251 req->rq_connect_cookie);
1252 }
1243} 1253}
1244 1254
1245/* 1255/*
@@ -1531,7 +1541,7 @@ void rpc_show_tasks(void)
1531 proc = -1; 1541 proc = -1;
1532 1542
1533 if (RPC_IS_QUEUED(t)) 1543 if (RPC_IS_QUEUED(t))
1534 rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq); 1544 rpc_waitq = rpc_qname(t->tk_waitqueue);
1535 1545
1536 printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", 1546 printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
1537 t->tk_pid, proc, 1547 t->tk_pid, proc,
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 56aa018dce3a..0517967a68bf 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -298,7 +298,7 @@ void rpcb_getport_async(struct rpc_task *task)
298 298
299 /* Put self on queue before sending rpcbind request, in case 299 /* Put self on queue before sending rpcbind request, in case
300 * rpcb_getport_done completes before we return from rpc_run_task */ 300 * rpcb_getport_done completes before we return from rpc_run_task */
301 rpc_sleep_on(&xprt->binding, task, NULL, NULL); 301 rpc_sleep_on(&xprt->binding, task, NULL);
302 302
303 /* Someone else may have bound if we slept */ 303 /* Someone else may have bound if we slept */
304 if (xprt_bound(xprt)) { 304 if (xprt_bound(xprt)) {
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 4c669121e607..6eab9bf94baf 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -38,9 +38,9 @@ static struct kmem_cache *rpc_buffer_slabp __read_mostly;
38static mempool_t *rpc_task_mempool __read_mostly; 38static mempool_t *rpc_task_mempool __read_mostly;
39static mempool_t *rpc_buffer_mempool __read_mostly; 39static mempool_t *rpc_buffer_mempool __read_mostly;
40 40
41static void __rpc_default_timer(struct rpc_task *task);
42static void rpc_async_schedule(struct work_struct *); 41static void rpc_async_schedule(struct work_struct *);
43static void rpc_release_task(struct rpc_task *task); 42static void rpc_release_task(struct rpc_task *task);
43static void __rpc_queue_timer_fn(unsigned long ptr);
44 44
45/* 45/*
46 * RPC tasks sit here while waiting for conditions to improve. 46 * RPC tasks sit here while waiting for conditions to improve.
@@ -57,41 +57,30 @@ struct workqueue_struct *rpciod_workqueue;
57 * queue->lock and bh_disabled in order to avoid races within 57 * queue->lock and bh_disabled in order to avoid races within
58 * rpc_run_timer(). 58 * rpc_run_timer().
59 */ 59 */
60static inline void 60static void
61__rpc_disable_timer(struct rpc_task *task) 61__rpc_disable_timer(struct rpc_wait_queue *queue, struct rpc_task *task)
62{ 62{
63 if (task->tk_timeout == 0)
64 return;
63 dprintk("RPC: %5u disabling timer\n", task->tk_pid); 65 dprintk("RPC: %5u disabling timer\n", task->tk_pid);
64 task->tk_timeout_fn = NULL;
65 task->tk_timeout = 0; 66 task->tk_timeout = 0;
67 list_del(&task->u.tk_wait.timer_list);
68 if (list_empty(&queue->timer_list.list))
69 del_timer(&queue->timer_list.timer);
66} 70}
67 71
68/* 72static void
69 * Run a timeout function. 73rpc_set_queue_timer(struct rpc_wait_queue *queue, unsigned long expires)
70 * We use the callback in order to allow __rpc_wake_up_task()
71 * and friends to disable the timer synchronously on SMP systems
72 * without calling del_timer_sync(). The latter could cause a
73 * deadlock if called while we're holding spinlocks...
74 */
75static void rpc_run_timer(struct rpc_task *task)
76{ 74{
77 void (*callback)(struct rpc_task *); 75 queue->timer_list.expires = expires;
78 76 mod_timer(&queue->timer_list.timer, expires);
79 callback = task->tk_timeout_fn;
80 task->tk_timeout_fn = NULL;
81 if (callback && RPC_IS_QUEUED(task)) {
82 dprintk("RPC: %5u running timer\n", task->tk_pid);
83 callback(task);
84 }
85 smp_mb__before_clear_bit();
86 clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate);
87 smp_mb__after_clear_bit();
88} 77}
89 78
90/* 79/*
91 * Set up a timer for the current task. 80 * Set up a timer for the current task.
92 */ 81 */
93static inline void 82static void
94__rpc_add_timer(struct rpc_task *task, rpc_action timer) 83__rpc_add_timer(struct rpc_wait_queue *queue, struct rpc_task *task)
95{ 84{
96 if (!task->tk_timeout) 85 if (!task->tk_timeout)
97 return; 86 return;
@@ -99,27 +88,10 @@ __rpc_add_timer(struct rpc_task *task, rpc_action timer)
99 dprintk("RPC: %5u setting alarm for %lu ms\n", 88 dprintk("RPC: %5u setting alarm for %lu ms\n",
100 task->tk_pid, task->tk_timeout * 1000 / HZ); 89 task->tk_pid, task->tk_timeout * 1000 / HZ);
101 90
102 if (timer) 91 task->u.tk_wait.expires = jiffies + task->tk_timeout;
103 task->tk_timeout_fn = timer; 92 if (list_empty(&queue->timer_list.list) || time_before(task->u.tk_wait.expires, queue->timer_list.expires))
104 else 93 rpc_set_queue_timer(queue, task->u.tk_wait.expires);
105 task->tk_timeout_fn = __rpc_default_timer; 94 list_add(&task->u.tk_wait.timer_list, &queue->timer_list.list);
106 set_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate);
107 mod_timer(&task->tk_timer, jiffies + task->tk_timeout);
108}
109
110/*
111 * Delete any timer for the current task. Because we use del_timer_sync(),
112 * this function should never be called while holding queue->lock.
113 */
114static void
115rpc_delete_timer(struct rpc_task *task)
116{
117 if (RPC_IS_QUEUED(task))
118 return;
119 if (test_and_clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate)) {
120 del_singleshot_timer_sync(&task->tk_timer);
121 dprintk("RPC: %5u deleting timer\n", task->tk_pid);
122 }
123} 95}
124 96
125/* 97/*
@@ -161,7 +133,7 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *
161 list_add(&task->u.tk_wait.list, &queue->tasks[0]); 133 list_add(&task->u.tk_wait.list, &queue->tasks[0]);
162 else 134 else
163 list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]); 135 list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]);
164 task->u.tk_wait.rpc_waitq = queue; 136 task->tk_waitqueue = queue;
165 queue->qlen++; 137 queue->qlen++;
166 rpc_set_queued(task); 138 rpc_set_queued(task);
167 139
@@ -181,22 +153,18 @@ static void __rpc_remove_wait_queue_priority(struct rpc_task *task)
181 list_move(&t->u.tk_wait.list, &task->u.tk_wait.list); 153 list_move(&t->u.tk_wait.list, &task->u.tk_wait.list);
182 list_splice_init(&task->u.tk_wait.links, &t->u.tk_wait.links); 154 list_splice_init(&task->u.tk_wait.links, &t->u.tk_wait.links);
183 } 155 }
184 list_del(&task->u.tk_wait.list);
185} 156}
186 157
187/* 158/*
188 * Remove request from queue. 159 * Remove request from queue.
189 * Note: must be called with spin lock held. 160 * Note: must be called with spin lock held.
190 */ 161 */
191static void __rpc_remove_wait_queue(struct rpc_task *task) 162static void __rpc_remove_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task)
192{ 163{
193 struct rpc_wait_queue *queue; 164 __rpc_disable_timer(queue, task);
194 queue = task->u.tk_wait.rpc_waitq;
195
196 if (RPC_IS_PRIORITY(queue)) 165 if (RPC_IS_PRIORITY(queue))
197 __rpc_remove_wait_queue_priority(task); 166 __rpc_remove_wait_queue_priority(task);
198 else 167 list_del(&task->u.tk_wait.list);
199 list_del(&task->u.tk_wait.list);
200 queue->qlen--; 168 queue->qlen--;
201 dprintk("RPC: %5u removed from queue %p \"%s\"\n", 169 dprintk("RPC: %5u removed from queue %p \"%s\"\n",
202 task->tk_pid, queue, rpc_qname(queue)); 170 task->tk_pid, queue, rpc_qname(queue));
@@ -229,6 +197,9 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c
229 INIT_LIST_HEAD(&queue->tasks[i]); 197 INIT_LIST_HEAD(&queue->tasks[i]);
230 queue->maxpriority = nr_queues - 1; 198 queue->maxpriority = nr_queues - 1;
231 rpc_reset_waitqueue_priority(queue); 199 rpc_reset_waitqueue_priority(queue);
200 queue->qlen = 0;
201 setup_timer(&queue->timer_list.timer, __rpc_queue_timer_fn, (unsigned long)queue);
202 INIT_LIST_HEAD(&queue->timer_list.list);
232#ifdef RPC_DEBUG 203#ifdef RPC_DEBUG
233 queue->name = qname; 204 queue->name = qname;
234#endif 205#endif
@@ -245,6 +216,12 @@ void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname)
245} 216}
246EXPORT_SYMBOL_GPL(rpc_init_wait_queue); 217EXPORT_SYMBOL_GPL(rpc_init_wait_queue);
247 218
219void rpc_destroy_wait_queue(struct rpc_wait_queue *queue)
220{
221 del_timer_sync(&queue->timer_list.timer);
222}
223EXPORT_SYMBOL_GPL(rpc_destroy_wait_queue);
224
248static int rpc_wait_bit_killable(void *word) 225static int rpc_wait_bit_killable(void *word)
249{ 226{
250 if (fatal_signal_pending(current)) 227 if (fatal_signal_pending(current))
@@ -313,7 +290,6 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task);
313 */ 290 */
314static void rpc_make_runnable(struct rpc_task *task) 291static void rpc_make_runnable(struct rpc_task *task)
315{ 292{
316 BUG_ON(task->tk_timeout_fn);
317 rpc_clear_queued(task); 293 rpc_clear_queued(task);
318 if (rpc_test_and_set_running(task)) 294 if (rpc_test_and_set_running(task))
319 return; 295 return;
@@ -326,7 +302,7 @@ static void rpc_make_runnable(struct rpc_task *task)
326 int status; 302 int status;
327 303
328 INIT_WORK(&task->u.tk_work, rpc_async_schedule); 304 INIT_WORK(&task->u.tk_work, rpc_async_schedule);
329 status = queue_work(task->tk_workqueue, &task->u.tk_work); 305 status = queue_work(rpciod_workqueue, &task->u.tk_work);
330 if (status < 0) { 306 if (status < 0) {
331 printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status); 307 printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status);
332 task->tk_status = status; 308 task->tk_status = status;
@@ -343,7 +319,7 @@ static void rpc_make_runnable(struct rpc_task *task)
343 * as it's on a wait queue. 319 * as it's on a wait queue.
344 */ 320 */
345static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, 321static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
346 rpc_action action, rpc_action timer) 322 rpc_action action)
347{ 323{
348 dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", 324 dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
349 task->tk_pid, rpc_qname(q), jiffies); 325 task->tk_pid, rpc_qname(q), jiffies);
@@ -357,11 +333,11 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
357 333
358 BUG_ON(task->tk_callback != NULL); 334 BUG_ON(task->tk_callback != NULL);
359 task->tk_callback = action; 335 task->tk_callback = action;
360 __rpc_add_timer(task, timer); 336 __rpc_add_timer(q, task);
361} 337}
362 338
363void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, 339void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
364 rpc_action action, rpc_action timer) 340 rpc_action action)
365{ 341{
366 /* Mark the task as being activated if so needed */ 342 /* Mark the task as being activated if so needed */
367 rpc_set_active(task); 343 rpc_set_active(task);
@@ -370,18 +346,19 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
370 * Protect the queue operations. 346 * Protect the queue operations.
371 */ 347 */
372 spin_lock_bh(&q->lock); 348 spin_lock_bh(&q->lock);
373 __rpc_sleep_on(q, task, action, timer); 349 __rpc_sleep_on(q, task, action);
374 spin_unlock_bh(&q->lock); 350 spin_unlock_bh(&q->lock);
375} 351}
376EXPORT_SYMBOL_GPL(rpc_sleep_on); 352EXPORT_SYMBOL_GPL(rpc_sleep_on);
377 353
378/** 354/**
379 * __rpc_do_wake_up_task - wake up a single rpc_task 355 * __rpc_do_wake_up_task - wake up a single rpc_task
356 * @queue: wait queue
380 * @task: task to be woken up 357 * @task: task to be woken up
381 * 358 *
382 * Caller must hold queue->lock, and have cleared the task queued flag. 359 * Caller must hold queue->lock, and have cleared the task queued flag.
383 */ 360 */
384static void __rpc_do_wake_up_task(struct rpc_task *task) 361static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task *task)
385{ 362{
386 dprintk("RPC: %5u __rpc_wake_up_task (now %lu)\n", 363 dprintk("RPC: %5u __rpc_wake_up_task (now %lu)\n",
387 task->tk_pid, jiffies); 364 task->tk_pid, jiffies);
@@ -395,8 +372,7 @@ static void __rpc_do_wake_up_task(struct rpc_task *task)
395 return; 372 return;
396 } 373 }
397 374
398 __rpc_disable_timer(task); 375 __rpc_remove_wait_queue(queue, task);
399 __rpc_remove_wait_queue(task);
400 376
401 rpc_make_runnable(task); 377 rpc_make_runnable(task);
402 378
@@ -404,48 +380,32 @@ static void __rpc_do_wake_up_task(struct rpc_task *task)
404} 380}
405 381
406/* 382/*
407 * Wake up the specified task 383 * Wake up a queued task while the queue lock is being held
408 */ 384 */
409static void __rpc_wake_up_task(struct rpc_task *task) 385static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct rpc_task *task)
410{ 386{
411 if (rpc_start_wakeup(task)) { 387 if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue)
412 if (RPC_IS_QUEUED(task)) 388 __rpc_do_wake_up_task(queue, task);
413 __rpc_do_wake_up_task(task);
414 rpc_finish_wakeup(task);
415 }
416} 389}
417 390
418/* 391/*
419 * Default timeout handler if none specified by user 392 * Wake up a task on a specific queue
420 */ 393 */
421static void 394void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task)
422__rpc_default_timer(struct rpc_task *task)
423{ 395{
424 dprintk("RPC: %5u timeout (default timer)\n", task->tk_pid); 396 spin_lock_bh(&queue->lock);
425 task->tk_status = -ETIMEDOUT; 397 rpc_wake_up_task_queue_locked(queue, task);
426 rpc_wake_up_task(task); 398 spin_unlock_bh(&queue->lock);
427} 399}
400EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task);
428 401
429/* 402/*
430 * Wake up the specified task 403 * Wake up the specified task
431 */ 404 */
432void rpc_wake_up_task(struct rpc_task *task) 405static void rpc_wake_up_task(struct rpc_task *task)
433{ 406{
434 rcu_read_lock_bh(); 407 rpc_wake_up_queued_task(task->tk_waitqueue, task);
435 if (rpc_start_wakeup(task)) {
436 if (RPC_IS_QUEUED(task)) {
437 struct rpc_wait_queue *queue = task->u.tk_wait.rpc_waitq;
438
439 /* Note: we're already in a bh-safe context */
440 spin_lock(&queue->lock);
441 __rpc_do_wake_up_task(task);
442 spin_unlock(&queue->lock);
443 }
444 rpc_finish_wakeup(task);
445 }
446 rcu_read_unlock_bh();
447} 408}
448EXPORT_SYMBOL_GPL(rpc_wake_up_task);
449 409
450/* 410/*
451 * Wake up the next task on a priority queue. 411 * Wake up the next task on a priority queue.
@@ -495,7 +455,7 @@ new_queue:
495new_owner: 455new_owner:
496 rpc_set_waitqueue_owner(queue, task->tk_owner); 456 rpc_set_waitqueue_owner(queue, task->tk_owner);
497out: 457out:
498 __rpc_wake_up_task(task); 458 rpc_wake_up_task_queue_locked(queue, task);
499 return task; 459 return task;
500} 460}
501 461
@@ -508,16 +468,14 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue)
508 468
509 dprintk("RPC: wake_up_next(%p \"%s\")\n", 469 dprintk("RPC: wake_up_next(%p \"%s\")\n",
510 queue, rpc_qname(queue)); 470 queue, rpc_qname(queue));
511 rcu_read_lock_bh(); 471 spin_lock_bh(&queue->lock);
512 spin_lock(&queue->lock);
513 if (RPC_IS_PRIORITY(queue)) 472 if (RPC_IS_PRIORITY(queue))
514 task = __rpc_wake_up_next_priority(queue); 473 task = __rpc_wake_up_next_priority(queue);
515 else { 474 else {
516 task_for_first(task, &queue->tasks[0]) 475 task_for_first(task, &queue->tasks[0])
517 __rpc_wake_up_task(task); 476 rpc_wake_up_task_queue_locked(queue, task);
518 } 477 }
519 spin_unlock(&queue->lock); 478 spin_unlock_bh(&queue->lock);
520 rcu_read_unlock_bh();
521 479
522 return task; 480 return task;
523} 481}
@@ -534,18 +492,16 @@ void rpc_wake_up(struct rpc_wait_queue *queue)
534 struct rpc_task *task, *next; 492 struct rpc_task *task, *next;
535 struct list_head *head; 493 struct list_head *head;
536 494
537 rcu_read_lock_bh(); 495 spin_lock_bh(&queue->lock);
538 spin_lock(&queue->lock);
539 head = &queue->tasks[queue->maxpriority]; 496 head = &queue->tasks[queue->maxpriority];
540 for (;;) { 497 for (;;) {
541 list_for_each_entry_safe(task, next, head, u.tk_wait.list) 498 list_for_each_entry_safe(task, next, head, u.tk_wait.list)
542 __rpc_wake_up_task(task); 499 rpc_wake_up_task_queue_locked(queue, task);
543 if (head == &queue->tasks[0]) 500 if (head == &queue->tasks[0])
544 break; 501 break;
545 head--; 502 head--;
546 } 503 }
547 spin_unlock(&queue->lock); 504 spin_unlock_bh(&queue->lock);
548 rcu_read_unlock_bh();
549} 505}
550EXPORT_SYMBOL_GPL(rpc_wake_up); 506EXPORT_SYMBOL_GPL(rpc_wake_up);
551 507
@@ -561,26 +517,48 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
561 struct rpc_task *task, *next; 517 struct rpc_task *task, *next;
562 struct list_head *head; 518 struct list_head *head;
563 519
564 rcu_read_lock_bh(); 520 spin_lock_bh(&queue->lock);
565 spin_lock(&queue->lock);
566 head = &queue->tasks[queue->maxpriority]; 521 head = &queue->tasks[queue->maxpriority];
567 for (;;) { 522 for (;;) {
568 list_for_each_entry_safe(task, next, head, u.tk_wait.list) { 523 list_for_each_entry_safe(task, next, head, u.tk_wait.list) {
569 task->tk_status = status; 524 task->tk_status = status;
570 __rpc_wake_up_task(task); 525 rpc_wake_up_task_queue_locked(queue, task);
571 } 526 }
572 if (head == &queue->tasks[0]) 527 if (head == &queue->tasks[0])
573 break; 528 break;
574 head--; 529 head--;
575 } 530 }
576 spin_unlock(&queue->lock); 531 spin_unlock_bh(&queue->lock);
577 rcu_read_unlock_bh();
578} 532}
579EXPORT_SYMBOL_GPL(rpc_wake_up_status); 533EXPORT_SYMBOL_GPL(rpc_wake_up_status);
580 534
535static void __rpc_queue_timer_fn(unsigned long ptr)
536{
537 struct rpc_wait_queue *queue = (struct rpc_wait_queue *)ptr;
538 struct rpc_task *task, *n;
539 unsigned long expires, now, timeo;
540
541 spin_lock(&queue->lock);
542 expires = now = jiffies;
543 list_for_each_entry_safe(task, n, &queue->timer_list.list, u.tk_wait.timer_list) {
544 timeo = task->u.tk_wait.expires;
545 if (time_after_eq(now, timeo)) {
546 dprintk("RPC: %5u timeout\n", task->tk_pid);
547 task->tk_status = -ETIMEDOUT;
548 rpc_wake_up_task_queue_locked(queue, task);
549 continue;
550 }
551 if (expires == now || time_after(expires, timeo))
552 expires = timeo;
553 }
554 if (!list_empty(&queue->timer_list.list))
555 rpc_set_queue_timer(queue, expires);
556 spin_unlock(&queue->lock);
557}
558
581static void __rpc_atrun(struct rpc_task *task) 559static void __rpc_atrun(struct rpc_task *task)
582{ 560{
583 rpc_wake_up_task(task); 561 task->tk_status = 0;
584} 562}
585 563
586/* 564/*
@@ -589,7 +567,7 @@ static void __rpc_atrun(struct rpc_task *task)
589void rpc_delay(struct rpc_task *task, unsigned long delay) 567void rpc_delay(struct rpc_task *task, unsigned long delay)
590{ 568{
591 task->tk_timeout = delay; 569 task->tk_timeout = delay;
592 rpc_sleep_on(&delay_queue, task, NULL, __rpc_atrun); 570 rpc_sleep_on(&delay_queue, task, __rpc_atrun);
593} 571}
594EXPORT_SYMBOL_GPL(rpc_delay); 572EXPORT_SYMBOL_GPL(rpc_delay);
595 573
@@ -644,10 +622,6 @@ static void __rpc_execute(struct rpc_task *task)
644 BUG_ON(RPC_IS_QUEUED(task)); 622 BUG_ON(RPC_IS_QUEUED(task));
645 623
646 for (;;) { 624 for (;;) {
647 /*
648 * Garbage collection of pending timers...
649 */
650 rpc_delete_timer(task);
651 625
652 /* 626 /*
653 * Execute any pending callback. 627 * Execute any pending callback.
@@ -816,8 +790,6 @@ EXPORT_SYMBOL_GPL(rpc_free);
816static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setup_data) 790static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setup_data)
817{ 791{
818 memset(task, 0, sizeof(*task)); 792 memset(task, 0, sizeof(*task));
819 setup_timer(&task->tk_timer, (void (*)(unsigned long))rpc_run_timer,
820 (unsigned long)task);
821 atomic_set(&task->tk_count, 1); 793 atomic_set(&task->tk_count, 1);
822 task->tk_flags = task_setup_data->flags; 794 task->tk_flags = task_setup_data->flags;
823 task->tk_ops = task_setup_data->callback_ops; 795 task->tk_ops = task_setup_data->callback_ops;
@@ -832,7 +804,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
832 task->tk_owner = current->tgid; 804 task->tk_owner = current->tgid;
833 805
834 /* Initialize workqueue for async tasks */ 806 /* Initialize workqueue for async tasks */
835 task->tk_workqueue = rpciod_workqueue; 807 task->tk_workqueue = task_setup_data->workqueue;
836 808
837 task->tk_client = task_setup_data->rpc_client; 809 task->tk_client = task_setup_data->rpc_client;
838 if (task->tk_client != NULL) { 810 if (task->tk_client != NULL) {
@@ -845,12 +817,11 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
845 task->tk_action = rpc_prepare_task; 817 task->tk_action = rpc_prepare_task;
846 818
847 if (task_setup_data->rpc_message != NULL) { 819 if (task_setup_data->rpc_message != NULL) {
848 memcpy(&task->tk_msg, task_setup_data->rpc_message, sizeof(task->tk_msg)); 820 task->tk_msg.rpc_proc = task_setup_data->rpc_message->rpc_proc;
821 task->tk_msg.rpc_argp = task_setup_data->rpc_message->rpc_argp;
822 task->tk_msg.rpc_resp = task_setup_data->rpc_message->rpc_resp;
849 /* Bind the user cred */ 823 /* Bind the user cred */
850 if (task->tk_msg.rpc_cred != NULL) 824 rpcauth_bindcred(task, task_setup_data->rpc_message->rpc_cred, task_setup_data->flags);
851 rpcauth_holdcred(task);
852 else
853 rpcauth_bindcred(task);
854 if (task->tk_action == NULL) 825 if (task->tk_action == NULL)
855 rpc_call_start(task); 826 rpc_call_start(task);
856 } 827 }
@@ -868,13 +839,6 @@ rpc_alloc_task(void)
868 return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); 839 return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS);
869} 840}
870 841
871static void rpc_free_task(struct rcu_head *rcu)
872{
873 struct rpc_task *task = container_of(rcu, struct rpc_task, u.tk_rcu);
874 dprintk("RPC: %5u freeing task\n", task->tk_pid);
875 mempool_free(task, rpc_task_mempool);
876}
877
878/* 842/*
879 * Create a new task for the specified client. 843 * Create a new task for the specified client.
880 */ 844 */
@@ -898,12 +862,25 @@ out:
898 return task; 862 return task;
899} 863}
900 864
901 865static void rpc_free_task(struct rpc_task *task)
902void rpc_put_task(struct rpc_task *task)
903{ 866{
904 const struct rpc_call_ops *tk_ops = task->tk_ops; 867 const struct rpc_call_ops *tk_ops = task->tk_ops;
905 void *calldata = task->tk_calldata; 868 void *calldata = task->tk_calldata;
906 869
870 if (task->tk_flags & RPC_TASK_DYNAMIC) {
871 dprintk("RPC: %5u freeing task\n", task->tk_pid);
872 mempool_free(task, rpc_task_mempool);
873 }
874 rpc_release_calldata(tk_ops, calldata);
875}
876
877static void rpc_async_release(struct work_struct *work)
878{
879 rpc_free_task(container_of(work, struct rpc_task, u.tk_work));
880}
881
882void rpc_put_task(struct rpc_task *task)
883{
907 if (!atomic_dec_and_test(&task->tk_count)) 884 if (!atomic_dec_and_test(&task->tk_count))
908 return; 885 return;
909 /* Release resources */ 886 /* Release resources */
@@ -915,9 +892,11 @@ void rpc_put_task(struct rpc_task *task)
915 rpc_release_client(task->tk_client); 892 rpc_release_client(task->tk_client);
916 task->tk_client = NULL; 893 task->tk_client = NULL;
917 } 894 }
918 if (task->tk_flags & RPC_TASK_DYNAMIC) 895 if (task->tk_workqueue != NULL) {
919 call_rcu_bh(&task->u.tk_rcu, rpc_free_task); 896 INIT_WORK(&task->u.tk_work, rpc_async_release);
920 rpc_release_calldata(tk_ops, calldata); 897 queue_work(task->tk_workqueue, &task->u.tk_work);
898 } else
899 rpc_free_task(task);
921} 900}
922EXPORT_SYMBOL_GPL(rpc_put_task); 901EXPORT_SYMBOL_GPL(rpc_put_task);
923 902
@@ -937,9 +916,6 @@ static void rpc_release_task(struct rpc_task *task)
937 } 916 }
938 BUG_ON (RPC_IS_QUEUED(task)); 917 BUG_ON (RPC_IS_QUEUED(task));
939 918
940 /* Synchronously delete any running timer */
941 rpc_delete_timer(task);
942
943#ifdef RPC_DEBUG 919#ifdef RPC_DEBUG
944 task->tk_magic = 0; 920 task->tk_magic = 0;
945#endif 921#endif
@@ -1029,11 +1005,20 @@ rpc_destroy_mempool(void)
1029 kmem_cache_destroy(rpc_task_slabp); 1005 kmem_cache_destroy(rpc_task_slabp);
1030 if (rpc_buffer_slabp) 1006 if (rpc_buffer_slabp)
1031 kmem_cache_destroy(rpc_buffer_slabp); 1007 kmem_cache_destroy(rpc_buffer_slabp);
1008 rpc_destroy_wait_queue(&delay_queue);
1032} 1009}
1033 1010
1034int 1011int
1035rpc_init_mempool(void) 1012rpc_init_mempool(void)
1036{ 1013{
1014 /*
1015 * The following is not strictly a mempool initialisation,
1016 * but there is no harm in doing it here
1017 */
1018 rpc_init_wait_queue(&delay_queue, "delayq");
1019 if (!rpciod_start())
1020 goto err_nomem;
1021
1037 rpc_task_slabp = kmem_cache_create("rpc_tasks", 1022 rpc_task_slabp = kmem_cache_create("rpc_tasks",
1038 sizeof(struct rpc_task), 1023 sizeof(struct rpc_task),
1039 0, SLAB_HWCACHE_ALIGN, 1024 0, SLAB_HWCACHE_ALIGN,
@@ -1054,13 +1039,6 @@ rpc_init_mempool(void)
1054 rpc_buffer_slabp); 1039 rpc_buffer_slabp);
1055 if (!rpc_buffer_mempool) 1040 if (!rpc_buffer_mempool)
1056 goto err_nomem; 1041 goto err_nomem;
1057 if (!rpciod_start())
1058 goto err_nomem;
1059 /*
1060 * The following is not strictly a mempool initialisation,
1061 * but there is no harm in doing it here
1062 */
1063 rpc_init_wait_queue(&delay_queue, "delayq");
1064 return 0; 1042 return 0;
1065err_nomem: 1043err_nomem:
1066 rpc_destroy_mempool(); 1044 rpc_destroy_mempool();
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index d5553b8179f9..75d748eee0eb 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -188,9 +188,9 @@ out_sleep:
188 task->tk_timeout = 0; 188 task->tk_timeout = 0;
189 task->tk_status = -EAGAIN; 189 task->tk_status = -EAGAIN;
190 if (req && req->rq_ntrans) 190 if (req && req->rq_ntrans)
191 rpc_sleep_on(&xprt->resend, task, NULL, NULL); 191 rpc_sleep_on(&xprt->resend, task, NULL);
192 else 192 else
193 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 193 rpc_sleep_on(&xprt->sending, task, NULL);
194 return 0; 194 return 0;
195} 195}
196EXPORT_SYMBOL_GPL(xprt_reserve_xprt); 196EXPORT_SYMBOL_GPL(xprt_reserve_xprt);
@@ -238,9 +238,9 @@ out_sleep:
238 task->tk_timeout = 0; 238 task->tk_timeout = 0;
239 task->tk_status = -EAGAIN; 239 task->tk_status = -EAGAIN;
240 if (req && req->rq_ntrans) 240 if (req && req->rq_ntrans)
241 rpc_sleep_on(&xprt->resend, task, NULL, NULL); 241 rpc_sleep_on(&xprt->resend, task, NULL);
242 else 242 else
243 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 243 rpc_sleep_on(&xprt->sending, task, NULL);
244 return 0; 244 return 0;
245} 245}
246EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong); 246EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);
@@ -447,13 +447,13 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_tasks);
447 * @task: task to be put to sleep 447 * @task: task to be put to sleep
448 * 448 *
449 */ 449 */
450void xprt_wait_for_buffer_space(struct rpc_task *task) 450void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
451{ 451{
452 struct rpc_rqst *req = task->tk_rqstp; 452 struct rpc_rqst *req = task->tk_rqstp;
453 struct rpc_xprt *xprt = req->rq_xprt; 453 struct rpc_xprt *xprt = req->rq_xprt;
454 454
455 task->tk_timeout = req->rq_timeout; 455 task->tk_timeout = req->rq_timeout;
456 rpc_sleep_on(&xprt->pending, task, NULL, NULL); 456 rpc_sleep_on(&xprt->pending, task, action);
457} 457}
458EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space); 458EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
459 459
@@ -472,7 +472,7 @@ void xprt_write_space(struct rpc_xprt *xprt)
472 if (xprt->snd_task) { 472 if (xprt->snd_task) {
473 dprintk("RPC: write space: waking waiting task on " 473 dprintk("RPC: write space: waking waiting task on "
474 "xprt %p\n", xprt); 474 "xprt %p\n", xprt);
475 rpc_wake_up_task(xprt->snd_task); 475 rpc_wake_up_queued_task(&xprt->pending, xprt->snd_task);
476 } 476 }
477 spin_unlock_bh(&xprt->transport_lock); 477 spin_unlock_bh(&xprt->transport_lock);
478} 478}
@@ -602,11 +602,37 @@ void xprt_force_disconnect(struct rpc_xprt *xprt)
602 /* Try to schedule an autoclose RPC call */ 602 /* Try to schedule an autoclose RPC call */
603 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) 603 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
604 queue_work(rpciod_workqueue, &xprt->task_cleanup); 604 queue_work(rpciod_workqueue, &xprt->task_cleanup);
605 else if (xprt->snd_task != NULL) 605 xprt_wake_pending_tasks(xprt, -ENOTCONN);
606 rpc_wake_up_task(xprt->snd_task); 606 spin_unlock_bh(&xprt->transport_lock);
607}
608
609/**
610 * xprt_conditional_disconnect - force a transport to disconnect
611 * @xprt: transport to disconnect
612 * @cookie: 'connection cookie'
613 *
614 * This attempts to break the connection if and only if 'cookie' matches
615 * the current transport 'connection cookie'. It ensures that we don't
616 * try to break the connection more than once when we need to retransmit
617 * a batch of RPC requests.
618 *
619 */
620void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie)
621{
622 /* Don't race with the test_bit() in xprt_clear_locked() */
623 spin_lock_bh(&xprt->transport_lock);
624 if (cookie != xprt->connect_cookie)
625 goto out;
626 if (test_bit(XPRT_CLOSING, &xprt->state) || !xprt_connected(xprt))
627 goto out;
628 set_bit(XPRT_CLOSE_WAIT, &xprt->state);
629 /* Try to schedule an autoclose RPC call */
630 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
631 queue_work(rpciod_workqueue, &xprt->task_cleanup);
632 xprt_wake_pending_tasks(xprt, -ENOTCONN);
633out:
607 spin_unlock_bh(&xprt->transport_lock); 634 spin_unlock_bh(&xprt->transport_lock);
608} 635}
609EXPORT_SYMBOL_GPL(xprt_force_disconnect);
610 636
611static void 637static void
612xprt_init_autodisconnect(unsigned long data) 638xprt_init_autodisconnect(unsigned long data)
@@ -653,7 +679,7 @@ void xprt_connect(struct rpc_task *task)
653 task->tk_rqstp->rq_bytes_sent = 0; 679 task->tk_rqstp->rq_bytes_sent = 0;
654 680
655 task->tk_timeout = xprt->connect_timeout; 681 task->tk_timeout = xprt->connect_timeout;
656 rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); 682 rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
657 xprt->stat.connect_start = jiffies; 683 xprt->stat.connect_start = jiffies;
658 xprt->ops->connect(task); 684 xprt->ops->connect(task);
659 } 685 }
@@ -749,18 +775,20 @@ EXPORT_SYMBOL_GPL(xprt_update_rtt);
749void xprt_complete_rqst(struct rpc_task *task, int copied) 775void xprt_complete_rqst(struct rpc_task *task, int copied)
750{ 776{
751 struct rpc_rqst *req = task->tk_rqstp; 777 struct rpc_rqst *req = task->tk_rqstp;
778 struct rpc_xprt *xprt = req->rq_xprt;
752 779
753 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", 780 dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
754 task->tk_pid, ntohl(req->rq_xid), copied); 781 task->tk_pid, ntohl(req->rq_xid), copied);
755 782
756 task->tk_xprt->stat.recvs++; 783 xprt->stat.recvs++;
757 task->tk_rtt = (long)jiffies - req->rq_xtime; 784 task->tk_rtt = (long)jiffies - req->rq_xtime;
758 785
759 list_del_init(&req->rq_list); 786 list_del_init(&req->rq_list);
787 req->rq_private_buf.len = copied;
760 /* Ensure all writes are done before we update req->rq_received */ 788 /* Ensure all writes are done before we update req->rq_received */
761 smp_wmb(); 789 smp_wmb();
762 req->rq_received = req->rq_private_buf.len = copied; 790 req->rq_received = copied;
763 rpc_wake_up_task(task); 791 rpc_wake_up_queued_task(&xprt->pending, task);
764} 792}
765EXPORT_SYMBOL_GPL(xprt_complete_rqst); 793EXPORT_SYMBOL_GPL(xprt_complete_rqst);
766 794
@@ -769,17 +797,17 @@ static void xprt_timer(struct rpc_task *task)
769 struct rpc_rqst *req = task->tk_rqstp; 797 struct rpc_rqst *req = task->tk_rqstp;
770 struct rpc_xprt *xprt = req->rq_xprt; 798 struct rpc_xprt *xprt = req->rq_xprt;
771 799
800 if (task->tk_status != -ETIMEDOUT)
801 return;
772 dprintk("RPC: %5u xprt_timer\n", task->tk_pid); 802 dprintk("RPC: %5u xprt_timer\n", task->tk_pid);
773 803
774 spin_lock(&xprt->transport_lock); 804 spin_lock_bh(&xprt->transport_lock);
775 if (!req->rq_received) { 805 if (!req->rq_received) {
776 if (xprt->ops->timer) 806 if (xprt->ops->timer)
777 xprt->ops->timer(task); 807 xprt->ops->timer(task);
778 task->tk_status = -ETIMEDOUT; 808 } else
779 } 809 task->tk_status = 0;
780 task->tk_timeout = 0; 810 spin_unlock_bh(&xprt->transport_lock);
781 rpc_wake_up_task(task);
782 spin_unlock(&xprt->transport_lock);
783} 811}
784 812
785/** 813/**
@@ -849,6 +877,7 @@ void xprt_transmit(struct rpc_task *task)
849 } else if (!req->rq_bytes_sent) 877 } else if (!req->rq_bytes_sent)
850 return; 878 return;
851 879
880 req->rq_connect_cookie = xprt->connect_cookie;
852 status = xprt->ops->send_request(task); 881 status = xprt->ops->send_request(task);
853 if (status == 0) { 882 if (status == 0) {
854 dprintk("RPC: %5u xmit complete\n", task->tk_pid); 883 dprintk("RPC: %5u xmit complete\n", task->tk_pid);
@@ -864,7 +893,7 @@ void xprt_transmit(struct rpc_task *task)
864 if (!xprt_connected(xprt)) 893 if (!xprt_connected(xprt))
865 task->tk_status = -ENOTCONN; 894 task->tk_status = -ENOTCONN;
866 else if (!req->rq_received) 895 else if (!req->rq_received)
867 rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); 896 rpc_sleep_on(&xprt->pending, task, xprt_timer);
868 spin_unlock_bh(&xprt->transport_lock); 897 spin_unlock_bh(&xprt->transport_lock);
869 return; 898 return;
870 } 899 }
@@ -875,7 +904,7 @@ void xprt_transmit(struct rpc_task *task)
875 */ 904 */
876 task->tk_status = status; 905 task->tk_status = status;
877 if (status == -ECONNREFUSED) 906 if (status == -ECONNREFUSED)
878 rpc_sleep_on(&xprt->sending, task, NULL, NULL); 907 rpc_sleep_on(&xprt->sending, task, NULL);
879} 908}
880 909
881static inline void do_xprt_reserve(struct rpc_task *task) 910static inline void do_xprt_reserve(struct rpc_task *task)
@@ -895,7 +924,7 @@ static inline void do_xprt_reserve(struct rpc_task *task)
895 dprintk("RPC: waiting for request slot\n"); 924 dprintk("RPC: waiting for request slot\n");
896 task->tk_status = -EAGAIN; 925 task->tk_status = -EAGAIN;
897 task->tk_timeout = 0; 926 task->tk_timeout = 0;
898 rpc_sleep_on(&xprt->backlog, task, NULL, NULL); 927 rpc_sleep_on(&xprt->backlog, task, NULL);
899} 928}
900 929
901/** 930/**
@@ -1052,6 +1081,11 @@ static void xprt_destroy(struct kref *kref)
1052 xprt->shutdown = 1; 1081 xprt->shutdown = 1;
1053 del_timer_sync(&xprt->timer); 1082 del_timer_sync(&xprt->timer);
1054 1083
1084 rpc_destroy_wait_queue(&xprt->binding);
1085 rpc_destroy_wait_queue(&xprt->pending);
1086 rpc_destroy_wait_queue(&xprt->sending);
1087 rpc_destroy_wait_queue(&xprt->resend);
1088 rpc_destroy_wait_queue(&xprt->backlog);
1055 /* 1089 /*
1056 * Tear down transport state and free the rpc_xprt 1090 * Tear down transport state and free the rpc_xprt
1057 */ 1091 */
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 613daf8c1ff7..ddbe981ab516 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -136,12 +136,6 @@ static ctl_table sunrpc_table[] = {
136#endif 136#endif
137 137
138/* 138/*
139 * How many times to try sending a request on a socket before waiting
140 * for the socket buffer to clear.
141 */
142#define XS_SENDMSG_RETRY (10U)
143
144/*
145 * Time out for an RPC UDP socket connect. UDP socket connects are 139 * Time out for an RPC UDP socket connect. UDP socket connects are
146 * synchronous, but we set a timeout anyway in case of resource 140 * synchronous, but we set a timeout anyway in case of resource
147 * exhaustion on the local host. 141 * exhaustion on the local host.
@@ -516,6 +510,14 @@ out:
516 return sent; 510 return sent;
517} 511}
518 512
513static void xs_nospace_callback(struct rpc_task *task)
514{
515 struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt);
516
517 transport->inet->sk_write_pending--;
518 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
519}
520
519/** 521/**
520 * xs_nospace - place task on wait queue if transmit was incomplete 522 * xs_nospace - place task on wait queue if transmit was incomplete
521 * @task: task to put to sleep 523 * @task: task to put to sleep
@@ -531,20 +533,27 @@ static void xs_nospace(struct rpc_task *task)
531 task->tk_pid, req->rq_slen - req->rq_bytes_sent, 533 task->tk_pid, req->rq_slen - req->rq_bytes_sent,
532 req->rq_slen); 534 req->rq_slen);
533 535
534 if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { 536 /* Protect against races with write_space */
535 /* Protect against races with write_space */ 537 spin_lock_bh(&xprt->transport_lock);
536 spin_lock_bh(&xprt->transport_lock); 538
537 539 /* Don't race with disconnect */
538 /* Don't race with disconnect */ 540 if (xprt_connected(xprt)) {
539 if (!xprt_connected(xprt)) 541 if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
540 task->tk_status = -ENOTCONN; 542 /*
541 else if (test_bit(SOCK_NOSPACE, &transport->sock->flags)) 543 * Notify TCP that we're limited by the application
542 xprt_wait_for_buffer_space(task); 544 * window size
545 */
546 set_bit(SOCK_NOSPACE, &transport->sock->flags);
547 transport->inet->sk_write_pending++;
548 /* ...and wait for more buffer space */
549 xprt_wait_for_buffer_space(task, xs_nospace_callback);
550 }
551 } else {
552 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
553 task->tk_status = -ENOTCONN;
554 }
543 555
544 spin_unlock_bh(&xprt->transport_lock); 556 spin_unlock_bh(&xprt->transport_lock);
545 } else
546 /* Keep holding the socket if it is blocked */
547 rpc_delay(task, HZ>>4);
548} 557}
549 558
550/** 559/**
@@ -588,19 +597,20 @@ static int xs_udp_send_request(struct rpc_task *task)
588 } 597 }
589 598
590 switch (status) { 599 switch (status) {
600 case -EAGAIN:
601 xs_nospace(task);
602 break;
591 case -ENETUNREACH: 603 case -ENETUNREACH:
592 case -EPIPE: 604 case -EPIPE:
593 case -ECONNREFUSED: 605 case -ECONNREFUSED:
594 /* When the server has died, an ICMP port unreachable message 606 /* When the server has died, an ICMP port unreachable message
595 * prompts ECONNREFUSED. */ 607 * prompts ECONNREFUSED. */
596 break; 608 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
597 case -EAGAIN:
598 xs_nospace(task);
599 break; 609 break;
600 default: 610 default:
611 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
601 dprintk("RPC: sendmsg returned unrecognized error %d\n", 612 dprintk("RPC: sendmsg returned unrecognized error %d\n",
602 -status); 613 -status);
603 break;
604 } 614 }
605 615
606 return status; 616 return status;
@@ -650,7 +660,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
650 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 660 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
651 struct xdr_buf *xdr = &req->rq_snd_buf; 661 struct xdr_buf *xdr = &req->rq_snd_buf;
652 int status; 662 int status;
653 unsigned int retry = 0;
654 663
655 xs_encode_tcp_record_marker(&req->rq_snd_buf); 664 xs_encode_tcp_record_marker(&req->rq_snd_buf);
656 665
@@ -681,9 +690,10 @@ static int xs_tcp_send_request(struct rpc_task *task)
681 return 0; 690 return 0;
682 } 691 }
683 692
693 if (status != 0)
694 continue;
684 status = -EAGAIN; 695 status = -EAGAIN;
685 if (retry++ > XS_SENDMSG_RETRY) 696 break;
686 break;
687 } 697 }
688 698
689 switch (status) { 699 switch (status) {
@@ -695,12 +705,13 @@ static int xs_tcp_send_request(struct rpc_task *task)
695 case -ENOTCONN: 705 case -ENOTCONN:
696 case -EPIPE: 706 case -EPIPE:
697 status = -ENOTCONN; 707 status = -ENOTCONN;
708 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
698 break; 709 break;
699 default: 710 default:
700 dprintk("RPC: sendmsg returned unrecognized error %d\n", 711 dprintk("RPC: sendmsg returned unrecognized error %d\n",
701 -status); 712 -status);
713 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
702 xs_tcp_shutdown(xprt); 714 xs_tcp_shutdown(xprt);
703 break;
704 } 715 }
705 716
706 return status; 717 return status;
@@ -1073,6 +1084,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
1073{ 1084{
1074 struct rpc_xprt *xprt; 1085 struct rpc_xprt *xprt;
1075 read_descriptor_t rd_desc; 1086 read_descriptor_t rd_desc;
1087 int read;
1076 1088
1077 dprintk("RPC: xs_tcp_data_ready...\n"); 1089 dprintk("RPC: xs_tcp_data_ready...\n");
1078 1090
@@ -1084,8 +1096,10 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
1084 1096
1085 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ 1097 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
1086 rd_desc.arg.data = xprt; 1098 rd_desc.arg.data = xprt;
1087 rd_desc.count = 65536; 1099 do {
1088 tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); 1100 rd_desc.count = 65536;
1101 read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
1102 } while (read > 0);
1089out: 1103out:
1090 read_unlock(&sk->sk_callback_lock); 1104 read_unlock(&sk->sk_callback_lock);
1091} 1105}
@@ -1128,6 +1142,7 @@ static void xs_tcp_state_change(struct sock *sk)
1128 break; 1142 break;
1129 case TCP_FIN_WAIT1: 1143 case TCP_FIN_WAIT1:
1130 /* The client initiated a shutdown of the socket */ 1144 /* The client initiated a shutdown of the socket */
1145 xprt->connect_cookie++;
1131 xprt->reestablish_timeout = 0; 1146 xprt->reestablish_timeout = 0;
1132 set_bit(XPRT_CLOSING, &xprt->state); 1147 set_bit(XPRT_CLOSING, &xprt->state);
1133 smp_mb__before_clear_bit(); 1148 smp_mb__before_clear_bit();
@@ -1140,6 +1155,7 @@ static void xs_tcp_state_change(struct sock *sk)
1140 set_bit(XPRT_CLOSING, &xprt->state); 1155 set_bit(XPRT_CLOSING, &xprt->state);
1141 xprt_force_disconnect(xprt); 1156 xprt_force_disconnect(xprt);
1142 case TCP_SYN_SENT: 1157 case TCP_SYN_SENT:
1158 xprt->connect_cookie++;
1143 case TCP_CLOSING: 1159 case TCP_CLOSING:
1144 /* 1160 /*
1145 * If the server closed down the connection, make sure that 1161 * If the server closed down the connection, make sure that
@@ -1186,9 +1202,11 @@ static void xs_udp_write_space(struct sock *sk)
1186 1202
1187 if (unlikely(!(sock = sk->sk_socket))) 1203 if (unlikely(!(sock = sk->sk_socket)))
1188 goto out; 1204 goto out;
1205 clear_bit(SOCK_NOSPACE, &sock->flags);
1206
1189 if (unlikely(!(xprt = xprt_from_sock(sk)))) 1207 if (unlikely(!(xprt = xprt_from_sock(sk))))
1190 goto out; 1208 goto out;
1191 if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))) 1209 if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0)
1192 goto out; 1210 goto out;
1193 1211
1194 xprt_write_space(xprt); 1212 xprt_write_space(xprt);
@@ -1219,9 +1237,11 @@ static void xs_tcp_write_space(struct sock *sk)
1219 1237
1220 if (unlikely(!(sock = sk->sk_socket))) 1238 if (unlikely(!(sock = sk->sk_socket)))
1221 goto out; 1239 goto out;
1240 clear_bit(SOCK_NOSPACE, &sock->flags);
1241
1222 if (unlikely(!(xprt = xprt_from_sock(sk)))) 1242 if (unlikely(!(xprt = xprt_from_sock(sk))))
1223 goto out; 1243 goto out;
1224 if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))) 1244 if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0)
1225 goto out; 1245 goto out;
1226 1246
1227 xprt_write_space(xprt); 1247 xprt_write_space(xprt);