All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] quota: Implement VFS support for Q_[X]GETNEXTQUOTA
@ 2016-01-27 11:46 Jan Kara
  2016-01-27 11:46 ` [PATCH 1/2] quota: Add support for ->get_nextdqblk() for VFS quota Jan Kara
  2016-01-27 11:46 ` [PATCH 2/2] quota_v2: Implement get_next_id() for V2 quota format Jan Kara
  0 siblings, 2 replies; 4+ messages in thread
From: Jan Kara @ 2016-01-27 11:46 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: Eric Sandeen

Hello,

two patches below implement support for Q_GETNEXTQUOTA and
Q_XGETNEXTQUOTA quotactls for VFS quotas - namely for the vfsv0 and
vfsv1 formats of quota files (so that includes non-ancient quota files
for ext2, ext4, reiserfs, jfs). Hooking up OCFS2 requires a small
wrapper to deal with peculiarities of cluster locking, I'll have a look
into that a bit later.

I have also implemented and pushed out support for the new quotactls in
quota-tools so repquota(8) and warnquota(8) now use the new quotactl
when direct access to the quota file is not available (and falls back to
iteration using getpwent() if quotactl is not available).

Unless somebody objects I'll queue these patches to my tree in a few
days.

								Honza


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] quota: Add support for ->get_nextdqblk() for VFS quota
  2016-01-27 11:46 [PATCH 0/2] quota: Implement VFS support for Q_[X]GETNEXTQUOTA Jan Kara
@ 2016-01-27 11:46 ` Jan Kara
  2016-01-27 11:55   ` kbuild test robot
  2016-01-27 11:46 ` [PATCH 2/2] quota_v2: Implement get_next_id() for V2 quota format Jan Kara
  1 sibling, 1 reply; 4+ messages in thread
From: Jan Kara @ 2016-01-27 11:46 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: Eric Sandeen, Jan Kara

Add infrastructure for supporting get_nextdqblk() callback for VFS
quotas.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/quota/dquot.c         | 26 ++++++++++++++++++++++++++
 include/linux/quota.h    |  1 +
 include/linux/quotaops.h |  2 ++
 3 files changed, 29 insertions(+)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index fbd70af98820..c3e15ca96c99 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2565,6 +2565,30 @@ int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
 }
 EXPORT_SYMBOL(dquot_get_dqblk);
 
+int dquot_get_next_dqblk(struct super_block *sb, struct kqid *qid,
+			 struct qc_dqblk *di)
+{
+	struct dquot *dquot;
+	struct quota_info *dqopt = sb_dqopt(sb);
+	int err;
+
+	if (!dqopt->ops[qid->type]->get_next_id)
+		return -ENOSYS;
+	mutex_lock(&dqopt->dqio_mutex);
+	err = dqopt->ops[qid->type]->get_next_id(sb, qid);
+	mutex_unlock(&dqopt->dqio_mutex);
+	if (err < 0)
+		return err;
+	dquot = dqget(sb, *qid);
+	if (IS_ERR(dquot))
+		return PTR_ERR(dquot);
+	do_get_dqblk(dquot, di);
+	dqput(dquot);
+
+	return 0;
+}
+EXPORT_SYMBOL(dquot_get_next_dqblk);
+
 #define VFS_QC_MASK \
 	(QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \
 	 QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \
@@ -2765,6 +2789,7 @@ const struct quotactl_ops dquot_quotactl_ops = {
 	.get_state	= dquot_get_state,
 	.set_info	= dquot_set_dqinfo,
 	.get_dqblk	= dquot_get_dqblk,
+	.get_nextdqblk	= dquot_get_next_dqblk,
 	.set_dqblk	= dquot_set_dqblk
 };
 EXPORT_SYMBOL(dquot_quotactl_ops);
@@ -2776,6 +2801,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = {
 	.get_state	= dquot_get_state,
 	.set_info	= dquot_set_dqinfo,
 	.get_dqblk	= dquot_get_dqblk,
+	.get_nextdqblk	= dquot_get_next_dqblk,
 	.set_dqblk	= dquot_set_dqblk
 };
 EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
diff --git a/include/linux/quota.h b/include/linux/quota.h
index fba92f5c1a63..9ba109410c90 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -306,6 +306,7 @@ struct quota_format_ops {
 	int (*read_dqblk)(struct dquot *dquot);		/* Read structure for one user */
 	int (*commit_dqblk)(struct dquot *dquot);	/* Write structure for one user */
 	int (*release_dqblk)(struct dquot *dquot);	/* Called when last reference to dquot is being dropped */
+	int (*get_next_id)(struct super_block *sb, struct kqid *qid);	/* Get next ID with existing structure in the quota file */
 };
 
 /* Operations working with dquots */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 7a57c28eb5e7..24ed5909ef77 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -99,6 +99,8 @@ int dquot_get_state(struct super_block *sb, struct qc_state *state);
 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_get_next_dqblk(struct super_block *sb, struct kqid *id,
+		struct qc_dqblk *di);
 int dquot_set_dqblk(struct super_block *sb, struct kqid id,
 		struct qc_dqblk *di);
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] quota_v2: Implement get_next_id() for V2 quota format
  2016-01-27 11:46 [PATCH 0/2] quota: Implement VFS support for Q_[X]GETNEXTQUOTA Jan Kara
  2016-01-27 11:46 ` [PATCH 1/2] quota: Add support for ->get_nextdqblk() for VFS quota Jan Kara
