Skip to content

Commit f67e8a5

Browse files
committed
Merge tag 'xfs-fixes-6.19-rc2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Carlos Maiolino: "This contains a few fixes for zoned devices support, an UAF and a compiler warning, and some cleaning up" * tag 'xfs-fixes-6.19-rc2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: fix the zoned RT growfs check for zone alignment xfs: validate that zoned RT devices are zone aligned xfs: fix XFS_ERRTAG_FORCE_ZERO_RANGE for zoned file system xfs: fix a memory leak in xfs_buf_item_init() xfs: fix stupid compiler warning xfs: fix a UAF problem in xattr repair xfs: ignore discard return value
2 parents f0ae3a5 + dc68c0f commit f67e8a5

8 files changed

Lines changed: 80 additions & 41 deletions

File tree

fs/xfs/libxfs/xfs_sb.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,21 @@ xfs_validate_rt_geometry(
301301
sbp->sb_rbmblocks != xfs_expected_rbmblocks(sbp))
302302
return false;
303303

304+
if (xfs_sb_is_v5(sbp) &&
305+
(sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_ZONED)) {
306+
uint32_t mod;
307+
308+
/*
309+
* Zoned RT devices must be aligned to the RT group size,
310+
* because garbage collection assumes that all zones have the
311+
* same size to avoid insane complexity if that weren't the
312+
* case.
313+
*/
314+
div_u64_rem(sbp->sb_rextents, sbp->sb_rgextents, &mod);
315+
if (mod)
316+
return false;
317+
}
318+
304319
return true;
305320
}
306321

