diff options
author | Eric Sandeen <sandeen@redhat.com> | 2014-08-01 19:12:46 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2015-02-16 12:48:46 -0500 |
commit | 63443bf54a746fada8ef2829148a29f28f07f7af (patch) | |
tree | 8acb761f3375f27731777284f87baf64e95f5a4b /fs/btrfs/disk-io.c | |
parent | 2a4581983f90d829d9aeaa4cb881031950f54937 (diff) |
btrfs: factor btrfs_replay_log() out of open_ctree()
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 93 |
1 files changed, 53 insertions, 40 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 9ecd19d98f89..954f0658dd0e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2303,6 +2303,57 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, | |||
2303 | return 0; | 2303 | return 0; |
2304 | } | 2304 | } |
2305 | 2305 | ||
2306 | static int btrfs_replay_log(struct btrfs_fs_info *fs_info, | ||
2307 | struct btrfs_fs_devices *fs_devices) | ||
2308 | { | ||
2309 | int ret; | ||
2310 | struct btrfs_root *tree_root = fs_info->tree_root; | ||
2311 | struct btrfs_root *log_tree_root; | ||
2312 | struct btrfs_super_block *disk_super = fs_info->super_copy; | ||
2313 | u64 bytenr = btrfs_super_log_root(disk_super); | ||
2314 | |||
2315 | if (fs_devices->rw_devices == 0) { | ||
2316 | printk(KERN_WARNING "BTRFS: log replay required " | ||
2317 | "on RO media\n"); | ||
2318 | return -EIO; | ||
2319 | } | ||
2320 | |||
2321 | log_tree_root = btrfs_alloc_root(fs_info); | ||
2322 | if (!log_tree_root) | ||
2323 | return -ENOMEM; | ||
2324 | |||
2325 | __setup_root(tree_root->nodesize, tree_root->sectorsize, | ||
2326 | tree_root->stripesize, log_tree_root, fs_info, | ||
2327 | BTRFS_TREE_LOG_OBJECTID); | ||
2328 | |||
2329 | log_tree_root->node = read_tree_block(tree_root, bytenr, | ||
2330 | fs_info->generation + 1); | ||
2331 | if (!log_tree_root->node || | ||
2332 | !extent_buffer_uptodate(log_tree_root->node)) { | ||
2333 | printk(KERN_ERR "BTRFS: failed to read log tree\n"); | ||
2334 | free_extent_buffer(log_tree_root->node); | ||
2335 | kfree(log_tree_root); | ||
2336 | return -EIO; | ||
2337 | } | ||
2338 | /* returns with log_tree_root freed on success */ | ||
2339 | ret = btrfs_recover_log_trees(log_tree_root); | ||
2340 | if (ret) { | ||
2341 | btrfs_error(tree_root->fs_info, ret, | ||
2342 | "Failed to recover log tree"); | ||
2343 | free_extent_buffer(log_tree_root->node); | ||
2344 | kfree(log_tree_root); | ||
2345 | return ret; | ||
2346 | } | ||
2347 | |||
2348 | if (fs_info->sb->s_flags & MS_RDONLY) { | ||
2349 | ret = btrfs_commit_super(tree_root); | ||
2350 | if (ret) | ||
2351 | return ret; | ||
2352 | } | ||
2353 | |||
2354 | return 0; | ||
2355 | } | ||
2356 | |||
2306 | int open_ctree(struct super_block *sb, | 2357 | int open_ctree(struct super_block *sb, |
2307 | struct btrfs_fs_devices *fs_devices, | 2358 | struct btrfs_fs_devices *fs_devices, |
2308 | char *options) | 2359 | char *options) |
@@ -2323,7 +2374,6 @@ int open_ctree(struct super_block *sb, | |||
2323 | struct btrfs_root *dev_root; | 2374 | struct btrfs_root *dev_root; |
2324 | struct btrfs_root *quota_root; | 2375 | struct btrfs_root *quota_root; |
2325 | struct btrfs_root *uuid_root; | 2376 | struct btrfs_root *uuid_root; |
2326 | struct btrfs_root *log_tree_root; | ||
2327 | int ret; | 2377 | int ret; |
2328 | int err = -EINVAL; | 2378 | int err = -EINVAL; |
2329 | int num_backups_tried = 0; | 2379 | int num_backups_tried = 0; |
@@ -2904,48 +2954,11 @@ retry_root_backup: | |||
2904 | 2954 | ||
2905 | /* do not make disk changes in broken FS */ | 2955 | /* do not make disk changes in broken FS */ |
2906 | if (btrfs_super_log_root(disk_super) != 0) { | 2956 | if (btrfs_super_log_root(disk_super) != 0) { |
2907 | u64 bytenr = btrfs_super_log_root(disk_super); | 2957 | ret = btrfs_replay_log(fs_info, fs_devices); |
2908 | |||
2909 | if (fs_devices->rw_devices == 0) { | ||
2910 | printk(KERN_WARNING "BTRFS: log replay required " | ||
2911 | "on RO media\n"); | ||
2912 | err = -EIO; | ||
2913 | goto fail_qgroup; | ||
2914 | } | ||
2915 | |||
2916 | log_tree_root = btrfs_alloc_root(fs_info); | ||
2917 | if (!log_tree_root) { | ||
2918 | err = -ENOMEM; | ||
2919 | goto fail_qgroup; | ||
2920 | } | ||
2921 | |||
2922 | __setup_root(nodesize, sectorsize, stripesize, | ||
2923 | log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID); | ||
2924 | |||
2925 | log_tree_root->node = read_tree_block(tree_root, bytenr, | ||
2926 | generation + 1); | ||
2927 | if (!log_tree_root->node || | ||
2928 | !extent_buffer_uptodate(log_tree_root->node)) { | ||
2929 | printk(KERN_ERR "BTRFS: failed to read log tree\n"); | ||
2930 | free_extent_buffer(log_tree_root->node); | ||
2931 | kfree(log_tree_root); | ||
2932 | goto fail_qgroup; | ||
2933 | } | ||
2934 | /* returns with log_tree_root freed on success */ | ||
2935 | ret = btrfs_recover_log_trees(log_tree_root); | ||
2936 | if (ret) { | 2958 | if (ret) { |
2937 | btrfs_error(tree_root->fs_info, ret, | 2959 | err = ret; |
2938 | "Failed to recover log tree"); | ||
2939 | free_extent_buffer(log_tree_root->node); | ||
2940 | kfree(log_tree_root); | ||
2941 | goto fail_qgroup; | 2960 | goto fail_qgroup; |
2942 | } | 2961 | } |
2943 | |||
2944 | if (sb->s_flags & MS_RDONLY) { | ||
2945 | ret = btrfs_commit_super(tree_root); | ||
2946 | if (ret) | ||
2947 | goto fail_qgroup; | ||
2948 | } | ||
2949 | } | 2962 | } |
2950 | 2963 | ||
2951 | ret = btrfs_find_orphan_roots(tree_root); | 2964 | ret = btrfs_find_orphan_roots(tree_root); |