aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index ef8809c1e69c..70b6ddfe15a1 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -70,6 +70,14 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
70 memset(p, 0, sizeof(*p)); 70 memset(p, 0, sizeof(*p));
71} 71}
72 72
73static void add_root_to_dirty_list(struct btrfs_root *root)
74{
75 if (root->track_dirty && list_empty(&root->dirty_list)) {
76 list_add(&root->dirty_list,
77 &root->fs_info->dirty_cowonly_roots);
78 }
79}
80
73int btrfs_copy_root(struct btrfs_trans_handle *trans, 81int btrfs_copy_root(struct btrfs_trans_handle *trans,
74 struct btrfs_root *root, 82 struct btrfs_root *root,
75 struct extent_buffer *buf, 83 struct extent_buffer *buf,
@@ -196,6 +204,7 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans,
196 root_gen, 0, 0, 1); 204 root_gen, 0, 0, 1);
197 } 205 }
198 free_extent_buffer(buf); 206 free_extent_buffer(buf);
207 add_root_to_dirty_list(root);
199 } else { 208 } else {
200 root_gen = btrfs_header_generation(parent); 209 root_gen = btrfs_header_generation(parent);
201 btrfs_set_node_blockptr(parent, parent_slot, 210 btrfs_set_node_blockptr(parent, parent_slot,
@@ -241,7 +250,7 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
241 return 0; 250 return 0;
242 } 251 }
243 252
244 search_start = buf->start & ~((u64)BTRFS_BLOCK_GROUP_SIZE - 1); 253 search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1);
245 ret = __btrfs_cow_block(trans, root, buf, parent, 254 ret = __btrfs_cow_block(trans, root, buf, parent,
246 parent_slot, cow_ret, search_start, 0); 255 parent_slot, cow_ret, search_start, 0);
247 return ret; 256 return ret;
@@ -724,6 +733,7 @@ static int balance_level(struct btrfs_trans_handle *trans,
724 BUG_ON(ret); 733 BUG_ON(ret);
725 734
726 root->node = child; 735 root->node = child;
736 add_root_to_dirty_list(root);
727 path->nodes[level] = NULL; 737 path->nodes[level] = NULL;
728 clean_tree_block(trans, root, mid); 738 clean_tree_block(trans, root, mid);
729 wait_on_tree_block_writeback(root, mid); 739 wait_on_tree_block_writeback(root, mid);
@@ -1369,6 +1379,7 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans,
1369 /* the super has an extra ref to root->node */ 1379 /* the super has an extra ref to root->node */
1370 free_extent_buffer(root->node); 1380 free_extent_buffer(root->node);
1371 root->node = c; 1381 root->node = c;
1382 add_root_to_dirty_list(root);
1372 extent_buffer_get(c); 1383 extent_buffer_get(c);
1373 path->nodes[level] = c; 1384 path->nodes[level] = c;
1374 path->slots[level] = 0; 1385 path->slots[level] = 0;
@@ -2777,3 +2788,28 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
2777 } 2788 }
2778 return 0; 2789 return 0;
2779} 2790}
2791
2792int btrfs_previous_item(struct btrfs_root *root,
2793 struct btrfs_path *path, u64 min_objectid,
2794 int type)
2795{
2796 struct btrfs_key found_key;
2797 struct extent_buffer *leaf;
2798 int ret;
2799
2800 while(1) {
2801 if (path->slots[0] == 0) {
2802 ret = btrfs_prev_leaf(root, path);
2803 if (ret != 0)
2804 return ret;
2805 } else {
2806 path->slots[0]--;
2807 }
2808 leaf = path->nodes[0];
2809 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
2810 if (found_key.type == type)
2811 return 0;
2812 }
2813 return 1;
2814}
2815