linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] quota: RFC add extend quota type v2
@ 2010-02-16  5:31 Dmitry Monakhov
  2010-02-16  5:31 ` [PATCH 1/4] quota: sb_quota state flags cleanup Dmitry Monakhov
  2010-02-16 21:13 ` [PATCH 0/4] quota: RFC add extend quota type v2 Jan Kara
  0 siblings, 2 replies; 11+ messages in thread
From: Dmitry Monakhov @ 2010-02-16  5:31 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: jack, Dmitry Monakhov

Currently only USER/GROUP quota are supported bu linux quota
But sometimes it is reasonable to have other types of quota
For example:
1) project_id in XFS
2) container_id in container(chroot) solutions.
This patch series is aimed to extend quota interface to support
different quota types. Last patch add the SUBTREE quota type.
This patch series does not contain fs-related part of
subtree-quota-type support. This is because generic subtree
support is relatively independent from quota part.
And in fact patches depends on two different devel trees
linux-fs.2.6 and ext4.git. So i've divided big subtree patchset
in to generic fs-related and quota-related parts.

First tree patches performs necessary cleanup work, And
the last one extends quota to support new quota's type.

Changes from v1:
 - fixes suggested by Jan Kara
 - redesign get_id() callback. Initially i've overlooked a quota transfer
   case. We have to pass new id's array to get_id() and it will return
   corresponding quota id. 
 - fix hard-coded values in dquot_initialize()

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>

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

* [PATCH 1/4] quota: sb_quota state flags cleanup
  2010-02-16  5:31 [PATCH 0/4] quota: RFC add extend quota type v2 Dmitry Monakhov
@ 2010-02-16  5:31 ` Dmitry Monakhov
  2010-02-16  5:31   ` [PATCH 2/4] quota: generalize quota transfer interface Dmitry Monakhov
  2010-02-16 21:13 ` [PATCH 0/4] quota: RFC add extend quota type v2 Jan Kara
  1 sibling, 1 reply; 11+ messages in thread
From: Dmitry Monakhov @ 2010-02-16  5:31 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: jack, Dmitry Monakhov

- remove hardcoded USRQUOTA/GRPQUOTA flags
- convert int to bool for appropriate functions

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 fs/quota/dquot.c         |    3 ++-
 include/linux/quota.h    |   15 +++++++--------
 include/linux/quotaops.h |   31 +++++++++++++++++--------------
 3 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 6c849de..ac38212 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1274,7 +1274,7 @@ int dquot_initialize(struct inode *inode, int type)
 {
 	unsigned int id = 0;
 	int cnt, ret = 0;
-	struct dquot *got[MAXQUOTAS] = { NULL, NULL };
+	struct dquot *got[MAXQUOTAS];
 	struct super_block *sb = inode->i_sb;
 	qsize_t rsv;
 
@@ -1285,6 +1285,7 @@ int dquot_initialize(struct inode *inode, int type)
 
 	/* First get references to structures we might need. */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		got[cnt] = NULL;
 		if (type != -1 && cnt != type)
 			continue;
 		switch (cnt) {
diff --git a/include/linux/quota.h b/include/linux/quota.h
index a6861f1..1f1a3a1 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -357,26 +357,25 @@ enum {
 #define DQUOT_STATE_FLAGS	(DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
 				 DQUOT_SUSPENDED)
 /* Other quota flags */
-#define DQUOT_QUOTA_SYS_FILE	(1 << 6)	/* Quota file is a special
+#define DQUOT_STATE_LAST	(_DQUOT_STATE_FLAGS * MAXQUOTAS)
+#define DQUOT_QUOTA_SYS_FILE	(1 << DQUOT_STATE_LAST)
+						/* Quota file is a special
 						 * system file and user cannot
 						 * touch it. Filesystem is
 						 * responsible for setting
 						 * S_NOQUOTA, S_NOATIME flags
 						 */
-#define DQUOT_NEGATIVE_USAGE	(1 << 7)	/* Allow negative quota usage */
+#define DQUOT_NEGATIVE_USAGE	(1 << (DQUOT_STATE_LAST + 1))
+					       /* Allow negative quota usage */
 
 static inline unsigned int dquot_state_flag(unsigned int flags, int type)
 {
-	if (type == USRQUOTA)
-		return flags;
-	return flags << _DQUOT_STATE_FLAGS;
+	return flags << _DQUOT_STATE_FLAGS * type;
 }
 
 static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
 {
-	if (type == USRQUOTA)
-		return flags;
-	return flags >> _DQUOT_STATE_FLAGS;
+	return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS;
 }
 
 #ifdef CONFIG_QUOTA_NETLINK_INTERFACE
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index a529d86..5bc9755 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -86,53 +86,56 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
  * Functions for checking status of quota
  */
 
-static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type)
+static inline bool sb_has_quota_usage_enabled(struct super_block *sb, int type)
 {
 	return sb_dqopt(sb)->flags &
 				dquot_state_flag(DQUOT_USAGE_ENABLED, type);
 }
 
-static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type)
+static inline bool sb_has_quota_limits_enabled(struct super_block *sb, int type)
 {
 	return sb_dqopt(sb)->flags &
 				dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
 }
 
-static inline int sb_has_quota_suspended(struct super_block *sb, int type)
+static inline bool sb_has_quota_suspended(struct super_block *sb, int type)
 {
 	return sb_dqopt(sb)->flags &
 				dquot_state_flag(DQUOT_SUSPENDED, type);
 }
 
-static inline int sb_any_quota_suspended(struct super_block *sb)
+static inline unsigned sb_any_quota_suspended(struct super_block *sb)
 {
-	return sb_has_quota_suspended(sb, USRQUOTA) ||
-		sb_has_quota_suspended(sb, GRPQUOTA);
+	unsigned type, tmsk = 0;
+	for (type = 0; type < MAXQUOTAS; type++)
+		tmsk |= sb_has_quota_suspended(sb, type) << type;
+	return tmsk;
 }
 
 /* Does kernel know about any quota information for given sb + type? */
-static inline int sb_has_quota_loaded(struct super_block *sb, int type)
+static inline bool sb_has_quota_loaded(struct super_block *sb, int type)
 {
 	/* Currently if anything is on, then quota usage is on as well */
 	return sb_has_quota_usage_enabled(sb, type);
 }
 
-static inline int sb_any_quota_loaded(struct super_block *sb)
+static inline unsigned sb_any_quota_loaded(struct super_block *sb)
 {
-	return sb_has_quota_loaded(sb, USRQUOTA) ||
-		sb_has_quota_loaded(sb, GRPQUOTA);
+	unsigned type, tmsk = 0;
+	for (type = 0; type < MAXQUOTAS; type++)
+		tmsk |= sb_has_quota_loaded(sb, type) << type;
+	return	tmsk;
 }
 
-static inline int sb_has_quota_active(struct super_block *sb, int type)
+static inline bool sb_has_quota_active(struct super_block *sb, int type)
 {
 	return sb_has_quota_loaded(sb, type) &&
 	       !sb_has_quota_suspended(sb, type);
 }
 
-static inline int sb_any_quota_active(struct super_block *sb)
+static inline unsigned sb_any_quota_active(struct super_block *sb)
 {
-	return sb_has_quota_active(sb, USRQUOTA) ||
-	       sb_has_quota_active(sb, GRPQUOTA);
+	return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb);
 }
 
 /*
-- 
1.6.6


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

* [PATCH 2/4] quota: generalize quota transfer interface
  2010-02-16  5:31 ` [PATCH 1/4] quota: sb_quota state flags cleanup Dmitry Monakhov
@ 2010-02-16  5:31   ` Dmitry Monakhov
  2010-02-16  5:31     ` [PATCH 3/4] introduce get_id callback Dmitry Monakhov
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Monakhov @ 2010-02-16  5:31 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: jack, Dmitry Monakhov

