Re: Quota bug in 2.0.3x?

Andrea Dell'Amico (adellam@link.it)
Mon, 06 Jul 1998 23:16:33 +0200 (MEST)


On 04-Jul-98 Andrea Arcangeli wrote:
> On Sat, 4 Jul 1998, Andrea Arcangeli wrote:
>
> >You could try this patch, but no warranty, I will not be amazed if you
>
> No, try the new one that seems a bit safer instead.
>
> --- linux/CREDITS.34 Thu Jun 18 23:48:09 1998
> +++ linux/CREDITS Sat Jul 4 16:40:42 1998
> @@ -37,9 +37,10 @@
>
> N: Andrea Arcangeli
> E: arcangeli@mbox.queen.it
> -W: http://www.cs.unibo.it/~arcangel/
> +W: http://e-mind.com/~andrea/
> P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5
> D: Fixed a 2.0.33 mm bug that corrupts memory in linux/mm/vmalloc.c
> +D: Discovered and maybe fixed a dquota deadlock condition in
> write_dquot().
> S: Via Ciaclini 26
> S: Imola 40026
> S: Italy
> --- linux/fs/dquot.c.34 Sat Jul 4 17:27:49 1998
> +++ linux/fs/dquot.c Sat Jul 4 17:32:01 1998
> @@ -21,6 +21,8 @@
> * removed race conditions in dqput(), dqget() and iput().
> * Nick Kralevich <nickkral@cal.alumni.berkeley.edu>, 21 Jul
> 97
> * Fixed a condition where user and group quotas could get
> mixed up.
> + * Removed a deadlock condition in write_dquot(),
> + * Andrea Arcangeli <arcangeli@mbox.queen.it>, 4 Jul 1998
> *
> * (C) Copyright 1994, 1995 Marco van Wieringen
> *
> @@ -36,6 +38,7 @@
> #include <linux/tty.h>
> #include <linux/malloc.h>
> #include <linux/mount.h>
> +#include <linux/locks.h>
>
> #include <asm/segment.h>
>
> @@ -219,6 +222,9 @@
> short type = dquot->dq_type;
> struct file *filp = dquot->dq_mnt->mnt_quotas[type];
> unsigned short fs;
> + int write_retval;
> + unsigned char old_super_lock;
> + struct super_block *sb;
>
> if (!(dquot->dq_flags & DQ_MOD) || (filp == (struct file *)NULL))
> return;
> @@ -240,8 +246,21 @@
> }
> fs = get_fs();
> set_fs(KERNEL_DS);
> - if (filp->f_op->write(filp->f_inode, filp,
> - (char *)&dquot->dq_dqb, sizeof(struct dqblk)) == sizeof(struct
> dqblk))
> + /*
> + * Here we have the superblock locked by ext2_free_inode(), but
> + * to run without deadlock in ext2_alloc_block() we need the
> superblock
> + * unlocked so I try to unlock it here before the write(),
> + * _hoping_ that it will not cause fs corruption ;-).
> + */
> + sb = filp->f_inode->i_sb;
> + if ((old_super_lock = sb->s_lock))
> + unlock_super(sb);
> + write_retval = filp->f_op->write(filp->f_inode, filp,
> + (char *)&dquot->dq_dqb,
> + sizeof(struct dqblk));
> + if (old_super_lock)
> + lock_super(sb);
> + if (write_retval == sizeof(struct dqblk))
> dquot->dq_flags &= ~DQ_MOD;
> up(&dquot->dq_mnt->mnt_sem);
> set_fs(fs);
>

Ok, I tried it for a while doing all the tests that produced the
malfunction on the unpatched kernel and something more. No problems at
all, and the file system isn't trashed.

The tests were things like:

while true

cd /usr/src; tar cf - ./linux-2.0.34 | tar -C /var/opt/petra/tmp -xvf - ;
/bin/rm -fr /var/opt/petra/tmp/linux-2.0.34

all done as a quoted user. In the meantime I played removing
/var/opt/petra/proxy/cache/0* while squid was running, replacing
quota.[users,group] on the /var/opt/petra filesystem, doing quotaoff,
quotacheck and quotaon, then re-quoting all the users.

> Andrea[s] Arcangeli

ciao
andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu