btrfs: defer adding raid type kobject until after chunk relocation
Any time the first block group of a new type is created, we add a new kobject to sysfs to hold the attributes for that type. Kobject-internal allocations always use GFP_KERNEL, making them prone to fs-reclaim races. While it appears as if this can occur any time a block group is created, the only times the first block group of a new type can be created in memory is at mount and when we create the first new block group during raid conversion. This patch adds a new list to track pending kobject additions and then handles them after we do chunk relocation. Between relocating the target chunk (or forcing allocation of a new chunk in the case of data) and removing the old chunk, we're in a safe place for fs-reclaim to occur. We're holding the volume mutex, which is already held across page faults, and the delete_unused_bgs_mutex, which will only stall the cleaner thread. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:

committed by
David Sterba

parent
dc2d3005d2
commit
75cb379d26
@@ -385,8 +385,9 @@ struct btrfs_dev_replace {
|
||||
|
||||
/* For raid type sysfs entries */
|
||||
struct raid_kobject {
|
||||
int raid_type;
|
||||
u64 flags;
|
||||
struct kobject kobj;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct btrfs_space_info {
|
||||
@@ -940,6 +941,8 @@ struct btrfs_fs_info {
|
||||
u32 thread_pool_size;
|
||||
|
||||
struct kobject *space_info_kobj;
|
||||
struct list_head pending_raid_kobjs;
|
||||
spinlock_t pending_raid_kobjs_lock; /* uncontended */
|
||||
|
||||
u64 total_pinned;
|
||||
|
||||
@@ -2700,6 +2703,7 @@ int btrfs_can_relocate(struct btrfs_fs_info *fs_info, u64 bytenr);
|
||||
int btrfs_make_block_group(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info, u64 bytes_used,
|
||||
u64 type, u64 chunk_offset, u64 size);
|
||||
void btrfs_add_raid_kobjects(struct btrfs_fs_info *fs_info);
|
||||
struct btrfs_trans_handle *btrfs_start_trans_remove_block_group(
|
||||
struct btrfs_fs_info *fs_info,
|
||||
const u64 chunk_offset);
|
||||
|
Reference in New Issue
Block a user