Current quota transfer interface support only uid/gid.
This patch extend interface in order to support various quotas types
The goal is accomplished without changes in most frequently used
vfs_dq_transfer() func.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 fs/quota/dquot.c         |   32 ++++++++++++++++++++------------
 include/linux/quota.h    |    2 +-
 include/linux/quotaops.h |    2 +-
 3 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index ac38212..6768584 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1668,15 +1668,13 @@ EXPORT_SYMBOL(dquot_free_inode);
  * This operation can block, but only after everything is updated
  * A transaction must be started when entering this function.
  */
-int dquot_transfer(struct inode *inode, struct iattr *iattr)
+int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask)
 {
 	qsize_t space, cur_space;
 	qsize_t rsv_space = 0;
 	struct dquot *transfer_from[MAXQUOTAS];
 	struct dquot *transfer_to[MAXQUOTAS];
 	int cnt, ret = QUOTA_OK;
-	int chuid = iattr->ia_valid & ATTR_UID && inode->i_uid != iattr->ia_uid,
-	    chgid = iattr->ia_valid & ATTR_GID && inode->i_gid != iattr->ia_gid;
 	char warntype_to[MAXQUOTAS];
 	char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
 
@@ -1690,13 +1688,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
 		transfer_to[cnt] = NULL;
 		warntype_to[cnt] = QUOTA_NL_NOWARN;
 	}
-	if (chuid)
-		transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid,
-					      USRQUOTA);
-	if (chgid)
-		transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid,
-					      GRPQUOTA);
-
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		if (mask & (1 << cnt))
+			transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt);
+	}
 	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	if (IS_NOQUOTA(inode)) {	/* File without quota accounting? */
 		up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1772,12 +1767,25 @@ over_quota:
 }
 EXPORT_SYMBOL(dquot_transfer);
 
-/* Wrapper for transferring ownership of an inode */
+/* Wrapper for transferring ownership of an inode for uid/gid only
+ * Called from FSXXX_setattr()
+ */
 int vfs_dq_transfer(struct inode *inode, struct iattr *iattr)
 {
+	qid_t chid[MAXQUOTAS];
+	unsigned long mask = 0;
+
+	if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) {
+		mask |= 1 << USRQUOTA;
+		chid[USRQUOTA] = iattr->ia_uid;
+	}
+	if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) {
+		mask |= 1 << GRPQUOTA;
+		chid[GRPQUOTA] = iattr->ia_gid;
+	}
 	if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) {
 		vfs_dq_init(inode);
-		if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
+		if (inode->i_sb->dq_op->transfer(inode, chid, mask) == NO_QUOTA)
 			return 1;
 	}
 	return 0;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 1f1a3a1..74738e9 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -301,7 +301,7 @@ struct dquot_operations {
 	int (*alloc_inode) (const struct inode *, qsize_t);
 	int (*free_space) (struct inode *, qsize_t);
 	int (*free_inode) (const struct inode *, qsize_t);
-	int (*transfer) (struct inode *, struct iattr *);
+	int (*transfer) (struct inode *, qid_t *, unsigned long);
 	int (*write_dquot) (struct dquot *);		/* Ordinary dquot write */
 	struct dquot *(*alloc_dquot)(struct super_block *, int);	/* Allocate memory for new dquot */
 	void (*destroy_dquot)(struct dquot *);		/* Free memory for dquot */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 5bc9755..d045a07 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -50,7 +50,7 @@ void dquot_release_reserved_space(struct inode *inode, qsize_t number);
 int dquot_free_space(struct inode *inode, qsize_t number);
 int dquot_free_inode(const struct inode *inode, qsize_t number);
 
-int dquot_transfer(struct inode *inode, struct iattr *iattr);
+int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask);
 int dquot_commit(struct dquot *dquot);
 int dquot_acquire(struct dquot *dquot);
 int dquot_release(struct dquot *dquot);
-- 
1.6.6


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

