Skip to content

Commit de631e1

Browse files
Dave Chinnerbrauner
authored andcommitted
xfs: use kvmalloc for xattr buffers
Pankaj Raghav reported that when filesystem block size is larger than page size, the xattr code can use kmalloc() for high order allocations. This triggers a useless warning in the allocator as it is a __GFP_NOFAIL allocation here: static inline struct page *rmqueue(struct zone *preferred_zone, struct zone *zone, unsigned int order, gfp_t gfp_flags, unsigned int alloc_flags, int migratetype) { struct page *page; /* * We most definitely don't want callers attempting to * allocate greater than order-1 page units with __GFP_NOFAIL. */ >>>> WARN_ON_ONCE((gfp_flags & __GFP_NOFAIL) && (order > 1)); ... Fix this by changing all these call sites to use kvmalloc(), which will strip the NOFAIL from the kmalloc attempt and if that fails will do a __GFP_NOFAIL vmalloc(). This is not an issue that productions systems will see as filesystems with block size > page size cannot be mounted by the kernel; Pankaj is developing this functionality right now. Reported-by: Pankaj Raghav <[email protected]> Fixes: f078d4e ("xfs: convert kmem_alloc() to kmalloc()") Signed-off-by: Dave Chinner <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Darrick J. Wong <[email protected]> Reviewed-by: Pankaj Raghav <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Acked-by: Darrick J. Wong <[email protected]> Reviewed-by: Daniel Gomez <[email protected]> Reviewed-by: Dave Chinner <[email protected]> Reviewed-by: Matthew Wilcox (Oracle) <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 10553a9 commit de631e1

File tree

1 file changed

+6
-9
lines changed

1 file changed

+6
-9
lines changed

fs/xfs/libxfs/xfs_attr_leaf.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,10 +1138,7 @@ xfs_attr3_leaf_to_shortform(
11381138

11391139
trace_xfs_attr_leaf_to_sf(args);
11401140

1141-
tmpbuffer = kmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL);
1142-
if (!tmpbuffer)
1143-
return -ENOMEM;
1144-
1141+
tmpbuffer = kvmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL);
11451142
memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
11461143

11471144
leaf = (xfs_attr_leafblock_t *)tmpbuffer;
@@ -1205,7 +1202,7 @@ xfs_attr3_leaf_to_shortform(
12051202
error = 0;
12061203

12071204
out:
1208-
kfree(tmpbuffer);
1205+
kvfree(tmpbuffer);
12091206
return error;
12101207
}
12111208

@@ -1613,7 +1610,7 @@ xfs_attr3_leaf_compact(
16131610

16141611
trace_xfs_attr_leaf_compact(args);
16151612

1616-
tmpbuffer = kmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL);
1613+
tmpbuffer = kvmalloc(args->geo->blksize, GFP_KERNEL | __GFP_NOFAIL);
16171614
memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
16181615
memset(bp->b_addr, 0, args->geo->blksize);
16191616
leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
@@ -1651,7 +1648,7 @@ xfs_attr3_leaf_compact(
16511648
*/
16521649
xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
16531650

1654-
kfree(tmpbuffer);
1651+
kvfree(tmpbuffer);
16551652
}
16561653

16571654
/*
@@ -2330,7 +2327,7 @@ xfs_attr3_leaf_unbalance(
23302327
struct xfs_attr_leafblock *tmp_leaf;
23312328
struct xfs_attr3_icleaf_hdr tmphdr;
23322329

2333-
tmp_leaf = kzalloc(state->args->geo->blksize,
2330+
tmp_leaf = kvzalloc(state->args->geo->blksize,
23342331
GFP_KERNEL | __GFP_NOFAIL);
23352332

23362333
/*
@@ -2371,7 +2368,7 @@ xfs_attr3_leaf_unbalance(
23712368
}
23722369
memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
23732370
savehdr = tmphdr; /* struct copy */
2374-
kfree(tmp_leaf);
2371+
kvfree(tmp_leaf);
23752372
}
23762373

23772374
xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr);

0 commit comments

Comments
 (0)