bcachefs: filemap_get_contig_folios_d()
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 23 Mar 2023 16:51:47 +0000 (12:51 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:59 +0000 (17:09 -0400)
Add a new helper for getting a range of contiguous folios and returning
them in a darray.

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

index 02262519aae9774898ea4cd4e3576d2c499c5c68..6584a64e56310dcb4c8ec20cd3f95e3fb194a074 100644 (file)
@@ -55,6 +55,41 @@ static inline loff_t folio_end_sector(struct folio *folio)
        return folio_end_pos(folio) >> 9;
 }
 
+typedef DARRAY(struct folio *) folios;
+
+static int filemap_get_contig_folios_d(struct address_space *mapping,
+                                      loff_t start, loff_t end,
+                                      int fgp_flags, gfp_t gfp,
+                                      folios *folios)
+{
+       struct folio *f;
+       loff_t pos = start;
+       int ret = 0;
+
+       while (pos < end) {
+               if ((u64) pos >= (u64) start + (1ULL << 20))
+                       fgp_flags &= ~FGP_CREAT;
+
+               ret = darray_make_room_gfp(folios, 1, gfp & GFP_KERNEL);
+               if (ret)
+                       break;
+
+               f = __filemap_get_folio(mapping, pos >> PAGE_SHIFT, fgp_flags, gfp);
+               if (!f)
+                       break;
+
+               BUG_ON(folios->nr && folio_pos(f) != pos);
+
+               pos = folio_end_pos(f);
+               darray_push(folios, f);
+       }
+
+       if (!folios->nr && !ret && (fgp_flags & FGP_CREAT))
+               ret = -ENOMEM;
+
+       return folios->nr ? 0 : ret;
+}
+
 struct nocow_flush {
        struct closure  *cl;
        struct bch_dev  *ca;
@@ -1754,8 +1789,6 @@ int bch2_write_end(struct file *file, struct address_space *mapping,
        return copied;
 }
 
-typedef DARRAY(struct folio *) folios;
-
 static noinline void folios_trunc(folios *folios, struct folio **fi)
 {
        while (folios->data + folios->nr > fi) {
@@ -1784,33 +1817,16 @@ static int __bch2_buffered_write(struct bch_inode_info *inode,
        bch2_folio_reservation_init(c, inode, &res);
        darray_init(&folios);
 
-       f_pos = pos;
-       while (f_pos < end) {
-               unsigned fgp_flags = FGP_LOCK|FGP_WRITE|FGP_STABLE;
-
-               if ((u64) f_pos < (u64) pos + (1U << 20))
-                       fgp_flags |= FGP_CREAT;
-
-               if (darray_make_room_gfp(&folios, 1,
-                               mapping_gfp_mask(mapping) & GFP_KERNEL))
-                       break;
-
-               f = __filemap_get_folio(mapping, f_pos >> PAGE_SHIFT,
-                                       fgp_flags, mapping_gfp_mask(mapping));
-               if (!f)
-                       break;
-
-               BUG_ON(folios.nr && folio_pos(f) != f_pos);
+       ret = filemap_get_contig_folios_d(mapping, pos, end,
+                                  FGP_LOCK|FGP_WRITE|FGP_STABLE|FGP_CREAT,
+                                  mapping_gfp_mask(mapping),
+                                  &folios);
+       if (ret)
+               goto out;
 
-               f_pos = folio_end_pos(f);
-               darray_push(&folios, f);
-       }
+       BUG_ON(!folios.nr);
 
-       end = min(end, f_pos);
-       if (end == pos) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       end = min(end, folio_end_pos(darray_last(folios)));
 
        f = darray_first(folios);
        if (pos != folio_pos(f) && !folio_test_uptodate(f)) {