forked from Minki/linux
xfs: only skip rmap owner checks for unknown-owner rmap removal
For rmap removal, refactor the rmap owner checks into a separate function, then skip the checks if we are performing an unknown-owner removal. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
33df3a9cf9
commit
68c58e9b9a
@ -367,6 +367,51 @@ xfs_rmap_lookup_le_range(
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform all the relevant owner checks for a removal op. If we're doing an
|
||||
* unknown-owner removal then we have no owner information to check.
|
||||
*/
|
||||
static int
|
||||
xfs_rmap_free_check_owner(
|
||||
struct xfs_mount *mp,
|
||||
uint64_t ltoff,
|
||||
struct xfs_rmap_irec *rec,
|
||||
xfs_fsblock_t bno,
|
||||
xfs_filblks_t len,
|
||||
uint64_t owner,
|
||||
uint64_t offset,
|
||||
unsigned int flags)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (owner == XFS_RMAP_OWN_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
/* Make sure the unwritten flag matches. */
|
||||
XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
|
||||
(rec->rm_flags & XFS_RMAP_UNWRITTEN), out);
|
||||
|
||||
/* Make sure the owner matches what we expect to find in the tree. */
|
||||
XFS_WANT_CORRUPTED_GOTO(mp, owner == rec->rm_owner, out);
|
||||
|
||||
/* Check the offset, if necessary. */
|
||||
if (XFS_RMAP_NON_INODE_OWNER(owner))
|
||||
goto out;
|
||||
|
||||
if (flags & XFS_RMAP_BMBT_BLOCK) {
|
||||
XFS_WANT_CORRUPTED_GOTO(mp, rec->rm_flags & XFS_RMAP_BMBT_BLOCK,
|
||||
out);
|
||||
} else {
|
||||
XFS_WANT_CORRUPTED_GOTO(mp, rec->rm_offset <= offset, out);
|
||||
XFS_WANT_CORRUPTED_GOTO(mp,
|
||||
ltoff + rec->rm_blockcount >= offset + len,
|
||||
out);
|
||||
}
|
||||
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the extent in the rmap btree and remove it.
|
||||
*
|
||||
@ -468,33 +513,16 @@ xfs_rmap_unmap(
|
||||
goto out_done;
|
||||
}
|
||||
|
||||
/* Make sure the unwritten flag matches. */
|
||||
XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
|
||||
(ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
|
||||
|
||||
/* Make sure the extent we found covers the entire freeing range. */
|
||||
XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
|
||||
ltrec.rm_startblock + ltrec.rm_blockcount >=
|
||||
bno + len, out_error);
|
||||
ltrec.rm_startblock + ltrec.rm_blockcount >=
|
||||
bno + len, out_error);
|
||||
|
||||
/* Make sure the owner matches what we expect to find in the tree. */
|
||||
XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner ||
|
||||
XFS_RMAP_NON_INODE_OWNER(owner), out_error);
|
||||
|
||||
/* Check the offset, if necessary. */
|
||||
if (!XFS_RMAP_NON_INODE_OWNER(owner)) {
|
||||
if (flags & XFS_RMAP_BMBT_BLOCK) {
|
||||
XFS_WANT_CORRUPTED_GOTO(mp,
|
||||
ltrec.rm_flags & XFS_RMAP_BMBT_BLOCK,
|
||||
out_error);
|
||||
} else {
|
||||
XFS_WANT_CORRUPTED_GOTO(mp,
|
||||
ltrec.rm_offset <= offset, out_error);
|
||||
XFS_WANT_CORRUPTED_GOTO(mp,
|
||||
ltoff + ltrec.rm_blockcount >= offset + len,
|
||||
out_error);
|
||||
}
|
||||
}
|
||||
/* Check owner information. */
|
||||
error = xfs_rmap_free_check_owner(mp, ltoff, <rec, bno, len, owner,
|
||||
offset, flags);
|
||||
if (error)
|
||||
goto out_error;
|
||||
|
||||
if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
|
||||
/* exact match, simply remove the record from rmap tree */
|
||||
|
Loading…
Reference in New Issue
Block a user