From: "Darrick J. Wong" djwong@kernel.org
maillist inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9VTE3 CVE: NA
Reference: https://lore.kernel.org/all/20240326133813.3224593-1-john.g.garry@oracle.com...
--------------------------------
The existing extsize hint code already did the work of expanding file range mapping requests so that the range is aligned to the hint value. Now add the code we need to guarantee that the space allocations are also always aligned.
XXX: still need to check all this with reflink
Signed-off-by: "Darrick J. Wong" djwong@kernel.org Co-developed-by: John Garry john.g.garry@oracle.com Signed-off-by: John Garry john.g.garry@oracle.com Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/libxfs/xfs_bmap.c | 18 +++++++++++++++--- fs/xfs/xfs_iomap.c | 4 +++- 2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 15e9e335d167..852988f9e51e 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3487,6 +3487,18 @@ xfs_bmap_btalloc( args.fsbno = ap->blkno; args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
+ /* + * xfs_get_cowextsz_hint() returns extsz_hint for when forcealign is + * set as forcealign and cowextsz_hint are mutually exclusive + */ + if (xfs_inode_forcealign(ap->ip) && align) { + args.alignment = align; + if (stripe_align == 0 || stripe_align % align) + stripe_align = align; + } else { + args.alignment = 1; + } + /* Trim the allocation back to the maximum an AG can fit. */ args.maxlen = min(ap->length, mp->m_ag_max_usable); blen = 0; @@ -3558,7 +3570,6 @@ xfs_bmap_btalloc( atype = args.type; tryagain = 1; args.type = XFS_ALLOCTYPE_THIS_BNO; - args.alignment = 1; /* * Compute the minlen+alignment for the * next case. Set slop so that the value @@ -3577,7 +3588,6 @@ xfs_bmap_btalloc( args.minalignslop = 0; } } else { - args.alignment = 1; args.minalignslop = 0; } args.postallocs = 1; @@ -3604,7 +3614,9 @@ xfs_bmap_btalloc( if ((error = xfs_alloc_vextent(&args))) return error; } - if (isaligned && args.fsbno == NULLFSBLOCK) { + + if (isaligned && args.fsbno == NULLFSBLOCK && + (args.alignment <= 1 || !xfs_inode_forcealign(ap->ip))) { /* * allocation failed, so turn off alignment and * try again. diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 76285db4aaec..af2fe2e2bd4b 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -167,7 +167,9 @@ xfs_eof_alignment( * If mounted with the "-o swalloc" option the alignment is * increased from the strip unit size to the stripe width. */ - if (mp->m_swidth && xfs_has_swalloc(mp)) + if (xfs_inode_forcealign(ip)) + align = xfs_get_extsz_hint(ip); + else if (mp->m_swidth && xfs_has_swalloc(mp)) align = mp->m_swidth; else if (mp->m_dalign) align = mp->m_dalign;