aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/write.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2020-02-06 14:22:28 +0000
committerDavid Howells <dhowells@redhat.com>2021-04-23 10:17:27 +0100
commitc450846461f88b8888d6f5c2a2aa63ab64864978 (patch)
treeb16a044f70d48605e7c838ae854b03f7098511e7 /fs/afs/write.c
parentafs: Log remote unmarshalling errors (diff)
downloadlinux-dev-c450846461f88b8888d6f5c2a2aa63ab64864978.tar.xz
linux-dev-c450846461f88b8888d6f5c2a2aa63ab64864978.zip
afs: Set up the iov_iter before calling afs_extract_data()
afs_extract_data() sets up a temporary iov_iter and passes it to AF_RXRPC each time it is called to describe the remaining buffer to be filled. Instead: (1) Put an iterator in the afs_call struct. (2) Set the iterator for each marshalling stage to load data into the appropriate places. A number of convenience functions are provided to this end (eg. afs_extract_to_buf()). This iterator is then passed to afs_extract_data(). (3) Use the new ITER_XARRAY iterator when reading data to load directly into the inode's pages without needing to create a list of them. This will allow O_DIRECT calls to be supported in future patches. Signed-off-by: David Howells <dhowells@redhat.com> Tested-By: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/152898380012.11616.12094591785228251717.stgit@warthog.procyon.org.uk/ Link: https://lore.kernel.org/r/153685394431.14766.3178466345696987059.stgit@warthog.procyon.org.uk/ Link: https://lore.kernel.org/r/153999787395.866.11218209749223643998.stgit@warthog.procyon.org.uk/ Link: https://lore.kernel.org/r/154033911195.12041.3882700371848894587.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/158861250059.340223.1248231474865140653.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/159465827399.1377938.11181327349704960046.stgit@warthog.procyon.org.uk/ Link: https://lore.kernel.org/r/160588533776.3465195.3612752083351956948.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/161118151238.1232039.17015723405750601161.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/161161047240.2537118.14721975104810564022.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/161340410333.1303470.16260122230371140878.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/161539554187.286939.15305559004905459852.stgit@warthog.procyon.org.uk/ # v4 Link: https://lore.kernel.org/r/161653810525.2770958.4630666029125411789.stgit@warthog.procyon.org.uk/ # v5 Link: https://lore.kernel.org/r/161789093719.6155.7877160739235087723.stgit@warthog.procyon.org.uk/ # v6
Diffstat (limited to 'fs/afs/write.c')
-rw-r--r--fs/afs/write.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/afs/write.c b/fs/afs/write.c
index a91da2e680da..cb24f849e592 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -23,6 +23,16 @@ int afs_set_page_dirty(struct page *page)
}
/*
+ * Handle completion of a read operation to fill a page.
+ */
+static void afs_fill_hole(struct afs_read *req)
+{
+ if (iov_iter_count(req->iter) > 0)
+ /* The read was short - clear the excess buffer. */
+ iov_iter_zero(iov_iter_count(req->iter), req->iter);
+}
+
+/*
* partly or wholly fill a page that's under preparation for writing
*/
static int afs_fill_page(struct file *file,
@@ -45,18 +55,19 @@ static int afs_fill_page(struct file *file,
return 0;
}
- req = kzalloc(struct_size(req, array, 1), GFP_KERNEL);
+ req = kzalloc(sizeof(struct afs_read), GFP_KERNEL);
if (!req)
return -ENOMEM;
refcount_set(&req->usage, 1);
- req->key = key_get(afs_file_key(file));
- req->pos = pos;
- req->len = len;
- req->nr_pages = 1;
- req->pages = req->array;
- req->pages[0] = page;
- get_page(page);
+ req->vnode = vnode;
+ req->done = afs_fill_hole;
+ req->key = key_get(afs_file_key(file));
+ req->pos = pos;
+ req->len = len;
+ req->nr_pages = 1;
+ req->iter = &req->def_iter;
+ iov_iter_xarray(&req->def_iter, READ, &file->f_mapping->i_pages, pos, len);
ret = afs_fetch_data(vnode, req);
afs_put_read(req);