diff options
-rw-r--r-- | fs/btrfs/btrfs_inode.h | 1 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 10 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 18 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 138 | ||||
-rw-r--r-- | fs/btrfs/super.c | 53 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 1 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 15 |
7 files changed, 181 insertions, 55 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 43a4f1ddb375..6b50076b02d5 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | struct btrfs_inode { | 4 | struct btrfs_inode { |
5 | struct btrfs_root *root; | 5 | struct btrfs_root *root; |
6 | struct btrfs_block_group_cache *block_group; | ||
6 | struct btrfs_key location; | 7 | struct btrfs_key location; |
7 | struct inode vfs_inode; | 8 | struct inode vfs_inode; |
8 | }; | 9 | }; |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b4783bf8bf4f..dbd3f636dd3d 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -61,7 +61,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | |||
61 | *cow_ret = buf; | 61 | *cow_ret = buf; |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | cow = btrfs_alloc_free_block(trans, root); | 64 | cow = btrfs_alloc_free_block(trans, root, buf->b_blocknr); |
65 | cow_node = btrfs_buffer_node(cow); | 65 | cow_node = btrfs_buffer_node(cow); |
66 | if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) | 66 | if (buf->b_size != root->blocksize || cow->b_size != root->blocksize) |
67 | WARN_ON(1); | 67 | WARN_ON(1); |
@@ -800,7 +800,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
800 | BUG_ON(path->nodes[level]); | 800 | BUG_ON(path->nodes[level]); |
801 | BUG_ON(path->nodes[level-1] != root->node); | 801 | BUG_ON(path->nodes[level-1] != root->node); |
802 | 802 | ||
803 | t = btrfs_alloc_free_block(trans, root); | 803 | t = btrfs_alloc_free_block(trans, root, root->node->b_blocknr); |
804 | c = btrfs_buffer_node(t); | 804 | c = btrfs_buffer_node(t); |
805 | memset(c, 0, root->blocksize); | 805 | memset(c, 0, root->blocksize); |
806 | btrfs_set_header_nritems(&c->header, 1); | 806 | btrfs_set_header_nritems(&c->header, 1); |
@@ -905,7 +905,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
905 | } | 905 | } |
906 | 906 | ||
907 | c_nritems = btrfs_header_nritems(&c->header); | 907 | c_nritems = btrfs_header_nritems(&c->header); |
908 | split_buffer = btrfs_alloc_free_block(trans, root); | 908 | split_buffer = btrfs_alloc_free_block(trans, root, t->b_blocknr); |
909 | split = btrfs_buffer_node(split_buffer); | 909 | split = btrfs_buffer_node(split_buffer); |
910 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); | 910 | btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); |
911 | btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); | 911 | btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); |
@@ -1277,7 +1277,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1277 | slot = path->slots[0]; | 1277 | slot = path->slots[0]; |
1278 | nritems = btrfs_header_nritems(&l->header); | 1278 | nritems = btrfs_header_nritems(&l->header); |
1279 | mid = (nritems + 1)/ 2; | 1279 | mid = (nritems + 1)/ 2; |
1280 | right_buffer = btrfs_alloc_free_block(trans, root); | 1280 | right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); |
1281 | BUG_ON(!right_buffer); | 1281 | BUG_ON(!right_buffer); |
1282 | right = btrfs_buffer_leaf(right_buffer); | 1282 | right = btrfs_buffer_leaf(right_buffer); |
1283 | memset(&right->header, 0, sizeof(right->header)); | 1283 | memset(&right->header, 0, sizeof(right->header)); |
@@ -1374,7 +1374,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1374 | 1374 | ||
1375 | if (!double_split) | 1375 | if (!double_split) |
1376 | return ret; | 1376 | return ret; |
1377 | right_buffer = btrfs_alloc_free_block(trans, root); | 1377 | right_buffer = btrfs_alloc_free_block(trans, root, l_buf->b_blocknr); |
1378 | BUG_ON(!right_buffer); | 1378 | BUG_ON(!right_buffer); |
1379 | right = btrfs_buffer_leaf(right_buffer); | 1379 | right = btrfs_buffer_leaf(right_buffer); |
1380 | memset(&right->header, 0, sizeof(right->header)); | 1380 | memset(&right->header, 0, sizeof(right->header)); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index c432222d40e3..e6bf9919536a 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -174,6 +174,7 @@ struct btrfs_inode_item { | |||
174 | __le64 generation; | 174 | __le64 generation; |
175 | __le64 size; | 175 | __le64 size; |
176 | __le64 nblocks; | 176 | __le64 nblocks; |
177 | __le64 block_group; | ||
177 | __le32 nlink; | 178 | __le32 nlink; |
178 | __le32 uid; | 179 | __le32 uid; |
179 | __le32 gid; | 180 | __le32 gid; |
@@ -241,6 +242,7 @@ struct btrfs_device_item { | |||
241 | 242 | ||
242 | /* tag for the radix tree of block groups in ram */ | 243 | /* tag for the radix tree of block groups in ram */ |
243 | #define BTRFS_BLOCK_GROUP_DIRTY 0 | 244 | #define BTRFS_BLOCK_GROUP_DIRTY 0 |
245 | #define BTRFS_BLOCK_GROUP_AVAIL 1 | ||
244 | #define BTRFS_BLOCK_GROUP_HINTS 8 | 246 | #define BTRFS_BLOCK_GROUP_HINTS 8 |
245 | #define BTRFS_BLOCK_GROUP_SIZE (256 * 1024 * 1024) | 247 | #define BTRFS_BLOCK_GROUP_SIZE (256 * 1024 * 1024) |
246 | struct btrfs_block_group_item { | 248 | struct btrfs_block_group_item { |
@@ -410,6 +412,17 @@ static inline void btrfs_set_inode_nblocks(struct btrfs_inode_item *i, u64 val) | |||
410 | i->nblocks = cpu_to_le64(val); | 412 | i->nblocks = cpu_to_le64(val); |
411 | } | 413 | } |
412 | 414 | ||
415 | static inline u64 btrfs_inode_block_group(struct btrfs_inode_item *i) | ||
416 | { | ||
417 | return le64_to_cpu(i->block_group); | ||
418 | } | ||
419 | |||
420 | static inline void btrfs_set_inode_block_group(struct btrfs_inode_item *i, | ||
421 | u64 val) | ||
422 | { | ||
423 | i->block_group = cpu_to_le64(val); | ||
424 | } | ||
425 | |||
413 | static inline u32 btrfs_inode_nlink(struct btrfs_inode_item *i) | 426 | static inline u32 btrfs_inode_nlink(struct btrfs_inode_item *i) |
414 | { | 427 | { |
415 | return le32_to_cpu(i->nlink); | 428 | return le32_to_cpu(i->nlink); |
@@ -1054,10 +1067,13 @@ static inline void btrfs_mark_buffer_dirty(struct buffer_head *bh) | |||
1054 | btrfs_item_offset((leaf)->items + (slot)))) | 1067 | btrfs_item_offset((leaf)->items + (slot)))) |
1055 | 1068 | ||
1056 | /* extent-tree.c */ | 1069 | /* extent-tree.c */ |
1070 | struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | ||
1071 | struct btrfs_block_group_cache | ||
1072 | *hint, int data); | ||
1057 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 1073 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, |
1058 | struct btrfs_root *root); | 1074 | struct btrfs_root *root); |
1059 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1075 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1060 | struct btrfs_root *root); | 1076 | struct btrfs_root *root, u64 hint); |
1061 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 1077 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
1062 | struct btrfs_root *root, u64 owner, | 1078 | struct btrfs_root *root, u64 owner, |
1063 | u64 num_blocks, u64 search_start, | 1079 | u64 num_blocks, u64 search_start, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 62051a36664a..8b8cbe25fffb 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -12,42 +12,57 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
12 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 12 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
13 | btrfs_root *extent_root); | 13 | btrfs_root *extent_root); |
14 | 14 | ||
15 | static int find_search_start(struct btrfs_root *root, int data) | 15 | struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, |
16 | struct btrfs_block_group_cache | ||
17 | *hint, int data) | ||
16 | { | 18 | { |
17 | struct btrfs_block_group_cache *cache[8]; | 19 | struct btrfs_block_group_cache *cache[8]; |
20 | struct btrfs_block_group_cache *found_group = NULL; | ||
18 | struct btrfs_fs_info *info = root->fs_info; | 21 | struct btrfs_fs_info *info = root->fs_info; |
19 | u64 used; | 22 | u64 used; |
20 | u64 last; | 23 | u64 last = 0; |
24 | u64 hint_last; | ||
21 | int i; | 25 | int i; |
22 | int ret; | 26 | int ret; |
23 | 27 | int full_search = 0; | |
24 | cache[0] = info->block_group_cache; | 28 | if (hint) { |
25 | if (!cache[0]) | 29 | used = btrfs_block_group_used(&hint->item); |
26 | goto find_new; | 30 | if (used < (hint->key.offset * 2) / 3) { |
27 | used = btrfs_block_group_used(&cache[0]->item); | 31 | return hint; |
28 | if (used < (cache[0]->key.offset * 3 / 2)) | 32 | } |
29 | return 0; | 33 | radix_tree_tag_clear(&info->block_group_radix, |
30 | find_new: | 34 | hint->key.objectid + hint->key.offset - 1, |
31 | last = 0; | 35 | BTRFS_BLOCK_GROUP_AVAIL); |
36 | last = hint->key.objectid + hint->key.offset; | ||
37 | hint_last = last; | ||
38 | } else { | ||
39 | hint_last = 0; | ||
40 | last = 0; | ||
41 | } | ||
32 | while(1) { | 42 | while(1) { |
33 | ret = radix_tree_gang_lookup_tag(&info->block_group_radix, | 43 | ret = radix_tree_gang_lookup_tag(&info->block_group_radix, |
34 | (void **)cache, | 44 | (void **)cache, |
35 | last, ARRAY_SIZE(cache), | 45 | last, ARRAY_SIZE(cache), |
36 | BTRFS_BLOCK_GROUP_DIRTY); | 46 | BTRFS_BLOCK_GROUP_AVAIL); |
37 | if (!ret) | 47 | if (!ret) |
38 | break; | 48 | break; |
39 | for (i = 0; i < ret; i++) { | 49 | for (i = 0; i < ret; i++) { |
40 | used = btrfs_block_group_used(&cache[i]->item); | 50 | used = btrfs_block_group_used(&cache[i]->item); |
41 | if (used < (cache[i]->key.offset * 3 / 2)) { | 51 | if (used < (cache[i]->key.offset * 2) / 3) { |
42 | info->block_group_cache = cache[i]; | 52 | info->block_group_cache = cache[i]; |
43 | cache[i]->last_alloc = cache[i]->first_free; | 53 | found_group = cache[i]; |
44 | return 0; | 54 | goto found; |
45 | } | 55 | } |
56 | radix_tree_tag_clear(&info->block_group_radix, | ||
57 | cache[i]->key.objectid + | ||
58 | cache[i]->key.offset - 1, | ||
59 | BTRFS_BLOCK_GROUP_AVAIL); | ||
46 | last = cache[i]->key.objectid + | 60 | last = cache[i]->key.objectid + |
47 | cache[i]->key.offset - 1; | 61 | cache[i]->key.offset; |
48 | } | 62 | } |
49 | } | 63 | } |
50 | last = 0; | 64 | last = hint_last; |
65 | again: | ||
51 | while(1) { | 66 | while(1) { |
52 | ret = radix_tree_gang_lookup(&info->block_group_radix, | 67 | ret = radix_tree_gang_lookup(&info->block_group_radix, |
53 | (void **)cache, | 68 | (void **)cache, |
@@ -56,17 +71,32 @@ find_new: | |||
56 | break; | 71 | break; |
57 | for (i = 0; i < ret; i++) { | 72 | for (i = 0; i < ret; i++) { |
58 | used = btrfs_block_group_used(&cache[i]->item); | 73 | used = btrfs_block_group_used(&cache[i]->item); |
59 | if (used < (cache[i]->key.offset * 3 / 2)) { | 74 | if (used < cache[i]->key.offset) { |
60 | info->block_group_cache = cache[i]; | 75 | info->block_group_cache = cache[i]; |
61 | cache[i]->last_alloc = cache[i]->first_free; | 76 | found_group = cache[i]; |
62 | return 0; | 77 | goto found; |
63 | } | 78 | } |
79 | radix_tree_tag_clear(&info->block_group_radix, | ||
80 | cache[i]->key.objectid + | ||
81 | cache[i]->key.offset - 1, | ||
82 | BTRFS_BLOCK_GROUP_AVAIL); | ||
64 | last = cache[i]->key.objectid + | 83 | last = cache[i]->key.objectid + |
65 | cache[i]->key.offset - 1; | 84 | cache[i]->key.offset; |
66 | } | 85 | } |
67 | } | 86 | } |
68 | info->block_group_cache = NULL; | 87 | info->block_group_cache = NULL; |
69 | return 0; | 88 | if (!full_search) { |
89 | last = 0; | ||
90 | full_search = 1; | ||
91 | goto again; | ||
92 | } | ||
93 | found: | ||
94 | if (!found_group) { | ||
95 | ret = radix_tree_gang_lookup(&info->block_group_radix, | ||
96 | (void **)&found_group, 0, 1); | ||
97 | BUG_ON(ret != 1); | ||
98 | } | ||
99 | return found_group; | ||
70 | } | 100 | } |
71 | 101 | ||
72 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 102 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
@@ -243,6 +273,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | |||
243 | path, cache[i]); | 273 | path, cache[i]); |
244 | if (err) | 274 | if (err) |
245 | werr = err; | 275 | werr = err; |
276 | cache[i]->last_alloc = cache[i]->first_free; | ||
246 | } | 277 | } |
247 | } | 278 | } |
248 | btrfs_free_path(path); | 279 | btrfs_free_path(path); |
@@ -322,10 +353,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct | |||
322 | btree_inode->i_blkbits)); | 353 | btree_inode->i_blkbits)); |
323 | } | 354 | } |
324 | } | 355 | } |
325 | if (root->fs_info->block_group_cache) { | ||
326 | root->fs_info->block_group_cache->last_alloc = | ||
327 | root->fs_info->block_group_cache->first_free; | ||
328 | } | ||
329 | return 0; | 356 | return 0; |
330 | } | 357 | } |
331 | 358 | ||
@@ -532,22 +559,43 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
532 | int total_found = 0; | 559 | int total_found = 0; |
533 | int fill_prealloc = 0; | 560 | int fill_prealloc = 0; |
534 | int level; | 561 | int level; |
562 | int update_block_group = 0; | ||
563 | struct btrfs_block_group_cache *hint_block_group; | ||
535 | 564 | ||
536 | path = btrfs_alloc_path(); | 565 | path = btrfs_alloc_path(); |
537 | ins->flags = 0; | 566 | ins->flags = 0; |
538 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); | 567 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); |
539 | 568 | ||
540 | level = btrfs_header_level(btrfs_buffer_header(root->node)); | 569 | level = btrfs_header_level(btrfs_buffer_header(root->node)); |
570 | /* find search start here */ | ||
571 | if (0 && search_start && num_blocks) { | ||
572 | u64 used; | ||
573 | ret = radix_tree_gang_lookup(&info->block_group_radix, | ||
574 | (void **)&hint_block_group, | ||
575 | search_start, 1); | ||
576 | if (ret) { | ||
577 | used = btrfs_block_group_used(&hint_block_group->item); | ||
578 | if (used > (hint_block_group->key.offset * 9) / 10) | ||
579 | search_start = 0; | ||
580 | else if (search_start < hint_block_group->last_alloc) | ||
581 | search_start = hint_block_group->last_alloc; | ||
582 | } else { | ||
583 | search_start = 0; | ||
584 | } | ||
585 | } | ||
541 | if (num_blocks == 0) { | 586 | if (num_blocks == 0) { |
542 | fill_prealloc = 1; | 587 | fill_prealloc = 1; |
543 | num_blocks = 1; | 588 | num_blocks = 1; |
544 | total_needed = (min(level + 1, BTRFS_MAX_LEVEL) + 2) * 3; | 589 | total_needed = (min(level + 1, BTRFS_MAX_LEVEL) + 2) * 3; |
545 | } | 590 | } |
546 | find_search_start(root, 0); | 591 | if (1 || !search_start) { |
547 | if (info->block_group_cache && | 592 | trans->block_group = btrfs_find_block_group(root, |
548 | info->block_group_cache->last_alloc > search_start) | 593 | trans->block_group, |
549 | search_start = info->block_group_cache->last_alloc; | 594 | 0); |
550 | 595 | if (trans->block_group->last_alloc > search_start) | |
596 | search_start = trans->block_group->last_alloc; | ||
597 | update_block_group = 1; | ||
598 | } | ||
551 | check_failed: | 599 | check_failed: |
552 | btrfs_init_path(path); | 600 | btrfs_init_path(path); |
553 | ins->objectid = search_start; | 601 | ins->objectid = search_start; |
@@ -662,11 +710,13 @@ check_pending: | |||
662 | } | 710 | } |
663 | info->extent_tree_prealloc_nr = total_found; | 711 | info->extent_tree_prealloc_nr = total_found; |
664 | } | 712 | } |
665 | ret = radix_tree_gang_lookup(&info->block_group_radix, | 713 | if (update_block_group) { |
666 | (void **)&info->block_group_cache, | 714 | ret = radix_tree_gang_lookup(&info->block_group_radix, |
667 | ins->objectid, 1); | 715 | (void **)&trans->block_group, |
668 | if (ret) { | 716 | ins->objectid, 1); |
669 | info->block_group_cache->last_alloc = ins->objectid; | 717 | if (ret) { |
718 | trans->block_group->last_alloc = ins->objectid; | ||
719 | } | ||
670 | } | 720 | } |
671 | ins->offset = num_blocks; | 721 | ins->offset = num_blocks; |
672 | btrfs_free_path(path); | 722 | btrfs_free_path(path); |
@@ -747,14 +797,14 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
747 | * returns the tree buffer or NULL. | 797 | * returns the tree buffer or NULL. |
748 | */ | 798 | */ |
749 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 799 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
750 | struct btrfs_root *root) | 800 | struct btrfs_root *root, u64 hint) |
751 | { | 801 | { |
752 | struct btrfs_key ins; | 802 | struct btrfs_key ins; |
753 | int ret; | 803 | int ret; |
754 | struct buffer_head *buf; | 804 | struct buffer_head *buf; |
755 | 805 | ||
756 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, | 806 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, |
757 | 1, 0, (unsigned long)-1, &ins); | 807 | 1, hint, (unsigned long)-1, &ins); |
758 | if (ret) { | 808 | if (ret) { |
759 | BUG(); | 809 | BUG(); |
760 | return NULL; | 810 | return NULL; |
@@ -975,6 +1025,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
975 | struct btrfs_key found_key; | 1025 | struct btrfs_key found_key; |
976 | struct btrfs_leaf *leaf; | 1026 | struct btrfs_leaf *leaf; |
977 | u64 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE / root->blocksize; | 1027 | u64 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE / root->blocksize; |
1028 | u64 used; | ||
978 | 1029 | ||
979 | root = root->fs_info->extent_root; | 1030 | root = root->fs_info->extent_root; |
980 | key.objectid = 0; | 1031 | key.objectid = 0; |
@@ -1005,8 +1056,8 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1005 | struct btrfs_block_group_item); | 1056 | struct btrfs_block_group_item); |
1006 | memcpy(&cache->item, bi, sizeof(*bi)); | 1057 | memcpy(&cache->item, bi, sizeof(*bi)); |
1007 | memcpy(&cache->key, &found_key, sizeof(found_key)); | 1058 | memcpy(&cache->key, &found_key, sizeof(found_key)); |
1008 | cache->last_alloc = 0; | 1059 | cache->last_alloc = cache->key.objectid; |
1009 | cache->first_free = 0; | 1060 | cache->first_free = cache->key.objectid; |
1010 | key.objectid = found_key.objectid + found_key.offset; | 1061 | key.objectid = found_key.objectid + found_key.offset; |
1011 | btrfs_release_path(root, path); | 1062 | btrfs_release_path(root, path); |
1012 | ret = radix_tree_insert(&root->fs_info->block_group_radix, | 1063 | ret = radix_tree_insert(&root->fs_info->block_group_radix, |
@@ -1014,6 +1065,13 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1014 | found_key.offset - 1, | 1065 | found_key.offset - 1, |
1015 | (void *)cache); | 1066 | (void *)cache); |
1016 | BUG_ON(ret); | 1067 | BUG_ON(ret); |
1068 | used = btrfs_block_group_used(bi); | ||
1069 | if (used < (key.offset * 2) / 3) { | ||
1070 | radix_tree_tag_set(&root->fs_info->block_group_radix, | ||
1071 | found_key.objectid + | ||
1072 | found_key.offset - 1, | ||
1073 | BTRFS_BLOCK_GROUP_AVAIL); | ||
1074 | } | ||
1017 | if (key.objectid >= | 1075 | if (key.objectid >= |
1018 | btrfs_super_total_blocks(root->fs_info->disk_super)) | 1076 | btrfs_super_total_blocks(root->fs_info->disk_super)) |
1019 | break; | 1077 | break; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 1890e8648dbd..7ecbe7c86186 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -52,6 +52,8 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
52 | struct btrfs_inode_item *inode_item; | 52 | struct btrfs_inode_item *inode_item; |
53 | struct btrfs_root *root = BTRFS_I(inode)->root; | 53 | struct btrfs_root *root = BTRFS_I(inode)->root; |
54 | struct btrfs_key location; | 54 | struct btrfs_key location; |
55 | struct btrfs_block_group_cache *alloc_group; | ||
56 | u64 alloc_group_block; | ||
55 | int ret; | 57 | int ret; |
56 | 58 | ||
57 | path = btrfs_alloc_path(); | 59 | path = btrfs_alloc_path(); |
@@ -82,6 +84,12 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
82 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); | 84 | inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); |
83 | inode->i_blocks = btrfs_inode_nblocks(inode_item); | 85 | inode->i_blocks = btrfs_inode_nblocks(inode_item); |
84 | inode->i_generation = btrfs_inode_generation(inode_item); | 86 | inode->i_generation = btrfs_inode_generation(inode_item); |
87 | alloc_group_block = btrfs_inode_block_group(inode_item); | ||
88 | ret = radix_tree_gang_lookup(&root->fs_info->block_group_radix, | ||
89 | (void **)&alloc_group, | ||
90 | alloc_group_block, 1); | ||
91 | BUG_ON(!ret); | ||
92 | BTRFS_I(inode)->block_group = alloc_group; | ||
85 | 93 | ||
86 | btrfs_free_path(path); | 94 | btrfs_free_path(path); |
87 | inode_item = NULL; | 95 | inode_item = NULL; |
@@ -136,6 +144,8 @@ static void fill_inode_item(struct btrfs_inode_item *item, | |||
136 | btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec); | 144 | btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec); |
137 | btrfs_set_inode_nblocks(item, inode->i_blocks); | 145 | btrfs_set_inode_nblocks(item, inode->i_blocks); |
138 | btrfs_set_inode_generation(item, inode->i_generation); | 146 | btrfs_set_inode_generation(item, inode->i_generation); |
147 | btrfs_set_inode_block_group(item, | ||
148 | BTRFS_I(inode)->block_group->key.objectid); | ||
139 | } | 149 | } |
140 | 150 | ||
141 | 151 | ||
@@ -237,6 +247,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
237 | root = BTRFS_I(dir)->root; | 247 | root = BTRFS_I(dir)->root; |
238 | mutex_lock(&root->fs_info->fs_mutex); | 248 | mutex_lock(&root->fs_info->fs_mutex); |
239 | trans = btrfs_start_transaction(root, 1); | 249 | trans = btrfs_start_transaction(root, 1); |
250 | btrfs_set_trans_block_group(trans, dir); | ||
240 | ret = btrfs_unlink_trans(trans, root, dir, dentry); | 251 | ret = btrfs_unlink_trans(trans, root, dir, dentry); |
241 | btrfs_end_transaction(trans, root); | 252 | btrfs_end_transaction(trans, root); |
242 | mutex_unlock(&root->fs_info->fs_mutex); | 253 | mutex_unlock(&root->fs_info->fs_mutex); |
@@ -262,6 +273,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
262 | btrfs_init_path(path); | 273 | btrfs_init_path(path); |
263 | mutex_lock(&root->fs_info->fs_mutex); | 274 | mutex_lock(&root->fs_info->fs_mutex); |
264 | trans = btrfs_start_transaction(root, 1); | 275 | trans = btrfs_start_transaction(root, 1); |
276 | btrfs_set_trans_block_group(trans, dir); | ||
265 | key.objectid = inode->i_ino; | 277 | key.objectid = inode->i_ino; |
266 | key.offset = (u64)-1; | 278 | key.offset = (u64)-1; |
267 | key.flags = (u32)-1; | 279 | key.flags = (u32)-1; |
@@ -429,6 +441,7 @@ static void btrfs_delete_inode(struct inode *inode) | |||
429 | inode->i_size = 0; | 441 | inode->i_size = 0; |
430 | mutex_lock(&root->fs_info->fs_mutex); | 442 | mutex_lock(&root->fs_info->fs_mutex); |
431 | trans = btrfs_start_transaction(root, 1); | 443 | trans = btrfs_start_transaction(root, 1); |
444 | btrfs_set_trans_block_group(trans, inode); | ||
432 | if (S_ISREG(inode->i_mode)) { | 445 | if (S_ISREG(inode->i_mode)) { |
433 | ret = btrfs_truncate_in_trans(trans, root, inode); | 446 | ret = btrfs_truncate_in_trans(trans, root, inode); |
434 | BUG_ON(ret); | 447 | BUG_ON(ret); |
@@ -731,6 +744,7 @@ static int btrfs_write_inode(struct inode *inode, int wait) | |||
731 | if (wait) { | 744 | if (wait) { |
732 | mutex_lock(&root->fs_info->fs_mutex); | 745 | mutex_lock(&root->fs_info->fs_mutex); |
733 | trans = btrfs_start_transaction(root, 1); | 746 | trans = btrfs_start_transaction(root, 1); |
747 | btrfs_set_trans_block_group(trans, inode); | ||
734 | ret = btrfs_commit_transaction(trans, root); | 748 | ret = btrfs_commit_transaction(trans, root); |
735 | mutex_unlock(&root->fs_info->fs_mutex); | 749 | mutex_unlock(&root->fs_info->fs_mutex); |
736 | } | 750 | } |
@@ -744,6 +758,7 @@ static void btrfs_dirty_inode(struct inode *inode) | |||
744 | 758 | ||
745 | mutex_lock(&root->fs_info->fs_mutex); | 759 | mutex_lock(&root->fs_info->fs_mutex); |
746 | trans = btrfs_start_transaction(root, 1); | 760 | trans = btrfs_start_transaction(root, 1); |
761 | btrfs_set_trans_block_group(trans, inode); | ||
747 | btrfs_update_inode(trans, root, inode); | 762 | btrfs_update_inode(trans, root, inode); |
748 | btrfs_end_transaction(trans, root); | 763 | btrfs_end_transaction(trans, root); |
749 | mutex_unlock(&root->fs_info->fs_mutex); | 764 | mutex_unlock(&root->fs_info->fs_mutex); |
@@ -751,7 +766,9 @@ static void btrfs_dirty_inode(struct inode *inode) | |||
751 | 766 | ||
752 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | 767 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, |
753 | struct btrfs_root *root, | 768 | struct btrfs_root *root, |
754 | u64 objectid, int mode) | 769 | u64 objectid, |
770 | struct btrfs_block_group_cache *group, | ||
771 | int mode) | ||
755 | { | 772 | { |
756 | struct inode *inode; | 773 | struct inode *inode; |
757 | struct btrfs_inode_item inode_item; | 774 | struct btrfs_inode_item inode_item; |
@@ -763,6 +780,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
763 | return ERR_PTR(-ENOMEM); | 780 | return ERR_PTR(-ENOMEM); |
764 | 781 | ||
765 | BTRFS_I(inode)->root = root; | 782 | BTRFS_I(inode)->root = root; |
783 | group = btrfs_find_block_group(root, group, 0); | ||
784 | BTRFS_I(inode)->block_group = group; | ||
766 | 785 | ||
767 | inode->i_uid = current->fsuid; | 786 | inode->i_uid = current->fsuid; |
768 | inode->i_gid = current->fsgid; | 787 | inode->i_gid = current->fsgid; |
@@ -832,6 +851,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
832 | 851 | ||
833 | mutex_lock(&root->fs_info->fs_mutex); | 852 | mutex_lock(&root->fs_info->fs_mutex); |
834 | trans = btrfs_start_transaction(root, 1); | 853 | trans = btrfs_start_transaction(root, 1); |
854 | btrfs_set_trans_block_group(trans, dir); | ||
835 | 855 | ||
836 | err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); | 856 | err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); |
837 | if (err) { | 857 | if (err) { |
@@ -839,11 +859,13 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
839 | goto out_unlock; | 859 | goto out_unlock; |
840 | } | 860 | } |
841 | 861 | ||
842 | inode = btrfs_new_inode(trans, root, objectid, mode); | 862 | inode = btrfs_new_inode(trans, root, objectid, |
863 | BTRFS_I(dir)->block_group, mode); | ||
843 | err = PTR_ERR(inode); | 864 | err = PTR_ERR(inode); |
844 | if (IS_ERR(inode)) | 865 | if (IS_ERR(inode)) |
845 | goto out_unlock; | 866 | goto out_unlock; |
846 | // FIXME mark the inode dirty | 867 | |
868 | btrfs_set_trans_block_group(trans, inode); | ||
847 | err = btrfs_add_nondir(trans, dentry, inode); | 869 | err = btrfs_add_nondir(trans, dentry, inode); |
848 | if (err) | 870 | if (err) |
849 | drop_inode = 1; | 871 | drop_inode = 1; |
@@ -853,6 +875,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
853 | inode->i_op = &btrfs_file_inode_operations; | 875 | inode->i_op = &btrfs_file_inode_operations; |
854 | } | 876 | } |
855 | dir->i_sb->s_dirt = 1; | 877 | dir->i_sb->s_dirt = 1; |
878 | btrfs_update_inode_block_group(trans, inode); | ||
879 | btrfs_update_inode_block_group(trans, dir); | ||
856 | out_unlock: | 880 | out_unlock: |
857 | btrfs_end_transaction(trans, root); | 881 | btrfs_end_transaction(trans, root); |
858 | mutex_unlock(&root->fs_info->fs_mutex); | 882 | mutex_unlock(&root->fs_info->fs_mutex); |
@@ -904,6 +928,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
904 | 928 | ||
905 | mutex_lock(&root->fs_info->fs_mutex); | 929 | mutex_lock(&root->fs_info->fs_mutex); |
906 | trans = btrfs_start_transaction(root, 1); | 930 | trans = btrfs_start_transaction(root, 1); |
931 | btrfs_set_trans_block_group(trans, dir); | ||
907 | if (IS_ERR(trans)) { | 932 | if (IS_ERR(trans)) { |
908 | err = PTR_ERR(trans); | 933 | err = PTR_ERR(trans); |
909 | goto out_unlock; | 934 | goto out_unlock; |
@@ -915,7 +940,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
915 | goto out_unlock; | 940 | goto out_unlock; |
916 | } | 941 | } |
917 | 942 | ||
918 | inode = btrfs_new_inode(trans, root, objectid, S_IFDIR | mode); | 943 | inode = btrfs_new_inode(trans, root, objectid, |
944 | BTRFS_I(dir)->block_group, S_IFDIR | mode); | ||
919 | if (IS_ERR(inode)) { | 945 | if (IS_ERR(inode)) { |
920 | err = PTR_ERR(inode); | 946 | err = PTR_ERR(inode); |
921 | goto out_fail; | 947 | goto out_fail; |
@@ -923,6 +949,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
923 | drop_on_err = 1; | 949 | drop_on_err = 1; |
924 | inode->i_op = &btrfs_dir_inode_operations; | 950 | inode->i_op = &btrfs_dir_inode_operations; |
925 | inode->i_fop = &btrfs_dir_file_operations; | 951 | inode->i_fop = &btrfs_dir_file_operations; |
952 | btrfs_set_trans_block_group(trans, inode); | ||
926 | 953 | ||
927 | err = btrfs_make_empty_dir(trans, root, inode->i_ino, dir->i_ino); | 954 | err = btrfs_make_empty_dir(trans, root, inode->i_ino, dir->i_ino); |
928 | if (err) | 955 | if (err) |
@@ -938,6 +965,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
938 | d_instantiate(dentry, inode); | 965 | d_instantiate(dentry, inode); |
939 | drop_on_err = 0; | 966 | drop_on_err = 0; |
940 | dir->i_sb->s_dirt = 1; | 967 | dir->i_sb->s_dirt = 1; |
968 | btrfs_update_inode_block_group(trans, inode); | ||
969 | btrfs_update_inode_block_group(trans, dir); | ||
941 | 970 | ||
942 | out_fail: | 971 | out_fail: |
943 | btrfs_end_transaction(trans, root); | 972 | btrfs_end_transaction(trans, root); |
@@ -1349,6 +1378,7 @@ static void btrfs_truncate(struct inode *inode) | |||
1349 | /* FIXME, add redo link to tree so we don't leak on crash */ | 1378 | /* FIXME, add redo link to tree so we don't leak on crash */ |
1350 | mutex_lock(&root->fs_info->fs_mutex); | 1379 | mutex_lock(&root->fs_info->fs_mutex); |
1351 | trans = btrfs_start_transaction(root, 1); | 1380 | trans = btrfs_start_transaction(root, 1); |
1381 | btrfs_set_trans_block_group(trans, inode); | ||
1352 | ret = btrfs_truncate_in_trans(trans, root, inode); | 1382 | ret = btrfs_truncate_in_trans(trans, root, inode); |
1353 | BUG_ON(ret); | 1383 | BUG_ON(ret); |
1354 | ret = btrfs_end_transaction(trans, root); | 1384 | ret = btrfs_end_transaction(trans, root); |
@@ -1445,6 +1475,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
1445 | 1475 | ||
1446 | mutex_lock(&root->fs_info->fs_mutex); | 1476 | mutex_lock(&root->fs_info->fs_mutex); |
1447 | trans = btrfs_start_transaction(root, 1); | 1477 | trans = btrfs_start_transaction(root, 1); |
1478 | btrfs_set_trans_block_group(trans, inode); | ||
1448 | 1479 | ||
1449 | bh = page_buffers(pages[i]); | 1480 | bh = page_buffers(pages[i]); |
1450 | if (buffer_mapped(bh) && bh->b_blocknr == 0) { | 1481 | if (buffer_mapped(bh) && bh->b_blocknr == 0) { |
@@ -1481,6 +1512,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
1481 | kunmap(pages[i]); | 1512 | kunmap(pages[i]); |
1482 | } | 1513 | } |
1483 | SetPageChecked(pages[i]); | 1514 | SetPageChecked(pages[i]); |
1515 | btrfs_update_inode_block_group(trans, inode); | ||
1484 | ret = btrfs_end_transaction(trans, root); | 1516 | ret = btrfs_end_transaction(trans, root); |
1485 | BUG_ON(ret); | 1517 | BUG_ON(ret); |
1486 | mutex_unlock(&root->fs_info->fs_mutex); | 1518 | mutex_unlock(&root->fs_info->fs_mutex); |
@@ -1821,6 +1853,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1821 | mutex_unlock(&root->fs_info->fs_mutex); | 1853 | mutex_unlock(&root->fs_info->fs_mutex); |
1822 | goto out_unlock; | 1854 | goto out_unlock; |
1823 | } | 1855 | } |
1856 | btrfs_set_trans_block_group(trans, inode); | ||
1824 | /* FIXME blocksize != 4096 */ | 1857 | /* FIXME blocksize != 4096 */ |
1825 | inode->i_blocks += num_blocks << 3; | 1858 | inode->i_blocks += num_blocks << 3; |
1826 | if (start_pos < inode->i_size) { | 1859 | if (start_pos < inode->i_size) { |
@@ -1845,6 +1878,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1845 | } | 1878 | } |
1846 | BUG_ON(ret); | 1879 | BUG_ON(ret); |
1847 | alloc_extent_start = ins.objectid; | 1880 | alloc_extent_start = ins.objectid; |
1881 | btrfs_update_inode_block_group(trans, inode); | ||
1848 | ret = btrfs_end_transaction(trans, root); | 1882 | ret = btrfs_end_transaction(trans, root); |
1849 | mutex_unlock(&root->fs_info->fs_mutex); | 1883 | mutex_unlock(&root->fs_info->fs_mutex); |
1850 | 1884 | ||
@@ -2017,6 +2051,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2017 | struct btrfs_leaf *leaf; | 2051 | struct btrfs_leaf *leaf; |
2018 | struct btrfs_root *new_root; | 2052 | struct btrfs_root *new_root; |
2019 | struct inode *inode; | 2053 | struct inode *inode; |
2054 | struct inode *dir; | ||
2020 | int ret; | 2055 | int ret; |
2021 | u64 objectid; | 2056 | u64 objectid; |
2022 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; | 2057 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; |
@@ -2025,7 +2060,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2025 | trans = btrfs_start_transaction(root, 1); | 2060 | trans = btrfs_start_transaction(root, 1); |
2026 | BUG_ON(!trans); | 2061 | BUG_ON(!trans); |
2027 | 2062 | ||
2028 | subvol = btrfs_alloc_free_block(trans, root); | 2063 | subvol = btrfs_alloc_free_block(trans, root, 0); |
2029 | if (subvol == NULL) | 2064 | if (subvol == NULL) |
2030 | return -ENOSPC; | 2065 | return -ENOSPC; |
2031 | leaf = btrfs_buffer_leaf(subvol); | 2066 | leaf = btrfs_buffer_leaf(subvol); |
@@ -2069,10 +2104,9 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2069 | * insert the directory item | 2104 | * insert the directory item |
2070 | */ | 2105 | */ |
2071 | key.offset = (u64)-1; | 2106 | key.offset = (u64)-1; |
2107 | dir = root->fs_info->sb->s_root->d_inode; | ||
2072 | ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, | 2108 | ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, |
2073 | name, namelen, | 2109 | name, namelen, dir->i_ino, &key, 0); |
2074 | root->fs_info->sb->s_root->d_inode->i_ino, | ||
2075 | &key, 0); | ||
2076 | BUG_ON(ret); | 2110 | BUG_ON(ret); |
2077 | 2111 | ||
2078 | ret = btrfs_commit_transaction(trans, root); | 2112 | ret = btrfs_commit_transaction(trans, root); |
@@ -2084,7 +2118,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2084 | trans = btrfs_start_transaction(new_root, 1); | 2118 | trans = btrfs_start_transaction(new_root, 1); |
2085 | BUG_ON(!trans); | 2119 | BUG_ON(!trans); |
2086 | 2120 | ||
2087 | inode = btrfs_new_inode(trans, new_root, new_dirid, S_IFDIR | 0700); | 2121 | inode = btrfs_new_inode(trans, new_root, new_dirid, |
2122 | BTRFS_I(dir)->block_group, S_IFDIR | 0700); | ||
2088 | inode->i_op = &btrfs_dir_inode_operations; | 2123 | inode->i_op = &btrfs_dir_inode_operations; |
2089 | inode->i_fop = &btrfs_dir_file_operations; | 2124 | inode->i_fop = &btrfs_dir_file_operations; |
2090 | 2125 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f9b8864dcc40..bdbf514c111f 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -77,6 +77,7 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | |||
77 | h->transaction = root->fs_info->running_transaction; | 77 | h->transaction = root->fs_info->running_transaction; |
78 | h->blocks_reserved = num_blocks; | 78 | h->blocks_reserved = num_blocks; |
79 | h->blocks_used = 0; | 79 | h->blocks_used = 0; |
80 | h->block_group = NULL; | ||
80 | root->fs_info->running_transaction->use_count++; | 81 | root->fs_info->running_transaction->use_count++; |
81 | mutex_unlock(&root->fs_info->trans_mutex); | 82 | mutex_unlock(&root->fs_info->trans_mutex); |
82 | h->magic = h->magic2 = TRANS_MAGIC; | 83 | h->magic = h->magic2 = TRANS_MAGIC; |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index afe42d167cee..b5378119e76c 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -1,5 +1,6 @@ | |||
1 | #ifndef __TRANSACTION__ | 1 | #ifndef __TRANSACTION__ |
2 | #define __TRANSACTION__ | 2 | #define __TRANSACTION__ |
3 | #include "btrfs_inode.h" | ||
3 | 4 | ||
4 | struct btrfs_transaction { | 5 | struct btrfs_transaction { |
5 | u64 transid; | 6 | u64 transid; |
@@ -20,10 +21,24 @@ struct btrfs_trans_handle { | |||
20 | unsigned long blocks_reserved; | 21 | unsigned long blocks_reserved; |
21 | unsigned long blocks_used; | 22 | unsigned long blocks_used; |
22 | struct btrfs_transaction *transaction; | 23 | struct btrfs_transaction *transaction; |
24 | struct btrfs_block_group_cache *block_group; | ||
23 | int magic2; | 25 | int magic2; |
24 | }; | 26 | }; |
25 | 27 | ||
26 | 28 | ||
29 | static inline void btrfs_set_trans_block_group(struct btrfs_trans_handle *trans, | ||
30 | struct inode *inode) | ||
31 | { | ||
32 | trans->block_group = BTRFS_I(inode)->block_group; | ||
33 | } | ||
34 | |||
35 | static inline void btrfs_update_inode_block_group(struct | ||
36 | btrfs_trans_handle *trans, | ||
37 | struct inode *inode) | ||
38 | { | ||
39 | BTRFS_I(inode)->block_group = trans->block_group; | ||
40 | } | ||
41 | |||
27 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, | 42 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, |
28 | struct btrfs_root *root); | 43 | struct btrfs_root *root); |
29 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | 44 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, |