[PATCH][RESEND] docs: filesystems: sysfs: convert sysfs.txt to reST

From: Jaskaran Singh
Date: Tue Nov 05 2019 - 02:19:01 EST


This patch converts sysfs.txt to sysfs.rst, and adds a corresponding
entry in index.rst.

Most of the whitespacing and indentation is kept similar to the
original document.

Changes to the original document include:

- Adding an authors statement in the header.
- Replacing the underscores in the title with asterisks. This is so
that the "The" in the title appears in italics in HTML.
- Replacing the tilde (~) headings with equal signs, for reST section
headings.
- List out the helper macros with backquotes and corresponding description
on the next line.
- Placing C code and shell code in reST code blocks, with an indentation
of an 8 length tab.

Signed-off-by: Jaskaran Singh <jaskaransingh7654321@xxxxxxxxx>
---
Documentation/filesystems/index.rst | 1 +
.../filesystems/{sysfs.txt => sysfs.rst} | 323 ++++++++++--------
2 files changed, 189 insertions(+), 135 deletions(-)
rename Documentation/filesystems/{sysfs.txt => sysfs.rst} (60%)

diff --git a/Documentation/filesystems/index.rst b/Documentation/filesystems/index.rst
index 2c3a9f761205..18b5ea780b9b 100644
--- a/Documentation/filesystems/index.rst
+++ b/Documentation/filesystems/index.rst
@@ -46,4 +46,5 @@ Documentation for filesystem implementations.
.. toctree::
:maxdepth: 2

+ sysfs
virtiofs
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.rst
similarity index 60%
rename from Documentation/filesystems/sysfs.txt
rename to Documentation/filesystems/sysfs.rst
index ddf15b1b0d5a..de0de5869323 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.rst
@@ -1,15 +1,18 @@
+======================================================
+sysfs - *The* filesystem for exporting kernel objects.
+======================================================

-sysfs - _The_ filesystem for exporting kernel objects.
+Authors:

-Patrick Mochel <mochel@xxxxxxxx>
-Mike Murphy <mamurph@xxxxxxxxxxxxxx>
+- Patrick Mochel <mochel@xxxxxxxx>
+- Mike Murphy <mamurph@xxxxxxxxxxxxxx>

-Revised: 16 August 2011
-Original: 10 January 2003
+| Revised: 16 August 2011
+| Original: 10 January 2003


What it is:
-~~~~~~~~~~~
+===========

sysfs is a ram-based filesystem initially based on ramfs. It provides
a means to export kernel data structures, their attributes, and the
@@ -21,16 +24,18 @@ interface.


Using sysfs
-~~~~~~~~~~~
+===========

sysfs is always compiled in if CONFIG_SYSFS is defined. You can access
it by doing:

- mount -t sysfs sysfs /sys
+.. code-block:: sh
+
+ mount -t sysfs sysfs /sys


Directory Creation
-~~~~~~~~~~~~~~~~~~
+==================

For every kobject that is registered with the system, a directory is
created for it in sysfs. That directory is created as a subdirectory
@@ -48,7 +53,7 @@ only modified directly by the function sysfs_schedule_callback().


Attributes
-~~~~~~~~~~
+==========

Attributes can be exported for kobjects in the form of regular files in
the filesystem. Sysfs forwards file I/O operations to methods defined
@@ -67,15 +72,16 @@ you publicly humiliated and your code rewritten without notice.

An attribute definition is simply:

-struct attribute {
- char * name;
- struct module *owner;
- umode_t mode;
-};
+.. code-block:: c

+ struct attribute {
+ char * name;
+ struct module *owner;
+ umode_t mode;
+ };

-int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
-void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);
+ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
+ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);


A bare attribute contains no means to read or write the value of the
@@ -85,36 +91,44 @@ a specific object type.

For example, the driver model defines struct device_attribute like:

-struct device_attribute {
- struct attribute attr;
- ssize_t (*show)(struct device *dev, struct device_attribute *attr,
- char *buf);
- ssize_t (*store)(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count);
-};
+.. code-block:: c
+
+ struct device_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+ };

-int device_create_file(struct device *, const struct device_attribute *);
-void device_remove_file(struct device *, const struct device_attribute *);
+ int device_create_file(struct device *, const struct device_attribute *);
+ void device_remove_file(struct device *, const struct device_attribute *);

It also defines this helper for defining device attributes:

-#define DEVICE_ATTR(_name, _mode, _show, _store) \
-struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
+.. code-block:: c
+
+ #define DEVICE_ATTR(_name, _mode, _show, _store) \
+ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

For example, declaring

-static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);
+.. code-block:: c
+
+ static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);

is equivalent to doing:

