diff options
| author | Filipe Manana <fdmanana@suse.com> | 2018-11-19 19:20:34 +0300 | 
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2018-11-22 20:59:59 +0300 | 
| commit | 552f0329c75b3e1d7f9bb8c9e421d37403f192cd (patch) | |
| tree | cb799ff55538719eea3aa5b7922d473f832f4622 /scripts/gcc-plugins/cyc_complexity_plugin.c | |
| parent | a4390aee72713d9e73f1132bcdeb17d72fbbf974 (diff) | |
| download | linux-552f0329c75b3e1d7f9bb8c9e421d37403f192cd.tar.xz | |
Btrfs: fix race between enabling quotas and subvolume creation
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.
CC: stable@vger.kernel.org # 4.4+
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'scripts/gcc-plugins/cyc_complexity_plugin.c')
0 files changed, 0 insertions, 0 deletions
