diff options
Diffstat (limited to 'fs/quota/dquot.c')
| -rw-r--r-- | fs/quota/dquot.c | 30 | 
1 files changed, 19 insertions, 11 deletions
| diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 8381db9db6d9..9f78b5015f2e 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   * Implementation of the diskquota system for the LINUX operating system. QUOTA   * is implemented using the BSD system call interface as the means of @@ -1297,21 +1298,18 @@ static int dquot_add_space(struct dquot *dquot, qsize_t space,  	spin_lock(&dquot->dq_dqb_lock);  	if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) ||  	    test_bit(DQ_FAKE_B, &dquot->dq_flags)) -		goto add; +		goto finish;  	tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace  		+ space + rsv_space; -	if (flags & DQUOT_SPACE_NOFAIL) -		goto add; -  	if (dquot->dq_dqb.dqb_bhardlimit &&  	    tspace > dquot->dq_dqb.dqb_bhardlimit &&              !ignore_hardlimit(dquot)) {  		if (flags & DQUOT_SPACE_WARN)  			prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN);  		ret = -EDQUOT; -		goto out; +		goto finish;  	}  	if (dquot->dq_dqb.dqb_bsoftlimit && @@ -1322,7 +1320,7 @@ static int dquot_add_space(struct dquot *dquot, qsize_t space,  		if (flags & DQUOT_SPACE_WARN)  			prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN);  		ret = -EDQUOT; -		goto out; +		goto finish;  	}  	if (dquot->dq_dqb.dqb_bsoftlimit && @@ -1338,13 +1336,21 @@ static int dquot_add_space(struct dquot *dquot, qsize_t space,  			 * be always printed  			 */  			ret = -EDQUOT; -			goto out; +			goto finish;  		}  	} -add: -	dquot->dq_dqb.dqb_rsvspace += rsv_space; -	dquot->dq_dqb.dqb_curspace += space; -out: +finish: +	/* +	 * We have to be careful and go through warning generation & grace time +	 * setting even if DQUOT_SPACE_NOFAIL is set. That's why we check it +	 * only here... +	 */ +	if (flags & DQUOT_SPACE_NOFAIL) +		ret = 0; +	if (!ret) { +		dquot->dq_dqb.dqb_rsvspace += rsv_space; +		dquot->dq_dqb.dqb_curspace += space; +	}  	spin_unlock(&dquot->dq_dqb_lock);  	return ret;  } @@ -1980,7 +1986,9 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)  		ret = dquot_add_space(transfer_to[cnt], cur_space, rsv_space, 0,  				      &warn_to[cnt]);  		if (ret) { +			spin_lock(&transfer_to[cnt]->dq_dqb_lock);  			dquot_decr_inodes(transfer_to[cnt], inode_usage); +			spin_unlock(&transfer_to[cnt]->dq_dqb_lock);  			goto over_quota;  		}  	} |