* [Cluster-devel] [PATCH 1/8] quota: Make VFS quotas use new interface for getting quota info
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 13:47 ` [Cluster-devel] [PATCH 2/8] quota: Wire up Q_GETXSTATE and Q_GETXSTATV calls to work with ->get_state Jan Kara
` (6 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
Create new internal interface for getting information about quota which
contains everything needed for both VFS quotas and XFS quotas. Make VFS
use this and hook it up to Q_GETINFO.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/ext3/super.c | 2 +-
fs/ext4/super.c | 2 +-
fs/quota/dquot.c | 41 +++++++++++++++++++++++++++--------------
fs/quota/quota.c | 25 +++++++++++++++++++++----
fs/reiserfs/super.c | 2 +-
include/linux/quota.h | 33 ++++++++++++++++++++++++++++++++-
include/linux/quotaops.h | 2 +-
7 files changed, 84 insertions(+), 23 deletions(-)
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index d4dbf3c259b3..f037b4b27300 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -789,7 +789,7 @@ static const struct quotactl_ops ext3_qctl_operations = {
.quota_on = ext3_quota_on,
.quota_off = dquot_quota_off,
.quota_sync = dquot_quota_sync,
- .get_info = dquot_get_dqinfo,
+ .get_state = dquot_get_state,
.set_info = dquot_set_dqinfo,
.get_dqblk = dquot_get_dqblk,
.set_dqblk = dquot_set_dqblk
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ac64edbe501d..c6e70831e135 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1076,7 +1076,7 @@ static const struct quotactl_ops ext4_qctl_operations = {
.quota_on = ext4_quota_on,
.quota_off = ext4_quota_off,
.quota_sync = dquot_quota_sync,
- .get_info = dquot_get_dqinfo,
+ .get_state = dquot_get_state,
.set_info = dquot_set_dqinfo,
.get_dqblk = dquot_get_dqblk,
.set_dqblk = dquot_set_dqblk
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 0ccd4ba3a246..cf4edd87e854 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2614,26 +2614,39 @@ out:
EXPORT_SYMBOL(dquot_set_dqblk);
/* Generic routine for getting common part of quota file information */
-int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
+int dquot_get_state(struct super_block *sb, struct qc_state *state)
{
struct mem_dqinfo *mi;
+ struct qc_type_state *tstate;
+ struct quota_info *dqopt = sb_dqopt(sb);
+ int type;
mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
- if (!sb_has_quota_active(sb, type)) {
- mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
- return -ESRCH;
+ memset(state, 0, sizeof(*state));
+ for (type = 0; type < MAXQUOTAS; type++) {
+ if (!sb_has_quota_active(sb, type))
+ continue;
+ tstate = state->s_state + type;
+ mi = sb_dqopt(sb)->info + type;
+ tstate->flags = QCI_ACCT_ENABLED;
+ spin_lock(&dq_data_lock);
+ if (mi->dqi_flags & DQF_SYS_FILE)
+ tstate->flags |= QCI_SYSFILE;
+ if (mi->dqi_flags & DQF_ROOT_SQUASH)
+ tstate->flags |= QCI_ROOT_SQUASH;
+ if (sb_has_quota_limits_enabled(sb, type))
+ tstate->flags |= QCI_LIMITS_ENFORCED;
+ tstate->spc_timelimit = mi->dqi_bgrace;
+ tstate->ino_timelimit = mi->dqi_igrace;
+ tstate->ino = dqopt->files[type]->i_ino;
+ tstate->blocks = dqopt->files[type]->i_blocks;
+ tstate->nextents = 1; /* We don't know... */
+ spin_unlock(&dq_data_lock);
}
- mi = sb_dqopt(sb)->info + type;
- spin_lock(&dq_data_lock);
- ii->dqi_bgrace = mi->dqi_bgrace;
- ii->dqi_igrace = mi->dqi_igrace;
- ii->dqi_flags = mi->dqi_flags & DQF_GETINFO_MASK;
- ii->dqi_valid = IIF_ALL;
- spin_unlock(&dq_data_lock);
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return 0;
}
-EXPORT_SYMBOL(dquot_get_dqinfo);
+EXPORT_SYMBOL(dquot_get_state);
/* Generic routine for setting common part of quota file information */
int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
@@ -2677,7 +2690,7 @@ const struct quotactl_ops dquot_quotactl_ops = {
.quota_on = dquot_quota_on,
.quota_off = dquot_quota_off,
.quota_sync = dquot_quota_sync,
- .get_info = dquot_get_dqinfo,
+ .get_state = dquot_get_state,
.set_info = dquot_set_dqinfo,
.get_dqblk = dquot_get_dqblk,
.set_dqblk = dquot_set_dqblk
@@ -2688,7 +2701,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = {
.quota_enable = dquot_quota_enable,
.quota_disable = dquot_quota_disable,
.quota_sync = dquot_quota_sync,
- .get_info = dquot_get_dqinfo,
+ .get_state = dquot_get_state,
.set_info = dquot_set_dqinfo,
.get_dqblk = dquot_get_dqblk,
.set_dqblk = dquot_set_dqblk
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index d14a799c7785..00d50fca1005 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -118,13 +118,30 @@ static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
{
- struct if_dqinfo info;
+ struct qc_state state;
+ struct qc_type_state *tstate;
+ struct if_dqinfo uinfo;
int ret;
- if (!sb->s_qcop->get_info)
+ /* This checks whether qc_state has enough entries... */
+ BUILD_BUG_ON(MAXQUOTAS > XQM_MAXQUOTAS);
+ if (!sb->s_qcop->get_state)
return -ENOSYS;
- ret = sb->s_qcop->get_info(sb, type, &info);
- if (!ret && copy_to_user(addr, &info, sizeof(info)))
+ ret = sb->s_qcop->get_state(sb, &state);
+ if (ret)
+ return ret;
+ tstate = state.s_state + type;
+ if (!(tstate->flags & QCI_ACCT_ENABLED))
+ return -ESRCH;
+ memset(&uinfo, 0, sizeof(uinfo));
+ uinfo.dqi_bgrace = tstate->spc_timelimit;
+ uinfo.dqi_igrace = tstate->ino_timelimit;
+ if (tstate->flags & QCI_SYSFILE)
+ uinfo.dqi_flags |= DQF_SYS_FILE;
+ if (tstate->flags & QCI_ROOT_SQUASH)
+ uinfo.dqi_flags |= DQF_ROOT_SQUASH;
+ uinfo.dqi_valid = IIF_ALL;
+ if (!ret && copy_to_user(addr, &uinfo, sizeof(uinfo)))
return -EFAULT;
return ret;
}
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 71fbbe3e2dab..68b5f182984e 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -805,7 +805,7 @@ static const struct quotactl_ops reiserfs_qctl_operations = {
.quota_on = reiserfs_quota_on,
.quota_off = dquot_quota_off,
.quota_sync = dquot_quota_sync,
- .get_info = dquot_get_dqinfo,
+ .get_state = dquot_get_state,
.set_info = dquot_set_dqinfo,
.get_dqblk = dquot_get_dqblk,
.set_dqblk = dquot_set_dqblk,
diff --git a/include/linux/quota.h b/include/linux/quota.h
index d534e8ed308a..6ecac0f3b2ca 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -366,6 +366,37 @@ struct qc_dqblk {
#define QC_RT_SPACE (1<<14)
#define QC_ACCT_MASK (QC_SPACE | QC_INO_COUNT | QC_RT_SPACE)
+#define QCI_SYSFILE (1 << 0) /* Quota file is hidden from userspace */
+#define QCI_ROOT_SQUASH (1 << 1) /* Root squash turned on */
+#define QCI_ACCT_ENABLED (1 << 2) /* Quota accounting enabled */
+#define QCI_LIMITS_ENFORCED (1 << 3) /* Quota limits enforced */
+
+/* Structures for communicating via ->get_state */
+struct qc_type_state {
+ unsigned int flags; /* Flags QCI_* */
+ unsigned int spc_timelimit; /* Time after which space softlimit is
+ * enforced */
+ unsigned int ino_timelimit; /* Ditto for inode softlimit */
+ unsigned int rt_spc_timelimit; /* Ditto for real-time space */
+ unsigned int spc_warnlimit; /* Limit for number of space warnings */
+ unsigned int ino_warnlimit; /* Ditto for inodes */
+ unsigned int rt_spc_warnlimit; /* Ditto for real-time space */
+ unsigned long long ino; /* Inode number of quota file */
+ blkcnt_t blocks; /* Number of 512-byte blocks in the file */
+ blkcnt_t nextents; /* Number of extents in the file */
+};
+
+struct qc_state {
+ unsigned int s_incoredqs; /* Number of dquots in core */
+ /*
+ * Per quota type information. The array should really have
+ * max(MAXQUOTAS, XQM_MAXQUOTAS) entries. BUILD_BUG_ON in
+ * quota_getinfo() makes sure XQM_MAXQUOTAS is large enough. Once VFS
+ * supports project quotas, this can be changed to MAXQUOTAS
+ */
+ struct qc_type_state s_state[XQM_MAXQUOTAS];
+};
+
/* Operations handling requests from userspace */
struct quotactl_ops {
int (*quota_on)(struct super_block *, int, int, struct path *);
@@ -373,10 +404,10 @@ struct quotactl_ops {
int (*quota_enable)(struct super_block *, unsigned int);
int (*quota_disable)(struct super_block *, unsigned int);
int (*quota_sync)(struct super_block *, int);
- int (*get_info)(struct super_block *, int, struct if_dqinfo *);
int (*set_info)(struct super_block *, int, struct if_dqinfo *);
int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
+ int (*get_state)(struct super_block *, struct qc_state *);
int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
int (*get_xstatev)(struct super_block *, struct fs_quota_statv *);
int (*rm_xquota)(struct super_block *, unsigned int);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index df73258cca47..6509a29523e2 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -95,7 +95,7 @@ int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
int dquot_quota_off(struct super_block *sb, int type);
int dquot_writeback_dquots(struct super_block *sb, int type);
int dquot_quota_sync(struct super_block *sb, int type);
-int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
+int dquot_get_state(struct super_block *sb, struct qc_state *state);
int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
int dquot_get_dqblk(struct super_block *sb, struct kqid id,
struct qc_dqblk *di);
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 2/8] quota: Wire up Q_GETXSTATE and Q_GETXSTATV calls to work with ->get_state
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
2015-02-18 13:47 ` [Cluster-devel] [PATCH 1/8] quota: Make VFS quotas use new interface for getting quota info Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 13:47 ` [Cluster-devel] [PATCH 3/8] xfs: Convert to using ->get_state callback Jan Kara
` (5 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
Add appropriate conversion functions so that filesystems supporting
->get_state() method can be queried using Q_GETXSTATE and Q_GETXSTATV
calls.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/quota/quota.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 134 insertions(+), 4 deletions(-)
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 00d50fca1005..83939ff4c444 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -269,25 +269,152 @@ static int quota_disable(struct super_block *sb, void __user *addr)
return sb->s_qcop->quota_disable(sb, flags);
}
+static int quota_state_to_flags(struct qc_state *state)
+{
+ int flags = 0;
+
+ if (state->s_state[USRQUOTA].flags & QCI_ACCT_ENABLED)
+ flags |= FS_QUOTA_UDQ_ACCT;
+ if (state->s_state[USRQUOTA].flags & QCI_LIMITS_ENFORCED)
+ flags |= FS_QUOTA_UDQ_ENFD;
+ if (state->s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED)
+ flags |= FS_QUOTA_GDQ_ACCT;
+ if (state->s_state[GRPQUOTA].flags & QCI_LIMITS_ENFORCED)
+ flags |= FS_QUOTA_GDQ_ENFD;
+ if (state->s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED)
+ flags |= FS_QUOTA_PDQ_ACCT;
+ if (state->s_state[PRJQUOTA].flags & QCI_LIMITS_ENFORCED)
+ flags |= FS_QUOTA_PDQ_ENFD;
+ return flags;
+}
+
+static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
+{
+ int type;
+ struct qc_state state;
+ int ret;
+
+ ret = sb->s_qcop->get_state(sb, &state);
+ if (ret < 0)
+ return ret;
+
+ memset(fqs, 0, sizeof(*fqs));
+ fqs->qs_version = FS_QSTAT_VERSION;
+ fqs->qs_flags = quota_state_to_flags(&state);
+ /* No quota enabled? */
+ if (!fqs->qs_flags)
+ return -ENOSYS;
+ fqs->qs_incoredqs = state.s_incoredqs;
+ /*
+ * GETXSTATE quotactl has space for just one set of time limits so
+ * report them for the first enabled quota type
+ */
+ for (type = 0; type < XQM_MAXQUOTAS; type++)
+ if (state.s_state[type].flags & QCI_ACCT_ENABLED)
+ break;
+ BUG_ON(type == XQM_MAXQUOTAS);
+ fqs->qs_btimelimit = state.s_state[type].spc_timelimit;
+ fqs->qs_itimelimit = state.s_state[type].ino_timelimit;
+ fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
+ fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit;
+ fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit;
+ if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) {
+ fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino;
+ fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks;
+ fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents;
+ }
+ if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) {
+ fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino;
+ fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks;
+ fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents;
+ }
+ if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) {
+ /*
+ * Q_XGETQSTAT doesn't have room for both group and project
+ * quotas. So, allow the project quota values to be copied out
+ * only if there is no group quota information available.
+ */
+ if (!(state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED)) {
+ fqs->qs_gquota.qfs_ino = state.s_state[PRJQUOTA].ino;
+ fqs->qs_gquota.qfs_nblks =
+ state.s_state[PRJQUOTA].blocks;
+ fqs->qs_gquota.qfs_nextents =
+ state.s_state[PRJQUOTA].nextents;
+ }
+ }
+ return 0;
+}
+
static int quota_getxstate(struct super_block *sb, void __user *addr)
{
struct fs_quota_stat fqs;
int ret;
- if (!sb->s_qcop->get_xstate)
+ if (!sb->s_qcop->get_xstate && !sb->s_qcop->get_state)
return -ENOSYS;
- ret = sb->s_qcop->get_xstate(sb, &fqs);
+ if (sb->s_qcop->get_state)
+ ret = quota_getstate(sb, &fqs);
+ else
+ ret = sb->s_qcop->get_xstate(sb, &fqs);
if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
return -EFAULT;
return ret;
}
+static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
+{
+ int type;
+ struct qc_state state;
+ int ret;
+
+ ret = sb->s_qcop->get_state(sb, &state);
+ if (ret < 0)
+ return ret;
+
+ memset(fqs, 0, sizeof(*fqs));
+ fqs->qs_version = FS_QSTAT_VERSION;
+ fqs->qs_flags = quota_state_to_flags(&state);
+ /* No quota enabled? */
+ if (!fqs->qs_flags)
+ return -ENOSYS;
+ fqs->qs_incoredqs = state.s_incoredqs;
+ /*
+ * GETXSTATV quotactl has space for just one set of time limits so
+ * report them for the first enabled quota type
+ */
+ for (type = 0; type < XQM_MAXQUOTAS; type++)
+ if (state.s_state[type].flags & QCI_ACCT_ENABLED)
+ break;
+ BUG_ON(type == XQM_MAXQUOTAS);
+ fqs->qs_btimelimit = state.s_state[type].spc_timelimit;
+ fqs->qs_itimelimit = state.s_state[type].ino_timelimit;
+ fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
+ fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit;
+ fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit;
+ if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) {
+ fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino;
+ fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks;
+ fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents;
+ }
+ if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) {
+ fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino;
+ fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks;
+ fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents;
+ }
+ if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) {
+ fqs->qs_pquota.qfs_ino = state.s_state[PRJQUOTA].ino;
+ fqs->qs_pquota.qfs_nblks = state.s_state[PRJQUOTA].blocks;
+ fqs->qs_pquota.qfs_nextents = state.s_state[PRJQUOTA].nextents;
+ }
+ return 0;
+}
+
static int quota_getxstatev(struct super_block *sb, void __user *addr)
{
struct fs_quota_statv fqs;
int ret;
- if (!sb->s_qcop->get_xstatev)
+ if (!sb->s_qcop->get_xstatev && !sb->s_qcop->get_state)
return -ENOSYS;
memset(&fqs, 0, sizeof(fqs));
@@ -301,7 +428,10 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr)
default:
return -EINVAL;
}
- ret = sb->s_qcop->get_xstatev(sb, &fqs);
+ if (sb->s_qcop->get_state)
+ ret = quota_getstatev(sb, &fqs);
+ else
+ ret = sb->s_qcop->get_xstatev(sb, &fqs);
if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
return -EFAULT;
return ret;
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 3/8] xfs: Convert to using ->get_state callback
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
2015-02-18 13:47 ` [Cluster-devel] [PATCH 1/8] quota: Make VFS quotas use new interface for getting quota info Jan Kara
2015-02-18 13:47 ` [Cluster-devel] [PATCH 2/8] quota: Wire up Q_GETXSTATE and Q_GETXSTATV calls to work with ->get_state Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 16:51 ` Christoph Hellwig
2015-02-18 13:47 ` [Cluster-devel] [PATCH 4/8] gfs2: " Jan Kara
` (4 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
Convert xfs to use ->get_state callback instead of ->get_xstate and
->get_xstatev.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/xfs/xfs_qm.h | 4 --
fs/xfs/xfs_qm_syscalls.c | 176 -----------------------------------------------
fs/xfs/xfs_quotaops.c | 98 +++++++++++++++++++-------
3 files changed, 72 insertions(+), 206 deletions(-)
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 0d4d3590cf85..996a04064894 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -168,10 +168,6 @@ extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t,
uint, struct qc_dqblk *);
extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint,
struct qc_dqblk *);
-extern int xfs_qm_scall_getqstat(struct xfs_mount *,
- struct fs_quota_stat *);
-extern int xfs_qm_scall_getqstatv(struct xfs_mount *,
- struct fs_quota_statv *);
extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint);
extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 9b965db45800..9a25c9275fb3 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -38,7 +38,6 @@
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 *,
uint);
-STATIC uint xfs_qm_export_flags(uint);
/*
* Turn off quota accounting and/or enforcement for all udquots and/or
@@ -389,159 +388,6 @@ xfs_qm_scall_quotaon(
return 0;
}
-
-/*
- * Return quota status information, such as uquota-off, enforcements, etc.
- * for Q_XGETQSTAT command.
- */
-int
-xfs_qm_scall_getqstat(
- struct xfs_mount *mp,
- struct fs_quota_stat *out)
-{
- struct xfs_quotainfo *q = mp->m_quotainfo;
- struct xfs_inode *uip = NULL;
- struct xfs_inode *gip = NULL;
- struct xfs_inode *pip = NULL;
- bool tempuqip = false;
- bool tempgqip = false;
- bool temppqip = false;
-
- memset(out, 0, sizeof(fs_quota_stat_t));
-
- out->qs_version = FS_QSTAT_VERSION;
- out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
- (XFS_ALL_QUOTA_ACCT|
- XFS_ALL_QUOTA_ENFD));
- uip = q->qi_uquotaip;
- gip = q->qi_gquotaip;
- pip = q->qi_pquotaip;
- if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
- 0, 0, &uip) == 0)
- tempuqip = true;
- }
- if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
- 0, 0, &gip) == 0)
- tempgqip = true;
- }
- /*
- * Q_XGETQSTAT doesn't have room for both group and project quotas.
- * So, allow the project quota values to be copied out only if
- * there is no group quota information available.
- */
- if (!gip) {
- if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
- 0, 0, &pip) == 0)
- temppqip = true;
- }
- } else
- pip = NULL;
- if (uip) {
- out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
- out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
- out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
- if (tempuqip)
- IRELE(uip);
- }
-
- if (gip) {
- out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
- out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
- out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
- if (tempgqip)
- IRELE(gip);
- }
- if (pip) {
- out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
- out->qs_gquota.qfs_nblks = pip->i_d.di_nblocks;
- out->qs_gquota.qfs_nextents = pip->i_d.di_nextents;
- if (temppqip)
- IRELE(pip);
- }
- out->qs_incoredqs = q->qi_dquots;
- out->qs_btimelimit = q->qi_btimelimit;
- out->qs_itimelimit = q->qi_itimelimit;
- out->qs_rtbtimelimit = q->qi_rtbtimelimit;
- out->qs_bwarnlimit = q->qi_bwarnlimit;
- out->qs_iwarnlimit = q->qi_iwarnlimit;
-
- return 0;
-}
-
-/*
- * Return quota status information, such as uquota-off, enforcements, etc.
- * for Q_XGETQSTATV command, to support separate project quota field.
- */
-int
-xfs_qm_scall_getqstatv(
- struct xfs_mount *mp,
- struct fs_quota_statv *out)
-{
- struct xfs_quotainfo *q = mp->m_quotainfo;
- struct xfs_inode *uip = NULL;
- struct xfs_inode *gip = NULL;
- struct xfs_inode *pip = NULL;
- bool tempuqip = false;
- bool tempgqip = false;
- bool temppqip = false;
-
- out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
- (XFS_ALL_QUOTA_ACCT|
- XFS_ALL_QUOTA_ENFD));
- out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
- out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
- out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
-
- uip = q->qi_uquotaip;
- gip = q->qi_gquotaip;
- pip = q->qi_pquotaip;
- if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
- 0, 0, &uip) == 0)
- tempuqip = true;
- }
- if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
- 0, 0, &gip) == 0)
- tempgqip = true;
- }
- if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
- 0, 0, &pip) == 0)
- temppqip = true;
- }
- if (uip) {
- out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
- out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
- if (tempuqip)
- IRELE(uip);
- }
-
- if (gip) {
- out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
- out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
- if (tempgqip)
- IRELE(gip);
- }
- if (pip) {
- out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks;
- out->qs_pquota.qfs_nextents = pip->i_d.di_nextents;
- if (temppqip)
- IRELE(pip);
- }
- out->qs_incoredqs = q->qi_dquots;
- out->qs_btimelimit = q->qi_btimelimit;
- out->qs_itimelimit = q->qi_itimelimit;
- out->qs_rtbtimelimit = q->qi_rtbtimelimit;
- out->qs_bwarnlimit = q->qi_bwarnlimit;
- out->qs_iwarnlimit = q->qi_iwarnlimit;
-
- return 0;
-}
-
#define XFS_QC_MASK \
(QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
@@ -873,28 +719,6 @@ out_put:
return error;
}
-STATIC uint
-xfs_qm_export_flags(
- uint flags)
-{
- uint uflags;
-
- uflags = 0;
- if (flags & XFS_UQUOTA_ACCT)
- uflags |= FS_QUOTA_UDQ_ACCT;
- if (flags & XFS_GQUOTA_ACCT)
- uflags |= FS_QUOTA_GDQ_ACCT;
- if (flags & XFS_PQUOTA_ACCT)
- uflags |= FS_QUOTA_PDQ_ACCT;
- if (flags & XFS_UQUOTA_ENFD)
- uflags |= FS_QUOTA_UDQ_ENFD;
- if (flags & XFS_GQUOTA_ENFD)
- uflags |= FS_QUOTA_GDQ_ENFD;
- if (flags & XFS_PQUOTA_ENFD)
- uflags |= FS_QUOTA_PDQ_ENFD;
- return uflags;
-}
-
STATIC int
xfs_dqrele_inode(
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index 6923905ab33d..df9835396c4f 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -23,45 +23,92 @@
#include "xfs_inode.h"
#include "xfs_quota.h"
#include "xfs_trans.h"
+#include "xfs_trace.h"
+#include "xfs_icache.h"
#include "xfs_qm.h"
#include <linux/quota.h>
-STATIC int
-xfs_quota_type(int type)
+static void
+xfs_qm_fill_state(
+ struct qc_type_state *tstate,
+ struct xfs_mount *mp,
+ struct xfs_inode *ip,
+ xfs_ino_t ino)
{
- switch (type) {
- case USRQUOTA:
- return XFS_DQ_USER;
- case GRPQUOTA:
- return XFS_DQ_GROUP;
- default:
- return XFS_DQ_PROJ;
+ struct xfs_quotainfo *q = mp->m_quotainfo;
+ bool tempqip = false;
+
+ tstate->ino = ino;
+ if (!ip && ino == NULLFSINO)
+ return;
+ if (!ip) {
+ if (xfs_iget(mp, NULL, ino, 0, 0, &ip))
+ return;
+ tempqip = true;
}
+ tstate->flags |= QCI_SYSFILE;
+ tstate->blocks = ip->i_d.di_nblocks;
+ tstate->nextents = ip->i_d.di_nextents;
+ tstate->spc_timelimit = q->qi_btimelimit;
+ tstate->ino_timelimit = q->qi_itimelimit;
+ tstate->rt_spc_timelimit = q->qi_rtbtimelimit;
+ tstate->spc_warnlimit = q->qi_bwarnlimit;
+ tstate->ino_warnlimit = q->qi_iwarnlimit;
+ tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit;
+ if (tempqip)
+ IRELE(ip);
}
-STATIC int
-xfs_fs_get_xstate(
- struct super_block *sb,
- struct fs_quota_stat *fqs)
+/*
+ * Return quota status information, such as enforcements, quota file inode
+ * numbers etc.
+ */
+static int
+xfs_fs_get_quota_state(
+ struct super_block *sb,
+ struct qc_state *state)
{
- struct xfs_mount *mp = XFS_M(sb);
+ struct xfs_mount *mp = XFS_M(sb);
+ struct xfs_quotainfo *q = mp->m_quotainfo;
+ memset(state, 0, sizeof(*state));
if (!XFS_IS_QUOTA_RUNNING(mp))
- return -ENOSYS;
- return xfs_qm_scall_getqstat(mp, fqs);
+ return 0;
+ state->s_incoredqs = q->qi_dquots;
+ if (XFS_IS_UQUOTA_RUNNING(mp))
+ state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED;
+ if (XFS_IS_UQUOTA_ENFORCED(mp))
+ state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
+ if (XFS_IS_GQUOTA_RUNNING(mp))
+ state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED;
+ if (XFS_IS_GQUOTA_ENFORCED(mp))
+ state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
+ if (XFS_IS_PQUOTA_RUNNING(mp))
+ state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED;
+ if (XFS_IS_PQUOTA_ENFORCED(mp))
+ state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED;
+
+ xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip,
+ mp->m_sb.sb_uquotino);
+ xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip,
+ mp->m_sb.sb_gquotino);
+ xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip,
+ mp->m_sb.sb_pquotino);
+ return 0;
}
STATIC int
-xfs_fs_get_xstatev(
- struct super_block *sb,
- struct fs_quota_statv *fqs)
+xfs_quota_type(int type)
{
- struct xfs_mount *mp = XFS_M(sb);
-
- if (!XFS_IS_QUOTA_RUNNING(mp))
- return -ENOSYS;
- return xfs_qm_scall_getqstatv(mp, fqs);
+ switch (type) {
+ case USRQUOTA:
+ return XFS_DQ_USER;
+ case GRPQUOTA:
+ return XFS_DQ_GROUP;
+ default:
+ return XFS_DQ_PROJ;
+ }
}
static unsigned int
@@ -178,8 +225,7 @@ xfs_fs_set_dqblk(
}
const struct quotactl_ops xfs_quotactl_operations = {
- .get_xstatev = xfs_fs_get_xstatev,
- .get_xstate = xfs_fs_get_xstate,
+ .get_state = xfs_fs_get_quota_state,
.quota_enable = xfs_quota_enable,
.quota_disable = xfs_quota_disable,
.rm_xquota = xfs_fs_rm_xquota,
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 3/8] xfs: Convert to using ->get_state callback
2015-02-18 13:47 ` [Cluster-devel] [PATCH 3/8] xfs: Convert to using ->get_state callback Jan Kara
@ 2015-02-18 16:51 ` Christoph Hellwig
2015-02-18 17:11 ` Jan Kara
0 siblings, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2015-02-18 16:51 UTC (permalink / raw)
To: cluster-devel.redhat.com
> +static void
> +xfs_qm_fill_state(
> + struct qc_type_state *tstate,
> + struct xfs_mount *mp,
> + struct xfs_inode *ip,
> + xfs_ino_t ino)
> +/*
> + * Return quota status information, such as enforcements, quota file inode
> + * numbers etc.
> + */
> +static int
> +xfs_fs_get_quota_state(
> + struct super_block *sb,
> + struct qc_state *state)
We usually tab-align the arguments in XFS prototypes.
Otherwise this patch looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 3/8] xfs: Convert to using ->get_state callback
2015-02-18 16:51 ` Christoph Hellwig
@ 2015-02-18 17:11 ` Jan Kara
0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2015-02-18 17:11 UTC (permalink / raw)
To: cluster-devel.redhat.com
On Wed 18-02-15 08:51:54, Christoph Hellwig wrote:
> > +static void
> > +xfs_qm_fill_state(
> > + struct qc_type_state *tstate,
> > + struct xfs_mount *mp,
> > + struct xfs_inode *ip,
> > + xfs_ino_t ino)
>
> > +/*
> > + * Return quota status information, such as enforcements, quota file inode
> > + * numbers etc.
> > + */
> > +static int
> > +xfs_fs_get_quota_state(
> > + struct super_block *sb,
> > + struct qc_state *state)
>
> We usually tab-align the arguments in XFS prototypes.
OK, fixed.
> Otherwise this patch looks good,
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
Thanks.
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 4/8] gfs2: Convert to using ->get_state callback
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
` (2 preceding siblings ...)
2015-02-18 13:47 ` [Cluster-devel] [PATCH 3/8] xfs: Convert to using ->get_state callback Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 13:55 ` Bob Peterson
2015-02-18 13:47 ` [Cluster-devel] [PATCH 5/8] quota: Remove ->get_xstate and ->get_xstatev callbacks Jan Kara
` (3 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
Convert gfs2 to use ->get_state callback instead of ->get_xstate.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/gfs2/quota.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 3e193cb36996..c76e031ccbb4 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1467,32 +1467,34 @@ int gfs2_quotad(void *data)
return 0;
}
-static int gfs2_quota_get_xstate(struct super_block *sb,
- struct fs_quota_stat *fqs)
+static int gfs2_quota_get_state(struct super_block *sb, struct qc_state *state)
{
struct gfs2_sbd *sdp = sb->s_fs_info;
- memset(fqs, 0, sizeof(struct fs_quota_stat));
- fqs->qs_version = FS_QSTAT_VERSION;
+ memset(state, 0, sizeof(*state));
switch (sdp->sd_args.ar_quota) {
case GFS2_QUOTA_ON:
- fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
+ state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
+ state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
/*FALLTHRU*/
case GFS2_QUOTA_ACCOUNT:
- fqs->qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT);
+ state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED |
+ QCI_SYSFILE;
+ state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED |
+ QCI_SYSFILE;
break;
case GFS2_QUOTA_OFF:
break;
}
-
if (sdp->sd_quota_inode) {
- fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr;
- fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks;
+ state->s_state[USRQUOTA].ino =
+ GFS2_I(sdp->sd_quota_inode)->i_no_addr;
+ state->s_state[USRQUOTA].blocks = sdp->sd_quota_inode->i_blocks;
}
- fqs->qs_uquota.qfs_nextents = 1; /* unsupported */
- fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */
- fqs->qs_incoredqs = list_lru_count(&gfs2_qd_lru);
+ state->s_state[USRQUOTA].nextents = 1; /* unsupported */
+ state->s_state[GRPQUOTA] = state->s_state[USRQUOTA];
+ state->s_incoredqs = list_lru_count(&gfs2_qd_lru);
return 0;
}
@@ -1637,7 +1639,7 @@ out_put:
const struct quotactl_ops gfs2_quotactl_ops = {
.quota_sync = gfs2_quota_sync,
- .get_xstate = gfs2_quota_get_xstate,
+ .get_state = gfs2_quota_get_state,
.get_dqblk = gfs2_get_dqblk,
.set_dqblk = gfs2_set_dqblk,
};
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 4/8] gfs2: Convert to using ->get_state callback
2015-02-18 13:47 ` [Cluster-devel] [PATCH 4/8] gfs2: " Jan Kara
@ 2015-02-18 13:55 ` Bob Peterson
0 siblings, 0 replies; 18+ messages in thread
From: Bob Peterson @ 2015-02-18 13:55 UTC (permalink / raw)
To: cluster-devel.redhat.com
----- Original Message -----
> Convert gfs2 to use ->get_state callback instead of ->get_xstate.
>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
> fs/gfs2/quota.c | 28 +++++++++++++++-------------
> 1 file changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
> index 3e193cb36996..c76e031ccbb4 100644
> --- a/fs/gfs2/quota.c
> +++ b/fs/gfs2/quota.c
> @@ -1467,32 +1467,34 @@ int gfs2_quotad(void *data)
> return 0;
> }
>
> -static int gfs2_quota_get_xstate(struct super_block *sb,
> - struct fs_quota_stat *fqs)
> +static int gfs2_quota_get_state(struct super_block *sb, struct qc_state
> *state)
> {
> struct gfs2_sbd *sdp = sb->s_fs_info;
>
> - memset(fqs, 0, sizeof(struct fs_quota_stat));
> - fqs->qs_version = FS_QSTAT_VERSION;
> + memset(state, 0, sizeof(*state));
>
> switch (sdp->sd_args.ar_quota) {
> case GFS2_QUOTA_ON:
> - fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
> + state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
> + state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
> /*FALLTHRU*/
> case GFS2_QUOTA_ACCOUNT:
> - fqs->qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT);
> + state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED |
> + QCI_SYSFILE;
> + state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED |
> + QCI_SYSFILE;
> break;
> case GFS2_QUOTA_OFF:
> break;
> }
> -
> if (sdp->sd_quota_inode) {
> - fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr;
> - fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks;
> + state->s_state[USRQUOTA].ino =
> + GFS2_I(sdp->sd_quota_inode)->i_no_addr;
> + state->s_state[USRQUOTA].blocks = sdp->sd_quota_inode->i_blocks;
> }
> - fqs->qs_uquota.qfs_nextents = 1; /* unsupported */
> - fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */
> - fqs->qs_incoredqs = list_lru_count(&gfs2_qd_lru);
> + state->s_state[USRQUOTA].nextents = 1; /* unsupported */
> + state->s_state[GRPQUOTA] = state->s_state[USRQUOTA];
> + state->s_incoredqs = list_lru_count(&gfs2_qd_lru);
> return 0;
> }
>
> @@ -1637,7 +1639,7 @@ out_put:
>
> const struct quotactl_ops gfs2_quotactl_ops = {
> .quota_sync = gfs2_quota_sync,
> - .get_xstate = gfs2_quota_get_xstate,
> + .get_state = gfs2_quota_get_state,
> .get_dqblk = gfs2_get_dqblk,
> .set_dqblk = gfs2_set_dqblk,
> };
> --
> 2.1.4
>
>
ACK
Looks right.
Bob Peterson
Red Hat File Systems
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 5/8] quota: Remove ->get_xstate and ->get_xstatev callbacks
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
` (3 preceding siblings ...)
2015-02-18 13:47 ` [Cluster-devel] [PATCH 4/8] gfs2: " Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 13:47 ` [Cluster-devel] [PATCH 6/8] quota: Make ->set_info use structure with neccesary info to VFS and XFS Jan Kara
` (2 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
These callbacks are now unused. Remove them.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/quota/quota.c | 14 ++++----------
include/linux/quota.h | 2 --
2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 83939ff4c444..20d11cd21247 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -350,12 +350,9 @@ static int quota_getxstate(struct super_block *sb, void __user *addr)
struct fs_quota_stat fqs;
int ret;
- if (!sb->s_qcop->get_xstate && !sb->s_qcop->get_state)
+ if (!sb->s_qcop->get_state)
return -ENOSYS;
- if (sb->s_qcop->get_state)
- ret = quota_getstate(sb, &fqs);
- else
- ret = sb->s_qcop->get_xstate(sb, &fqs);
+ ret = quota_getstate(sb, &fqs);
if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
return -EFAULT;
return ret;
@@ -414,7 +411,7 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr)
struct fs_quota_statv fqs;
int ret;
- if (!sb->s_qcop->get_xstatev && !sb->s_qcop->get_state)
+ if (!sb->s_qcop->get_state)
return -ENOSYS;
memset(&fqs, 0, sizeof(fqs));
@@ -428,10 +425,7 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr)
default:
return -EINVAL;
}
- if (sb->s_qcop->get_state)
- ret = quota_getstatev(sb, &fqs);
- else
- ret = sb->s_qcop->get_xstatev(sb, &fqs);
+ ret = quota_getstatev(sb, &fqs);
if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
return -EFAULT;
return ret;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 6ecac0f3b2ca..a07f2ed25284 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -408,8 +408,6 @@ struct quotactl_ops {
int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
int (*get_state)(struct super_block *, struct qc_state *);
- int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
- int (*get_xstatev)(struct super_block *, struct fs_quota_statv *);
int (*rm_xquota)(struct super_block *, unsigned int);
};
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 6/8] quota: Make ->set_info use structure with neccesary info to VFS and XFS
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
` (4 preceding siblings ...)
2015-02-18 13:47 ` [Cluster-devel] [PATCH 5/8] quota: Remove ->get_xstate and ->get_xstatev callbacks Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 16:53 ` Christoph Hellwig
2015-02-18 13:47 ` [Cluster-devel] [PATCH 7/8] xfs: Add support for Q_SETINFO Jan Kara
2015-02-18 13:47 ` [Cluster-devel] [PATCH 8/8] quota: Hook up Q_XSETQLIM for id 0 to ->set_info Jan Kara
7 siblings, 1 reply; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
Change ->set_info to take new qc_info structure which contains all the
necessary information both for XFS and VFS. Convert Q_SETINFO handler
to use this structure.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/quota/dquot.c | 27 ++++++++++++++++-----------
fs/quota/quota.c | 21 ++++++++++++++++++++-
include/linux/quota.h | 21 +++++++++++++++++++--
include/linux/quotaops.h | 2 +-
4 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index cf4edd87e854..f37b74eab807 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2649,33 +2649,38 @@ int dquot_get_state(struct super_block *sb, struct qc_state *state)
EXPORT_SYMBOL(dquot_get_state);
/* Generic routine for setting common part of quota file information */
-int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
+int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii)
{
struct mem_dqinfo *mi;
int err = 0;
+ if ((ii->i_fieldmask & QC_WARNS_MASK) ||
+ (ii->i_fieldmask & QC_RT_SPC_TIMER))
+ return -EINVAL;
mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
if (!sb_has_quota_active(sb, type)) {
err = -ESRCH;
goto out;
}
mi = sb_dqopt(sb)->info + type;
- if (ii->dqi_valid & IIF_FLAGS) {
- if (ii->dqi_flags & ~DQF_SETINFO_MASK ||
- (ii->dqi_flags & DQF_ROOT_SQUASH &&
+ if (ii->i_fieldmask & QC_FLAGS) {
+ if ((ii->i_flags & QCI_ROOT_SQUASH &&
mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) {
err = -EINVAL;
goto out;
}
}
spin_lock(&dq_data_lock);
- if (ii->dqi_valid & IIF_BGRACE)
- mi->dqi_bgrace = ii->dqi_bgrace;
- if (ii->dqi_valid & IIF_IGRACE)
- mi->dqi_igrace = ii->dqi_igrace;
- if (ii->dqi_valid & IIF_FLAGS)
- mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) |
- (ii->dqi_flags & DQF_SETINFO_MASK);
+ if (ii->i_fieldmask & QC_SPC_TIMER)
+ mi->dqi_bgrace = ii->i_spc_timelimit;
+ if (ii->i_fieldmask & QC_INO_TIMER)
+ mi->dqi_igrace = ii->i_ino_timelimit;
+ if (ii->i_fieldmask & QC_FLAGS) {
+ if (ii->i_flags & QCI_ROOT_SQUASH)
+ mi->dqi_flags |= DQF_ROOT_SQUASH;
+ else
+ mi->dqi_flags &= ~DQF_ROOT_SQUASH;
+ }
spin_unlock(&dq_data_lock);
mark_info_dirty(sb, type);
/* Force write to disk */
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 20d11cd21247..741d5a178268 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -149,12 +149,31 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
{
struct if_dqinfo info;
+ struct qc_info qinfo;
if (copy_from_user(&info, addr, sizeof(info)))
return -EFAULT;
if (!sb->s_qcop->set_info)
return -ENOSYS;
- return sb->s_qcop->set_info(sb, type, &info);
+ if (info.dqi_valid & ~(IIF_FLAGS | IIF_BGRACE | IIF_IGRACE))
+ return -EINVAL;
+ memset(&qinfo, 0, sizeof(qinfo));
+ if (info.dqi_valid & IIF_FLAGS) {
+ if (info.dqi_flags & ~DQF_SETINFO_MASK)
+ return -EINVAL;
+ if (info.dqi_flags & DQF_ROOT_SQUASH)
+ qinfo.i_flags |= QCI_ROOT_SQUASH;
+ qinfo.i_fieldmask |= QC_FLAGS;
+ }
+ if (info.dqi_valid & IIF_BGRACE) {
+ qinfo.i_spc_timelimit = info.dqi_bgrace;
+ qinfo.i_fieldmask |= QC_SPC_TIMER;
+ }
+ if (info.dqi_valid & IIF_IGRACE) {
+ qinfo.i_ino_timelimit = info.dqi_igrace;
+ qinfo.i_fieldmask |= QC_INO_TIMER;
+ }
+ return sb->s_qcop->set_info(sb, type, &qinfo);
}
static inline qsize_t qbtos(qsize_t blocks)
diff --git a/include/linux/quota.h b/include/linux/quota.h
index a07f2ed25284..3d521199a0bd 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -344,7 +344,10 @@ struct qc_dqblk {
int d_rt_spc_warns; /* # warnings issued wrt RT space */
};
-/* Field specifiers for ->set_dqblk() in struct qc_dqblk */
+/*
+ * Field specifiers for ->set_dqblk() in struct qc_dqblk and also for
+ * ->set_info() in struct qc_info
+ */
#define QC_INO_SOFT (1<<0)
#define QC_INO_HARD (1<<1)
#define QC_SPC_SOFT (1<<2)
@@ -365,6 +368,7 @@ struct qc_dqblk {
#define QC_INO_COUNT (1<<13)
#define QC_RT_SPACE (1<<14)
#define QC_ACCT_MASK (QC_SPACE | QC_INO_COUNT | QC_RT_SPACE)
+#define QC_FLAGS (1<<15)
#define QCI_SYSFILE (1 << 0) /* Quota file is hidden from userspace */
#define QCI_ROOT_SQUASH (1 << 1) /* Root squash turned on */
@@ -397,6 +401,19 @@ struct qc_state {
struct qc_type_state s_state[XQM_MAXQUOTAS];
};
+/* Structure for communicating via ->set_info */
+struct qc_info {
+ int i_fieldmask; /* mask of fields to change in ->set_info() */
+ unsigned int i_flags; /* Flags QCI_* */
+ unsigned int i_spc_timelimit; /* Time after which space softlimit is
+ * enforced */
+ unsigned int i_ino_timelimit; /* Ditto for inode softlimit */
+ unsigned int i_rt_spc_timelimit;/* Ditto for real-time space */
+ unsigned int i_spc_warnlimit; /* Limit for number of space warnings */
+ unsigned int i_ino_warnlimit; /* Limit for number of inode warnings */
+ unsigned int i_rt_spc_warnlimit; /* Ditto for real-time space */
+};
+
/* Operations handling requests from userspace */
struct quotactl_ops {
int (*quota_on)(struct super_block *, int, int, struct path *);
@@ -404,7 +421,7 @@ struct quotactl_ops {
int (*quota_enable)(struct super_block *, unsigned int);
int (*quota_disable)(struct super_block *, unsigned int);
int (*quota_sync)(struct super_block *, int);
- int (*set_info)(struct super_block *, int, struct if_dqinfo *);
+ int (*set_info)(struct super_block *, int, struct qc_info *);
int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
int (*get_state)(struct super_block *, struct qc_state *);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 6509a29523e2..9f4b07ba9e8c 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -96,7 +96,7 @@ int dquot_quota_off(struct super_block *sb, int type);
int dquot_writeback_dquots(struct super_block *sb, int type);
int dquot_quota_sync(struct super_block *sb, int type);
int dquot_get_state(struct super_block *sb, struct qc_state *state);
-int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
+int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii);
int dquot_get_dqblk(struct super_block *sb, struct kqid id,
struct qc_dqblk *di);
int dquot_set_dqblk(struct super_block *sb, struct kqid id,
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 6/8] quota: Make ->set_info use structure with neccesary info to VFS and XFS
2015-02-18 13:47 ` [Cluster-devel] [PATCH 6/8] quota: Make ->set_info use structure with neccesary info to VFS and XFS Jan Kara
@ 2015-02-18 16:53 ` Christoph Hellwig
2015-02-18 17:17 ` Jan Kara
0 siblings, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2015-02-18 16:53 UTC (permalink / raw)
To: cluster-devel.redhat.com
On Wed, Feb 18, 2015 at 02:47:52PM +0100, Jan Kara wrote:
> Change ->set_info to take new qc_info structure which contains all the
> necessary information both for XFS and VFS. Convert Q_SETINFO handler
> to use this structure.
>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
> fs/quota/dquot.c | 27 ++++++++++++++++-----------
> fs/quota/quota.c | 21 ++++++++++++++++++++-
> include/linux/quota.h | 21 +++++++++++++++++++--
> include/linux/quotaops.h | 2 +-
> 4 files changed, 56 insertions(+), 15 deletions(-)
>
> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
> index cf4edd87e854..f37b74eab807 100644
> --- a/fs/quota/dquot.c
> +++ b/fs/quota/dquot.c
> @@ -2649,33 +2649,38 @@ int dquot_get_state(struct super_block *sb, struct qc_state *state)
> EXPORT_SYMBOL(dquot_get_state);
>
> /* Generic routine for setting common part of quota file information */
> -int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
> +int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii)
> {
> struct mem_dqinfo *mi;
> int err = 0;
>
> + if ((ii->i_fieldmask & QC_WARNS_MASK) ||
> + (ii->i_fieldmask & QC_RT_SPC_TIMER))
> + return -EINVAL;
> mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
> if (!sb_has_quota_active(sb, type)) {
> err = -ESRCH;
> goto out;
> }
> mi = sb_dqopt(sb)->info + type;
> - if (ii->dqi_valid & IIF_FLAGS) {
> - if (ii->dqi_flags & ~DQF_SETINFO_MASK ||
> - (ii->dqi_flags & DQF_ROOT_SQUASH &&
> + if (ii->i_fieldmask & QC_FLAGS) {
> + if ((ii->i_flags & QCI_ROOT_SQUASH &&
> mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD)) {
> err = -EINVAL;
> goto out;
> }
> }
> spin_lock(&dq_data_lock);
> - if (ii->dqi_valid & IIF_BGRACE)
> - mi->dqi_bgrace = ii->dqi_bgrace;
> - if (ii->dqi_valid & IIF_IGRACE)
> - mi->dqi_igrace = ii->dqi_igrace;
> - if (ii->dqi_valid & IIF_FLAGS)
> - mi->dqi_flags = (mi->dqi_flags & ~DQF_SETINFO_MASK) |
> - (ii->dqi_flags & DQF_SETINFO_MASK);
> + if (ii->i_fieldmask & QC_SPC_TIMER)
> + mi->dqi_bgrace = ii->i_spc_timelimit;
> + if (ii->i_fieldmask & QC_INO_TIMER)
> + mi->dqi_igrace = ii->i_ino_timelimit;
> + if (ii->i_fieldmask & QC_FLAGS) {
> + if (ii->i_flags & QCI_ROOT_SQUASH)
> + mi->dqi_flags |= DQF_ROOT_SQUASH;
> + else
> + mi->dqi_flags &= ~DQF_ROOT_SQUASH;
> + }
> spin_unlock(&dq_data_lock);
> mark_info_dirty(sb, type);
> /* Force write to disk */
> diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> index 20d11cd21247..741d5a178268 100644
> --- a/fs/quota/quota.c
> +++ b/fs/quota/quota.c
> @@ -149,12 +149,31 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
> static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
> {
> struct if_dqinfo info;
> + struct qc_info qinfo;
>
> if (copy_from_user(&info, addr, sizeof(info)))
> return -EFAULT;
> if (!sb->s_qcop->set_info)
> return -ENOSYS;
> - return sb->s_qcop->set_info(sb, type, &info);
> + if (info.dqi_valid & ~(IIF_FLAGS | IIF_BGRACE | IIF_IGRACE))
> + return -EINVAL;
> + memset(&qinfo, 0, sizeof(qinfo));
> + if (info.dqi_valid & IIF_FLAGS) {
> + if (info.dqi_flags & ~DQF_SETINFO_MASK)
> + return -EINVAL;
> + if (info.dqi_flags & DQF_ROOT_SQUASH)
> + qinfo.i_flags |= QCI_ROOT_SQUASH;
> + qinfo.i_fieldmask |= QC_FLAGS;
> + }
> + if (info.dqi_valid & IIF_BGRACE) {
> + qinfo.i_spc_timelimit = info.dqi_bgrace;
> + qinfo.i_fieldmask |= QC_SPC_TIMER;
> + }
> + if (info.dqi_valid & IIF_IGRACE) {
> + qinfo.i_ino_timelimit = info.dqi_igrace;
> + qinfo.i_fieldmask |= QC_INO_TIMER;
> + }
> + return sb->s_qcop->set_info(sb, type, &qinfo);
> }
>
> static inline qsize_t qbtos(qsize_t blocks)
> diff --git a/include/linux/quota.h b/include/linux/quota.h
> index a07f2ed25284..3d521199a0bd 100644
> --- a/include/linux/quota.h
> +++ b/include/linux/quota.h
> @@ -344,7 +344,10 @@ struct qc_dqblk {
> int d_rt_spc_warns; /* # warnings issued wrt RT space */
> };
>
> -/* Field specifiers for ->set_dqblk() in struct qc_dqblk */
> +/*
> + * Field specifiers for ->set_dqblk() in struct qc_dqblk and also for
> + * ->set_info() in struct qc_info
> + */
> #define QC_INO_SOFT (1<<0)
> #define QC_INO_HARD (1<<1)
> #define QC_SPC_SOFT (1<<2)
> @@ -365,6 +368,7 @@ struct qc_dqblk {
> #define QC_INO_COUNT (1<<13)
> #define QC_RT_SPACE (1<<14)
> #define QC_ACCT_MASK (QC_SPACE | QC_INO_COUNT | QC_RT_SPACE)
> +#define QC_FLAGS (1<<15)
>
> #define QCI_SYSFILE (1 << 0) /* Quota file is hidden from userspace */
> #define QCI_ROOT_SQUASH (1 << 1) /* Root squash turned on */
> @@ -397,6 +401,19 @@ struct qc_state {
> struct qc_type_state s_state[XQM_MAXQUOTAS];
> };
>
> +/* Structure for communicating via ->set_info */
> +struct qc_info {
> + int i_fieldmask; /* mask of fields to change in ->set_info() */
> + unsigned int i_flags; /* Flags QCI_* */
> + unsigned int i_spc_timelimit; /* Time after which space softlimit is
> + * enforced */
> + unsigned int i_ino_timelimit; /* Ditto for inode softlimit */
> + unsigned int i_rt_spc_timelimit;/* Ditto for real-time space */
> + unsigned int i_spc_warnlimit; /* Limit for number of space warnings */
> + unsigned int i_ino_warnlimit; /* Limit for number of inode warnings */
> + unsigned int i_rt_spc_warnlimit; /* Ditto for real-time space */
> +};
What does the i_ prefix stand for?
Otherwise this looks fine to me.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 6/8] quota: Make ->set_info use structure with neccesary info to VFS and XFS
2015-02-18 16:53 ` Christoph Hellwig
@ 2015-02-18 17:17 ` Jan Kara
0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2015-02-18 17:17 UTC (permalink / raw)
To: cluster-devel.redhat.com
On Wed 18-02-15 08:53:34, Christoph Hellwig wrote:
> On Wed, Feb 18, 2015 at 02:47:52PM +0100, Jan Kara wrote:
> > Change ->set_info to take new qc_info structure which contains all the
> > necessary information both for XFS and VFS. Convert Q_SETINFO handler
> > to use this structure.
...
> > +/* Structure for communicating via ->set_info */
> > +struct qc_info {
> > + int i_fieldmask; /* mask of fields to change in ->set_info() */
> > + unsigned int i_flags; /* Flags QCI_* */
> > + unsigned int i_spc_timelimit; /* Time after which space softlimit is
> > + * enforced */
> > + unsigned int i_ino_timelimit; /* Ditto for inode softlimit */
> > + unsigned int i_rt_spc_timelimit;/* Ditto for real-time space */
> > + unsigned int i_spc_warnlimit; /* Limit for number of space warnings */
> > + unsigned int i_ino_warnlimit; /* Limit for number of inode warnings */
> > + unsigned int i_rt_spc_warnlimit; /* Ditto for real-time space */
> > +};
>
> What does the i_ prefix stand for?
It stands for info. I can change it e.g. to qci_ for quotactl info if you
think that would be better...
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 7/8] xfs: Add support for Q_SETINFO
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
` (5 preceding siblings ...)
2015-02-18 13:47 ` [Cluster-devel] [PATCH 6/8] quota: Make ->set_info use structure with neccesary info to VFS and XFS Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 16:54 ` Christoph Hellwig
2015-02-18 13:47 ` [Cluster-devel] [PATCH 8/8] quota: Hook up Q_XSETQLIM for id 0 to ->set_info Jan Kara
7 siblings, 1 reply; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
Add support to XFS so that time limits can be set through Q_SETINFO
quotactl.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/xfs/xfs_quotaops.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index df9835396c4f..bbe8ddf1f700 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -111,6 +111,42 @@ xfs_quota_type(int type)
}
}
+#define XFS_QC_SETINFO_MASK (QC_TIMER_MASK | QC_WARNS_MASK)
+
+/*
+ * Adjust quota timers & warnings
+ */
+static int
+xfs_fs_set_info(
+ struct super_block *sb,
+ int type,
+ struct qc_info *info)
+{
+ struct xfs_mount *mp = XFS_M(sb);
+ struct qc_dqblk newlim;
+
+ 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 (info->i_fieldmask & ~XFS_QC_SETINFO_MASK)
+ return -EINVAL;
+ if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0)
+ return 0;
+
+ newlim.d_fieldmask = info->i_fieldmask;
+ newlim.d_spc_timer = info->i_spc_timelimit;
+ newlim.d_ino_timer = info->i_ino_timelimit;
+ newlim.d_rt_spc_timer = info->i_rt_spc_timelimit;
+ newlim.d_ino_warns = info->i_ino_warnlimit;
+ newlim.d_spc_warns = info->i_spc_warnlimit;
+ newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit;
+
+ return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim);
+}
+
static unsigned int
xfs_quota_flags(unsigned int uflags)
{
@@ -226,6 +262,7 @@ xfs_fs_set_dqblk(
const struct quotactl_ops xfs_quotactl_operations = {
.get_state = xfs_fs_get_quota_state,
+ .set_info = xfs_fs_set_info,
.quota_enable = xfs_quota_enable,
.quota_disable = xfs_quota_disable,
.rm_xquota = xfs_fs_rm_xquota,
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 8/8] quota: Hook up Q_XSETQLIM for id 0 to ->set_info
2015-02-18 13:47 [Cluster-devel] [PATCH 0/8 v5] quota: Unify VFS and XFS quota interfaces Jan Kara
` (6 preceding siblings ...)
2015-02-18 13:47 ` [Cluster-devel] [PATCH 7/8] xfs: Add support for Q_SETINFO Jan Kara
@ 2015-02-18 13:47 ` Jan Kara
2015-02-18 16:54 ` Christoph Hellwig
7 siblings, 1 reply; 18+ messages in thread
From: Jan Kara @ 2015-02-18 13:47 UTC (permalink / raw)
To: cluster-devel.redhat.com
Setting timers or warning counts for id 0 via Q_XSETQLIM is used to
actually set time limits and warning limits for all users. Hook up
->set_info to this so that VFS quota time limits get set the same
way as XFS ones.
When doing this Q_XSETQLIM for XFS is effectively split into two
independent transactions - one for setting timers and warning limits and
one for setting space and inode limits. Although this is inefficient, it
is rare enough that it does not matter.
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/quota/quota.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 741d5a178268..86ded7375c21 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -517,6 +517,30 @@ static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src)
dst->d_fieldmask |= QC_RT_SPACE;
}
+static void copy_qcinfo_from_xfs_dqblk(struct qc_info *dst,
+ struct fs_disk_quota *src)
+{
+ memset(dst, 0, sizeof(*dst));
+ dst->i_spc_timelimit = src->d_btimer;
+ dst->i_ino_timelimit = src->d_itimer;
+ dst->i_rt_spc_timelimit = src->d_rtbtimer;
+ dst->i_ino_warnlimit = src->d_iwarns;
+ dst->i_spc_warnlimit = src->d_bwarns;
+ dst->i_rt_spc_warnlimit = src->d_rtbwarns;
+ if (src->d_fieldmask & FS_DQ_BWARNS)
+ dst->i_fieldmask |= QC_SPC_WARNS;
+ if (src->d_fieldmask & FS_DQ_IWARNS)
+ dst->i_fieldmask |= QC_INO_WARNS;
+ if (src->d_fieldmask & FS_DQ_RTBWARNS)
+ dst->i_fieldmask |= QC_RT_SPC_WARNS;
+ if (src->d_fieldmask & FS_DQ_BTIMER)
+ dst->i_fieldmask |= QC_SPC_TIMER;
+ if (src->d_fieldmask & FS_DQ_ITIMER)
+ dst->i_fieldmask |= QC_INO_TIMER;
+ if (src->d_fieldmask & FS_DQ_RTBTIMER)
+ dst->i_fieldmask |= QC_RT_SPC_TIMER;
+}
+
static int quota_setxquota(struct super_block *sb, int type, qid_t id,
void __user *addr)
{
@@ -531,6 +555,21 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id,
qid = make_kqid(current_user_ns(), type, id);
if (!qid_valid(qid))
return -EINVAL;
+ /* Are we actually setting timer / warning limits for all users? */
+ if (from_kqid(&init_user_ns, qid) == 0 &&
+ fdq.d_fieldmask & (FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK)) {
+ struct qc_info qinfo;
+ int ret;
+
+ if (!sb->s_qcop->set_info)
+ return -EINVAL;
+ copy_qcinfo_from_xfs_dqblk(&qinfo, &fdq);
+ ret = sb->s_qcop->set_info(sb, type, &qinfo);
+ if (ret)
+ return ret;
+ /* These are already done */
+ fdq.d_fieldmask &= ~(FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK);
+ }
copy_from_xfs_dqblk(&qdq, &fdq);
return sb->s_qcop->set_dqblk(sb, qid, &qdq);
}
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Cluster-devel] [PATCH 3/8] xfs: Convert to using ->get_state callback
2015-03-04 15:15 [Cluster-devel] [PATCH 0/8 v6] quota: Unify VFS and XFS quota interfaces Jan Kara
@ 2015-03-04 15:15 ` Jan Kara
0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2015-03-04 15:15 UTC (permalink / raw)
To: cluster-devel.redhat.com
Convert xfs to use ->get_state callback instead of ->get_xstate and
->get_xstatev.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/xfs/xfs_qm.h | 4 --
fs/xfs/xfs_qm_syscalls.c | 176 -----------------------------------------------
fs/xfs/xfs_quotaops.c | 96 +++++++++++++++++++-------
3 files changed, 71 insertions(+), 205 deletions(-)
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 0d4d3590cf85..996a04064894 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -168,10 +168,6 @@ extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t,
uint, struct qc_dqblk *);
extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint,
struct qc_dqblk *);
-extern int xfs_qm_scall_getqstat(struct xfs_mount *,
- struct fs_quota_stat *);
-extern int xfs_qm_scall_getqstatv(struct xfs_mount *,
- struct fs_quota_statv *);
extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint);
extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 9b965db45800..9a25c9275fb3 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -38,7 +38,6 @@
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 *,
uint);
-STATIC uint xfs_qm_export_flags(uint);
/*
* Turn off quota accounting and/or enforcement for all udquots and/or
@@ -389,159 +388,6 @@ xfs_qm_scall_quotaon(
return 0;
}
-
-/*
- * Return quota status information, such as uquota-off, enforcements, etc.
- * for Q_XGETQSTAT command.
- */
-int
-xfs_qm_scall_getqstat(
- struct xfs_mount *mp,
- struct fs_quota_stat *out)
-{
- struct xfs_quotainfo *q = mp->m_quotainfo;
- struct xfs_inode *uip = NULL;
- struct xfs_inode *gip = NULL;
- struct xfs_inode *pip = NULL;
- bool tempuqip = false;
- bool tempgqip = false;
- bool temppqip = false;
-
- memset(out, 0, sizeof(fs_quota_stat_t));
-
- out->qs_version = FS_QSTAT_VERSION;
- out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
- (XFS_ALL_QUOTA_ACCT|
- XFS_ALL_QUOTA_ENFD));
- uip = q->qi_uquotaip;
- gip = q->qi_gquotaip;
- pip = q->qi_pquotaip;
- if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
- 0, 0, &uip) == 0)
- tempuqip = true;
- }
- if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
- 0, 0, &gip) == 0)
- tempgqip = true;
- }
- /*
- * Q_XGETQSTAT doesn't have room for both group and project quotas.
- * So, allow the project quota values to be copied out only if
- * there is no group quota information available.
- */
- if (!gip) {
- if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
- 0, 0, &pip) == 0)
- temppqip = true;
- }
- } else
- pip = NULL;
- if (uip) {
- out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
- out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
- out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
- if (tempuqip)
- IRELE(uip);
- }
-
- if (gip) {
- out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
- out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
- out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
- if (tempgqip)
- IRELE(gip);
- }
- if (pip) {
- out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
- out->qs_gquota.qfs_nblks = pip->i_d.di_nblocks;
- out->qs_gquota.qfs_nextents = pip->i_d.di_nextents;
- if (temppqip)
- IRELE(pip);
- }
- out->qs_incoredqs = q->qi_dquots;
- out->qs_btimelimit = q->qi_btimelimit;
- out->qs_itimelimit = q->qi_itimelimit;
- out->qs_rtbtimelimit = q->qi_rtbtimelimit;
- out->qs_bwarnlimit = q->qi_bwarnlimit;
- out->qs_iwarnlimit = q->qi_iwarnlimit;
-
- return 0;
-}
-
-/*
- * Return quota status information, such as uquota-off, enforcements, etc.
- * for Q_XGETQSTATV command, to support separate project quota field.
- */
-int
-xfs_qm_scall_getqstatv(
- struct xfs_mount *mp,
- struct fs_quota_statv *out)
-{
- struct xfs_quotainfo *q = mp->m_quotainfo;
- struct xfs_inode *uip = NULL;
- struct xfs_inode *gip = NULL;
- struct xfs_inode *pip = NULL;
- bool tempuqip = false;
- bool tempgqip = false;
- bool temppqip = false;
-
- out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
- (XFS_ALL_QUOTA_ACCT|
- XFS_ALL_QUOTA_ENFD));
- out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
- out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
- out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
-
- uip = q->qi_uquotaip;
- gip = q->qi_gquotaip;
- pip = q->qi_pquotaip;
- if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
- 0, 0, &uip) == 0)
- tempuqip = true;
- }
- if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
- 0, 0, &gip) == 0)
- tempgqip = true;
- }
- if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) {
- if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
- 0, 0, &pip) == 0)
- temppqip = true;
- }
- if (uip) {
- out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
- out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
- if (tempuqip)
- IRELE(uip);
- }
-
- if (gip) {
- out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
- out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
- if (tempgqip)
- IRELE(gip);
- }
- if (pip) {
- out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks;
- out->qs_pquota.qfs_nextents = pip->i_d.di_nextents;
- if (temppqip)
- IRELE(pip);
- }
- out->qs_incoredqs = q->qi_dquots;
- out->qs_btimelimit = q->qi_btimelimit;
- out->qs_itimelimit = q->qi_itimelimit;
- out->qs_rtbtimelimit = q->qi_rtbtimelimit;
- out->qs_bwarnlimit = q->qi_bwarnlimit;
- out->qs_iwarnlimit = q->qi_iwarnlimit;
-
- return 0;
-}
-
#define XFS_QC_MASK \
(QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
@@ -873,28 +719,6 @@ out_put:
return error;
}
-STATIC uint
-xfs_qm_export_flags(
- uint flags)
-{
- uint uflags;
-
- uflags = 0;
- if (flags & XFS_UQUOTA_ACCT)
- uflags |= FS_QUOTA_UDQ_ACCT;
- if (flags & XFS_GQUOTA_ACCT)
- uflags |= FS_QUOTA_GDQ_ACCT;
- if (flags & XFS_PQUOTA_ACCT)
- uflags |= FS_QUOTA_PDQ_ACCT;
- if (flags & XFS_UQUOTA_ENFD)
- uflags |= FS_QUOTA_UDQ_ENFD;
- if (flags & XFS_GQUOTA_ENFD)
- uflags |= FS_QUOTA_GDQ_ENFD;
- if (flags & XFS_PQUOTA_ENFD)
- uflags |= FS_QUOTA_PDQ_ENFD;
- return uflags;
-}
-
STATIC int
xfs_dqrele_inode(
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index 6923905ab33d..5775acb0589b 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -23,45 +23,92 @@
#include "xfs_inode.h"
#include "xfs_quota.h"
#include "xfs_trans.h"
+#include "xfs_trace.h"
+#include "xfs_icache.h"
#include "xfs_qm.h"
#include <linux/quota.h>
-STATIC int
-xfs_quota_type(int type)
+static void
+xfs_qm_fill_state(
+ struct qc_type_state *tstate,
+ struct xfs_mount *mp,
+ struct xfs_inode *ip,
+ xfs_ino_t ino)
{
- switch (type) {
- case USRQUOTA:
- return XFS_DQ_USER;
- case GRPQUOTA:
- return XFS_DQ_GROUP;
- default:
- return XFS_DQ_PROJ;
+ struct xfs_quotainfo *q = mp->m_quotainfo;
+ bool tempqip = false;
+
+ tstate->ino = ino;
+ if (!ip && ino == NULLFSINO)
+ return;
+ if (!ip) {
+ if (xfs_iget(mp, NULL, ino, 0, 0, &ip))
+ return;
+ tempqip = true;
}
+ tstate->flags |= QCI_SYSFILE;
+ tstate->blocks = ip->i_d.di_nblocks;
+ tstate->nextents = ip->i_d.di_nextents;
+ tstate->spc_timelimit = q->qi_btimelimit;
+ tstate->ino_timelimit = q->qi_itimelimit;
+ tstate->rt_spc_timelimit = q->qi_rtbtimelimit;
+ tstate->spc_warnlimit = q->qi_bwarnlimit;
+ tstate->ino_warnlimit = q->qi_iwarnlimit;
+ tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit;
+ if (tempqip)
+ IRELE(ip);
}
-STATIC int
-xfs_fs_get_xstate(
+/*
+ * Return quota status information, such as enforcements, quota file inode
+ * numbers etc.
+ */
+static int
+xfs_fs_get_quota_state(
struct super_block *sb,
- struct fs_quota_stat *fqs)
+ struct qc_state *state)
{
- struct xfs_mount *mp = XFS_M(sb);
+ struct xfs_mount *mp = XFS_M(sb);
+ struct xfs_quotainfo *q = mp->m_quotainfo;
+ memset(state, 0, sizeof(*state));
if (!XFS_IS_QUOTA_RUNNING(mp))
- return -ENOSYS;
- return xfs_qm_scall_getqstat(mp, fqs);
+ return 0;
+ state->s_incoredqs = q->qi_dquots;
+ if (XFS_IS_UQUOTA_RUNNING(mp))
+ state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED;
+ if (XFS_IS_UQUOTA_ENFORCED(mp))
+ state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
+ if (XFS_IS_GQUOTA_RUNNING(mp))
+ state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED;
+ if (XFS_IS_GQUOTA_ENFORCED(mp))
+ state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
+ if (XFS_IS_PQUOTA_RUNNING(mp))
+ state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED;
+ if (XFS_IS_PQUOTA_ENFORCED(mp))
+ state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED;
+
+ xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip,
+ mp->m_sb.sb_uquotino);
+ xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip,
+ mp->m_sb.sb_gquotino);
+ xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip,
+ mp->m_sb.sb_pquotino);
+ return 0;
}
STATIC int
-xfs_fs_get_xstatev(
- struct super_block *sb,
- struct fs_quota_statv *fqs)
+xfs_quota_type(int type)
{
- struct xfs_mount *mp = XFS_M(sb);
-
- if (!XFS_IS_QUOTA_RUNNING(mp))
- return -ENOSYS;
- return xfs_qm_scall_getqstatv(mp, fqs);
+ switch (type) {
+ case USRQUOTA:
+ return XFS_DQ_USER;
+ case GRPQUOTA:
+ return XFS_DQ_GROUP;
+ default:
+ return XFS_DQ_PROJ;
+ }
}
static unsigned int
@@ -178,8 +225,7 @@ xfs_fs_set_dqblk(
}
const struct quotactl_ops xfs_quotactl_operations = {
- .get_xstatev = xfs_fs_get_xstatev,
- .get_xstate = xfs_fs_get_xstate,
+ .get_state = xfs_fs_get_quota_state,
.quota_enable = xfs_quota_enable,
.quota_disable = xfs_quota_disable,
.rm_xquota = xfs_fs_rm_xquota,
--
2.1.4
^ permalink raw reply related [flat|nested] 18+ messages in thread