+++ /dev/null
-From 452061fd4521b2bf3225fc391dbe536e5f9c05e2 Mon Sep 17 00:00:00 2001
-From: Vivek Goyal <vgoyal@redhat.com>
-Date: Fri, 9 Mar 2018 15:44:41 -0500
-Subject: ovl: Set d->last properly during lookup
-
-From: Vivek Goyal <vgoyal@redhat.com>
-
-commit 452061fd4521b2bf3225fc391dbe536e5f9c05e2 upstream.
-
-d->last signifies that this is the last layer we are looking into and there
-is no more. And that means this allows for some optimzation opportunities
-during lookup. For example, in ovl_lookup_single() we don't have to check
-for opaque xattr of a directory is this is the last layer we are looking
-into (d->last = true).
-
-But knowing for sure whether we are looking into last layer can be very
-tricky. If redirects are not enabled, then we can look at poe->numlower and
-figure out if the lookup we are about to is last layer or not. But if
-redircts are enabled then it is possible poe->numlower suggests that we are
-looking in last layer, but there is an absolute redirect present in found
-element and that redirects us to a layer in root and that means lookup will
-continue in lower layers further.
-
-For example, consider following.
-
-/upperdir/pure (opaque=y)
-/upperdir/pure/foo (opaque=y,redirect=/bar)
-/lowerdir/bar
-
-In this case pure is "pure upper". When we look for "foo", that time
-poe->numlower=0. But that alone does not mean that we will not search for a
-merge candidate in /lowerdir. Absolute redirect changes that.
-
-IOW, d->last should not be set just based on poe->numlower if redirects are
-enabled. That can lead to setting d->last while it should not have and that
-means we will not check for opaque xattr while we should have.
-
-So do this.
-
- - If redirects are not enabled, then continue to rely on poe->numlower
- information to determine if it is last layer or not.
-
- - If redirects are enabled, then set d->last = true only if this is the
- last layer in root ovl_entry (roe).
-
-Suggested-by: Amir Goldstein <amir73il@gmail.com>
-Reviewed-by: Amir Goldstein <amir73il@gmail.com>
-Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
-Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-Fixes: 02b69b284cd7 ("ovl: lookup redirects")
-Cc: <stable@vger.kernel.org> #v4.10
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- fs/overlayfs/namei.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/fs/overlayfs/namei.c
-+++ b/fs/overlayfs/namei.c
-@@ -607,7 +607,7 @@ struct dentry *ovl_lookup(struct inode *
- .is_dir = false,
- .opaque = false,
- .stop = false,
-- .last = !poe->numlower,
-+ .last = ofs->config.redirect_follow ? false : !poe->numlower,
- .redirect = NULL,
- };
-
-@@ -666,7 +666,11 @@ struct dentry *ovl_lookup(struct inode *
- for (i = 0; !d.stop && i < poe->numlower; i++) {
- struct ovl_path lower = poe->lowerstack[i];
-
-- d.last = i == poe->numlower - 1;
-+ if (!ofs->config.redirect_follow)
-+ d.last = i == poe->numlower - 1;
-+ else
-+ d.last = lower.layer->idx == roe->numlower;
-+
- err = ovl_lookup_layer(lower.dentry, &d, &this);
- if (err)
- goto out_put;