A recent patch series[1] adds support for calling fallocate() in mode 0 on block devices. This test adds a basic sanity test for loopback devices setup on a sparse file and validates that writes to the loopback device succeed, even when the underlying filesystem runs out of space. Signed-off-by: Sarthak Kukreti <sarthakkukreti@xxxxxxxxxxxx> --- tests/loop/010 | 60 ++++++++++++++++++++++++++++++++++++++++++++++ tests/loop/010.out | 2 ++ 2 files changed, 62 insertions(+) create mode 100644 tests/loop/010 create mode 100644 tests/loop/010.out diff --git a/tests/loop/010 b/tests/loop/010 new file mode 100644 index 0000000..091be5e --- /dev/null +++ b/tests/loop/010 @@ -0,0 +1,60 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-3.0+ +# Copyright (C) 2023 Google LLC. +# Author: sarthakkukret@xxxxxxxxxx (Sarthak Kukreti) +# +# Test if fallocate() on a loopback device provisions space on the underlying +# filesystem and writes on the loop device succeed, even if the lower +# filesystem is filled up. + +. tests/loop/rc + +DESCRIPTION="Loop device fallocate() space provisioning" +QUICK=1 + +requires() { + _have_program mkfs.ext4 +} + +test() { + echo "Running ${TEST_NAME}" + + local mount_dir="$TMPDIR/mnt" + mkdir -p ${mount_dir} + + local image_file="$TMPDIR/img" + truncate -s 1G "${image_file}" + + local loop_device + loop_device="$(losetup -P -f --show "${image_file}")" + + mkfs.ext4 ${loop_device} &> /dev/null + mount -t ext4 ${loop_device} ${mount_dir} + + local provisioned_file="${mount_dir}/provisioned" + truncate -s 200M "${provisioned_file}" + + local provisioned_loop_device + provisioned_loop_device="$(losetup -P -f --show "${provisioned_file}")" + + # Provision space for the file: without provisioning support, this fails + # with EOPNOTSUPP. + fallocate -l 200M "${provisioned_loop_device}" + + # Fill the filesystem, this command will error out with ENOSPC. + local fs_fill_file="${mount_dir}/fill" + dd if=/dev/zero of="${fs_fill_file}" bs=1M count=1024 status=none &>/dev/null + sync + + # Write to provisioned loop device, ensure that it does not run into ENOSPC. + dd if=/dev/zero of="${provisioned_loop_device}" bs=1M count=200 status=none + sync + + # Cleanup. + losetup --detach "${provisioned_loop_device}" + umount "${mount_dir}" + losetup --detach "${loop_device}" + rm "${image_file}" + + echo "Test complete" +} \ No newline at end of file diff --git a/tests/loop/010.out b/tests/loop/010.out new file mode 100644 index 0000000..068c489 --- /dev/null +++ b/tests/loop/010.out @@ -0,0 +1,2 @@ +Running loop/009 +Test complete -- 2.42.0.758.gaed0368e0e-goog