Skip to content

Commit ee12eaa

Browse files
author
Darrick J. Wong
committed
xfs: complain about bad records in query_range helpers
For every btree type except for the bmbt, refactor the code that complains about bad records into a helper and make the ->query_range helpers call it so that corruptions found via that avenue are logged. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
1 parent 69010fe commit ee12eaa

4 files changed

Lines changed: 91 additions & 57 deletions

File tree

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,24 @@ xfs_alloc_check_irec(
261261
return NULL;
262262
}
263263

264+
static inline int
265+
xfs_alloc_complain_bad_rec(
266+
struct xfs_btree_cur *cur,
267+
xfs_failaddr_t fa,
268+
const struct xfs_alloc_rec_incore *irec)
269+
{
270+
struct xfs_mount *mp = cur->bc_mp;
271+
272+
xfs_warn(mp,
273+
"%s Freespace BTree record corruption in AG %d detected at %pS!",
274+
cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size",
275+
cur->bc_ag.pag->pag_agno, fa);
276+
xfs_warn(mp,
277+
"start block 0x%x block count 0x%x", irec->ar_startblock,
278+
irec->ar_blockcount);
279+
return -EFSCORRUPTED;
280+
}
281+
264282
/*
265283
* Get the data from the pointed-to record.
266284
*/
@@ -272,8 +290,6 @@ xfs_alloc_get_rec(
272290
int *stat) /* output: success/failure */
273291
{
274292
struct xfs_alloc_rec_incore irec;
275-
struct xfs_mount *mp = cur->bc_mp;
276-
struct xfs_perag *pag = cur->bc_ag.pag;
277293
union xfs_btree_rec *rec;
278294
xfs_failaddr_t fa;
279295
int error;
@@ -285,21 +301,11 @@ xfs_alloc_get_rec(
285301
xfs_alloc_btrec_to_irec(rec, &irec);
286302
fa = xfs_alloc_check_irec(cur, &irec);
287303
if (fa)
288-
goto out_bad_rec;
304+
return xfs_alloc_complain_bad_rec(cur, fa, &irec);
289305

290306
*bno = irec.ar_startblock;
291307
*len = irec.ar_blockcount;
292308
return 0;
293-
294-
out_bad_rec:
295-
xfs_warn(mp,
296-
"%s Freespace BTree record corruption in AG %d detected at %pS!",
297-
cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size",
298-
pag->pag_agno, fa);
299-
xfs_warn(mp,
300-
"start block 0x%x block count 0x%x", irec.ar_startblock,
301-
irec.ar_blockcount);
302-
return -EFSCORRUPTED;
303309
}
304310

305311
/*
@@ -3692,10 +3698,12 @@ xfs_alloc_query_range_helper(
36923698
{
36933699
struct xfs_alloc_query_range_info *query = priv;
36943700
struct xfs_alloc_rec_incore irec;
3701+
xfs_failaddr_t fa;
36953702

36963703
xfs_alloc_btrec_to_irec(rec, &irec);
3697-
if (xfs_alloc_check_irec(cur, &irec) != NULL)
3698-
return -EFSCORRUPTED;
3704+
fa = xfs_alloc_check_irec(cur, &irec);
3705+
if (fa)
3706+
return xfs_alloc_complain_bad_rec(cur, fa, &irec);
36993707

37003708
return query->fn(cur, &irec, query->priv);
37013709
}

fs/xfs/libxfs/xfs_ialloc.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,25 @@ xfs_inobt_check_irec(
122122
return NULL;
123123
}
124124

125+
static inline int
126+
xfs_inobt_complain_bad_rec(
127+
struct xfs_btree_cur *cur,
128+
xfs_failaddr_t fa,
129+
const struct xfs_inobt_rec_incore *irec)
130+
{
131+
struct xfs_mount *mp = cur->bc_mp;
132+
133+
xfs_warn(mp,
134+
"%s Inode BTree record corruption in AG %d detected at %pS!",
135+
cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free",
136+
cur->bc_ag.pag->pag_agno, fa);
137+
xfs_warn(mp,
138+
"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x",
139+
irec->ir_startino, irec->ir_count, irec->ir_freecount,
140+
irec->ir_free, irec->ir_holemask);
141+
return -EFSCORRUPTED;
142+
}
143+
125144
/*
126145
* Get the data from the pointed-to record.
127146
*/
@@ -143,20 +162,9 @@ xfs_inobt_get_rec(
143162
xfs_inobt_btrec_to_irec(mp, rec, irec);
144163
fa = xfs_inobt_check_irec(cur, irec);
145164
if (fa)
146-
goto out_bad_rec;
165+
return xfs_inobt_complain_bad_rec(cur, fa, irec);
147166

148167
return 0;
149-
150-
out_bad_rec:
151-
xfs_warn(mp,
152-
"%s Inode BTree record corruption in AG %d detected at %pS!",
153-
cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free",
154-
cur->bc_ag.pag->pag_agno, fa);
155-
xfs_warn(mp,
156-
"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x",
157-
irec->ir_startino, irec->ir_count, irec->ir_freecount,
158-
irec->ir_free, irec->ir_holemask);
159-
return -EFSCORRUPTED;
160168
}
161169

162170
/*
@@ -2702,10 +2710,12 @@ xfs_ialloc_count_inodes_rec(
27022710
{
27032711
struct xfs_inobt_rec_incore irec;
27042712
struct xfs_ialloc_count_inodes *ci = priv;
2713+
xfs_failaddr_t fa;
27052714

27062715
xfs_inobt_btrec_to_irec(cur->bc_mp, rec, &irec);
2707-
if (xfs_inobt_check_irec(cur, &irec) != NULL)
2708-
return -EFSCORRUPTED;
2716+
fa = xfs_inobt_check_irec(cur, &irec);
2717+
if (fa)
2718+
return xfs_inobt_complain_bad_rec(cur, fa, &irec);
27092719

27102720
ci->count += irec.ir_count;
27112721
ci->freecount += irec.ir_freecount;

fs/xfs/libxfs/xfs_refcount.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,23 @@ xfs_refcount_check_irec(
144144
return NULL;
145145
}
146146

147+
static inline int
148+
xfs_refcount_complain_bad_rec(
149+
struct xfs_btree_cur *cur,
150+
xfs_failaddr_t fa,
151+
const struct xfs_refcount_irec *irec)
152+
{
153+
struct xfs_mount *mp = cur->bc_mp;
154+
155+
xfs_warn(mp,
156+
"Refcount BTree record corruption in AG %d detected at %pS!",
157+
cur->bc_ag.pag->pag_agno, fa);
158+
xfs_warn(mp,
159+
"Start block 0x%x, block count 0x%x, references 0x%x",
160+
irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount);
161+
return -EFSCORRUPTED;
162+
}
163+
147164
/*
148165
* Get the data from the pointed-to record.
149166
*/
@@ -153,8 +170,6 @@ xfs_refcount_get_rec(
153170
struct xfs_refcount_irec *irec,
154171
int *stat)
155172
{
156-
struct xfs_mount *mp = cur->bc_mp;
157-
struct xfs_perag *pag = cur->bc_ag.pag;
158173
union xfs_btree_rec *rec;
159174
xfs_failaddr_t fa;
160175
int error;
@@ -166,19 +181,10 @@ xfs_refcount_get_rec(
166181
xfs_refcount_btrec_to_irec(rec, irec);
167182
fa = xfs_refcount_check_irec(cur, irec);
168183
if (fa)
169-
goto out_bad_rec;
184+
return xfs_refcount_complain_bad_rec(cur, fa, irec);
170185

171-
trace_xfs_refcount_get(cur->bc_mp, pag->pag_agno, irec);
186+
trace_xfs_refcount_get(cur->bc_mp, cur->bc_ag.pag->pag_agno, irec);
172187
return 0;
173-
174-
out_bad_rec:
175-
xfs_warn(mp,
176-
"Refcount BTree record corruption in AG %d detected at %pS!",
177-
pag->pag_agno, fa);
178-
xfs_warn(mp,
179-
"Start block 0x%x, block count 0x%x, references 0x%x",
180-
irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount);
181-
return -EFSCORRUPTED;
182188
}
183189

184190
/*

fs/xfs/libxfs/xfs_rmap.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,24 @@ xfs_rmap_check_irec(
235235
return NULL;
236236
}
237237

238+
static inline int
239+
xfs_rmap_complain_bad_rec(
240+
struct xfs_btree_cur *cur,
241+
xfs_failaddr_t fa,
242+
const struct xfs_rmap_irec *irec)
243+
{
244+
struct xfs_mount *mp = cur->bc_mp;
245+
246+
xfs_warn(mp,
247+
"Reverse Mapping BTree record corruption in AG %d detected at %pS!",
248+
cur->bc_ag.pag->pag_agno, fa);
249+
xfs_warn(mp,
250+
"Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
251+
irec->rm_owner, irec->rm_flags, irec->rm_startblock,
252+
irec->rm_blockcount);
253+
return -EFSCORRUPTED;
254+
}
255+
238256
/*
239257
* Get the data from the pointed-to record.
240258
*/
@@ -244,8 +262,6 @@ xfs_rmap_get_rec(
244262
struct xfs_rmap_irec *irec,
245263
int *stat)
246264
{
247-
struct xfs_mount *mp = cur->bc_mp;
248-
struct xfs_perag *pag = cur->bc_ag.pag;
249265
union xfs_btree_rec *rec;
250266
xfs_failaddr_t fa;
251267
int error;
@@ -258,18 +274,9 @@ xfs_rmap_get_rec(
258274
if (!fa)
259275
fa = xfs_rmap_check_irec(cur, irec);
260276
if (fa)
261-
goto out_bad_rec;
277+
return xfs_rmap_complain_bad_rec(cur, fa, irec);
262278

263279
return 0;
264-
out_bad_rec:
265-
xfs_warn(mp,
266-
"Reverse Mapping BTree record corruption in AG %d detected at %pS!",
267-
pag->pag_agno, fa);
268-
xfs_warn(mp,
269-
"Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
270-
irec->rm_owner, irec->rm_flags, irec->rm_startblock,
271-
irec->rm_blockcount);
272-
return -EFSCORRUPTED;
273280
}
274281

275282
struct xfs_find_left_neighbor_info {
@@ -2335,10 +2342,13 @@ xfs_rmap_query_range_helper(
23352342
{
23362343
struct xfs_rmap_query_range_info *query = priv;
23372344
struct xfs_rmap_irec irec;
2345+
xfs_failaddr_t fa;
23382346

2339-
if (xfs_rmap_btrec_to_irec(rec, &irec) != NULL ||
2340-
xfs_rmap_check_irec(cur, &irec) != NULL)
2341-
return -EFSCORRUPTED;
2347+
fa = xfs_rmap_btrec_to_irec(rec, &irec);
2348+
if (!fa)
2349+
fa = xfs_rmap_check_irec(cur, &irec);
2350+
if (fa)
2351+
return xfs_rmap_complain_bad_rec(cur, fa, &irec);
23422352

23432353
return query->fn(cur, &irec, query->priv);
23442354
}

0 commit comments

Comments
 (0)