Skip to contentSkip to conversation

debugfs: improve DEFINE_DEBUGFS_ATTRIBUTE for !CONFIG_DEBUGFS_FS

PATCH Applied Arnd Bergmann 5 participants 9 messages Oct 10, 2016 – Oct 21, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 debugfs: improve DEFINE_DEBUGFS_ATTRIBUTE for !CONFIG_DEBUGFS_FS

The slp_s0_residency_usec debugfs file currently uses DEFINE_DEBUGFS_ATTRIBUTE(), but that macro cannot really be used to define files outside of the debugfs code, as it has no reference to the get/set functions if CONFIG_DEBUGFS_FS is not defined:

drivers/platform/x86/intel_pmc_core.c:80:12: error: ‘pmc_core_dev_state_get’ defined but not used [-Werror=unused-function]

This fixes the macro to always contain the reference, and instead rely on the stubbed-out debugfs_create_file to not actually refer to its arguments so the compiler can still drop the reference. This works because the attribute definition is always 'static', and the dead-code removal silently drops all static symbols that are not used.

Fixes c64688081490 ("debugfs: add support for self-protecting attribute file fops")
Fixes df2294fb6428 ("intel_pmc_core: Convert to DEFINE_DEBUGFS_ATTRIBUTE")
---
 include/linux/debugfs.h | 43 ++++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 23 deletions(-)
include/linux/debugfs.h +20 -23
index 4d3f0d1aec73..e94f5f8dced3 100644
@@ -62,6 +62,26 @@ static inline const struct file_operations *debugfs_real_fops(struct file *filp)
 	return filp->f_path.dentry->d_fsdata;
 }
 
+ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+			size_t len, loff_t *ppos);
+ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+			size_t len, loff_t *ppos);
+
+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+static int __fops ## _open(struct inode *inode, struct file *file)	\
+{									\
+	__simple_attr_check_format(__fmt, 0ull);			\
+	return simple_attr_open(inode, file, __get, __set, __fmt);	\
+}									\
+static const struct file_operations __fops = {				\
+	.owner	 = THIS_MODULE,						\
+	.open	 = __fops ## _open,					\
+	.release = simple_attr_release,					\
+	.read	 = debugfs_attr_read,					\
+	.write	 = debugfs_attr_write,					\
+	.llseek  = generic_file_llseek,					\
+}
+
 #if defined(CONFIG_DEBUG_FS)
 
 struct dentry *debugfs_create_file(const char *name, umode_t mode,
@@ -94,26 +114,6 @@ int debugfs_use_file_start(const struct dentry *dentry, int *srcu_idx)
 
 void debugfs_use_file_finish(int srcu_idx) __releases(&debugfs_srcu);
 
-ssize_t debugfs_attr_read(struct file *file, char __user *buf,
-			size_t len, loff_t *ppos);
-ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
-			size_t len, loff_t *ppos);
-
-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
-static int __fops ## _open(struct inode *inode, struct file *file)	\
-{									\
-	__simple_attr_check_format(__fmt, 0ull);			\
-	return simple_attr_open(inode, file, __get, __set, __fmt);	\
-}									\
-static const struct file_operations __fops = {				\
-	.owner	 = THIS_MODULE,					\
-	.open	 = __fops ## _open,					\
-	.release = simple_attr_release,				\
-	.read	 = debugfs_attr_read,					\
-	.write	 = debugfs_attr_write,					\
-	.llseek  = generic_file_llseek,				\
-}
-
 struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, const char *new_name);
 
@@ -233,9 +233,6 @@ static inline void debugfs_use_file_finish(int srcu_idx)
 	__releases(&debugfs_srcu)
 { }
 
-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)	\
-	static const struct file_operations __fops = { 0 }
-
 static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, char *new_name)
 {
Signature · 1 line
2.9.0
#1 lore raw

PATCH 2/2 intel_pmc_core: avoid boot time warning for !CONFIG_DEBUGFS_FS

While looking at a patch that introduced a compile-time warning "‘pmc_core_dev_state_get’ defined but not used" (I sent a patch for debugfs to fix it), I noticed that the same patch caused it in intel_pmc_core also introduced a bogus run-time warning:
"PMC Core: debugfs register failed".

The problem is the IS_ERR_OR_NULL() check that as usual gets things wrong: when CONFIG_DEBUGFS_FS is disabled, debugfs_create_dir() fails with an error code, and we don't need to warn about it, unlike the case in which it returns NULL.

This reverts the driver to the previous state of not warning about CONFIG_DEBUGFS_FS being disabled. I chose not to restore the driver to making a runtime error in debugfs fatal in pmc_core_probe().

Fixes df2294fb6428 ("intel_pmc_core: Convert to DEFINE_DEBUGFS_ATTRIBUTE")
---
 drivers/platform/x86/intel_pmc_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/intel_pmc_core.c +1 -1
index 520b58a04daa..e8b1b836ca2d 100644
@@ -100,7 +100,7 @@ static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
 	struct dentry *dir, *file;
 
 	dir = debugfs_create_dir("pmc_core", NULL);
-	if (IS_ERR_OR_NULL(dir))
+	if (!dir)
 		return -ENOMEM;
 
 	pmcdev->dbgfs_dir = dir;
Signature · 1 line
2.9.0
#2 lore raw

Re: [PATCH 2/2] intel_pmc_core: avoid boot time warning for !CONFIG_DEBUGFS_FS

Quoted 28 lines · Arnd Bergmann

While looking at a patch that introduced a compile-time warning "‘pmc_core_dev_state_get’ defined but not used" (I sent a patch for debugfs to fix it), I noticed that the same patch caused it in intel_pmc_core also introduced a bogus run-time warning:
"PMC Core: debugfs register failed".

The problem is the IS_ERR_OR_NULL() check that as usual gets things wrong: when CONFIG_DEBUGFS_FS is disabled, debugfs_create_dir() fails with an error code, and we don't need to warn about it, unlike the case in which it returns NULL.

This reverts the driver to the previous state of not warning about CONFIG_DEBUGFS_FS being disabled. I chose not to restore the driver to making a runtime error in debugfs fatal in pmc_core_probe().

Fixes df2294fb6428 ("intel_pmc_core: Convert to DEFINE_DEBUGFS_ATTRIBUTE")
---
 drivers/platform/x86/intel_pmc_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/intel_pmc_core.c +0 -0
index 520b58a04daa..e8b1b836ca2d 100644

drivers/platform/x86/intel_pmc_core.c static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev) · line 104

Quoted 6 lines
drivers/platform/x86/intel_pmc_core.c +1 -1
@@ -100,7 +100,7 @@ static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
 	struct dentry *dir, *file;
 
 	dir = debugfs_create_dir("pmc_core", NULL);
-	if (IS_ERR_OR_NULL(dir))
+	if (!dir)
 		return -ENOMEM;

Hah, no, you shouldn't ever care about any return value being "wrong" from debugfs, the code should just continue on as normal.

And yes, you are correct, the IS_ERR_OR_NULL() is totally wrong.

thanks,

greg k-h

Applied
#3 lore raw

Re: [PATCH 2/2] intel_pmc_core: avoid boot time warning for !CONFIG_DEBUGFS_FS

Quoted 39 lines · Greg Kroah-Hartman
Quoted 28 lines · Arnd Bergmann

While looking at a patch that introduced a compile-time warning "‘pmc_core_dev_state_get’ defined but not used" (I sent a patch for debugfs to fix it), I noticed that the same patch caused it in intel_pmc_core also introduced a bogus run-time warning:
"PMC Core: debugfs register failed".

The problem is the IS_ERR_OR_NULL() check that as usual gets things wrong: when CONFIG_DEBUGFS_FS is disabled, debugfs_create_dir() fails with an error code, and we don't need to warn about it, unlike the case in which it returns NULL.

This reverts the driver to the previous state of not warning about CONFIG_DEBUGFS_FS being disabled. I chose not to restore the driver to making a runtime error in debugfs fatal in pmc_core_probe().

Fixes df2294fb6428 ("intel_pmc_core: Convert to DEFINE_DEBUGFS_ATTRIBUTE")
---
 drivers/platform/x86/intel_pmc_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/intel_pmc_core.c +0 -0
index 520b58a04daa..e8b1b836ca2d 100644

drivers/platform/x86/intel_pmc_core.c static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev) · line 104

Quoted 6 lines
drivers/platform/x86/intel_pmc_core.c +1 -1
@@ -100,7 +100,7 @@ static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
 	struct dentry *dir, *file;
 
 	dir = debugfs_create_dir("pmc_core", NULL);
-	if (IS_ERR_OR_NULL(dir))
+	if (!dir)
 		return -ENOMEM;

