On Sat, 09 Oct 2010 19:24:56 +0400, Dmitry Monakhov <dmonakhov@xxxxxxxxxx> wrote: > Jan please take care of the patch attached. This race relatively easy > to reproduce so IMHO it is candidate for stable trees OOps, please excuse me, this patch was prepared against my local tree which has not "Pass back references to put" logic at the end. Please ignore this patch. I'll send correct one soon. > > From 1c438550a9aca7c3e209a492a9747954de571d38 Mon Sep 17 00:00:00 2001 > From: Dmitry Monakhov <dmonakhov@xxxxxxxxx> > Date: Sat, 9 Oct 2010 18:57:45 +0400 > Subject: [PATCH] quota: fix dquot_disable vs dquot_trasnfer race > > I've got following race: > dquot_disable dquot_transfer > ->dqget() > sb_has_quota_active > dqopt->flags &= ~dquot_state_flag(f, cnt) atomic_inc(dq->dq_count) > ->drop_dquot_ref(sb, cnt); > down_write(dqptr_sem) > inode->i_dquot[cnt] = NULL ->__dquot_transfer > invalidate_dquots(sb, cnt); down_write(&dqptr_sem) > ->wait for dq_wait_unused inode->i_dquot = new_dquot > /* wait forever */ ^^^^New quota user^^^^^^ > > Inodes was already cleaned from quotas, and we can not allow new ones. > We have to recheck quota state under dqptr_sem and before assignment, > as we do it in dquot_initialize() > > Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxx> > --- > fs/quota/dquot.c | 5 +++++ > 1 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c > index 686c2b7..94fc2a0 100644 > --- a/fs/quota/dquot.c > +++ b/fs/quota/dquot.c > @@ -1759,6 +1759,9 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) > for (cnt = 0; cnt < MAXQUOTAS; cnt++) { > if (!transfer_to[cnt]) > continue; > + /* Avoid races with quotaoff() */ > + if (!sb_has_quota_active(inode->i_sb, cnt)) > + continue; > transfer_from[cnt] = inode->i_dquot[cnt]; > ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt); > if (ret) > @@ -1777,6 +1780,8 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) > */ > if (!transfer_to[cnt]) > continue; > + if (!sb_has_quota_active(inode->i_sb, cnt)) > + continue; > > /* Due to IO error we might not have transfer_from[] structure */ > if (transfer_from[cnt]) { > -- > 1.6.6.1 > -- 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