Commit 8c9b0f7b authored by Brian Foster's avatar Brian Foster Committed by Kent Overstreet

bcachefs: fix up wonky error handling in bch2_seek_pagecache_hole()

The folio_hole_offset() helper returns a mix of bool and int types.
The latter is to support a possible -EAGAIN error code when using
nonblocking locks. This is not only confusing, but the only caller
also essentially ignores errors outside of stopping the range
iteration. This means an -EAGAIN error can't return directly from
folio_hole_offset() and may be lost via bch2_clamp_data_hole().

Fix up the error handling and make it more readable.
__filemap_get_folio() returns -ENOENT instead of NULL when no folio
exists, so reuse the same error code in folio_hole_offset(). Fix up
bch2_seek_pagecache_hole() to return the current offset on -ENOENT,
but otherwise return unexpected error code up to the caller.
Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 029b85fe
......@@ -698,20 +698,26 @@ loff_t bch2_seek_pagecache_data(struct inode *vinode,
return end_offset;
}
/*
* Search for a hole in a folio.
*
* The filemap layer returns -ENOENT if no folio exists, so reuse the same error
* code to indicate a pagecache hole exists at the returned offset. Otherwise
* return 0 if the folio is filled with data, or an error code. This function
* can return -EAGAIN if nonblock is specified.
*/
static int folio_hole_offset(struct address_space *mapping, loff_t *offset,
unsigned min_replicas, bool nonblock)
{
struct folio *folio;
struct bch_folio *s;
unsigned i, sectors;
bool ret = true;
int ret = -ENOENT;
folio = __filemap_get_folio(mapping, *offset >> PAGE_SHIFT,
FGP_LOCK|(nonblock ? FGP_NOWAIT : 0), 0);
if (folio == ERR_PTR(-EAGAIN))
return -EAGAIN;
if (IS_ERR_OR_NULL(folio))
return true;
if (IS_ERR(folio))
return PTR_ERR(folio);
s = bch2_folio(folio);
if (!s)
......@@ -727,7 +733,7 @@ static int folio_hole_offset(struct address_space *mapping, loff_t *offset,
}
*offset = folio_end_pos(folio);
ret = false;
ret = 0;
unlock:
folio_unlock(folio);
folio_put(folio);
......@@ -742,11 +748,13 @@ loff_t bch2_seek_pagecache_hole(struct inode *vinode,
{
struct address_space *mapping = vinode->i_mapping;
loff_t offset = start_offset;
loff_t ret = 0;
while (offset < end_offset &&
!folio_hole_offset(mapping, &offset, min_replicas, nonblock))
;
while (!ret && offset < end_offset)
ret = folio_hole_offset(mapping, &offset, min_replicas, nonblock);
if (ret && ret != -ENOENT)
return ret;
return min(offset, end_offset);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment