All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] CONFIG_VFS_DEBUG at last
@ 2025-02-06 17:03 Mateusz Guzik
  2025-02-06 17:03 ` [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG Mateusz Guzik
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Mateusz Guzik @ 2025-02-06 17:03 UTC (permalink / raw)
  To: brauner; +Cc: viro, jack, linux-kernel, linux-fsdevel, Mateusz Guzik

This adds a super basic version just to get the mechanism going and
adds sample usage.

The macro set is incomplete (e.g., lack of locking macros) and
dump_inode routine fails to dump any state yet, to be implemented(tm).

I think despite the primitive state this is complete enough to start
sprinkling warns as necessary.

v2:
- correct may_open
- fixed up condition reporting:
before:
VFS_WARN_ON_INODE(__builtin_choose_expr((sizeof(int) ==
sizeof(*(8 ? ((void *)((long)(__builtin_strlen(link)) * 0l)) : (int
*)8))), __builtin_strlen(link), __fortify_strlen(link)) != linklen)
failed for inode ff32f7c350c8aec8
after:
VFS_WARN_ON_INODE(strlen(link) != linklen) failed for inode ff2b81ddca13f338

Mateusz Guzik (3):
  vfs: add initial support for CONFIG_VFS_DEBUG
  vfs: catch invalid modes in may_open()
  vfs: use the new debug macros in inode_set_cached_link()

 fs/namei.c               |  2 ++
 include/linux/fs.h       | 16 +++----------
 include/linux/vfsdebug.h | 49 ++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug        |  9 ++++++++
 4 files changed, 63 insertions(+), 13 deletions(-)
 create mode 100644 include/linux/vfsdebug.h

-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG
  2025-02-06 17:03 [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik
@ 2025-02-06 17:03 ` Mateusz Guzik
  2025-02-07 13:15   ` Jan Kara
  2025-02-06 17:03 ` [PATCH v2 2/3] vfs: catch invalid modes in may_open() Mateusz Guzik
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Mateusz Guzik @ 2025-02-06 17:03 UTC (permalink / raw)
  To: brauner; +Cc: viro, jack, linux-kernel, linux-fsdevel, Mateusz Guzik

Small collection of macros taken from mmdebug.h

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
---
 include/linux/fs.h       |  1 +
 include/linux/vfsdebug.h | 49 ++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug        |  9 ++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 include/linux/vfsdebug.h

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1437a3323731..034745af9702 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2,6 +2,7 @@
 #ifndef _LINUX_FS_H
 #define _LINUX_FS_H
 
+#include <linux/vfsdebug.h>
 #include <linux/linkage.h>
 #include <linux/wait_bit.h>
 #include <linux/kdev_t.h>
diff --git a/include/linux/vfsdebug.h b/include/linux/vfsdebug.h
new file mode 100644
index 000000000000..c96dc589fa01
--- /dev/null
+++ b/include/linux/vfsdebug.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LINUX_VFS_DEBUG_H
+#define LINUX_VFS_DEBUG_H 1
+
+#include <linux/bug.h>
+
+struct inode;
+
+#ifdef CONFIG_DEBUG_VFS
+/*
+ * TODO: add a proper inode dumping routine, this is a stub to get debug off the ground
+ */
+static inline void dump_inode(struct inode *inode, const char *reason) {
+	pr_crit("%s failed for inode %px", reason, inode);
+}
+#define VFS_BUG_ON(cond) BUG_ON(cond)
+#define VFS_WARN_ON(cond) (void)WARN_ON(cond)
+#define VFS_WARN_ON_ONCE(cond) (void)WARN_ON_ONCE(cond)
+#define VFS_WARN_ONCE(cond, format...) (void)WARN_ONCE(cond, format)
+#define VFS_WARN(cond, format...) (void)WARN(cond, format)
+
+#define VFS_BUG_ON_INODE(cond, inode)		({			\
+	if (unlikely(!!(cond))) {					\
+		dump_inode(inode, "VFS_BUG_ON_INODE(" #cond")");\
+		BUG_ON(1);						\
+	}								\
+})
+
+#define VFS_WARN_ON_INODE(cond, inode)		({			\
+	int __ret_warn = !!(cond);					\
+									\
+	if (unlikely(__ret_warn)) {					\
+		dump_inode(inode, "VFS_WARN_ON_INODE(" #cond")");\
+		WARN_ON(1);						\
+	}								\
+	unlikely(__ret_warn);						\
+})
+#else
+#define VFS_BUG_ON(cond) BUILD_BUG_ON_INVALID(cond)
+#define VFS_WARN_ON(cond) BUILD_BUG_ON_INVALID(cond)
+#define VFS_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond)
+#define VFS_WARN_ONCE(cond, format...) BUILD_BUG_ON_INVALID(cond)
+#define VFS_WARN(cond, format...) BUILD_BUG_ON_INVALID(cond)
+
+#define VFS_BUG_ON_INODE(cond, inode) VFS_BUG_ON(cond)
+#define VFS_WARN_ON_INODE(cond, inode)  BUILD_BUG_ON_INVALID(cond)
+#endif /* CONFIG_DEBUG_VFS */
+
+#endif
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 1af972a92d06..c08ce985c482 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -808,6 +808,15 @@ config ARCH_HAS_DEBUG_VM_PGTABLE
 	  An architecture should select this when it can successfully
 	  build and run DEBUG_VM_PGTABLE.
 
+config DEBUG_VFS
+	bool "Debug VFS"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on extended checks in the VFS layer that may impact
+	  performance.
+
+	  If unsure, say N.
+
 config DEBUG_VM_IRQSOFF
 	def_bool DEBUG_VM && !PREEMPT_RT
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] vfs: catch invalid modes in may_open()
  2025-02-06 17:03 [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik
  2025-02-06 17:03 ` [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG Mateusz Guzik
@ 2025-02-06 17:03 ` Mateusz Guzik
  2025-02-07 13:16   ` Jan Kara
  2025-02-06 17:03 ` [PATCH v2 3/3] vfs: use the new debug macros in inode_set_cached_link() Mateusz Guzik
  2025-02-06 17:33 ` [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik
  3 siblings, 1 reply; 9+ messages in thread
From: Mateusz Guzik @ 2025-02-06 17:03 UTC (permalink / raw)
  To: brauner; +Cc: viro, jack, linux-kernel, linux-fsdevel, Mateusz Guzik

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
---
 fs/namei.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/namei.c b/fs/namei.c
index 3ab9440c5b93..21630a0f8e30 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3415,6 +3415,8 @@ static int may_open(struct mnt_idmap *idmap, const struct path *path,
 		if ((acc_mode & MAY_EXEC) && path_noexec(path))
 			return -EACCES;
 		break;
+	default:
+		VFS_BUG_ON_INODE(1, inode);
 	}
 
 	error = inode_permission(idmap, inode, MAY_OPEN | acc_mode);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] vfs: use the new debug macros in inode_set_cached_link()
  2025-02-06 17:03 [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik
  2025-02-06 17:03 ` [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG Mateusz Guzik
  2025-02-06 17:03 ` [PATCH v2 2/3] vfs: catch invalid modes in may_open() Mateusz Guzik
@ 2025-02-06 17:03 ` Mateusz Guzik
  2025-02-07 13:16   ` Jan Kara
  2025-02-06 17:33 ` [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik
  3 siblings, 1 reply; 9+ messages in thread
From: Mateusz Guzik @ 2025-02-06 17:03 UTC (permalink / raw)
  To: brauner; +Cc: viro, jack, linux-kernel, linux-fsdevel, Mateusz Guzik

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
---
 include/linux/fs.h | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 034745af9702..e71d58c7f59c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -792,19 +792,8 @@ struct inode {
 
 static inline void inode_set_cached_link(struct inode *inode, char *link, int linklen)
 {
-	int testlen;
-
-	/*
-	 * TODO: patch it into a debug-only check if relevant macros show up.
-	 * In the meantime, since we are suffering strlen even on production kernels
-	 * to find the right length, do a fixup if the wrong value got passed.
-	 */
-	testlen = strlen(link);
-	if (testlen != linklen) {
-		WARN_ONCE(1, "bad length passed for symlink [%s] (got %d, expected %d)",
-			  link, linklen, testlen);
-		linklen = testlen;
-	}
+	VFS_WARN_ON_INODE(strlen(link) != linklen, inode);
+	VFS_WARN_ON_INODE(inode->i_opflags & IOP_CACHED_LINK, inode);
 	inode->i_link = link;
 	inode->i_linklen = linklen;
 	inode->i_opflags |= IOP_CACHED_LINK;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/3] CONFIG_VFS_DEBUG at last
  2025-02-06 17:03 [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik
                   ` (2 preceding siblings ...)
  2025-02-06 17:03 ` [PATCH v2 3/3] vfs: use the new debug macros in inode_set_cached_link() Mateusz Guzik
@ 2025-02-06 17:33 ` Mateusz Guzik
  3 siblings, 0 replies; 9+ messages in thread
From: Mateusz Guzik @ 2025-02-06 17:33 UTC (permalink / raw)
  To: brauner; +Cc: viro, jack, linux-kernel, linux-fsdevel

On Thu, Feb 6, 2025 at 6:03 PM Mateusz Guzik <mjguzik@gmail.com> wrote:
>
> This adds a super basic version just to get the mechanism going and
> adds sample usage.
>
> The macro set is incomplete (e.g., lack of locking macros) and
> dump_inode routine fails to dump any state yet, to be implemented(tm).
>
> I think despite the primitive state this is complete enough to start
> sprinkling warns as necessary.
>
> v2:
> - correct may_open
> - fixed up condition reporting:
> before:
> VFS_WARN_ON_INODE(__builtin_choose_expr((sizeof(int) ==
> sizeof(*(8 ? ((void *)((long)(__builtin_strlen(link)) * 0l)) : (int
> *)8))), __builtin_strlen(link), __fortify_strlen(link)) != linklen)
> failed for inode ff32f7c350c8aec8
> after:
> VFS_WARN_ON_INODE(strlen(link) != linklen) failed for inode ff2b81ddca13f338
>

welp, the BSD asserts fire when the condition is false, while Linux
when it is true, so the *text* is backwards. should:
VFS_WARN_ON_INODE(strlen(link) != linklen) encountered for inode
ff2b81ddca13f338

modulo this bit I think this is fine for now

> Mateusz Guzik (3):
>   vfs: add initial support for CONFIG_VFS_DEBUG
>   vfs: catch invalid modes in may_open()
>   vfs: use the new debug macros in inode_set_cached_link()
>
>  fs/namei.c               |  2 ++
>  include/linux/fs.h       | 16 +++----------
>  include/linux/vfsdebug.h | 49 ++++++++++++++++++++++++++++++++++++++++
>  lib/Kconfig.debug        |  9 ++++++++
>  4 files changed, 63 insertions(+), 13 deletions(-)
>  create mode 100644 include/linux/vfsdebug.h
>
> --
> 2.43.0
>


-- 
Mateusz Guzik <mjguzik gmail.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG
  2025-02-06 17:03 ` [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG Mateusz Guzik
@ 2025-02-07 13:15   ` Jan Kara
  2025-02-08 16:10     ` Mateusz Guzik
  0 siblings, 1 reply; 9+ messages in thread
From: Jan Kara @ 2025-02-07 13:15 UTC (permalink / raw)
  To: Mateusz Guzik; +Cc: brauner, viro, jack, linux-kernel, linux-fsdevel

On Thu 06-02-25 18:03:05, Mateusz Guzik wrote:
> Small collection of macros taken from mmdebug.h
> 
> Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>

For start this looks good! Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

BTW:

> +/*
> + * TODO: add a proper inode dumping routine, this is a stub to get debug off the ground
> + */
> +static inline void dump_inode(struct inode *inode, const char *reason) {
> +	pr_crit("%s failed for inode %px", reason, inode);
> +}

fs/inode.c:dump_mapping() already has quite a bit of what you'd want here
so just refactoring dump_mapping() so it can be used in the new asserts
would get you 90% there I'd think.

								Honza

-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] vfs: use the new debug macros in inode_set_cached_link()
  2025-02-06 17:03 ` [PATCH v2 3/3] vfs: use the new debug macros in inode_set_cached_link() Mateusz Guzik
@ 2025-02-07 13:16   ` Jan Kara
  0 siblings, 0 replies; 9+ messages in thread
From: Jan Kara @ 2025-02-07 13:16 UTC (permalink / raw)
  To: Mateusz Guzik; +Cc: brauner, viro, jack, linux-kernel, linux-fsdevel

On Thu 06-02-25 18:03:07, Mateusz Guzik wrote:
> Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  include/linux/fs.h | 15 ++-------------
>  1 file changed, 2 insertions(+), 13 deletions(-)
> 
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 034745af9702..e71d58c7f59c 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -792,19 +792,8 @@ struct inode {
>  
>  static inline void inode_set_cached_link(struct inode *inode, char *link, int linklen)
>  {
> -	int testlen;
> -
> -	/*
> -	 * TODO: patch it into a debug-only check if relevant macros show up.
> -	 * In the meantime, since we are suffering strlen even on production kernels
> -	 * to find the right length, do a fixup if the wrong value got passed.
> -	 */
> -	testlen = strlen(link);
> -	if (testlen != linklen) {
> -		WARN_ONCE(1, "bad length passed for symlink [%s] (got %d, expected %d)",
> -			  link, linklen, testlen);
> -		linklen = testlen;
> -	}
> +	VFS_WARN_ON_INODE(strlen(link) != linklen, inode);
> +	VFS_WARN_ON_INODE(inode->i_opflags & IOP_CACHED_LINK, inode);
>  	inode->i_link = link;
>  	inode->i_linklen = linklen;
>  	inode->i_opflags |= IOP_CACHED_LINK;
> -- 
> 2.43.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] vfs: catch invalid modes in may_open()
  2025-02-06 17:03 ` [PATCH v2 2/3] vfs: catch invalid modes in may_open() Mateusz Guzik
@ 2025-02-07 13:16   ` Jan Kara
  0 siblings, 0 replies; 9+ messages in thread
From: Jan Kara @ 2025-02-07 13:16 UTC (permalink / raw)
  To: Mateusz Guzik; +Cc: brauner, viro, jack, linux-kernel, linux-fsdevel

On Thu 06-02-25 18:03:06, Mateusz Guzik wrote:
> Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza
> ---
>  fs/namei.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index 3ab9440c5b93..21630a0f8e30 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3415,6 +3415,8 @@ static int may_open(struct mnt_idmap *idmap, const struct path *path,
>  		if ((acc_mode & MAY_EXEC) && path_noexec(path))
>  			return -EACCES;
>  		break;
> +	default:
> +		VFS_BUG_ON_INODE(1, inode);
>  	}
>  
>  	error = inode_permission(idmap, inode, MAY_OPEN | acc_mode);
> -- 
> 2.43.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG
  2025-02-07 13:15   ` Jan Kara
@ 2025-02-08 16:10     ` Mateusz Guzik
  0 siblings, 0 replies; 9+ messages in thread
From: Mateusz Guzik @ 2025-02-08 16:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: brauner, viro, linux-kernel, linux-fsdevel

On Fri, Feb 7, 2025 at 2:15 PM Jan Kara <jack@suse.cz> wrote:
>
> On Thu 06-02-25 18:03:05, Mateusz Guzik wrote:
> > Small collection of macros taken from mmdebug.h
> >
> > Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
>
> For start this looks good! Feel free to add:
>
> Reviewed-by: Jan Kara <jack@suse.cz>
>
> BTW:
>
> > +/*
> > + * TODO: add a proper inode dumping routine, this is a stub to get debug off the ground
> > + */
> > +static inline void dump_inode(struct inode *inode, const char *reason) {
> > +     pr_crit("%s failed for inode %px", reason, inode);
> > +}
>
> fs/inode.c:dump_mapping() already has quite a bit of what you'd want here
> so just refactoring dump_mapping() so it can be used in the new asserts
> would get you 90% there I'd think.
>

It looks rather underwhelming.

I was thinking about an equivalent of vn_printf like here:
https://cgit.freebsd.org/src/tree/sys/kern/vfs_subr.c#n4533

Dumps all fields, with spelled out flag names and so on. Also there is
a hook for fs-specific dump routine.

Very useful, but also quite a chore to fully implement and future-proof.
-- 
Mateusz Guzik <mjguzik gmail.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-02-08 16:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-06 17:03 [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik
2025-02-06 17:03 ` [PATCH v2 1/3] vfs: add initial support for CONFIG_VFS_DEBUG Mateusz Guzik
2025-02-07 13:15   ` Jan Kara
2025-02-08 16:10     ` Mateusz Guzik
2025-02-06 17:03 ` [PATCH v2 2/3] vfs: catch invalid modes in may_open() Mateusz Guzik
2025-02-07 13:16   ` Jan Kara
2025-02-06 17:03 ` [PATCH v2 3/3] vfs: use the new debug macros in inode_set_cached_link() Mateusz Guzik
2025-02-07 13:16   ` Jan Kara
2025-02-06 17:33 ` [PATCH v2 0/3] CONFIG_VFS_DEBUG at last Mateusz Guzik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.