mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 07:03:03 +02:00
xfs: hoist recovered refcount intent checks out of xfs_cui_item_recover
When we recover a refcount intent from the log, we need to validate its contents before we try to replay them. Hoist the checking code into a separate function in preparation to refactor this code to use validation helpers. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Brian Foster <bfoster@redhat.com>
This commit is contained in:
parent
c447ad62dc
commit
ed64f8343a
|
|
@ -417,6 +417,38 @@ const struct xfs_defer_op_type xfs_refcount_update_defer_type = {
|
|||
.cancel_item = xfs_refcount_update_cancel_item,
|
||||
};
|
||||
|
||||
/* Is this recovered CUI ok? */
|
||||
static inline bool
|
||||
xfs_cui_validate_phys(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_phys_extent *refc)
|
||||
{
|
||||
xfs_fsblock_t startblock_fsb;
|
||||
bool op_ok;
|
||||
|
||||
startblock_fsb = XFS_BB_TO_FSB(mp,
|
||||
XFS_FSB_TO_DADDR(mp, refc->pe_startblock));
|
||||
switch (refc->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK) {
|
||||
case XFS_REFCOUNT_INCREASE:
|
||||
case XFS_REFCOUNT_DECREASE:
|
||||
case XFS_REFCOUNT_ALLOC_COW:
|
||||
case XFS_REFCOUNT_FREE_COW:
|
||||
op_ok = true;
|
||||
break;
|
||||
default:
|
||||
op_ok = false;
|
||||
break;
|
||||
}
|
||||
if (!op_ok || startblock_fsb == 0 ||
|
||||
refc->pe_len == 0 ||
|
||||
startblock_fsb >= mp->m_sb.sb_dblocks ||
|
||||
refc->pe_len >= mp->m_sb.sb_agblocks ||
|
||||
(refc->pe_flags & ~XFS_REFCOUNT_EXTENT_FLAGS))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a refcount update intent item that was recovered from the log.
|
||||
* We need to update the refcountbt.
|
||||
|
|
@ -433,11 +465,9 @@ xfs_cui_item_recover(
|
|||
struct xfs_trans *tp;
|
||||
struct xfs_btree_cur *rcur = NULL;
|
||||
struct xfs_mount *mp = lip->li_mountp;
|
||||
xfs_fsblock_t startblock_fsb;
|
||||
xfs_fsblock_t new_fsb;
|
||||
xfs_extlen_t new_len;
|
||||
unsigned int refc_type;
|
||||
bool op_ok;
|
||||
bool requeue_only = false;
|
||||
enum xfs_refcount_intent_type type;
|
||||
int i;
|
||||
|
|
@ -449,26 +479,13 @@ xfs_cui_item_recover(
|
|||
* just toss the CUI.
|
||||
*/
|
||||
for (i = 0; i < cuip->cui_format.cui_nextents; i++) {
|
||||
refc = &cuip->cui_format.cui_extents[i];
|
||||
startblock_fsb = XFS_BB_TO_FSB(mp,
|
||||
XFS_FSB_TO_DADDR(mp, refc->pe_startblock));
|
||||
switch (refc->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK) {
|
||||
case XFS_REFCOUNT_INCREASE:
|
||||
case XFS_REFCOUNT_DECREASE:
|
||||
case XFS_REFCOUNT_ALLOC_COW:
|
||||
case XFS_REFCOUNT_FREE_COW:
|
||||
op_ok = true;
|
||||
break;
|
||||
default:
|
||||
op_ok = false;
|
||||
break;
|
||||
}
|
||||
if (!op_ok || startblock_fsb == 0 ||
|
||||
refc->pe_len == 0 ||
|
||||
startblock_fsb >= mp->m_sb.sb_dblocks ||
|
||||
refc->pe_len >= mp->m_sb.sb_agblocks ||
|
||||
(refc->pe_flags & ~XFS_REFCOUNT_EXTENT_FLAGS))
|
||||
if (!xfs_cui_validate_phys(mp,
|
||||
&cuip->cui_format.cui_extents[i])) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
|
||||
&cuip->cui_format,
|
||||
sizeof(cuip->cui_format));
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user