-static struct device_attribute dev_attr_foo = {
- .attr = {
- .name = "foo",
- .mode = S_IWUSR | S_IRUGO,
- },
- .show = show_foo,
- .store = store_foo,
-};
+.. code-block:: c
+
+ static struct device_attribute dev_attr_foo = {
+ .attr = {
+ .name = "foo",
+ .mode = S_IWUSR | S_IRUGO,
+ },
+ .show = show_foo,
+ .store = store_foo,
+ };

Note as stated in include/linux/kernel.h "OTHER_WRITABLE? Generally
considered a bad idea." so trying to set a sysfs file writable for
@@ -124,31 +138,45 @@ For the common cases sysfs.h provides convenience macros to make
defining attributes easier as well as making code more concise and
readable. The above case could be shortened to:

-static struct device_attribute dev_attr_foo = __ATTR_RW(foo);
+.. code-block:: c
+
+ static struct device_attribute dev_attr_foo = __ATTR_RW(foo);

the list of helpers available to define your wrapper function is:
-__ATTR_RO(name): assumes default name_show and mode 0444
-__ATTR_WO(name): assumes a name_store only and is restricted to mode
- 0200 that is root write access only.
-__ATTR_RO_MODE(name, mode): fore more restrictive RO access currently
- only use case is the EFI System Resource Table
- (see drivers/firmware/efi/esrt.c)
-__ATTR_RW(name): assumes default name_show, name_store and setting
- mode to 0644.
-__ATTR_NULL: which sets the name to NULL and is used as end of list
- indicator (see: kernel/workqueue.c)
+
+``__ATTR_RO(name)``
+ assumes default name_show and mode 0444
+
+``__ATTR_WO(name)``
+ assumes a name_store only and is restricted to mode
+ 0200 that is root write access only.
+
+``__ATTR_RO_MODE(name, mode)``
+ for more restrictive RO access currently
+ only use case is the EFI System Resource Table
+ (see drivers/firmware/efi/esrt.c)
+
+``__ATTR_RW(name)``
+ assumes default name_show, name_store and setting
+ mode to 0644.
+
+``__ATTR_NULL``
+ which sets the name to NULL and is used as end of list
+ indicator (see: kernel/workqueue.c)

Subsystem-Specific Callbacks
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+============================

When a subsystem defines a new attribute type, it must implement a
set of sysfs operations for forwarding read and write calls to the
show and store methods of the attribute owners.

-struct sysfs_ops {
- ssize_t (*show)(struct kobject *, struct attribute *, char *);
- ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
-};
+.. code-block:: c
+
+ struct sysfs_ops {
+ ssize_t (*show)(struct kobject *, struct attribute *, char *);
+ ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
+ };

[ Subsystems should have already defined a struct kobj_type as a
descriptor for this type, which is where the sysfs_ops pointer is
@@ -162,37 +190,41 @@ calls the associated methods.

To illustrate:

-#define to_dev(obj) container_of(obj, struct device, kobj)
-#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
+.. code-block:: c

-static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
- char *buf)
-{
- struct device_attribute *dev_attr = to_dev_attr(attr);
- struct device *dev = to_dev(kobj);
- ssize_t ret = -EIO;
+ #define to_dev(obj) container_of(obj, struct device, kobj)
+ #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)

- if (dev_attr->show)
- ret = dev_attr->show(dev, dev_attr, buf);
- if (ret >= (ssize_t)PAGE_SIZE) {
- printk("dev_attr_show: %pS returned bad count\n",
- dev_attr->show);
- }
- return ret;
-}
+ static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+ {
+ struct device_attribute *dev_attr = to_dev_attr(attr);
+ struct device *dev = to_dev(kobj);
+ ssize_t ret = -EIO;
+
+ if (dev_attr->show)
+ ret = dev_attr->show(dev, dev_attr, buf);
+ if (ret >= (ssize_t)PAGE_SIZE) {
+ printk("dev_attr_show: %pS returned bad count\n",
+ dev_attr->show);
+ }
+ return ret;
+ }



Reading/Writing Attribute Data
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==============================

To read or write attributes, show() or store() methods must be
specified when declaring the attribute. The method types should be as
simple as those defined for device attributes:

-ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
-ssize_t (*store)(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count);
+.. code-block:: c
+
+ ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
+ ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);

IOW, they should take only an object, an attribute, and a buffer as parameters.

@@ -253,21 +285,23 @@ Other notes:

A very simple (and naive) implementation of a device attribute is:

-static ssize_t show_name(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "%s\n", dev->name);
-}
+.. code-block:: c

