static int __commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) { u64 start; u64 end; struct extent_buffer *eb; struct extent_io_tree *tree = &root->fs_info->extent_cache; int ret; while(1) { ret = find_first_extent_bit(tree, 0, &start, &end, EXTENT_DIRTY); if (ret) break; while(start <= end) { eb = find_first_extent_buffer(tree, start); BUG_ON(!eb || eb->start != start); ret = write_tree_block(trans, root, eb); BUG_ON(ret); start += eb->len; clear_extent_buffer_dirty(eb); free_extent_buffer(eb); } } return 0; }
static int change_header_uuid(struct btrfs_root *root, struct extent_buffer *eb) { struct btrfs_fs_info *fs_info = root->fs_info; int same_fsid = 1; int same_chunk_tree_uuid = 1; int ret; same_fsid = !memcmp_extent_buffer(eb, fs_info->new_fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); same_chunk_tree_uuid = !memcmp_extent_buffer(eb, fs_info->new_chunk_tree_uuid, btrfs_header_chunk_tree_uuid(eb), BTRFS_UUID_SIZE); if (same_fsid && same_chunk_tree_uuid) return 0; if (!same_fsid) write_extent_buffer(eb, fs_info->new_fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); if (!same_chunk_tree_uuid) write_extent_buffer(eb, fs_info->new_chunk_tree_uuid, btrfs_header_chunk_tree_uuid(eb), BTRFS_UUID_SIZE); ret = write_tree_block(NULL, root, eb); return ret; }
static int change_fsid_prepare(struct btrfs_fs_info *fs_info) { struct btrfs_root *tree_root = fs_info->tree_root; u64 flags = btrfs_super_flags(fs_info->super_copy); int ret = 0; flags |= BTRFS_SUPER_FLAG_CHANGING_FSID; btrfs_set_super_flags(fs_info->super_copy, flags); memcpy(fs_info->super_copy->fsid, fs_info->new_fsid, BTRFS_FSID_SIZE); ret = write_all_supers(tree_root); if (ret < 0) return ret; /* also restore new chunk_tree_id into tree_root for restore */ write_extent_buffer(tree_root->node, fs_info->new_chunk_tree_uuid, btrfs_header_chunk_tree_uuid(tree_root->node), BTRFS_UUID_SIZE); return write_tree_block(NULL, tree_root, tree_root->node); }
static int change_device_uuid(struct btrfs_root *root, struct extent_buffer *eb, int slot) { struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_dev_item *di; int ret = 0; di = btrfs_item_ptr(eb, slot, struct btrfs_dev_item); if (!memcmp_extent_buffer(eb, fs_info->new_fsid, (unsigned long)btrfs_device_fsid(di), BTRFS_FSID_SIZE)) return ret; write_extent_buffer(eb, fs_info->new_fsid, (unsigned long)btrfs_device_fsid(di), BTRFS_FSID_SIZE); ret = write_tree_block(NULL, root, eb); return ret; }