From cb0b868591b574eb344e9c564a44e2f9b5e923eb Mon Sep 17 00:00:00 2001 From: Robin Dong Date: Mon, 12 Mar 2012 13:44:59 +0800 Subject: [PATCH 10/13] overlayfs: create new inode in ovl_link Patch-mainline: not yet Imaging using ext4 as upperdir which has a file "hello" and lowdir is totally empty. 1. mount -t overlayfs overlayfs -o lowerdir=/lower,upperdir=/upper /overlay 2. cd /overlay 3. ln hello bye then the overlayfs code will call vfs_link to create a real ext4 dentry for "bye" and create a new overlayfs dentry point to overlayfs inode (which standed for "hello"). That means: two overlayfs dentries and only one overlayfs inode. and then 4. umount /overlay 5. mount -t overlayfs overlayfs -o lowerdir=/lower,upperdir=/upper /overlay (again) 6. cd /overlay 7. ls hello bye the overlayfs will create two inodes(one for the "hello", another for the "bye") and two dentries (each point a inode).That means: two dentries and two inodes. As above, with different order of "create link" and "mount", the result is not the same. In order to make the behavior coherent, we need to create inode in ovl_link. Signed-off-by: Robin Dong Signed-off-by: Miklos Szeredi --- fs/overlayfs/dir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) Index: linux-3.6-rc7-master/fs/overlayfs/dir.c =================================================================== --- linux-3.6-rc7-master.orig/fs/overlayfs/dir.c 2012-09-28 13:36:53.000000000 +0200 +++ linux-3.6-rc7-master/fs/overlayfs/dir.c 2012-09-28 13:37:04.000000000 +0200 @@ -417,6 +417,7 @@ static int ovl_link(struct dentry *old, struct dentry *olddentry; struct dentry *newdentry; struct dentry *upperdir; + struct inode *newinode; err = ovl_copy_up(old); if (err) @@ -441,13 +442,17 @@ static int ovl_link(struct dentry *old, err = -ENOENT; goto out_unlock; } + newinode = ovl_new_inode(old->d_sb, newdentry->d_inode->i_mode, + new->d_fsdata); + if (!newinode) + goto link_fail; ovl_dentry_version_inc(new->d_parent); ovl_dentry_update(new, newdentry); - ihold(old->d_inode); - d_instantiate(new, old->d_inode); + d_instantiate(new, newinode); } else { +link_fail: if (ovl_dentry_is_opaque(new)) ovl_whiteout(upperdir, new); dput(newdentry);