From: Jeff Layton <jlayton@kernel.org>
To: Miklos Szeredi <mszeredi@redhat.com>, linux-fsdevel@vger.kernel.org
Cc: linux-api@vger.kernel.org, Karel Zak <kzak@redhat.com>,
Christian Brauner <christian@brauner.io>,
Josef Bacik <josef@toxicpanda.com>
Subject: Re: [PATCH] statmount: add flag to retrieve unescaped options
Date: Tue, 12 Nov 2024 07:20:03 -0500 [thread overview]
Message-ID: <2faa89f0ad18d8f8015f65b202f8ddc64a810a71.camel@kernel.org> (raw)
In-Reply-To: <20241112101006.30715-1-mszeredi@redhat.com>
On Tue, 2024-11-12 at 11:10 +0100, Miklos Szeredi wrote:
> Filesystem options can be retrieved with STATMOUNT_MNT_OPTS, which
> returns a string of comma separated options, where some characters are
> escaped using the \OOO notation.
>
> Add a new flag, STATMOUNT_OPT_ARRAY, which instead returns the raw
> option values separated with '\0' charaters.
>
> Since escaped charaters are rare, this inteface is preferable for
> non-libmount users which likley don't want to deal with option
> de-escaping.
>
> Example code:
>
> if (st->mask & STATMOUNT_OPT_ARRAY) {
> const char *opt = st->str + st->opt_array;
>
> for (unsigned int i = 0; i < st->opt_num; i++) {
> printf("opt_array[%i]: <%s>\n", i, opt);
> opt += strlen(opt) + 1;
> }
> }
>
If the options are separated by NULs, how does userland know where to
stop?
At some point we will probably end up adding a new string value that
would go after the opt array, and userland will need some way to
clearly tell where that new string begins and the NUL-terminated
options array ends.
> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> ---
> fs/namespace.c | 42 ++++++++++++++++++++++++++++++++++++++
> include/uapi/linux/mount.h | 7 +++++--
> 2 files changed, 47 insertions(+), 2 deletions(-)
>
> diff --git a/fs/namespace.c b/fs/namespace.c
> index 9a4ab1bc8b94..a16f75011610 100644
> --- a/fs/namespace.c
> +++ b/fs/namespace.c
> @@ -5074,6 +5074,41 @@ static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq)
> return 0;
> }
>
> +static int statmount_opt_array(struct kstatmount *s, struct seq_file *seq)
> +{
> + struct vfsmount *mnt = s->mnt;
> + struct super_block *sb = mnt->mnt_sb;
> + size_t start = seq->count;
> + u32 count = 0;
> + char *p, *end, *next, *u = seq->buf + start;
> + int err;
> +
> + if (!sb->s_op->show_options)
> + return 0;
> +
> + err = sb->s_op->show_options(seq, mnt->mnt_root);
> + if (err)
> + return err;
> +
> + if (unlikely(seq_has_overflowed(seq)))
> + return -EAGAIN;
> +
> + end = seq->buf + seq->count;
> + *end = '\0';
> + for (p = u + 1; p < end; p = next + 1) {
> + next = strchrnul(p, ',');
> + *next = '\0';
> + u += string_unescape(p, u, 0, UNESCAPE_OCTAL) + 1;
> + count++;
> + if (!count)
> + return -EOVERFLOW;
> + }
> + seq->count = u - 1 - seq->buf;
> + s->sm.opt_num = count;
> +
> + return 0;
> +}
> +
> static int statmount_string(struct kstatmount *s, u64 flag)
> {
> int ret = 0;
> @@ -5099,6 +5134,10 @@ static int statmount_string(struct kstatmount *s, u64 flag)
> sm->mnt_opts = start;
> ret = statmount_mnt_opts(s, seq);
> break;
> + case STATMOUNT_OPT_ARRAY:
> + sm->opt_array = start;
> + ret = statmount_opt_array(s, seq);
> + break;
> case STATMOUNT_FS_SUBTYPE:
> sm->fs_subtype = start;
> statmount_fs_subtype(s, seq);
> @@ -5252,6 +5291,9 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,
> if (!err && s->mask & STATMOUNT_MNT_OPTS)
> err = statmount_string(s, STATMOUNT_MNT_OPTS);
>
> + if (!err && s->mask & STATMOUNT_OPT_ARRAY)
> + err = statmount_string(s, STATMOUNT_OPT_ARRAY);
> +
> if (!err && s->mask & STATMOUNT_FS_SUBTYPE)
> err = statmount_string(s, STATMOUNT_FS_SUBTYPE);
>
> diff --git a/include/uapi/linux/mount.h b/include/uapi/linux/mount.h
> index 2b49e9131d77..c0fda4604187 100644
> --- a/include/uapi/linux/mount.h
> +++ b/include/uapi/linux/mount.h
> @@ -154,7 +154,7 @@ struct mount_attr {
> */
> struct statmount {
> __u32 size; /* Total size, including strings */
> - __u32 mnt_opts; /* [str] Mount options of the mount */
> + __u32 mnt_opts; /* [str] Options (comma separated, escaped) */
> __u64 mask; /* What results were written */
> __u32 sb_dev_major; /* Device ID */
> __u32 sb_dev_minor;
> @@ -175,7 +175,9 @@ struct statmount {
> __u64 mnt_ns_id; /* ID of the mount namespace */
> __u32 fs_subtype; /* [str] Subtype of fs_type (if any) */
> __u32 sb_source; /* [str] Source string of the mount */
> - __u64 __spare2[48];
> + __u32 opt_num; /* Number of fs options */
> + __u32 opt_array; /* [str] Array of nul terminated fs options */
> + __u64 __spare2[47];
> char str[]; /* Variable size part containing strings */
> };
>
> @@ -211,6 +213,7 @@ struct mnt_id_req {
> #define STATMOUNT_MNT_OPTS 0x00000080U /* Want/got mnt_opts */
> #define STATMOUNT_FS_SUBTYPE 0x00000100U /* Want/got fs_subtype */
> #define STATMOUNT_SB_SOURCE 0x00000200U /* Want/got sb_source */
> +#define STATMOUNT_OPT_ARRAY 0x00000400U /* Want/got opt_... */
>
> /*
> * Special @mnt_id values that can be passed to listmount
--
Jeff Layton <jlayton@kernel.org>
next prev parent reply other threads:[~2024-11-12 12:20 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-12 10:10 [PATCH] statmount: add flag to retrieve unescaped options Miklos Szeredi
2024-11-12 12:20 ` Jeff Layton [this message]
2024-11-12 12:24 ` Miklos Szeredi
2024-11-12 12:29 ` Jeff Layton
2024-11-13 12:27 ` Christian Brauner
2024-11-13 16:30 ` Christian Brauner
2024-11-14 14:53 ` Miklos Szeredi
2024-11-15 8:10 ` Christian Brauner
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=2faa89f0ad18d8f8015f65b202f8ddc64a810a71.camel@kernel.org \
--to=jlayton@kernel.org \
--cc=christian@brauner.io \
--cc=josef@toxicpanda.com \
--cc=kzak@redhat.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=mszeredi@redhat.com \
/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.