Skip to content

Commit 99b150d

Browse files
Matthew Wilcox (Oracle)tytso
authored andcommitted
ext4: convert bd_bitmap_page to bd_bitmap_folio
There is no need to make this a multi-page folio, so leave all the infrastructure around it in pages. But since we're locking it, playing with its refcount and checking whether it's uptodate, it needs to move to the folio API. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Link: https://lore.kernel.org/r/20240416172900.244637-2-willy@infradead.org Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent da5704e commit 99b150d

File tree

2 files changed

+52
-48
lines changed

2 files changed

+52
-48
lines changed

fs/ext4/mballoc.c

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,9 +1452,10 @@ static int ext4_mb_get_buddy_page_lock(struct super_block *sb,
14521452
int block, pnum, poff;
14531453
int blocks_per_page;
14541454
struct page *page;
1455+
struct folio *folio;
14551456

14561457
e4b->bd_buddy_page = NULL;
1457-
e4b->bd_bitmap_page = NULL;
1458+
e4b->bd_bitmap_folio = NULL;
14581459

14591460
blocks_per_page = PAGE_SIZE / sb->s_blocksize;
14601461
/*
@@ -1465,12 +1466,13 @@ static int ext4_mb_get_buddy_page_lock(struct super_block *sb,
14651466
block = group * 2;
14661467
pnum = block / blocks_per_page;
14671468
poff = block % blocks_per_page;
1468-
page = find_or_create_page(inode->i_mapping, pnum, gfp);
1469-
if (!page)
1470-
return -ENOMEM;
1471-
BUG_ON(page->mapping != inode->i_mapping);
1472-
e4b->bd_bitmap_page = page;
1473-
e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize);
1469+
folio = __filemap_get_folio(inode->i_mapping, pnum,
1470+
FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);
1471+
if (IS_ERR(folio))
1472+
return PTR_ERR(folio);
1473+
BUG_ON(folio->mapping != inode->i_mapping);
1474+
e4b->bd_bitmap_folio = folio;
1475+
e4b->bd_bitmap = folio_address(folio) + (poff * sb->s_blocksize);
14741476

14751477
if (blocks_per_page >= 2) {
14761478
/* buddy and bitmap are on the same page */
@@ -1488,9 +1490,9 @@ static int ext4_mb_get_buddy_page_lock(struct super_block *sb,
14881490

14891491
static void ext4_mb_put_buddy_page_lock(struct ext4_buddy *e4b)
14901492
{
1491-
if (e4b->bd_bitmap_page) {
1492-
unlock_page(e4b->bd_bitmap_page);
1493-
put_page(e4b->bd_bitmap_page);
1493+
if (e4b->bd_bitmap_folio) {
1494+
folio_unlock(e4b->bd_bitmap_folio);
1495+
folio_put(e4b->bd_bitmap_folio);
14941496
}
14951497
if (e4b->bd_buddy_page) {
14961498
unlock_page(e4b->bd_buddy_page);
@@ -1510,6 +1512,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp)
15101512
struct ext4_group_info *this_grp;
15111513
struct ext4_buddy e4b;
15121514
struct page *page;
1515+
struct folio *folio;
15131516
int ret = 0;
15141517

15151518
might_sleep();
@@ -1536,11 +1539,11 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp)
15361539
goto err;
15371540
}
15381541

1539-
page = e4b.bd_bitmap_page;
1540-
ret = ext4_mb_init_cache(page, NULL, gfp);
1542+
folio = e4b.bd_bitmap_folio;
1543+
ret = ext4_mb_init_cache(&folio->page, NULL, gfp);
15411544
if (ret)
15421545
goto err;
1543-
if (!PageUptodate(page)) {
1546+
if (!folio_test_uptodate(folio)) {
15441547
ret = -EIO;
15451548
goto err;
15461549
}
@@ -1582,6 +1585,7 @@ ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group,
15821585
int pnum;
15831586
int poff;
15841587
struct page *page;
1588+
struct folio *folio;
15851589
int ret;
15861590
struct ext4_group_info *grp;
15871591
struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -1600,7 +1604,7 @@ ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group,
16001604
e4b->bd_sb = sb;
16011605
e4b->bd_group = group;
16021606
e4b->bd_buddy_page = NULL;
1603-
e4b->bd_bitmap_page = NULL;
1607+
e4b->bd_bitmap_folio = NULL;
16041608

16051609
if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
16061610
/*
@@ -1621,53 +1625,53 @@ ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group,
16211625
pnum = block / blocks_per_page;
16221626
poff = block % blocks_per_page;
16231627

1624-
/* we could use find_or_create_page(), but it locks page
1625-
* what we'd like to avoid in fast path ... */
1626-
page = find_get_page_flags(inode->i_mapping, pnum, FGP_ACCESSED);
1627-
if (page == NULL || !PageUptodate(page)) {
1628-
if (page)
1628+
/* Avoid locking the folio in the fast path ... */
1629+
folio = __filemap_get_folio(inode->i_mapping, pnum, FGP_ACCESSED, 0);
1630+
if (IS_ERR(folio) || !folio_test_uptodate(folio)) {
1631+
if (!IS_ERR(folio))
16291632
/*
1630-
* drop the page reference and try
1631-
* to get the page with lock. If we
1633+
* drop the folio reference and try
1634+
* to get the folio with lock. If we
16321635
* are not uptodate that implies
1633-
* somebody just created the page but
1634-
* is yet to initialize the same. So
1636+
* somebody just created the folio but
1637+
* is yet to initialize it. So
16351638
* wait for it to initialize.
16361639
*/
1637-
put_page(page);
1638-
page = find_or_create_page(inode->i_mapping, pnum, gfp);
1639-
if (page) {
1640-
if (WARN_RATELIMIT(page->mapping != inode->i_mapping,
1641-
"ext4: bitmap's paging->mapping != inode->i_mapping\n")) {
1640+
folio_put(folio);
1641+
folio = __filemap_get_folio(inode->i_mapping, pnum,
1642+
FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);
1643+
if (!IS_ERR(folio)) {
1644+
if (WARN_RATELIMIT(folio->mapping != inode->i_mapping,
1645+
"ext4: bitmap's mapping != inode->i_mapping\n")) {
16421646
/* should never happen */
1643-
unlock_page(page);
1647+
folio_unlock(folio);
16441648
ret = -EINVAL;
16451649
goto err;
16461650
}
1647-
if (!PageUptodate(page)) {
1648-
ret = ext4_mb_init_cache(page, NULL, gfp);
1651+
if (!folio_test_uptodate(folio)) {
1652+
ret = ext4_mb_init_cache(&folio->page, NULL, gfp);
16491653
if (ret) {
1650-
unlock_page(page);
1654+
folio_unlock(folio);
16511655
goto err;
16521656
}
1653-
mb_cmp_bitmaps(e4b, page_address(page) +
1657+
mb_cmp_bitmaps(e4b, folio_address(folio) +
16541658
(poff * sb->s_blocksize));
16551659
}
1656-
unlock_page(page);
1660+
folio_unlock(folio);
16571661
}
16581662
}
1659-
if (page == NULL) {
1660-
ret = -ENOMEM;
1663+
if (IS_ERR(folio)) {
1664+
ret = PTR_ERR(folio);
16611665
goto err;
16621666
}
1663-
if (!PageUptodate(page)) {
1667+
if (!folio_test_uptodate(folio)) {
16641668
ret = -EIO;
16651669
goto err;
16661670
}
16671671

16681672
/* Pages marked accessed already */
1669-
e4b->bd_bitmap_page = page;
1670-
e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize);
1673+
e4b->bd_bitmap_folio = folio;
1674+
e4b->bd_bitmap = folio_address(folio) + (poff * sb->s_blocksize);
16711675

16721676
block++;
16731677
pnum = block / blocks_per_page;
@@ -1715,8 +1719,8 @@ ext4_mb_load_buddy_gfp(struct super_block *sb, ext4_group_t group,
17151719
err:
17161720
if (page)
17171721
put_page(page);
1718-
if (e4b->bd_bitmap_page)
1719-
put_page(e4b->bd_bitmap_page);
1722+
if (e4b->bd_bitmap_folio)
1723+
folio_put(e4b->bd_bitmap_folio);
17201724

17211725
e4b->bd_buddy = NULL;
17221726
e4b->bd_bitmap = NULL;
@@ -1731,8 +1735,8 @@ static int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
17311735

17321736
static void ext4_mb_unload_buddy(struct ext4_buddy *e4b)
17331737
{
1734-
if (e4b->bd_bitmap_page)
1735-
put_page(e4b->bd_bitmap_page);
1738+
if (e4b->bd_bitmap_folio)
1739+
folio_put(e4b->bd_bitmap_folio);
17361740
if (e4b->bd_buddy_page)
17371741
put_page(e4b->bd_buddy_page);
17381742
}
@@ -2157,7 +2161,7 @@ static void ext4_mb_use_best_found(struct ext4_allocation_context *ac,
21572161
* double allocate blocks. The reference is dropped
21582162
* in ext4_mb_release_context
21592163
*/
2160-
ac->ac_bitmap_page = e4b->bd_bitmap_page;
2164+
ac->ac_bitmap_page = &e4b->bd_bitmap_folio->page;
21612165
get_page(ac->ac_bitmap_page);
21622166
ac->ac_buddy_page = e4b->bd_buddy_page;
21632167
get_page(ac->ac_buddy_page);
@@ -3894,7 +3898,7 @@ static void ext4_free_data_in_buddy(struct super_block *sb,
38943898
* balance refcounts from ext4_mb_free_metadata()
38953899
*/
38963900
put_page(e4b.bd_buddy_page);
3897-
put_page(e4b.bd_bitmap_page);
3901+
folio_put(e4b.bd_bitmap_folio);
38983902
}
38993903
ext4_unlock_group(sb, entry->efd_group);
39003904
ext4_mb_unload_buddy(&e4b);
@@ -6316,7 +6320,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
63166320
struct rb_node *parent = NULL, *new_node;
63176321

63186322
BUG_ON(!ext4_handle_valid(handle));
6319-
BUG_ON(e4b->bd_bitmap_page == NULL);
6323+
BUG_ON(e4b->bd_bitmap_folio == NULL);
63206324
BUG_ON(e4b->bd_buddy_page == NULL);
63216325

63226326
new_node = &new_entry->efd_node;
@@ -6329,7 +6333,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
63296333
* on-disk bitmap and lose not-yet-available
63306334
* blocks */
63316335
get_page(e4b->bd_buddy_page);
6332-
get_page(e4b->bd_bitmap_page);
6336+
folio_get(e4b->bd_bitmap_folio);
63336337
}
63346338
while (*n) {
63356339
parent = *n;

fs/ext4/mballoc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ struct ext4_allocation_context {
217217
struct ext4_buddy {
218218
struct page *bd_buddy_page;
219219
void *bd_buddy;
220-
struct page *bd_bitmap_page;
220+
struct folio *bd_bitmap_folio;
221221
void *bd_bitmap;
222222
struct ext4_group_info *bd_info;
223223
struct super_block *bd_sb;

0 commit comments

Comments
 (0)