[PATCH 3/7] docs: sysfs.rst: document additional attribute group macros

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add documentation to Documentation/filesystems/sysfs.rst for several sysfs
helper macros, including recently introduced and previously undocumented
helpers.

Document the following macros:

	__ATTR_IGNORE_LOCKDEP
	DEFINE_SYSFS_GROUP_VISIBILITY
	DEFINE_SYSFS_BIN_GROUP_VISIBILITY
	DEFINE_SYSFS_BIN_GROUP_COMBO_VISIBILITY
	ATTRIBUTE_GROUPS
	BIN_ATTRIBUTE_GROUPS
	NAMED_ATTRIBUTE_GROUP_VISIBLE
	NAMED_ATTRIBUTE_GROUPS_VISIBLE
	NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE
	NAMED_ATTRIBUTE_GROUPS_COMBO_VISIBLE

Suggested-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Signed-off-by: David E. Box <david.e.box@xxxxxxxxxxxxxxx>
---
 Documentation/filesystems/sysfs.rst | 244 ++++++++++++++++++++++++++++
 1 file changed, 244 insertions(+)

diff --git a/Documentation/filesystems/sysfs.rst b/Documentation/filesystems/sysfs.rst
index c32993bc83c7..16bcc3e7c80c 100644
--- a/Documentation/filesystems/sysfs.rst
+++ b/Documentation/filesystems/sysfs.rst
@@ -147,6 +147,250 @@ __ATTR_RW(name):
 __ATTR_NULL:
 	         which sets the name to NULL and is used as end of list
                  indicator (see: kernel/workqueue.c)
+__ATTR_IGNORE_LOCKDEP(name, mode, show, store):
+                 like __ATTR() but disables lockdep checks; used in cases
+                 where lockdep may emit false positives
+
+Additional Attribute Helpers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ATTRIBUTE_GROUPS(name):
+       Convenience macro to create an array of attribute group pointers.
+
+Example::
+
+    static struct attribute *foo_attrs[] = {
+            &attr1.attr,
+            &attr2.attr,
+            NULL
+    };
+    ATTRIBUTE_GROUPS(foo);
+
+BIN_ATTRIBUTE_GROUPS(name):
+        Same as ATTRIBUTE_GROUPS(), but for bin_attribute_group structures.
+
+Example::
+
+    static struct bin_attribute *foo_attrs[] = {
+            &bin_attr1.attr,
+            &bin_attr2.attr,
+            NULL
+    };
+    BIN_ATTRIBUTE_GROUPS(bin_foo);
+
+DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(name):
+        A helper macro to pair with the assignment of
+
+                ".is_visible = SYSFS_GROUP_VISIBLE(name)",
+
+        that arranges for the directory associated with a named attribute_group
+        to optionally be hidden.  This allows for static declaration of
+        attribute_groups, and the simplification of attribute visibility
+        lifetime that implies, without polluting sysfs with empty attribute
+        directories.
+
+Example::
+
+    static umode_t example_attr_visible(struct kobject *kobj,
+                                        struct attribute *attr, int n)
+    {
+            if (example_attr_condition)
+                    return 0;
+            if (ro_attr_condition)
+                    return 0444;
+            return a->mode;
+    }
+
+    static bool example_group_visible(struct kobject *kobj)
+    {
+            if (example_group_condition)
+                    return false;
+            return true;
+    }
+
+    DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(example);
+
+    static struct attribute_group example_group = {
+            .name = "example",
+            .is_visible = SYSFS_GROUP_VISIBLE(example),
+            .attrs = &example_attrs,
+    };
+
+Note that it expects <name>_attr_visible and <name>_group_visible to
+be defined. For cases where individual attributes do not need
+separate visibility consideration, only entire group visibility at
+once, see DEFINE_SYSFS_GROUP_VISIBILITY().
+
+DEFINE_SYSFS_GROUP_VISIBILITY(name):
+        A helper macro to pair with SYSFS_GROUP_VISIBLE() that, like
+        DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(), controls group visibility, but
+        does not require the implementation of a per-attribute visibility
+        callback.
+
+Example::
+
+    static bool example_group_visible(struct kobject *kobj)
+    {
+            if (example_group_condition)
+                    return false;
+            return true;
+    }
+
+    DEFINE_SYSFS_GROUP_VISIBILITY(example);
+
+    static struct attribute_group example_group = {
+            .name = "example",
+            .is_visible = SYSFS_GROUP_VISIBLE(example),
+            .attrs = &example_attrs,
+    };
+
+DEFINE_SYSFS_BIN_GROUP_COMBO_VISIBILITY(name):
+DEFINE_SYSFS_BIN_GROUP_VISIBILITY(name):
+        Same as DEFINE_SYSFS_GROUP_VISIBILITY(), but for groups with only binary
+        attributes. If an attribute_group defines both text and binary
+        attributes, the group visibility is determined by the function
+        specified to is_visible() not is_bin_visible().
+
+Named Attribute Group Macros (with visibility)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These macros define struct attribute_group objects with a static name and
+visibility function(s). They are useful for creating named directories in sysfs
+where individual attributes can be conditionally exposed.
+
+NAMED_ATTRIBUTE_GROUP_VISIBLE(name):
+        Defines an attribute group with a fixed directory name (matching name)
+        with a group visibility function. Expects an attribute array
+        <name>_attrs. The macro automatically defines the visibility function.
+
+Example::
+
+    static ssize_t foo_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+    {
+            ...
+    }
+
+    static ssize_t foo_store(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+    {
+            ...
+    }
+    static DEVICE_ATTR_RW(foo);
+
+    static bool bar_group_visible(struct kobject *kobj)
+    {
+            if (bar_group_condition)
+                    return false;
+            return true;
+    }
+
+    static struct attribute *bar_attrs[] = {
+            &dev_attr_foo.attr,
+            NULL
+    };
+    NAMED_ATTRIBUTE_GROUP_VISIBLE(bar);
+
+Creates::
+
+    static const struct attribute_group bar_group = {
+            .name = "bar",
+            .attrs = bar_attrs,
+            .is_visible = SYSFS_GROUP_VISIBLE(bar),
+    };
+
+    /*
+     * Where SYSFS_GROUP_VISIBLE(bar) is a function created by
+     * DEFINE_SYSFS_GROUP_VISIBILITY(bar) that calls bar_group_visible().
+     */
+
+NAMED_ATTRIBUTE_GROUPS_VISIBLE(name):
+        Like NAMED_ATTRIBUTE_GROUP_VISIBLE(), defines the visible attribute
+        group but also creates the group list <name>_groups[].
+
+Example::
+
+    ...
+
+    static struct attribute *bar_attrs[] = {
+            &attr1.attr,
+            &attr2.attr,
+            NULL
+    };
+    NAMED_ATTRIBUTE_GROUPS_VISIBLE(bar);
+
+Creates::
+
+    static const struct attribute_group bar_group = {
+            .name = "bar",
+            .attrs = bar_attrs,
+            .is_visible = SYSFS_GROUP_VISIBLE(bar),
+    };
+
+    static const struct attribute_group *bar_groups[] = {
+            &bar_group,
+            NULL
+    };
+
+NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE(name):
+        Same as NAMED_ATTRIBUTE_GROUP_VISIBLE(), but uses the "combo" visibility
+        variant to support both group and per-attribute visibility control.
+        Automatically generates the combo visibility boilerplate.
+
+Example::
+
+    static ssize_t foo_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+    {
+            ...
+    }
+
+    static ssize_t foo_store(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+    {
+            ...
+    }
+    static DEVICE_ATTR_RW(foo);
+
+    static umode_t foo_attr_visible(struct kobject *kobj,
+                                    struct attribute *attr, int n)
+    {
+            if (example_attr_condition)
+                    return 0;
+            return attr->mode;
+    }
+
+    static bool foo_group_visible(struct kobject *kobj)
+    {
+            if (foo_group_condition)
+                    return false;
+            return true;
+    }
+
+    static struct attribute *foo_attrs[] = {
+            &dev_attr_foo.attr,
+            NULL
+    };
+    NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE(foo);
+
+Creates::
+
+    static const struct attribute_group foo_group = {
+            .name = "foo",
+            .attrs = foo_attrs,
+            .is_visible = SYSFS_GROUP_VISIBLE(foo),
+    };
+
+    /*
+     * Where SYSFS_GROUP_VISIBLE(foo) is a function created by
+     * DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(foo) that calls foo_group_visible()
+     * and foo_attr_visible().
+     */
+
+NAMED_ATTRIBUTE_GROUPS_COMBO_VISIBLE(name):
+        Like NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE() defines the attribute group,
+        supporting both group and per-attribute visibility control, but also
+        creates the group list <name>_groups[].
 
 Subsystem-Specific Callbacks
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- 
2.43.0





[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux