@@ -138,6 +138,7 @@ struct share_check {
138138 u64 root_objectid ;
139139 u64 inum ;
140140 int share_count ;
141+ bool have_delayed_delete_refs ;
141142};
142143
143144static inline int extent_is_shared (struct share_check * sc )
@@ -820,16 +821,11 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
820821 struct preftrees * preftrees , struct share_check * sc )
821822{
822823 struct btrfs_delayed_ref_node * node ;
823- struct btrfs_delayed_extent_op * extent_op = head -> extent_op ;
824824 struct btrfs_key key ;
825- struct btrfs_key tmp_op_key ;
826825 struct rb_node * n ;
827826 int count ;
828827 int ret = 0 ;
829828
830- if (extent_op && extent_op -> update_key )
831- btrfs_disk_key_to_cpu (& tmp_op_key , & extent_op -> key );
832-
833829 spin_lock (& head -> lock );
834830 for (n = rb_first_cached (& head -> ref_tree ); n ; n = rb_next (n )) {
835831 node = rb_entry (n , struct btrfs_delayed_ref_node ,
@@ -855,10 +851,16 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
855851 case BTRFS_TREE_BLOCK_REF_KEY : {
856852 /* NORMAL INDIRECT METADATA backref */
857853 struct btrfs_delayed_tree_ref * ref ;
854+ struct btrfs_key * key_ptr = NULL ;
855+
856+ if (head -> extent_op && head -> extent_op -> update_key ) {
857+ btrfs_disk_key_to_cpu (& key , & head -> extent_op -> key );
858+ key_ptr = & key ;
859+ }
858860
859861 ref = btrfs_delayed_node_to_tree_ref (node );
860862 ret = add_indirect_ref (fs_info , preftrees , ref -> root ,
861- & tmp_op_key , ref -> level + 1 ,
863+ key_ptr , ref -> level + 1 ,
862864 node -> bytenr , count , sc ,
863865 GFP_ATOMIC );
864866 break ;
@@ -884,13 +886,22 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
884886 key .offset = ref -> offset ;
885887
886888 /*
887- * Found a inum that doesn't match our known inum, we
888- * know it's shared.
889+ * If we have a share check context and a reference for
890+ * another inode, we can't exit immediately. This is
891+ * because even if this is a BTRFS_ADD_DELAYED_REF
892+ * reference we may find next a BTRFS_DROP_DELAYED_REF
893+ * which cancels out this ADD reference.
894+ *
895+ * If this is a DROP reference and there was no previous
896+ * ADD reference, then we need to signal that when we
897+ * process references from the extent tree (through
898+ * add_inline_refs() and add_keyed_refs()), we should
899+ * not exit early if we find a reference for another
900+ * inode, because one of the delayed DROP references
901+ * may cancel that reference in the extent tree.
889902 */
890- if (sc && sc -> inum && ref -> objectid != sc -> inum ) {
891- ret = BACKREF_FOUND_SHARED ;
892- goto out ;
893- }
903+ if (sc && count < 0 )
904+ sc -> have_delayed_delete_refs = true;
894905
895906 ret = add_indirect_ref (fs_info , preftrees , ref -> root ,
896907 & key , 0 , node -> bytenr , count , sc ,
@@ -920,7 +931,7 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
920931 }
921932 if (!ret )
922933 ret = extent_is_shared (sc );
923- out :
934+
924935 spin_unlock (& head -> lock );
925936 return ret ;
926937}
@@ -1023,7 +1034,8 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info,
10231034 key .type = BTRFS_EXTENT_DATA_KEY ;
10241035 key .offset = btrfs_extent_data_ref_offset (leaf , dref );
10251036
1026- if (sc && sc -> inum && key .objectid != sc -> inum ) {
1037+ if (sc && sc -> inum && key .objectid != sc -> inum &&
1038+ !sc -> have_delayed_delete_refs ) {
10271039 ret = BACKREF_FOUND_SHARED ;
10281040 break ;
10291041 }
@@ -1033,6 +1045,7 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info,
10331045 ret = add_indirect_ref (fs_info , preftrees , root ,
10341046 & key , 0 , bytenr , count ,
10351047 sc , GFP_NOFS );
1048+
10361049 break ;
10371050 }
10381051 default :
@@ -1122,7 +1135,8 @@ static int add_keyed_refs(struct btrfs_root *extent_root,
11221135 key .type = BTRFS_EXTENT_DATA_KEY ;
11231136 key .offset = btrfs_extent_data_ref_offset (leaf , dref );
11241137
1125- if (sc && sc -> inum && key .objectid != sc -> inum ) {
1138+ if (sc && sc -> inum && key .objectid != sc -> inum &&
1139+ !sc -> have_delayed_delete_refs ) {
11261140 ret = BACKREF_FOUND_SHARED ;
11271141 break ;
11281142 }
@@ -1522,6 +1536,9 @@ static bool lookup_backref_shared_cache(struct btrfs_backref_shared_cache *cache
15221536{
15231537 struct btrfs_backref_shared_cache_entry * entry ;
15241538
1539+ if (!cache -> use_cache )
1540+ return false;
1541+
15251542 if (WARN_ON_ONCE (level >= BTRFS_MAX_LEVEL ))
15261543 return false;
15271544
@@ -1557,6 +1574,19 @@ static bool lookup_backref_shared_cache(struct btrfs_backref_shared_cache *cache
15571574 return false;
15581575
15591576 * is_shared = entry -> is_shared ;
1577+ /*
1578+ * If the node at this level is shared, than all nodes below are also
1579+ * shared. Currently some of the nodes below may be marked as not shared
1580+ * because we have just switched from one leaf to another, and switched
1581+ * also other nodes above the leaf and below the current level, so mark
1582+ * them as shared.
1583+ */
1584+ if (* is_shared ) {
1585+ for (int i = 0 ; i < level ; i ++ ) {
1586+ cache -> entries [i ].is_shared = true;
1587+ cache -> entries [i ].gen = entry -> gen ;
1588+ }
1589+ }
15601590
15611591 return true;
15621592}
@@ -1573,6 +1603,9 @@ static void store_backref_shared_cache(struct btrfs_backref_shared_cache *cache,
15731603 struct btrfs_backref_shared_cache_entry * entry ;
15741604 u64 gen ;
15751605
1606+ if (!cache -> use_cache )
1607+ return ;
1608+
15761609 if (WARN_ON_ONCE (level >= BTRFS_MAX_LEVEL ))
15771610 return ;
15781611
@@ -1648,6 +1681,7 @@ int btrfs_is_data_extent_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
16481681 .root_objectid = root -> root_key .objectid ,
16491682 .inum = inum ,
16501683 .share_count = 0 ,
1684+ .have_delayed_delete_refs = false,
16511685 };
16521686 int level ;
16531687
@@ -1669,6 +1703,7 @@ int btrfs_is_data_extent_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
16691703 /* -1 means we are in the bytenr of the data extent. */
16701704 level = -1 ;
16711705 ULIST_ITER_INIT (& uiter );
1706+ cache -> use_cache = true;
16721707 while (1 ) {
16731708 bool is_shared ;
16741709 bool cached ;
@@ -1698,6 +1733,24 @@ int btrfs_is_data_extent_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
16981733 extent_gen > btrfs_root_last_snapshot (& root -> root_item ))
16991734 break ;
17001735
1736+ /*
1737+ * If our data extent was not directly shared (without multiple
1738+ * reference items), than it might have a single reference item
1739+ * with a count > 1 for the same offset, which means there are 2
1740+ * (or more) file extent items that point to the data extent -
1741+ * this happens when a file extent item needs to be split and
1742+ * then one item gets moved to another leaf due to a b+tree leaf
1743+ * split when inserting some item. In this case the file extent
1744+ * items may be located in different leaves and therefore some
1745+ * of the leaves may be referenced through shared subtrees while
1746+ * others are not. Since our extent buffer cache only works for
1747+ * a single path (by far the most common case and simpler to
1748+ * deal with), we can not use it if we have multiple leaves
1749+ * (which implies multiple paths).
1750+ */
1751+ if (level == -1 && tmp -> nnodes > 1 )
1752+ cache -> use_cache = false;
1753+
17011754 if (level >= 0 )
17021755 store_backref_shared_cache (cache , root , bytenr ,
17031756 level , false);
@@ -1713,6 +1766,7 @@ int btrfs_is_data_extent_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
17131766 break ;
17141767 }
17151768 shared .share_count = 0 ;
1769+ shared .have_delayed_delete_refs = false;
17161770 cond_resched ();
17171771 }
17181772
0 commit comments