diff options
Diffstat (limited to 'fs/btrfs/qgroup.c')
| -rw-r--r-- | fs/btrfs/qgroup.c | 11 | 
1 files changed, 10 insertions, 1 deletions
| diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 52a7d2fa2284..f41da7ac360d 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -2828,13 +2828,22 @@ cleanup:  }  /* - * called from commit_transaction. Writes all changed qgroups to disk. + * Writes all changed qgroups to disk. + * Called by the transaction commit path and the qgroup assign ioctl.   */  int btrfs_run_qgroups(struct btrfs_trans_handle *trans)  {  	struct btrfs_fs_info *fs_info = trans->fs_info;  	int ret = 0; +	/* +	 * In case we are called from the qgroup assign ioctl, assert that we +	 * are holding the qgroup_ioctl_lock, otherwise we can race with a quota +	 * disable operation (ioctl) and access a freed quota root. +	 */ +	if (trans->transaction->state != TRANS_STATE_COMMIT_DOING) +		lockdep_assert_held(&fs_info->qgroup_ioctl_lock); +  	if (!fs_info->quota_root)  		return ret; |