* [PATCH 1/2] quota: reorder flags in quota state
@ 2015-02-12 9:36 Konstantin Khlebnikov
2015-02-12 9:36 ` [PATCH 2/2] quota: merge sb->s_quota_types into sb->s_dquot.flags Konstantin Khlebnikov
2015-02-12 15:05 ` [PATCH 1/2] quota: reorder flags in quota state Jan Kara
0 siblings, 2 replies; 6+ messages in thread
From: Konstantin Khlebnikov @ 2015-02-12 9:36 UTC (permalink / raw)
To: linux-fsdevel, Jan Kara; +Cc: linux-kernel
Flags in struct quota_state keep flags for each quota type and
some common flags. This patch reorders typed flags:
Before:
0 USRQUOTA DQUOT_USAGE_ENABLED
1 USRQUOTA DQUOT_LIMITS_ENABLED
2 USRQUOTA DQUOT_SUSPENDED
3 GRPQUOTA DQUOT_USAGE_ENABLED
4 GRPQUOTA DQUOT_LIMITS_ENABLED
5 GRPQUOTA DQUOT_SUSPENDED
6 DQUOT_QUOTA_SYS_FILE
7 DQUOT_NEGATIVE_USAGE
After:
0 USRQUOTA DQUOT_USAGE_ENABLED
1 GRPQUOTA DQUOT_USAGE_ENABLED
2 USRQUOTA DQUOT_LIMITS_ENABLED
3 GRPQUOTA DQUOT_LIMITS_ENABLED
4 USRQUOTA DQUOT_SUSPENDED
5 GRPQUOTA DQUOT_SUSPENDED
6 DQUOT_QUOTA_SYS_FILE
7 DQUOT_NEGATIVE_USAGE
Now we can get bitmap of all enabled/suspended quota types without loop.
For example suspended: (flags / DQUOT_SUSPENDED) & ((1 << MAXQUOTAS) - 1).
add/remove: 0/1 grow/shrink: 3/11 up/down: 56/-215 (-159)
function old new delta
__dquot_initialize 423 447 +24
dquot_transfer 181 197 +16
dquot_alloc_inode 286 302 +16
dquot_reclaim_space_nodirty 316 313 -3
dquot_claim_space_nodirty 314 311 -3
dquot_resume 286 281 -5
dquot_free_inode 332 324 -8
__dquot_alloc_space 500 492 -8
dquot_disable 1944 1929 -15
dquot_quota_enable 252 236 -16
__dquot_free_space 750 734 -16
dquot_writeback_dquots 625 608 -17
__dquot_transfer 1186 1154 -32
dquot_quota_sync 299 261 -38
dquot_active.isra 54 - -54
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
include/linux/quota.h | 18 ++++++++++++------
include/linux/quotaops.h | 10 ++--------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/include/linux/quota.h b/include/linux/quota.h
index d534e8e..205b4f7 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -398,9 +398,9 @@ enum {
* memory to turn them on */
_DQUOT_STATE_FLAGS
};
-#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED)
-#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED)
-#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED)
+#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED * MAXQUOTAS)
+#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED * MAXQUOTAS)
+#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED * MAXQUOTAS)
#define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
DQUOT_SUSPENDED)
/* Other quota flags */
@@ -414,15 +414,21 @@ enum {
*/
#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)
{
- return flags << _DQUOT_STATE_FLAGS * type;
+ return flags << type;
}
static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
{
- return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS;
+ return (flags >> type) & DQUOT_STATE_FLAGS;
+}
+
+/* Bitmap of quota types where flag is set in flags */
+static __always_inline unsigned dquot_state_types(unsigned flags, unsigned flag)
+{
+ BUILD_BUG_ON_NOT_POWER_OF_2(flag);
+ return (flags / flag) & ((1 << MAXQUOTAS) - 1);
}
#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index df73258..8778ec4 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -134,10 +134,7 @@ static inline bool sb_has_quota_suspended(struct super_block *sb, int type)
static inline unsigned sb_any_quota_suspended(struct super_block *sb)
{
- unsigned type, tmsk = 0;
- for (type = 0; type < MAXQUOTAS; type++)
- tmsk |= sb_has_quota_suspended(sb, type) << type;
- return tmsk;
+ return dquot_state_types(sb_dqopt(sb)->flags, DQUOT_SUSPENDED);
}
/* Does kernel know about any quota information for given sb + type? */
@@ -149,10 +146,7 @@ static inline bool sb_has_quota_loaded(struct super_block *sb, int type)
static inline unsigned sb_any_quota_loaded(struct super_block *sb)
{
- unsigned type, tmsk = 0;
- for (type = 0; type < MAXQUOTAS; type++)
- tmsk |= sb_has_quota_loaded(sb, type) << type;
- return tmsk;
+ return dquot_state_types(sb_dqopt(sb)->flags, DQUOT_USAGE_ENABLED);
}
static inline bool sb_has_quota_active(struct super_block *sb, int type)
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] quota: merge sb->s_quota_types into sb->s_dquot.flags
2015-02-12 9:36 [PATCH 1/2] quota: reorder flags in quota state Konstantin Khlebnikov
@ 2015-02-12 9:36 ` Konstantin Khlebnikov
2015-02-12 15:13 ` Jan Kara
2015-02-12 15:05 ` [PATCH 1/2] quota: reorder flags in quota state Jan Kara
1 sibling, 1 reply; 6+ messages in thread
From: Konstantin Khlebnikov @ 2015-02-12 9:36 UTC (permalink / raw)
To: linux-fsdevel, Jan Kara; +Cc: linux-kernel
This patch converts supported quota types bitmask (sb->s_quota_types)
into per-type flag DQUOT_SUPPORTED in sb->s_dquot.flags.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
fs/ext2/super.c | 3 ++-
fs/ext3/super.c | 3 ++-
fs/ext4/super.c | 3 ++-
fs/gfs2/ops_fstype.c | 3 ++-
fs/jfs/super.c | 3 ++-
fs/ocfs2/super.c | 3 ++-
fs/quota/quota.c | 6 +++---
fs/reiserfs/super.c | 3 ++-
fs/xfs/xfs_super.c | 5 ++++-
include/linux/fs.h | 1 -
include/linux/quota.h | 4 +++-
include/linux/quotaops.h | 10 ++++++++++
12 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index ae55fdd..9e2b1c3 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1099,7 +1099,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
#ifdef CONFIG_QUOTA
sb->dq_op = &dquot_operations;
sb->s_qcop = &dquot_quotactl_ops;
- sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
#endif
root = ext2_iget(sb, EXT2_ROOT_INO);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index d4dbf3c..fc71d08 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2012,7 +2012,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
#ifdef CONFIG_QUOTA
sb->s_qcop = &ext3_qctl_operations;
sb->dq_op = &ext3_quota_operations;
- sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
#endif
memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ac64edb..e36d73c 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3925,7 +3925,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sb->s_qcop = &dquot_quotactl_sysfile_ops;
else
sb->s_qcop = &ext4_qctl_operations;
- sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
#endif
memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 8633ad3..3e8f590 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1074,7 +1074,8 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
sb->s_export_op = &gfs2_export_ops;
sb->s_xattr = gfs2_xattr_handlers;
sb->s_qcop = &gfs2_quotactl_ops;
- sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
sb->s_time_gran = 1;
sb->s_maxbytes = MAX_LFS_FILESIZE;
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 16c3a95..b820b76 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -540,7 +540,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
#ifdef CONFIG_QUOTA
sb->dq_op = &dquot_operations;
sb->s_qcop = &dquot_quotactl_ops;
- sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
#endif
/*
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 87a1f76..1db5903 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -2059,7 +2059,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
sb->s_export_op = &ocfs2_export_ops;
sb->s_qcop = &dquot_quotactl_sysfile_ops;
sb->dq_op = &ocfs2_quota_operations;
- sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
sb->s_xattr = ocfs2_xattr_handlers;
sb->s_time_gran = 1;
sb->s_flags |= MS_NOATIME;
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index d14a799..28d54bc 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -50,7 +50,7 @@ static void quota_sync_one(struct super_block *sb, void *arg)
int type = *(int *)arg;
if (sb->s_qcop && sb->s_qcop->quota_sync &&
- (sb->s_quota_types & (1 << type)))
+ sb_has_quota_supported(sb, type))
sb->s_qcop->quota_sync(sb, type);
}
@@ -446,12 +446,12 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
return -EINVAL;
/*
- * Quota not supported on this fs? Check this before s_quota_types
+ * Quota not supported on this fs? Check this before sb_dqopt flags
* since they needn't be set if quota is not supported at all.
*/
if (!sb->s_qcop)
return -ENOSYS;
- if (!(sb->s_quota_types & (1 << type)))
+ if (!sb_has_quota_supported(sb, type))
return -EINVAL;
ret = check_quotactl_permission(sb, type, cmd, id);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 71fbbe3..f08740f 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1643,7 +1643,8 @@ static int read_super_block(struct super_block *s, int offset)
#ifdef CONFIG_QUOTA
s->s_qcop = &reiserfs_qctl_operations;
s->dq_op = &reiserfs_quota_operations;
- s->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
#endif
/*
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index f2449fd..f8806c89 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -55,6 +55,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/parser.h>
+#include <linux/quotaops.h>
static const struct super_operations xfs_super_operations;
static kmem_zone_t *xfs_ioend_zone;
@@ -1434,7 +1435,9 @@ xfs_fs_fill_super(
sb->s_export_op = &xfs_export_operations;
#ifdef CONFIG_XFS_QUOTA
sb->s_qcop = &xfs_quotactl_operations;
- sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
+ sb_set_quota_supported(sb, USRQUOTA);
+ sb_set_quota_supported(sb, GRPQUOTA);
+ sb_set_quota_supported(sb, PRJQUOTA);
#endif
sb->s_op = &xfs_super_operations;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f125b88..e1d19b6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1257,7 +1257,6 @@ struct super_block {
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
- unsigned int s_quota_types; /* Bitmask of supported quota types */
struct quota_info s_dquot; /* Diskquota specific options */
struct sb_writers s_writers;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 205b4f7..3c6cc80 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -391,13 +391,15 @@ struct quota_format_type {
/* Quota state flags - they actually come in two flavors - for users and groups */
enum {
- _DQUOT_USAGE_ENABLED = 0, /* Track disk usage for users */
+ _DQUOT_SUPPORTED = 0, /* Quota type supported by fs */
+ _DQUOT_USAGE_ENABLED, /* Track disk usage for users */
_DQUOT_LIMITS_ENABLED, /* Enforce quota limits for users */
_DQUOT_SUSPENDED, /* User diskquotas are off, but
* we have necessary info in
* memory to turn them on */
_DQUOT_STATE_FLAGS
};
+#define DQUOT_SUPPORTED (1 << _DQUOT_SUPPORTED * MAXQUOTAS)
#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED * MAXQUOTAS)
#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED * MAXQUOTAS)
#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED * MAXQUOTAS)
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 8778ec4..e431a87 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -110,10 +110,20 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
return sb_dqopt(sb)->info + type;
}
+static inline void sb_set_quota_supported(struct super_block *sb, unsigned type)
+{
+ sb_dqopt(sb)->flags |= dquot_state_flag(DQUOT_SUPPORTED, type);
+}
+
/*
* Functions for checking status of quota
*/
+static inline bool sb_has_quota_supported(struct super_block *sb, unsigned type)
+{
+ return sb_dqopt(sb)->flags & dquot_state_flag(DQUOT_SUPPORTED, type);
+}
+
static inline bool sb_has_quota_usage_enabled(struct super_block *sb, int type)
{
return sb_dqopt(sb)->flags &
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] quota: reorder flags in quota state
2015-02-12 9:36 [PATCH 1/2] quota: reorder flags in quota state Konstantin Khlebnikov
2015-02-12 9:36 ` [PATCH 2/2] quota: merge sb->s_quota_types into sb->s_dquot.flags Konstantin Khlebnikov
@ 2015-02-12 15:05 ` Jan Kara
2015-02-12 15:46 ` Konstantin Khlebnikov
1 sibling, 1 reply; 6+ messages in thread
From: Jan Kara @ 2015-02-12 15:05 UTC (permalink / raw)
To: Konstantin Khlebnikov; +Cc: linux-fsdevel, Jan Kara, linux-kernel
On Thu 12-02-15 12:36:44, Konstantin Khlebnikov wrote:
> Flags in struct quota_state keep flags for each quota type and
> some common flags. This patch reorders typed flags:
>
> Before:
>
> 0 USRQUOTA DQUOT_USAGE_ENABLED
> 1 USRQUOTA DQUOT_LIMITS_ENABLED
> 2 USRQUOTA DQUOT_SUSPENDED
> 3 GRPQUOTA DQUOT_USAGE_ENABLED
> 4 GRPQUOTA DQUOT_LIMITS_ENABLED
> 5 GRPQUOTA DQUOT_SUSPENDED
> 6 DQUOT_QUOTA_SYS_FILE
> 7 DQUOT_NEGATIVE_USAGE
>
> After:
>
> 0 USRQUOTA DQUOT_USAGE_ENABLED
> 1 GRPQUOTA DQUOT_USAGE_ENABLED
> 2 USRQUOTA DQUOT_LIMITS_ENABLED
> 3 GRPQUOTA DQUOT_LIMITS_ENABLED
> 4 USRQUOTA DQUOT_SUSPENDED
> 5 GRPQUOTA DQUOT_SUSPENDED
> 6 DQUOT_QUOTA_SYS_FILE
> 7 DQUOT_NEGATIVE_USAGE
>
> Now we can get bitmap of all enabled/suspended quota types without loop.
> For example suspended: (flags / DQUOT_SUSPENDED) & ((1 << MAXQUOTAS) - 1).
>
> add/remove: 0/1 grow/shrink: 3/11 up/down: 56/-215 (-159)
> function old new delta
> __dquot_initialize 423 447 +24
> dquot_transfer 181 197 +16
> dquot_alloc_inode 286 302 +16
> dquot_reclaim_space_nodirty 316 313 -3
> dquot_claim_space_nodirty 314 311 -3
> dquot_resume 286 281 -5
> dquot_free_inode 332 324 -8
> __dquot_alloc_space 500 492 -8
> dquot_disable 1944 1929 -15
> dquot_quota_enable 252 236 -16
> __dquot_free_space 750 734 -16
> dquot_writeback_dquots 625 608 -17
> __dquot_transfer 1186 1154 -32
> dquot_quota_sync 299 261 -38
> dquot_active.isra 54 - -54
Two minor comments below. Otherwise the patch looks good.
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> ---
> include/linux/quota.h | 18 ++++++++++++------
> include/linux/quotaops.h | 10 ++--------
> 2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/include/linux/quota.h b/include/linux/quota.h
> index d534e8e..205b4f7 100644
> --- a/include/linux/quota.h
> +++ b/include/linux/quota.h
> @@ -398,9 +398,9 @@ enum {
> * memory to turn them on */
> _DQUOT_STATE_FLAGS
> };
Please explain how the flags are exactly laid out in a comment in
include/linux/quota.h at the enum definition above.
> -#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED)
> -#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED)
> -#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED)
> +#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED * MAXQUOTAS)
> +#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED * MAXQUOTAS)
> +#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED * MAXQUOTAS)
> #define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
> DQUOT_SUSPENDED)
> /* Other quota flags */
> @@ -414,15 +414,21 @@ enum {
> */
> #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)
> {
> - return flags << _DQUOT_STATE_FLAGS * type;
> + return flags << type;
> }
>
> static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
> {
> - return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS;
> + return (flags >> type) & DQUOT_STATE_FLAGS;
> +}
> +
> +/* Bitmap of quota types where flag is set in flags */
> +static __always_inline unsigned dquot_state_types(unsigned flags, unsigned flag)
Why do you have __always_inline here? Just use inline if the function
works standalone (which seems to be the case here).
> +{
> + BUILD_BUG_ON_NOT_POWER_OF_2(flag);
> + return (flags / flag) & ((1 << MAXQUOTAS) - 1);
> }
>
> #ifdef CONFIG_QUOTA_NETLINK_INTERFACE
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] quota: merge sb->s_quota_types into sb->s_dquot.flags
2015-02-12 9:36 ` [PATCH 2/2] quota: merge sb->s_quota_types into sb->s_dquot.flags Konstantin Khlebnikov
@ 2015-02-12 15:13 ` Jan Kara
2015-02-12 15:40 ` Konstantin Khlebnikov
0 siblings, 1 reply; 6+ messages in thread
From: Jan Kara @ 2015-02-12 15:13 UTC (permalink / raw)
To: Konstantin Khlebnikov; +Cc: linux-fsdevel, Jan Kara, linux-kernel
On Thu 12-02-15 12:36:45, Konstantin Khlebnikov wrote:
> This patch converts supported quota types bitmask (sb->s_quota_types)
> into per-type flag DQUOT_SUPPORTED in sb->s_dquot.flags.
I had something like this previously (although your patch is nicer) but
Christoph objected that filesystems not using VFS quotas (XFS, GFS2) don't
touch sb->s_dquot at all and this would make them use it. So I used a
special field in the superblock instead.
Honza
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> ---
> fs/ext2/super.c | 3 ++-
> fs/ext3/super.c | 3 ++-
> fs/ext4/super.c | 3 ++-
> fs/gfs2/ops_fstype.c | 3 ++-
> fs/jfs/super.c | 3 ++-
> fs/ocfs2/super.c | 3 ++-
> fs/quota/quota.c | 6 +++---
> fs/reiserfs/super.c | 3 ++-
> fs/xfs/xfs_super.c | 5 ++++-
> include/linux/fs.h | 1 -
> include/linux/quota.h | 4 +++-
> include/linux/quotaops.h | 10 ++++++++++
> 12 files changed, 34 insertions(+), 13 deletions(-)
>
> diff --git a/fs/ext2/super.c b/fs/ext2/super.c
> index ae55fdd..9e2b1c3 100644
> --- a/fs/ext2/super.c
> +++ b/fs/ext2/super.c
> @@ -1099,7 +1099,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
> #ifdef CONFIG_QUOTA
> sb->dq_op = &dquot_operations;
> sb->s_qcop = &dquot_quotactl_ops;
> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> #endif
>
> root = ext2_iget(sb, EXT2_ROOT_INO);
> diff --git a/fs/ext3/super.c b/fs/ext3/super.c
> index d4dbf3c..fc71d08 100644
> --- a/fs/ext3/super.c
> +++ b/fs/ext3/super.c
> @@ -2012,7 +2012,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
> #ifdef CONFIG_QUOTA
> sb->s_qcop = &ext3_qctl_operations;
> sb->dq_op = &ext3_quota_operations;
> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> #endif
> memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
> INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index ac64edb..e36d73c 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -3925,7 +3925,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
> sb->s_qcop = &dquot_quotactl_sysfile_ops;
> else
> sb->s_qcop = &ext4_qctl_operations;
> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> #endif
> memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
>
> diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
> index 8633ad3..3e8f590 100644
> --- a/fs/gfs2/ops_fstype.c
> +++ b/fs/gfs2/ops_fstype.c
> @@ -1074,7 +1074,8 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
> sb->s_export_op = &gfs2_export_ops;
> sb->s_xattr = gfs2_xattr_handlers;
> sb->s_qcop = &gfs2_quotactl_ops;
> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
> sb->s_time_gran = 1;
> sb->s_maxbytes = MAX_LFS_FILESIZE;
> diff --git a/fs/jfs/super.c b/fs/jfs/super.c
> index 16c3a95..b820b76 100644
> --- a/fs/jfs/super.c
> +++ b/fs/jfs/super.c
> @@ -540,7 +540,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
> #ifdef CONFIG_QUOTA
> sb->dq_op = &dquot_operations;
> sb->s_qcop = &dquot_quotactl_ops;
> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> #endif
>
> /*
> diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
> index 87a1f76..1db5903 100644
> --- a/fs/ocfs2/super.c
> +++ b/fs/ocfs2/super.c
> @@ -2059,7 +2059,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
> sb->s_export_op = &ocfs2_export_ops;
> sb->s_qcop = &dquot_quotactl_sysfile_ops;
> sb->dq_op = &ocfs2_quota_operations;
> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> sb->s_xattr = ocfs2_xattr_handlers;
> sb->s_time_gran = 1;
> sb->s_flags |= MS_NOATIME;
> diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> index d14a799..28d54bc 100644
> --- a/fs/quota/quota.c
> +++ b/fs/quota/quota.c
> @@ -50,7 +50,7 @@ static void quota_sync_one(struct super_block *sb, void *arg)
> int type = *(int *)arg;
>
> if (sb->s_qcop && sb->s_qcop->quota_sync &&
> - (sb->s_quota_types & (1 << type)))
> + sb_has_quota_supported(sb, type))
> sb->s_qcop->quota_sync(sb, type);
> }
>
> @@ -446,12 +446,12 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
> if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
> return -EINVAL;
> /*
> - * Quota not supported on this fs? Check this before s_quota_types
> + * Quota not supported on this fs? Check this before sb_dqopt flags
> * since they needn't be set if quota is not supported at all.
> */
> if (!sb->s_qcop)
> return -ENOSYS;
> - if (!(sb->s_quota_types & (1 << type)))
> + if (!sb_has_quota_supported(sb, type))
> return -EINVAL;
>
> ret = check_quotactl_permission(sb, type, cmd, id);
> diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
> index 71fbbe3..f08740f 100644
> --- a/fs/reiserfs/super.c
> +++ b/fs/reiserfs/super.c
> @@ -1643,7 +1643,8 @@ static int read_super_block(struct super_block *s, int offset)
> #ifdef CONFIG_QUOTA
> s->s_qcop = &reiserfs_qctl_operations;
> s->dq_op = &reiserfs_quota_operations;
> - s->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> #endif
>
> /*
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index f2449fd..f8806c89 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -55,6 +55,7 @@
> #include <linux/kthread.h>
> #include <linux/freezer.h>
> #include <linux/parser.h>
> +#include <linux/quotaops.h>
>
> static const struct super_operations xfs_super_operations;
> static kmem_zone_t *xfs_ioend_zone;
> @@ -1434,7 +1435,9 @@ xfs_fs_fill_super(
> sb->s_export_op = &xfs_export_operations;
> #ifdef CONFIG_XFS_QUOTA
> sb->s_qcop = &xfs_quotactl_operations;
> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
> + sb_set_quota_supported(sb, USRQUOTA);
> + sb_set_quota_supported(sb, GRPQUOTA);
> + sb_set_quota_supported(sb, PRJQUOTA);
> #endif
> sb->s_op = &xfs_super_operations;
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index f125b88..e1d19b6 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1257,7 +1257,6 @@ struct super_block {
> struct backing_dev_info *s_bdi;
> struct mtd_info *s_mtd;
> struct hlist_node s_instances;
> - unsigned int s_quota_types; /* Bitmask of supported quota types */
> struct quota_info s_dquot; /* Diskquota specific options */
>
> struct sb_writers s_writers;
> diff --git a/include/linux/quota.h b/include/linux/quota.h
> index 205b4f7..3c6cc80 100644
> --- a/include/linux/quota.h
> +++ b/include/linux/quota.h
> @@ -391,13 +391,15 @@ struct quota_format_type {
>
> /* Quota state flags - they actually come in two flavors - for users and groups */
> enum {
> - _DQUOT_USAGE_ENABLED = 0, /* Track disk usage for users */
> + _DQUOT_SUPPORTED = 0, /* Quota type supported by fs */
> + _DQUOT_USAGE_ENABLED, /* Track disk usage for users */
> _DQUOT_LIMITS_ENABLED, /* Enforce quota limits for users */
> _DQUOT_SUSPENDED, /* User diskquotas are off, but
> * we have necessary info in
> * memory to turn them on */
> _DQUOT_STATE_FLAGS
> };
> +#define DQUOT_SUPPORTED (1 << _DQUOT_SUPPORTED * MAXQUOTAS)
> #define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED * MAXQUOTAS)
> #define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED * MAXQUOTAS)
> #define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED * MAXQUOTAS)
> diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
> index 8778ec4..e431a87 100644
> --- a/include/linux/quotaops.h
> +++ b/include/linux/quotaops.h
> @@ -110,10 +110,20 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
> return sb_dqopt(sb)->info + type;
> }
>
> +static inline void sb_set_quota_supported(struct super_block *sb, unsigned type)
> +{
> + sb_dqopt(sb)->flags |= dquot_state_flag(DQUOT_SUPPORTED, type);
> +}
> +
> /*
> * Functions for checking status of quota
> */
>
> +static inline bool sb_has_quota_supported(struct super_block *sb, unsigned type)
> +{
> + return sb_dqopt(sb)->flags & dquot_state_flag(DQUOT_SUPPORTED, type);
> +}
> +
> static inline bool sb_has_quota_usage_enabled(struct super_block *sb, int type)
> {
> return sb_dqopt(sb)->flags &
>
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] quota: merge sb->s_quota_types into sb->s_dquot.flags
2015-02-12 15:13 ` Jan Kara
@ 2015-02-12 15:40 ` Konstantin Khlebnikov
0 siblings, 0 replies; 6+ messages in thread
From: Konstantin Khlebnikov @ 2015-02-12 15:40 UTC (permalink / raw)
To: Jan Kara; +Cc: linux-fsdevel, linux-kernel
On 12.02.2015 18:13, Jan Kara wrote:
> On Thu 12-02-15 12:36:45, Konstantin Khlebnikov wrote:
>> This patch converts supported quota types bitmask (sb->s_quota_types)
>> into per-type flag DQUOT_SUPPORTED in sb->s_dquot.flags.
> I had something like this previously (although your patch is nicer) but
> Christoph objected that filesystems not using VFS quotas (XFS, GFS2) don't
> touch sb->s_dquot at all and this would make them use it. So I used a
> special field in the superblock instead.
Ok. This makes sense.
>
> Honza
>
>> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
>> ---
>> fs/ext2/super.c | 3 ++-
>> fs/ext3/super.c | 3 ++-
>> fs/ext4/super.c | 3 ++-
>> fs/gfs2/ops_fstype.c | 3 ++-
>> fs/jfs/super.c | 3 ++-
>> fs/ocfs2/super.c | 3 ++-
>> fs/quota/quota.c | 6 +++---
>> fs/reiserfs/super.c | 3 ++-
>> fs/xfs/xfs_super.c | 5 ++++-
>> include/linux/fs.h | 1 -
>> include/linux/quota.h | 4 +++-
>> include/linux/quotaops.h | 10 ++++++++++
>> 12 files changed, 34 insertions(+), 13 deletions(-)
>>
>> diff --git a/fs/ext2/super.c b/fs/ext2/super.c
>> index ae55fdd..9e2b1c3 100644
>> --- a/fs/ext2/super.c
>> +++ b/fs/ext2/super.c
>> @@ -1099,7 +1099,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
>> #ifdef CONFIG_QUOTA
>> sb->dq_op = &dquot_operations;
>> sb->s_qcop = &dquot_quotactl_ops;
>> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> #endif
>>
>> root = ext2_iget(sb, EXT2_ROOT_INO);
>> diff --git a/fs/ext3/super.c b/fs/ext3/super.c
>> index d4dbf3c..fc71d08 100644
>> --- a/fs/ext3/super.c
>> +++ b/fs/ext3/super.c
>> @@ -2012,7 +2012,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
>> #ifdef CONFIG_QUOTA
>> sb->s_qcop = &ext3_qctl_operations;
>> sb->dq_op = &ext3_quota_operations;
>> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> #endif
>> memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
>> INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
>> index ac64edb..e36d73c 100644
>> --- a/fs/ext4/super.c
>> +++ b/fs/ext4/super.c
>> @@ -3925,7 +3925,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
>> sb->s_qcop = &dquot_quotactl_sysfile_ops;
>> else
>> sb->s_qcop = &ext4_qctl_operations;
>> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> #endif
>> memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
>>
>> diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
>> index 8633ad3..3e8f590 100644
>> --- a/fs/gfs2/ops_fstype.c
>> +++ b/fs/gfs2/ops_fstype.c
>> @@ -1074,7 +1074,8 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
>> sb->s_export_op = &gfs2_export_ops;
>> sb->s_xattr = gfs2_xattr_handlers;
>> sb->s_qcop = &gfs2_quotactl_ops;
>> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
>> sb->s_time_gran = 1;
>> sb->s_maxbytes = MAX_LFS_FILESIZE;
>> diff --git a/fs/jfs/super.c b/fs/jfs/super.c
>> index 16c3a95..b820b76 100644
>> --- a/fs/jfs/super.c
>> +++ b/fs/jfs/super.c
>> @@ -540,7 +540,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
>> #ifdef CONFIG_QUOTA
>> sb->dq_op = &dquot_operations;
>> sb->s_qcop = &dquot_quotactl_ops;
>> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> #endif
>>
>> /*
>> diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
>> index 87a1f76..1db5903 100644
>> --- a/fs/ocfs2/super.c
>> +++ b/fs/ocfs2/super.c
>> @@ -2059,7 +2059,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
>> sb->s_export_op = &ocfs2_export_ops;
>> sb->s_qcop = &dquot_quotactl_sysfile_ops;
>> sb->dq_op = &ocfs2_quota_operations;
>> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> sb->s_xattr = ocfs2_xattr_handlers;
>> sb->s_time_gran = 1;
>> sb->s_flags |= MS_NOATIME;
>> diff --git a/fs/quota/quota.c b/fs/quota/quota.c
>> index d14a799..28d54bc 100644
>> --- a/fs/quota/quota.c
>> +++ b/fs/quota/quota.c
>> @@ -50,7 +50,7 @@ static void quota_sync_one(struct super_block *sb, void *arg)
>> int type = *(int *)arg;
>>
>> if (sb->s_qcop && sb->s_qcop->quota_sync &&
>> - (sb->s_quota_types & (1 << type)))
>> + sb_has_quota_supported(sb, type))
>> sb->s_qcop->quota_sync(sb, type);
>> }
>>
>> @@ -446,12 +446,12 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
>> if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
>> return -EINVAL;
>> /*
>> - * Quota not supported on this fs? Check this before s_quota_types
>> + * Quota not supported on this fs? Check this before sb_dqopt flags
>> * since they needn't be set if quota is not supported at all.
>> */
>> if (!sb->s_qcop)
>> return -ENOSYS;
>> - if (!(sb->s_quota_types & (1 << type)))
>> + if (!sb_has_quota_supported(sb, type))
>> return -EINVAL;
>>
>> ret = check_quotactl_permission(sb, type, cmd, id);
>> diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
>> index 71fbbe3..f08740f 100644
>> --- a/fs/reiserfs/super.c
>> +++ b/fs/reiserfs/super.c
>> @@ -1643,7 +1643,8 @@ static int read_super_block(struct super_block *s, int offset)
>> #ifdef CONFIG_QUOTA
>> s->s_qcop = &reiserfs_qctl_operations;
>> s->dq_op = &reiserfs_quota_operations;
>> - s->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> #endif
>>
>> /*
>> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
>> index f2449fd..f8806c89 100644
>> --- a/fs/xfs/xfs_super.c
>> +++ b/fs/xfs/xfs_super.c
>> @@ -55,6 +55,7 @@
>> #include <linux/kthread.h>
>> #include <linux/freezer.h>
>> #include <linux/parser.h>
>> +#include <linux/quotaops.h>
>>
>> static const struct super_operations xfs_super_operations;
>> static kmem_zone_t *xfs_ioend_zone;
>> @@ -1434,7 +1435,9 @@ xfs_fs_fill_super(
>> sb->s_export_op = &xfs_export_operations;
>> #ifdef CONFIG_XFS_QUOTA
>> sb->s_qcop = &xfs_quotactl_operations;
>> - sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP | QTYPE_MASK_PRJ;
>> + sb_set_quota_supported(sb, USRQUOTA);
>> + sb_set_quota_supported(sb, GRPQUOTA);
>> + sb_set_quota_supported(sb, PRJQUOTA);
>> #endif
>> sb->s_op = &xfs_super_operations;
>>
>> diff --git a/include/linux/fs.h b/include/linux/fs.h
>> index f125b88..e1d19b6 100644
>> --- a/include/linux/fs.h
>> +++ b/include/linux/fs.h
>> @@ -1257,7 +1257,6 @@ struct super_block {
>> struct backing_dev_info *s_bdi;
>> struct mtd_info *s_mtd;
>> struct hlist_node s_instances;
>> - unsigned int s_quota_types; /* Bitmask of supported quota types */
>> struct quota_info s_dquot; /* Diskquota specific options */
>>
>> struct sb_writers s_writers;
>> diff --git a/include/linux/quota.h b/include/linux/quota.h
>> index 205b4f7..3c6cc80 100644
>> --- a/include/linux/quota.h
>> +++ b/include/linux/quota.h
>> @@ -391,13 +391,15 @@ struct quota_format_type {
>>
>> /* Quota state flags - they actually come in two flavors - for users and groups */
>> enum {
>> - _DQUOT_USAGE_ENABLED = 0, /* Track disk usage for users */
>> + _DQUOT_SUPPORTED = 0, /* Quota type supported by fs */
>> + _DQUOT_USAGE_ENABLED, /* Track disk usage for users */
>> _DQUOT_LIMITS_ENABLED, /* Enforce quota limits for users */
>> _DQUOT_SUSPENDED, /* User diskquotas are off, but
>> * we have necessary info in
>> * memory to turn them on */
>> _DQUOT_STATE_FLAGS
>> };
>> +#define DQUOT_SUPPORTED (1 << _DQUOT_SUPPORTED * MAXQUOTAS)
>> #define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED * MAXQUOTAS)
>> #define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED * MAXQUOTAS)
>> #define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED * MAXQUOTAS)
>> diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
>> index 8778ec4..e431a87 100644
>> --- a/include/linux/quotaops.h
>> +++ b/include/linux/quotaops.h
>> @@ -110,10 +110,20 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
>> return sb_dqopt(sb)->info + type;
>> }
>>
>> +static inline void sb_set_quota_supported(struct super_block *sb, unsigned type)
>> +{
>> + sb_dqopt(sb)->flags |= dquot_state_flag(DQUOT_SUPPORTED, type);
>> +}
>> +
>> /*
>> * Functions for checking status of quota
>> */
>>
>> +static inline bool sb_has_quota_supported(struct super_block *sb, unsigned type)
>> +{
>> + return sb_dqopt(sb)->flags & dquot_state_flag(DQUOT_SUPPORTED, type);
>> +}
>> +
>> static inline bool sb_has_quota_usage_enabled(struct super_block *sb, int type)
>> {
>> return sb_dqopt(sb)->flags &
>>
--
Konstantin
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] quota: reorder flags in quota state
2015-02-12 15:05 ` [PATCH 1/2] quota: reorder flags in quota state Jan Kara
@ 2015-02-12 15:46 ` Konstantin Khlebnikov
0 siblings, 0 replies; 6+ messages in thread
From: Konstantin Khlebnikov @ 2015-02-12 15:46 UTC (permalink / raw)
To: Jan Kara; +Cc: linux-fsdevel, linux-kernel
On 12.02.2015 18:05, Jan Kara wrote:
> On Thu 12-02-15 12:36:44, Konstantin Khlebnikov wrote:
>> Flags in struct quota_state keep flags for each quota type and
>> some common flags. This patch reorders typed flags:
>>
>> Before:
>>
>> 0 USRQUOTA DQUOT_USAGE_ENABLED
>> 1 USRQUOTA DQUOT_LIMITS_ENABLED
>> 2 USRQUOTA DQUOT_SUSPENDED
>> 3 GRPQUOTA DQUOT_USAGE_ENABLED
>> 4 GRPQUOTA DQUOT_LIMITS_ENABLED
>> 5 GRPQUOTA DQUOT_SUSPENDED
>> 6 DQUOT_QUOTA_SYS_FILE
>> 7 DQUOT_NEGATIVE_USAGE
>>
>> After:
>>
>> 0 USRQUOTA DQUOT_USAGE_ENABLED
>> 1 GRPQUOTA DQUOT_USAGE_ENABLED
>> 2 USRQUOTA DQUOT_LIMITS_ENABLED
>> 3 GRPQUOTA DQUOT_LIMITS_ENABLED
>> 4 USRQUOTA DQUOT_SUSPENDED
>> 5 GRPQUOTA DQUOT_SUSPENDED
>> 6 DQUOT_QUOTA_SYS_FILE
>> 7 DQUOT_NEGATIVE_USAGE
>>
>> Now we can get bitmap of all enabled/suspended quota types without loop.
>> For example suspended: (flags / DQUOT_SUSPENDED) & ((1 << MAXQUOTAS) - 1).
>>
>> add/remove: 0/1 grow/shrink: 3/11 up/down: 56/-215 (-159)
>> function old new delta
>> __dquot_initialize 423 447 +24
>> dquot_transfer 181 197 +16
>> dquot_alloc_inode 286 302 +16
>> dquot_reclaim_space_nodirty 316 313 -3
>> dquot_claim_space_nodirty 314 311 -3
>> dquot_resume 286 281 -5
>> dquot_free_inode 332 324 -8
>> __dquot_alloc_space 500 492 -8
>> dquot_disable 1944 1929 -15
>> dquot_quota_enable 252 236 -16
>> __dquot_free_space 750 734 -16
>> dquot_writeback_dquots 625 608 -17
>> __dquot_transfer 1186 1154 -32
>> dquot_quota_sync 299 261 -38
>> dquot_active.isra 54 - -54
> Two minor comments below. Otherwise the patch looks good.
>
>> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
>> ---
>> include/linux/quota.h | 18 ++++++++++++------
>> include/linux/quotaops.h | 10 ++--------
>> 2 files changed, 14 insertions(+), 14 deletions(-)
>>
>> diff --git a/include/linux/quota.h b/include/linux/quota.h
>> index d534e8e..205b4f7 100644
>> --- a/include/linux/quota.h
>> +++ b/include/linux/quota.h
>> @@ -398,9 +398,9 @@ enum {
>> * memory to turn them on */
>> _DQUOT_STATE_FLAGS
>> };
> Please explain how the flags are exactly laid out in a comment in
> include/linux/quota.h at the enum definition above.
>
>> -#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED)
>> -#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED)
>> -#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED)
>> +#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED * MAXQUOTAS)
>> +#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED * MAXQUOTAS)
>> +#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED * MAXQUOTAS)
>> #define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
>> DQUOT_SUSPENDED)
>> /* Other quota flags */
>> @@ -414,15 +414,21 @@ enum {
>> */
>> #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)
>> {
>> - return flags << _DQUOT_STATE_FLAGS * type;
>> + return flags << type;
>> }
>>
>> static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
>> {
>> - return (flags >> _DQUOT_STATE_FLAGS * type) & DQUOT_STATE_FLAGS;
>> + return (flags >> type) & DQUOT_STATE_FLAGS;
>> +}
>> +
>> +/* Bitmap of quota types where flag is set in flags */
>> +static __always_inline unsigned dquot_state_types(unsigned flags, unsigned flag)
> Why do you have __always_inline here? Just use inline if the function
> works standalone (which seems to be the case here).
It works better if "flag" is constant -- dividing turns into bit shift.
And I'm not sure how BUILD_BUG_ON* work for non-constant expressions.
>
>> +{
>> + BUILD_BUG_ON_NOT_POWER_OF_2(flag);
>> + return (flags / flag) & ((1 << MAXQUOTAS) - 1);
>> }
>>
>> #ifdef CONFIG_QUOTA_NETLINK_INTERFACE
>
> Honza
>
--
Konstantin
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-02-12 15:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-12 9:36 [PATCH 1/2] quota: reorder flags in quota state Konstantin Khlebnikov
2015-02-12 9:36 ` [PATCH 2/2] quota: merge sb->s_quota_types into sb->s_dquot.flags Konstantin Khlebnikov
2015-02-12 15:13 ` Jan Kara
2015-02-12 15:40 ` Konstantin Khlebnikov
2015-02-12 15:05 ` [PATCH 1/2] quota: reorder flags in quota state Jan Kara
2015-02-12 15:46 ` Konstantin Khlebnikov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox