From: Karel Zak Date: Mon, 26 Sep 2022 13:22:57 +0000 (+0200) Subject: libmount: (mount) create new FS instance by new Linux API X-Git-Tag: v2.39-rc1~251 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c15b21c162090dd0fdfedab1d85695e9e2b30bc4;p=thirdparty%2Futil-linux.git libmount: (mount) create new FS instance by new Linux API Signed-off-by: Karel Zak --- diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index 4cc44b8c19..df5bc57398 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -122,13 +122,95 @@ static int hook_reconfigure_mount(struct libmnt_context *cxt __attribute__((__un return 0; } -static int hook_create_mount(struct libmnt_context *cxt __attribute__((__unused__)), - const struct libmnt_hookset *hs __attribute__((__unused__)), - void *data __attribute__((__unused__))) +static int configure_superblock(struct libmnt_context *cxt, + const struct libmnt_hookset *hs, int fd) { + struct libmnt_optlist *ol; + struct libmnt_iter itr; + struct libmnt_opt *opt; + int rc; + + DBG(HOOK, ul_debugobj(hs, " configure FS")); + + ol = mnt_context_get_optlist(cxt); + if (!ol) + return -ENOMEM; + + mnt_reset_iter(&itr, MNT_ITER_FORWARD); + + while (mnt_optlist_next_opt(ol, &itr, &opt) == 0) { + const char *name = mnt_opt_get_name(opt); + const char *value = mnt_opt_get_value(opt); + const struct libmnt_optmap *ent = mnt_opt_get_mapent(opt); + + if (ent && mnt_opt_get_map(opt) == cxt->map_linux && + ent->id == MS_RDONLY) + ; + else if (!name || mnt_opt_get_map(opt) || mnt_opt_is_external(opt)) + continue; + + DBG(HOOK, ul_debugobj(hs, " fsconfig(name=%s,value=%s)", name, value)); + if (value) + rc = fsconfig(fd, FSCONFIG_SET_STRING, name, value, 0); + else + rc = fsconfig(fd, FSCONFIG_SET_FLAG, name, NULL, 0); + + set_syscall_status(cxt, "fsconfig", rc == 0); + if (rc != 0) + return -errno; + } + return 0; } +static int hook_create_mount(struct libmnt_context *cxt, + const struct libmnt_hookset *hs, + void *data __attribute__((__unused__))) +{ + struct libmnt_sysapi *api; + const char *src; + int rc = 0; + + assert(cxt); + assert(cxt->fs); + + api = get_sysapi(cxt, hs); + assert(api); + assert(api->fd_fs >= 0); + + src = mnt_fs_get_srcpath(cxt->fs); + if (!src) + return -EINVAL; + + DBG(HOOK, ul_debugobj(hs, "create FS instance")); + + rc = fsconfig(api->fd_fs, FSCONFIG_SET_STRING, "source", src, 0); + set_syscall_status(cxt, "fsconfig", rc == 0); + + if (!rc) + rc = configure_superblock(cxt, hs, api->fd_fs); + if (!rc) { + rc = fsconfig(api->fd_fs, FSCONFIG_CMD_CREATE, NULL, NULL, 0); + set_syscall_status(cxt, "fsconfig", rc == 0); + } + + if (!rc) { + api->fd_tree = fsmount(api->fd_fs, FSMOUNT_CLOEXEC, 0); + set_syscall_status(cxt, "fsmount", api->fd_tree >= 0); + if (api->fd_tree < 0) + return -errno; + } + if (!rc && cxt->fs) { + struct statx st; + + rc = statx(api->fd_tree, "", AT_EMPTY_PATH, STATX_MNT_ID, &st); + cxt->fs->id = (int) st.stx_mnt_id; + } + + DBG(HOOK, ul_debugobj(hs, "create FS done [rc=%d]", rc)); + return rc; +} + static int hook_set_vfsflags(struct libmnt_context *cxt, const struct libmnt_hookset *hs, void *data __attribute__((__unused__))) @@ -375,13 +457,8 @@ static int hook_prepare(struct libmnt_context *cxt, rc = mnt_context_append_hook(cxt, hs, MNT_STAGE_MOUNT, NULL, hook_reconfigure_mount); - /* call mount_setattr() */ - if (!rc && (set != 0 || clr != 0)) - rc = mnt_context_append_hook(cxt, hs, MNT_STAGE_MOUNT, NULL, - hook_set_vfsflags); - /* create a new FS instance */ - if (!rc + else if (!rc && !(flags & MS_BIND) && !(flags & MS_MOVE) && !(flags & MS_REMOUNT) @@ -389,6 +466,11 @@ static int hook_prepare(struct libmnt_context *cxt, rc = mnt_context_append_hook(cxt, hs, MNT_STAGE_MOUNT, NULL, hook_create_mount); + /* call mount_setattr() */ + if (!rc && (set != 0 || clr != 0)) + rc = mnt_context_append_hook(cxt, hs, MNT_STAGE_MOUNT, NULL, + hook_set_vfsflags); + /* call move_mount() to attach target */ if (!rc && !(flags & MS_REMOUNT)