aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-09-03 09:35:40 -0400
committerChris Mason <clm@fb.com>2014-09-17 16:38:41 -0400
commit15484377f597ca98ee84de87caa13667ea68bb14 (patch)
tree70ccf2e4e260ec20e46e3b477865b71c22949f66 /fs
parentfe48a5c00f3c8087fc0a447caee2b5f9f97cf238 (diff)
Btrfs: fix unprotected device list access when getting the fs information
When we get the fs information, we forgot to acquire the mutex of device list, it might cause the problem we might access a device that was removed. Fix it by acquiring the device list mutex. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/super.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3f1f4e2dc78f..2375f94fb780 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1696,7 +1696,11 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1696 struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; 1696 struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
1697 int ret; 1697 int ret;
1698 1698
1699 /* holding chunk_muext to avoid allocating new chunks */ 1699 /*
1700 * holding chunk_muext to avoid allocating new chunks, holding
1701 * device_list_mutex to avoid the device being removed
1702 */
1703 mutex_lock(&fs_info->fs_devices->device_list_mutex);
1700 mutex_lock(&fs_info->chunk_mutex); 1704 mutex_lock(&fs_info->chunk_mutex);
1701 rcu_read_lock(); 1705 rcu_read_lock();
1702 list_for_each_entry_rcu(found, head, list) { 1706 list_for_each_entry_rcu(found, head, list) {
@@ -1737,11 +1741,13 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1737 ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data); 1741 ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data);
1738 if (ret) { 1742 if (ret) {
1739 mutex_unlock(&fs_info->chunk_mutex); 1743 mutex_unlock(&fs_info->chunk_mutex);
1744 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
1740 return ret; 1745 return ret;
1741 } 1746 }
1742 buf->f_bavail += div_u64(total_free_data, factor); 1747 buf->f_bavail += div_u64(total_free_data, factor);
1743 buf->f_bavail = buf->f_bavail >> bits; 1748 buf->f_bavail = buf->f_bavail >> bits;
1744 mutex_unlock(&fs_info->chunk_mutex); 1749 mutex_unlock(&fs_info->chunk_mutex);
1750 mutex_unlock(&fs_info->fs_devices->device_list_mutex);
1745 1751
1746 buf->f_type = BTRFS_SUPER_MAGIC; 1752 buf->f_type = BTRFS_SUPER_MAGIC;
1747 buf->f_bsize = dentry->d_sb->s_blocksize; 1753 buf->f_bsize = dentry->d_sb->s_blocksize;