[PATCH v2 32/51] netfs: Make netfs_skip_folio_read() take account of blocksize

From: David Howells
Date: Fri Nov 17 2023 - 16:20:58 EST


Make netfs_skip_folio_read() take account of blocksize such as crypto
blocksize.

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
cc: Jeff Layton <jlayton@xxxxxxxxxx>
cc: linux-cachefs@xxxxxxxxxx
cc: linux-fsdevel@xxxxxxxxxxxxxxx
cc: linux-mm@xxxxxxxxx
---
fs/netfs/buffered_read.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index e06461ef0bfa..de696aaaefbd 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -337,6 +337,7 @@ EXPORT_SYMBOL(netfs_read_folio);

/*
* Prepare a folio for writing without reading first
+ * @ctx: File context
* @folio: The folio being prepared
* @pos: starting position for the write
* @len: length of write
@@ -350,32 +351,41 @@ EXPORT_SYMBOL(netfs_read_folio);
* If any of these criteria are met, then zero out the unwritten parts
* of the folio and return true. Otherwise, return false.
*/
-static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
- bool always_fill)
+static bool netfs_skip_folio_read(struct netfs_inode *ctx, struct folio *folio,
+ loff_t pos, size_t len, bool always_fill)
{
struct inode *inode = folio_inode(folio);
- loff_t i_size = i_size_read(inode);
+ loff_t i_size = i_size_read(inode), low, high;
size_t offset = offset_in_folio(folio, pos);
size_t plen = folio_size(folio);
+ size_t min_bsize = 1UL << ctx->min_bshift;
+
+ if (likely(min_bsize == 1)) {
+ low = folio_file_pos(folio);
+ high = low + plen;
+ } else {
+ low = round_down(pos, min_bsize);
+ high = round_up(pos + len, min_bsize);
+ }

if (unlikely(always_fill)) {
- if (pos - offset + len <= i_size)
- return false; /* Page entirely before EOF */
+ if (low < i_size)
+ return false; /* Some part of the block before EOF */
zero_user_segment(&folio->page, 0, plen);
folio_mark_uptodate(folio);
return true;
}

- /* Full folio write */
- if (offset == 0 && len >= plen)
+ /* Full page write */
+ if (pos == low && high == pos + len)
return true;

- /* Page entirely beyond the end of the file */
- if (pos - offset >= i_size)
+ /* pos beyond last page in the file */
+ if (low >= i_size)
goto zero_out;

/* Write that covers from the start of the folio to EOF or beyond */
- if (offset == 0 && (pos + len) >= i_size)
+ if (pos == low && (pos + len) >= i_size)
goto zero_out;

return false;
@@ -454,7 +464,7 @@ int netfs_write_begin(struct netfs_inode *ctx,
* to preload the granule.
*/
if (!netfs_is_cache_enabled(ctx) &&
- netfs_skip_folio_read(folio, pos, len, false)) {
+ netfs_skip_folio_read(ctx, folio, pos, len, false)) {
netfs_stat(&netfs_n_rh_write_zskip);
goto have_folio_no_wait;
}