On Mon, Nov 19, 2018 at 04:20:34PM +0000, fdmanana@xxxxxxxxxx wrote: > From: Filipe Manana <fdmanana@xxxxxxxx> > > We have a race between enabling quotas end subvolume creation that cause > subvolume creation to fail with -EINVAL, and the following diagram shows > how it happens: > > CPU 0 CPU 1 > > btrfs_ioctl() > btrfs_ioctl_quota_ctl() > btrfs_quota_enable() > mutex_lock(fs_info->qgroup_ioctl_lock) > > btrfs_ioctl() > create_subvol() > btrfs_qgroup_inherit() > -> save fs_info->quota_root > into quota_root > -> stores a NULL value > -> tries to lock the mutex > qgroup_ioctl_lock > -> blocks waiting for > the task at CPU0 > > -> sets BTRFS_FS_QUOTA_ENABLED in fs_info > -> sets quota_root in fs_info->quota_root > (non-NULL value) > > mutex_unlock(fs_info->qgroup_ioctl_lock) > > -> checks quota enabled > flag is set > -> returns -EINVAL because > fs_info->quota_root was > NULL before it acquired > the mutex > qgroup_ioctl_lock > -> ioctl returns -EINVAL > > Returning -EINVAL to user space will be confusing if all the arguments > passed to the subvolume creation ioctl were valid. > > Fix it by grabbing the value from fs_info->quota_root after acquiring > the mutex. > > Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx> Reviewed-by: David Sterba <dsterba@xxxxxxxx> Added to misc-next, thanks.
