Re: git: 80446fc7b5e5 - main - linuxkpi: Move `struct kobject` code to `linux_kobject.c`

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Thu, 14 Dec 2023 00:02:47 UTC
On Wed, 13 Dec 2023, Jean-SébastienPédron wrote:

> The branch main has been updated by dumbbell:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=80446fc7b5e5d22e2bac28bc0474dbe2fec83e43
>
> commit 80446fc7b5e5d22e2bac28bc0474dbe2fec83e43
> Author:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
> AuthorDate: 2023-12-08 17:58:03 +0000
> Commit:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
> CommitDate: 2023-12-13 18:18:46 +0000
>
>    linuxkpi: Move `struct kobject` code to `linux_kobject.c`
>
>    [Why]
>    `linux_compat.c` is already too long. I will need to add `struct kset`
>    in a follow-up commit, so let's move the existing `struct kobject` code
>    to its own file.
>
>    Reviewed by:    manu
>    Approved by:    manu
>    Differential Revision:  https://reviews.freebsd.org/D43019
> ---
> sys/compat/linuxkpi/common/include/linux/kobject.h |   2 +
> sys/compat/linuxkpi/common/src/linux_compat.c      | 190 ------------------
> sys/compat/linuxkpi/common/src/linux_kobject.c     | 221 +++++++++++++++++++++
> sys/conf/files                                     |   2 +
> sys/modules/linuxkpi/Makefile                      |   1 +
> 5 files changed, 226 insertions(+), 190 deletions(-)
>
> diff --git a/sys/compat/linuxkpi/common/include/linux/kobject.h b/sys/compat/linuxkpi/common/include/linux/kobject.h
> index 6e59e0952d62..06d71faaa873 100644
> --- a/sys/compat/linuxkpi/common/include/linux/kobject.h
> +++ b/sys/compat/linuxkpi/common/include/linux/kobject.h
> @@ -154,4 +154,6 @@ kobject_uevent_env(struct kobject *kobj, int action, char *envp[])
> 	 */
> }
>
> +void linux_kobject_kfree_name(struct kobject *kobj);


This is not part of the Linux KPI but an internal function?
If so this should go into an internal header in the src/ directory?



