diff mbox

[6/8] quota: Make ->set_info use structure with neccesary info to VFS and XFS

Message ID 1424267274-11836-7-git-send-email-jack@suse.cz (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kara Feb. 18, 2015, 1:47 p.m. UTC
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(-)

Comments

Christoph Hellwig Feb. 18, 2015, 4:53 p.m. UTC | #1
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.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Kara Feb. 18, 2015, 5:17 p.m. UTC | #2
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
diff mbox

Patch

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,