[PATCH 05/19] netfs: Refactor arguments for netfs_alloc_read_request

From: David Howells
Date: Wed Mar 02 2022 - 09:05:57 EST


From: Jeff Layton <jlayton@xxxxxxxxxx>

Pass start and len to the rreq allocator. This should ensure that the
fields are set so that init_rreq can use them.

Also add a parameter to indicates the origin of the request. Ceph can use
this to tell whether to get caps.

Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
cc: linux-cachefs@xxxxxxxxxx
---

fs/netfs/read_helper.c | 25 ++++++++++++++++---------
include/linux/netfs.h | 7 +++++++
2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/fs/netfs/read_helper.c b/fs/netfs/read_helper.c
index a90b3fbcb93f..37125ed95d1a 100644
--- a/fs/netfs/read_helper.c
+++ b/fs/netfs/read_helper.c
@@ -36,8 +36,11 @@ static void netfs_put_subrequest(struct netfs_io_subrequest *subreq,
__netfs_put_subrequest(subreq, was_async);
}

-static struct netfs_io_request *netfs_alloc_read_request(struct address_space *mapping,
- struct file *file)
+static struct netfs_io_request *netfs_alloc_read_request(
+ struct address_space *mapping,
+ struct file *file,
+ loff_t start, size_t len,
+ enum netfs_read_origin origin)
{
static atomic_t debug_ids;
struct inode *inode = file ? file_inode(file) : mapping->host;
@@ -46,8 +49,11 @@ static struct netfs_io_request *netfs_alloc_read_request(struct address_space *m

rreq = kzalloc(sizeof(struct netfs_io_request), GFP_KERNEL);
if (rreq) {
+ rreq->start = start;
+ rreq->len = len;
rreq->mapping = mapping;
rreq->inode = inode;
+ rreq->origin = origin;
rreq->netfs_ops = ctx->ops;
rreq->i_size = i_size_read(inode);
rreq->debug_id = atomic_inc_return(&debug_ids);
@@ -874,11 +880,12 @@ void netfs_readahead(struct readahead_control *ractl)
if (readahead_count(ractl) == 0)
return;

- rreq = netfs_alloc_read_request(ractl->mapping, ractl->file);
+ rreq = netfs_alloc_read_request(ractl->mapping, ractl->file,
+ readahead_pos(ractl),
+ readahead_length(ractl),
+ NETFS_READAHEAD);
if (!rreq)
return;
- rreq->start = readahead_pos(ractl);
- rreq->len = readahead_length(ractl);

if (ctx->ops->begin_cache_operation) {
ret = ctx->ops->begin_cache_operation(rreq);
@@ -941,11 +948,10 @@ int netfs_readpage(struct file *file, struct page *subpage)

_enter("%lx", folio_index(folio));

- rreq = netfs_alloc_read_request(mapping, file);
+ rreq = netfs_alloc_read_request(mapping, file, folio_file_pos(folio),
+ folio_size(folio), NETFS_READPAGE);
if (!rreq)
goto nomem;
- rreq->start = folio_file_pos(folio);
- rreq->len = folio_size(folio);

if (ctx->ops->begin_cache_operation) {
ret = ctx->ops->begin_cache_operation(rreq);
@@ -1118,7 +1124,8 @@ int netfs_write_begin(struct file *file, struct address_space *mapping,
}

ret = -ENOMEM;
- rreq = netfs_alloc_read_request(mapping, file);
+ rreq = netfs_alloc_read_request(mapping, file, folio_file_pos(folio),
+ folio_size(folio), NETFS_READ_FOR_WRITE);
if (!rreq)
goto error;
rreq->start = folio_file_pos(folio);
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index 630b0400e9fa..a5434bc80e1c 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -158,6 +158,12 @@ struct netfs_io_subrequest {
#define NETFS_SREQ_NO_PROGRESS 4 /* Set if we didn't manage to read any data */
};

+enum netfs_read_origin {
+ NETFS_READAHEAD, /* This read was triggered by readahead */
+ NETFS_READPAGE, /* This read is a synchronous read */
+ NETFS_READ_FOR_WRITE, /* This read is to prepare a write */
+} __mode(byte);
+
/*
* Descriptor for a read helper request. This is used to make multiple I/O
* requests on a variety of sources and then stitch the result together.
@@ -175,6 +181,7 @@ struct netfs_io_request {
size_t submitted; /* Amount submitted for I/O so far */
size_t len; /* Length of the request */
short error; /* 0 or error that occurred */
+ enum netfs_read_origin origin; /* Origin of the read */
loff_t i_size; /* Size of the file */
loff_t start; /* Start position */
pgoff_t no_unlock_folio; /* Don't unlock this folio after read */