diff options
author | Amir Goldstein <amir73il@gmail.com> | 2017-10-24 17:38:33 +0300 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2018-01-24 11:25:56 +0100 |
commit | e7dd0e71348c1e3bc4b9d767c1ffbcbdee46a726 (patch) | |
tree | dcba3e99e1d07da04c4f9cfec83715c4b0d169ea /fs/overlayfs/util.c | |
parent | 89a17556ce4d113f6e7896e118a14f79a84484e9 (diff) |
ovl: whiteout index when union nlink drops to zero
With NFS export feature enabled, when overlay inode nlink drops to
zero, instead of removing the index entry, replace it with a whiteout
index entry.
This is needed for NFS export in order to prevent future open by handle
from opening the lower file directly.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/util.c')
-rw-r--r-- | fs/overlayfs/util.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 6b11e116f190..aa2234d52007 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -487,7 +487,8 @@ bool ovl_need_index(struct dentry *dentry) /* Caller must hold OVL_I(inode)->lock */ static void ovl_cleanup_index(struct dentry *dentry) { - struct inode *dir = ovl_indexdir(dentry->d_sb)->d_inode; + struct dentry *indexdir = ovl_indexdir(dentry->d_sb); + struct inode *dir = indexdir->d_inode; struct dentry *lowerdentry = ovl_dentry_lower(dentry); struct dentry *upperdentry = ovl_dentry_upper(dentry); struct dentry *index = NULL; @@ -518,13 +519,17 @@ static void ovl_cleanup_index(struct dentry *dentry) } inode_lock_nested(dir, I_MUTEX_PARENT); - /* TODO: whiteout instead of cleanup to block future open by handle */ - index = lookup_one_len(name.name, ovl_indexdir(dentry->d_sb), name.len); + index = lookup_one_len(name.name, indexdir, name.len); err = PTR_ERR(index); - if (!IS_ERR(index)) - err = ovl_cleanup(dir, index); - else + if (IS_ERR(index)) { index = NULL; + } else if (ovl_index_all(dentry->d_sb)) { + /* Whiteout orphan index to block future open by handle */ + err = ovl_cleanup_and_whiteout(indexdir, dir, index); + } else { + /* Cleanup orphan index entries */ + err = ovl_cleanup(dir, index); + } inode_unlock(dir); if (err) |