Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 42509
b: refs/heads/master
c: 24c5684
h: refs/heads/master
i:
  42507: 1cc3c1a
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Dec 6, 2006
1 parent 78c8f2c commit 66a10c9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 76 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bee57c99c322d64407b80c8171958b4384902da4
refs/heads/master: 24c5684b65ff52ebfa942e8086d91a4966121ae7
140 changes: 65 additions & 75 deletions trunk/net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,37 +168,52 @@ static void xs_free_peer_addresses(struct rpc_xprt *xprt)

#define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL)

static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len)
static int xs_send_kvec(struct socket *sock, struct sockaddr *addr, int addrlen, struct kvec *vec, unsigned int base, int more)
{
struct kvec iov = {
.iov_base = xdr->head[0].iov_base + base,
.iov_len = len - base,
};
struct msghdr msg = {
.msg_name = addr,
.msg_namelen = addrlen,
.msg_flags = XS_SENDMSG_FLAGS,
.msg_flags = XS_SENDMSG_FLAGS | (more ? MSG_MORE : 0),
};
struct kvec iov = {
.iov_base = vec->iov_base + base,
.iov_len = vec->iov_len - base,
};

if (xdr->len > len)
msg.msg_flags |= MSG_MORE;

if (likely(iov.iov_len))
if (iov.iov_len != 0)
return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
return kernel_sendmsg(sock, &msg, NULL, 0, 0);
}

static int xs_send_tail(struct socket *sock, struct xdr_buf *xdr, unsigned int base, unsigned int len)
static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more)
{
struct kvec iov = {
.iov_base = xdr->tail[0].iov_base + base,
.iov_len = len - base,
};
struct msghdr msg = {
.msg_flags = XS_SENDMSG_FLAGS,
};
struct page **ppage;
unsigned int remainder;
int err, sent = 0;

remainder = xdr->page_len - base;
base += xdr->page_base;
ppage = xdr->pages + (base >> PAGE_SHIFT);
base &= ~PAGE_MASK;
for(;;) {
unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder);
int flags = XS_SENDMSG_FLAGS;

return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
remainder -= len;
if (remainder != 0 || more)
flags |= MSG_MORE;
err = sock->ops->sendpage(sock, *ppage, base, len, flags);
if (remainder == 0 || err != len)
break;
sent += err;
ppage++;
base = 0;
}
if (sent == 0)
return err;
if (err > 0)
sent += err;
return sent;
}

/**
Expand All @@ -210,76 +225,51 @@ static int xs_send_tail(struct socket *sock, struct xdr_buf *xdr, unsigned int b
* @base: starting position in the buffer
*
*/
static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
{
struct page **ppage = xdr->pages;
unsigned int len, pglen = xdr->page_len;
int err, ret = 0;
unsigned int remainder = xdr->len - base;
int err, sent = 0;

if (unlikely(!sock))
return -ENOTCONN;

clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
if (base != 0) {
addr = NULL;
addrlen = 0;
}

len = xdr->head[0].iov_len;
if (base < len || (addr != NULL && base == 0)) {
err = xs_send_head(sock, addr, addrlen, xdr, base, len);
if (ret == 0)
ret = err;
else if (err > 0)
ret += err;
if (err != (len - base))
if (base < xdr->head[0].iov_len || addr != NULL) {
unsigned int len = xdr->head[0].iov_len - base;
remainder -= len;
err = xs_send_kvec(sock, addr, addrlen, &xdr->head[0], base, remainder != 0);
if (remainder == 0 || err != len)
goto out;
sent += err;
base = 0;
} else
base -= len;

if (unlikely(pglen == 0))
goto copy_tail;
if (unlikely(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 {
int flags = XS_SENDMSG_FLAGS;
base -= xdr->head[0].iov_len;

len = PAGE_CACHE_SIZE;
if (base)
len -= base;
if (pglen < len)
len = pglen;

if (pglen != len || xdr->tail[0].iov_len != 0)
flags |= MSG_MORE;

err = kernel_sendpage(sock, *ppage, base, len, flags);
if (ret == 0)
ret = err;
else if (err > 0)
ret += err;
if (err != len)
if (base < xdr->page_len) {
unsigned int len = xdr->page_len - base;
remainder -= len;
err = xs_send_pagedata(sock, xdr, base, remainder != 0);
if (remainder == 0 || err != len)
goto out;
sent += err;
base = 0;
ppage++;
} while ((pglen -= len) != 0);
copy_tail:
len = xdr->tail[0].iov_len;
if (base < len) {
err = xs_send_tail(sock, xdr, base, len);
if (ret == 0)
ret = err;
else if (err > 0)
ret += err;
}
} else
base -= xdr->page_len;

if (base >= xdr->tail[0].iov_len)
return sent;
err = xs_send_kvec(sock, NULL, 0, &xdr->tail[0], base, 0);
out:
return ret;
if (sent == 0)
return err;
if (err > 0)
sent += err;
return sent;
}

/**
Expand Down

0 comments on commit 66a10c9

Please sign in to comment.