On Mon 12-04-10 22:16:50, Andrew Perepechko wrote: > From: Andrew Perepechko <andrew.perepechko@xxxxxxx> > > Non-atomic __set_bit calls are replaced with atomic set_bit calls in do_set_dqblk > so that individual bits should not be lost in a possible race condition. I took a liberty of modifying the changelog to be more descriptive: quota: Fix possible dq_flags corruption dq_flags are modified non-atomically in do_set_dqblk via __set_bit calls and atomically for example in mark_dquot_dirty or clear_dquot_dirty. Hence a change done by an atomic operation can be overwritten by a change done by a non-atomic one. Fix the problem by using atomic bitops even in do_set_dqblk. Otherwise I've merged the patch. Honza > Signed-off-by: Andrew Perepechko <andrew.perepechko@xxxxxxx> > --- > diff -puN fs/dquot.c fs/dquot.c > --- a/fs/dquot.c > +++ b/fs/dquot.c > @@ -2065,32 +2065,32 @@ static int do_set_dqblk(struct dquot *dq > if (di->dqb_valid & QIF_SPACE) { > dm->dqb_curspace = di->dqb_curspace; > check_blim = 1; > - __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); > + set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); > } > if (di->dqb_valid & QIF_BLIMITS) { > dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); > dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); > check_blim = 1; > - __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); > + set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); > } > if (di->dqb_valid & QIF_INODES) { > dm->dqb_curinodes = di->dqb_curinodes; > check_ilim = 1; > - __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); > + set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); > } > if (di->dqb_valid & QIF_ILIMITS) { > dm->dqb_isoftlimit = di->dqb_isoftlimit; > dm->dqb_ihardlimit = di->dqb_ihardlimit; > check_ilim = 1; > - __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); > + set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); > } > if (di->dqb_valid & QIF_BTIME) { > dm->dqb_btime = di->dqb_btime; > - __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); > + set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); > } > if (di->dqb_valid & QIF_ITIME) { > dm->dqb_itime = di->dqb_itime; > - __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); > + set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); > } > > if (check_blim) { -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html