Skip to content

Commit e0b5b97

Browse files
author
Darrick J. Wong
committed
xfs: move the min and max group block numbers to xfs_group
Move the min and max agblock numbers to the generic xfs_group structure so that we can start building validators for extents within an rtgroup. While we're at it, use check_add_overflow for the extent length computation because that has much better overflow checking. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
1 parent ceaa0bd commit e0b5b97

File tree

11 files changed

+94
-39
lines changed

11 files changed

+94
-39
lines changed

fs/xfs/libxfs/xfs_ag.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,10 @@ xfs_update_last_ag_size(
205205

206206
if (!pag)
207207
return -EFSCORRUPTED;
208-
pag->block_count = __xfs_ag_block_count(mp, prev_agcount - 1,
209-
mp->m_sb.sb_agcount, mp->m_sb.sb_dblocks);
210-
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
208+
pag_group(pag)->xg_block_count = __xfs_ag_block_count(mp,
209+
prev_agcount - 1, mp->m_sb.sb_agcount,
210+
mp->m_sb.sb_dblocks);
211+
__xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
211212
&pag->agino_max);
212213
xfs_perag_rele(pag);
213214
return 0;
@@ -241,9 +242,10 @@ xfs_perag_alloc(
241242
/*
242243
* Pre-calculated geometry
243244
*/
244-
pag->block_count = __xfs_ag_block_count(mp, index, agcount, dblocks);
245-
pag->min_block = XFS_AGFL_BLOCK(mp) + 1;
246-
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
245+
pag_group(pag)->xg_block_count = __xfs_ag_block_count(mp, index, agcount,
246+
dblocks);
247+
pag_group(pag)->xg_min_gbno = XFS_AGFL_BLOCK(mp) + 1;
248+
__xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
247249
&pag->agino_max);
248250

249251
error = xfs_group_insert(mp, pag_group(pag), index, XG_TYPE_AG);
@@ -852,8 +854,8 @@ xfs_ag_shrink_space(
852854
}
853855

854856
/* Update perag geometry */
855-
pag->block_count -= delta;
856-
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
857+
pag_group(pag)->xg_block_count -= delta;
858+
__xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
857859
&pag->agino_max);
858860

859861
xfs_ialloc_log_agi(*tpp, agibp, XFS_AGI_LENGTH);
@@ -924,8 +926,8 @@ xfs_ag_extend_space(
924926
return error;
925927

926928
/* Update perag geometry */
927-
pag->block_count = be32_to_cpu(agf->agf_length);
928-
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
929+
pag_group(pag)->xg_block_count = be32_to_cpu(agf->agf_length);
930+
__xfs_agino_range(mp, pag_group(pag)->xg_block_count, &pag->agino_min,
929931
&pag->agino_max);
930932
return 0;
931933
}

fs/xfs/libxfs/xfs_ag.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ struct xfs_perag {
6161
struct xfs_ag_resv pag_rmapbt_resv;
6262

6363
/* Precalculated geometry info */
64-
xfs_agblock_t block_count;
65-
xfs_agblock_t min_block;
6664
xfs_agino_t agino_min;
6765
xfs_agino_t agino_max;
6866

@@ -220,11 +218,7 @@ void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
220218
static inline bool
221219
xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno)
222220
{
223-
if (agbno >= pag->block_count)
224-
return false;
225-
if (agbno < pag->min_block)
226-
return false;
227-
return true;
221+
return xfs_verify_gbno(pag_group(pag), agbno);
228222
}
229223

230224
static inline bool
@@ -233,13 +227,7 @@ xfs_verify_agbext(
233227
xfs_agblock_t agbno,
234228
xfs_agblock_t len)
235229
{
236-
if (agbno + len <= agbno)
237-
return false;
238-
239-
if (!xfs_verify_agbno(pag, agbno))
240-
return false;
241-
242-
return xfs_verify_agbno(pag, agbno + len - 1);
230+
return xfs_verify_gbext(pag_group(pag), agbno, len);
243231
}
244232

245233
/*

fs/xfs/libxfs/xfs_group.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ struct xfs_group {
1212
atomic_t xg_ref; /* passive reference count */
1313
atomic_t xg_active_ref; /* active reference count */
1414

15+
/* Precalculated geometry info */
16+
uint32_t xg_block_count; /* max usable gbno */
17+
uint32_t xg_min_gbno; /* min usable gbno */
18+
1519
#ifdef __KERNEL__
1620
/* -- kernel only structures below this line -- */
1721

