Jan please take care of the patch attached. This race relatively easy to reproduce so IMHO it is candidate for stable trees
>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