Source-Changes-HG archive

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

[src/bouyer-quota2]: src/sys/ufs Don't count snapshot files in inode quota too.



details:   https://anonhg.NetBSD.org/src/rev/356b881eeacc
branches:  bouyer-quota2
changeset: 761169:356b881eeacc
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sat Feb 12 21:48:09 2011 +0000

description:
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.

diffstat:

 sys/ufs/ffs/ffs_snapshot.c |  39 +++++++++++++++++++++++++++++----------
 sys/ufs/ufs/ufs_quota.c    |   7 +++++--
 sys/ufs/ufs/ufs_quota2.c   |  15 ++++++++++++---
 3 files changed, 46 insertions(+), 15 deletions(-)

diffs (162 lines):

diff -r 0c5192d411cc -r 356b881eeacc sys/ufs/ffs/ffs_snapshot.c
--- a/sys/ufs/ffs/ffs_snapshot.c        Sat Feb 12 19:53:32 2011 +0000
+++ b/sys/ufs/ffs/ffs_snapshot.c        Sat Feb 12 21:48:09 2011 +0000
@@ -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
 }
 
 /*
diff -r 0c5192d411cc -r 356b881eeacc sys/ufs/ufs/ufs_quota.c
--- a/sys/ufs/ufs/ufs_quota.c   Sat Feb 12 19:53:32 2011 +0000
+++ b/sys/ufs/ufs/ufs_quota.c   Sat Feb 12 21:48:09 2011 +0000
@@ -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);
diff -r 0c5192d411cc -r 356b881eeacc sys/ufs/ufs/ufs_quota2.c
--- a/sys/ufs/ufs/ufs_quota2.c  Sat Feb 12 19:53:32 2011 +0000
+++ b/sys/ufs/ufs/ufs_quota2.c  Sat Feb 12 21:48:09 2011 +0000
@@ -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) {



Home | Main Index | Thread Index | Old Index