Commit e8d28c3e authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_seek_pagecache_hole() folio conversion

This converts bch2_seek_pagecache_hole() to handle large folios.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent ff9c301f
...@@ -3592,37 +3592,34 @@ static loff_t bch2_seek_data(struct file *file, u64 offset) ...@@ -3592,37 +3592,34 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
return vfs_setpos(file, next_data, MAX_LFS_FILESIZE); 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); struct folio *folio;
unsigned i; struct bch_folio *s;
unsigned i, sectors, f_offset;
if (!s) bool ret = true;
return 0;
for (i = offset >> 9; i < PAGE_SECTORS; i++) folio = filemap_lock_folio(mapping, *offset >> PAGE_SHIFT);
if (s->s[i].state < SECTOR_DIRTY) if (!folio)
return i << 9; 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) sectors = folio_sectors(folio);
{ f_offset = *offset - folio_pos(folio);
pgoff_t index = offset >> PAGE_SHIFT;
struct folio *folio;
int folio_offset;
loff_t ret = -1;
folio = filemap_lock_folio(mapping, index); for (i = f_offset >> 9; i < sectors; i++)
if (!folio) if (s->s[i].state < SECTOR_DIRTY) {
return offset; *offset = max(*offset, folio_pos(folio) + (i << 9));
goto unlock;
}
folio_offset = __folio_hole_offset(folio, offset & (folio_size(folio) - 1)); *offset = folio_end_pos(folio);
if (folio_offset >= 0) ret = false;
ret = folio_pos(folio) + folio_offset; unlock:
folio_unlock(folio); folio_unlock(folio);
return ret; return ret;
} }
...@@ -3631,18 +3628,13 @@ static loff_t bch2_seek_pagecache_hole(struct inode *vinode, ...@@ -3631,18 +3628,13 @@ static loff_t bch2_seek_pagecache_hole(struct inode *vinode,
loff_t end_offset) loff_t end_offset)
{ {
struct address_space *mapping = vinode->i_mapping; struct address_space *mapping = vinode->i_mapping;
loff_t offset = start_offset, hole; loff_t offset = start_offset;
while (offset < end_offset) { while (offset < end_offset &&
hole = folio_hole_offset(mapping, offset); !folio_hole_offset(mapping, &offset))
if (hole >= 0 && hole <= end_offset) ;
return max(start_offset, hole);
offset += PAGE_SIZE; return min(offset, end_offset);
offset &= PAGE_MASK;
}
return end_offset;
} }
static loff_t bch2_seek_hole(struct file *file, u64 offset) static loff_t bch2_seek_hole(struct file *file, u64 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