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) {