2009-02-09 08:47:34 +01:00
/*
* 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"
2013-08-12 20:49:26 +10:00
# include "xfs_format.h"
2013-10-23 10:50:10 +11:00
# include "xfs_log_format.h"
2013-08-12 20:49:32 +10:00
# include "xfs_trans_resv.h"
2009-02-09 08:47:34 +01:00
# include "xfs_mount.h"
2013-10-23 10:51:50 +11:00
# include "xfs_inode.h"
2009-02-09 08:47:34 +01:00
# include "xfs_quota.h"
# include "xfs_trans.h"
2011-08-12 13:57:55 -05:00
# include "xfs_qm.h"
2009-02-09 08:47:34 +01:00
# 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_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 ;
2014-06-25 14:58:08 +10:00
return xfs_qm_scall_getqstat ( mp , fqs ) ;
2009-02-09 08:47:34 +01:00
}
2013-08-06 17:27:08 -05:00
STATIC int
xfs_fs_get_xstatev (
struct super_block * sb ,
struct fs_quota_statv * fqs )
{
struct xfs_mount * mp = XFS_M ( sb ) ;
if ( ! XFS_IS_QUOTA_RUNNING ( mp ) )
return - ENOSYS ;
2014-06-25 14:58:08 +10:00
return xfs_qm_scall_getqstatv ( mp , fqs ) ;
2013-08-06 17:27:08 -05:00
}
2014-10-08 15:56:21 +02:00
static unsigned int
xfs_quota_flags ( unsigned int uflags )
2009-02-09 08:47:34 +01:00
{
2014-10-08 15:56:21 +02:00
unsigned int flags = 0 ;
2009-02-09 08:47:34 +01:00
2010-06-04 10:56:01 +02:00
if ( uflags & FS_QUOTA_UDQ_ACCT )
2009-02-09 08:47:34 +01:00
flags | = XFS_UQUOTA_ACCT ;
2010-06-04 10:56:01 +02:00
if ( uflags & FS_QUOTA_PDQ_ACCT )
2009-02-09 08:47:34 +01:00
flags | = XFS_PQUOTA_ACCT ;
2010-06-04 10:56:01 +02:00
if ( uflags & FS_QUOTA_GDQ_ACCT )
2009-02-09 08:47:34 +01:00
flags | = XFS_GQUOTA_ACCT ;
2010-06-04 10:56:01 +02:00
if ( uflags & FS_QUOTA_UDQ_ENFD )
2009-02-09 08:47:34 +01:00
flags | = XFS_UQUOTA_ENFD ;
2013-06-27 17:25:10 -05:00
if ( uflags & FS_QUOTA_GDQ_ENFD )
flags | = XFS_GQUOTA_ENFD ;
if ( uflags & FS_QUOTA_PDQ_ENFD )
flags | = XFS_PQUOTA_ENFD ;
2009-02-09 08:47:34 +01:00
2014-10-08 15:56:21 +02:00
return flags ;
}
STATIC int
xfs_quota_enable (
struct super_block * sb ,
unsigned int uflags )
{
struct xfs_mount * mp = XFS_M ( sb ) ;
if ( sb - > s_flags & MS_RDONLY )
return - EROFS ;
if ( ! XFS_IS_QUOTA_RUNNING ( mp ) )
return - ENOSYS ;
return xfs_qm_scall_quotaon ( mp , xfs_quota_flags ( uflags ) ) ;
}
STATIC int
xfs_quota_disable (
struct super_block * sb ,
unsigned int uflags )
{
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 - EINVAL ;
2009-02-09 08:47:34 +01:00
2014-10-08 15:56:21 +02:00
return xfs_qm_scall_quotaoff ( mp , xfs_quota_flags ( uflags ) ) ;
2009-02-09 08:47:34 +01:00
}
xfs: fix Q_XQUOTARM ioctl
The Q_XQUOTARM quotactl was not working properly, because
we weren't passing around proper flags. The xfs_fs_set_xstate()
ioctl handler used the same flags for Q_XQUOTAON/OFF as
well as for Q_XQUOTARM, but Q_XQUOTAON/OFF look for
XFS_UQUOTA_ACCT, XFS_UQUOTA_ENFD, XFS_GQUOTA_ACCT etc,
i.e. quota type + state, while Q_XQUOTARM looks only for
the type of quota, i.e. XFS_DQ_USER, XFS_DQ_GROUP etc.
Unfortunately these flag spaces overlap a bit, so we
got semi-random results for Q_XQUOTARM; i.e. the value
for XFS_DQ_USER == XFS_UQUOTA_ACCT, etc. yeargh.
Add a new quotactl op vector specifically for the QUOTARM
operation, since it operates with a different flag space.
This has been broken more or less forever, AFAICT.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-05-05 17:25:50 +10:00
STATIC int
xfs_fs_rm_xquota (
struct super_block * sb ,
unsigned int uflags )
{
struct xfs_mount * mp = XFS_M ( sb ) ;
unsigned int flags = 0 ;
2014-06-25 14:58:08 +10:00
xfs: fix Q_XQUOTARM ioctl
The Q_XQUOTARM quotactl was not working properly, because
we weren't passing around proper flags. The xfs_fs_set_xstate()
ioctl handler used the same flags for Q_XQUOTAON/OFF as
well as for Q_XQUOTARM, but Q_XQUOTAON/OFF look for
XFS_UQUOTA_ACCT, XFS_UQUOTA_ENFD, XFS_GQUOTA_ACCT etc,
i.e. quota type + state, while Q_XQUOTARM looks only for
the type of quota, i.e. XFS_DQ_USER, XFS_DQ_GROUP etc.
Unfortunately these flag spaces overlap a bit, so we
got semi-random results for Q_XQUOTARM; i.e. the value
for XFS_DQ_USER == XFS_UQUOTA_ACCT, etc. yeargh.
Add a new quotactl op vector specifically for the QUOTARM
operation, since it operates with a different flag space.
This has been broken more or less forever, AFAICT.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-05-05 17:25:50 +10:00
if ( sb - > s_flags & MS_RDONLY )
return - EROFS ;
if ( XFS_IS_QUOTA_ON ( mp ) )
return - EINVAL ;
if ( uflags & FS_USER_QUOTA )
flags | = XFS_DQ_USER ;
if ( uflags & FS_GROUP_QUOTA )
flags | = XFS_DQ_GROUP ;
2014-07-24 21:27:17 +10:00
if ( uflags & FS_PROJ_QUOTA )
xfs: fix Q_XQUOTARM ioctl
The Q_XQUOTARM quotactl was not working properly, because
we weren't passing around proper flags. The xfs_fs_set_xstate()
ioctl handler used the same flags for Q_XQUOTAON/OFF as
well as for Q_XQUOTARM, but Q_XQUOTAON/OFF look for
XFS_UQUOTA_ACCT, XFS_UQUOTA_ENFD, XFS_GQUOTA_ACCT etc,
i.e. quota type + state, while Q_XQUOTARM looks only for
the type of quota, i.e. XFS_DQ_USER, XFS_DQ_GROUP etc.
Unfortunately these flag spaces overlap a bit, so we
got semi-random results for Q_XQUOTARM; i.e. the value
for XFS_DQ_USER == XFS_UQUOTA_ACCT, etc. yeargh.
Add a new quotactl op vector specifically for the QUOTARM
operation, since it operates with a different flag space.
This has been broken more or less forever, AFAICT.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-05-05 17:25:50 +10:00
flags | = XFS_DQ_PROJ ;
2014-06-25 14:58:08 +10:00
return xfs_qm_scall_trunc_qfiles ( mp , flags ) ;
}
xfs: fix Q_XQUOTARM ioctl
The Q_XQUOTARM quotactl was not working properly, because
we weren't passing around proper flags. The xfs_fs_set_xstate()
ioctl handler used the same flags for Q_XQUOTAON/OFF as
well as for Q_XQUOTARM, but Q_XQUOTAON/OFF look for
XFS_UQUOTA_ACCT, XFS_UQUOTA_ENFD, XFS_GQUOTA_ACCT etc,
i.e. quota type + state, while Q_XQUOTARM looks only for
the type of quota, i.e. XFS_DQ_USER, XFS_DQ_GROUP etc.
Unfortunately these flag spaces overlap a bit, so we
got semi-random results for Q_XQUOTARM; i.e. the value
for XFS_DQ_USER == XFS_UQUOTA_ACCT, etc. yeargh.
Add a new quotactl op vector specifically for the QUOTARM
operation, since it operates with a different flag space.
This has been broken more or less forever, AFAICT.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-05-05 17:25:50 +10:00
2009-02-09 08:47:34 +01:00
STATIC int
2010-05-06 17:04:58 -04:00
xfs_fs_get_dqblk (
2009-02-09 08:47:34 +01:00
struct super_block * sb ,
2012-09-16 02:07:49 -07:00
struct kqid qid ,
2014-10-09 16:03:13 +02:00
struct qc_dqblk * qdq )
2009-02-09 08:47:34 +01:00
{
struct xfs_mount * mp = XFS_M ( sb ) ;
if ( ! XFS_IS_QUOTA_RUNNING ( mp ) )
return - ENOSYS ;
if ( ! XFS_IS_QUOTA_ON ( mp ) )
return - ESRCH ;
2014-06-25 14:58:08 +10:00
return xfs_qm_scall_getquota ( mp , from_kqid ( & init_user_ns , qid ) ,
2014-10-09 16:03:13 +02:00
xfs_quota_type ( qid . type ) , qdq ) ;
2009-02-09 08:47:34 +01:00
}
STATIC int
2010-05-06 17:05:17 -04:00
xfs_fs_set_dqblk (
2009-02-09 08:47:34 +01:00
struct super_block * sb ,
2012-09-16 02:07:49 -07:00
struct kqid qid ,
2014-10-09 16:03:13 +02:00
struct qc_dqblk * qdq )
2009-02-09 08:47:34 +01:00
{
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 ;
2014-06-25 14:58:08 +10:00
return xfs_qm_scall_setqlim ( mp , from_kqid ( & init_user_ns , qid ) ,
2014-10-09 16:03:13 +02:00
xfs_quota_type ( qid . type ) , qdq ) ;
2009-02-09 08:47:34 +01:00
}
2009-09-21 17:01:09 -07:00
const struct quotactl_ops xfs_quotactl_operations = {
2013-08-06 17:27:08 -05:00
. get_xstatev = xfs_fs_get_xstatev ,
2009-02-09 08:47:34 +01:00
. get_xstate = xfs_fs_get_xstate ,
2014-10-08 15:56:21 +02:00
. quota_enable = xfs_quota_enable ,
. quota_disable = xfs_quota_disable ,
xfs: fix Q_XQUOTARM ioctl
The Q_XQUOTARM quotactl was not working properly, because
we weren't passing around proper flags. The xfs_fs_set_xstate()
ioctl handler used the same flags for Q_XQUOTAON/OFF as
well as for Q_XQUOTARM, but Q_XQUOTAON/OFF look for
XFS_UQUOTA_ACCT, XFS_UQUOTA_ENFD, XFS_GQUOTA_ACCT etc,
i.e. quota type + state, while Q_XQUOTARM looks only for
the type of quota, i.e. XFS_DQ_USER, XFS_DQ_GROUP etc.
Unfortunately these flag spaces overlap a bit, so we
got semi-random results for Q_XQUOTARM; i.e. the value
for XFS_DQ_USER == XFS_UQUOTA_ACCT, etc. yeargh.
Add a new quotactl op vector specifically for the QUOTARM
operation, since it operates with a different flag space.
This has been broken more or less forever, AFAICT.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
2014-05-05 17:25:50 +10:00
. rm_xquota = xfs_fs_rm_xquota ,
2010-05-06 17:04:58 -04:00
. get_dqblk = xfs_fs_get_dqblk ,
2010-05-06 17:05:17 -04:00
. set_dqblk = xfs_fs_set_dqblk ,
2009-02-09 08:47:34 +01:00
} ;