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() */
#define EFSCORRUPTED 990 /* Filesystem is corrupted */
#define SYNCHRONIZE() barrier()
#define rootdev ROOT_DEV
#define __return_address __builtin_return_address(0)
/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
......
......@@ -101,7 +101,6 @@ STATIC struct export_operations linvfs_export_ops;
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
#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_UQUOTA "usrquota" /* user quota enabled */
#define MNTOPT_GQUOTA "grpquota" /* group quota enabled */
......
......@@ -1839,10 +1839,9 @@ xlog_recover_do_dquot_buffer(
uint type;
/*
* Non-root filesystems are required to send in quota flags
* at mount time.
* Filesystems are required to send in quota flags at mount time.
*/
if (mp->m_qflags == 0 && mp->m_dev != rootdev) {
if (mp->m_qflags == 0) {
return;
}
......@@ -2289,30 +2288,28 @@ xlog_recover_do_dquot_trans(xlog_t *log,
mp = log->l_mp;
/*
* Non-root filesystems are required to send in quota flags
* at mount time.
* Filesystems are required to send in quota flags at mount time.
*/
if (mp->m_qflags == 0 && mp->m_dev != rootdev) {
if (mp->m_qflags == 0)
return (0);
}
recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr;
ASSERT(recddq);
/*
* 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);
if (log->l_quotaoffs_flag & type)
return (0);
/*
* At this point we know that if we are recovering a root filesystem
* then quota was _not_ turned off. Since there is no other flag
* indicate to us otherwise, this must mean that quota's on,
* and the dquot needs to be replayed. Remember that we may not have
* fully recovered the superblock yet, so we can't do the usual trick
* of looking at the SB quota bits.
* At this point we know that quota was _not_ turned off.
* Since the mount flags are not indicating to us otherwise, this
* must mean that quota is on, and the dquot needs to be replayed.
* Remember that we may not have fully recovered the superblock yet,
* so we can't do the usual trick of looking at the SB quota bits.
*
* The other possibility, of course, is that the quota subsystem was
* removed since the last mount - ENOSYS.
......@@ -2323,7 +2320,7 @@ xlog_recover_do_dquot_trans(xlog_t *log,
dq_f->qlf_id,
0, XFS_QMOPT_DOWARN,
"xlog_recover_do_dquot_trans (log copy)"))) {
if (error == ENOSYS)
if (error == ENOSYS)
return (0);
return XFS_ERROR(EIO);
}
......
......@@ -560,7 +560,7 @@ xfs_mountfs(
xfs_daddr_t d;
extern xfs_ioops_t xfs_iocore_xfs; /* from xfs_iocore.c */
__uint64_t ret64;
uint quotaflags, quotaondisk, rootqcheck, needquotacheck;
uint quotaflags, quotaondisk;
uint uquotaondisk = 0, gquotaondisk = 0;
boolean_t needquotamount;
__int64_t update_flags;
......@@ -967,21 +967,13 @@ xfs_mountfs(
/*
* 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) {
/*
* Call mount_quotas at this point only if we won't have to do
* a quotacheck.
*/
if (quotaondisk && !needquotacheck) {
if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
/*
* If the xfs quota code isn't installed,
* we have to reset the quotachk'd bit.
......@@ -1020,10 +1012,6 @@ xfs_mountfs(
if (needquotamount) {
ASSERT(mp->m_qflags == 0);
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))
xfs_mount_reset_sbqflags(mp);
}
......
......@@ -265,7 +265,7 @@ typedef struct xfs_mount {
#if XFS_BIG_FILESYSTEMS
#define XFS_MOUNT_INO64 0x00000002
#endif
#define XFS_MOUNT_ROOTQCHECK 0x00000004
/* 0x00000004 -- currently unused */
/* 0x00000008 -- currently unused */
#define XFS_MOUNT_FS_SHUTDOWN 0x00000010 /* atomic stop of all filesystem
operations, typically for
......
......@@ -301,27 +301,24 @@ xfs_qm_unmount_quotadestroy(
/*
* This is called from xfs_mountfs to start quotas and initialize all
* necessary data structures like quotainfo, and in the rootfs's case
* xfs_Gqm. This is also responsible for running a quotacheck as necessary.
* We are guaranteed that the superblock is consistently read in at this
* point.
* necessary data structures like quotainfo. This is also responsible for
* running a quotacheck as necessary. We are guaranteed that the superblock
* is consistently read in at this point.
*/
int
xfs_qm_mount_quotas(
xfs_mount_t *mp)
{
unsigned long s;
int error;
unsigned long s;
int error = 0;
uint sbf;
error = 0;
/*
* If a non-root file system had quotas running earlier, but decided
* to mount without -o quota/pquota options, revoke the quotachecked
* license, and bail out.
* If a file system had quotas running earlier, but decided to
* mount without -o quota/uquota/gquota options, revoke the
* quotachecked license, and bail out.
*/
if (! XFS_IS_QUOTA_ON(mp) &&
(mp->m_dev != rootdev) &&
(mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) {
mp->m_qflags = 0;
goto write_changes;
......@@ -342,32 +339,6 @@ xfs_qm_mount_quotas(
#if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
cmn_err(CE_NOTE, "Attempting to turn on disk quotas.");
#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));
/*
......@@ -545,20 +516,6 @@ xfs_qm_dqflush_all(
if (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);
if (recl != XFS_QI_MPLRECLAIMS(mp)) {
xfs_qm_mplist_unlock(mp);
......@@ -1568,22 +1525,6 @@ xfs_qm_dqiter_bufs(
flags & XFS_QMOPT_UQUOTA ?
XFS_DQ_USER : XFS_DQ_GROUP);
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.
*/
......@@ -1982,7 +1923,6 @@ xfs_qm_quotacheck(
error_return:
cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
mp->m_flags &= ~(XFS_MOUNT_ROOTQCHECK);
return (error);
}
......@@ -2034,9 +1974,9 @@ xfs_qm_init_quotainos(
/*
* 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
* 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 ((error = xfs_qm_qino_alloc(mp, &uip,
sbflags | XFS_SB_UQUOTINO,
......@@ -2145,20 +2085,6 @@ xfs_qm_shake_freelist(
*/
if (XFS_DQ_IS_DIRTY(dqp)) {
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
* releasing the mplock.
......@@ -2329,21 +2255,6 @@ xfs_qm_dqreclaim_one(void)
*/
if (XFS_DQ_IS_DIRTY(dqp)) {
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
* releasing the freelist lock.
......
......@@ -99,8 +99,6 @@ linvfs_setxstate(
return -xfs_qm_scall_quotaon(mp, qflags);
case Q_XQUOTAOFF:
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))
return -ESRCH;
return -xfs_qm_scall_quotaoff(mp, qflags, B_FALSE);
......@@ -169,17 +167,16 @@ xfs_qm_scall_quotaoff(
int error;
uint inactivate_flags;
xfs_qoff_logitem_t *qoffstart;
uint sbflags, newflags;
int nculprits;
if (!force && !capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM);
/*
* Only root file system can have quotas enabled on disk but not
* in core. Note that quota utilities (like quotaoff) _expect_
* No file system can have quotas enabled on disk but not in core.
* Note that quota utilities (like quotaoff) _expect_
* errno == EEXIST here.
*/
if (mp->m_dev != rootdev && (mp->m_qflags & flags) == 0)
if ((mp->m_qflags & flags) == 0)
return XFS_ERROR(EEXIST);
error = 0;
......@@ -191,54 +188,14 @@ xfs_qm_scall_quotaoff(
* critical thing.
* 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)
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);
/*
* 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) {
mp->m_qflags &= ~(flags);
......@@ -272,8 +229,8 @@ xfs_qm_scall_quotaoff(
}
/*
* Nothing to do? Don't complain.
* This happens when we're just turning off quota enforcement.
* Nothing to do? Don't complain. This happens when we're just
* turning off quota enforcement.
*/
if ((mp->m_qflags & flags) == 0) {
mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
......@@ -326,9 +283,8 @@ xfs_qm_scall_quotaoff(
* So, if we couldn't purge all the dquots from the filesystem,
* 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);
}
/*
* Transactions that had started before ACTIVE state bit was cleared
......@@ -406,11 +362,9 @@ xfs_qm_scall_trunc_qfiles(
/*
* This does two separate functions:
* Switch on quotas for the root file system. This will take effect only
* on reboot.
* Switch on (a given) quota enforcement for both root and non-root filesystems.
* This takes effect immediately.
* Switch on (a given) quota enforcement for a filesystem. This takes
* effect immediately.
* (Switching on quota accounting must be done at mount time.)
*/
STATIC int
xfs_qm_scall_quotaon(
......@@ -422,37 +376,26 @@ xfs_qm_scall_quotaon(
uint qf;
uint accflags;
__int64_t sbflags;
boolean_t rootfs;
boolean_t delay;
if (!capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM);
rootfs = (boolean_t) (mp->m_dev == rootdev);
flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
/*
* If caller wants to turn on accounting on /, but accounting
* is already turned on, ignore ACCTing flags.
* Switching on quota accounting for non-root filesystems
* must be done at mount time.
* Switching on quota accounting must be done at mount time.
*/
accflags = flags & XFS_ALL_QUOTA_ACCT;
if (!rootfs ||
(accflags && rootfs && ((mp->m_qflags & accflags) == accflags))) {
flags &= ~(XFS_ALL_QUOTA_ACCT);
}
flags &= ~(XFS_ALL_QUOTA_ACCT);
sbflags = 0;
delay = (boolean_t) ((flags & XFS_ALL_QUOTA_ACCT) != 0);
if (flags == 0) {
qdprintk("quotaon: zero flags, m_qflags=%x\n", mp->m_qflags);
return XFS_ERROR(EINVAL);
}
/* Only rootfs can turn on quotas with a delayed effect */
ASSERT(!delay || rootfs);
/* No fs can turn on quotas with a delayed effect */
ASSERT((flags & XFS_ALL_QUOTA_ACCT) == 0);
/*
* Can't enforce without accounting. We check the superblock
......@@ -476,22 +419,6 @@ xfs_qm_scall_quotaon(
if ((mp->m_qflags & flags) == flags)
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
* if this is the root filesystem.
......@@ -511,11 +438,9 @@ xfs_qm_scall_quotaon(
if ((error = xfs_qm_write_sb_changes(mp, sbflags)))
return (error);
/*
* If we had just turned on quotas (ondisk) for rootfs, or if we aren't
* trying to switch on quota enforcement, we are done.
* If we aren't trying to switch on quota enforcement, we are done.
*/
if (delay ||
((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
(mp->m_qflags & XFS_UQUOTA_ACCT)) ||
(flags & XFS_ALL_QUOTA_ENFD) == 0)
return (0);
......@@ -524,8 +449,7 @@ xfs_qm_scall_quotaon(
return XFS_ERROR(ESRCH);
/*
* Switch on quota enforcement in core. This applies to both root
* and non-root file systems.
* Switch on quota enforcement in core.
*/
mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
......@@ -546,7 +470,6 @@ xfs_qm_scall_getqstat(
{
xfs_inode_t *uip, *gip;
boolean_t tempuqip, tempgqip;
__uint16_t sbflags;
uip = gip = NULL;
tempuqip = tempgqip = B_FALSE;
......@@ -561,20 +484,6 @@ xfs_qm_scall_getqstat(
out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
(XFS_ALL_QUOTA_ACCT|
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_uquota.qfs_ino = mp->m_sb.sb_uquotino;
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