On Mon, Nov 19, 2018 at 04:20:34PM +0000, fdman...@kernel.org wrote: > From: Filipe Manana <fdman...@suse.com> > > 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 <fdman...@suse.com>
Reviewed-by: David Sterba <dste...@suse.com> Added to misc-next, thanks.