diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-03-19 19:06:42 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-05-12 19:42:32 -0400 |
commit | af403c4a8a6f591b8c706486aa6c77d151c9879f (patch) | |
tree | b3448bccb7560d427ffc8c08e3dde8101543d7d1 | |
parent | ffa724656c871bdd45d02e356624904591715859 (diff) |
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>
-rw-r--r-- | fs/bcachefs/fs-io.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index 7b89aaadf88f..0cb5e6ac447a 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -3590,37 +3590,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; } @@ -3629,18 +3626,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) |