svn commit: r352114 - in stable/12/sys: compat/linuxkpi/common/include/linux sys

Johannes Lundberg johalun at FreeBSD.org
Tue Sep 10 02:21:18 UTC 2019


Author: johalun
Date: Tue Sep 10 02:21:17 2019
New Revision: 352114
URL: https://svnweb.freebsd.org/changeset/base/352114

Log:
  MFC r351937:
  LinuxKPI: Improve sysfs support.
  
  - Add functions for creating and merging sysfs groups.
  - Add sysfs_streq function to compare strings ignoring newline from the
    sysctl userland call.
  - Add a call to sysfs_create_groups in device_add.
  - Remove duplicate header include.
  - Bump __FreeBSD_version.
  
  Reviewed by:	hselasky
  Approved by:	imp (mentor), hselasky

Modified:
  stable/12/sys/compat/linuxkpi/common/include/linux/device.h
  stable/12/sys/compat/linuxkpi/common/include/linux/sysfs.h
  stable/12/sys/sys/param.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/compat/linuxkpi/common/include/linux/device.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/device.h	Tue Sep 10 01:56:47 2019	(r352113)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/device.h	Tue Sep 10 02:21:17 2019	(r352114)
@@ -40,7 +40,6 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/workqueue.h>
-#include <linux/sysfs.h>
 #include <linux/kdev_t.h>
 #include <asm/atomic.h>
 
@@ -316,6 +315,10 @@ device_add(struct device *dev)
 			dev->devt = makedev(0, device_get_unit(dev->bsddev));
 	}
 	kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
+
+	if (dev->groups)
+		return (sysfs_create_groups(&dev->kobj, dev->groups));
+
 	return (0);
 }
 

Modified: stable/12/sys/compat/linuxkpi/common/include/linux/sysfs.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/sysfs.h	Tue Sep 10 01:56:47 2019	(r352113)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/sysfs.h	Tue Sep 10 02:21:17 2019	(r352114)
@@ -175,6 +175,27 @@ sysfs_remove_files(struct kobject *kobj, const struct 
 		sysfs_remove_file(kobj, attrs[i]);
 }
 
+static inline int
+sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
+{
+	struct attribute **attr;
+	struct sysctl_oid *oidp;
+
+	/* Don't create the group node if grp->name is undefined. */
+	if (grp->name)
+		oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(kobj->oidp),
+		    OID_AUTO, grp->name, CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, grp->name);
+	else
+		oidp = kobj->oidp;
+	for (attr = grp->attrs; *attr != NULL; attr++) {
+		SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(oidp), OID_AUTO,
+		    (*attr)->name, CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_MPSAFE,
+		    kobj, (uintptr_t)*attr, sysctl_handle_attr, "A", "");
+	}
+
+	return (0);
+}
+
 static inline void
 sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp)
 {
@@ -184,20 +205,40 @@ sysfs_remove_group(struct kobject *kobj, const struct 
 }
 
 static inline int
-sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp)
+sysfs_create_groups(struct kobject *kobj, const struct attribute_group **grps)
 {
+	int error = 0;
+	int i;
+
+	for (i = 0; grps[i] && !error; i++)
+		error = sysfs_create_group(kobj, grps[i]);
+	while (error && --i >= 0)
+		sysfs_remove_group(kobj, grps[i]);
+
+	return (error);
+}
+
+static inline int
+sysfs_merge_group(struct kobject *kobj, const struct attribute_group *grp)
+{
+
+	/* Really expected behavior is to return failure if group exists. */
+	return (sysfs_create_group(kobj, grp));
+}
+
+static inline void
+sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp)
+{
 	struct attribute **attr;
 	struct sysctl_oid *oidp;
 
-	oidp = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(kobj->oidp),
-	    OID_AUTO, grp->name, CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, grp->name);
-	for (attr = grp->attrs; *attr != NULL; attr++) {
-		SYSCTL_ADD_OID(NULL, SYSCTL_CHILDREN(oidp), OID_AUTO,
-		    (*attr)->name, CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_MPSAFE,
-		    kobj, (uintptr_t)*attr, sysctl_handle_attr, "A", "");
+	SLIST_FOREACH(oidp, SYSCTL_CHILDREN(kobj->oidp), oid_link) {
+		if (strcmp(oidp->oid_name, grp->name) != 0)
+			continue;
+		for (attr = grp->attrs; *attr != NULL; attr++) {
+			sysctl_remove_name(oidp, (*attr)->name, 1, 1);
+		}
 	}
-
-	return (0);
 }
 
 static inline int
@@ -222,6 +263,22 @@ sysfs_remove_dir(struct kobject *kobj)
 	if (kobj->oidp == NULL)
 		return;
 	sysctl_remove_oid(kobj->oidp, 1, 1);
+}
+
+static inline bool
+sysfs_streq(const char *s1, const char *s2)
+{
+	int l1, l2;
+
+	l1 = strlen(s1);
+	l2 = strlen(s2);
+
+	if (l1 != 0 && s1[l1-1] == '\n')
+		l1--;
+	if (l2 != 0 && s2[l2-1] == '\n')
+		l2--;
+
+	return (l1 == l2 && strncmp(s1, s2, l1) == 0);
 }
 
 #define sysfs_attr_init(attr) do {} while(0)

Modified: stable/12/sys/sys/param.h
==============================================================================
--- stable/12/sys/sys/param.h	Tue Sep 10 01:56:47 2019	(r352113)
+++ stable/12/sys/sys/param.h	Tue Sep 10 02:21:17 2019	(r352114)
@@ -60,7 +60,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1200517	/* Master, propagated to newvers */
+#define __FreeBSD_version 1200518	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,


More information about the svn-src-stable-12 mailing list