aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2014-02-07 08:34:12 -0500
committerChris Mason <clm@fb.com>2014-04-07 13:41:53 -0400
commit36523e95129c0e69bf1592cd009261b1c6d96e77 (patch)
treef210c9e347318a954dec2e7a4d367f76ebf0da9e
parent800ee2247f483b6d05ed47ef3bbc90b56451746c (diff)
btrfs: export global block reserve size as space_info
Introduce a block group type bit for a global reserve and fill the space info for SPACE_INFO ioctl. This should replace the newly added ioctl (01e219e8069516cdb98594d417b8bb8d906ed30d) to get just the 'size' part of the global reserve, while the actual usage can be now visible in the 'btrfs fi df' output during ENOSPC stress. The unpatched userspace tools will show the blockgroup as 'unknown'. CC: Jeff Mahoney <jeffm@suse.com> CC: Josef Bacik <jbacik@fb.com> Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/ctree.h9
-rw-r--r--fs/btrfs/ioctl.c20
2 files changed, 28 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index d8a669ed5506..ad1a5943a923 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -987,7 +987,8 @@ struct btrfs_dev_replace_item {
987#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6) 987#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
988#define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7) 988#define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7)
989#define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8) 989#define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8)
990#define BTRFS_BLOCK_GROUP_RESERVED BTRFS_AVAIL_ALLOC_BIT_SINGLE 990#define BTRFS_BLOCK_GROUP_RESERVED (BTRFS_AVAIL_ALLOC_BIT_SINGLE | \
991 BTRFS_SPACE_INFO_GLOBAL_RSV)
991 992
992enum btrfs_raid_types { 993enum btrfs_raid_types {
993 BTRFS_RAID_RAID10, 994 BTRFS_RAID_RAID10,
@@ -1019,6 +1020,12 @@ enum btrfs_raid_types {
1019 */ 1020 */
1020#define BTRFS_AVAIL_ALLOC_BIT_SINGLE (1ULL << 48) 1021#define BTRFS_AVAIL_ALLOC_BIT_SINGLE (1ULL << 48)
1021 1022
1023/*
1024 * A fake block group type that is used to communicate global block reserve
1025 * size to userspace via the SPACE_INFO ioctl.
1026 */
1027#define BTRFS_SPACE_INFO_GLOBAL_RSV (1ULL << 49)
1028
1022#define BTRFS_EXTENDED_PROFILE_MASK (BTRFS_BLOCK_GROUP_PROFILE_MASK | \ 1029#define BTRFS_EXTENDED_PROFILE_MASK (BTRFS_BLOCK_GROUP_PROFILE_MASK | \
1023 BTRFS_AVAIL_ALLOC_BIT_SINGLE) 1030 BTRFS_AVAIL_ALLOC_BIT_SINGLE)
1024 1031
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 89d5db7eb452..f2e8fcc279a3 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3562,6 +3562,11 @@ static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
3562 up_read(&info->groups_sem); 3562 up_read(&info->groups_sem);
3563 } 3563 }
3564 3564
3565 /*
3566 * Global block reserve, exported as a space_info
3567 */
3568 slot_count++;
3569
3565 /* space_slots == 0 means they are asking for a count */ 3570 /* space_slots == 0 means they are asking for a count */
3566 if (space_args.space_slots == 0) { 3571 if (space_args.space_slots == 0) {
3567 space_args.total_spaces = slot_count; 3572 space_args.total_spaces = slot_count;
@@ -3620,6 +3625,21 @@ static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
3620 up_read(&info->groups_sem); 3625 up_read(&info->groups_sem);
3621 } 3626 }
3622 3627
3628 /*
3629 * Add global block reserve
3630 */
3631 if (slot_count) {
3632 struct btrfs_block_rsv *block_rsv = &root->fs_info->global_block_rsv;
3633
3634 spin_lock(&block_rsv->lock);
3635 space.total_bytes = block_rsv->size;
3636 space.used_bytes = block_rsv->size - block_rsv->reserved;
3637 spin_unlock(&block_rsv->lock);
3638 space.flags = BTRFS_SPACE_INFO_GLOBAL_RSV;
3639 memcpy(dest, &space, sizeof(space));
3640 space_args.total_spaces++;
3641 }
3642
3623 user_dest = (struct btrfs_ioctl_space_info __user *) 3643 user_dest = (struct btrfs_ioctl_space_info __user *)
3624 (arg + sizeof(struct btrfs_ioctl_space_args)); 3644 (arg + sizeof(struct btrfs_ioctl_space_args));
3625 3645