diff options
| author | David Howells <dhowells@redhat.com> | 2024-12-16 20:41:09 +0000 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2024-12-20 22:34:06 +0100 |
| commit | 49866ce7ea8d41a3dc198f519cc9caa2d6be1891 (patch) | |
| tree | c2642c8c52ce186f2f686338c531527653ce0bcb /fs/netfs/read_collect.c | |
| parent | e61bfaad8fd86ac84eac633e0bbaac47a5dfd358 (diff) | |
netfs: Add support for caching single monolithic objects such as AFS dirs
Add support for caching the content of a file that contains a single
monolithic object that must be read/written with a single I/O operation,
such as an AFS directory.
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/20241216204124.3752367-20-dhowells@redhat.com
cc: Jeff Layton <jlayton@kernel.org>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: netfs@lists.linux.dev
cc: linux-afs@lists.infradead.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/netfs/read_collect.c')
| -rw-r--r-- | fs/netfs/read_collect.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c index 26e430baeb5a..2e9291ab1d62 100644 --- a/fs/netfs/read_collect.c +++ b/fs/netfs/read_collect.c @@ -362,6 +362,39 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq) } /* + * Do processing after reading a monolithic single object. + */ +static void netfs_rreq_assess_single(struct netfs_io_request *rreq) +{ + struct netfs_io_subrequest *subreq; + struct netfs_io_stream *stream = &rreq->io_streams[0]; + + subreq = list_first_entry_or_null(&stream->subrequests, + struct netfs_io_subrequest, rreq_link); + if (subreq) { + if (test_bit(NETFS_SREQ_FAILED, &subreq->flags)) + rreq->error = subreq->error; + else + rreq->transferred = subreq->transferred; + + if (!rreq->error && subreq->source == NETFS_DOWNLOAD_FROM_SERVER && + fscache_resources_valid(&rreq->cache_resources)) { + trace_netfs_rreq(rreq, netfs_rreq_trace_dirty); + netfs_single_mark_inode_dirty(rreq->inode); + } + } + + if (rreq->iocb) { + rreq->iocb->ki_pos += rreq->transferred; + if (rreq->iocb->ki_complete) + rreq->iocb->ki_complete( + rreq->iocb, rreq->error ? rreq->error : rreq->transferred); + } + if (rreq->netfs_ops->done) + rreq->netfs_ops->done(rreq); +} + +/* * Assess the state of a read request and decide what to do next. * * Note that we're in normal kernel thread context at this point, possibly @@ -378,9 +411,17 @@ void netfs_rreq_terminated(struct netfs_io_request *rreq) return; } - if (rreq->origin == NETFS_DIO_READ || - rreq->origin == NETFS_READ_GAPS) + switch (rreq->origin) { + case NETFS_DIO_READ: + case NETFS_READ_GAPS: netfs_rreq_assess_dio(rreq); + break; + case NETFS_READ_SINGLE: + netfs_rreq_assess_single(rreq); + break; + default: + break; + } task_io_account_read(rreq->transferred); trace_netfs_rreq(rreq, netfs_rreq_trace_wake_ip); |