From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752687AbcFVM10 (ORCPT ); Wed, 22 Jun 2016 08:27:26 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:23596 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752643AbcFVM1X (ORCPT ); Wed, 22 Jun 2016 08:27:23 -0400 X-IBM-Helo: d03dlp02.boulder.ibm.com X-IBM-MailFrom: groug@kaod.org Subject: [PATCH 3/3] fs/9p: search open fids first From: Greg Kurz To: Eric Van Hensbergen Cc: Latchesar Ionkov , Dominique Martinet , linux-kernel@vger.kernel.org, qemu-devel@nongnu.org, v9fs-developer@lists.sourceforge.net, Ron Minnich , "David S. Miller" Date: Wed, 22 Jun 2016 14:25:49 +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 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16062212-0028-0000-0000-000005031D3A X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062212-0029-0000-0000-00002CE29C45 Message-Id: <146659834943.15781.13292558431898075264.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 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org A previous patch fixed the "create-unlink-getattr" idiom: if getattr is called on an unlinked file, we try to find an open fid attached to the corresponding inode. We have a similar issue with file permissions and setattr: open("./test.txt", O_RDWR|O_CREAT, 0666) = 4 chmod("./test.txt", 0) = 0 truncate("./test.txt", 0) = -1 EACCES (Permission denied) ftruncate(4, 0) = -1 EACCES (Permission denied) The failure is expected with truncate() but not with ftruncate(). This happens because the lookup code does find a matching fid in the dentry list. Unfortunately, this is not an open fid and the server will be forced to rely on the path name, rather than on an open file descriptor. This is the case in QEMU: the setattr operation will use truncate() and fail because of bad write permissions. This patch changes the logic in the lookup code, so that we consider open fids first. It gives a chance to the server to match this open fid to an open file descriptor and use ftruncate() instead of truncate(). This does not change the current behaviour for truncate() and other path name based syscalls, since file permissions are checked earlier in the VFS layer. With this patch, we get: open("./test.txt", O_RDWR|O_CREAT, 0666) = 4 chmod("./test.txt", 0) = 0 truncate("./test.txt", 0) = -1 EACCES (Permission denied) ftruncate(4, 0) = 0 Signed-off-by: Greg Kurz --- fs/9p/fid.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 6ac68df50dca..ffe945995378 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -109,8 +109,12 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) dentry, dentry, from_kuid(&init_user_ns, uid), any); ret = NULL; + + if (d_inode(dentry)) + ret = v9fs_fid_find_inode(d_inode(dentry), uid); + /* we'll recheck under lock if there's anything to look in */ - if (dentry->d_fsdata) { + if (!ret && dentry->d_fsdata) { struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata; spin_lock(&dentry->d_lock); hlist_for_each_entry(fid, h, dlist) { @@ -120,9 +124,6 @@ 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;