Re: git: 80446fc7b5e5 - main - linuxkpi: Move `struct kobject` code to `linux_kobject.c`
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