diff options
author | Christoph Hellwig <hch@lst.de> | 2009-02-09 08:47:34 +0100 |
---|---|---|
committer | Christoph Hellwig <hch@brick.lst.de> | 2009-02-09 08:47:34 +0100 |
commit | fcafb71b57a039f2113b0321b3b5535fea3a0aca (patch) | |
tree | ba092276254f40cecb55764b7b4038eccdc6a296 /fs/xfs/linux-2.6 | |
parent | c9a192dcf906a33f59c555924e7796a4b9454217 (diff) |
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>
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_linux.h | 11 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_quotaops.c | 157 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 62 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.h | 1 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 1 |
5 files changed, 161 insertions, 71 deletions
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 507492d6dcc..fc8d776ba05 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -147,17 +147,6 @@ #define SYNCHRONIZE() barrier() #define __return_address __builtin_return_address(0) -/* - * IRIX (BSD) quotactl makes use of separate commands for user/group, - * whereas on Linux the syscall encodes this information into the cmd - * field (see the QCMD macro in quota.h). These macros help keep the - * code portable - they are not visible from the syscall interface. - */ -#define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */ -#define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */ -#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */ -#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */ - #define dfltprid 0 #define MAXPATHLEN 1024 diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c new file mode 100644 index 00000000000..94d9a633d3d --- /dev/null +++ b/fs/xfs/linux-2.6/xfs_quotaops.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2008, Christoph Hellwig + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" +#include "xfs_dmapi.h" +#include "xfs_sb.h" +#include "xfs_inum.h" +#include "xfs_ag.h" +#include "xfs_mount.h" +#include "xfs_quota.h" +#include "xfs_log.h" +#include "xfs_trans.h" +#include "xfs_bmap_btree.h" +#include "xfs_inode.h" +#include "quota/xfs_qm.h" +#include <linux/quota.h> + + +STATIC int +xfs_quota_type(int type) +{ + switch (type) { + case USRQUOTA: + return XFS_DQ_USER; + case GRPQUOTA: + return XFS_DQ_GROUP; + default: + return XFS_DQ_PROJ; + } +} + +STATIC int +xfs_fs_quota_sync( + struct super_block *sb, + int type) +{ + struct xfs_mount *mp = XFS_M(sb); + + if (!XFS_IS_QUOTA_RUNNING(mp)) + return -ENOSYS; + return -xfs_sync_inodes(mp, SYNC_DELWRI); +} + +STATIC int +xfs_fs_get_xstate( + struct super_block *sb, + struct fs_quota_stat *fqs) +{ + struct xfs_mount *mp = XFS_M(sb); + + if (!XFS_IS_QUOTA_RUNNING(mp)) + return -ENOSYS; + return -xfs_qm_scall_getqstat(mp, fqs); +} + +STATIC int +xfs_fs_set_xstate( + struct super_block *sb, + unsigned int uflags, + int op) +{ + struct xfs_mount *mp = XFS_M(sb); + unsigned int flags = 0; + + if (sb->s_flags & MS_RDONLY) + return -EROFS; + if (!XFS_IS_QUOTA_RUNNING(mp)) + return -ENOSYS; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + 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; + + switch (op) { + case Q_XQUOTAON: + return -xfs_qm_scall_quotaon(mp, flags); + case Q_XQUOTAOFF: + if (!XFS_IS_QUOTA_ON(mp)) + return -EINVAL; + return -xfs_qm_scall_quotaoff(mp, flags); + case Q_XQUOTARM: + if (XFS_IS_QUOTA_ON(mp)) + return -EINVAL; + return -xfs_qm_scall_trunc_qfiles(mp, flags); + } + + return -EINVAL; +} + +STATIC int +xfs_fs_get_xquota( + struct super_block *sb, + int type, + qid_t id, + struct fs_disk_quota *fdq) +{ + struct xfs_mount *mp = XFS_M(sb); + + if (!XFS_IS_QUOTA_RUNNING(mp)) + return -ENOSYS; + if (!XFS_IS_QUOTA_ON(mp)) + return -ESRCH; + + return -xfs_qm_scall_getquota(mp, id, xfs_quota_type(type), fdq); +} + +STATIC int +xfs_fs_set_xquota( + struct super_block *sb, + int type, + qid_t id, + struct fs_disk_quota *fdq) +{ + struct xfs_mount *mp = XFS_M(sb); + + if (sb->s_flags & MS_RDONLY) + return -EROFS; + if (!XFS_IS_QUOTA_RUNNING(mp)) + return -ENOSYS; + if (!XFS_IS_QUOTA_ON(mp)) + return -ESRCH; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + return -xfs_qm_scall_setqlim(mp, id, xfs_quota_type(type), fdq); +} + +struct quotactl_ops xfs_quotactl_operations = { + .quota_sync = xfs_fs_quota_sync, + .get_xstate = xfs_fs_get_xstate, + .set_xstate = xfs_fs_set_xstate, + .get_xquota = xfs_fs_get_xquota, + .set_xquota = xfs_fs_set_xquota, +}; diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 712fa295087..bc1e64708e2 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -68,7 +68,6 @@ #include <linux/freezer.h> #include <linux/parser.h> -static struct quotactl_ops xfs_quotactl_operations; static struct super_operations xfs_super_operations; static kmem_zone_t *xfs_ioend_zone; mempool_t *xfs_ioend_pool; @@ -1333,57 +1332,6 @@ xfs_fs_show_options( return -xfs_showargs(XFS_M(mnt->mnt_sb), m); } -STATIC int -xfs_fs_quotasync( - struct super_block *sb, - int type) -{ - return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL); -} - -STATIC int -xfs_fs_getxstate( - struct super_block *sb, - struct fs_quota_stat *fqs) -{ - return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); -} - -STATIC int -xfs_fs_setxstate( - struct super_block *sb, - unsigned int flags, - int op) -{ - return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags); -} - -STATIC int -xfs_fs_getxquota( - struct super_block *sb, - int type, - qid_t id, - struct fs_disk_quota *fdq) -{ - return -XFS_QM_QUOTACTL(XFS_M(sb), - (type == USRQUOTA) ? Q_XGETQUOTA : - ((type == GRPQUOTA) ? Q_XGETGQUOTA : - Q_XGETPQUOTA), id, (caddr_t)fdq); -} - -STATIC int -xfs_fs_setxquota( - struct super_block *sb, - int type, - qid_t id, - struct fs_disk_quota *fdq) -{ - return -XFS_QM_QUOTACTL(XFS_M(sb), - (type == USRQUOTA) ? Q_XSETQLIM : - ((type == GRPQUOTA) ? Q_XSETGQLIM : - Q_XSETPQLIM), id, (caddr_t)fdq); -} - /* * This function fills in xfs_mount_t fields based on mount args. * Note: the superblock _has_ now been read in. @@ -1466,7 +1414,9 @@ xfs_fs_fill_super( sb_min_blocksize(sb, BBSIZE); sb->s_xattr = xfs_xattr_handlers; sb->s_export_op = &xfs_export_operations; +#ifdef CONFIG_XFS_QUOTA sb->s_qcop = &xfs_quotactl_operations; +#endif sb->s_op = &xfs_super_operations; error = xfs_dmops_get(mp); @@ -1609,14 +1559,6 @@ static struct super_operations xfs_super_operations = { .show_options = xfs_fs_show_options, }; -static struct quotactl_ops xfs_quotactl_operations = { - .quota_sync = xfs_fs_quotasync, - .get_xstate = xfs_fs_getxstate, - .set_xstate = xfs_fs_setxstate, - .get_xquota = xfs_fs_getxquota, - .set_xquota = xfs_fs_setxquota, -}; - static struct file_system_type xfs_fs_type = { .owner = THIS_MODULE, .name = "xfs", diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index d5d776d4cd6..5a2ea3a2178 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h @@ -93,6 +93,7 @@ extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); extern const struct export_operations xfs_export_operations; extern struct xattr_handler *xfs_xattr_handlers[]; +extern struct quotactl_ops xfs_quotactl_operations; #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index 5f6de1efe1f..04f058c848a 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h @@ -19,6 +19,7 @@ #define XFS_SYNC_H 1 struct xfs_mount; +struct xfs_perag; typedef struct bhv_vfs_sync_work { struct list_head w_list; |