> #endif /* _LINUXKPI_LINUX_KOBJECT_H_ */
> diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c
> index b913ae602ab3..a493dc2538ec 100644
> --- a/sys/compat/linuxkpi/common/src/linux_compat.c
> +++ b/sys/compat/linuxkpi/common/src/linux_compat.c
> @@ -159,176 +159,6 @@ RB_GENERATE(linux_root, rb_node, __entry, panic_cmp);
> INTERVAL_TREE_DEFINE(struct interval_tree_node, rb, unsigned long,, START,
>     LAST,, lkpi_interval_tree)
>
> -struct kobject *
> -kobject_create(void)
> -{
> -	struct kobject *kobj;
> -
> -	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
> -	if (kobj == NULL)
> -		return (NULL);
> -	kobject_init(kobj, &linux_kfree_type);
> -
> -	return (kobj);
> -}
> -
> -
> -int
> -kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list args)
> -{
> -	va_list tmp_va;
> -	int len;
> -	char *old;
> -	char *name;
> -	char dummy;
> -
> -	old = kobj->name;
> -
> -	if (old && fmt == NULL)
> -		return (0);
> -
> -	/* compute length of string */
> -	va_copy(tmp_va, args);
> -	len = vsnprintf(&dummy, 0, fmt, tmp_va);
> -	va_end(tmp_va);
> -
> -	/* account for zero termination */
> -	len++;
> -
> -	/* check for error */
> -	if (len < 1)
> -		return (-EINVAL);
> -
> -	/* allocate memory for string */
> -	name = kzalloc(len, GFP_KERNEL);
> -	if (name == NULL)
> -		return (-ENOMEM);
> -	vsnprintf(name, len, fmt, args);
> -	kobj->name = name;
> -
> -	/* free old string */
> -	kfree(old);
> -
> -	/* filter new string */
> -	for (; *name != '\0'; name++)
> -		if (*name == '/')
> -			*name = '!';
> -	return (0);
> -}
> -
> -int
> -kobject_set_name(struct kobject *kobj, const char *fmt, ...)
> -{
> -	va_list args;
> -	int error;
> -
> -	va_start(args, fmt);
> -	error = kobject_set_name_vargs(kobj, fmt, args);
> -	va_end(args);
> -
> -	return (error);
> -}
> -
> -static int
> -kobject_add_complete(struct kobject *kobj, struct kobject *parent)
> -{
> -	const struct kobj_type *t;
> -	int error;
> -
> -	kobj->parent = parent;
> -	error = sysfs_create_dir(kobj);
> -	if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) {
> -		struct attribute **attr;
> -		t = kobj->ktype;
> -
> -		for (attr = t->default_attrs; *attr != NULL; attr++) {
> -			error = sysfs_create_file(kobj, *attr);
> -			if (error)
> -				break;
> -		}
> -		if (error)
> -			sysfs_remove_dir(kobj);
> -	}
> -	return (error);
> -}
> -
> -int
> -kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...)
> -{
> -	va_list args;
> -	int error;
> -
> -	va_start(args, fmt);
> -	error = kobject_set_name_vargs(kobj, fmt, args);
> -	va_end(args);
> -	if (error)
> -		return (error);
> -
> -	return kobject_add_complete(kobj, parent);
> -}
> -
> -void
> -linux_kobject_release(struct kref *kref)
> -{
> -	struct kobject *kobj;
> -	char *name;
> -
> -	kobj = container_of(kref, struct kobject, kref);
> -	sysfs_remove_dir(kobj);
> -	name = kobj->name;
> -	if (kobj->ktype && kobj->ktype->release)
> -		kobj->ktype->release(kobj);
> -	kfree(name);
> -}
> -
> -static void
> -linux_kobject_kfree(struct kobject *kobj)
> -{
> -	kfree(kobj);
> -}
> -
> -static void
> -linux_kobject_kfree_name(struct kobject *kobj)
> -{
> -	if (kobj) {
> -		kfree(kobj->name);
> -	}
> -}
> -
> -const struct kobj_type linux_kfree_type = {
> -	.release = linux_kobject_kfree
> -};
> -
> -static ssize_t
> -lkpi_kobj_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
> -{
> -	struct kobj_attribute *ka =
> -	    container_of(attr, struct kobj_attribute, attr);
> -
> -	if (ka->show == NULL)
> -		return (-EIO);
> -
> -	return (ka->show(kobj, ka, buf));
> -}
> -
> -static ssize_t
> -lkpi_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
> -    const char *buf, size_t count)
> -{
> -	struct kobj_attribute *ka =
> -	    container_of(attr, struct kobj_attribute, attr);
> -
> -	if (ka->store == NULL)
> -		return (-EIO);
> -
> -	return (ka->store(kobj, ka, buf, count));
> -}
> -
> -const struct sysfs_ops kobj_sysfs_ops = {
> -	.show	= lkpi_kobj_attr_show,
> -	.store	= lkpi_kobj_attr_store,
> -};
> -
> static void
> linux_device_release(struct device *dev)
> {
> @@ -518,26 +348,6 @@ class_create(struct module *owner, const char *name)
> 	return (class);
> }
>
> -int
> -kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
> -    struct kobject *parent, const char *fmt, ...)
> -{
> -	va_list args;
> -	int error;
> -
> -	kobject_init(kobj, ktype);
> -	kobj->ktype = ktype;
> -	kobj->parent = parent;
> -	kobj->name = NULL;
> -
> -	va_start(args, fmt);
> -	error = kobject_set_name_vargs(kobj, fmt, args);
> -	va_end(args);
> -	if (error)
> -		return (error);
> -	return kobject_add_complete(kobj, parent);
> -}
> -
> static void
> linux_kq_lock(void *arg)
> {
> diff --git a/sys/compat/linuxkpi/common/src/linux_kobject.c b/sys/compat/linuxkpi/common/src/linux_kobject.c
> new file mode 100644
> index 000000000000..ddd0a58660f1
> --- /dev/null
> +++ b/sys/compat/linuxkpi/common/src/linux_kobject.c
> @@ -0,0 +1,221 @@
> +/*-
> + * Copyright (c) 2010 Isilon Systems, Inc.
> + * Copyright (c) 2010 iX Systems, Inc.
> + * Copyright (c) 2010 Panasas, Inc.
> + * Copyright (c) 2013-2021 Mellanox Technologies, Ltd.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice unmodified, this list of conditions, and the following
> + *    disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <linux/kobject.h>
> +#include <linux/sysfs.h>
> +
> +struct kobject *
> +kobject_create(void)
> +{
> +	struct kobject *kobj;
> +
> +	kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
> +	if (kobj == NULL)
> +		return (NULL);
> +	kobject_init(kobj, &linux_kfree_type);
> +
> +	return (kobj);
> +}
> +
> +
> +int
> +kobject_set_name_vargs(struct kobject *kobj, const char *fmt, va_list args)
> +{
> +	va_list tmp_va;
> +	int len;
> +	char *old;
> +	char *name;
> +	char dummy;
> +
> +	old = kobj->name;
> +
> +	if (old && fmt == NULL)
> +		return (0);
> +
> +	/* compute length of string */
> +	va_copy(tmp_va, args);
> +	len = vsnprintf(&dummy, 0, fmt, tmp_va);
> +	va_end(tmp_va);
> +
> +	/* account for zero termination */
> +	len++;
> +
> +	/* check for error */
> +	if (len < 1)
> +		return (-EINVAL);
> +
> +	/* allocate memory for string */
> +	name = kzalloc(len, GFP_KERNEL);
> +	if (name == NULL)
> +		return (-ENOMEM);
> +	vsnprintf(name, len, fmt, args);
> +	kobj->name = name;
> +
> +	/* free old string */
> +	kfree(old);
> +
> +	/* filter new string */
> +	for (; *name != '\0'; name++)
> +		if (*name == '/')
> +			*name = '!';
> +	return (0);
> +}
> +
> +int
> +kobject_set_name(struct kobject *kobj, const char *fmt, ...)
> +{
> +	va_list args;
> +	int error;
> +
> +	va_start(args, fmt);
> +	error = kobject_set_name_vargs(kobj, fmt, args);
> +	va_end(args);
> +
> +	return (error);
> +}
> +
> +static int
> +kobject_add_complete(struct kobject *kobj, struct kobject *parent)
> +{
> +	const struct kobj_type *t;
> +	int error;
> +
> +	kobj->parent = parent;
> +	error = sysfs_create_dir(kobj);
> +	if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) {
> +		struct attribute **attr;
> +		t = kobj->ktype;
> +
> +		for (attr = t->default_attrs; *attr != NULL; attr++) {
> +			error = sysfs_create_file(kobj, *attr);
> +			if (error)
> +				break;
> +		}
> +		if (error)
> +			sysfs_remove_dir(kobj);
> +	}
> +	return (error);
> +}
> +
> +int
> +kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...)
> +{
> +	va_list args;
> +	int error;
> +
> +	va_start(args, fmt);
> +	error = kobject_set_name_vargs(kobj, fmt, args);
> +	va_end(args);
> +	if (error)
> +		return (error);
> +
> +	return kobject_add_complete(kobj, parent);
> +}
> +
> +int
> +kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
> +    struct kobject *parent, const char *fmt, ...)
> +{
> +	va_list args;
> +	int error;
> +
> +	kobject_init(kobj, ktype);
> +	kobj->ktype = ktype;
> +	kobj->parent = parent;
> +	kobj->name = NULL;
> +
> +	va_start(args, fmt);
> +	error = kobject_set_name_vargs(kobj, fmt, args);
> +	va_end(args);
> +	if (error)
> +		return (error);
> +	return kobject_add_complete(kobj, parent);
> +}
> +
> +void
> +linux_kobject_release(struct kref *kref)
> +{
> +	struct kobject *kobj;
> +	char *name;
> +
> +	kobj = container_of(kref, struct kobject, kref);
> +	sysfs_remove_dir(kobj);
> +	name = kobj->name;
> +	if (kobj->ktype && kobj->ktype->release)
> +		kobj->ktype->release(kobj);
> +	kfree(name);
> +}
> +
> +static void
> +linux_kobject_kfree(struct kobject *kobj)
> +{
> +	kfree(kobj);
> +}
> +
> +const struct kobj_type linux_kfree_type = {
> +	.release = linux_kobject_kfree
> +};
> +
> +void
> +linux_kobject_kfree_name(struct kobject *kobj)
> +{
> +	if (kobj) {
> +		kfree(kobj->name);
> +	}
> +}
> +
> +static ssize_t
> +lkpi_kobj_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
> +{
> +	struct kobj_attribute *ka =
> +	    container_of(attr, struct kobj_attribute, attr);
> +
> +	if (ka->show == NULL)
> +		return (-EIO);
> +
> +	return (ka->show(kobj, ka, buf));
> +}
> +
> +static ssize_t
> +lkpi_kobj_attr_store(struct kobject *kobj, struct attribute *attr,
> +    const char *buf, size_t count)
> +{
> +	struct kobj_attribute *ka =
> +	    container_of(attr, struct kobj_attribute, attr);
> +
> +	if (ka->store == NULL)
> +		return (-EIO);
> +
> +	return (ka->store(kobj, ka, buf, count));
> +}
> +
> +const struct sysfs_ops kobj_sysfs_ops = {
> +	.show	= lkpi_kobj_attr_show,
> +	.store	= lkpi_kobj_attr_store,
> +};
> diff --git a/sys/conf/files b/sys/conf/files
> index 377d65926462..bf951d789de3 100644
> --- a/sys/conf/files
> +++ b/sys/conf/files
> @@ -4567,6 +4567,8 @@ compat/linuxkpi/common/src/linux_i2cbb.c	optional compat_linuxkpi \
> 	compile-with "${LINUXKPI_C}"
> compat/linuxkpi/common/src/linux_interrupt.c	optional compat_linuxkpi \
> 	compile-with "${LINUXKPI_C}"
> +compat/linuxkpi/common/src/linux_kobject.c	optional compat_linuxkpi \
> +	compile-with "${LINUXKPI_C}"
> compat/linuxkpi/common/src/linux_kthread.c	optional compat_linuxkpi \
> 	compile-with "${LINUXKPI_C}"
> compat/linuxkpi/common/src/linux_lock.c		optional compat_linuxkpi \
> diff --git a/sys/modules/linuxkpi/Makefile b/sys/modules/linuxkpi/Makefile
> index bf40d64de9df..692f69c1f4e1 100644
> --- a/sys/modules/linuxkpi/Makefile
> +++ b/sys/modules/linuxkpi/Makefile
> @@ -14,6 +14,7 @@ SRCS=	linux_compat.c \
> 	linux_i2c.c \
> 	linux_i2cbb.c \
> 	linux_kmod.c \
> +	linux_kobject.c \
> 	linux_kthread.c \
> 	linux_lock.c \
> 	linux_netdev.c \
>

-- 
Bjoern A. Zeeb                                                     r15:7