Hah, no, you shouldn't ever care about any return value being "wrong" from debugfs, the code should just continue on as normal.

Quoted 6 lines

And yes, you are correct, the IS_ERR_OR_NULL() is totally wrong.

thanks,

greg k-h

Thanks Arnd and Greg, appreciate the catch and the fix.

Applied.

Signature · 2 lines
Darren Hart
Intel Open Source Technology Center
#4 lore raw
In reply to Arnd Bergmann

Hi Arnd,

thanks for this (and sorry for the late reply)!

Quoted 36 lines · Arnd Bergmann

The slp_s0_residency_usec debugfs file currently uses DEFINE_DEBUGFS_ATTRIBUTE(), but that macro cannot really be used to define files outside of the debugfs code, as it has no reference to the get/set functions if CONFIG_DEBUGFS_FS is not defined:

drivers/platform/x86/intel_pmc_core.c:80:12: error: ‘pmc_core_dev_state_get’ defined but not used [-Werror=unused-function]

This fixes the macro to always contain the reference, and instead rely on the stubbed-out debugfs_create_file to not actually refer to its arguments so the compiler can still drop the reference. This works because the attribute definition is always 'static', and the dead-code removal silently drops all static symbols that are not used.

Fixes c64688081490 ("debugfs: add support for self-protecting attribute file fops")
Fixes df2294fb6428 ("intel_pmc_core: Convert to DEFINE_DEBUGFS_ATTRIBUTE")
---
 include/linux/debugfs.h | 43 ++++++++++++++++++++-----------------------
 1 file changed, 20 insertions(+), 23 deletions(-)
include/linux/debugfs.h +7 -0
index 4d3f0d1aec73..e94f5f8dced3 100644
@@ -62,6 +62,26 @@ static inline const struct file_operations *debugfs_real_fops(struct file *filp)
 	return filp->f_path.dentry->d_fsdata;
 }
 
+ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+			size_t len, loff_t *ppos);
+ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+			size_t len, loff_t *ppos);
+
+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+static int __fops ## _open(struct inode *inode, struct file *file)	\

include/linux/debugfs.h static inline const struct file_operations *debugfs_real_fops(struct file *filp) · line 81

Quoted 10 lines
include/linux/debugfs.h +10 -0
+{									\
+	__simple_attr_check_format(__fmt, 0ull);			\
+	return simple_attr_open(inode, file, __get, __set, __fmt);	\
+}									\
+static const struct file_operations __fops = {				\
+	.owner	 = THIS_MODULE,						\
+	.open	 = __fops ## _open,					\
+	.release = simple_attr_release,					\
+	.read	 = debugfs_attr_read,					\
+	.write	 = debugfs_attr_write,					\

This depends on GCC dead code elimination to always work for this situation, otherwise we'd get undefined references to debugfs_attr_read/write(), right?

In order to avoid having to test your patch against all those older versions of GCC, can we have a safety net here and define some dummy debugfs_attr_read/write() for the !CONFIG_DEBUGFS case?

If nothing else, it would IMHO make the !CONFIG_DEBUGFS case more understandable because one had not to figure out that this actually relies on dead code elimination to work.

Thanks,

Nicolai

#5 lore raw
Quoted 14 lines · CEST Nicolai Stange
Quoted 14 lines
include/linux/debugfs.h +13 -0
+ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+                     size_t len, loff_t *ppos);
+ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+                     size_t len, loff_t *ppos);
+
+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)                \
+static int __fops ## _open(struct inode *inode, struct file *file)   \
+{                                                                    \
+     __simple_attr_check_format(__fmt, 0ull);                        \
+     return simple_attr_open(inode, file, __get, __set, __fmt);      \
+}                                                                    \
+static const struct file_operations __fops = {                               \
+     .owner   = THIS_MODULE,                                         \
Quoted 8 lines

include/linux/debugfs.h static inline const struct file_operations *debugfs_real_fops(struct file *filp) · line 81

Quoted 4 lines
include/linux/debugfs.h +4 -0
+     .open    = __fops ## _open,                                     \
+     .release = simple_attr_release,                                 \
+     .read    = debugfs_attr_read,                                   \
+     .write   = debugfs_attr_write,                                  \

This depends on GCC dead code elimination to always work for this situation, otherwise we'd get undefined references to debugfs_attr_read/write(), right?

Correct.

Quoted 3 lines

In order to avoid having to test your patch against all those older versions of GCC, can we have a safety net here and define some dummy debugfs_attr_read/write() for the !CONFIG_DEBUGFS case?

The question of dead-code elimination in older gcc versions comes up occasionally, and I think all versions that are able to build the kernel these days get this right all the time, otherwise any code using IS_ENABLED() helpers to control the calling of external interfaces would be broken.

We could probably use that macro here if you think that's better and do:

static const struct file_operations __fops = {
.owner = THIS_MODULE,
.open = IS_ENABLED(CONFIG_DEBUGFS_FS) ? __fops ## _open : NULL,
...

Quoted 3 lines

If nothing else, it would IMHO make the !CONFIG_DEBUGFS case more understandable because one had not to figure out that this actually relies on dead code elimination to work.

Sure, that's fine. Can you do the new version of that patch with the change then?

Arnd

#6 lore raw
Quoted 44 lines · Arnd Bergmann
Quoted 14 lines · CEST Nicolai Stange
Quoted 14 lines
include/linux/debugfs.h +13 -0
+ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+                     size_t len, loff_t *ppos);
+ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+                     size_t len, loff_t *ppos);
+
+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)                \
+static int __fops ## _open(struct inode *inode, struct file *file)   \
+{                                                                    \
+     __simple_attr_check_format(__fmt, 0ull);                        \
+     return simple_attr_open(inode, file, __get, __set, __fmt);      \
+}                                                                    \
+static const struct file_operations __fops = {                               \
+     .owner   = THIS_MODULE,                                         \
Quoted 8 lines

include/linux/debugfs.h static inline const struct file_operations *debugfs_real_fops(struct file *filp) · line 81

Quoted 4 lines
include/linux/debugfs.h +4 -0
+     .open    = __fops ## _open,                                     \
+     .release = simple_attr_release,                                 \
+     .read    = debugfs_attr_read,                                   \
+     .write   = debugfs_attr_write,                                  \

This depends on GCC dead code elimination to always work for this situation, otherwise we'd get undefined references to debugfs_attr_read/write(), right?

Correct.

Quoted 3 lines

In order to avoid having to test your patch against all those older versions of GCC, can we have a safety net here and define some dummy debugfs_attr_read/write() for the !CONFIG_DEBUGFS case?

The question of dead-code elimination in older gcc versions comes up occasionally, and I think all versions that are able to build the kernel these days get this right all the time, otherwise any code using IS_ENABLED() helpers to control the calling of external interfaces would be broken.

We could probably use that macro here if you think that's better and do:

static const struct file_operations __fops = {
.owner = THIS_MODULE,
.open = IS_ENABLED(CONFIG_DEBUGFS_FS) ? __fops ## _open : NULL,
...

Quoted 6 lines
Quoted 3 lines

If nothing else, it would IMHO make the !CONFIG_DEBUGFS case more understandable because one had not to figure out that this actually relies on dead code elimination to work.

Sure, that's fine. Can you do the new version of that patch with the change then?

I'd be happy to (won't be able to do this before tomorrow though).

Thanks,

Nicolai

#7 lore raw

PATCH v2 1/1 debugfs: improve DEFINE_DEBUGFS_ATTRIBUTE for !CONFIG_DEBUG_FS

In reply to Arnd Bergmann

From: Arnd Bergmann <[email protected]>

The slp_s0_residency_usec debugfs file currently uses DEFINE_DEBUGFS_ATTRIBUTE(), but that macro cannot really be used to define files outside of the debugfs code, as it has no reference to the get/set functions if CONFIG_DEBUG_FS is not defined:

drivers/platform/x86/intel_pmc_core.c:80:12: error: ‘pmc_core_dev_state_get’ defined but not used [-Werror=unused-function]

This fixes the macro to always contain the reference, and instead rely on the stubbed-out debugfs_create_file to not actually refer to its arguments so the compiler can still drop the reference. This works because the attribute definition is always 'static', and the dead-code removal silently drops all static symbols that are not used.

Fixes c64688081490 ("debugfs: add support for self-protecting attribute file fops")
Fixes df2294fb6428 ("intel_pmc_core: Convert to DEFINE_DEBUGFS_ATTRIBUTE")

[[email protected]: Add dummy implementations of debugfs_attr_read() and
debugfs_attr_write() in order to protect against possibly broken dead code elimination and to improve readability.
Correct CONFIG_DEBUGFS_FS -> CONFIG_DEBUG_FS typo in changelog.]

---
Compile-tested on top of next-20161020 with gcc-4.9.0 and gcc-6.2.1, CONFIG_INTEL_PMC_CORE=y and both, CONFIG_DEBUG_FS=n and CONFIG_DEBUG_FS=y.

I verified that there isn't anything in the intel_pmc_core.o that shouldn'tbe there with CONFIG_DEBUG_FS=n.

Changes to v1:
- Add dummy implementations of debugfs_attr_read()/debugfs_attr_write() for the CONFIG_DEBUG_FS=n case.
- Fix a typo in the changelog.

 include/linux/debugfs.h | 44 +++++++++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 17 deletions(-)
include/linux/debugfs.h +27 -17
index 4d3f0d1..1b413a9 100644
@@ -62,6 +62,21 @@ static inline const struct file_operations *debugfs_real_fops(struct file *filp)
 	return filp->f_path.dentry->d_fsdata;
 }
 
+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+static int __fops ## _open(struct inode *inode, struct file *file)	\
+{									\
+	__simple_attr_check_format(__fmt, 0ull);			\
+	return simple_attr_open(inode, file, __get, __set, __fmt);	\
+}									\
+static const struct file_operations __fops = {				\
+	.owner	 = THIS_MODULE,						\
+	.open	 = __fops ## _open,					\
+	.release = simple_attr_release,					\
+	.read	 = debugfs_attr_read,					\
+	.write	 = debugfs_attr_write,					\
+	.llseek  = generic_file_llseek,					\
+}
+
 #if defined(CONFIG_DEBUG_FS)
 
 struct dentry *debugfs_create_file(const char *name, umode_t mode,
@@ -99,21 +114,6 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
 ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
 			size_t len, loff_t *ppos);
 
-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
-static int __fops ## _open(struct inode *inode, struct file *file)	\
-{									\
-	__simple_attr_check_format(__fmt, 0ull);			\
-	return simple_attr_open(inode, file, __get, __set, __fmt);	\
-}									\
-static const struct file_operations __fops = {				\
-	.owner	 = THIS_MODULE,					\
-	.open	 = __fops ## _open,					\
-	.release = simple_attr_release,				\
-	.read	 = debugfs_attr_read,					\
-	.write	 = debugfs_attr_write,					\
-	.llseek  = generic_file_llseek,				\
-}
-
 struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, const char *new_name);
 
@@ -233,8 +233,18 @@ static inline void debugfs_use_file_finish(int srcu_idx)
 	__releases(&debugfs_srcu)
 { }
 
-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)	\
-	static const struct file_operations __fops = { 0 }
+static inline ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+					size_t len, loff_t *ppos)
+{
+	return -ENODEV;
+}
+
+static inline ssize_t debugfs_attr_write(struct file *file,
+					const char __user *buf,
+					size_t len, loff_t *ppos)
+{
+	return -ENODEV;
+}
 
 static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, char *new_name)
Signature · 1 line
2.10.1
Reviewed-by on v2 1/1
#8 lore raw

Re: [PATCH v2] debugfs: improve DEFINE_DEBUGFS_ATTRIBUTE for !CONFIG_DEBUG_FS

Quoted 11 lines · Nicolai Stange

From: Arnd Bergmann <[email protected]>

The slp_s0_residency_usec debugfs file currently uses DEFINE_DEBUGFS_ATTRIBUTE(), but that macro cannot really be used to define files outside of the debugfs code, as it has no reference to the get/set functions if CONFIG_DEBUG_FS is not defined:

drivers/platform/x86/intel_pmc_core.c:80:12: error:
‘pmc_core_dev_state_get’ defined but not used [-Werror=unused- function]

Quoted 6 lines

This fixes the macro to always contain the reference, and instead rely on the stubbed-out debugfs_create_file to not actually refer to its arguments so the compiler can still drop the reference. This works because the attribute definition is always 'static', and the dead-code removal silently drops all static symbols that are not used.

Thanks for the fix! Looks good to me.

