diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c index f65affa5a9e4..6f3c0404f4b8 100644 --- a/fs/netfs/read_collect.c +++ b/fs/netfs/read_collect.c @@ -207,6 +207,7 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq) * in progress. The issuer thread may be adding stuff to the tail * whilst we're doing this. */ + spin_lock(&rreq->lock); front = READ_ONCE(stream->front); while (front) { size_t transferred; @@ -288,7 +289,6 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq) /* Remove if completely consumed. */ stream->source = front->source; - spin_lock(&rreq->lock); remove = front; trace_netfs_sreq(front, netfs_sreq_trace_discard); @@ -296,12 +296,12 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq) front = list_first_entry_or_null(&stream->subrequests, struct netfs_io_subrequest, rreq_link); stream->front = front; - spin_unlock(&rreq->lock); netfs_put_subrequest(remove, false, notes & ABANDON_SREQ ? netfs_sreq_trace_put_abandon : netfs_sreq_trace_put_done); } + spin_unlock(&rreq->lock); trace_netfs_collect_stream(rreq, stream); trace_netfs_collect_state(rreq, rreq->collected_to, notes); @@ -369,12 +369,17 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq) } } + spin_lock(&rreq->lock); if (rreq->iocb) { rreq->iocb->ki_pos += rreq->transferred; - if (rreq->iocb->ki_complete) + if (rreq->iocb->ki_complete) { rreq->iocb->ki_complete( rreq->iocb, rreq->error ? rreq->error : rreq->transferred); + rreq->iocb = NULL; + } } + spin_unlock(&rreq->lock); + if (rreq->netfs_ops->done) rreq->netfs_ops->done(rreq); if (rreq->origin == NETFS_DIO_READ)