]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
jffs2: reduce the breakage on recovery from halfway failed rename()
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 8 Mar 2016 04:07:10 +0000 (23:07 -0500)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 26 May 2016 22:45:42 +0000 (15:45 -0700)
Orabug: 23331003

[ Upstream commit f93812846f31381d35c04c6c577d724254355e7f ]

d_instantiate(new_dentry, old_inode) is absolutely wrong thing to
do - it will oops if new_dentry used to be positive, for starters.
What we need is d_invalidate() the target and be done with that.

Cc: stable@vger.kernel.org # v3.18+
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
(cherry picked from commit c62aadae234ffad0901c20ac1a1aa4e13cce1c20)

Signed-off-by: Dan Duval <dan.duval@oracle.com>
fs/jffs2/dir.c

index 1ba5c97943b8751f0210870a7bb51636dd4e5ecd..cfbceb116356f13659d26f96da9557f598ef452e 100644 (file)
@@ -845,9 +845,14 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
 
                pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n",
                          __func__, ret);
-               /* Might as well let the VFS know */
-               d_instantiate(new_dentry, d_inode(old_dentry));
-               ihold(d_inode(old_dentry));
+               /*
+                * We can't keep the target in dcache after that.
+                * For one thing, we can't afford dentry aliases for directories.
+                * For another, if there was a victim, we _can't_ set new inode
+                * for that sucker and we have to trigger mount eviction - the
+                * caller won't do it on its own since we are returning an error.
+                */
+               d_invalidate(new_dentry);
                new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
                return ret;
        }