Commit 768ddb1e authored by David Howells's avatar David Howells
Browse files

netfs: Limit subrequest by size or number of segments



Limit a subrequest to a maximum size and/or a maximum number of contiguous
physical regions.  This permits, for instance, an subreq's iterator to be
limited to the number of DMA'able segments that a large RDMA request can
handle.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
cc: linux-cachefs@redhat.com
cc: linux-fsdevel@vger.kernel.org
cc: linux-mm@kvack.org
parent cae932d3
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -525,6 +525,7 @@ netfs_rreq_prepare_read(struct netfs_io_request *rreq,
			struct iov_iter *io_iter)
{
	enum netfs_io_source source;
	size_t lsize;

	_enter("%llx-%llx,%llx", subreq->start, subreq->start + subreq->len, rreq->i_size);

@@ -547,13 +548,30 @@ netfs_rreq_prepare_read(struct netfs_io_request *rreq,
			source = NETFS_INVALID_READ;
			goto out;
		}

		if (subreq->max_nr_segs) {
			lsize = netfs_limit_iter(io_iter, 0, subreq->len,
						 subreq->max_nr_segs);
			if (subreq->len > lsize) {
				subreq->len = lsize;
				trace_netfs_sreq(subreq, netfs_sreq_trace_limited);
			}
		}
	}

	if (subreq->len > rreq->len)
		pr_warn("R=%08x[%u] SREQ>RREQ %zx > %zx\n",
			rreq->debug_id, subreq->debug_index,
			subreq->len, rreq->len);

	if (WARN_ON(subreq->len == 0)) {
		source = NETFS_INVALID_READ;
		goto out;
	}

	subreq->source = source;
	trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);

	subreq->io_iter = *io_iter;
	iov_iter_truncate(&subreq->io_iter, subreq->len);
	iov_iter_advance(io_iter, subreq->len);
+1 −0
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ struct netfs_io_subrequest {
	refcount_t		ref;
	short			error;		/* 0 or error that occurred */
	unsigned short		debug_index;	/* Index in list (for debugging output) */
	unsigned int		max_nr_segs;	/* 0 or max number of segments in an iterator */
	enum netfs_io_source	source;		/* Where to read from/write to */
	unsigned long		flags;
#define NETFS_SREQ_COPY_TO_CACHE	0	/* Set if should copy the data to the cache */
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#define netfs_sreq_traces					\
	EM(netfs_sreq_trace_download_instead,	"RDOWN")	\
	EM(netfs_sreq_trace_free,		"FREE ")	\
	EM(netfs_sreq_trace_limited,		"LIMIT")	\
	EM(netfs_sreq_trace_prepare,		"PREP ")	\
	EM(netfs_sreq_trace_resubmit_short,	"SHORT")	\
	EM(netfs_sreq_trace_submit,		"SUBMT")	\