* [PATCH 3/4] introduce  get_id callback
  2010-02-16  5:31   ` [PATCH 2/4] quota: generalize quota transfer interface Dmitry Monakhov
@ 2010-02-16  5:31     ` Dmitry Monakhov
  2010-02-16  5:31       ` [PATCH 4/4] quota: add generic subtree quota support Dmitry Monakhov
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Monakhov @ 2010-02-16  5:31 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: jack, Dmitry Monakhov

During some quota oparations we have to determine quota_id for given inode
according to quota_type. But only USRQUOTA/GRPQUOTA id are intermediately
accessible from generic vfs-inode. This patch introduce new per_sb quota
operation for this purpose.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 fs/ext3/super.c          |    1 +
 fs/ext4/super.c          |    1 +
 fs/ocfs2/quota_global.c  |    1 +
 fs/quota/dquot.c         |   39 +++++++++++++++++++++++++++++----------
 fs/reiserfs/super.c      |    1 +
 include/linux/quota.h    |    1 +
 include/linux/quotaops.h |    1 +
 7 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 241c520..82bf9c8 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -757,6 +757,7 @@ static const struct dquot_operations ext3_quota_operations = {
 	.free_space	= dquot_free_space,
 	.free_inode	= dquot_free_inode,
 	.transfer	= dquot_transfer,
+	.get_id		= dquot_get_id,
 	.write_dquot	= ext3_write_dquot,
 	.acquire_dquot	= ext3_acquire_dquot,
 	.release_dquot	= ext3_release_dquot,
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 735c20d..cd0dffa 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1025,6 +1025,7 @@ static const struct dquot_operations ext4_quota_operations = {
 	.free_space	= dquot_free_space,
 	.free_inode	= dquot_free_inode,
 	.transfer	= dquot_transfer,
+	.get_id		= dquot_get_id,
 	.write_dquot	= ext4_write_dquot,
 	.acquire_dquot	= ext4_acquire_dquot,
 	.release_dquot	= ext4_release_dquot,
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index b437dc0..1ede78f 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -858,6 +858,7 @@ const struct dquot_operations ocfs2_quota_operations = {
 	.free_space	= dquot_free_space,
 	.free_inode	= dquot_free_inode,
 	.transfer	= dquot_transfer,
+	.get_id		= dquot_get_id,
 	.write_dquot	= ocfs2_write_dquot,
 	.acquire_dquot	= ocfs2_acquire_dquot,
 	.release_dquot	= ocfs2_release_dquot,
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 6768584..22bf600 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -298,6 +298,26 @@ static inline void remove_inuse(struct dquot *dquot)
 	dqstats.allocated_dquots--;
 	list_del(&dquot->dq_inuse);
 }
+
+qid_t dquot_get_id(struct inode *inode, int type, qid_t *new)
+{
+	switch (type) {
+	case USRQUOTA:
+		if (new)
+			return new[USRQUOTA];
+		else
+			return inode->i_uid;
+	case GRPQUOTA:
+		if (new)
+			return new[GRPQUOTA];
+		else
+			return inode->i_gid;
+	default:
+		BUG();
+	}
+}
+EXPORT_SYMBOL(dquot_get_id);
+
 /*
  * End of list functions needing dq_list_lock
  */
@@ -1288,14 +1308,9 @@ int dquot_initialize(struct inode *inode, int type)
 		got[cnt] = NULL;
 		if (type != -1 && cnt != type)
 			continue;
-		switch (cnt) {
-		case USRQUOTA:
-			id = inode->i_uid;
-			break;
-		case GRPQUOTA:
-			id = inode->i_gid;
-			break;
-		}
+		if (!sb_has_quota_active(sb, cnt))
+			continue;
+		id = inode->i_sb->dq_op->get_id(inode, cnt, NULL);
 		got[cnt] = dqget(sb, id, cnt);
 	}
 
@@ -1677,6 +1692,7 @@ int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask)
 	int cnt, ret = QUOTA_OK;
 	char warntype_to[MAXQUOTAS];
 	char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
+	qid_t id;
 
 	/* First test before acquiring mutex - solves deadlocks when we
          * re-enter the quota code and are already holding the mutex */
@@ -1689,8 +1705,10 @@ int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask)
 		warntype_to[cnt] = QUOTA_NL_NOWARN;
 	}
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (mask & (1 << cnt))
-			transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt);
+		if (mask & (1 << cnt)) {
+			id = inode->i_sb->dq_op->get_id(inode, cnt, chid);
+			transfer_to[cnt] = dqget(inode->i_sb, id, cnt);
+		}
 	}
 	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	if (IS_NOQUOTA(inode)) {	/* File without quota accounting? */
@@ -1818,6 +1836,7 @@ const struct dquot_operations dquot_operations = {
 	.free_space	= dquot_free_space,
 	.free_inode	= dquot_free_inode,
 	.transfer	= dquot_transfer,
+	.get_id		= dquot_get_id,
 	.write_dquot	= dquot_commit,
 	.acquire_dquot	= dquot_acquire,
 	.release_dquot	= dquot_release,
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index b4a7dd0..897f2bc 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -623,6 +623,7 @@ static const struct dquot_operations reiserfs_quota_operations = {
 	.free_space = dquot_free_space,
 	.free_inode = dquot_free_inode,
 	.transfer = dquot_transfer,
+	.get_id		= dquot_get_id,
 	.write_dquot = reiserfs_write_dquot,
 	.acquire_dquot = reiserfs_acquire_dquot,
 	.release_dquot = reiserfs_release_dquot,
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 74738e9..abf6a5a 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -303,6 +303,7 @@ struct dquot_operations {
 	int (*free_inode) (const struct inode *, qsize_t);
 	int (*transfer) (struct inode *, qid_t *, unsigned long);
 	int (*write_dquot) (struct dquot *);		/* Ordinary dquot write */
+	qid_t (*get_id)(struct inode *, int, qid_t *new); /* Quota id for given type */
 	struct dquot *(*alloc_dquot)(struct super_block *, int);	/* Allocate memory for new dquot */
 	void (*destroy_dquot)(struct dquot *);		/* Free memory for dquot */
 	int (*acquire_dquot) (struct dquot *);		/* Quota is going to be created on disk */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index d045a07..e4c6d6e 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -30,6 +30,7 @@ void inode_add_rsv_space(struct inode *inode, qsize_t number);
 void inode_claim_rsv_space(struct inode *inode, qsize_t number);
 void inode_sub_rsv_space(struct inode *inode, qsize_t number);
 
+qid_t dquot_get_id(struct inode *inode, int type, qid_t *new);
 int dquot_initialize(struct inode *inode, int type);
 int dquot_drop(struct inode *inode);
 struct dquot *dqget(struct super_block *sb, unsigned int id, int type);
-- 
1.6.6


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

* [PATCH 4/4] quota: add generic subtree quota support
  2010-02-16  5:31     ` [PATCH 3/4] introduce get_id callback Dmitry Monakhov