-static ssize_t store_name(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- snprintf(dev->name, sizeof(dev->name), "%.*s",
- (int)min(count, sizeof(dev->name) - 1), buf);
- return count;
-}
+ static ssize_t show_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ return scnprintf(buf, PAGE_SIZE, "%s\n", dev->name);
+ }

-static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);
+ static ssize_t store_name(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ snprintf(dev->name, sizeof(dev->name), "%.*s",
+ (int)min(count, sizeof(dev->name) - 1), buf);
+ return count;
+ }
+
+ static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);


(Note that the real implementation doesn't allow userspace to set the
@@ -275,28 +309,28 @@ name for a device.)


Top Level Directory Layout
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+==========================

The sysfs directory arrangement exposes the relationship of kernel
data structures.

-The top level sysfs directory looks like:
+The top level sysfs directory looks like: ::

-block/
-bus/
-class/
-dev/
-devices/
-firmware/
-net/
-fs/
+ block/
+ bus/
+ class/
+ dev/
+ devices/
+ firmware/
+ net/
+ fs/

devices/ contains a filesystem representation of the device tree. It maps
directly to the internal kernel device tree, which is a hierarchy of
struct device.

bus/ contains flat directory layout of the various bus types in the
-kernel. Each bus's directory contains two subdirectories:
+kernel. Each bus's directory contains two subdirectories: ::

devices/
drivers/
@@ -326,80 +360,99 @@ TODO: Finish this section.


Current Interfaces
-~~~~~~~~~~~~~~~~~~
+==================

The following interface layers currently exist in sysfs:


-- devices (include/linux/device.h)
-----------------------------------
+devices (include/linux/device.h)
+--------------------------------
Structure:

-struct device_attribute {
- struct attribute attr;
- ssize_t (*show)(struct device *dev, struct device_attribute *attr,
- char *buf);
- ssize_t (*store)(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count);
-};
+.. code-block:: c
+
+ struct device_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+ };

Declaring:

-DEVICE_ATTR(_name, _mode, _show, _store);
+.. code-block:: c
+
+ DEVICE_ATTR(_name, _mode, _show, _store);

Creation/Removal:

-int device_create_file(struct device *dev, const struct device_attribute * attr);
-void device_remove_file(struct device *dev, const struct device_attribute * attr);
+.. code-block:: c
+
+ int device_create_file(struct device *dev, const struct device_attribute * attr);
+ void device_remove_file(struct device *dev, const struct device_attribute * attr);


-- bus drivers (include/linux/device.h)
---------------------------------------
+bus drivers (include/linux/device.h)
+------------------------------------
+
Structure:

-struct bus_attribute {
- struct attribute attr;
- ssize_t (*show)(struct bus_type *, char * buf);
- ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
-};
+.. code-block:: c
+
+ struct bus_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct bus_type *, char * buf);
+ ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
+ };

Declaring:

-static BUS_ATTR_RW(name);
-static BUS_ATTR_RO(name);
-static BUS_ATTR_WO(name);
+.. code-block:: c
+
+ static BUS_ATTR_RW(name);
+ static BUS_ATTR_RO(name);
+ static BUS_ATTR_WO(name);

Creation/Removal:

-int bus_create_file(struct bus_type *, struct bus_attribute *);
-void bus_remove_file(struct bus_type *, struct bus_attribute *);
+.. code-block:: c
+
+ int bus_create_file(struct bus_type *, struct bus_attribute *);
+ void bus_remove_file(struct bus_type *, struct bus_attribute *);


-- device drivers (include/linux/device.h)
------------------------------------------
+device drivers (include/linux/device.h)
+---------------------------------------

Structure:

-struct driver_attribute {
- struct attribute attr;
- ssize_t (*show)(struct device_driver *, char * buf);
- ssize_t (*store)(struct device_driver *, const char * buf,
- size_t count);
-};
+.. code-block:: c
+
+ struct driver_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct device_driver *, char * buf);
+ ssize_t (*store)(struct device_driver *, const char * buf,
+ size_t count);
+ };

Declaring:

-DRIVER_ATTR_RO(_name)
-DRIVER_ATTR_RW(_name)
+.. code-block:: c
+
+ DRIVER_ATTR_RO(_name)
+ DRIVER_ATTR_RW(_name)

Creation/Removal:

-int driver_create_file(struct device_driver *, const struct driver_attribute *);
-void driver_remove_file(struct device_driver *, const struct driver_attribute *);
+.. code-block:: c
+
+ int driver_create_file(struct device_driver *, const struct driver_attribute *);
+ void driver_remove_file(struct device_driver *, const struct driver_attribute *);


Documentation
-~~~~~~~~~~~~~
+=============

The sysfs directory structure and the attributes in each directory define an
ABI between the kernel and user space. As for any ABI, it is important that
--
2.21.0