Btrfs: use seqlock to protect fs_info->avail_{data, metadata, system}_alloc_bits
PATCH 9/11 Btrfs: use seqlock to protect fs_info->avail_{data, metadata, system}_alloc_bits
There is no lock to protect fs_info->avail_{data, metadata, system}_alloc_bits, it may introduce some problem, such as the wrong profile information, so we add a seqlock to protect them.
Signed-off-by Zhao Lei <[email protected]>
Signed-off-by Miao Xie <[email protected]>
--- fs/btrfs/ctree.h | 2 ++ fs/btrfs/disk-io.c | 1 + fs/btrfs/extent-tree.c | 22 ++++++++++++++------ fs/btrfs/volumes.c | 56 +++++++++++++++++++++++++++----------------------- 4 files changed, 49 insertions(+), 32 deletions(-)
fs/btrfs/ctree.h +2 -0
@@ -1474,6 +1474,8 @@ struct btrfs_fs_info {struct rb_root defrag_inodes;atomic_t defrag_running; +/* Used to protect avail_{data, metadata, system}_alloc_bits */ +seqlock_t profiles_lock;/* * these three are in extended format (availability of single * chunks is denoted by BTRFS_AVAIL_ALLOC_BIT_SINGLE bit, other
fs/btrfs/disk-io.c +1 -0
@@ -2036,6 +2036,7 @@ int open_ctree(struct super_block *sb,spin_lock_init (&fs_info->tree_mod_seq_lock);rwlock_init (&fs_info->tree_mod_log_lock);mutex_init (&fs_info->reloc_mutex); +seqlock_init (&fs_info->profiles_lock);init_completion (&fs_info->kobj_unregister);INIT_LIST_HEAD (&fs_info->dirty_cowonly_roots);
fs/btrfs/extent-tree.c +16 -6
@@ -3229,12 +3229,14 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)u64 extra_flags =chunk_to_extended (flags) &BTRFS_EXTENDED_PROFILE_MASK ; +write_seqlock (&fs_info->profiles_lock);if (flags &BTRFS_BLOCK_GROUP_DATA ) fs_info->avail_data_alloc_bits |= extra_flags;if (flags &BTRFS_BLOCK_GROUP_METADATA ) fs_info->avail_metadata_alloc_bits |= extra_flags;if (flags &BTRFS_BLOCK_GROUP_SYSTEM ) fs_info->avail_system_alloc_bits |= extra_flags; +write_sequnlock (&fs_info->profiles_lock); }/*
@@ -3326,12 +3328,18 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)static u64 get_alloc_profile (struct btrfs_root *root,u64 flags) { -if (flags &BTRFS_BLOCK_GROUP_DATA ) - flags |= root->fs_info->avail_data_alloc_bits; -else if (flags &BTRFS_BLOCK_GROUP_SYSTEM ) - flags |= root->fs_info->avail_system_alloc_bits; -else if (flags &BTRFS_BLOCK_GROUP_METADATA ) - flags |= root->fs_info->avail_metadata_alloc_bits; +unsigned seq; + +do { + seq =read_seqbegin (&root->fs_info->profiles_lock); + +if (flags &BTRFS_BLOCK_GROUP_DATA ) + flags |= root->fs_info->avail_data_alloc_bits; +else if (flags &BTRFS_BLOCK_GROUP_SYSTEM ) + flags |= root->fs_info->avail_system_alloc_bits; +else if (flags &BTRFS_BLOCK_GROUP_METADATA ) + flags |= root->fs_info->avail_metadata_alloc_bits; + }while (read_seqretry (&root->fs_info->profiles_lock, seq));return btrfs_reduce_alloc_profile (root, flags); }
@@ -7963,12 +7971,14 @@ static void clear_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)u64 extra_flags =chunk_to_extended (flags) &BTRFS_EXTENDED_PROFILE_MASK ; +write_seqlock (&fs_info->profiles_lock);if (flags &BTRFS_BLOCK_GROUP_DATA ) fs_info->avail_data_alloc_bits &= ~extra_flags;if (flags &BTRFS_BLOCK_GROUP_METADATA ) fs_info->avail_metadata_alloc_bits &= ~extra_flags;if (flags &BTRFS_BLOCK_GROUP_SYSTEM ) fs_info->avail_system_alloc_bits &= ~extra_flags; +write_sequnlock (&fs_info->profiles_lock); } int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
fs/btrfs/volumes.c +30 -26
92 lines not on this page · raw message
Signature · 1 line
1.7.11.7