@@ -128,4 +132,33 @@ xfs_fsb_to_gbno(
128132
return fsbno & mp->m_groups[type].blkmask;
129133
}
130134

135+
static inline bool
136+
xfs_verify_gbno(
137+
struct xfs_group *xg,
138+
uint32_t gbno)
139+
{
140+
if (gbno >= xg->xg_block_count)
141+
return false;
142+
if (gbno < xg->xg_min_gbno)
143+
return false;
144+
return true;
145+
}
146+
147+
static inline bool
148+
xfs_verify_gbext(
149+
struct xfs_group *xg,
150+
uint32_t gbno,
151+
uint32_t glen)
152+
{
153+
uint32_t end;
154+
155+
if (!xfs_verify_gbno(xg, gbno))
156+
return false;
157+
if (glen == 0 || check_add_overflow(gbno, glen - 1, &end))
158+
return false;
159+
if (!xfs_verify_gbno(xg, end))
160+
return false;
161+
return true;
162+
}
163+
131164
#endif /* __LIBXFS_GROUP_H */

fs/xfs/libxfs/xfs_ialloc_btree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ xfs_inobt_max_size(
717717
struct xfs_perag *pag)
718718
{
719719
struct xfs_mount *mp = pag_mount(pag);
720-
xfs_agblock_t agblocks = pag->block_count;
720+
xfs_agblock_t agblocks = pag_group(pag)->xg_block_count;
721721

722722
/* Bail out if we're uninitialized, which can happen in mkfs. */
723723
if (M_IGEO(mp)->inobt_mxr[0] == 0)

fs/xfs/libxfs/xfs_rtgroup.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,32 @@
3434
#include "xfs_metafile.h"
3535
#include "xfs_metadir.h"
3636

37+
/* Find the first usable fsblock in this rtgroup. */
38+
static inline uint32_t
39+
xfs_rtgroup_min_block(
40+
struct xfs_mount *mp,
41+
xfs_rgnumber_t rgno)
42+
{
43+
if (xfs_has_rtsb(mp) && rgno == 0)
44+
return mp->m_sb.sb_rextsize;
45+
46+
return 0;
47+
}
48+
49+
/* Precompute this group's geometry */
50+
void
51+
xfs_rtgroup_calc_geometry(
52+
struct xfs_mount *mp,
53+
struct xfs_rtgroup *rtg,
54+
xfs_rgnumber_t rgno,
55+
xfs_rgnumber_t rgcount,
56+
xfs_rtbxlen_t rextents)
57+
{
58+
rtg->rtg_extents = __xfs_rtgroup_extents(mp, rgno, rgcount, rextents);
59+
rtg_group(rtg)->xg_block_count = rtg->rtg_extents * mp->m_sb.sb_rextsize;
60+
rtg_group(rtg)->xg_min_gbno = xfs_rtgroup_min_block(mp, rgno);
61+
}
62+
3763
int
3864
xfs_rtgroup_alloc(
3965
struct xfs_mount *mp,
@@ -48,6 +74,8 @@ xfs_rtgroup_alloc(
4874
if (!rtg)
4975
return -ENOMEM;
5076

77+
xfs_rtgroup_calc_geometry(mp, rtg, rgno, rgcount, rextents);
78+
5179
error = xfs_group_insert(mp, rtg_group(rtg), rgno, XG_TYPE_RTG);
5280
if (error)
5381
goto out_free_rtg;
@@ -149,6 +177,7 @@ xfs_update_last_rtgroup_size(
149177
return -EFSCORRUPTED;
150178
rtg->rtg_extents = __xfs_rtgroup_extents(mp, prev_rgcount - 1,
151179
mp->m_sb.sb_rgcount, mp->m_sb.sb_rextents);
180+
rtg_group(rtg)->xg_block_count = rtg->rtg_extents * mp->m_sb.sb_rextsize;
152181
xfs_rtgroup_rele(rtg);
153182
return 0;
154183
}
@@ -223,7 +252,7 @@ xfs_rtgroup_get_geometry(
223252
/* Fill out form. */
224253
memset(rgeo, 0, sizeof(*rgeo));
225254
rgeo->rg_number = rtg_rgno(rtg);
226-
rgeo->rg_length = rtg->rtg_extents * rtg_mount(rtg)->m_sb.sb_rextsize;
255+
rgeo->rg_length = rtg_group(rtg)->xg_block_count;
227256
xfs_rtgroup_geom_health(rtg, rgeo);
228257
return 0;
229258
}

fs/xfs/libxfs/xfs_rtgroup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno,
199199
xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno,
200200
xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents);
201201
xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno);
202+
void xfs_rtgroup_calc_geometry(struct xfs_mount *mp, struct xfs_rtgroup *rtg,
203+
xfs_rgnumber_t rgno, xfs_rgnumber_t rgcount,
204+
xfs_rtbxlen_t rextents);
202205

203206
int xfs_update_last_rtgroup_size(struct xfs_mount *mp,
204207
xfs_rgnumber_t prev_rgcount);

fs/xfs/scrub/agheader.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ xchk_agf(
564564

565565
/* Check the AG length */
566566
eoag = be32_to_cpu(agf->agf_length);
567-
if (eoag != pag->block_count)
567+
if (eoag != pag_group(pag)->xg_block_count)
568568
xchk_block_set_corrupt(sc, sc->sa.agf_bp);
569569

570570
/* Check the AGF btree roots and levels */
@@ -944,7 +944,7 @@ xchk_agi(
944944

945945
/* Check the AG length */
946946
eoag = be32_to_cpu(agi->agi_length);
947-
if (eoag != pag->block_count)
947+
if (eoag != pag_group(pag)->xg_block_count)
948948
xchk_block_set_corrupt(sc, sc->sa.agi_bp);
949949

950950
/* Check btree roots and levels */

fs/xfs/scrub/agheader_repair.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ xrep_agf_init_header(
209209
agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
210210
agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
211211
agf->agf_seqno = cpu_to_be32(pag_agno(pag));
212-
agf->agf_length = cpu_to_be32(pag->block_count);
212+
agf->agf_length = cpu_to_be32(pag_group(pag)->xg_block_count);
213213
agf->agf_flfirst = old_agf->agf_flfirst;
214214
agf->agf_fllast = old_agf->agf_fllast;
215215
agf->agf_flcount = old_agf->agf_flcount;
@@ -898,7 +898,7 @@ xrep_agi_init_header(
898898
agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
899899
agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
900900
agi->agi_seqno = cpu_to_be32(pag_agno(pag));
901-
agi->agi_length = cpu_to_be32(pag->block_count);
901+
agi->agi_length = cpu_to_be32(pag_group(pag)->xg_block_count);
902902
agi->agi_newino = cpu_to_be32(NULLAGINO);
903903
agi->agi_dirino = cpu_to_be32(NULLAGINO);
904904
if (xfs_has_crc(mp))

fs/xfs/scrub/repair.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ xrep_calc_ag_resblks(
306306
/* Now grab the block counters from the AGF. */
307307
error = xfs_alloc_read_agf(pag, NULL, 0, &bp);
308308
if (error) {
309-
aglen = pag->block_count;
309+
aglen = pag_group(pag)->xg_block_count;
310310
freelen = aglen;
311311
usedlen = aglen;
312312
} else {
@@ -326,9 +326,9 @@ xrep_calc_ag_resblks(
326326

327327
/* If the block counts are impossible, make worst-case assumptions. */
328328
if (aglen == NULLAGBLOCK ||
329-
aglen != pag->block_count ||
329+
aglen != pag_group(pag)->xg_block_count ||
330330
freelen >= aglen) {
331-
aglen = pag->block_count;
331+
aglen = pag_group(pag)->xg_block_count;
332332
freelen = aglen;
333333
usedlen = aglen;
334334
}

fs/xfs/xfs_discard.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ xfs_trim_perag_extents(
337337
};
338338
int error = 0;
339339

340-
if (start != 0 || end != pag->block_count)
340+
if (start != 0 || end != pag_group(pag)->xg_block_count)
341341
tcur.by_bno = true;
342342

343343
do {
@@ -403,7 +403,7 @@ xfs_trim_datadev_extents(
403403
end_agbno = xfs_daddr_to_agbno(mp, ddev_end);
404404

405405
while ((pag = xfs_perag_next_range(mp, pag, start_agno, end_agno))) {
406-
xfs_agblock_t agend = pag->block_count;
406+
xfs_agblock_t agend = pag_group(pag)->xg_block_count;
407407

408408
if (pag_agno(pag) == end_agno)
409409
agend = end_agbno;

0 commit comments

Comments
 (0)