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

trouble implementing default quotas



Folks,

I'm implementing a default quota scheme on xfs and have something weird
going on that I don't understand.  I am using a recent cvs snapshot and
linux 2.4.17.  

I want to use root to store the default user and group quota and only
enforce the default quota if a user doesn't have an explicit quota set.
When I apply this patch, I lock up when a user, with or without a quota,
tries to write to the disk.  When I copy some files to the filesystem with
my altered xfs, it appears to lock up returning from the xfs_create call in
xfs_vnodeops.c.  It leaves this function via std_return with error 0, but
the console never returns a prompt.  

Without my patch, all appears ok, so I know I'm doing something screwy, I
just don't know what.

Any help would be appreciated.

Cary 

diff -Nur linux.orig/fs/xfs/xfs_trans_dquot.c linux/fs/xfs/xfs_trans_dquot.c
--- linux.orig/fs/xfs/xfs_trans_dquot.c	Thu Feb  7 13:02:57 2002
+++ linux/fs/xfs/xfs_trans_dquot.c	Fri Feb  8 11:20:09 2002
@@ -573,6 +573,7 @@
 xfs_trans_dqresv(
 	xfs_trans_t	*tp,
 	xfs_dquot_t 	*dqp,
+	xfs_dquot_t	*defaultqp,
 	long		nblks,
 	long		ninos,
 	uint		flags)
@@ -588,14 +589,22 @@
 	} 
 	ASSERT(XFS_DQ_IS_LOCKED(dqp));
 	if (flags & XFS_TRANS_DQ_RES_BLKS) {
-		hardlimit = INT_GET(dqp->q_core.d_blk_hardlimit,
ARCH_CONVERT);
-		softlimit = INT_GET(dqp->q_core.d_blk_softlimit,
ARCH_CONVERT);
+		if ((hardlimit = INT_GET(dqp->q_core.d_blk_hardlimit,
ARCH_CONVERT)) == 0) {
+			hardlimit =
INT_GET(defaultqp->q_core.d_blk_hardlimit, ARCH_CONVERT);
+		}
+		if ((softlimit = INT_GET(dqp->q_core.d_blk_softlimit,
ARCH_CONVERT)) == 0) {
+			softlimit =
INT_GET(defaultqp->q_core.d_blk_hardlimit, ARCH_CONVERT);
+		}
 		btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
 		resbcountp = &dqp->q_res_bcount;
 	} else {
 		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
-		hardlimit = INT_GET(dqp->q_core.d_rtb_hardlimit,
ARCH_CONVERT);
-		softlimit = INT_GET(dqp->q_core.d_rtb_softlimit,
ARCH_CONVERT);
+		if ((hardlimit = INT_GET(dqp->q_core.d_rtb_hardlimit,
ARCH_CONVERT)) == 0) {
+			hardlimit =
INT_GET(defaultqp->q_core.d_rtb_hardlimit, ARCH_CONVERT);
+		}
+		if ((softlimit = INT_GET(dqp->q_core.d_rtb_softlimit,
ARCH_CONVERT)) == 0) {
+			softlimit =
INT_GET(defaultqp->q_core.d_rtb_hardlimit, ARCH_CONVERT);
+		}
 		btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
 		resbcountp = &dqp->q_res_rtbcount;
 	}
@@ -711,6 +720,9 @@
  * 	   XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
  * dquots are unlocked on return, if they were not locked by caller.
  */
+
+
+
 int
 xfs_trans_reserve_quota_bydquots(
 	xfs_trans_t 	*tp,
@@ -721,6 +733,8 @@
 	uint		flags)
 {
 	int 		resvd;
+	int	error;
+	xfs_dquot_t	*defaultqp;
 
 	if (tp && tp->t_dqinfo == NULL)
 		xfs_trans_alloc_dqinfo(tp);
@@ -729,18 +743,20 @@
 	resvd = 0;
 
 	if (udqp) {
-		if (xfs_trans_dqresv(tp, udqp, nblks, ninos, flags))
+		error = xfs_qm_dqget(udqp->q_mount, NULL, 0, XFS_DQ_USER, 0,
&defaultqp);
+		if (xfs_trans_dqresv(tp, udqp, defaultqp, nblks, ninos,
flags))
 			return (EDQUOT);
 		resvd = 1;
 	}
 	
 	if (gdqp) {
-		if (xfs_trans_dqresv(tp, gdqp, nblks, ninos, flags)) {
+		error = xfs_qm_dqget(udqp->q_mount, NULL, 0, XFS_DQ_GROUP,
0, &defaultqp);
+		if (xfs_trans_dqresv(tp, gdqp, defaultqp, nblks, ninos,
flags)) {
 			/* 
 			 * can't do it, so backout previous reservation
 			 */
 			if (resvd) {
-				xfs_trans_dqresv(tp, udqp,  -nblks, -ninos,
+				xfs_trans_dqresv(tp, udqp, defaultqp,
-nblks, -ninos,
 						 flags);
 			}
 			return (EDQUOT);