diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-04-30 15:25:45 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-04-30 15:25:45 -0400 |
commit | 31f3c99b73483f7b738a886c552050cbd6128ff3 (patch) | |
tree | 35c961e01b8fe25525b9ac4a691fd931ac1dbe59 /fs/btrfs/super.c | |
parent | 308535a05e4c39d2be26e0aeee722682deeb6f77 (diff) |
Btrfs: allocator improvements, inode block groups
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 53 |
1 files changed, 44 insertions, 9 deletions
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 | ||