Module Name:    src
Committed By:   bouyer
Date:           Sat Feb 12 21:48:10 UTC 2011

Modified Files:
        src/sys/ufs/ffs [bouyer-quota2]: ffs_snapshot.c
        src/sys/ufs/ufs [bouyer-quota2]: ufs_quota.c ufs_quota2.c

Log Message:
Don't count snapshot files in inode quota too.
At umount time, chk?q may be called after quota have been shutdown,
as there is a final vflush pass after quota?_umount(); so skip quota
checks if the quota vnode is not there any more.


To generate a diff of this commit:
cvs rdiff -u -r1.102.4.1 -r1.102.4.2 src/sys/ufs/ffs/ffs_snapshot.c
cvs rdiff -u -r1.68.4.12 -r1.68.4.13 src/sys/ufs/ufs/ufs_quota.c
cvs rdiff -u -r1.1.2.14 -r1.1.2.15 src/sys/ufs/ufs/ufs_quota2.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/ffs/ffs_snapshot.c
diff -u src/sys/ufs/ffs/ffs_snapshot.c:1.102.4.1 src/sys/ufs/ffs/ffs_snapshot.c:1.102.4.2
--- src/sys/ufs/ffs/ffs_snapshot.c:1.102.4.1	Sat Feb 12 19:52:39 2011
+++ src/sys/ufs/ffs/ffs_snapshot.c	Sat Feb 12 21:48:09 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffs_snapshot.c,v 1.102.4.1 2011/02/12 19:52:39 bouyer Exp $	*/
+/*	$NetBSD: ffs_snapshot.c,v 1.102.4.2 2011/02/12 21:48:09 bouyer Exp $	*/
 
 /*
  * Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
@@ -38,10 +38,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.102.4.1 2011/02/12 19:52:39 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.102.4.2 2011/02/12 21:48:09 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
+#include "opt_quota.h"
 #endif
 
 #include <sys/param.h>
@@ -213,6 +214,19 @@
 	error = snapshot_setup(mp, vp);
 	if (error)
 		goto out;
+	/* quota inodes are not accounted in quotas */
+#if defined(QUOTA) || defined(QUOTA2)
+	chkdq(ip, -DIP(ip, blocks), l->l_cred, 0);
+	chkiq(ip, -1, l->l_cred, 0);
+#endif
+	/*
+	 * Change inode to snapshot type file.
+	 */
+	ip->i_flags |= SF_SNAPSHOT;
+	DIP_ASSIGN(ip, flags, ip->i_flags);
+	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+
+
 	/*
 	 * Copy all the cylinder group maps. Although the
 	 * filesystem is still active, we hope that only a few
@@ -402,7 +416,6 @@
 	struct buf *ibp, *nbp;
 	struct fs *fs = VFSTOUFS(mp)->um_fs;
 	struct lwp *l = curlwp;
-	struct inode *ip = VTOI(vp);
 
 	/*
 	 * Check mount, exclusive reference and owner.
@@ -422,13 +435,6 @@
 			return error;
 	}
 	/*
-	 * Change inode to snapshot type file.
-	 * Do it now so that allocations below are not recorded in quotas
-	 */
-	ip->i_flags |= SF_SNAPSHOT;
-	DIP_ASSIGN(ip, flags, ip->i_flags);
-	ip->i_flag |= IN_CHANGE | IN_UPDATE;
-	/*
 	 * Write an empty list of preallocated blocks to the end of
 	 * the snapshot to set size to at least that of the filesystem.
 	 */
@@ -1029,6 +1035,11 @@
 		dip1->di_flags =
 		    ufs_rw32(ufs_rw32(dip1->di_flags, ns) & ~SF_SNAPSHOT, ns);
 		memset(&dip1->di_db[0], 0, (NDADDR + NIADDR) * sizeof(int32_t));
