aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-09-03 09:35:42 -0400
committerChris Mason <clm@fb.com>2014-09-17 16:38:43 -0400
commitadbbb8631beda8e4e5d2c964b8b47e04cfa0a2ae (patch)
tree4ee13e368464d455415919b0d52ca75defa4ff3e /fs/btrfs/volumes.c
parent2196d6e8a71fc901e31c1d81581fc6cc6c64913e (diff)
Btrfs: fix unprotected device list access when cloning fs devices
We can build a new filesystem based a seed filesystem, and we need clone the fs devices when we open the new filesystem. But someone might clear the seed flag of the seed filesystem, then mount that filesystem and remove some device. If we mount the new filesystem, we might access a device list which was being changed when we clone the fs devices. Fix it. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 105c5fe004db..d28e1761fdeb 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -583,6 +583,7 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
583 if (IS_ERR(fs_devices)) 583 if (IS_ERR(fs_devices))
584 return fs_devices; 584 return fs_devices;
585 585
586 mutex_lock(&orig->device_list_mutex);
586 fs_devices->total_devices = orig->total_devices; 587 fs_devices->total_devices = orig->total_devices;
587 588
588 /* We have held the volume lock, it is safe to get the devices. */ 589 /* We have held the volume lock, it is safe to get the devices. */
@@ -611,8 +612,10 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
611 device->fs_devices = fs_devices; 612 device->fs_devices = fs_devices;
612 fs_devices->num_devices++; 613 fs_devices->num_devices++;
613 } 614 }
615 mutex_unlock(&orig->device_list_mutex);
614 return fs_devices; 616 return fs_devices;
615error: 617error:
618 mutex_unlock(&orig->device_list_mutex);
616 free_fs_devices(fs_devices); 619 free_fs_devices(fs_devices);
617 return ERR_PTR(-ENOMEM); 620 return ERR_PTR(-ENOMEM);
618} 621}