aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:47 -0500
committerIlya Dryomov <idryomov@gmail.com>2012-01-16 15:04:47 -0500
commita46d11a8b06dd0431a3888fbc4856ea13a8e634f (patch)
tree2aebc4d3ef2318a08cb067bb4a597a51e2455a65 /fs
parent52ba692972532f8d652080214b6599ece3dd51b9 (diff)
Btrfs: add BTRFS_AVAIL_ALLOC_BIT_SINGLE bit
Right now on-disk BTRFS_BLOCK_GROUP_* profile bits are used for avail_{data,metadata,system}_alloc_bits fields, which gather info about available allocation profiles in the FS. When chunk is created or read from disk, its profile is OR'ed with the corresponding avail_alloc_bits field. Since SINGLE is denoted by 0 in the on-disk format, currently there is no way to tell when such chunks become avaialble. Restriper needs that information, so add a separate bit for SINGLE profile. This bit is going to be in-memory only, it should never be written out to disk, so it's not a disk format change. However to avoid remappings in future, reserve corresponding on-disk bit. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h15
-rw-r--r--fs/btrfs/extent-tree.c30
2 files changed, 36 insertions, 9 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 4370a56fe81a..3f8f11e18b53 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -758,6 +758,7 @@ struct btrfs_csum_item {
758#define BTRFS_BLOCK_GROUP_RAID1 (1ULL << 4) 758#define BTRFS_BLOCK_GROUP_RAID1 (1ULL << 4)
759#define BTRFS_BLOCK_GROUP_DUP (1ULL << 5) 759#define BTRFS_BLOCK_GROUP_DUP (1ULL << 5)
760#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6) 760#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
761#define BTRFS_BLOCK_GROUP_RESERVED BTRFS_AVAIL_ALLOC_BIT_SINGLE
761#define BTRFS_NR_RAID_TYPES 5 762#define BTRFS_NR_RAID_TYPES 5
762 763
763#define BTRFS_BLOCK_GROUP_TYPE_MASK (BTRFS_BLOCK_GROUP_DATA | \ 764#define BTRFS_BLOCK_GROUP_TYPE_MASK (BTRFS_BLOCK_GROUP_DATA | \
@@ -768,6 +769,15 @@ struct btrfs_csum_item {
768 BTRFS_BLOCK_GROUP_RAID1 | \ 769 BTRFS_BLOCK_GROUP_RAID1 | \
769 BTRFS_BLOCK_GROUP_DUP | \ 770 BTRFS_BLOCK_GROUP_DUP | \
770 BTRFS_BLOCK_GROUP_RAID10) 771 BTRFS_BLOCK_GROUP_RAID10)
772/*
773 * We need a bit for restriper to be able to tell when chunks of type
774 * SINGLE are available. This "extended" profile format is used in
775 * fs_info->avail_*_alloc_bits (in-memory) and balance item fields
776 * (on-disk). The corresponding on-disk bit in chunk.type is reserved
777 * to avoid remappings between two formats in future.
778 */
779#define BTRFS_AVAIL_ALLOC_BIT_SINGLE (1ULL << 48)
780
771struct btrfs_block_group_item { 781struct btrfs_block_group_item {
772 __le64 used; 782 __le64 used;
773 __le64 chunk_objectid; 783 __le64 chunk_objectid;
@@ -1140,6 +1150,11 @@ struct btrfs_fs_info {
1140 spinlock_t ref_cache_lock; 1150 spinlock_t ref_cache_lock;
1141 u64 total_ref_cache_size; 1151 u64 total_ref_cache_size;
1142 1152
1153 /*
1154 * these three are in extended format (availability of single
1155 * chunks is denoted by BTRFS_AVAIL_ALLOC_BIT_SINGLE bit, other
1156 * types are denoted by corresponding BTRFS_BLOCK_GROUP_* bits)
1157 */
1143 u64 avail_data_alloc_bits; 1158 u64 avail_data_alloc_bits;
1144 u64 avail_metadata_alloc_bits; 1159 u64 avail_metadata_alloc_bits;
1145 u64 avail_system_alloc_bits; 1160 u64 avail_system_alloc_bits;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a8d8204188d1..15a22949da17 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3014,16 +3014,24 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
3014static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) 3014static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
3015{ 3015{
3016 u64 extra_flags = flags & BTRFS_BLOCK_GROUP_PROFILE_MASK; 3016 u64 extra_flags = flags & BTRFS_BLOCK_GROUP_PROFILE_MASK;
3017 if (extra_flags) { 3017
3018 if (flags & BTRFS_BLOCK_GROUP_DATA) 3018 /* chunk -> extended profile */
3019 fs_info->avail_data_alloc_bits |= extra_flags; 3019 if (extra_flags == 0)
3020 if (flags & BTRFS_BLOCK_GROUP_METADATA) 3020 extra_flags = BTRFS_AVAIL_ALLOC_BIT_SINGLE;
3021 fs_info->avail_metadata_alloc_bits |= extra_flags; 3021
3022 if (flags & BTRFS_BLOCK_GROUP_SYSTEM) 3022 if (flags & BTRFS_BLOCK_GROUP_DATA)
3023 fs_info->avail_system_alloc_bits |= extra_flags; 3023 fs_info->avail_data_alloc_bits |= extra_flags;
3024 } 3024 if (flags & BTRFS_BLOCK_GROUP_METADATA)
3025 fs_info->avail_metadata_alloc_bits |= extra_flags;
3026 if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
3027 fs_info->avail_system_alloc_bits |= extra_flags;
3025} 3028}
3026 3029
3030/*
3031 * @flags: available profiles in extended format (see ctree.h)
3032 *
3033 * Returns reduced profile in chunk format.
3034 */
3027u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) 3035u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
3028{ 3036{
3029 /* 3037 /*
@@ -3053,8 +3061,12 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
3053 if ((flags & BTRFS_BLOCK_GROUP_RAID0) && 3061 if ((flags & BTRFS_BLOCK_GROUP_RAID0) &&
3054 ((flags & BTRFS_BLOCK_GROUP_RAID1) | 3062 ((flags & BTRFS_BLOCK_GROUP_RAID1) |
3055 (flags & BTRFS_BLOCK_GROUP_RAID10) | 3063 (flags & BTRFS_BLOCK_GROUP_RAID10) |
3056 (flags & BTRFS_BLOCK_GROUP_DUP))) 3064 (flags & BTRFS_BLOCK_GROUP_DUP))) {
3057 flags &= ~BTRFS_BLOCK_GROUP_RAID0; 3065 flags &= ~BTRFS_BLOCK_GROUP_RAID0;
3066 }
3067
3068 /* extended -> chunk profile */
3069 flags &= ~BTRFS_AVAIL_ALLOC_BIT_SINGLE;
3058 return flags; 3070 return flags;
3059} 3071}
3060 3072