From: Miklos Szeredi <mszeredi@redhat.com>
To: 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: [PATCH] statmount: add flag to retrieve unescaped options
Date: Tue, 12 Nov 2024 11:10:04 +0100 [thread overview]
Message-ID: <20241112101006.30715-1-mszeredi@redhat.com> (raw)
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;
}
}
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
--
2.47.0
next reply other threads:[~2024-11-12 10:10 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-12 10:10 Miklos Szeredi [this message]
2024-11-12 12:20 ` [PATCH] statmount: add flag to retrieve unescaped options Jeff Layton
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=20241112101006.30715-1-mszeredi@redhat.com \
--to=mszeredi@redhat.com \
--cc=christian@brauner.io \
--cc=josef@toxicpanda.com \
--cc=kzak@redhat.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-fsdevel@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.