From: Giuseppe Scrivano <giuseppe@scrivano.org>
To: Amir Goldstein <amir73il@gmail.com>
Cc: fstests@vger.kernel.org, linux-unionfs@vger.kernel.org
Subject: Re: [PATCH fstests v2] overlay: add a test for redirect_dir=followdata
Date: Tue, 10 Nov 2026 15:02:31 +0100 [thread overview]
Message-ID: <878q30ss20.fsf@scrivano.org> (raw)
In-Reply-To: <CAOQ4uxjsNEyB0H8CqGp9En1bFCH92bYAu8UJ8SovXUeaG=z-DA@mail.gmail.com> (Amir Goldstein's message of "Tue, 10 Nov 2026 12:43:47 +0100")
Hi Amir,
Amir Goldstein <amir73il@gmail.com> writes:
> On Mon, Nov 9, 2026 at 2:40 PM Giuseppe Scrivano <giuseppe@scrivano.org> wrote:
>>
>> Test that data-only layers select redirect_dir=followdata, which follows
>> redirects from lower to lowerdata from any lower layer, with userxattr
>> and trusted xattrs, and that redirect_dir=nofollow is refused with
>> data-only layers.
>>
>> Also test following an absolute redirect past a lower layer that has the
>> parent directory of the target, which failed with EIO before the fix
>> "ovl: do not always clear absolute_redirect".
>>
>> Signed-off-by: Giuseppe Scrivano <giuseppe@scrivano.org>
>> Reviewed-by: Amir Goldstein <amir73il@gmail.com>
>> ---
>> common/overlay | 15 +++++
>> tests/overlay/090 | 149 ++++++++++++++++++++++++++++++++++++++++++
>> tests/overlay/090.out | 43 ++++++++++++
>> 3 files changed, 207 insertions(+)
>> create mode 100755 tests/overlay/090
>> create mode 100644 tests/overlay/090.out
>>
>> diff --git a/common/overlay b/common/overlay
>> index 8e89d6e4..382960c3 100644
>> --- a/common/overlay
>> +++ b/common/overlay
>> @@ -286,6 +286,21 @@ _require_scratch_overlay_datadir_without_metacopy()
>>
>> }
>>
>> +# Check kernel support for the "redirect_dir=followdata" mount option
>> +_require_scratch_overlay_redirect_followdata()
>> +{
>> + local lowerdir="$OVL_BASE_SCRATCH_MNT/$OVL_UPPER"
>> + local datadir="$OVL_BASE_SCRATCH_MNT/$OVL_LOWER"
>> +
>> + _scratch_mkfs > /dev/null 2>&1
>> + _overlay_scratch_mount_opts \
>> + -o"lowerdir+=$lowerdir,datadir+=$datadir" \
>> + -o"userxattr,redirect_dir=followdata" > /dev/null 2>&1 || \
>> + _notrun "overlay redirect_dir=followdata not supported on ${SCRATCH_DEV}"
>> +
>> + _scratch_unmount
>> +}
>> +
>>
>> # Helper function to check underlying dirs of overlay filesystem
>> _overlay_fsck_dirs()
>> diff --git a/tests/overlay/090 b/tests/overlay/090
>> new file mode 100755
>> index 00000000..6eeeacdf
>> --- /dev/null
>> +++ b/tests/overlay/090
>> @@ -0,0 +1,149 @@
>> +#! /bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (c) 2026 Giuseppe Scrivano. All Rights Reserved.
>> +#
>> +# FS QA Test 090
>> +#
>> +# Test the redirect_dir=followdata mount option.
>> +#
>> +# Data-only layers select redirect_dir=followdata, which follows redirects
>> +# from any lower layer to a data-only layer, and cannot be used with
>> +# redirect_dir=nofollow.
>> +#
>> +# Also test following an absolute redirect past a lower layer that has the
>> +# parent directory of the redirect target, with metacopy=on.
>> +#
>> +. ./common/preamble
>> +_begin_fstest auto quick metacopy redirect attr
>> +
>> +# Import common functions.
>> +. ./common/filter
>> +. ./common/attr
>> +
>> +# We use non-default scratch underlying overlay dirs, we need to check
>> +# them explicitly after test.
>> +_require_scratch_nocheck
>> +_require_attrs user
>> +_require_attrs trusted
>> +_require_scratch_overlay_redirect_followdata
>> +_require_scratch_overlay_features redirect_dir metacopy
>> +_require_scratch_overlay_lowerdata_layers
>> +
>> +data=$OVL_BASE_SCRATCH_MNT/data
>> +l1=$OVL_BASE_SCRATCH_MNT/lower1
>> +l2=$OVL_BASE_SCRATCH_MNT/lower2
>> +l3=$OVL_BASE_SCRATCH_MNT/lower3
>> +upper=$OVL_BASE_SCRATCH_MNT/upper
>> +work=$OVL_BASE_SCRATCH_MNT/work
>> +layers="$l3:$l2:$l1::$data"
>> +
>> +# Make a metacopy file <file> with the redirect <redirect>, for both
>> +# userxattr and trusted xattr mounts
>> +make_stub()
>> +{
>> + local file=$1 redirect=$2 x
>> +
>> + touch $file
>> + for x in user.overlay. ${OVL_XATTR_METACOPY%metacopy}; do
>> + $SETFATTR_PROG -n ${x}metacopy $file
>> + $SETFATTR_PROG -n ${x}redirect -v $redirect $file
>> + done
>> + truncate -s 4 $file
>> +}
>> +
>> +# Mount the layers $layers with the options <opts>, print redirect_dir=followdata
>> +# if the mount shows it and <opts> has userxattr or redirect_dir (otherwise it
>> +# depends on the kernel config), and the content of each of the following files,
>> +# or the error reading it
>> +check()
>> +{
>> + local opts=$1 f
>> +
>> + shift
>> + echo "== $opts"
>> + _overlay_scratch_mount_dirs "$layers" $upper $work -o $opts
>> + case $opts in
>> + *userxattr*|*redirect_dir=*)
>> + _fs_options $OVL_BASE_SCRATCH_MNT | grep -o redirect_dir=followdata
>> + ;;
>> + esac
>> + for f; do
>> + echo "$f: $(cat $SCRATCH_MNT/$f 2>&1 | sed 's/^cat: .*: //')"
>> + done
>> + _unmount $SCRATCH_MNT
>> +}
>> +
>> +# Mounting the layers $layers with the options <opts> must fail
>> +check_fail()
>> +{
>> + local opts=$1
>> +
>> + echo "== $opts"
>> + _overlay_scratch_mount_dirs "$layers" $upper $work -o $opts \
>> + >> $seqres.full 2>&1 && echo "mount succeeded" && \
>> + _unmount $SCRATCH_MNT
>> +}
>> +
>> +_scratch_mkfs
>> +mkdir -p $data/base $l1/base $l2/base $l3 $upper $work
>> +echo -n "data" > $data/base/file
>> +
>> +make_stub $l1/s1 /base/file
>> +make_stub $l2/s2 /base/file
>> +make_stub $l3/s3 /base/file
>> +# The redirect target in a lower layer below s3, which is not looked up
>> +echo -n "lowr" > $l2/base/file
>> +# Redirects that are not followed: relative, directory, upper
>> +echo -n "lowr" > $l2/reltarget
>> +make_stub $l3/rel reltarget
>> +mkdir $l3/dir
>> +$SETFATTR_PROG -n user.overlay.redirect -v /base $l3/dir
>> +$SETFATTR_PROG -n $OVL_XATTR_REDIRECT -v /base $l3/dir
>> +make_stub $upper/up /base/file
>> +
>> +# followdata is selected by default with userxattr and a data-only layer
>> +check userxattr s1 s2 s3
>> +check userxattr,redirect_dir=followdata s1 s2 s3 rel dir up
>> +# a data-only layer cannot be used without following redirects
>> +check_fail userxattr,redirect_dir=nofollow
>> +check_fail userxattr,redirect_dir=off
>
> The test looks good but this expectation of failure is problematic.
>
> First of all the test would fail with redirect_always_follow=N
> because that makes redirect_dir=off => followdata
>
> But I also think that redirect_dir=off should not fail with
> redirect_always_follow=Y.
>
> I will explain with the documentation.
> You documentation v2 patch says:
>
> :A data-only layer selects "redirect_dir=followdata", unless
> "redirect_dir=follow"
> :or "redirect_dir=on" is in effect.
>
> So it implies redirect_dir=off => followdata
>
> All that redirect_dir=off really means is "don't create redirects".
>
> I amended the document as follows to clarify that:
>
> - "redirect_dir=on":
> Redirects are created and followed.
> - "redirect_dir=follow":
> Redirects are not created, but followed.
> - "redirect_dir=followdata":
> Redirects are not created.
> Only redirects from lower to lowerdata are followed.
> - "redirect_dir=nofollow":
> Redirects are not created and not followed.
> - "redirect_dir=off":
> Redirects are not created.
> Which redirects are followed depends on "redirect_always_follow" in the
> kernel/module config, on data-only lower layers and on the "userxattr"
> mount option.
>
> Made this off => followdata change in the code and pushed to ovl-fixes:
>
> -static int ovl_redirect_follow_mode(size_t nr_data)
> +int ovl_redirect_follow_mode(bool follow_lower, size_t nr_data)
> {
> - return ovl_redirect_always_follow ? OVL_REDIRECT_FOLLOW :
> - ovl_redirect_nofollow_mode(nr_data);
> + if (ovl_redirect_always_follow && follow_lower)
> + return OVL_REDIRECT_FOLLOW;
> +
> + /* Data-only layers cannot be used without following redirects
> to them */
> + return nr_data ? OVL_REDIRECT_FOLLOWDATA : OVL_REDIRECT_NOFOLLOW;
> }
>
> /*
> @@ -137,7 +140,7 @@ static int ovl_redirect_follow_mode(size_t nr_data)
> static int ovl_redirect_mode_def(void)
> {
> return ovl_redirect_dir_def ? OVL_REDIRECT_ON :
> - ovl_redirect_follow_mode(0);
> + ovl_redirect_follow_mode(true, 0);
> }
>
> static const struct constant_table ovl_parameter_verity[] = {
> @@ -896,6 +899,9 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> struct ovl_opt_set set = ctx->set;
> /* The requested redirect_dir=, for reporting conflicts with it */
> int redirect_opt = config->redirect_mode;
> + /* The redirect follow mode for redirect_dir=off and for the default */
> + int follow_mode = ovl_redirect_follow_mode(!config->userxattr,
> + ctx->nr_data);
>
> /* Workdir/index are useless in non-upper mount */
> if (!config->upperdir) {
> @@ -922,9 +928,12 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> config->uuid = OVL_UUID_NULL;
> }
>
> - /* Resolve redirect_dir=off to the default redirect follow mode */
> + /*
> + * Resolve redirect_dir=off to the default redirect follow mode.
> + * With userxattr, redirects are not followed to lower by default.
> + */
> if (config->redirect_mode == OVL_REDIRECT_OFF)
> - config->redirect_mode = ovl_redirect_follow_mode(ctx->nr_data);
> + config->redirect_mode = follow_mode;
>
> /*
> * This is to make the logic below simpler. It doesn't make any other
> @@ -1038,7 +1047,7 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
> * userxattr.
> */
> if (!set.redirect)
> - config->redirect_mode =
> ovl_redirect_nofollow_mode(ctx->nr_data);
> + config->redirect_mode = follow_mode;
> config->metacopy = false;
> }
>
>
> Please amend the test and test with the latest ovl-fixes:
> d0d57557b76de ovl: follow lower to lowerdata redirects from any lower layer
I've tested this modified version and it works fine. Do you want me to
send a v3 or will you amend it?
Thanks,
Giuseppe
next prev parent reply other threads:[~2026-11-10 14:02 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 13:38 [PATCH fstests v2] overlay: add a test for redirect_dir=followdata Giuseppe Scrivano
2026-11-10 11:43 ` Amir Goldstein
2026-11-10 14:02 ` Giuseppe Scrivano [this message]
2026-11-10 14:27 ` Amir Goldstein
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=878q30ss20.fsf@scrivano.org \
--to=giuseppe@scrivano.org \
--cc=amir73il@gmail.com \
--cc=fstests@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.