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 0d47e5ea6870..8b27ef2e78ca 100644 --- a/fs/netfs/buffered_read.c +++ b/fs/netfs/buffered_read.c @@ -331,6 +331,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 @@ -344,32 +345,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; @@ -448,7 +458,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; }