Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2231574/?format=api
{ "id": 2231574, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2231574/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/patch/177758363604.1314717.1565554096353858559.stgit@frogsfrogsfrogs/", "project": { "id": 8, "url": "http://patchwork.ozlabs.org/api/1.1/projects/8/?format=api", "name": "Linux ext4 filesystem development", "link_name": "linux-ext4", "list_id": "linux-ext4.vger.kernel.org", "list_email": "linux-ext4@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null }, "msgid": "<177758363604.1314717.1565554096353858559.stgit@frogsfrogsfrogs>", "date": "2026-04-30T21:16:04", "name": "[04/13] mount_service: use the new mount api for the mount service", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "b1def086e9e9fb882a150c7cb89884edd274c6ed", "submitter": { "id": 77032, "url": "http://patchwork.ozlabs.org/api/1.1/people/77032/?format=api", "name": "Darrick J. Wong", "email": "djwong@kernel.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-ext4/patch/177758363604.1314717.1565554096353858559.stgit@frogsfrogsfrogs/mbox/", "series": [ { "id": 502386, "url": "http://patchwork.ozlabs.org/api/1.1/series/502386/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/list/?series=502386", "date": "2026-04-30T21:15:17", "name": "[01/13] Refactor mount code / move common functions to mount_util.c", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/502386/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2231574/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2231574/checks/", "tags": {}, "headers": { "Return-Path": "\n <SRS0=vArY=C5=vger.kernel.org=linux-ext4+bounces-16256-patchwork-incoming=ozlabs.org@ozlabs.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-ext4@vger.kernel.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "patchwork-incoming@ozlabs.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=VNG85iN9;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=ozlabs.org\n (client-ip=2404:9400:2221:ea00::3; helo=mail.ozlabs.org;\n envelope-from=srs0=vary=c5=vger.kernel.org=linux-ext4+bounces-16256-patchwork-incoming=ozlabs.org@ozlabs.org;\n receiver=patchwork.ozlabs.org)", "gandalf.ozlabs.org;\n arc=pass smtp.remote-ip=172.234.253.10 arc.chain=subspace.kernel.org", "gandalf.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=kernel.org", "gandalf.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=VNG85iN9;\n\tdkim-atps=neutral", "gandalf.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-ext4+bounces-16256-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"VNG85iN9\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201" ], "Received": [ "from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g66TS5bw1z1yHZ\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 07:18:04 +1000 (AEST)", "from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\tby gandalf.ozlabs.org (Postfix) with ESMTP id 4g66TS55s6z4wTD\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 07:18:04 +1000 (AEST)", "by gandalf.ozlabs.org (Postfix)\n\tid 4g66TS525Dz4wSd; Fri, 01 May 2026 07:18:04 +1000 (AEST)", "from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby gandalf.ozlabs.org (Postfix) with ESMTPS id 4g66TP1J7jz4wTD\n\tfor <patchwork-incoming@ozlabs.org>; Fri, 01 May 2026 07:18:01 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id EA59930265AA\n\tfor <patchwork-incoming@ozlabs.org>; Thu, 30 Apr 2026 21:16:05 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 21B063A6B6B;\n\tThu, 30 Apr 2026 21:16:05 +0000 (UTC)", "from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id D8BA4175A5;\n\tThu, 30 Apr 2026 21:16:04 +0000 (UTC)", "by smtp.kernel.org (Postfix) with ESMTPSA id A3321C2BCB3;\n\tThu, 30 Apr 2026 21:16:04 +0000 (UTC)" ], "ARC-Seal": [ "i=2; a=rsa-sha256; d=ozlabs.org; s=201707; t=1777583884; cv=pass;\n\tb=v/4/jEhqgIXG87yNW6TCVjeiWRPPirdr7JRqXvrwDTbwHsXeJ9kIQ1r7sn4y3WXeM84c9lKJSkikW6Fo/2LBF2UBPAtkwSBMEgHAV1ebR3xPNlzylqkDEHXv1v4V1tiyzCW8g1p3NiV1iievnP4WG3TWYGlUFaImmUou+4roauI7arMP7Je1YNPD6kU51z/Gtv2EC47GdO8ANMJFg4vpmCfx3xVuycGLO89UisWEwo25vNovfGlIGdVSC7hQXzL+u8u8zmnfBmJMrWvgsTtQ780HK5DQURohNioXIIBtsY3flWpP20rsP3Au9MRq2Kw8WEJrF+S66jMjdogD17HyQQ==", "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777583764; cv=none;\n b=PV5y7EEV32FNwn38wHVnLklvo7OHcPB2u0p9rL6Frzwyq3f1l9trUuDDqzlx0JvmqePvK6neefoZoskVE12wyv7JgpzdwXnY3VqPMQwhkfqsEry3cPWuio1J2DXvIN3VQg9qYxG5L4oWbrJL2NwL5abB3tSa4vTi9H4YDjE/vaY=" ], "ARC-Message-Signature": [ "i=2; a=rsa-sha256; d=ozlabs.org; s=201707;\n\tt=1777583884; c=relaxed/relaxed;\n\tbh=lDUKEnkwEARMCv3YebMjaklfe5mEwhyUG+j1PLHRLvg=;\n\th=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=SZUnd3sgy2h6r5cCCodSnoumSIaGx+5A7Zd5ayV5v1xhAiR20GWTDTT/QEAqwMBG2I1aBJIUMOFiciBKvUwPLlKZGir54QV9mXiN4flgBUylIMWq0v7vk/hlbZ+vamAaIhstCLN2dRDhlEQx7dShSQCsY8mUbX1E5pnVBuxDcD6Pzvt/nOR9dUvZ77tK+CUfWkzjLKX9ag4m60TIJ7FKY2Y0FSc11bU9/ftXLis41b9ghzl6xVKTGOU+GKTm9vF0k0fJwC1QxkEBGMNIiBFhOkwdYEWbshOIYGxm0CiEwAcsdtdmjeagY52JPkY+szkre6habEiaZPagO7mcdrK6qw==", "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777583764; c=relaxed/simple;\n\tbh=zBeHADBPSY0fHb6BGs6WaRFYGtkHkmbZ2SWR3rfLHW8=;\n\th=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=iYVJS8sfnF9fuKDYVXJBfPX9XrBkJV8rfQmmmzrM01jR5qCAr3lfw9OVvK8ybzBwcMU0Hj5YIeLtCzz5hV0N3OoErBrek3klduixbs74O7bcIl1KqepVzFFPNgk2qJppB0lHLmpk0n49Pwzkf8LSQfvwtN8agrSQbL/G0dy55lc=" ], "ARC-Authentication-Results": [ "i=2; gandalf.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=kernel.org;\n dkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=VNG85iN9; dkim-atps=neutral;\n spf=pass (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-ext4+bounces-16256-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org) smtp.mailfrom=vger.kernel.org", "i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=VNG85iN9; arc=none smtp.client-ip=10.30.226.201" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1777583764;\n\tbh=zBeHADBPSY0fHb6BGs6WaRFYGtkHkmbZ2SWR3rfLHW8=;\n\th=Date:Subject:From:To:Cc:In-Reply-To:References:From;\n\tb=VNG85iN9F8Qbce/EhnjlzyBexJjA8BKNDNXB3AejldSIcIRcNwutwXEuU+l/piyxC\n\t 56nUPbG/oGtJ7UhhosaRPnHyCQY46KTcsmw3Vp3/G5/BFCrrh1N/9/qxM16HF8Vl9p\n\t O+wlS902u1FMBOxSXcxfeDeHpbA+CZGRoIQKfbjGaZSCOQ81aWM9+nPef3zUBtyHPQ\n\t 0MFtMCEAt5D5K9E2TSWcqsxDglzfB5AO5VSgO+J1recV2rBjPeEGlvFYDX3DQK5DOh\n\t 22xCw2Pbcmn8yjIJqthHOSTO9BQsWS4prdYkZSvUKzT0D3GsR8xgTd4s51qmJSX0Ys\n\t 9BgK5o0D+Kehw==", "Date": "Thu, 30 Apr 2026 14:16:04 -0700", "Subject": "[PATCH 04/13] mount_service: use the new mount api for the mount\n service", "From": "\"Darrick J. Wong\" <djwong@kernel.org>", "To": "bernd@bsbernd.com, djwong@kernel.org", "Cc": "linux-fsdevel@vger.kernel.org, fuse-devel@lists.linux.dev,\n linux-ext4@vger.kernel.org, miklos@szeredi.hu, neal@gompa.dev,\n joannelkoong@gmail.com", "Message-ID": "<177758363604.1314717.1565554096353858559.stgit@frogsfrogsfrogs>", "In-Reply-To": "<177758363484.1314717.11777978893472254088.stgit@frogsfrogsfrogs>", "References": "<177758363484.1314717.11777978893472254088.stgit@frogsfrogsfrogs>", "Precedence": "bulk", "X-Mailing-List": "linux-ext4@vger.kernel.org", "List-Id": "<linux-ext4.vger.kernel.org>", "List-Subscribe": "<mailto:linux-ext4+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-ext4+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "X-Spam-Status": "No, score=-1.2 required=5.0 tests=ARC_SIGNED,ARC_VALID,\n\tDKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DMARC_PASS,\n\tMAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=disabled\n\tversion=4.0.1", "X-Spam-Checker-Version": "SpamAssassin 4.0.1 (2024-03-25) on gandalf.ozlabs.org" }, "content": "From: Darrick J. Wong <djwong@kernel.org>\n\nUse the new fsopen/fsmount system calls to mount the filesystem so that\nwe get somewhat better diagnostics if something gets screwed up.\n\nSigned-off-by: \"Darrick J. Wong\" <djwong@kernel.org>\n---\n lib/fuse_i.h | 3 \n meson.build | 15 ++\n util/mount_service.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 346 insertions(+), 4 deletions(-)", "diff": "diff --git a/lib/fuse_i.h b/lib/fuse_i.h\nindex 0ca13d132585f6..1710a872e19c72 100644\n--- a/lib/fuse_i.h\n+++ b/lib/fuse_i.h\n@@ -215,6 +215,9 @@ struct fuse_chan *fuse_chan_get(struct fuse_chan *ch);\n */\n void fuse_chan_put(struct fuse_chan *ch);\n \n+/* Special return value for mount functions to indicate fallback to fusermount3 is needed */\n+#define FUSE_MOUNT_FALLBACK_NEEDED (-2)\n+\n struct mount_opts *parse_mount_opts(struct fuse_args *args);\n void destroy_mount_opts(struct mount_opts *mo);\n void fuse_mount_version(void);\ndiff --git a/meson.build b/meson.build\nindex 66425a0d4cc16f..c8326b79fcee8f 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -135,6 +135,21 @@ special_funcs = {\n \tint main(int argc, char *argv[]) {\n return SD_LISTEN_FDS_START;\n \t}\n+ ''',\n+ 'new_mount_api': '''\n+ #define _GNU_SOURCE\n+ #include <sys/mount.h>\n+ #include <linux/mount.h>\n+ #include <unistd.h>\n+ #include <fcntl.h>\n+\n+ int main(void) {\n+ int fsfd = fsopen(\"fuse\", FSOPEN_CLOEXEC);\n+ int res = fsconfig(fsfd, FSCONFIG_SET_STRING, \"source\", \"test\", 0);\n+ int mntfd = fsmount(fsfd, FSMOUNT_CLOEXEC, 0);\n+ res = move_mount(mntfd, \"\", AT_FDCWD, \"/mnt\", MOVE_MOUNT_F_EMPTY_PATH | MOVE_MOUNT_T_EMPTY_PATH);\n+ return 0;\n+ }\n '''\n }\n \ndiff --git a/util/mount_service.c b/util/mount_service.c\nindex a43ff79c7bfb6f..f2a515a2cc3b37 100644\n--- a/util/mount_service.c\n+++ b/util/mount_service.c\n@@ -28,6 +28,11 @@\n #include <sys/ioctl.h>\n #include <linux/fs.h>\n \n+#ifdef HAVE_NEW_MOUNT_API\n+#include <sys/mount.h>\n+#include <linux/mount.h>\n+#endif\n+\n #include \"mount_util.h\"\n #include \"util.h\"\n #include \"fuse_i.h\"\n@@ -68,6 +73,9 @@ struct mount_service {\n \t/* fd for mount point */\n \tint mountfd;\n \n+\t/* fd for fsopen */\n+\tint fsopenfd;\n+\n \t/* did we actually mount successfully? */\n \tbool mounted;\n \n@@ -187,6 +195,7 @@ static int mount_service_init(struct mount_service *mo, int argc, char *argv[])\n \tmo->argvfd = -1;\n \tmo->fusedevfd = -1;\n \tmo->mountfd = -1;\n+\tmo->fsopenfd = -1;\n \n \tfor (i = 0; i < argc; i++) {\n \t\tif (!strcmp(argv[i], \"-t\") && i + 1 < argc) {\n@@ -782,6 +791,20 @@ static inline const char *fsname(const struct mount_service *mo)\n \treturn mo->fuseblk ? \"fuseblk\" : \"fuse\";\n }\n \n+#ifdef HAVE_NEW_MOUNT_API\n+static void try_fsopen(struct mount_service *mo)\n+{\n+\t/*\n+\t * As of Linux 7.0 you can pass subtypes to fsopen, but the manpage for\n+\t * fsopen only says that you can pass any value of the second column of\n+\t * /proc/filesystems into fsopen.\n+\t */\n+\tmo->fsopenfd = fsopen(fsname(mo), FSOPEN_CLOEXEC);\n+}\n+#else\n+# define try_fsopen(...)\t((void)0)\n+#endif\n+\n static int mount_service_handle_fsopen_cmd(struct mount_service *mo,\n \t\t\t\t\t const struct fuse_service_packet *p,\n \t\t\t\t\t size_t psz)\n@@ -820,15 +843,52 @@ static int mount_service_handle_fsopen_cmd(struct mount_service *mo,\n \t}\n \tmo->fsopened = true;\n \n+\t/* If this fails we fall back on mount(); oc->value is mutated */\n+\ttry_fsopen(mo);\n \treturn mount_service_send_reply(mo, 0);\n }\n \n+#ifdef HAVE_NEW_MOUNT_API\n+/* callers must preserve errno */\n+static void emit_fsconfig_messages(const struct mount_service *mo)\n+{\n+\tuint8_t buf[BUFSIZ];\n+\tssize_t sz;\n+\n+\twhile ((sz = read(mo->fsopenfd, buf, sizeof(buf) - 1)) >= 1) {\n+\t\tif (buf[sz - 1] == '\\n')\n+\t\t\tbuf[--sz] = '\\0';\n+\t\telse\n+\t\t\tbuf[sz] = '\\0';\n+\n+\t\tif (!*buf)\n+\t\t\tcontinue;\n+\n+\t\tswitch (buf[0]) {\n+\t\tcase 'e':\n+\t\t\tfprintf(stderr, \"Error: %s\\n\", buf + 2);\n+\t\t\tbreak;\n+\t\tcase 'w':\n+\t\t\tfprintf(stderr, \"Warning: %s\\n\", buf + 2);\n+\t\t\tbreak;\n+\t\tcase 'i':\n+\t\t\tfprintf(stderr, \"Info: %s\\n\", buf + 2);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tfprintf(stderr, \" %s\\n\", buf);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+}\n+#endif\n+\n static int mount_service_handle_source_cmd(struct mount_service *mo,\n \t\t\t\t\t const struct fuse_service_packet *p,\n \t\t\t\t\t size_t psz)\n {\n \tstruct fuse_service_string_command *oc =\n \t\t\tcontainer_of(p, struct fuse_service_string_command, p);\n+\tchar *source;\n \n \tif (psz < sizeof_fuse_service_string_command(1)) {\n \t\tfprintf(stderr, \"%s: source command too small\\n\",\n@@ -848,8 +908,8 @@ static int mount_service_handle_source_cmd(struct mount_service *mo,\n \t\treturn mount_service_send_reply(mo, EINVAL);\n \t}\n \n-\tmo->source = strdup(oc->value);\n-\tif (!mo->source) {\n+\tsource = strdup(oc->value);\n+\tif (!source) {\n \t\tint error = errno;\n \n \t\tfprintf(stderr, \"%s: alloc source string: %s\\n\",\n@@ -857,6 +917,23 @@ static int mount_service_handle_source_cmd(struct mount_service *mo,\n \t\treturn mount_service_send_reply(mo, error);\n \t}\n \n+#ifdef HAVE_NEW_MOUNT_API\n+\tif (mo->fsopenfd >= 0) {\n+\t\tint ret = fsconfig(mo->fsopenfd, FSCONFIG_SET_STRING, \"source\",\n+\t\t\t oc->value, 0);\n+\t\tif (ret) {\n+\t\t\tint error = errno;\n+\n+\t\t\tfprintf(stderr, \"%s: fsconfig source: %s\\n\",\n+\t\t\t\tmo->msgtag, strerror(error));\n+\t\t\temit_fsconfig_messages(mo);\n+\t\t\tfree(source);\n+\t\t\treturn mount_service_send_reply(mo, error);\n+\t\t}\n+\t}\n+#endif\n+\n+\tmo->source = source;\n \treturn mount_service_send_reply(mo, 0);\n }\n \n@@ -866,6 +943,9 @@ static int mount_service_handle_mntopts_cmd(struct mount_service *mo,\n {\n \tstruct fuse_service_string_command *oc =\n \t\t\tcontainer_of(p, struct fuse_service_string_command, p);\n+\tchar *tokstr = oc->value;\n+\tchar *tok, *savetok;\n+\tchar *mntopts;\n \n \tif (psz < sizeof_fuse_service_string_command(1)) {\n \t\tfprintf(stderr, \"%s: mount options command too small\\n\",\n@@ -885,8 +965,8 @@ static int mount_service_handle_mntopts_cmd(struct mount_service *mo,\n \t\treturn mount_service_send_reply(mo, EINVAL);\n \t}\n \n-\tmo->mntopts = strdup(oc->value);\n-\tif (!mo->mntopts) {\n+\tmntopts = strdup(oc->value);\n+\tif (!mntopts) {\n \t\tint error = errno;\n \n \t\tfprintf(stderr, \"%s: alloc mount options string: %s\\n\",\n@@ -894,6 +974,47 @@ static int mount_service_handle_mntopts_cmd(struct mount_service *mo,\n \t\treturn mount_service_send_reply(mo, error);\n \t}\n \n+\t/* strtok_r mutates tokstr aka oc->value */\n+\twhile ((tok = strtok_r(tokstr, \",\", &savetok)) != NULL) {\n+\t\tchar *equals = strchr(tok, '=');\n+\t\tchar oldchar = 0;\n+\n+\t\tif (equals) {\n+\t\t\toldchar = *equals;\n+\t\t\t*equals = 0;\n+\t\t}\n+\n+#ifdef HAVE_NEW_MOUNT_API\n+\t\tif (mo->fsopenfd >= 0) {\n+\t\t\tint ret;\n+\n+\t\t\tif (equals)\n+\t\t\t\tret = fsconfig(mo->fsopenfd,\n+\t\t\t\t\t FSCONFIG_SET_STRING, tok,\n+\t\t\t\t\t equals + 1, 0);\n+\t\t\telse\n+\t\t\t\tret = fsconfig(mo->fsopenfd,\n+\t\t\t\t\t FSCONFIG_SET_FLAG, tok,\n+\t\t\t\t\t NULL, 0);\n+\t\t\tif (ret) {\n+\t\t\t\tint error = errno;\n+\n+\t\t\t\tfprintf(stderr, \"%s: set mount option: %s\\n\",\n+\t\t\t\t\tmo->msgtag, strerror(error));\n+\t\t\t\temit_fsconfig_messages(mo);\n+\t\t\t\tfree(mntopts);\n+\t\t\t\treturn mount_service_send_reply(mo, error);\n+\t\t\t}\n+\t\t}\n+#endif\n+\n+\t\tif (equals)\n+\t\t\t*equals = oldchar;\n+\n+\t\ttokstr = NULL;\n+\t}\n+\n+\tmo->mntopts = mntopts;\n \treturn mount_service_send_reply(mo, 0);\n }\n \n@@ -1181,6 +1302,201 @@ static int mount_service_regular_mount(struct mount_service *mo,\n \treturn ret;\n }\n \n+#ifdef HAVE_NEW_MOUNT_API\n+struct ms_to_mount_map {\n+\tunsigned long ms_flag;\n+\tunsigned int mount_attr_flag;\n+};\n+\n+static const struct ms_to_mount_map attrs[] = {\n+\t{ MS_RDONLY,\t\tMOUNT_ATTR_RDONLY },\n+\t{ MS_NOSUID,\t\tMOUNT_ATTR_NOSUID },\n+\t{ MS_NODEV,\t\tMOUNT_ATTR_NODEV },\n+\t{ MS_NOEXEC,\t\tMOUNT_ATTR_NOEXEC },\n+\t{ MS_RELATIME,\t\tMOUNT_ATTR_RELATIME },\n+\t{ MS_NOATIME,\t\tMOUNT_ATTR_NOATIME },\n+\t{ MS_STRICTATIME,\tMOUNT_ATTR_STRICTATIME },\n+\t{ MS_NODIRATIME,\tMOUNT_ATTR_NODIRATIME },\n+#ifdef MOUNT_ATTR_NOSYMFOLLOW\n+\t{ MS_NOSYMFOLLOW,\tMOUNT_ATTR_NOSYMFOLLOW },\n+#endif\n+\t{ 0, 0 },\n+};\n+\n+static void get_mount_attr_flags(const struct fuse_service_mount_command *oc,\n+\t\t\t\t unsigned int *attr_flags,\n+\t\t\t\t unsigned long *leftover_ms_flags)\n+{\n+\tconst struct ms_to_mount_map *i;\n+\tunsigned int ms_flags = ntohl(oc->ms_flags);\n+\tunsigned int mount_attr_flags = 0;\n+\n+\tfor (i = attrs; i->ms_flag != 0; i++) {\n+\t\tif (ms_flags & i->ms_flag)\n+\t\t\tmount_attr_flags |= i->mount_attr_flag;\n+\t\tms_flags &= ~i->ms_flag;\n+\t}\n+\n+\t*leftover_ms_flags = ms_flags;\n+\t*attr_flags = mount_attr_flags;\n+}\n+\n+struct ms_to_str_map {\n+\tunsigned long ms_flag;\n+\tconst char *string;\n+};\n+\n+static const struct ms_to_str_map strflags[] = {\n+\t{ MS_SYNCHRONOUS,\t\"sync\" },\n+\t{ MS_DIRSYNC,\t\t\"dirsync\" },\n+\t{ MS_LAZYTIME,\t\t\"lazytime\" },\n+\t{ 0, 0 },\n+};\n+\n+static int set_ms_flags(struct mount_service *mo, unsigned long ms_flags)\n+{\n+\tconst struct ms_to_str_map *i;\n+\tint ret;\n+\n+\tfor (i = strflags; i->ms_flag != 0; i++) {\n+\t\tif (!(ms_flags & i->ms_flag))\n+\t\t\tcontinue;\n+\n+\t\tret = fsconfig(mo->fsopenfd, FSCONFIG_SET_FLAG, i->string,\n+\t\t\t NULL, 0);\n+\t\tif (ret) {\n+\t\t\tint error = errno;\n+\n+\t\t\tfprintf(stderr, \"%s: set %s option: %s\\n\",\n+\t\t\t\tmo->msgtag, i->string, strerror(error));\n+\t\t\temit_fsconfig_messages(mo);\n+\n+\t\t\terrno = error;\n+\t\t\treturn -1;\n+\t\t}\n+\t\tms_flags &= ~i->ms_flag;\n+\t}\n+\n+\t/*\n+\t * We can't translate all the supplied MS_ flags into MOUNT_ATTR_ flags\n+\t * or string flags! Return a magic code so the caller will fall back\n+\t * to regular mount(2).\n+\t */\n+\tif (ms_flags)\n+\t\treturn FUSE_MOUNT_FALLBACK_NEEDED;\n+\n+\treturn 0;\n+}\n+\n+static int mount_service_fsopen_mount(struct mount_service *mo,\n+\t\t\t\t struct fuse_service_mount_command *oc,\n+\t\t\t\t struct stat *stbuf)\n+{\n+\tchar tmp[64];\n+\tunsigned long ms_flags;\n+\tunsigned int attr_flags;\n+\tint mfd;\n+\tint error;\n+\tint ret;\n+\n+\tget_mount_attr_flags(oc, &attr_flags, &ms_flags);\n+\n+\tret = set_ms_flags(mo, ms_flags);\n+\tif (ret == FUSE_MOUNT_FALLBACK_NEEDED)\n+\t\treturn ret;\n+\tif (ret) {\n+\t\terror = errno;\n+\t\tgoto fail_mount;\n+\t}\n+\n+\tret = fsconfig(mo->fsopenfd, FSCONFIG_SET_STRING, \"subtype\",\n+\t\t mo->subtype, 0);\n+\tif (ret) {\n+\t\terror = errno;\n+\n+\t\t/* The subtype option was merged after fsopen */\n+\t\tif (error == EINVAL)\n+\t\t\treturn FUSE_MOUNT_FALLBACK_NEEDED;\n+\n+\t\tfprintf(stderr, \"%s: set subtype option: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_fsconfig;\n+\t}\n+\n+\tsnprintf(tmp, sizeof(tmp), \"%i\", mo->fusedevfd);\n+\tret = fsconfig(mo->fsopenfd, FSCONFIG_SET_STRING, \"fd\", tmp, 0);\n+\tif (ret) {\n+\t\terror = errno;\n+\t\tfprintf(stderr, \"%s: set fd option: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_fsconfig;\n+\t}\n+\n+\tsnprintf(tmp, sizeof(tmp), \"%o\", stbuf->st_mode & S_IFMT);\n+\tret = fsconfig(mo->fsopenfd, FSCONFIG_SET_STRING, \"rootmode\", tmp, 0);\n+\tif (ret) {\n+\t\terror = errno;\n+\t\tfprintf(stderr, \"%s: set rootmode option: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_fsconfig;\n+\t}\n+\n+\tsnprintf(tmp, sizeof(tmp), \"%u\", getuid());\n+\tret = fsconfig(mo->fsopenfd, FSCONFIG_SET_STRING, \"user_id\", tmp, 0);\n+\tif (ret) {\n+\t\terror = errno;\n+\t\tfprintf(stderr, \"%s: set user_id option: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_fsconfig;\n+\t}\n+\n+\tsnprintf(tmp, sizeof(tmp), \"%u\", getgid());\n+\tret = fsconfig(mo->fsopenfd, FSCONFIG_SET_STRING, \"group_id\", tmp, 0);\n+\tif (ret) {\n+\t\terror = errno;\n+\t\tfprintf(stderr, \"%s: set group_id option: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_fsconfig;\n+\t}\n+\n+\tret = fsconfig(mo->fsopenfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);\n+\tif (ret) {\n+\t\terror = errno;\n+\t\tfprintf(stderr, \"%s: creating filesystem: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_fsconfig;\n+\t}\n+\n+\tmfd = fsmount(mo->fsopenfd, FSMOUNT_CLOEXEC, attr_flags);\n+\tif (mfd < 0) {\n+\t\terror = errno;\n+\t\tfprintf(stderr, \"%s: fsmount: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_fsconfig;\n+\t}\n+\n+\tret = move_mount(mfd, \"\", mo->mountfd, \"\",\n+\t\t\t MOVE_MOUNT_F_EMPTY_PATH | MOVE_MOUNT_T_EMPTY_PATH);\n+\tclose(mfd);\n+\tif (ret) {\n+\t\terror = errno;\n+\t\tfprintf(stderr, \"%s: move_mount: %s\\n\",\n+\t\t\tmo->msgtag, strerror(error));\n+\t\tgoto fail_mount;\n+\t}\n+\n+\tmo->mounted = true;\n+\treturn mount_service_send_reply(mo, 0);\n+\n+fail_fsconfig:\n+\temit_fsconfig_messages(mo);\n+fail_mount:\n+\treturn mount_service_send_reply(mo, error);\n+}\n+#else\n+# define mount_service_fsopen_mount(...)\t(FUSE_MOUNT_FALLBACK_NEEDED)\n+#endif\n+\n static int mount_service_handle_mount_cmd(struct mount_service *mo,\n \t\t\t\t\t struct fuse_service_packet *p,\n \t\t\t\t\t size_t psz)\n@@ -1222,6 +1538,12 @@ static int mount_service_handle_mount_cmd(struct mount_service *mo,\n \t\treturn mount_service_send_reply(mo, error);\n \t}\n \n+\tif (mo->fsopenfd >= 0) {\n+\t\tret = mount_service_fsopen_mount(mo, oc, &stbuf);\n+\t\tif (ret != FUSE_MOUNT_FALLBACK_NEEDED)\n+\t\t\treturn ret;\n+\t}\n+\n \treturn mount_service_regular_mount(mo, oc, &stbuf);\n }\n \n@@ -1301,6 +1623,7 @@ static void mount_service_destroy(struct mount_service *mo)\n \tclose(mo->mountfd);\n \tclose(mo->fusedevfd);\n \tclose(mo->argvfd);\n+\tclose(mo->fsopenfd);\n \tshutdown(mo->sockfd, SHUT_RDWR);\n \tclose(mo->sockfd);\n \n@@ -1316,6 +1639,7 @@ static void mount_service_destroy(struct mount_service *mo)\n \tmo->argvfd = -1;\n \tmo->fusedevfd = -1;\n \tmo->mountfd = -1;\n+\tmo->fsopenfd = -1;\n }\n \n int mount_service_main(int argc, char *argv[])\n", "prefixes": [ "04/13" ] }