6.6-stable review patch. If anyone has any objections, please let me know. ------------------ From: Andreas Gruenbacher <agruenba@xxxxxxxxxx> [ Upstream commit 59ebc33201237bf38e5adca3794716100660c5b4 ] Rename qd_check_sync() to qd_grab_sync() and make it return a bool. Turn the sync_gen pointer into a regular u64 and pass in U64_MAX instead of a NULL pointer when sync generation checking isn't needed. Introduce a new qd_ungrab_sync() helper for undoing the effects of qd_grab_sync() if the subsequent bh_get() on the qd object fails. Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx> Stable-dep-of: 4b4b6374dc61 ("gfs2: Revert "ignore negated quota changes"") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> --- fs/gfs2/quota.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 62522d4011106..ed602352fe1d3 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -446,13 +446,13 @@ static void bh_put(struct gfs2_quota_data *qd) mutex_unlock(&sdp->sd_quota_mutex); } -static int qd_check_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd, - u64 *sync_gen) +static bool qd_grab_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd, + u64 sync_gen) { if (test_bit(QDF_LOCKED, &qd->qd_flags) || !test_bit(QDF_CHANGE, &qd->qd_flags) || - (sync_gen && (qd->qd_sync_gen >= *sync_gen))) - return 0; + qd->qd_sync_gen >= sync_gen) + return false; /* * If qd_change is 0 it means a pending quota change was negated. @@ -462,17 +462,24 @@ static int qd_check_sync(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd, if (!qd->qd_change && test_and_clear_bit(QDF_CHANGE, &qd->qd_flags)) { slot_put(qd); qd_put(qd); - return 0; + return false; } if (!lockref_get_not_dead(&qd->qd_lockref)) - return 0; + return false; list_move_tail(&qd->qd_list, &sdp->sd_quota_list); set_bit(QDF_LOCKED, &qd->qd_flags); qd->qd_change_sync = qd->qd_change; slot_hold(qd); - return 1; + return true; +} + +static void qd_ungrab_sync(struct gfs2_quota_data *qd) +{ + clear_bit(QDF_LOCKED, &qd->qd_flags); + slot_put(qd); + qd_put(qd); } static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp) @@ -488,7 +495,7 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp) spin_lock(&qd_lock); list_for_each_entry(iter, &sdp->sd_quota_list, qd_list) { - if (qd_check_sync(sdp, iter, &sdp->sd_quota_sync_gen)) { + if (qd_grab_sync(sdp, iter, sdp->sd_quota_sync_gen)) { qd = iter; break; } @@ -499,9 +506,7 @@ static int qd_fish(struct gfs2_sbd *sdp, struct gfs2_quota_data **qdp) if (qd) { error = bh_get(qd); if (error) { - clear_bit(QDF_LOCKED, &qd->qd_flags); - slot_put(qd); - qd_put(qd); + qd_ungrab_sync(qd); return error; } } @@ -1139,7 +1144,6 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) struct gfs2_quota_data *qda[2 * GFS2_MAXQUOTAS]; unsigned int count = 0; u32 x; - int found; if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) return; @@ -1147,6 +1151,7 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { struct gfs2_quota_data *qd; bool sync; + int error; qd = ip->i_qadata->qa_qd[x]; sync = need_sync(qd); @@ -1156,17 +1161,16 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) continue; spin_lock(&qd_lock); - found = qd_check_sync(sdp, qd, NULL); + sync = qd_grab_sync(sdp, qd, U64_MAX); spin_unlock(&qd_lock); - if (!found) + if (!sync) continue; gfs2_assert_warn(sdp, qd->qd_change_sync); - if (bh_get(qd)) { - clear_bit(QDF_LOCKED, &qd->qd_flags); - slot_put(qd); - qd_put(qd); + error = bh_get(qd); + if (error) { + qd_ungrab_sync(qd); continue; } -- 2.43.0