@ 2010-02-16  5:31       ` Dmitry Monakhov
  2010-02-16  8:14         ` Christoph Hellwig
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Monakhov @ 2010-02-16  5:31 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: jack, Dmitry Monakhov

After this patch it is possible to implement fs-speciffic
subtree quota part.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 fs/quota/dquot.c      |    5 +++++
 fs/quota/quotaio_v2.h |    6 ++++--
 include/linux/quota.h |    6 ++++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 22bf600..c6bea23 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1083,6 +1083,11 @@ static int need_print_warning(struct dquot *dquot)
 			return current_fsuid() == dquot->dq_id;
 		case GRPQUOTA:
 			return in_group_p(dquot->dq_id);
+		case SBTRQUOTA:
+			/* XXX: Currently there is no way to understand
+			   which subtree this task belonges to, So print
+			   a warn message unconditionally. -dmon */
+			return 1;
 	}
 	return 0;
 }
diff --git a/fs/quota/quotaio_v2.h b/fs/quota/quotaio_v2.h
index f1966b4..01e8203 100644
--- a/fs/quota/quotaio_v2.h
+++ b/fs/quota/quotaio_v2.h
@@ -13,12 +13,14 @@
  */
 #define V2_INITQMAGICS {\
 	0xd9c01f11,	/* USRQUOTA */\
