Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

More iov_iter work from Al Viro.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2015-02-04 20:46:55 -08:00
33 changed files with 327 additions and 693 deletions

View File

@@ -232,10 +232,7 @@ int rxrpc_kernel_send_data(struct rxrpc_call *call, struct msghdr *msg,
call->state != RXRPC_CALL_SERVER_SEND_REPLY) {
ret = -EPROTO; /* request phase complete for this client call */
} else {
mm_segment_t oldfs = get_fs();
set_fs(KERNEL_DS);
ret = rxrpc_send_data(NULL, call->socket, call, msg, len);
set_fs(oldfs);
}
release_sock(&call->socket->sk);
@@ -529,13 +526,11 @@ static int rxrpc_send_data(struct kiocb *iocb,
struct msghdr *msg, size_t len)
{
struct rxrpc_skb_priv *sp;
unsigned char __user *from;
struct sk_buff *skb;
const struct iovec *iov;
struct sock *sk = &rx->sk;
long timeo;
bool more;
int ret, ioc, segment, copied;
int ret, copied;
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
@@ -545,25 +540,17 @@ static int rxrpc_send_data(struct kiocb *iocb,
if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
return -EPIPE;
iov = msg->msg_iter.iov;
ioc = msg->msg_iter.nr_segs - 1;
from = iov->iov_base;
segment = iov->iov_len;
iov++;
more = msg->msg_flags & MSG_MORE;
skb = call->tx_pending;
call->tx_pending = NULL;
copied = 0;
do {
if (len > iov_iter_count(&msg->msg_iter))
len = iov_iter_count(&msg->msg_iter);
while (len) {
int copy;
if (segment > len)
segment = len;
_debug("SEGMENT %d @%p", segment, from);
if (!skb) {
size_t size, chunk, max, space;
@@ -631,13 +618,13 @@ static int rxrpc_send_data(struct kiocb *iocb,
/* append next segment of data to the current buffer */
copy = skb_tailroom(skb);
ASSERTCMP(copy, >, 0);
if (copy > segment)
copy = segment;
if (copy > len)
copy = len;
if (copy > sp->remain)
copy = sp->remain;
_debug("add");
ret = skb_add_data(skb, from, copy);
ret = skb_add_data(skb, &msg->msg_iter, copy);
_debug("added");
if (ret < 0)
goto efault;
@@ -646,18 +633,6 @@ static int rxrpc_send_data(struct kiocb *iocb,
copied += copy;
len -= copy;
segment -= copy;
from += copy;
while (segment == 0 && ioc > 0) {
from = iov->iov_base;
segment = iov->iov_len;
iov++;
ioc--;
}
if (len == 0) {
segment = 0;
ioc = 0;
}
/* check for the far side aborting the call or a network error
* occurring */
@@ -665,7 +640,7 @@ static int rxrpc_send_data(struct kiocb *iocb,
goto call_aborted;
/* add the packet to the send queue if it's now full */
if (sp->remain <= 0 || (segment == 0 && !more)) {
if (sp->remain <= 0 || (!len && !more)) {
struct rxrpc_connection *conn = call->conn;
uint32_t seq;
size_t pad;
@@ -711,11 +686,10 @@ static int rxrpc_send_data(struct kiocb *iocb,
memcpy(skb->head, &sp->hdr,
sizeof(struct rxrpc_header));
rxrpc_queue_packet(call, skb, segment == 0 && !more);
rxrpc_queue_packet(call, skb, !iov_iter_count(&msg->msg_iter) && !more);
skb = NULL;
}
} while (segment > 0);
}
success:
ret = copied;