aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 8d9457b5aef5..25ce07908ee3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -9,6 +9,7 @@
9#include "radix-tree.h" 9#include "radix-tree.h"
10#include "ctree.h" 10#include "ctree.h"
11#include "disk-io.h" 11#include "disk-io.h"
12#include "transaction.h"
12 13
13static int allocated_blocks = 0; 14static int allocated_blocks = 0;
14int cache_max = 10000; 15int cache_max = 10000;
@@ -107,7 +108,8 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
107 return buf; 108 return buf;
108} 109}
109 110
110int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) 111int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
112 struct btrfs_buffer *buf)
111{ 113{
112 if (!list_empty(&buf->dirty)) 114 if (!list_empty(&buf->dirty))
113 return 0; 115 return 0;
@@ -116,7 +118,8 @@ int dirty_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
116 return 0; 118 return 0;
117} 119}
118 120
119int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) 121int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
122 struct btrfs_buffer *buf)
120{ 123{
121 if (!list_empty(&buf->dirty)) { 124 if (!list_empty(&buf->dirty)) {
122 list_del_init(&buf->dirty); 125 list_del_init(&buf->dirty);
@@ -125,7 +128,8 @@ int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
125 return 0; 128 return 0;
126} 129}
127 130
128int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) 131int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
132 struct btrfs_buffer *buf)
129{ 133{
130 u64 blocknr = buf->blocknr; 134 u64 blocknr = buf->blocknr;
131 loff_t offset = blocknr * root->blocksize; 135 loff_t offset = blocknr * root->blocksize;
@@ -139,7 +143,8 @@ int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
139 return 0; 143 return 0;
140} 144}
141 145
142static int __commit_transaction(struct btrfs_root *root) 146static int __commit_transaction(struct btrfs_trans_handle *trans, struct
147 btrfs_root *root)
143{ 148{
144 struct btrfs_buffer *b; 149 struct btrfs_buffer *b;
145 int ret = 0; 150 int ret = 0;
@@ -147,7 +152,7 @@ static int __commit_transaction(struct btrfs_root *root)
147 while(!list_empty(&root->trans)) { 152 while(!list_empty(&root->trans)) {
148 b = list_entry(root->trans.next, struct btrfs_buffer, dirty); 153 b = list_entry(root->trans.next, struct btrfs_buffer, dirty);
149 list_del_init(&b->dirty); 154 list_del_init(&b->dirty);
150 wret = write_tree_block(root, b); 155 wret = write_tree_block(trans, root, b);
151 if (wret) 156 if (wret)
152 ret = wret; 157 ret = wret;
153 btrfs_block_release(root, b); 158 btrfs_block_release(root, b);
@@ -155,8 +160,9 @@ static int __commit_transaction(struct btrfs_root *root)
155 return ret; 160 return ret;
156} 161}
157 162
158static int commit_extent_and_tree_roots(struct btrfs_root *tree_root, 163static int commit_extent_and_tree_roots(struct btrfs_trans_handle *trans,
159 struct btrfs_root *extent_root) 164 struct btrfs_root *tree_root, struct
165 btrfs_root *extent_root)
160{ 166{
161 int ret; 167 int ret;
162 u64 old_extent_block; 168 u64 old_extent_block;
@@ -167,24 +173,24 @@ static int commit_extent_and_tree_roots(struct btrfs_root *tree_root,
167 break; 173 break;
168 btrfs_set_root_blocknr(&extent_root->root_item, 174 btrfs_set_root_blocknr(&extent_root->root_item,
169 extent_root->node->blocknr); 175 extent_root->node->blocknr);
170 ret = btrfs_update_root(tree_root, 176 ret = btrfs_update_root(trans, tree_root,
171 &extent_root->root_key, 177 &extent_root->root_key,
172 &extent_root->root_item); 178 &extent_root->root_item);
173 BUG_ON(ret); 179 BUG_ON(ret);
174 } 180 }
175 __commit_transaction(extent_root); 181 __commit_transaction(trans, extent_root);
176 __commit_transaction(tree_root); 182 __commit_transaction(trans, tree_root);
177 return 0; 183 return 0;
178} 184}
179 185
180int btrfs_commit_transaction(struct btrfs_root *root, 186int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
181 struct btrfs_super_block *s) 187 btrfs_root *root, struct btrfs_super_block *s)
182{ 188{
183 int ret = 0; 189 int ret = 0;
184 struct btrfs_buffer *snap = root->commit_root; 190 struct btrfs_buffer *snap = root->commit_root;
185 struct btrfs_key snap_key; 191 struct btrfs_key snap_key;
186 192
187 ret = __commit_transaction(root); 193 ret = __commit_transaction(trans, root);
188 BUG_ON(ret); 194 BUG_ON(ret);
189 195
190 if (root->commit_root == root->node) 196 if (root->commit_root == root->node)
@@ -194,23 +200,24 @@ int btrfs_commit_transaction(struct btrfs_root *root,
194 root->root_key.offset++; 200 root->root_key.offset++;
195 201
196 btrfs_set_root_blocknr(&root->root_item, root->node->blocknr); 202 btrfs_set_root_blocknr(&root->root_item, root->node->blocknr);
197 ret = btrfs_insert_root(root->tree_root, &root->root_key, 203 ret = btrfs_insert_root(trans, root->tree_root, &root->root_key,
198 &root->root_item); 204 &root->root_item);
199 BUG_ON(ret); 205 BUG_ON(ret);
200 206
201 ret = commit_extent_and_tree_roots(root->tree_root, root->extent_root); 207 ret = commit_extent_and_tree_roots(trans, root->tree_root,
208 root->extent_root);
202 BUG_ON(ret); 209 BUG_ON(ret);
203 210
204 write_ctree_super(root, s); 211 write_ctree_super(trans, root, s);
205 btrfs_finish_extent_commit(root->extent_root); 212 btrfs_finish_extent_commit(trans, root->extent_root);
206 btrfs_finish_extent_commit(root->tree_root); 213 btrfs_finish_extent_commit(trans, root->tree_root);
207 214
208 root->commit_root = root->node; 215 root->commit_root = root->node;
209 root->node->count++; 216 root->node->count++;
210 ret = btrfs_drop_snapshot(root, snap); 217 ret = btrfs_drop_snapshot(trans, root, snap);
211 BUG_ON(ret); 218 BUG_ON(ret);
212 219
213 ret = btrfs_del_root(root->tree_root, &snap_key); 220 ret = btrfs_del_root(trans, root->tree_root, &snap_key);
214 BUG_ON(ret); 221 BUG_ON(ret);
215 222
216 return ret; 223 return ret;
@@ -312,7 +319,8 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
312 return root; 319 return root;
313} 320}
314 321
315int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s) 322int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
323 *root, struct btrfs_super_block *s)
316{ 324{
317 int ret; 325 int ret;
318 btrfs_set_super_root(s, root->tree_root->node->blocknr); 326 btrfs_set_super_root(s, root->tree_root->node->blocknr);
@@ -338,10 +346,14 @@ static int drop_cache(struct btrfs_root *root)
338int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s) 346int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s)
339{ 347{
340 int ret; 348 int ret;
341 btrfs_commit_transaction(root, s); 349 struct btrfs_trans_handle *trans;
342 ret = commit_extent_and_tree_roots(root->tree_root, root->extent_root); 350
351 trans = root->running_transaction;
352 btrfs_commit_transaction(trans, root, s);
353 ret = commit_extent_and_tree_roots(trans, root->tree_root,
354 root->extent_root);
343 BUG_ON(ret); 355 BUG_ON(ret);
344 write_ctree_super(root, s); 356 write_ctree_super(trans, root, s);
345 drop_cache(root->extent_root); 357 drop_cache(root->extent_root);
346 drop_cache(root->tree_root); 358 drop_cache(root->tree_root);
347 drop_cache(root); 359 drop_cache(root);