Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp4150061pxb; Mon, 27 Sep 2021 10:24:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx0v783Gmp7YYzqazIGijHC4DsFBuBhY7+RXrMV9WzfylO04qdp66u2by5vz/kHGd2uByOJ X-Received: by 2002:a50:cf87:: with SMTP id h7mr1401871edk.152.1632763467718; Mon, 27 Sep 2021 10:24:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632763467; cv=none; d=google.com; s=arc-20160816; b=kbegLox3kDwoThuRcv2YOV4XhtFkVBVtEUqX8Twd7OdzM00MfFe5wKoxIkIakE8nco uD/lwToBUhhuvd5qAFPKI79xwn+G7QjZsSqmTQzbxuinJRPraebcZ71sHEP4C5No1T08 tQ4qAJtZLlVYL6mV6MUR08BoJs7aO7OXVNq3m3u9kdiWX34//C1sO0sfLcDyaMfeZZcz hqLMPkLeZeopVaMwrypOgQJmsFqLl+29uqHLIjtFnP0yX/up659vVsdR2dL2vxV1qtkE CiY8dCrzZ/OYo9rfDI/pb6lsmO6RA0yB9oYd40i86fyMsuWca3CHv6ME0sVJyFVwS+9/ 0PgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=mQjxoAE/cECLoQbMGF5+HSql4fFxcmuU2JpwRL7/TVU=; b=sLMPuu3cwkLmOe9hDYUuSBTSXW6ssT2mHyaqBH1Q8V8FZyS/ICijWF0M4tbHGoq3nr goishpGA0MsTgflEEfz4hJIE+CAUwdFatcOvbq5iTmLwMTyqz9ghUj8etypciHaPf1AT p+0e1tmZ+855qU/kCbYtaBYF3W8EtkB+602obv+IZXlTsfbQO7gHCAEvwERPvc+19QIt ComHzUfwT7r/2/ujB9JkitaBTSgOUgg/eO+qJds0Xr0hEiBnuKy5UCU4xSM0bC4N0HNb IgJNhST8ZDkU7cpkgEBqwYjMuEUV51/fzqgUJ5Wqn4tEU6KutAlw0XnUEPOwliOe3sv3 lEiA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=x3p870w2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s2si19109064ejs.755.2021.09.27.10.24.01; Mon, 27 Sep 2021 10:24:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=x3p870w2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237376AbhI0RXL (ORCPT + 99 others); Mon, 27 Sep 2021 13:23:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:37176 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236763AbhI0RTy (ORCPT ); Mon, 27 Sep 2021 13:19:54 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A48BB61357; Mon, 27 Sep 2021 17:13:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1632762785; bh=M4aPNCCqKbCrvFzFZjx7zUTnetDQz8mry2ePRCFcYrQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=x3p870w2kd1EP8++Kdj3dpkkbV+KirTMKO8lAIuZH1b+8hdqwO/ctZHyZ1xHTaz4t tEHHoMuLmOs815TCzmNDIByDXv4WxUqf+dJj1pg0ho4fupRQQKe1f2tx4XkADp5c8f iERmZTc8ZDpvzz7JCV+mtDlWu93OLs6GCc66cEZo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Markus Suvanto , David Howells , linux-afs@lists.infradead.org, Sasha Levin Subject: [PATCH 5.14 049/162] afs: Fix incorrect triggering of sillyrename on 3rd-party invalidation Date: Mon, 27 Sep 2021 19:01:35 +0200 Message-Id: <20210927170235.195360006@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210927170233.453060397@linuxfoundation.org> References: <20210927170233.453060397@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: David Howells [ Upstream commit 63d49d843ef5fffeea069e0ffdfbd2bf40ba01c6 ] The AFS filesystem is currently triggering the silly-rename cleanup from afs_d_revalidate() when it sees that a dentry has been changed by a third party[1]. It should not be doing this as the cleanup includes deleting the silly-rename target file on iput. Fix this by removing the places in the d_revalidate handling that validate anything other than the directory and the dirent. It probably should not be looking to validate the target inode of the dentry also. This includes removing the point in afs_d_revalidate() where the inode that a dentry used to point to was marked as being deleted (AFS_VNODE_DELETED). We don't know it got deleted. It could have been renamed or it could have hard links remaining. This was reproduced by cloning a git repo onto an afs volume on one machine, switching to another machine and doing "git status", then switching back to the first and doing "git status". The second status would show weird output due to ".git/index" getting deleted by the above mentioned mechanism. A simpler way to do it is to do: machine 1: touch a machine 2: touch b; mv -f b a machine 1: stat a on an afs volume. The bug shows up as the stat failing with ENOENT and the file server log showing that machine 1 deleted "a". Fixes: 79ddbfa500b3 ("afs: Implement sillyrename for unlink and rename") Reported-by: Markus Suvanto Signed-off-by: David Howells Tested-by: Markus Suvanto cc: linux-afs@lists.infradead.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=214217#c4 [1] Link: https://lore.kernel.org/r/163111668100.283156.3851669884664475428.stgit@warthog.procyon.org.uk/ Signed-off-by: Sasha Levin --- fs/afs/dir.c | 46 +++++++--------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/fs/afs/dir.c b/fs/afs/dir.c index ac829e63c570..54ee54ae36bc 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -1077,9 +1077,9 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, */ static int afs_d_revalidate_rcu(struct dentry *dentry) { - struct afs_vnode *dvnode, *vnode; + struct afs_vnode *dvnode; struct dentry *parent; - struct inode *dir, *inode; + struct inode *dir; long dir_version, de_version; _enter("%p", dentry); @@ -1109,18 +1109,6 @@ static int afs_d_revalidate_rcu(struct dentry *dentry) return -ECHILD; } - /* Check to see if the vnode referred to by the dentry still - * has a callback. - */ - if (d_really_is_positive(dentry)) { - inode = d_inode_rcu(dentry); - if (inode) { - vnode = AFS_FS_I(inode); - if (!afs_check_validity(vnode)) - return -ECHILD; - } - } - return 1; /* Still valid */ } @@ -1156,17 +1144,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) if (IS_ERR(key)) key = NULL; - if (d_really_is_positive(dentry)) { - inode = d_inode(dentry); - if (inode) { - vnode = AFS_FS_I(inode); - afs_validate(vnode, key); - if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) - goto out_bad; - } - } - - /* lock down the parent dentry so we can peer at it */ + /* Hold the parent dentry so we can peer at it */ parent = dget_parent(dentry); dir = AFS_FS_I(d_inode(parent)); @@ -1175,7 +1153,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) if (test_bit(AFS_VNODE_DELETED, &dir->flags)) { _debug("%pd: parent dir deleted", dentry); - goto out_bad_parent; + goto not_found; } /* We only need to invalidate a dentry if the server's copy changed @@ -1201,12 +1179,12 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) case 0: /* the filename maps to something */ if (d_really_is_negative(dentry)) - goto out_bad_parent; + goto not_found; inode = d_inode(dentry); if (is_bad_inode(inode)) { printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n", dentry); - goto out_bad_parent; + goto not_found; } vnode = AFS_FS_I(inode); @@ -1228,9 +1206,6 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) dentry, fid.unique, vnode->fid.unique, vnode->vfs_inode.i_generation); - write_seqlock(&vnode->cb_lock); - set_bit(AFS_VNODE_DELETED, &vnode->flags); - write_sequnlock(&vnode->cb_lock); goto not_found; } goto out_valid; @@ -1245,7 +1220,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) default: _debug("failed to iterate dir %pd: %d", parent, ret); - goto out_bad_parent; + goto not_found; } out_valid: @@ -1256,16 +1231,9 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) _leave(" = 1 [valid]"); return 1; - /* the dirent, if it exists, now points to a different vnode */ not_found: - spin_lock(&dentry->d_lock); - dentry->d_flags |= DCACHE_NFSFS_RENAMED; - spin_unlock(&dentry->d_lock); - -out_bad_parent: _debug("dropping dentry %pd2", dentry); dput(parent); -out_bad: key_put(key); _leave(" = 0 [bad]"); -- 2.33.0