Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753830AbcCNRyI (ORCPT ); Mon, 14 Mar 2016 13:54:08 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:43790 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753638AbcCNRyC (ORCPT ); Mon, 14 Mar 2016 13:54:02 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Al Viro Subject: [PATCH 4.4 16/50] jffs2: reduce the breakage on recovery from halfway failed rename() Date: Mon, 14 Mar 2016 10:50:34 -0700 Message-Id: <20160314175015.727444026@linuxfoundation.org> X-Mailer: git-send-email 2.7.2 In-Reply-To: <20160314175013.403628835@linuxfoundation.org> References: <20160314175013.403628835@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1380 Lines: 40 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Al Viro commit f93812846f31381d35c04c6c577d724254355e7f upstream. 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. Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- fs/jffs2/dir.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -843,9 +843,14 @@ static int jffs2_rename (struct inode *o 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; }