public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Eric Sandeen <sandeen@sandeen.net>
To: fsdevel <linux-fsdevel@vger.kernel.org>, xfs@oss.sgi.com
Cc: Jan Kara <jack@suse.cz>
Subject: [PATCH 1/4] quota: add new quotactl Q_XGETQUOTA2
Date: Fri, 8 Jan 2016 10:57:07 -0600	[thread overview]
Message-ID: <568FEA63.5020604@sandeen.net> (raw)
In-Reply-To: <568FEA2C.6080708@redhat.com>

Q_XGETQUOTA2 is exactly like Q_XGETQUOTA, except that it will
return quota information for the id equal to or greater than
the id requested.  In other words, if the specified id has
no quota, the command will return quota information for the
next higher id which does have a quota set.  If no higher id
has an active quota, -ESRCH is returned.

This allows filesystems to do efficient iteration in kernelspace,
much like extN filesystems do in userspace when asked to report
all active quotas.

Today, filesystems such as XFS require getpwent-style iterations,
and for systems which have i.e. LDAP backends, this can be very
slow, or even impossible, if iteration is not allowed in the
configuration.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
 fs/quota/quota.c               |   30 ++++++++++++++++++++++++++++++
 include/linux/quota.h          |    2 ++
 include/uapi/linux/dqblk_xfs.h |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 3746367..441a4e6 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -33,6 +33,7 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
 	/* allow to query information for dquots we "own" */
 	case Q_GETQUOTA:
 	case Q_XGETQUOTA:
+	case Q_XGETQUOTA2:
 		if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) ||
 		    (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id))))
 			break;
@@ -625,6 +626,32 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id,
 	return ret;
 }
 
+/*
+ * Return quota for next active quota >= this id, if any exists,
+ * otherwise return -ESRCH.
+ */
+static int quota_getxquota2(struct super_block *sb, int type, qid_t id,
+			    void __user *addr)
+{
+	struct fs_disk_quota fdq;
+	struct qc_dqblk qdq;
+	struct kqid qid;
+	int ret;
+
+	if (!sb->s_qcop->get_dqblk2)
+		return -ENOSYS;
+	qid = make_kqid(current_user_ns(), type, id);
+	if (!qid_valid(qid))
+		return -EINVAL;
+	ret = sb->s_qcop->get_dqblk2(sb, qid, &id, &qdq);
+	if (ret)
+		return ret;
+	copy_to_xfs_dqblk(&fdq, &qdq, type, id);
+	if (copy_to_user(addr, &fdq, sizeof(fdq)))
+		return -EFAULT;
+	return ret;
+}
+
 static int quota_rmxquota(struct super_block *sb, void __user *addr)
 {
 	__u32 flags;
@@ -690,6 +717,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 		return quota_setxquota(sb, type, id, addr);
 	case Q_XGETQUOTA:
 		return quota_getxquota(sb, type, id, addr);
+	case Q_XGETQUOTA2:
+		return quota_getxquota2(sb, type, id, addr);
 	case Q_XQUOTASYNC:
 		if (sb->s_flags & MS_RDONLY)
 			return -EROFS;
@@ -712,6 +741,7 @@ static int quotactl_cmd_write(int cmd)
 	case Q_XGETQSTAT:
 	case Q_XGETQSTATV:
 	case Q_XGETQUOTA:
+	case Q_XGETQUOTA2:
 	case Q_XQUOTASYNC:
 		return 0;
 	}
diff --git a/include/linux/quota.h b/include/linux/quota.h
index b2505ac..49e4f7c 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -425,6 +425,8 @@ struct quotactl_ops {
 	int (*quota_sync)(struct super_block *, int);
 	int (*set_info)(struct super_block *, int, struct qc_info *);
 	int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
+	int (*get_dqblk2)(struct super_block *, struct kqid, qid_t *,
+			  struct qc_dqblk *);
 	int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *);
 	int (*get_state)(struct super_block *, struct qc_state *);
 	int (*rm_xquota)(struct super_block *, unsigned int);
diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h
index dcd75cc..62441da 100644
--- a/include/uapi/linux/dqblk_xfs.h
+++ b/include/uapi/linux/dqblk_xfs.h
@@ -39,6 +39,7 @@
 #define Q_XQUOTARM	XQM_CMD(6)	/* free disk space used by dquots */
 #define Q_XQUOTASYNC	XQM_CMD(7)	/* delalloc flush, updates dquots */
 #define Q_XGETQSTATV	XQM_CMD(8)	/* newer version of get quota */
+#define Q_XGETQUOTA2	XQM_CMD(9)	/* get disk limits and usage >= ID */
 
 /*
  * fs_disk_quota structure:
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  reply	other threads:[~2016-01-08 16:57 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-08 16:56 [PATCH 0/4] quota: add new quotactl Q_XGETQUOTA2 Eric Sandeen
2016-01-08 16:57 ` Eric Sandeen [this message]
2016-01-08 16:57 ` [PATCH 2/4] xfs: get quota inode from mp & flags rather than dqp Eric Sandeen
2016-01-08 16:58 ` [PATCH 3/4] xfs: Factor xfs_seek_hole_data into helper Eric Sandeen
2016-01-08 17:07   ` [PATCH 3/4 V2] " Eric Sandeen
2016-01-11 15:57   ` [PATCH 3/4] " Jan Kara
2016-01-11 16:01   ` [PATCH 3/4 V3] " Eric Sandeen
2016-01-08 16:59 ` [PATCH 4/4] xfs: wire up Q_XGETQUOTA2 / get_dqblk2 Eric Sandeen
2016-01-08 18:36 ` [PATCH] linux-quota: wire Q_XGETQUOTA2 into generic repquota Eric Sandeen
2016-01-09  7:26 ` [PATCH 0/4] quota: add new quotactl Q_XGETQUOTA2 Christoph Hellwig
2016-01-11 13:26   ` Jan Kara
2016-01-11 16:07     ` Eric Sandeen
2016-01-11 16:28       ` Jan Kara
2016-01-13 22:40         ` Eric Sandeen
2016-01-13 22:40         ` Eric Sandeen
2016-01-15  9:35           ` Jan Kara
2016-01-15 17:31             ` Eric Sandeen
2016-01-15 19:38               ` Eric Sandeen
2016-01-18 10:33               ` Jan Kara
2016-01-18 11:00                 ` Christoph Hellwig
2016-01-18 15:18                 ` Eric Sandeen
2016-01-18 15:40                   ` Jan Kara
2016-01-19  0:31                     ` Eric Sandeen
2016-01-15 22:50             ` Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=568FEA63.5020604@sandeen.net \
    --to=sandeen@sandeen.net \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox