summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/fs-io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-03-19 19:06:42 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:59 -0400
commite8d28c3e47d25f6a9bf83a6548395078c851d532 (patch)
tree2aa5cb4134c45fde0a140bb56edbc2aeb2f6e281 /fs/bcachefs/fs-io.c
parentff9c301f287657c445136d9168261b5fa7f7ae91 (diff)
downloadlinux-e8d28c3e47d25f6a9bf83a6548395078c851d532.tar.gz
linux-e8d28c3e47d25f6a9bf83a6548395078c851d532.tar.bz2
linux-e8d28c3e47d25f6a9bf83a6548395078c851d532.zip
bcachefs: bch2_seek_pagecache_hole() folio conversion
This converts bch2_seek_pagecache_hole() to handle large folios. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/fs-io.c')
-rw-r--r--fs/bcachefs/fs-io.c60
1 files changed, 26 insertions, 34 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 018ada1a0136..0cb76238f487 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -3592,37 +3592,34 @@ err:
return vfs_setpos(file, next_data, MAX_LFS_FILESIZE);
}
-static int __folio_hole_offset(struct folio *folio, unsigned offset)
+static bool folio_hole_offset(struct address_space *mapping, loff_t *offset)
{
- struct bch_folio *s = bch2_folio(folio);
- unsigned i;
-
- if (!s)
- return 0;
+ struct folio *folio;
+ struct bch_folio *s;
+ unsigned i, sectors, f_offset;
+ bool ret = true;
- for (i = offset >> 9; i < PAGE_SECTORS; i++)
- if (s->s[i].state < SECTOR_DIRTY)
- return i << 9;
+ folio = filemap_lock_folio(mapping, *offset >> PAGE_SHIFT);
+ if (!folio)
+ return true;
- return -1;
-}
+ s = bch2_folio(folio);
+ if (!s)
+ goto unlock;
-static loff_t folio_hole_offset(struct address_space *mapping, loff_t offset)
-{
- pgoff_t index = offset >> PAGE_SHIFT;
- struct folio *folio;
- int folio_offset;
- loff_t ret = -1;
+ sectors = folio_sectors(folio);
+ f_offset = *offset - folio_pos(folio);
- folio = filemap_lock_folio(mapping, index);
- if (!folio)
- return offset;
+ for (i = f_offset >> 9; i < sectors; i++)
+ if (s->s[i].state < SECTOR_DIRTY) {
+ *offset = max(*offset, folio_pos(folio) + (i << 9));
+ goto unlock;
+ }
- folio_offset = __folio_hole_offset(folio, offset & (folio_size(folio) - 1));
- if (folio_offset >= 0)
- ret = folio_pos(folio) + folio_offset;
+ *offset = folio_end_pos(folio);
+ ret = false;
+unlock:
folio_unlock(folio);
-
return ret;
}
@@ -3631,18 +3628,13 @@ static loff_t bch2_seek_pagecache_hole(struct inode *vinode,
loff_t end_offset)
{
struct address_space *mapping = vinode->i_mapping;
- loff_t offset = start_offset, hole;
+ loff_t offset = start_offset;
- while (offset < end_offset) {
- hole = folio_hole_offset(mapping, offset);
- if (hole >= 0 && hole <= end_offset)
- return max(start_offset, hole);
+ while (offset < end_offset &&
+ !folio_hole_offset(mapping, &offset))
+ ;
- offset += PAGE_SIZE;
- offset &= PAGE_MASK;
- }
-
- return end_offset;
+ return min(offset, end_offset);
}
static loff_t bch2_seek_hole(struct file *file, u64 offset)