From patchwork Wed Jun 22 12:25:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 9192649 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AD96A6075A for ; Wed, 22 Jun 2016 12:35:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9D9B0283A6 for ; Wed, 22 Jun 2016 12:35:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 927F0283F7; Wed, 22 Jun 2016 12:35:33 +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=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1DF57283A6 for ; Wed, 22 Jun 2016 12:35:33 +0000 (UTC) Received: from localhost ([::1]:57947 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bFhNU-0005Bc-5H for patchwork-qemu-devel@patchwork.kernel.org; Wed, 22 Jun 2016 08:35:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49794) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bFhE4-0003Mx-5G for qemu-devel@nongnu.org; Wed, 22 Jun 2016 08:25:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bFhE0-0001uE-SA for qemu-devel@nongnu.org; Wed, 22 Jun 2016 08:25:48 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:34402) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bFhE0-0001tz-Iy for qemu-devel@nongnu.org; Wed, 22 Jun 2016 08:25:44 -0400 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u5MCJcSB043006 for ; Wed, 22 Jun 2016 08:25:42 -0400 Received: from e19.ny.us.ibm.com (e19.ny.us.ibm.com [129.33.205.209]) by mx0a-001b2d01.pphosted.com with ESMTP id 23qcxe8v67-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 22 Jun 2016 08:25:42 -0400 Received: from localhost by e19.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 22 Jun 2016 08:25:41 -0400 Received: from d01dlp03.pok.ibm.com (9.56.250.168) by e19.ny.us.ibm.com (146.89.104.206) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 22 Jun 2016 08:25:37 -0400 X-IBM-Helo: d01dlp03.pok.ibm.com X-IBM-MailFrom: groug@kaod.org Received: from b01cxnp23033.gho.pok.ibm.com (b01cxnp23033.gho.pok.ibm.com [9.57.198.28]) by d01dlp03.pok.ibm.com (Postfix) with ESMTP id CA674C90042; Wed, 22 Jun 2016 08:25:27 -0400 (EDT) Received: from b01ledav005.gho.pok.ibm.com (b01ledav005.gho.pok.ibm.com [9.57.199.110]) by b01cxnp23033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u5MCPbdg37748954; Wed, 22 Jun 2016 12:25:37 GMT Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 71E98AE04E; Wed, 22 Jun 2016 08:25:36 -0400 (EDT) Received: from bahia.lan (unknown [9.83.174.77]) by b01ledav005.gho.pok.ibm.com (Postfix) with ESMTP id 1D54EAE051; Wed, 22 Jun 2016 08:25:34 -0400 (EDT) From: Greg Kurz To: Eric Van Hensbergen Date: Wed, 22 Jun 2016 14:25:33 +0200 In-Reply-To: <146659832556.15781.17414806975641516683.stgit@bahia.lan> References: <146659832556.15781.17414806975641516683.stgit@bahia.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16062212-0056-0000-0000-000000973181 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062212-0057-0000-0000-000004B09C33 Message-Id: <146659833390.15781.17019447863817814499.stgit@bahia.lan> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-06-22_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606220132 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH 1/3] fs/9p: fix create-unlink-getattr idiom X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Latchesar Ionkov , Dominique Martinet , linux-kernel@vger.kernel.org, qemu-devel@nongnu.org, Ron Minnich , v9fs-developer@lists.sourceforge.net, "David S. Miller" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 47db55aee7f2..e6f81f327407 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -54,6 +54,33 @@ void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) } /** + * 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 * @uid: return fid that belongs to the specified user @@ -80,6 +107,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 f4645c515262..729144ad0c2c 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -624,6 +624,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 3fc94a49ccd5..98980bacefd4 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1208,7 +1208,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; @@ -1261,6 +1261,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; @@ -1306,6 +1307,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, (unsigned long long)qid->path, qid->version, iounit); + memmove(&ofid->qid, qid, sizeof(struct p9_qid)); ofid->mode = mode; ofid->iounit = iounit; @@ -1351,6 +1353,7 @@ int p9_client_fcreate(struct p9_fid *fid, 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;