Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.linux-nfs.org/projects/trondmy/nfs-2.6

* git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (80 commits)
SUNRPC: Invalidate the RPCSEC_GSS session if the server dropped the request
make nfs_automount_list static
NFS: remove duplicate flags assignment from nfs_validate_mount_data
NFS - fix potential NULL pointer dereference v2
SUNRPC: Don't change the RPCSEC_GSS context on a credential that is in use
SUNRPC: Fix a race in gss_refresh_upcall()
SUNRPC: Don't disconnect more than once if retransmitting NFSv4 requests
SUNRPC: Remove the unused export of xprt_force_disconnect
SUNRPC: remove XS_SENDMSG_RETRY
SUNRPC: Protect creds against early garbage collection
NFSv4: Attempt to use machine credentials in SETCLIENTID calls
NFSv4: Reintroduce machine creds
NFSv4: Don't use cred->cr_ops->cr_name in nfs4_proc_setclientid()
nfs: fix printout of multiword bitfields
nfs: return negative error value from nfs{,4}_stat_to_errno
NLM/lockd: Ensure client locking calls use correct credentials
NFS: Remove the buggy lock-if-signalled case from do_setlk()
NLM/lockd: Fix a race when cancelling a blocking lock
NLM/lockd: Ensure that nlmclnt_cancel() returns results of the CANCEL call
NLM: Remove the signal masking in nlmclnt_proc/nlmclnt_cancel
...

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