10 Oct, 2018

1 commit

  • commit 1a8f8d2a443ef9ad9a3065ba8c8119df714240fa upstream.

    Format has a typo: it was meant to be "%.*s", not "%*s". But at some point
    callers grew nonprintable values as well, so use "%*pE" instead with a
    maximized length.

    Reported-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi
    Fixes: 3a1e819b4e80 ("ovl: store file handle of lower inode on copy up")
    Cc: # v4.12
    Signed-off-by: Greg Kroah-Hartman

    Miklos Szeredi
     

24 Oct, 2017

1 commit

  • Commit fbaf94ee3cd5 ("ovl: don't set origin on broken lower hardlink")
    attempt to avoid the condition of non-indexed upper inode with lower
    hardlink as origin. If this condition is found, lookup returns EIO.

    The protection of commit mentioned above does not cover the case of lower
    that is not a hardlink when it is copied up (with either index=off/on)
    and then lower is hardlinked while overlay is offline.

    Changes to lower layer while overlayfs is offline should not result in
    unexpected behavior, so a permanent EIO error after creating a link in
    lower layer should not be considered as correct behavior.

    This fix replaces EIO error with success in cases where upper has origin
    but no index is found, or index is found that does not match upper
    inode. In those cases, lookup will not fail and the returned overlay inode
    will be hashed by upper inode instead of by lower origin inode.

    Fixes: 359f392ca53e ("ovl: lookup index entry for copy up origin")
    Cc: # v4.13
    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     

05 Oct, 2017

1 commit


28 Jul, 2017

1 commit

  • Impure directories are ones which contain objects with origins (i.e. those
    that have been copied up). These are relevant to readdir operation only
    because of the d_ino field, no other transformation is necessary. Also a
    directory can become impure between two getdents(2) calls.

    This patch creates a cache for impure directories. Unlike the cache for
    merged directories, this one only contains entries with origin and is not
    refcounted but has a its lifetime tied to that of the dentry.

    Similarly to the merged cache, the impure cache is invalidated based on a
    version number. This version number is incremented when an entry with
    origin is added or removed from the directory.

    If the cache is empty, then the impure xattr is removed from the directory.

    This patch also fixes up handling of d_ino for the ".." entry if the parent
    directory is merged.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

20 Jul, 2017

1 commit

  • inode_doinit_with_dentry() in SELinux wants to read the upper inode's xattr
    to get security label, and ovl_xattr_get() calls ovl_dentry_real(), which
    depends on dentry->d_inode, but d_inode is null and not initialized yet at
    this point resulting in an Oops.

    Fix by getting the upperdentry info from the inode directly in this case.

    Reported-by: Eryu Guan
    Fixes: 09d8b586731b ("ovl: move __upperdentry to ovl_inode")
    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

14 Jul, 2017

1 commit

  • Commit 54fb347e836f ("ovl: verify index dir matches upper dir")
    introduced a new ovl_fh flag OVL_FH_FLAG_PATH_UPPER to indicate
    an upper file handle, but forgot to add the flag to the mask of
    valid flags, so index dir origin verification always discards
    existing origin and stores a new one.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     

05 Jul, 2017

13 commits

  • index entry should live only as long as there are upper or lower
    hardlinks.

    Cleanup orphan index entries on mount and when dropping the last
    overlay inode nlink.

    When about to cleanup or link up to orphan index and the index inode
    nlink > 1, admit that something went wrong and adjust overlay nlink
    to index inode nlink - 1 to prevent it from dropping below zero.
    This could happen when adding lower hardlinks underneath a mounted
    overlay and then trying to unlink them.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • With inodes index enabled, an overlay inode nlink counts the union of upper
    and non-covered lower hardlinks. During the lifetime of a non-pure upper
    inode, the following nlink modifying operations can happen:

    1. Lower hardlink copy up
    2. Upper hardlink created, unlinked or renamed over
    3. Lower hardlink whiteout or renamed over

    For the first, copy up case, the union nlink does not change, whether the
    operation succeeds or fails, but the upper inode nlink may change.
    Therefore, before copy up, we store the union nlink value relative to the
    lower inode nlink in the index inode xattr trusted.overlay.nlink.

    For the second, upper hardlink case, the union nlink should be incremented
    or decremented IFF the operation succeeds, aligned with nlink change of the
    upper inode. Therefore, before link/unlink/rename, we store the union nlink
    value relative to the upper inode nlink in the index inode.

    For the last, lower cover up case, we simplify things by preceding the
    whiteout or cover up with copy up. This makes sure that there is an index
    upper inode where the nlink xattr can be stored before the copied up upper
    entry is unlink.

    Return the overlay inode nlinks for indexed upper inodes on stat(2).

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • For rename, we need to ensure that an upper alias exists for hard links
    before attempting the operation. Introduce a flag in ovl_entry to track
    the state of the upper alias.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Bad index entries are entries whose name does not match the
    origin file handle stored in trusted.overlay.origin xattr.
    Bad index entries could be a result of a system power off in
    the middle of copy up.

    Stale index entries are entries whose origin file handle is
    stale. Stale index entries could be a result of copying layers
    or removing lower entries while the overlay is not mounted.
    The case of copying layers should be detected earlier by the
    verification of upper root dir origin and index dir origin.

    Both bad and stale index entries are detected and removed
    on mount.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • When inodes index feature is enabled, lookup in indexdir for the index
    entry of lower real inode or copy up origin inode. The index entry name
    is the hex representation of the lower inode file handle.

    If the index dentry in negative, then either no lower aliases have been
    copied up yet, or aliases have been copied up in older kernels and are
    not indexed.

    If the index dentry for a copy up origin inode is positive, but points
    to an inode different than the upper inode, then either the upper inode
    has been copied up and not indexed or it was indexed, but since then
    index dir was cleared. Either way, that index cannot be used to indentify
    the overlay inode.

    If a positive dentry that matches the upper inode was found, then it is
    safe to use the copy up origin st_ino for upper hardlinks, because all
    indexed upper hardlinks are represented by the same overlay inode as the
    copy up origin.

    Set the INDEX type flag on an indexed upper dentry. A non-upper dentry
    may also have a positive index from copy up of another lower hardlink.
    This situation will be handled by following patches.

    Index lookup is going to be used to prevent breaking hardlinks on copy up.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • An index dir contains persistent hardlinks to files in upper dir.
    Therefore, we must never mount an existing index dir with a differnt
    upper dir.

    Store the upper root dir file handle in index dir inode when index
    dir is created and verify the file handle before using an existing
    index dir on mount.

    Add an 'is_upper' flag to the overlay file handle encoding and set it
    when encoding the upper root file handle. This is not critical for index
    dir verification, but it is good practice towards a standard overlayfs
    file handle format for NFS export.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • When inodes index feature is enabled, verify that the file handle stored
    in upper root dir matches the lower root dir or fail to mount.

    If upper root dir has no stored file handle, encode and store the lower
    root dir file handle in overlay.origin xattr.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • Create the index dir on mount. The index dir will contain hardlinks to
    upper inodes, named after the hex representation of their origin lower
    inodes.

    The index dir is going to be used to prevent breaking lower hardlinks
    on copy up and to implement overlayfs NFS export.

    Because the feature is not fully backward compat, enabling the feature
    is opt-in by config/module/mount option.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • Added an i_state flag I_INUSE and helpers to set/clear/test the bit.

    The 'inuse' lock is an 'advisory' inode lock, that can be used to extend
    exclusive create protection beyond parent->i_mutex lock among cooperating
    users.

    This is going to be used by overlayfs to get exclusive ownership on upper
    and work dirs among overlayfs mounts.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     

05 Jun, 2017

1 commit


29 May, 2017

1 commit

  • An upper dir is marked "impure" to let ovl_iterate() know that this
    directory may contain non pure upper entries whose d_ino may need to be
    read from the origin inode.

    We already mark a non-merge dir "impure" when moving a non-pure child
    entry inside it, to let ovl_iterate() know not to iterate the non-merge
    dir directly.

    Mark also a merge dir "impure" when moving a non-pure child entry inside
    it and when copying up a child entry inside it.

    This can be used to optimize ovl_iterate() to perform a "pure merge" of
    upper and lower directories, merging the content of the directories,
    without having to read d_ino from origin inodes.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     

19 May, 2017

3 commits

  • When moving a merge dir or non-dir with copy up origin into a non-merge
    upper dir (a.k.a pure upper dir), we are marking the target parent dir
    "impure". ovl_iterate() iterates pure upper dirs directly, because there is
    no need to filter out whiteouts and merge dir content with lower dir. But
    for the case of an "impure" upper dir, ovl_iterate() will not be able to
    iterate the real upper dir directly, because it will need to lookup the
    origin inode and use it to fill d_ino.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • On failure to set opaque/redirect xattr on rename, skip setting xattr and
    return -EXDEV.

    On failure to set opaque xattr when creating a new directory, -EIO is
    returned instead of -EOPNOTSUPP.

    Any failure to set those xattr will be recorded in super block and
    then setting any xattr on upper won't be attempted again.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     

18 May, 2017

1 commit


05 May, 2017

