Skip to content

Commit

Permalink
buffer: add alloc_folio_buffers() helper
Browse files Browse the repository at this point in the history
Folio version of alloc_page_buffers() helper. This is required to convert
create_page_buffers() to create_folio_buffers() later in the series.

It removes one call to compound_head() compared to alloc_page_buffers().

Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
  • Loading branch information
Panky-codes authored and intel-lab-lkp committed Apr 14, 2023
1 parent 274aa68 commit a5c44e7
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,65 @@ struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size,
}
EXPORT_SYMBOL_GPL(alloc_page_buffers);

/*
* Create the appropriate buffers when given a folio for data area and
* the size of each buffer.. Use the bh->b_this_page linked list to
* follow the buffers created. Return NULL if unable to create more
* buffers.
*
* The retry flag is used to differentiate async IO (paging, swapping)
* which may not fail from ordinary buffer allocations.
*/
struct buffer_head *alloc_folio_buffers(struct folio *folio, unsigned long size,
bool retry)
{
struct buffer_head *bh, *head;
gfp_t gfp = GFP_NOFS | __GFP_ACCOUNT;
long offset;
struct mem_cgroup *memcg, *old_memcg;

if (retry)
gfp |= __GFP_NOFAIL;

/* The folio lock pins the memcg */
memcg = folio_memcg(folio);
old_memcg = set_active_memcg(memcg);

head = NULL;
offset = folio_size(folio);
while ((offset -= size) >= 0) {
bh = alloc_buffer_head(gfp);
if (!bh)
goto no_grow;

bh->b_this_page = head;
bh->b_blocknr = -1;
head = bh;

bh->b_size = size;

/* Link the buffer to its folio */
set_bh_folio(bh, folio, offset);
}
out:
set_active_memcg(old_memcg);
return head;
/*
* In case anything failed, we just free everything we got.
*/
no_grow:
if (head) {
do {
bh = head;
head = head->b_this_page;
free_buffer_head(bh);
} while (head);
}

goto out;
}
EXPORT_SYMBOL_GPL(alloc_folio_buffers);

static inline void
link_dev_buffers(struct page *page, struct buffer_head *head)
{
Expand Down

0 comments on commit a5c44e7

Please sign in to comment.