diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 16:48:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 16:48:29 -0400 |
commit | 74eb94b218d087798a52c0b4f1379b635287a4b8 (patch) | |
tree | 4e467c3014c2b1169f6f71d88cf5d1598f3ce28e /net/sunrpc | |
parent | 7b6181e06841f5ad15c4ff708b967b4db65a64de (diff) | |
parent | 9a84d38031c258a17bb39beed1e500eadee67407 (diff) |
Merge branch 'nfs-for-2.6.37' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'nfs-for-2.6.37' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6: (67 commits)
SUNRPC: Cleanup duplicate assignment in rpcauth_refreshcred
nfs: fix unchecked value
Ask for time_delta during fsinfo probe
Revalidate caches on lock
SUNRPC: After calling xprt_release(), we must restart from call_reserve
NFSv4: Fix up the 'dircount' hint in encode_readdir
NFSv4: Clean up nfs4_decode_dirent
NFSv4: nfs4_decode_dirent must clear entry->fattr->valid
NFSv4: Fix a regression in decode_getfattr
NFSv4: Fix up decode_attr_filehandle() to handle the case of empty fh pointer
NFS: Ensure we check all allocation return values in new readdir code
NFS: Readdir plus in v4
NFS: introduce generic decode_getattr function
NFS: check xdr_decode for errors
NFS: nfs_readdir_filler catch all errors
NFS: readdir with vmapped pages
NFS: remove page size checking code
NFS: decode_dirent should use an xdr_stream
SUNRPC: Add a helper function xdr_inline_peek
NFS: remove readdir plus limit
...
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/auth.c | 2 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 2 | ||||
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 56 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xdr.c | 61 |
5 files changed, 58 insertions, 65 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index e9eaaf7d43c1..68192e562749 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -595,7 +595,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | |||
595 | int | 595 | int |
596 | rpcauth_refreshcred(struct rpc_task *task) | 596 | rpcauth_refreshcred(struct rpc_task *task) |
597 | { | 597 | { |
598 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 598 | struct rpc_cred *cred; |
599 | int err; | 599 | int err; |
600 | 600 | ||
601 | cred = task->tk_rqstp->rq_cred; | 601 | cred = task->tk_rqstp->rq_cred; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index fa5549079d79..cbc5b8ccc8be 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -1675,7 +1675,7 @@ rpc_verify_header(struct rpc_task *task) | |||
1675 | rpcauth_invalcred(task); | 1675 | rpcauth_invalcred(task); |
1676 | /* Ensure we obtain a new XID! */ | 1676 | /* Ensure we obtain a new XID! */ |
1677 | xprt_release(task); | 1677 | xprt_release(task); |
1678 | task->tk_action = call_refresh; | 1678 | task->tk_action = call_reserve; |
1679 | goto out_retry; | 1679 | goto out_retry; |
1680 | case RPC_AUTH_BADCRED: | 1680 | case RPC_AUTH_BADCRED: |
1681 | case RPC_AUTH_BADVERF: | 1681 | case RPC_AUTH_BADVERF: |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index dac219a56ae1..63ec116b4dd4 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -211,8 +211,9 @@ static int rpcb_create_local(void) | |||
211 | */ | 211 | */ |
212 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); | 212 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); |
213 | if (IS_ERR(clnt4)) { | 213 | if (IS_ERR(clnt4)) { |
214 | dprintk("RPC: failed to create local rpcbind v4 " | 214 | dprintk("RPC: failed to bind second program to " |
215 | "cleint (errno %ld).\n", PTR_ERR(clnt4)); | 215 | "rpcbind v4 client (errno %ld).\n", |
216 | PTR_ERR(clnt4)); | ||
216 | clnt4 = NULL; | 217 | clnt4 = NULL; |
217 | } | 218 | } |
218 | 219 | ||
@@ -475,57 +476,6 @@ int rpcb_v4_register(const u32 program, const u32 version, | |||
475 | return -EAFNOSUPPORT; | 476 | return -EAFNOSUPPORT; |
476 | } | 477 | } |
477 | 478 | ||
478 | /** | ||
479 | * rpcb_getport_sync - obtain the port for an RPC service on a given host | ||
480 | * @sin: address of remote peer | ||
481 | * @prog: RPC program number to bind | ||
482 | * @vers: RPC version number to bind | ||
483 | * @prot: transport protocol to use to make this request | ||
484 | * | ||
485 | * Return value is the requested advertised port number, | ||
486 | * or a negative errno value. | ||
487 | * | ||
488 | * Called from outside the RPC client in a synchronous task context. | ||
489 | * Uses default timeout parameters specified by underlying transport. | ||
490 | * | ||
491 | * XXX: Needs to support IPv6 | ||
492 | */ | ||
493 | int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) | ||
494 | { | ||
495 | struct rpcbind_args map = { | ||
496 | .r_prog = prog, | ||
497 | .r_vers = vers, | ||
498 | .r_prot = prot, | ||
499 | .r_port = 0, | ||
500 | }; | ||
501 | struct rpc_message msg = { | ||
502 | .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT], | ||
503 | .rpc_argp = &map, | ||
504 | .rpc_resp = &map, | ||
505 | }; | ||
506 | struct rpc_clnt *rpcb_clnt; | ||
507 | int status; | ||
508 | |||
509 | dprintk("RPC: %s(%pI4, %u, %u, %d)\n", | ||
510 | __func__, &sin->sin_addr.s_addr, prog, vers, prot); | ||
511 | |||
512 | rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin, | ||
513 | sizeof(*sin), prot, RPCBVERS_2); | ||
514 | if (IS_ERR(rpcb_clnt)) | ||
515 | return PTR_ERR(rpcb_clnt); | ||
516 | |||
517 | status = rpc_call_sync(rpcb_clnt, &msg, 0); | ||
518 | rpc_shutdown_client(rpcb_clnt); | ||
519 | |||
520 | if (status >= 0) { | ||
521 | if (map.r_port != 0) | ||
522 | return map.r_port; | ||
523 | status = -EACCES; | ||
524 | } | ||
525 | return status; | ||
526 | } | ||
527 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); | ||
528 | |||
529 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc) | 479 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc) |
530 | { | 480 | { |
531 | struct rpc_message msg = { | 481 | struct rpc_message msg = { |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index aa5dbda6608c..243fc09b164e 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -908,7 +908,7 @@ static int rpciod_start(void) | |||
908 | * Create the rpciod thread and wait for it to start. | 908 | * Create the rpciod thread and wait for it to start. |
909 | */ | 909 | */ |
910 | dprintk("RPC: creating workqueue rpciod\n"); | 910 | dprintk("RPC: creating workqueue rpciod\n"); |
911 | wq = create_workqueue("rpciod"); | 911 | wq = alloc_workqueue("rpciod", WQ_RESCUER, 0); |
912 | rpciod_workqueue = wq; | 912 | rpciod_workqueue = wq; |
913 | return rpciod_workqueue != NULL; | 913 | return rpciod_workqueue != NULL; |
914 | } | 914 | } |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index a1f82a87d34d..cd9e841e7492 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -111,6 +111,23 @@ xdr_decode_string_inplace(__be32 *p, char **sp, | |||
111 | } | 111 | } |
112 | EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); | 112 | EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); |
113 | 113 | ||
114 | /** | ||
115 | * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf | ||
116 | * @buf: XDR buffer where string resides | ||
117 | * @len: length of string, in bytes | ||
118 | * | ||
119 | */ | ||
120 | void | ||
121 | xdr_terminate_string(struct xdr_buf *buf, const u32 len) | ||
122 | { | ||
123 | char *kaddr; | ||
124 | |||
125 | kaddr = kmap_atomic(buf->pages[0], KM_USER0); | ||
126 | kaddr[buf->page_base + len] = '\0'; | ||
127 | kunmap_atomic(kaddr, KM_USER0); | ||
128 | } | ||
129 | EXPORT_SYMBOL(xdr_terminate_string); | ||
130 | |||
114 | void | 131 | void |
115 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | 132 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, |
116 | unsigned int len) | 133 | unsigned int len) |
@@ -395,24 +412,29 @@ xdr_shrink_pagelen(struct xdr_buf *buf, size_t len) | |||
395 | { | 412 | { |
396 | struct kvec *tail; | 413 | struct kvec *tail; |
397 | size_t copy; | 414 | size_t copy; |
398 | char *p; | ||
399 | unsigned int pglen = buf->page_len; | 415 | unsigned int pglen = buf->page_len; |
416 | unsigned int tailbuf_len; | ||
400 | 417 | ||
401 | tail = buf->tail; | 418 | tail = buf->tail; |
402 | BUG_ON (len > pglen); | 419 | BUG_ON (len > pglen); |
403 | 420 | ||
421 | tailbuf_len = buf->buflen - buf->head->iov_len - buf->page_len; | ||
422 | |||
404 | /* Shift the tail first */ | 423 | /* Shift the tail first */ |
405 | if (tail->iov_len != 0) { | 424 | if (tailbuf_len != 0) { |
406 | p = (char *)tail->iov_base + len; | 425 | unsigned int free_space = tailbuf_len - tail->iov_len; |
426 | |||
427 | if (len < free_space) | ||
428 | free_space = len; | ||
429 | tail->iov_len += free_space; | ||
430 | |||
431 | copy = len; | ||
407 | if (tail->iov_len > len) { | 432 | if (tail->iov_len > len) { |
408 | copy = tail->iov_len - len; | 433 | char *p = (char *)tail->iov_base + len; |
409 | memmove(p, tail->iov_base, copy); | 434 | memmove(p, tail->iov_base, tail->iov_len - len); |
410 | } else | 435 | } else |
411 | buf->buflen -= len; | ||
412 | /* Copy from the inlined pages into the tail */ | ||
413 | copy = len; | ||
414 | if (copy > tail->iov_len) | ||
415 | copy = tail->iov_len; | 436 | copy = tail->iov_len; |
437 | /* Copy from the inlined pages into the tail */ | ||
416 | _copy_from_pages((char *)tail->iov_base, | 438 | _copy_from_pages((char *)tail->iov_base, |
417 | buf->pages, buf->page_base + pglen - len, | 439 | buf->pages, buf->page_base + pglen - len, |
418 | copy); | 440 | copy); |
@@ -551,6 +573,27 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | |||
551 | EXPORT_SYMBOL_GPL(xdr_init_decode); | 573 | EXPORT_SYMBOL_GPL(xdr_init_decode); |
552 | 574 | ||
553 | /** | 575 | /** |
576 | * xdr_inline_peek - Allow read-ahead in the XDR data stream | ||
577 | * @xdr: pointer to xdr_stream struct | ||
578 | * @nbytes: number of bytes of data to decode | ||
579 | * | ||
580 | * Check if the input buffer is long enough to enable us to decode | ||
581 | * 'nbytes' more bytes of data starting at the current position. | ||
582 | * If so return the current pointer without updating the current | ||
583 | * pointer position. | ||
584 | */ | ||
585 | __be32 * xdr_inline_peek(struct xdr_stream *xdr, size_t nbytes) | ||
586 | { | ||
587 | __be32 *p = xdr->p; | ||
588 | __be32 *q = p + XDR_QUADLEN(nbytes); | ||
589 | |||
590 | if (unlikely(q > xdr->end || q < p)) | ||
591 | return NULL; | ||
592 | return p; | ||
593 | } | ||
594 | EXPORT_SYMBOL_GPL(xdr_inline_peek); | ||
595 | |||
596 | /** | ||
554 | * xdr_inline_decode - Retrieve non-page XDR data to decode | 597 | * xdr_inline_decode - Retrieve non-page XDR data to decode |
555 | * @xdr: pointer to xdr_stream struct | 598 | * @xdr: pointer to xdr_stream struct |
556 | * @nbytes: number of bytes of data to decode | 599 | * @nbytes: number of bytes of data to decode |