2121 */
2222static void netfs_clear_unread (struct netfs_io_subrequest * subreq )
2323{
24- struct iov_iter iter ;
25-
26- iov_iter_xarray (& iter , ITER_DEST , & subreq -> rreq -> mapping -> i_pages ,
27- subreq -> start + subreq -> transferred ,
28- subreq -> len - subreq -> transferred );
29- iov_iter_zero (iov_iter_count (& iter ), & iter );
24+ iov_iter_zero (iov_iter_count (& subreq -> io_iter ), & subreq -> io_iter );
3025}
3126
3227static void netfs_cache_read_terminated (void * priv , ssize_t transferred_or_error ,
@@ -46,14 +41,9 @@ static void netfs_read_from_cache(struct netfs_io_request *rreq,
4641 enum netfs_read_from_hole read_hole )
4742{
4843 struct netfs_cache_resources * cres = & rreq -> cache_resources ;
49- struct iov_iter iter ;
5044
5145 netfs_stat (& netfs_n_rh_read );
52- iov_iter_xarray (& iter , ITER_DEST , & rreq -> mapping -> i_pages ,
53- subreq -> start + subreq -> transferred ,
54- subreq -> len - subreq -> transferred );
55-
56- cres -> ops -> read (cres , subreq -> start , & iter , read_hole ,
46+ cres -> ops -> read (cres , subreq -> start , & subreq -> io_iter , read_hole ,
5747 netfs_cache_read_terminated , subreq );
5848}
5949
@@ -88,6 +78,11 @@ static void netfs_read_from_server(struct netfs_io_request *rreq,
8878 struct netfs_io_subrequest * subreq )
8979{
9080 netfs_stat (& netfs_n_rh_download );
81+ if (iov_iter_count (& subreq -> io_iter ) != subreq -> len - subreq -> transferred )
82+ pr_warn ("R=%08x[%u] ITER PRE-MISMATCH %zx != %zx-%zx %lx\n" ,
83+ rreq -> debug_id , subreq -> debug_index ,
84+ iov_iter_count (& subreq -> io_iter ), subreq -> len ,
85+ subreq -> transferred , subreq -> flags );
9186 rreq -> netfs_ops -> issue_read (subreq );
9287}
9388
@@ -259,6 +254,30 @@ static void netfs_rreq_short_read(struct netfs_io_request *rreq,
259254 netfs_read_from_server (rreq , subreq );
260255}
261256
257+ /*
258+ * Reset the subrequest iterator prior to resubmission.
259+ */
260+ static void netfs_reset_subreq_iter (struct netfs_io_request * rreq ,
261+ struct netfs_io_subrequest * subreq )
262+ {
263+ size_t remaining = subreq -> len - subreq -> transferred ;
264+ size_t count = iov_iter_count (& subreq -> io_iter );
265+
266+ if (count == remaining )
267+ return ;
268+
269+ _debug ("R=%08x[%u] ITER RESUB-MISMATCH %zx != %zx-%zx-%llx %x\n" ,
270+ rreq -> debug_id , subreq -> debug_index ,
271+ iov_iter_count (& subreq -> io_iter ), subreq -> transferred ,
272+ subreq -> len , rreq -> i_size ,
273+ subreq -> io_iter .iter_type );
274+
275+ if (count < remaining )
276+ iov_iter_revert (& subreq -> io_iter , remaining - count );
277+ else
278+ iov_iter_advance (& subreq -> io_iter , count - remaining );
279+ }
280+
262281/*
263282 * Resubmit any short or failed operations. Returns true if we got the rreq
264283 * ref back.
@@ -287,6 +306,7 @@ static bool netfs_rreq_perform_resubmissions(struct netfs_io_request *rreq)
287306 trace_netfs_sreq (subreq , netfs_sreq_trace_download_instead );
288307 netfs_get_subrequest (subreq , netfs_sreq_trace_get_resubmit );
289308 atomic_inc (& rreq -> nr_outstanding );
309+ netfs_reset_subreq_iter (rreq , subreq );
290310 netfs_read_from_server (rreq , subreq );
291311 } else if (test_bit (NETFS_SREQ_SHORT_IO , & subreq -> flags )) {
292312 netfs_rreq_short_read (rreq , subreq );
@@ -399,9 +419,9 @@ void netfs_subreq_terminated(struct netfs_io_subrequest *subreq,
399419 struct netfs_io_request * rreq = subreq -> rreq ;
400420 int u ;
401421
402- _enter ("[%u ]{%llx,%lx},%zd" ,
403- subreq -> debug_index , subreq -> start , subreq -> flags ,
404- transferred_or_error );
422+ _enter ("R=%x[%x ]{%llx,%lx},%zd" ,
423+ rreq -> debug_id , subreq -> debug_index ,
424+ subreq -> start , subreq -> flags , transferred_or_error );
405425
406426 switch (subreq -> source ) {
407427 case NETFS_READ_FROM_CACHE :
@@ -501,7 +521,8 @@ static enum netfs_io_source netfs_cache_prepare_read(struct netfs_io_subrequest
501521 */
502522static enum netfs_io_source
503523netfs_rreq_prepare_read (struct netfs_io_request * rreq ,
504- struct netfs_io_subrequest * subreq )
524+ struct netfs_io_subrequest * subreq ,
525+ struct iov_iter * io_iter )
505526{
506527 enum netfs_io_source source ;
507528
@@ -528,9 +549,14 @@ netfs_rreq_prepare_read(struct netfs_io_request *rreq,
528549 }
529550 }
530551
531- if (WARN_ON (subreq -> len == 0 ))
552+ if (WARN_ON (subreq -> len == 0 )) {
532553 source = NETFS_INVALID_READ ;
554+ goto out ;
555+ }
533556
557+ subreq -> io_iter = * io_iter ;
558+ iov_iter_truncate (& subreq -> io_iter , subreq -> len );
559+ iov_iter_advance (io_iter , subreq -> len );
534560out :
535561 subreq -> source = source ;
536562 trace_netfs_sreq (subreq , netfs_sreq_trace_prepare );
@@ -541,6 +567,7 @@ netfs_rreq_prepare_read(struct netfs_io_request *rreq,
541567 * Slice off a piece of a read request and submit an I/O request for it.
542568 */
543569static bool netfs_rreq_submit_slice (struct netfs_io_request * rreq ,
570+ struct iov_iter * io_iter ,
544571 unsigned int * _debug_index )
545572{
546573 struct netfs_io_subrequest * subreq ;
@@ -565,7 +592,7 @@ static bool netfs_rreq_submit_slice(struct netfs_io_request *rreq,
565592 * (the starts must coincide), in which case, we go around the loop
566593 * again and ask it to download the next piece.
567594 */
568- source = netfs_rreq_prepare_read (rreq , subreq );
595+ source = netfs_rreq_prepare_read (rreq , subreq , io_iter );
569596 if (source == NETFS_INVALID_READ )
570597 goto subreq_failed ;
571598
@@ -603,6 +630,7 @@ static bool netfs_rreq_submit_slice(struct netfs_io_request *rreq,
603630 */
604631int netfs_begin_read (struct netfs_io_request * rreq , bool sync )
605632{
633+ struct iov_iter io_iter ;
606634 unsigned int debug_index = 0 ;
607635 int ret ;
608636
@@ -615,6 +643,8 @@ int netfs_begin_read(struct netfs_io_request *rreq, bool sync)
615643 return - EIO ;
616644 }
617645
646+ rreq -> io_iter = rreq -> iter ;
647+
618648 INIT_WORK (& rreq -> work , netfs_rreq_work );
619649
620650 if (sync )
@@ -624,8 +654,9 @@ int netfs_begin_read(struct netfs_io_request *rreq, bool sync)
624654 * want and submit each one.
625655 */
626656 atomic_set (& rreq -> nr_outstanding , 1 );
657+ io_iter = rreq -> io_iter ;
627658 do {
628- if (!netfs_rreq_submit_slice (rreq , & debug_index ))
659+ if (!netfs_rreq_submit_slice (rreq , & io_iter , & debug_index ))
629660 break ;
630661
631662 } while (rreq -> submitted < rreq -> len );
0 commit comments