Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1879419pxk; Sun, 13 Sep 2020 20:43:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzgdarGNbssd+ZSp+4s3dhbbbR832TqBX8UB+M6NGW8UzjQdM3nrQyq9KbmzcSjFaaT5YMx X-Received: by 2002:aa7:d30b:: with SMTP id p11mr15334666edq.80.1600054981721; Sun, 13 Sep 2020 20:43:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600054981; cv=none; d=google.com; s=arc-20160816; b=RBPuLFEOqrVqNFykD9t51xxuPxnnKcikpSaYDV7wjb26VR5hwSJ5d/DGtDFYGpgrmL e3XGoi13zoO1uonbf+q0PKjQuJxg3yy+zG6osVUINRL+xlF0o8i2Eqo8VRFdobjUMdlB Ou8+gZS9EF5sXwkSxstOXXVPXz9X/F8OMjZ9vMl65zQscA8tJkX4t/I9JaIQEFWW2pgx cjdu/QpfZzBLwlVpdwLXkVTDQc0Z1V1EqA300rQOTTHYmx9YJyCH/B/whK/zLsW/JZ4y 0zYn6Ckq2+9LF/ZXP5jmyCWRAW+HqJ9VmW0KcYkiVCBkIg2IybOjm3TfKjvifT90pYDh KcTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=+Ycdim3KP9r5C/GGLv79mwkHcmy7wG/lgHUdaveh5E8=; b=ulpkLfGTVSgcuymTcSf3GNT2OHTUufJDB9qKq1MX+agTHx1AmyKHlmmyqL3csG8yaG NRhn5UNnswow4Vv4jjYpn0kPh9JUengx+qVtR7Ai8iVhQCwMYNRBSykmqzrnkQEv6JRl fj4Mt7JRBaxnpLnwZZVnMP/0wEoUX4QL3yQMwzk/NQ4rBJfioYGHLtVpKIurER1TI0Cp 2xfOpckds6i8mavVoMafIlapiMEpwpGjdV4k7Xl+Y2EqLsI/X/0y8fzIGq6uZHfksGAI NzLzp404+2NlXJ2PkrfrSTFBm/pgzVu9ChjBHDM133mU8tHEAQJiT4MCj9wWk4JaR/gn Ryow== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id os2si406643ejb.112.2020.09.13.20.42.39; Sun, 13 Sep 2020 20:43:01 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726045AbgINDiU (ORCPT + 99 others); Sun, 13 Sep 2020 23:38:20 -0400 Received: from foss.arm.com ([217.140.110.172]:58118 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725965AbgINDiQ (ORCPT ); Sun, 13 Sep 2020 23:38:16 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 71E06113E; Sun, 13 Sep 2020 20:38:15 -0700 (PDT) Received: from entos-thunderx2-desktop.shanghai.arm.com (entos-thunderx2-desktop.shanghai.arm.com [10.169.212.215]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id D554A3F718; Sun, 13 Sep 2020 20:38:12 -0700 (PDT) From: Jianyong Wu To: ericvh@gmail.com, lucho@ionkov.net, asmadeus@codewreck.org, v9fs-developer@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org, justin.he@arm.com, jianyong.wu@arm.com, Greg Kurz Subject: [PATCH RFC 1/4] fs/9p: fix create-unlink-getattr idiom Date: Mon, 14 Sep 2020 11:37:51 +0800 Message-Id: <20200914033754.29188-2-jianyong.wu@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200914033754.29188-1-jianyong.wu@arm.com> References: <20200914033754.29188-1-jianyong.wu@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Van Hensbergen Fixes several outstanding bug reports of not being able to getattr from an open file after an unlink. This patch cleans up transient fids on an unlink and will search open fids on a client if it detects a dentry that appears to have been unlinked. This search is necessary because fstat does not pass fd information through the VFS API to the filesystem, only the dentry which for 9p has an imperfect match to fids. Inherent in this patch is also a fix for the qid handling on create/open which apparently wasn't being set correctly and was necessary for the search to succeed. A possible optimization over this fix is to include accounting of open fids with the inode in the private data (in a similar fashion to the way we track transient fids with dentries). This would allow a much quicker search for a matching open fid. Signed-off-by: Eric Van Hensbergen (changed v9fs_fid_find_global to v9fs_fid_find_inode in comment) Signed-off-by: Greg Kurz Signed-off-by: Jianyong Wu Change-Id: Ifd5c8cdca8b40216e3e7d021eb6d0afd750096e7 --- fs/9p/fid.c | 30 ++++++++++++++++++++++++++++++ fs/9p/vfs_inode.c | 4 ++++ net/9p/client.c | 5 ++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 3d681a2c2731..3304984c0fad 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -38,6 +38,33 @@ void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) spin_unlock(&dentry->d_lock); } +/** + * v9fs_fid_find_inode - search for a fid off of the client list + * @inode: return a fid pointing to a specific inode + * @uid: return a fid belonging to the specified user + * + */ + +static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid) +{ + struct p9_client *clnt = v9fs_inode2v9ses(inode)->clnt; + struct p9_fid *fid, *fidptr, *ret = NULL; + unsigned long flags; + + p9_debug(P9_DEBUG_VFS, " inode: %p\n", inode); + + spin_lock_irqsave(&clnt->lock, flags); + list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) { + if (uid_eq(fid->uid, uid) && + (inode->i_ino == v9fs_qid2ino(&fid->qid))) { + ret = fid; + break; + } + } + spin_unlock_irqrestore(&clnt->lock, flags); + return ret; +} + /** * v9fs_fid_find - retrieve a fid that belongs to the specified uid * @dentry: dentry to look for fid in @@ -65,6 +92,9 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) } } spin_unlock(&dentry->d_lock); + } else { + if (dentry->d_inode) + ret = v9fs_fid_find_inode(dentry->d_inode, uid); } return ret; diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index ae0c38ad1fcb..31c2fddabb82 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -570,6 +570,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) v9fs_invalidate_inode_attr(inode); v9fs_invalidate_inode_attr(dir); + + /* invalidate all fids associated with dentry */ + /* NOTE: This will not include open fids */ + dentry->d_op->d_release(dentry); } return retval; } diff --git a/net/9p/client.c b/net/9p/client.c index 09f1ec589b80..1a3f72bf45fc 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1219,7 +1219,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname, if (nwname) memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid)); else - fid->qid = oldfid->qid; + memmove(&fid->qid, &oldfid->qid, sizeof(struct p9_qid)); kfree(wqids); return fid; @@ -1272,6 +1272,7 @@ int p9_client_open(struct p9_fid *fid, int mode) p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN", qid.type, (unsigned long long)qid.path, qid.version, iounit); + memmove(&fid->qid, &qid, sizeof(struct p9_qid)); fid->mode = mode; fid->iounit = iounit; @@ -1317,6 +1318,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 (unsigned long long)qid->path, qid->version, iounit); + memmove(&ofid->qid, qid, sizeof(struct p9_qid)); ofid->mode = mode; ofid->iounit = iounit; @@ -1362,6 +1364,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode, (unsigned long long)qid.path, qid.version, iounit); + memmove(&fid->qid, &qid, sizeof(struct p9_qid)); fid->mode = mode; fid->iounit = iounit; -- 2.17.1