* [PATCH 4/5] ext4: add project quota support
2010-03-18 14:02 ` [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem Dmitry Monakhov
@ 2010-03-18 14:02 ` Dmitry Monakhov
0 siblings, 0 replies; 18+ messages in thread
From: Dmitry Monakhov @ 2010-03-18 14:02 UTC (permalink / raw)
To: linux-ext4
Cc: linux-fsdevel, tytso, adilger, hch, jack, david, viro, xemul,
Dmitry Monakhov
Both regular and journaled quota are supported.
---
fs/ext4/ext4.h | 1 +
fs/ext4/super.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++------
fs/quota/dquot.c | 2 +-
3 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 5df54ae..3fa3602 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -745,6 +745,7 @@ struct ext4_inode_info {
#define EXT4_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */
#define EXT4_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */
#define EXT4_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/
+#define EXT4_MOUNT_PRJQUOTA 0x00200 /* Project quota support */
#define EXT4_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */
#define EXT4_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */
#define EXT4_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ddb4588..43a525e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -834,11 +834,18 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
if (sbi->s_qf_names[GRPQUOTA])
seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
+ if (sbi->s_qf_names[PRJQUOTA])
+ seq_printf(seq, ",prjjquota=%s", sbi->s_qf_names[PRJQUOTA]);
+
if (test_opt(sb, USRQUOTA))
seq_puts(seq, ",usrquota");
if (test_opt(sb, GRPQUOTA))
seq_puts(seq, ",grpquota");
+
+ if (test_opt(sb, PRJQUOTA))
+ seq_puts(seq, ",prjquota");
+
#endif
}
@@ -1039,8 +1046,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
}
#ifdef CONFIG_QUOTA
-#define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
-#define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
+static char *quotatypes[] = INITQFNAMES;
+#define QTYPE2NAME(t) (quotatypes[t])
static int ext4_write_dquot(struct dquot *dquot);
static int ext4_acquire_dquot(struct dquot *dquot);
@@ -1136,10 +1143,11 @@ enum {
Opt_journal_checksum, Opt_journal_async_commit,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Opt_data_err_abort, Opt_data_err_ignore,
- Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
+ Opt_usrjquota, Opt_grpjquota, Opt_prjjquota, Opt_offusrjquota,
+ Opt_offgrpjquota, Opt_offprjjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
- Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
+ Opt_resize, Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version,
Opt_stripe, Opt_delalloc, Opt_nodelalloc,
Opt_block_validity, Opt_noblock_validity,
Opt_inode_readahead_blks, Opt_journal_ioprio,
@@ -1189,10 +1197,13 @@ static const match_table_t tokens = {
{Opt_usrjquota, "usrjquota=%s"},
{Opt_offgrpjquota, "grpjquota="},
{Opt_grpjquota, "grpjquota=%s"},
+ {Opt_offprjjquota, "prjjquota="},
+ {Opt_prjjquota, "prjjquota=%s"},
{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
{Opt_grpquota, "grpquota"},
+ {Opt_prjquota, "prjquota"},
{Opt_noquota, "noquota"},
{Opt_quota, "quota"},
{Opt_usrquota, "usrquota"},
@@ -1512,6 +1523,16 @@ static int parse_options(char *options, struct super_block *sb,
if (!set_qf_name(sb, GRPQUOTA, &args[0]))
return 0;
break;
+
+ case Opt_prjjquota:
+#ifdef CONFIG_PROJECT_ID
+ if (!set_qf_name(sb, PRJQUOTA, &args[0]))
+ return 0;
+#else
+ ext4_msg(sb, KERN_ERR,
+ "project quota options not supported");
+#endif
+ break;
case Opt_offusrjquota:
if (!clear_qf_name(sb, USRQUOTA))
return 0;
@@ -1520,7 +1541,15 @@ static int parse_options(char *options, struct super_block *sb,
if (!clear_qf_name(sb, GRPQUOTA))
return 0;
break;
-
+ case Opt_offprjjquota:
+#ifdef CONFIG_PROJECT_ID
+ if (!clear_qf_name(sb, PRJQUOTA))
+ return 0;
+#else
+ ext4_msg(sb, KERN_ERR,
+ "project quota options not supported");
+#endif
+ break;
case Opt_jqfmt_vfsold:
qfmt = QFMT_VFS_OLD;
goto set_qf_format;
@@ -1548,6 +1577,15 @@ set_qf_format:
set_opt(sbi->s_mount_opt, QUOTA);
set_opt(sbi->s_mount_opt, GRPQUOTA);
break;
+ case Opt_prjquota:
+#ifdef CONFIG_PROJECT_ID
+ set_opt(sbi->s_mount_opt, QUOTA);
+ set_opt(sbi->s_mount_opt, PRJQUOTA);
+#else
+ ext4_msg(sb, KERN_ERR,
+ "project quota options not supported");
+#endif
+ break;
case Opt_noquota:
if (sb_any_quota_loaded(sb)) {
ext4_msg(sb, KERN_ERR, "Cannot change quota "
@@ -1557,18 +1595,22 @@ set_qf_format:
clear_opt(sbi->s_mount_opt, QUOTA);
clear_opt(sbi->s_mount_opt, USRQUOTA);
clear_opt(sbi->s_mount_opt, GRPQUOTA);
+ clear_opt(sbi->s_mount_opt, PRJQUOTA);
break;
#else
case Opt_quota:
case Opt_usrquota:
case Opt_grpquota:
+ case Opt_prjquota:
ext4_msg(sb, KERN_ERR,
"quota options not supported");
break;
case Opt_usrjquota:
case Opt_grpjquota:
+ case Opt_prjjquota:
case Opt_offusrjquota:
case Opt_offgrpjquota:
+ case Opt_offprjjquota:
case Opt_jqfmt_vfsold:
case Opt_jqfmt_vfsv0:
case Opt_jqfmt_vfsv1:
@@ -1695,14 +1737,19 @@ set_qf_format:
}
}
#ifdef CONFIG_QUOTA
- if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
+ if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA] ||
+ sbi->s_qf_names[PRJQUOTA]) {
if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
clear_opt(sbi->s_mount_opt, USRQUOTA);
if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
clear_opt(sbi->s_mount_opt, GRPQUOTA);
- if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) {
+ if (test_opt(sb, PRJQUOTA) && sbi->s_qf_names[PRJQUOTA])
+ clear_opt(sbi->s_mount_opt, PRJQUOTA);
+
+ if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA) ||
+ test_opt(sb, PRJQUOTA)) {
ext4_msg(sb, KERN_ERR, "old and new quota "
"format mixing");
return 0;
@@ -3868,7 +3915,8 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot)
{
/* Are we journaling quotas? */
if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
- EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
+ EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA] ||
+ EXT4_SB(dquot->dq_sb)->s_qf_names[PRJQUOTA]) {
dquot_mark_dquot_dirty(dquot);
return ext4_write_dquot(dquot);
} else {
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 3590888..73ef888 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1807,7 +1807,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
#ifdef CONFIG_PROJECT_ID
if (iattr->ia_valid & ATTR_PRJID && iattr->ia_prjid != inode->i_prjid) {
mask |= 1 << PRJQUOTA;
- chid[GRPQUOTA] = iattr->ia_prjid;
+ chid[PRJQUOTA] = iattr->ia_prjid;
}
#endif
if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) {
--
1.6.6.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 0/5] RFC: introduce extended inode owner identifier v9
@ 2012-06-21 9:08 Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 1/5] Add additional owner identifier Dmitry Monakhov
` (4 more replies)
0 siblings, 5 replies; 18+ messages in thread
From: Dmitry Monakhov @ 2012-06-21 9:08 UTC (permalink / raw)
To: linux-ext4; +Cc: linux-fsdevel, Dmitry Monakhov
Hi, I've updated old standing project quota id patch-set.
Please take a look at it and replay me your oppinion, especially if you
do not like it by some reason :) This is really important because i do
want this feature to be merged sooner or later.
*Feature description*
1) Inode may has a project identifier which has same meaning as uid/gid.
2) In general case Id is stored in inode's xattr named "system.project_id"
NOTE: by historical reasons XFS has speciffic API,
3) Id is inherent from parent inode on creation.
4) This id is cached in memory fs_inode structure and may be accessible
via s_op->get_prjid(). This field it restricted by CONFIG_PROJECT_ID.
So no wasting of memory happens.
5) Since id is cached in memory it may be used for different purposes
such as:
5A) Implement additional quota id space orthogonal to uid/gid. This is
useful in managing quota for some filesystem hierarchy(chroot or
container over bindmount)
*User interface *
Project id is managed via generic xattr interface "system.project_id"
This good because
1) We may use already existing interface.
2) xattr already supported by generic utilities tar/rsync and etc
PATCH SET TOC:
1) generic projectid support
2) generic project quota support
3) ext4: small mount flags cleanup
4) ext4 project support implementation
4A) ext4: generic project support
4B) ext4: project quota support
NOTE:Ext4 quota is now managed via e2fsprogs, changes which add prjquota suppport for
e2fsprogs will be submitted as separate patch-set.
5) XFS: prjquota and grpquota may coexist now
Patch against next-20120605-1-g20a6ee4
Actually vfs part is really small, and most changes happen in ext4-tree
Changes against V7
- Small fix for project switch error path
- Remove usless macro expressions
Changes against v6
- get rid of iattr stuff, current __dquot_transfer() provides sane interface
for quota manipulation. i_prjid can must be changed only by fs-speciffic
methods so only get() method is really necessery.
- remove #ifdef tricks from generic code.
- move i_prjid from vfs_inode to fs_inode, to prevent inode bloating.
- get rid of isolation logic, because this feature confuse most users.
Changes against v5
- convert dquota_transfer to struct iattr interface. Not it is possible
to change i_prjid via notify_changes()
- some bugfixes.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index 0d718ed..8dbcc39 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ VERSION = 3
PATCHLEVEL = 5
SUBLEVEL = 0
EXTRAVERSION = -rc1
-NAME = Saber-toothed Squirrel
+NAME = Saber-toothed Squirrel-tree-quota
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
--
1.7.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 1/5] Add additional owner identifier
2012-06-21 9:08 [PATCH 0/5] RFC: introduce extended inode owner identifier v9 Dmitry Monakhov
@ 2012-06-21 9:08 ` Dmitry Monakhov
2012-06-22 0:03 ` Jan Kara
2012-06-21 9:08 ` [PATCH 2/5] Implement project id support for generic quota Dmitry Monakhov
` (3 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Dmitry Monakhov @ 2012-06-21 9:08 UTC (permalink / raw)
To: linux-ext4; +Cc: linux-fsdevel, Dmitry Monakhov
This patch add project inode identifier. Project ID may be used as
auxiliary owner specifier in addition to standard uid/gid.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/Kconfig | 7 +++++++
include/linux/fs.h | 1 +
include/linux/xattr.h | 3 +++
3 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/fs/Kconfig b/fs/Kconfig
index c8554b5..1932458 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -60,6 +60,13 @@ config FILE_LOCKING
This option enables standard file locking support, required
for filesystems like NFS and for the flock() system
call. Disabling this option saves about 11k.
+config PROJECT_ID
+ bool "Enable project inode identifier"
+ default y
+ help
+ This option enables project inode identifier. Project ID
+ may be used as auxiliary owner specifier in addition to
+ standard uid/gid.
source "fs/notify/Kconfig"
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b0a6d44..6779fc2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1739,6 +1739,7 @@ struct super_operations {
int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
int (*nr_cached_objects)(struct super_block *);
void (*free_cached_objects)(struct super_block *, int);
+ u32 (*get_prjid)(const struct inode *inode);
};
/*
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index e5d1220..f8a83c3 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -61,6 +61,9 @@
#include <linux/types.h>
+#define XATTR_PRJID "system.project_id"
+#define XATTR_PRJID_LEN (sizeof (XATTR_PRJID))
+
struct inode;
struct dentry;
--
1.7.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/5] Implement project id support for generic quota
2012-06-21 9:08 [PATCH 0/5] RFC: introduce extended inode owner identifier v9 Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 1/5] Add additional owner identifier Dmitry Monakhov
@ 2012-06-21 9:08 ` Dmitry Monakhov
2012-06-22 0:01 ` Jan Kara
2012-06-21 9:08 ` [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem Dmitry Monakhov
` (2 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Dmitry Monakhov @ 2012-06-21 9:08 UTC (permalink / raw)
To: linux-ext4; +Cc: linux-fsdevel, Dmitry Monakhov
Since all preparation code are already in quota-tree,
So this patch is really small.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/quota/dquot.c | 10 ++++++++++
fs/quota/quotaio_v2.h | 6 ++++--
include/linux/quota.h | 9 ++++++++-
3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 10cbe84..db4148b 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1141,6 +1141,11 @@ static int need_print_warning(struct dquot_warn *warn)
return current_fsuid() == warn->w_dq_id;
case GRPQUOTA:
return in_group_p(warn->w_dq_id);
+ case PRJQUOTA:
+ /* XXX: Currently there is no way to understand
+ which project_id this task belonges to, So print
+ a warn message unconditionally. -dmon */
+ return 1;
}
return 0;
}
@@ -1395,6 +1400,11 @@ static void __dquot_initialize(struct inode *inode, int type)
case GRPQUOTA:
id = inode->i_gid;
break;
+ case PRJQUOTA:
+ if (!inode->i_sb->s_op->get_prjid)
+ continue;
+ id = inode->i_sb->s_op->get_prjid(inode);
+ break;
}
got[cnt] = dqget(sb, id, cnt);
}
diff --git a/fs/quota/quotaio_v2.h b/fs/quota/quotaio_v2.h
index f1966b4..bfab9df 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 /* PRJQUOTA */\
}
#define V2_INITQVERSIONS {\
1, /* USRQUOTA */\
- 1 /* GRPQUOTA */\
+ 1, /* GRPQUOTA */ \
+ 1 /* PRJQUOTA */\
}
/* First generic header */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index c09fa04..86f5cc2 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -36,11 +36,17 @@
#include <linux/errno.h>
#include <linux/types.h>
-#define __DQUOT_VERSION__ "dquot_6.5.2"
+#define __DQUOT_VERSION__ "dquot_6.6.0"
+#ifdef CONFIG_PROJECT_ID
+#define MAXQUOTAS 3
+#else
#define MAXQUOTAS 2
+#endif
+
#define USRQUOTA 0 /* element used for user quotas */
#define GRPQUOTA 1 /* element used for group quotas */
+#define PRJQUOTA 2 /* element used for project quotas */
/*
* Definitions for the default names of the quotas files.
@@ -48,6 +54,7 @@
#define INITQFNAMES { \
"user", /* USRQUOTA */ \
"group", /* GRPQUOTA */ \
+ "project", /* RPJQUOTA */ \
"undefined", \
};
--
1.7.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem
2012-06-21 9:08 [PATCH 0/5] RFC: introduce extended inode owner identifier v9 Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 1/5] Add additional owner identifier Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 2/5] Implement project id support for generic quota Dmitry Monakhov
@ 2012-06-21 9:08 ` Dmitry Monakhov
2012-06-21 23:51 ` Jan Kara
2012-06-22 3:07 ` Dave Chinner
2012-06-21 9:08 ` [PATCH 4/5] ext4: add project quota support Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 5/5] XFS: prjquota and grpqouta now may coexist Dmitry Monakhov
4 siblings, 2 replies; 18+ messages in thread
From: Dmitry Monakhov @ 2012-06-21 9:08 UTC (permalink / raw)
To: linux-ext4; +Cc: linux-fsdevel, Dmitry Monakhov
* Abstract
A subtree of a directory tree T is a tree consisting of a directory
(the subtree root) in T and all of its descendants in T.
*NOTE*: User is allowed to break pure subtree hierarchy via manual
id manipulation.
Project subtrees assumptions:
(1) Each inode has an id. This id is persistently stored inside
inode (xattr, usually inside ibody)
(2) Project id is inherent from parent directory
This feature is similar to project-id in XFS. One may assign some id to
a subtree. Each entry from the subtree may be accounted in directory
project quota. Will appear in later patches.
* Disk layout
Project id is stored on disk inside xattr usually inside ibody.
Xattr is used only as a data storage, It has not user visible xattr
interface.
* User interface
Project id is accessible via generic xattr interface "system.project_id"
* Notes
ext4_setattr interface to prjid: Semantically prjid must being changed
similar to uid/gid, but project_id is stored inside xattr so on-disk
structures updates is not that trivial, so I've move prjid change
logic to separate function.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/ext4/Kconfig | 8 ++
fs/ext4/Makefile | 1 +
fs/ext4/ext4.h | 4 +
fs/ext4/ialloc.c | 6 ++
fs/ext4/inode.c | 4 +
fs/ext4/project.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/ext4/project.h | 45 +++++++++++
fs/ext4/super.c | 16 ++++
fs/ext4/xattr.c | 7 ++
fs/ext4/xattr.h | 2 +
10 files changed, 306 insertions(+), 0 deletions(-)
create mode 100644 fs/ext4/project.c
create mode 100644 fs/ext4/project.h
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index c22f170..377af40 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -76,6 +76,14 @@ config EXT4_FS_SECURITY
If you are not using a security module that requires using
extended attributes for file security labels, say N.
+config EXT4_PROJECT_ID
+ bool "Ext4 project_id support"
+ depends on PROJECT_ID
+ depends on EXT4_FS_XATTR
+ help
+ Enables project inode identifier support for ext4 filesystem.
+ This feature allow to assign some id to inodes similar to
+ uid/gid.
config EXT4_DEBUG
bool "EXT4 debugging support"
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
index 56fd8f8..692fe56 100644
--- a/fs/ext4/Makefile
+++ b/fs/ext4/Makefile
@@ -12,3 +12,4 @@ ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \
ext4-$(CONFIG_EXT4_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o
+ext4-$(CONFIG_EXT4_PROJECT_ID) += project.o
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index cfc4e01..c0e33d7 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -925,6 +925,9 @@ struct ext4_inode_info {
/* Precomputed uuid+inum+igen checksum for seeding inode checksums */
__u32 i_csum_seed;
+#ifdef CONFIG_EXT4_PROJECT_ID
+ __u32 i_prjid;
+#endif
};
/*
@@ -962,6 +965,7 @@ struct ext4_inode_info {
#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
#define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */
#define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */
+#define EXT4_MOUNT_PROJECT_ID 0x40000 /* project owner id support */
#define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
#define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
#define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index d48e8b1..d4b72e5 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -28,6 +28,7 @@
#include "ext4_jbd2.h"
#include "xattr.h"
#include "acl.h"
+#include "project.h"
#include <trace/events/ext4.h>
@@ -898,6 +899,8 @@ got:
ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
+ ext4_setprjid(inode, ext4_getprjid(dir));
+
ret = inode;
dquot_initialize(inode);
err = dquot_alloc_inode(inode);
@@ -911,6 +914,9 @@ got:
err = ext4_init_security(handle, inode, dir, qstr);
if (err)
goto fail_free_drop;
+ err = ext4_prj_init(handle, inode);
+ if (err)
+ goto fail_free_drop;
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
/* set extent flag only for directory, file and normal symlink*/
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 02bc8cb..c98d8d6 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -42,6 +42,7 @@
#include "xattr.h"
#include "acl.h"
#include "truncate.h"
+#include "project.h"
#include <trace/events/ext4.h>
@@ -3870,6 +3871,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
}
if (ret)
goto bad_inode;
+ ret = ext4_prj_read(inode);
+ if (ret)
+ goto bad_inode;
if (S_ISREG(inode->i_mode)) {
inode->i_op = &ext4_file_inode_operations;
diff --git a/fs/ext4/project.c b/fs/ext4/project.c
new file mode 100644
index 0000000..a262a49
--- /dev/null
+++ b/fs/ext4/project.c
@@ -0,0 +1,213 @@
+/*
+ * linux/fs/ext4/projectid.c
+ *
+ * Copyright (C) 2010 Parallels Inc
+ * Dmitry Monakhov <dmonakhov@openvz.org>
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/capability.h>
+#include <linux/fs.h>
+#include <linux/quotaops.h>
+#include "ext4_jbd2.h"
+#include "ext4.h"
+#include "xattr.h"
+#include "project.h"
+
+
+/*
+ * PROJECT SUBTREE
+ * A subtree of a directory tree T is a tree consisting of a directory
+ * (the subtree root) in T and all of its descendants in T.
+ *
+ * Project Subtree's assumptions:
+ * (1) Each inode has subtree id. This id is persistently stored inside
+ * inode's xattr, usually inside ibody
+ * (2) Subtree id is inherent from parent directory
+ */
+
+/*
+ * Read project_id id from inode's xattr
+ * Locking: none
+ */
+int ext4_prj_xattr_read(struct inode *inode, unsigned int *prjid)
+{
+ __le32 dsk_prjid;
+ int retval;
+ retval = ext4_xattr_get(inode, EXT4_XATTR_INDEX_PROJECT_ID, "",
+ &dsk_prjid, sizeof (dsk_prjid));
+ if (retval > 0) {
+ if (retval != sizeof(dsk_prjid))
+ return -EIO;
+ else
+ retval = 0;
+ }
+ *prjid = le32_to_cpu(dsk_prjid);
+ return retval;
+
+}
+
+/*
+ * Save project_id id to inode's xattr
+ * Locking: none
+ */
+int ext4_prj_xattr_write(handle_t *handle, struct inode *inode,
+ unsigned int prjid, int xflags)
+{
+ __le32 dsk_prjid = cpu_to_le32(prjid);
+ int retval;
+ retval = ext4_xattr_set_handle(handle,
+ inode, EXT4_XATTR_INDEX_PROJECT_ID, "",
+ &dsk_prjid, sizeof (dsk_prjid), xflags);
+ if (retval > 0) {
+ if (retval != sizeof(dsk_prjid))
+ retval = -EIO;
+ else
+ retval = 0;
+ }
+ return retval;
+}
+
+/*
+ * Change project_id id.
+ * Called under inode->i_mutex
+ */
+int ext4_prj_change(struct inode *inode, unsigned int new_prjid)
+{
+ /*
+ * One data_trans_blocks chunk for xattr update.
+ * One quota_trans_blocks chunk for quota transfer, and one
+ * quota_trans_block chunk for emergency quota rollback transfer,
+ * because quota rollback may result new quota blocks allocation.
+ */
+ unsigned credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) +
+ EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb) * 2;
+ int ret, ret2 = 0;
+ unsigned retries = 0;
+ handle_t *handle;
+ struct dquot *dquot[MAXQUOTAS] = {};
+ int old_id = ext4_getprjid(inode);
+ dquot_initialize(inode);
+
+ dquot[PRJQUOTA] = dqget(inode->i_sb, new_prjid, PRJQUOTA);
+retry:
+ handle = ext4_journal_start(inode, credits);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ ext4_std_error(inode->i_sb, ret);
+ goto out;
+ }
+ /* Inode may not have project_id xattr yet. Create it explicitly */
+ ret = ext4_prj_xattr_write(handle, inode, old_id, XATTR_CREATE);
+ if (ret == -EEXIST)
+ ret = 0;
+ if (ret) {
+ ret2 = ext4_journal_stop(handle);
+ if (ret2)
+ ret = ret2;
+ if (ret == -ENOSPC &&
+ ext4_should_retry_alloc(inode->i_sb, &retries))
+ goto retry;
+ }
+#ifdef CONFIG_QUOTA
+ ret = __dquot_transfer(inode, dquot);
+ if (ret)
+ return ret;
+#endif
+ ret = ext4_prj_xattr_write(handle, inode, new_prjid, XATTR_REPLACE);
+ if (ret) {
+ /*
+ * Function may fail only due to fatal error, Nor than less
+ * we have try to rollback quota changes.
+ */
+#ifdef CONFIG_QUOTA
+ __dquot_transfer(inode, dquot);
+#endif
+ ext4_std_error(inode->i_sb, ret);
+
+ } else
+ ext4_setprjid(inode, new_prjid);
+
+ ret2 = ext4_journal_stop(handle);
+out:
+ dqput(dquot[PRJQUOTA]);
+ if (ret2)
+ ret = ret2;
+ return ret;
+}
+
+int ext4_prj_read(struct inode *inode)
+{
+ int ret = 0;
+ int prjid = 0;
+ if(test_opt(inode->i_sb, PROJECT_ID)) {
+ ret = ext4_prj_xattr_read(inode, &prjid);
+ if (ret == -ENODATA) {
+ prjid = 0;
+ ret = 0;
+ }
+ }
+ if (!ret)
+ ext4_setprjid(inode, prjid);
+ return ret;
+}
+/*
+ * Initialize the projectid xattr of a new inode. Called from ext4_new_inode.
+ *
+ * dir->i_mutex: down
+ * inode->i_mutex: up (access to inode is still exclusive)
+ * Note: caller must assign correct project id to inode before.
+ */
+int ext4_prj_init(handle_t *handle, struct inode *inode)
+{
+ return ext4_prj_xattr_write(handle, inode, EXT4_I(inode)->i_prjid,
+ XATTR_CREATE);
+}
+
+static size_t
+ext4_xattr_prj_list(struct dentry *dentry, char *list, size_t list_size,
+ const char *name, size_t name_len, int type)
+{
+ if (list && XATTR_PRJID_LEN <= list_size)
+ memcpy(list, XATTR_PRJID, XATTR_PRJID_LEN);
+ return XATTR_PRJID_LEN;
+
+}
+
+static int
+ext4_xattr_prj_get(struct dentry *dentry, const char *name,
+ void *buffer, size_t size, int type)
+{
+ int ret;
+ unsigned prjid;
+ char buf[32];
+ if (strcmp(name, "") != 0)
+ return -EINVAL;
+ ret = ext4_prj_xattr_read(dentry->d_inode, &prjid);
+ if (ret)
+ return ret;
+ snprintf(buf, sizeof(buf)-1, "%u", prjid);
+ buf[31] = '\0';
+ strncpy(buffer, buf, size);
+ return strlen(buf);
+}
+
+static int
+ext4_xattr_prj_set(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags, int type)
+{
+ unsigned int new_prjid;
+ if (strcmp(name, "") != 0)
+ return -EINVAL;
+ new_prjid = simple_strtoul(value, (char **)&value, 0);
+ return ext4_prj_change(dentry->d_inode, new_prjid);
+}
+
+const struct xattr_handler ext4_xattr_prj_handler = {
+ .prefix = XATTR_PRJID,
+ .list = ext4_xattr_prj_list,
+ .get = ext4_xattr_prj_get,
+ .set = ext4_xattr_prj_set,
+};
diff --git a/fs/ext4/project.h b/fs/ext4/project.h
new file mode 100644
index 0000000..054ec4c
--- /dev/null
+++ b/fs/ext4/project.h
@@ -0,0 +1,45 @@
+#include <linux/xattr.h>
+#include <linux/fs.h>
+
+#ifdef CONFIG_EXT4_PROJECT_ID
+extern int ext4_prj_xattr_read(struct inode *inode, unsigned int *prjid);
+extern int ext4_prj_xattr_write(handle_t *handle, struct inode *inode,
+ unsigned int prjid, int xflags);
+extern int ext4_prj_init(handle_t *handle, struct inode *inode);
+extern int ext4_prj_read(struct inode *inode);
+extern int ext4_prj_change(struct inode *inode, unsigned int new_prjid);
+static inline u32 ext4_getprjid(const struct inode *inode)
+{
+ const struct ext4_inode_info *ei =
+ container_of(inode, const struct ext4_inode_info, vfs_inode);
+ return ei->i_prjid;
+}
+static inline void ext4_setprjid(struct inode *inode, u32 id)
+{
+ EXT4_I(inode)->i_prjid = id;
+}
+#else
+#define ext4_getprjid(inode) do {} while (0)
+#define ext4_setprjid(inode, id) do {} while (0)
+static inline int ext4_prj_xattr_read(struct inode *inode, unsigned int *prjid)
+{
+ return -ENOTSUPP;
+}
+static inline int ext4_prj_xattr_write(handle_t *handle, struct inode *inode,
+ unsigned int prjid, int xflags)
+{
+ return -ENOTSUPP;
+}
+static inline int ext4_prj_read(struct inode *inode)
+{
+ return 0;
+}
+static inline int ext4_prj_change(struct inode *inode, unsigned int new_prjid)
+{
+ return -ENOTSUPP;
+}
+static inline int ext4_prj_init(handle_t *handle, struct inode *inode)
+{
+ return 0;
+}
+#endif
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index eb7aa3e..bf6f4ba 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -50,6 +50,7 @@
#include "xattr.h"
#include "acl.h"
#include "mballoc.h"
+#include "project.h"
#define CREATE_TRACE_POINTS
#include <trace/events/ext4.h>
@@ -1185,6 +1186,9 @@ static const struct super_operations ext4_sops = {
.quota_write = ext4_quota_write,
#endif
.bdev_try_to_free_page = bdev_try_to_free_page,
+#ifdef CONFIG_EXT4_PROJECT_ID
+ .get_prjid = ext4_getprjid,
+#endif
};
static const struct super_operations ext4_nojournal_sops = {
@@ -1204,6 +1208,9 @@ static const struct super_operations ext4_nojournal_sops = {
.quota_write = ext4_quota_write,
#endif
.bdev_try_to_free_page = bdev_try_to_free_page,
+#ifdef CONFIG_EXT4_PROJECT_ID
+ .get_prjid = ext4_getprjid,
+#endif
};
static const struct export_operations ext4_export_ops = {
@@ -1231,6 +1238,7 @@ enum {
Opt_inode_readahead_blks, Opt_journal_ioprio,
Opt_dioread_nolock, Opt_dioread_lock,
Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
+ Opt_project_id,
};
static const match_table_t tokens = {
@@ -1304,6 +1312,7 @@ static const match_table_t tokens = {
{Opt_init_itable, "init_itable=%u"},
{Opt_init_itable, "init_itable"},
{Opt_noinit_itable, "noinit_itable"},
+ {Opt_project_id, "prjid"},
{Opt_removed, "check=none"}, /* mount option from ext2/3 */
{Opt_removed, "nocheck"}, /* mount option from ext2/3 */
{Opt_removed, "reservation"}, /* mount option from ext2/3 */
@@ -1484,6 +1493,11 @@ static const struct mount_opts {
{Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT},
{Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT},
{Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
+#ifdef CONFIG_EXT4_PROJECT_ID
+ {Opt_project_id, EXT4_MOUNT_PROJECT_ID, MOPT_SET},
+#else
+ {Opt_project_id, 0, MOPT_NOSUPPORT},
+#endif
{Opt_err, 0, 0}
};
@@ -1822,6 +1836,8 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
SEQ_OPTS_PUTS("data=writeback");
}
+ if (test_opt(sb, PROJECT_ID))
+ SEQ_OPTS_PUTS("prjid");
if (nodefs ||
sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS)
SEQ_OPTS_PRINT("inode_readahead_blks=%u",
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index e56c9ed..ff24df7 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -107,6 +107,10 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = {
#ifdef CONFIG_EXT4_FS_SECURITY
[EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler,
#endif
+#ifdef CONFIG_EXT4_PROJECT_ID
+ [EXT4_XATTR_INDEX_PROJECT_ID] = &ext4_xattr_prj_handler,
+#endif
+
};
const struct xattr_handler *ext4_xattr_handlers[] = {
@@ -119,6 +123,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = {
#ifdef CONFIG_EXT4_FS_SECURITY
&ext4_xattr_security_handler,
#endif
+#ifdef CONFIG_EXT4_PROJECT_ID
+ &ext4_xattr_prj_handler,
+#endif
NULL
};
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index 91f31ca..2b3e1ff 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -21,6 +21,7 @@
#define EXT4_XATTR_INDEX_TRUSTED 4
#define EXT4_XATTR_INDEX_LUSTRE 5
#define EXT4_XATTR_INDEX_SECURITY 6
+#define EXT4_XATTR_INDEX_PROJECT_ID 7
struct ext4_xattr_header {
__le32 h_magic; /* magic number for identification */
@@ -72,6 +73,7 @@ extern const struct xattr_handler ext4_xattr_trusted_handler;
extern const struct xattr_handler ext4_xattr_acl_access_handler;
extern const struct xattr_handler ext4_xattr_acl_default_handler;
extern const struct xattr_handler ext4_xattr_security_handler;
+extern const struct xattr_handler ext4_xattr_prj_handler;
extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
--
1.7.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 4/5] ext4: add project quota support
2012-06-21 9:08 [PATCH 0/5] RFC: introduce extended inode owner identifier v9 Dmitry Monakhov
` (2 preceding siblings ...)
2012-06-21 9:08 ` [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem Dmitry Monakhov
@ 2012-06-21 9:08 ` Dmitry Monakhov
2012-06-21 23:56 ` Jan Kara
2012-06-21 9:08 ` [PATCH 5/5] XFS: prjquota and grpqouta now may coexist Dmitry Monakhov
4 siblings, 1 reply; 18+ messages in thread
From: Dmitry Monakhov @ 2012-06-21 9:08 UTC (permalink / raw)
To: linux-ext4; +Cc: linux-fsdevel, Dmitry Monakhov
Both regular and journaled quota are supported.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/ext4/ext4.h | 1 +
fs/ext4/super.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c0e33d7..940b41d 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -955,6 +955,7 @@ struct ext4_inode_info {
#define EXT4_MOUNT_ERRORS_MASK 0x00070
#define EXT4_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */
#define EXT4_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/
+#define EXT4_MOUNT_PRJQUOTA 0x00200 /* Project quota support */
#define EXT4_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */
#define EXT4_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */
#define EXT4_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index bf6f4ba..b407ff2 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1128,8 +1128,8 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
}
#ifdef CONFIG_QUOTA
-#define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
-#define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
+static char *quotatypes[] = INITQFNAMES;
+#define QTYPE2NAME(t) (quotatypes[t])
static int ext4_write_dquot(struct dquot *dquot);
static int ext4_acquire_dquot(struct dquot *dquot);
@@ -1229,10 +1229,11 @@ enum {
Opt_journal_dev, Opt_journal_checksum, Opt_journal_async_commit,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Opt_data_err_abort, Opt_data_err_ignore,
- Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
+ Opt_usrjquota, Opt_grpjquota, Opt_prjjquota,
+ Opt_offusrjquota, Opt_offgrpjquota, Opt_offprjjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
- Opt_usrquota, Opt_grpquota, Opt_i_version,
+ Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version,
Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
Opt_inode_readahead_blks, Opt_journal_ioprio,
@@ -1282,10 +1283,13 @@ static const match_table_t tokens = {
{Opt_usrjquota, "usrjquota=%s"},
{Opt_offgrpjquota, "grpjquota="},
{Opt_grpjquota, "grpjquota=%s"},
+ {Opt_offprjjquota, "prjjquota="},
+ {Opt_prjjquota, "prjjquota=%s"},
{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
{Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
{Opt_grpquota, "grpquota"},
+ {Opt_prjquota, "prjquota"},
{Opt_noquota, "noquota"},
{Opt_quota, "quota"},
{Opt_usrquota, "usrquota"},
@@ -1488,15 +1492,20 @@ static const struct mount_opts {
EXT4_MOUNT_GRPQUOTA), MOPT_CLEAR | MOPT_Q},
{Opt_usrjquota, 0, MOPT_Q},
{Opt_grpjquota, 0, MOPT_Q},
+ {Opt_prjjquota, 0, MOPT_Q},
{Opt_offusrjquota, 0, MOPT_Q},
{Opt_offgrpjquota, 0, MOPT_Q},
+ {Opt_offprjjquota, 0, MOPT_Q},
{Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT},
{Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT},
{Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
#ifdef CONFIG_EXT4_PROJECT_ID
{Opt_project_id, EXT4_MOUNT_PROJECT_ID, MOPT_SET},
+ {Opt_prjquota, EXT4_MOUNT_PROJECT_ID | EXT4_MOUNT_QUOTA | EXT4_MOUNT_PRJQUOTA,
+ MOPT_SET | MOPT_Q},
#else
{Opt_project_id, 0, MOPT_NOSUPPORT},
+ {Opt_prjquota, 0, MOPT_NOSUPPORT},
#endif
{Opt_err, 0, 0}
};
@@ -1516,10 +1525,21 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
return set_qf_name(sb, USRQUOTA, &args[0]);
else if (token == Opt_grpjquota)
return set_qf_name(sb, GRPQUOTA, &args[0]);
- else if (token == Opt_offusrjquota)
+ else if (token == Opt_offusrjquota)
return clear_qf_name(sb, USRQUOTA);
else if (token == Opt_offgrpjquota)
return clear_qf_name(sb, GRPQUOTA);
+#ifdef CONFIG_PROJECT_ID
+ else if (token == Opt_prjjquota)
+ return set_qf_name(sb, PRJQUOTA, &args[0]);
+ else if (token == Opt_offprjjquota)
+ return clear_qf_name(sb, PRJQUOTA);
+#else
+ else if (token == Opt_prjjquota || token == Opt_offprjjquota) {
+ ext4_msg(sb, KERN_ERR, "project quota options not supported");
+ return 0;
+ }
+#endif
#endif
if (args->from && match_int(args, &arg))
return -1;
@@ -1692,13 +1712,17 @@ static int parse_options(char *options, struct super_block *sb,
return 0;
}
#ifdef CONFIG_QUOTA
- if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
+ if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA] ||
+ sbi->s_qf_names[PRJQUOTA]) {
if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
clear_opt(sb, USRQUOTA);
if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA])
clear_opt(sb, GRPQUOTA);
+ if (test_opt(sb, PRJQUOTA) && sbi->s_qf_names[PRJQUOTA])
+ clear_opt(sb, PRJQUOTA);
+
if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) {
ext4_msg(sb, KERN_ERR, "old and new quota "
"format mixing");
@@ -1750,12 +1774,19 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
if (sbi->s_qf_names[GRPQUOTA])
seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
-
+#ifdef CONFIG_EXT4_PROJECT_ID
+ if (sbi->s_qf_names[PRJQUOTA])
+ seq_printf(seq, ",prjjquota=%s", sbi->s_qf_names[PRJQUOTA]);
+#endif
if (test_opt(sb, USRQUOTA))
seq_puts(seq, ",usrquota");
if (test_opt(sb, GRPQUOTA))
seq_puts(seq, ",grpquota");
+
+ if (test_opt(sb, PRJQUOTA))
+ seq_puts(seq, ",prjquota");
+
#endif
}
@@ -4769,7 +4800,8 @@ static int ext4_mark_dquot_dirty(struct dquot *dquot)
{
/* Are we journaling quotas? */
if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
- EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
+ EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA] ||
+ EXT4_SB(dquot->dq_sb)->s_qf_names[PRJQUOTA]) {
dquot_mark_dquot_dirty(dquot);
return ext4_write_dquot(dquot);
} else {
--
1.7.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 5/5] XFS: prjquota and grpqouta now may coexist
2012-06-21 9:08 [PATCH 0/5] RFC: introduce extended inode owner identifier v9 Dmitry Monakhov
` (3 preceding siblings ...)
2012-06-21 9:08 ` [PATCH 4/5] ext4: add project quota support Dmitry Monakhov
@ 2012-06-21 9:08 ` Dmitry Monakhov
2012-06-22 2:36 ` Dave Chinner
4 siblings, 1 reply; 18+ messages in thread
From: Dmitry Monakhov @ 2012-06-21 9:08 UTC (permalink / raw)
To: linux-ext4; +Cc: linux-fsdevel, Dmitry Monakhov
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/xfs/xfs_super.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 0d9de41..f408a27 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -538,14 +538,14 @@ xfs_showargs(
else if (mp->m_qflags & XFS_UQUOTA_ACCT)
seq_puts(m, "," MNTOPT_UQUOTANOENF);
- /* Either project or group quotas can be active, not both */
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem
2012-06-21 9:08 ` [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem Dmitry Monakhov
@ 2012-06-21 23:51 ` Jan Kara
2012-07-03 18:46 ` Dmitry Monakhov
2012-06-22 3:07 ` Dave Chinner
1 sibling, 1 reply; 18+ messages in thread
From: Jan Kara @ 2012-06-21 23:51 UTC (permalink / raw)
To: Dmitry Monakhov; +Cc: linux-ext4, linux-fsdevel
On Thu 21-06-12 13:08:51, Dmitry Monakhov wrote:
> * Abstract
> A subtree of a directory tree T is a tree consisting of a directory
> (the subtree root) in T and all of its descendants in T.
>
> *NOTE*: User is allowed to break pure subtree hierarchy via manual
> id manipulation.
>
> Project subtrees assumptions:
> (1) Each inode has an id. This id is persistently stored inside
> inode (xattr, usually inside ibody)
> (2) Project id is inherent from parent directory
>
> This feature is similar to project-id in XFS. One may assign some id to
> a subtree. Each entry from the subtree may be accounted in directory
> project quota. Will appear in later patches.
>
> * Disk layout
> Project id is stored on disk inside xattr usually inside ibody.
> Xattr is used only as a data storage, It has not user visible xattr
> interface.
>
> * User interface
> Project id is accessible via generic xattr interface "system.project_id"
>
> * Notes
> ext4_setattr interface to prjid: Semantically prjid must being changed
> similar to uid/gid, but project_id is stored inside xattr so on-disk
> structures updates is not that trivial, so I've move prjid change
> logic to separate function.
Generally, I like the patch. Some comments are below.
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
> fs/ext4/Kconfig | 8 ++
> fs/ext4/Makefile | 1 +
> fs/ext4/ext4.h | 4 +
> fs/ext4/ialloc.c | 6 ++
> fs/ext4/inode.c | 4 +
> fs/ext4/project.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> fs/ext4/project.h | 45 +++++++++++
> fs/ext4/super.c | 16 ++++
> fs/ext4/xattr.c | 7 ++
> fs/ext4/xattr.h | 2 +
> 10 files changed, 306 insertions(+), 0 deletions(-)
> create mode 100644 fs/ext4/project.c
> create mode 100644 fs/ext4/project.h
>
> diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
> index c22f170..377af40 100644
> --- a/fs/ext4/Kconfig
> +++ b/fs/ext4/Kconfig
> @@ -76,6 +76,14 @@ config EXT4_FS_SECURITY
>
> If you are not using a security module that requires using
> extended attributes for file security labels, say N.
> +config EXT4_PROJECT_ID
> + bool "Ext4 project_id support"
> + depends on PROJECT_ID
> + depends on EXT4_FS_XATTR
> + help
> + Enables project inode identifier support for ext4 filesystem.
> + This feature allow to assign some id to inodes similar to
> + uid/gid.
Is separate config option useful? The amount of code added for this is
not really big and there is not other speed / space benefit in disabling
this, is there?
> config EXT4_DEBUG
> bool "EXT4 debugging support"
> diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
> index 56fd8f8..692fe56 100644
> --- a/fs/ext4/Makefile
> +++ b/fs/ext4/Makefile
> @@ -12,3 +12,4 @@ ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \
> ext4-$(CONFIG_EXT4_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
> ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
> ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o
> +ext4-$(CONFIG_EXT4_PROJECT_ID) += project.o
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index cfc4e01..c0e33d7 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -925,6 +925,9 @@ struct ext4_inode_info {
>
> /* Precomputed uuid+inum+igen checksum for seeding inode checksums */
> __u32 i_csum_seed;
> +#ifdef CONFIG_EXT4_PROJECT_ID
> + __u32 i_prjid;
> +#endif
> };
>
> /*
> @@ -962,6 +965,7 @@ struct ext4_inode_info {
> #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
> #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */
> #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */
> +#define EXT4_MOUNT_PROJECT_ID 0x40000 /* project owner id support */
And I would even question the necessity of the mount option. Can we make
the rule that no system.prjid xattr simply means prjid == 0. When someone
sets prjid, it gets further automatically inherited and everything works
fine. I don't see the need for special mount option for this - again no
significant overhead is introduced when we always check whether we should
inherit non-zero prjid... Thoughts?
> #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
> #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
> #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
> diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
> index d48e8b1..d4b72e5 100644
> --- a/fs/ext4/ialloc.c
> +++ b/fs/ext4/ialloc.c
> @@ -28,6 +28,7 @@
> #include "ext4_jbd2.h"
> #include "xattr.h"
> #include "acl.h"
> +#include "project.h"
>
> #include <trace/events/ext4.h>
>
> @@ -898,6 +899,8 @@ got:
>
> ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
>
> + ext4_setprjid(inode, ext4_getprjid(dir));
> +
> ret = inode;
> dquot_initialize(inode);
> err = dquot_alloc_inode(inode);
> @@ -911,6 +914,9 @@ got:
> err = ext4_init_security(handle, inode, dir, qstr);
> if (err)
> goto fail_free_drop;
> + err = ext4_prj_init(handle, inode);
> + if (err)
> + goto fail_free_drop;
>
> if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
> /* set extent flag only for directory, file and normal symlink*/
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 02bc8cb..c98d8d6 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -42,6 +42,7 @@
> #include "xattr.h"
> #include "acl.h"
> #include "truncate.h"
> +#include "project.h"
>
> #include <trace/events/ext4.h>
>
> @@ -3870,6 +3871,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
> }
> if (ret)
> goto bad_inode;
> + ret = ext4_prj_read(inode);
> + if (ret)
> + goto bad_inode;
>
> if (S_ISREG(inode->i_mode)) {
> inode->i_op = &ext4_file_inode_operations;
> diff --git a/fs/ext4/project.c b/fs/ext4/project.c
> new file mode 100644
> index 0000000..a262a49
> --- /dev/null
> +++ b/fs/ext4/project.c
> @@ -0,0 +1,213 @@
> +/*
> + * linux/fs/ext4/projectid.c
> + *
> + * Copyright (C) 2010 Parallels Inc
> + * Dmitry Monakhov <dmonakhov@openvz.org>
> + */
> +
> +#include <linux/init.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/capability.h>
> +#include <linux/fs.h>
> +#include <linux/quotaops.h>
> +#include "ext4_jbd2.h"
> +#include "ext4.h"
> +#include "xattr.h"
> +#include "project.h"
> +
> +
> +/*
> + * PROJECT SUBTREE
> + * A subtree of a directory tree T is a tree consisting of a directory
> + * (the subtree root) in T and all of its descendants in T.
> + *
> + * Project Subtree's assumptions:
> + * (1) Each inode has subtree id. This id is persistently stored inside
> + * inode's xattr, usually inside ibody
> + * (2) Subtree id is inherent from parent directory
> + */
> +
> +/*
> + * Read project_id id from inode's xattr
> + * Locking: none
> + */
> +int ext4_prj_xattr_read(struct inode *inode, unsigned int *prjid)
> +{
> + __le32 dsk_prjid;
> + int retval;
Please add empty line between declarations and function body... Also
holds for some functions below.
> + retval = ext4_xattr_get(inode, EXT4_XATTR_INDEX_PROJECT_ID, "",
> + &dsk_prjid, sizeof (dsk_prjid));
> + if (retval > 0) {
> + if (retval != sizeof(dsk_prjid))
> + return -EIO;
> + else
> + retval = 0;
> + }
> + *prjid = le32_to_cpu(dsk_prjid);
> + return retval;
> +
> +}
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/5] ext4: add project quota support
2012-06-21 9:08 ` [PATCH 4/5] ext4: add project quota support Dmitry Monakhov
@ 2012-06-21 23:56 ` Jan Kara
0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2012-06-21 23:56 UTC (permalink / raw)
To: Dmitry Monakhov; +Cc: linux-ext4, linux-fsdevel
On Thu 21-06-12 13:08:52, Dmitry Monakhov wrote:
> Both regular and journaled quota are supported.
Looks good, just one whitespace damage caught below. You can add:
Reviewed-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
> fs/ext4/ext4.h | 1 +
> fs/ext4/super.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 41 insertions(+), 8 deletions(-)
>
...
> @@ -1516,10 +1525,21 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
> return set_qf_name(sb, USRQUOTA, &args[0]);
> else if (token == Opt_grpjquota)
> return set_qf_name(sb, GRPQUOTA, &args[0]);
> - else if (token == Opt_offusrjquota)
> + else if (token == Opt_offusrjquota)
Spaces instead of TAB here... Checkpatch would catch this BTW.
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] Implement project id support for generic quota
2012-06-21 9:08 ` [PATCH 2/5] Implement project id support for generic quota Dmitry Monakhov
@ 2012-06-22 0:01 ` Jan Kara
0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2012-06-22 0:01 UTC (permalink / raw)
To: Dmitry Monakhov; +Cc: linux-ext4, linux-fsdevel
On Thu 21-06-12 13:08:50, Dmitry Monakhov wrote:
> Since all preparation code are already in quota-tree,
> So this patch is really small.
>
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
...
> @@ -48,6 +54,7 @@
> #define INITQFNAMES { \
> "user", /* USRQUOTA */ \
> "group", /* GRPQUOTA */ \
> + "project", /* RPJQUOTA */ \
Typo above - should be PRJQUOTA.
> "undefined", \
> };
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/5] Add additional owner identifier
2012-06-21 9:08 ` [PATCH 1/5] Add additional owner identifier Dmitry Monakhov
@ 2012-06-22 0:03 ` Jan Kara
2012-07-03 18:42 ` Dmitry Monakhov
0 siblings, 1 reply; 18+ messages in thread
From: Jan Kara @ 2012-06-22 0:03 UTC (permalink / raw)
To: Dmitry Monakhov; +Cc: linux-ext4, linux-fsdevel
On Thu 21-06-12 13:08:49, Dmitry Monakhov wrote:
> This patch add project inode identifier. Project ID may be used as
> auxiliary owner specifier in addition to standard uid/gid.
I would just join patches 1 and 2. One without the other looks a bit
dumb... Otherwise I'm OK with the changes. I can take these two patches
through my tree when filesystem maintainers agree they want this feature and
are going to merge corresponding fs patches...
Honza
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
> fs/Kconfig | 7 +++++++
> include/linux/fs.h | 1 +
> include/linux/xattr.h | 3 +++
> 3 files changed, 11 insertions(+), 0 deletions(-)
>
> diff --git a/fs/Kconfig b/fs/Kconfig
> index c8554b5..1932458 100644
> --- a/fs/Kconfig
> +++ b/fs/Kconfig
> @@ -60,6 +60,13 @@ config FILE_LOCKING
> This option enables standard file locking support, required
> for filesystems like NFS and for the flock() system
> call. Disabling this option saves about 11k.
> +config PROJECT_ID
> + bool "Enable project inode identifier"
> + default y
> + help
> + This option enables project inode identifier. Project ID
> + may be used as auxiliary owner specifier in addition to
> + standard uid/gid.
>
> source "fs/notify/Kconfig"
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index b0a6d44..6779fc2 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1739,6 +1739,7 @@ struct super_operations {
> int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
> int (*nr_cached_objects)(struct super_block *);
> void (*free_cached_objects)(struct super_block *, int);
> + u32 (*get_prjid)(const struct inode *inode);
> };
>
> /*
> diff --git a/include/linux/xattr.h b/include/linux/xattr.h
> index e5d1220..f8a83c3 100644
> --- a/include/linux/xattr.h
> +++ b/include/linux/xattr.h
> @@ -61,6 +61,9 @@
>
> #include <linux/types.h>
>
> +#define XATTR_PRJID "system.project_id"
> +#define XATTR_PRJID_LEN (sizeof (XATTR_PRJID))
> +
> struct inode;
> struct dentry;
>
> --
> 1.7.1
>
> --
> 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 <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 5/5] XFS: prjquota and grpqouta now may coexist
2012-06-21 9:08 ` [PATCH 5/5] XFS: prjquota and grpqouta now may coexist Dmitry Monakhov
@ 2012-06-22 2:36 ` Dave Chinner
2012-07-03 19:14 ` Dmitry Monakhov
0 siblings, 1 reply; 18+ messages in thread
From: Dave Chinner @ 2012-06-22 2:36 UTC (permalink / raw)
To: Dmitry Monakhov; +Cc: linux-ext4, linux-fsdevel
On Thu, Jun 21, 2012 at 01:08:53PM +0400, Dmitry Monakhov wrote:
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
> fs/xfs/xfs_super.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 0d9de41..f408a27 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -538,14 +538,14 @@ xfs_showargs(
> else if (mp->m_qflags & XFS_UQUOTA_ACCT)
> seq_puts(m, "," MNTOPT_UQUOTANOENF);
>
> - /* Either project or group quotas can be active, not both */
> -
> if (mp->m_qflags & XFS_PQUOTA_ACCT) {
> if (mp->m_qflags & XFS_OQUOTA_ENFD)
> seq_puts(m, "," MNTOPT_PRJQUOTA);
> else
> seq_puts(m, "," MNTOPT_PQUOTANOENF);
> - } else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
> + }
> +
> + if (mp->m_qflags & XFS_GQUOTA_ACCT) {
> if (mp->m_qflags & XFS_OQUOTA_ENFD)
> seq_puts(m, "," MNTOPT_GRPQUOTA);
> else
Why can they co-exist now? XFS does not use the VFS quota
code, and you've made no other changes to XFS so I can't see how you
can make that assertion. There's a current patchset under review
that allows XFS to have co-existing group and project quotas - it's
complex, changes the on-disk format and requires userspace tool
support (e.g. mkfs, repair, xfs_db, etc).
So I can't see how this works with XFS at all...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem
2012-06-21 9:08 ` [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem Dmitry Monakhov
2012-06-21 23:51 ` Jan Kara
@ 2012-06-22 3:07 ` Dave Chinner
2012-06-28 10:16 ` Jan Kara
2012-07-03 19:11 ` Dmitry Monakhov
1 sibling, 2 replies; 18+ messages in thread
From: Dave Chinner @ 2012-06-22 3:07 UTC (permalink / raw)
To: Dmitry Monakhov; +Cc: linux-ext4, linux-fsdevel
On Thu, Jun 21, 2012 at 01:08:51PM +0400, Dmitry Monakhov wrote:
> * Abstract
> A subtree of a directory tree T is a tree consisting of a directory
> (the subtree root) in T and all of its descendants in T.
>
> *NOTE*: User is allowed to break pure subtree hierarchy via manual
> id manipulation.
>
> Project subtrees assumptions:
> (1) Each inode has an id. This id is persistently stored inside
> inode (xattr, usually inside ibody)
> (2) Project id is inherent from parent directory
You are mashing two different concepts into one, and naming it in a
manner guaranteed to create confusion with all the people already
using project quotas on XFS. You're implementing subtree quotas, not
project quotas.
> This feature is similar to project-id in XFS. One may assign
> some id to a subtree. Each entry from the subtree may be
> accounted in directory project quota. Will appear in later
> patches.
As implied above, project quotas ID in XFS are not subtree quotas.
They are used to implement project quotas, not subtree quotas.
subtree quotas are a userspace management construction using a
subset of project quota infrastructure. i.e. the inheritance of
project IDs in XFS and the restriction of operations to within
subtrees is not a function of project quotas - it's a separately
managed feature that was added to support the functioanlity needed
for subtree quotas.
ISTR raising this objection last time you posted this patch set -
either you implement project quotas as they exist in XFS and handle
subtree quotas as a constrainted set of project quota functionality
or you need to drop all references to "project quotas" and call this
something like sub-tree quotas that uses subtree IDs.
> * Disk layout
> Project id is stored on disk inside xattr usually inside ibody.
> Xattr is used only as a data storage, It has not user visible xattr
> interface.
If you've got enough xattrs on the inode, then it will end up out of
line and performance is going to suck - every time you write to a
cold file you now need two IOs - one to read the extent list, and
one to read the xattrs to get the project ID....
> * User interface
> Project id is accessible via generic xattr interface "system.project_id"
Which means it is an incompatible with XFS. What purpose does this
serve except to confuse people? Why not a generic set/get project ID
quotactl/ioctl? That's much easier for applications to use compared
to xattrs, and far easier to support different implementations
across filesystems. The way the project ID is stored in ext4 should
not define the API.
Indeed, an ioctl/quotactl style interface matches the existing quota
interface, so it's much more natural to use a similar API to one
already used for quota manipulation...
> * Notes
> ext4_setattr interface to prjid: Semantically prjid must being changed
> similar to uid/gid, but project_id is stored inside xattr so on-disk
> structures updates is not that trivial, so I've move prjid change
> logic to separate function.
I suspect that there are corner cases you haven't thought about
yet. What happens when you hard link a file into two separate
subtrees? how do you account for that? What happens when you remove
the hard link from the subtree the inode is accounted to? What
happens when a rename occurs, moving a file from one subtree to
another?
.....
> +static int
> +ext4_xattr_prj_set(struct dentry *dentry, const char *name,
> + const void *value, size_t size, int flags, int type)
> +{
> + unsigned int new_prjid;
> + if (strcmp(name, "") != 0)
> + return -EINVAL;
> + new_prjid = simple_strtoul(value, (char **)&value, 0);
> + return ext4_prj_change(dentry->d_inode, new_prjid);
Because you are using strings rather than integers for the ID, you
need to do a lot better verification here - what will happen when
someone tries to set an ID of "frobnozzle"? Using integers via
ioctls for the user API make this problem....
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem
2012-06-22 3:07 ` Dave Chinner
@ 2012-06-28 10:16 ` Jan Kara
2012-07-03 19:11 ` Dmitry Monakhov
1 sibling, 0 replies; 18+ messages in thread
From: Jan Kara @ 2012-06-28 10:16 UTC (permalink / raw)
To: Dave Chinner; +Cc: Dmitry Monakhov, linux-ext4, linux-fsdevel
On Fri 22-06-12 13:07:53, Dave Chinner wrote:
> On Thu, Jun 21, 2012 at 01:08:51PM +0400, Dmitry Monakhov wrote:
> > * Abstract
> > A subtree of a directory tree T is a tree consisting of a directory
> > (the subtree root) in T and all of its descendants in T.
> >
> > *NOTE*: User is allowed to break pure subtree hierarchy via manual
> > id manipulation.
> >
> > Project subtrees assumptions:
> > (1) Each inode has an id. This id is persistently stored inside
> > inode (xattr, usually inside ibody)
> > (2) Project id is inherent from parent directory
>
> You are mashing two different concepts into one, and naming it in a
> manner guaranteed to create confusion with all the people already
> using project quotas on XFS. You're implementing subtree quotas, not
> project quotas.
>
> > This feature is similar to project-id in XFS. One may assign
> > some id to a subtree. Each entry from the subtree may be
> > accounted in directory project quota. Will appear in later
> > patches.
>
> As implied above, project quotas ID in XFS are not subtree quotas.
> They are used to implement project quotas, not subtree quotas.
> subtree quotas are a userspace management construction using a
> subset of project quota infrastructure. i.e. the inheritance of
> project IDs in XFS and the restriction of operations to within
> subtrees is not a function of project quotas - it's a separately
> managed feature that was added to support the functioanlity needed
> for subtree quotas.
>
> ISTR raising this objection last time you posted this patch set -
> either you implement project quotas as they exist in XFS and handle
> subtree quotas as a constrainted set of project quota functionality
> or you need to drop all references to "project quotas" and call this
> something like sub-tree quotas that uses subtree IDs.
Frankly, I fail to see the difference between XFS project quotas and how
Dmitry implemented his variant of quotas. He associated additional ID with
each inode and that ID can have quota limits. This seems pretty much like
what XFS project quotas do but maybe I'm missing something.
I agree that his changelogs somewhat suggest that he had only subtrees in
mind but the code does not really depend on that AFAICS. The only
difference I can see is that in XFS project ID is inherited only if
XFS_DIFLAG_PROJINHERIT is set and that is inherited by default but can be
manipulated from userspace. But that looks like a minor thing.
> > * Disk layout
> > Project id is stored on disk inside xattr usually inside ibody.
> > Xattr is used only as a data storage, It has not user visible xattr
> > interface.
>
> If you've got enough xattrs on the inode, then it will end up out of
> line and performance is going to suck - every time you write to a
> cold file you now need two IOs - one to read the extent list, and
> one to read the xattrs to get the project ID....
>
> > * User interface
> > Project id is accessible via generic xattr interface "system.project_id"
>
> Which means it is an incompatible with XFS. What purpose does this
> serve except to confuse people? Why not a generic set/get project ID
> quotactl/ioctl? That's much easier for applications to use compared
> to xattrs, and far easier to support different implementations
> across filesystems. The way the project ID is stored in ext4 should
> not define the API.
>
> Indeed, an ioctl/quotactl style interface matches the existing quota
> interface, so it's much more natural to use a similar API to one
> already used for quota manipulation...
I'm kind of undecided here - xattrs have the disadvantages you wrote
above but also some advantages like that backup tools know about them, you
can manipulate them with setxattr, getxattr, etc.
>From kernel POV I agree that for XFS it's a bit ugly to fake the project
quota xattr though...
> > * Notes
> > ext4_setattr interface to prjid: Semantically prjid must being changed
> > similar to uid/gid, but project_id is stored inside xattr so on-disk
> > structures updates is not that trivial, so I've move prjid change
> > logic to separate function.
>
> I suspect that there are corner cases you haven't thought about
> yet. What happens when you hard link a file into two separate
> subtrees? how do you account for that? What happens when you remove
> the hard link from the subtree the inode is accounted to? What
> happens when a rename occurs, moving a file from one subtree to
> another?
Yeah, handling of these things is missing from an ext4 patch. Good that
you've spotted that. I forgot about it.
> .....
>
> > +static int
> > +ext4_xattr_prj_set(struct dentry *dentry, const char *name,
> > + const void *value, size_t size, int flags, int type)
> > +{
> > + unsigned int new_prjid;
> > + if (strcmp(name, "") != 0)
> > + return -EINVAL;
> > + new_prjid = simple_strtoul(value, (char **)&value, 0);
> > + return ext4_prj_change(dentry->d_inode, new_prjid);
>
> Because you are using strings rather than integers for the ID, you
> need to do a lot better verification here - what will happen when
> someone tries to set an ID of "frobnozzle"? Using integers via
> ioctls for the user API make this problem....
Well, simple_strtoul() returns something for arbitary string - that's the
project ID ;). But I agree forcing project ID 0 if there's parse error is
more user friendly given the simple_strtoul() return value for unparseable
strings can change.
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/5] Add additional owner identifier
2012-06-22 0:03 ` Jan Kara
@ 2012-07-03 18:42 ` Dmitry Monakhov
0 siblings, 0 replies; 18+ messages in thread
From: Dmitry Monakhov @ 2012-07-03 18:42 UTC (permalink / raw)
To: Jan Kara; +Cc: linux-ext4, linux-fsdevel
On Fri, 22 Jun 2012 02:03:53 +0200, Jan Kara <jack@suse.cz> wrote:
> On Thu 21-06-12 13:08:49, Dmitry Monakhov wrote:
> > This patch add project inode identifier. Project ID may be used as
> > auxiliary owner specifier in addition to standard uid/gid.
Hi,
First of all please excuse me for a very very late replay.
Where were some very urgent work to do, Please excuse me one more time.
> I would just join patches 1 and 2. One without the other looks a bit
> dumb... Otherwise I'm OK with the changes. I can take these two patches
> through my tree when filesystem maintainers agree they want this feature and
> are going to merge corresponding fs patches...
Ok, seem reasonable will redo.
>
>
> Honza
>
> > Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> > ---
> > fs/Kconfig | 7 +++++++
> > include/linux/fs.h | 1 +
> > include/linux/xattr.h | 3 +++
> > 3 files changed, 11 insertions(+), 0 deletions(-)
> >
> > diff --git a/fs/Kconfig b/fs/Kconfig
> > index c8554b5..1932458 100644
> > --- a/fs/Kconfig
> > +++ b/fs/Kconfig
> > @@ -60,6 +60,13 @@ config FILE_LOCKING
> > This option enables standard file locking support, required
> > for filesystems like NFS and for the flock() system
> > call. Disabling this option saves about 11k.
> > +config PROJECT_ID
> > + bool "Enable project inode identifier"
> > + default y
> > + help
> > + This option enables project inode identifier. Project ID
> > + may be used as auxiliary owner specifier in addition to
> > + standard uid/gid.
> >
> > source "fs/notify/Kconfig"
> >
> > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > index b0a6d44..6779fc2 100644
> > --- a/include/linux/fs.h
> > +++ b/include/linux/fs.h
> > @@ -1739,6 +1739,7 @@ struct super_operations {
> > int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
> > int (*nr_cached_objects)(struct super_block *);
> > void (*free_cached_objects)(struct super_block *, int);
> > + u32 (*get_prjid)(const struct inode *inode);
> > };
> >
> > /*
> > diff --git a/include/linux/xattr.h b/include/linux/xattr.h
> > index e5d1220..f8a83c3 100644
> > --- a/include/linux/xattr.h
> > +++ b/include/linux/xattr.h
> > @@ -61,6 +61,9 @@
> >
> > #include <linux/types.h>
> >
> > +#define XATTR_PRJID "system.project_id"
> > +#define XATTR_PRJID_LEN (sizeof (XATTR_PRJID))
> > +
> > struct inode;
> > struct dentry;
> >
> > --
> > 1.7.1
> >
> > --
> > 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 <jack@suse.cz>
> SUSE Labs, CR
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem
2012-06-21 23:51 ` Jan Kara
@ 2012-07-03 18:46 ` Dmitry Monakhov
0 siblings, 0 replies; 18+ messages in thread
From: Dmitry Monakhov @ 2012-07-03 18:46 UTC (permalink / raw)
To: Jan Kara; +Cc: linux-ext4, linux-fsdevel
On Fri, 22 Jun 2012 01:51:46 +0200, Jan Kara <jack@suse.cz> wrote:
> On Thu 21-06-12 13:08:51, Dmitry Monakhov wrote:
> > * Abstract
> > A subtree of a directory tree T is a tree consisting of a directory
> > (the subtree root) in T and all of its descendants in T.
> >
> > *NOTE*: User is allowed to break pure subtree hierarchy via manual
> > id manipulation.
> >
> > Project subtrees assumptions:
> > (1) Each inode has an id. This id is persistently stored inside
> > inode (xattr, usually inside ibody)
> > (2) Project id is inherent from parent directory
> >
> > This feature is similar to project-id in XFS. One may assign some id to
> > a subtree. Each entry from the subtree may be accounted in directory
> > project quota. Will appear in later patches.
> >
> > * Disk layout
> > Project id is stored on disk inside xattr usually inside ibody.
> > Xattr is used only as a data storage, It has not user visible xattr
> > interface.
> >
> > * User interface
> > Project id is accessible via generic xattr interface "system.project_id"
> >
> > * Notes
> > ext4_setattr interface to prjid: Semantically prjid must being changed
> > similar to uid/gid, but project_id is stored inside xattr so on-disk
> > structures updates is not that trivial, so I've move prjid change
> > logic to separate function.
> Generally, I like the patch. Some comments are below.
Also reasonable, will redo.
>
> > Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> > ---
> > fs/ext4/Kconfig | 8 ++
> > fs/ext4/Makefile | 1 +
> > fs/ext4/ext4.h | 4 +
> > fs/ext4/ialloc.c | 6 ++
> > fs/ext4/inode.c | 4 +
> > fs/ext4/project.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> > fs/ext4/project.h | 45 +++++++++++
> > fs/ext4/super.c | 16 ++++
> > fs/ext4/xattr.c | 7 ++
> > fs/ext4/xattr.h | 2 +
> > 10 files changed, 306 insertions(+), 0 deletions(-)
> > create mode 100644 fs/ext4/project.c
> > create mode 100644 fs/ext4/project.h
> >
> > diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
> > index c22f170..377af40 100644
> > --- a/fs/ext4/Kconfig
> > +++ b/fs/ext4/Kconfig
> > @@ -76,6 +76,14 @@ config EXT4_FS_SECURITY
> >
> > If you are not using a security module that requires using
> > extended attributes for file security labels, say N.
> > +config EXT4_PROJECT_ID
> > + bool "Ext4 project_id support"
> > + depends on PROJECT_ID
> > + depends on EXT4_FS_XATTR
> > + help
> > + Enables project inode identifier support for ext4 filesystem.
> > + This feature allow to assign some id to inodes similar to
> > + uid/gid.
> Is separate config option useful? The amount of code added for this is
> not really big and there is not other speed / space benefit in disabling
> this, is there?
>
> > config EXT4_DEBUG
> > bool "EXT4 debugging support"
> > diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
> > index 56fd8f8..692fe56 100644
> > --- a/fs/ext4/Makefile
> > +++ b/fs/ext4/Makefile
> > @@ -12,3 +12,4 @@ ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \
> > ext4-$(CONFIG_EXT4_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
> > ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
> > ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o
> > +ext4-$(CONFIG_EXT4_PROJECT_ID) += project.o
> > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> > index cfc4e01..c0e33d7 100644
> > --- a/fs/ext4/ext4.h
> > +++ b/fs/ext4/ext4.h
> > @@ -925,6 +925,9 @@ struct ext4_inode_info {
> >
> > /* Precomputed uuid+inum+igen checksum for seeding inode checksums */
> > __u32 i_csum_seed;
> > +#ifdef CONFIG_EXT4_PROJECT_ID
> > + __u32 i_prjid;
> > +#endif
> > };
> >
> > /*
> > @@ -962,6 +965,7 @@ struct ext4_inode_info {
> > #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
> > #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */
> > #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */
> > +#define EXT4_MOUNT_PROJECT_ID 0x40000 /* project owner id support */
> And I would even question the necessity of the mount option. Can we make
> the rule that no system.prjid xattr simply means prjid == 0. When someone
> sets prjid, it gets further automatically inherited and everything works
> fine. I don't see the need for special mount option for this - again no
> significant overhead is introduced when we always check whether we should
> inherit non-zero prjid... Thoughts?
Yep. this reasonable, Also it allows us to save mountopt bit space for
new crazy stuff.
>
> > #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
> > #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
> > #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
> > diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
> > index d48e8b1..d4b72e5 100644
> > --- a/fs/ext4/ialloc.c
> > +++ b/fs/ext4/ialloc.c
> > @@ -28,6 +28,7 @@
> > #include "ext4_jbd2.h"
> > #include "xattr.h"
> > #include "acl.h"
> > +#include "project.h"
> >
> > #include <trace/events/ext4.h>
> >
> > @@ -898,6 +899,8 @@ got:
> >
> > ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
> >
> > + ext4_setprjid(inode, ext4_getprjid(dir));
> > +
> > ret = inode;
> > dquot_initialize(inode);
> > err = dquot_alloc_inode(inode);
> > @@ -911,6 +914,9 @@ got:
> > err = ext4_init_security(handle, inode, dir, qstr);
> > if (err)
> > goto fail_free_drop;
> > + err = ext4_prj_init(handle, inode);
> > + if (err)
> > + goto fail_free_drop;
> >
> > if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
> > /* set extent flag only for directory, file and normal symlink*/
> > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> > index 02bc8cb..c98d8d6 100644
> > --- a/fs/ext4/inode.c
> > +++ b/fs/ext4/inode.c
> > @@ -42,6 +42,7 @@
> > #include "xattr.h"
> > #include "acl.h"
> > #include "truncate.h"
> > +#include "project.h"
> >
> > #include <trace/events/ext4.h>
> >
> > @@ -3870,6 +3871,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
> > }
> > if (ret)
> > goto bad_inode;
> > + ret = ext4_prj_read(inode);
> > + if (ret)
> > + goto bad_inode;
> >
> > if (S_ISREG(inode->i_mode)) {
> > inode->i_op = &ext4_file_inode_operations;
> > diff --git a/fs/ext4/project.c b/fs/ext4/project.c
> > new file mode 100644
> > index 0000000..a262a49
> > --- /dev/null
> > +++ b/fs/ext4/project.c
> > @@ -0,0 +1,213 @@
> > +/*
> > + * linux/fs/ext4/projectid.c
> > + *
> > + * Copyright (C) 2010 Parallels Inc
> > + * Dmitry Monakhov <dmonakhov@openvz.org>
> > + */
> > +
> > +#include <linux/init.h>
> > +#include <linux/sched.h>
> > +#include <linux/slab.h>
> > +#include <linux/capability.h>
> > +#include <linux/fs.h>
> > +#include <linux/quotaops.h>
> > +#include "ext4_jbd2.h"
> > +#include "ext4.h"
> > +#include "xattr.h"
> > +#include "project.h"
> > +
> > +
> > +/*
> > + * PROJECT SUBTREE
> > + * A subtree of a directory tree T is a tree consisting of a directory
> > + * (the subtree root) in T and all of its descendants in T.
> > + *
> > + * Project Subtree's assumptions:
> > + * (1) Each inode has subtree id. This id is persistently stored inside
> > + * inode's xattr, usually inside ibody
> > + * (2) Subtree id is inherent from parent directory
> > + */
> > +
> > +/*
> > + * Read project_id id from inode's xattr
> > + * Locking: none
> > + */
> > +int ext4_prj_xattr_read(struct inode *inode, unsigned int *prjid)
> > +{
> > + __le32 dsk_prjid;
> > + int retval;
> Please add empty line between declarations and function body... Also
> holds for some functions below.
>
> > + retval = ext4_xattr_get(inode, EXT4_XATTR_INDEX_PROJECT_ID, "",
> > + &dsk_prjid, sizeof (dsk_prjid));
> > + if (retval > 0) {
> > + if (retval != sizeof(dsk_prjid))
> > + return -EIO;
> > + else
> > + retval = 0;
> > + }
> > + *prjid = le32_to_cpu(dsk_prjid);
> > + return retval;
> > +
> > +}
>
> Honza
> --
> Jan Kara <jack@suse.cz>
> SUSE Labs, CR
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem
2012-06-22 3:07 ` Dave Chinner
2012-06-28 10:16 ` Jan Kara
@ 2012-07-03 19:11 ` Dmitry Monakhov
1 sibling, 0 replies; 18+ messages in thread
From: Dmitry Monakhov @ 2012-07-03 19:11 UTC (permalink / raw)
To: Dave Chinner; +Cc: linux-ext4, linux-fsdevel
On Fri, 22 Jun 2012 13:07:53 +1000, Dave Chinner <david@fromorbit.com> wrote:
> On Thu, Jun 21, 2012 at 01:08:51PM +0400, Dmitry Monakhov wrote:
> > * Abstract
> > A subtree of a directory tree T is a tree consisting of a directory
> > (the subtree root) in T and all of its descendants in T.
> >
> > *NOTE*: User is allowed to break pure subtree hierarchy via manual
> > id manipulation.
> >
> > Project subtrees assumptions:
> > (1) Each inode has an id. This id is persistently stored inside
> > inode (xattr, usually inside ibody)
> > (2) Project id is inherent from parent directory
>
Very very sorry for a long replay,
> You are mashing two different concepts into one, and naming it in a
> manner guaranteed to create confusion with all the people already
> using project quotas on XFS. You're implementing subtree quotas, not
> project quotas.
Actually this was already discussed, Initially i've called it as
subtree-id will strict tree behavior similar to XFS
1) Subtrees are true ADG
2) Id inherited from a parent
1) No hadrlink allowed across two subtries with different id
2) No cross-tree renames are allowed
But it some people, especially AlViro was not happy about this.
So i've simplify id ideology to simple rule
1) Inherent id from parent
This this is just an third ID similar to UID and GID without any
restrictions, but in case of project-id (or subtree-id) it can not be
inherent from current task because currently there is no way to
understand which container or sub-process group this task belongs to
That's why i've chose simplest and most obvious rule just inherent id
from parent.
As far as i know nor project-id nor subtree-id are not ideal, but you
probably right most people already know that project-id affect
rename/link so i have to change the name to 'subtree-id', or may be 'bundle-id'
>
> > This feature is similar to project-id in XFS. One may assign
> > some id to a subtree. Each entry from the subtree may be
> > accounted in directory project quota. Will appear in later
> > patches.
>
> As implied above, project quotas ID in XFS are not subtree quotas.
> They are used to implement project quotas, not subtree quotas.
> subtree quotas are a userspace management construction using a
> subset of project quota infrastructure. i.e. the inheritance of
> project IDs in XFS and the restriction of operations to within
> subtrees is not a function of project quotas - it's a separately
> managed feature that was added to support the functioanlity needed
> for subtree quotas.
>
> ISTR raising this objection last time you posted this patch set -
> either you implement project quotas as they exist in XFS and handle
> subtree quotas as a constrainted set of project quota functionality
> or you need to drop all references to "project quotas" and call this
> something like sub-tree quotas that uses subtree IDs.
>
> > * Disk layout
> > Project id is stored on disk inside xattr usually inside ibody.
> > Xattr is used only as a data storage, It has not user visible xattr
> > interface.
>
> If you've got enough xattrs on the inode, then it will end up out of
> line and performance is going to suck - every time you write to a
> cold file you now need two IOs - one to read the extent list, and
> one to read the xattrs to get the project ID....
>
> > * User interface
> > Project id is accessible via generic xattr interface "system.project_id"
>
> Which means it is an incompatible with XFS. What purpose does this
> serve except to confuse people? Why not a generic set/get project ID
> quotactl/ioctl? That's much easier for applications to use compared
> to xattrs, and far easier to support different implementations
> across filesystems. The way the project ID is stored in ext4 should
> not define the API.
>
> Indeed, an ioctl/quotactl style interface matches the existing quota
> interface, so it's much more natural to use a similar API to one
> already used for quota manipulation...
>
> > * Notes
> > ext4_setattr interface to prjid: Semantically prjid must being changed
> > similar to uid/gid, but project_id is stored inside xattr so on-disk
> > structures updates is not that trivial, so I've move prjid change
> > logic to separate function.
>
> I suspect that there are corner cases you haven't thought about
> yet. What happens when you hard link a file into two separate
> subtrees? how do you account for that? What happens when you remove
> the hard link from the subtree the inode is accounted to? What
> happens when a rename occurs, moving a file from one subtree to
> another?
As i already noted my implementation does not affect rename/link at all.
But as far as i know most obvious use-case is when will restrict access
to some subtree via bindmout and pass it as a root to some set of tasks (container,cgroup)
Such set of task should not have privileges to change project-id
explicitly (only inheritance are allowed), in that case we will have
pure sub-trees hierarchy.
>
> .....
>
> > +static int
> > +ext4_xattr_prj_set(struct dentry *dentry, const char *name,
> > + const void *value, size_t size, int flags, int type)
> > +{
> > + unsigned int new_prjid;
> > + if (strcmp(name, "") != 0)
> > + return -EINVAL;
> > + new_prjid = simple_strtoul(value, (char **)&value, 0);
> > + return ext4_prj_change(dentry->d_inode, new_prjid);
>
> Because you are using strings rather than integers for the ID, you
> need to do a lot better verification here - what will happen when
> someone tries to set an ID of "frobnozzle"? Using integers via
> ioctls for the user API make this problem....
>
> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@fromorbit.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 5/5] XFS: prjquota and grpqouta now may coexist
2012-06-22 2:36 ` Dave Chinner
@ 2012-07-03 19:14 ` Dmitry Monakhov
0 siblings, 0 replies; 18+ messages in thread
From: Dmitry Monakhov @ 2012-07-03 19:14 UTC (permalink / raw)
To: Dave Chinner; +Cc: linux-ext4, linux-fsdevel
On Fri, 22 Jun 2012 12:36:12 +1000, Dave Chinner <david@fromorbit.com> wrote:
> On Thu, Jun 21, 2012 at 01:08:53PM +0400, Dmitry Monakhov wrote:
> > Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> > ---
> > fs/xfs/xfs_super.c | 6 +++---
> > 1 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 0d9de41..f408a27 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -538,14 +538,14 @@ xfs_showargs(
> > else if (mp->m_qflags & XFS_UQUOTA_ACCT)
> > seq_puts(m, "," MNTOPT_UQUOTANOENF);
> >
> > - /* Either project or group quotas can be active, not both */
> > -
> > if (mp->m_qflags & XFS_PQUOTA_ACCT) {
> > if (mp->m_qflags & XFS_OQUOTA_ENFD)
> > seq_puts(m, "," MNTOPT_PRJQUOTA);
> > else
> > seq_puts(m, "," MNTOPT_PQUOTANOENF);
> > - } else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
> > + }
> > +
> > + if (mp->m_qflags & XFS_GQUOTA_ACCT) {
> > if (mp->m_qflags & XFS_OQUOTA_ENFD)
> > seq_puts(m, "," MNTOPT_GRPQUOTA);
> > else
>
> Why can they co-exist now? XFS does not use the VFS quota
> code, and you've made no other changes to XFS so I can't see how you
> can make that assertion. There's a current patchset under review
> that allows XFS to have co-existing group and project quotas - it's
> complex, changes the on-disk format and requires userspace tool
> support (e.g. mkfs, repair, xfs_db, etc).
>
> So I can't see how this works with XFS at all...
Yes, you right, let's just drop that patch at all.
>
> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@fromorbit.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2012-07-03 19:14 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-21 9:08 [PATCH 0/5] RFC: introduce extended inode owner identifier v9 Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 1/5] Add additional owner identifier Dmitry Monakhov
2012-06-22 0:03 ` Jan Kara
2012-07-03 18:42 ` Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 2/5] Implement project id support for generic quota Dmitry Monakhov
2012-06-22 0:01 ` Jan Kara
2012-06-21 9:08 ` [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem Dmitry Monakhov
2012-06-21 23:51 ` Jan Kara
2012-07-03 18:46 ` Dmitry Monakhov
2012-06-22 3:07 ` Dave Chinner
2012-06-28 10:16 ` Jan Kara
2012-07-03 19:11 ` Dmitry Monakhov
2012-06-21 9:08 ` [PATCH 4/5] ext4: add project quota support Dmitry Monakhov
2012-06-21 23:56 ` Jan Kara
2012-06-21 9:08 ` [PATCH 5/5] XFS: prjquota and grpqouta now may coexist Dmitry Monakhov
2012-06-22 2:36 ` Dave Chinner
2012-07-03 19:14 ` Dmitry Monakhov
-- strict thread matches above, loose matches on Subject: below --
2010-03-18 14:02 [PATCH 0/5] RFC: introduce extended inode owner identifier v6 Dmitry Monakhov
2010-03-18 14:02 ` [PATCH 1/5] vfs: Add additional owner identifier Dmitry Monakhov
2010-03-18 14:02 ` [PATCH 2/5] quota: Implement project id support for generic quota Dmitry Monakhov
2010-03-18 14:02 ` [PATCH 3/5] ext4: Implement project ID support for ext4 filesystem Dmitry Monakhov
2010-03-18 14:02 ` [PATCH 4/5] ext4: add project quota support Dmitry Monakhov
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).