112 lines
3.7 KiB
Diff
112 lines
3.7 KiB
Diff
|
|
From 0c5485348b155420ecd1bfcdabb1b869ca5ee3c2 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Karel Zak <kzak@redhat.com>
|
||
|
|
Date: Wed, 20 Mar 2024 16:08:16 +0100
|
||
|
|
Subject: [PATCH] libmount: make sure "option=" is used as string
|
||
|
|
|
||
|
|
mount(8) cares about case when option specified as "name=" (it means
|
||
|
|
without data). See for example 727c689908c5e68c92aa1dd65e0d3bdb6d91c1e5.
|
||
|
|
|
||
|
|
We need this also for new mount API and use FSCONFIG_SET_STRING rather
|
||
|
|
than FSCONFIG_SET_FLAG.
|
||
|
|
|
||
|
|
strace -e fsconfig ./mount -o usrjquota= /dev/sdc1 /mnt/test
|
||
|
|
|
||
|
|
Old:
|
||
|
|
fsconfig(3, FSCONFIG_SET_STRING, "source", "/dev/sdc1", 0) = 0
|
||
|
|
fsconfig(3, FSCONFIG_SET_FLAG, "usrjquota", NULL, 0) = -1 EINVAL (Invalid argument)
|
||
|
|
|
||
|
|
Fixed:
|
||
|
|
fsconfig(3, FSCONFIG_SET_STRING, "source", "/dev/sdc1", 0) = 0
|
||
|
|
fsconfig(3, FSCONFIG_SET_STRING, "usrjquota", "", 0) = 0
|
||
|
|
|
||
|
|
Fixes: https://github.com/util-linux/util-linux/issues/2837
|
||
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||
|
|
---
|
||
|
|
libmount/src/hook_mount.c | 3 +++
|
||
|
|
libmount/src/mountP.h | 1 +
|
||
|
|
libmount/src/optlist.c | 14 +++++++++++++-
|
||
|
|
3 files changed, 17 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c
|
||
|
|
index 92438966c..f0cc38196 100644
|
||
|
|
--- a/libmount/src/hook_mount.c
|
||
|
|
+++ b/libmount/src/hook_mount.c
|
||
|
|
@@ -224,6 +224,9 @@ static int configure_superblock(struct libmnt_context *cxt,
|
||
|
|
/* Ignore VFS flags, userspace and external options */
|
||
|
|
continue;
|
||
|
|
|
||
|
|
+ if (!value && mnt_opt_is_sepnodata(opt))
|
||
|
|
+ value = ""; /* force use the value as string */
|
||
|
|
+
|
||
|
|
rc = fsconfig_set_value(cxt, hs, fd, name, value);
|
||
|
|
if (rc != 0)
|
||
|
|
goto done;
|
||
|
|
diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
|
||
|
|
index 458aa1a00..fcc40bffc 100644
|
||
|
|
--- a/libmount/src/mountP.h
|
||
|
|
+++ b/libmount/src/mountP.h
|
||
|
|
@@ -608,6 +608,7 @@ extern int mnt_opt_set_value(struct libmnt_opt *opt, const char *str);
|
||
|
|
extern int mnt_opt_set_u64value(struct libmnt_opt *opt, uint64_t num);
|
||
|
|
extern int mnt_opt_set_quoted_value(struct libmnt_opt *opt, const char *str);
|
||
|
|
extern int mnt_opt_is_external(struct libmnt_opt *opt);
|
||
|
|
+extern int mnt_opt_is_sepnodata(struct libmnt_opt *opt);
|
||
|
|
|
||
|
|
/* fs.c */
|
||
|
|
extern int mnt_fs_follow_optlist(struct libmnt_fs *fs, struct libmnt_optlist *ol);
|
||
|
|
diff --git a/libmount/src/optlist.c b/libmount/src/optlist.c
|
||
|
|
index 101c908ae..476acfd65 100644
|
||
|
|
--- a/libmount/src/optlist.c
|
||
|
|
+++ b/libmount/src/optlist.c
|
||
|
|
@@ -46,6 +46,7 @@ struct libmnt_opt {
|
||
|
|
|
||
|
|
unsigned int external : 1, /* visible for external helpers only */
|
||
|
|
recursive : 1, /* recursive flag */
|
||
|
|
+ sepnodata : 1, /* value separator, but without data ("name=") */
|
||
|
|
is_linux : 1, /* defined in ls->linux_map (VFS attr) */
|
||
|
|
quoted : 1; /* name="value" */
|
||
|
|
};
|
||
|
|
@@ -438,6 +439,10 @@ static struct libmnt_opt *optlist_new_opt(struct libmnt_optlist *ls,
|
||
|
|
opt->value = strndup(value, valsz);
|
||
|
|
if (!opt->value)
|
||
|
|
goto fail;
|
||
|
|
+
|
||
|
|
+ } else if (value) {
|
||
|
|
+ /* separator specified, but empty value ("name=") */
|
||
|
|
+ opt->sepnodata = 1;
|
||
|
|
}
|
||
|
|
if (namesz) {
|
||
|
|
opt->name = strndup(name, namesz);
|
||
|
|
@@ -957,7 +962,8 @@ int mnt_optlist_strdup_optstr(struct libmnt_optlist *ls, char **optstr,
|
||
|
|
continue;
|
||
|
|
rc = mnt_buffer_append_option(&buf,
|
||
|
|
opt->name, strlen(opt->name),
|
||
|
|
- opt->value,
|
||
|
|
+ opt->value ? opt->value :
|
||
|
|
+ opt->sepnodata ? "" : NULL,
|
||
|
|
opt->value ? strlen(opt->value) : 0,
|
||
|
|
opt->quoted);
|
||
|
|
if (rc)
|
||
|
|
@@ -1043,6 +1049,7 @@ struct libmnt_optlist *mnt_copy_optlist(struct libmnt_optlist *ls)
|
||
|
|
no->src = opt->src;
|
||
|
|
no->external = opt->external;
|
||
|
|
no->quoted = opt->quoted;
|
||
|
|
+ no->sepnodata = opt->sepnodata;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -1184,6 +1191,11 @@ int mnt_opt_is_external(struct libmnt_opt *opt)
|
||
|
|
return opt && opt->external ? 1 : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+int mnt_opt_is_sepnodata(struct libmnt_opt *opt)
|
||
|
|
+{
|
||
|
|
+ return opt->sepnodata;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
|
||
|
|
#ifdef TEST_PROGRAM
|
||
|
|
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|