aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-30 15:25:45 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-30 15:25:45 -0400
commit31f3c99b73483f7b738a886c552050cbd6128ff3 (patch)
tree35c961e01b8fe25525b9ac4a691fd931ac1dbe59 /fs/btrfs
parent308535a05e4c39d2be26e0aeee722682deeb6f77 (diff)
Btrfs: allocator improvements, inode block groups
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/btrfs_inode.h1
-rw-r--r--fs/btrfs/ctree.c10
-rw-r--r--fs/btrfs/ctree.h18
-rw-r--r--fs/btrfs/extent-tree.c138
-rw-r--r--fs/btrfs/super.c53
-rw-r--r--fs/btrfs/transaction.c1
-rw-r--r--fs/btrfs/transaction.h15
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
4struct btrfs_inode { 4struct 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)
246struct btrfs_block_group_item { 248struct 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
415static inline u64 btrfs_inode_block_group(struct btrfs_inode_item *i)
416{
417 return le64_to_cpu(i->block_group);
418}
419
420static 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
413static inline u32 btrfs_inode_nlink(struct btrfs_inode_item *i) 426static 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 */
1070struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
1071 struct btrfs_block_group_cache
1072 *hint, int data);
1057int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, 1073int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
1058 struct btrfs_root *root); 1074 struct btrfs_root *root);
1059struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 1075struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
1060 struct btrfs_root *root); 1076 struct btrfs_root *root, u64 hint);
1061int btrfs_alloc_extent(struct btrfs_trans_handle *trans, 1077int 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
12static int del_pending_extents(struct btrfs_trans_handle *trans, struct 12static int del_pending_extents(struct btrfs_trans_handle *trans, struct
13 btrfs_root *extent_root); 13 btrfs_root *extent_root);
14 14
15static int find_search_start(struct btrfs_root *root, int data) 15struct 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,
30find_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;
65again:
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 }
93found:
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
72int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, 102int 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 }
551check_failed: 599check_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 */
749struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 799struct 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
752static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, 767static 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);
856out_unlock: 880out_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
942out_fail: 971out_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
4struct btrfs_transaction { 5struct 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
29static 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
35static 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
27int btrfs_end_transaction(struct btrfs_trans_handle *trans, 42int btrfs_end_transaction(struct btrfs_trans_handle *trans,
28 struct btrfs_root *root); 43 struct btrfs_root *root);
29struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, 44struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,