-	0xd9c01927	/* GRPQUOTA */\
+	0xd9c01927,	/* GRPQUOTA */\
+	0xd9c03f14	/* SBTRQUOTA */\
 }
 
 #define V2_INITQVERSIONS {\
 	1,		/* USRQUOTA */\
-	1		/* GRPQUOTA */\
+	1,		/* GRPQUOTA */	\
+	1		/* SBTRPQUOTA */\
 }
 
 /* First generic header */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index abf6a5a..0bcd295 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -36,11 +36,12 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
-#define __DQUOT_VERSION__	"dquot_6.5.2"
+#define __DQUOT_VERSION__	"dquot_6.6.0"
 
-#define MAXQUOTAS 2
+#define MAXQUOTAS 3
 #define USRQUOTA  0		/* element used for user quotas */
 #define GRPQUOTA  1		/* element used for group quotas */
+#define SBTRQUOTA   2		/* element used for directory tree quotas */
 
 /*
  * Definitions for the default names of the quotas files.
@@ -48,6 +49,7 @@
 #define INITQFNAMES { \
 	"user",    /* USRQUOTA */ \
 	"group",   /* GRPQUOTA */ \
+	"subtree",    /* SBTRQUOTA */ \
 	"undefined", \
 };
 
-- 
1.6.6


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

* Re: [PATCH 4/4] quota: add generic subtree quota support
  2010-02-16  5:31       ` [PATCH 4/4] quota: add generic subtree quota support Dmitry Monakhov
@ 2010-02-16  8:14         ` Christoph Hellwig
  2010-02-16  8:25           ` Dmitry Monakhov
  0 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2010-02-16  8:14 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-fsdevel, jack

On Tue, Feb 16, 2010 at 08:31:52AM +0300, Dmitry Monakhov wrote:
> After this patch it is possible to implement fs-speciffic
> subtree quota part.
> 
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
>  fs/quota/dquot.c      |    5 +++++
>  fs/quota/quotaio_v2.h |    6 ++++--
>  include/linux/quota.h |    6 ++++--
>  3 files changed, 13 insertions(+), 4 deletions(-)

Please call this project quota, and instead of introducing the get_id
callback make it entirely generic.  There's no point in adding artifical
differences just at the point where I'm doing the long overdue
consolidation of the XFS quota support and the "VFS" quote bits.


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

* Re: [PATCH 4/4] quota: add generic subtree quota support
  2010-02-16  8:14         ` Christoph Hellwig
@ 2010-02-16  8:25           ` Dmitry Monakhov
  2010-02-16  8:28             ` Christoph Hellwig
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Monakhov @ 2010-02-16  8:25 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, jack

Christoph Hellwig <hch@infradead.org> writes:

> On Tue, Feb 16, 2010 at 08:31:52AM +0300, Dmitry Monakhov wrote:
>> After this patch it is possible to implement fs-speciffic
>> subtree quota part.
>> 
>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>> ---
>>  fs/quota/dquot.c      |    5 +++++
>>  fs/quota/quotaio_v2.h |    6 ++++--
>>  include/linux/quota.h |    6 ++++--
>>  3 files changed, 13 insertions(+), 4 deletions(-)
>
> Please call this project quota, and instead of introducing the get_id
> callback make it entirely generic.  There's no point in adding artifical
> differences just at the point where I'm doing the long overdue
> consolidation of the XFS quota support and the "VFS" quote bits.
But this is not "project quota". Project quota is XFS feature.
This patch aimed to give an opportunity to implement fs-specific
quota_id mapping, and XFS is just an one of possible usecases.

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