@ 2016-01-27 11:46 ` Jan Kara
  1 sibling, 0 replies; 4+ messages in thread
From: Jan Kara @ 2016-01-27 11:46 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: Eric Sandeen, Jan Kara

Implement functions to get id of next existing quota structure in quota
file for quota tree based formats and thus for V2 quota format.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/quota/quota_tree.c       | 67 +++++++++++++++++++++++++++++++++++++++++++--
 fs/quota/quota_v2.c         |  6 ++++
 include/linux/dqblk_qtree.h |  2 ++
 3 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c
index 58efb83dec1c..0738972e8d3f 100644
--- a/fs/quota/quota_tree.c
+++ b/fs/quota/quota_tree.c
@@ -22,10 +22,9 @@ MODULE_LICENSE("GPL");
 
 #define __QUOTA_QT_PARANOIA
 
-static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
+static int __get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth)
 {
 	unsigned int epb = info->dqi_usable_bs >> 2;
-	qid_t id = from_kqid(&init_user_ns, qid);
 
 	depth = info->dqi_qtree_depth - depth - 1;
 	while (depth--)
@@ -33,6 +32,13 @@ static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
 	return id % epb;
 }
 
+static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
+{
+	qid_t id = from_kqid(&init_user_ns, qid);
+
+	return __get_index(info, id, depth);
+}
+
 /* Number of entries in one blocks */
 static int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info)
 {
@@ -668,3 +674,60 @@ int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
 	return 0;
 }
 EXPORT_SYMBOL(qtree_release_dquot);
+
+static int find_next_id(struct qtree_mem_dqinfo *info, qid_t *id,
+			unsigned int blk, int depth)
+{
+	char *buf = getdqbuf(info->dqi_usable_bs);
+	__le32 *ref = (__le32 *)buf;
+	ssize_t ret;
+	unsigned int epb = info->dqi_usable_bs >> 2;
+	unsigned int level_inc = 1;
+	int i;
+
+	if (!buf)
+		return -ENOMEM;
+
+	for (i = depth; i < info->dqi_qtree_depth - 1; i++)
+		level_inc *= epb;
+
+	ret = read_blk(info, blk, buf);
+	if (ret < 0) {
+		quota_error(info->dqi_sb,
+			    "Can't read quota tree block %u", blk);
+		goto out_buf;
+	}
+	for (i = __get_index(info, *id, depth); i < epb; i++) {
+		if (ref[i] == cpu_to_le32(0)) {
+			*id += level_inc;
+			continue;
+		}
+		if (depth == info->dqi_qtree_depth - 1) {
+			ret = 0;
+			goto out_buf;
+		}
+		ret = find_next_id(info, id, le32_to_cpu(ref[i]), depth + 1);
+		if (ret != -ENOENT)
+			break;
+	}
+	if (i == epb) {
+		ret = -ENOENT;
+		goto out_buf;
+	}
+out_buf:
+	kfree(buf);
+	return ret;
+}
+
+int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid)
+{
+	qid_t id = from_kqid(&init_user_ns, *qid);
+	int ret;
+
+	ret = find_next_id(info, &id, QT_TREEOFF, 0);
+	if (ret < 0)
+		return ret;
+	*qid = make_kqid(&init_user_ns, qid->type, id);
+	return 0;
+}
+EXPORT_SYMBOL(qtree_get_next_id);
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c
index ed85d4f35c04..ca71bf881ad1 100644
--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -304,6 +304,11 @@ static int v2_free_file_info(struct super_block *sb, int type)
 	return 0;
 }
 
+static int v2_get_next_id(struct super_block *sb, struct kqid *qid)
+{
+	return qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid);
+}
+
 static const struct quota_format_ops v2_format_ops = {
 	.check_quota_file	= v2_check_quota_file,
 	.read_file_info		= v2_read_file_info,
@@ -312,6 +317,7 @@ static const struct quota_format_ops v2_format_ops = {
 	.read_dqblk		= v2_read_dquot,
 	.commit_dqblk		= v2_write_dquot,
 	.release_dqblk		= v2_release_dquot,
+	.get_next_id		= v2_get_next_id,
 };
 
 static struct quota_format_type v2r0_quota_format = {
diff --git a/include/linux/dqblk_qtree.h b/include/linux/dqblk_qtree.h
index ff8b55359648..0de21e935976 100644
--- a/include/linux/dqblk_qtree.h
+++ b/include/linux/dqblk_qtree.h
@@ -15,6 +15,7 @@
 #define QTREE_DEL_REWRITE 6
 
 struct dquot;
+struct kqid;
 
 /* Operations */
 struct qtree_fmt_operations {
@@ -52,5 +53,6 @@ static inline int qtree_depth(struct qtree_mem_dqinfo *info)
 		entries *= epb;
 	return i;
 }
+int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid);
 
 #endif /* _LINUX_DQBLK_QTREE_H */
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] quota: Add support for ->get_nextdqblk() for VFS quota
  2016-01-27 11:46 ` [PATCH 1/2] quota: Add support for ->get_nextdqblk() for VFS quota Jan Kara
