lkml.org 
[lkml]   [2018]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.16 44/68] ovl: Set d->last properly during lookup
    Date
    4.16-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    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
    @@ -815,7 +815,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,
    };

    @@ -873,7 +873,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;

    \
     
     \ /
      Last update: 2018-04-17 19:04    [W:5.924 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site