[XFS] Need to be able to reset sb_qflags if not mounting with quotas
authorTim Shimmin <tes@sgi.com>
Sun, 4 Sep 2005 22:24:10 +0000 (08:24 +1000)
committerNathan Scott <nathans@sgi.com>
Sun, 4 Sep 2005 22:24:10 +0000 (08:24 +1000)
having previously mounted with quotas.

SGI-PV: 940491
SGI-Modid: xfs-linux:xfs-kern:23388a

Signed-off-by: Tim Shimmin <tes@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
fs/xfs/quota/xfs_dquot.h
fs/xfs/quota/xfs_qm.c
fs/xfs/quota/xfs_qm.h
fs/xfs/quota/xfs_qm_bhv.c
fs/xfs/xfs_qmops.c
fs/xfs/xfs_quota.h

index 39175103c8e0ca5ec2c81a859d5dc846aa6dab0e..8ebc87176c78c464f32a7069def5fbe6fbca127a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -113,20 +113,6 @@ typedef struct xfs_dquot {
 
 #define XFS_DQHOLD(dqp)                ((dqp)->q_nrefs++)
 
-/*
- * Quota Accounting/Enforcement flags
- */
-#define XFS_ALL_QUOTA_ACCT     \
-               (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
-#define XFS_ALL_QUOTA_ENFD     (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
-#define XFS_ALL_QUOTA_CHKD     (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
-
-#define XFS_IS_QUOTA_RUNNING(mp)       ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
-#define XFS_IS_QUOTA_ENFORCED(mp)      ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
-#define XFS_IS_UQUOTA_RUNNING(mp)      ((mp)->m_qflags & XFS_UQUOTA_ACCT)
-#define XFS_IS_PQUOTA_RUNNING(mp)      ((mp)->m_qflags & XFS_PQUOTA_ACCT)
-#define XFS_IS_GQUOTA_RUNNING(mp)      ((mp)->m_qflags & XFS_GQUOTA_ACCT)
-
 #ifdef DEBUG
 static inline int
 XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
index 4badf38df5e9c0faff9f692c29cc370d34abd50f..efde16e0a91345b182aa1731c42f8388dd8cf31e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -365,16 +365,6 @@ xfs_qm_mount_quotas(
        int             error = 0;
        uint            sbf;
 
-       /*
-        * If a file system had quotas running earlier, but decided to
-        * mount without -o uquota/pquota/gquota options, revoke the
-        * quotachecked license, and bail out.
-        */
-       if (! XFS_IS_QUOTA_ON(mp) &&
-           (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) {
-               mp->m_qflags = 0;
-               goto write_changes;
-       }
 
        /*
         * If quotas on realtime volumes is not supported, we disable
@@ -2002,7 +1992,7 @@ xfs_qm_quotacheck(
                ASSERT(mp->m_quotainfo != NULL);
                ASSERT(xfs_Gqm != NULL);
                xfs_qm_destroy_quotainfo(mp);
-               xfs_mount_reset_sbqflags(mp);
+               (void)xfs_mount_reset_sbqflags(mp);
        } else {
                cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
        }
index b03eecf3b6cb19c4dba39596ce440178ebd858fd..0b00b3c67015eede68ce28da43a5d27beb19aeee 100644 (file)
@@ -184,8 +184,6 @@ typedef struct xfs_dquot_acct {
 #define XFS_QM_HOLD(xqm)       ((xqm)->qm_nrefs++)
 #define XFS_QM_RELE(xqm)       ((xqm)->qm_nrefs--)
 
-extern void            xfs_mount_reset_sbqflags(xfs_mount_t *);
-
 extern void            xfs_qm_destroy_quotainfo(xfs_mount_t *);
 extern int             xfs_qm_mount_quotas(xfs_mount_t *, int);
 extern void            xfs_qm_mount_quotainit(xfs_mount_t *, uint);
index dc3c37a1e1585702eeb814da992b216b57f4c96d..8890a18a99d8cc98857d694fc55368eb41ede195 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -229,48 +229,6 @@ xfs_qm_syncall(
        return error;
 }
 
-/*
- * Clear the quotaflags in memory and in the superblock.
- */
-void
-xfs_mount_reset_sbqflags(
-       xfs_mount_t             *mp)
-{
-       xfs_trans_t             *tp;
-       unsigned long           s;
-
-       mp->m_qflags = 0;
-       /*
-        * It is OK to look at sb_qflags here in mount path,
-        * without SB_LOCK.
-        */
-       if (mp->m_sb.sb_qflags == 0)
-               return;
-       s = XFS_SB_LOCK(mp);
-       mp->m_sb.sb_qflags = 0;
-       XFS_SB_UNLOCK(mp, s);
-
-       /*
-        * if the fs is readonly, let the incore superblock run
-        * with quotas off but don't flush the update out to disk
-        */
-       if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
-               return;
-#ifdef QUOTADEBUG
-       xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
-#endif
-       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
-       if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
-                                     XFS_DEFAULT_LOG_COUNT)) {
-               xfs_trans_cancel(tp, 0);
-               xfs_fs_cmn_err(CE_ALERT, mp,
-                       "xfs_mount_reset_sbqflags: Superblock update failed!");
-               return;
-       }
-       xfs_mod_sb(tp, XFS_SB_QFLAGS);
-       xfs_trans_commit(tp, 0, NULL);
-}
-
 STATIC int
 xfs_qm_newmount(
        xfs_mount_t     *mp,
index 4f40c92863d51ffda17cf7d7832f0dec86a3b536..a6cd6324e946af65d2f1e949606a6e7c25be0f90 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -42,7 +42,8 @@
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
-
+#include "xfs_quota.h"
+#include "xfs_error.h"
 
 STATIC struct xfs_dquot *
 xfs_dqvopchown_default(
@@ -54,8 +55,79 @@ xfs_dqvopchown_default(
        return NULL;
 }
 
+/*
+ * Clear the quotaflags in memory and in the superblock.
+ */
+int
+xfs_mount_reset_sbqflags(xfs_mount_t *mp)
+{
+       int                     error;
+       xfs_trans_t             *tp;
+       unsigned long           s;
+
+       mp->m_qflags = 0;
+       /*
+        * It is OK to look at sb_qflags here in mount path,
+        * without SB_LOCK.
+        */
+       if (mp->m_sb.sb_qflags == 0)
+               return 0;
+       s = XFS_SB_LOCK(mp);
+       mp->m_sb.sb_qflags = 0;
+       XFS_SB_UNLOCK(mp, s);
+
+       /*
+        * if the fs is readonly, let the incore superblock run
+        * with quotas off but don't flush the update out to disk
+        */
+       if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
+               return 0;
+#ifdef QUOTADEBUG
+       xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
+#endif
+       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
+       if ((error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
+                                     XFS_DEFAULT_LOG_COUNT))) {
+               xfs_trans_cancel(tp, 0);
+               xfs_fs_cmn_err(CE_ALERT, mp,
+                       "xfs_mount_reset_sbqflags: Superblock update failed!");
+               return error;
+       }
+       xfs_mod_sb(tp, XFS_SB_QFLAGS);
+       error = xfs_trans_commit(tp, 0, NULL);
+       return error;
+}
+
+STATIC int
+xfs_noquota_init(
+       xfs_mount_t     *mp,
+       uint            *needquotamount,
+       uint            *quotaflags)
+{
+       int             error = 0;
+
+       *quotaflags = 0;
+       *needquotamount = B_FALSE;
+
+       ASSERT(!XFS_IS_QUOTA_ON(mp));
+
+       /*
+        * If a file system had quotas running earlier, but decided to
+        * mount without -o uquota/pquota/gquota options, revoke the
+        * quotachecked license.
+        */
+       if (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT) {
+               cmn_err(CE_NOTE,
+                        "XFS resetting qflags for filesystem %s",
+                        mp->m_fsname);
+
+               error = xfs_mount_reset_sbqflags(mp);
+       }
+       return error;
+}
+
 xfs_qmops_t    xfs_qmcore_stub = {
-       .xfs_qminit             = (xfs_qminit_t) fs_noerr,
+       .xfs_qminit             = (xfs_qminit_t) xfs_noquota_init,
        .xfs_qmdone             = (xfs_qmdone_t) fs_noerr,
        .xfs_qmmount            = (xfs_qmmount_t) fs_noerr,
        .xfs_qmunmount          = (xfs_qmunmount_t) fs_noerr,
index 7134576ae7faed4f64e1dbb0661bc634a0dbd611..32cb79752d5d57a5306069269fc4acf051998cb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -159,6 +159,20 @@ typedef struct xfs_qoff_logformat {
 #define XFS_OQUOTA_CHKD        0x0020  /* quotacheck run on other (grp/prj) quotas */
 #define XFS_GQUOTA_ACCT        0x0040  /* group quota accounting ON */
 
+/*
+ * Quota Accounting/Enforcement flags
+ */
+#define XFS_ALL_QUOTA_ACCT     \
+               (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
+#define XFS_ALL_QUOTA_ENFD     (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
+#define XFS_ALL_QUOTA_CHKD     (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
+
+#define XFS_IS_QUOTA_RUNNING(mp)       ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
+#define XFS_IS_QUOTA_ENFORCED(mp)      ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
+#define XFS_IS_UQUOTA_RUNNING(mp)      ((mp)->m_qflags & XFS_UQUOTA_ACCT)
+#define XFS_IS_PQUOTA_RUNNING(mp)      ((mp)->m_qflags & XFS_PQUOTA_ACCT)
+#define XFS_IS_GQUOTA_RUNNING(mp)      ((mp)->m_qflags & XFS_GQUOTA_ACCT)
+
 /*
  * Incore only flags for quotaoff - these bits get cleared when quota(s)
  * are in the process of getting turned off. These flags are in m_qflags but
@@ -362,6 +376,7 @@ typedef struct xfs_dqtrxops {
                                f | XFS_QMOPT_RES_REGBLKS)
 
 extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
+extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
 
 extern struct bhv_vfsops xfs_qmops;