summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_rmap.c19
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);