* Re: [PATCH 4/4] quota: add generic subtree quota support
  2010-02-16  8:25           ` Dmitry Monakhov
@ 2010-02-16  8:28             ` Christoph Hellwig
  2010-02-16  8:56               ` Dmitry Monakhov
  0 siblings, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2010-02-16  8:28 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: Christoph Hellwig, linux-fsdevel, jack

On Tue, Feb 16, 2010 at 11:25:28AM +0300, Dmitry Monakhov wrote:
> But this is not "project quota". Project quota is XFS feature.
> This patch aimed to give an opportunity to implement fs-specific
> quota_id mapping, and XFS is just an one of possible usecases.

What you desribe as subtree quota is exactly a slightly limited
implementation of project quotas.  And yes, fs-specific quota interfaces
are a horribly bad idea.  If you add features add them in generic code
and make them opt-in for a specific filesystem to support.

And yes, fs-specific quota interfaces are an utter nightmare, speaking
as the person fixing all this crap up right now.

---end quoted text---

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

* Re: [PATCH 4/4] quota: add generic subtree quota support
  2010-02-16  8:28             ` Christoph Hellwig
@ 2010-02-16  8:56               ` Dmitry Monakhov
  2010-02-16  9:03                 ` Christoph Hellwig
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Monakhov @ 2010-02-16  8:56 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, jack

Christoph Hellwig <hch@infradead.org> writes:

> On Tue, Feb 16, 2010 at 11:25:28AM +0300, Dmitry Monakhov wrote:
>> But this is not "project quota". Project quota is XFS feature.
>> This patch aimed to give an opportunity to implement fs-specific
>> quota_id mapping, and XFS is just an one of possible usecases.
>
> What you desribe as subtree quota is exactly a slightly limited
> implementation of project quotas.  And yes, fs-specific quota interfaces
what do you mean by "slightly limited" ?
I dont now xfs project-id feature very well.
I cant find good explanation of this feature(except man pages).
Can you please post main design assumptions.
> are a horribly bad idea.  If you add features add them in generic code
> and make them opt-in for a specific filesystem to support.
Please read following thread.
http://marc.info/?l=linux-ext4&m=126563931215496&w=2
It will be good idea to implement this in generic vfs layer.
Today i'll plan to post patches which introduce genetic subtree support
on vfs layer.
In fact i use get_id in order to support second-level quota feature
*Second-level quota*
 In order to isolate user/group quota in one subtree from other subtree
 we have to remap quota id similar to:
   quota_uid = (subtree_id << 32) | uid;
>
> And yes, fs-specific quota interfaces are an utter nightmare, speaking
> as the person fixing all this crap up right now.
I've prepare patches against ext4 because:
- i do know something about it internals
- it has journalled quota support.
But off course it will be brilliant to have this feature in VFS layer.
>
> ---end quoted text---

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

* Re: [PATCH 4/4] quota: add generic subtree quota support
  2010-02-16  8:56               ` Dmitry Monakhov
@ 2010-02-16  9:03                 ` Christoph Hellwig
  0 siblings, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2010-02-16  9:03 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: Christoph Hellwig, linux-fsdevel, jack

On Tue, Feb 16, 2010 at 11:56:44AM +0300, Dmitry Monakhov wrote:
> what do you mean by "slightly limited" ?
> I dont now xfs project-id feature very well.
> I cant find good explanation of this feature(except man pages).
> Can you please post main design assumptions.

The only difference from your subtree quota is that multiple subtrees
can belong to a project.

XFS project quotas work the following way:

 - an inode can be marked as belonging to a project, in which case a
   32bit project ID is stored in the inode
 - a flag on the inode is set to inherit the project ID
 - adding links from outside the subtree is not allowed

quota uses the project ID for accounting, similar to the user/group id.

One other small difference is that going over the project quota does
not return EDQUOT but ENOSPC.

> In fact i use get_id in order to support second-level quota feature
> *Second-level quota*
>  In order to isolate user/group quota in one subtree from other subtree
>  we have to remap quota id similar to:
>    quota_uid = (subtree_id << 32) | uid;

