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.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 0e1c31e682fb..2fe31c3508c1 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -153,13 +153,24 @@ static int __commit_transaction(struct ctree_root *root)
153 return ret; 153 return ret;
154} 154}
155 155
156int commit_transaction(struct ctree_root *root) 156int commit_transaction(struct ctree_root *root, struct ctree_super_block *s)
157{ 157{
158 int ret; 158 int ret = 0;
159
159 ret = __commit_transaction(root); 160 ret = __commit_transaction(root);
160 if (!ret && root != root->extent_root) 161 if (!ret && root != root->extent_root)
161 ret = __commit_transaction(root->extent_root); 162 ret = __commit_transaction(root->extent_root);
162 BUG_ON(ret); 163 BUG_ON(ret);
164 if (root->commit_root != root->node) {
165 struct tree_buffer *snap = root->commit_root;
166 root->commit_root = root->node;
167 root->node->count++;
168 ret = btrfs_drop_snapshot(root, snap);
169 BUG_ON(ret);
170 tree_block_release(root, snap);
171 }
172 write_ctree_super(root, s);
173 btrfs_finish_extent_commit(root);
163 return ret; 174 return ret;
164} 175}
165 176
@@ -168,10 +179,13 @@ static int __setup_root(struct ctree_root *root, struct ctree_root *extent_root,
168{ 179{
169 INIT_LIST_HEAD(&root->trans); 180 INIT_LIST_HEAD(&root->trans);
170 INIT_LIST_HEAD(&root->cache); 181 INIT_LIST_HEAD(&root->cache);
182 root->cache_size = 0;
171 root->fp = fp; 183 root->fp = fp;
172 root->node = NULL; 184 root->node = NULL;
173 root->node = read_tree_block(root, info->tree_root);
174 root->extent_root = extent_root; 185 root->extent_root = extent_root;
186 root->commit_root = NULL;
187 root->node = read_tree_block(root, info->tree_root);
188 memset(&root->current_insert, 0, sizeof(root->current_insert));
175 return 0; 189 return 0;
176} 190}
177 191
@@ -188,6 +202,8 @@ struct ctree_root *open_ctree(char *filename, struct ctree_super_block *super)
188 return NULL; 202 return NULL;
189 } 203 }
190 INIT_RADIX_TREE(&root->cache_radix, GFP_KERNEL); 204 INIT_RADIX_TREE(&root->cache_radix, GFP_KERNEL);
205 INIT_RADIX_TREE(&root->pinned_radix, GFP_KERNEL);
206 INIT_RADIX_TREE(&extent_root->pinned_radix, GFP_KERNEL);
191 INIT_RADIX_TREE(&extent_root->cache_radix, GFP_KERNEL); 207 INIT_RADIX_TREE(&extent_root->cache_radix, GFP_KERNEL);
192 ret = pread(fp, super, sizeof(struct ctree_super_block), 208 ret = pread(fp, super, sizeof(struct ctree_super_block),
193 CTREE_SUPER_INFO_OFFSET(CTREE_BLOCKSIZE)); 209 CTREE_SUPER_INFO_OFFSET(CTREE_BLOCKSIZE));
@@ -204,6 +220,8 @@ struct ctree_root *open_ctree(char *filename, struct ctree_super_block *super)
204 BUG_ON(ret < 0); 220 BUG_ON(ret < 0);
205 __setup_root(root, extent_root, &super->root_info, fp); 221 __setup_root(root, extent_root, &super->root_info, fp);
206 __setup_root(extent_root, extent_root, &super->extent_info, fp); 222 __setup_root(extent_root, extent_root, &super->extent_info, fp);
223 root->commit_root = root->node;
224 root->node->count++;
207 return root; 225 return root;
208} 226}
209 227
@@ -236,9 +254,11 @@ static int drop_cache(struct ctree_root *root)
236 } 254 }
237 return 0; 255 return 0;
238} 256}
239int close_ctree(struct ctree_root *root) 257int close_ctree(struct ctree_root *root, struct ctree_super_block *s)
240{ 258{
241 commit_transaction(root); 259 commit_transaction(root, s);
260 __commit_transaction(root->extent_root);
261 write_ctree_super(root, s);
242 drop_cache(root->extent_root); 262 drop_cache(root->extent_root);
243 drop_cache(root); 263 drop_cache(root);
244 BUG_ON(!list_empty(&root->trans)); 264 BUG_ON(!list_empty(&root->trans));
@@ -249,6 +269,7 @@ int close_ctree(struct ctree_root *root)
249 tree_block_release(root, root->node); 269 tree_block_release(root, root->node);
250 if (root->extent_root->node) 270 if (root->extent_root->node)
251 tree_block_release(root->extent_root, root->extent_root->node); 271 tree_block_release(root->extent_root, root->extent_root->node);
272 tree_block_release(root, root->commit_root);
252 free(root); 273 free(root);
253 printf("on close %d blocks are allocated\n", allocated_blocks); 274 printf("on close %d blocks are allocated\n", allocated_blocks);
254 return 0; 275 return 0;