Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15484377 authored by Miao Xie's avatar Miao Xie Committed by Chris Mason
Browse files

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: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent fe48a5c0
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1696,7 +1696,11 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
	struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
	int ret;

	/* holding chunk_muext to avoid allocating new chunks */
	/*
	 * holding chunk_muext to avoid allocating new chunks, holding
	 * device_list_mutex to avoid the device being removed
	 */
	mutex_lock(&fs_info->fs_devices->device_list_mutex);
	mutex_lock(&fs_info->chunk_mutex);
	rcu_read_lock();
	list_for_each_entry_rcu(found, head, list) {
@@ -1737,11 +1741,13 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
	ret = btrfs_calc_avail_data_space(fs_info->tree_root, &total_free_data);
	if (ret) {
		mutex_unlock(&fs_info->chunk_mutex);
		mutex_unlock(&fs_info->fs_devices->device_list_mutex);
		return ret;
	}
	buf->f_bavail += div_u64(total_free_data, factor);
	buf->f_bavail = buf->f_bavail >> bits;
	mutex_unlock(&fs_info->chunk_mutex);
	mutex_unlock(&fs_info->fs_devices->device_list_mutex);

	buf->f_type = BTRFS_SUPER_MAGIC;
	buf->f_bsize = dentry->d_sb->s_blocksize;