Module Name:    src
Committed By:   bouyer
Date:           Sat Feb 12 19:52:40 UTC 2011

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

Log Message:
Do not update disk quotas for snapshot inodes, as this may require a
write to the same filesystem, which will trigger a copy on write,
which will trigger another update to the same block.
Set SF_SNAPSHOT just after truncating the snapshot inode, so that this
inode always account for 0 blocks in quotas.


To generate a diff of this commit:
cvs rdiff -u -r1.102 -r1.102.4.1 src/sys/ufs/ffs/ffs_snapshot.c
cvs rdiff -u -r1.68.4.11 -r1.68.4.12 src/sys/ufs/ufs/ufs_quota.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 src/sys/ufs/ffs/ffs_snapshot.c:1.102.4.1
--- src/sys/ufs/ffs/ffs_snapshot.c:1.102	Mon Dec 20 00:25:47 2010
+++ src/sys/ufs/ffs/ffs_snapshot.c	Sat Feb 12 19:52:39 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffs_snapshot.c,v 1.102 2010/12/20 00:25:47 matt Exp $	*/
+/*	$NetBSD: ffs_snapshot.c,v 1.102.4.1 2011/02/12 19:52:39 bouyer Exp $	*/
 
 /*
  * Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.102 2010/12/20 00:25:47 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.102.4.1 2011/02/12 19:52:39 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -214,12 +214,6 @@
 	if (error)
 		goto out;
 	/*
-	 * 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
 	 * cylinder groups will change between now and when we
@@ -408,6 +402,7 @@
 	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.
@@ -427,6 +422,13 @@
 			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.
 	 */

Index: src/sys/ufs/ufs/ufs_quota.c
diff -u src/sys/ufs/ufs/ufs_quota.c:1.68.4.11 src/sys/ufs/ufs/ufs_quota.c:1.68.4.12
--- src/sys/ufs/ufs/ufs_quota.c:1.68.4.11	Wed Feb  9 16:15:01 2011
+++ src/sys/ufs/ufs/ufs_quota.c	Sat Feb 12 19:52:40 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_quota.c,v 1.68.4.11 2011/02/09 16:15:01 bouyer Exp $	*/
+/*	$NetBSD: ufs_quota.c,v 1.68.4.12 2011/02/12 19:52:40 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.11 2011/02/09 16:15:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.68.4.12 2011/02/12 19:52:40 bouyer Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -118,6 +118,10 @@
 int
 chkdq(struct inode *ip, int64_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 chkdq1(ip, change, cred, flags);

Reply via email to