Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp428572ybx; Mon, 4 Nov 2019 23:14:29 -0800 (PST) X-Google-Smtp-Source: APXvYqy41f65djoFO2Elo9m3Pb1/EtY0BWIQ3Fu3p+QOleOeBtksH+pYuNOE/YHBK7nAP98mI1zN X-Received: by 2002:a17:906:5494:: with SMTP id r20mr27556034ejo.293.1572938069342; Mon, 04 Nov 2019 23:14:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1572938069; cv=none; d=google.com; s=arc-20160816; b=o9xdTT/TxfTYr7IRzqrBHzW644i2HXtwe/OB+A49B5Rdd8CPUQxApsZoNY9/NH6MYU UuQ8CettUWIESx77GtrLNXQqtcyT3r4QmR/v1M7vvugZ+krE6nkfVeRrcdLhgLHR/8nE WDXOy8vEhQ6VPoXo/vR37BMc44Yq7LALk/Xeczsn/sjz3SWjr0jDb2rG64SUp6Ns5UK9 uBr+M7rzQ254LBCbfAp8Pp9tLTymF8suSwoitqDRuis1UPV1vC2Jos0RFcF5ANURCsAN 5WbUz6b6866ztFE5MRppTNdqZqN4Xc7qZs1oB0j9VwhN2gC6qNXmeGrV+3wsTpB6K1T0 IJVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:content-disposition :mime-version:message-id:subject:cc:to:from:date:dkim-signature; bh=C3V4q8Hphd3d9zZDUmVOsx50l1MD7niZTtsL+eJD5Xk=; b=KnxGWjh8Z7e06KHBLzvJAWVuY50S2/RqBikWryKLipFmUTG38sy2lYhR4bZSGBPAt0 NYpqrZ0NL7MhmWI/KhtQG94u21jqdXOcCy4iHgB8+763XSjEv/gx0YP9ARp9lN7vdHzt O2U8Ss+NerUCZ8uFjbW5pZtIuBFyGJ+tETmPjY3LiMYArEuyzkimo9xxdjGJpIuTUyaA XHYEJ6IJqeBvkd345jWUaQjwXQ7KVgfvSxUj7xfwQKAJcXDsd+QiZJTRiSQ/6jAEvxOs tRoBmYKODJ4RHsMiJQ5lxgIFsVm2LlFItFBVcMgYs1G9PL86qiZqo1C3Kdyt6s9L8ODP WYOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=GMRXPOaV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i47si9300094eda.91.2019.11.04.23.14.03; Mon, 04 Nov 2019 23:14:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=GMRXPOaV; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387591AbfKEHNU (ORCPT + 99 others); Tue, 5 Nov 2019 02:13:20 -0500 Received: from mail-pl1-f193.google.com ([209.85.214.193]:46868 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387442AbfKEHNU (ORCPT ); Tue, 5 Nov 2019 02:13:20 -0500 Received: by mail-pl1-f193.google.com with SMTP id l4so3666369plt.13; Mon, 04 Nov 2019 23:13:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=C3V4q8Hphd3d9zZDUmVOsx50l1MD7niZTtsL+eJD5Xk=; b=GMRXPOaV/cScc5bIi2rVhUTqtbqLX4F1wEVunTUoNXt1ZiqUT04szIir06nk4AeyXd vf3gnf5ntFv6KjSE7TLmWtCRiPhCBvwrek0c2AxtmtZMk2+InVoLX37g4ecKYeBgMfX/ 4qpYj5vyWLCioOgo886c51bQCu7AvxAbdgpYPTsUG8HM8VgIlEGDha+ngJ2g8gFQ1lys ygCtEwCD73COluK1unePJic7addR8Pg/gEoh3CRqyX+Iq1kWmCOp11FspIGJYSmnoYz2 ZpnlZB5/LnD7g36vZcGVFuwyYvZAYrUBgkzUvffm0DmKBSYGioEN9QX43Lua8V6ahUg/ lvfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=C3V4q8Hphd3d9zZDUmVOsx50l1MD7niZTtsL+eJD5Xk=; b=icaqkaZNsjkdoRjbHQF63DmzkhGSF05+FD7QEC8VM36Mci6JpD0WmoBM692A+BxGd3 /15iXu41HLPH2TWUl/j8oKPILhj2vsEpvypxGK48WVMy/vRDskihY1MUWojnm3Q62cQx qMyMCG0uIn6rWh7hy4kIDiO2JYNR4VpQNQKW9K1Pnr9gCTVqhANgUk0WFA9bqO32urRD nXgW0qxxY6hXamxt+I3ULBmTh58ScT2ij4cWCkg4k+pkxIsJAU0f90yui6epHdbJWsO6 frQ+/UiDnADDsEAJK8NGACXbof2160TTPWHqrXX9EnhUjeeCMFCi13UXgsgjPkfFl0I3 vidw== X-Gm-Message-State: APjAAAX+ik+Nu+S3xch28dRJStsP4uks0wuqi7t8BAj3aWxcx5Qriy5t X/snqNVBl50C+KUu42mYDPSDAcPFXNi0rA== X-Received: by 2002:a17:902:a717:: with SMTP id w23mr31962348plq.27.1572937998685; Mon, 04 Nov 2019 23:13:18 -0800 (PST) Received: from localhost ([2402:3a80:680:8b3a:2a4c:218c:b0b3:eada]) by smtp.gmail.com with ESMTPSA id i126sm19838563pfc.29.2019.11.04.23.13.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2019 23:13:18 -0800 (PST) Date: Tue, 5 Nov 2019 12:43:09 +0530 From: Jaskaran Singh To: linux-kernel@vger.kernel.org Cc: corbet@lwn.net, mchehab+samsung@kernel.org, christian@brauner.io, neilb@suse.com, willy@infradead.org, jaskaransingh7654321@gmail.com, tobin@kernel.org, stefanha@redhat.com, hofrat@osadl.org, gregkh@linuxfoundation.org, jeffrey.t.kirsher@intel.com, linux-doc@vger.kernel.org, skhan@linuxfoundation.org, linux-kernel-mentees@vger.kernel.org Subject: [PATCH] docs: filesystems: sysfs: convert sysfs.txt to reST Message-ID: <20191105071309.GA28093@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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 -Mike Murphy +- Patrick Mochel +- Mike Murphy -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