disk-io.c (e089f05c18ab36ed5fa7e2319052e03ab800d518) | disk-io.c (9f5fae2fe6dc35b46bf56183f11398451851cb3f) |
---|---|
1#define _XOPEN_SOURCE 500 2#include <stdio.h> 3#include <stdlib.h> 4#include <sys/types.h> 5#include <sys/stat.h> 6#include <fcntl.h> 7#include <unistd.h> 8#include "kerncompat.h" --- 14 unchanged lines hidden (view full) --- 23 BUG(); 24 return 0; 25} 26 27static int free_some_buffers(struct btrfs_root *root) 28{ 29 struct list_head *node, *next; 30 struct btrfs_buffer *b; | 1#define _XOPEN_SOURCE 500 2#include <stdio.h> 3#include <stdlib.h> 4#include <sys/types.h> 5#include <sys/stat.h> 6#include <fcntl.h> 7#include <unistd.h> 8#include "kerncompat.h" --- 14 unchanged lines hidden (view full) --- 23 BUG(); 24 return 0; 25} 26 27static int free_some_buffers(struct btrfs_root *root) 28{ 29 struct list_head *node, *next; 30 struct btrfs_buffer *b; |
31 if (root->cache_size < cache_max) | 31 if (root->fs_info->cache_size < cache_max) |
32 return 0; | 32 return 0; |
33 list_for_each_safe(node, next, &root->cache) { | 33 list_for_each_safe(node, next, &root->fs_info->cache) { |
34 b = list_entry(node, struct btrfs_buffer, cache); 35 if (b->count == 1) { 36 BUG_ON(!list_empty(&b->dirty)); 37 list_del_init(&b->cache); 38 btrfs_block_release(root, b); | 34 b = list_entry(node, struct btrfs_buffer, cache); 35 if (b->count == 1) { 36 BUG_ON(!list_empty(&b->dirty)); 37 list_del_init(&b->cache); 38 btrfs_block_release(root, b); |
39 if (root->cache_size < cache_max) | 39 if (root->fs_info->cache_size < cache_max) |
40 break; 41 } 42 } 43 return 0; 44} 45 46struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr) 47{ --- 4 unchanged lines hidden (view full) --- 52 if (!buf) 53 return buf; 54 allocated_blocks++; 55 buf->blocknr = blocknr; 56 buf->count = 2; 57 INIT_LIST_HEAD(&buf->dirty); 58 free_some_buffers(root); 59 radix_tree_preload(GFP_KERNEL); | 40 break; 41 } 42 } 43 return 0; 44} 45 46struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr) 47{ --- 4 unchanged lines hidden (view full) --- 52 if (!buf) 53 return buf; 54 allocated_blocks++; 55 buf->blocknr = blocknr; 56 buf->count = 2; 57 INIT_LIST_HEAD(&buf->dirty); 58 free_some_buffers(root); 59 radix_tree_preload(GFP_KERNEL); |
60 ret = radix_tree_insert(&root->cache_radix, blocknr, buf); | 60 ret = radix_tree_insert(&root->fs_info->cache_radix, blocknr, buf); |
61 radix_tree_preload_end(); | 61 radix_tree_preload_end(); |
62 list_add_tail(&buf->cache, &root->cache); 63 root->cache_size++; | 62 list_add_tail(&buf->cache, &root->fs_info->cache); 63 root->fs_info->cache_size++; |
64 if (ret) { 65 free(buf); 66 return NULL; 67 } 68 return buf; 69} 70 71struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr) 72{ 73 struct btrfs_buffer *buf; | 64 if (ret) { 65 free(buf); 66 return NULL; 67 } 68 return buf; 69} 70 71struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr) 72{ 73 struct btrfs_buffer *buf; |
74 buf = radix_tree_lookup(&root->cache_radix, blocknr); | 74 buf = radix_tree_lookup(&root->fs_info->cache_radix, blocknr); |
75 if (buf) { 76 buf->count++; 77 } else { 78 buf = alloc_tree_block(root, blocknr); 79 if (!buf) { 80 BUG(); 81 return NULL; 82 } 83 } 84 return buf; 85} 86 87struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr) 88{ 89 loff_t offset = blocknr * root->blocksize; 90 struct btrfs_buffer *buf; 91 int ret; 92 | 75 if (buf) { 76 buf->count++; 77 } else { 78 buf = alloc_tree_block(root, blocknr); 79 if (!buf) { 80 BUG(); 81 return NULL; 82 } 83 } 84 return buf; 85} 86 87struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr) 88{ 89 loff_t offset = blocknr * root->blocksize; 90 struct btrfs_buffer *buf; 91 int ret; 92 |
93 buf = radix_tree_lookup(&root->cache_radix, blocknr); | 93 buf = radix_tree_lookup(&root->fs_info->cache_radix, blocknr); |
94 if (buf) { 95 buf->count++; 96 } else { 97 buf = alloc_tree_block(root, blocknr); 98 if (!buf) 99 return NULL; | 94 if (buf) { 95 buf->count++; 96 } else { 97 buf = alloc_tree_block(root, blocknr); 98 if (!buf) 99 return NULL; |
100 ret = pread(root->fp, &buf->node, root->blocksize, offset); | 100 ret = pread(root->fs_info->fp, &buf->node, root->blocksize, 101 offset); |
101 if (ret != root->blocksize) { 102 free(buf); 103 return NULL; 104 } 105 } 106 if (check_tree_block(root, buf)) 107 BUG(); 108 return buf; 109} 110 111int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 112 struct btrfs_buffer *buf) 113{ 114 if (!list_empty(&buf->dirty)) 115 return 0; | 102 if (ret != root->blocksize) { 103 free(buf); 104 return NULL; 105 } 106 } 107 if (check_tree_block(root, buf)) 108 BUG(); 109 return buf; 110} 111 112int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 113 struct btrfs_buffer *buf) 114{ 115 if (!list_empty(&buf->dirty)) 116 return 0; |
116 list_add_tail(&buf->dirty, &root->trans); | 117 list_add_tail(&buf->dirty, &root->fs_info->trans); |
117 buf->count++; 118 return 0; 119} 120 121int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 122 struct btrfs_buffer *buf) 123{ 124 if (!list_empty(&buf->dirty)) { --- 7 unchanged lines hidden (view full) --- 132 struct btrfs_buffer *buf) 133{ 134 u64 blocknr = buf->blocknr; 135 loff_t offset = blocknr * root->blocksize; 136 int ret; 137 138 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header)) 139 BUG(); | 118 buf->count++; 119 return 0; 120} 121 122int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 123 struct btrfs_buffer *buf) 124{ 125 if (!list_empty(&buf->dirty)) { --- 7 unchanged lines hidden (view full) --- 133 struct btrfs_buffer *buf) 134{ 135 u64 blocknr = buf->blocknr; 136 loff_t offset = blocknr * root->blocksize; 137 int ret; 138 139 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header)) 140 BUG(); |
140 ret = pwrite(root->fp, &buf->node, root->blocksize, offset); | 141 ret = pwrite(root->fs_info->fp, &buf->node, root->blocksize, offset); |
141 if (ret != root->blocksize) 142 return ret; 143 return 0; 144} 145 146static int __commit_transaction(struct btrfs_trans_handle *trans, struct 147 btrfs_root *root) 148{ 149 struct btrfs_buffer *b; 150 int ret = 0; 151 int wret; | 142 if (ret != root->blocksize) 143 return ret; 144 return 0; 145} 146 147static int __commit_transaction(struct btrfs_trans_handle *trans, struct 148 btrfs_root *root) 149{ 150 struct btrfs_buffer *b; 151 int ret = 0; 152 int wret; |
152 while(!list_empty(&root->trans)) { 153 b = list_entry(root->trans.next, struct btrfs_buffer, dirty); | 153 while(!list_empty(&root->fs_info->trans)) { 154 b = list_entry(root->fs_info->trans.next, struct btrfs_buffer, 155 dirty); |
154 list_del_init(&b->dirty); 155 wret = write_tree_block(trans, root, b); 156 if (wret) 157 ret = wret; 158 btrfs_block_release(root, b); 159 } 160 return ret; 161} 162 | 156 list_del_init(&b->dirty); 157 wret = write_tree_block(trans, root, b); 158 if (wret) 159 ret = wret; 160 btrfs_block_release(root, b); 161 } 162 return ret; 163} 164 |
163static int commit_extent_and_tree_roots(struct btrfs_trans_handle *trans, 164 struct btrfs_root *tree_root, struct 165 btrfs_root *extent_root) | 165static int commit_tree_roots(struct btrfs_trans_handle *trans, 166 struct btrfs_fs_info *fs_info) |
166{ 167 int ret; 168 u64 old_extent_block; | 167{ 168 int ret; 169 u64 old_extent_block; |
170 struct btrfs_root *tree_root = fs_info->tree_root; 171 struct btrfs_root *extent_root = fs_info->extent_root; 172 struct btrfs_root *inode_root = fs_info->inode_root; |
|
169 | 173 |
174 btrfs_set_root_blocknr(&inode_root->root_item, 175 inode_root->node->blocknr); 176 ret = btrfs_update_root(trans, tree_root, 177 &inode_root->root_key, 178 &inode_root->root_item); 179 BUG_ON(ret); |
|
170 while(1) { 171 old_extent_block = btrfs_root_blocknr(&extent_root->root_item); 172 if (old_extent_block == extent_root->node->blocknr) 173 break; 174 btrfs_set_root_blocknr(&extent_root->root_item, 175 extent_root->node->blocknr); 176 ret = btrfs_update_root(trans, tree_root, 177 &extent_root->root_key, 178 &extent_root->root_item); 179 BUG_ON(ret); 180 } | 180 while(1) { 181 old_extent_block = btrfs_root_blocknr(&extent_root->root_item); 182 if (old_extent_block == extent_root->node->blocknr) 183 break; 184 btrfs_set_root_blocknr(&extent_root->root_item, 185 extent_root->node->blocknr); 186 ret = btrfs_update_root(trans, tree_root, 187 &extent_root->root_key, 188 &extent_root->root_item); 189 BUG_ON(ret); 190 } |
181 __commit_transaction(trans, extent_root); 182 __commit_transaction(trans, tree_root); | |
183 return 0; 184} 185 186int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct 187 btrfs_root *root, struct btrfs_super_block *s) 188{ 189 int ret = 0; 190 struct btrfs_buffer *snap = root->commit_root; 191 struct btrfs_key snap_key; 192 | 191 return 0; 192} 193 194int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct 195 btrfs_root *root, struct btrfs_super_block *s) 196{ 197 int ret = 0; 198 struct btrfs_buffer *snap = root->commit_root; 199 struct btrfs_key snap_key; 200 |
193 ret = __commit_transaction(trans, root); 194 BUG_ON(ret); 195 | |
196 if (root->commit_root == root->node) 197 return 0; 198 199 memcpy(&snap_key, &root->root_key, sizeof(snap_key)); 200 root->root_key.offset++; 201 202 btrfs_set_root_blocknr(&root->root_item, root->node->blocknr); | 201 if (root->commit_root == root->node) 202 return 0; 203 204 memcpy(&snap_key, &root->root_key, sizeof(snap_key)); 205 root->root_key.offset++; 206 207 btrfs_set_root_blocknr(&root->root_item, root->node->blocknr); |
203 ret = btrfs_insert_root(trans, root->tree_root, &root->root_key, 204 &root->root_item); | 208 ret = btrfs_insert_root(trans, root->fs_info->tree_root, 209 &root->root_key, &root->root_item); |
205 BUG_ON(ret); 206 | 210 BUG_ON(ret); 211 |
207 ret = commit_extent_and_tree_roots(trans, root->tree_root, 208 root->extent_root); | 212 ret = commit_tree_roots(trans, root->fs_info); |
209 BUG_ON(ret); 210 | 213 BUG_ON(ret); 214 |
215 ret = __commit_transaction(trans, root); 216 BUG_ON(ret); 217 |
|
211 write_ctree_super(trans, root, s); | 218 write_ctree_super(trans, root, s); |
212 btrfs_finish_extent_commit(trans, root->extent_root); 213 btrfs_finish_extent_commit(trans, root->tree_root); | 219 btrfs_finish_extent_commit(trans, root->fs_info->extent_root); 220 btrfs_finish_extent_commit(trans, root->fs_info->tree_root); |
214 215 root->commit_root = root->node; 216 root->node->count++; 217 ret = btrfs_drop_snapshot(trans, root, snap); 218 BUG_ON(ret); 219 | 221 222 root->commit_root = root->node; 223 root->node->count++; 224 ret = btrfs_drop_snapshot(trans, root, snap); 225 BUG_ON(ret); 226 |
220 ret = btrfs_del_root(trans, root->tree_root, &snap_key); | 227 ret = btrfs_del_root(trans, root->fs_info->tree_root, &snap_key); |
221 BUG_ON(ret); 222 223 return ret; 224} 225 226static int __setup_root(struct btrfs_super_block *super, | 228 BUG_ON(ret); 229 230 return ret; 231} 232 233static int __setup_root(struct btrfs_super_block *super, |
227 struct btrfs_root *root, u64 objectid, int fp) | 234 struct btrfs_root *root, 235 struct btrfs_fs_info *fs_info, 236 u64 objectid, int fp) |
228{ | 237{ |
229 INIT_LIST_HEAD(&root->trans); 230 INIT_LIST_HEAD(&root->cache); 231 root->cache_size = 0; 232 root->fp = fp; | |
233 root->node = NULL; 234 root->commit_root = NULL; 235 root->blocksize = btrfs_super_blocksize(super); 236 root->ref_cows = 0; | 238 root->node = NULL; 239 root->commit_root = NULL; 240 root->blocksize = btrfs_super_blocksize(super); 241 root->ref_cows = 0; |
237 memset(&root->current_insert, 0, sizeof(root->current_insert)); 238 memset(&root->last_insert, 0, sizeof(root->last_insert)); | 242 root->fs_info = fs_info; |
239 memset(&root->root_key, 0, sizeof(root->root_key)); 240 memset(&root->root_item, 0, sizeof(root->root_item)); 241 return 0; 242} 243 244static int find_and_setup_root(struct btrfs_super_block *super, | 243 memset(&root->root_key, 0, sizeof(root->root_key)); 244 memset(&root->root_item, 0, sizeof(root->root_item)); 245 return 0; 246} 247 248static int find_and_setup_root(struct btrfs_super_block *super, |
245 struct btrfs_root *tree_root, u64 objectid, | 249 struct btrfs_root *tree_root, 250 struct btrfs_fs_info *fs_info, 251 u64 objectid, |
246 struct btrfs_root *root, int fp) 247{ 248 int ret; 249 | 252 struct btrfs_root *root, int fp) 253{ 254 int ret; 255 |
250 __setup_root(super, root, objectid, fp); | 256 __setup_root(super, root, fs_info, objectid, fp); |
251 ret = btrfs_find_last_root(tree_root, objectid, 252 &root->root_item, &root->root_key); 253 BUG_ON(ret); 254 255 root->node = read_tree_block(root, 256 btrfs_root_blocknr(&root->root_item)); 257 BUG_ON(!root->node); 258 return 0; 259} 260 261struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super) 262{ 263 struct btrfs_root *root = malloc(sizeof(struct btrfs_root)); 264 struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root)); 265 struct btrfs_root *tree_root = malloc(sizeof(struct btrfs_root)); | 257 ret = btrfs_find_last_root(tree_root, objectid, 258 &root->root_item, &root->root_key); 259 BUG_ON(ret); 260 261 root->node = read_tree_block(root, 262 btrfs_root_blocknr(&root->root_item)); 263 BUG_ON(!root->node); 264 return 0; 265} 266 267struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super) 268{ 269 struct btrfs_root *root = malloc(sizeof(struct btrfs_root)); 270 struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root)); 271 struct btrfs_root *tree_root = malloc(sizeof(struct btrfs_root)); |
272 struct btrfs_root *inode_root = malloc(sizeof(struct btrfs_root)); 273 struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info)); |
|
266 int fp; 267 int ret; 268 | 274 int fp; 275 int ret; 276 |
269 root->extent_root = extent_root; 270 root->tree_root = tree_root; 271 272 extent_root->extent_root = extent_root; 273 extent_root->tree_root = tree_root; 274 275 tree_root->extent_root = extent_root; 276 tree_root->tree_root = tree_root; 277 | |
278 fp = open(filename, O_CREAT | O_RDWR, 0600); 279 if (fp < 0) { 280 free(root); 281 return NULL; 282 } | 277 fp = open(filename, O_CREAT | O_RDWR, 0600); 278 if (fp < 0) { 279 free(root); 280 return NULL; 281 } |
283 INIT_RADIX_TREE(&root->cache_radix, GFP_KERNEL); 284 INIT_RADIX_TREE(&root->pinned_radix, GFP_KERNEL); 285 INIT_RADIX_TREE(&extent_root->pinned_radix, GFP_KERNEL); 286 INIT_RADIX_TREE(&extent_root->cache_radix, GFP_KERNEL); 287 INIT_RADIX_TREE(&tree_root->pinned_radix, GFP_KERNEL); 288 INIT_RADIX_TREE(&tree_root->cache_radix, GFP_KERNEL); | 282 INIT_RADIX_TREE(&fs_info->cache_radix, GFP_KERNEL); 283 INIT_RADIX_TREE(&fs_info->pinned_radix, GFP_KERNEL); 284 INIT_LIST_HEAD(&fs_info->trans); 285 INIT_LIST_HEAD(&fs_info->cache); 286 fs_info->cache_size = 0; 287 fs_info->fp = fp; 288 fs_info->running_transaction = NULL; 289 fs_info->fs_root = root; 290 fs_info->tree_root = tree_root; 291 fs_info->extent_root = extent_root; 292 fs_info->inode_root = inode_root; 293 fs_info->last_inode_alloc = 0; 294 fs_info->last_inode_alloc_dirid = 0; 295 memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert)); 296 memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); |
289 290 ret = pread(fp, super, sizeof(struct btrfs_super_block), 291 BTRFS_SUPER_INFO_OFFSET); 292 if (ret == 0 || btrfs_super_root(super) == 0) { 293 printf("making new FS!\n"); 294 ret = mkfs(fp, 0, 1024); 295 if (ret) 296 return NULL; 297 ret = pread(fp, super, sizeof(struct btrfs_super_block), 298 BTRFS_SUPER_INFO_OFFSET); 299 if (ret != sizeof(struct btrfs_super_block)) 300 return NULL; 301 } 302 BUG_ON(ret < 0); 303 | 297 298 ret = pread(fp, super, sizeof(struct btrfs_super_block), 299 BTRFS_SUPER_INFO_OFFSET); 300 if (ret == 0 || btrfs_super_root(super) == 0) { 301 printf("making new FS!\n"); 302 ret = mkfs(fp, 0, 1024); 303 if (ret) 304 return NULL; 305 ret = pread(fp, super, sizeof(struct btrfs_super_block), 306 BTRFS_SUPER_INFO_OFFSET); 307 if (ret != sizeof(struct btrfs_super_block)) 308 return NULL; 309 } 310 BUG_ON(ret < 0); 311 |
304 __setup_root(super, tree_root, BTRFS_ROOT_TREE_OBJECTID, fp); | 312 __setup_root(super, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID, fp); |
305 tree_root->node = read_tree_block(tree_root, btrfs_super_root(super)); 306 BUG_ON(!tree_root->node); 307 | 313 tree_root->node = read_tree_block(tree_root, btrfs_super_root(super)); 314 BUG_ON(!tree_root->node); 315 |
308 ret = find_and_setup_root(super, tree_root, BTRFS_EXTENT_TREE_OBJECTID, 309 extent_root, fp); | 316 ret = find_and_setup_root(super, tree_root, fs_info, 317 BTRFS_EXTENT_TREE_OBJECTID, extent_root, fp); |
310 BUG_ON(ret); 311 | 318 BUG_ON(ret); 319 |
312 ret = find_and_setup_root(super, tree_root, BTRFS_FS_TREE_OBJECTID, 313 root, fp); | 320 ret = find_and_setup_root(super, tree_root, fs_info, 321 BTRFS_INODE_MAP_OBJECTID, inode_root, fp); |
314 BUG_ON(ret); 315 | 322 BUG_ON(ret); 323 |
324 ret = find_and_setup_root(super, tree_root, fs_info, 325 BTRFS_FS_TREE_OBJECTID, root, fp); 326 BUG_ON(ret); 327 |
|
316 root->commit_root = root->node; 317 root->node->count++; 318 root->ref_cows = 1; 319 return root; 320} 321 322int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root 323 *root, struct btrfs_super_block *s) 324{ 325 int ret; | 328 root->commit_root = root->node; 329 root->node->count++; 330 root->ref_cows = 1; 331 return root; 332} 333 334int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root 335 *root, struct btrfs_super_block *s) 336{ 337 int ret; |
326 btrfs_set_super_root(s, root->tree_root->node->blocknr); 327 ret = pwrite(root->fp, s, sizeof(*s), | 338 btrfs_set_super_root(s, root->fs_info->tree_root->node->blocknr); 339 ret = pwrite(root->fs_info->fp, s, sizeof(*s), |
328 BTRFS_SUPER_INFO_OFFSET); 329 if (ret != sizeof(*s)) { 330 fprintf(stderr, "failed to write new super block err %d\n", ret); 331 return ret; 332 } 333 return 0; 334} 335 336static int drop_cache(struct btrfs_root *root) 337{ | 340 BTRFS_SUPER_INFO_OFFSET); 341 if (ret != sizeof(*s)) { 342 fprintf(stderr, "failed to write new super block err %d\n", ret); 343 return ret; 344 } 345 return 0; 346} 347 348static int drop_cache(struct btrfs_root *root) 349{ |
338 while(!list_empty(&root->cache)) { 339 struct btrfs_buffer *b = list_entry(root->cache.next, 340 struct btrfs_buffer, cache); | 350 while(!list_empty(&root->fs_info->cache)) { 351 struct btrfs_buffer *b = list_entry(root->fs_info->cache.next, 352 struct btrfs_buffer, 353 cache); |
341 list_del_init(&b->cache); 342 btrfs_block_release(root, b); 343 } 344 return 0; 345} 346int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s) 347{ 348 int ret; 349 struct btrfs_trans_handle *trans; 350 | 354 list_del_init(&b->cache); 355 btrfs_block_release(root, b); 356 } 357 return 0; 358} 359int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s) 360{ 361 int ret; 362 struct btrfs_trans_handle *trans; 363 |
351 trans = root->running_transaction; | 364 trans = root->fs_info->running_transaction; |
352 btrfs_commit_transaction(trans, root, s); | 365 btrfs_commit_transaction(trans, root, s); |
353 ret = commit_extent_and_tree_roots(trans, root->tree_root, 354 root->extent_root); | 366 ret = commit_tree_roots(trans, root->fs_info); |
355 BUG_ON(ret); | 367 BUG_ON(ret); |
368 ret = __commit_transaction(trans, root); 369 BUG_ON(ret); |
|
356 write_ctree_super(trans, root, s); | 370 write_ctree_super(trans, root, s); |
357 drop_cache(root->extent_root); 358 drop_cache(root->tree_root); | |
359 drop_cache(root); | 371 drop_cache(root); |
360 BUG_ON(!list_empty(&root->trans)); 361 BUG_ON(!list_empty(&root->extent_root->trans)); 362 BUG_ON(!list_empty(&root->tree_root->trans)); | 372 BUG_ON(!list_empty(&root->fs_info->trans)); |
363 | 373 |
364 close(root->fp); | 374 close(root->fs_info->fp); |
365 if (root->node) 366 btrfs_block_release(root, root->node); | 375 if (root->node) 376 btrfs_block_release(root, root->node); |
367 if (root->extent_root->node) 368 btrfs_block_release(root->extent_root, root->extent_root->node); 369 if (root->tree_root->node) 370 btrfs_block_release(root->tree_root, root->tree_root->node); | 377 if (root->fs_info->extent_root->node) 378 btrfs_block_release(root->fs_info->extent_root, 379 root->fs_info->extent_root->node); 380 if (root->fs_info->inode_root->node) 381 btrfs_block_release(root->fs_info->inode_root, 382 root->fs_info->inode_root->node); 383 if (root->fs_info->tree_root->node) 384 btrfs_block_release(root->fs_info->tree_root, 385 root->fs_info->tree_root->node); |
371 btrfs_block_release(root, root->commit_root); 372 free(root); 373 printf("on close %d blocks are allocated\n", allocated_blocks); 374 return 0; 375} 376 377void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf) 378{ 379 buf->count--; 380 if (buf->count < 0) 381 BUG(); 382 if (buf->count == 0) { 383 BUG_ON(!list_empty(&buf->cache)); 384 BUG_ON(!list_empty(&buf->dirty)); | 386 btrfs_block_release(root, root->commit_root); 387 free(root); 388 printf("on close %d blocks are allocated\n", allocated_blocks); 389 return 0; 390} 391 392void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf) 393{ 394 buf->count--; 395 if (buf->count < 0) 396 BUG(); 397 if (buf->count == 0) { 398 BUG_ON(!list_empty(&buf->cache)); 399 BUG_ON(!list_empty(&buf->dirty)); |
385 if (!radix_tree_lookup(&root->cache_radix, buf->blocknr)) | 400 if (!radix_tree_lookup(&root->fs_info->cache_radix, 401 buf->blocknr)) |
386 BUG(); | 402 BUG(); |
387 radix_tree_delete(&root->cache_radix, buf->blocknr); | 403 radix_tree_delete(&root->fs_info->cache_radix, buf->blocknr); |
388 memset(buf, 0, sizeof(*buf)); 389 free(buf); 390 BUG_ON(allocated_blocks == 0); 391 allocated_blocks--; | 404 memset(buf, 0, sizeof(*buf)); 405 free(buf); 406 BUG_ON(allocated_blocks == 0); 407 allocated_blocks--; |
392 BUG_ON(root->cache_size == 0); 393 root->cache_size--; | 408 BUG_ON(root->fs_info->cache_size == 0); 409 root->fs_info->cache_size--; |
394 } 395} 396 | 410 } 411} 412 |