xfs: get rid of indirections in the quotaops implementation

Currently we call from the nicely abstracted linux quotaops into a ugly
multiplexer just to split the calls out at the same boundary again.
Rewrite the quota ops handling to remove that obfucation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
Christoph Hellwig
2009-02-09 08:47:34 +01:00
committed by Christoph Hellwig
parent c9a192dcf9
commit fcafb71b57
12 changed files with 181 additions and 262 deletions

View File

@@ -173,6 +173,16 @@ extern void xfs_qm_dqdetach(xfs_inode_t *);
extern int xfs_qm_dqpurge_all(xfs_mount_t *, uint);
extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
/* quota ops */
extern int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
extern int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
fs_disk_quota_t *);
extern int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
fs_disk_quota_t *);
extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
/* vop stuff */
extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
uid_t, gid_t, prid_t, uint,
@@ -190,10 +200,6 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
/* system call interface */
extern int xfs_qm_quotactl(struct xfs_mount *, int, int,
xfs_caddr_t);
#ifdef DEBUG
extern int xfs_qm_internalqcheck(xfs_mount_t *);
#else

View File

@@ -235,7 +235,6 @@ struct xfs_qmops xfs_qmcore_xfs = {
.xfs_dqvopchownresv = xfs_qm_vop_chown_reserve,
.xfs_dqstatvfs = xfs_qm_statvfs,
.xfs_dqsync = xfs_qm_sync,
.xfs_quotactl = xfs_qm_quotactl,
.xfs_dqtrxops = &xfs_trans_dquot_ops,
};
EXPORT_SYMBOL(xfs_qmcore_xfs);

View File