@ 2016-01-27 11:55   ` kbuild test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2016-01-27 11:55 UTC (permalink / raw)
  To: Jan Kara; +Cc: kbuild-all, linux-fsdevel, Eric Sandeen, Jan Kara

[-- Attachment #1: Type: text/plain, Size: 1925 bytes --]

Hi Jan,

[auto build test ERROR on v4.5-rc1]
[also build test ERROR on next-20160127]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Jan-Kara/quota-Implement-VFS-support-for-Q_-X-GETNEXTQUOTA/20160127-194845
config: x86_64-randconfig-x011-01270835 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

>> fs/quota/dquot.c:2792:2: error: unknown field 'get_nextdqblk' specified in initializer
     .get_nextdqblk = dquot_get_next_dqblk,
     ^
>> fs/quota/dquot.c:2792:19: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
     .get_nextdqblk = dquot_get_next_dqblk,
                      ^
   fs/quota/dquot.c:2792:19: note: (near initialization for 'dquot_quotactl_ops.set_dqblk')
   fs/quota/dquot.c:2804:2: error: unknown field 'get_nextdqblk' specified in initializer
     .get_nextdqblk = dquot_get_next_dqblk,
     ^
   fs/quota/dquot.c:2804:19: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
     .get_nextdqblk = dquot_get_next_dqblk,
                      ^
   fs/quota/dquot.c:2804:19: note: (near initialization for 'dquot_quotactl_sysfile_ops.set_dqblk')

vim +/get_nextdqblk +2792 fs/quota/dquot.c

  2786		.quota_on	= dquot_quota_on,
  2787		.quota_off	= dquot_quota_off,
  2788		.quota_sync	= dquot_quota_sync,
  2789		.get_state	= dquot_get_state,
  2790		.set_info	= dquot_set_dqinfo,
  2791		.get_dqblk	= dquot_get_dqblk,
> 2792		.get_nextdqblk	= dquot_get_next_dqblk,
  2793		.set_dqblk	= dquot_set_dqblk
  2794	};
  2795	EXPORT_SYMBOL(dquot_quotactl_ops);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 28734 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-01-27 11:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-27 11:46 [PATCH 0/2] quota: Implement VFS support for Q_[X]GETNEXTQUOTA Jan Kara
2016-01-27 11:46 ` [PATCH 1/2] quota: Add support for ->get_nextdqblk() for VFS quota Jan Kara
2016-01-27 11:55   ` kbuild test robot
2016-01-27 11:46 ` [PATCH 2/2] quota_v2: Implement get_next_id() for V2 quota format Jan Kara

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.