* [PATCH blktests] loop/014: Add test for backing file on loop device partition
@ 2026-08-20 20:00 Bart Van Assche
2026-08-24 10:55 ` Shin'ichiro Kawasaki
0 siblings, 1 reply; 2+ messages in thread
From: Bart Van Assche @ 2026-08-20 20:00 UTC (permalink / raw)
To: Shin'ichiro Kawasaki; +Cc: linux-block, Bart Van Assche
Add a new loop driver test that verifies that attempting to set the
backing file of a loop device to a file located on a filesystem on one of
the same loop device's partitions fails as expected by triggering the
kernel function loop_validate_file().
Modify src/loop_change_fd.c to accept a -r option to open the loop device
and backing file in read-only mode (O_RDONLY).
The test performs the following steps:
- Create a 1 GB image file ($TMPDIR/img).
- Instantiate a loop device for the image file with partition scanning
enabled.
- Create two partitions of equal size on that loop device.
- Format the second partition with the ext4 filesystem and mount it.
- Create a 1 GB file on the mounted filesystem.
- Unmount the filesystem, detach the loop device, and re-instantiate it in
read-only mode.
- Mount the partition read-only.
- Use src/loop_change_fd -r to attempt to change the backing file
descriptor of the loop device to the file on its own partition via
LOOP_CHANGE_FD, and verify that loop_validate_file() rejects it.
- Clean up by unmounting the filesystem and detaching the loop device.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
src/loop_change_fd.c | 20 ++++++--
tests/loop/014 | 107 +++++++++++++++++++++++++++++++++++++++++++
tests/loop/014.out | 2 +
3 files changed, 125 insertions(+), 4 deletions(-)
create mode 100755 tests/loop/014
create mode 100644 tests/loop/014.out
diff --git a/src/loop_change_fd.c b/src/loop_change_fd.c
index b124d829f380..722f14d3d91f 100644
--- a/src/loop_change_fd.c
+++ b/src/loop_change_fd.c
@@ -11,25 +11,37 @@
void usage(const char *progname)
{
- fprintf(stderr, "usage: %s LOOPDEV PATH\n", progname);
+ fprintf(stderr, "usage: %s [-r] LOOPDEV PATH\n", progname);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
+ int flags = O_RDWR;
int ret;
int fd, filefd;
+ int c;
- if (argc != 3)
+ while ((c = getopt(argc, argv, "r")) != -1) {
+ switch (c) {
+ case 'r':
+ flags = O_RDONLY;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+
+ if (optind + 2 != argc)
usage(argv[0]);
- fd = open(argv[1], O_RDWR);
+ fd = open(argv[optind], flags);
if (fd == -1) {
perror("open");
return EXIT_FAILURE;
}
- filefd = open(argv[2], O_RDWR);
+ filefd = open(argv[optind + 1], flags);
if (filefd == -1) {
perror("open");
return EXIT_FAILURE;
diff --git a/tests/loop/014 b/tests/loop/014
new file mode 100755
index 000000000000..5814b8148a26
--- /dev/null
+++ b/tests/loop/014
@@ -0,0 +1,107 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2026 Google LLC
+#
+# Verify that attempting to change a loop device's backing file (via
+# LOOP_CHANGE_FD) to a file on a filesystem residing on one of its own
+# partitions triggers the kernel function loop_validate_file() and fails.
+
+. tests/loop/rc
+
+DESCRIPTION="trigger loop_validate_file() when changing backing file to own partition"
+QUICK=1
+
+loop_device=
+mount_dir=
+
+requires() {
+ _have_program mkfs.ext4
+ _have_program parted
+ _have_src_program loop_change_fd
+}
+
+cleanup() {
+ if [[ -n "$mount_dir" ]]; then
+ umount "$mount_dir" &>/dev/null
+ fi
+ if [[ -n "$loop_device" ]]; then
+ losetup --detach "$loop_device" &>/dev/null
+ fi
+}
+
+test() {
+ echo "Running ${TEST_NAME}"
+ _register_test_cleanup cleanup
+
+ mount_dir="$TMPDIR/mnt"
+
+ truncate -s 1G "$TMPDIR/img"
+
+ if ! loop_device="$(losetup --find --partscan --show "$TMPDIR/img")"; then
+ echo "Failed to instantiate loop device"
+ return 1
+ fi
+
+ if ! parted --script "$loop_device" \
+ mklabel gpt \
+ mkpart primary 0% 50% \
+ mkpart primary 50% 100% >>"$FULL" 2>&1; then
+ echo "Failed to create partitions on loop device"
+ return 1
+ fi
+
+ udevadm settle
+
+ local part="${loop_device}p2"
+ if [[ ! -b "$part" ]]; then
+ echo "Partition $part does not exist"
+ return 1
+ fi
+
+ if ! mkfs.ext4 -F "$part" >>"$FULL" 2>&1; then
+ echo "Failed to format $part with ext4"
+ return 1
+ fi
+
+ mkdir -p "$mount_dir"
+ if ! mount -t ext4 "$part" "$mount_dir" >>"$FULL" 2>&1; then
+ echo "Failed to mount $part on $mount_dir"
+ return 1
+ fi
+
+ truncate -s 1G "$mount_dir/file"
+
+ umount "$mount_dir"
+ losetup --detach "$loop_device"
+ udevadm settle
+
+ # Reopen the loop device in read-only mode so that LOOP_CHANGE_FD can be used.
+ if ! loop_device="$(losetup --read-only --partscan --find --show "$TMPDIR/img")"; then
+ echo "Failed to re-instantiate loop device in read-only mode"
+ return 1
+ fi
+
+ udevadm settle
+
+ part="${loop_device}p2"
+ if ! mount -o ro -t ext4 "$part" "$mount_dir" >>"$FULL" 2>&1; then
+ echo "Failed to mount $part read-only on $mount_dir"
+ return 1
+ fi
+
+ # LOOP_CHANGE_FD triggers loop_validate_file() in the kernel, which must
+ # detect that the backing file resides on a partition of this loop device
+ # and reject the change.
+ if src/loop_change_fd -r "$loop_device" "$mount_dir/file" >>"$FULL" 2>&1; then
+ echo "Changing backing file succeeded unexpectedly"
+ fi
+
+ umount "$mount_dir"
+ mount_dir=
+
+ losetup --detach "$loop_device"
+ loop_device=
+ udevadm settle
+
+ echo "Test complete"
+}
diff --git a/tests/loop/014.out b/tests/loop/014.out
new file mode 100644
index 000000000000..78a7928c5249
--- /dev/null
+++ b/tests/loop/014.out
@@ -0,0 +1,2 @@
+Running loop/014
+Test complete
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH blktests] loop/014: Add test for backing file on loop device partition
2026-08-20 20:00 [PATCH blktests] loop/014: Add test for backing file on loop device partition Bart Van Assche
@ 2026-08-24 10:55 ` Shin'ichiro Kawasaki
0 siblings, 0 replies; 2+ messages in thread
From: Shin'ichiro Kawasaki @ 2026-08-24 10:55 UTC (permalink / raw)
To: Bart Van Assche; +Cc: linux-block
On Aug 20, 2026 / 13:00, Bart Van Assche wrote:
> Add a new loop driver test that verifies that attempting to set the
> backing file of a loop device to a file located on a filesystem on one of
> the same loop device's partitions fails as expected by triggering the
> kernel function loop_validate_file().
>
> Modify src/loop_change_fd.c to accept a -r option to open the loop device
> and backing file in read-only mode (O_RDONLY).
>
> The test performs the following steps:
> - Create a 1 GB image file ($TMPDIR/img).
> - Instantiate a loop device for the image file with partition scanning
> enabled.
> - Create two partitions of equal size on that loop device.
> - Format the second partition with the ext4 filesystem and mount it.
> - Create a 1 GB file on the mounted filesystem.
> - Unmount the filesystem, detach the loop device, and re-instantiate it in
> read-only mode.
> - Mount the partition read-only.
> - Use src/loop_change_fd -r to attempt to change the backing file
> descriptor of the loop device to the file on its own partition via
> LOOP_CHANGE_FD, and verify that loop_validate_file() rejects it.
> - Clean up by unmounting the filesystem and detaching the loop device.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Thanks for the patch. Overall, it looks good to me. I ran the test using the
kernel at the current Linus master branch tip, and confirmed the test case
recreates the failrue, and the kernel side fix patch avoids the failure [1].
Good.
[1] https://lore.kernel.org/linux-block/0c8a65b8870b2ef09119093b485e37896b80e2a4.1787255652.git.bvanassche@acm.org/
Please find two nit comments in line below. They are not a big deal. If you
want, I can fold-in the changes when I apply this patch after the kernel side
fix get upstreamed.
> diff --git a/tests/loop/014 b/tests/loop/014
> new file mode 100755
> index 000000000000..5814b8148a26
> --- /dev/null
> +++ b/tests/loop/014
> @@ -0,0 +1,107 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-3.0+
> +# Copyright (C) 2026 Google LLC
> +#
> +# Verify that attempting to change a loop device's backing file (via
> +# LOOP_CHANGE_FD) to a file on a filesystem residing on one of its own
> +# partitions triggers the kernel function loop_validate_file() and fails.
I think the kernel side fix commit should be mentioned here.
> +
> +. tests/loop/rc
> +
> +DESCRIPTION="trigger loop_validate_file() when changing backing file to own partition"
> +QUICK=1
> +
> +loop_device=
> +mount_dir=
> +
> +requires() {
> + _have_program mkfs.ext4
> + _have_program parted
> + _have_src_program loop_change_fd
> +}
> +
> +cleanup() {
> + if [[ -n "$mount_dir" ]]; then
> + umount "$mount_dir" &>/dev/null
> + fi
> + if [[ -n "$loop_device" ]]; then
> + losetup --detach "$loop_device" &>/dev/null
> + fi
> +}
> +
> +test() {
> + echo "Running ${TEST_NAME}"
> + _register_test_cleanup cleanup
> +
> + mount_dir="$TMPDIR/mnt"
> +
> + truncate -s 1G "$TMPDIR/img"
Nit: I suggest the long option "--size=1G" instead of the short option "-s 1G".
Same for mkdir -p option and mount -t option.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-24 10:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20 20:00 [PATCH blktests] loop/014: Add test for backing file on loop device partition Bart Van Assche
2026-08-24 10:55 ` Shin'ichiro Kawasaki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox