bcachefs: bch2_seek_pagecache_hole() folio conversion
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 19 Mar 2023 23:06:42 +0000 (19:06 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:59 +0000 (17:09 -0400)
This converts bch2_seek_pagecache_hole() to handle large folios.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs-io.c

index 018ada1a0136842b9ef16706d49ed622b509555d..0cb76238f4871faf5c6febe673c99451424f2aa3 100644 (file)
@@ -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)