From owner-freebsd-bugs Thu Mar 2 5:10:14 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id C7EF937C02C for ; Thu, 2 Mar 2000 05:10:03 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id FAA80232; Thu, 2 Mar 2000 05:10:03 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from goliath.siemens.de (goliath.siemens.de [194.138.37.131]) by hub.freebsd.org (Postfix) with ESMTP id F33E337BB99 for ; Thu, 2 Mar 2000 05:07:44 -0800 (PST) (envelope-from andre.albsmeier@mchp.siemens.de) Received: from mail2.siemens.de (mail2.siemens.de [139.25.208.11]) by goliath.siemens.de (8.9.3/8.9.3) with ESMTP id OAA07646 for ; Thu, 2 Mar 2000 14:07:42 +0100 (MET) Received: from curry.mchp.siemens.de (curry.mchp.siemens.de [139.25.42.7]) by mail2.siemens.de (8.9.3/8.9.3) with ESMTP id OAA21250 for ; Thu, 2 Mar 2000 14:07:42 +0100 (MET) Received: (from daemon@localhost) by curry.mchp.siemens.de (8.9.3/8.9.3) id OAA64115 for ; Thu, 2 Mar 2000 14:07:42 +0100 (CET) Message-Id: <200003021307.OAA41883@internal> Date: Thu, 2 Mar 2000 14:07:39 +0100 (CET) From: Andre Albsmeier To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/17128: Fix for quotas grace time when using chown and soft limits are hit again Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 17128 >Category: kern >Synopsis: Fix for quotas grace time when using chown and soft limits are hit again >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Mar 2 05:10:02 PST 2000 >Closed-Date: >Last-Modified: >Originator: Andre Albsmeier >Release: FreeBSD 3.4-STABLE i386 >Organization: >Environment: FreeBSD 3.4-STABLE (but I assume all versions are affected) with quotas enabled >Description: Here is a problem with FreeBSD's quotas that I have observed for a long time now but finally found some time to track it down: Let's assume the following settings on a quota enabled system: soft limits : 100MB hard limits : 200MB grace period: 7 days On day 1, the user U1 creates 150MB of data. The soft limits are reached but not the hard limits. The internal grace timer is set accordingly (to current_time + 7 days). On day 3, the user U1 removes 100MB. There are 50MB remaining and the grace period is no more important. From now on, the users U1's amount of data stays between 50 and 60 MB. On day 10, user U2 leaves system forever. He got 100MB of data and the admin decides that U1 has to take care of them. So he moves U2's data to U1's directory and runs a "chown -R U1" there. Now, U1 has around 150MB of data belonging to him. The admin tells U1 that he is now over the soft limit and has got 7 days time to inspect U2's data. This is where the problem starts: When examining the quotas for U1 we find that the grace period is already over and the soft limits have turned into hard limits. This only happens if U1 has been over the soft limit some time before. So far for the facts - now let's start the wild guess :-) I assume the problem appears because the system still uses the old grace timer (set to day 7) which is exceeded on day 10 when the files are given to U1. This was no problem before (on days 8 and 9) because the grace time is only used if we are over the soft limits. When root does his chown, the grace timer for U1 is not set to day 10 + 7 days. I think the problem can be fixed _somehow_ with the following patch to /sys/ufs/ufs/ufs_quota.c: (I have included some comments manually _after_ creating the patch) --- /sys/ufs/ufs/ufs_quota.c Mon Aug 30 17:56:23 1999 +++ ufs_quota.c Wed Mar 1 21:27:14 2000 @@ -163,6 +163,10 @@ (void) tsleep((caddr_t)dq, PINOD+1, "chkdq2", 0); } dq->dq_curblocks += change; /* check if we hit the soft limits */ + if (dq->dq_curblocks >= dq->dq_bsoftlimit && dq->dq_bsoftlimit) /* check if we have been below the soft limits before */ + if (dq->dq_curblocks - change < dq->dq_bsoftlimit) /* yes, update the timer */ + dq->dq_btime = time_second + + VFSTOUFS(ITOV(ip)->v_mount)->um_btime[i]; dq->dq_flags |= DQ_MOD; } return (0); @@ -279,6 +283,10 @@ (void) tsleep((caddr_t)dq, PINOD+1, "chkiq2", 0); } dq->dq_curinodes += change; /* same as above for inodes */ + if (dq->dq_curinodes >= dq->dq_isoftlimit && dq->dq_isoftlimit) + if (dq->dq_curinodes - change < dq->dq_isoftlimit) + dq->dq_itime = time_second + + VFSTOUFS(ITOV(ip)->v_mount)->um_itime[i]; dq->dq_flags |= DQ_MOD; } return (0); As far as I understood things correctly, chkdq() is being called from the chown code in the kernel. When the amount of blocks (inodes) changes, there is no check being done if the soft limit is hit. In chkdqchg() we find the interesting part which I tried to bring into chkdq() with the above patch. I have no idea about vfs, ufs and all these things so maybe one of the more enlightened people (Matt, Alfred, ...) might be able to correct me. >How-To-Repeat: - Create a file system with quotas enabled. - Do mount, quotacheck, quotaon, ... - Set soft and hard limits for a user. Set a grace period so we dont' have to wait 7 days (I used 10 minutes). - Let the user allocate space somewhere between soft and hard limits. - Use the quota command to examine that the grace timer has started. - Make the user deallocate enough space to drop below soft limits. - Use the quota command to examine that the grace timer is no more important since we are below the soft limits. - Wait a bit more than the grace period (I waited 15 minutes). - As root, use chown gto ive so much space to the user that the soft limits are hit but the hard limits not. - Use the quota command to see that the grace timer has changed to "none" instead of the grace period (here 10 minutes) because it was not reset when the files were give to the user. >Fix: This is what _might_ fix it. I have tried it on a test machine and it seems to work. I will put it on my production machines as soon as I can reboot them without my users riping my head of (weekend ?!?). Please remember that this is wild gues only... --- /sys/ufs/ufs/ufs_quota.c.ORI Thu Mar 2 13:53:38 2000 +++ /sys/ufs/ufs/ufs_quota.c Thu Mar 2 13:53:55 2000 @@ -163,6 +163,10 @@ (void) tsleep((caddr_t)dq, PINOD+1, "chkdq2", 0); } dq->dq_curblocks += change; + if (dq->dq_curblocks >= dq->dq_bsoftlimit && dq->dq_bsoftlimit) + if (dq->dq_curblocks - change < dq->dq_bsoftlimit) + dq->dq_btime = time_second + + VFSTOUFS(ITOV(ip)->v_mount)->um_btime[i]; dq->dq_flags |= DQ_MOD; } return (0); @@ -279,6 +283,10 @@ (void) tsleep((caddr_t)dq, PINOD+1, "chkiq2", 0); } dq->dq_curinodes += change; + if (dq->dq_curinodes >= dq->dq_isoftlimit && dq->dq_isoftlimit) + if (dq->dq_curinodes - change < dq->dq_isoftlimit) + dq->dq_itime = time_second + + VFSTOUFS(ITOV(ip)->v_mount)->um_itime[i]; dq->dq_flags |= DQ_MOD; } return (0); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message