From patchwork Wed Apr 17 18:39:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeffrey Layton X-Patchwork-Id: 10905845 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6477B17E0 for ; Wed, 17 Apr 2019 18:40:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 514AA2873F for ; Wed, 17 Apr 2019 18:40:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 459D4287A2; Wed, 17 Apr 2019 18:40:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E16C028857 for ; Wed, 17 Apr 2019 18:40:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732687AbfDQSkH (ORCPT ); Wed, 17 Apr 2019 14:40:07 -0400 Received: from mail.kernel.org ([198.145.29.99]:41030 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732549AbfDQSkF (ORCPT ); Wed, 17 Apr 2019 14:40:05 -0400 Received: from tleilax.poochiereds.net (cpe-71-70-156-158.nc.res.rr.com [71.70.156.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 71C6D206BA; Wed, 17 Apr 2019 18:40:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555526405; bh=PmDOGGHdFHfmcgvwK47usZ98MbGvxcjMFJfKS/zB2Mw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W03zANHdOpMzWBjagNOkn0IvZ13BKDh4dVeT33KZZuTcNiPGwC+rZLIXCjycro9Vj 2tE4r4yehcp+QbpJy8xndhjhBvpLcsBrVI1Q/9vaow+PAKG6weKhkphrfGGjjyIjaW 16WsiOJO30SBRUgUJOjtFZQuEIZJMS0JtFCwddhM= From: Jeff Layton To: zyan@redhat.com, sage@redhat.com, idryomov@gmail.com Cc: ceph-devel@vger.kernel.org, bengland@redhat.com Subject: [PATCH v2 4/4] ceph: handle the case where a dentry has been renamed on outstanding req Date: Wed, 17 Apr 2019 14:39:59 -0400 Message-Id: <20190417183959.11296-5-jlayton@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190417183959.11296-1-jlayton@kernel.org> References: <20190417183959.11296-1-jlayton@kernel.org> MIME-Version: 1.0 Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP It's possible for us to issue a lookup to revalidate a dentry concurrently with a rename. If done in the right order, then we could end up processing dentry info in the reply that no longer reflects the state of the dentry. If req->r_dentry->d_name differs from the one in the trace, then just ignore the trace in the reply. We only need to do this however if the parent's i_rwsem is not held. Reported-by: "Yan, Zheng" Signed-off-by: Jeff Layton Reviewed-by: "Yan, Zheng" --- fs/ceph/inode.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index b33ba16f7ae8..e1ac10f960dd 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1163,6 +1163,20 @@ static int splice_dentry(struct dentry **pdn, struct inode *in) return 0; } +static bool +d_name_cmp(struct dentry *dentry, const char *name, size_t len) +{ + int ret; + + /* take d_lock to ensure dentry->d_name stability */ + spin_lock(&dentry->d_lock); + ret = dentry->d_name.len - len; + if (!ret) + ret = memcmp(dentry->d_name.name, name, len); + spin_unlock(&dentry->d_lock); + return ret; +} + /* * Incorporate results into the local cache. This is either just * one inode, or a directory, dentry, and possibly linked-to inode (e.g., @@ -1412,7 +1426,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) err = splice_dentry(&req->r_dentry, in); if (err < 0) goto done; - } else if (rinfo->head->is_dentry) { + } else if (rinfo->head->is_dentry && + !d_name_cmp(req->r_dentry, rinfo->dname, rinfo->dname_len)) { struct ceph_vino *ptvino = NULL; if ((le32_to_cpu(rinfo->diri.in->cap.caps) & CEPH_CAP_FILE_SHARED) ||