From patchwork Wed Oct 23 23:52:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dominique Martinet X-Patchwork-Id: 13848127 Received: from submarine.notk.org (submarine.notk.org [62.210.214.84]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E70A4200120 for ; Wed, 23 Oct 2024 23:52:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.210.214.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727545; cv=none; b=cR9lBfdO2hNiP9Jp1Ls1cNvNFTtquUa28BJpI7vEClI3yKXYds6yzRREBAXxRaxHG6QVrjSkIQEEo3uqSbycgAgWBavUitsNkMfWD17PgSKEkQ93NJWZYb0RTq8Pxks9Hf7imPxq9HifhyS56uTn6PDTaSJ8jmmj5zG3ms9UZ7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727545; c=relaxed/simple; bh=tsqUPM/PR8xfiBAclCOaHQKBESque+aEHCT06C3Sarg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aS03bznTRCorbSxh4vdFlvSVTo8hIeNbMJ40+jZ3WT+wRvhW9YFn9NzkIOFqq6KLJ9Cue8xP7Gb7T9bB5PPch7psaO/WdyMrmjeG13ywp7jTosR0fJ02F/FYcFyM7fxgB31A7efoO445wqGaesewBfiH+ovs8noJuhCACQGI5Xo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org; spf=pass smtp.mailfrom=codewreck.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b=RAPaK2sQ; arc=none smtp.client-ip=62.210.214.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codewreck.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b="RAPaK2sQ" Received: from gaia.codewreck.org (localhost [127.0.0.1]) by submarine.notk.org (Postfix) with ESMTPS id 5B2CF14C2DD; Thu, 24 Oct 2024 01:52:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codewreck.org; s=2; t=1729727542; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+oCYvnKC+qsBiQ6wpcOfEeHkKt8lulKZ/lLgqGbYceI=; b=RAPaK2sQx4Jo3GHxnQXO4A7Hlmx9yFPz3YDmKPeSKezvirsWsBmDmVKK4NTZxIYlI++YBN Tq0e2qbH5FIQ8o/X0RnDbuoVesqI/WazCOVP7Zo+2fPKjhea4QQDprYV2uRY3V3qQYFuDu 6FWcIbaEbNfJxp5cLYWVwln9WWEXonen1bfoxJALs798vUTqCXpD0BofDUx5MDxB6roZPa WQLSWPxpHlGFHownqs6etfObqAAyXEkBV0Igt/suLsO5KJnHUJcnR8oxQI05CPxVXDe13s QTpHCYR9cdeGJHAKwtXaCTX8XuP/xs0c3eAWzrutmROvUMLAoGsbZ6MaUPyVgg== Received: from [127.0.0.1] (localhost.lan [::1]) by gaia.codewreck.org (OpenSMTPD) with ESMTP id 04112cb7; Wed, 23 Oct 2024 23:52:14 +0000 (UTC) From: Dominique Martinet Date: Thu, 24 Oct 2024 08:52:10 +0900 Subject: [PATCH 1/4] Revert " fs/9p: mitigate inode collisions" Precedence: bulk X-Mailing-List: v9fs@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241024-revert_iget-v1-1-4cac63d25f72@codewreck.org> References: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> In-Reply-To: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> To: Eric Van Hensbergen , Latchesar Ionkov , Christian Schoenebeck Cc: "Linux regression tracking (Thorsten Leemhuis)" , v9fs@lists.linux.dev, linux-kernel@vger.kernel.org, Dominique Martinet , Will Deacon , stable@vger.kernel.org X-Mailer: b4 0.14-dev-87f09 X-Developer-Signature: v=1; a=openpgp-sha256; l=8144; i=asmadeus@codewreck.org; h=from:subject:message-id; bh=tsqUPM/PR8xfiBAclCOaHQKBESque+aEHCT06C3Sarg=; b=owEBbQKS/ZANAwAIAatOm+xqmOZwAcsmYgBnGYwuGciyQHcgdjLOxNKBzAGyGA8TzqwkCvfe4 je3Q8vJ6gSJAjMEAAEIAB0WIQT8g9txgG5a3TOhiE6rTpvsapjmcAUCZxmMLgAKCRCrTpvsapjm cMCND/9LufOUyOUzMBZn8LT8J/R+6+49eiyOkEwPeorw7lKQyhFS/6KYtNqxA4zOect6y3viQPv kZkFbxbOP6LMNAtCgmTlqtRFst+7t5WFe0uM3+z1tlXyrzxrXGKdlYJG2k96jwBCESpFjNGsP3Y N3Wx3zw6EFZR7PkOJ266q2Y1OJ2+J8VsVHX5IT3yX3rvPmbnLlHhmTnlPPDbjJlCizskkGQhv7W gKpW0ULdSTQ0RB6idf/e8kHzp7UBUebTutGbvRB5wdHglvEzSaqvUe8Gsm3b9Xq2KUTgb4qSYMB Z3tTJ3Xm1uHXXuhw9kra6+gg76ZDOT3qhTYvpDkRcOdvuo7NOvM2jOien2eZTYdPpNXt4IOJrB9 VkS6zwqsaFPbfN+6t75tnekaGllP+fZYg+JZ/O6ZmRXxSk3K2c0U7i663xztsG2KQnccTh325jk EFW89iwf9528lPOLIEXujwrOmgrr0H4HmiQGDTUCHlVK7/AMPmAKhMJtLEtnN1m2eC4wYWhsPnm B9FfjatADqofHYk0BS/JqKoebFwQNmBAQtdr7Sq5EkrthhGWKLx4Ak0Ih5B+Vqm54XwGpFEJLkr rPoeZwWbEwbz9uneQp7o7HA/jtK36pOd2bRGmIwkl6RVFv1eFSoTQthWaeYkr6k1wQhjPoMls/k 4SjVHIV8mIkqLmg== X-Developer-Key: i=asmadeus@codewreck.org; a=openpgp; fpr=B894379F662089525B3FB1B9333F1F391BBBB00A This reverts commit d05dcfdf5e1659b2949d13060284eff3888b644e. This is a requirement to revert commit 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths"), see that revert for details. Fixes: 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths") Reported-by: Will Deacon Link: https://lkml.kernel.org/r/20240923100508.GA32066@willie-the-truck Cc: stable@vger.kernel.org # v6.9+ Signed-off-by: Dominique Martinet --- fs/9p/v9fs.h | 11 +++++------ fs/9p/vfs_inode.c | 37 ++++++++----------------------------- fs/9p/vfs_inode_dotl.c | 28 ++++++++-------------------- fs/9p/vfs_super.c | 2 +- 4 files changed, 22 insertions(+), 56 deletions(-) diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 1775fcc7f0e8..9defa12208f9 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -179,14 +179,13 @@ extern int v9fs_vfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags); -extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, - bool new); +extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid); extern const struct inode_operations v9fs_dir_inode_operations_dotl; extern const struct inode_operations v9fs_file_inode_operations_dotl; extern const struct inode_operations v9fs_symlink_inode_operations_dotl; extern const struct netfs_request_ops v9fs_req_ops; extern struct inode *v9fs_fid_iget_dotl(struct super_block *sb, - struct p9_fid *fid, bool new); + struct p9_fid *fid); /* other default globals */ #define V9FS_PORT 564 @@ -225,12 +224,12 @@ static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses) */ static inline struct inode * v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, - struct super_block *sb, bool new) + struct super_block *sb) { if (v9fs_proto_dotl(v9ses)) - return v9fs_fid_iget_dotl(sb, fid, new); + return v9fs_fid_iget_dotl(sb, fid); else - return v9fs_fid_iget(sb, fid, new); + return v9fs_fid_iget(sb, fid); } #endif diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index effb3aa1f3ed..5e05ec7af42e 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -366,8 +366,7 @@ void v9fs_evict_inode(struct inode *inode) clear_inode(inode); } -struct inode * -v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, bool new) +struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid) { dev_t rdev; int retval; @@ -379,18 +378,8 @@ v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, bool new) inode = iget_locked(sb, QID2INO(&fid->qid)); if (unlikely(!inode)) return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) { - if (!new) { - goto done; - } else { - p9_debug(P9_DEBUG_VFS, "WARNING: Inode collision %ld\n", - inode->i_ino); - iput(inode); - remove_inode_hash(inode); - inode = iget_locked(sb, QID2INO(&fid->qid)); - WARN_ON(!(inode->i_state & I_NEW)); - } - } + if (!(inode->i_state & I_NEW)) + return inode; /* * initialize the inode with the stat info @@ -414,11 +403,11 @@ v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, bool new) v9fs_set_netfs_context(inode); v9fs_cache_inode_get_cookie(inode); unlock_new_inode(inode); -done: return inode; error: iget_failed(inode); return ERR_PTR(retval); + } /** @@ -450,15 +439,8 @@ static int v9fs_at_to_dotl_flags(int flags) */ static void v9fs_dec_count(struct inode *inode) { - if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) { - if (inode->i_nlink) { - drop_nlink(inode); - } else { - p9_debug(P9_DEBUG_VFS, - "WARNING: unexpected i_nlink zero %d inode %ld\n", - inode->i_nlink, inode->i_ino); - } - } + if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) + drop_nlink(inode); } /** @@ -509,9 +491,6 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) } else v9fs_dec_count(inode); - if (inode->i_nlink <= 0) /* no more refs unhash it */ - remove_inode_hash(inode); - v9fs_invalidate_inode_attr(inode); v9fs_invalidate_inode_attr(dir); @@ -577,7 +556,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, /* * instantiate inode and assign the unopened fid to the dentry */ - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb, true); + inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, @@ -706,7 +685,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, else if (IS_ERR(fid)) inode = ERR_CAST(fid); else - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb, false); + inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); /* * If we had a rename on the server and a parallel lookup * for the new name, then make sure we instantiate with diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index c61b97bd13b9..55dde186041a 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -52,10 +52,7 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) return current_fsgid(); } - - -struct inode * -v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new) +struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid) { int retval; struct inode *inode; @@ -65,18 +62,8 @@ v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new) inode = iget_locked(sb, QID2INO(&fid->qid)); if (unlikely(!inode)) return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) { - if (!new) { - goto done; - } else { /* deal with race condition in inode number reuse */ - p9_debug(P9_DEBUG_ERROR, "WARNING: Inode collision %lx\n", - inode->i_ino); - iput(inode); - remove_inode_hash(inode); - inode = iget_locked(sb, QID2INO(&fid->qid)); - WARN_ON(!(inode->i_state & I_NEW)); - } - } + if (!(inode->i_state & I_NEW)) + return inode; /* * initialize the inode with the stat info @@ -103,11 +90,12 @@ v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new) goto error; unlock_new_inode(inode); -done: + return inode; error: iget_failed(inode); return ERR_PTR(retval); + } struct dotl_openflag_map { @@ -259,7 +247,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); goto out; } - inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true); + inode = v9fs_fid_iget_dotl(dir->i_sb, fid); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err); @@ -352,7 +340,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap, } /* instantiate inode and assign the unopened fid to the dentry */ - inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true); + inode = v9fs_fid_iget_dotl(dir->i_sb, fid); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", @@ -788,7 +776,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, err); goto error; } - inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true); + inode = v9fs_fid_iget_dotl(dir->i_sb, fid); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index f52fdf42945c..55e67e36ae68 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -139,7 +139,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, else sb->s_d_op = &v9fs_dentry_operations; - inode = v9fs_get_inode_from_fid(v9ses, fid, sb, true); + inode = v9fs_get_inode_from_fid(v9ses, fid, sb); if (IS_ERR(inode)) { retval = PTR_ERR(inode); goto release_sb; From patchwork Wed Oct 23 23:52:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dominique Martinet X-Patchwork-Id: 13848128 Received: from submarine.notk.org (submarine.notk.org [62.210.214.84]) by smtp.subspace.kernel.org (Postfix) with ESMTP id ADF0D1553AB for ; Wed, 23 Oct 2024 23:52:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.210.214.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727546; cv=none; b=EDqxtOpZuEi78agYX+eKn1OwXIOUEg4rEAraV59qW55XRnYS1r2Hnqo3JRK2UaHIg3zijHNNgwPH1k9X7KoHnoUHTBpaCd2xPU7H0jMdH6EdlYHKuwaz3F49wsBoPixNSbwZ3JCXeYRwCL3G7t5Y3N6NfX/IfKpXTHbS9g73U5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727546; c=relaxed/simple; bh=2jNRSNETBdoBmXcxqoPcSW/Pu+5mOR/5FQsdWsgGU1g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eXh0KB67XmdxAA/0kq7OZip9qmp/aXwT0azaQxYqZmZBVjl4Z0z3dZFJIRt+CWdEGM4D9MhkBJQwWhGDfODJsdVh/POkjkVUN6vsZ9rHJEL04Cuq552GSgugH4fnN2xUMwYs1uDfDkF4+vgExageTI6ZXKpJYyDr+x64PMhvNIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org; spf=pass smtp.mailfrom=codewreck.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b=QKnzaIV8; arc=none smtp.client-ip=62.210.214.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codewreck.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b="QKnzaIV8" Received: from gaia.codewreck.org (localhost [127.0.0.1]) by submarine.notk.org (Postfix) with ESMTPS id 494E214C2DE; Thu, 24 Oct 2024 01:52:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codewreck.org; s=2; t=1729727543; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=c9RUoHXYJukKxYmUrbnbvTXMN6BCsDk1ng65p881zxY=; b=QKnzaIV8nv6sJ0N/C1zf77MAnsd5hTyD2me5tv/nJ4kDZ+7VggPA0vVHmcjU5Y8ueVFseX 4ltvTyRZYWssqmTlWmWs4k/cqhH5SDJ5jj802392QfZR2oZGcAvwlq/EmEZZf2QGUd1iZ9 UufM/uGwnpL456/XcJxLN2haoZaSN8lIuOu4KJ8JGDIgUoMgztdWl8ms+Nm+AqjTFCLtAE wYvP5ixeiTr3Kzk5+JZIJSnIIGvpDlHYs8AlD8Fa8bBeaHK42q+J9q4b3KDL1SNeJHlgSg UCJ7bBGmUEcQhKS1zmEuMIQ7V6s+XSgVqw8OG7yy41qWPKIzIsKyN6wIVIpFRQ== Received: from [127.0.0.1] (localhost.lan [::1]) by gaia.codewreck.org (OpenSMTPD) with ESMTP id 23319dd8; Wed, 23 Oct 2024 23:52:14 +0000 (UTC) From: Dominique Martinet Date: Thu, 24 Oct 2024 08:52:11 +0900 Subject: [PATCH 2/4] Revert "fs/9p: remove redundant pointer v9ses" Precedence: bulk X-Mailing-List: v9fs@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241024-revert_iget-v1-2-4cac63d25f72@codewreck.org> References: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> In-Reply-To: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> To: Eric Van Hensbergen , Latchesar Ionkov , Christian Schoenebeck Cc: "Linux regression tracking (Thorsten Leemhuis)" , v9fs@lists.linux.dev, linux-kernel@vger.kernel.org, Dominique Martinet , Will Deacon , stable@vger.kernel.org X-Mailer: b4 0.14-dev-87f09 X-Developer-Signature: v=1; a=openpgp-sha256; l=1796; i=asmadeus@codewreck.org; h=from:subject:message-id; bh=2jNRSNETBdoBmXcxqoPcSW/Pu+5mOR/5FQsdWsgGU1g=; b=owEBbQKS/ZANAwAIAatOm+xqmOZwAcsmYgBnGYwusNK+2S7ozYMD51VyLjMOVOK7Jzb5Kvx2y w87QOPuXe+JAjMEAAEIAB0WIQT8g9txgG5a3TOhiE6rTpvsapjmcAUCZxmMLgAKCRCrTpvsapjm cFefD/94l9C7Rbe1mO1CEvyJQ6fNSmwP9/KG7tEXeLw6OKzMgwnV+VUryXJDxEy+C6UujLoKyv1 Q7mieUoJ6FGFzHxhCrP2rQ66TIIuGy+HbcPAJuaYUEFR4hIi62Ti78wj7KI3Uz1Vov2gY2s/8DR 9tkHd2VMNpHUG7fNEmouSVwAjrDwjIkop0LOuZfXqhXA7fw4Fx0uHNzhHGHUeZfrNkDJGBgwc3l CvC4W8H/J0SiWbCXITmyEiX/3mXJ4vLmBKn6BvpGxoYezQdkRLZT3m2cmgmT5p/JkEIKXc9LWP1 2+UdtRKQrJA6AQWiK111r3+vUZ1VocBSbpo354b5w6wBgE6PhxJELoilClbOfbYOYE6Jj8KYfbI rx+ERHTrtwUVqikJeOrV6K9v7rNY5pCqDvtXPnza+YZOTw+dAFhDtM9LCeWC3+sCcC/+y7MkdiR sV1FSVgKRxGwXc/stzDsIWUvyGQ/iq4j20CgDtiCdu4BE7eudLqISfmq+ERcAjcFRBF6YeU2hPD HfoRlZWh2lMQ7aPdMcx8+H8LE9HVt/0R3Cfz+FC8SviJFzDTHS21utNEewWDweeKnuTxJcBwKiV 1CEy+ppL4yx83tJqFbgYx/h1CbF2Q7iWrUGrl+QEgfvRZIXf0SMi/tm7QJEht/lSs4UHN3xvPyM utlQNgLKVwf1btA== X-Developer-Key: i=asmadeus@codewreck.org; a=openpgp; fpr=B894379F662089525B3FB1B9333F1F391BBBB00A This reverts commit 10211b4a23cf4a3df5c11a10e5b3d371f16a906f. This is a requirement to revert commit 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths"), see that revert for details. Fixes: 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths") Reported-by: Will Deacon Link: https://lkml.kernel.org/r/20240923100508.GA32066@willie-the-truck Cc: stable@vger.kernel.org # v6.9+ Signed-off-by: Dominique Martinet --- fs/9p/vfs_inode_dotl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 55dde186041a..2b313fe7003e 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -297,6 +297,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap, umode_t omode) { int err; + struct v9fs_session_info *v9ses; struct p9_fid *fid = NULL, *dfid = NULL; kgid_t gid; const unsigned char *name; @@ -306,6 +307,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap, struct posix_acl *dacl = NULL, *pacl = NULL; p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); + v9ses = v9fs_inode2v9ses(dir); omode |= S_IFDIR; if (dir->i_mode & S_ISGID) @@ -737,6 +739,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, kgid_t gid; const unsigned char *name; umode_t mode; + struct v9fs_session_info *v9ses; struct p9_fid *fid = NULL, *dfid = NULL; struct inode *inode; struct p9_qid qid; @@ -746,6 +749,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, dir->i_ino, dentry, omode, MAJOR(rdev), MINOR(rdev)); + v9ses = v9fs_inode2v9ses(dir); dfid = v9fs_parent_fid(dentry); if (IS_ERR(dfid)) { err = PTR_ERR(dfid); From patchwork Wed Oct 23 23:52:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dominique Martinet X-Patchwork-Id: 13848129 Received: from submarine.notk.org (submarine.notk.org [62.210.214.84]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 051272003AF for ; Wed, 23 Oct 2024 23:52:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.210.214.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727547; cv=none; b=V/tha7CoiPto/ANp3WGwLj6cemiCqzrYW5ogsDpmQWiLaNaoIZjmZmNaCvK+qKeaOZI2npSXvEShTE8/mdpseQBdHCtFwHO/h3d7qshPSMZ75wcCYNFGoseWV4o4j1heKzS5eIQWfxvp9m/9dfT1QOghg8J6PD+tWG/+R2bbHTQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727547; c=relaxed/simple; bh=1a/Bd6MVgtny3x6qYfGD1H0MSVQ/x7ApD2BNdRoVBjY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eqFvFNvjCREfAP5txJb6MQluGMTgbx7AZiLba7geRL1DtgL3YHTT3CiLH53jNcMwsFtEt4RfB4LIZS4Upol+b+1auN20hzN81J7lw6Oo/UctVkCb2UGdaDBy1hPTfs5HM2q0AZKt+jy+bhTZddP8tTobPBqI9thA6xqX0Pz/Fn8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org; spf=pass smtp.mailfrom=codewreck.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b=aNmWzHQp; arc=none smtp.client-ip=62.210.214.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codewreck.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b="aNmWzHQp" Received: from gaia.codewreck.org (localhost [127.0.0.1]) by submarine.notk.org (Postfix) with ESMTPS id 95AF214C2DF; Thu, 24 Oct 2024 01:52:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codewreck.org; s=2; t=1729727545; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pCSeVIizETL3AZftJfJ4jkpxwztAnC+IPubkBSbvaD0=; b=aNmWzHQpdqtaCpcPJ+Bo19UVr2Q73v1wQYWATcRXp0mh23C6dPqhdUFl8VTWovTEX0KzqI uv3d1ofEX1WVggbsw4VaTL/Aa433qLOJSKeIXXj0Sifp/O9cYUkO5oua6sfLqCx+MGTNwK L72BRY8gYnX/Oo5Hfh7e0E/rLByTOc/PIZdEAtHtCM80HWmEodQsmc8Bho+xaxppHdxIcD t2yqZXgaHmnJKepP+B08wI9cKVuGoYWsflJo+kgmZCwoLFFHKPnaaDkaO+wzWAPkezqIf5 Zf6+MXnVHDk2osRJndOFYMWKCOHH41maVLhBjnbyokCAA8l+NiFsYzqpuGBx5w== Received: from [127.0.0.1] (localhost.lan [::1]) by gaia.codewreck.org (OpenSMTPD) with ESMTP id 129c9a46; Wed, 23 Oct 2024 23:52:14 +0000 (UTC) From: Dominique Martinet Date: Thu, 24 Oct 2024 08:52:12 +0900 Subject: [PATCH 3/4] Revert "fs/9p: fix uaf in in v9fs_stat2inode_dotl" Precedence: bulk X-Mailing-List: v9fs@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241024-revert_iget-v1-3-4cac63d25f72@codewreck.org> References: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> In-Reply-To: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> To: Eric Van Hensbergen , Latchesar Ionkov , Christian Schoenebeck Cc: "Linux regression tracking (Thorsten Leemhuis)" , v9fs@lists.linux.dev, linux-kernel@vger.kernel.org, Dominique Martinet , Will Deacon , stable@vger.kernel.org X-Mailer: b4 0.14-dev-87f09 X-Developer-Signature: v=1; a=openpgp-sha256; l=1197; i=asmadeus@codewreck.org; h=from:subject:message-id; bh=1a/Bd6MVgtny3x6qYfGD1H0MSVQ/x7ApD2BNdRoVBjY=; b=owEBbQKS/ZANAwAIAatOm+xqmOZwAcsmYgBnGYwuBF/ECwjzn/a5TaI2xjpsECqsuVnI9ymMv yXRWunPSeeJAjMEAAEIAB0WIQT8g9txgG5a3TOhiE6rTpvsapjmcAUCZxmMLgAKCRCrTpvsapjm cFzPD/4/lWbe3id79E4xDe688DeGhvsWIY9ghzSh2A5Ski6zbjtXFQk7dVIxnMupZOKIC0XYXl6 0V/uzW/fpcpif7PNkS8iVt6VAFzNpZN5/Pw+X/SwQU/r0WZElhXQr/oF7z42WlHv9+PHEZEfgmq 4EJeYJ+gBVAZF+CKyCte7hTY4dWkBe/JQ+rMxDp4tbNZG9qITxDVC8b9CVJKe3hhHWDveaYv0lW BoDRA8t+yN/EgL2bG3mC/YJz8iZ3BJUXARtmiVNddP2GBMTpQitSpt6y4QwcL/HJHXWNs1AAa65 Q1tMZs45n2aR+RgM26m2Yjh50xwPMk/9ir1wXVcfo3Gfyi6Te8wXzkDFrQO35Gvs5uoKWsvpZ3h HibBBoeScRMn90UkwYKbHKlBqY0jyW3MUM1d2msAu/HCMPLBsixotP3UpsY883xvIPOexQTKzax BGgJFzR0a2yKA0hs+JyJA5cwrG8wxxAG9jZUP5JPgbvhl3CgfLe7F4oLzRPfJhpFv/4DNZZvubM vsQLyz5JTtVGSexKifx5QbKjqPyj36lm1bA/59LyOGOitbvXKP5P/1RLi+VZt4br/jPXiEFZqAe Mxx4TRSxypxZ7U/Jym9nV0MOMZw3jaBrPKjCeSZxLpEmXv5hXoCIOwSTb4HxH/wblpmnUIJO0S0 pg5wa8iVEJr3dhg== X-Developer-Key: i=asmadeus@codewreck.org; a=openpgp; fpr=B894379F662089525B3FB1B9333F1F391BBBB00A This reverts commit 11763a8598f888dec631a8a903f7ada32181001f. This is a requirement to revert commit 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths"), see that revert for details. Fixes: 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths") Reported-by: Will Deacon Link: https://lkml.kernel.org/r/20240923100508.GA32066@willie-the-truck Cc: stable@vger.kernel.org # v6.9+ Signed-off-by: Dominique Martinet --- fs/9p/vfs_inode_dotl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 2b313fe7003e..ef9db3e03506 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -78,11 +78,11 @@ struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid) retval = v9fs_init_inode(v9ses, inode, &fid->qid, st->st_mode, new_decode_dev(st->st_rdev)); - v9fs_stat2inode_dotl(st, inode, 0); kfree(st); if (retval) goto error; + v9fs_stat2inode_dotl(st, inode, 0); v9fs_set_netfs_context(inode); v9fs_cache_inode_get_cookie(inode); retval = v9fs_get_acl(inode, fid); From patchwork Wed Oct 23 23:52:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dominique Martinet X-Patchwork-Id: 13848130 Received: from submarine.notk.org (submarine.notk.org [62.210.214.84]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C84DF200B82 for ; Wed, 23 Oct 2024 23:52:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.210.214.84 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727550; cv=none; b=Ys7OVTPhca1FWCB+FAM42/gt4rqtwfMNPDVWe+9IOJ782AyzVguQjGVRM8nQNoJrL6Hufj21jBRdPZvIk+wd5siuTM3n3vII5wU3WpEnm0S2JzAPs0wmLpxTcmFbB9/f2tRQ2wtDBjea9swCvLuCLvFjB68PjYnLATlsJg3vj+k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729727550; c=relaxed/simple; bh=PPkik43Ft+ziz/KL7sgGGZXrZDSANPKFv63JbrbMYKk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BtOhUc942WF6UL/QR1rN7qbBr3kQcczMCpJCBBGsRQ4l0lOEr2qd7BWho17RBUphQYGvD5/55Z+tQVSQ40eTcWTwERS/8wLWbGEsXb3M6//XXwF6b6y62m0SHM8iGrHPjsiMWNMKdibjSVpF31oKvM1GxQtzWewujpY8dQSAkvA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org; spf=pass smtp.mailfrom=codewreck.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b=yqJicc7f; arc=none smtp.client-ip=62.210.214.84 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codewreck.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codewreck.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codewreck.org header.i=@codewreck.org header.b="yqJicc7f" Received: from gaia.codewreck.org (localhost [127.0.0.1]) by submarine.notk.org (Postfix) with ESMTPS id 856F014C2E0; Thu, 24 Oct 2024 01:52:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codewreck.org; s=2; t=1729727547; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YBuilkAE0mEP50w0sfwMqno3aFOex5ZsPzmLQrBt/eU=; b=yqJicc7f4niXza4eh2/DFr/EMwE4QxVsdMY0U2eR0HzhYYlXmdumPxJ1Q1W4D5mUPBeFYW VrF6PbK7z9k2ax6fy84kVaEt85fYWGE19M/T2Q0HqmoY2LCoZa1ArgoC315QFJAd/+HYOL zT6KrK5q9BebNOC2cJMvjVLakTcfwEzmPP0kibs3pXAGHR5S2oshLfYvBM+G6pg35NM5aX ak+1XVNLtj+HOSoyf9dbKB2YXZVKzeK4a5TwrYeGk3GOjx/JG4HOAdwZHQcU3MGS65J1ex P3YQmbPm0d7eeySRC+xO5SKXMiK+JPmJrFO0tPU2KQfuHF287UrqtHYl1x2E2Q== Received: from [127.0.0.1] (localhost.lan [::1]) by gaia.codewreck.org (OpenSMTPD) with ESMTP id 9385011d; Wed, 23 Oct 2024 23:52:14 +0000 (UTC) From: Dominique Martinet Date: Thu, 24 Oct 2024 08:52:13 +0900 Subject: [PATCH 4/4] Revert "fs/9p: simplify iget to remove unnecessary paths" Precedence: bulk X-Mailing-List: v9fs@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241024-revert_iget-v1-4-4cac63d25f72@codewreck.org> References: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> In-Reply-To: <20241024-revert_iget-v1-0-4cac63d25f72@codewreck.org> To: Eric Van Hensbergen , Latchesar Ionkov , Christian Schoenebeck Cc: "Linux regression tracking (Thorsten Leemhuis)" , v9fs@lists.linux.dev, linux-kernel@vger.kernel.org, Dominique Martinet , Will Deacon , stable@vger.kernel.org X-Mailer: b4 0.14-dev-87f09 X-Developer-Signature: v=1; a=openpgp-sha256; l=15014; i=asmadeus@codewreck.org; h=from:subject:message-id; bh=PPkik43Ft+ziz/KL7sgGGZXrZDSANPKFv63JbrbMYKk=; b=owEBbQKS/ZANAwAIAatOm+xqmOZwAcsmYgBnGYwuVSjuK+6OOqZl2inM7epu748jxmsciFjrS 6nXenBLrMuJAjMEAAEIAB0WIQT8g9txgG5a3TOhiE6rTpvsapjmcAUCZxmMLgAKCRCrTpvsapjm cO8wD/oDyKbCOSsDyzLtQCVDMbSM4krc8ST19/4iAZMoJSs9N8TC5vn4GCRs56BQd/WPXtBWpln 8HQvxD5AECP6iG8FNnn99QkWZ3+PWF84qDNtky+2TGUD3u3YsqHC1Pw3jwqWHmdMX6opl1KijZO 6Lq3NU+AXLSjfQuBfUgljRsS5+EoD4knE62C9Rr5ttzVi2gsV6BBDJg6w11ofiyB9WHM3VOe3gF llJOHe1M1k6pn//HxGPgfaWGZ7p/VAawAQ2+W/la1zcY5NRt9ArhD8c0isBUUTDvaO3ChOWV4xL b+44JVdN+DEXXIDsVp27wfcgHmtv0/16S93PfFOY/2T9eJmt+K9MciOozGUho2+25I33Ul/Suw4 /U5TPOjxiULmH/QziNm7nq0078mwTpYqiFoaS+GjGCIESVnPMv4JUmgHdRDM1YtZj2fWD58Pek9 L1XbOpMIeWWGZi5/Ra/CLSb306eXkMhrwODrlUx8LJ5vWrzZrdL+wfiW1tkhlQWc+06y2aKmQmX Tj8Ky8C2kKoARsPVPjCTvOLiLkKqCqTRDr+0cLIEejXRwiQ6HlAGMBg8MJs1+GIW9cgINB8eani 0uflN1hxfDsPLniDRZ7RPsuNm+l8pQSRQ6kJ/bz3chnTLttPXSCX40kTvzkXJ4Imxi6554+D+ub ub1B1/L+iXYakAA== X-Developer-Key: i=asmadeus@codewreck.org; a=openpgp; fpr=B894379F662089525B3FB1B9333F1F391BBBB00A This reverts commit 724a08450f74b02bd89078a596fd24857827c012. This code simplification introduced significant regressions on servers that do not remap inode numbers when exporting multiple underlying filesystems with colliding inodes, as can be illustrated with simple tmpfs exports in qemu with remapping disabled: --- # host side cd /tmp/linux-test mkdir m1 m2 mount -t tmpfs tmpfs m1 mount -t tmpfs tmpfs m2 mkdir m1/dir m2/dir echo foo > m1/dir/foo echo bar > m2/dir/bar # guest side # started with -virtfs local,path=/tmp/linux-test,mount_tag=tmp,security_model=mapped-file mount -t 9p -o trans=virtio,debug=1 tmp /mnt/t ls /mnt/t/m1/dir # foo ls /mnt/t/m2/dir # bar (works ok if directry isn't open) # cd to keep first dir's inode alive cd /mnt/t/m1/dir ls /mnt/t/m2/dir # foo (should be bar) --- Other examples can be crafted with regular files with fscache enabled, in which case I/Os just happen to the wrong file leading to corruptions, or guest failing to boot with: | VFS: Lookup of 'com.android.runtime' in 9p 9p would have caused loop In theory, we'd want the servers to be smart enough and ensure they never send us two different files with the same 'qid.path', but while qemu has an option to remap that is recommended (and qemu prints a warning if this case happens), there are many other servers which do not (kvmtool, nfs-ganesha, probably diod...), we should at least ensure we don't cause regressions on this: - assume servers can't be trusted and operations that should get a 'new' inode properly do so. commit d05dcfdf5e16 (" fs/9p: mitigate inode collisions") attempted to do this, but v9fs_fid_iget_dotl() was not called so some higher level of caching got in the way; this needs to be fixed properly before we can re-apply the patches. - if we ever want to really simplify this code, we will need to add some negotiation with the server at mount time where the server could claim they handle this properly, at which point we could optimize this out. (but that might not be needed at all if we properly handle the 'new' check?) Fixes: 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths") Reported-by: Will Deacon Link: https://lore.kernel.org/all/20240408141436.GA17022@redhat.com/ Link: https://lkml.kernel.org/r/20240923100508.GA32066@willie-the-truck Cc: stable@vger.kernel.org # v6.9+ Signed-off-by: Dominique Martinet --- fs/9p/v9fs.h | 31 +++++++++++++--- fs/9p/v9fs_vfs.h | 2 +- fs/9p/vfs_inode.c | 98 +++++++++++++++++++++++++++++++++++++++----------- fs/9p/vfs_inode_dotl.c | 92 ++++++++++++++++++++++++++++++++++++++--------- fs/9p/vfs_super.c | 2 +- 5 files changed, 180 insertions(+), 45 deletions(-) diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 9defa12208f9..698c43dd5dc8 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -179,13 +179,16 @@ extern int v9fs_vfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags); -extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid); +extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, + struct p9_fid *fid, + struct super_block *sb, int new); extern const struct inode_operations v9fs_dir_inode_operations_dotl; extern const struct inode_operations v9fs_file_inode_operations_dotl; extern const struct inode_operations v9fs_symlink_inode_operations_dotl; extern const struct netfs_request_ops v9fs_req_ops; -extern struct inode *v9fs_fid_iget_dotl(struct super_block *sb, - struct p9_fid *fid); +extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, + struct p9_fid *fid, + struct super_block *sb, int new); /* other default globals */ #define V9FS_PORT 564 @@ -227,9 +230,27 @@ v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, struct super_block *sb) { if (v9fs_proto_dotl(v9ses)) - return v9fs_fid_iget_dotl(sb, fid); + return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0); else - return v9fs_fid_iget(sb, fid); + return v9fs_inode_from_fid(v9ses, fid, sb, 0); +} + +/** + * v9fs_get_new_inode_from_fid - Helper routine to populate an inode by + * issuing a attribute request + * @v9ses: session information + * @fid: fid to issue attribute request for + * @sb: superblock on which to create inode + * + */ +static inline struct inode * +v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, + struct super_block *sb) +{ + if (v9fs_proto_dotl(v9ses)) + return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1); + else + return v9fs_inode_from_fid(v9ses, fid, sb, 1); } #endif diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 7923c3c347cb..d3aefbec4de6 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h @@ -42,7 +42,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb); void v9fs_free_inode(struct inode *inode); void v9fs_set_netfs_context(struct inode *inode); int v9fs_init_inode(struct v9fs_session_info *v9ses, - struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev); + struct inode *inode, umode_t mode, dev_t rdev); void v9fs_evict_inode(struct inode *inode); #if (BITS_PER_LONG == 32) #define QID2INO(q) ((ino_t) (((q)->path+2) ^ (((q)->path) >> 32))) diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 5e05ec7af42e..e9c052b35dd9 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -256,12 +256,9 @@ void v9fs_set_netfs_context(struct inode *inode) } int v9fs_init_inode(struct v9fs_session_info *v9ses, - struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev) + struct inode *inode, umode_t mode, dev_t rdev) { int err = 0; - struct v9fs_inode *v9inode = V9FS_I(inode); - - memcpy(&v9inode->qid, qid, sizeof(struct p9_qid)); inode_init_owner(&nop_mnt_idmap, inode, NULL, mode); inode->i_blocks = 0; @@ -366,40 +363,80 @@ void v9fs_evict_inode(struct inode *inode) clear_inode(inode); } -struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid) +static int v9fs_test_inode(struct inode *inode, void *data) +{ + int umode; + dev_t rdev; + struct v9fs_inode *v9inode = V9FS_I(inode); + struct p9_wstat *st = (struct p9_wstat *)data; + struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); + + umode = p9mode2unixmode(v9ses, st, &rdev); + /* don't match inode of different type */ + if (inode_wrong_type(inode, umode)) + return 0; + + /* compare qid details */ + if (memcmp(&v9inode->qid.version, + &st->qid.version, sizeof(v9inode->qid.version))) + return 0; + + if (v9inode->qid.type != st->qid.type) + return 0; + + if (v9inode->qid.path != st->qid.path) + return 0; + return 1; +} + +static int v9fs_test_new_inode(struct inode *inode, void *data) +{ + return 0; +} + +static int v9fs_set_inode(struct inode *inode, void *data) +{ + struct v9fs_inode *v9inode = V9FS_I(inode); + struct p9_wstat *st = (struct p9_wstat *)data; + + memcpy(&v9inode->qid, &st->qid, sizeof(st->qid)); + return 0; +} + +static struct inode *v9fs_qid_iget(struct super_block *sb, + struct p9_qid *qid, + struct p9_wstat *st, + int new) { dev_t rdev; int retval; umode_t umode; struct inode *inode; - struct p9_wstat *st; struct v9fs_session_info *v9ses = sb->s_fs_info; + int (*test)(struct inode *inode, void *data); - inode = iget_locked(sb, QID2INO(&fid->qid)); - if (unlikely(!inode)) + if (new) + test = v9fs_test_new_inode; + else + test = v9fs_test_inode; + + inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode, st); + if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; - /* * initialize the inode with the stat info * FIXME!! we may need support for stale inodes * later. */ - st = p9_client_stat(fid); - if (IS_ERR(st)) { - retval = PTR_ERR(st); - goto error; - } - + inode->i_ino = QID2INO(qid); umode = p9mode2unixmode(v9ses, st, &rdev); - retval = v9fs_init_inode(v9ses, inode, &fid->qid, umode, rdev); - v9fs_stat2inode(st, inode, sb, 0); - p9stat_free(st); - kfree(st); + retval = v9fs_init_inode(v9ses, inode, umode, rdev); if (retval) goto error; + v9fs_stat2inode(st, inode, sb, 0); v9fs_set_netfs_context(inode); v9fs_cache_inode_get_cookie(inode); unlock_new_inode(inode); @@ -410,6 +447,23 @@ struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid) } +struct inode * +v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, + struct super_block *sb, int new) +{ + struct p9_wstat *st; + struct inode *inode = NULL; + + st = p9_client_stat(fid); + if (IS_ERR(st)) + return ERR_CAST(st); + + inode = v9fs_qid_iget(sb, &st->qid, st, new); + p9stat_free(st); + kfree(st); + return inode; +} + /** * v9fs_at_to_dotl_flags- convert Linux specific AT flags to * plan 9 AT flag. @@ -556,7 +610,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, /* * instantiate inode and assign the unopened fid to the dentry */ - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, @@ -684,8 +738,10 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, inode = NULL; else if (IS_ERR(fid)) inode = ERR_CAST(fid); - else + else if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); + else + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); /* * If we had a rename on the server and a parallel lookup * for the new name, then make sure we instantiate with diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index ef9db3e03506..143ac03b7425 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -52,33 +52,76 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) return current_fsgid(); } -struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid) +static int v9fs_test_inode_dotl(struct inode *inode, void *data) +{ + struct v9fs_inode *v9inode = V9FS_I(inode); + struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; + + /* don't match inode of different type */ + if (inode_wrong_type(inode, st->st_mode)) + return 0; + + if (inode->i_generation != st->st_gen) + return 0; + + /* compare qid details */ + if (memcmp(&v9inode->qid.version, + &st->qid.version, sizeof(v9inode->qid.version))) + return 0; + + if (v9inode->qid.type != st->qid.type) + return 0; + + if (v9inode->qid.path != st->qid.path) + return 0; + return 1; +} + +/* Always get a new inode */ +static int v9fs_test_new_inode_dotl(struct inode *inode, void *data) +{ + return 0; +} + +static int v9fs_set_inode_dotl(struct inode *inode, void *data) +{ + struct v9fs_inode *v9inode = V9FS_I(inode); + struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; + + memcpy(&v9inode->qid, &st->qid, sizeof(st->qid)); + inode->i_generation = st->st_gen; + return 0; +} + +static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, + struct p9_qid *qid, + struct p9_fid *fid, + struct p9_stat_dotl *st, + int new) { int retval; struct inode *inode; - struct p9_stat_dotl *st; struct v9fs_session_info *v9ses = sb->s_fs_info; + int (*test)(struct inode *inode, void *data); - inode = iget_locked(sb, QID2INO(&fid->qid)); - if (unlikely(!inode)) + if (new) + test = v9fs_test_new_inode_dotl; + else + test = v9fs_test_inode_dotl; + + inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode_dotl, st); + if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; - /* * initialize the inode with the stat info * FIXME!! we may need support for stale inodes * later. */ - st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN); - if (IS_ERR(st)) { - retval = PTR_ERR(st); - goto error; - } - - retval = v9fs_init_inode(v9ses, inode, &fid->qid, + inode->i_ino = QID2INO(qid); + retval = v9fs_init_inode(v9ses, inode, st->st_mode, new_decode_dev(st->st_rdev)); - kfree(st); if (retval) goto error; @@ -90,7 +133,6 @@ struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid) goto error; unlock_new_inode(inode); - return inode; error: iget_failed(inode); @@ -98,6 +140,22 @@ struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid) } +struct inode * +v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, + struct super_block *sb, int new) +{ + struct p9_stat_dotl *st; + struct inode *inode = NULL; + + st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN); + if (IS_ERR(st)) + return ERR_CAST(st); + + inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new); + kfree(st); + return inode; +} + struct dotl_openflag_map { int open_flag; int dotl_flag; @@ -247,7 +305,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); goto out; } - inode = v9fs_fid_iget_dotl(dir->i_sb, fid); + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err); @@ -342,7 +400,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap, } /* instantiate inode and assign the unopened fid to the dentry */ - inode = v9fs_fid_iget_dotl(dir->i_sb, fid); + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", @@ -780,7 +838,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, err); goto error; } - inode = v9fs_fid_iget_dotl(dir->i_sb, fid); + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 55e67e36ae68..489db161abc9 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -139,7 +139,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, else sb->s_d_op = &v9fs_dentry_operations; - inode = v9fs_get_inode_from_fid(v9ses, fid, sb); + inode = v9fs_get_new_inode_from_fid(v9ses, fid, sb); if (IS_ERR(inode)) { retval = PTR_ERR(inode); goto release_sb;