summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/dir.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2017-04-24 19:54:13 +0300
committerMiklos Szeredi <mszeredi@redhat.com>2017-05-05 11:38:58 +0200
commit5b6c9053fb38a66fd5c6177fcf5022b24767811a (patch)
treecf556629b3d2a344fb33a1497e31d345b8577f2a /fs/overlayfs/dir.c
parent5b712091a3a3904b0ae8311e18e6b540a070d464 (diff)
downloadlinux-5b6c9053fb38a66fd5c6177fcf5022b24767811a.tar.bz2
ovl: persistent inode numbers for upper hardlinks
An upper type non directory dentry that is a copy up target should have a reference to its lower copy up origin. There are three ways for an upper type dentry to be instantiated: 1. A lower type dentry that is being copied up 2. An entry that is found in upper dir by ovl_lookup() 3. A negative dentry is hardlinked to an upper type dentry In the first case, the lower reference is set before copy up. In the second case, the lower reference is found by ovl_lookup(). In the last case of hardlinked upper dentry, it is not easy to update the lower reference of the negative dentry. Instead, drop the newly hardlinked negative dentry from dcache and let the next access call ovl_lookup() to find its lower reference. This makes sure that the inode number reported by stat(2) after the hardlink is created is the same inode number that will be reported by stat(2) after mount cycle, which is the inode number of the lower copy up origin of the hardlink source. NOTE that this does not fix breaking of lower hardlinks on copy up, but only fixes the case of lower nlink == 1, whose upper copy up inode is hardlinked in upper dir. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/dir.c')
-rw-r--r--fs/overlayfs/dir.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index f4cf2928cf8e..723b98b90698 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -152,6 +152,9 @@ static void ovl_instantiate(struct dentry *dentry, struct inode *inode,
inc_nlink(inode);
}
d_instantiate(dentry, inode);
+ /* Force lookup of new upper hardlink to find its lower */
+ if (hardlink)
+ d_drop(dentry);
}
static bool ovl_type_merge(struct dentry *dentry)