diff options
Diffstat (limited to 'fs/ncpfs/sock.c')
| -rw-r--r-- | fs/ncpfs/sock.c | 112 | 
1 files changed, 42 insertions, 70 deletions
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 97b111d79489..98b6db0ed63e 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c @@ -16,6 +16,7 @@  #include <linux/fcntl.h>  #include <linux/stat.h>  #include <linux/string.h> +#include <linux/sched/signal.h>  #include <linux/uaccess.h>  #include <linux/in.h>  #include <linux/net.h> @@ -40,19 +41,12 @@ static int _recv(struct socket *sock, void *buf, int size, unsigned flags)  	return kernel_recvmsg(sock, &msg, &iov, 1, size, flags);  } -static inline int do_send(struct socket *sock, struct kvec *vec, int count, -			  int len, unsigned flags) -{ -	struct msghdr msg = { .msg_flags = flags }; -	return kernel_sendmsg(sock, &msg, vec, count, len); -} -  static int _send(struct socket *sock, const void *buff, int len)  { -	struct kvec vec; -	vec.iov_base = (void *) buff; -	vec.iov_len = len; -	return do_send(sock, &vec, 1, len, 0); +	struct msghdr msg = { .msg_flags = 0 }; +	struct kvec vec = {.iov_base = (void *)buff, .iov_len = len}; +	iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &vec, 1, len); +	return sock_sendmsg(sock, &msg);  }  struct ncp_request_reply { @@ -63,9 +57,7 @@ struct ncp_request_reply {  	size_t datalen;  	int result;  	enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; -	struct kvec* tx_ciov; -	size_t tx_totallen; -	size_t tx_iovlen; +	struct iov_iter from;  	struct kvec tx_iov[3];  	u_int16_t tx_type;  	u_int32_t sign[6]; @@ -205,28 +197,22 @@ static inline void __ncptcp_abort(struct ncp_server *server)  static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req)  { -	struct kvec vec[3]; -	/* sock_sendmsg updates iov pointers for us :-( */ -	memcpy(vec, req->tx_ciov, req->tx_iovlen * sizeof(vec[0])); -	return do_send(sock, vec, req->tx_iovlen, -		       req->tx_totallen, MSG_DONTWAIT); +	struct msghdr msg = { .msg_iter = req->from, .msg_flags = MSG_DONTWAIT }; +	return sock_sendmsg(sock, &msg);  }  static void __ncptcp_try_send(struct ncp_server *server)  {  	struct ncp_request_reply *rq; -	struct kvec *iov; -	struct kvec iovc[3]; +	struct msghdr msg = { .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT };  	int result;  	rq = server->tx.creq;  	if (!rq)  		return; -	/* sock_sendmsg updates iov pointers for us :-( */ -	memcpy(iovc, rq->tx_ciov, rq->tx_iovlen * sizeof(iov[0])); -	result = do_send(server->ncp_sock, iovc, rq->tx_iovlen, -			 rq->tx_totallen, MSG_NOSIGNAL | MSG_DONTWAIT); +	msg.msg_iter = rq->from; +	result = sock_sendmsg(server->ncp_sock, &msg);  	if (result == -EAGAIN)  		return; @@ -236,21 +222,12 @@ static void __ncptcp_try_send(struct ncp_server *server)  		__ncp_abort_request(server, rq, result);  		return;  	} -	if (result >= rq->tx_totallen) { +	if (!msg_data_left(&msg)) {  		server->rcv.creq = rq;  		server->tx.creq = NULL;  		return;  	} -	rq->tx_totallen -= result; -	iov = rq->tx_ciov; -	while (iov->iov_len <= result) { -		result -= iov->iov_len; -		iov++; -		rq->tx_iovlen--; -	} -	iov->iov_base += result; -	iov->iov_len -= result; -	rq->tx_ciov = iov; +	rq->from = msg.msg_iter;  }  static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h) @@ -263,22 +240,21 @@ static inline void ncp_init_header(struct ncp_server *server, struct ncp_request  static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req)  { -	size_t signlen; -	struct ncp_request_header* h; +	size_t signlen, len = req->tx_iov[1].iov_len; +	struct ncp_request_header *h = req->tx_iov[1].iov_base; -	req->tx_ciov = req->tx_iov + 1; - -	h = req->tx_iov[1].iov_base;  	ncp_init_header(server, req, h); -	signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,  -			req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, -			cpu_to_le32(req->tx_totallen), req->sign); +	signlen = sign_packet(server, +			req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,  +			len - sizeof(struct ncp_request_header) + 1, +			cpu_to_le32(len), req->sign);  	if (signlen) { -		req->tx_ciov[1].iov_base = req->sign; -		req->tx_ciov[1].iov_len = signlen; -		req->tx_iovlen += 1; -		req->tx_totallen += signlen; +		/* NCP over UDP appends signature */ +		req->tx_iov[2].iov_base = req->sign; +		req->tx_iov[2].iov_len = signlen;  	} +	iov_iter_kvec(&req->from, WRITE | ITER_KVEC, +			req->tx_iov + 1, signlen ? 2 : 1, len + signlen);  	server->rcv.creq = req;  	server->timeout_last = server->m.time_out;  	server->timeout_retries = server->m.retry_count; @@ -292,24 +268,23 @@ static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request  static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req)  { -	size_t signlen; -	struct ncp_request_header* h; +	size_t signlen, len = req->tx_iov[1].iov_len; +	struct ncp_request_header *h = req->tx_iov[1].iov_base; -	req->tx_ciov = req->tx_iov; -	h = req->tx_iov[1].iov_base;  	ncp_init_header(server, req, h);  	signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, -			req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, -			cpu_to_be32(req->tx_totallen + 24), req->sign + 4) + 16; +			len - sizeof(struct ncp_request_header) + 1, +			cpu_to_be32(len + 24), req->sign + 4) + 16;  	req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC); -	req->sign[1] = htonl(req->tx_totallen + signlen); +	req->sign[1] = htonl(len + signlen);  	req->sign[2] = htonl(NCP_TCP_XMIT_VERSION);  	req->sign[3] = htonl(req->datalen + 8); +	/* NCP over TCP prepends signature */  	req->tx_iov[0].iov_base = req->sign;  	req->tx_iov[0].iov_len = signlen; -	req->tx_iovlen += 1; -	req->tx_totallen += signlen; +	iov_iter_kvec(&req->from, WRITE | ITER_KVEC, +			req->tx_iov, 2, len + signlen);  	server->tx.creq = req;  	__ncptcp_try_send(server); @@ -364,18 +339,17 @@ static void __ncp_next_request(struct ncp_server *server)  static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len)  {  	if (server->info_sock) { -		struct kvec iov[2]; -		__be32 hdr[2]; -	 -		hdr[0] = cpu_to_be32(len + 8); -		hdr[1] = cpu_to_be32(id); -	 -		iov[0].iov_base = hdr; -		iov[0].iov_len = 8; -		iov[1].iov_base = (void *) data; -		iov[1].iov_len = len; +		struct msghdr msg = { .msg_flags = MSG_NOSIGNAL }; +		__be32 hdr[2] = {cpu_to_be32(len + 8), cpu_to_be32(id)}; +		struct kvec iov[2] = { +			{.iov_base = hdr, .iov_len = 8}, +			{.iov_base = (void *)data, .iov_len = len}, +		}; + +		iov_iter_kvec(&msg.msg_iter, ITER_KVEC | WRITE, +				iov, 2, len + 8); -		do_send(server->info_sock, iov, 2, len + 8, MSG_NOSIGNAL); +		sock_sendmsg(server->info_sock, &msg);  	}  } @@ -711,8 +685,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,  	req->datalen = max_reply_size;  	req->tx_iov[1].iov_base = server->packet;  	req->tx_iov[1].iov_len = size; -	req->tx_iovlen = 1; -	req->tx_totallen = size;  	req->tx_type = *(u_int16_t*)server->packet;  	result = ncp_add_request(server, req);  | 
