remove dependency of the quota module on behaviors.
PATCH 11/17 remove dependency of the quota module on behaviors.
Mount options are now parsed by the main XFS module and rejected if quota support is not available, and there are some new quota operation for the quotactl syscall and calls to quote in the mount, unmount and sync callchains.
fs/xfs/quota/xfs_qm_bhv.c +33 -208
@@ -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, -bhv_vnode_t *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,30 +235,18 @@ 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);static int __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); -bhv_module_init (XFS_QMOPS ,THIS_MODULE , &xfs_qmops);xfs_qm_init_procfs ();return 0 ; }
@@ -428,8 +255,6 @@ static void __exitxfs_qm_exit (void) {xfs_qm_cleanup_procfs (); -bhv_module_exit (XFS_QMOPS ); -vfs_bhv_clr_custom (&xfs_qmops);if (qm_dqzone)kmem_zone_destroy (qm_dqzone);if (qm_dqtrxzone)
fs/xfs/xfs_mount.h +28 -15
85 lines not on this page · raw message
fs/xfs/xfs_quota.h +5 -5
@@ -330,12 +330,12 @@ typedef struct xfs_dqtrxops { } xfs_dqtrxops_t; #define XFS_DQTRXOP(mp, tp, op, args...) \ - ((mp)->m_qm_ops.xfs_dqtrxops ? \ - ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0) + ((mp)->m_qm_ops->xfs_dqtrxops ? \ + ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : 0) #define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ - ((mp)->m_qm_ops.xfs_dqtrxops ? \ - ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0) + ((mp)->m_qm_ops->xfs_dqtrxops ? \ + ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : (void)0)#define XFS_TRANS_DUP_DQINFO (mp, otp, ntp) \ XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp)
@@ -364,7 +364,7 @@ typedef struct xfs_dqtrxops {extern int xfs_qm_dqcheck (xfs_disk_dquot_t *,xfs_dqid_t ,uint ,uint ,char *);extern int xfs_mount_reset_sbqflags (struct xfs_mount *); -extern struct bhv_module_vfsops xfs_qmops; +extern struct xfs_qmops xfs_qmcore_xfs;#endif /* __KERNEL__ */
fs/xfs/xfs_vfsops.c +103 -4
179 lines not on this page · raw message
fs/xfs/quota/xfs_qm.c +1 -40
53 lines not on this page · raw message
fs/xfs/quota/xfs_qm.h +3 -3
@@ -166,12 +166,11 @@ typedef struct xfs_dquot_acct {extern void xfs_qm_destroy_quotainfo (xfs_mount_t *);extern int xfs_qm_mount_quotas (xfs_mount_t *,int ); -extern void xfs_qm_mount_quotainit (xfs_mount_t *,uint );extern int xfs_qm_quotacheck (xfs_mount_t *);extern void xfs_qm_unmount_quotadestroy (xfs_mount_t *);extern int xfs_qm_unmount_quotas (xfs_mount_t *);extern int xfs_qm_write_sb_changes (xfs_mount_t *,__int64_t ); -extern int xfs_qm_sync (xfs_mount_t *,short ); +extern int xfs_qm_sync (xfs_mount_t *,int );/* dquot stuff */ extern boolean_t xfs_qm_dqalloc_incore (xfs_dquot_t **);
@@ -199,7 +198,8 @@ extern void xfs_qm_freelist_unlink(xfs_extern int xfs_qm_freelist_lock_nowait (xfs_qm_t *);/* system call interface */ -extern int xfs_qm_quotactl (bhv_desc_t *,int ,int ,xfs_caddr_t ); +extern int xfs_qm_quotactl (struct xfs_mount *,int ,int , +xfs_caddr_t );#ifdef DEBUG extern int xfs_qm_internalqcheck (xfs_mount_t *);
fs/xfs/linux-2.6/xfs_super.h +3 -0
@@ -89,4 +89,7 @@ extern void xfs_blkdev_issue_flush(strucextern struct export_operations xfs_export_operations; +#define XFS_M (sb) \ + XFS_VFSTOM(vfs_from_sb(sb)) +#endif /* __XFS_SUPER_H__ */
fs/xfs/quota/xfs_qm_syscalls.c +2 -5
@@ -81,17 +81,14 @@ STATIC void xfs_qm_export_dquot(xfs_moun*/ int xfs_qm_quotactl ( -struct bhv_desc *bdp, +xfs_mount_t *mp,int cmd,int id,xfs_caddr_t addr) { -xfs_mount_t *mp; -bhv_vfs_t *vfsp; +bhv_vfs_t *vfsp =XFS_MTOVFS (mp);int error; - vfsp =bhvtovfs (bdp); - mp =XFS_VFSTOM (vfsp);ASSERT (addr !=NULL || cmd ==Q_XQUOTASYNC );
fs/xfs/linux-2.6/xfs_ksyms.c +0 -1
@@ -199,7 +199,6 @@ EXPORT_SYMBOL(vfs_root);EXPORT_SYMBOL (vfs_statvfs);EXPORT_SYMBOL (vfs_sync);EXPORT_SYMBOL (vfs_vget); -EXPORT_SYMBOL (vfs_quotactl);EXPORT_SYMBOL (vfs_get_inode);EXPORT_SYMBOL (vfs_init_vnode);EXPORT_SYMBOL (vfs_force_shutdown);
fs/xfs/linux-2.6/xfs_vfs.c +0 -15
@@ -155,21 +155,6 @@ vfs_vget(return ((*bhvtovfsops (next)->vfs_vget)(next, vpp, fidp)); } -int -vfs_quotactl ( -struct bhv_desc *bdp, -int cmd, -int id, -caddr_t addr) -{ -struct bhv_desc *next = bdp; - -ASSERT (next); -while (! (bhvtovfsops (next))->vfs_quotactl) - next =BHV_NEXT (next); -return ((*bhvtovfsops (next)->vfs_quotactl)(next, cmd, id, addr)); -} -struct inode * vfs_get_inode( struct bhv_desc *bdp,
fs/xfs/linux-2.6/xfs_vfs.h +0 -5
@@ -127,7 +127,6 @@ typedef int (*vfs_statvfs_t)(bhv_desc_t struct inode *);typedef int (*vfs_sync_t )(bhv_desc_t *,int ,struct cred *);typedef int (*vfs_vget_t )(bhv_desc_t *,struct inode **,struct fid *); -typedef int (*vfs_quotactl_t )(bhv_desc_t *,int ,int ,caddr_t );typedef void (*vfs_init_vnode_t )(bhv_desc_t *,struct inode *,struct xfs_inode *,int );typedef void (*vfs_force_shutdown_t )(bhv_desc_t *,int ,char *,int );
@@ -145,7 +144,6 @@ typedef struct bhv_vfsops {vfs_statvfs_t vfs_statvfs;/* file system statistics */ vfs_sync_t vfs_sync;/* flush files */ vfs_vget_t vfs_vget;/* get vnode from fid */ -vfs_quotactl_t vfs_quotactl;/* disk quota */ vfs_get_inode_t vfs_get_inode;/* bhv specific iget */ vfs_init_vnode_t vfs_init_vnode;/* initialize a new vnode */ vfs_force_shutdown_t vfs_force_shutdown;/* crash and burn */
@@ -165,7 +163,6 @@ typedef struct bhv_vfsops {#define bhv_vfs_statvfs (v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)#define bhv_vfs_sync (v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)#define bhv_vfs_vget (v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp) -#define bhv_vfs_quotactl (v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)#define bhv_vfs_get_inode (v, ino, fl) vfs_get_inode(VFSHEAD(v), ino,fl)#define bhv_vfs_init_vnode (v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)#define bhv_vfs_force_shutdown (v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
@@ -183,7 +180,6 @@ typedef struct bhv_vfsops {#define bhv_next_vfs_statvfs (b, sp,vp) vfs_statvfs(b, sp,vp)#define bhv_next_vfs_sync (b, flag,cr) vfs_sync(b, flag,cr)#define bhv_next_vfs_vget (b, vpp,fidp) vfs_vget(b, vpp,fidp) -#define bhv_next_vfs_quotactl (b, c,id,p) vfs_quotactl(b, c,id,p)#define bhv_next_vfs_get_inode (b, ino,fl) vfs_get_inode(b, ino,fl)#define bhv_next_vfs_init_vnode (b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)#define bhv_next_force_shutdown (b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
@@ -198,7 +194,6 @@ extern int vfs_root(bhv_desc_t *, structextern int vfs_statvfs (bhv_desc_t *,bhv_statvfs_t *,struct inode *);extern int vfs_sync (bhv_desc_t *,int ,struct cred *);extern int vfs_vget (bhv_desc_t *,struct inode **,struct fid *); -extern int vfs_quotactl (bhv_desc_t *,int ,int ,caddr_t );extern struct inode *vfs_get_inode (bhv_desc_t *,xfs_ino_t ,int );extern void vfs_init_vnode (bhv_desc_t *,struct inode *,struct xfs_inode *,int );extern void vfs_force_shutdown (bhv_desc_t *,int ,char *,int );
fs/xfs/linux-2.6/xfs_super.c +5 -5
@@ -735,7 +735,7 @@ xfs_fs_quotasync( struct super_block *sb, int type) { -return -bhv_vfs_quotactl (vfs_from_sb (sb),Q_XQUOTASYNC ,0 ,NULL ); +return -XFS_QM_QUOTACTL (XFS_M (sb),Q_XQUOTASYNC ,0 ,NULL ); }STATIC int
@@ -743,7 +743,7 @@ xfs_fs_getxstate(struct super_block *sb, struct fs_quota_stat *fqs) { - return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); + return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); } STATIC int
@@ -752,7 +752,7 @@ xfs_fs_setxstate( unsigned int flags, int op) { -return -bhv_vfs_quotactl (vfs_from_sb (sb), op,0 , (caddr_t)&flags); +return -XFS_QM_QUOTACTL (XFS_M (sb), op,0 , (caddr_t)&flags); }STATIC int
@@ -762,7 +762,7 @@ xfs_fs_getxquota(qid_t id, struct fs_disk_quota *fdq) { - return -bhv_vfs_quotactl(vfs_from_sb(sb), + return -XFS_QM_QUOTACTL(XFS_M(sb), (type == USRQUOTA) ? Q_XGETQUOTA : ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA), id, (caddr_t)fdq);
@@ -775,7 +775,7 @@ xfs_fs_setxquota(qid_t id, struct fs_disk_quota *fdq) { - return -bhv_vfs_quotactl(vfs_from_sb(sb), + return -XFS_QM_QUOTACTL(XFS_M(sb), (type == USRQUOTA) ? Q_XSETQLIM : ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM), id, (caddr_t)fdq);
fs/xfs/xfs_qmops.c +37 -1
@@ -28,6 +28,8 @@#include "xfs_mount.h" #include "xfs_quota.h" #include "xfs_error.h" +#include "xfs_clnt.h" + STATIC struct xfs_dquot * xfs_dqvopchown_default(
@@ -110,7 +112,7 @@ xfs_noquota_init(return error; } -xfs_qmops_t xfs_qmcore_stub = { +static struct xfs_qmops xfs_qmcore_stub = { .xfs_qminit = (xfs_qminit_t ) xfs_noquota_init, .xfs_qmdone = (xfs_qmdone_t ) fs_noerr, .xfs_qmmount = (xfs_qmmount_t ) fs_noerr,
@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = { .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, .xfs_dqvopchown = xfs_dqvopchown_default, .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, + .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, + .xfs_dqsync = (xfs_dqsync_t) fs_noerr, + .xfs_quotactl = (xfs_quotactl_t) fs_noerr, }; + +int +xfs_qmops_get (struct xfs_mount *mp,struct xfs_mount_args *args) +{ +if (args->flags & (XFSMNT_UQUOTA |XFSMNT_PQUOTA |XFSMNT_GQUOTA )) { +struct xfs_qmops *ops; + + ops =symbol_get (xfs_qmcore_xfs); +if (!ops) { +request_module ("xfs_quota" ); + ops =symbol_get (xfs_qmcore_xfs); + } + +if (!ops) { +cmn_err (CE_WARN ,"XFS: no quota support available." ); +return EINVAL ; + } + mp->m_qm_ops = ops; + }else { + mp->m_qm_ops = &xfs_qmcore_stub; + } + +return 0 ; +} + +void +xfs_qmops_put (struct xfs_mount *mp) +{ +if (mp->m_qm_ops != &xfs_qmcore_stub) +symbol_put (xfs_qmcore_xfs); +}
Quoted 4 lines · Christoph Hellwig
Mount options are now parsed by the main XFS module and rejected if quota support is not available, and there are some new quota operation for the quotactl syscall and calls to quote in the mount, unmount and sync callchains.
....
Quoted 6 lines
fs/xfs/quota/xfs_qm_bhv.c +0
-5-STATIC int -xfs_qm_syncall ( -struct bhv_desc *bhv, -int flags, -cred_t *credp)
.....
Quoted 4 lines
fs/xfs/quota/xfs_qm_bhv.c +0
-4-/* -* Get the Quota Manager to flush the dquots. -*/ -if (XFS_IS_QUOTA_ON (mp)) {
fs/xfs/quota/xfs_qm_bhv.c xfs_qm_statvfs( · line 265
Quoted 10 lines
fs/xfs/quota/xfs_qm_bhv.c +0
-10-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); - } - }
So we check for quota being enabled here before syncing.
Quoted 9 lines
fs/xfs/xfs_vfsops.c +5
-0@@ -941,6 +962,21 @@ xfs_sync( cred_t *credp) {xfs_mount_t *mp =XFS_BHVTOM (bdp); +int error; + +/* +* Get the Quota Manager to flush the dquots. +*/
fs/xfs/xfs_vfsops.c xfs_sync( · line 979
Quoted 10 lines
fs/xfs/xfs_vfsops.c +10
-0+ error =XFS_QM_DQSYNC (mp, flags); +if (error) { +/* +* 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); + }
but we don't for the new code. I assume that this is because of the stub:
fs/xfs/xfs_qmops.c xfs_qmops_t xfs_qmcore_stub = { · line 130
Quoted 10 lines
fs/xfs/xfs_qmops.c +3
-0+static struct xfs_qmops xfs_qmcore_stub = { .xfs_qminit = (xfs_qminit_t ) xfs_noquota_init, .xfs_qmdone = (xfs_qmdone_t ) fs_noerr, .xfs_qmmount = (xfs_qmmount_t ) fs_noerr,@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = { .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, .xfs_dqvopchown = xfs_dqvopchown_default, .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, + .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, + .xfs_dqsync = (xfs_dqsync_t) fs_noerr,
That returns no error.
This is slightly non-obvious that if quotas are not enabled or loaded that this quota sync does not actually return an error. Perhaps a small addition to the comment above XFS_QM_DQSYNC() to explain this would help prevent future misunderstandings.
Cheers,
Dave.
Signature · 3 lines
Dave Chinner Principal Engineer SGI Australian Software Group
Quoted 13 lines · David Chinner
fs/xfs/xfs_qmops.c xfs_qmops_t xfs_qmcore_stub = { · line 130
Quoted 10 lines
fs/xfs/xfs_qmops.c +3
-0+static struct xfs_qmops xfs_qmcore_stub = { .xfs_qminit = (xfs_qminit_t ) xfs_noquota_init, .xfs_qmdone = (xfs_qmdone_t ) fs_noerr, .xfs_qmmount = (xfs_qmmount_t ) fs_noerr,@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = { .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, .xfs_dqvopchown = xfs_dqvopchown_default, .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, + .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, + .xfs_dqsync = (xfs_dqsync_t) fs_noerr,That returns no error.
Quoted 4 lines
This is slightly non-obvious that if quotas are not enabled or loaded that this quota sync does not actually return an error. Perhaps a small addition to the comment above
XFS_QM_DQSYNC()to explain this would help prevent future misunderstandings.
Sure, I'll add a comment.
Quoted 4 lines · Christoph Hellwig
Mount options are now parsed by the main XFS module and rejected if quota support is not available, and there are some new quota operation for the quotactl syscall and calls to quote in the mount, unmount and sync callchains.
....
Quoted 10 lines
(quoted diff) +1
-1@@ -110,7 +112,7 @@ xfs_noquota_init( return error; } -xfs_qmops_t xfs_qmcore_stub = { +static struct xfs_qmops xfs_qmcore_stub = { .xfs_qminit = (xfs_qminit_t) xfs_noquota_init, .xfs_qmdone = (xfs_qmdone_t) fs_noerr, .xfs_qmmount = (xfs_qmmount_t) fs_noerr,
Review xfs_qmops_t xfs_qmcore_stub = { · line 131
Quoted 6 lines
(quoted diff) +3
-0@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = { .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, .xfs_dqvopchown = xfs_dqvopchown_default, .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, + .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, + .xfs_dqsync = (xfs_dqsync_t) fs_noerr, + .xfs_quotactl = (xfs_quotactl_t) fs_noerr,
quotactl needs to return ENOSYS when quota is not enabled on the filesystem, otherwise the quota tools think quota is enabled, no error occurred and they interpret unitialised data as quota data.
This causes all the xfsdump/restore tests to fail in xfsqa because they erroneously detect that quota is enabled and dump/restore garbage for the quota. This:
--- fs/xfs/xfs_qmops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_qmops.c +1 -1
@@ -128,7 +128,7 @@ static struct xfs_qmops xfs_qmcore_stub .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, .xfs_dqsync = (xfs_dqsync_t) fs_noerr, - .xfs_quotactl = (xfs_quotactl_t) fs_noerr, + .xfs_quotactl = (xfs_quotactl_t) fs_nosys, };int
makes qa tests 026 028 046 047 063 065 066 (all in the dump group) pass.
Otherwise, the patch set passes xfsqa without introducing any new regressions.
Cheers,
Dave.
Signature · 3 lines
Dave Chinner Principal Engineer SGI Australian Software Group