Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Mar 2000 14:07:39 +0100 (CET)
From:      Andre Albsmeier <andre.albsmeier@mchp.siemens.de>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/17128: Fix for quotas grace time when using chown and soft limits are hit again
Message-ID:  <200003021307.OAA41883@internal>

next in thread | raw e-mail | index | archive | help

>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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200003021307.OAA41883>