Messages in this thread Patches in this message | | | Date | Mon, 21 Jul 1997 08:37:06 -0700 (PDT) | From | Nick Kralevich <> | Subject | fix to quotas for 2.0.30 and 2.1.46 |
| |
Under some circumstances, user quotas and group quotas can get mixed up, and all block and inode allocations and deallocations are applied to only the user quota, not to the group quota. The net result is that the user ends up being quotaed for 2x the amount of disk space they should actually have for any new blocks or inodes. The following fix fixes this problem. Included below are patches for 2.0.30 and 2.1.46. I would appreciate it if you could forward this to whoever's responsible for incorporating this into the next kernel.
The problem is dependent on what specific device, uid, and gid that is in use at the time. I was able to duplicate the problem on device /dev/sda8 (major 8, minor 8), with UID == GID == 540. This value hashes out to "0" for both the user and group quota. When dqget() is called before the patch, it could not tell the difference between a group quota and a user quota (because they were both put into the same bucket in the hash table). Now it can tell the difference.
I've tested these patches on my system (1100 users) and they seem to work fine. Before, of the 773 accounts that we have on that one hard drive, 18 were having problems with quotas. After the patch, none of them are.
Thanks to Daniel Eischen for helping me solve this problem.
Take care, -- Nick Kralevich nickkral@autobahn.org
--- linux-2.0.30/fs/dquot.c Sun May 12 21:36:19 1996 +++ linux/fs/dquot.c Mon Jul 21 07:11:32 1997 @@ -19,6 +19,8 @@ * * Fixes: Dmitry Gorodchanin <begemot@bgm.rosprint.net>, 11 Feb 96 * 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. * * (C) Copyright 1994, 1995 Marco van Wieringen * @@ -549,12 +551,14 @@ repeat: dquot = *(hash(dev, id, type)); while (dquot) { - if (dquot->dq_dev != dev || dquot->dq_id != id) { + if (dquot->dq_dev != dev || dquot->dq_id != id || + dquot->dq_type != type) { dquot = dquot->dq_hash_next; continue; } wait_on_dquot(dquot); - if (dquot->dq_dev != dev || dquot->dq_id != id) + if (dquot->dq_dev != dev || dquot->dq_id != id || + dquot->dq_type != type) goto repeat; if (!dquot->dq_count) nr_free_dquots--;
---------------------- --- linux-2.1.46/fs/dquot.c Sun Jul 13 21:20:10 1997 +++ linux/fs/dquot.c Mon Jul 21 07:18:09 1997 @@ -20,6 +20,8 @@ * Fixes: Dmitry Gorodchanin <begemot@bgm.rosprint.net>, 11 Feb 96 * removed race conditions in dqput(), dqget() and iput(). * Andi Kleen removed all verify_area() calls, 31 Dec 96 + * Nick Kralevich <nickkral@cal.alumni.berkeley.edu>, 21 Jul 97 + * Fixed a condition where user and group quotas could get mixed up. * * (C) Copyright 1994, 1995 Marco van Wieringen * @@ -555,12 +557,14 @@ repeat: dquot = *(hash(dev, id, type)); while (dquot) { - if (dquot->dq_dev != dev || dquot->dq_id != id) { + if (dquot->dq_dev != dev || dquot->dq_id != id || + dquot->dq_type != type) { dquot = dquot->dq_hash_next; continue; } wait_on_dquot(dquot); - if (dquot->dq_dev != dev || dquot->dq_id != id) + if (dquot->dq_dev != dev || dquot->dq_id != id || + dquot->dq_type != type) goto repeat; if (!dquot->dq_count) nr_free_dquots--;
| |