@@ -891,6 +891,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
bool old_opaque;
bool new_opaque;
bool cleanup_whiteout = false;
+ bool new_drop_nlink = false;
bool overwrite = !(flags & RENAME_EXCHANGE);
bool is_dir = d_is_dir(old);
bool new_is_dir = d_is_dir(new);
@@ -952,6 +953,8 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
flags |= RENAME_EXCHANGE;
cleanup_whiteout = true;
}
+ if (!new_is_dir && new->d_inode)
+ new_drop_nlink = true;
}
old_upperdir = ovl_dentry_upper(old->d_parent);
@@ -1046,6 +1049,9 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
if (cleanup_whiteout)
ovl_cleanup(old_upperdir->d_inode, newdentry);
+ if (new_drop_nlink)
+ drop_nlink(new->d_inode);
+
ovl_dentry_version_inc(old->d_parent);
ovl_dentry_version_inc(new->d_parent);
This patch fixes an overlay inode nlink leak in the case where ovl_rename() renames over a non-dir. This is not so critical, because overlay inode doesn't rely on nlink dropping to zero for inode deletion. Signed-off-by: Amir Goldstein <amir73il@gmail.com> --- fs/overlayfs/dir.c | 6 ++++++ 1 file changed, 6 insertions(+)