Commit 2df1a93b authored by Christoph Hellwig's avatar Christoph Hellwig

[XFS] Remove rootfs special-casing in the quota code

SGI Modid: 2.5.x-xfs:slinx:132862a
parent 71ffd957
...@@ -153,7 +153,6 @@ typedef struct xfs_dirent { /* data from readdir() */ ...@@ -153,7 +153,6 @@ typedef struct xfs_dirent { /* data from readdir() */
#define EFSCORRUPTED 990 /* Filesystem is corrupted */ #define EFSCORRUPTED 990 /* Filesystem is corrupted */
#define SYNCHRONIZE() barrier() #define SYNCHRONIZE() barrier()
#define rootdev ROOT_DEV
#define __return_address __builtin_return_address(0) #define __return_address __builtin_return_address(0)
/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
......
...@@ -101,7 +101,6 @@ STATIC struct export_operations linvfs_export_ops; ...@@ -101,7 +101,6 @@ STATIC struct export_operations linvfs_export_ops;
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */ #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
#define MNTOPT_QUOTA "quota" /* disk quotas */ #define MNTOPT_QUOTA "quota" /* disk quotas */
#define MNTOPT_MRQUOTA "mrquota" /* don't turnoff if SB has quotas on */
#define MNTOPT_NOQUOTA "noquota" /* no quotas */ #define MNTOPT_NOQUOTA "noquota" /* no quotas */
#define MNTOPT_UQUOTA "usrquota" /* user quota enabled */ #define MNTOPT_UQUOTA "usrquota" /* user quota enabled */
#define MNTOPT_GQUOTA "grpquota" /* group quota enabled */ #define MNTOPT_GQUOTA "grpquota" /* group quota enabled */
......
...@@ -1839,10 +1839,9 @@ xlog_recover_do_dquot_buffer( ...@@ -1839,10 +1839,9 @@ xlog_recover_do_dquot_buffer(
uint type; uint type;
/* /*
* Non-root filesystems are required to send in quota flags * Filesystems are required to send in quota flags at mount time.
* at mount time.
*/ */
if (mp->m_qflags == 0 && mp->m_dev != rootdev) { if (mp->m_qflags == 0) {
return; return;
} }
...@@ -2289,30 +2288,28 @@ xlog_recover_do_dquot_trans(xlog_t *log, ...@@ -2289,30 +2288,28 @@ xlog_recover_do_dquot_trans(xlog_t *log,
mp = log->l_mp; mp = log->l_mp;
/* /*
* Non-root filesystems are required to send in quota flags * Filesystems are required to send in quota flags at mount time.
* at mount time.
*/ */
if (mp->m_qflags == 0 && mp->m_dev != rootdev) { if (mp->m_qflags == 0)
return (0); return (0);
}
recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr; recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr;
ASSERT(recddq); ASSERT(recddq);
/* /*
* This type of quotas was turned off, so ignore this record. * This type of quotas was turned off, so ignore this record.
*/ */
type = INT_GET(recddq->d_flags, ARCH_CONVERT)&(XFS_DQ_USER|XFS_DQ_GROUP); type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
(XFS_DQ_USER | XFS_DQ_GROUP);
ASSERT(type); ASSERT(type);
if (log->l_quotaoffs_flag & type) if (log->l_quotaoffs_flag & type)
return (0); return (0);
/* /*
* At this point we know that if we are recovering a root filesystem * At this point we know that quota was _not_ turned off.
* then quota was _not_ turned off. Since there is no other flag * Since the mount flags are not indicating to us otherwise, this
* indicate to us otherwise, this must mean that quota's on, * must mean that quota is on, and the dquot needs to be replayed.
* and the dquot needs to be replayed. Remember that we may not have * Remember that we may not have fully recovered the superblock yet,
* fully recovered the superblock yet, so we can't do the usual trick * so we can't do the usual trick of looking at the SB quota bits.
* of looking at the SB quota bits.
* *
* The other possibility, of course, is that the quota subsystem was * The other possibility, of course, is that the quota subsystem was
* removed since the last mount - ENOSYS. * removed since the last mount - ENOSYS.
...@@ -2323,7 +2320,7 @@ xlog_recover_do_dquot_trans(xlog_t *log, ...@@ -2323,7 +2320,7 @@ xlog_recover_do_dquot_trans(xlog_t *log,
dq_f->qlf_id, dq_f->qlf_id,
0, XFS_QMOPT_DOWARN, 0, XFS_QMOPT_DOWARN,
"xlog_recover_do_dquot_trans (log copy)"))) { "xlog_recover_do_dquot_trans (log copy)"))) {
if (error == ENOSYS) if (error == ENOSYS)
return (0); return (0);
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
} }
......
...@@ -560,7 +560,7 @@ xfs_mountfs( ...@@ -560,7 +560,7 @@ xfs_mountfs(
xfs_daddr_t d; xfs_daddr_t d;
extern xfs_ioops_t xfs_iocore_xfs; /* from xfs_iocore.c */ extern xfs_ioops_t xfs_iocore_xfs; /* from xfs_iocore.c */
__uint64_t ret64; __uint64_t ret64;
uint quotaflags, quotaondisk, rootqcheck, needquotacheck; uint quotaflags, quotaondisk;
uint uquotaondisk = 0, gquotaondisk = 0; uint uquotaondisk = 0, gquotaondisk = 0;
boolean_t needquotamount; boolean_t needquotamount;
__int64_t update_flags; __int64_t update_flags;
...@@ -967,21 +967,13 @@ xfs_mountfs( ...@@ -967,21 +967,13 @@ xfs_mountfs(
/* /*
* Figure out if we'll need to do a quotacheck. * Figure out if we'll need to do a quotacheck.
* The requirements are a little different depending on whether
* this fs is root or not.
*/ */
rootqcheck = (mp->m_dev == rootdev && quotaondisk &&
((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT &&
(mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) ||
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT &&
(mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD) == 0)));
needquotacheck = rootqcheck || XFS_QM_NEED_QUOTACHECK(mp);
if (XFS_IS_QUOTA_ON(mp) || quotaondisk) { if (XFS_IS_QUOTA_ON(mp) || quotaondisk) {
/* /*
* Call mount_quotas at this point only if we won't have to do * Call mount_quotas at this point only if we won't have to do
* a quotacheck. * a quotacheck.
*/ */
if (quotaondisk && !needquotacheck) { if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
/* /*
* If the xfs quota code isn't installed, * If the xfs quota code isn't installed,
* we have to reset the quotachk'd bit. * we have to reset the quotachk'd bit.
...@@ -1020,10 +1012,6 @@ xfs_mountfs( ...@@ -1020,10 +1012,6 @@ xfs_mountfs(
if (needquotamount) { if (needquotamount) {
ASSERT(mp->m_qflags == 0); ASSERT(mp->m_qflags == 0);
mp->m_qflags = quotaflags; mp->m_qflags = quotaflags;
rootqcheck = (mp->m_dev == rootdev && needquotacheck);
if (rootqcheck && (error = xfs_dev_is_read_only(mp,
"quotacheck")))
goto error2;
if (xfs_qm_mount_quotas(mp)) if (xfs_qm_mount_quotas(mp))
xfs_mount_reset_sbqflags(mp); xfs_mount_reset_sbqflags(mp);
} }
......
...@@ -265,7 +265,7 @@ typedef struct xfs_mount { ...@@ -265,7 +265,7 @@ typedef struct xfs_mount {
#if XFS_BIG_FILESYSTEMS #if XFS_BIG_FILESYSTEMS
#define XFS_MOUNT_INO64 0x00000002 #define XFS_MOUNT_INO64 0x00000002
#endif #endif
#define XFS_MOUNT_ROOTQCHECK 0x00000004 /* 0x00000004 -- currently unused */
/* 0x00000008 -- currently unused */ /* 0x00000008 -- currently unused */
#define XFS_MOUNT_FS_SHUTDOWN 0x00000010 /* atomic stop of all filesystem #define XFS_MOUNT_FS_SHUTDOWN 0x00000010 /* atomic stop of all filesystem
operations, typically for operations, typically for
......
...@@ -301,27 +301,24 @@ xfs_qm_unmount_quotadestroy( ...@@ -301,27 +301,24 @@ xfs_qm_unmount_quotadestroy(
/* /*
* This is called from xfs_mountfs to start quotas and initialize all * This is called from xfs_mountfs to start quotas and initialize all
* necessary data structures like quotainfo, and in the rootfs's case * necessary data structures like quotainfo. This is also responsible for
* xfs_Gqm. This is also responsible for running a quotacheck as necessary. * running a quotacheck as necessary. We are guaranteed that the superblock
* We are guaranteed that the superblock is consistently read in at this * is consistently read in at this point.
* point.
*/ */
int int
xfs_qm_mount_quotas( xfs_qm_mount_quotas(
xfs_mount_t *mp) xfs_mount_t *mp)
{ {
unsigned long s; unsigned long s;
int error; int error = 0;
uint sbf; uint sbf;
error = 0;
/* /*
* If a non-root file system had quotas running earlier, but decided * If a file system had quotas running earlier, but decided to
* to mount without -o quota/pquota options, revoke the quotachecked * mount without -o quota/uquota/gquota options, revoke the
* license, and bail out. * quotachecked license, and bail out.
*/ */
if (! XFS_IS_QUOTA_ON(mp) && if (! XFS_IS_QUOTA_ON(mp) &&
(mp->m_dev != rootdev) &&
(mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) { (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) {
mp->m_qflags = 0; mp->m_qflags = 0;
goto write_changes; goto write_changes;
...@@ -342,32 +339,6 @@ xfs_qm_mount_quotas( ...@@ -342,32 +339,6 @@ xfs_qm_mount_quotas(
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
cmn_err(CE_NOTE, "Attempting to turn on disk quotas."); cmn_err(CE_NOTE, "Attempting to turn on disk quotas.");
#endif #endif
/*
* If this is the root file system, mark flags in mount struct first.
* We couldn't do this earlier because we didn't have the superblock
* read in.
*/
if (mp->m_dev == rootdev) {
ASSERT(XFS_SB_VERSION_HASQUOTA(&mp->m_sb));
ASSERT(mp->m_sb.sb_qflags &
(XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT));
if (xfs_Gqm == NULL) {
if ((xfs_Gqm = xfs_qm_init()) == NULL) {
mp->m_qflags = 0;
error = EINVAL;
goto write_changes;
}
}
mp->m_qflags = mp->m_sb.sb_qflags;
if (mp->m_qflags & XFS_UQUOTA_ACCT)
mp->m_qflags |= XFS_UQUOTA_ACTIVE;
if (mp->m_qflags & XFS_GQUOTA_ACCT)
mp->m_qflags |= XFS_GQUOTA_ACTIVE;
/*
* The quotainode of the root file system may or may not
* exist at this point.
*/
}
ASSERT(XFS_IS_QUOTA_RUNNING(mp)); ASSERT(XFS_IS_QUOTA_RUNNING(mp));
/* /*
...@@ -545,20 +516,6 @@ xfs_qm_dqflush_all( ...@@ -545,20 +516,6 @@ xfs_qm_dqflush_all(
if (error) if (error)
return (error); return (error);
/*
* If this is the root filesystem doing a quotacheck,
* we should do periodic bflushes. This is because there's
* no bflushd at this point.
*/
if (mp->m_flags & XFS_MOUNT_ROOTQCHECK) {
if (++niters == XFS_QM_MAX_DQCLUSTER_LOGSZ) {
xfs_log_force(mp, (xfs_lsn_t)0,
XFS_LOG_FORCE | XFS_LOG_SYNC);
XFS_bflush(mp->m_ddev_targp);
niters = 0;
}
}
xfs_qm_mplist_lock(mp); xfs_qm_mplist_lock(mp);
if (recl != XFS_QI_MPLRECLAIMS(mp)) { if (recl != XFS_QI_MPLRECLAIMS(mp)) {
xfs_qm_mplist_unlock(mp); xfs_qm_mplist_unlock(mp);
...@@ -1568,22 +1525,6 @@ xfs_qm_dqiter_bufs( ...@@ -1568,22 +1525,6 @@ xfs_qm_dqiter_bufs(
flags & XFS_QMOPT_UQUOTA ? flags & XFS_QMOPT_UQUOTA ?
XFS_DQ_USER : XFS_DQ_GROUP); XFS_DQ_USER : XFS_DQ_GROUP);
xfs_bdwrite(mp, bp); xfs_bdwrite(mp, bp);
/*
* When quotachecking the root filesystem,
* we may not have bdflush, and we may fill
* up all available freebufs.
* The workaround here is to push on the
* log and do a bflush on the rootdev
* periodically.
*/
if (mp->m_flags & XFS_MOUNT_ROOTQCHECK) {
if (++notcommitted == incr) {
xfs_log_force(mp, (xfs_lsn_t)0,
XFS_LOG_FORCE | XFS_LOG_SYNC);
XFS_bflush(mp->m_ddev_targp);
notcommitted = 0;
}
}
/* /*
* goto the next block. * goto the next block.
*/ */
...@@ -1982,7 +1923,6 @@ xfs_qm_quotacheck( ...@@ -1982,7 +1923,6 @@ xfs_qm_quotacheck(
error_return: error_return:
cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname); cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
mp->m_flags &= ~(XFS_MOUNT_ROOTQCHECK);
return (error); return (error);
} }
...@@ -2034,9 +1974,9 @@ xfs_qm_init_quotainos( ...@@ -2034,9 +1974,9 @@ xfs_qm_init_quotainos(
/* /*
* Create the two inodes, if they don't exist already. The changes * Create the two inodes, if they don't exist already. The changes
* made above will get added to a transaction and logged in one of * made above will get added to a transaction and logged in one of
* the qino_alloc calls below. * the qino_alloc calls below. If the device is readonly,
* temporarily switch to read-write to do this.
*/ */
if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) { if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
if ((error = xfs_qm_qino_alloc(mp, &uip, if ((error = xfs_qm_qino_alloc(mp, &uip,
sbflags | XFS_SB_UQUOTINO, sbflags | XFS_SB_UQUOTINO,
...@@ -2145,20 +2085,6 @@ xfs_qm_shake_freelist( ...@@ -2145,20 +2085,6 @@ xfs_qm_shake_freelist(
*/ */
if (XFS_DQ_IS_DIRTY(dqp)) { if (XFS_DQ_IS_DIRTY(dqp)) {
xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY"); xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY");
/*
* We'll be doing a dqflush, and it is
* possible to fill up the entire buffer cache
* with dirty delayed write buffers when doing
* this on a root filesystem, if bdflush isn't
* running. So, do a flush periodically.
*/
if (dqp->q_mount->m_flags & XFS_MOUNT_ROOTQCHECK) {
if (!(++nflushes % XFS_QM_MAX_DQCLUSTER_LOGSZ)){
xfs_log_force(dqp->q_mount, (xfs_lsn_t)0,
XFS_LOG_FORCE | XFS_LOG_SYNC);
XFS_bflush(dqp->q_mount->m_ddev_targp);
}
}
/* /*
* We flush it delayed write, so don't bother * We flush it delayed write, so don't bother
* releasing the mplock. * releasing the mplock.
...@@ -2329,21 +2255,6 @@ xfs_qm_dqreclaim_one(void) ...@@ -2329,21 +2255,6 @@ xfs_qm_dqreclaim_one(void)
*/ */
if (XFS_DQ_IS_DIRTY(dqp)) { if (XFS_DQ_IS_DIRTY(dqp)) {
xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY"); xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY");
/*
* We'll be doing a dqflush, and it is
* possible to fill up the entire buffer cache
* with dirty delayed write buffers when doing
* this on a root filesystem, if bdflush isn't
* running. So, do a flush periodically.
*/
if (dqp->q_mount->m_flags & XFS_MOUNT_ROOTQCHECK) {
if (!(++nflushes % XFS_QM_MAX_DQCLUSTER_LOGSZ)) {
xfs_log_force(dqp->q_mount, (xfs_lsn_t)0,
XFS_LOG_FORCE | XFS_LOG_SYNC);
XFS_bflush(dqp->q_mount->m_ddev_targp);
}
}
/* /*
* We flush it delayed write, so don't bother * We flush it delayed write, so don't bother
* releasing the freelist lock. * releasing the freelist lock.
......
...@@ -99,8 +99,6 @@ linvfs_setxstate( ...@@ -99,8 +99,6 @@ linvfs_setxstate(
return -xfs_qm_scall_quotaon(mp, qflags); return -xfs_qm_scall_quotaon(mp, qflags);
case Q_XQUOTAOFF: case Q_XQUOTAOFF:
qflags = xfs_qm_import_flags(flags); qflags = xfs_qm_import_flags(flags);
if (mp->m_dev == rootdev)
return -xfs_qm_scall_quotaoff(mp, qflags, B_FALSE);
if (!XFS_IS_QUOTA_ON(mp)) if (!XFS_IS_QUOTA_ON(mp))
return -ESRCH; return -ESRCH;
return -xfs_qm_scall_quotaoff(mp, qflags, B_FALSE); return -xfs_qm_scall_quotaoff(mp, qflags, B_FALSE);
...@@ -169,17 +167,16 @@ xfs_qm_scall_quotaoff( ...@@ -169,17 +167,16 @@ xfs_qm_scall_quotaoff(
int error; int error;
uint inactivate_flags; uint inactivate_flags;
xfs_qoff_logitem_t *qoffstart; xfs_qoff_logitem_t *qoffstart;
uint sbflags, newflags;
int nculprits; int nculprits;
if (!force && !capable(CAP_SYS_ADMIN)) if (!force && !capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM); return XFS_ERROR(EPERM);
/* /*
* Only root file system can have quotas enabled on disk but not * No file system can have quotas enabled on disk but not in core.
* in core. Note that quota utilities (like quotaoff) _expect_ * Note that quota utilities (like quotaoff) _expect_
* errno == EEXIST here. * errno == EEXIST here.
*/ */
if (mp->m_dev != rootdev && (mp->m_qflags & flags) == 0) if ((mp->m_qflags & flags) == 0)
return XFS_ERROR(EEXIST); return XFS_ERROR(EEXIST);
error = 0; error = 0;
...@@ -191,54 +188,14 @@ xfs_qm_scall_quotaoff( ...@@ -191,54 +188,14 @@ xfs_qm_scall_quotaoff(
* critical thing. * critical thing.
* If quotaoff, then we must be dealing with the root filesystem. * If quotaoff, then we must be dealing with the root filesystem.
*/ */
ASSERT(mp->m_quotainfo || mp->m_dev == rootdev); ASSERT(mp->m_quotainfo);
if (mp->m_quotainfo) if (mp->m_quotainfo)
mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD); mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
/*
* Root file system may or may not have quotas on in core.
* We have to perform the quotaoff accordingly.
*/
if (mp->m_dev == rootdev) {
s = XFS_SB_LOCK(mp);
sbflags = mp->m_sb.sb_qflags;
if ((mp->m_qflags & flags) == 0) {
mp->m_sb.sb_qflags &= ~(flags);
newflags = mp->m_sb.sb_qflags;
XFS_SB_UNLOCK(mp, s);
if (mp->m_quotainfo)
mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
if (sbflags != newflags)
error = xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS);
return (error);
}
XFS_SB_UNLOCK(mp, s);
if ((sbflags & flags) != (mp->m_qflags & flags)) {
/*
* This can happen only with grp+usr quota
* combination. Note: 1) accounting cannot be turned
* off without enforcement also getting turned off.
* 2) Every flag that exists in mpqflags MUST exist
* in sbqflags (but not vice versa).
* which means at this point sbqflags = UQ+GQ+..,
* and mpqflags = UQ or GQ.
*/
ASSERT(sbflags & XFS_GQUOTA_ACCT);
ASSERT((sbflags & XFS_ALL_QUOTA_ACCT) !=
(mp->m_qflags & XFS_ALL_QUOTA_ACCT));
qdprintk("quotaoff, sbflags=%x flags=%x m_qflags=%x\n",
sbflags, flags, mp->m_qflags);
/* XXX TBD Finish this for group quota support */
/* We need to update the SB and mp separately */
return XFS_ERROR(EINVAL);
}
}
ASSERT(mp->m_quotainfo); ASSERT(mp->m_quotainfo);
/* /*
* if we're just turning off quota enforcement, change mp and go. * If we're just turning off quota enforcement, change mp and go.
*/ */
if ((flags & XFS_ALL_QUOTA_ACCT) == 0) { if ((flags & XFS_ALL_QUOTA_ACCT) == 0) {
mp->m_qflags &= ~(flags); mp->m_qflags &= ~(flags);
...@@ -272,8 +229,8 @@ xfs_qm_scall_quotaoff( ...@@ -272,8 +229,8 @@ xfs_qm_scall_quotaoff(
} }
/* /*
* Nothing to do? Don't complain. * Nothing to do? Don't complain. This happens when we're just
* This happens when we're just turning off quota enforcement. * turning off quota enforcement.
*/ */
if ((mp->m_qflags & flags) == 0) { if ((mp->m_qflags & flags) == 0) {
mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
...@@ -326,9 +283,8 @@ xfs_qm_scall_quotaoff( ...@@ -326,9 +283,8 @@ xfs_qm_scall_quotaoff(
* So, if we couldn't purge all the dquots from the filesystem, * So, if we couldn't purge all the dquots from the filesystem,
* we can't get rid of the incore data structures. * we can't get rid of the incore data structures.
*/ */
while ((nculprits = xfs_qm_dqpurge_all(mp, dqtype|XFS_QMOPT_QUOTAOFF))) { while ((nculprits = xfs_qm_dqpurge_all(mp, dqtype|XFS_QMOPT_QUOTAOFF)))
delay(10 * nculprits); delay(10 * nculprits);
}
/* /*
* Transactions that had started before ACTIVE state bit was cleared * Transactions that had started before ACTIVE state bit was cleared
...@@ -406,11 +362,9 @@ xfs_qm_scall_trunc_qfiles( ...@@ -406,11 +362,9 @@ xfs_qm_scall_trunc_qfiles(
/* /*
* This does two separate functions: * Switch on (a given) quota enforcement for a filesystem. This takes
* Switch on quotas for the root file system. This will take effect only * effect immediately.
* on reboot. * (Switching on quota accounting must be done at mount time.)
* Switch on (a given) quota enforcement for both root and non-root filesystems.
* This takes effect immediately.
*/ */
STATIC int STATIC int
xfs_qm_scall_quotaon( xfs_qm_scall_quotaon(
...@@ -422,37 +376,26 @@ xfs_qm_scall_quotaon( ...@@ -422,37 +376,26 @@ xfs_qm_scall_quotaon(
uint qf; uint qf;
uint accflags; uint accflags;
__int64_t sbflags; __int64_t sbflags;
boolean_t rootfs;
boolean_t delay;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM); return XFS_ERROR(EPERM);
rootfs = (boolean_t) (mp->m_dev == rootdev);
flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
/* /*
* If caller wants to turn on accounting on /, but accounting * Switching on quota accounting must be done at mount time.
* is already turned on, ignore ACCTing flags.
* Switching on quota accounting for non-root filesystems
* must be done at mount time.
*/ */
accflags = flags & XFS_ALL_QUOTA_ACCT; accflags = flags & XFS_ALL_QUOTA_ACCT;
if (!rootfs || flags &= ~(XFS_ALL_QUOTA_ACCT);
(accflags && rootfs && ((mp->m_qflags & accflags) == accflags))) {
flags &= ~(XFS_ALL_QUOTA_ACCT);
}
sbflags = 0; sbflags = 0;
delay = (boolean_t) ((flags & XFS_ALL_QUOTA_ACCT) != 0);
if (flags == 0) { if (flags == 0) {
qdprintk("quotaon: zero flags, m_qflags=%x\n", mp->m_qflags); qdprintk("quotaon: zero flags, m_qflags=%x\n", mp->m_qflags);
return XFS_ERROR(EINVAL); return XFS_ERROR(EINVAL);
} }
/* Only rootfs can turn on quotas with a delayed effect */ /* No fs can turn on quotas with a delayed effect */
ASSERT(!delay || rootfs); ASSERT((flags & XFS_ALL_QUOTA_ACCT) == 0);
/* /*
* Can't enforce without accounting. We check the superblock * Can't enforce without accounting. We check the superblock
...@@ -476,22 +419,6 @@ xfs_qm_scall_quotaon( ...@@ -476,22 +419,6 @@ xfs_qm_scall_quotaon(
if ((mp->m_qflags & flags) == flags) if ((mp->m_qflags & flags) == flags)
return XFS_ERROR(EEXIST); return XFS_ERROR(EEXIST);
/*
* Change superblock version (if needed) for the root filesystem
*/
if (rootfs && !XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) {
qdprintk("Old superblock version %x\n", mp->m_sb.sb_versionnum);
s = XFS_SB_LOCK(mp);
XFS_SB_VERSION_ADDQUOTA(&mp->m_sb);
mp->m_sb.sb_uquotino = NULLFSINO;
mp->m_sb.sb_gquotino = NULLFSINO;
mp->m_sb.sb_qflags = 0;
XFS_SB_UNLOCK(mp, s);
qdprintk("Converted to version %x\n", mp->m_sb.sb_versionnum);
sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
XFS_SB_GQUOTINO | XFS_SB_QFLAGS);
}
/* /*
* Change sb_qflags on disk but not incore mp->qflags * Change sb_qflags on disk but not incore mp->qflags
* if this is the root filesystem. * if this is the root filesystem.
...@@ -511,11 +438,9 @@ xfs_qm_scall_quotaon( ...@@ -511,11 +438,9 @@ xfs_qm_scall_quotaon(
if ((error = xfs_qm_write_sb_changes(mp, sbflags))) if ((error = xfs_qm_write_sb_changes(mp, sbflags)))
return (error); return (error);
/* /*
* If we had just turned on quotas (ondisk) for rootfs, or if we aren't * If we aren't trying to switch on quota enforcement, we are done.
* trying to switch on quota enforcement, we are done.
*/ */
if (delay || if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
(mp->m_qflags & XFS_UQUOTA_ACCT)) || (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
(flags & XFS_ALL_QUOTA_ENFD) == 0) (flags & XFS_ALL_QUOTA_ENFD) == 0)
return (0); return (0);
...@@ -524,8 +449,7 @@ xfs_qm_scall_quotaon( ...@@ -524,8 +449,7 @@ xfs_qm_scall_quotaon(
return XFS_ERROR(ESRCH); return XFS_ERROR(ESRCH);
/* /*
* Switch on quota enforcement in core. This applies to both root * Switch on quota enforcement in core.
* and non-root file systems.
*/ */
mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD); mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD); mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
...@@ -546,7 +470,6 @@ xfs_qm_scall_getqstat( ...@@ -546,7 +470,6 @@ xfs_qm_scall_getqstat(
{ {
xfs_inode_t *uip, *gip; xfs_inode_t *uip, *gip;
boolean_t tempuqip, tempgqip; boolean_t tempuqip, tempgqip;
__uint16_t sbflags;
uip = gip = NULL; uip = gip = NULL;
tempuqip = tempgqip = B_FALSE; tempuqip = tempgqip = B_FALSE;
...@@ -561,20 +484,6 @@ xfs_qm_scall_getqstat( ...@@ -561,20 +484,6 @@ xfs_qm_scall_getqstat(
out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags & out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
(XFS_ALL_QUOTA_ACCT| (XFS_ALL_QUOTA_ACCT|
XFS_ALL_QUOTA_ENFD)); XFS_ALL_QUOTA_ENFD));
/*
* If the qflags are different on disk, as can be the case when
* root filesystem's quotas are being turned on, return them in the
* HI 8 bits.
*/
if (mp->m_dev == rootdev) {
sbflags = (__uint16_t) xfs_qm_export_flags(mp->m_sb.sb_qflags &
(XFS_ALL_QUOTA_ACCT|
XFS_ALL_QUOTA_ENFD));
ASSERT((out->qs_flags & 0xff00) == 0);
if (sbflags != out->qs_flags)
out->qs_flags |= ((sbflags & 0x00ff) << 8);
}
out->qs_pad = 0; out->qs_pad = 0;
out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino; out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino; out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment