2023-02-02 03:32:33

by Longlong Xia

[permalink] [raw]
Subject: [PATCH -next 2/3] devtmpfs: add debug info to handle()

The devtmpfs_*_node() are used to mount/unmount devices to /dev, but their
callers don't check their return value, so we don't know the reason for
the failure. Let's add some debug info in handle() to help users know
why failed.

Signed-off-by: Longlong Xia <[email protected]>
---
drivers/base/devtmpfs.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index ae72d4ba8547..77ca64f708ce 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -389,10 +389,18 @@ static __initdata DECLARE_COMPLETION(setup_done);
static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
struct device *dev)
{
+ int ret;
+
if (mode)
- return handle_create(name, mode, uid, gid, dev);
+ ret = handle_create(name, mode, uid, gid, dev);
else
- return handle_remove(name, dev);
+ ret = handle_remove(name, dev);
+
+ if (ret)
+ pr_err_ratelimited("failed to %s %s, ret = %d\n",
+ mode ? "create" : "remove", name, ret);
+
+ return ret;
}

static void __noreturn devtmpfs_work_loop(void)
--
2.25.1



2023-02-02 08:30:43

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH -next 2/3] devtmpfs: add debug info to handle()

On Thu, Feb 02, 2023 at 03:32:02AM +0000, Longlong Xia wrote:
> The devtmpfs_*_node() are used to mount/unmount devices to /dev, but their
> callers don't check their return value, so we don't know the reason for
> the failure. Let's add some debug info in handle() to help users know
> why failed.
>
> Signed-off-by: Longlong Xia <[email protected]>
> ---
> drivers/base/devtmpfs.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
> index ae72d4ba8547..77ca64f708ce 100644
> --- a/drivers/base/devtmpfs.c
> +++ b/drivers/base/devtmpfs.c
> @@ -389,10 +389,18 @@ static __initdata DECLARE_COMPLETION(setup_done);
> static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
> struct device *dev)
> {
> + int ret;
> +
> if (mode)
> - return handle_create(name, mode, uid, gid, dev);
> + ret = handle_create(name, mode, uid, gid, dev);
> else
> - return handle_remove(name, dev);
> + ret = handle_remove(name, dev);
> +
> + if (ret)
> + pr_err_ratelimited("failed to %s %s, ret = %d\n",
> + mode ? "create" : "remove", name, ret);

As you have a struct device * here, why not use dev_err() instead?

And why rate limited? What is going to cause this to be spammed with
lots and lots of failures? What were you doing that caused a failure
here, how is it triggered?

thanks,

greg k-h

2023-02-10 07:35:07

by Longlong Xia

[permalink] [raw]
Subject: Re: [PATCH -next 0/3] cleanup of devtmpfs_*_node()

The test steps:
1. Set the SElinux label of /dev to user_home_t
2. modprobe zram num_devices=1000

The above test result is that there is no zram device was found in the
/dev. And don't see any errors printed in jouranls/dmesg. Of course,
it is rare to create 1000 zram devices, use dev_err may be better.

Longlong Xia (3):
devtmpfs: add debug info to handle()
driver core: add error handling for devtmpfs_create_node()
devtmpfs: remove return value of devtmpfs_delete_node()

drivers/base/base.h | 4 ++--
drivers/base/core.c | 8 ++++++--
drivers/base/devtmpfs.c | 20 ++++++++++++++------
3 files changed, 22 insertions(+), 10 deletions(-)

Best Regards,
Longlong Xia

2023-02-10 07:35:10

by Longlong Xia

[permalink] [raw]
Subject: [PATCH -next 2/3] driver core: add error handling for devtmpfs_create_node()

In some cases, devtmpfs_create_node() can return error value.
So, make use of it.

Signed-off-by: Longlong Xia <[email protected]>
---
drivers/base/core.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 7dab705f2937..aaa3088e5456 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3405,7 +3405,9 @@ int device_add(struct device *dev)
if (error)
goto SysEntryError;

- devtmpfs_create_node(dev);
+ error = devtmpfs_create_node(dev);
+ if (error)
+ goto DevtmpfsError;
}

/* Notify clients of device addition. This call must come
@@ -3461,6 +3463,8 @@ int device_add(struct device *dev)
done:
put_device(dev);
return error;
+ DevtmpfsError:
+ device_remove_sys_dev_entry(dev);
SysEntryError:
if (MAJOR(dev->devt))
device_remove_file(dev, &dev_attr_dev);
--
2.25.1


2023-02-10 07:35:12

by Longlong Xia

[permalink] [raw]
Subject: [PATCH -next 3/3] devtmpfs: remove return value of devtmpfs_delete_node()

The only caller of device_del() does not check the return value. And
there's nothing we can do when cleaning things up on a remove path.
Let's make it a void function.

Signed-off-by: Longlong Xia <[email protected]>
---
drivers/base/base.h | 4 ++--
drivers/base/devtmpfs.c | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 0e806f641079..f7996bf8d28b 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -201,10 +201,10 @@ void device_pm_move_to_tail(struct device *dev);

#ifdef CONFIG_DEVTMPFS
int devtmpfs_create_node(struct device *dev);
-int devtmpfs_delete_node(struct device *dev);
+void devtmpfs_delete_node(struct device *dev);
#else
static inline int devtmpfs_create_node(struct device *dev) { return 0; }
-static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
+static inline void devtmpfs_delete_node(struct device *dev) { return 0; }
#endif

void software_node_notify(struct device *dev);
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 7789b7be4ee5..e5c4d3e98ec9 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -147,22 +147,22 @@ int devtmpfs_create_node(struct device *dev)
return devtmpfs_submit_req(&req, tmp);
}

-int devtmpfs_delete_node(struct device *dev)
+void devtmpfs_delete_node(struct device *dev)
{
const char *tmp = NULL;
struct req req;

if (!thread)
- return 0;
+ return;

req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp);
if (!req.name)
- return -ENOMEM;
+ return;

req.mode = 0;
req.dev = dev;

- return devtmpfs_submit_req(&req, tmp);
+ devtmpfs_submit_req(&req, tmp);
}

static int dev_mkdir(const char *name, umode_t mode)
--
2.25.1


2023-02-10 08:17:23

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH -next 0/3] cleanup of devtmpfs_*_node()

On Fri, Feb 10, 2023 at 07:33:06AM +0000, Longlong Xia wrote:
> The test steps:
> 1. Set the SElinux label of /dev to user_home_t
> 2. modprobe zram num_devices=1000
>
> The above test result is that there is no zram device was found in the
> /dev. And don't see any errors printed in jouranls/dmesg. Of course,
> it is rare to create 1000 zram devices, use dev_err may be better.
>
> Longlong Xia (3):
> devtmpfs: add debug info to handle()
> driver core: add error handling for devtmpfs_create_node()
> devtmpfs: remove return value of devtmpfs_delete_node()
>
> drivers/base/base.h | 4 ++--
> drivers/base/core.c | 8 ++++++--
> drivers/base/devtmpfs.c | 20 ++++++++++++++------
> 3 files changed, 22 insertions(+), 10 deletions(-)
>
> Best Regards,
> Longlong Xia

This is a v2 series, please mark them as such, saying what changed from
the previous submission. Otherwise our tools get totally confused and I
can not apply them.

Also just send it as a new thread, don't reply to the old one, there's
no need for making it that complex.

thanks,

greg k-h