> > And yes, fs-specific quota interfaces are an utter nightmare, speaking
> > as the person fixing all this crap up right now.
> I've prepare patches against ext4 because:

It's perfectly fine to impement it for one filesystem, the important bit
is to make sure we have consistant interfaces for it in generic code.
I don't think having a get_id callback to allow fs-specific mappings is
a good idea for that.


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

* Re: [PATCH 0/4] quota: RFC add extend quota type v2
  2010-02-16  5:31 [PATCH 0/4] quota: RFC add extend quota type v2 Dmitry Monakhov
  2010-02-16  5:31 ` [PATCH 1/4] quota: sb_quota state flags cleanup Dmitry Monakhov
@ 2010-02-16 21:13 ` Jan Kara
  1 sibling, 0 replies; 11+ messages in thread
From: Jan Kara @ 2010-02-16 21:13 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-fsdevel, jack, hch

On Tue 16-02-10 08:31:48, Dmitry Monakhov wrote:
> Currently only USER/GROUP quota are supported bu linux quota
> But sometimes it is reasonable to have other types of quota
> For example:
> 1) project_id in XFS
> 2) container_id in container(chroot) solutions.
> This patch series is aimed to extend quota interface to support
> different quota types. Last patch add the SUBTREE quota type.
> This patch series does not contain fs-related part of
> subtree-quota-type support. This is because generic subtree
> support is relatively independent from quota part.
> And in fact patches depends on two different devel trees
> linux-fs.2.6 and ext4.git. So i've divided big subtree patchset
> in to generic fs-related and quota-related parts.
> 
> First tree patches performs necessary cleanup work, And
> the last one extends quota to support new quota's type.
> 
> Changes from v1:
>  - fixes suggested by Jan Kara
>  - redesign get_id() callback. Initially i've overlooked a quota transfer
>    case. We have to pass new id's array to get_id() and it will return
>    corresponding quota id. 
>  - fix hard-coded values in dquot_initialize()
  Dmitry, I like the first two patches now so I've merged those. About the
other two: I was thinking about what you and Christoph wrote. My conclusion
was that maybe you are trying to mix two different features into one.
  If I understand it right, one of your requirements is that you want to
limit the amount of space some subtree (container in your case) uses. This
is exactly what XFS project quota does.
  Another requirement which I see as a different feature is that you
want a separate accounting of quotas for each user / group in each
container. And your intention is to implement this feature by remapping
uid to (tree_id << 32 | uid) for quota purposes. Right?
  The trouble with your uid / gid mapping is that you would need 64-bit
ids but kernel-userspace interface (quotactl) takes just a 32-bit value.
So you cannot use this interface for getting and setting quota limits.
At least not in the obvious way.
  Also I think having tree_id explicitely separated from uid / gid might
make things clearer. We would store it in dquot, compare it in dqget and
quota formats that are able to handle tree_ids (none currently ;) would
decide how to store all the information.

								Honza
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

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

end of thread, other threads:[~2010-02-16 21:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-16  5:31 [PATCH 0/4] quota: RFC add extend quota type v2 Dmitry Monakhov
2010-02-16  5:31 ` [PATCH 1/4] quota: sb_quota state flags cleanup Dmitry Monakhov
2010-02-16  5:31   ` [PATCH 2/4] quota: generalize quota transfer interface Dmitry Monakhov
2010-02-16  5:31     ` [PATCH 3/4] introduce get_id callback Dmitry Monakhov
2010-02-16  5:31       ` [PATCH 4/4] quota: add generic subtree quota support Dmitry Monakhov
2010-02-16  8:14         ` Christoph Hellwig
2010-02-16  8:25           ` Dmitry Monakhov
2010-02-16  8:28             ` Christoph Hellwig
2010-02-16  8:56               ` Dmitry Monakhov
2010-02-16  9:03                 ` Christoph Hellwig
2010-02-16 21:13 ` [PATCH 0/4] quota: RFC add extend quota type v2 Jan Kara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).