aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2012-06-05 10:41:24 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2012-06-14 12:44:22 -0400
commita95236d99fa56766f11056903439f55fe5038bcf (patch)
tree90a9ea2656772900ac411cf43333ec25ed712363 /fs/btrfs
parent8ba97a15e7d4f70b9af71fa1db86a28dd17ad1b2 (diff)
Btrfs: fix return value for __tree_mod_log_oldest_root
In __tree_mod_log_oldest_root() we must return the found operation even if it's not a ROOT_REPLACE operation. Otherwise, the caller assumes that there are no operations to be rewinded and returns immediately. The code in the caller is modified to improve readability. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 2cde7b0a010..50d7c99ddce 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1023,6 +1023,10 @@ __tree_mod_log_oldest_root(struct btrfs_fs_info *fs_info,
1023 looped = 1; 1023 looped = 1;
1024 } 1024 }
1025 1025
1026 /* if there's no old root to return, return what we found instead */
1027 if (!found)
1028 found = tm;
1029
1026 return found; 1030 return found;
1027} 1031}
1028 1032
@@ -1155,18 +1159,24 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
1155{ 1159{
1156 struct tree_mod_elem *tm; 1160 struct tree_mod_elem *tm;
1157 struct extent_buffer *eb; 1161 struct extent_buffer *eb;
1158 struct tree_mod_root *old_root; 1162 struct tree_mod_root *old_root = NULL;
1159 u64 old_generation; 1163 u64 old_generation;
1164 u64 logical;
1160 1165
1161 eb = btrfs_read_lock_root_node(root); 1166 eb = btrfs_read_lock_root_node(root);
1162 tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq); 1167 tm = __tree_mod_log_oldest_root(root->fs_info, root, time_seq);
1163 if (!tm) 1168 if (!tm)
1164 return root->node; 1169 return root->node;
1165 1170
1166 old_root = &tm->old_root; 1171 if (tm->op == MOD_LOG_ROOT_REPLACE) {
1167 old_generation = tm->generation; 1172 old_root = &tm->old_root;
1173 old_generation = tm->generation;
1174 logical = old_root->logical;
1175 } else {
1176 logical = root->node->start;
1177 }
1168 1178
1169 tm = tree_mod_log_search(root->fs_info, old_root->logical, time_seq); 1179 tm = tree_mod_log_search(root->fs_info, logical, time_seq);
1170 /* 1180 /*
1171 * there was an item in the log when __tree_mod_log_oldest_root 1181 * there was an item in the log when __tree_mod_log_oldest_root
1172 * returned. this one must not go away, because the time_seq passed to 1182 * returned. this one must not go away, because the time_seq passed to
@@ -1174,26 +1184,23 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
1174 */ 1184 */
1175 BUG_ON(!tm); 1185 BUG_ON(!tm);
1176 1186
1177 if (old_root->logical == root->node->start) { 1187 if (old_root)
1178 /* there are logged operations for the current root */
1179 eb = btrfs_clone_extent_buffer(root->node);
1180 } else {
1181 /* there's a root replace operation for the current root */
1182 eb = alloc_dummy_extent_buffer(tm->index << PAGE_CACHE_SHIFT, 1188 eb = alloc_dummy_extent_buffer(tm->index << PAGE_CACHE_SHIFT,
1183 root->nodesize); 1189 root->nodesize);
1184 } 1190 else
1191 eb = btrfs_clone_extent_buffer(root->node);
1185 btrfs_tree_read_unlock(root->node); 1192 btrfs_tree_read_unlock(root->node);
1186 free_extent_buffer(root->node); 1193 free_extent_buffer(root->node);
1187 if (!eb) 1194 if (!eb)
1188 return NULL; 1195 return NULL;
1189 btrfs_tree_read_lock(eb); 1196 btrfs_tree_read_lock(eb);
1190 if (old_root->logical != root->node->start) { 1197 if (old_root) {
1191 btrfs_set_header_bytenr(eb, eb->start); 1198 btrfs_set_header_bytenr(eb, eb->start);
1192 btrfs_set_header_backref_rev(eb, BTRFS_MIXED_BACKREF_REV); 1199 btrfs_set_header_backref_rev(eb, BTRFS_MIXED_BACKREF_REV);
1193 btrfs_set_header_owner(eb, root->root_key.objectid); 1200 btrfs_set_header_owner(eb, root->root_key.objectid);
1201 btrfs_set_header_level(eb, old_root->level);
1202 btrfs_set_header_generation(eb, old_generation);
1194 } 1203 }
1195 btrfs_set_header_level(eb, old_root->level);
1196 btrfs_set_header_generation(eb, old_generation);
1197 __tree_mod_log_rewind(eb, time_seq, tm); 1204 __tree_mod_log_rewind(eb, time_seq, tm);
1198 extent_buffer_get(eb); 1205 extent_buffer_get(eb);
1199 1206