btrfs: introduce btrfs_alloc_folio_array()
authorQu Wenruo <wqu@suse.com>
Mon, 29 Jan 2024 09:46:10 +0000 (20:16 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 7 May 2024 19:31:02 +0000 (21:31 +0200)
The new helper will do the same thing as btrfs_alloc_page_array(), but
with folios.

One extra difference is, there is no extra helper for bulk allocation,
thus it may not be as efficient as the page version.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h

index ecb18a8db373277a4705584c7eaadd613731ad2d..d90330f26827086ed3681fddcadf4195b12f9b49 100644 (file)
@@ -666,6 +666,37 @@ static void end_bbio_data_read(struct btrfs_bio *bbio)
        bio_put(bio);
 }
 
+/*
+ * Populate every free slot in a provided array with folios.
+ *
+ * @nr_folios:   number of folios to allocate
+ * @folio_array: the array to fill with folios; any existing non-NULL entries in
+ *              the array will be skipped
+ * @extra_gfp:  the extra GFP flags for the allocation
+ *
+ * Return: 0        if all folios were able to be allocated;
+ *         -ENOMEM  otherwise, the partially allocated folios would be freed and
+ *                  the array slots zeroed
+ */
+int btrfs_alloc_folio_array(unsigned int nr_folios, struct folio **folio_array,
+                           gfp_t extra_gfp)
+{
+       for (int i = 0; i < nr_folios; i++) {
+               if (folio_array[i])
+                       continue;
+               folio_array[i] = folio_alloc(GFP_NOFS | extra_gfp, 0);
+               if (!folio_array[i])
+                       goto error;
+       }
+       return 0;
+error:
+       for (int i = 0; i < nr_folios; i++) {
+               if (folio_array[i])
+                       folio_put(folio_array[i]);
+       }
+       return -ENOMEM;
+}
+
 /*
  * Populate every free slot in a provided array with pages.
  *
index 818431b37124c059896bbd69b6086713825bc79d..c81a9b546c9f8e5c79bb81db9a1ce364abcf3a53 100644 (file)
@@ -360,6 +360,8 @@ void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans,
 
 int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array,
                           gfp_t extra_gfp);
+int btrfs_alloc_folio_array(unsigned int nr_folios, struct folio **folio_array,
+                           gfp_t extra_gfp);
 
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
 bool find_lock_delalloc_range(struct inode *inode,