}
/*
- * Populate every free slot in a provided array with folios using GFP_NOFS.
+ * Populate every free slot in a provided array with folios.
*
- * @nr_folios: number of folios to allocate
- * @order: the order of the folios to be allocated
- * @folio_array: the array to fill with folios; any existing non-NULL entries in
- * the array will be skipped
+ * @nr_folios: number of folios to allocate
+ * @order: folio order
+ * @folio_array: array to fill with folios; non-NULL entries are skipped
+ * @gfp: 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, unsigned int order,
- struct folio **folio_array)
+ struct folio **folio_array, gfp_t gfp)
{
for (int i = 0; i < nr_folios; i++) {
if (folio_array[i])
continue;
- folio_array[i] = folio_alloc(GFP_NOFS, order);
+ folio_array[i] = folio_alloc(gfp, order);
if (!folio_array[i])
goto error;
}
}
/*
- * Populate every free slot in a provided array with pages, using GFP_NOFS.
+ * Populate every free slot in a provided array with pages.
*
- * @nr_pages: number of pages to allocate
- * @page_array: the array to fill with pages; any existing non-null entries in
- * the array will be skipped
- * @nofail: whether using __GFP_NOFAIL flag
+ * @nr_pages: number of pages to allocate
+ * @page_array: array to fill; non-NULL entries are skipped
+ * @gfp: GFP flags for the allocation
*
* Return: 0 if all pages were able to be allocated;
* -ENOMEM otherwise, the partially allocated pages would be freed and
* the array slots zeroed
*/
-int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array,
- bool nofail)
+int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array, gfp_t gfp)
{
- const gfp_t gfp = nofail ? (GFP_NOFS | __GFP_NOFAIL) : GFP_NOFS;
unsigned int allocated;
for (allocated = 0; allocated < nr_pages;) {
*
* For now, the folios populated are always in order 0 (aka, single page).
*/
-static int alloc_eb_folio_array(struct extent_buffer *eb, bool nofail)
+static int alloc_eb_folio_array(struct extent_buffer *eb, gfp_t gfp)
{
struct page *page_array[INLINE_EXTENT_BUFFER_PAGES] = { 0 };
int num_pages = num_extent_pages(eb);
int ret;
- ret = btrfs_alloc_page_array(num_pages, page_array, nofail);
+ ret = btrfs_alloc_page_array(num_pages, page_array, gfp);
if (ret < 0)
return ret;
*/
set_bit(EXTENT_BUFFER_UNMAPPED, &new->bflags);
- ret = alloc_eb_folio_array(new, false);
+ ret = alloc_eb_folio_array(new, GFP_NOFS);
if (ret)
goto release_eb;
if (!eb)
return NULL;
- ret = alloc_eb_folio_array(eb, false);
+ ret = alloc_eb_folio_array(eb, GFP_NOFS);
if (ret)
goto release_eb;
}
reallocate:
- /* Allocate all pages first. */
- ret = alloc_eb_folio_array(eb, true);
+ /*
+ * Allocate all pages first. These will be attached to btree_inode->i_mapping
+ * below (added to LRU, served by btree_migrate_folio), so request
+ * __GFP_MOVABLE so the page allocator places them in MOVABLE pageblocks.
+ */
+ ret = alloc_eb_folio_array(eb, GFP_NOFS | __GFP_NOFAIL | __GFP_MOVABLE);
if (ret < 0) {
btrfs_free_folio_state(prealloc);
goto out;
{
int ret;
- ret = btrfs_alloc_page_array(rbio->nr_pages, rbio->stripe_pages, false);
+ ret = btrfs_alloc_page_array(rbio->nr_pages, rbio->stripe_pages, GFP_NOFS);
if (ret < 0)
return ret;
/* Mapping all sectors */
int ret;
ret = btrfs_alloc_page_array(rbio->nr_pages - data_pages,
- rbio->stripe_pages + data_pages, false);
+ rbio->stripe_pages + data_pages, GFP_NOFS);
if (ret < 0)
return ret;
const int data_pages = rbio->nr_data * rbio->stripe_npages;
int ret;
- ret = btrfs_alloc_page_array(data_pages, rbio->stripe_pages, false);
+ ret = btrfs_alloc_page_array(data_pages, rbio->stripe_pages, GFP_NOFS);
if (ret < 0)
return ret;