diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-03-19 19:06:42 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:59 -0400 |
commit | e8d28c3e47d25f6a9bf83a6548395078c851d532 (patch) | |
tree | 2aa5cb4134c45fde0a140bb56edbc2aeb2f6e281 /fs/bcachefs/fs-io.c | |
parent | ff9c301f287657c445136d9168261b5fa7f7ae91 (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>
Diffstat (limited to 'fs/bcachefs/fs-io.c')
-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 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) |