summaryrefslogtreecommitdiff
path: root/fs/xfs/quota/xfs_qm_bhv.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota/xfs_qm_bhv.c')
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c239
1 files changed, 33 insertions, 206 deletions
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index d2cdb8a2aad..97bb3293758 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -48,172 +48,13 @@
#include "xfs_buf_item.h"
#include "xfs_qm.h"
-#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
-#define MNTOPT_NOQUOTA "noquota" /* no quotas */
-#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
-#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
-#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
-#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
-#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
-#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
-#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
-#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
-#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
-#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
-STATIC int
-xfs_qm_parseargs(
- struct bhv_desc *bhv,
- char *options,
- struct xfs_mount_args *args,
- int update)
-{
- size_t length;
- char *local_options = options;
- char *this_char;
- int error;
- int referenced = update;
-
- while ((this_char = strsep(&local_options, ",")) != NULL) {
- length = strlen(this_char);
- if (local_options)
- length++;
-
- if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
- args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
- args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
- referenced = update;
- } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
- !strcmp(this_char, MNTOPT_UQUOTA) ||
- !strcmp(this_char, MNTOPT_USRQUOTA)) {
- args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
- !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
- args->flags |= XFSMNT_UQUOTA;
- args->flags &= ~XFSMNT_UQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
- !strcmp(this_char, MNTOPT_PRJQUOTA)) {
- args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
- args->flags |= XFSMNT_PQUOTA;
- args->flags &= ~XFSMNT_PQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
- !strcmp(this_char, MNTOPT_GRPQUOTA)) {
- args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
- args->flags |= XFSMNT_GQUOTA;
- args->flags &= ~XFSMNT_GQUOTAENF;
- referenced = 1;
- } else {
- if (local_options)
- *(local_options-1) = ',';
- continue;
- }
-
- while (length--)
- *this_char++ = ',';
- }
-
- if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
- cmn_err(CE_WARN,
- "XFS: cannot mount with both project and group quota");
- return XFS_ERROR(EINVAL);
- }
-
- error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
- if (!error && !referenced)
- bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
- return error;
-}
-
-STATIC int
-xfs_qm_showargs(
- struct bhv_desc *bhv,
- struct seq_file *m)
-{
- struct bhv_vfs *vfsp = bhvtovfs(bhv);
- struct xfs_mount *mp = XFS_VFSTOM(vfsp);
-
- if (mp->m_qflags & XFS_UQUOTA_ACCT) {
- (mp->m_qflags & XFS_UQUOTA_ENFD) ?
- seq_puts(m, "," MNTOPT_USRQUOTA) :
- seq_puts(m, "," MNTOPT_UQUOTANOENF);
- }
-
- if (mp->m_qflags & XFS_PQUOTA_ACCT) {
- (mp->m_qflags & XFS_OQUOTA_ENFD) ?
- seq_puts(m, "," MNTOPT_PRJQUOTA) :
- seq_puts(m, "," MNTOPT_PQUOTANOENF);
- }
-
- if (mp->m_qflags & XFS_GQUOTA_ACCT) {
- (mp->m_qflags & XFS_OQUOTA_ENFD) ?
- seq_puts(m, "," MNTOPT_GRPQUOTA) :
- seq_puts(m, "," MNTOPT_GQUOTANOENF);
- }
-
- if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
- seq_puts(m, "," MNTOPT_NOQUOTA);
-
- return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
-}
-
-STATIC int
-xfs_qm_mount(
- struct bhv_desc *bhv,
- struct xfs_mount_args *args,
- struct cred *cr)
-{
- struct bhv_vfs *vfsp = bhvtovfs(bhv);
- struct xfs_mount *mp = XFS_VFSTOM(vfsp);
-
- if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
- xfs_qm_mount_quotainit(mp, args->flags);
- return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
-}
-
-/*
- * Directory tree accounting is implemented using project quotas, where
- * the project identifier is inherited from parent directories.
- * A statvfs (df, etc.) of a directory that is using project quota should
- * return a statvfs of the project, not the entire filesystem.
- * This makes such trees appear as if they are filesystems in themselves.
- */
-STATIC int
-xfs_qm_statvfs(
- struct bhv_desc *bhv,
+STATIC void
+xfs_fill_statvfs_from_dquot(
bhv_statvfs_t *statp,
- struct bhv_vnode *vnode)
+ xfs_disk_dquot_t *dp)
{
- xfs_mount_t *mp;
- xfs_inode_t *ip;
- xfs_dquot_t *dqp;
- xfs_disk_dquot_t *dp;
__uint64_t limit;
- int error;
-
- error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
- if (error || !vnode)
- return error;
-
- mp = xfs_vfstom(bhvtovfs(bhv));
- ip = xfs_vtoi(vnode);
-
- if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
- return 0;
- if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
- return 0;
- if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
- return 0;
-
- if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
- return 0;
- dp = &dqp->q_core;
limit = dp->d_blk_softlimit ?
be64_to_cpu(dp->d_blk_softlimit) :
@@ -234,37 +75,35 @@ xfs_qm_statvfs(
(statp->f_files > be64_to_cpu(dp->d_icount)) ?
(statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0;
}
-
- xfs_qm_dqput(dqp);
- return 0;
}
-STATIC int
-xfs_qm_syncall(
- struct bhv_desc *bhv,
- int flags,
- cred_t *credp)
+
+/*
+ * Directory tree accounting is implemented using project quotas, where
+ * the project identifier is inherited from parent directories.
+ * A statvfs (df, etc.) of a directory that is using project quota should
+ * return a statvfs of the project, not the entire filesystem.
+ * This makes such trees appear as if they are filesystems in themselves.
+ */
+STATIC void
+xfs_qm_statvfs(
+ xfs_inode_t *ip,
+ bhv_statvfs_t *statp)
{
- struct bhv_vfs *vfsp = bhvtovfs(bhv);
- struct xfs_mount *mp = XFS_VFSTOM(vfsp);
- int error;
+ xfs_mount_t *mp = ip->i_mount;
+ xfs_dquot_t *dqp;
- /*
- * Get the Quota Manager to flush the dquots.
- */
- if (XFS_IS_QUOTA_ON(mp)) {
- if ((error = xfs_qm_sync(mp, flags))) {
- /*
- * If we got an IO error, we will be shutting down.
- * So, there's nothing more for us to do here.
- */
- ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
- if (XFS_FORCED_SHUTDOWN(mp)) {
- return XFS_ERROR(error);
- }
- }
+ if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
+ !((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+ (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
+ return;
+
+ if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
+ xfs_disk_dquot_t *dp = &dqp->q_core;
+
+ xfs_fill_statvfs_from_dquot(statp, dp);
+ xfs_qm_dqput(dqp);
}
- return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
}
STATIC int
@@ -382,7 +221,7 @@ xfs_qm_dqrele_null(
}
-static struct xfs_qmops xfs_qmcore_xfs = {
+struct xfs_qmops xfs_qmcore_xfs = {
.xfs_qminit = xfs_qm_newmount,
.xfs_qmdone = xfs_qm_unmount_quotadestroy,
.xfs_qmmount = xfs_qm_endmount,
@@ -396,36 +235,24 @@ static struct xfs_qmops xfs_qmcore_xfs = {
.xfs_dqvoprename = xfs_qm_vop_rename_dqattach,
.xfs_dqvopchown = xfs_qm_vop_chown,
.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,
};
-
-struct bhv_module_vfsops xfs_qmops = { {
- BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
- .vfs_parseargs = xfs_qm_parseargs,
- .vfs_showargs = xfs_qm_showargs,
- .vfs_mount = xfs_qm_mount,
- .vfs_statvfs = xfs_qm_statvfs,
- .vfs_sync = xfs_qm_syncall,
- .vfs_quotactl = xfs_qm_quotactl, },
-};
-
+EXPORT_SYMBOL(xfs_qmcore_xfs);
void __init
xfs_qm_init(void)
{
- static char message[] __initdata =
- KERN_INFO "SGI XFS Quota Management subsystem\n";
-
- printk(message);
+ printk(KERN_INFO "SGI XFS Quota Management subsystem\n");
mutex_init(&xfs_Gqm_lock);
- vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs);
xfs_qm_init_procfs();
}
void __exit
xfs_qm_exit(void)
{
- vfs_bhv_clr_custom(&xfs_qmops);
xfs_qm_cleanup_procfs();
if (qm_dqzone)
kmem_zone_destroy(qm_dqzone);