From patchwork Tue Jan 30 19:03:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Torvalds X-Patchwork-Id: 194277 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1435743dyb; Tue, 30 Jan 2024 11:04:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IFI2NGA4cgT/2gpmk66tGC4KSzIyUayKaAcDVJ0isDiAMUQHceVUE3W2m9S/aCLbVpcl3Hk X-Received: by 2002:a17:90a:17a2:b0:28f:f1c0:3d21 with SMTP id q31-20020a17090a17a200b0028ff1c03d21mr5036839pja.41.1706641466724; Tue, 30 Jan 2024 11:04:26 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706641466; cv=pass; d=google.com; s=arc-20160816; b=sdtoJ9rIXL0pknEociuv+JkwnDwtSQWI+4C8gR4+z4wlAG4l5NPHLCdlB/1xGB/Tyn 0hDcCu3K3tglkA6yTN1CCHmcuaJo9nQyMfSMwxGwZgyRVqvpjeoznOSgIlG4Vx16OgiN oW90P99cL1zNp67VIsst8kLc+i8LdrTY1Uk5odNuY6MQWQ2ywStpw1eysrqsnhLbaQHo Ub/PsvzI3zVVbVXZgfg9Kfgfc8T8CKI591ybnLleEXUTwjuB1qJBBc63AuGv77/yWipR da1ISQuN3lbKbepIe8xYffburH2Dv5TRDKN+P/2KalAgnZ4BED4eobTta4ANzAQW3ENw D+uw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=/5/Xj2Srlhp4uYDTTMzT4Qjup+7kuic8fjKtxQpR9Lk=; fh=aD/wDFT3pdBCiZXVST/riRN8xCPBouJr3XfOtoKVvRw=; b=aTaBMl4+xli1PpesyRMePtzB8Hwk68lk/EOa6vqTDmaV4caz97pR+yRrpah2fZ+p7O /8l9buD4NYrSE6nUffR38wvLV0iYHjT1ElrG13vCMgPSgjU6dCljZBHULWNN/LfNu7N7 HmiOoxUdZDlxfjLSE+LMRO6eU91lJSZowBD2MmXM56h21GfjJgtd6mKclwUsMa8F0Kjf ypbiDIxr/vAwaFr7/ZAm+E8kdhEEUV9tbv8F9JT1qw9caiBnDR96mL0B8wja72NIZihQ xFlcaDNyUY4yLblHrp/xsdYxdC4hX+jjaQwDsNFUelsSOo0Jb5IXMqKi2TrWU78E7Qul SABA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=sPvFIbvn; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45154-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45154-ouuuleilei=gmail.com@vger.kernel.org" Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id v20-20020a17090a899400b00292e3004eb0si8968318pjn.152.2024.01.30.11.04.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 11:04:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-45154-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=sPvFIbvn; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45154-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45154-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 7FC95289C28 for ; Tue, 30 Jan 2024 19:04:26 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2491E7995F; Tue, 30 Jan 2024 19:04:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="sPvFIbvn" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 083FD79948; Tue, 30 Jan 2024 19:04:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641452; cv=none; b=S50TscRi5ny3JoTnv/gnaSB1I33qw2jO28EwMtTb3Dq+Zs3WfdblTMRXyQFNwbY6ZKKFxQPXfGbq2sipuwr3r3tfbkNaUy4Az/UEk+Fe5ZjJkqZ9g+dXjCNMRjAyjF8nBQZA9CqAnog52J10SROr/13L9GT+ikkW155D7lx36K4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641452; c=relaxed/simple; bh=/VhpS5sd/6Wo9lZmVmUCPhzalbMspHdeI+886w/8Nls=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=AjnBtPXejlonvizDos76qup11iEzPBy/yXFcmGOO1aLQH8tFS//ZkGmmqbcjS0jcarxZp3LMT0SOwkR7jlbM5RXvMqiUnilJCf5tdJO8OelF1p19JdKGyThD9Mdo7jbvy40B4Sd7UCP/xx2KlUwbt9zlL3WUv6ELa3JGrOyONjg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=sPvFIbvn; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 48FA5C433C7; Tue, 30 Jan 2024 19:04:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1706641451; bh=/VhpS5sd/6Wo9lZmVmUCPhzalbMspHdeI+886w/8Nls=; h=From:To:Cc:Subject:Date:From; b=sPvFIbvnEnAfVnGnWpE1wIA6AsVzmHu44QSP4mHgzR0gVpraQ6hb0UWMyr45N6ncO /fVUj47CsgFdoUz4mICcPYg7bl3baxe6qDxRRPpihbNyvnDIKLYXMGkumfcjW6TN2z iDwbrd2zJw+5M5jf/ePV/Uv8EaiQdo1lrUABqMrI= From: Linus Torvalds To: Steven Rostedt Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Linus Torvalds Subject: [PATCH 1/6] tracefs: avoid using the ei->dentry pointer unnecessarily Date: Tue, 30 Jan 2024 11:03:50 -0800 Message-ID: <20240130190355.11486-1-torvalds@linux-foundation.org> X-Mailer: git-send-email 2.43.0.5.g38fb137bdb Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789543282332710531 X-GMAIL-MSGID: 1789543282332710531 The eventfs_find_events() code tries to walk up the tree to find the event directory that a dentry belongs to, in order to then find the eventfs inode that is associated with that event directory. However, it uses an odd combination of walking the dentry parent, looking up the eventfs inode associated with that, and then looking up the dentry from there. Repeat. But the code shouldn't have back-pointers to dentries in the first place, and it should just walk the dentry parenthood chain directly. Similarly, 'set_top_events_ownership()' looks up the dentry from the eventfs inode, but the only reason it wants a dentry is to look up the superblock in order to look up the root dentry. But it already has the real filesystem inode, which has that same superblock pointer. So just pass in the superblock pointer using the information that's already there, instead of looking up extraneous data that is irrelevant. Signed-off-by: Linus Torvalds --- fs/tracefs/event_inode.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 1c3dd0ad4660..2d128bedd654 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -156,33 +156,30 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry, return ret; } -static void update_top_events_attr(struct eventfs_inode *ei, struct dentry *dentry) +static void update_top_events_attr(struct eventfs_inode *ei, struct super_block *sb) { - struct inode *inode; + struct inode *root; /* Only update if the "events" was on the top level */ if (!ei || !(ei->attr.mode & EVENTFS_TOPLEVEL)) return; /* Get the tracefs root inode. */ - inode = d_inode(dentry->d_sb->s_root); - ei->attr.uid = inode->i_uid; - ei->attr.gid = inode->i_gid; + root = d_inode(sb->s_root); + ei->attr.uid = root->i_uid; + ei->attr.gid = root->i_gid; } static void set_top_events_ownership(struct inode *inode) { struct tracefs_inode *ti = get_tracefs(inode); struct eventfs_inode *ei = ti->private; - struct dentry *dentry; /* The top events directory doesn't get automatically updated */ if (!ei || !ei->is_events || !(ei->attr.mode & EVENTFS_TOPLEVEL)) return; - dentry = ei->dentry; - - update_top_events_attr(ei, dentry); + update_top_events_attr(ei, inode->i_sb); if (!(ei->attr.mode & EVENTFS_SAVE_UID)) inode->i_uid = ei->attr.uid; @@ -235,8 +232,10 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry) mutex_lock(&eventfs_mutex); do { - /* The parent always has an ei, except for events itself */ - ei = dentry->d_parent->d_fsdata; + // The parent is stable because we do not do renames + dentry = dentry->d_parent; + // ... and directories always have d_fsdata + ei = dentry->d_fsdata; /* * If the ei is being freed, the ownership of the children @@ -246,12 +245,11 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry) ei = NULL; break; } - - dentry = ei->dentry; + // Walk upwards until you find the events inode } while (!ei->is_events); mutex_unlock(&eventfs_mutex); - update_top_events_attr(ei, dentry); + update_top_events_attr(ei, dentry->d_sb); return ei; } From patchwork Tue Jan 30 19:03:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Torvalds X-Patchwork-Id: 194285 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1437980dyb; Tue, 30 Jan 2024 11:07:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IE+GM60aTL+ZSYirsP2k1EZBHDRG9YmX38tg+/6adDdVk1VjS1IrzxTUsz1eod64Pyyxar8 X-Received: by 2002:a05:6871:5210:b0:218:5163:d118 with SMTP id ht16-20020a056871521000b002185163d118mr8672829oac.8.1706641670749; Tue, 30 Jan 2024 11:07:50 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706641670; cv=pass; d=google.com; s=arc-20160816; b=lhbbk59U/bWD349x6byUlvSVbXtdMhs3v/znomyiQJ09AIzDzeqyEh3kpgqAupLJVU HOYuCzF8PStT7siv9Vq9rZETzARjfI7EvsyPhruJdW5d5RvLT9VORTNrzoC9LznORe1V UbdwkyfLjrecVs1UvXrMcY1JEaczWhvcjim5jYcmNb8MiQmgjfIPXKYHUD8/Z/7hiZpm RHBEL5k7uZqEJVmVbMCVmPPcNxJ6vwZl5kcyguEwon1u9zaF0DCE1ZuqVidGpPhH+zdg IbVLAiFEM6qy4GPWvemUgCgmVLxUfGLcj8ZzXjx6NGX99gqBI224qOeAiqBKFCLuCuu2 q+4w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=kxF++LiKDtDULdRc9IWq0v8KTlzVdnVwtGMDFPC/o08=; fh=aD/wDFT3pdBCiZXVST/riRN8xCPBouJr3XfOtoKVvRw=; b=XsaY3jpryTv2i9Q8IL2bxpsJvnvISbH+LaExEUz78C65gc3eHhHDRT5GqboWh+RM9/ dnfXx2iZIcDkD6jDBImjFwwSt7VUlZAKv/YUPLTLXR71tL2TpJlUM5Fhz9M+eJ43vJAa gfMUfH7VVHQe9dG7HEV5u7Q+lSZPv9nqMyrrKGLT5RbX3YsW3Vn3JIGETGLBLG+DTZTe HslHtH5zsxUdYpv2WY6dCB+U1NzaUl86CtuqNmvjQStCpfz6KAgztrMxTcuA2GvGt/Cx 9T5qlbc/WM+9CadWZenNm/k3xcNvxeBg2TV0W1RKxeRVZcH4kpXg/skWmn1jr0e8heuj QouQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=Vd1hrNDi; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45155-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45155-ouuuleilei=gmail.com@vger.kernel.org" Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id i14-20020a63e44e000000b005d8b3138f64si6152424pgk.279.2024.01.30.11.07.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 11:07:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-45155-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=Vd1hrNDi; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45155-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45155-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id B92CFB2326A for ; Tue, 30 Jan 2024 19:04:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B891079953; Tue, 30 Jan 2024 19:04:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="Vd1hrNDi" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE3DE7994D; Tue, 30 Jan 2024 19:04:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641458; cv=none; b=QvZCbPjauh+biMAwaCIyFStY/sToMfJfvO910z+8NyjspITMR4b/2ePsYOisK3jB1OWhBtSpZS5qWlXbjH1JCGl6RqzoG+Fwp5JdO+AutVzXzE7Oj/HcWab6fTadbYZEIQ951aufQ7psAMRQP8wHy2ho6Ajuwob5ojArhUqofYs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641458; c=relaxed/simple; bh=UN73rU1wKgk+kPZG4I6r0l+EYowt6RDqJg5XsMuGiLQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V/2OZDZm7Le22C/grg8G+n782s3uw1yVqFq36mhl7SHuo9M2CtVK1hUCB4OWZuFkXB/i2OVPPr9YCh8OO6O9M9ziDF+LhtmEo75wpo+iC+xhNFarKmeNLJZMGX1oLexKPrJrWgaxfhenxKNTB/+oGtPpLOy0cngkKBkgg11ZhG4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=Vd1hrNDi; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4B164C433F1; Tue, 30 Jan 2024 19:04:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1706641457; bh=UN73rU1wKgk+kPZG4I6r0l+EYowt6RDqJg5XsMuGiLQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Vd1hrNDi9XyJiMLBg7nk96fWw9ntucwuoWji3NVvRxAagTIdMFOl0KoD36I7e+2VN VnHMY7fCpF6mvFH03bTwvvq/HhaKy3ufgcODBFOxIt/jukpRAqV9ZQPeNO61tr5hZy XzWvd6ERZDEGPk+VJTU5IUICtY1fOooFW2U32I7k= From: Linus Torvalds To: Steven Rostedt Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Linus Torvalds Subject: [PATCH 2/6] eventfsfs: initialize the tracefs inode properly Date: Tue, 30 Jan 2024 11:03:51 -0800 Message-ID: <20240130190355.11486-2-torvalds@linux-foundation.org> X-Mailer: git-send-email 2.43.0.5.g38fb137bdb In-Reply-To: <20240130190355.11486-1-torvalds@linux-foundation.org> References: <20240130190355.11486-1-torvalds@linux-foundation.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789543496708488528 X-GMAIL-MSGID: 1789543496708488528 The tracefs-specific fields in the inode were not initialized before the inode was exposed to others through the dentry with 'd_instantiate()'. And the ->flags file was initialized incorrectly with a '|=', when the old value was stale. It should have just been a straight assignment. Move the field initializations up to before the d_instantiate, and fix the use of uninitialized data. Signed-off-by: Linus Torvalds --- fs/tracefs/event_inode.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 2d128bedd654..c0d977e6c0f2 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -328,7 +328,9 @@ static struct dentry *create_file(const char *name, umode_t mode, inode->i_ino = EVENTFS_FILE_INODE_INO; ti = get_tracefs(inode); - ti->flags |= TRACEFS_EVENT_INODE; + ti->flags = TRACEFS_EVENT_INODE; + ti->private = NULL; // Directories have 'ei', files not + d_instantiate(dentry, inode); fsnotify_create(dentry->d_parent->d_inode, dentry); return eventfs_end_creating(dentry); @@ -367,7 +369,8 @@ static struct dentry *create_dir(struct eventfs_inode *ei, struct dentry *parent inode->i_ino = eventfs_dir_ino(ei); ti = get_tracefs(inode); - ti->flags |= TRACEFS_EVENT_INODE; + ti->flags = TRACEFS_EVENT_INODE; + ti->private = ei; inc_nlink(inode); d_instantiate(dentry, inode); @@ -513,7 +516,6 @@ create_file_dentry(struct eventfs_inode *ei, int idx, static void eventfs_post_create_dir(struct eventfs_inode *ei) { struct eventfs_inode *ei_child; - struct tracefs_inode *ti; lockdep_assert_held(&eventfs_mutex); @@ -523,9 +525,6 @@ static void eventfs_post_create_dir(struct eventfs_inode *ei) srcu_read_lock_held(&eventfs_srcu)) { ei_child->d_parent = ei->dentry; } - - ti = get_tracefs(ei->dentry->d_inode); - ti->private = ei; } /** @@ -943,7 +942,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry INIT_LIST_HEAD(&ei->list); ti = get_tracefs(inode); - ti->flags |= TRACEFS_EVENT_INODE | TRACEFS_EVENT_TOP_INODE; + ti->flags = TRACEFS_EVENT_INODE | TRACEFS_EVENT_TOP_INODE; ti->private = ei; inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; From patchwork Tue Jan 30 19:03:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Torvalds X-Patchwork-Id: 194279 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1436354dyb; Tue, 30 Jan 2024 11:05:16 -0800 (PST) X-Google-Smtp-Source: AGHT+IFqafoxYjqU8ssfQXJbY40qhKdXgcp/+MYyEd8/l2a0pz89t+usj00oxYQE4OOCJiR74kOj X-Received: by 2002:a05:620a:40c7:b0:783:549a:aa3f with SMTP id g7-20020a05620a40c700b00783549aaa3fmr425470qko.67.1706641515960; Tue, 30 Jan 2024 11:05:15 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706641515; cv=pass; d=google.com; s=arc-20160816; b=cLTCaQ0Bg4QN1KuiGQiZ5t7P9NIKp3efwfsgnuUjTeWyW1TmtqFJNLXlwlky3EPUKe KpZrV4N/jfYQLxRTxR4JEuGyk4RF71LO3UFkkIMonC0AjbnbWY0TFLj5obMD3dHljpoH Qk7XKh50o81hOxQCEnxYc63O4kJP8TAT2wzNYPogoun7gHnppL246UHiC1yglmludATK AsFhZnrwobL4lOOLRa4W0QgiAGZ+JLKm7Z+It/Uzt8l3nlxTDgyOZhxwv1fvwzYOWt1A 4K6Yn4Kk9YvHB2vfxARdtJ+SG26X2MY4a47kYvhZDmh8RyScAUDmtGQKjZLe259XM2ha eB+Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=7fXUHpnP2xOsjf3L6QEhuKt7+6tn3GhobqSLZryJXSw=; fh=aD/wDFT3pdBCiZXVST/riRN8xCPBouJr3XfOtoKVvRw=; b=WR/TLf5NmNH8u6Nw0oto/BAkHv60IEDNs7j04mYh8cqjGvU67tZLNuqFBZ313P0mfC L2FR14NH/STMslEj+UZtGnMPX6/M6mZocY9S/yo7w4f5xjoH+YMoXAYdxN7cl7Gzc0uK YZ33UgNZTY7BVSw8fs+q32y9bjhDIElmIdI/ypwX6JyuVjLwXwMzIjAOe93vBSm2NgOU L+B3tD+q1pcZhKGl4pbcm8xO31rk6URU8gKep/o0HI1B3OcqxC5cBFB8FEnyVOdzK9rF Vb/Ph5EoXjnHC+4hytRn+FWQLDAlul5URFSMeryD/GT+OnBo6eumzdfmoeP6KBwna3Ja BVwQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=p0VAlaMz; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45156-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45156-ouuuleilei=gmail.com@vger.kernel.org" Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id c1-20020a37e101000000b00783a190785csi6953449qkm.235.2024.01.30.11.05.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 11:05:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-45156-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=p0VAlaMz; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45156-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45156-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 55D231C24921 for ; Tue, 30 Jan 2024 19:05:10 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E34B0762F7; Tue, 30 Jan 2024 19:04:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="p0VAlaMz" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D6E369E0B; Tue, 30 Jan 2024 19:04:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641459; cv=none; b=p9I9kj/Nfhd4pANEJrMmOCcfjY/kmSCzKdsDpnc1AJPzhyC8aq5SpPhUA6P9/+aMNVUTUnoXNfv/+ES6/n+zFJUiXDKNfqBb98/bkbcjZak3c+U/BFa5IEqBM51xMYqhBX9SBNNmnZgJ16usC2uEjitrr/utRJTbY1WR2TduN/s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641459; c=relaxed/simple; bh=LbesOErzRPHz1hwSxWlEynNIaeMRVBOlM3K2fcN2MmQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lRsSRwMXv9sok7me7ITc17X8ilUx3993x+7T6rv/nk5wFccb7ATSU1Jpxh9bI2i5khRQBUeZLS+5Mps08sGLPtNsX/9WwiOogPHT/UmcuLP6UuLkuUiQz1v53X8LQ8J0dDhn4hTPsOpkArTLXhCYf9a5/niEDsbK8sjiooK+3uc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=p0VAlaMz; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2C73C43394; Tue, 30 Jan 2024 19:04:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1706641459; bh=LbesOErzRPHz1hwSxWlEynNIaeMRVBOlM3K2fcN2MmQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p0VAlaMziE9y3oNPr5/epHXp2SUJ4/Qn6OAxtYA15ci5BQxHZjIhI8Sd4LLbXa2An CiZwEdqTxZpDaWJ3AusoDGwuy4ehpWT1WiYW7RIdWA4Ewqk9zLzWsNXNHonK4G+riv LFaQ75c+qky16C1qS9AzYDpJKmtNkGz7WFhKR+1c= From: Linus Torvalds To: Steven Rostedt Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Linus Torvalds Subject: [PATCH 3/6] tracefs: dentry lookup crapectomy Date: Tue, 30 Jan 2024 11:03:52 -0800 Message-ID: <20240130190355.11486-3-torvalds@linux-foundation.org> X-Mailer: git-send-email 2.43.0.5.g38fb137bdb In-Reply-To: <20240130190355.11486-1-torvalds@linux-foundation.org> References: <20240130190355.11486-1-torvalds@linux-foundation.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789543333831924356 X-GMAIL-MSGID: 1789543333831924356 The dentry lookup for eventfs files was very broken, and had lots of signs of the old situation where the filesystem names were all created statically in the dentry tree, rather than being looked up dynamically based on the eventfs data structures. You could see it in the naming - how it claimed to "create" dentries rather than just look up the dentries that were given it. You could see it in various nonsensical and very incorrect operations, like using "simple_lookup()" on the dentries that were passed in, which only results in those dentries becoming negative dentries. Which meant that any other lookup would possibly return ENOENT if it saw that negative dentry before the data rwas then later filled in. You could see it in the immesnse amount of nonsensical code that didn't actually just do lookups. Signed-off-by: Linus Torvalds --- fs/tracefs/event_inode.c | 275 ++++++++------------------------------- 1 file changed, 52 insertions(+), 223 deletions(-) diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index c0d977e6c0f2..ad11063bdd53 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -230,7 +230,6 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry) { struct eventfs_inode *ei; - mutex_lock(&eventfs_mutex); do { // The parent is stable because we do not do renames dentry = dentry->d_parent; @@ -247,7 +246,6 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry) } // Walk upwards until you find the events inode } while (!ei->is_events); - mutex_unlock(&eventfs_mutex); update_top_events_attr(ei, dentry->d_sb); @@ -280,11 +278,10 @@ static void update_inode_attr(struct dentry *dentry, struct inode *inode, } /** - * create_file - create a file in the tracefs filesystem - * @name: the name of the file to create. + * lookup_file - look up a file in the tracefs filesystem + * @dentry: the dentry to look up * @mode: the permission that the file should have. * @attr: saved attributes changed by user - * @parent: parent dentry for this file. * @data: something that the caller will want to get to later on. * @fop: struct file_operations that should be used for this file. * @@ -292,13 +289,13 @@ static void update_inode_attr(struct dentry *dentry, struct inode *inode, * directory. The inode.i_private pointer will point to @data in the open() * call. */ -static struct dentry *create_file(const char *name, umode_t mode, +static struct dentry *lookup_file(struct dentry *dentry, + umode_t mode, struct eventfs_attr *attr, - struct dentry *parent, void *data, + void *data, const struct file_operations *fop) { struct tracefs_inode *ti; - struct dentry *dentry; struct inode *inode; if (!(mode & S_IFMT)) @@ -307,12 +304,6 @@ static struct dentry *create_file(const char *name, umode_t mode, if (WARN_ON_ONCE(!S_ISREG(mode))) return NULL; - WARN_ON_ONCE(!parent); - dentry = eventfs_start_creating(name, parent); - - if (IS_ERR(dentry)) - return dentry; - inode = tracefs_get_inode(dentry->d_sb); if (unlikely(!inode)) return eventfs_failed_creating(dentry); @@ -331,29 +322,25 @@ static struct dentry *create_file(const char *name, umode_t mode, ti->flags = TRACEFS_EVENT_INODE; ti->private = NULL; // Directories have 'ei', files not - d_instantiate(dentry, inode); + d_add(dentry, inode); fsnotify_create(dentry->d_parent->d_inode, dentry); return eventfs_end_creating(dentry); }; /** - * create_dir - create a dir in the tracefs filesystem + * lookup_dir_entry - look up a dir in the tracefs filesystem + * @dentry: the directory to look up * @ei: the eventfs_inode that represents the directory to create - * @parent: parent dentry for this file. * - * This function will create a dentry for a directory represented by + * This function will look up a dentry for a directory represented by * a eventfs_inode. */ -static struct dentry *create_dir(struct eventfs_inode *ei, struct dentry *parent) +static struct dentry *lookup_dir_entry(struct dentry *dentry, + struct eventfs_inode *pei, struct eventfs_inode *ei) { struct tracefs_inode *ti; - struct dentry *dentry; struct inode *inode; - dentry = eventfs_start_creating(ei->name, parent); - if (IS_ERR(dentry)) - return dentry; - inode = tracefs_get_inode(dentry->d_sb); if (unlikely(!inode)) return eventfs_failed_creating(dentry); @@ -372,8 +359,11 @@ static struct dentry *create_dir(struct eventfs_inode *ei, struct dentry *parent ti->flags = TRACEFS_EVENT_INODE; ti->private = ei; + dentry->d_fsdata = ei; + ei->dentry = dentry; // Remove me! + inc_nlink(inode); - d_instantiate(dentry, inode); + d_add(dentry, inode); inc_nlink(dentry->d_parent->d_inode); fsnotify_mkdir(dentry->d_parent->d_inode, dentry); return eventfs_end_creating(dentry); @@ -426,7 +416,7 @@ void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry) } /** - * create_file_dentry - create a dentry for a file of an eventfs_inode + * lookup_file_dentry - create a dentry for a file of an eventfs_inode * @ei: the eventfs_inode that the file will be created under * @idx: the index into the d_children[] of the @ei * @parent: The parent dentry of the created file. @@ -439,157 +429,21 @@ void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry) * address located at @e_dentry. */ static struct dentry * -create_file_dentry(struct eventfs_inode *ei, int idx, - struct dentry *parent, const char *name, umode_t mode, void *data, +lookup_file_dentry(struct dentry *dentry, + struct eventfs_inode *ei, int idx, + umode_t mode, void *data, const struct file_operations *fops) { struct eventfs_attr *attr = NULL; struct dentry **e_dentry = &ei->d_children[idx]; - struct dentry *dentry; - WARN_ON_ONCE(!inode_is_locked(parent->d_inode)); - - mutex_lock(&eventfs_mutex); - if (ei->is_freed) { - mutex_unlock(&eventfs_mutex); - return NULL; - } - /* If the e_dentry already has a dentry, use it */ - if (*e_dentry) { - dget(*e_dentry); - mutex_unlock(&eventfs_mutex); - return *e_dentry; - } - - /* ei->entry_attrs are protected by SRCU */ if (ei->entry_attrs) attr = &ei->entry_attrs[idx]; - mutex_unlock(&eventfs_mutex); + dentry->d_fsdata = ei; // NOTE: ei of _parent_ + lookup_file(dentry, mode, attr, data, fops); - dentry = create_file(name, mode, attr, parent, data, fops); - - mutex_lock(&eventfs_mutex); - - if (IS_ERR_OR_NULL(dentry)) { - /* - * When the mutex was released, something else could have - * created the dentry for this e_dentry. In which case - * use that one. - * - * If ei->is_freed is set, the e_dentry is currently on its - * way to being freed, don't return it. If e_dentry is NULL - * it means it was already freed. - */ - if (ei->is_freed) { - dentry = NULL; - } else { - dentry = *e_dentry; - dget(dentry); - } - mutex_unlock(&eventfs_mutex); - return dentry; - } - - if (!*e_dentry && !ei->is_freed) { - *e_dentry = dentry; - dentry->d_fsdata = ei; - } else { - /* - * Should never happen unless we get here due to being freed. - * Otherwise it means two dentries exist with the same name. - */ - WARN_ON_ONCE(!ei->is_freed); - dentry = NULL; - } - mutex_unlock(&eventfs_mutex); - - return dentry; -} - -/** - * eventfs_post_create_dir - post create dir routine - * @ei: eventfs_inode of recently created dir - * - * Map the meta-data of files within an eventfs dir to their parent dentry - */ -static void eventfs_post_create_dir(struct eventfs_inode *ei) -{ - struct eventfs_inode *ei_child; - - lockdep_assert_held(&eventfs_mutex); - - /* srcu lock already held */ - /* fill parent-child relation */ - list_for_each_entry_srcu(ei_child, &ei->children, list, - srcu_read_lock_held(&eventfs_srcu)) { - ei_child->d_parent = ei->dentry; - } -} - -/** - * create_dir_dentry - Create a directory dentry for the eventfs_inode - * @pei: The eventfs_inode parent of ei. - * @ei: The eventfs_inode to create the directory for - * @parent: The dentry of the parent of this directory - * - * This creates and attaches a directory dentry to the eventfs_inode @ei. - */ -static struct dentry * -create_dir_dentry(struct eventfs_inode *pei, struct eventfs_inode *ei, - struct dentry *parent) -{ - struct dentry *dentry = NULL; - - WARN_ON_ONCE(!inode_is_locked(parent->d_inode)); - - mutex_lock(&eventfs_mutex); - if (pei->is_freed || ei->is_freed) { - mutex_unlock(&eventfs_mutex); - return NULL; - } - if (ei->dentry) { - /* If the eventfs_inode already has a dentry, use it */ - dentry = ei->dentry; - dget(dentry); - mutex_unlock(&eventfs_mutex); - return dentry; - } - mutex_unlock(&eventfs_mutex); - - dentry = create_dir(ei, parent); - - mutex_lock(&eventfs_mutex); - - if (IS_ERR_OR_NULL(dentry) && !ei->is_freed) { - /* - * When the mutex was released, something else could have - * created the dentry for this e_dentry. In which case - * use that one. - * - * If ei->is_freed is set, the e_dentry is currently on its - * way to being freed. - */ - dentry = ei->dentry; - if (dentry) - dget(dentry); - mutex_unlock(&eventfs_mutex); - return dentry; - } - - if (!ei->dentry && !ei->is_freed) { - ei->dentry = dentry; - eventfs_post_create_dir(ei); - dentry->d_fsdata = ei; - } else { - /* - * Should never happen unless we get here due to being freed. - * Otherwise it means two dentries exist with the same name. - */ - WARN_ON_ONCE(!ei->is_freed); - dentry = NULL; - } - mutex_unlock(&eventfs_mutex); + *e_dentry = dentry; // Remove me return dentry; } @@ -608,79 +462,54 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { - const struct file_operations *fops; - const struct eventfs_entry *entry; struct eventfs_inode *ei_child; struct tracefs_inode *ti; struct eventfs_inode *ei; - struct dentry *ei_dentry = NULL; - struct dentry *ret = NULL; - struct dentry *d; const char *name = dentry->d_name.name; - umode_t mode; - void *data; - int idx; - int i; - int r; ti = get_tracefs(dir); if (!(ti->flags & TRACEFS_EVENT_INODE)) - return NULL; + return ERR_PTR(-EIO); - /* Grab srcu to prevent the ei from going away */ - idx = srcu_read_lock(&eventfs_srcu); - - /* - * Grab the eventfs_mutex to consistent value from ti->private. - * This s - */ mutex_lock(&eventfs_mutex); - ei = READ_ONCE(ti->private); - if (ei && !ei->is_freed) - ei_dentry = READ_ONCE(ei->dentry); - mutex_unlock(&eventfs_mutex); - if (!ei || !ei_dentry) - goto out; + ei = ti->private; + if (!ei || ei->is_freed) + goto enoent; - data = ei->data; - - list_for_each_entry_srcu(ei_child, &ei->children, list, - srcu_read_lock_held(&eventfs_srcu)) { + list_for_each_entry(ei_child, &ei->children, list) { if (strcmp(ei_child->name, name) != 0) continue; - ret = simple_lookup(dir, dentry, flags); - if (IS_ERR(ret)) - goto out; - d = create_dir_dentry(ei, ei_child, ei_dentry); - dput(d); + if (ei_child->is_freed) + goto enoent; + lookup_dir_entry(dentry, ei, ei_child); goto out; } - for (i = 0; i < ei->nr_entries; i++) { - entry = &ei->entries[i]; - if (strcmp(name, entry->name) == 0) { - void *cdata = data; - mutex_lock(&eventfs_mutex); - /* If ei->is_freed, then the event itself may be too */ - if (!ei->is_freed) - r = entry->callback(name, &mode, &cdata, &fops); - else - r = -1; - mutex_unlock(&eventfs_mutex); - if (r <= 0) - continue; - ret = simple_lookup(dir, dentry, flags); - if (IS_ERR(ret)) - goto out; - d = create_file_dentry(ei, i, ei_dentry, name, mode, cdata, fops); - dput(d); - break; - } + for (int i = 0; i < ei->nr_entries; i++) { + void *data; + umode_t mode; + const struct file_operations *fops; + const struct eventfs_entry *entry = &ei->entries[i]; + + if (strcmp(name, entry->name) != 0) + continue; + + data = ei->data; + if (entry->callback(name, &mode, &data, &fops) <= 0) + goto enoent; + + lookup_file_dentry(dentry, ei, i, mode, data, fops); + goto out; } + + enoent: + /* Nothing found? */ + d_add(dentry, NULL); + out: - srcu_read_unlock(&eventfs_srcu, idx); - return ret; + mutex_unlock(&eventfs_mutex); + return NULL; } /* From patchwork Tue Jan 30 19:03:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Torvalds X-Patchwork-Id: 194278 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1436281dyb; Tue, 30 Jan 2024 11:05:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IHebVyBQrSQ7dVh1osDwDSjilVcbTI7yRmrg9NdMWJLY335JnSpInrHnPWm7d2KTQh4XUjG X-Received: by 2002:a17:906:2354:b0:a35:7191:d952 with SMTP id m20-20020a170906235400b00a357191d952mr6119787eja.53.1706641510051; Tue, 30 Jan 2024 11:05:10 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706641510; cv=pass; d=google.com; s=arc-20160816; b=whaKzW/7OU9kEsWXbA9GzrQ9rjIA7LB+eIXtEvDNgdadxtCpAAC55403zgbr2ZaSl/ TcW09AifEbe91wWFtv4/lIxGF6MJScCGgBnMWDF5RmbBIffTTy+2r7DvNkfh5IozXG4O rcUoV2y6z0dH2CuokRxZT8U+mSDIwANz84I1SvJrL+yFj+hNfPTTql9QzXcedtMM3ti6 Q4PO17tbqQQ/w6gb0G8M1aM0nafXY5Ky0vTUtC5psxxPk9HbFMuD4wopqi5EaXypBVs8 mm5lKdyaUoxyXb+1FZMHZh0athG4uWcxaTQmNtA4n5+IHTOXv8YISQmeajLrzgb6m529 o3pw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=Zs62IJhwdmF2K5b/X0hA5YSVDgHXig4aJyLkpkF+3Pk=; fh=aD/wDFT3pdBCiZXVST/riRN8xCPBouJr3XfOtoKVvRw=; b=dJRCaSZzBJdNeXZW6DN/Ea+PiPUJ8kpak0RFDL/FerYRoLHAA5lrDyFzDV4f3quAt8 arAHn/OedU4mEbz/DYinm8xBTJqy3Sf38RIXR+KcNTmijZzCsNaYYX49OnPD+BaPunlZ yAnnDdnCLHWa2oQNynXTlQ7lkoRVTKkX0Gb5RpsPr6FFjtdQH4xKZaL4NNjjDjzABLW4 FKHP1o71Ra5LdvfkUqNv2nvEXUrjUKisPSg9L3/YruGKj6Zj0yxTkfwZZY0vt45aglbv 6o9uXVYt4MnKoftPfYQn3nBThZOIOyMRpKBFonhxxE79WglkFzyWl06V0rIqwqQC2OAh F7pQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=HE4bR2zZ; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45157-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45157-ouuuleilei=gmail.com@vger.kernel.org" Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id g26-20020a170906199a00b00a3084baf944si4842324ejd.390.2024.01.30.11.05.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 11:05:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-45157-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=HE4bR2zZ; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45157-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45157-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 8DF291F26852 for ; Tue, 30 Jan 2024 19:05:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CF853762F5; Tue, 30 Jan 2024 19:04:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="HE4bR2zZ" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 20788762CE; Tue, 30 Jan 2024 19:04:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641461; cv=none; b=iWDtrsQTVlFu5eCKEMyxxGsdFA607TjAzbQNad4n/BLhTURrlbV68I9tYRJJ3DvGLmIHKY5lJUsyezLUarsSilmiSs2WrsY1kOfgmxmfGWgJF8GDZmLdeGKWyXW28ITHXZJNJiUZAQMfuvWa1r8oz8SjUBy1QFreZryyFdvbC48= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641461; c=relaxed/simple; bh=VfkCiOcbDiF97nCdF1XS/rB91kgxot2LBBvCXyBvEHs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DCb56iAsAPw5P1qSTGqAt9q60jE73ofoLOjw4aIQYvPiGT+kcPvUTy795FHZEwQZmrAv4kxJXS20RvrU4ziLaq9yGkvYBXnbBMsgvoXStAl5sFrRHlJkBbVfE68h82rTXN/N3jluFIogg7bCNQ3ZsqOyCquPSQNQrNG81iQ3FDU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=HE4bR2zZ; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 695FAC433C7; Tue, 30 Jan 2024 19:04:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1706641460; bh=VfkCiOcbDiF97nCdF1XS/rB91kgxot2LBBvCXyBvEHs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HE4bR2zZg6i+6WEvZ49qbdu3atDQF/Z8KiZkSjdlT+O1NoUOIzsHjUoIRCP0QPJPP aJ4XKQn5U4yPeZG9xliQ//NBL4c/PRXF4H9a/nrpDxp+YP61Y7NoCjk25mH6+H2tL8 w4VfRlXOs48PNEwx2vOS8lxTp5vkNw+uvpbN60D0= From: Linus Torvalds To: Steven Rostedt Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Linus Torvalds Subject: [PATCH 4/6] eventfs: remove unused 'd_parent' pointer field Date: Tue, 30 Jan 2024 11:03:53 -0800 Message-ID: <20240130190355.11486-4-torvalds@linux-foundation.org> X-Mailer: git-send-email 2.43.0.5.g38fb137bdb In-Reply-To: <20240130190355.11486-1-torvalds@linux-foundation.org> References: <20240130190355.11486-1-torvalds@linux-foundation.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789543328341086871 X-GMAIL-MSGID: 1789543328341086871 It's never used Signed-off-by: Linus Torvalds --- fs/tracefs/event_inode.c | 4 +--- fs/tracefs/internal.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index ad11063bdd53..1d0102bfd7da 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -685,10 +685,8 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode INIT_LIST_HEAD(&ei->list); mutex_lock(&eventfs_mutex); - if (!parent->is_freed) { + if (!parent->is_freed) list_add_tail(&ei->list, &parent->children); - ei->d_parent = parent->dentry; - } mutex_unlock(&eventfs_mutex); /* Was the parent freed? */ diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h index 91c2bf0b91d9..8f38740bfb5b 100644 --- a/fs/tracefs/internal.h +++ b/fs/tracefs/internal.h @@ -35,7 +35,6 @@ struct eventfs_attr { * @name: the name of the directory to create * @children: link list into the child eventfs_inode * @dentry: the dentry of the directory - * @d_parent: pointer to the parent's dentry * @d_children: The array of dentries to represent the files when created * @entry_attrs: Saved mode and ownership of the @d_children * @attr: Saved mode and ownership of eventfs_inode itself @@ -50,7 +49,6 @@ struct eventfs_inode { const char *name; struct list_head children; struct dentry *dentry; /* Check is_freed to access */ - struct dentry *d_parent; struct dentry **d_children; struct eventfs_attr *entry_attrs; struct eventfs_attr attr; From patchwork Tue Jan 30 19:03:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Torvalds X-Patchwork-Id: 194281 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1436590dyb; Tue, 30 Jan 2024 11:05:37 -0800 (PST) X-Google-Smtp-Source: AGHT+IFnVw2llAPb+RxKwM5K8p/GvRGmvoNTLcaW18ug/OsHN31POq3hexQh64nOfZkceNsenElw X-Received: by 2002:a05:6402:268c:b0:55f:5197:6314 with SMTP id w12-20020a056402268c00b0055f51976314mr1774299edd.18.1706641537344; Tue, 30 Jan 2024 11:05:37 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706641537; cv=pass; d=google.com; s=arc-20160816; b=YG06fOEPC6vqHJZJ/2Z9NrXREPNNRq4Qx+2VXdoZg+Xwykuv0Co/MGtQPxqXMuku13 3dFk6sv/G965CPihJV/MQFKVho0r9YZlAQEmBvZmcbpQej9ShJ46gwgKUSJLQHymfKZv nxJp7sU64NYMxOe2j/kEmmxrFqBCSz5cIt9IKK3A05o6+nADQbNwhFzH9N9xsDpmzN9r csyagGCBwagcQJJdnEXuPvUbGVB16bSld3q3PYaCbvS6MZkZmuVFsfTehtM0q7XJ3FD6 p59oIGsxleLT4KADKVDU6qR8K9FCsw2DyYAAnrysqyHrSLO+q048osaPsIPAtTDd0QQw 7ieQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=5CeHz4fcE/KP3+ljtML3yrF5BBz2qFlZVmycZhKtdrA=; fh=aD/wDFT3pdBCiZXVST/riRN8xCPBouJr3XfOtoKVvRw=; b=rPo3CYV6rAt4Z1VChMyDepsNz/2EffdVTps5FfQ2D5neqGXl+csnIVkZIYiUKuCOzq BM8xI8q40+Izi1/+XidoSJjwJZ3K66H2dD7k60u4v9TygIPmVxZzWDX1Xse35bD/rx/9 3sO4UAIx2I7tcjIF/XY4yCYbW241L2lNb1m7Z729HsXSC6Kg2XepgmmcIQgiBKgXRKba styXUvbxwya9weSvsGFj7GWjOi1SMUdUxQeFRtGgUTCPh/0Pm8tH3N9p06WhRhuiQTiL u+/AMCrKdIdwO0aF2iVGT0q2092lj8mwVq/4pvEOFFFTjcFCnw3O2r1reDMs5Snc4cR7 gfGg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=z15KhCVN; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45158-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45158-ouuuleilei=gmail.com@vger.kernel.org" Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id b19-20020a0564021f1300b0055f179146easi1733733edb.651.2024.01.30.11.05.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 11:05:37 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-45158-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=z15KhCVN; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45158-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45158-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id C6C281F266C2 for ; Tue, 30 Jan 2024 19:05:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8B14B4E1B7; Tue, 30 Jan 2024 19:04:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="z15KhCVN" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 95E35762E2; Tue, 30 Jan 2024 19:04:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641462; cv=none; b=IAcFrRiRoVNfGwHcxDh5hIbpHmQp1gqQjLfKneDV5kKxb6N7h2DpDEGyl1O6tT4hRDhikTazw6rmBaoA6frEoQXsykLePFf9xpjgwGPT65IsZp2bRGPXhm8nhPVdafr11PDqvK1bN+h37oZLXHP93bJuhJe899/86+G7zWohGL0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641462; c=relaxed/simple; bh=/AduH2y6UR3zLY3u5BVwfhnp623uLwZq8kEsuen1JbE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lblda4/+g39q/XdKV4yxU1ujovzf+X4PpkUhxnJEcuKY5IZxf5ZnWtef9Nh0eWHeh4VvjdfYf0+BKGudd4J4yVO2H1JcKYO/5Z/pyhHQFm3KHLBSAxY2OwKWh/eoR65rg7i0gOCDpdgOP2BJLhOfRa7FcAmw4NOSLO/julT+6YU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=z15KhCVN; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id EF2EEC433F1; Tue, 30 Jan 2024 19:04:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1706641462; bh=/AduH2y6UR3zLY3u5BVwfhnp623uLwZq8kEsuen1JbE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=z15KhCVNcKxl05ai2J3k0CNNcgWmCkmvkUx1/1GwEjWVWQokGXRR/FmgQGd0ou9g0 MyLSscd3Ld0SC4H4UfVrdg5zdIye4qGr/g/L3a6O5SqV8dS6mPC+DxKLwbJyIZibHm tQoupqGzDFg6+U/Bsyewhcb+wS7spUA+2I6pTSvQ= From: Linus Torvalds To: Steven Rostedt Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Linus Torvalds Subject: [PATCH 5/6] eventfs: get rid of dentry pointers without refcounts Date: Tue, 30 Jan 2024 11:03:54 -0800 Message-ID: <20240130190355.11486-5-torvalds@linux-foundation.org> X-Mailer: git-send-email 2.43.0.5.g38fb137bdb In-Reply-To: <20240130190355.11486-1-torvalds@linux-foundation.org> References: <20240130190355.11486-1-torvalds@linux-foundation.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789543356457231572 X-GMAIL-MSGID: 1789543356457231572 The eventfs inode had pointers to dentries (and child dentries) without actually holding a refcount on said pointer. That is fundamentally broken, and while eventfs tried to then maintain coherence with dentries going away by hooking into the '.d_iput' callback, that doesn't actually work since it's not ordered wrt lookups. There were two reasonms why eventfs tried to keep a pointer to a dentry: - the creation of a 'events' directory would actually have a stable dentry pointer that it created with tracefs_start_creating(). And it needed that dentry when tearing it all down again in eventfs_remove_events_dir(). This use is actually ok, because the special top-level events directory dentries are actually stable, not just a temporary cache of the eventfs data structures. - the 'eventfs_inode' (aka ei) needs to stay around as long as there are dentries that refer to it. It then used these dentry pointers as a replacement for doing reference counting: it would try to make sure that there was only ever one dentry associated with an event_inode, and keep a child dentry array around to see which dentries might still refer to the parent ei. This gets rid of the invalid dentry pointer use, and renames the one valid case to a different name to make it clear that it's not just any random dentry. The magic child dentry array that is kind of a "reverse reference list" is simply replaced by having child dentries take a ref to the ei. As does the directory dentries. That makes the broken use case go away. Signed-off-by: Linus Torvalds --- fs/tracefs/event_inode.c | 245 ++++++++++++--------------------------- fs/tracefs/internal.h | 9 +- 2 files changed, 80 insertions(+), 174 deletions(-) diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 1d0102bfd7da..a37db0dac302 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -62,6 +62,34 @@ enum { #define EVENTFS_MODE_MASK (EVENTFS_SAVE_MODE - 1) +/* + * eventfs_inode reference count management. + * + * NOTE! We count only references from dentries, in the + * form 'dentry->d_fsdata'. There are also references from + * directory inodes ('ti->private'), but the dentry reference + * count is always a superset of the inode reference count. + */ +static void release_ei(struct kref *ref) +{ + struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref); + kfree(ei->entry_attrs); + kfree(ei); +} + +static inline void put_ei(struct eventfs_inode *ei) +{ + if (ei) + kref_put(&ei->kref, release_ei); +} + +static inline struct eventfs_inode *get_ei(struct eventfs_inode *ei) +{ + if (ei) + kref_get(&ei->kref); + return ei; +} + static struct dentry *eventfs_root_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags); @@ -289,7 +317,8 @@ static void update_inode_attr(struct dentry *dentry, struct inode *inode, * directory. The inode.i_private pointer will point to @data in the open() * call. */ -static struct dentry *lookup_file(struct dentry *dentry, +static struct dentry *lookup_file(struct eventfs_inode *parent_ei, + struct dentry *dentry, umode_t mode, struct eventfs_attr *attr, void *data, @@ -302,11 +331,11 @@ static struct dentry *lookup_file(struct dentry *dentry, mode |= S_IFREG; if (WARN_ON_ONCE(!S_ISREG(mode))) - return NULL; + return ERR_PTR(-EIO); inode = tracefs_get_inode(dentry->d_sb); if (unlikely(!inode)) - return eventfs_failed_creating(dentry); + return ERR_PTR(-ENOMEM); /* If the user updated the directory's attributes, use them */ update_inode_attr(dentry, inode, attr, mode); @@ -322,9 +351,12 @@ static struct dentry *lookup_file(struct dentry *dentry, ti->flags = TRACEFS_EVENT_INODE; ti->private = NULL; // Directories have 'ei', files not + // Files have their parent's ei as their fsdata + dentry->d_fsdata = get_ei(parent_ei); + d_add(dentry, inode); fsnotify_create(dentry->d_parent->d_inode, dentry); - return eventfs_end_creating(dentry); + return NULL; }; /** @@ -343,7 +375,7 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry, inode = tracefs_get_inode(dentry->d_sb); if (unlikely(!inode)) - return eventfs_failed_creating(dentry); + return ERR_PTR(-ENOMEM); /* If the user updated the directory's attributes, use them */ update_inode_attr(dentry, inode, &ei->attr, @@ -359,24 +391,28 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry, ti->flags = TRACEFS_EVENT_INODE; ti->private = ei; - dentry->d_fsdata = ei; - ei->dentry = dentry; // Remove me! + dentry->d_fsdata = get_ei(ei); inc_nlink(inode); d_add(dentry, inode); inc_nlink(dentry->d_parent->d_inode); fsnotify_mkdir(dentry->d_parent->d_inode, dentry); - return eventfs_end_creating(dentry); + return NULL; } -static void free_ei(struct eventfs_inode *ei) +static inline struct eventfs_inode *alloc_ei(const char *name) { - kfree_const(ei->name); - kfree(ei->d_children); - kfree(ei->entry_attrs); - kfree(ei); + int namesize = strlen(name) + 1; + struct eventfs_inode *ei = kzalloc(sizeof(*ei) + namesize, GFP_KERNEL); + + if (ei) { + memcpy((char *)ei->name, name, namesize); + kref_init(&ei->kref); + } + return ei; } + /** * eventfs_set_ei_status_free - remove the dentry reference from an eventfs_inode * @ti: the tracefs_inode of the dentry @@ -387,38 +423,20 @@ static void free_ei(struct eventfs_inode *ei) void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry) { struct eventfs_inode *ei; - int i; mutex_lock(&eventfs_mutex); - ei = dentry->d_fsdata; - if (!ei) - goto out; - - /* This could belong to one of the files of the ei */ - if (ei->dentry != dentry) { - for (i = 0; i < ei->nr_entries; i++) { - if (ei->d_children[i] == dentry) - break; - } - if (WARN_ON_ONCE(i == ei->nr_entries)) - goto out; - ei->d_children[i] = NULL; - } else if (ei->is_freed) { - free_ei(ei); - } else { - ei->dentry = NULL; + if (ei) { + dentry->d_fsdata = NULL; + put_ei(ei); } - - dentry->d_fsdata = NULL; - out: mutex_unlock(&eventfs_mutex); } /** * lookup_file_dentry - create a dentry for a file of an eventfs_inode * @ei: the eventfs_inode that the file will be created under - * @idx: the index into the d_children[] of the @ei + * @idx: the index into the entry_attrs[] of the @ei * @parent: The parent dentry of the created file. * @name: The name of the file to create * @mode: The mode of the file. @@ -435,17 +453,11 @@ lookup_file_dentry(struct dentry *dentry, const struct file_operations *fops) { struct eventfs_attr *attr = NULL; - struct dentry **e_dentry = &ei->d_children[idx]; if (ei->entry_attrs) attr = &ei->entry_attrs[idx]; - dentry->d_fsdata = ei; // NOTE: ei of _parent_ - lookup_file(dentry, mode, attr, data, fops); - - *e_dentry = dentry; // Remove me - - return dentry; + return lookup_file(ei, dentry, mode, attr, data, fops); } /** @@ -466,6 +478,7 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, struct tracefs_inode *ti; struct eventfs_inode *ei; const char *name = dentry->d_name.name; + struct dentry *result; ti = get_tracefs(dir); if (!(ti->flags & TRACEFS_EVENT_INODE)) @@ -482,7 +495,7 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, continue; if (ei_child->is_freed) goto enoent; - lookup_dir_entry(dentry, ei, ei_child); + result = lookup_dir_entry(dentry, ei, ei_child); goto out; } @@ -499,17 +512,18 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, if (entry->callback(name, &mode, &data, &fops) <= 0) goto enoent; - lookup_file_dentry(dentry, ei, i, mode, data, fops); + result = lookup_file_dentry(dentry, ei, i, mode, data, fops); goto out; } enoent: /* Nothing found? */ d_add(dentry, NULL); + result = NULL; out: mutex_unlock(&eventfs_mutex); - return NULL; + return result; } /* @@ -659,25 +673,10 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode if (!parent) return ERR_PTR(-EINVAL); - ei = kzalloc(sizeof(*ei), GFP_KERNEL); + ei = alloc_ei(name); if (!ei) return ERR_PTR(-ENOMEM); - ei->name = kstrdup_const(name, GFP_KERNEL); - if (!ei->name) { - kfree(ei); - return ERR_PTR(-ENOMEM); - } - - if (size) { - ei->d_children = kcalloc(size, sizeof(*ei->d_children), GFP_KERNEL); - if (!ei->d_children) { - kfree_const(ei->name); - kfree(ei); - return ERR_PTR(-ENOMEM); - } - } - ei->entries = entries; ei->nr_entries = size; ei->data = data; @@ -691,7 +690,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode /* Was the parent freed? */ if (list_empty(&ei->list)) { - free_ei(ei); + put_ei(ei); ei = NULL; } return ei; @@ -726,28 +725,20 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry if (IS_ERR(dentry)) return ERR_CAST(dentry); - ei = kzalloc(sizeof(*ei), GFP_KERNEL); + ei = alloc_ei(name); if (!ei) - goto fail_ei; + goto fail; inode = tracefs_get_inode(dentry->d_sb); if (unlikely(!inode)) goto fail; - if (size) { - ei->d_children = kcalloc(size, sizeof(*ei->d_children), GFP_KERNEL); - if (!ei->d_children) - goto fail; - } - - ei->dentry = dentry; + // Note: we have a ref to the dentry from tracefs_start_creating() + ei->events_dir = dentry; ei->entries = entries; ei->nr_entries = size; ei->is_events = 1; ei->data = data; - ei->name = kstrdup_const(name, GFP_KERNEL); - if (!ei->name) - goto fail; /* Save the ownership of this directory */ uid = d_inode(dentry->d_parent)->i_uid; @@ -778,7 +769,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry inode->i_op = &eventfs_root_dir_inode_operations; inode->i_fop = &eventfs_file_operations; - dentry->d_fsdata = ei; + dentry->d_fsdata = get_ei(ei); /* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink(inode); @@ -790,72 +781,11 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry return ei; fail: - kfree(ei->d_children); - kfree(ei); - fail_ei: + put_ei(ei); tracefs_failed_creating(dentry); return ERR_PTR(-ENOMEM); } -static LLIST_HEAD(free_list); - -static void eventfs_workfn(struct work_struct *work) -{ - struct eventfs_inode *ei, *tmp; - struct llist_node *llnode; - - llnode = llist_del_all(&free_list); - llist_for_each_entry_safe(ei, tmp, llnode, llist) { - /* This dput() matches the dget() from unhook_dentry() */ - for (int i = 0; i < ei->nr_entries; i++) { - if (ei->d_children[i]) - dput(ei->d_children[i]); - } - /* This should only get here if it had a dentry */ - if (!WARN_ON_ONCE(!ei->dentry)) - dput(ei->dentry); - } -} - -static DECLARE_WORK(eventfs_work, eventfs_workfn); - -static void free_rcu_ei(struct rcu_head *head) -{ - struct eventfs_inode *ei = container_of(head, struct eventfs_inode, rcu); - - if (ei->dentry) { - /* Do not free the ei until all references of dentry are gone */ - if (llist_add(&ei->llist, &free_list)) - queue_work(system_unbound_wq, &eventfs_work); - return; - } - - /* If the ei doesn't have a dentry, neither should its children */ - for (int i = 0; i < ei->nr_entries; i++) { - WARN_ON_ONCE(ei->d_children[i]); - } - - free_ei(ei); -} - -static void unhook_dentry(struct dentry *dentry) -{ - if (!dentry) - return; - /* - * Need to add a reference to the dentry that is expected by - * simple_recursive_removal(), which will include a dput(). - */ - dget(dentry); - - /* - * Also add a reference for the dput() in eventfs_workfn(). - * That is required as that dput() will free the ei after - * the SRCU grace period is over. - */ - dget(dentry); -} - /** * eventfs_remove_rec - remove eventfs dir or file from list * @ei: eventfs_inode to be removed. @@ -868,8 +798,6 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, int level) { struct eventfs_inode *ei_child; - if (!ei) - return; /* * Check recursion depth. It should never be greater than 3: * 0 - events/ @@ -881,28 +809,12 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, int level) return; /* search for nested folders or files */ - list_for_each_entry_srcu(ei_child, &ei->children, list, - lockdep_is_held(&eventfs_mutex)) { - /* Children only have dentry if parent does */ - WARN_ON_ONCE(ei_child->dentry && !ei->dentry); + list_for_each_entry(ei_child, &ei->children, list) eventfs_remove_rec(ei_child, level + 1); - } - ei->is_freed = 1; - - for (int i = 0; i < ei->nr_entries; i++) { - if (ei->d_children[i]) { - /* Children only have dentry if parent does */ - WARN_ON_ONCE(!ei->dentry); - unhook_dentry(ei->d_children[i]); - } - } - - unhook_dentry(ei->dentry); - - list_del_rcu(&ei->list); - call_srcu(&eventfs_srcu, &ei->rcu, free_rcu_ei); + list_del(&ei->list); + put_ei(ei); } /** @@ -913,22 +825,12 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, int level) */ void eventfs_remove_dir(struct eventfs_inode *ei) { - struct dentry *dentry; - if (!ei) return; mutex_lock(&eventfs_mutex); - dentry = ei->dentry; eventfs_remove_rec(ei, 0); mutex_unlock(&eventfs_mutex); - - /* - * If any of the ei children has a dentry, then the ei itself - * must have a dentry. - */ - if (dentry) - simple_recursive_removal(dentry, NULL); } /** @@ -941,7 +843,11 @@ void eventfs_remove_events_dir(struct eventfs_inode *ei) { struct dentry *dentry; - dentry = ei->dentry; + dentry = ei->events_dir; + if (!dentry) + return; + + ei->events_dir = NULL; eventfs_remove_dir(ei); /* @@ -951,5 +857,6 @@ void eventfs_remove_events_dir(struct eventfs_inode *ei) * sticks around while the other ei->dentry are created * and destroyed dynamically. */ + simple_recursive_removal(dentry, NULL); dput(dentry); } diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h index 8f38740bfb5b..72db3bdc4dfb 100644 --- a/fs/tracefs/internal.h +++ b/fs/tracefs/internal.h @@ -34,8 +34,7 @@ struct eventfs_attr { * @entries: the array of entries representing the files in the directory * @name: the name of the directory to create * @children: link list into the child eventfs_inode - * @dentry: the dentry of the directory - * @d_children: The array of dentries to represent the files when created + * @events_dir: the dentry of the events directory * @entry_attrs: Saved mode and ownership of the @d_children * @attr: Saved mode and ownership of eventfs_inode itself * @data: The private data to pass to the callbacks @@ -44,12 +43,11 @@ struct eventfs_attr { * @nr_entries: The number of items in @entries */ struct eventfs_inode { + struct kref kref; struct list_head list; const struct eventfs_entry *entries; - const char *name; struct list_head children; - struct dentry *dentry; /* Check is_freed to access */ - struct dentry **d_children; + struct dentry *events_dir; struct eventfs_attr *entry_attrs; struct eventfs_attr attr; void *data; @@ -66,6 +64,7 @@ struct eventfs_inode { struct llist_node llist; struct rcu_head rcu; }; + const char name[]; }; static inline struct tracefs_inode *get_tracefs(const struct inode *inode) From patchwork Tue Jan 30 19:03:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Torvalds X-Patchwork-Id: 194280 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1436563dyb; Tue, 30 Jan 2024 11:05:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IH7cC0gm70/npjpTHDHDh0TRvKfcz2jZEdvPO6dk0bMXxrcevkHk6PN0r0ipk+CRMa67/aE X-Received: by 2002:a05:6871:5a93:b0:214:ff0e:2134 with SMTP id oo19-20020a0568715a9300b00214ff0e2134mr5403369oac.31.1706641535083; Tue, 30 Jan 2024 11:05:35 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706641535; cv=pass; d=google.com; s=arc-20160816; b=dnFEL7+1Hg4WSm+CkrEPxImcLXkPVzuEfj3mi1zSK1GUeTL0m9WCifc1wM3dDSrOEp F/hTcxWtphHalFJqYZVqfawuw3E2S0QazLB0vUvgpP+VPu1qZmzGTj5V3mdTNEmEnxnX ddbLgAoFKSwB0d0gl7NS3e5D3RuzAMoqcWa8ea0IkiMIKAe2ZK5u3e6qemUkr02F7akZ N11E6lrE9XyIXKSQiS7mTGdHwMcP25UDJ5XE+Qb11nbGuo4ygbWmqxdJyXslpDvsaWeO JUjTkwTTyUJqHGYkl5tt9F3vkpC3KWhKVjWrcCFoU3wYM5pbAtdSa4qHbL434Y+9vF/C AMiQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=l3o/afZBWKsKsQon6Z1UIFLCalkwQ6Wqu6ahwPboOzA=; fh=aD/wDFT3pdBCiZXVST/riRN8xCPBouJr3XfOtoKVvRw=; b=pQkryFHBzYyCU/YibinfDuCqkF6oIwVrnabWCFr/cviP/Tu0HqQitblLVFQMJBt+pj 2tL4OLGGrUdY6FOTGdQKKcmNHmVTeuRNKXL3JAv5SQUI7a1eY+zriP7Jl+XqNXIjFR61 8xWxxHuVB8x3Wyf0ubhMlLX8XEBo5JRluQTv/2T1PfXj2GdqbiC69iM0g1XKwjDENIHR XyYQPQCKFuQFDkCfIDBE9t7OHYRuuP7TKHbQ+x0LoykW0JgrUH12JEvOlHY0hSX+IL8Q df7J+3o4i7RW8icwNmrQ6/ObXhopqCOjwYWSyIL9pX4QMwDhkdMNjSrm5d+qNf6TOmki uJhg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=wGjmvTEi; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45159-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45159-ouuuleilei=gmail.com@vger.kernel.org" Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id h5-20020ac5c285000000b004b71a117299si1302858vkk.98.2024.01.30.11.05.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 11:05:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-45159-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=korg header.b=wGjmvTEi; arc=pass (i=1 dkim=pass dkdomain=linux-foundation.org); spf=pass (google.com: domain of linux-kernel+bounces-45159-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-45159-ouuuleilei=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id F3CE91C23A5E for ; Tue, 30 Jan 2024 19:05:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 23B1A69DE4; Tue, 30 Jan 2024 19:04:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="wGjmvTEi" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D3977995D; Tue, 30 Jan 2024 19:04:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641464; cv=none; b=o0B7DM++OveallHu48BMF14JVDcFOYVD4rYR+55EMSDg4qZSCBrzp+5WqCXxV8z3ZSIn4PMKtc80fIgd4RIg5JRcbme86sITk8pkUp/YIt9KJB2pY6thmu8AxYbQxgnjrl4lJ/8xww29JUVlH/Fp3uoUUF1vOVXXlS2KU7f2n9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706641464; c=relaxed/simple; bh=uW+OU0rYpytIA1AFMT3QHS+mJXzgQjvRvaoJkHkudIo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KjfluNwvKJDeD+m5VhlIkZIEqsV8mNomNZQlOqihH2wEG2Kp5663Id0pk/IxGyApLEQXzK/aKJ928l4645gHN0ur7dDJ9YmgemH0E5u0kjQHl+dQT/lRZKfcxQIBXUtGIwDYRq1iY4dhYpUONa2+zCaojXNKmzwVRQIxNUz/itw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=wGjmvTEi; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 91369C43399; Tue, 30 Jan 2024 19:04:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1706641463; bh=uW+OU0rYpytIA1AFMT3QHS+mJXzgQjvRvaoJkHkudIo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wGjmvTEiT7sEcOAeBTVz3vAxOPiWnLBmpzpTnw7l8nUEO5LLLIbDIWjK6IaFdeOU4 Fkw4pWkwCYXU+aJqTOdxCzGuWtI+ab9/xRDcPLzv9FA7ZJzGJUlVoTC/GLbo2EXcGM S6VRjgiALRhRcIhP+0JXRRnUDEZkBplONVjBTeA0= From: Linus Torvalds To: Steven Rostedt Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, Linus Torvalds Subject: [PATCH 6/6] eventfs: clean up dentry ops and add revalidate function Date: Tue, 30 Jan 2024 11:03:55 -0800 Message-ID: <20240130190355.11486-6-torvalds@linux-foundation.org> X-Mailer: git-send-email 2.43.0.5.g38fb137bdb In-Reply-To: <20240130190355.11486-1-torvalds@linux-foundation.org> References: <20240130190355.11486-1-torvalds@linux-foundation.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789543354434867235 X-GMAIL-MSGID: 1789543354434867235 In order for the dentries to stay up-to-date with the eventfs changes, just add a 'd_revalidate' function that checks the 'is_freed' bit. Also, clean up the dentry release to actually use d_release() rather than the slightly odd d_iput() function. We don't care about the inode, all we want to do is to get rid of the refcount to the eventfs data added by dentry->d_fsdata. It would probably be cleaner to make eventfs its own filesystem, or at least set its own dentry ops when looking up eventfs files. But as it is, only eventfs dentries use d_fsdata, so we don't really need to split these things up by use. Another thing that might be worth doing is to make all eventfs lookups mark their dentries as not worth caching. We could do that with d_delete(), but the DCACHE_DONTCACHE flag would likely be even better. As it is, the dentries are all freeable, but they only tend to get freed at memory pressure rather than more proactively. But that's a separate issue. Signed-off-by: Linus Torvalds --- fs/tracefs/event_inode.c | 21 +++++---------------- fs/tracefs/inode.c | 27 ++++++++++++++++++--------- fs/tracefs/internal.h | 3 ++- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index a37db0dac302..acdc797bd9c0 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -414,23 +414,14 @@ static inline struct eventfs_inode *alloc_ei(const char *name) /** - * eventfs_set_ei_status_free - remove the dentry reference from an eventfs_inode - * @ti: the tracefs_inode of the dentry + * eventfs_d_release - dentry is going away * @dentry: dentry which has the reference to remove. * * Remove the association between a dentry from an eventfs_inode. */ -void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry) +void eventfs_d_release(struct dentry *dentry) { - struct eventfs_inode *ei; - - mutex_lock(&eventfs_mutex); - ei = dentry->d_fsdata; - if (ei) { - dentry->d_fsdata = NULL; - put_ei(ei); - } - mutex_unlock(&eventfs_mutex); + put_ei(dentry->d_fsdata); } /** @@ -517,9 +508,8 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, } enoent: - /* Nothing found? */ - d_add(dentry, NULL); - result = NULL; + /* Don't cache negative lookups, just return an error */ + result = ERR_PTR(-ENOENT); out: mutex_unlock(&eventfs_mutex); @@ -857,6 +847,5 @@ void eventfs_remove_events_dir(struct eventfs_inode *ei) * sticks around while the other ei->dentry are created * and destroyed dynamically. */ - simple_recursive_removal(dentry, NULL); dput(dentry); } diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index e1b172c0e091..64122787e5d0 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -379,21 +379,30 @@ static const struct super_operations tracefs_super_operations = { .show_options = tracefs_show_options, }; -static void tracefs_dentry_iput(struct dentry *dentry, struct inode *inode) +/* + * It would be cleaner if eventfs had its own dentry ops. + * + * Note that d_revalidate is called potentially under RCU, + * so it can't take the eventfs mutex etc. It's fine - if + * we open a file just as it's marked dead, things will + * still work just fine, and just see the old stale case. + */ +static void tracefs_d_release(struct dentry *dentry) { - struct tracefs_inode *ti; + if (dentry->d_fsdata) + eventfs_d_release(dentry); +} - if (!dentry || !inode) - return; +static int tracefs_d_revalidate(struct dentry *dentry, unsigned int flags) +{ + struct eventfs_inode *ei = dentry->d_fsdata; - ti = get_tracefs(inode); - if (ti && ti->flags & TRACEFS_EVENT_INODE) - eventfs_set_ei_status_free(ti, dentry); - iput(inode); + return !(ei && ei->is_freed); } static const struct dentry_operations tracefs_dentry_operations = { - .d_iput = tracefs_dentry_iput, + .d_revalidate = tracefs_d_revalidate, + .d_release = tracefs_d_release, }; static int trace_fill_super(struct super_block *sb, void *data, int silent) diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h index 72db3bdc4dfb..d4194466b643 100644 --- a/fs/tracefs/internal.h +++ b/fs/tracefs/internal.h @@ -79,6 +79,7 @@ struct inode *tracefs_get_inode(struct super_block *sb); struct dentry *eventfs_start_creating(const char *name, struct dentry *parent); struct dentry *eventfs_failed_creating(struct dentry *dentry); struct dentry *eventfs_end_creating(struct dentry *dentry); -void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry); + +void eventfs_d_release(struct dentry *dentry); #endif /* _TRACEFS_INTERNAL_H */