All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jaegeuk Kim via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: Chunhai Guo <guochunhai@vivo.com>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-f2fs-devel@lists.sourceforge.net"
	<linux-f2fs-devel@lists.sourceforge.net>
Subject: Re: [f2fs-dev] [PATCH v4] f2fs: add reserved nodes for privileged users
Date: Tue, 5 Aug 2025 02:38:02 +0000	[thread overview]
Message-ID: <aJFuinsBEdMeRbiN@google.com> (raw)
In-Reply-To: <564db113-d910-4337-9581-ca59128dadc0@vivo.com>

On 07/31, Chunhai Guo wrote:
> 在 7/31/2025 4:46 PM, Chao Yu 写道:
> > On 7/31/25 15:57, Chunhai Guo wrote:
> >> This patch allows privileged users to reserve nodes via the
> >> 'reserve_node' mount option, which is similar to the existing
> >> 'reserve_root' option.
> >>
> >> "-o reserve_node=<N>" means <N> nodes are reserved for privileged
> >> users only.
> >>
> >> Signed-off-by: Chunhai Guo <guochunhai@vivo.com>
> >> ---
> >> v3->v4: Rebase this patch on https://lore.kernel.org/linux-f2fs-devel/20250731060338.1136086-1-chao@kernel.org
> >> v2->v3: Apply Chao's suggestion from v2.
> >> v1->v2: Add two missing handling parts.
> >> v1: https://lore.kernel.org/linux-f2fs-devel/20250729095238.607433-1-guochunhai@vivo.com/
> >> ---
> >>   Documentation/filesystems/f2fs.rst |  9 ++++---
> >>   fs/f2fs/f2fs.h                     | 14 +++++++---
> >>   fs/f2fs/super.c                    | 43 +++++++++++++++++++++++++-----
> >>   3 files changed, 52 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
> >> index 03b1efa6d3b2..95dbcd7ac9a8 100644
> >> --- a/Documentation/filesystems/f2fs.rst
> >> +++ b/Documentation/filesystems/f2fs.rst
> >> @@ -173,9 +173,12 @@ data_flush               Enable data flushing before checkpoint in order to
> >>                       persist data of regular and symlink.
> >>   reserve_root=%d             Support configuring reserved space which is used for
> >>                       allocation from a privileged user with specified uid or
> >> -                     gid, unit: 4KB, the default limit is 0.2% of user blocks.
> >> -resuid=%d            The user ID which may use the reserved blocks.
> >> -resgid=%d            The group ID which may use the reserved blocks.
> >> +                     gid, unit: 4KB, the default limit is 12.5% of user blocks.
> >> +reserve_node=%d              Support configuring reserved nodes which are used for
> >> +                     allocation from a privileged user with specified uid or
> >> +                     gid, the default limit is 12.5% of all nodes.
> >> +resuid=%d            The user ID which may use the reserved blocks and nodes.
> >> +resgid=%d            The group ID which may use the reserved blocks and nodes.
> >>   fault_injection=%d  Enable fault injection in all supported types with
> >>                       specified injection rate.
> >>   fault_type=%d               Support configuring fault injection type, should be
> >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >> index eb372af22edc..b9676ef16246 100644
> >> --- a/fs/f2fs/f2fs.h
> >> +++ b/fs/f2fs/f2fs.h
> >> @@ -131,6 +131,7 @@ extern const char *f2fs_fault_name[FAULT_MAX];
> >>    * string rather than using the MS_LAZYTIME flag, so this must remain.
> >>    */
> >>   #define F2FS_MOUNT_LAZYTIME                0x40000000
> >> +#define F2FS_MOUNT_RESERVE_NODE             0x80000000
> >>
> >>   #define F2FS_OPTION(sbi)   ((sbi)->mount_opt)
> >>   #define clear_opt(sbi, option)     (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
> >> @@ -172,6 +173,7 @@ struct f2fs_rwsem {
> >>   struct f2fs_mount_info {
> >>      unsigned int opt;
> >>      block_t root_reserved_blocks;   /* root reserved blocks */
> >> +    block_t root_reserved_nodes;    /* root reserved nodes */
> >>      kuid_t s_resuid;                /* reserved blocks for uid */
> >>      kgid_t s_resgid;                /* reserved blocks for gid */
> >>      int active_logs;                /* # of active logs */
> >> @@ -2355,7 +2357,7 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs)
> >>      return ofs == XATTR_NODE_OFFSET;
> >>   }
> >>
> >> -static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
> >> +static inline bool __allow_reserved_root(struct f2fs_sb_info *sbi,
> >>                                      struct inode *inode, bool cap)
> >>   {
> >>      if (!inode)
> >> @@ -2380,7 +2382,7 @@ static inline unsigned int get_available_block_count(struct f2fs_sb_info *sbi,
> >>      avail_user_block_count = sbi->user_block_count -
> >>                                      sbi->current_reserved_blocks;
> >>
> >> -    if (test_opt(sbi, RESERVE_ROOT) && !__allow_reserved_blocks(sbi, inode, cap))
> >> +    if (test_opt(sbi, RESERVE_ROOT) && !__allow_reserved_root(sbi, inode, cap))
> >>              avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
> >>
> >>      if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
> >> @@ -2738,7 +2740,7 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
> >>                                      struct inode *inode, bool is_inode)
> >>   {
> >>      block_t valid_block_count;
> >> -    unsigned int valid_node_count;
> >> +    unsigned int valid_node_count, avail_user_node_count;
> >>      unsigned int avail_user_block_count;
> >>      int err;
> >>
> >> @@ -2767,8 +2769,12 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
> >>              goto enospc;
> >>      }
> >>
> >> +    avail_user_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
> >> +    if (test_opt(sbi, RESERVE_NODE) &&
> >> +                    !__allow_reserved_root(sbi, inode, false))
> > Chunhai,
> >
> > Do we need to pass cap=true to __allow_reserved_root()?
> >
> > In addition, do we need to change cap as well for below statement?
> >
> > avail_user_block_count = get_available_block_count(sbi, inode, false);
> 
> 
> Hi Jaegeuk,
> 
> 
> Based on the description in commit a90a0884ac75 ("f2fs: check
> cap_resource only for data blocks"), it seems that inode or node blocks
> don't need to perform a check on the cap_resource. I'm not certain about
> the reasoning behind this. Could you please help to clarify it?

I don't quite remember as I had to fix the selinx issue long long time ago.

> 
> 
> Thanks,
> 
> >
> > Thanks,
> >
> >> +            avail_user_node_count -= F2FS_OPTION(sbi).root_reserved_nodes;
> >>      valid_node_count = sbi->total_valid_node_count + 1;
> >> -    if (unlikely(valid_node_count > sbi->total_node_count)) {
> >> +    if (unlikely(valid_node_count > avail_user_node_count)) {
> >>              spin_unlock(&sbi->stat_lock);
> >>              goto enospc;
> >>      }
> >> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> >> index 30c038413040..a24e855a38ed 100644
> >> --- a/fs/f2fs/super.c
> >> +++ b/fs/f2fs/super.c
> >> @@ -143,6 +143,7 @@ enum {
> >>      Opt_extent_cache,
> >>      Opt_data_flush,
> >>      Opt_reserve_root,
> >> +    Opt_reserve_node,
> >>      Opt_resgid,
> >>      Opt_resuid,
> >>      Opt_mode,
> >> @@ -265,6 +266,7 @@ static const struct fs_parameter_spec f2fs_param_specs[] = {
> >>      fsparam_flag_no("extent_cache", Opt_extent_cache),
> >>      fsparam_flag("data_flush", Opt_data_flush),
> >>      fsparam_u32("reserve_root", Opt_reserve_root),
> >> +    fsparam_u32("reserve_node", Opt_reserve_node),
> >>      fsparam_gid("resgid", Opt_resgid),
> >>      fsparam_uid("resuid", Opt_resuid),
> >>      fsparam_enum("mode", Opt_mode, f2fs_param_mode),
> >> @@ -336,6 +338,7 @@ static match_table_t f2fs_checkpoint_tokens = {
> >>   #define F2FS_SPEC_discard_unit                     (1 << 21)
> >>   #define F2FS_SPEC_memory_mode                      (1 << 22)
> >>   #define F2FS_SPEC_errors                   (1 << 23)
> >> +#define F2FS_SPEC_reserve_node                      (1 << 24)
> >>
> >>   struct f2fs_fs_context {
> >>      struct f2fs_mount_info info;
> >> @@ -437,22 +440,30 @@ static void f2fs_destroy_casefold_cache(void) { }
> >>
> >>   static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
> >>   {
> >> -    block_t limit = min((sbi->user_block_count >> 3),
> >> +    block_t block_limit = min((sbi->user_block_count >> 3),
> >>                      sbi->user_block_count - sbi->reserved_blocks);
> >> +    block_t node_limit = sbi->total_node_count >> 3;
> >>
> >>      /* limit is 12.5% */
> >>      if (test_opt(sbi, RESERVE_ROOT) &&
> >> -                    F2FS_OPTION(sbi).root_reserved_blocks > limit) {
> >> -            F2FS_OPTION(sbi).root_reserved_blocks = limit;
> >> +                    F2FS_OPTION(sbi).root_reserved_blocks > block_limit) {
> >> +            F2FS_OPTION(sbi).root_reserved_blocks = block_limit;
> >>              f2fs_info(sbi, "Reduce reserved blocks for root = %u",
> >>                        F2FS_OPTION(sbi).root_reserved_blocks);
> >>      }
> >> -    if (!test_opt(sbi, RESERVE_ROOT) &&
> >> +    if (test_opt(sbi, RESERVE_NODE) &&
> >> +                    F2FS_OPTION(sbi).root_reserved_nodes > node_limit) {
> >> +            F2FS_OPTION(sbi).root_reserved_nodes = node_limit;
> >> +            f2fs_info(sbi, "Reduce reserved nodes for root = %u",
> >> +                      F2FS_OPTION(sbi).root_reserved_nodes);
> >> +    }
> >> +    if (!test_opt(sbi, RESERVE_ROOT) && !test_opt(sbi, RESERVE_NODE) &&
> >>              (!uid_eq(F2FS_OPTION(sbi).s_resuid,
> >>                              make_kuid(&init_user_ns, F2FS_DEF_RESUID)) ||
> >>              !gid_eq(F2FS_OPTION(sbi).s_resgid,
> >>                              make_kgid(&init_user_ns, F2FS_DEF_RESGID))))
> >> -            f2fs_info(sbi, "Ignore s_resuid=%u, s_resgid=%u w/o reserve_root",
> >> +            f2fs_info(sbi, "Ignore s_resuid=%u, s_resgid=%u w/o reserve_root"
> >> +                            " and reserve_node",
> >>                        from_kuid_munged(&init_user_ns,
> >>                                         F2FS_OPTION(sbi).s_resuid),
> >>                        from_kgid_munged(&init_user_ns,
> >> @@ -841,6 +852,11 @@ static int f2fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
> >>              F2FS_CTX_INFO(ctx).root_reserved_blocks = result.uint_32;
> >>              ctx->spec_mask |= F2FS_SPEC_reserve_root;
> >>              break;
> >> +    case Opt_reserve_node:
> >> +            ctx_set_opt(ctx, F2FS_MOUNT_RESERVE_NODE);
> >> +            F2FS_CTX_INFO(ctx).root_reserved_nodes = result.uint_32;
> >> +            ctx->spec_mask |= F2FS_SPEC_reserve_node;
> >> +            break;
> >>      case Opt_resuid:
> >>              F2FS_CTX_INFO(ctx).s_resuid = result.uid;
> >>              ctx->spec_mask |= F2FS_SPEC_resuid;
> >> @@ -1424,6 +1440,14 @@ static int f2fs_check_opt_consistency(struct fs_context *fc,
> >>              ctx_clear_opt(ctx, F2FS_MOUNT_RESERVE_ROOT);
> >>              ctx->opt_mask &= ~F2FS_MOUNT_RESERVE_ROOT;
> >>      }
> >> +    if (test_opt(sbi, RESERVE_NODE) &&
> >> +                    (ctx->opt_mask & F2FS_MOUNT_RESERVE_NODE) &&
> >> +                    ctx_test_opt(ctx, F2FS_MOUNT_RESERVE_NODE)) {
> >> +            f2fs_info(sbi, "Preserve previous reserve_node=%u",
> >> +                    F2FS_OPTION(sbi).root_reserved_nodes);
> >> +            ctx_clear_opt(ctx, F2FS_MOUNT_RESERVE_NODE);
> >> +            ctx->opt_mask &= ~F2FS_MOUNT_RESERVE_NODE;
> >> +    }
> >>
> >>      err = f2fs_check_test_dummy_encryption(fc, sb);
> >>      if (err)
> >> @@ -1623,6 +1647,9 @@ static void f2fs_apply_options(struct fs_context *fc, struct super_block *sb)
> >>      if (ctx->spec_mask & F2FS_SPEC_reserve_root)
> >>              F2FS_OPTION(sbi).root_reserved_blocks =
> >>                                      F2FS_CTX_INFO(ctx).root_reserved_blocks;
> >> +    if (ctx->spec_mask & F2FS_SPEC_reserve_node)
> >> +            F2FS_OPTION(sbi).root_reserved_nodes =
> >> +                                    F2FS_CTX_INFO(ctx).root_reserved_nodes;
> >>      if (ctx->spec_mask & F2FS_SPEC_resgid)
> >>              F2FS_OPTION(sbi).s_resgid = F2FS_CTX_INFO(ctx).s_resgid;
> >>      if (ctx->spec_mask & F2FS_SPEC_resuid)
> >> @@ -2342,9 +2369,11 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
> >>      else if (F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_BLK)
> >>              seq_puts(seq, "fragment:block");
> >>      seq_printf(seq, ",active_logs=%u", F2FS_OPTION(sbi).active_logs);
> >> -    if (test_opt(sbi, RESERVE_ROOT))
> >> -            seq_printf(seq, ",reserve_root=%u,resuid=%u,resgid=%u",
> >> +    if (test_opt(sbi, RESERVE_ROOT) || test_opt(sbi, RESERVE_NODE))
> >> +            seq_printf(seq, ",reserve_root=%u,reserve_node=%u,resuid=%u,"
> >> +                            "resgid=%u",
> >>                              F2FS_OPTION(sbi).root_reserved_blocks,
> >> +                            F2FS_OPTION(sbi).root_reserved_nodes,
> >>                              from_kuid_munged(&init_user_ns,
> >>                                      F2FS_OPTION(sbi).s_resuid),
> >>                              from_kgid_munged(&init_user_ns,
> 
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

WARNING: multiple messages have this Message-ID (diff)
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Chunhai Guo <guochunhai@vivo.com>
Cc: Chao Yu <chao@kernel.org>,
	"linux-f2fs-devel@lists.sourceforge.net"
	<linux-f2fs-devel@lists.sourceforge.net>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v4] f2fs: add reserved nodes for privileged users
Date: Tue, 5 Aug 2025 02:38:02 +0000	[thread overview]
Message-ID: <aJFuinsBEdMeRbiN@google.com> (raw)
In-Reply-To: <564db113-d910-4337-9581-ca59128dadc0@vivo.com>

On 07/31, Chunhai Guo wrote:
> 在 7/31/2025 4:46 PM, Chao Yu 写道:
> > On 7/31/25 15:57, Chunhai Guo wrote:
> >> This patch allows privileged users to reserve nodes via the
> >> 'reserve_node' mount option, which is similar to the existing
> >> 'reserve_root' option.
> >>
> >> "-o reserve_node=<N>" means <N> nodes are reserved for privileged
> >> users only.
> >>
> >> Signed-off-by: Chunhai Guo <guochunhai@vivo.com>
> >> ---
> >> v3->v4: Rebase this patch on https://lore.kernel.org/linux-f2fs-devel/20250731060338.1136086-1-chao@kernel.org
> >> v2->v3: Apply Chao's suggestion from v2.
> >> v1->v2: Add two missing handling parts.
> >> v1: https://lore.kernel.org/linux-f2fs-devel/20250729095238.607433-1-guochunhai@vivo.com/
> >> ---
> >>   Documentation/filesystems/f2fs.rst |  9 ++++---
> >>   fs/f2fs/f2fs.h                     | 14 +++++++---
> >>   fs/f2fs/super.c                    | 43 +++++++++++++++++++++++++-----
> >>   3 files changed, 52 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
> >> index 03b1efa6d3b2..95dbcd7ac9a8 100644
> >> --- a/Documentation/filesystems/f2fs.rst
> >> +++ b/Documentation/filesystems/f2fs.rst
> >> @@ -173,9 +173,12 @@ data_flush               Enable data flushing before checkpoint in order to
> >>                       persist data of regular and symlink.
> >>   reserve_root=%d             Support configuring reserved space which is used for
> >>                       allocation from a privileged user with specified uid or
> >> -                     gid, unit: 4KB, the default limit is 0.2% of user blocks.
> >> -resuid=%d            The user ID which may use the reserved blocks.
> >> -resgid=%d            The group ID which may use the reserved blocks.
> >> +                     gid, unit: 4KB, the default limit is 12.5% of user blocks.
> >> +reserve_node=%d              Support configuring reserved nodes which are used for
> >> +                     allocation from a privileged user with specified uid or
> >> +                     gid, the default limit is 12.5% of all nodes.
> >> +resuid=%d            The user ID which may use the reserved blocks and nodes.
> >> +resgid=%d            The group ID which may use the reserved blocks and nodes.
> >>   fault_injection=%d  Enable fault injection in all supported types with
> >>                       specified injection rate.
> >>   fault_type=%d               Support configuring fault injection type, should be
> >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >> index eb372af22edc..b9676ef16246 100644
> >> --- a/fs/f2fs/f2fs.h
> >> +++ b/fs/f2fs/f2fs.h
> >> @@ -131,6 +131,7 @@ extern const char *f2fs_fault_name[FAULT_MAX];
> >>    * string rather than using the MS_LAZYTIME flag, so this must remain.
> >>    */
> >>   #define F2FS_MOUNT_LAZYTIME                0x40000000
> >> +#define F2FS_MOUNT_RESERVE_NODE             0x80000000
> >>
> >>   #define F2FS_OPTION(sbi)   ((sbi)->mount_opt)
> >>   #define clear_opt(sbi, option)     (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
> >> @@ -172,6 +173,7 @@ struct f2fs_rwsem {
> >>   struct f2fs_mount_info {
> >>      unsigned int opt;
> >>      block_t root_reserved_blocks;   /* root reserved blocks */
> >> +    block_t root_reserved_nodes;    /* root reserved nodes */
> >>      kuid_t s_resuid;                /* reserved blocks for uid */
> >>      kgid_t s_resgid;                /* reserved blocks for gid */
> >>      int active_logs;                /* # of active logs */
> >> @@ -2355,7 +2357,7 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs)
> >>      return ofs == XATTR_NODE_OFFSET;
> >>   }
> >>
> >> -static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
> >> +static inline bool __allow_reserved_root(struct f2fs_sb_info *sbi,
> >>                                      struct inode *inode, bool cap)
> >>   {
> >>      if (!inode)
> >> @@ -2380,7 +2382,7 @@ static inline unsigned int get_available_block_count(struct f2fs_sb_info *sbi,
> >>      avail_user_block_count = sbi->user_block_count -
> >>                                      sbi->current_reserved_blocks;
> >>
> >> -    if (test_opt(sbi, RESERVE_ROOT) && !__allow_reserved_blocks(sbi, inode, cap))
> >> +    if (test_opt(sbi, RESERVE_ROOT) && !__allow_reserved_root(sbi, inode, cap))
> >>              avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks;
> >>
> >>      if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
> >> @@ -2738,7 +2740,7 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
> >>                                      struct inode *inode, bool is_inode)
> >>   {
> >>      block_t valid_block_count;
> >> -    unsigned int valid_node_count;
> >> +    unsigned int valid_node_count, avail_user_node_count;
> >>      unsigned int avail_user_block_count;
> >>      int err;
> >>
> >> @@ -2767,8 +2769,12 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
> >>              goto enospc;
> >>      }
> >>
> >> +    avail_user_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
> >> +    if (test_opt(sbi, RESERVE_NODE) &&
> >> +                    !__allow_reserved_root(sbi, inode, false))
> > Chunhai,
> >
> > Do we need to pass cap=true to __allow_reserved_root()?
> >
> > In addition, do we need to change cap as well for below statement?
> >
> > avail_user_block_count = get_available_block_count(sbi, inode, false);
> 
> 
> Hi Jaegeuk,
> 
> 
> Based on the description in commit a90a0884ac75 ("f2fs: check
> cap_resource only for data blocks"), it seems that inode or node blocks
> don't need to perform a check on the cap_resource. I'm not certain about
> the reasoning behind this. Could you please help to clarify it?

I don't quite remember as I had to fix the selinx issue long long time ago.

> 
> 
> Thanks,
> 
> >
> > Thanks,
> >
> >> +            avail_user_node_count -= F2FS_OPTION(sbi).root_reserved_nodes;
> >>      valid_node_count = sbi->total_valid_node_count + 1;
> >> -    if (unlikely(valid_node_count > sbi->total_node_count)) {
> >> +    if (unlikely(valid_node_count > avail_user_node_count)) {
> >>              spin_unlock(&sbi->stat_lock);
> >>              goto enospc;
> >>      }
> >> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> >> index 30c038413040..a24e855a38ed 100644
> >> --- a/fs/f2fs/super.c
> >> +++ b/fs/f2fs/super.c
> >> @@ -143,6 +143,7 @@ enum {
> >>      Opt_extent_cache,
> >>      Opt_data_flush,
> >>      Opt_reserve_root,
> >> +    Opt_reserve_node,
> >>      Opt_resgid,
> >>      Opt_resuid,
> >>      Opt_mode,
> >> @@ -265,6 +266,7 @@ static const struct fs_parameter_spec f2fs_param_specs[] = {
> >>      fsparam_flag_no("extent_cache", Opt_extent_cache),
> >>      fsparam_flag("data_flush", Opt_data_flush),
> >>      fsparam_u32("reserve_root", Opt_reserve_root),
> >> +    fsparam_u32("reserve_node", Opt_reserve_node),
> >>      fsparam_gid("resgid", Opt_resgid),
> >>      fsparam_uid("resuid", Opt_resuid),
> >>      fsparam_enum("mode", Opt_mode, f2fs_param_mode),
> >> @@ -336,6 +338,7 @@ static match_table_t f2fs_checkpoint_tokens = {
> >>   #define F2FS_SPEC_discard_unit                     (1 << 21)
> >>   #define F2FS_SPEC_memory_mode                      (1 << 22)
> >>   #define F2FS_SPEC_errors                   (1 << 23)
> >> +#define F2FS_SPEC_reserve_node                      (1 << 24)
> >>
> >>   struct f2fs_fs_context {
> >>      struct f2fs_mount_info info;
> >> @@ -437,22 +440,30 @@ static void f2fs_destroy_casefold_cache(void) { }
> >>
> >>   static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
> >>   {
> >> -    block_t limit = min((sbi->user_block_count >> 3),
> >> +    block_t block_limit = min((sbi->user_block_count >> 3),
> >>                      sbi->user_block_count - sbi->reserved_blocks);
> >> +    block_t node_limit = sbi->total_node_count >> 3;
> >>
> >>      /* limit is 12.5% */
> >>      if (test_opt(sbi, RESERVE_ROOT) &&
> >> -                    F2FS_OPTION(sbi).root_reserved_blocks > limit) {
> >> -            F2FS_OPTION(sbi).root_reserved_blocks = limit;
> >> +                    F2FS_OPTION(sbi).root_reserved_blocks > block_limit) {
> >> +            F2FS_OPTION(sbi).root_reserved_blocks = block_limit;
> >>              f2fs_info(sbi, "Reduce reserved blocks for root = %u",
> >>                        F2FS_OPTION(sbi).root_reserved_blocks);
> >>      }
> >> -    if (!test_opt(sbi, RESERVE_ROOT) &&
> >> +    if (test_opt(sbi, RESERVE_NODE) &&
> >> +                    F2FS_OPTION(sbi).root_reserved_nodes > node_limit) {
> >> +            F2FS_OPTION(sbi).root_reserved_nodes = node_limit;
> >> +            f2fs_info(sbi, "Reduce reserved nodes for root = %u",
> >> +                      F2FS_OPTION(sbi).root_reserved_nodes);
> >> +    }
> >> +    if (!test_opt(sbi, RESERVE_ROOT) && !test_opt(sbi, RESERVE_NODE) &&
> >>              (!uid_eq(F2FS_OPTION(sbi).s_resuid,
> >>                              make_kuid(&init_user_ns, F2FS_DEF_RESUID)) ||
> >>              !gid_eq(F2FS_OPTION(sbi).s_resgid,
> >>                              make_kgid(&init_user_ns, F2FS_DEF_RESGID))))
> >> -            f2fs_info(sbi, "Ignore s_resuid=%u, s_resgid=%u w/o reserve_root",
> >> +            f2fs_info(sbi, "Ignore s_resuid=%u, s_resgid=%u w/o reserve_root"
> >> +                            " and reserve_node",
> >>                        from_kuid_munged(&init_user_ns,
> >>                                         F2FS_OPTION(sbi).s_resuid),
> >>                        from_kgid_munged(&init_user_ns,
> >> @@ -841,6 +852,11 @@ static int f2fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
> >>              F2FS_CTX_INFO(ctx).root_reserved_blocks = result.uint_32;
> >>              ctx->spec_mask |= F2FS_SPEC_reserve_root;
> >>              break;
> >> +    case Opt_reserve_node:
> >> +            ctx_set_opt(ctx, F2FS_MOUNT_RESERVE_NODE);
> >> +            F2FS_CTX_INFO(ctx).root_reserved_nodes = result.uint_32;
> >> +            ctx->spec_mask |= F2FS_SPEC_reserve_node;
> >> +            break;
> >>      case Opt_resuid:
> >>              F2FS_CTX_INFO(ctx).s_resuid = result.uid;
> >>              ctx->spec_mask |= F2FS_SPEC_resuid;
> >> @@ -1424,6 +1440,14 @@ static int f2fs_check_opt_consistency(struct fs_context *fc,
> >>              ctx_clear_opt(ctx, F2FS_MOUNT_RESERVE_ROOT);
> >>              ctx->opt_mask &= ~F2FS_MOUNT_RESERVE_ROOT;
> >>      }
> >> +    if (test_opt(sbi, RESERVE_NODE) &&
> >> +                    (ctx->opt_mask & F2FS_MOUNT_RESERVE_NODE) &&
> >> +                    ctx_test_opt(ctx, F2FS_MOUNT_RESERVE_NODE)) {
> >> +            f2fs_info(sbi, "Preserve previous reserve_node=%u",
> >> +                    F2FS_OPTION(sbi).root_reserved_nodes);
> >> +            ctx_clear_opt(ctx, F2FS_MOUNT_RESERVE_NODE);
> >> +            ctx->opt_mask &= ~F2FS_MOUNT_RESERVE_NODE;
> >> +    }
> >>
> >>      err = f2fs_check_test_dummy_encryption(fc, sb);
> >>      if (err)
> >> @@ -1623,6 +1647,9 @@ static void f2fs_apply_options(struct fs_context *fc, struct super_block *sb)
> >>      if (ctx->spec_mask & F2FS_SPEC_reserve_root)
> >>              F2FS_OPTION(sbi).root_reserved_blocks =
> >>                                      F2FS_CTX_INFO(ctx).root_reserved_blocks;
> >> +    if (ctx->spec_mask & F2FS_SPEC_reserve_node)
> >> +            F2FS_OPTION(sbi).root_reserved_nodes =
> >> +                                    F2FS_CTX_INFO(ctx).root_reserved_nodes;
> >>      if (ctx->spec_mask & F2FS_SPEC_resgid)
> >>              F2FS_OPTION(sbi).s_resgid = F2FS_CTX_INFO(ctx).s_resgid;
> >>      if (ctx->spec_mask & F2FS_SPEC_resuid)
> >> @@ -2342,9 +2369,11 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
> >>      else if (F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_BLK)
> >>              seq_puts(seq, "fragment:block");
> >>      seq_printf(seq, ",active_logs=%u", F2FS_OPTION(sbi).active_logs);
> >> -    if (test_opt(sbi, RESERVE_ROOT))
> >> -            seq_printf(seq, ",reserve_root=%u,resuid=%u,resgid=%u",
> >> +    if (test_opt(sbi, RESERVE_ROOT) || test_opt(sbi, RESERVE_NODE))
> >> +            seq_printf(seq, ",reserve_root=%u,reserve_node=%u,resuid=%u,"
> >> +                            "resgid=%u",
> >>                              F2FS_OPTION(sbi).root_reserved_blocks,
> >> +                            F2FS_OPTION(sbi).root_reserved_nodes,
> >>                              from_kuid_munged(&init_user_ns,
> >>                                      F2FS_OPTION(sbi).s_resuid),
> >>                              from_kgid_munged(&init_user_ns,
> 
> 

  reply	other threads:[~2025-08-05  2:38 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-31  7:57 [f2fs-dev] [PATCH v4] f2fs: add reserved nodes for privileged users Chunhai Guo via Linux-f2fs-devel
2025-07-31  7:57 ` Chunhai Guo
2025-07-31  8:46 ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2025-07-31  8:46   ` Chao Yu
2025-07-31 10:53   ` [f2fs-dev] " Chunhai Guo via Linux-f2fs-devel
2025-07-31 10:53     ` Chunhai Guo
2025-08-05  2:38     ` Jaegeuk Kim via Linux-f2fs-devel [this message]
2025-08-05  2:38       ` Jaegeuk Kim
2025-08-06  8:56       ` [f2fs-dev] " Chunhai Guo via Linux-f2fs-devel
2025-08-06  8:56         ` Chunhai Guo
2025-08-05  8:56   ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2025-08-05  8:56     ` Chao Yu
2025-08-06  8:56     ` [f2fs-dev] " Chunhai Guo via Linux-f2fs-devel
2025-08-06  8:56       ` Chunhai Guo

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=aJFuinsBEdMeRbiN@google.com \
    --to=linux-f2fs-devel@lists.sourceforge.net \
    --cc=guochunhai@vivo.com \
    --cc=jaegeuk@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

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

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