linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] 9pnet: allow making incomplete read requests
@ 2020-02-05 20:40 Sergey Alirzaev
  2020-02-05 21:54 ` Dominique Martinet
  0 siblings, 1 reply; 3+ messages in thread
From: Sergey Alirzaev @ 2020-02-05 20:40 UTC (permalink / raw)
  To: v9fs-developer
  Cc: Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
	David S. Miller, Jakub Kicinski, netdev, linux-kernel,
	Sergey Alirzaev

A user doesn't necessarily want to wait for all the requested data to
be available, since the waiting time for each request is unbounded.

The new method permits sending one read request at a time and getting
the response ASAP, allowing to use 9pnet with synthetic file systems
representing arbitrary data streams.

Signed-off-by: Sergey Alirzaev <l29ah@cock.li>
---
 include/net/9p/client.h |   2 +
 net/9p/client.c         | 135 ++++++++++++++++++++++------------------
 2 files changed, 76 insertions(+), 61 deletions(-)

diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index acc60d8a3b3b..f6c890e94f87 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -200,6 +200,8 @@ int p9_client_fsync(struct p9_fid *fid, int datasync);
 int p9_client_remove(struct p9_fid *fid);
 int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags);
 int p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err);
+int p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
+		int *err);
 int p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err);
 int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset);
 int p9dirent_read(struct p9_client *clnt, char *buf, int len,
diff --git a/net/9p/client.c b/net/9p/client.c
index 1d48afc7033c..240d7c05b282 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1549,82 +1549,95 @@ EXPORT_SYMBOL(p9_client_unlinkat);
 int
 p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
 {
-	struct p9_client *clnt = fid->clnt;
-	struct p9_req_t *req;
 	int total = 0;
 	*err = 0;
 
+	while (iov_iter_count(to)) {
+		int count;
+
+		count = p9_client_read_once(fid, offset, to, err);
+		if (!count || *err)
+			break;
+		offset += count;
+		total += count;
+	}
+	return total;
+}
+EXPORT_SYMBOL(p9_client_read);
+
+int
+p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
+		    int *err)
+{
+	struct p9_client *clnt = fid->clnt;
+	struct p9_req_t *req;
+	int count = iov_iter_count(to);
+	int rsize, non_zc = 0;
+	char *dataptr;
+
+	*err = 0;
 	p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
 		   fid->fid, (unsigned long long) offset, (int)iov_iter_count(to));
 
-	while (iov_iter_count(to)) {
-		int count = iov_iter_count(to);
-		int rsize, non_zc = 0;
-		char *dataptr;
+	rsize = fid->iounit;
+	if (!rsize || rsize > clnt->msize - P9_IOHDRSZ)
+		rsize = clnt->msize - P9_IOHDRSZ;
 
-		rsize = fid->iounit;
-		if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
-			rsize = clnt->msize - P9_IOHDRSZ;
+	if (count < rsize)
+		rsize = count;
 
-		if (count < rsize)
-			rsize = count;
+	/* Don't bother zerocopy for small IO (< 1024) */
+	if (clnt->trans_mod->zc_request && rsize > 1024) {
+		/* response header len is 11
+		 * PDU Header(7) + IO Size (4)
+		 */
+		req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize,
+				       0, 11, "dqd", fid->fid,
+				       offset, rsize);
+	} else {
+		non_zc = 1;
+		req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
+				    rsize);
+	}
+	if (IS_ERR(req)) {
+		*err = PTR_ERR(req);
+		return 0;
+	}
 
-		/* Don't bother zerocopy for small IO (< 1024) */
-		if (clnt->trans_mod->zc_request && rsize > 1024) {
-			/*
-			 * response header len is 11
-			 * PDU Header(7) + IO Size (4)
-			 */
-			req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize,
-					       0, 11, "dqd", fid->fid,
-					       offset, rsize);
-		} else {
-			non_zc = 1;
-			req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
-					    rsize);
-		}
-		if (IS_ERR(req)) {
-			*err = PTR_ERR(req);
-			break;
-		}
+	*err = p9pdu_readf(&req->rc, clnt->proto_version,
+			   "D", &count, &dataptr);
+	if (*err) {
+		trace_9p_protocol_dump(clnt, &req->rc);
+		p9_tag_remove(clnt, req);
+		return 0;
+	}
+	if (rsize < count) {
+		pr_err("bogus RREAD count (%d > %d)\n", count, rsize);
+		count = rsize;
+	}
 
-		*err = p9pdu_readf(&req->rc, clnt->proto_version,
-				   "D", &count, &dataptr);
-		if (*err) {
-			trace_9p_protocol_dump(clnt, &req->rc);
-			p9_tag_remove(clnt, req);
-			break;
-		}
-		if (rsize < count) {
-			pr_err("bogus RREAD count (%d > %d)\n", count, rsize);
-			count = rsize;
-		}
+	p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
+	if (!count) {
+		p9_tag_remove(clnt, req);
+		return 0;
+	}
 
-		p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
-		if (!count) {
-			p9_tag_remove(clnt, req);
-			break;
-		}
+	if (non_zc) {
+		int n = copy_to_iter(dataptr, count, to);
 
-		if (non_zc) {
-			int n = copy_to_iter(dataptr, count, to);
-			total += n;
-			offset += n;
-			if (n != count) {
-				*err = -EFAULT;
-				p9_tag_remove(clnt, req);
-				break;
-			}
-		} else {
-			iov_iter_advance(to, count);
-			total += count;
-			offset += count;
+		if (n != count) {
+			*err = -EFAULT;
+			p9_tag_remove(clnt, req);
+			return n;
 		}
-		p9_tag_remove(clnt, req);
+	} else {
+		iov_iter_advance(to, count);
+		count;
 	}
-	return total;
+	p9_tag_remove(clnt, req);
+	return count;
 }
-EXPORT_SYMBOL(p9_client_read);
+EXPORT_SYMBOL(p9_client_read_once);
 
 int
 p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] 9pnet: allow making incomplete read requests
  2020-02-05 20:40 [PATCH] 9pnet: allow making incomplete read requests Sergey Alirzaev
@ 2020-02-05 21:54 ` Dominique Martinet
  2020-02-05 22:06   ` l29ah
  0 siblings, 1 reply; 3+ messages in thread
From: Dominique Martinet @ 2020-02-05 21:54 UTC (permalink / raw)
  To: Sergey Alirzaev
  Cc: v9fs-developer, Eric Van Hensbergen, Latchesar Ionkov,
	David S. Miller, Jakub Kicinski, netdev, linux-kernel

Sergey Alirzaev wrote on Wed, Feb 05, 2020:
> A user doesn't necessarily want to wait for all the requested data to
> be available, since the waiting time for each request is unbounded.
> 
> The new method permits sending one read request at a time and getting
> the response ASAP, allowing to use 9pnet with synthetic file systems
> representing arbitrary data streams.

Much better, thanks!

> Signed-off-by: Sergey Alirzaev <l29ah@cock.li>
> [...]
> +		if (n != count) {
> +			*err = -EFAULT;
> +			p9_tag_remove(clnt, req);
> +			return n;
>  		}
> -		p9_tag_remove(clnt, req);
> +	} else {
> +		iov_iter_advance(to, count);
> +		count;

Any reason for this stray 'count;' statement?

If you're ok with this I'll just take patch without that line, don't
bother resubmitting.
Will take a fair amount of time to make it to linux-next though, test
setup needs some love and I want to run tests even if this should be
straightforward...

Thanks,
-- 
Dominique

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] 9pnet: allow making incomplete read requests
  2020-02-05 21:54 ` Dominique Martinet
@ 2020-02-05 22:06   ` l29ah
  0 siblings, 0 replies; 3+ messages in thread
From: l29ah @ 2020-02-05 22:06 UTC (permalink / raw)
  To: Dominique Martinet
  Cc: Sergey Alirzaev, v9fs-developer, Eric Van Hensbergen,
	Latchesar Ionkov, David S. Miller, Jakub Kicinski, netdev,
	linux-kernel

On Wed, Feb 05, 2020 at 10:54:46PM +0100, Dominique Martinet wrote:
> > [...]
> > +		if (n != count) {
> > +			*err = -EFAULT;
> > +			p9_tag_remove(clnt, req);
> > +			return n;
> >  		}
> > -		p9_tag_remove(clnt, req);
> > +	} else {
> > +		iov_iter_advance(to, count);
> > +		count;
> 
> Any reason for this stray 'count;' statement?
> If you're ok with this I'll just take patch without that line, don't
> bother resubmitting.

No reason, i've just accidentally left it.

> Will take a fair amount of time to make it to linux-next though, test
> setup needs some love and I want to run tests even if this should be
> straightforward...

Thanks!

-- 
()  ascii ribbon campaign - against html mail
/\  http://arc.pasp.de/   - against proprietary attachments

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-02-05 22:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-05 20:40 [PATCH] 9pnet: allow making incomplete read requests Sergey Alirzaev
2020-02-05 21:54 ` Dominique Martinet
2020-02-05 22:06   ` l29ah

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).