From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D645606A323 for ; Fri, 13 Nov 2026 23:36:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amutable-com.20260707.gappssmtp.com header.i=@amutable-com.20260707.gappssmtp.com header.a=rsa-sha256 header.s=20260707 header.b=qBXMkKQK Received: from boromir.ozlabs.org (localhost [127.0.0.1]) by lists.ozlabs.org (Postfix) with ESMTP id 4jRDCx5mN7z3cZm; Sat, 14 Nov 2026 10:36:13 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; arc=none smtp.remote-ip="2a00:1450:4864:20::32e" ARC-Seal: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1794565726; cv=none; b=j21kMTOZcOZkJxbtTHaRyBZBQKCPqlY75RKsPWwDpeYkvXPL8AJpkGy/ntgDCaRxLDSmv/3aql9ANJwDe5UzSnQLRoSdSHjT0nzExXrjdOPOov2qXx/oOJa3C/uAJC7eYpcmYXjqFrGu+gA7X3JyxEjMhoEIhC0crAjIbjru9d/rgZVfFwP/ynckm/a3FTmD32bksHZBFfPQ0o60G+HtunHmI8hn65AXFlDCpIiynIerndHNeu0spIBkhv5Ql40mdS5GUa4Q06lBW7DwU/i5XuFQrUb7Un+SjQZdQUATJpk0v9eBiXjRFduoysQBPORjpJIgLPtYn8aF/SB7TA1iHg== ARC-Message-Signature: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1794565726; c=relaxed/relaxed; bh=HIAZ+a2RY8snYu8gjwIzGL7aFLB+UDjcbceUrGWDUl0=; h=Message-ID:Subject:From:To:Cc:Date:In-Reply-To:References: Content-Type:MIME-Version; b=Hy/FGFd2b2vmLsiltZuTJmvYf0eTXU7IV1g/zUhXRLX3rx/UQbFtiRkghsPok5IykizEN2wvFTEsQA3MCVN6JjZD5QINB0wG5zEkmB9r1JdjoF2cW0pUgFE60PrvQ15gRih4Tw7iUDl8VCcpdsQ8M480/9vlQcy3UmDAgoPgOEd+utLp5tK1CfY8d2hjF+86wIBHJwn8AYLjaE71ciKboAaxDdCkCL9wKBwFl3l2QRDeNxbtcQFyM8FjokTkYlaLwf2NR1yXsrwCeehyZNeqmnPo9iWueBHweYRRPYJG7fb7tbvv50JTMknwUFE/RbglNsU04W0UDLNM2banCm7dEg== ARC-Authentication-Results: i=1; lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=amutable.com; dkim=pass (2048-bit key; unprotected) header.d=amutable-com.20260707.gappssmtp.com header.i=@amutable-com.20260707.gappssmtp.com header.a=rsa-sha256 header.s=20260707 header.b=qBXMkKQK; dkim-atps=neutral; spf=pass (client-ip=2a00:1450:4864:20::32e; helo=mail-wm1-x32e.google.com; envelope-from=alex@amutable.com; receiver=lists.ozlabs.org) smtp.mailfrom=amutable.com Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=amutable.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=amutable-com.20260707.gappssmtp.com header.i=@amutable-com.20260707.gappssmtp.com header.a=rsa-sha256 header.s=20260707 header.b=qBXMkKQK; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=amutable.com (client-ip=2a00:1450:4864:20::32e; helo=mail-wm1-x32e.google.com; envelope-from=alex@amutable.com; receiver=lists.ozlabs.org) Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4jQtlJ3w23z3bgx for ; Fri, 13 Nov 2026 21:28:44 +1100 (AEDT) Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-4b7252a32c8so11958745e9.0 for ; Fri, 13 Nov 2026 02:28:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amutable-com.20260707.gappssmtp.com; s=20260707; t=1794565721; x=1795170521; darn=lists.ozlabs.org; h=mime-version:user-agent:content-transfer-encoding:content-type :references:in-reply-to:date:cc:to:from:subject:message-id:from:to :cc:subject:date:message-id:reply-to:content-type; bh=HIAZ+a2RY8snYu8gjwIzGL7aFLB+UDjcbceUrGWDUl0=; b=qBXMkKQKEgAdjViE84Z4UEVrx6SgBnNPhWer7RllnafD+dn0sY3QEAL5nwuoFhbywd oh7Vkczm8n00YVBVAZVuUIIK0lRJ7ik3MQ8CCdb1rCcNX2GNMGNgZ0cP6ShFLAyVFAQ7 rGuXBp1me+HCk59iYix8xYNGodddESti4llFHGYJeGfhMh7RadN/xwrEI5WJWkEKNr6z j1+bVuaVP+jiVrewvkF0qZUUms2wbdv149mylV20oQPnyAIzYZabbsaGwByNMyaU1ede QXpY9G0Dn8oZCg1D0DRQdbSIiPDS3PCZcbpmNBpLXyZKwRkDq6rIWzYxUyJPq7jHQP9U YNUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794565721; x=1795170521; h=mime-version:user-agent:content-transfer-encoding:content-type :references:in-reply-to:date:cc:to:from:subject:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=HIAZ+a2RY8snYu8gjwIzGL7aFLB+UDjcbceUrGWDUl0=; b=lgFAO6fewGt861nB0t/i/qP4WTO4N4NSQaZoBWI+tadGWti52wEps+HS/ff3Byuot2 iquAovm0z5sDobj9aX0DpighND2ZRETQoSxl+vEIBBcX2PWgBEjN2f4+xtxlKEvsO0r6 m2FgGhUyJa8pSOR3N/ffl4nFHJ+kRUiNLAbLdk/2ZNa6OBo/xHQi91AgYqTVuOERUx85 ZtG8hZwsDAeS0KMI05m1eSfPnYRSCVHEzsCyy/pIdVjn5Xf7CjFSee5EGOLDwfL37f3R jRzzhxY4zDmGXm4KwpRLUBFJ5zUuBCHGZT5uLCEV9x2JlZ1ErOm5KFPvM3sHr9GF4PJr AaEw== X-Forwarded-Encrypted: i=1; AL+hErEK2bBvyyAHCCILurOIzU5YqInG06UIiOUVs6QurhJtAYC8Jy8iwr76i/60HS7fkhGCe53uJHT0XxGoAtQ=@lists.ozlabs.org X-Gm-Message-State: APuU4Z/1kwbdJ1xdU9lBjwCufNdZ9T+frwuZ88iveCyyNc9cS8pxeoTx mo/DR3wVNdMeLDB0OBvAGzOontDdhYbiQytFOU21zFBhJ/oBL2p3gl+lBTfEqzdCJ3vz X-Gm-Gg: AYBFou3zM9ZxwM1Ft+oLkJisOUXBs7TxVPjbdOAT6jd6Fboepzl/iCrosLnLUAP9Sim xKk7ng/xDSn4ozF5xdhWMNgLKX/rwgALbUPJIWf0X0Q7mc8DtOx9VjsE3tq8uXxTw6snC9ra9Sk EilmwP6qsHVDJQkUlMP/VSm/g/qI3+R6XFwh3UL57Oq+n1KYPoQgpJXae5GomhKjDYPo8csz78c 0NqxUA+8jFJB0vS6Whh6l5e9jC3oS5y37sh7xYmNStqqbxpLXVuVn0Buk7laS4WQd5Qo2mLRh1r Q/aMkWgb3S45w3rvtyOUBr+1kXvv5+2ebobOiwflE5kBDJbH2EuYcuH0UPj5UC+4A8ZWpTHKpPu YOmwxEWGClPpx6z51DhBRr28hq7QWxzVeluEkEhrUrjC7Bo25Y5SFALj0ocw2E157jLYNHcUpdP wTsOZuQLJcfHbtcnM7XXSG6OaxpdxK0ckkJs+ID24xCKXX1H3VnFV5fFWJATW5QdAMKDC9RvdsF M6dz4Uj1nrB6Bvzr2CDgNbGKBX9zDgrZlxwhQ7QGZsiQU2JJrz6eh/dbtQw/MY/k6qtWC49hYgF C5Fcip9znN+3PW5lkKBrHVex2CIDG//N482ZcYSKbi/ANt/L3SV3LE5u5g67myY= X-Received: by 2002:a05:600c:428c:b0:4a1:9661:14b5 with SMTP id 5b1f17b1804b1-4bb55aabd53mr26666375e9.29.1794565721222; Fri, 13 Nov 2026 02:28:41 -0800 (PST) Received: from [10.0.0.233] (tmo-086-54.customers.d1-online.com. [80.187.86.54]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4bb4e252f7fsm152260095e9.2.2026.11.13.02.28.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Nov 2026 02:28:40 -0800 (PST) Message-ID: Subject: Re: [PATCH RFC 41/41] selftests/filesystems: add backing file tests for pseudo files From: Alexander Mikhalitsyn To: Christian Brauner , linux-fsdevel@vger.kernel.org Cc: Jann Horn , Chris Mason , Josef Bacik , Christoph Hellwig , linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nvme@lists.infradead.org, Alexander Viro , Jan Kara , linux-scsi@vger.kernel.org, target-devel@vger.kernel.org, driver-core@lists.linux.dev, linux-mm@kvack.org, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, apparmor@lists.ubuntu.com, linux-nfs@vger.kernel.org, netdev@vger.kernel.org, fuse-devel@lists.linux.dev, linux-efi@vger.kernel.org, xen-devel@lists.xenproject.org, ocfs2-devel@lists.linux.dev, linux-s390@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-usb@vger.kernel.org, Amir Goldstein , linux-erofs@lists.ozlabs.org, linux-kselftest@vger.kernel.org Date: Fri, 13 Nov 2026 11:28:38 +0100 In-Reply-To: <20261110-work-loop-pseudo-v1-41-4c998976c6c7@kernel.org> References: <20261110-work-loop-pseudo-v1-0-4c998976c6c7@kernel.org> <20261110-work-loop-pseudo-v1-41-4c998976c6c7@kernel.org> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.56.2-0+deb13u1 X-Mailing-List: linuxppc-dev@lists.ozlabs.org List-Id: List-Help: List-Owner: List-Post: List-Archive: , List-Subscribe: , , Precedence: list X-Archived-By: MIME-Version: 1.0 X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_PASS,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on aws-us-west-2-korg-listserv-alma10-1 On Tue, 2026-11-10 at 10:14 +0100, Christian Brauner wrote: > Add tests that files on pseudo filesystems can't be used as storage: >=20 > - a procfs file attached read-only to a loop device > - sysfs files attached read-only and read-write to a loop device > - a sysfs file behind a lower-only overlayfs attached to a loop > device > - a sysfs file as the backing file of a usb mass storage gadget LUN > - a sysfs file as the source of a file-backed erofs mount >=20 > And make sure that a memfd and another loop device still work as loop > backing files and that loop refuses a backing file that isn't open > for > reading. >=20 > Signed-off-by: Christian Brauner (Amutable) Reviewed-by: Alexander Mikhalitsyn > --- > =C2=A0tools/testing/selftests/filesystems/.gitignore=C2=A0=C2=A0=C2=A0=C2= =A0 |=C2=A0=C2=A0 1 + > =C2=A0tools/testing/selftests/filesystems/Makefile=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0 2 +- > =C2=A0tools/testing/selftests/filesystems/config=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 9 + > =C2=A0.../selftests/filesystems/pseudo_backing_test.c=C2=A0=C2=A0=C2=A0 |= 274 > +++++++++++++++++++++ > =C2=A04 files changed, 285 insertions(+), 1 deletion(-) >=20 > diff --git a/tools/testing/selftests/filesystems/.gitignore > b/tools/testing/selftests/filesystems/.gitignore > index cf79000e4092..8df38eabb125 100644 > --- a/tools/testing/selftests/filesystems/.gitignore > +++ b/tools/testing/selftests/filesystems/.gitignore > @@ -7,3 +7,4 @@ kernfs_test > =C2=A0idmapped_tmpfile > =C2=A0ustat_test > =C2=A0rw_hint_test > +pseudo_backing_test > diff --git a/tools/testing/selftests/filesystems/Makefile > b/tools/testing/selftests/filesystems/Makefile > index fbd5c27505ef..0ebb9005bcd2 100644 > --- a/tools/testing/selftests/filesystems/Makefile > +++ b/tools/testing/selftests/filesystems/Makefile > @@ -2,7 +2,7 @@ > =C2=A0 > =C2=A0CFLAGS +=3D $(KHDR_INCLUDES) > =C2=A0TEST_GEN_PROGS :=3D devpts_pts anon_inode_test kernfs_test fclog > ustat_test rw_hint_test > -TEST_GEN_PROGS +=3D idmapped_tmpfile > +TEST_GEN_PROGS +=3D idmapped_tmpfile pseudo_backing_test > =C2=A0TEST_GEN_PROGS_EXTENDED :=3D dnotify_test > =C2=A0 > =C2=A0include ../lib.mk > diff --git a/tools/testing/selftests/filesystems/config > b/tools/testing/selftests/filesystems/config > index 9f45bc493a30..228196160d29 100644 > --- a/tools/testing/selftests/filesystems/config > +++ b/tools/testing/selftests/filesystems/config > @@ -6,3 +6,12 @@ CONFIG_NET=3Dy > =C2=A0CONFIG_NET_NS=3Dy > =C2=A0CONFIG_INET=3Dy > =C2=A0CONFIG_SYSFS=3Dy > +CONFIG_BLK_DEV_LOOP=3Dy > +CONFIG_OVERLAY_FS=3Dy > +CONFIG_TMPFS=3Dy > +CONFIG_CONFIGFS_FS=3Dy > +CONFIG_USB_GADGET=3Dy > +CONFIG_USB_CONFIGFS=3Dy > +CONFIG_USB_CONFIGFS_MASS_STORAGE=3Dy > +CONFIG_EROFS_FS=3Dy > +CONFIG_EROFS_FS_BACKED_BY_FILE=3Dy > diff --git > a/tools/testing/selftests/filesystems/pseudo_backing_test.c > b/tools/testing/selftests/filesystems/pseudo_backing_test.c > new file mode 100644 > index 000000000000..bc8e17ab8e6e > --- /dev/null > +++ b/tools/testing/selftests/filesystems/pseudo_backing_test.c > @@ -0,0 +1,274 @@ > +// SPDX-License-Identifier: GPL-2.0 > +#define _GNU_SOURCE > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "kselftest_harness.h" > +#include "wrappers.h" > + > +/* > + * Put @fd behind a free loop device. The device is set up with > + * LO_FLAGS_AUTOCLEAR and goes away again when it is closed here. > + */ > +static int loop_attach(int fd, bool rw, char *dev, size_t len) > +{ > + struct loop_config cfg =3D {}; > + int ctl, nr, lfd, ret =3D 0; > + > + ctl =3D open("/dev/loop-control", O_RDWR | O_CLOEXEC); > + if (ctl < 0) > + return -errno; > + nr =3D ioctl(ctl, LOOP_CTL_GET_FREE); > + if (nr < 0) > + ret =3D -errno; > + close(ctl); > + if (ret) > + return ret; > + > + snprintf(dev, len, "/dev/loop%d", nr); > + lfd =3D open(dev, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC); > + if (lfd < 0) > + return -errno; > + > + cfg.fd =3D fd; > + cfg.info.lo_flags =3D LO_FLAGS_AUTOCLEAR; > + if (!rw) > + cfg.info.lo_flags |=3D LO_FLAGS_READ_ONLY; > + if (ioctl(lfd, LOOP_CONFIGURE, &cfg)) { > + ret =3D -errno; > + close(lfd); > + } else { > + ret =3D lfd; > + } > + return ret; > +} > + > +static int attach_path(const char *path, bool rw) > +{ > + char dev[PATH_MAX]; > + int fd, ret; > + > + fd =3D open(path, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC); > + if (fd < 0) > + return -errno; > + ret =3D loop_attach(fd, rw, dev, sizeof(dev)); > + close(fd); > + if (ret >=3D 0) { > + close(ret); > + ret =3D 0; > + } > + return ret; > +} > + > +static bool can_use_loop(void) > +{ > + return geteuid() =3D=3D 0 && access("/dev/loop-control", R_OK | > W_OK) =3D=3D 0; > +} > + > +TEST(memfd_backing_file) > +{ > + char dev[PATH_MAX]; > + int fd, lfd; > + > + if (!can_use_loop()) > + SKIP(return, "loop devices unavailable"); > + > + fd =3D memfd_create("pseudo_backing_test", MFD_CLOEXEC); > + ASSERT_GE(fd, 0); > + ASSERT_EQ(ftruncate(fd, 1 << 20), 0); > + > + lfd =3D loop_attach(fd, true, dev, sizeof(dev)); > + ASSERT_GE(lfd, 0); > + EXPECT_EQ(close(lfd), 0); > + EXPECT_EQ(close(fd), 0); > +} > + > +TEST(loop_device_backing_file) > +{ > + char dev[PATH_MAX], dev2[PATH_MAX]; > + int fd, lfd, bfd, lfd2; > + > + if (!can_use_loop()) > + SKIP(return, "loop devices unavailable"); > + > + fd =3D memfd_create("pseudo_backing_test", MFD_CLOEXEC); > + ASSERT_GE(fd, 0); > + ASSERT_EQ(ftruncate(fd, 1 << 20), 0); > + lfd =3D loop_attach(fd, true, dev, sizeof(dev)); > + ASSERT_GE(lfd, 0); > + > + /* A block device stays fine as a backing file. */ > + bfd =3D open(dev, O_RDWR | O_CLOEXEC); > + ASSERT_GE(bfd, 0); > + lfd2 =3D loop_attach(bfd, true, dev2, sizeof(dev2)); > + ASSERT_GE(lfd2, 0); > + > + EXPECT_EQ(close(lfd2), 0); > + EXPECT_EQ(close(bfd), 0); > + EXPECT_EQ(close(lfd), 0); > + EXPECT_EQ(close(fd), 0); > +} > + > +TEST(write_only_backing_file) > +{ > + char dev[PATH_MAX], path[PATH_MAX]; > + int fd, wfd, lfd; > + > + if (!can_use_loop()) > + SKIP(return, "loop devices unavailable"); > + > + fd =3D memfd_create("pseudo_backing_test", MFD_CLOEXEC); > + ASSERT_GE(fd, 0); > + ASSERT_EQ(ftruncate(fd, 1 << 20), 0); > + > + /* Loop reads from its backing file so it must be open for > reading. */ > + snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); > + wfd =3D open(path, O_WRONLY | O_CLOEXEC); > + ASSERT_GE(wfd, 0); > + > + lfd =3D loop_attach(wfd, true, dev, sizeof(dev)); > + if (lfd >=3D 0) > + close(lfd); > + EXPECT_EQ(lfd, -EBADF); > + EXPECT_EQ(close(wfd), 0); > + EXPECT_EQ(close(fd), 0); > +} > + > +TEST(procfs_backing_file) > +{ > + if (!can_use_loop()) > + SKIP(return, "loop devices unavailable"); > + > + ASSERT_EQ(attach_path("/proc/cpuinfo", false), -EINVAL); > +} > + > +TEST(sysfs_backing_file) > +{ > + if (!can_use_loop()) > + SKIP(return, "loop devices unavailable"); > + > + ASSERT_EQ(attach_path("/sys/kernel/warn_count", false), - > EINVAL); > + > + if (access("/sys/kernel/reboot/mode", F_OK)) > + SKIP(return, "no /sys/kernel/reboot/mode"); > + ASSERT_EQ(attach_path("/sys/kernel/reboot/mode", true), - > EINVAL); > +} > + > +TEST(overlayfs_on_sysfs_backing_file) > +{ > + if (!can_use_loop()) > + SKIP(return, "loop devices unavailable"); > + > + ASSERT_EQ(unshare(CLONE_NEWNS), 0); > + ASSERT_EQ(mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL), > 0); > + ASSERT_EQ(mount("tmpfs", "/tmp", "tmpfs", 0, NULL), 0); > + ASSERT_EQ(mkdir("/tmp/empty", 0755), 0); > + ASSERT_EQ(mkdir("/tmp/merged", 0755), 0); > + > + /* A lower-only overlayfs serves reads from sysfs. */ > + if (mount("overlay", "/tmp/merged", "overlay", MS_RDONLY, > + =C2=A0 "lowerdir=3D/sys/kernel:/tmp/empty")) > + SKIP(return, "no overlayfs on top of sysfs: %s", > strerror(errno)); > + > + ASSERT_EQ(attach_path("/tmp/merged/warn_count", false), - > EINVAL); > +} > + > +#define CONFIGFS_DIR "/sys/kernel/config" > +#define GADGET_DIR CONFIGFS_DIR "/usb_gadget/pseudo_backing_test" > +#define MASS_STORAGE_DIR GADGET_DIR "/functions/mass_storage.0" > + > +TEST(usb_mass_storage_backing_file) > +{ > + const char *path =3D "/sys/kernel/warn_count"; > + struct statfs sfs; > + ssize_t ret; > + int fd, err; > + > + if (geteuid()) > + SKIP(return, "needs root"); > + > + /* Mounting configfs on top of itself fails with EBUSY. */ > + if (statfs(CONFIGFS_DIR, &sfs) || sfs.f_type !=3D > CONFIGFS_MAGIC) { > + ASSERT_EQ(unshare(CLONE_NEWNS), 0); > + ASSERT_EQ(mount(NULL, "/", NULL, MS_REC | > MS_PRIVATE, NULL), 0); > + if (mount("configfs", CONFIGFS_DIR, "configfs", 0, > NULL)) > + SKIP(return, "no configfs: %s", > strerror(errno)); > + } > + > + if (mkdir(GADGET_DIR, 0755)) > + SKIP(return, "no usb gadget configfs: %s", > strerror(errno)); > + if (mkdir(MASS_STORAGE_DIR, 0755)) { > + err =3D errno; > + rmdir(GADGET_DIR); > + SKIP(return, "no usb mass storage function: %s", > strerror(err)); > + } > + > + /* Writing the path opens the LUN's backing file right away. > */ > + fd =3D open(MASS_STORAGE_DIR "/lun.0/file", O_WRONLY | > O_CLOEXEC); > + EXPECT_GE(fd, 0); > + if (fd >=3D 0) { > + ret =3D write(fd, path, strlen(path)); > + err =3D errno; > + EXPECT_EQ(ret, -1); > + EXPECT_EQ(err, EINVAL); > + EXPECT_EQ(close(fd), 0); > + } > + > + EXPECT_EQ(rmdir(MASS_STORAGE_DIR), 0); > + EXPECT_EQ(rmdir(GADGET_DIR), 0); > +} > + > +TEST(erofs_backing_file) > +{ > + bool refused =3D false; > + char buf[256]; > + int fsfd, ret, err; > + ssize_t n; > + > + if (geteuid()) > + SKIP(return, "needs root"); > + > + fsfd =3D sys_fsopen("erofs", FSOPEN_CLOEXEC); > + if (fsfd < 0) > + SKIP(return, "no erofs: %s", strerror(errno)); > + > + ASSERT_EQ(sys_fsconfig(fsfd, FSCONFIG_SET_STRING, "source", > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "/sys/kernel/warn_count", 0), 0)= ; > + ret =3D sys_fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, > 0); > + err =3D errno; > + if (ret && err =3D=3D ENOTBLK) { > + close(fsfd); > + SKIP(return, "no file-backed erofs mounts"); > + } > + ASSERT_EQ(ret, -1); > + ASSERT_EQ(err, EINVAL); > + > + /* > + * Something that isn't an erofs image fails with EINVAL as > well so > + * check that the source itself was refused. > + */ > + while ((n =3D read(fsfd, buf, sizeof(buf) - 1)) > 0) { > + buf[n] =3D '\0'; > + if (strstr(buf, "pseudo filesystem")) > + refused =3D true; > + } > + EXPECT_TRUE(refused); > + EXPECT_EQ(close(fsfd), 0); > +} > + > +TEST_HARNESS_MAIN