From: Karel Zak Date: Tue, 25 Apr 2023 14:25:14 +0000 (+0200) Subject: libmount: improve ENOSYS fallback X-Git-Tag: v2.39~56 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=009b369c7d95e811470eb5d626b9b498539a007a;p=thirdparty%2Futil-linux.git libmount: improve ENOSYS fallback In some cases, for example: # mount -t foo,bar,ext4 /dev/sdc /mnt/test libmount calls fsopen() later (after mount preparation stage), but we need during preparation check if hook_mount.c stuff (new API) is usable. Let's do it by dummy fsopen() call. Signed-off-by: Karel Zak --- diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index 2dbe5217cc..9d1ffaf0d1 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -496,6 +496,20 @@ static int hook_attach_target(struct libmnt_context *cxt, return rc == 0 ? 0 : -errno; } +static inline int fsopen_is_supported(void) +{ + int dummy, rc = 1; + + errno = 0; + dummy = fsopen(NULL, FSOPEN_CLOEXEC); + + if (errno == ENOSYS) + rc = 0; + if (dummy >= 0) + close(dummy); + return rc; +} + /* * open_tree() and fsopen() */ @@ -547,12 +561,19 @@ static int init_sysapi(struct libmnt_context *cxt, * is called later in hook_create_mount(). */ } else { const char *type = mnt_fs_get_fstype(cxt->fs); + int rc = 0; + + /* fsopen() to create a superblock */ + if (cxt->helper == NULL && type && !strchr(type, ',')) + rc = open_fs_configuration_context(cxt, api, type); - if (mnt_context_is_fake(cxt)) - goto fake; - if (cxt->helper == NULL - && type && !strchr(type, ',') - && open_fs_configuration_context(cxt, api, type) < 0) + /* dummy fsopen() to test if API is available */ + else if (!fsopen_is_supported()) { + errno = ENOSYS; + rc = -errno; + set_syscall_status(cxt, "fsopen", rc == 0); + } + if (rc < 0) goto fail; }