mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
xfs: repair rmap btree inodes
Teach the inode repair code how to deal with realtime rmap btree inodes that won't load properly. This is most likely moot since the filesystem generally won't mount without the rtrmapbt inodes being usable, but we'll add this for completeness. Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
1bd0843027
commit
3dd3aba6b9
|
|
@ -944,6 +944,34 @@ xrep_dinode_bad_bmbt_fork(
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Return true if this rmap-format ifork looks like garbage. */
|
||||
STATIC bool
|
||||
xrep_dinode_bad_rtrmapbt_fork(
|
||||
struct xfs_scrub *sc,
|
||||
struct xfs_dinode *dip,
|
||||
unsigned int dfork_size)
|
||||
{
|
||||
struct xfs_rtrmap_root *dfp;
|
||||
unsigned int nrecs;
|
||||
unsigned int level;
|
||||
|
||||
if (dfork_size < sizeof(struct xfs_rtrmap_root))
|
||||
return true;
|
||||
|
||||
dfp = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
|
||||
nrecs = be16_to_cpu(dfp->bb_numrecs);
|
||||
level = be16_to_cpu(dfp->bb_level);
|
||||
|
||||
if (level > sc->mp->m_rtrmap_maxlevels)
|
||||
return true;
|
||||
if (xfs_rtrmap_droot_space_calc(level, nrecs) > dfork_size)
|
||||
return true;
|
||||
if (level > 0 && nrecs == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check a metadata-btree fork. */
|
||||
STATIC bool
|
||||
xrep_dinode_bad_metabt_fork(
|
||||
|
|
@ -956,6 +984,8 @@ xrep_dinode_bad_metabt_fork(
|
|||
return true;
|
||||
|
||||
switch (be16_to_cpu(dip->di_metatype)) {
|
||||
case XFS_METAFILE_RTRMAP:
|
||||
return xrep_dinode_bad_rtrmapbt_fork(sc, dip, dfork_size);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1220,6 +1250,7 @@ xrep_dinode_ensure_forkoff(
|
|||
uint16_t mode)
|
||||
{
|
||||
struct xfs_bmdr_block *bmdr;
|
||||
struct xfs_rtrmap_root *rmdr;
|
||||
struct xfs_scrub *sc = ri->sc;
|
||||
xfs_extnum_t attr_extents, data_extents;
|
||||
size_t bmdr_minsz = xfs_bmdr_space_calc(1);
|
||||
|
|
@ -1328,6 +1359,10 @@ xrep_dinode_ensure_forkoff(
|
|||
break;
|
||||
case XFS_DINODE_FMT_META_BTREE:
|
||||
switch (be16_to_cpu(dip->di_metatype)) {
|
||||
case XFS_METAFILE_RTRMAP:
|
||||
rmdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK);
|
||||
dfork_min = xfs_rtrmap_broot_space(sc->mp, rmdr);
|
||||
break;
|
||||
default:
|
||||
dfork_min = 0;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user