@@ -57,134 +57,15 @@
# define qdprintk(s, args...) do { } while (0)
#endif
STATIC int xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
STATIC int xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
fs_disk_quota_t *);
STATIC int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
STATIC int xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
fs_disk_quota_t *);
STATIC int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
STATIC int xfs_qm_scall_quotaoff(xfs_mount_t *, uint, boolean_t);
STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
uint);
STATIC uint xfs_qm_import_flags(uint);
STATIC uint xfs_qm_export_flags(uint);
STATIC uint xfs_qm_import_qtype_flags(uint);
STATIC uint xfs_qm_export_qtype_flags(uint);
STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
fs_disk_quota_t *);
/*
* The main distribution switch of all XFS quotactl system calls.
*/
int
xfs_qm_quotactl(
xfs_mount_t *mp,
int cmd,
int id,
xfs_caddr_t addr)
{
int error;
ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);
/*
* The following commands are valid even when quotaoff.
*/
switch (cmd) {
case Q_XQUOTARM:
/*
* Truncate quota files. quota must be off.
*/
if (XFS_IS_QUOTA_ON(mp))
return XFS_ERROR(EINVAL);
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
return (xfs_qm_scall_trunc_qfiles(mp,
xfs_qm_import_qtype_flags(*(uint *)addr)));
case Q_XGETQSTAT:
/*
* Get quota status information.
*/
return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
case Q_XQUOTAON:
/*
* QUOTAON - enabling quota enforcement.
* Quota accounting must be turned on at mount time.
*/
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
return (xfs_qm_scall_quotaon(mp,
xfs_qm_import_flags(*(uint *)addr)));
case Q_XQUOTAOFF:
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
break;
case Q_XQUOTASYNC:
return xfs_sync_inodes(mp, SYNC_DELWRI);
default:
break;
}
if (! XFS_IS_QUOTA_ON(mp))
return XFS_ERROR(ESRCH);
switch (cmd) {
case Q_XQUOTAOFF:
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_quotaoff(mp,
xfs_qm_import_flags(*(uint *)addr),
B_FALSE);
break;
case Q_XGETQUOTA:
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
(fs_disk_quota_t *)addr);
break;
case Q_XGETGQUOTA:
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
(fs_disk_quota_t *)addr);
break;
case Q_XGETPQUOTA:
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
(fs_disk_quota_t *)addr);
break;
case Q_XSETQLIM:
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
(fs_disk_quota_t *)addr);
break;
case Q_XSETGQLIM:
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
(fs_disk_quota_t *)addr);
break;
case Q_XSETPQLIM:
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
(fs_disk_quota_t *)addr);
break;
default:
error = XFS_ERROR(EINVAL);
break;
}
return (error);
}
/*
* Turn off quota accounting and/or enforcement for all udquots and/or
* gdquots. Called only at unmount time.
@@ -193,11 +74,10 @@ xfs_qm_quotactl(
* incore, and modifies the ondisk dquot directly. Therefore, for example,
* it is an error to call this twice, without purging the cache.
*/
STATIC int
int
xfs_qm_scall_quotaoff(
xfs_mount_t *mp,
uint flags,
boolean_t force)
uint flags)
{
uint dqtype;
int error;
@@ -205,8 +85,6 @@ xfs_qm_scall_quotaoff(
xfs_qoff_logitem_t *qoffstart;
int nculprits;
if (!force && !capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM);
/*
* No file system can have quotas enabled on disk but not in core.
* Note that quota utilities (like quotaoff) _expect_
@@ -375,7 +253,7 @@ out_error:
return (error);
}
STATIC int
int
xfs_qm_scall_trunc_qfiles(
xfs_mount_t *mp,
uint flags)
@@ -383,8 +261,6 @@ xfs_qm_scall_trunc_qfiles(
int error = 0, error2 = 0;
xfs_inode_t *qip;
if (!capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM);
if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags);
return XFS_ERROR(EINVAL);
@@ -416,7 +292,7 @@ xfs_qm_scall_trunc_qfiles(
* effect immediately.
* (Switching on quota accounting must be done at mount time.)
*/
STATIC int
int
xfs_qm_scall_quotaon(
xfs_mount_t *mp,
uint flags)
@@ -426,9 +302,6 @@ xfs_qm_scall_quotaon(
uint accflags;
__int64_t sbflags;
if (!capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM);
flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
/*
* Switching on quota accounting must be done at mount time.
@@ -517,7 +390,7 @@ xfs_qm_scall_quotaon(
/*
* Return quota status information, such as uquota-off, enforcements, etc.
*/
STATIC int
int
xfs_qm_scall_getqstat(
xfs_mount_t *mp,
fs_quota_stat_t *out)
@@ -582,7 +455,7 @@ xfs_qm_scall_getqstat(
/*
* Adjust quota limits, and start/stop timers accordingly.
*/
STATIC int
int
xfs_qm_scall_setqlim(
xfs_mount_t *mp,
xfs_dqid_t id,
@@ -595,9 +468,6 @@ xfs_qm_scall_setqlim(
int error;
xfs_qcnt_t hard, soft;
if (!capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM);
if ((newlim->d_fieldmask &
(FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
return (0);
@@ -742,7 +612,7 @@ xfs_qm_scall_setqlim(
return error;
}
STATIC int
int
xfs_qm_scall_getquota(
xfs_mount_t *mp,
xfs_dqid_t id,
@@ -934,30 +804,6 @@ xfs_qm_export_dquot(
#endif
}
STATIC uint
xfs_qm_import_qtype_flags(
uint uflags)
{
uint oflags = 0;
/*
* Can't be more than one, or none.
*/
if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
(XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
(XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
(XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
return (0);
oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
return oflags;
}
STATIC uint
xfs_qm_export_qtype_flags(
uint flags)
@@ -978,26 +824,6 @@ xfs_qm_export_qtype_flags(
XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
}
STATIC uint
xfs_qm_import_flags(
uint uflags)
{
uint flags = 0;
if (uflags & XFS_QUOTA_UDQ_ACCT)
flags |= XFS_UQUOTA_ACCT;
if (uflags & XFS_QUOTA_PDQ_ACCT)
flags |= XFS_PQUOTA_ACCT;
if (uflags & XFS_QUOTA_GDQ_ACCT)
flags |= XFS_GQUOTA_ACCT;
if (uflags & XFS_QUOTA_UDQ_ENFD)
flags |= XFS_UQUOTA_ENFD;
if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
flags |= XFS_OQUOTA_ENFD;
return (flags);
}
STATIC uint
xfs_qm_export_flags(
uint flags)