Re: [PATCH] ovl: fix false negative ESTALE on lookup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Title should be false positive, and in commit message as well,
but feel free to change the title to better explain the issue.

On Mon, Sep 11, 2017 at 4:30 PM, Amir Goldstein <amir73il@xxxxxxxxx> wrote:
> Commit b9ac5c274b8c ("ovl: hash overlay non-dir inodes by copy up
> origin") verifies that the origin lower inode stored in the overlayfs
> inode matched the inode of a copy up origin dentry found by lookup.
>
> There is a false negative result in that check when lower fs does
> not support file handles and copy up origin cannot be followed by
> file handle at lookup time.
>
> The false negative happens when finding an overlay inode in cache on
> a copied up overlay dentry lookup. The overlay inode still 'remembers'
> the copy up origin inode, but the copy up origin dentry is not available
> for verification.
>
> Relax the check in case copy up origin dentry is not available.
>
> Fixes: b9ac5c274b8c ("ovl: hash overlay non-dir inodes by copy up...")
> Cc: <stable@xxxxxxxxxxxxxxx> # v4.13
> Reported-by: Jordi Pujol <jordipujolp@xxxxxxxxx>
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> ---
>
> Miklos,
>
> This is a fix for the v4.13 issue of overlayfs over squashfs
> reported by Jordi.
>
> I added run --squashfs option to unionmount-testsuite:
> https://github.com/amir73il/unionmount-testsuite/commits/overlayfs-devel
>
> The test 'run --squashfs hard-link' fails on kernel v4.13.
>
> Amir.
>
>
>  fs/overlayfs/inode.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
> index aecaadc8f9e7..a619addecafc 100644
> --- a/fs/overlayfs/inode.c
> +++ b/fs/overlayfs/inode.c
> @@ -579,10 +579,13 @@ static int ovl_inode_set(struct inode *inode, void *data)
>  static bool ovl_verify_inode(struct inode *inode, struct dentry *lowerdentry,
>                              struct dentry *upperdentry)
>  {
> -       struct inode *lowerinode = lowerdentry ? d_inode(lowerdentry) : NULL;
> -
> -       /* Lower (origin) inode must match, even if NULL */
> -       if (ovl_inode_lower(inode) != lowerinode)
> +       /*
> +        * Allow non-NULL lower inode in ovl_inode even if lowerdentry is NULL.
> +        * This happens when finding a copied up overlay inode for a renamed
> +        * or hardlinked overlay dentry and lower dentry cannot be followed
> +        * by origin because lower fs does not support file handles.
> +        */
> +       if (lowerdentry && ovl_inode_lower(inode) != d_inode(lowerdentry))
>                 return false;
>
>         /*
> --
> 2.7.4
>



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]