From nobody Tue Apr 7 14:03:42 2026 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16CC733BBDD for ; Wed, 25 Feb 2026 22:34:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772058856; cv=none; b=mdy/FvpTj/dRBFTwIrCeXQqkjGw3LJsxvEkttD194DDDW3dik4/I2x53GjyuLxye83vRbkbjbHKOF+I3izgKzqViqtlGgl84dEhyCxB3prs7I2YBPeLnopI7RPnARPxPzGSgNl+XUb7NZUUAcIihginSrult0ky2+kGhOBoPCmY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772058856; c=relaxed/simple; bh=d/Njxo6LsxfyrmnJNgQrbf4Jrkxu+B4X3AZ0DsjVEVo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SpEbpM6yEvTBDBeP3lKiFVLW2TqCiq8I7ZLs9QoDaoyV9bu7gBbCIlSwMvBUj9LA8bIfiVDTqlcGhV4lticJK6wTB3pIfAvRq2wTU2Ip8PJZLQrRQkKWLP7DutfjrSgCWD0vP11LJBBgsAbbrQf4vr5E3Z/GTN59hAWdqenvcdY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tjmercier.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=BxzG4G3L; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--tjmercier.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BxzG4G3L" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-824b461dc9dso744365b3a.1 for ; Wed, 25 Feb 2026 14:34:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772058854; x=1772663654; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Ej8LZF1b2o/Ks4R9g/3WwRmZsBfUCiZmdJJkOcGo2tM=; b=BxzG4G3LajyWmNwxkvDlwpBcseYaD7ZbGndoatMSkBckWFxRfxbphZtibZ0hyraLjE Kl10IbA+mdZ32WOc6bbNFoMajjDCVWlXW2FDSPFQyOmfCaoCW1aoRg8Vuw4i8d7DdPCZ u69sgXA9X1oIeXkAb2reT67dShvUYVs7nJ79FiAUJv++cS349qRgf7EoNYbNs2UeRY+j o3MckmvdIhfSHceJBaSjUbrTSOgWXofI/CrlR54a+ydm7a7n4Ld/M9AwyrSMEGhGI3xC +/JOek7nLoMpUlB4CvMOIVx4GZ4LalpntsluNLyqeItkaRTOKt7rXOCSMMXpQtZrpJNZ DKrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772058854; x=1772663654; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ej8LZF1b2o/Ks4R9g/3WwRmZsBfUCiZmdJJkOcGo2tM=; b=EpqOwgvgHioyqoD9G2b1gomw4soeHwII9Ha+1RtyQnFXW4jRGHpvmBkPtLpE8KPgtw TNxRIEIuu9NZWoVQ2R56bW9sTYKKmHqGXyxI3SCvOLmFx6ohWA7GsYgU5ztoAdC6ak3H YCq131JPTMmUSLkj+4Z20BrDqOnjqnODa6D0vj2CIZqX8lQdEG+JDya+XP90NlURma3W r5xYiEvbuzDx7lkLOGtovcxBFEp0VbZiBOZy0o4ZuFPW+G5o8WirO0VB0MKkHh5dWA9W Fk7dvPAtCvLcsov607eNfB3XoKiaRUjdx4E3qDymgTsxr13yi4S9kSBhvRLWr5dQ2kHy RnjQ== X-Forwarded-Encrypted: i=1; AJvYcCVSODWkdhtS3SFLUAM2IvfdX6zxFGLotb9O6zRG+Th6UGRc7Mdk8TVyXCBlvMWLpLQe5UsXIoICVWgi34c=@vger.kernel.org X-Gm-Message-State: AOJu0YwmvlU28aUutMTUXrrauV6VlwgRz8SbrTCJ56C1UQgkrigN8cpI 0CAglyrHG3fwwq1zX+qfI2vDU7FuxVINuxPrhTwEMv7Oy92Y6HsxrQ+i5By87Rwg2wtUSY9EqN5 9kg2m1RmOhcKRGseWXw== X-Received: from pfbey14.prod.google.com ([2002:a05:6a00:38ce:b0:824:b235:888c]) (user=tjmercier job=prod-delivery.src-stubby-dispatcher) by 2002:aa7:930a:0:b0:823:533d:5559 with SMTP id d2e1a72fcca58-826da9ee9b0mr17908704b3a.39.1772058854168; Wed, 25 Feb 2026 14:34:14 -0800 (PST) Date: Wed, 25 Feb 2026 14:34:02 -0800 In-Reply-To: <20260225223404.783173-1-tjmercier@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260225223404.783173-1-tjmercier@google.com> X-Mailer: git-send-email 2.53.0.414.gf7e9f6c205-goog Message-ID: <20260225223404.783173-2-tjmercier@google.com> Subject: [PATCH v5 1/3] kernfs: Don't set_nlink for directories being removed From: "T.J. Mercier" To: gregkh@linuxfoundation.org, tj@kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, linux-fsdevel@vger.kernel.org, jack@suse.cz, amir73il@gmail.com, shuah@kernel.org, linux-kselftest@vger.kernel.org Cc: "T.J. Mercier" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If a directory is already in the process of removal its i_nlink count becomes irrelevant because its contents are also about to be removed and any pending filesystem operations on it or its contents will soon start to fail. So we can avoid setting it for directories already flagged for removal. This avoids a race in the next patch, which adds clearing of the i_nlink count for kernfs nodes being removed to support inotify delete events. Use protection from the kernfs_iattr_rwsem to avoid adding more contention to the kernfs_rwsem for calls to kernfs_refresh_inode. Signed-off-by: T.J. Mercier --- fs/kernfs/dir.c | 2 ++ fs/kernfs/inode.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 29baeeb97871..5b6ce2351a53 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1491,12 +1491,14 @@ static void __kernfs_remove(struct kernfs_node *kn) pr_debug("kernfs %s: removing\n", kernfs_rcu_name(kn)); =20 /* prevent new usage by marking all nodes removing and deactivating */ + down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); pos =3D NULL; while ((pos =3D kernfs_next_descendant_post(pos, kn))) { pos->flags |=3D KERNFS_REMOVING; if (kernfs_active(pos)) atomic_add(KN_DEACTIVATED_BIAS, &pos->active); } + up_write(&kernfs_root(kn)->kernfs_iattr_rwsem); =20 /* deactivate and unlink the subtree node-by-node */ do { diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index a36aaee98dce..afdc4021e81a 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -178,7 +178,7 @@ static void kernfs_refresh_inode(struct kernfs_node *kn= , struct inode *inode) */ set_inode_attr(inode, attrs); =20 - if (kernfs_type(kn) =3D=3D KERNFS_DIR) + if (kernfs_type(kn) =3D=3D KERNFS_DIR && !(kn->flags & KERNFS_REMOVING)) set_nlink(inode, kn->dir.subdirs + 2); } =20 --=20 2.53.0.414.gf7e9f6c205-goog From nobody Tue Apr 7 14:03:43 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C904733C514 for ; Wed, 25 Feb 2026 22:34:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772058859; cv=none; b=T/n3cDYc8lBPN259aJAiRWAlhJprjrI4El8sx9p/5IBJWZgEQgwcYTRHvGGzvTE4Zskk6/LJv9lkglP7nj6OmFRKioWzA+GKeyaYIJyjG5JY0l//g4eWu7P0LAX7q+rgJsH8ffLL6gzqOc0QT7VufUWASB2NdubCcmfjgX06LiU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772058859; c=relaxed/simple; bh=rSm9eO5Ae7qCYX7mFMqmd32iA6mbsCBNJytO0KWipNg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=harUUUpijinxO5Rgg0XOVjR8+3vmZvkgkQjW3HX473cLFZnGSGcJ5xqDl5hjRXDGxkypGp9LTf1AcN9S5p8BkHAcL2A1oMUYyUXF4qTVOyBTxXEt/gS1S/EU9fuk1og33dXZgKCcKKss1AHbwbSfr5OE/ObW3M7Rwp0taY/cL5w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tjmercier.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=es/U5aFj; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--tjmercier.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="es/U5aFj" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2add182f21eso1300785ad.1 for ; Wed, 25 Feb 2026 14:34:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772058857; x=1772663657; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=NU8CwwwJNtwj6NKE5VGHBuhoRDOVzhXUv5Gj/T+7KkI=; b=es/U5aFjRFMNvljq3G9LLMpLEnDW7LerIGyE7IuQbTW6aXu8uN/NyA8wdpSn4hmdtx OWSIKSiFqiAL7J2+oa6IjCO/pKxHtrqPkX0ccUWmyRjW7b/6BmkYDMkVoldKsWeLM/3p pcgDB3+AaVPNL9K6XkrGh/NsSMZU9MSr4TKrGrKL9kapLQkbmMcCjuKxNb6Ei+psazEg awLrG1Eou+z5Sct+u/CvNOAMuLZOh0xWViaw45ZC3xUKRUVJ7l9loEaC50adMulpGcK1 CFxublVnJO/O2XPkQMNfLqcGyQRpjSLzKsm8av9xecvnewd1LAleGOusbcQW1oqPEzkZ OLuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772058857; x=1772663657; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NU8CwwwJNtwj6NKE5VGHBuhoRDOVzhXUv5Gj/T+7KkI=; b=kcxTC9T3uwEUCwtqzQptSgcIq/3PX1Bc3J4dY2Yu12UVZ2D0ivodWm6Hbi/9Zw9w2a 5oDtcE+giiLX/pO83TeLpHQKkUWZeMGSGIphFko0TVVsx+a81Y9+O5izPNqxT/n62J80 zMGUprK/RVOW6t+NPuwY+tVKTTGTr30vDvU0m/ZBzySXkY6r60PezXkyX/gvVqfzd3KO TQqSQ41I3BEsSC8dWjkSrNk7MvFjdS7kLRoEcERoRVFL0gjY9zsP36qsadBLIjeVKa9W zwvKQ3kK2bobX+EAaaukpz90YWwZhvNtv5yMkugoXdG531zUYmZxHAq/crYXbWyZGwia Eoqg== X-Forwarded-Encrypted: i=1; AJvYcCWALbJTangr1TOH0K0VNnwMTufhsNHq09jh18ViNKmur7JcBKLQC1h+D8ESotd2qba+LIihof4UZvUcWNc=@vger.kernel.org X-Gm-Message-State: AOJu0YyMHQYjEb6ArMMN1xGvU21kl39/vatcTR2DfJG8+kuk8jBEallB 5fpNmOnjesTVHeoAWtDlfBShMWzfif0ShCxc+PjzbTR/Lur4vc5uGWN6xm6pGe9vyJzs3DH1oxH 7hF0ip57ROdljxYoc7A== X-Received: from plrd12.prod.google.com ([2002:a17:902:aa8c:b0:2ad:9a1a:f7de]) (user=tjmercier job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2311:b0:2ad:b959:3de3 with SMTP id d9443c01a7336-2ade9991115mr13800735ad.19.1772058857077; Wed, 25 Feb 2026 14:34:17 -0800 (PST) Date: Wed, 25 Feb 2026 14:34:03 -0800 In-Reply-To: <20260225223404.783173-1-tjmercier@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260225223404.783173-1-tjmercier@google.com> X-Mailer: git-send-email 2.53.0.414.gf7e9f6c205-goog Message-ID: <20260225223404.783173-3-tjmercier@google.com> Subject: [PATCH v5 2/3] kernfs: Send IN_DELETE_SELF and IN_IGNORED From: "T.J. Mercier" To: gregkh@linuxfoundation.org, tj@kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, linux-fsdevel@vger.kernel.org, jack@suse.cz, amir73il@gmail.com, shuah@kernel.org, linux-kselftest@vger.kernel.org Cc: "T.J. Mercier" , syzbot@syzkaller.appspotmail.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently some kernfs files (e.g. cgroup.events, memory.events) support inotify watches for IN_MODIFY, but unlike with regular filesystems, they do not receive IN_DELETE_SELF or IN_IGNORED events when they are removed. This means inotify watches persist after file deletion until the process exits and the inotify file descriptor is cleaned up, or until inotify_rm_watch is called manually. This creates a problem for processes monitoring cgroups. For example, a service monitoring memory.events for memory.high breaches needs to know when a cgroup is removed to clean up its state. Where it's known that a cgroup is removed when all processes die, without IN_DELETE_SELF the service must resort to inefficient workarounds such as: 1) Periodically scanning procfs to detect process death (wastes CPU and is susceptible to PID reuse). 2) Holding a pidfd for every monitored cgroup (can exhaust file descriptors). This patch enables IN_DELETE_SELF and IN_IGNORED events for kernfs files and directories by clearing inode i_nlink values during removal. This allows VFS to make the necessary fsnotify calls so that userspace receives the inotify events. As a result, applications can rely on a single existing watch on a file of interest (e.g. memory.events) to receive notifications for both modifications and the eventual removal of the file, as well as automatic watch descriptor cleanup, simplifying userspace logic and improving efficiency. There is gap in this implementation for certain file removals due their unique nature in kernfs. Directory removals that trigger file removals occur through vfs_rmdir, which shrinks the dcache and emits fsnotify events after the rmdir operation; there is no issue here. However kernfs writes to particular files (e.g. cgroup.subtree_control) can also cause file removal, but vfs_write does not attempt to emit fsnotify events after the write operation, even if i_nlink counts are 0. As a usecase for monitoring this category of file removals is not known, they are left without having IN_DELETE or IN_DELETE_SELF events generated. Fanotify recursive monitoring also does not work for kernfs nodes that do not have inodes attached, as they are created on-demand in kernfs. Suggested-by: Jan Kara Signed-off-by: T.J. Mercier Tested-by: syzbot@syzkaller.appspotmail.com Acked-by: Tejun Heo --- fs/kernfs/dir.c | 54 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 5b6ce2351a53..9c4eabc9c7a1 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -486,7 +486,7 @@ void kernfs_put_active(struct kernfs_node *kn) * removers may invoke this function concurrently on @kn and all will * return after draining is complete. */ -static void kernfs_drain(struct kernfs_node *kn) +static void kernfs_drain(struct kernfs_node *kn, bool drop_supers) __releases(&kernfs_root(kn)->kernfs_rwsem) __acquires(&kernfs_root(kn)->kernfs_rwsem) { @@ -506,6 +506,8 @@ static void kernfs_drain(struct kernfs_node *kn) return; =20 up_write(&root->kernfs_rwsem); + if (drop_supers) + up_read(&root->kernfs_supers_rwsem); =20 if (kernfs_lockdep(kn)) { rwsem_acquire(&kn->dep_map, 0, 0, _RET_IP_); @@ -524,6 +526,8 @@ static void kernfs_drain(struct kernfs_node *kn) if (kernfs_should_drain_open_files(kn)) kernfs_drain_open_files(kn); =20 + if (drop_supers) + down_read(&root->kernfs_supers_rwsem); down_write(&root->kernfs_rwsem); } =20 @@ -1465,12 +1469,43 @@ void kernfs_show(struct kernfs_node *kn, bool show) kn->flags |=3D KERNFS_HIDDEN; if (kernfs_active(kn)) atomic_add(KN_DEACTIVATED_BIAS, &kn->active); - kernfs_drain(kn); + kernfs_drain(kn, false); } =20 up_write(&root->kernfs_rwsem); } =20 +/* + * This function enables VFS to send fsnotify events for deletions. + * There is gap in this implementation for certain file removals due their + * unique nature in kernfs. Directory removals that trigger file removals = occur + * through vfs_rmdir, which shrinks the dcache and emits fsnotify events a= fter + * the rmdir operation; there is no issue here. However kernfs writes to + * particular files (e.g. cgroup.subtree_control) can also cause file remo= val, + * but vfs_write does not attempt to emit fsnotify events after the write + * operation, even if i_nlink counts are 0. As a usecase for monitoring th= is + * category of file removals is not known, they are left without having + * IN_DELETE or IN_DELETE_SELF events generated. + * Fanotify recursive monitoring also does not work for kernfs nodes that = do not + * have inodes attached, as they are created on-demand in kernfs. + */ +static void kernfs_clear_inode_nlink(struct kernfs_node *kn) +{ + struct kernfs_root *root =3D kernfs_root(kn); + struct kernfs_super_info *info; + + lockdep_assert_held_read(&root->kernfs_supers_rwsem); + + list_for_each_entry(info, &root->supers, node) { + struct inode *inode =3D ilookup(info->sb, kernfs_ino(kn)); + + if (inode) { + clear_nlink(inode); + iput(inode); + } + } +} + static void __kernfs_remove(struct kernfs_node *kn) { struct kernfs_node *pos, *parent; @@ -1479,6 +1514,7 @@ static void __kernfs_remove(struct kernfs_node *kn) if (!kn) return; =20 + lockdep_assert_held_read(&kernfs_root(kn)->kernfs_supers_rwsem); lockdep_assert_held_write(&kernfs_root(kn)->kernfs_rwsem); =20 /* @@ -1512,7 +1548,7 @@ static void __kernfs_remove(struct kernfs_node *kn) */ kernfs_get(pos); =20 - kernfs_drain(pos); + kernfs_drain(pos, true); parent =3D kernfs_parent(pos); /* * kernfs_unlink_sibling() succeeds once per node. Use it @@ -1522,9 +1558,11 @@ static void __kernfs_remove(struct kernfs_node *kn) struct kernfs_iattrs *ps_iattr =3D parent ? parent->iattr : NULL; =20 - /* update timestamps on the parent */ down_write(&kernfs_root(kn)->kernfs_iattr_rwsem); =20 + kernfs_clear_inode_nlink(pos); + + /* update timestamps on the parent */ if (ps_iattr) { ktime_get_real_ts64(&ps_iattr->ia_ctime); ps_iattr->ia_mtime =3D ps_iattr->ia_ctime; @@ -1553,9 +1591,11 @@ void kernfs_remove(struct kernfs_node *kn) =20 root =3D kernfs_root(kn); =20 + down_read(&root->kernfs_supers_rwsem); down_write(&root->kernfs_rwsem); __kernfs_remove(kn); up_write(&root->kernfs_rwsem); + up_read(&root->kernfs_supers_rwsem); } =20 /** @@ -1646,6 +1686,7 @@ bool kernfs_remove_self(struct kernfs_node *kn) bool ret; struct kernfs_root *root =3D kernfs_root(kn); =20 + down_read(&root->kernfs_supers_rwsem); down_write(&root->kernfs_rwsem); kernfs_break_active_protection(kn); =20 @@ -1675,7 +1716,9 @@ bool kernfs_remove_self(struct kernfs_node *kn) break; =20 up_write(&root->kernfs_rwsem); + up_read(&root->kernfs_supers_rwsem); schedule(); + down_read(&root->kernfs_supers_rwsem); down_write(&root->kernfs_rwsem); } finish_wait(waitq, &wait); @@ -1690,6 +1733,7 @@ bool kernfs_remove_self(struct kernfs_node *kn) kernfs_unbreak_active_protection(kn); =20 up_write(&root->kernfs_rwsem); + up_read(&root->kernfs_supers_rwsem); return ret; } =20 @@ -1716,6 +1760,7 @@ int kernfs_remove_by_name_ns(struct kernfs_node *pare= nt, const char *name, } =20 root =3D kernfs_root(parent); + down_read(&root->kernfs_supers_rwsem); down_write(&root->kernfs_rwsem); =20 kn =3D kernfs_find_ns(parent, name, ns); @@ -1726,6 +1771,7 @@ int kernfs_remove_by_name_ns(struct kernfs_node *pare= nt, const char *name, } =20 up_write(&root->kernfs_rwsem); + up_read(&root->kernfs_supers_rwsem); =20 if (kn) return 0; --=20 2.53.0.414.gf7e9f6c205-goog From nobody Tue Apr 7 14:03:43 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B505B33C1A7 for ; Wed, 25 Feb 2026 22:34:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772058866; cv=none; b=ijShZ2eWDzBwu52LTwDoR3q22NTjA7LGbW0tPHZX5d+AKQ5ZypZdtEzdKL55ya7dKDGXDzPB44bP1Z6VEqJ/DItrdNtMTPIw4sJfoc5N357Ton3kmJjKzFts5k/ORNHCG+1yLyQIV4xs8iitBjMWTW6dVMdo3VmPKBWHuPcG/3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772058866; c=relaxed/simple; bh=ymKrZvnn1wXoX3MO7tLDPSCDvegTjqhP4f2VwqTSGPs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=gOM0ypT8Zx7slKOMrG4Cph4JR2EEkCd7xoaY7YGo2hxROjy6UMO2j1jbhv0g8Ntm1mfCq3gFR5QxV9Wkb4PTSatoPH54pwikk4/cn7balweRLoXoQ07YmP0jgxdEGCYBJmUOU8qFTrjlb6QeG8c+QRfmgpK7cggzYKvmzmhQ0N8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tjmercier.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=fRyqgEis; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--tjmercier.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fRyqgEis" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2add59d1a5aso997405ad.3 for ; Wed, 25 Feb 2026 14:34:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772058860; x=1772663660; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=VLezOUj++5KtU+iy76kNFYSHOIOxW3z9n/oglLgyr0s=; b=fRyqgEis2xyUjaczHDwUma1EDA4AN3QlAcp39p2ElDW4QdhH0DTLDPCl7rTl5rsZfh Y/ck5cCTlHbNLSolchZLjwn9VSuHY3NZZ1siS5e/dTqtYxfDTWYgaUqQ9RbV42/Dx2lp 5aJsid0eP1DXY4+W6icRzkGWD8wx1Qmv4uRhPoUzdIKx7wwtLVb1iW5xHv0trPMR3qDo 4oOanaN7QY1I2kSkutdShCw1hportGfjNSeQH6lxleyityFGAjNU91i7EA+eyop34/e0 R5REy3LkQFB3KGJRT274Er5i19oVizrit3USMZ0IZxf6EZgXh0+M7llGlnj5nVMB5zlM 118g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772058860; x=1772663660; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=VLezOUj++5KtU+iy76kNFYSHOIOxW3z9n/oglLgyr0s=; b=C8Q5pBnCpTtYd24y1Sbn2VFZT7kkRoZuSSl6GO9cuukP4FmjeEz7sLkwWkzTdGFPfS RNcVrHh+xZtk5xi55GJWZuL4EmJpzkWbVJgPRTCx+2a4hArjyDG6v9ST7dp2CqyjMv9L TvASzsUzzDDNQkJgWTaJcvMfMdYg+SqzdRNfz2mHOA78pOyGB5T3JDjxU4pH4CL+fV+y lkG3X0ScrKzGFezA3zNsGQgcQ42ekGsJT/xv4v8YxHjH4gArRvegioKAn1b2CO3HXEOU bdC4u4ztvOPI7Yc3ibFSRsu0NsNo4rUpAgZ6WJlleP2XG3YbjZq93SorivBQ2m3jt8l6 4dSw== X-Forwarded-Encrypted: i=1; AJvYcCWMQQoiWwvic0D2S022MLRkIJV8fi2LwoWLhjaJFdaa2gmXJMwfktdN/JGYw0wCpOdTDNADsx7W8zrG4aI=@vger.kernel.org X-Gm-Message-State: AOJu0YxAEFqONPnn6bZqTbyVNWRxt1akHqgr63TqDrjvxHRpD71+IWmj gfzV4hN8WAawBeo1dngL9fVV968Ih2ZNq6+o8imVh8/QvW1jbD1GJ1sJDzm6ZuuvwT7YOr/68IM RcnYW7W5F74NJLXSWIA== X-Received: from plbld14.prod.google.com ([2002:a17:902:face:b0:2a7:7822:9011]) (user=tjmercier job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:b48:b0:2a0:bb05:df55 with SMTP id d9443c01a7336-2ae034613a3mr358175ad.21.1772058859947; Wed, 25 Feb 2026 14:34:19 -0800 (PST) Date: Wed, 25 Feb 2026 14:34:04 -0800 In-Reply-To: <20260225223404.783173-1-tjmercier@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260225223404.783173-1-tjmercier@google.com> X-Mailer: git-send-email 2.53.0.414.gf7e9f6c205-goog Message-ID: <20260225223404.783173-4-tjmercier@google.com> Subject: [PATCH v5 3/3] selftests: memcg: Add tests for IN_DELETE_SELF and IN_IGNORED From: "T.J. Mercier" To: gregkh@linuxfoundation.org, tj@kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, linux-fsdevel@vger.kernel.org, jack@suse.cz, amir73il@gmail.com, shuah@kernel.org, linux-kselftest@vger.kernel.org Cc: "T.J. Mercier" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add two new tests that verify inotify events are sent when memcg files or directories are removed with rmdir. Signed-off-by: T.J. Mercier Acked-by: Tejun Heo Acked-by: Amir Goldstein --- .../selftests/cgroup/test_memcontrol.c | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testi= ng/selftests/cgroup/test_memcontrol.c index 4e1647568c5b..57726bc82757 100644 --- a/tools/testing/selftests/cgroup/test_memcontrol.c +++ b/tools/testing/selftests/cgroup/test_memcontrol.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1625,6 +1626,115 @@ static int test_memcg_oom_group_score_events(const = char *root) return ret; } =20 +static int read_event(int inotify_fd, int expected_event, int expected_wd) +{ + struct inotify_event event; + ssize_t len =3D 0; + + len =3D read(inotify_fd, &event, sizeof(event)); + if (len < (ssize_t)sizeof(event)) + return -1; + + if (event.mask !=3D expected_event || event.wd !=3D expected_wd) { + fprintf(stderr, + "event does not match expected values: mask %d (expected %d) wd %d (exp= ected %d)\n", + event.mask, expected_event, event.wd, expected_wd); + return -1; + } + + return 0; +} + +static int test_memcg_inotify_delete_file(const char *root) +{ + int ret =3D KSFT_FAIL; + char *memcg =3D NULL; + int fd, wd; + + memcg =3D cg_name(root, "memcg_test_0"); + + if (!memcg) + goto cleanup; + + if (cg_create(memcg)) + goto cleanup; + + fd =3D inotify_init1(0); + if (fd =3D=3D -1) + goto cleanup; + + wd =3D inotify_add_watch(fd, cg_control(memcg, "memory.events"), IN_DELET= E_SELF); + if (wd =3D=3D -1) + goto cleanup; + + if (cg_destroy(memcg)) + goto cleanup; + free(memcg); + memcg =3D NULL; + + if (read_event(fd, IN_DELETE_SELF, wd)) + goto cleanup; + + if (read_event(fd, IN_IGNORED, wd)) + goto cleanup; + + ret =3D KSFT_PASS; + +cleanup: + if (fd >=3D 0) + close(fd); + if (memcg) + cg_destroy(memcg); + free(memcg); + + return ret; +} + +static int test_memcg_inotify_delete_dir(const char *root) +{ + int ret =3D KSFT_FAIL; + char *memcg =3D NULL; + int fd, wd; + + memcg =3D cg_name(root, "memcg_test_0"); + + if (!memcg) + goto cleanup; + + if (cg_create(memcg)) + goto cleanup; + + fd =3D inotify_init1(0); + if (fd =3D=3D -1) + goto cleanup; + + wd =3D inotify_add_watch(fd, memcg, IN_DELETE_SELF); + if (wd =3D=3D -1) + goto cleanup; + + if (cg_destroy(memcg)) + goto cleanup; + free(memcg); + memcg =3D NULL; + + if (read_event(fd, IN_DELETE_SELF, wd)) + goto cleanup; + + if (read_event(fd, IN_IGNORED, wd)) + goto cleanup; + + ret =3D KSFT_PASS; + +cleanup: + if (fd >=3D 0) + close(fd); + if (memcg) + cg_destroy(memcg); + free(memcg); + + return ret; +} + #define T(x) { x, #x } struct memcg_test { int (*fn)(const char *root); @@ -1644,6 +1754,8 @@ struct memcg_test { T(test_memcg_oom_group_leaf_events), T(test_memcg_oom_group_parent_events), T(test_memcg_oom_group_score_events), + T(test_memcg_inotify_delete_file), + T(test_memcg_inotify_delete_dir), }; #undef T =20 --=20 2.53.0.414.gf7e9f6c205-goog