Skip to content

Commit 09623e3

Browse files
dhowellsbrauner
authored andcommitted
netfs: Fix looping in wait functions
netfs_wait_for_request() and netfs_wait_for_pause() can loop forever if netfs_collect_in_app() returns 2, indicating that it wants to repeat because the ALL_QUEUED flag isn't yet set and there are no subreqs left that haven't been collected. The problem is that, unless collection is offloaded (OFFLOAD_COLLECTION), we have to return to the application thread to continue and eventually set ALL_QUEUED after pausing to deal with a retry - but we never get there. Fix this by inserting checks for the IN_PROGRESS and PAUSE flags as appropriate before cycling round - and add cond_resched() for good measure. Fixes: 2b1424c ("netfs: Fix wait/wake to be consistent about the waitqueue used") Signed-off-by: David Howells <[email protected]> Link: https://lore.kernel.org/[email protected] Tested-by: Steve French <[email protected]> Reviewed-by: Paulo Alcantara <[email protected]> cc: [email protected] cc: [email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 1a6d45f commit 09623e3

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

fs/netfs/misc.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,8 @@ static int netfs_collect_in_app(struct netfs_io_request *rreq,
430430
/*
431431
* Wait for a request to complete, successfully or otherwise.
432432
*/
433-
static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
434-
bool (*collector)(struct netfs_io_request *rreq))
433+
static ssize_t netfs_wait_for_in_progress(struct netfs_io_request *rreq,
434+
bool (*collector)(struct netfs_io_request *rreq))
435435
{
436436
DEFINE_WAIT(myself);
437437
ssize_t ret;
@@ -447,6 +447,9 @@ static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
447447
case 1:
448448
goto all_collected;
449449
case 2:
450+
if (!netfs_check_rreq_in_progress(rreq))
451+
break;
452+
cond_resched();
450453
continue;
451454
}
452455
}
@@ -485,12 +488,12 @@ static ssize_t netfs_wait_for_request(struct netfs_io_request *rreq,
485488

486489
ssize_t netfs_wait_for_read(struct netfs_io_request *rreq)
487490
{
488-
return netfs_wait_for_request(rreq, netfs_read_collection);
491+
return netfs_wait_for_in_progress(rreq, netfs_read_collection);
489492
}
490493

491494
ssize_t netfs_wait_for_write(struct netfs_io_request *rreq)
492495
{
493-
return netfs_wait_for_request(rreq, netfs_write_collection);
496+
return netfs_wait_for_in_progress(rreq, netfs_write_collection);
494497
}
495498

496499
/*
@@ -514,6 +517,10 @@ static void netfs_wait_for_pause(struct netfs_io_request *rreq,
514517
case 1:
515518
goto all_collected;
516519
case 2:
520+
if (!netfs_check_rreq_in_progress(rreq) ||
521+
!test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
522+
break;
523+
cond_resched();
517524
continue;
518525
}
519526
}

0 commit comments

Comments
 (0)