aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-15 15:41:47 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:01 -0400
commite17cade25ff8074101d653557a78df09c16ca276 (patch)
treec4bddc201bf77c9a460e726a5cdd5ca1add8c256
parentb248a4152956cbae1b23f4c70ef5b51d6ea2ecfb (diff)
Btrfs: Add chunk uuids and update multi-device back references
Block headers now store the chunk tree uuid Chunk items records the device uuid for each stripes Device extent items record better back refs to the chunk tree Block groups record better back refs to the chunk tree The chunk tree format has also changed. The objectid of BTRFS_CHUNK_ITEM_KEY used to be the logical offset of the chunk. Now it is a chunk tree id, with the logical offset being stored in the offset field of the key. This allows a single chunk tree to record multiple logical address spaces, upping the number of bytes indexed by a chunk tree from 2^64 to 2^128. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.c12
-rw-r--r--fs/btrfs/ctree.h80
-rw-r--r--fs/btrfs/disk-io.c6
-rw-r--r--fs/btrfs/extent-tree.c22
-rw-r--r--fs/btrfs/print-tree.c20
-rw-r--r--fs/btrfs/volumes.c76
-rw-r--r--fs/btrfs/volumes.h6
7 files changed, 160 insertions, 62 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index e8bf6c221e4e..618e526c9046 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1382,6 +1382,11 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans,
1382 write_extent_buffer(c, root->fs_info->fsid, 1382 write_extent_buffer(c, root->fs_info->fsid,
1383 (unsigned long)btrfs_header_fsid(c), 1383 (unsigned long)btrfs_header_fsid(c),
1384 BTRFS_FSID_SIZE); 1384 BTRFS_FSID_SIZE);
1385
1386 write_extent_buffer(c, root->fs_info->chunk_tree_uuid,
1387 (unsigned long)btrfs_header_chunk_tree_uuid(c),
1388 BTRFS_UUID_SIZE);
1389
1385 btrfs_set_node_key(c, &lower_key, 0); 1390 btrfs_set_node_key(c, &lower_key, 0);
1386 btrfs_set_node_blockptr(c, 0, lower->start); 1391 btrfs_set_node_blockptr(c, 0, lower->start);
1387 lower_gen = btrfs_header_generation(lower); 1392 lower_gen = btrfs_header_generation(lower);
@@ -1513,6 +1518,9 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
1513 write_extent_buffer(split, root->fs_info->fsid, 1518 write_extent_buffer(split, root->fs_info->fsid,
1514 (unsigned long)btrfs_header_fsid(split), 1519 (unsigned long)btrfs_header_fsid(split),
1515 BTRFS_FSID_SIZE); 1520 BTRFS_FSID_SIZE);
1521 write_extent_buffer(split, root->fs_info->chunk_tree_uuid,
1522 (unsigned long)btrfs_header_chunk_tree_uuid(split),
1523 BTRFS_UUID_SIZE);
1516 1524
1517 mid = (c_nritems + 1) / 2; 1525 mid = (c_nritems + 1) / 2;
1518 1526
@@ -2043,6 +2051,10 @@ again:
2043 write_extent_buffer(right, root->fs_info->fsid, 2051 write_extent_buffer(right, root->fs_info->fsid,
2044 (unsigned long)btrfs_header_fsid(right), 2052 (unsigned long)btrfs_header_fsid(right),
2045 BTRFS_FSID_SIZE); 2053 BTRFS_FSID_SIZE);
2054
2055 write_extent_buffer(right, root->fs_info->chunk_tree_uuid,
2056 (unsigned long)btrfs_header_chunk_tree_uuid(right),
2057 BTRFS_UUID_SIZE);
2046 if (mid <= slot) { 2058 if (mid <= slot) {
2047 if (nritems == 1 || 2059 if (nritems == 1 ||
2048 leaf_space_used(l, mid, nritems - mid) + space_needed > 2060 leaf_space_used(l, mid, nritems - mid) + space_needed >
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 09d614fcafb1..82d67c3db8bc 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -70,6 +70,7 @@ extern struct kmem_cache *btrfs_path_cachep;
70 * All files have objectids higher than this. 70 * All files have objectids higher than this.
71 */ 71 */
72#define BTRFS_FIRST_FREE_OBJECTID 256ULL 72#define BTRFS_FIRST_FREE_OBJECTID 256ULL
73#define BTRFS_FIRST_CHUNK_TREE_OBJECTID 256ULL
73 74
74 75
75/* 76/*
@@ -131,7 +132,7 @@ struct btrfs_mapping_tree {
131 struct extent_map_tree map_tree; 132 struct extent_map_tree map_tree;
132}; 133};
133 134
134#define BTRFS_DEV_UUID_SIZE 16 135#define BTRFS_UUID_SIZE 16
135struct btrfs_dev_item { 136struct btrfs_dev_item {
136 /* the internal btrfs device id */ 137 /* the internal btrfs device id */
137 __le64 devid; 138 __le64 devid;
@@ -154,17 +155,32 @@ struct btrfs_dev_item {
154 /* type and info about this device */ 155 /* type and info about this device */
155 __le64 type; 156 __le64 type;
156 157
158 /* grouping information for allocation decisions */
159 __le32 dev_group;
160
161 /* seek speed 0-100 where 100 is fastest */
162 u8 seek_speed;
163
164 /* bandwidth 0-100 where 100 is fastest */
165 u8 bandwidth;
166
157 /* btrfs generated uuid for this device */ 167 /* btrfs generated uuid for this device */
158 u8 uuid[BTRFS_DEV_UUID_SIZE]; 168 u8 uuid[BTRFS_UUID_SIZE];
159} __attribute__ ((__packed__)); 169} __attribute__ ((__packed__));
160 170
161struct btrfs_stripe { 171struct btrfs_stripe {
162 __le64 devid; 172 __le64 devid;
163 __le64 offset; 173 __le64 offset;
174 u8 dev_uuid[BTRFS_UUID_SIZE];
164} __attribute__ ((__packed__)); 175} __attribute__ ((__packed__));
165 176
166struct btrfs_chunk { 177struct btrfs_chunk {
178 /* size of this chunk in bytes */
179 __le64 length;
180
181 /* objectid of the root referencing this chunk */
167 __le64 owner; 182 __le64 owner;
183
168 __le64 stripe_len; 184 __le64 stripe_len;
169 __le64 type; 185 __le64 type;
170 186
@@ -199,10 +215,14 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
199 * every tree block (leaf or node) starts with this header. 215 * every tree block (leaf or node) starts with this header.
200 */ 216 */
201struct btrfs_header { 217struct btrfs_header {
218 /* these first four must match the super block */
202 u8 csum[BTRFS_CSUM_SIZE]; 219 u8 csum[BTRFS_CSUM_SIZE];
203 u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ 220 u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
204 __le64 bytenr; /* which block this node is supposed to live in */ 221 __le64 bytenr; /* which block this node is supposed to live in */
205 __le64 flags; 222 __le64 flags;
223
224 /* allowed to be different from the super from here on down */
225 u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
206 __le64 generation; 226 __le64 generation;
207 __le64 owner; 227 __le64 owner;
208 __le32 nritems; 228 __le32 nritems;
@@ -235,6 +255,8 @@ struct btrfs_super_block {
235 u8 fsid[16]; /* FS specific uuid */ 255 u8 fsid[16]; /* FS specific uuid */
236 __le64 bytenr; /* this block number */ 256 __le64 bytenr; /* this block number */
237 __le64 flags; 257 __le64 flags;
258
259 /* allowed to be different from the btrfs_header from here own down */
238 __le64 magic; 260 __le64 magic;
239 __le64 generation; 261 __le64 generation;
240 __le64 root; 262 __le64 root;
@@ -323,14 +345,16 @@ struct btrfs_extent_ref {
323 345
324/* dev extents record free space on individual devices. The owner 346/* dev extents record free space on individual devices. The owner
325 * field points back to the chunk allocation mapping tree that allocated 347 * field points back to the chunk allocation mapping tree that allocated
326 * the extent 348 * the extent. The chunk tree uuid field is a way to double check the owner
327 */ 349 */
328struct btrfs_dev_extent { 350struct btrfs_dev_extent {
329 __le64 owner; 351 __le64 chunk_tree;
352 __le64 chunk_objectid;
353 __le64 chunk_offset;
330 __le64 length; 354 __le64 length;
355 u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
331} __attribute__ ((__packed__)); 356} __attribute__ ((__packed__));
332 357
333
334struct btrfs_inode_ref { 358struct btrfs_inode_ref {
335 __le16 name_len; 359 __le16 name_len;
336 /* name goes here */ 360 /* name goes here */
@@ -424,7 +448,6 @@ struct btrfs_csum_item {
424 448
425struct btrfs_block_group_item { 449struct btrfs_block_group_item {
426 __le64 used; 450 __le64 used;
427 __le64 chunk_tree;
428 __le64 chunk_objectid; 451 __le64 chunk_objectid;
429 __le64 flags; 452 __le64 flags;
430} __attribute__ ((__packed__)); 453} __attribute__ ((__packed__));
@@ -451,6 +474,7 @@ struct btrfs_device;
451struct btrfs_fs_devices; 474struct btrfs_fs_devices;
452struct btrfs_fs_info { 475struct btrfs_fs_info {
453 u8 fsid[BTRFS_FSID_SIZE]; 476 u8 fsid[BTRFS_FSID_SIZE];
477 u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
454 struct btrfs_root *extent_root; 478 struct btrfs_root *extent_root;
455 struct btrfs_root *tree_root; 479 struct btrfs_root *tree_root;
456 struct btrfs_root *chunk_root; 480 struct btrfs_root *chunk_root;
@@ -697,6 +721,9 @@ BTRFS_SETGET_FUNCS(device_io_align, struct btrfs_dev_item, io_align, 32);
697BTRFS_SETGET_FUNCS(device_io_width, struct btrfs_dev_item, io_width, 32); 721BTRFS_SETGET_FUNCS(device_io_width, struct btrfs_dev_item, io_width, 32);
698BTRFS_SETGET_FUNCS(device_sector_size, struct btrfs_dev_item, sector_size, 32); 722BTRFS_SETGET_FUNCS(device_sector_size, struct btrfs_dev_item, sector_size, 32);
699BTRFS_SETGET_FUNCS(device_id, struct btrfs_dev_item, devid, 64); 723BTRFS_SETGET_FUNCS(device_id, struct btrfs_dev_item, devid, 64);
724BTRFS_SETGET_FUNCS(device_group, struct btrfs_dev_item, dev_group, 32);
725BTRFS_SETGET_FUNCS(device_seek_speed, struct btrfs_dev_item, seek_speed, 8);
726BTRFS_SETGET_FUNCS(device_bandwidth, struct btrfs_dev_item, bandwidth, 8);
700 727
701BTRFS_SETGET_STACK_FUNCS(stack_device_type, struct btrfs_dev_item, type, 64); 728BTRFS_SETGET_STACK_FUNCS(stack_device_type, struct btrfs_dev_item, type, 64);
702BTRFS_SETGET_STACK_FUNCS(stack_device_total_bytes, struct btrfs_dev_item, 729BTRFS_SETGET_STACK_FUNCS(stack_device_total_bytes, struct btrfs_dev_item,
@@ -710,12 +737,19 @@ BTRFS_SETGET_STACK_FUNCS(stack_device_io_width, struct btrfs_dev_item,
710BTRFS_SETGET_STACK_FUNCS(stack_device_sector_size, struct btrfs_dev_item, 737BTRFS_SETGET_STACK_FUNCS(stack_device_sector_size, struct btrfs_dev_item,
711 sector_size, 32); 738 sector_size, 32);
712BTRFS_SETGET_STACK_FUNCS(stack_device_id, struct btrfs_dev_item, devid, 64); 739BTRFS_SETGET_STACK_FUNCS(stack_device_id, struct btrfs_dev_item, devid, 64);
740BTRFS_SETGET_STACK_FUNCS(stack_device_group, struct btrfs_dev_item,
741 dev_group, 32);
742BTRFS_SETGET_STACK_FUNCS(stack_device_seek_speed, struct btrfs_dev_item,
743 seek_speed, 8);
744BTRFS_SETGET_STACK_FUNCS(stack_device_bandwidth, struct btrfs_dev_item,
745 bandwidth, 8);
713 746
714static inline char *btrfs_device_uuid(struct btrfs_dev_item *d) 747static inline char *btrfs_device_uuid(struct btrfs_dev_item *d)
715{ 748{
716 return (char *)d + offsetof(struct btrfs_dev_item, uuid); 749 return (char *)d + offsetof(struct btrfs_dev_item, uuid);
717} 750}
718 751
752BTRFS_SETGET_FUNCS(chunk_length, struct btrfs_chunk, length, 64);
719BTRFS_SETGET_FUNCS(chunk_owner, struct btrfs_chunk, owner, 64); 753BTRFS_SETGET_FUNCS(chunk_owner, struct btrfs_chunk, owner, 64);
720BTRFS_SETGET_FUNCS(chunk_stripe_len, struct btrfs_chunk, stripe_len, 64); 754BTRFS_SETGET_FUNCS(chunk_stripe_len, struct btrfs_chunk, stripe_len, 64);
721BTRFS_SETGET_FUNCS(chunk_io_align, struct btrfs_chunk, io_align, 32); 755BTRFS_SETGET_FUNCS(chunk_io_align, struct btrfs_chunk, io_align, 32);
@@ -726,6 +760,12 @@ BTRFS_SETGET_FUNCS(chunk_num_stripes, struct btrfs_chunk, num_stripes, 16);
726BTRFS_SETGET_FUNCS(stripe_devid, struct btrfs_stripe, devid, 64); 760BTRFS_SETGET_FUNCS(stripe_devid, struct btrfs_stripe, devid, 64);
727BTRFS_SETGET_FUNCS(stripe_offset, struct btrfs_stripe, offset, 64); 761BTRFS_SETGET_FUNCS(stripe_offset, struct btrfs_stripe, offset, 64);
728 762
763static inline char *btrfs_stripe_dev_uuid(struct btrfs_stripe *s)
764{
765 return (char *)s + offsetof(struct btrfs_stripe, dev_uuid);
766}
767
768BTRFS_SETGET_STACK_FUNCS(stack_chunk_length, struct btrfs_chunk, length, 64);
729BTRFS_SETGET_STACK_FUNCS(stack_chunk_owner, struct btrfs_chunk, owner, 64); 769BTRFS_SETGET_STACK_FUNCS(stack_chunk_owner, struct btrfs_chunk, owner, 64);
730BTRFS_SETGET_STACK_FUNCS(stack_chunk_stripe_len, struct btrfs_chunk, 770BTRFS_SETGET_STACK_FUNCS(stack_chunk_stripe_len, struct btrfs_chunk,
731 stripe_len, 64); 771 stripe_len, 64);
@@ -781,13 +821,10 @@ BTRFS_SETGET_STACK_FUNCS(block_group_used, struct btrfs_block_group_item,
781 used, 64); 821 used, 64);
782BTRFS_SETGET_FUNCS(disk_block_group_used, struct btrfs_block_group_item, 822BTRFS_SETGET_FUNCS(disk_block_group_used, struct btrfs_block_group_item,
783 used, 64); 823 used, 64);
784BTRFS_SETGET_STACK_FUNCS(block_group_chunk_tree, struct btrfs_block_group_item,
785 chunk_tree, 64);
786BTRFS_SETGET_FUNCS(disk_block_group_chunk_tree, struct btrfs_block_group_item,
787 chunk_tree, 64);
788BTRFS_SETGET_STACK_FUNCS(block_group_chunk_objectid, 824BTRFS_SETGET_STACK_FUNCS(block_group_chunk_objectid,
789 struct btrfs_block_group_item, chunk_objectid, 64); 825 struct btrfs_block_group_item, chunk_objectid, 64);
790BTRFS_SETGET_FUNCS(disk_block_group_chunk_objecitd, 826
827BTRFS_SETGET_FUNCS(disk_block_group_chunk_objectid,
791 struct btrfs_block_group_item, chunk_objectid, 64); 828 struct btrfs_block_group_item, chunk_objectid, 64);
792BTRFS_SETGET_FUNCS(disk_block_group_flags, 829BTRFS_SETGET_FUNCS(disk_block_group_flags,
793 struct btrfs_block_group_item, flags, 64); 830 struct btrfs_block_group_item, flags, 64);
@@ -850,9 +887,20 @@ BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_timespec, nsec, 32);
850BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32); 887BTRFS_SETGET_FUNCS(extent_refs, struct btrfs_extent_item, refs, 32);
851 888
852/* struct btrfs_dev_extent */ 889/* struct btrfs_dev_extent */
853BTRFS_SETGET_FUNCS(dev_extent_owner, struct btrfs_dev_extent, owner, 64); 890BTRFS_SETGET_FUNCS(dev_extent_chunk_tree, struct btrfs_dev_extent,
891 chunk_tree, 64);
892BTRFS_SETGET_FUNCS(dev_extent_chunk_objectid, struct btrfs_dev_extent,
893 chunk_objectid, 64);
894BTRFS_SETGET_FUNCS(dev_extent_chunk_offset, struct btrfs_dev_extent,
895 chunk_offset, 64);
854BTRFS_SETGET_FUNCS(dev_extent_length, struct btrfs_dev_extent, length, 64); 896BTRFS_SETGET_FUNCS(dev_extent_length, struct btrfs_dev_extent, length, 64);
855 897
898static inline u8 *btrfs_dev_extent_chunk_tree_uuid(struct btrfs_dev_extent *dev)
899{
900 unsigned long ptr = offsetof(struct btrfs_dev_extent, chunk_tree_uuid);
901 return (u8 *)((unsigned long)dev + ptr);
902}
903
856/* struct btrfs_extent_ref */ 904/* struct btrfs_extent_ref */
857BTRFS_SETGET_FUNCS(ref_root, struct btrfs_extent_ref, root, 64); 905BTRFS_SETGET_FUNCS(ref_root, struct btrfs_extent_ref, root, 64);
858BTRFS_SETGET_FUNCS(ref_generation, struct btrfs_extent_ref, generation, 64); 906BTRFS_SETGET_FUNCS(ref_generation, struct btrfs_extent_ref, generation, 64);
@@ -1087,6 +1135,12 @@ static inline u8 *btrfs_header_fsid(struct extent_buffer *eb)
1087 return (u8 *)ptr; 1135 return (u8 *)ptr;
1088} 1136}
1089 1137
1138static inline u8 *btrfs_header_chunk_tree_uuid(struct extent_buffer *eb)
1139{
1140 unsigned long ptr = offsetof(struct btrfs_header, chunk_tree_uuid);
1141 return (u8 *)ptr;
1142}
1143
1090static inline u8 *btrfs_super_fsid(struct extent_buffer *eb) 1144static inline u8 *btrfs_super_fsid(struct extent_buffer *eb)
1091{ 1145{
1092 unsigned long ptr = offsetof(struct btrfs_super_block, fsid); 1146 unsigned long ptr = offsetof(struct btrfs_super_block, fsid);
@@ -1311,7 +1365,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info);
1311int btrfs_read_block_groups(struct btrfs_root *root); 1365int btrfs_read_block_groups(struct btrfs_root *root);
1312int btrfs_make_block_group(struct btrfs_trans_handle *trans, 1366int btrfs_make_block_group(struct btrfs_trans_handle *trans,
1313 struct btrfs_root *root, u64 bytes_used, 1367 struct btrfs_root *root, u64 bytes_used,
1314 u64 type, u64 chunk_tree, u64 chunk_objectid, 1368 u64 type, u64 chunk_objectid, u64 chunk_offset,
1315 u64 size); 1369 u64 size);
1316/* ctree.c */ 1370/* ctree.c */
1317int btrfs_previous_item(struct btrfs_root *root, 1371int btrfs_previous_item(struct btrfs_root *root,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 9c94dddde704..79c284c87286 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1125,6 +1125,10 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1125 blocksize); 1125 blocksize);
1126 BUG_ON(!chunk_root->node); 1126 BUG_ON(!chunk_root->node);
1127 1127
1128 read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
1129 (unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node),
1130 BTRFS_UUID_SIZE);
1131
1128 ret = btrfs_read_chunk_tree(chunk_root); 1132 ret = btrfs_read_chunk_tree(chunk_root);
1129 BUG_ON(ret); 1133 BUG_ON(ret);
1130 1134
@@ -1229,7 +1233,7 @@ int write_all_supers(struct btrfs_root *root)
1229 btrfs_set_device_sector_size(sb, dev_item, dev->sector_size); 1233 btrfs_set_device_sector_size(sb, dev_item, dev->sector_size);
1230 write_extent_buffer(sb, dev->uuid, 1234 write_extent_buffer(sb, dev->uuid,
1231 (unsigned long)btrfs_device_uuid(dev_item), 1235 (unsigned long)btrfs_device_uuid(dev_item),
1232 BTRFS_DEV_UUID_SIZE); 1236 BTRFS_UUID_SIZE);
1233 1237
1234 btrfs_set_header_flag(sb, BTRFS_HEADER_FLAG_WRITTEN); 1238 btrfs_set_header_flag(sb, BTRFS_HEADER_FLAG_WRITTEN);
1235 csum_tree_block(root, sb, 0); 1239 csum_tree_block(root, sb, 0);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e49147e767df..71f045c63493 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -35,10 +35,6 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
35 btrfs_root *extent_root); 35 btrfs_root *extent_root);
36static int del_pending_extents(struct btrfs_trans_handle *trans, struct 36static int del_pending_extents(struct btrfs_trans_handle *trans, struct
37 btrfs_root *extent_root); 37 btrfs_root *extent_root);
38int btrfs_make_block_group(struct btrfs_trans_handle *trans,
39 struct btrfs_root *root, u64 bytes_used,
40 u64 type, u64 chunk_tree, u64 chunk_objectid,
41 u64 size);
42 38
43 39
44static int cache_block_group(struct btrfs_root *root, 40static int cache_block_group(struct btrfs_root *root,
@@ -980,7 +976,6 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
980 ret = get_state_private(block_group_cache, start, &ptr); 976 ret = get_state_private(block_group_cache, start, &ptr);
981 if (ret) 977 if (ret)
982 break; 978 break;
983
984 cache = (struct btrfs_block_group_cache *)(unsigned long)ptr; 979 cache = (struct btrfs_block_group_cache *)(unsigned long)ptr;
985 err = write_one_cache_group(trans, root, 980 err = write_one_cache_group(trans, root,
986 path, cache); 981 path, cache);
@@ -1094,8 +1089,7 @@ printk("space info full %Lu\n", flags);
1094 BUG_ON(ret); 1089 BUG_ON(ret);
1095 1090
1096 ret = btrfs_make_block_group(trans, extent_root, 0, flags, 1091 ret = btrfs_make_block_group(trans, extent_root, 0, flags,
1097 extent_root->fs_info->chunk_root->root_key.objectid, 1092 BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes);
1098 start, num_bytes);
1099 BUG_ON(ret); 1093 BUG_ON(ret);
1100 1094
1101 return 0; 1095 return 0;
@@ -2782,7 +2776,7 @@ error:
2782 2776
2783int btrfs_make_block_group(struct btrfs_trans_handle *trans, 2777int btrfs_make_block_group(struct btrfs_trans_handle *trans,
2784 struct btrfs_root *root, u64 bytes_used, 2778 struct btrfs_root *root, u64 bytes_used,
2785 u64 type, u64 chunk_tree, u64 chunk_objectid, 2779 u64 type, u64 chunk_objectid, u64 chunk_offset,
2786 u64 size) 2780 u64 size)
2787{ 2781{
2788 int ret; 2782 int ret;
@@ -2796,14 +2790,14 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
2796 2790
2797 cache = kmalloc(sizeof(*cache), GFP_NOFS); 2791 cache = kmalloc(sizeof(*cache), GFP_NOFS);
2798 BUG_ON(!cache); 2792 BUG_ON(!cache);
2799 cache->key.objectid = chunk_objectid; 2793 cache->key.objectid = chunk_offset;
2800 cache->key.offset = size; 2794 cache->key.offset = size;
2801 cache->cached = 0; 2795 cache->cached = 0;
2802 cache->pinned = 0; 2796 cache->pinned = 0;
2797
2803 btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY); 2798 btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
2804 memset(&cache->item, 0, sizeof(cache->item)); 2799 memset(&cache->item, 0, sizeof(cache->item));
2805 btrfs_set_block_group_used(&cache->item, bytes_used); 2800 btrfs_set_block_group_used(&cache->item, bytes_used);
2806 btrfs_set_block_group_chunk_tree(&cache->item, chunk_tree);
2807 btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid); 2801 btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid);
2808 cache->flags = type; 2802 cache->flags = type;
2809 btrfs_set_block_group_flags(&cache->item, type); 2803 btrfs_set_block_group_flags(&cache->item, type);
@@ -2813,12 +2807,12 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
2813 BUG_ON(ret); 2807 BUG_ON(ret);
2814 2808
2815 bit = block_group_state_bits(type); 2809 bit = block_group_state_bits(type);
2816 set_extent_bits(block_group_cache, chunk_objectid, 2810 set_extent_bits(block_group_cache, chunk_offset,
2817 chunk_objectid + size - 1, 2811 chunk_offset + size - 1,
2818 bit | EXTENT_LOCKED, GFP_NOFS); 2812 bit | EXTENT_LOCKED, GFP_NOFS);
2819 set_state_private(block_group_cache, chunk_objectid,
2820 (unsigned long)cache);
2821 2813
2814 set_state_private(block_group_cache, chunk_offset,
2815 (unsigned long)cache);
2822 ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item, 2816 ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item,
2823 sizeof(cache->item)); 2817 sizeof(cache->item));
2824 BUG_ON(ret); 2818 BUG_ON(ret);
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index ee0de112cf5a..e99f3249d05a 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -24,7 +24,8 @@ static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk)
24{ 24{
25 int num_stripes = btrfs_chunk_num_stripes(eb, chunk); 25 int num_stripes = btrfs_chunk_num_stripes(eb, chunk);
26 int i; 26 int i;
27 printk("\t\tchunk owner %llu type %llu num_stripes %d\n", 27 printk("\t\tchunk length %llu owner %llu type %llu num_stripes %d\n",
28 (unsigned long long)btrfs_chunk_length(eb, chunk),
28 (unsigned long long)btrfs_chunk_owner(eb, chunk), 29 (unsigned long long)btrfs_chunk_owner(eb, chunk),
29 (unsigned long long)btrfs_chunk_type(eb, chunk), 30 (unsigned long long)btrfs_chunk_type(eb, chunk),
30 num_stripes); 31 num_stripes);
@@ -140,17 +141,24 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
140 case BTRFS_DEV_EXTENT_KEY: 141 case BTRFS_DEV_EXTENT_KEY:
141 dev_extent = btrfs_item_ptr(l, i, 142 dev_extent = btrfs_item_ptr(l, i,
142 struct btrfs_dev_extent); 143 struct btrfs_dev_extent);
143 printk("\t\tdev extent owner %llu length %llu\n", 144 printk("\t\tdev extent chunk_tree %llu\n"
144 (unsigned long long)btrfs_dev_extent_owner(l, dev_extent), 145 "\t\tchunk objectid %llu chunk offset %llu "
145 (unsigned long long)btrfs_dev_extent_length(l, dev_extent)); 146 "length %llu\n",
147 (unsigned long long)
148 btrfs_dev_extent_chunk_tree(l, dev_extent),
149 (unsigned long long)
150 btrfs_dev_extent_chunk_objectid(l, dev_extent),
151 (unsigned long long)
152 btrfs_dev_extent_chunk_offset(l, dev_extent),
153 (unsigned long long)
154 btrfs_dev_extent_length(l, dev_extent));
146 }; 155 };
147 } 156 }
148} 157}
149 158
150void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c) 159void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c)
151{ 160{
152 int i; 161 int i; u32 nr;
153 u32 nr;
154 struct btrfs_key key; 162 struct btrfs_key key;
155 int level; 163 int level;
156 164
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index f81519f0e4a7..23ebd95b25e0 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -180,7 +180,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
180 list_for_each(cur, head) { 180 list_for_each(cur, head) {
181 device = list_entry(cur, struct btrfs_device, dev_list); 181 device = list_entry(cur, struct btrfs_device, dev_list);
182 bdev = open_bdev_excl(device->name, flags, holder); 182 bdev = open_bdev_excl(device->name, flags, holder);
183printk("opening %s devid %Lu\n", device->name, device->devid); 183
184 if (IS_ERR(bdev)) { 184 if (IS_ERR(bdev)) {
185 printk("open %s failed\n", device->name); 185 printk("open %s failed\n", device->name);
186 ret = PTR_ERR(bdev); 186 ret = PTR_ERR(bdev);
@@ -190,7 +190,6 @@ printk("opening %s devid %Lu\n", device->name, device->devid);
190 fs_devices->latest_bdev = bdev; 190 fs_devices->latest_bdev = bdev;
191 if (device->devid == fs_devices->lowest_devid) { 191 if (device->devid == fs_devices->lowest_devid) {
192 fs_devices->lowest_bdev = bdev; 192 fs_devices->lowest_bdev = bdev;
193printk("lowest bdev %s\n", device->name);
194 } 193 }
195 device->bdev = bdev; 194 device->bdev = bdev;
196 } 195 }
@@ -372,7 +371,9 @@ error:
372 371
373int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, 372int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
374 struct btrfs_device *device, 373 struct btrfs_device *device,
375 u64 owner, u64 num_bytes, u64 *start) 374 u64 chunk_tree, u64 chunk_objectid,
375 u64 chunk_offset,
376 u64 num_bytes, u64 *start)
376{ 377{
377 int ret; 378 int ret;
378 struct btrfs_path *path; 379 struct btrfs_path *path;
@@ -400,7 +401,14 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
400 leaf = path->nodes[0]; 401 leaf = path->nodes[0];
401 extent = btrfs_item_ptr(leaf, path->slots[0], 402 extent = btrfs_item_ptr(leaf, path->slots[0],
402 struct btrfs_dev_extent); 403 struct btrfs_dev_extent);
403 btrfs_set_dev_extent_owner(leaf, extent, owner); 404 btrfs_set_dev_extent_chunk_tree(leaf, extent, chunk_tree);
405 btrfs_set_dev_extent_chunk_objectid(leaf, extent, chunk_objectid);
406 btrfs_set_dev_extent_chunk_offset(leaf, extent, chunk_offset);
407
408 write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid,
409 (unsigned long)btrfs_dev_extent_chunk_tree_uuid(extent),
410 BTRFS_UUID_SIZE);
411
404 btrfs_set_dev_extent_length(leaf, extent, num_bytes); 412 btrfs_set_dev_extent_length(leaf, extent, num_bytes);
405 btrfs_mark_buffer_dirty(leaf); 413 btrfs_mark_buffer_dirty(leaf);
406err: 414err:
@@ -408,17 +416,18 @@ err:
408 return ret; 416 return ret;
409} 417}
410 418
411static int find_next_chunk(struct btrfs_root *root, u64 *objectid) 419static int find_next_chunk(struct btrfs_root *root, u64 objectid, u64 *offset)
412{ 420{
413 struct btrfs_path *path; 421 struct btrfs_path *path;
414 int ret; 422 int ret;
415 struct btrfs_key key; 423 struct btrfs_key key;
424 struct btrfs_chunk *chunk;
416 struct btrfs_key found_key; 425 struct btrfs_key found_key;
417 426
418 path = btrfs_alloc_path(); 427 path = btrfs_alloc_path();
419 BUG_ON(!path); 428 BUG_ON(!path);
420 429
421 key.objectid = (u64)-1; 430 key.objectid = objectid;
422 key.offset = (u64)-1; 431 key.offset = (u64)-1;
423 key.type = BTRFS_CHUNK_ITEM_KEY; 432 key.type = BTRFS_CHUNK_ITEM_KEY;
424 433
@@ -430,11 +439,18 @@ static int find_next_chunk(struct btrfs_root *root, u64 *objectid)
430 439
431 ret = btrfs_previous_item(root, path, 0, BTRFS_CHUNK_ITEM_KEY); 440 ret = btrfs_previous_item(root, path, 0, BTRFS_CHUNK_ITEM_KEY);
432 if (ret) { 441 if (ret) {
433 *objectid = 0; 442 *offset = 0;
434 } else { 443 } else {
435 btrfs_item_key_to_cpu(path->nodes[0], &found_key, 444 btrfs_item_key_to_cpu(path->nodes[0], &found_key,
436 path->slots[0]); 445 path->slots[0]);
437 *objectid = found_key.objectid + found_key.offset; 446 if (found_key.objectid != objectid)
447 *offset = 0;
448 else {
449 chunk = btrfs_item_ptr(path->nodes[0], path->slots[0],
450 struct btrfs_chunk);
451 *offset = found_key.offset +
452 btrfs_chunk_length(path->nodes[0], chunk);
453 }
438 } 454 }
439 ret = 0; 455 ret = 0;
440error: 456error:
@@ -520,9 +536,12 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
520 btrfs_set_device_sector_size(leaf, dev_item, device->sector_size); 536 btrfs_set_device_sector_size(leaf, dev_item, device->sector_size);
521 btrfs_set_device_total_bytes(leaf, dev_item, device->total_bytes); 537 btrfs_set_device_total_bytes(leaf, dev_item, device->total_bytes);
522 btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used); 538 btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used);
539 btrfs_set_device_group(leaf, dev_item, 0);
540 btrfs_set_device_seek_speed(leaf, dev_item, 0);
541 btrfs_set_device_bandwidth(leaf, dev_item, 0);
523 542
524 ptr = (unsigned long)btrfs_device_uuid(dev_item); 543 ptr = (unsigned long)btrfs_device_uuid(dev_item);
525 write_extent_buffer(leaf, device->uuid, ptr, BTRFS_DEV_UUID_SIZE); 544 write_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE);
526 btrfs_mark_buffer_dirty(leaf); 545 btrfs_mark_buffer_dirty(leaf);
527 ret = 0; 546 ret = 0;
528 547
@@ -674,7 +693,10 @@ again:
674 return -ENOSPC; 693 return -ENOSPC;
675 } 694 }
676 695
677 ret = find_next_chunk(chunk_root, &key.objectid); 696 key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
697 key.type = BTRFS_CHUNK_ITEM_KEY;
698 ret = find_next_chunk(chunk_root, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
699 &key.offset);
678 if (ret) 700 if (ret)
679 return ret; 701 return ret;
680 702
@@ -696,8 +718,9 @@ again:
696 *num_bytes = calc_size * num_stripes; 718 *num_bytes = calc_size * num_stripes;
697 719
698 index = 0; 720 index = 0;
699printk("new chunk type %Lu start %Lu size %Lu\n", type, key.objectid, *num_bytes); 721printk("new chunk type %Lu start %Lu size %Lu\n", type, key.offset, *num_bytes);
700 while(index < num_stripes) { 722 while(index < num_stripes) {
723 struct btrfs_stripe *stripe;
701 BUG_ON(list_empty(&private_devs)); 724 BUG_ON(list_empty(&private_devs));
702 cur = private_devs.next; 725 cur = private_devs.next;
703 device = list_entry(cur, struct btrfs_device, dev_list); 726 device = list_entry(cur, struct btrfs_device, dev_list);
@@ -708,26 +731,28 @@ printk("new chunk type %Lu start %Lu size %Lu\n", type, key.objectid, *num_bytes
708 list_move_tail(&device->dev_list, dev_list); 731 list_move_tail(&device->dev_list, dev_list);
709 732
710 ret = btrfs_alloc_dev_extent(trans, device, 733 ret = btrfs_alloc_dev_extent(trans, device,
711 key.objectid, 734 info->chunk_root->root_key.objectid,
712 calc_size, &dev_offset); 735 BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset,
736 calc_size, &dev_offset);
713 BUG_ON(ret); 737 BUG_ON(ret);
714printk("alloc chunk start %Lu size %Lu from dev %Lu type %Lu\n", key.objectid, calc_size, device->devid, type); 738printk("alloc chunk start %Lu size %Lu from dev %Lu type %Lu\n", key.offset, calc_size, device->devid, type);
715 device->bytes_used += calc_size; 739 device->bytes_used += calc_size;
716 ret = btrfs_update_device(trans, device); 740 ret = btrfs_update_device(trans, device);
717 BUG_ON(ret); 741 BUG_ON(ret);
718 742
719 map->stripes[index].dev = device; 743 map->stripes[index].dev = device;
720 map->stripes[index].physical = dev_offset; 744 map->stripes[index].physical = dev_offset;
721 btrfs_set_stack_stripe_devid(stripes + index, device->devid); 745 stripe = stripes + index;
722 btrfs_set_stack_stripe_offset(stripes + index, dev_offset); 746 btrfs_set_stack_stripe_devid(stripe, device->devid);
747 btrfs_set_stack_stripe_offset(stripe, dev_offset);
748 memcpy(stripe->dev_uuid, device->uuid, BTRFS_UUID_SIZE);
723 physical = dev_offset; 749 physical = dev_offset;
724 index++; 750 index++;
725 } 751 }
726 BUG_ON(!list_empty(&private_devs)); 752 BUG_ON(!list_empty(&private_devs));
727 753
728 /* key.objectid was set above */ 754 /* key was set above */
729 key.offset = *num_bytes; 755 btrfs_set_stack_chunk_length(chunk, *num_bytes);
730 key.type = BTRFS_CHUNK_ITEM_KEY;
731 btrfs_set_stack_chunk_owner(chunk, extent_root->root_key.objectid); 756 btrfs_set_stack_chunk_owner(chunk, extent_root->root_key.objectid);
732 btrfs_set_stack_chunk_stripe_len(chunk, stripe_len); 757 btrfs_set_stack_chunk_stripe_len(chunk, stripe_len);
733 btrfs_set_stack_chunk_type(chunk, type); 758 btrfs_set_stack_chunk_type(chunk, type);
@@ -745,14 +770,14 @@ printk("alloc chunk start %Lu size %Lu from dev %Lu type %Lu\n", key.objectid, c
745 ret = btrfs_insert_item(trans, chunk_root, &key, chunk, 770 ret = btrfs_insert_item(trans, chunk_root, &key, chunk,
746 btrfs_chunk_item_size(num_stripes)); 771 btrfs_chunk_item_size(num_stripes));
747 BUG_ON(ret); 772 BUG_ON(ret);
748 *start = key.objectid; 773 *start = key.offset;;
749 774
750 em = alloc_extent_map(GFP_NOFS); 775 em = alloc_extent_map(GFP_NOFS);
751 if (!em) 776 if (!em)
752 return -ENOMEM; 777 return -ENOMEM;
753 em->bdev = (struct block_device *)map; 778 em->bdev = (struct block_device *)map;
754 em->start = key.objectid; 779 em->start = key.offset;
755 em->len = key.offset; 780 em->len = *num_bytes;
756 em->block_start = 0; 781 em->block_start = 0;
757 782
758 kfree(chunk); 783 kfree(chunk);
@@ -1056,8 +1081,8 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
1056 int ret; 1081 int ret;
1057 int i; 1082 int i;
1058 1083
1059 logical = key->objectid; 1084 logical = key->offset;
1060 length = key->offset; 1085 length = btrfs_chunk_length(leaf, chunk);
1061 spin_lock(&map_tree->map_tree.lock); 1086 spin_lock(&map_tree->map_tree.lock);
1062 em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); 1087 em = lookup_extent_mapping(&map_tree->map_tree, logical, 1);
1063 spin_unlock(&map_tree->map_tree.lock); 1088 spin_unlock(&map_tree->map_tree.lock);
@@ -1131,7 +1156,7 @@ static int fill_device_from_item(struct extent_buffer *leaf,
1131 device->sector_size = btrfs_device_sector_size(leaf, dev_item); 1156 device->sector_size = btrfs_device_sector_size(leaf, dev_item);
1132 1157
1133 ptr = (unsigned long)btrfs_device_uuid(dev_item); 1158 ptr = (unsigned long)btrfs_device_uuid(dev_item);
1134 read_extent_buffer(leaf, device->uuid, ptr, BTRFS_DEV_UUID_SIZE); 1159 read_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE);
1135 1160
1136 return 0; 1161 return 0;
1137} 1162}
@@ -1143,7 +1168,6 @@ static int read_one_dev(struct btrfs_root *root,
1143 struct btrfs_device *device; 1168 struct btrfs_device *device;
1144 u64 devid; 1169 u64 devid;
1145 int ret; 1170 int ret;
1146
1147 devid = btrfs_device_id(leaf, dev_item); 1171 devid = btrfs_device_id(leaf, dev_item);
1148 device = btrfs_find_device(root, devid); 1172 device = btrfs_find_device(root, devid);
1149 if (!device) { 1173 if (!device) {
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 89548837a1cc..f9cae3072171 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -57,7 +57,7 @@ struct btrfs_device {
57 u64 type; 57 u64 type;
58 58
59 /* physical drive uuid (or lvm uuid) */ 59 /* physical drive uuid (or lvm uuid) */
60 u8 uuid[BTRFS_DEV_UUID_SIZE]; 60 u8 uuid[BTRFS_UUID_SIZE];
61}; 61};
62 62
63struct btrfs_fs_devices { 63struct btrfs_fs_devices {
@@ -93,7 +93,9 @@ struct btrfs_multi_bio {
93 93
94int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, 94int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
95 struct btrfs_device *device, 95 struct btrfs_device *device,
96 u64 owner, u64 num_bytes, u64 *start); 96 u64 chunk_tree, u64 chunk_objectid,
97 u64 chunk_offset,
98 u64 num_bytes, u64 *start);
97int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 99int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
98 u64 logical, u64 *length, 100 u64 logical, u64 *length,
99 struct btrfs_multi_bio **multi_ret, int mirror_num); 101 struct btrfs_multi_bio **multi_ret, int mirror_num);