4 commits

  • Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • For directory entries, non zero oe->numlower implies OVL_TYPE_MERGE.
    Define a new type flag OVL_TYPE_ORIGIN to indicate that an entry holds a
    reference to its lower copy up origin.

    For directory entries ORIGIN := MERGE && UPPER. For non-dir entries ORIGIN
    means that a lower type dentry has been recently copied up or that we were
    able to find the copy up origin from overlay.origin xattr.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • Sometimes it is interesting to know if an upper file is pure upper or a
    copy up target, and if it is a copy up target, it may be interesting to
    find the copy up origin.

    This will be used to preserve lower inode numbers across copy up.

    Store the lower inode file handle in upper inode extended attribute
    overlay.origin on copy up to use it later for these cases. Store the lower
    filesystem uuid along side the file handle, so we can validate that we are
    looking for the origin file in the original fs.

    If lower fs does not support NFS export ops store a zero sized xattr so we
    can always use the overlay.origin xattr to distinguish between a copy up
    and a pure upper inode.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • Some features can only work when all layers are on the same fs. Test this
    condition during mount time, so features can check them later.

    Add helper ovl_same_sb() to return the common super block in case all
    layers are on the same fs.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     

07 Feb, 2017

2 commits


16 Dec, 2016

9 commits

  • FWIW, there's a bit of abuse of struct kstat in overlayfs object
    creation paths - for one thing, it ends up with a very small subset
    of struct kstat (mode + rdev), for another it also needs link in
    case of symlinks and ends up passing it separately.

    IMO it would be better to introduce a separate object for that.

    In principle, we might even lift that thing into general API and switch
    ->mkdir()/->mknod()/->symlink() to identical calling conventions. Hell
    knows, perhaps ->create() as well...

    Signed-off-by: Miklos Szeredi

    Al Viro
     
  • This removes code duplication.

    Signed-off-by: Amir Goldstein
    Signed-off-by: Miklos Szeredi

    Amir Goldstein
     
  • oe->opaque is set for

    a) whiteouts
    b) directories having the "trusted.overlay.opaque" xattr

    Case b can be simplified, since setting the xattr always implies setting
    oe->opaque. Also once set, the opaque flag is never cleared.

    Don't need to set opaque flag for non-directories.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Current code returns EXDEV when a directory would need to be copied up to
    move. We could copy up the directory tree in this case, but there's
    another, simpler solution: point to old lower directory from moved upper
    directory.

    This is achieved with a "trusted.overlay.redirect" xattr storing the path
    relative to the root of the overlay. After such attribute has been set,
    the directory can be moved without further actions required.

    This is a backward incompatible feature, old kernels won't be able to
    correctly mount an overlay containing redirected directories.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • If a directory has the "trusted.overlay.redirect" xattr, it means that the
    value of the xattr should be used to find the underlying directory on the
    next lower layer.

    The redirect may be relative or absolute. Absolute redirects begin with a
    slash.

    A relative redirect means: instead of the current dentry's name use the
    value of the redirect to find the directory in the next lower
    layer. Relative redirects must not contain a slash.

    An absolute redirect means: look up the directory relative to the root of
    the overlay using the value of the redirect in the next lower layer.

    Redirects work on lower layers as well.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • fs/overlayfs/super.c is the biggest of the overlayfs source files and it
    contains various utility functions as well as the rather complicated lookup
    code. Split these parts out to separate files.

    Before:

    1446 fs/overlayfs/super.c

    After:

    919 fs/overlayfs/super.c
    267 fs/overlayfs/namei.c
    235 fs/overlayfs/util.c
    51 fs/overlayfs/ovl_entry.h

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • d_is_dir() is safe to call on a negative dentry. Use this fact to simplify
    handling of the lower or merged directories.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • The remainging uses of __OVL_PATH_PURE can be replaced by
    ovl_dentry_is_opaque().

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi
     
  • Currently ovl_lookup() checks existence of lower file even if there's a
    non-directory on upper (which is always opaque). This is done so that
    remove can decide whether a whiteout is needed or not.

    It would be better to defer this check to unlink, since most of the time
    the gathered information about opaqueness will be unused.

    This adds a helper ovl_lower_positive() that checks if there's anything on
    the lower layer(s).

    The following patches also introduce changes to how the "opaque" attribute
    is updated on directories: this attribute is added when the directory is
    creted or moved over a whiteout or object covering something on the lower
    layer. However following changes will allow the attribute to remain on the
    directory after being moved, even if the new location doesn't cover
    anything. Because of this, we need to check lower layers even for opaque
    directories, so that whiteout is only created when necessary.

    This function will later be also used to decide about marking a directory
    opaque, so deal with negative dentries as well. When dealing with
    negative, it's enough to check for being a whiteout

    If the dentry is positive but not upper then it also obviously needs
    whiteout/opaque.

    Signed-off-by: Miklos Szeredi

    Miklos Szeredi