diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 9 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 20 |
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 | ||
| 992 | enum btrfs_raid_types { | 993 | enum 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 | ||
