mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 17:41:50 +00:00
xfs: hoist recovered bmap intent checks out of xfs_bui_item_recover
When we recover a bmap 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
96f65bad7c
commit
bc525cf455
1 changed files with 47 additions and 27 deletions
|
@ -417,6 +417,49 @@ const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
|
||||||
.cancel_item = xfs_bmap_update_cancel_item,
|
.cancel_item = xfs_bmap_update_cancel_item,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Is this recovered BUI ok? */
|
||||||
|
static inline bool
|
||||||
|
xfs_bui_validate(
|
||||||
|
struct xfs_mount *mp,
|
||||||
|
struct xfs_bui_log_item *buip)
|
||||||
|
{
|
||||||
|
struct xfs_map_extent *bmap;
|
||||||
|
xfs_fsblock_t startblock_fsb;
|
||||||
|
xfs_fsblock_t inode_fsb;
|
||||||
|
|
||||||
|
/* Only one mapping operation per BUI... */
|
||||||
|
if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bmap = &buip->bui_format.bui_extents[0];
|
||||||
|
startblock_fsb = XFS_BB_TO_FSB(mp,
|
||||||
|
XFS_FSB_TO_DADDR(mp, bmap->me_startblock));
|
||||||
|
inode_fsb = XFS_BB_TO_FSB(mp, XFS_FSB_TO_DADDR(mp,
|
||||||
|
XFS_INO_TO_FSB(mp, bmap->me_owner)));
|
||||||
|
|
||||||
|
if (bmap->me_flags & ~XFS_BMAP_EXTENT_FLAGS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK) {
|
||||||
|
case XFS_BMAP_MAP:
|
||||||
|
case XFS_BMAP_UNMAP:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startblock_fsb == 0 ||
|
||||||
|
bmap->me_len == 0 ||
|
||||||
|
inode_fsb == 0 ||
|
||||||
|
startblock_fsb >= mp->m_sb.sb_dblocks ||
|
||||||
|
bmap->me_len >= mp->m_sb.sb_agblocks ||
|
||||||
|
inode_fsb >= mp->m_sb.sb_dblocks ||
|
||||||
|
(bmap->me_flags & ~XFS_BMAP_EXTENT_FLAGS))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Process a bmap update intent item that was recovered from the log.
|
* Process a bmap update intent item that was recovered from the log.
|
||||||
* We need to update some inode's bmbt.
|
* We need to update some inode's bmbt.
|
||||||
|
@ -433,47 +476,24 @@ xfs_bui_item_recover(
|
||||||
struct xfs_mount *mp = lip->li_mountp;
|
struct xfs_mount *mp = lip->li_mountp;
|
||||||
struct xfs_map_extent *bmap;
|
struct xfs_map_extent *bmap;
|
||||||
struct xfs_bud_log_item *budp;
|
struct xfs_bud_log_item *budp;
|
||||||
xfs_fsblock_t startblock_fsb;
|
|
||||||
xfs_fsblock_t inode_fsb;
|
|
||||||
xfs_filblks_t count;
|
xfs_filblks_t count;
|
||||||
xfs_exntst_t state;
|
xfs_exntst_t state;
|
||||||
unsigned int bui_type;
|
unsigned int bui_type;
|
||||||
int whichfork;
|
int whichfork;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
/* Only one mapping operation per BUI... */
|
if (!xfs_bui_validate(mp, buip)) {
|
||||||
if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS)
|
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
|
||||||
|
&buip->bui_format, sizeof(buip->bui_format));
|
||||||
return -EFSCORRUPTED;
|
return -EFSCORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* First check the validity of the extent described by the
|
|
||||||
* BUI. If anything is bad, then toss the BUI.
|
|
||||||
*/
|
|
||||||
bmap = &buip->bui_format.bui_extents[0];
|
bmap = &buip->bui_format.bui_extents[0];
|
||||||
startblock_fsb = XFS_BB_TO_FSB(mp,
|
|
||||||
XFS_FSB_TO_DADDR(mp, bmap->me_startblock));
|
|
||||||
inode_fsb = XFS_BB_TO_FSB(mp, XFS_FSB_TO_DADDR(mp,
|
|
||||||
XFS_INO_TO_FSB(mp, bmap->me_owner)));
|
|
||||||
state = (bmap->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
|
state = (bmap->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
|
||||||
XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
|
XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
|
||||||
whichfork = (bmap->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
|
whichfork = (bmap->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
|
||||||
XFS_ATTR_FORK : XFS_DATA_FORK;
|
XFS_ATTR_FORK : XFS_DATA_FORK;
|
||||||
bui_type = bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
|
bui_type = bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
|
||||||
switch (bui_type) {
|
|
||||||
case XFS_BMAP_MAP:
|
|
||||||
case XFS_BMAP_UNMAP:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EFSCORRUPTED;
|
|
||||||
}
|
|
||||||
if (startblock_fsb == 0 ||
|
|
||||||
bmap->me_len == 0 ||
|
|
||||||
inode_fsb == 0 ||
|
|
||||||
startblock_fsb >= mp->m_sb.sb_dblocks ||
|
|
||||||
bmap->me_len >= mp->m_sb.sb_agblocks ||
|
|
||||||
inode_fsb >= mp->m_sb.sb_dblocks ||
|
|
||||||
(bmap->me_flags & ~XFS_BMAP_EXTENT_FLAGS))
|
|
||||||
return -EFSCORRUPTED;
|
|
||||||
|
|
||||||
/* Grab the inode. */
|
/* Grab the inode. */
|
||||||
error = xfs_iget(mp, NULL, bmap->me_owner, 0, 0, &ip);
|
error = xfs_iget(mp, NULL, bmap->me_owner, 0, 0, &ip);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue