Skip to content

Commit 768ddb1

Browse files
committed
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: David Howells <[email protected]> Reviewed-by: Jeff Layton <[email protected]> cc: [email protected] cc: [email protected] cc: [email protected]
1 parent cae932d commit 768ddb1

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

fs/netfs/io.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ netfs_rreq_prepare_read(struct netfs_io_request *rreq,
525525
struct iov_iter *io_iter)
526526
{
527527
enum netfs_io_source source;
528+
size_t lsize;
528529

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

@@ -547,13 +548,30 @@ netfs_rreq_prepare_read(struct netfs_io_request *rreq,
547548
source = NETFS_INVALID_READ;
548549
goto out;
549550
}
551+
552+
if (subreq->max_nr_segs) {
553+
lsize = netfs_limit_iter(io_iter, 0, subreq->len,
554+
subreq->max_nr_segs);
555+
if (subreq->len > lsize) {
556+
subreq->len = lsize;
557+
trace_netfs_sreq(subreq, netfs_sreq_trace_limited);
558+
}
559+
}
550560
}
551561

562+
if (subreq->len > rreq->len)
563+
pr_warn("R=%08x[%u] SREQ>RREQ %zx > %zx\n",
564+
rreq->debug_id, subreq->debug_index,
565+
subreq->len, rreq->len);
566+
552567
if (WARN_ON(subreq->len == 0)) {
553568
source = NETFS_INVALID_READ;
554569
goto out;
555570
}
556571

572+
subreq->source = source;
573+
trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
574+
557575
subreq->io_iter = *io_iter;
558576
iov_iter_truncate(&subreq->io_iter, subreq->len);
559577
iov_iter_advance(io_iter, subreq->len);

include/linux/netfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ struct netfs_io_subrequest {
161161
refcount_t ref;
162162
short error; /* 0 or error that occurred */
163163
unsigned short debug_index; /* Index in list (for debugging output) */
164+
unsigned int max_nr_segs; /* 0 or max number of segments in an iterator */
164165
enum netfs_io_source source; /* Where to read from/write to */
165166
unsigned long flags;
166167
#define NETFS_SREQ_COPY_TO_CACHE 0 /* Set if should copy the data to the cache */

include/trace/events/netfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define netfs_sreq_traces \
4545
EM(netfs_sreq_trace_download_instead, "RDOWN") \
4646
EM(netfs_sreq_trace_free, "FREE ") \
47+
EM(netfs_sreq_trace_limited, "LIMIT") \
4748
EM(netfs_sreq_trace_prepare, "PREP ") \
4849
EM(netfs_sreq_trace_resubmit_short, "SHORT") \
4950
EM(netfs_sreq_trace_submit, "SUBMT") \

0 commit comments

Comments
 (0)