aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-12-11 16:30:39 -0500
committerChris Mason <chris.mason@oracle.com>2008-12-11 16:30:39 -0500
commitd2fb3437e4d8d12c73c587615ad187d5288547ec (patch)
tree894e4c698970dd35226b2614b8a38fb8a96580e7 /fs/btrfs/inode.c
parentcfc8ea87201dc9bb6aeb3fc80c61abee83e7cc06 (diff)
Btrfs: fix leaking block group on balance
The block group structs are referenced in many different places, and it's not safe to free while balancing. So, those block group structs were simply leaked instead. This patch replaces the block group pointer in the inode with the starting byte offset of the block group and adds reference counting to the block group struct. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c43
1 files changed, 13 insertions, 30 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 932d8c0b2c05..0a28b7706314 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -989,7 +989,6 @@ next_slot:
989 989
990 if (extent_type == BTRFS_FILE_EXTENT_REG || 990 if (extent_type == BTRFS_FILE_EXTENT_REG ||
991 extent_type == BTRFS_FILE_EXTENT_PREALLOC) { 991 extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
992 struct btrfs_block_group_cache *block_group;
993 disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); 992 disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
994 extent_end = found_key.offset + 993 extent_end = found_key.offset +
995 btrfs_file_extent_num_bytes(leaf, fi); 994 btrfs_file_extent_num_bytes(leaf, fi);
@@ -1007,9 +1006,7 @@ next_slot:
1007 goto out_check; 1006 goto out_check;
1008 if (btrfs_cross_ref_exist(trans, root, disk_bytenr)) 1007 if (btrfs_cross_ref_exist(trans, root, disk_bytenr))
1009 goto out_check; 1008 goto out_check;
1010 block_group = btrfs_lookup_block_group(root->fs_info, 1009 if (btrfs_extent_readonly(root, disk_bytenr))
1011 disk_bytenr);
1012 if (!block_group || block_group->ro)
1013 goto out_check; 1010 goto out_check;
1014 disk_bytenr += btrfs_file_extent_offset(leaf, fi); 1011 disk_bytenr += btrfs_file_extent_offset(leaf, fi);
1015 nocow = 1; 1012 nocow = 1;
@@ -1969,16 +1966,11 @@ void btrfs_read_locked_inode(struct inode *inode)
1969 rdev = btrfs_inode_rdev(leaf, inode_item); 1966 rdev = btrfs_inode_rdev(leaf, inode_item);
1970 1967
1971 BTRFS_I(inode)->index_cnt = (u64)-1; 1968 BTRFS_I(inode)->index_cnt = (u64)-1;
1969 BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
1972 1970
1973 alloc_group_block = btrfs_inode_block_group(leaf, inode_item); 1971 alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
1974 BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info, 1972 BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
1975 alloc_group_block); 1973 alloc_group_block, 0);
1976 BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
1977 if (!BTRFS_I(inode)->block_group) {
1978 BTRFS_I(inode)->block_group = btrfs_find_block_group(root,
1979 NULL, 0,
1980 BTRFS_BLOCK_GROUP_METADATA, 0);
1981 }
1982 btrfs_free_path(path); 1974 btrfs_free_path(path);
1983 inode_item = NULL; 1975 inode_item = NULL;
1984 1976
@@ -2048,8 +2040,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
2048 btrfs_set_inode_transid(leaf, item, trans->transid); 2040 btrfs_set_inode_transid(leaf, item, trans->transid);
2049 btrfs_set_inode_rdev(leaf, item, inode->i_rdev); 2041 btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
2050 btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); 2042 btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
2051 btrfs_set_inode_block_group(leaf, item, 2043 btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group);
2052 BTRFS_I(inode)->block_group->key.objectid);
2053} 2044}
2054 2045
2055/* 2046/*
@@ -3358,14 +3349,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3358 struct btrfs_root *root, 3349 struct btrfs_root *root,
3359 struct inode *dir, 3350 struct inode *dir,
3360 const char *name, int name_len, 3351 const char *name, int name_len,
3361 u64 ref_objectid, 3352 u64 ref_objectid, u64 objectid,
3362 u64 objectid, 3353 u64 alloc_hint, int mode, u64 *index)
3363 struct btrfs_block_group_cache *group,
3364 int mode, u64 *index)
3365{ 3354{
3366 struct inode *inode; 3355 struct inode *inode;
3367 struct btrfs_inode_item *inode_item; 3356 struct btrfs_inode_item *inode_item;
3368 struct btrfs_block_group_cache *new_inode_group;
3369 struct btrfs_key *location; 3357 struct btrfs_key *location;
3370 struct btrfs_path *path; 3358 struct btrfs_path *path;
3371 struct btrfs_inode_ref *ref; 3359 struct btrfs_inode_ref *ref;
@@ -3401,13 +3389,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3401 owner = 0; 3389 owner = 0;
3402 else 3390 else
3403 owner = 1; 3391 owner = 1;
3404 new_inode_group = btrfs_find_block_group(root, group, 0, 3392 BTRFS_I(inode)->block_group =
3405 BTRFS_BLOCK_GROUP_METADATA, owner); 3393 btrfs_find_block_group(root, 0, alloc_hint, owner);
3406 if (!new_inode_group) {
3407 printk("find_block group failed\n");
3408 new_inode_group = group;
3409 }
3410 BTRFS_I(inode)->block_group = new_inode_group;
3411 3394
3412 key[0].objectid = objectid; 3395 key[0].objectid = objectid;
3413 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); 3396 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
@@ -4366,16 +4349,16 @@ out:
4366/* 4349/*
4367 * create a new subvolume directory/inode (helper for the ioctl). 4350 * create a new subvolume directory/inode (helper for the ioctl).
4368 */ 4351 */
4369int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry, 4352int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
4370 struct btrfs_trans_handle *trans, u64 new_dirid, 4353 struct btrfs_root *new_root, struct dentry *dentry,
4371 struct btrfs_block_group_cache *block_group) 4354 u64 new_dirid, u64 alloc_hint)
4372{ 4355{
4373 struct inode *inode; 4356 struct inode *inode;
4374 int error; 4357 int error;
4375 u64 index = 0; 4358 u64 index = 0;
4376 4359
4377 inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, 4360 inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
4378 new_dirid, block_group, S_IFDIR | 0700, &index); 4361 new_dirid, alloc_hint, S_IFDIR | 0700, &index);
4379 if (IS_ERR(inode)) 4362 if (IS_ERR(inode))
4380 return PTR_ERR(inode); 4363 return PTR_ERR(inode);
4381 inode->i_op = &btrfs_dir_inode_operations; 4364 inode->i_op = &btrfs_dir_inode_operations;