aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h8
-rw-r--r--fs/btrfs/extent-tree.c39
-rw-r--r--fs/btrfs/sysfs.c5
3 files changed, 36 insertions, 16 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 02895a126ab9..af523d695432 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1123,6 +1123,12 @@ struct btrfs_qgroup_limit_item {
1123 __le64 rsv_excl; 1123 __le64 rsv_excl;
1124} __attribute__ ((__packed__)); 1124} __attribute__ ((__packed__));
1125 1125
1126/* For raid type sysfs entries */
1127struct raid_kobject {
1128 int raid_type;
1129 struct kobject kobj;
1130};
1131
1126struct btrfs_space_info { 1132struct btrfs_space_info {
1127 spinlock_t lock; 1133 spinlock_t lock;
1128 1134
@@ -1173,7 +1179,7 @@ struct btrfs_space_info {
1173 wait_queue_head_t wait; 1179 wait_queue_head_t wait;
1174 1180
1175 struct kobject kobj; 1181 struct kobject kobj;
1176 struct kobject block_group_kobjs[BTRFS_NR_RAID_TYPES]; 1182 struct kobject *block_group_kobjs[BTRFS_NR_RAID_TYPES];
1177}; 1183};
1178 1184
1179#define BTRFS_BLOCK_RSV_GLOBAL 1 1185#define BTRFS_BLOCK_RSV_GLOBAL 1
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 6caddd5970e4..fafb3e53ecde 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3497,10 +3497,8 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
3497 return ret; 3497 return ret;
3498 } 3498 }
3499 3499
3500 for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) { 3500 for (i = 0; i < BTRFS_NR_RAID_TYPES; i++)
3501 INIT_LIST_HEAD(&found->block_groups[i]); 3501 INIT_LIST_HEAD(&found->block_groups[i]);
3502 kobject_init(&found->block_group_kobjs[i], &btrfs_raid_ktype);
3503 }
3504 init_rwsem(&found->groups_sem); 3502 init_rwsem(&found->groups_sem);
3505 spin_lock_init(&found->lock); 3503 spin_lock_init(&found->lock);
3506 found->flags = flags & BTRFS_BLOCK_GROUP_TYPE_MASK; 3504 found->flags = flags & BTRFS_BLOCK_GROUP_TYPE_MASK;
@@ -8586,8 +8584,9 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
8586 list_del(&space_info->list); 8584 list_del(&space_info->list);
8587 for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) { 8585 for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) {
8588 struct kobject *kobj; 8586 struct kobject *kobj;
8589 kobj = &space_info->block_group_kobjs[i]; 8587 kobj = space_info->block_group_kobjs[i];
8590 if (kobj->parent) { 8588 space_info->block_group_kobjs[i] = NULL;
8589 if (kobj) {
8591 kobject_del(kobj); 8590 kobject_del(kobj);
8592 kobject_put(kobj); 8591 kobject_put(kobj);
8593 } 8592 }
@@ -8611,17 +8610,26 @@ static void __link_block_group(struct btrfs_space_info *space_info,
8611 up_write(&space_info->groups_sem); 8610 up_write(&space_info->groups_sem);
8612 8611
8613 if (first) { 8612 if (first) {
8614 struct kobject *kobj = &space_info->block_group_kobjs[index]; 8613 struct raid_kobject *rkobj;
8615 int ret; 8614 int ret;
8616 8615
8617 kobject_get(&space_info->kobj); /* put in release */ 8616 rkobj = kzalloc(sizeof(*rkobj), GFP_NOFS);
8618 ret = kobject_add(kobj, &space_info->kobj, "%s", 8617 if (!rkobj)
8619 get_raid_name(index)); 8618 goto out_err;
8619 rkobj->raid_type = index;
8620 kobject_init(&rkobj->kobj, &btrfs_raid_ktype);
8621 ret = kobject_add(&rkobj->kobj, &space_info->kobj,
8622 "%s", get_raid_name(index));
8620 if (ret) { 8623 if (ret) {
8621 pr_warn("BTRFS: failed to add kobject for block cache. ignoring.\n"); 8624 kobject_put(&rkobj->kobj);
8622 kobject_put(&space_info->kobj); 8625 goto out_err;
8623 } 8626 }
8627 space_info->block_group_kobjs[index] = &rkobj->kobj;
8624 } 8628 }
8629
8630 return;
8631out_err:
8632 pr_warn("BTRFS: failed to add kobject for block cache. ignoring.\n");
8625} 8633}
8626 8634
8627static struct btrfs_block_group_cache * 8635static struct btrfs_block_group_cache *
@@ -8956,6 +8964,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
8956 struct btrfs_root *tree_root = root->fs_info->tree_root; 8964 struct btrfs_root *tree_root = root->fs_info->tree_root;
8957 struct btrfs_key key; 8965 struct btrfs_key key;
8958 struct inode *inode; 8966 struct inode *inode;
8967 struct kobject *kobj = NULL;
8959 int ret; 8968 int ret;
8960 int index; 8969 int index;
8961 int factor; 8970 int factor;
@@ -9055,11 +9064,15 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
9055 */ 9064 */
9056 list_del_init(&block_group->list); 9065 list_del_init(&block_group->list);
9057 if (list_empty(&block_group->space_info->block_groups[index])) { 9066 if (list_empty(&block_group->space_info->block_groups[index])) {
9058 kobject_del(&block_group->space_info->block_group_kobjs[index]); 9067 kobj = block_group->space_info->block_group_kobjs[index];
9059 kobject_put(&block_group->space_info->block_group_kobjs[index]); 9068 block_group->space_info->block_group_kobjs[index] = NULL;
9060 clear_avail_alloc_bits(root->fs_info, block_group->flags); 9069 clear_avail_alloc_bits(root->fs_info, block_group->flags);
9061 } 9070 }
9062 up_write(&block_group->space_info->groups_sem); 9071 up_write(&block_group->space_info->groups_sem);
9072 if (kobj) {
9073 kobject_del(kobj);
9074 kobject_put(kobj);
9075 }
9063 9076
9064 if (block_group->cached == BTRFS_CACHE_STARTED) 9077 if (block_group->cached == BTRFS_CACHE_STARTED)
9065 wait_block_group_cache_done(block_group); 9078 wait_block_group_cache_done(block_group);
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index c0dfda5644f2..df39458f1487 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -254,6 +254,7 @@ static ssize_t global_rsv_reserved_show(struct kobject *kobj,
254BTRFS_ATTR(global_rsv_reserved, 0444, global_rsv_reserved_show); 254BTRFS_ATTR(global_rsv_reserved, 0444, global_rsv_reserved_show);
255 255
256#define to_space_info(_kobj) container_of(_kobj, struct btrfs_space_info, kobj) 256#define to_space_info(_kobj) container_of(_kobj, struct btrfs_space_info, kobj)
257#define to_raid_kobj(_kobj) container_of(_kobj, struct raid_kobject, kobj)
257 258
258static ssize_t raid_bytes_show(struct kobject *kobj, 259static ssize_t raid_bytes_show(struct kobject *kobj,
259 struct kobj_attribute *attr, char *buf); 260 struct kobj_attribute *attr, char *buf);
@@ -266,7 +267,7 @@ static ssize_t raid_bytes_show(struct kobject *kobj,
266{ 267{
267 struct btrfs_space_info *sinfo = to_space_info(kobj->parent); 268 struct btrfs_space_info *sinfo = to_space_info(kobj->parent);
268 struct btrfs_block_group_cache *block_group; 269 struct btrfs_block_group_cache *block_group;
269 int index = kobj - sinfo->block_group_kobjs; 270 int index = to_raid_kobj(kobj)->raid_type;
270 u64 val = 0; 271 u64 val = 0;
271 272
272 down_read(&sinfo->groups_sem); 273 down_read(&sinfo->groups_sem);
@@ -288,7 +289,7 @@ static struct attribute *raid_attributes[] = {
288 289
289static void release_raid_kobj(struct kobject *kobj) 290static void release_raid_kobj(struct kobject *kobj)
290{ 291{
291 kobject_put(kobj->parent); 292 kfree(to_raid_kobj(kobj));
292} 293}
293 294
294struct kobj_type btrfs_raid_ktype = { 295struct kobj_type btrfs_raid_ktype = {