aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e3af2c035687..2818f1c57170 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -49,6 +49,7 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
49 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); 49 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item);
50 refs = btrfs_extent_refs(item); 50 refs = btrfs_extent_refs(item);
51 btrfs_set_extent_refs(item, refs + 1); 51 btrfs_set_extent_refs(item, refs + 1);
52 mark_buffer_dirty(path.nodes[0]);
52 53
53 btrfs_release_path(root->fs_info->extent_root, &path); 54 btrfs_release_path(root->fs_info->extent_root, &path);
54 finish_current_insert(trans, root->fs_info->extent_root); 55 finish_current_insert(trans, root->fs_info->extent_root);
@@ -103,7 +104,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
103int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct 104int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
104 btrfs_root *root) 105 btrfs_root *root)
105{ 106{
106 unsigned long gang[8]; 107 struct buffer_head *gang[8];
107 u64 first = 0; 108 u64 first = 0;
108 int ret; 109 int ret;
109 int i; 110 int i;
@@ -116,13 +117,15 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
116 if (!ret) 117 if (!ret)
117 break; 118 break;
118 if (!first) 119 if (!first)
119 first = gang[0]; 120 first = gang[0]->b_blocknr;
120 for (i = 0; i < ret; i++) { 121 for (i = 0; i < ret; i++) {
121 radix_tree_delete(&root->fs_info->pinned_radix, 122 radix_tree_delete(&root->fs_info->pinned_radix,
122 gang[i]); 123 gang[i]->b_blocknr);
124 brelse(gang[i]);
123 } 125 }
124 } 126 }
125 root->fs_info->last_insert.objectid = first; 127 if (root->fs_info->last_insert.objectid > first)
128 root->fs_info->last_insert.objectid = first;
126 root->fs_info->last_insert.offset = 0; 129 root->fs_info->last_insert.offset = 0;
127 return 0; 130 return 0;
128} 131}
@@ -161,8 +164,10 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
161static int pin_down_block(struct btrfs_root *root, u64 blocknr, int tag) 164static int pin_down_block(struct btrfs_root *root, u64 blocknr, int tag)
162{ 165{
163 int err; 166 int err;
167 struct buffer_head *bh = sb_getblk(root->fs_info->sb, blocknr);
168 BUG_ON(!bh);
164 err = radix_tree_insert(&root->fs_info->pinned_radix, 169 err = radix_tree_insert(&root->fs_info->pinned_radix,
165 blocknr, (void *)blocknr); 170 blocknr, bh);
166 BUG_ON(err); 171 BUG_ON(err);
167 if (err) 172 if (err)
168 return err; 173 return err;
@@ -217,6 +222,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
217 if (ret) 222 if (ret)
218 BUG(); 223 BUG();
219 } 224 }
225 mark_buffer_dirty(path.nodes[0]);
220 btrfs_release_path(extent_root, &path); 226 btrfs_release_path(extent_root, &path);
221 finish_current_insert(trans, extent_root); 227 finish_current_insert(trans, extent_root);
222 return ret; 228 return ret;
@@ -232,7 +238,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
232 int ret; 238 int ret;
233 int wret; 239 int wret;
234 int err = 0; 240 int err = 0;
235 unsigned long gang[4]; 241 struct buffer_head *gang[4];
236 int i; 242 int i;
237 struct radix_tree_root *radix = &extent_root->fs_info->pinned_radix; 243 struct radix_tree_root *radix = &extent_root->fs_info->pinned_radix;
238 244
@@ -245,10 +251,12 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
245 if (!ret) 251 if (!ret)
246 break; 252 break;
247 for (i = 0; i < ret; i++) { 253 for (i = 0; i < ret; i++) {
248 radix_tree_tag_set(radix, gang[i], CTREE_EXTENT_PINNED); 254 radix_tree_tag_set(radix, gang[i]->b_blocknr,
249 radix_tree_tag_clear(radix, gang[i], 255 CTREE_EXTENT_PINNED);
256 radix_tree_tag_clear(radix, gang[i]->b_blocknr,
250 CTREE_EXTENT_PENDING_DEL); 257 CTREE_EXTENT_PENDING_DEL);
251 wret = __free_extent(trans, extent_root, gang[i], 1); 258 wret = __free_extent(trans, extent_root,
259 gang[i]->b_blocknr, 1);
252 if (wret) 260 if (wret)
253 err = wret; 261 err = wret;
254 } 262 }