summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@redhat.com>2014-08-01 19:12:46 -0400
committerDavid Sterba <dsterba@suse.cz>2015-02-16 12:48:46 -0500
commit63443bf54a746fada8ef2829148a29f28f07f7af (patch)
tree8acb761f3375f27731777284f87baf64e95f5a4b /fs/btrfs/disk-io.c
parent2a4581983f90d829d9aeaa4cb881031950f54937 (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.c93
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
2306static 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
2306int open_ctree(struct super_block *sb, 2357int 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);