Quoted 134 lines
Fixes c64688081490 ("debugfs: add support for self-protecting

attribute file fops")

Fixes df2294fb6428 ("intel_pmc_core: Convert to

DEFINE_DEBUGFS_ATTRIBUTE")

[[email protected]: Add dummy implementations of debugfs_attr_read() and
  debugfs_attr_write() in order to protect against possibly broken dead
  code elimination and to improve readability.
  Correct CONFIG_DEBUGFS_FS -> CONFIG_DEBUG_FS typo in changelog.]

---
Compile-tested on top of next-20161020 with gcc-4.9.0 and gcc-6.2.1, CONFIG_INTEL_PMC_CORE=y and both, CONFIG_DEBUG_FS=n and CONFIG_DEBUG_FS=y.

I verified that there isn't anything in the intel_pmc_core.o that shouldn'tbe there with CONFIG_DEBUG_FS=n.

Changes to v1:
 - Add dummy implementations of
debugfs_attr_read()/debugfs_attr_write()
   for the CONFIG_DEBUG_FS=n case.
 - Fix a typo in the changelog.

 include/linux/debugfs.h | 44 +++++++++++++++++++++++++++-------------
----

 1 file changed, 27 insertions(+), 17 deletions(-)
include/linux/debugfs.h +0 -0
index 4d3f0d1..1b413a9 100644
@@ -62,6 +62,21 @@ static inline const struct file_operations
 *debugfs_real_fops(struct file *filp)
  	return filp->f_path.dentry->d_fsdata;
  }


+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
+static int __fops ## _open(struct inode *inode, struct file *file) \
+{
\

include/linux/debugfs.h +1 -0
+	__simple_attr_check_format(__fmt, 0ull);			

\

include/linux/debugfs.h +1 -0
+	return simple_attr_open(inode, file, __get, __set, __fmt);	

\
+}
\

+static const struct file_operations __fops = {			
	\
include/linux/debugfs.h +1 -0
+	.owner	 = THIS_MODULE,					
	\
include/linux/debugfs.h +1 -0
+	.open	 = __fops ## _open,				
	\
include/linux/debugfs.h +1 -0
+	.release = simple_attr_release,				
	\
include/linux/debugfs.h +1 -0
+	.read	 = debugfs_attr_read,				
	\
include/linux/debugfs.h +1 -0
+	.write	 = debugfs_attr_write,				
	\
include/linux/debugfs.h +1 -0
+	.llseek  = generic_file_llseek,				
	\
include/linux/debugfs.h +2 -0
+}
+

 #if defined(CONFIG_DEBUG_FS)

 struct dentry *debugfs_create_file(const char *name, umode_t mode,

include/linux/debugfs.h +0 -0
@@ -99,21 +114,6 @@ ssize_t debugfs_attr_read(struct file *file, char
 __user *buf,
  ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
  			size_t len, loff_t *ppos);


-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
-static int __fops ## _open(struct inode *inode, struct file *file) \
-{
\

include/linux/debugfs.h +0 -1
-	__simple_attr_check_format(__fmt, 0ull);			

\

include/linux/debugfs.h +0 -1
-	return simple_attr_open(inode, file, __get, __set, __fmt);	

\
-}
\

-static const struct file_operations __fops = {			
	\
include/linux/debugfs.h +0 -1
-	.owner	 = THIS_MODULE,					

\

include/linux/debugfs.h +0 -1
-	.open	 = __fops ## _open,				
	\
include/linux/debugfs.h +0 -1
-	.release = simple_attr_release,				

\

include/linux/debugfs.h +0 -1
-	.read	 = debugfs_attr_read,				
	\
include/linux/debugfs.h +0 -1
-	.write	 = debugfs_attr_write,				
	\
include/linux/debugfs.h +0 -1
-	.llseek  = generic_file_llseek,				

\

include/linux/debugfs.h +0 -2
-}
-

 struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, const char *new_name);

include/linux/debugfs.h +0 -0
@@ -233,8 +233,18 @@ static inline void debugfs_use_file_finish(int
 srcu_idx)
  	__releases(&debugfs_srcu)
  { }


-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \

include/linux/debugfs.h +1 -1
-	static const struct file_operations __fops = { 0 }
+static inline ssize_t debugfs_attr_read(struct file *file, char

__user *buf,

include/linux/debugfs.h +11 -0
+					size_t len, loff_t *ppos)
+{
+	return -ENODEV;
+}
+
+static inline ssize_t debugfs_attr_write(struct file *file,
+					const char __user *buf,
+					size_t len, loff_t *ppos)
+{
+	return -ENODEV;
+}


 static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, char *new_name)

Signature · 2 lines
Andy Shevchenko <[email protected]>
Intel Finland Oy