+		/* quota inodes are not accounted in quotas */
+#if defined(QUOTA) || defined(QUOTA2)
+		if (dip1->di_mode != 0)
+			chkiq(cancelip, 1, l->l_cred, FORCE);
+#endif
 	} else {
 		dip2 = (struct ufs2_dinode *)bp->b_data +
 		    ino_to_fsbo(fs, cancelip->i_number);
@@ -1039,6 +1050,10 @@
 		dip2->di_flags =
 		    ufs_rw32(ufs_rw32(dip2->di_flags, ns) & ~SF_SNAPSHOT, ns);
 		memset(&dip2->di_db[0], 0, (NDADDR + NIADDR) * sizeof(int64_t));
+#if defined(QUOTA) || defined(QUOTA2)
+		if (dip2->di_mode != 0)
+			chkiq(cancelip, 1, l->l_cred, FORCE);
+#endif
 	}
 	bdwrite(bp);
 	/*
@@ -1387,6 +1402,10 @@
 	ip->i_flags &= ~SF_SNAPSHOT;
 	DIP_ASSIGN(ip, flags, ip->i_flags);
 	ip->i_flag |= IN_CHANGE | IN_UPDATE;
+#if defined(QUOTA) || defined(QUOTA2)
+	chkdq(ip, DIP(ip, blocks), l->l_cred, FORCE);
+	chkiq(ip, 1, l->l_cred, FORCE);
+#endif
 }
 
 /*

Index: src/sys/ufs/ufs/ufs_quota.c
diff -u src/sys/ufs/ufs/ufs_quota.c:1.68.4.12 src/sys/ufs/ufs/ufs_quota.c:1.68.4.13
--- src/sys/ufs/ufs/ufs_quota.c:1.68.4.12	Sat Feb 12 19:52:40 2011
+++ src/sys/ufs/ufs/ufs_quota.c	Sat Feb 12 21:48:09 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_quota.c,v 1.68.4.12 2011/02/12 19:52:40 bouyer Exp $	*/
+/*	$NetBSD: ufs_quota.c,v 1.68.4.13 2011/02/12 21:48:09 bouyer Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.12 2011/02/12 19:52:40 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.13 2011/02/12 21:48:09 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -139,6 +139,9 @@
 int
 chkiq(struct inode *ip, int32_t change, kauth_cred_t cred, int flags)
 {
+	/* do not track snapshot usage, or we will deadlock */
+	if ((ip->i_flags & SF_SNAPSHOT) != 0)
+		return 0;
 #ifdef QUOTA
 	if (ip->i_ump->um_flags & UFS_QUOTA)
 		return chkiq1(ip, change, cred, flags);

Index: src/sys/ufs/ufs/ufs_quota2.c
diff -u src/sys/ufs/ufs/ufs_quota2.c:1.1.2.14 src/sys/ufs/ufs/ufs_quota2.c:1.1.2.15
--- src/sys/ufs/ufs/ufs_quota2.c:1.1.2.14	Fri Feb 11 16:55:35 2011
+++ src/sys/ufs/ufs/ufs_quota2.c	Sat Feb 12 21:48:09 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_quota2.c,v 1.1.2.14 2011/02/11 16:55:35 bouyer Exp $ */
+/* $NetBSD: ufs_quota2.c,v 1.1.2.15 2011/02/12 21:48:09 bouyer Exp $ */
 /*-
   * Copyright (c) 2010 Manuel Bouyer
   * All rights reserved.
@@ -28,7 +28,7 @@
   */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.1.2.14 2011/02/11 16:55:35 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.1.2.15 2011/02/12 21:48:09 bouyer Exp $");
 
 #include <sys/buf.h>
 #include <sys/param.h>
@@ -353,7 +353,16 @@
 		dq = ip->i_dquot[i];
 		if (dq == NODQUOT)
 			continue;
-		KASSERT(ump->um_quotas[i] != NULL);
+		if (__predict_false(ump->um_quotas[i] == NULL)) {
+			/*
+			 * quotas have been turned off. This can happen
+			 * at umount time.
+			 */
+			mutex_exit(&dq->dq_interlock);
+			dqrele(NULLVP, dq);
+			ip->i_dquot[i] = NULL;
+			continue;
+		}
 
 		if ((dq->dq2_lblkno | dq->dq2_blkoff) == 0) {
 			if (alloc == 0) {

Reply via email to