diff mbox series

[v4,1/3] fs: don't let statmount return empty strings

Message ID 20241111-statmount-v4-1-2eaf35d07a80@kernel.org (mailing list archive)
State New
Headers show
Series fs: allow statmount to fetch the fs_subtype and sb_source | expand

Commit Message

Jeff Layton Nov. 11, 2024, 3:09 p.m. UTC
When one of the statmount_string() handlers doesn't emit anything to
seq, the kernel currently sets the corresponding flag and emits an empty
string.

Given that statmount() returns a mask of accessible fields, just leave
the bit unset in this case, and skip any NULL termination. If nothing
was emitted to the seq, then the EOVERFLOW and EAGAIN cases aren't
applicable and the function can just return immediately.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/namespace.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

Comments

Jan Kara Nov. 11, 2024, 5:44 p.m. UTC | #1
On Mon 11-11-24 10:09:55, Jeff Layton wrote:
> When one of the statmount_string() handlers doesn't emit anything to
> seq, the kernel currently sets the corresponding flag and emits an empty
> string.
> 
> Given that statmount() returns a mask of accessible fields, just leave
> the bit unset in this case, and skip any NULL termination. If nothing
> was emitted to the seq, then the EOVERFLOW and EAGAIN cases aren't
> applicable and the function can just return immediately.
> 
> Signed-off-by: Jeff Layton <jlayton@kernel.org>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/namespace.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/namespace.c b/fs/namespace.c
> index ba77ce1c6788dfe461814b5826fcbb3aab68fad4..28ad153b1fb6f49653c0a85d12da457c4650a87e 100644
> --- a/fs/namespace.c
> +++ b/fs/namespace.c
> @@ -5046,22 +5046,23 @@ static int statmount_string(struct kstatmount *s, u64 flag)
>  	size_t kbufsize;
>  	struct seq_file *seq = &s->seq;
>  	struct statmount *sm = &s->sm;
> +	u32 start = seq->count;
>  
>  	switch (flag) {
>  	case STATMOUNT_FS_TYPE:
> -		sm->fs_type = seq->count;
> +		sm->fs_type = start;
>  		ret = statmount_fs_type(s, seq);
>  		break;
>  	case STATMOUNT_MNT_ROOT:
> -		sm->mnt_root = seq->count;
> +		sm->mnt_root = start;
>  		ret = statmount_mnt_root(s, seq);
>  		break;
>  	case STATMOUNT_MNT_POINT:
> -		sm->mnt_point = seq->count;
> +		sm->mnt_point = start;
>  		ret = statmount_mnt_point(s, seq);
>  		break;
>  	case STATMOUNT_MNT_OPTS:
> -		sm->mnt_opts = seq->count;
> +		sm->mnt_opts = start;
>  		ret = statmount_mnt_opts(s, seq);
>  		break;
>  	default:
> @@ -5069,6 +5070,12 @@ static int statmount_string(struct kstatmount *s, u64 flag)
>  		return -EINVAL;
>  	}
>  
> +	/*
> +	 * If nothing was emitted, return to avoid setting the flag
> +	 * and terminating the buffer.
> +	 */
> +	if (seq->count == start)
> +		return ret;
>  	if (unlikely(check_add_overflow(sizeof(*sm), seq->count, &kbufsize)))
>  		return -EOVERFLOW;
>  	if (kbufsize >= s->bufsize)
> 
> -- 
> 2.47.0
>
diff mbox series

Patch

diff --git a/fs/namespace.c b/fs/namespace.c
index ba77ce1c6788dfe461814b5826fcbb3aab68fad4..28ad153b1fb6f49653c0a85d12da457c4650a87e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -5046,22 +5046,23 @@  static int statmount_string(struct kstatmount *s, u64 flag)
 	size_t kbufsize;
 	struct seq_file *seq = &s->seq;
 	struct statmount *sm = &s->sm;
+	u32 start = seq->count;
 
 	switch (flag) {
 	case STATMOUNT_FS_TYPE:
-		sm->fs_type = seq->count;
+		sm->fs_type = start;
 		ret = statmount_fs_type(s, seq);
 		break;
 	case STATMOUNT_MNT_ROOT:
-		sm->mnt_root = seq->count;
+		sm->mnt_root = start;
 		ret = statmount_mnt_root(s, seq);
 		break;
 	case STATMOUNT_MNT_POINT:
-		sm->mnt_point = seq->count;
+		sm->mnt_point = start;
 		ret = statmount_mnt_point(s, seq);
 		break;
 	case STATMOUNT_MNT_OPTS:
-		sm->mnt_opts = seq->count;
+		sm->mnt_opts = start;
 		ret = statmount_mnt_opts(s, seq);
 		break;
 	default:
@@ -5069,6 +5070,12 @@  static int statmount_string(struct kstatmount *s, u64 flag)
 		return -EINVAL;
 	}
 
+	/*
+	 * If nothing was emitted, return to avoid setting the flag
+	 * and terminating the buffer.
+	 */
+	if (seq->count == start)
+		return ret;
 	if (unlikely(check_add_overflow(sizeof(*sm), seq->count, &kbufsize)))
 		return -EOVERFLOW;
 	if (kbufsize >= s->bufsize)