@@ -2032,6 +2032,34 @@ xfs_rmap_map_shared(
20322032 return error ;
20332033}
20342034
2035+ /* Insert a raw rmap into the rmapbt. */
2036+ int
2037+ xfs_rmap_map_raw (
2038+ struct xfs_btree_cur * cur ,
2039+ struct xfs_rmap_irec * rmap )
2040+ {
2041+ struct xfs_owner_info oinfo ;
2042+
2043+ oinfo .oi_owner = rmap -> rm_owner ;
2044+ oinfo .oi_offset = rmap -> rm_offset ;
2045+ oinfo .oi_flags = 0 ;
2046+ if (rmap -> rm_flags & XFS_RMAP_ATTR_FORK )
2047+ oinfo .oi_flags |= XFS_OWNER_INFO_ATTR_FORK ;
2048+ if (rmap -> rm_flags & XFS_RMAP_BMBT_BLOCK )
2049+ oinfo .oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK ;
2050+
2051+ if (rmap -> rm_flags || XFS_RMAP_NON_INODE_OWNER (rmap -> rm_owner ))
2052+ return xfs_rmap_map (cur , rmap -> rm_startblock ,
2053+ rmap -> rm_blockcount ,
2054+ rmap -> rm_flags & XFS_RMAP_UNWRITTEN ,
2055+ & oinfo );
2056+
2057+ return xfs_rmap_map_shared (cur , rmap -> rm_startblock ,
2058+ rmap -> rm_blockcount ,
2059+ rmap -> rm_flags & XFS_RMAP_UNWRITTEN ,
2060+ & oinfo );
2061+ }
2062+
20352063struct xfs_rmap_query_range_info {
20362064 xfs_rmap_query_range_fn fn ;
20372065 void * priv ;
@@ -2455,3 +2483,56 @@ xfs_rmap_record_exists(
24552483 irec .rm_startblock + irec .rm_blockcount >= bno + len );
24562484 return 0 ;
24572485}
2486+
2487+ struct xfs_rmap_key_state {
2488+ uint64_t owner ;
2489+ uint64_t offset ;
2490+ unsigned int flags ;
2491+ bool has_rmap ;
2492+ };
2493+
2494+ /* For each rmap given, figure out if it doesn't match the key we want. */
2495+ STATIC int
2496+ xfs_rmap_has_other_keys_helper (
2497+ struct xfs_btree_cur * cur ,
2498+ struct xfs_rmap_irec * rec ,
2499+ void * priv )
2500+ {
2501+ struct xfs_rmap_key_state * rks = priv ;
2502+
2503+ if (rks -> owner == rec -> rm_owner && rks -> offset == rec -> rm_offset &&
2504+ ((rks -> flags & rec -> rm_flags ) & XFS_RMAP_KEY_FLAGS ) == rks -> flags )
2505+ return 0 ;
2506+ rks -> has_rmap = true;
2507+ return XFS_BTREE_QUERY_RANGE_ABORT ;
2508+ }
2509+
2510+ /*
2511+ * Given an extent and some owner info, can we find records overlapping
2512+ * the extent whose owner info does not match the given owner?
2513+ */
2514+ int
2515+ xfs_rmap_has_other_keys (
2516+ struct xfs_btree_cur * cur ,
2517+ xfs_agblock_t bno ,
2518+ xfs_extlen_t len ,
2519+ struct xfs_owner_info * oinfo ,
2520+ bool * has_rmap )
2521+ {
2522+ struct xfs_rmap_irec low = {0 };
2523+ struct xfs_rmap_irec high ;
2524+ struct xfs_rmap_key_state rks ;
2525+ int error ;
2526+
2527+ xfs_owner_info_unpack (oinfo , & rks .owner , & rks .offset , & rks .flags );
2528+ rks .has_rmap = false;
2529+
2530+ low .rm_startblock = bno ;
2531+ memset (& high , 0xFF , sizeof (high ));
2532+ high .rm_startblock = bno + len - 1 ;
2533+
2534+ error = xfs_rmap_query_range (cur , & low , & high ,
2535+ xfs_rmap_has_other_keys_helper , & rks );
2536+ * has_rmap = rks .has_rmap ;
2537+ return error ;
2538+ }
0 commit comments