[PATCH] RPC: extract socket logic common to both client and server
Clean-up: Move some code that is common to both RPC client- and server-side socket transports into its own source file, net/sunrpc/socklib.c. Test-plan: Compile kernel with CONFIG_NFS enabled. Millions of fsx operations over UDP, client and server. Connectathon over UDP. Version: Thu, 11 Aug 2005 16:03:09 -0400 Signed-off-by: Chuck Lever <cel@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
committed by
Trond Myklebust
parent
602f83273c
commit
094bb20b9f
@@ -176,81 +176,6 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
|
||||
xdr->buflen += len;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
|
||||
skb_reader_t *desc,
|
||||
skb_read_actor_t copy_actor)
|
||||
{
|
||||
struct page **ppage = xdr->pages;
|
||||
unsigned int len, pglen = xdr->page_len;
|
||||
ssize_t copied = 0;
|
||||
int ret;
|
||||
|
||||
len = xdr->head[0].iov_len;
|
||||
if (base < len) {
|
||||
len -= base;
|
||||
ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
|
||||
copied += ret;
|
||||
if (ret != len || !desc->count)
|
||||
goto out;
|
||||
base = 0;
|
||||
} else
|
||||
base -= len;
|
||||
|
||||
if (pglen == 0)
|
||||
goto copy_tail;
|
||||
if (base >= pglen) {
|
||||
base -= pglen;
|
||||
goto copy_tail;
|
||||
}
|
||||
if (base || xdr->page_base) {
|
||||
pglen -= base;
|
||||
base += xdr->page_base;
|
||||
ppage += base >> PAGE_CACHE_SHIFT;
|
||||
base &= ~PAGE_CACHE_MASK;
|
||||
}
|
||||
do {
|
||||
char *kaddr;
|
||||
|
||||
/* ACL likes to be lazy in allocating pages - ACLs
|
||||
* are small by default but can get huge. */
|
||||
if (unlikely(*ppage == NULL)) {
|
||||
*ppage = alloc_page(GFP_ATOMIC);
|
||||
if (unlikely(*ppage == NULL)) {
|
||||
if (copied == 0)
|
||||
copied = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
len = PAGE_CACHE_SIZE;
|
||||
kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
|
||||
if (base) {
|
||||
len -= base;
|
||||
if (pglen < len)
|
||||
len = pglen;
|
||||
ret = copy_actor(desc, kaddr + base, len);
|
||||
base = 0;
|
||||
} else {
|
||||
if (pglen < len)
|
||||
len = pglen;
|
||||
ret = copy_actor(desc, kaddr, len);
|
||||
}
|
||||
flush_dcache_page(*ppage);
|
||||
kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
|
||||
copied += ret;
|
||||
if (ret != len || !desc->count)
|
||||
goto out;
|
||||
ppage++;
|
||||
} while ((pglen -= len) != 0);
|
||||
copy_tail:
|
||||
len = xdr->tail[0].iov_len;
|
||||
if (base < len)
|
||||
copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
|
||||
out:
|
||||
return copied;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
xdr_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
|
||||
|
Reference in New Issue
Block a user