diff options
Diffstat (limited to 'net/9p/client.c')
| -rw-r--r-- | net/9p/client.c | 49 | 
1 files changed, 49 insertions, 0 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index f7e90b4769bb..00774656eeac 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -18,6 +18,7 @@  #include <linux/sched/signal.h>  #include <linux/uaccess.h>  #include <linux/uio.h> +#include <linux/netfs.h>  #include <net/9p/9p.h>  #include <linux/parser.h>  #include <linux/seq_file.h> @@ -1661,6 +1662,54 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)  }  EXPORT_SYMBOL(p9_client_write); +void +p9_client_write_subreq(struct netfs_io_subrequest *subreq) +{ +	struct netfs_io_request *wreq = subreq->rreq; +	struct p9_fid *fid = wreq->netfs_priv; +	struct p9_client *clnt = fid->clnt; +	struct p9_req_t *req; +	unsigned long long start = subreq->start + subreq->transferred; +	int written, len = subreq->len - subreq->transferred; +	int err; + +	p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu len %d\n", +		 fid->fid, start, len); + +	/* Don't bother zerocopy for small IO (< 1024) */ +	if (clnt->trans_mod->zc_request && len > 1024) { +		req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, &subreq->io_iter, +				       0, wreq->len, P9_ZC_HDR_SZ, "dqd", +				       fid->fid, start, len); +	} else { +		req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid, +				    start, len, &subreq->io_iter); +	} +	if (IS_ERR(req)) { +		netfs_write_subrequest_terminated(subreq, PTR_ERR(req), false); +		return; +	} + +	err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &written); +	if (err) { +		trace_9p_protocol_dump(clnt, &req->rc); +		p9_req_put(clnt, req); +		netfs_write_subrequest_terminated(subreq, err, false); +		return; +	} + +	if (written > len) { +		pr_err("bogus RWRITE count (%d > %u)\n", written, len); +		written = len; +	} + +	p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", len); + +	p9_req_put(clnt, req); +	netfs_write_subrequest_terminated(subreq, written, false); +} +EXPORT_SYMBOL(p9_client_write_subreq); +  struct p9_wstat *p9_client_stat(struct p9_fid *fid)  {  	int err;  |