|
@@ -57,134 +57,15 @@
|
|
# define qdprintk(s, args...) do { } while (0)
|
|
# define qdprintk(s, args...) do { } while (0)
|
|
#endif
|
|
#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(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
|
|
STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
|
|
STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
|
|
uint);
|
|
uint);
|
|
-STATIC uint xfs_qm_import_flags(uint);
|
|
|
|
STATIC uint xfs_qm_export_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 uint xfs_qm_export_qtype_flags(uint);
|
|
STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
|
|
STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
|
|
fs_disk_quota_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
|
|
* Turn off quota accounting and/or enforcement for all udquots and/or
|
|
* gdquots. Called only at unmount time.
|
|
* gdquots. Called only at unmount time.
|
|
@@ -193,11 +74,10 @@ xfs_qm_quotactl(
|
|
* incore, and modifies the ondisk dquot directly. Therefore, for example,
|
|
* incore, and modifies the ondisk dquot directly. Therefore, for example,
|
|
* it is an error to call this twice, without purging the cache.
|
|
* it is an error to call this twice, without purging the cache.
|
|
*/
|
|
*/
|
|
-STATIC int
|
|
|
|
|
|
+int
|
|
xfs_qm_scall_quotaoff(
|
|
xfs_qm_scall_quotaoff(
|
|
xfs_mount_t *mp,
|
|
xfs_mount_t *mp,
|
|
- uint flags,
|
|
|
|
- boolean_t force)
|
|
|
|
|
|
+ uint flags)
|
|
{
|
|
{
|
|
uint dqtype;
|
|
uint dqtype;
|
|
int error;
|
|
int error;
|
|
@@ -205,8 +85,6 @@ xfs_qm_scall_quotaoff(
|
|
xfs_qoff_logitem_t *qoffstart;
|
|
xfs_qoff_logitem_t *qoffstart;
|
|
int nculprits;
|
|
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.
|
|
* No file system can have quotas enabled on disk but not in core.
|
|
* Note that quota utilities (like quotaoff) _expect_
|
|
* Note that quota utilities (like quotaoff) _expect_
|
|
@@ -375,7 +253,7 @@ out_error:
|
|
return (error);
|
|
return (error);
|
|
}
|
|
}
|
|
|
|
|
|
-STATIC int
|
|
|
|
|
|
+int
|
|
xfs_qm_scall_trunc_qfiles(
|
|
xfs_qm_scall_trunc_qfiles(
|
|
xfs_mount_t *mp,
|
|
xfs_mount_t *mp,
|
|
uint flags)
|
|
uint flags)
|
|
@@ -383,8 +261,6 @@ xfs_qm_scall_trunc_qfiles(
|
|
int error = 0, error2 = 0;
|
|
int error = 0, error2 = 0;
|
|
xfs_inode_t *qip;
|
|
xfs_inode_t *qip;
|
|
|
|
|
|
- if (!capable(CAP_SYS_ADMIN))
|
|
|
|
- return XFS_ERROR(EPERM);
|
|
|
|
if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
|
|
if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
|
|
qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags);
|
|
qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags);
|
|
return XFS_ERROR(EINVAL);
|
|
return XFS_ERROR(EINVAL);
|
|
@@ -416,7 +292,7 @@ xfs_qm_scall_trunc_qfiles(
|
|
* effect immediately.
|
|
* effect immediately.
|
|
* (Switching on quota accounting must be done at mount time.)
|
|
* (Switching on quota accounting must be done at mount time.)
|
|
*/
|
|
*/
|
|
-STATIC int
|
|
|
|
|
|
+int
|
|
xfs_qm_scall_quotaon(
|
|
xfs_qm_scall_quotaon(
|
|
xfs_mount_t *mp,
|
|
xfs_mount_t *mp,
|
|
uint flags)
|
|
uint flags)
|
|
@@ -426,9 +302,6 @@ xfs_qm_scall_quotaon(
|
|
uint accflags;
|
|
uint accflags;
|
|
__int64_t sbflags;
|
|
__int64_t sbflags;
|
|
|
|
|
|
- if (!capable(CAP_SYS_ADMIN))
|
|
|
|
- return XFS_ERROR(EPERM);
|
|
|
|
-
|
|
|
|
flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
|
|
flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
|
|
/*
|
|
/*
|
|
* Switching on quota accounting must be done at mount time.
|
|
* 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.
|
|
* Return quota status information, such as uquota-off, enforcements, etc.
|
|
*/
|
|
*/
|
|
-STATIC int
|
|
|
|
|
|
+int
|
|
xfs_qm_scall_getqstat(
|
|
xfs_qm_scall_getqstat(
|
|
xfs_mount_t *mp,
|
|
xfs_mount_t *mp,
|
|
fs_quota_stat_t *out)
|
|
fs_quota_stat_t *out)
|
|
@@ -582,7 +455,7 @@ xfs_qm_scall_getqstat(
|
|
/*
|
|
/*
|
|
* Adjust quota limits, and start/stop timers accordingly.
|
|
* Adjust quota limits, and start/stop timers accordingly.
|
|
*/
|
|
*/
|
|
-STATIC int
|
|
|
|
|
|
+int
|
|
xfs_qm_scall_setqlim(
|
|
xfs_qm_scall_setqlim(
|
|
xfs_mount_t *mp,
|
|
xfs_mount_t *mp,
|
|
xfs_dqid_t id,
|
|
xfs_dqid_t id,
|
|
@@ -595,9 +468,6 @@ xfs_qm_scall_setqlim(
|
|
int error;
|
|
int error;
|
|
xfs_qcnt_t hard, soft;
|
|
xfs_qcnt_t hard, soft;
|
|
|
|
|
|
- if (!capable(CAP_SYS_ADMIN))
|
|
|
|
- return XFS_ERROR(EPERM);
|
|
|
|
-
|
|
|
|
if ((newlim->d_fieldmask &
|
|
if ((newlim->d_fieldmask &
|
|
(FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
|
|
(FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
|
|
return (0);
|
|
return (0);
|
|
@@ -742,7 +612,7 @@ xfs_qm_scall_setqlim(
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
-STATIC int
|
|
|
|
|
|
+int
|
|
xfs_qm_scall_getquota(
|
|
xfs_qm_scall_getquota(
|
|
xfs_mount_t *mp,
|
|
xfs_mount_t *mp,
|
|
xfs_dqid_t id,
|
|
xfs_dqid_t id,
|
|
@@ -934,30 +804,6 @@ xfs_qm_export_dquot(
|
|
#endif
|
|
#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
|
|
STATIC uint
|
|
xfs_qm_export_qtype_flags(
|
|
xfs_qm_export_qtype_flags(
|
|
uint flags)
|
|
uint flags)
|
|
@@ -978,26 +824,6 @@ xfs_qm_export_qtype_flags(
|
|
XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
|
|
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
|
|
STATIC uint
|
|
xfs_qm_export_flags(
|
|
xfs_qm_export_flags(
|
|
uint flags)
|
|
uint flags)
|