diff options
-rw-r--r-- | fs/xfs/libxfs/xfs_rmap.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 4ed07e1d333c..424b358c08fb 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -2751,6 +2751,7 @@ xfs_rmap_record_exists( struct xfs_rmap_key_state { uint64_t owner; uint64_t offset; + uint64_t len; unsigned int flags; }; @@ -2763,10 +2764,20 @@ xfs_rmap_has_other_keys_helper( { struct xfs_rmap_key_state *rks = priv; - if (rks->owner == rec->rm_owner && rks->offset == rec->rm_offset && - ((rks->flags & rec->rm_flags) & XFS_RMAP_KEY_FLAGS) == rks->flags) + if (rks->owner != rec->rm_owner) + return -ECANCELED; + if (((rks->flags & rec->rm_flags) & XFS_RMAP_KEY_FLAGS) != rks->flags) + return -ECANCELED; + + if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) || + (rec->rm_flags & XFS_RMAP_BMBT_BLOCK)) return 0; - return -ECANCELED; + + if (rec->rm_offset + rec->rm_blockcount <= rks->offset) + return -ECANCELED; + if (rks->offset + rks->len <= rec->rm_offset) + return -ECANCELED; + return 0; } /* @@ -2783,7 +2794,7 @@ xfs_rmap_has_other_keys( { struct xfs_rmap_irec low = {0}; struct xfs_rmap_irec high; - struct xfs_rmap_key_state rks; + struct xfs_rmap_key_state rks = { .len = len }; int error; xfs_owner_info_unpack(oinfo, &rks.owner, &rks.offset, &rks.flags); |