if (last_ref && btrfs_header_generation(buf) == trans->transid) {
struct btrfs_block_group *cache;
+ bool have_mod_log_users;\r
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
ret = check_ref_cleanup(trans, buf->start);
goto out;
}
- if (btrfs_is_zoned(fs_info)) {
+ /*\r
+ * If there are tree mod log users, we may have recorded mog log\r
+ * operations on this extent buffer, so we can not add back this\r
+ * extent buffer to the free space cache/tree, because if it gets\r
+ * allocated and changed while there are mod log users, replaying\r
+ * the mod log operations will result in all sorts of unexpected\r
+ * results.\r
+ */\r
+ read_lock(&fs_info->tree_mod_log_lock);\r
+ have_mod_log_users = !list_empty(&fs_info->tree_mod_seq_list);\r
+ read_unlock(&fs_info->tree_mod_log_lock);\r
+\r
+ if (have_mod_log_users || btrfs_is_zoned(fs_info)) {\r
btrfs_redirty_list_add(trans->transaction, buf);
pin_down_extent(trans, cache, buf->start, buf->len, 1);
btrfs_put_block_group(cache);