Re: [PATCH] quota: fix dquot_disable vs dquot_trasnfer race

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux