[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <61415c38-1846-4107-8612-ab763159a3bd@vivo.com>
Date: Wed, 6 Aug 2025 08:56:50 +0000
From: Chunhai Guo <guochunhai@...o.com>
To: Chao Yu <chao@...nel.org>, Chunhai Guo <guochunhai@...o.com>,
"jaegeuk@...nel.org" <jaegeuk@...nel.org>
CC: "linux-f2fs-devel@...ts.sourceforge.net"
<linux-f2fs-devel@...ts.sourceforge.net>, "linux-kernel@...r.kernel.org"
<linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v4] f2fs: add reserved nodes for privileged users
在 8/5/2025 4:56 PM, Chao Yu 写道:
> On 7/31/25 16:46, Chao Yu wrote:
>> 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@...o.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);
> I meant something like this? not sure.
I think this is fine. I have tested with your modifications on an
Android device and no selinx issue has been found. I will send the v5
patch with your modifications.
Thanks,
>
> ---
> fs/f2fs/f2fs.h | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 3804b70e5a28..d0aa5766ea66 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -2805,7 +2805,8 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
> spin_lock(&sbi->stat_lock);
>
> valid_block_count = sbi->total_valid_block_count + 1;
> - avail_user_block_count = get_available_block_count(sbi, inode, false);
> + avail_user_block_count = get_available_block_count(sbi, inode,
> + test_opt(sbi, RESERVE_NODE));
>
> if (unlikely(valid_block_count > avail_user_block_count)) {
> spin_unlock(&sbi->stat_lock);
> @@ -2814,7 +2815,7 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
>
> avail_user_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
> if (test_opt(sbi, RESERVE_NODE) &&
> - !__allow_reserved_root(sbi, inode, false))
> + !__allow_reserved_root(sbi, inode, true))
> avail_user_node_count -= F2FS_OPTION(sbi).root_reserved_nodes;
> valid_node_count = sbi->total_valid_node_count + 1;
> if (unlikely(valid_node_count > avail_user_node_count)) {
Powered by blists - more mailing lists