diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 15cbc2bf4ff0..7d1e4fc5fb6a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1024,11 +1024,18 @@ __tree_mod_log_oldest_root(struct btrfs_fs_info *fs_info, | |||
1024 | if (!looped && !tm) | 1024 | if (!looped && !tm) |
1025 | return 0; | 1025 | return 0; |
1026 | /* | 1026 | /* |
1027 | * we must have key remove operations in the log before the | 1027 | * if there are no tree operation for the oldest root, we simply |
1028 | * replace operation. | 1028 | * return it. this should only happen if that (old) root is at |
1029 | * level 0. | ||
1029 | */ | 1030 | */ |
1030 | BUG_ON(!tm); | 1031 | if (!tm) |
1032 | break; | ||
1031 | 1033 | ||
1034 | /* | ||
1035 | * if there's an operation that's not a root replacement, we | ||
1036 | * found the oldest version of our root. normally, we'll find a | ||
1037 | * MOD_LOG_KEY_REMOVE_WHILE_FREEING operation here. | ||
1038 | */ | ||
1032 | if (tm->op != MOD_LOG_ROOT_REPLACE) | 1039 | if (tm->op != MOD_LOG_ROOT_REPLACE) |
1033 | break; | 1040 | break; |
1034 | 1041 | ||
@@ -1192,16 +1199,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1192 | } | 1199 | } |
1193 | 1200 | ||
1194 | tm = tree_mod_log_search(root->fs_info, logical, time_seq); | 1201 | tm = tree_mod_log_search(root->fs_info, logical, time_seq); |
1195 | /* | ||
1196 | * there was an item in the log when __tree_mod_log_oldest_root | ||
1197 | * returned. this one must not go away, because the time_seq passed to | ||
1198 | * us must be blocking its removal. | ||
1199 | */ | ||
1200 | BUG_ON(!tm); | ||
1201 | |||
1202 | if (old_root) | 1202 | if (old_root) |
1203 | eb = alloc_dummy_extent_buffer(tm->index << PAGE_CACHE_SHIFT, | 1203 | eb = alloc_dummy_extent_buffer(logical, root->nodesize); |
1204 | root->nodesize); | ||
1205 | else | 1204 | else |
1206 | eb = btrfs_clone_extent_buffer(root->node); | 1205 | eb = btrfs_clone_extent_buffer(root->node); |
1207 | btrfs_tree_read_unlock(root->node); | 1206 | btrfs_tree_read_unlock(root->node); |
@@ -1216,7 +1215,10 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1216 | btrfs_set_header_level(eb, old_root->level); | 1215 | btrfs_set_header_level(eb, old_root->level); |
1217 | btrfs_set_header_generation(eb, old_generation); | 1216 | btrfs_set_header_generation(eb, old_generation); |
1218 | } | 1217 | } |
1219 | __tree_mod_log_rewind(eb, time_seq, tm); | 1218 | if (tm) |
1219 | __tree_mod_log_rewind(eb, time_seq, tm); | ||
1220 | else | ||
1221 | WARN_ON(btrfs_header_level(eb) != 0); | ||
1220 | extent_buffer_get(eb); | 1222 | extent_buffer_get(eb); |
1221 | 1223 | ||
1222 | return eb; | 1224 | return eb; |