diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/super.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8e16bca69c56..18cdcd1dbe11 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1672,6 +1672,21 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | |||
1672 | return 0; | 1672 | return 0; |
1673 | } | 1673 | } |
1674 | 1674 | ||
1675 | /* | ||
1676 | * Calculate numbers for 'df', pessimistic in case of mixed raid profiles. | ||
1677 | * | ||
1678 | * If there's a redundant raid level at DATA block groups, use the respective | ||
1679 | * multiplier to scale the sizes. | ||
1680 | * | ||
1681 | * Unused device space usage is based on simulating the chunk allocator | ||
1682 | * algorithm that respects the device sizes, order of allocations and the | ||
1683 | * 'alloc_start' value, this is a close approximation of the actual use but | ||
1684 | * there are other factors that may change the result (like a new metadata | ||
1685 | * chunk). | ||
1686 | * | ||
1687 | * FIXME: not accurate for mixed block groups, total and free/used are ok, | ||
1688 | * available appears slightly larger. | ||
1689 | */ | ||
1675 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 1690 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
1676 | { | 1691 | { |
1677 | struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); | 1692 | struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); |
@@ -1682,6 +1697,8 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1682 | u64 total_free_data = 0; | 1697 | u64 total_free_data = 0; |
1683 | int bits = dentry->d_sb->s_blocksize_bits; | 1698 | int bits = dentry->d_sb->s_blocksize_bits; |
1684 | __be32 *fsid = (__be32 *)fs_info->fsid; | 1699 | __be32 *fsid = (__be32 *)fs_info->fsid; |
1700 | unsigned factor = 1; | ||
1701 | struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; | ||
1685 | int ret; | 1702 | int ret; |
1686 | 1703 | ||
1687 | /* holding chunk_muext to avoid allocating new chunks */ | 1704 | /* holding chunk_muext to avoid allocating new chunks */ |
@@ -1689,30 +1706,52 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1689 | rcu_read_lock(); | 1706 | rcu_read_lock(); |
1690 | list_for_each_entry_rcu(found, head, list) { | 1707 | list_for_each_entry_rcu(found, head, list) { |
1691 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { | 1708 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { |
1709 | int i; | ||
1710 | |||
1692 | total_free_data += found->disk_total - found->disk_used; | 1711 | total_free_data += found->disk_total - found->disk_used; |
1693 | total_free_data -= | 1712 | total_free_data -= |
1694 | btrfs_account_ro_block_groups_free_space(found); | 1713 | btrfs_account_ro_block_groups_free_space(found); |
1714 | |||
1715 | for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) { | ||
1716 | if (!list_empty(&found->block_groups[i])) { | ||
1717 | switch (i) { | ||
1718 | case BTRFS_RAID_DUP: | ||
1719 | case BTRFS_RAID_RAID1: | ||
1720 | case BTRFS_RAID_RAID10: | ||
1721 | factor = 2; | ||
1722 | } | ||
1723 | } | ||
1724 | } | ||
1695 | } | 1725 | } |
1696 | 1726 | ||
1697 | total_used += found->disk_used; | 1727 | total_used += found->disk_used; |
1698 | } | 1728 | } |
1729 | |||
1699 | rcu_read_unlock(); | 1730 | rcu_read_unlock(); |
1700 | 1731 | ||
1701 | buf->f_namelen = BTRFS_NAME_LEN; | 1732 | buf->f_blocks = div_u64(btrfs_super_total_bytes(disk_super), factor); |
1702 | buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; | 1733 | buf->f_blocks >>= bits; |
1703 | buf->f_bfree = buf->f_blocks - (total_used >> bits); | 1734 | buf->f_bfree = buf->f_blocks - (div_u64(total_used, factor) >> bits); |
1704 | buf->f_bsize = dentry->d_sb->s_blocksize; | 1735 | |
1705 | buf->f_type = BTRFS_SUPER_MAGIC; | 1736 | /* Account global block reserve as used, it's in logical size already */ |
1737 | spin_lock(&block_rsv->lock); | ||
1738 | buf->f_bfree -= block_rsv->size >> bits; | ||
1739 | spin_unlock(&block_rsv->lock); | ||
1740 | |||
1706 | buf->f_bavail = total_free_data; | 1741 | buf->f_bavail = total_free_data; |
1707 | ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); | 1742 | ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); |
1708 | if (ret) { | 1743 | if (ret) { |
1709 | mutex_unlock(&fs_info->chunk_mutex); | 1744 | mutex_unlock(&fs_info->chunk_mutex); |
1710 | return ret; | 1745 | return ret; |
1711 | } | 1746 | } |
1712 | buf->f_bavail += total_free_data; | 1747 | buf->f_bavail += div_u64(total_free_data, factor); |
1713 | buf->f_bavail = buf->f_bavail >> bits; | 1748 | buf->f_bavail = buf->f_bavail >> bits; |
1714 | mutex_unlock(&fs_info->chunk_mutex); | 1749 | mutex_unlock(&fs_info->chunk_mutex); |
1715 | 1750 | ||
1751 | buf->f_type = BTRFS_SUPER_MAGIC; | ||
1752 | buf->f_bsize = dentry->d_sb->s_blocksize; | ||
1753 | buf->f_namelen = BTRFS_NAME_LEN; | ||
1754 | |||
1716 | /* We treat it as constant endianness (it doesn't matter _which_) | 1755 | /* We treat it as constant endianness (it doesn't matter _which_) |
1717 | because we want the fsid to come out the same whether mounted | 1756 | because we want the fsid to come out the same whether mounted |
1718 | on a big-endian or little-endian host */ | 1757 | on a big-endian or little-endian host */ |