fs/xfs/scrub/attr_repair.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,6 @@ xrep_xattr_salvage_remote_attr(
333333
.attr_filter = ent->flags & XFS_ATTR_NSP_ONDISK_MASK,
334334
.namelen = rentry->namelen,
335335
.name = rentry->name,
336-
.value = ab->value,
337336
.valuelen = be32_to_cpu(rentry->valuelen),
338337
};
339338
unsigned int namesize;
@@ -363,6 +362,7 @@ xrep_xattr_salvage_remote_attr(
363362
error = -EDEADLOCK;
364363
if (error)
365364
return error;
365+
args.value = ab->value;
366366

367367
/* Look up the remote value and stash it for reconstruction. */
368368
error = xfs_attr3_leaf_getvalue(leaf_bp, &args);

fs/xfs/xfs_attr_item.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ xfs_attr_recover_work(
737737
struct xfs_attri_log_item *attrip = ATTRI_ITEM(lip);
738738
struct xfs_attr_intent *attr;
739739
struct xfs_mount *mp = lip->li_log->l_mp;
740-
struct xfs_inode *ip;
740+
struct xfs_inode *ip = NULL;
741741
struct xfs_da_args *args;
742742
struct xfs_trans *tp;
743743
struct xfs_trans_res resv;

fs/xfs/xfs_buf_item.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,7 @@ xfs_buf_item_init(
896896
map_size = DIV_ROUND_UP(chunks, NBWORD);
897897

898898
if (map_size > XFS_BLF_DATAMAP_SIZE) {
899+
xfs_buf_item_free_format(bip);
899900
kmem_cache_free(xfs_buf_item_cache, bip);
900901
xfs_err(mp,
901902
"buffer item dirty bitmap (%u uints) too small to reflect %u bytes!",

fs/xfs/xfs_discard.c

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,14 @@ xfs_discard_endio(
108108
* list. We plug and chain the bios so that we only need a single completion
109109
* call to clear all the busy extents once the discards are complete.
110110
*/
111-
int
111+
void
112112
xfs_discard_extents(
113113
struct xfs_mount *mp,
114114
struct xfs_busy_extents *extents)
115115
{
116116
struct xfs_extent_busy *busyp;
117117
struct bio *bio = NULL;
118118
struct blk_plug plug;
119-
int error = 0;
120119

121120
blk_start_plug(&plug);
122121
list_for_each_entry(busyp, &extents->extent_list, list) {
@@ -126,18 +125,10 @@ xfs_discard_extents(
126125

127126
trace_xfs_discard_extent(xg, busyp->bno, busyp->length);
128127

129-
error = __blkdev_issue_discard(btp->bt_bdev,
128+
__blkdev_issue_discard(btp->bt_bdev,
130129
xfs_gbno_to_daddr(xg, busyp->bno),
131130
XFS_FSB_TO_BB(mp, busyp->length),
132131
GFP_KERNEL, &bio);
133-
if (error && error != -EOPNOTSUPP) {
134-
xfs_info(mp,
135-
"discard failed for extent [0x%llx,%u], error %d",
136-
(unsigned long long)busyp->bno,
137-
busyp->length,
138-
error);
139-
break;
140-
}
141132
}
142133

143134
if (bio) {
@@ -148,8 +139,6 @@ xfs_discard_extents(
148139
xfs_discard_endio_work(&extents->endio_work);
149140
}
150141
blk_finish_plug(&plug);
151-
152-
return error;
153142
}
154143

155144
/*
@@ -385,9 +374,7 @@ xfs_trim_perag_extents(
385374
* list after this function call, as it may have been freed by
386375
* the time control returns to us.
387376
*/
388-
error = xfs_discard_extents(pag_mount(pag), extents);
389-
if (error)
390-
break;
377+
xfs_discard_extents(pag_mount(pag), extents);
391378

392379
if (xfs_trim_should_stop())
393380
break;
@@ -496,12 +483,10 @@ xfs_discard_rtdev_extents(
496483

497484
trace_xfs_discard_rtextent(mp, busyp->bno, busyp->length);
498485

499-
error = __blkdev_issue_discard(bdev,
486+
__blkdev_issue_discard(bdev,
500487
xfs_rtb_to_daddr(mp, busyp->bno),
501488
XFS_FSB_TO_BB(mp, busyp->length),
502489
GFP_NOFS, &bio);
503-
if (error)
504-
break;
505490
}
506491
xfs_discard_free_rtdev_extents(tr);
507492

@@ -741,9 +726,7 @@ xfs_trim_rtgroup_extents(
741726
* list after this function call, as it may have been freed by
742727
* the time control returns to us.
743728
*/
744-
error = xfs_discard_extents(rtg_mount(rtg), tr.extents);
745-
if (error)
746-
break;
729+
xfs_discard_extents(rtg_mount(rtg), tr.extents);
747730

748731
low = tr.restart_rtx;
749732
} while (!xfs_trim_should_stop() && low <= high);

fs/xfs/xfs_discard.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ struct fstrim_range;
66
struct xfs_mount;
77
struct xfs_busy_extents;
88

9-
int xfs_discard_extents(struct xfs_mount *mp, struct xfs_busy_extents *busy);
9+
void xfs_discard_extents(struct xfs_mount *mp, struct xfs_busy_extents *busy);
1010
int xfs_ioc_trim(struct xfs_mount *mp, struct fstrim_range __user *fstrim);
1111

1212
#endif /* XFS_DISCARD_H */

fs/xfs/xfs_file.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,38 @@ xfs_falloc_insert_range(
12401240
return xfs_insert_file_space(XFS_I(inode), offset, len);
12411241
}
12421242

1243+
/*
1244+
* For various operations we need to zero up to one block at each end of
1245+
* the affected range. For zoned file systems this will require a space
1246+
* allocation, for which we need a reservation ahead of time.
1247+
*/
1248+
#define XFS_ZONED_ZERO_EDGE_SPACE_RES 2
1249+
1250+
/*
1251+
* Zero range implements a full zeroing mechanism but is only used in limited
1252+
* situations. It is more efficient to allocate unwritten extents than to
1253+
* perform zeroing here, so use an errortag to randomly force zeroing on DEBUG
1254+
* kernels for added test coverage.
1255+
*
1256+
* On zoned file systems, the error is already injected by
1257+
* xfs_file_zoned_fallocate, which then reserves the additional space needed.
1258+
* We only check for this extra space reservation here.
1259+
*/
1260+
static inline bool
1261+
xfs_falloc_force_zero(
1262+
struct xfs_inode *ip,
1263+
struct xfs_zone_alloc_ctx *ac)
1264+
{
1265+
if (xfs_is_zoned_inode(ip)) {
1266+
if (ac->reserved_blocks > XFS_ZONED_ZERO_EDGE_SPACE_RES) {
1267+
ASSERT(IS_ENABLED(CONFIG_XFS_DEBUG));
1268+
return true;
1269+
}
1270+
return false;
1271+
}
1272+
return XFS_TEST_ERROR(ip->i_mount, XFS_ERRTAG_FORCE_ZERO_RANGE);
1273+
}
1274+
12431275
/*
12441276
* Punch a hole and prealloc the range. We use a hole punch rather than
12451277
* unwritten extent conversion for two reasons:
@@ -1268,14 +1300,7 @@ xfs_falloc_zero_range(
12681300
if (error)
12691301
return error;
12701302

1271-
/*
1272-
* Zero range implements a full zeroing mechanism but is only used in
1273-
* limited situations. It is more efficient to allocate unwritten
1274-
* extents than to perform zeroing here, so use an errortag to randomly
1275-
* force zeroing on DEBUG kernels for added test coverage.
1276-
*/
1277-
if (XFS_TEST_ERROR(ip->i_mount,
1278-
XFS_ERRTAG_FORCE_ZERO_RANGE)) {
1303+
if (xfs_falloc_force_zero(ip, ac)) {
12791304
error = xfs_zero_range(ip, offset, len, ac, NULL);
12801305
} else {
12811306
error = xfs_free_file_space(ip, offset, len, ac);
@@ -1423,13 +1448,26 @@ xfs_file_zoned_fallocate(
14231448
{
14241449
struct xfs_zone_alloc_ctx ac = { };
14251450
struct xfs_inode *ip = XFS_I(file_inode(file));
1451+
struct xfs_mount *mp = ip->i_mount;
1452+
xfs_filblks_t count_fsb;
14261453
int error;
14271454

1428-
error = xfs_zoned_space_reserve(ip->i_mount, 2, XFS_ZR_RESERVED, &ac);
1455+
/*
1456+
* If full zeroing is forced by the error injection knob, we need a
1457+
* space reservation that covers the entire range. See the comment in
1458+
* xfs_zoned_write_space_reserve for the rationale for the calculation.
1459+
* Otherwise just reserve space for the two boundary blocks.
1460+
*/
1461+
count_fsb = XFS_ZONED_ZERO_EDGE_SPACE_RES;
1462+
if ((mode & FALLOC_FL_MODE_MASK) == FALLOC_FL_ZERO_RANGE &&
1463+
XFS_TEST_ERROR(mp, XFS_ERRTAG_FORCE_ZERO_RANGE))
1464+
count_fsb += XFS_B_TO_FSB(mp, len) + 1;
1465+
1466+
error = xfs_zoned_space_reserve(mp, count_fsb, XFS_ZR_RESERVED, &ac);
14291467
if (error)
14301468
return error;
14311469
error = __xfs_file_fallocate(file, mode, offset, len, &ac);
1432-
xfs_zoned_space_unreserve(ip->i_mount, &ac);
1470+
xfs_zoned_space_unreserve(mp, &ac);
14331471
return error;
14341472
}
14351473

fs/xfs/xfs_rtalloc.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,29 +1255,31 @@ xfs_growfs_check_rtgeom(
12551255
min_logfsbs = min_t(xfs_extlen_t, xfs_log_calc_minimum_size(nmp),
12561256
nmp->m_rsumblocks * 2);
12571257

1258-
kfree(nmp);
1259-
12601258
trace_xfs_growfs_check_rtgeom(mp, min_logfsbs);
12611259

12621260
if (min_logfsbs > mp->m_sb.sb_logblocks)
1263-
return -EINVAL;
1261+
goto out_inval;
12641262

12651263
if (xfs_has_zoned(mp)) {
12661264
uint32_t gblocks = mp->m_groups[XG_TYPE_RTG].blocks;
12671265
uint32_t rem;
12681266

12691267
if (rextsize != 1)
12701268
return -EINVAL;
1271-
div_u64_rem(mp->m_sb.sb_rblocks, gblocks, &rem);
1269+
div_u64_rem(nmp->m_sb.sb_rblocks, gblocks, &rem);
12721270
if (rem) {
12731271
xfs_warn(mp,
12741272
"new RT volume size (%lld) not aligned to RT group size (%d)",
1275-
mp->m_sb.sb_rblocks, gblocks);
1276-
return -EINVAL;
1273+
nmp->m_sb.sb_rblocks, gblocks);
1274+
goto out_inval;
12771275
}
12781276
}
12791277

1278+
kfree(nmp);
12801279
return 0;
1280+
out_inval:
1281+
kfree(nmp);
1282+
return -EINVAL;
12811283
}
12821284

12831285
/*

0 commit comments

Comments
 (0)