diff options
-rw-r--r-- | fs/btrfs/ctree.c | 5 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 45 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 1 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 15 | ||||
-rw-r--r-- | fs/btrfs/super.c | 13 |
5 files changed, 65 insertions, 14 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 1bae035f5171..b4783bf8bf4f 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -68,6 +68,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root | |||
68 | memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); | 68 | memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); |
69 | btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); | 69 | btrfs_set_header_blocknr(&cow_node->header, bh_blocknr(cow)); |
70 | btrfs_set_header_generation(&cow_node->header, trans->transid); | 70 | btrfs_set_header_generation(&cow_node->header, trans->transid); |
71 | btrfs_set_header_owner(&cow_node->header, root->root_key.objectid); | ||
71 | btrfs_inc_ref(trans, root, buf); | 72 | btrfs_inc_ref(trans, root, buf); |
72 | if (buf == root->node) { | 73 | if (buf == root->node) { |
73 | root->node = cow; | 74 | root->node = cow; |
@@ -806,6 +807,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root | |||
806 | btrfs_set_header_level(&c->header, level); | 807 | btrfs_set_header_level(&c->header, level); |
807 | btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); | 808 | btrfs_set_header_blocknr(&c->header, bh_blocknr(t)); |
808 | btrfs_set_header_generation(&c->header, trans->transid); | 809 | btrfs_set_header_generation(&c->header, trans->transid); |
810 | btrfs_set_header_owner(&c->header, root->root_key.objectid); | ||
809 | lower = btrfs_buffer_node(path->nodes[level-1]); | 811 | lower = btrfs_buffer_node(path->nodes[level-1]); |
810 | memcpy(c->header.fsid, root->fs_info->disk_super->fsid, | 812 | memcpy(c->header.fsid, root->fs_info->disk_super->fsid, |
811 | sizeof(c->header.fsid)); | 813 | sizeof(c->header.fsid)); |
@@ -909,6 +911,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | |||
909 | btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); | 911 | btrfs_set_header_level(&split->header, btrfs_header_level(&c->header)); |
910 | btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); | 912 | btrfs_set_header_blocknr(&split->header, bh_blocknr(split_buffer)); |
911 | btrfs_set_header_generation(&split->header, trans->transid); | 913 | btrfs_set_header_generation(&split->header, trans->transid); |
914 | btrfs_set_header_owner(&split->header, root->root_key.objectid); | ||
912 | memcpy(split->header.fsid, root->fs_info->disk_super->fsid, | 915 | memcpy(split->header.fsid, root->fs_info->disk_super->fsid, |
913 | sizeof(split->header.fsid)); | 916 | sizeof(split->header.fsid)); |
914 | mid = (c_nritems + 1) / 2; | 917 | mid = (c_nritems + 1) / 2; |
@@ -1280,6 +1283,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1280 | memset(&right->header, 0, sizeof(right->header)); | 1283 | memset(&right->header, 0, sizeof(right->header)); |
1281 | btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); | 1284 | btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); |
1282 | btrfs_set_header_generation(&right->header, trans->transid); | 1285 | btrfs_set_header_generation(&right->header, trans->transid); |
1286 | btrfs_set_header_owner(&right->header, root->root_key.objectid); | ||
1283 | btrfs_set_header_level(&right->header, 0); | 1287 | btrfs_set_header_level(&right->header, 0); |
1284 | memcpy(right->header.fsid, root->fs_info->disk_super->fsid, | 1288 | memcpy(right->header.fsid, root->fs_info->disk_super->fsid, |
1285 | sizeof(right->header.fsid)); | 1289 | sizeof(right->header.fsid)); |
@@ -1376,6 +1380,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1376 | memset(&right->header, 0, sizeof(right->header)); | 1380 | memset(&right->header, 0, sizeof(right->header)); |
1377 | btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); | 1381 | btrfs_set_header_blocknr(&right->header, bh_blocknr(right_buffer)); |
1378 | btrfs_set_header_generation(&right->header, trans->transid); | 1382 | btrfs_set_header_generation(&right->header, trans->transid); |
1383 | btrfs_set_header_owner(&right->header, root->root_key.objectid); | ||
1379 | btrfs_set_header_level(&right->header, 0); | 1384 | btrfs_set_header_level(&right->header, 0); |
1380 | memcpy(right->header.fsid, root->fs_info->disk_super->fsid, | 1385 | memcpy(right->header.fsid, root->fs_info->disk_super->fsid, |
1381 | sizeof(right->header.fsid)); | 1386 | sizeof(right->header.fsid)); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 681b23933d9b..78248d577290 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -62,6 +62,7 @@ struct btrfs_header { | |||
62 | u8 fsid[16]; /* FS specific uuid */ | 62 | u8 fsid[16]; /* FS specific uuid */ |
63 | __le64 blocknr; /* which block this node is supposed to live in */ | 63 | __le64 blocknr; /* which block this node is supposed to live in */ |
64 | __le64 generation; | 64 | __le64 generation; |
65 | __le64 owner; | ||
65 | __le16 nritems; | 66 | __le16 nritems; |
66 | __le16 flags; | 67 | __le16 flags; |
67 | u8 level; | 68 | u8 level; |
@@ -151,12 +152,17 @@ struct btrfs_path { | |||
151 | int slots[BTRFS_MAX_LEVEL]; | 152 | int slots[BTRFS_MAX_LEVEL]; |
152 | }; | 153 | }; |
153 | 154 | ||
155 | /* values for the type field in btrfs_extent_item */ | ||
156 | #define BTRFS_EXTENT_TREE 1 | ||
157 | #define BTRFS_EXTENT_FILE 2 | ||
154 | /* | 158 | /* |
155 | * items in the extent btree are used to record the objectid of the | 159 | * items in the extent btree are used to record the objectid of the |
156 | * owner of the block and the number of references | 160 | * owner of the block and the number of references |
157 | */ | 161 | */ |
158 | struct btrfs_extent_item { | 162 | struct btrfs_extent_item { |
159 | __le32 refs; | 163 | __le32 refs; |
164 | __le64 owner; | ||
165 | u8 type; | ||
160 | } __attribute__ ((__packed__)); | 166 | } __attribute__ ((__packed__)); |
161 | 167 | ||
162 | struct btrfs_inode_timespec { | 168 | struct btrfs_inode_timespec { |
@@ -473,11 +479,32 @@ static inline void btrfs_set_extent_refs(struct btrfs_extent_item *ei, u32 val) | |||
473 | ei->refs = cpu_to_le32(val); | 479 | ei->refs = cpu_to_le32(val); |
474 | } | 480 | } |
475 | 481 | ||
482 | static inline u64 btrfs_extent_owner(struct btrfs_extent_item *ei) | ||
483 | { | ||
484 | return le64_to_cpu(ei->owner); | ||
485 | } | ||
486 | |||
487 | static inline void btrfs_set_extent_owner(struct btrfs_extent_item *ei, u64 val) | ||
488 | { | ||
489 | ei->owner = cpu_to_le64(val); | ||
490 | } | ||
491 | |||
492 | static inline u8 btrfs_extent_type(struct btrfs_extent_item *ei) | ||
493 | { | ||
494 | return ei->type; | ||
495 | } | ||
496 | |||
497 | static inline void btrfs_set_extent_type(struct btrfs_extent_item *ei, u8 val) | ||
498 | { | ||
499 | ei->type = val; | ||
500 | } | ||
501 | |||
476 | static inline u64 btrfs_node_blockptr(struct btrfs_node *n, int nr) | 502 | static inline u64 btrfs_node_blockptr(struct btrfs_node *n, int nr) |
477 | { | 503 | { |
478 | return le64_to_cpu(n->ptrs[nr].blockptr); | 504 | return le64_to_cpu(n->ptrs[nr].blockptr); |
479 | } | 505 | } |
480 | 506 | ||
507 | |||
481 | static inline void btrfs_set_node_blockptr(struct btrfs_node *n, int nr, | 508 | static inline void btrfs_set_node_blockptr(struct btrfs_node *n, int nr, |
482 | u64 val) | 509 | u64 val) |
483 | { | 510 | { |
@@ -636,6 +663,17 @@ static inline void btrfs_set_header_generation(struct btrfs_header *h, | |||
636 | h->generation = cpu_to_le64(val); | 663 | h->generation = cpu_to_le64(val); |
637 | } | 664 | } |
638 | 665 | ||
666 | static inline u64 btrfs_header_owner(struct btrfs_header *h) | ||
667 | { | ||
668 | return le64_to_cpu(h->owner); | ||
669 | } | ||
670 | |||
671 | static inline void btrfs_set_header_owner(struct btrfs_header *h, | ||
672 | u64 val) | ||
673 | { | ||
674 | h->owner = cpu_to_le64(val); | ||
675 | } | ||
676 | |||
639 | static inline u16 btrfs_header_nritems(struct btrfs_header *h) | 677 | static inline u16 btrfs_header_nritems(struct btrfs_header *h) |
640 | { | 678 | { |
641 | return le16_to_cpu(h->nritems); | 679 | return le16_to_cpu(h->nritems); |
@@ -996,9 +1034,10 @@ int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | |||
996 | struct btrfs_root *root); | 1034 | struct btrfs_root *root); |
997 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1035 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
998 | struct btrfs_root *root); | 1036 | struct btrfs_root *root); |
999 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 1037 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
1000 | *root, u64 num_blocks, u64 search_start, u64 | 1038 | struct btrfs_root *root, u64 owner, |
1001 | search_end, struct btrfs_key *ins); | 1039 | u8 type, u64 num_blocks, u64 search_start, |
1040 | u64 search_end, struct btrfs_key *ins); | ||
1002 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 1041 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1003 | struct buffer_head *buf); | 1042 | struct buffer_head *buf); |
1004 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 1043 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 13046295bf7a..7aff6bb55d91 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -319,6 +319,7 @@ static int __setup_root(int blocksize, | |||
319 | root->last_inode_alloc = 0; | 319 | root->last_inode_alloc = 0; |
320 | memset(&root->root_key, 0, sizeof(root->root_key)); | 320 | memset(&root->root_key, 0, sizeof(root->root_key)); |
321 | memset(&root->root_item, 0, sizeof(root->root_item)); | 321 | memset(&root->root_item, 0, sizeof(root->root_item)); |
322 | root->root_key.objectid = objectid; | ||
322 | return 0; | 323 | return 0; |
323 | } | 324 | } |
324 | 325 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b2faad3e8791..49f7cd6e067c 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -460,9 +460,10 @@ error: | |||
460 | * | 460 | * |
461 | * returns 0 if everything worked, non-zero otherwise. | 461 | * returns 0 if everything worked, non-zero otherwise. |
462 | */ | 462 | */ |
463 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 463 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
464 | *root, u64 num_blocks, u64 search_start, u64 | 464 | struct btrfs_root *root, u64 owner, |
465 | search_end, struct btrfs_key *ins) | 465 | u8 type, u64 num_blocks, u64 search_start, |
466 | u64 search_end, struct btrfs_key *ins) | ||
466 | { | 467 | { |
467 | int ret; | 468 | int ret; |
468 | int pending_ret; | 469 | int pending_ret; |
@@ -472,6 +473,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
472 | struct btrfs_extent_item extent_item; | 473 | struct btrfs_extent_item extent_item; |
473 | 474 | ||
474 | btrfs_set_extent_refs(&extent_item, 1); | 475 | btrfs_set_extent_refs(&extent_item, 1); |
476 | btrfs_set_extent_owner(&extent_item, owner); | ||
477 | btrfs_set_extent_type(&extent_item, type); | ||
475 | 478 | ||
476 | if (root == extent_root) { | 479 | if (root == extent_root) { |
477 | BUG_ON(extent_root->fs_info->current_insert.offset == 0); | 480 | BUG_ON(extent_root->fs_info->current_insert.offset == 0); |
@@ -508,13 +511,15 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
508 | * returns the tree buffer or NULL. | 511 | * returns the tree buffer or NULL. |
509 | */ | 512 | */ |
510 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 513 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
511 | struct btrfs_root *root) | 514 | struct btrfs_root *root) |
512 | { | 515 | { |
513 | struct btrfs_key ins; | 516 | struct btrfs_key ins; |
514 | int ret; | 517 | int ret; |
515 | struct buffer_head *buf; | 518 | struct buffer_head *buf; |
516 | 519 | ||
517 | ret = btrfs_alloc_extent(trans, root, 1, 0, (unsigned long)-1, &ins); | 520 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, |
521 | BTRFS_EXTENT_TREE, | ||
522 | 1, 0, (unsigned long)-1, &ins); | ||
518 | if (ret) { | 523 | if (ret) { |
519 | BUG(); | 524 | BUG(); |
520 | return NULL; | 525 | return NULL; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f99c764a59db..eba239cce212 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1819,8 +1819,9 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
1819 | } | 1819 | } |
1820 | if (inode->i_size >= PAGE_CACHE_SIZE || pos + count < inode->i_size || | 1820 | if (inode->i_size >= PAGE_CACHE_SIZE || pos + count < inode->i_size || |
1821 | pos + count - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) { | 1821 | pos + count - start_pos > BTRFS_MAX_INLINE_DATA_SIZE(root)) { |
1822 | ret = btrfs_alloc_extent(trans, root, num_blocks, 1, | 1822 | ret = btrfs_alloc_extent(trans, root, inode->i_ino, |
1823 | (u64)-1, &ins); | 1823 | BTRFS_EXTENT_FILE, num_blocks, 1, |
1824 | (u64)-1, &ins); | ||
1824 | BUG_ON(ret); | 1825 | BUG_ON(ret); |
1825 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, | 1826 | ret = btrfs_insert_file_extent(trans, root, inode->i_ino, |
1826 | start_pos, ins.objectid, ins.offset); | 1827 | start_pos, ins.objectid, ins.offset); |
@@ -2017,8 +2018,12 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2017 | btrfs_set_header_level(&leaf->header, 0); | 2018 | btrfs_set_header_level(&leaf->header, 0); |
2018 | btrfs_set_header_blocknr(&leaf->header, bh_blocknr(subvol)); | 2019 | btrfs_set_header_blocknr(&leaf->header, bh_blocknr(subvol)); |
2019 | btrfs_set_header_generation(&leaf->header, trans->transid); | 2020 | btrfs_set_header_generation(&leaf->header, trans->transid); |
2021 | btrfs_set_header_owner(&leaf->header, root->root_key.objectid); | ||
2020 | memcpy(leaf->header.fsid, root->fs_info->disk_super->fsid, | 2022 | memcpy(leaf->header.fsid, root->fs_info->disk_super->fsid, |
2021 | sizeof(leaf->header.fsid)); | 2023 | sizeof(leaf->header.fsid)); |
2024 | mark_buffer_dirty(subvol); | ||
2025 | brelse(subvol); | ||
2026 | subvol = NULL; | ||
2022 | 2027 | ||
2023 | inode_item = &root_item.inode; | 2028 | inode_item = &root_item.inode; |
2024 | memset(inode_item, 0, sizeof(*inode_item)); | 2029 | memset(inode_item, 0, sizeof(*inode_item)); |
@@ -2031,10 +2036,6 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen) | |||
2031 | btrfs_set_root_blocknr(&root_item, bh_blocknr(subvol)); | 2036 | btrfs_set_root_blocknr(&root_item, bh_blocknr(subvol)); |
2032 | btrfs_set_root_refs(&root_item, 1); | 2037 | btrfs_set_root_refs(&root_item, 1); |
2033 | 2038 | ||
2034 | mark_buffer_dirty(subvol); | ||
2035 | brelse(subvol); | ||
2036 | subvol = NULL; | ||
2037 | |||
2038 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | 2039 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, |
2039 | 0, &objectid); | 2040 | 0, &objectid); |
2040 | BUG_ON(ret); | 2041 | BUG_ON(ret); |