{"id":2226964,"url":"http://patchwork.ozlabs.org/api/patches/2226964/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-ext4/patch/177689989611.3821326.8531164266373897005.stgit@frogsfrogsfrogs/","project":{"id":8,"url":"http://patchwork.ozlabs.org/api/projects/8/?format=json","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,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<177689989611.3821326.8531164266373897005.stgit@frogsfrogsfrogs>","list_archive_url":null,"date":"2026-04-22T23:24:35","name":"[04/10] libext2fs: fix MMP code to work with unixfd IO manager","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"b40b62d8670cf0a112284c0036dd57a2d574a6ee","submitter":{"id":77032,"url":"http://patchwork.ozlabs.org/api/people/77032/?format=json","name":"Darrick J. Wong","email":"djwong@kernel.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-ext4/patch/177689989611.3821326.8531164266373897005.stgit@frogsfrogsfrogs/mbox/","series":[{"id":501127,"url":"http://patchwork.ozlabs.org/api/series/501127/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-ext4/list/?series=501127","date":"2026-04-22T23:23:47","name":"[01/10] libext2fs: make it possible to extract the fd from an IO manager","version":1,"mbox":"http://patchwork.ozlabs.org/series/501127/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2226964/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2226964/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <SRS0=gB5Z=CV=vger.kernel.org=linux-ext4+bounces-16008-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=GJA2h8lH;\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=gb5z=cv=vger.kernel.org=linux-ext4+bounces-16008-patchwork-incoming=ozlabs.org@ozlabs.org;\n receiver=patchwork.ozlabs.org)","gandalf.ozlabs.org;\n arc=pass smtp.remote-ip=\"2600:3c0a:e001:db::12fc:5321\"\n 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=GJA2h8lH;\n\tdkim-atps=neutral","gandalf.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-ext4+bounces-16008-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=\"GJA2h8lH\"","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 4g1FkS6Ht6z1yDD\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 09:27:28 +1000 (AEST)","from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\tby gandalf.ozlabs.org (Postfix) with ESMTP id 4g1FkS5nQmz4wHx\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 09:27:28 +1000 (AEST)","by gandalf.ozlabs.org (Postfix)\n\tid 4g1FkS5hzsz4wCM; Thu, 23 Apr 2026 09:27:28 +1000 (AEST)","from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\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 4g1FkP2bFlz4wHx\n\tfor <patchwork-incoming@ozlabs.org>; Thu, 23 Apr 2026 09:27:25 +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 E282530C66C6\n\tfor <patchwork-incoming@ozlabs.org>; Wed, 22 Apr 2026 23:24:39 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 177463A3833;\n\tWed, 22 Apr 2026 23:24:39 +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 CDC5C1D6DA9;\n\tWed, 22 Apr 2026 23:24:38 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 6CD22C2BCAF;\n\tWed, 22 Apr 2026 23:24:38 +0000 (UTC)"],"ARC-Seal":["i=2; a=rsa-sha256; d=ozlabs.org; s=201707; t=1776900448; cv=pass;\n\tb=IyRt66a9NwiXzAxq8K6DOC/osQ+Ogg9lHVXRTW0Xr9b7u8ZKvAA4ARcA+FeWnZkwtBFwo3xS3odwCdIoyaJCbfXzCp1RhYs/Qe40XFvqJwS/h9YKO6FlDpTRD5F4/WM1CnL6FDVAPNqdtD7ryb3XLx04e91HTGkGOJ6lHwtz2ATtrqKioiwFhs6QM7WrzJifw5dx3/odW2VTGZ9Px1I7VdRse6QBvgZvoluiR44wI2aBmbX4TGMzzUW2tlRJ68m9CpOigdozJNoywXPTiVwNO/7LvPoTe46PzwZow9fVkJGbWb4s9T0NTqiK99QLZRDFtY6kljiaVbhDLbDl9ewi2g==","i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776900278; cv=none;\n b=q1fWFdejAnKIPccIyxw3jf27XhAbAg8EWVNsPQaSIqFwqq758Ho/OlI38A2AacksB/A2n7fzQqHz9b+SK/+AQx+LUb+HswPkmtzKbzOP8kh3BHCjnyD7GtaOGuKKwaVDucXn4WG0w9Tugfz0MoJKkgnSHN/WcJZswL+rQuU25no="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=ozlabs.org; s=201707;\n\tt=1776900448; c=relaxed/relaxed;\n\tbh=tVlwmVi0eoAxD7e+9VpI8NojxdwOdIFl2WkHxOf1HOs=;\n\th=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=Vk11BNARUCVo0SeQC8QTHvoItZVogHC8KhXUWO3BH7qNTeHNoJ64t09WXpoZhbxJzAWOFnp+tehPZtHr6BomGS8OVqbNTxBphaAsqtiMDc/rCuahWcPr3AJDCbSKWXax4RWG50smgQDWRXcF6lyNN5CD8X9LamzRAM1LlhLFylHlz9c1w2LeTBjEPFfv1csEZQeRzsxmWvnjuyqgpWJLPumMxWzhIJXslGRcRrdY1KGOzjzdI/ohen234bzkuIPTHoPKrTCUewR0R2phW1CDE+caOuZ9AvtcVON6llge/P6U+W535Nx9V99PD3NSP5obo8fd8BlrYecR77xS2K3IwQ==","i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776900278; c=relaxed/simple;\n\tbh=n3hiKEVglNnaTzGKlSiTXniL2rk1+rBKTzXjMnfRhdY=;\n\th=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=IBinKDMdrSz933scGiH5qTMcUZ9+q5jaEh/98X6U9wcctwb36loZCMZz5w6goebMUhTcNT0lNv13ZQ29lrK2on27C/OZp+jvS4/P+/n4RUPHracCYR1kk6f131yCh+zFU0Vfk7xgtbEoT/NdrCD3VAIjtXbwWrWqyjxNtM/IByY="],"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=GJA2h8lH; dkim-atps=neutral;\n spf=pass (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-ext4+bounces-16008-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=GJA2h8lH; 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=1776900278;\n\tbh=n3hiKEVglNnaTzGKlSiTXniL2rk1+rBKTzXjMnfRhdY=;\n\th=Date:Subject:From:To:Cc:In-Reply-To:References:From;\n\tb=GJA2h8lHug5LaGKqm3jSmgsrbSCgEejzHdyb53J8o4Ev7kVlj4Ew2w6Bxu8FEXkmW\n\t EvDmGuA2eS2ha5gLCfXVn0YsKEFD1Je9XJykokUVFsqVygaFVqPtNm+sR+euG8G7p1\n\t EOhWNk5pNcz2xc3zO2cekRsqNqkzfdfHIZPls8NKoRNPTZ4fxxecwGw66ZdI0IkG38\n\t hrLletWbTu7ovBsqEBbz2MwctTWyzLhyTX2qdSdINVVMtBMV+6StjSEJ9SECtuomA2\n\t xXq4OzCmMFADG0ZBE7CVIDBsukWHcg3QFtVyy+1xDNFK+qBYgaelLI2m/615syaC/f\n\t UGas3kD/ixEBQ==","Date":"Wed, 22 Apr 2026 16:24:35 -0700","Subject":"[PATCH 04/10] libext2fs: fix MMP code to work with unixfd IO manager","From":"\"Darrick J. Wong\" <djwong@kernel.org>","To":"tytso@mit.edu","Cc":"linux-fsdevel@vger.kernel.org, fuse-devel@lists.linux.dev,\n linux-ext4@vger.kernel.org, neal@gompa.dev, joannelkoong@gmail.com,\n miklos@szeredi.hu, bernd@bsbernd.com","Message-ID":"<177689989611.3821326.8531164266373897005.stgit@frogsfrogsfrogs>","In-Reply-To":"<177689989498.3821326.15497525132012299039.stgit@frogsfrogsfrogs>","References":"<177689989498.3821326.15497525132012299039.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\nThe MMP code wants to be able to read and write the MMP block directly\nto storage so that the pagecache does not get in the way.  This is\ncritical for correct operation of MMP, because it is guarding against\ntwo cluster nodes trying to change the filesystem at the same time.\n\nUnfortunately there's no convenient way to tell an IO manager to perform\na particular IO in directio mode, so the MMP code open()s the filesystem\nsource device a second time so that it can set O_DIRECT and maintain its\nown file position independently of the IO channel.  This is a gross\nlayering violation.\n\nFor unprivileged containerized fuse4fs, we're going to have a privileged\nmount helper pass us the fd to the block device, so we'll be using the\nunixfd IO manager.  The enhanced security posture provided by the\nservice definition file (minimal /dev) means that we cannot reopen the\nsource device.  In this case, MMP can only duplicate the fd and use the\nIO channel carefully.\n\nFix this (sort of) by detecting the unixfd IO manager and duplicating\nthe open fd if it's in use.  This adds a requirement that the unixfd\noriginally be opened in O_DIRECT mode if the filesystem is on a block\ndevice, but that's the best we can do here.\n\nSigned-off-by: \"Darrick J. Wong\" <djwong@kernel.org>\n---\n lib/ext2fs/ext2fs.h  |    1 +\n lib/ext2fs/ext2fsP.h |    4 ++\n lib/ext2fs/mmp.c     |   95 +++++++++++++++++++++++++++++++++++++++++++++++++-\n lib/ext2fs/unix_io.c |    2 +\n 4 files changed, 100 insertions(+), 2 deletions(-)","diff":"diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h\nindex c4fcb10bea0fb9..02c3cbcea92482 100644\n--- a/lib/ext2fs/ext2fs.h\n+++ b/lib/ext2fs/ext2fs.h\n@@ -225,6 +225,7 @@ typedef struct ext2_file *ext2_file_t;\n  * Internal flags for use by the ext2fs library only\n  */\n #define EXT2_FLAG2_USE_FAKE_TIME\t0x000000001\n+#define EXT2_FLAG2_MMP_USE_IOCHANNEL\t0x000000002\n \n /*\n  * Special flag in the ext2 inode i_flag field that means that this is\ndiff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h\nindex 428081c9e2ff38..bdc92991e7dda0 100644\n--- a/lib/ext2fs/ext2fsP.h\n+++ b/lib/ext2fs/ext2fsP.h\n@@ -218,3 +218,7 @@ errcode_t ext2fs_remove_exit_fn(ext2_exit_fn fn, void *data);\n         (sizeof(array) / sizeof(array[0]))\n \n #define EXT2FS_BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2*!!(cond)]))\n+\n+#ifndef _WIN32\n+int possible_unixfd_pathname(const char *path);\n+#endif\ndiff --git a/lib/ext2fs/mmp.c b/lib/ext2fs/mmp.c\nindex cb15a18fce5547..188cdb68900e97 100644\n--- a/lib/ext2fs/mmp.c\n+++ b/lib/ext2fs/mmp.c\n@@ -26,9 +26,11 @@\n #include <sys/types.h>\n #include <sys/stat.h>\n #include <fcntl.h>\n+#include <limits.h>\n \n #include \"ext2fs/ext2_fs.h\"\n #include \"ext2fs/ext2fs.h\"\n+#include \"ext2fs/ext2fsP.h\"\n \n #ifndef O_DIRECT\n #define O_DIRECT 0\n@@ -48,6 +50,86 @@ errcode_t ext2fs_mmp_get_mem(ext2_filsys fs, void **ptr)\n \treturn ext2fs_get_memalign(fs->blocksize, align, ptr);\n }\n \n+#ifdef _WIN32\n+static int ext2fs_mmp_open_device(ext2_filsys fs, int flags)\n+{\n+\treturn open(fs->device_name, flags);\n+}\n+#else\n+static int ext2fs_mmp_open_device(ext2_filsys fs, int flags)\n+{\n+\tstruct stat stbuf;\n+\tchar path[64];\n+\tint maybe_fd = -1;\n+\tint new_fd;\n+\tint ret;\n+\terrcode_t retval = 0;\n+\n+\t/*\n+\t * If we can't possibly be using the unixfd IO manager, open the device\n+\t * a second time, which is the historical behavior.  This is a huge\n+\t * and historic layering violation!\n+\t *\n+\t * It's also broken if the unixfd IO manager was passed a string with a\n+\t * file descriptor number instead of a /dev/fd/XX path, but the\n+\t * internet thinks there are no users of the manager outside of Google.\n+\t */\n+\tif (!possible_unixfd_pathname(fs->device_name))\n+\t\treturn open(fs->device_name, flags);\n+\n+\t/*\n+\t * Try to get the fd of the open block device.  If this fails for any\n+\t * reason, fall back to the classic open path.\n+\t */\n+\tretval = io_channel_get_fd(fs->io, &maybe_fd);\n+\tif (retval || maybe_fd < 0)\n+\t\treturn open(fs->device_name, flags);\n+\n+\t/*\n+\t * We extracted the fd from the IO manager.\n+\t *\n+\t * Skip directio if this is a regular file, just ext2fs_mmp_read does.\n+\t * Note that the O_DIRECT-clearing logic in the caller might not have\n+\t * cleared the bit because it is path based.\n+\t */\n+\tif (fstat(maybe_fd, &stbuf) == 0 && S_ISREG(stbuf.st_mode))\n+\t\tflags &= ~O_DIRECT;\n+\n+\t/*\n+\t * Try to reopen the same file descriptor, but with the new mode flags.\n+\t * If that works then we're done.  Note that these magic symlinks do\n+\t * not have to resolve anywhere.\n+\t */\n+\tsnprintf(path, sizeof(path), \"/dev/fd/%d\", maybe_fd);\n+\tnew_fd = open(path, flags);\n+\tif (new_fd >= 0)\n+\t\treturn new_fd;\n+\n+\t/*\n+\t * Reopening didn't work.  Instead, duplicate the file descriptor and\n+\t * check that we actually got directio if that's required.  Note that\n+\t * we can't change the mode on the IO channel's fd because we already\n+\t * set it up for buffered IO.\n+\t */\n+\tnew_fd = dup(maybe_fd);\n+\tif (flags & O_DIRECT) {\n+\t\tret = fcntl(new_fd, F_GETFL);\n+\t\tif (ret < 0 || !(ret & O_DIRECT)) {\n+\t\t\tclose(new_fd);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * The MMP fd shadows the io channel fd, so we must use that for all\n+\t * MMP block accesses because the two fds share the same file position\n+\t * and O_DIRECT state, and the iochannel must know about that.\n+\t */\n+\tfs->flags2 |= EXT2_FLAG2_MMP_USE_IOCHANNEL;\n+\treturn new_fd;\n+}\n+#endif\n+\n errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf)\n {\n #ifdef CONFIG_MMP\n@@ -77,7 +159,7 @@ errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf)\n \t\t    S_ISREG(st.st_mode))\n \t\t\tflags &= ~O_DIRECT;\n \n-\t\tfs->mmp_fd = open(fs->device_name, flags);\n+\t\tfs->mmp_fd = ext2fs_mmp_open_device(fs, flags);\n \t\tif (fs->mmp_fd < 0) {\n \t\t\tretval = EXT2_ET_MMP_OPEN_DIRECT;\n \t\t\tgoto out;\n@@ -90,6 +172,15 @@ errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf)\n \t\t\treturn retval;\n \t}\n \n+\tif (fs->flags2 & EXT2_FLAG2_MMP_USE_IOCHANNEL) {\n+\t\tretval = io_channel_read_blk64(fs->io, mmp_blk, -fs->blocksize,\n+\t\t\t\t\t       fs->mmp_cmp);\n+\t\tif (retval)\n+\t\t\treturn retval;\n+\n+\t\tgoto read_compare;\n+\t}\n+\n \tif ((blk64_t) ext2fs_llseek(fs->mmp_fd, mmp_blk * fs->blocksize,\n \t\t\t\t    SEEK_SET) !=\n \t    mmp_blk * fs->blocksize) {\n@@ -102,6 +193,7 @@ errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf)\n \t\tgoto out;\n \t}\n \n+read_compare:\n \tmmp_cmp = fs->mmp_cmp;\n \n \tif (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) &&\n@@ -428,6 +520,7 @@ errcode_t ext2fs_mmp_stop(ext2_filsys fs)\n \n mmp_error:\n \tif (fs->mmp_fd >= 0) {\n+\t\tfs->flags2 &= ~EXT2_FLAG2_MMP_USE_IOCHANNEL;\n \t\tclose(fs->mmp_fd);\n \t\tfs->mmp_fd = -1;\n \t}\ndiff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c\nindex a9b1fac62a0250..567bbd9493f7f1 100644\n--- a/lib/ext2fs/unix_io.c\n+++ b/lib/ext2fs/unix_io.c\n@@ -1152,7 +1152,7 @@ static errcode_t unix_open_channel(const char *name, int fd,\n #define DEV_FD_PATH\t\"/dev/fd/\"\n #define DEV_FD_PATHLEN\t(sizeof(DEV_FD_PATH) - 1)\n \n-static int possible_unixfd_pathname(const char *path)\n+int possible_unixfd_pathname(const char *path)\n {\n \treturn strncmp(DEV_FD_PATH, path, DEV_FD_PATHLEN) == 0;\n }\n","prefixes":["04/10"]}