aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/super.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 54bd91ece35b..dc337d14ef5c 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1644,8 +1644,20 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
1644 int i = 0, nr_devices; 1644 int i = 0, nr_devices;
1645 int ret; 1645 int ret;
1646 1646
1647 /*
1648 * We aren't under the device list lock, so this is racey-ish, but good
1649 * enough for our purposes.
1650 */
1647 nr_devices = fs_info->fs_devices->open_devices; 1651 nr_devices = fs_info->fs_devices->open_devices;
1648 BUG_ON(!nr_devices); 1652 if (!nr_devices) {
1653 smp_mb();
1654 nr_devices = fs_info->fs_devices->open_devices;
1655 ASSERT(nr_devices);
1656 if (!nr_devices) {
1657 *free_bytes = 0;
1658 return 0;
1659 }
1660 }
1649 1661
1650 devices_info = kmalloc_array(nr_devices, sizeof(*devices_info), 1662 devices_info = kmalloc_array(nr_devices, sizeof(*devices_info),
1651 GFP_NOFS); 1663 GFP_NOFS);
@@ -1670,11 +1682,17 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
1670 else 1682 else
1671 min_stripe_size = BTRFS_STRIPE_LEN; 1683 min_stripe_size = BTRFS_STRIPE_LEN;
1672 1684
1673 list_for_each_entry(device, &fs_devices->devices, dev_list) { 1685 if (fs_info->alloc_start)
1686 mutex_lock(&fs_devices->device_list_mutex);
1687 rcu_read_lock();
1688 list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) {
1674 if (!device->in_fs_metadata || !device->bdev || 1689 if (!device->in_fs_metadata || !device->bdev ||
1675 device->is_tgtdev_for_dev_replace) 1690 device->is_tgtdev_for_dev_replace)
1676 continue; 1691 continue;
1677 1692
1693 if (i >= nr_devices)
1694 break;
1695
1678 avail_space = device->total_bytes - device->bytes_used; 1696 avail_space = device->total_bytes - device->bytes_used;
1679 1697
1680 /* align with stripe_len */ 1698 /* align with stripe_len */
@@ -1689,24 +1707,32 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
1689 skip_space = 1024 * 1024; 1707 skip_space = 1024 * 1024;
1690 1708
1691 /* user can set the offset in fs_info->alloc_start. */ 1709 /* user can set the offset in fs_info->alloc_start. */
1692 if (fs_info->alloc_start + BTRFS_STRIPE_LEN <= 1710 if (fs_info->alloc_start &&
1693 device->total_bytes) 1711 fs_info->alloc_start + BTRFS_STRIPE_LEN <=
1712 device->total_bytes) {
1713 rcu_read_unlock();
1694 skip_space = max(fs_info->alloc_start, skip_space); 1714 skip_space = max(fs_info->alloc_start, skip_space);
1695 1715
1696 /* 1716 /*
1697 * btrfs can not use the free space in [0, skip_space - 1], 1717 * btrfs can not use the free space in
1698 * we must subtract it from the total. In order to implement 1718 * [0, skip_space - 1], we must subtract it from the
1699 * it, we account the used space in this range first. 1719 * total. In order to implement it, we account the used
1700 */ 1720 * space in this range first.
1701 ret = btrfs_account_dev_extents_size(device, 0, skip_space - 1, 1721 */
1702 &used_space); 1722 ret = btrfs_account_dev_extents_size(device, 0,
1703 if (ret) { 1723 skip_space - 1,
1704 kfree(devices_info); 1724 &used_space);
1705 return ret; 1725 if (ret) {
1706 } 1726 kfree(devices_info);
1727 mutex_unlock(&fs_devices->device_list_mutex);
1728 return ret;
1729 }
1707 1730
1708 /* calc the free space in [0, skip_space - 1] */ 1731 rcu_read_lock();
1709 skip_space -= used_space; 1732
1733 /* calc the free space in [0, skip_space - 1] */
1734 skip_space -= used_space;
1735 }
1710 1736
1711 /* 1737 /*
1712 * we can use the free space in [0, skip_space - 1], subtract 1738 * we can use the free space in [0, skip_space - 1], subtract
@@ -1725,6 +1751,9 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
1725 1751
1726 i++; 1752 i++;
1727 } 1753 }
1754 rcu_read_unlock();
1755 if (fs_info->alloc_start)
1756 mutex_unlock(&fs_devices->device_list_mutex);
1728 1757
1729 nr_devices = i; 1758 nr_devices = i;
1730 1759
@@ -1787,8 +1816,6 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1787 * holding chunk_muext to avoid allocating new chunks, holding 1816 * holding chunk_muext to avoid allocating new chunks, holding
1788 * device_list_mutex to avoid the device being removed 1817 * device_list_mutex to avoid the device being removed
1789 */ 1818 */
1790 mutex_lock(&fs_info->fs_devices->device_list_mutex);
1791 mutex_lock(&fs_info->chunk_mutex);
1792 rcu_read_lock(); 1819 rcu_read_lock();
1793 list_for_each_entry_rcu(found, head, list) { 1820 list_for_each_entry_rcu(found, head, list) {
1794 if (found->flags & BTRFS_BLOCK_GROUP_DATA) { 1821 if (found->flags & BTRFS_BLOCK_GROUP_DATA) {
@@ -1826,15 +1853,10 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1826 1853
1827 buf->f_bavail = total_free_data; 1854 buf->f_bavail = total_free_data;
1828 ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); 1855 ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data);
1829 if (ret) { 1856 if (ret)
1830 mutex_unlock(&fs_info->chunk_mutex);
1831 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
1832 return ret; 1857 return ret;
1833 }
1834 buf->f_bavail += div_u64(total_free_data, factor); 1858 buf->f_bavail += div_u64(total_free_data, factor);
1835 buf->f_bavail = buf->f_bavail >> bits; 1859 buf->f_bavail = buf->f_bavail >> bits;
1836 mutex_unlock(&fs_info->chunk_mutex);
1837 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
1838 1860
1839 buf->f_type = BTRFS_SUPER_MAGIC; 1861 buf->f_type = BTRFS_SUPER_MAGIC;
1840 buf->f_bsize = dentry->d_sb->s_blocksize; 1862 buf->f_bsize = dentry->d_sb->s_blocksize;