* [PATCH 1/8] [SCSI] scst: Split sysfs type attribute
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
@ 2010-12-27 13:36 ` Bart Van Assche
2010-12-27 13:37 ` [PATCH 2/8] [SCSI] scst: Split version and stats attributes Bart Van Assche
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:36 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
The device 'type' sysfs attribute contains two values: the SCSI
peripheral device type as a number and its textual description. Split
this sysfs attribute into two attributes such that both satisfy the
"one value per file" rule. Also, fix a potential out-of-bounds access
of the array scst_dev_handler_types.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Vladislav Bolkhovitin <vst@vlnb.net>
---
.../ABI/stable/sysfs-devices-scst_tgt_dev | 8 +++-
Documentation/ABI/stable/sysfs-driver-scst_tgt_dev | 12 +++--
drivers/scst/scst_sysfs.c | 46 ++++++++++++++-----
3 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev b/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
index cfa791e..a7d5070 100644
--- a/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
+++ b/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
@@ -118,7 +118,13 @@ What: /sys/bus/scst_tgt_dev/device/*/type
Date: December 2010
Contact: Bart Van Assche <bvanassche@acm.org>
Description:
- SCSI type of this device. Read-only.
+ SCSI type of this device as a number. Read-only.
+
+What: /sys/bus/scst_tgt_dev/device/*/type_description
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ SCSI type of this device as a textual description. Read-only.
What: /sys/bus/scst_tgt_dev/device/*/usn
Date: December 2010
diff --git a/Documentation/ABI/stable/sysfs-driver-scst_tgt_dev b/Documentation/ABI/stable/sysfs-driver-scst_tgt_dev
index c79aee0..2787c4d 100644
--- a/Documentation/ABI/stable/sysfs-driver-scst_tgt_dev
+++ b/Documentation/ABI/stable/sysfs-driver-scst_tgt_dev
@@ -20,8 +20,12 @@ What: /sys/bus/scst_tgt_dev/drivers/*/type
Date: December 2010
Contact: Bart Van Assche <bvanassche@acm.org>
Description:
- SCSI type of the devices managed by this driver. Read-only.
- An example:
+ SCSI type of the devices managed by this driver as a number.
+ Read-only.
- $ cat /sys/bus/scst_tgt_dev/drivers/vcdrom/type
- 5 - CD-ROM device
+What: /sys/bus/scst_tgt_dev/drivers/*/type_description
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ SCSI type of the devices managed by this driver as a textual
+ description. Read-only.
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index 3901f20..23cba83 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -1091,16 +1091,22 @@ void scst_tgt_sysfs_put(struct scst_tgt *tgt)
static ssize_t scst_dev_sysfs_type_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos;
struct scst_device *dev;
dev = scst_dev_to_dev(device);
+ return scnprintf(buf, PAGE_SIZE, "%d\n", dev->type);
+}
- pos = sprintf(buf, "%d - %s\n", dev->type,
- (unsigned)dev->type > ARRAY_SIZE(scst_dev_handler_types) ?
- "unknown" : scst_dev_handler_types[dev->type]);
+static ssize_t scst_dev_sysfs_type_description_show(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct scst_device *dev;
+ const char *descr;
- return pos;
+ dev = scst_dev_to_dev(device);
+ descr = (unsigned)dev->type < ARRAY_SIZE(scst_dev_handler_types) ?
+ scst_dev_handler_types[dev->type] : "unknown";
+ return scnprintf(buf, PAGE_SIZE, "%s\n", descr);
}
static int scst_process_dev_sysfs_threads_data_store(
@@ -1265,8 +1271,13 @@ static const struct device_attribute *dev_thread_attr[] = {
static const struct device_attribute scst_dev_sysfs_type_attr =
__ATTR(type, S_IRUGO, scst_dev_sysfs_type_show, NULL);
+static const struct device_attribute scst_dev_sysfs_type_description_attr =
+ __ATTR(type_description, S_IRUGO, scst_dev_sysfs_type_description_show,
+ NULL);
+
static const struct device_attribute *scst_devt_dev_attrs[] = {
&scst_dev_sysfs_type_attr,
+ &scst_dev_sysfs_type_description_attr,
NULL
};
@@ -2852,23 +2863,34 @@ out:
static ssize_t scst_devt_type_show(struct device_driver *drv, char *buf)
{
- int pos;
struct scst_dev_type *devt;
devt = scst_drv_to_devt(drv);
-
- pos = sprintf(buf, "%d - %s\n", devt->type,
- (unsigned)devt->type > ARRAY_SIZE(scst_dev_handler_types) ?
- "unknown" : scst_dev_handler_types[devt->type]);
-
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", devt->type);
}
static const struct driver_attribute scst_devt_type_attr =
__ATTR(type, S_IRUGO, scst_devt_type_show, NULL);
+static ssize_t scst_devt_type_description_show(struct device_driver *drv,
+ char *buf)
+{
+ struct scst_dev_type *devt;
+ const char *descr;
+
+ devt = scst_drv_to_devt(drv);
+ descr = (unsigned)devt->type < ARRAY_SIZE(scst_dev_handler_types) ?
+ scst_dev_handler_types[devt->type] : "unknown";
+ return scnprintf(buf, PAGE_SIZE, "%s\n", descr);
+}
+
+static const struct driver_attribute scst_devt_type_description_attr =
+ __ATTR(type_description, S_IRUGO, scst_devt_type_description_show,
+ NULL);
+
static const struct driver_attribute *scst_devt_default_attrs[] = {
&scst_devt_type_attr,
+ &scst_devt_type_description_attr,
NULL
};
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/8] [SCSI] scst: Split version and stats attributes
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
2010-12-27 13:36 ` [PATCH 1/8] [SCSI] scst: Split sysfs type attribute Bart Van Assche
@ 2010-12-27 13:37 ` Bart Van Assche
2010-12-27 13:38 ` [PATCH 3/8] [SCSI] scst: Remove [key] marker from sysfs files Bart Van Assche
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:37 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
Split the scst_local 'stats' sysfs attribute into three attributes such
that the "one value per file" rule is honered. The three new attributes
are: aborts, device_resets and target_resets. Export the scst_local
release date via the module information instead of sysfs. Remove the
build options from the 'version' attribute of scst_local and scst since
this duplicates information already available in the kernel .config.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Vladislav Bolkhovitin <vst@vlnb.net>
Cc: Richard Sharpe <realrichardsharpe@gmail.com>
---
Documentation/ABI/stable/sysfs-driver-scst_target | 9 +---
.../ABI/stable/sysfs-driver-scst_target-scst_local | 23 ++++++---
drivers/scst/scst_local/scst_local.c | 49 +++++++++++--------
drivers/scst/scst_sysfs.c | 47 +------------------
4 files changed, 47 insertions(+), 81 deletions(-)
diff --git a/Documentation/ABI/stable/sysfs-driver-scst_target b/Documentation/ABI/stable/sysfs-driver-scst_target
index 0c2b6a1..ca8944a 100644
--- a/Documentation/ABI/stable/sysfs-driver-scst_target
+++ b/Documentation/ABI/stable/sysfs-driver-scst_target
@@ -48,12 +48,7 @@ What: /sys/bus/scst_target/drivers/*/version
Date: December 2010
Contact: Bart Van Assche <bvanassche@acm.org>
Description:
- Target driver version and build options. The driver version
- and build date appear on the first line separated by a
- slash and the build options appear on subsequent
- lines. Read-only. An example:
+ Target driver version. Read-only. An example:
$ cat /sys/bus/scst_target/drivers/scst_local/version
- 1.0.0/20100910
- TRACING
- DEBUG
+ 1.0.0
diff --git a/Documentation/ABI/stable/sysfs-driver-scst_target-scst_local b/Documentation/ABI/stable/sysfs-driver-scst_target-scst_local
index 56e50f7..3ea28dc 100644
--- a/Documentation/ABI/stable/sysfs-driver-scst_target-scst_local
+++ b/Documentation/ABI/stable/sysfs-driver-scst_target-scst_local
@@ -1,11 +1,20 @@
-What: /sys/bus/scst_target/drivers/scst_local/stats
+What: /sys/bus/scst_target/drivers/scst_local/aborts
Date: December 2010
Contact: Richard Sharpe <realrichardsharpe@gmail.com>
Description:
- Statistics about processing of SCSI commands received via the
- Linux SCSI initiator: the number of SCSI commands that have
- been aborted, the number of SCSI device resets and the number
- of SCSI target resets. Read-only. An example:
+ Number of SCSI commands that have been aborted by the SCSI
+ initiator. Read-only.
- # cat /sys/bus/scst_target/drivers/scst_local/stats
- Aborts: 0, Device Resets: 0, Target Resets: 0
+What: /sys/bus/scst_target/drivers/scst_local/device_resets
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ Number of SCSI device resets that have been performed by the
+ SCSI initiator. Read-only.
+
+What: /sys/bus/scst_target/drivers/scst_local/target_resets
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ Number of SCSI target resets that have been performed by the
+ SCSI initiator. Read-only.
diff --git a/drivers/scst/scst_local/scst_local.c b/drivers/scst/scst_local/scst_local.c
index 14c8fd9..b0c989a 100644
--- a/drivers/scst/scst_local/scst_local.c
+++ b/drivers/scst/scst_local/scst_local.c
@@ -54,7 +54,7 @@ static unsigned long scst_local_trace_flag = SCST_LOCAL_DEFAULT_LOG_FLAGS;
#define FALSE 0
#define SCST_LOCAL_VERSION "1.0.0"
-static const char *scst_local_version_date = "20100910";
+#define SCST_LOCAL_VERSION_DATE "20100910"
/* Some statistics */
static atomic_t num_aborts = ATOMIC_INIT(0);
@@ -128,6 +128,7 @@ MODULE_AUTHOR("Richard Sharpe, Vladislav Bolkhovitin + ideas from SCSI_DEBUG");
MODULE_DESCRIPTION("SCSI+SCST local adapter driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(SCST_LOCAL_VERSION);
+MODULE_INFO(release_date, SCST_LOCAL_VERSION_DATE);
static int scst_local_get_sas_transport_id(struct scst_local_sess *sess,
uint8_t **transport_id, int *len)
@@ -222,38 +223,44 @@ out:
static ssize_t scst_local_version_show(struct device_driver *drv, char *buf)
{
- sprintf(buf, "%s/%s\n", SCST_LOCAL_VERSION, scst_local_version_date);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", SCST_LOCAL_VERSION);
+}
-#ifdef CONFIG_SCST_EXTRACHECKS
- strcat(buf, "EXTRACHECKS\n");
-#endif
+static struct driver_attribute scst_local_version_attr =
+ __ATTR(version, S_IRUGO, scst_local_version_show, NULL);
-#ifdef CONFIG_SCST_TRACING
- strcat(buf, "TRACING\n");
-#endif
+static ssize_t scst_local_aborts_show(struct device_driver *drv, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%u\n", atomic_read(&num_aborts));
+}
-#ifdef CONFIG_SCST_DEBUG
- strcat(buf, "DEBUG\n");
-#endif
- return strlen(buf);
+static struct driver_attribute scst_local_aborts_attr =
+ __ATTR(aborts, S_IRUGO, scst_local_aborts_show, NULL);
+
+static ssize_t scst_local_device_resets_show(struct device_driver *drv,
+ char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%u\n", atomic_read(&num_dev_resets));
}
-static struct driver_attribute scst_local_version_attr =
- __ATTR(version, S_IRUGO, scst_local_version_show, NULL);
+static struct driver_attribute scst_local_device_resets_attr =
+ __ATTR(device_resets, S_IRUGO, scst_local_device_resets_show, NULL);
-static ssize_t scst_local_stats_show(struct device_driver *drv, char *buf)
+static ssize_t scst_local_target_resets_show(struct device_driver *drv,
+ char *buf)
{
- return sprintf(buf, "Aborts: %d, Device Resets: %d, Target Resets: %d",
- atomic_read(&num_aborts), atomic_read(&num_dev_resets),
- atomic_read(&num_target_resets));
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ atomic_read(&num_target_resets));
}
-static struct driver_attribute scst_local_stats_attr =
- __ATTR(stats, S_IRUGO, scst_local_stats_show, NULL);
+static struct driver_attribute scst_local_target_resets_attr =
+ __ATTR(target_resets, S_IRUGO, scst_local_target_resets_show, NULL);
static const struct driver_attribute *scst_local_tgtt_attrs[] = {
&scst_local_version_attr,
- &scst_local_stats_attr,
+ &scst_local_aborts_attr,
+ &scst_local_device_resets_attr,
+ &scst_local_target_resets_attr,
NULL,
};
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index 23cba83..05344cc 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -3611,52 +3611,7 @@ out:
static ssize_t scst_version_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- sprintf(buf, "%s\n", SCST_VERSION_STRING);
-
-#ifdef CONFIG_SCST_STRICT_SERIALIZING
- strcat(buf, "STRICT_SERIALIZING\n");
-#endif
-
-#ifdef CONFIG_SCST_EXTRACHECKS
- strcat(buf, "EXTRACHECKS\n");
-#endif
-
-#ifdef CONFIG_SCST_TRACING
- strcat(buf, "TRACING\n");
-#endif
-
-#ifdef CONFIG_SCST_DEBUG
- strcat(buf, "DEBUG\n");
-#endif
-
-#ifdef CONFIG_SCST_DEBUG_TM
- strcat(buf, "DEBUG_TM\n");
-#endif
-
-#ifdef CONFIG_SCST_DEBUG_RETRY
- strcat(buf, "DEBUG_RETRY\n");
-#endif
-
-#ifdef CONFIG_SCST_DEBUG_OOM
- strcat(buf, "DEBUG_OOM\n");
-#endif
-
-#ifdef CONFIG_SCST_DEBUG_SN
- strcat(buf, "DEBUG_SN\n");
-#endif
-
-#ifdef CONFIG_SCST_USE_EXPECTED_VALUES
- strcat(buf, "USE_EXPECTED_VALUES\n");
-#endif
-
-#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
- strcat(buf, "TEST_IO_IN_SIRQ\n");
-#endif
-
-#ifdef CONFIG_SCST_STRICT_SECURITY
- strcat(buf, "STRICT_SECURITY\n");
-#endif
- return strlen(buf);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", SCST_VERSION_STRING);
}
static struct device_attribute scst_mgmt_attr =
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/8] [SCSI] scst: Remove [key] marker from sysfs files
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
2010-12-27 13:36 ` [PATCH 1/8] [SCSI] scst: Split sysfs type attribute Bart Van Assche
2010-12-27 13:37 ` [PATCH 2/8] [SCSI] scst: Split version and stats attributes Bart Van Assche
@ 2010-12-27 13:38 ` Bart Van Assche
2010-12-27 13:39 ` [PATCH 4/8] [SCSI] scst: Substitute SCST_SYSFS_BLOCK_SIZE Bart Van Assche
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:38 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
While the '[key]' marker on the second line of sysfs files is convenient
for user-space tools that save the SCST state (e.g. scstadmin) to find
out whether or not a value is a default value, remove this marker to make
the contents of sysfs files created by SCST uniform with other sysfs
files.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Vladislav Bolkhovitin <vst@vlnb.net>
---
.../ABI/stable/sysfs-devices-scst_tgt_dev | 1 -
Documentation/scst/SysfsRules | 160 --------------------
drivers/scst/dev_handlers/scst_vdisk.c | 62 ++------
drivers/scst/scst_local/scst_local.c | 10 +-
drivers/scst/scst_sysfs.c | 66 +++------
include/scst/scst_const.h | 2 -
6 files changed, 34 insertions(+), 267 deletions(-)
delete mode 100644 Documentation/scst/SysfsRules
diff --git a/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev b/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
index a7d5070..2048875 100644
--- a/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
+++ b/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
@@ -24,7 +24,6 @@ Description:
# cat /sys/devices/disk01/filename
/dev/sdc
- [key]
What: /sys/bus/scst_tgt_dev/device/*/nv_cache
Date: December 2010
diff --git a/Documentation/scst/SysfsRules b/Documentation/scst/SysfsRules
deleted file mode 100644
index 5790511..0000000
--- a/Documentation/scst/SysfsRules
+++ /dev/null
@@ -1,160 +0,0 @@
- SCST SYSFS interface rules
- ==========================
-
-This document explains the rules SCST target drivers, device handlers and
-management utilities must adhere to. These rules make it possible for a
-user space tool like scstadmin to save and restore the entire state of the
-SCST core, target drivers and device handlers.
-
-If the last line of a modifiable sysfs attribute contains the text "[key]",
-this means the value of that attribute is not the default value of that
-attribute. That text is added by SCST when such an attribute is read but
-must not be added when modifying an SCST sysfs attribute.
-
-I. Rules for target drivers
-===========================
-
-The SCST core creates a directory for each target driver (struct
-scst_tgt_template) in /sys/bus/scst_target. And for each SCSI target (struct
-scst_tgt) the SCST core creates a directory in /sys/bus/scst_target/devices/.
-
-There are two types of SCSI targets, namely hardware and virtual. Hardware
-targets are targets corresponding to a hardware entity, e.g. a port of a Fibre
-Channel adapter or an InfiniBand HCA. Virtual targets can be added and removed
-dynamically and do not have a one-to-one correspondence to hardware. As an
-example, iSCSI targets and NPIV Fibre Channel targets are virtual targets.
-
-Virtual targets are created and removed via the commands "add_target" and
-"del_target" respectively.
-
-A target driver that supports both hardware targets and virtual targets
-(e.g. an FC adapter that supports NPIV) must mark each hardware target with
-"hw_target" (see further).
-
-Querying the current state
---------------------------
-
-Querying the current state is possible by reading individual sysfs attributes.
-As an example, querying the state of the SCST core, all device drivers and
-target drivers is possible as follows:
-
-# find /sys/devices/scst /sys/bus/scst_target /sys/bus/scst_tgt_dev -type f -perm -u+r | xargs head
-
-Modifying the current state
----------------------------
-
-If a sysfs attribute has write permission, it can be modified by writing a new
-value into that attribute. Many management actions though happen via the
-"mgmt" attribute of the SCST device itself. The documentation of the syntax of
-the management commands can be revealed by reading that attribute. An example:
-
-# cd /sys/devices/scst
-# cat mgmt
-[ ... ]
-# cat /sys/devices/disk01/threads_num
-6
-[key]
-# echo "in device/disk01 set_threads_num 1" >mgmt
-# cat /sys/devices/disk01/threads_num
-1
-[key]
-
-
-II. Rules for device handlers
-=============================
-
-There are two types of device handlers: parent device handlers and child
-device handlers. The child device handlers depend on their parent device
-handler.
-
-The SCST core creates a directory for each parent device handler (struct
-scst_dev_type where the parent member equals NULL) in
-/sys/bus/scst_tgt_dev/driver. Parent device handlers can have one or more
-subdirectories for child device handlers.
-
-Only one level is allowed in the parent/child hierarchy. Parent device
-handlers that support child device handlers must not handle devices themselves.
-
-In this document child device handlers and parent device handlers without
-child device handlers will be called "end level device handlers".
-
-For each device (struct scst_device) the SCST core creates a directory in
-/sys/bus/scst_tgt_dev.
-
-Device handler attributes
--------------------------
-
-The following attributes may be supported for a device handler:
-
-1. "trace_level" - Allows to query and/or modify the log level for a device
-handler.
-
-2. "add_device_parameters" - Parameters supported by the add_device command.
-
-3. "driver_attributes" - Attributes supported by the add_attribute and
-del_attribute commands.
-
-4. "device_attributes" - Attributes supported by the add_device_attribute and
-del_device_attribute commands.
-
-5. "type" - SCSI device type. A number followed by a description, e.g.:
-
-# cat /sys/bus/scst_tgt_dev/drivers/vcdrom/type
-5 - CD-ROM device
-
-
-Device attributes
------------------
-
-The following attributes may be supported for a device:
-
-1. blocksize - Native SCSI block size of this device.
-
-2. filename - For virtual devices, the path of the associated file or device.
-An example:
-
-# cat /sys/devices/disk01/filename
-/dev/sdc
-[key]
-
-3. nv_cache - Whether or not the device has a non-volatile cache. SCST uses
-this information to decide whether or not it is safe to acknowledge writes
-early to the initiator. Setting this attribute to 1 for a device that neither
-has a non-volatile cache nor an UPS will decrease I/O latency but may result
-in data loss in case of a power failure.
-
-4. o_direct - For virtual devices that use file I/O, whether to use
-non-buffered (direct) I/O or buffered (asynchronous) I/O. In direct I/O mode
-both read and write caching is disabled.
-
-5. read_only - For virtual devices, whether or not to deny write commands.
-
-6. removable - For virtual devices, whether or not the underlying storage
-medium is removable.
-
-7. resync_size - For virtual devices, writing to this attribute will update
-the internally cached device size.
-
-8. size_mb - For virtual devices, the internally cached size in MB of the
-underlying storage device.
-
-9. t10_dev_id - SCSI device ID associated with the virtual device. This is the
-ID reported via the Device Identification page (0x83) of the INQUIRY command.
-
-10. thin_provisioned - Whether or not the virtual device supports thin
-provisioning.
-
-11. threads_num - Number of threads that exist in the thread pool that is
-used for processing SCSI commands for this device.
-
-12. threads_pool_type - Whether to use a distinct thread pool per initiator
-("per_initiator") or one thread pool for all initiators accessing this device
-("shared").
-
-13. type - SCSI type of this device.
-
-14. usn - Unique serial number as reported in the SCSI INQUIRY response.
-
-15. write_through - Allows to disable write-back caching for virtual devices.
-
-See also the SCST core README for more information about those attributes.
diff --git a/drivers/scst/dev_handlers/scst_vdisk.c b/drivers/scst/dev_handlers/scst_vdisk.c
index 0700c60..cb41962 100644
--- a/drivers/scst/dev_handlers/scst_vdisk.c
+++ b/drivers/scst/dev_handlers/scst_vdisk.c
@@ -532,7 +532,7 @@ static char *__vdev_get_filename(struct scst_vdisk_dev *virt_dev)
if (virt_dev->filename != NULL)
return virt_dev->filename;
else
- return "none";
+ return "";
}
static void vdev_set_filename(struct scst_vdisk_dev *virt_dev, char *n)
@@ -3788,115 +3788,80 @@ static ssize_t vdev_sysfs_size_show(struct device *device,
static ssize_t vdisk_sysfs_blocksize_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos = 0;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
dev = scst_dev_to_dev(device);
virt_dev = dev->dh_priv;
-
- pos = sprintf(buf, "%d\n%s", (int)virt_dev->block_size,
- (virt_dev->block_size == DEF_DISK_BLOCKSIZE) ? "" :
- SCST_SYSFS_KEY_MARK "\n");
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", (int)virt_dev->block_size);
}
static ssize_t vdisk_sysfs_rd_only_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos = 0;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
dev = scst_dev_to_dev(device);
virt_dev = dev->dh_priv;
-
- pos = sprintf(buf, "%d\n%s", virt_dev->rd_only ? 1 : 0,
- (virt_dev->rd_only == DEF_RD_ONLY) ? "" :
- SCST_SYSFS_KEY_MARK "");
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", virt_dev->rd_only ? 1 : 0);
}
static ssize_t vdisk_sysfs_wt_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos = 0;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
dev = scst_dev_to_dev(device);
virt_dev = dev->dh_priv;
-
- pos = sprintf(buf, "%d\n%s", virt_dev->wt_flag ? 1 : 0,
- (virt_dev->wt_flag == DEF_WRITE_THROUGH) ? "" :
- SCST_SYSFS_KEY_MARK "");
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", virt_dev->wt_flag ? 1 : 0);
}
static ssize_t vdisk_sysfs_tp_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos = 0;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
dev = scst_dev_to_dev(device);
virt_dev = dev->dh_priv;
-
- pos = sprintf(buf, "%d\n%s", virt_dev->thin_provisioned ? 1 : 0,
- (virt_dev->thin_provisioned == DEF_THIN_PROVISIONED) ? "" :
- SCST_SYSFS_KEY_MARK "");
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ virt_dev->thin_provisioned ? 1 : 0);
}
static ssize_t vdisk_sysfs_nv_cache_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos = 0;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
dev = scst_dev_to_dev(device);
virt_dev = dev->dh_priv;
-
- pos = sprintf(buf, "%d\n%s", virt_dev->nv_cache ? 1 : 0,
- (virt_dev->nv_cache == DEF_NV_CACHE) ? "" :
- SCST_SYSFS_KEY_MARK "");
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", virt_dev->nv_cache ? 1 : 0);
}
static ssize_t vdisk_sysfs_o_direct_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos = 0;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
dev = scst_dev_to_dev(device);
virt_dev = dev->dh_priv;
-
- pos = sprintf(buf, "%d\n%s", virt_dev->o_direct_flag ? 1 : 0,
- (virt_dev->o_direct_flag == DEF_O_DIRECT) ? "" :
- SCST_SYSFS_KEY_MARK "");
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ virt_dev->o_direct_flag ? 1 : 0);
}
static ssize_t vdisk_sysfs_removable_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
dev = scst_dev_to_dev(device);
virt_dev = dev->dh_priv;
-
- pos = sprintf(buf, "%d\n", virt_dev->removable ? 1 : 0);
-
- if ((virt_dev->dev->type != TYPE_ROM) &&
- (virt_dev->removable != DEF_REMOVABLE))
- pos += sprintf(&buf[pos], "%s\n", SCST_SYSFS_KEY_MARK);
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", virt_dev->removable ? 1 : 0);
}
static ssize_t vdev_sysfs_filename_show(struct device *device,
@@ -3912,9 +3877,7 @@ static ssize_t vdev_sysfs_filename_show(struct device *device,
res = mutex_lock_interruptible(&virt_dev->filename_mutex);
if (res)
goto out;
- res = snprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n%s",
- __vdev_get_filename(virt_dev),
- virt_dev->filename ? SCST_SYSFS_KEY_MARK "\n" : "");
+ res = scnprintf(buf, PAGE_SIZE, "%s\n", __vdev_get_filename(virt_dev));
mutex_unlock(&virt_dev->filename_mutex);
out:
@@ -4003,8 +3966,7 @@ static ssize_t vdev_sysfs_t10_dev_id_show(struct device *device,
virt_dev = dev->dh_priv;
read_lock_bh(&vdisk_t10_dev_id_rwlock);
- pos = sprintf(buf, "%s\n%s", virt_dev->t10_dev_id,
- virt_dev->t10_dev_id_set ? SCST_SYSFS_KEY_MARK "\n" : "");
+ pos = scnprintf(buf, PAGE_SIZE, "%s\n", virt_dev->t10_dev_id);
read_unlock_bh(&vdisk_t10_dev_id_rwlock);
return pos;
}
diff --git a/drivers/scst/scst_local/scst_local.c b/drivers/scst/scst_local/scst_local.c
index b0c989a..a3804cb 100644
--- a/drivers/scst/scst_local/scst_local.c
+++ b/drivers/scst/scst_local/scst_local.c
@@ -285,10 +285,10 @@ static ssize_t scst_local_scsi_transport_version_show(struct device *dev,
goto out_up;
if (tgt->scsi_transport_version != 0)
- res = sprintf(buf, "0x%x\n%s", tgt->scsi_transport_version,
- SCST_SYSFS_KEY_MARK "\n");
+ res = scnprintf(buf, PAGE_SIZE, "0x%x\n",
+ tgt->scsi_transport_version);
else
- res = sprintf(buf, "0x%x\n", 0x0BE0); /* SAS */
+ res = scnprintf(buf, PAGE_SIZE, "0x%x\n", 0x0BE0); /* SAS */
out_up:
up_read(&scst_local_exit_rwsem);
@@ -350,9 +350,7 @@ static ssize_t scst_local_phys_transport_version_show(struct device *dev,
if (!tgt)
goto out_up;
- res = sprintf(buf, "0x%x\n%s", tgt->phys_transport_version,
- (tgt->phys_transport_version != 0) ?
- SCST_SYSFS_KEY_MARK "\n" : "");
+ res = scnprintf(buf, PAGE_SIZE, "0x%x\n", tgt->phys_transport_version);
out_up:
up_read(&scst_local_exit_rwsem);
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index 05344cc..da325f5 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -500,9 +500,6 @@ static ssize_t __scst_acg_addr_method_show(struct scst_acg *acg, char *buf)
break;
}
- if (acg->addr_method != acg->tgt->tgtt->preferred_addr_method)
- res += sprintf(&buf[res], "%s\n", SCST_SYSFS_KEY_MARK);
-
return res;
}
@@ -568,17 +565,16 @@ static ssize_t __scst_acg_io_grouping_type_show(struct scst_acg *acg, char *buf)
res = sprintf(buf, "%s\n", SCST_IO_GROUPING_AUTO_STR);
break;
case SCST_IO_GROUPING_THIS_GROUP_ONLY:
- res = sprintf(buf, "%s\n%s\n",
- SCST_IO_GROUPING_THIS_GROUP_ONLY_STR,
- SCST_SYSFS_KEY_MARK);
+ res = scnprintf(buf, PAGE_SIZE, "%s\n",
+ SCST_IO_GROUPING_THIS_GROUP_ONLY_STR);
break;
case SCST_IO_GROUPING_NEVER:
- res = sprintf(buf, "%s\n%s\n", SCST_IO_GROUPING_NEVER_STR,
- SCST_SYSFS_KEY_MARK);
+ res = scnprintf(buf, PAGE_SIZE, "%s\n",
+ SCST_IO_GROUPING_NEVER_STR);
break;
default:
- res = sprintf(buf, "%d\n%s\n", acg->acg_io_grouping_type,
- SCST_SYSFS_KEY_MARK);
+ res = scnprintf(buf, PAGE_SIZE, "%d\n",
+ acg->acg_io_grouping_type);
break;
}
@@ -698,10 +694,6 @@ static ssize_t __scst_acg_cpu_mask_show(struct scst_acg *acg, char *buf)
res = cpumask_scnprintf(buf, PAGE_SIZE, &acg->acg_cpu_mask);
res += scnprintf(buf + res, PAGE_SIZE - res, "\n");
- if (!cpus_equal(acg->acg_cpu_mask, default_cpu_mask))
- res += scnprintf(buf + res, PAGE_SIZE - res, "%s",
- SCST_SYSFS_KEY_MARK "\n");
-
return res;
}
@@ -839,13 +831,9 @@ static ssize_t scst_rel_tgt_id_show(struct device *device,
struct device_attribute *attr, char *buf)
{
struct scst_tgt *tgt;
- int res;
tgt = scst_dev_to_tgt(device);
-
- res = sprintf(buf, "%d\n%s", tgt->rel_tgt_id,
- (tgt->rel_tgt_id != 0) ? SCST_SYSFS_KEY_MARK "\n" : "");
- return res;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", tgt->rel_tgt_id);
}
static int scst_process_rel_tgt_id_store(struct scst_tgt *tgt,
@@ -1176,15 +1164,10 @@ out:
static ssize_t scst_dev_sysfs_threads_num_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int pos;
struct scst_device *dev;
dev = scst_dev_to_dev(device);
-
- pos = sprintf(buf, "%d\n%s", dev->threads_num,
- (dev->threads_num != dev->handler->threads_num) ?
- SCST_SYSFS_KEY_MARK "\n" : "");
- return pos;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", dev->threads_num);
}
static ssize_t scst_dev_set_threads_num(struct scst_device *dev, long newtn)
@@ -1224,17 +1207,15 @@ static ssize_t scst_dev_sysfs_threads_pool_type_show(struct device *device,
switch (dev->threads_pool_type) {
case SCST_THREADS_POOL_PER_INITIATOR:
- pos = sprintf(buf, "%s\n%s", SCST_THREADS_POOL_PER_INITIATOR_STR,
- (dev->threads_pool_type != dev->handler->threads_pool_type) ?
- SCST_SYSFS_KEY_MARK "\n" : "");
+ pos = scnprintf(buf, PAGE_SIZE, "%s\n",
+ SCST_THREADS_POOL_PER_INITIATOR_STR);
break;
case SCST_THREADS_POOL_SHARED:
- pos = sprintf(buf, "%s\n%s", SCST_THREADS_POOL_SHARED_STR,
- (dev->threads_pool_type != dev->handler->threads_pool_type) ?
- SCST_SYSFS_KEY_MARK "\n" : "");
+ pos = scnprintf(buf, PAGE_SIZE, "%s\n",
+ SCST_THREADS_POOL_SHARED_STR);
break;
default:
- pos = sprintf(buf, "Unknown\n");
+ pos = scnprintf(buf, PAGE_SIZE, "Unknown\n");
break;
}
@@ -2051,11 +2032,8 @@ static ssize_t scst_lun_rd_only_show(struct kobject *kobj,
struct scst_acg_dev *acg_dev;
acg_dev = scst_kobj_to_acg_dev(kobj);
-
- if (acg_dev->rd_only || acg_dev->dev->rd_only)
- return sprintf(buf, "%d\n%s\n", 1, SCST_SYSFS_KEY_MARK);
- else
- return sprintf(buf, "%d\n", 0);
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ acg_dev->rd_only || acg_dev->dev->rd_only);
}
static struct kobj_attribute lun_options_attr =
@@ -3514,12 +3492,8 @@ out:
static ssize_t scst_threads_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int count;
-
- count = sprintf(buf, "%d\n%s", scst_main_cmd_threads.nr_threads,
- (scst_main_cmd_threads.nr_threads != scst_threads) ?
- SCST_SYSFS_KEY_MARK "\n" : "");
- return count;
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ scst_main_cmd_threads.nr_threads);
}
static int scst_process_threads_store(int newtn)
@@ -3580,11 +3554,7 @@ out:
static ssize_t scst_setup_id_show(struct device *device,
struct device_attribute *attr, char *buf)
{
- int count;
-
- count = sprintf(buf, "0x%x\n%s\n", scst_setup_id,
- (scst_setup_id == 0) ? "" : SCST_SYSFS_KEY_MARK);
- return count;
+ return scnprintf(buf, PAGE_SIZE, "0x%x\n", scst_setup_id);
}
static ssize_t scst_setup_id_store(struct device *device,
diff --git a/include/scst/scst_const.h b/include/scst/scst_const.h
index b7b06ea..d1dadfa 100644
--- a/include/scst/scst_const.h
+++ b/include/scst/scst_const.h
@@ -385,8 +385,6 @@ enum scst_cdb_flags {
#define TID_COMMON_SIZE 24
-#define SCST_SYSFS_KEY_MARK "[key]"
-
#define SCST_MIN_REL_TGT_ID 1
#define SCST_MAX_REL_TGT_ID 65535
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/8] [SCSI] scst: Substitute SCST_SYSFS_BLOCK_SIZE
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
` (2 preceding siblings ...)
2010-12-27 13:38 ` [PATCH 3/8] [SCSI] scst: Remove [key] marker from sysfs files Bart Van Assche
@ 2010-12-27 13:39 ` Bart Van Assche
2010-12-27 13:39 ` [PATCH 5/8] [SCSI] scst: Improve sysfs parsing robustness Bart Van Assche
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:39 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
Replace all instances of SCST_SYSFS_BLOCK_SIZE by PAGE_SIZE and remove the
symbolic constant SCST_SYSFS_BLOCK_SIZE.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Vladislav Bolkhovitin <vst@vlnb.net>
---
drivers/scst/scst_sysfs.c | 54 +++++++++++++++++++-------------------------
include/scst/scst_const.h | 2 -
2 files changed, 23 insertions(+), 33 deletions(-)
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index da325f5..ed10475 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -1531,7 +1531,7 @@ static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
processed_cmds_wr = latency_stat->processed_cmds_wr;
processed_cmds_rd = latency_stat->processed_cmds_rd;
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-5s %-9s %-15lu ", "Write", scst_io_size_names[i],
(unsigned long)processed_cmds_wr);
if (processed_cmds_wr == 0)
@@ -1543,8 +1543,7 @@ static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
(unsigned long)scst_time_wr,
(unsigned long)latency_stat->max_scst_time_wr,
(unsigned long)latency_stat->scst_time_wr);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
- "%-47s", buf);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
do_div(tgt_time_wr, processed_cmds_wr);
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
@@ -1552,8 +1551,7 @@ static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
(unsigned long)tgt_time_wr,
(unsigned long)latency_stat->max_tgt_time_wr,
(unsigned long)latency_stat->tgt_time_wr);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
- "%-47s", buf);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
do_div(dev_time_wr, processed_cmds_wr);
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
@@ -1561,10 +1559,9 @@ static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
(unsigned long)dev_time_wr,
(unsigned long)latency_stat->max_dev_time_wr,
(unsigned long)latency_stat->dev_time_wr);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
- "%-47s\n", buf);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s\n", buf);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-5s %-9s %-15lu ", "Read", scst_io_size_names[i],
(unsigned long)processed_cmds_rd);
if (processed_cmds_rd == 0)
@@ -1576,8 +1573,7 @@ static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
(unsigned long)scst_time_rd,
(unsigned long)latency_stat->max_scst_time_rd,
(unsigned long)latency_stat->scst_time_rd);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
- "%-47s", buf);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
do_div(tgt_time_rd, processed_cmds_rd);
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
@@ -1585,8 +1581,7 @@ static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
(unsigned long)tgt_time_rd,
(unsigned long)latency_stat->max_tgt_time_rd,
(unsigned long)latency_stat->tgt_time_rd);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
- "%-47s", buf);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
do_div(dev_time_rd, processed_cmds_rd);
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
@@ -1594,8 +1589,7 @@ static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
(unsigned long)dev_time_rd,
(unsigned long)latency_stat->max_dev_time_rd,
(unsigned long)latency_stat->dev_time_rd);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
- "%-47s\n", buf);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s\n", buf);
}
return res;
}
@@ -1671,7 +1665,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
sess = scst_kobj_to_sess(kobj);
res = 0;
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-15s %-15s %-46s %-46s %-46s\n",
"T-L names", "Total commands", "SCST latency",
"Target latency", "Dev latency (min/avg/max/all ns)");
@@ -1695,7 +1689,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
processed_cmds_wr = latency_stat->processed_cmds_wr;
processed_cmds_rd = latency_stat->processed_cmds_rd;
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-5s %-9s %-15lu ",
"Write", scst_io_size_names[i],
(unsigned long)processed_cmds_wr);
@@ -1708,7 +1702,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)scst_time_wr,
(unsigned long)latency_stat->max_scst_time_wr,
(unsigned long)latency_stat->scst_time_wr);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s", buf);
do_div(tgt_time_wr, processed_cmds_wr);
@@ -1717,7 +1711,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)tgt_time_wr,
(unsigned long)latency_stat->max_tgt_time_wr,
(unsigned long)latency_stat->tgt_time_wr);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s", buf);
do_div(dev_time_wr, processed_cmds_wr);
@@ -1726,10 +1720,10 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)dev_time_wr,
(unsigned long)latency_stat->max_dev_time_wr,
(unsigned long)latency_stat->dev_time_wr);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s\n", buf);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-5s %-9s %-15lu ",
"Read", scst_io_size_names[i],
(unsigned long)processed_cmds_rd);
@@ -1742,7 +1736,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)scst_time_rd,
(unsigned long)latency_stat->max_scst_time_rd,
(unsigned long)latency_stat->scst_time_rd);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s", buf);
do_div(tgt_time_rd, processed_cmds_rd);
@@ -1751,7 +1745,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)tgt_time_rd,
(unsigned long)latency_stat->max_tgt_time_rd,
(unsigned long)latency_stat->tgt_time_rd);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s", buf);
do_div(dev_time_rd, processed_cmds_rd);
@@ -1760,7 +1754,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)dev_time_rd,
(unsigned long)latency_stat->max_dev_time_rd,
(unsigned long)latency_stat->dev_time_rd);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s\n", buf);
}
@@ -1769,7 +1763,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
dev_time = sess->dev_time;
processed_cmds = sess->processed_cmds;
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"\n%-15s %-16d", "Overall ", processed_cmds);
if (processed_cmds == 0)
@@ -1781,7 +1775,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)scst_time,
(unsigned long)sess->max_scst_time,
(unsigned long)sess->scst_time);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s", buf);
do_div(tgt_time, processed_cmds);
@@ -1790,7 +1784,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)tgt_time,
(unsigned long)sess->max_tgt_time,
(unsigned long)sess->tgt_time);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s", buf);
do_div(dev_time, processed_cmds);
@@ -1799,7 +1793,7 @@ static ssize_t scst_sess_latency_show(struct kobject *kobj,
(unsigned long)dev_time,
(unsigned long)sess->max_dev_time,
(unsigned long)sess->dev_time);
- res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
"%-47s\n\n", buf);
spin_unlock_bh(&sess->lat_lock);
@@ -1937,8 +1931,7 @@ static ssize_t scst_sess_sysfs_initiator_name_show(struct kobject *kobj,
sess = scst_kobj_to_sess(kobj);
- return scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n",
- sess->initiator_name);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", sess->initiator_name);
}
static struct kobj_attribute session_initiator_name_attr =
@@ -2588,8 +2581,7 @@ out:
static ssize_t scst_acn_file_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
- return scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n",
- attr->attr.name);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", attr->attr.name);
}
int scst_acn_sysfs_create(struct scst_acn *acn)
diff --git a/include/scst/scst_const.h b/include/scst/scst_const.h
index d1dadfa..ac446fa 100644
--- a/include/scst/scst_const.h
+++ b/include/scst/scst_const.h
@@ -379,8 +379,6 @@ enum scst_cdb_flags {
/*************************************************************
** Misc constants
*************************************************************/
-#define SCST_SYSFS_BLOCK_SIZE PAGE_SIZE
-
#define SCST_PR_DIR "/var/lib/scst/pr"
#define TID_COMMON_SIZE 24
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/8] [SCSI] scst: Improve sysfs parsing robustness
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
` (3 preceding siblings ...)
2010-12-27 13:39 ` [PATCH 4/8] [SCSI] scst: Substitute SCST_SYSFS_BLOCK_SIZE Bart Van Assche
@ 2010-12-27 13:39 ` Bart Van Assche
2010-12-27 13:40 ` [PATCH 6/8] [SCSI] scst: Fix online documentation Bart Van Assche
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:39 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
Improve the robustness of the code for parsing management commands
received via the sysfs file /sys/devices/scst/mgmt. Allow several spaces
between parameters where only a single space was allowed, and consistenly
ignore trailing newlines.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scst/scst_sysfs.c | 85 ++++++++++++++++++++++++--------------------
1 files changed, 46 insertions(+), 39 deletions(-)
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index ed10475..525f368 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -937,20 +937,24 @@ out_free:
static int scst_process_tgt_mgmt_store(char *cmd, struct scst_tgt *tgt)
{
+ char *arg, *tail;
int res;
res = -EINVAL;
+ arg = cmd;
+ cmd = scst_get_next_lexem(&arg);
+ tail = arg;
+ scst_get_next_lexem(&tail);
if (strcmp(cmd, "enable") == 0)
res = scst_process_tgt_enable_store(tgt, true);
else if (strcmp(cmd, "disable") == 0)
res = scst_process_tgt_enable_store(tgt, false);
- else if (strncmp(cmd, "set_cpu_mask ", 13) == 0) {
+ else if (strcmp(cmd, "set_cpu_mask") == 0) {
cpumask_t *cpumask;
BUG_ON(!tgt->default_acg);
- res = scst_alloc_and_parse_cpumask(&cpumask, cmd + 13,
- strlen(cmd + 13));
+ res = scst_alloc_and_parse_cpumask(&cpumask, arg, strlen(arg));
if (res)
goto out;
res = __scst_acg_process_cpu_mask_store(tgt, tgt->default_acg,
@@ -1264,20 +1268,25 @@ static const struct device_attribute *scst_devt_dev_attrs[] = {
static int scst_process_dev_mgmt_store(char *cmd, struct scst_device *dev)
{
+ char *arg, *tail;
int res;
res = -EINVAL;
- if (strncmp(cmd, "set_filename ", 13) == 0) {
+ arg = cmd;
+ cmd = scst_get_next_lexem(&arg);
+ tail = arg;
+ scst_get_next_lexem(&tail);
+ if (strcmp(cmd, "set_filename") == 0) {
res = -EPERM;
if (!dev->handler->set_filename)
goto out;
- res = dev->handler->set_filename(dev, cmd + 13);
- } else if (strncmp(cmd, "set_threads_num ", 16) == 0) {
+ res = dev->handler->set_filename(dev, arg);
+ } else if (strcmp(cmd, "set_threads_num") == 0) {
long num_threads;
- res = strict_strtol(cmd + 16, 0, &num_threads);
+ res = strict_strtol(arg, 0, &num_threads);
if (res) {
- PRINT_ERROR("Bad thread count %s", cmd + 16);
+ PRINT_ERROR("Bad thread count %s", arg);
goto out;
}
if (num_threads < 0) {
@@ -1285,13 +1294,12 @@ static int scst_process_dev_mgmt_store(char *cmd, struct scst_device *dev)
goto out;
}
res = scst_dev_set_threads_num(dev, num_threads);
- } else if (strncmp(cmd, "set_thread_pool_type ", 21) == 0) {
+ } else if (strcmp(cmd, "set_thread_pool_type") == 0) {
enum scst_dev_type_threads_pool_type newtpt;
- newtpt = scst_parse_threads_pool_type(cmd + 21,
- strlen(cmd + 21));
+ newtpt = scst_parse_threads_pool_type(arg, strlen(arg));
if (newtpt == SCST_THREADS_POOL_TYPE_INVALID) {
- PRINT_ERROR("Invalid thread pool type %s", cmd + 21);
+ PRINT_ERROR("Invalid thread pool type %s", arg);
goto out;
}
res = scst_dev_set_thread_pool_type(dev, newtpt);
@@ -2095,16 +2103,20 @@ out_del:
** ini_groups directory implementation.
**/
-static int scst_process_acg_mgmt_store(const char *cmd, struct scst_acg *acg)
+static int scst_process_acg_mgmt_store(char *cmd, struct scst_acg *acg)
{
+ char *arg, *tail;
int res;
res = -EINVAL;
- if (strncmp(cmd, "set_cpu_mask ", 13) == 0) {
+ arg = cmd;
+ cmd = scst_get_next_lexem(&arg);
+ tail = arg;
+ scst_get_next_lexem(&tail);
+ if (strcmp(cmd, "set_cpu_mask") == 0) {
cpumask_t *cpumask;
- res = scst_alloc_and_parse_cpumask(&cpumask, cmd + 13,
- strlen(cmd + 13));
+ res = scst_alloc_and_parse_cpumask(&cpumask, arg, strlen(arg));
if (res)
goto out;
res = __scst_acg_process_cpu_mask_store(acg->tgt, acg, cpumask);
@@ -3390,7 +3402,7 @@ static ssize_t scst_mgmt_store(struct device *device,
struct device_attribute *attr, const char *buf, size_t count)
{
ssize_t res;
- char *buffer, *path, *path_end, *cmd;
+ char *buffer, *path, *cmd, *tail;
enum mgmt_path_type mgmt_path_type;
struct scst_dev_type *devt;
struct scst_device *dev;
@@ -3409,19 +3421,13 @@ static ssize_t scst_mgmt_store(struct device *device,
goto out;
res = -EINVAL;
- if (strncmp(buffer, "in ", 3) != 0)
+ path = buffer;
+ cmd = scst_get_next_lexem(&path);
+ if (strcmp(cmd, "in") != 0)
goto out;
- path = buffer + 3;
- while (*path && isspace((u8)*path))
- path++;
- path_end = path;
- while (*path_end && !isspace((u8)*path_end))
- path_end++;
- *path_end++ = '\0';
- cmd = path_end;
- while (*cmd && isspace((u8)*cmd))
- cmd++;
+ tail = path;
+ scst_get_next_lexem(&tail);
res = scst_suspend_activity(true);
if (res)
@@ -3437,36 +3443,37 @@ static ssize_t scst_mgmt_store(struct device *device,
res = -EINVAL;
switch (mgmt_path_type) {
case DEVICE_PATH:
- res = scst_process_dev_mgmt_store(cmd, dev);
+ res = scst_process_dev_mgmt_store(tail, dev);
break;
case DEVICE_TYPE_PATH:
if (devt->add_device)
- res = scst_process_devt_mgmt_store(cmd, devt);
+ res = scst_process_devt_mgmt_store(tail, devt);
else
- res = scst_process_devt_pass_through_mgmt_store(cmd,
+ res = scst_process_devt_pass_through_mgmt_store(tail,
devt);
break;
case TARGET_TEMPLATE_PATH:
- res = scst_process_tgtt_mgmt_store(cmd, tgtt);
+ res = scst_process_tgtt_mgmt_store(tail, tgtt);
break;
case TARGET_PATH:
- res = scst_process_tgt_mgmt_store(cmd, tgt);
+ res = scst_process_tgt_mgmt_store(tail, tgt);
break;
case TARGET_LUNS_PATH:
- res = __scst_process_luns_mgmt_store(cmd, tgt, tgt->default_acg,
- true);
+ res = __scst_process_luns_mgmt_store(tail, tgt,
+ tgt->default_acg, true);
break;
case TARGET_INI_GROUPS_PATH:
- res = scst_process_ini_group_mgmt_store(cmd, tgt);
+ res = scst_process_ini_group_mgmt_store(tail, tgt);
break;
case ACG_PATH:
- res = scst_process_acg_mgmt_store(cmd, acg);
+ res = scst_process_acg_mgmt_store(tail, acg);
break;
case ACG_LUNS_PATH:
- res = __scst_process_luns_mgmt_store(cmd, acg->tgt, acg, false);
+ res = __scst_process_luns_mgmt_store(tail, acg->tgt, acg,
+ false);
break;
case ACG_INITIATOR_GROUPS_PATH:
- res = scst_process_acg_ini_mgmt_store(cmd, acg->tgt, acg);
+ res = scst_process_acg_ini_mgmt_store(tail, acg->tgt, acg);
break;
case PATH_NOT_RECOGNIZED:
break;
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/8] [SCSI] scst: Fix online documentation
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
` (4 preceding siblings ...)
2010-12-27 13:39 ` [PATCH 5/8] [SCSI] scst: Improve sysfs parsing robustness Bart Van Assche
@ 2010-12-27 13:40 ` Bart Van Assche
2010-12-27 13:43 ` [PATCH 8/8] Make SCST sysfs documentation more complete Bart Van Assche
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:40 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
Fix an error in the online documentation of /sys/devices/scst/mgmt,
reorder it and make that documentation more consistent.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scst/scst_sysfs.c | 37 +++++++++++++++++--------------------
1 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index 525f368..aadb066 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -3217,21 +3217,21 @@ static ssize_t scst_mgmt_show(struct device *device,
{
ssize_t count;
static const char help[] =
-/* device/<dev>/filename */
-"in device/<dev> <dev_cmd>\n"
/* scst_devt_mgmt or scst_devt_pass_through_mgmt */
"in device_driver/<devt> <devt_cmd>\n"
+/* device/<dev>/filename */
+"in device/<dev> <dev_cmd>\n"
/* scst_tgtt_mgmt */
"in target_driver/<tgtt> <tgtt_cmd>\n"
/* scst_tgt_mgmt */
-"in target_driver/<tgtt>/<target>/luns <tgt_cmd>\n"
+"in target_driver/<tgtt>/<target> <tgt_cmd>\n"
/* scst_luns_mgmt */
"in target_driver/<tgtt>/<target>/luns <luns_cmd>\n"
/* scst_ini_group_mgmt */
"in target_driver/<tgtt>/<target>/ini_groups <acg_mgmt_cmd>\n"
"in target_driver/<tgtt>/<target>/ini_groups/<acg> <acg_cmd>\n"
/* scst_acg_luns_mgmt */
-"in target_driver/<tgtt>/<target>/ini_groups/<acg>/luns <luns_cmd>\n"
+"in target_driver/<tgtt>/<target>/ini_groups/<acg>/luns <lun_cmd>\n"
/* scst_acg_ini_mgmt */
"in target_driver/<tgtt>/<target>/ini_groups/<acg>/initiators <acg_ini_cmd>\n"
"\n"
@@ -3243,12 +3243,12 @@ static ssize_t scst_mgmt_show(struct device *device,
"\n"
"devt_cmd syntax:\n"
"\n"
-"add_device device_name [parameters]\n"
-"del_device device_name\n"
+"add_device <device_name> [<parameters>]\n"
+"del_device <device_name>\n"
"add_attribute <attribute> <value>\n"
"del_attribute <attribute> <value>\n"
-"add_device_attribute device_name <attribute> <value>\n"
-"del_device_attribute device_name <attribute> <value>\n"
+"add_device_attribute <device_name> <attribute> <value>\n"
+"del_device_attribute <device_name> <attribute> <value>\n"
"\n"
"devt_cmd syntax for pass-through device types:\n"
"\n"
@@ -3257,12 +3257,9 @@ static ssize_t scst_mgmt_show(struct device *device,
"\n"
"tgtt_cmd syntax:\n"
"\n"
-"add_target target_name [parameters]\n"
-"del_target target_name\n"
-"add_attribute <attribute> <value>\n"
-"del_attribute <attribute> <value>\n"
-"add_target_attribute target_name <attribute> <value>\"\n"
-"del_target_attribute target_name <attribute> <value>\"\n"
+"add_target <target_name> [<parameters>]\n"
+"del_target <target_name>\n"
+"<target-driver-specific-command-and-parameters>\n"
"\n"
"where parameters is one or more <name>=<value> pairs separated by ';'\n"
"\n"
@@ -3272,13 +3269,13 @@ static ssize_t scst_mgmt_show(struct device *device,
"disable\n"
"set_cpu_mask <mask>\n"
"\n"
-"luns_cmd syntax:\n"
+"lun_cmd syntax:\n"
"\n"
-"add|del H:C:I:L lun [parameters]\n"
-"add VNAME lun [parameters]\n"
-"del lun\n"
-"replace H:C:I:L lun [parameters]\n"
-"replace VNAME lun [parameters]\n"
+"add|del H:C:I:L <lun> [<parameters>]\n"
+"add <vname> <lun> [<parameters>]\n"
+"del <lun>\n"
+"replace H:C:I:L <lun> [<parameters>]\n"
+"replace <vname> <lun> [<parameters>]\n"
"clear\n"
"\n"
"where parameters is either 'read_only' or empty.\n"
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 8/8] Make SCST sysfs documentation more complete
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
` (5 preceding siblings ...)
2010-12-27 13:40 ` [PATCH 6/8] [SCSI] scst: Fix online documentation Bart Van Assche
@ 2010-12-27 13:43 ` Bart Van Assche
2010-12-27 13:46 ` [PATCH 7/8] [SCSI] scst: Correct SCST core version number Bart Van Assche
2010-12-28 17:23 ` [PATCH 0/8] Address recent SCST comments Bart Van Assche
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:43 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
Since the previous time the SCST sysfs documentation has been posted, detailed
documentation about /sys/devices/scst/mgmt has been added and the
documentation of several sysfs attributes has been made more clear.
Note: this patch contains the entire SCST sysfs documentation since it has
been generated as follows:
git diff origin/master..scst Documentation/ABI/stable
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
sysfs-devices-scst | 318 +++++++++++++++++++++++++++++++++++
sysfs-devices-scst_target | 226 ++++++++++++++++++++++++
sysfs-devices-scst_target-scst_local | 23 ++
sysfs-devices-scst_tgt_dev | 217 +++++++++++++++++++++++
sysfs-driver-scst_target | 55 ++++++
sysfs-driver-scst_target-scst_local | 20 ++
sysfs-driver-scst_tgt_dev | 51 +++++
7 files changed, 910 insertions(+)
diff --git a/Documentation/ABI/stable/sysfs-devices-scst b/Documentation/ABI/stable/sysfs-devices-scst
new file mode 100644
index 0000000..e25d1a4
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-devices-scst
@@ -0,0 +1,318 @@
+What: /sys/devices/scst/mgmt
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Interface through which SCST management commands can be
+ issued. Read-write. Brief documentation of the syntax of these
+ commands can be obtained by reading this file (e.g. cat
+ /sys/devices/scst/mgmt). Detailed information is available
+ below.
+
+What: /sys/devices/scst/setup_id
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ SCST setup ID. Allows to identify otherwise identical SCST
+ setups on different systems. As an example, the
+ vdisk device handler uses this to generate the T10 vendor
+ specific identifier ID and USN of virtual devices. Must be
+ set before any virtual devices are created. Read-write.
+
+What: /sys/devices/scst/sgv/global_stats
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Global SGV (scatter/gather vector) cache statistics. Read-only.
+ An example:
+
+ $ cat sgv/global_stats
+ Inactive/active pages 0/0
+ Hi/lo watermarks [pages] 62208/0
+ Hi watermark releases/failures 0/0
+ Other allocs 0
+
+What: /sys/devices/scst/sgv/sgv/stats
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Statistics for the regular SGV cache. Read-only.
+
+What: /sys/devices/scst/sgv/sgv-clust/stats
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Statistics for the clustering SGV cache. Read-only.
+
+What: /sys/devices/scst/sgv/sgv-dma/stats
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Statistics for the DMA SGV cache. Read-only.
+
+What: /sys/devices/scst/threads
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Number of global I/O threads. The global I/O threads are used
+ by asynchronous device handlers or when explicitly configured
+ (i.e. when threads_num has been set to zero). Read-write.
+
+What: /sys/devices/scst/version
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ SCST version number. Read-only. An example:
+
+ $ cat /sys/devices/scst/version
+ 2.0.0
+
+-------------------------------------------------------------------------------
+
+
+Issuing management commands via /sys/devices/scst/mgmt
+
+
+1 Device driver commands
+========================
+
+1.1 Managing virtual devices
+----------------------------
+
+The syntax for creating a virtual device is as follows:
+
+echo "in device_driver/<devt> add_device <device_name> [<parameters>]" \
+ >/sys/devices/scst/mgmt
+
+where <devt> is the name of a virtual device handler and <parameters> is a
+semicolon-separated list of <name>=<value> pairs. The supported parameters are
+enumerated in the add_device_parameters file of each virtual device
+driver. E.g. for vdisk_fileio the parameters supported at device creation time
+are:
+
+$ cat /sys/bus/scst_tgt_dev/drivers/vdisk_fileio/add_device_parameters
+filename
+blocksize
+write_through
+nv_cache
+o_direct
+read_only
+removable
+thin_provisioned
+
+An example of how to create a vdisk_fileio device with NV-cache and thin
+provisioning enabled:
+
+echo "in device_driver/vdisk_fileio add_device disk01 filename=/home/exported-storage;nv_cache=1;thin_provisioned=1" >/sys/devices/scst/mgmt
+
+Removing virtual devices is possible via the del_device command. An example:
+
+echo "in device_driver/vdisk_fileio del_device disk01" >/sys/devices/scst/mgmt
+
+The remaining commands (add_attribute, del_attribute, add_device_attribute and
+del_device_attribute) allow to add or remove dynamically sysfs files for
+virtual devices and their drivers. There are not yet any virtual devices or
+virtual device drivers that allow this.
+
+1.2 Managing pass-through devices
+---------------------------------
+
+SCST supports SCSI pass-through. Before a LUN number can be assigned to a SCSI
+device, a device handler has to be assigned via the add_device command:
+
+echo "in device_driver/<devt> add_device H:C:I:L" >/sys/devices/scst/mgmt
+
+The syntax for disabling SCSI passthrough is similar:
+
+echo "in device_driver/<devt> del_device H:C:I:L" >/sys/devices/scst/mgmt
+
+In the above <devt> is the name of a pass-through handler and H:C:I:L is a
+quadruplet identifying a local SCSI device. An example:
+
+echo "in device_driver/dev_disk add_device 2:0:0:0" >/sys/devices/scst/mgmt
+echo "in device_driver/dev_disk del_device 2:0:0:0" >/sys/devices/scst/mgmt
+
+A list with the names of all currently loaded virtual and pass-through drivers
+can be obtained as follows:
+
+$ ls /sys/bus/scst_tgt_dev/drivers
+dev_cdrom dev_disk_perf dev_processor dev_tape_perf vdisk_fileio
+dev_changer dev_modisk dev_raid vcdrom vdisk_nullio
+dev_disk dev_modisk_perf dev_tape vdisk_blockio
+
+
+2 Device management commands
+============================
+
+The syntax of device management commands is as follows:
+
+echo "in device/<dev> <dev_cmd>" >/sys/devices/scst/mgmt
+
+where <dev> is a device name and <dev_cmd> is one of:
+
+set_filename <filename>
+set_threads_num <n>
+set_thread_pool_type <thread_pool_type>
+
+These commands are documented in
+Documentation/ABI/stable/sysfs-devices-scst_tgt_dev.
+
+
+3 Target driver commands
+========================
+
+3.1 Adding and removing targets
+-------------------------------
+
+Adding and removing targets dynamically is possible with the add_target and
+remove_target commands. This is supported by scst_local but not by ib_srpt. An
+example for scst_local:
+
+# echo "in target_driver/scst_local add_target tgt2 session_name=tgt2_sess" >/sys/devices/scst/mgmt
+# ls /sys/bus/scst_target/drivers/scst_local/tgt2/sessions
+tgt2_sess
+# echo "in target_driver/scst_local del_target tgt2" >/sys/devices/scst/mgmt
+# ls /sys/bus/scst_target/drivers/scst_local/tgt2/sessions
+ls: cannot access /sys/bus/scst_target/drivers/scst_local/tgt2/sessions: No such file or directory
+
+3.2 Driver-specific commands
+----------------------------
+
+Each driver can define additional commands. As an example, the scst_local
+driver supports the add_session and del_session commands. See also the
+driver-specific documentation for more information.
+
+
+4 Target commands
+=================
+
+The following target commands are supported via /sys/devices/scst/mgmt:
+enable, disable and set_cpu_mask. These commands are documented in
+Documentation/ABI/stable/sysfs-devices-scst_target.
+
+
+5 Target LUN commands
+=====================
+
+The syntax of the commands for managing the set of LUNs associated with a
+target is as follows:
+
+in target_driver/<tgtt>/<target>/luns <lun_cmd>
+
+where lun_cmd is one of:
+
+add|del H:C:I:L <lun> [<parameters>]
+add <vname> <lun> [<parameters>]
+del <lun>
+replace H:C:I:L <lun> [<parameters>]
+replace <vname> <lun> [<parameters>]
+clear
+
+and where <vname> is the name of a virtual device, <lun> is a LUN number and
+<parameters> is a semicolon-separated list of parameters. Currently the only
+supported parameter is the parameter called "read_only" (either 0 or 1).
+
+# echo "in target_driver/ib_srpt/ib_srpt_target_0/luns clear" >/sys/devices/scst/mgmt
+# echo "in target_driver/ib_srpt/ib_srpt_target_0/luns add disk01 0" >/sys/devices/scst/mgmt
+# readlink /sys/bus/scst_target/drivers/ib_srpt/ib_srpt_target_0/luns/0/device
+../../../disk01
+# echo "in target_driver/ib_srpt/ib_srpt_target_0/luns replace disk02 0" >/sys/devices/scst/mgmt
+# readlink /sys/bus/scst_target/drivers/ib_srpt/ib_srpt_target_0/luns/0/device
+../../../disk02
+
+
+6 Access control group commands
+===============================
+
+6.1 Access control group creation and removal
+---------------------------------------------
+
+A list of zero or more access control groups (ACGs) can be associated with
+each target. ACGs allow to define which initiator has access to which LUNs.
+The syntax for creating and removing ACGs is:
+
+in target_driver/<tgtt>/<target>/ini_groups <acg_mgmt_cmd>
+
+where <acg_mgmt_cmd> is one of:
+
+create <group_name>
+del <group_name>
+
+An example:
+
+# echo "in target_driver/ib_srpt/ib_srpt_target_0/ini_groups create group1" >/sys/devices/scst/mgmt
+# ls /sys/bus/scst_target/drivers/ib_srpt/ib_srpt_target_0/ini_groups
+group1
+
+6.2 Access control group properties
+-----------------------------------
+
+The access control group CPU mask can be modified via the set_cpu_mask
+command. See also Documentation/ABI/stable/sysfs-devices-scst_target for more
+information.
+
+6.3 Managing ACG LUNs
+---------------------
+
+The syntax of the commands for managing the LUNs associated with an ACG is as
+follows:
+
+in target_driver/<tgtt>/<target>/ini_groups/<acg>/luns <lun_cmd>
+
+add|del H:C:I:L <lun> [<parameters>]
+add <vname> <lun> [<parameters>]
+del <lun>
+replace H:C:I:L <lun> [<parameters>]
+replace <vname> <lun> [<parameters>]
+clear
+
+See also section 5 for more information about these commands. An example:
+
+# echo "in target_driver/ib_srpt/ib_srpt_target_0/ini_groups/group1/luns add disk01 0" >/sys/devices/scst/mgmt
+# readlink /sys/bus/scst_target/drivers/ib_srpt/ib_srpt_target_0/ini_groups/group1/luns/0/device
+../../../disk01
+
+6.4 Associating initiators with an ACG
+--------------------------------------
+
+The syntax of the commands for manipulating the list of initiators associated
+with an ACG is as follows:
+
+in target_driver/<tgtt>/<target>/ini_groups/<acg>/initiators <acg_ini_cmd>
+
+where <acg_ini_cmd> is one of:
+
+add <initiator_name>
+del <initiator_name>
+move <initiator_name> <dest_group_name>
+clear
+
+These commands allow to add an initiator name to the initiator name list of an
+ACG, remove an initiator name from that list, move an initatior name from one
+ACG to another or to clear that initiator name list entirely. For the "add"
+and "del" commands the initiator name may be a pattern instead of a literal
+initator name. The following wildcard characters are supported:
+- '*' matches any substring.
+- '?' matches any character.
+- '!' at the start of a pattern will cause the pattern to match with every
+ initiator name that does not match with the subsequent pattern.
+As an example, the pattern "!abc*" will match with every initiator name that
+does not start with the sequence "abc".
+
+Below one can find an example for the target driver ib_srpt. For the SRP
+protocol initiator names are 128-bit hexadecimal numbers (a HCA port GUID).
+Associating the ACG called "group1" with the two HCA ports with GUIDs $port1
+and $port2 is possible as follows:
+
+# port1="0x00000000000000000002c9030005f34b"
+# port2="0x00000000000000000002c9030005f34c"
+# echo "in target_driver/ib_srpt/ib_srpt_target_0/ini_groups/group1/initiators add $port1" >/sys/devices/scst/mgmt
+# echo "in target_driver/ib_srpt/ib_srpt_target_0/ini_groups/group1/initiators add $port2" >/sys/devices/scst/mgmt
+# ls /sys/bus/scst_target/drivers/ib_srpt/ib_srpt_target_0/ini_groups/group1/initiators
+0x00000000000000000002c9030005f34b 0x00000000000000000002c9030005f34c
+
+The cumulative effect of the commands shown as examples in sections 6.1, 6.3
+and this section is that the initiator identified by GUID $ini1 and only that
+initiator will see the LUNs defined in the ACG with name "group1". If no other
+ACGs have been defined, all other initiators that log in to the same target
+will see the LUNs associated with the target itself. Making a LUN available to
+some hosts and not available to other hosts is also called LUN masking.
diff --git a/Documentation/ABI/stable/sysfs-devices-scst_target b/Documentation/ABI/stable/sysfs-devices-scst_target
new file mode 100644
index 0000000..2d3a388
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-devices-scst_target
@@ -0,0 +1,226 @@
+What: /sys/bus/scst_target/devices/*/addr_method
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ LUN addressing method used by this target when e.g. responding
+ to a REPORT_LUNS command. One of the values PERIPHERAL, FLAT
+ or LUN. Read-write. While most initiators work well with the
+ default addressing method (PERIPHERAL), some initiators need
+ the FLAT addressing method (HP/UX) or LUN addressing (AIX).
+ Note: the LUN addressing method can also be configured for a
+ security group. That allows to define the LUN addressing
+ method on a per-initiator basis. See also SAM-4, section 4.6,
+ Logical Unit Numbers.
+
+What: /sys/bus/scst_target/devices/*/cpu_mask
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Target-specific CPU mask in hexadecimal format. While this
+ file is read-only, changing the CPU mask is possible via
+ the set_cpu_mask command. As an example, the commands below
+ show how to make scst_local use any CPU for processing SCSI
+ commands except CPUs 0, 1, 2 or 3:
+
+ # cat /sys/bus/scst_target/devices/scst_local_tgt/cpu_mask
+ ffffffff,ffffffff
+ # echo "in target_driver/scst_local/scst_local_tgt set_cpu_mask ffffffff,fffffff0" >/sys/devices/scst/mgmt
+ # cat /sys/bus/scst_target/devices/scst_local_tgt/cpu_mask
+ ffffffff,fffffff0
+
+What: /sys/bus/scst_target/devices/*/force_close
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ If this file exists, writing any data to this file will
+ forcibly close all sessions associated with a target.
+ Write-only.
+
+What: /sys/bus/scst_target/devices/*/enabled
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Whether a target is currently enabled ("1") or disabled ("0").
+ No new connections are accepted for a
+ target that is in the disabled state. Defaults to disabled
+ ("0"). This allows to configure a target before any connections
+ are accepted. Read-only. Notes:
+ - Enabling a target is only allowed if its relative target
+ port identifier is unique.
+ - Enabling or disabling a target is possible via the SCST
+ device. An example:
+
+ $ echo "in target_driver/ib_srpt/ib_srpt_target_0 disable" >/sys/devices/scst/mgmt
+ $ cat /sys/devices/ib_srpt_target_0/enabled
+ 0
+ $ echo "in target_driver/ib_srpt/ib_srpt_target_0 enable" >/sys/devices/scst/mgmt
+ $ cat /sys/devices/ib_srpt_target_0/enabled
+
+What: /sys/bus/scst_target/devices/*/hw_target
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Allows to distinguish hardware and virtual targets. The value
+ 1 means that there is a one-to-one correspondence between this
+ target and a hardware entity, and the value 0 means that there
+ is no such one-to-one correspondence. This file only exists
+ when the target driver supports both hardware and virtual
+ targets. Read-only.
+
+What: /sys/bus/scst_target/devices/*/ini_groups/<acg>/addr_method
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ LUN addressing method for this ACG (access control group).
+ Read-write.
+
+What: /sys/bus/scst_target/devices/*/ini_groups/<acg>/cpu_mask
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ CPU mask associated with this ACG. Read-only. Modifying this
+ CPU mask is possible via the set_cpu_mask command. An example:
+
+ # cat /sys/bus/scst_target/devices/scst_local_tgt/ini_groups/group1/cpu_mask
+ ffffffff,ffffffff
+ # echo "in target_driver/scst_local/scst_local_tgt/ini_groups/group1 set_cpu_mask 1" >/sys/devices/scst/mgmt
+ # cat /sys/bus/scst_target/devices/scst_local_tgt/ini_groups/group1/cpu_mask
+ 00000000,00000001
+
+What: /sys/bus/scst_target/devices/*/ini_groups/<acg>/initiators/<ini>
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Name of an initiator associated with this ACG. The contents
+ of this file is the same as the filename. Read-only.
+
+What: /sys/bus/scst_target/devices/*/ini_groups/<acg>/initiators/luns/parameters
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Names of the parameters supported when adding a LUN to an ACG,
+ one per line. Read-only.
+
+What: /sys/bus/scst_target/devices/*/ini_groups/<acg>/initiators/luns/<number>/device
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Soft link to the SCST device associated with this LUN. An
+ example:
+ $ readlink /sys/bus/scst_target/devices/scst_local_tgt/ini_groups/group1/luns/0/device
+ ../../../../../disk01
+
+What: /sys/bus/scst_target/devices/*/ini_groups/<acg>/initiators/luns/<number>/read_only
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Whether the LUN has been exported read-only ("1") or
+ read-write ("0"). This file is read-only.
+
+What: /sys/bus/scst_target/devices/*/io_grouping_type
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ I/O context sharing setting. I/O context sharing may improve
+ I/O performance significantly when using the CFQ I/O scheduler
+ and rotating storage media. The allowed values for this
+ parameter are:
+ * "auto" Use one I/O context per initiator.
+ * "this_group_only" Use the same I/O context for all
+ sessions associated with this target.
+ * "never" Never share I/O contexts.
+ * <I/O context number> Share an I/O context over all targets
+ that have this I/O context number. Must
+ be a number above zero.
+ Read-write.
+
+What: /sys/bus/scst_target/devices/*/luns/parameters
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Names of the parameters supported when adding a LUN to a
+ target, one per line. Read-only.
+
+What: /sys/bus/scst_target/devices/*/luns/<number>/device
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Soft link to the exported SCST device. Read-only.
+
+What: /sys/bus/scst_target/devices/*/luns/<number>/read_only
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Whether this LUN is read-only (1) or read-write (0).
+ Read-create.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/active_commands
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Number of SCSI commands being executed for this session.
+ Read-only.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/commands
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Number of SCSI commands being executed for this session.
+ Read-only.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/force_close
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Attribute that allows to forcibly close a session. Optional,
+ write-only.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/initiator_name
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Session name. For most target drivers this is a name that
+ identifies the initiator. Read-only.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/latency
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Latency statistics for this session. Only available if
+ CONFIG_SCST_MEASURE_LATENCY has been enabled in the
+ kernel configuration. Read-only.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/lun<number>/active_commands
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Number of active commands. Read-only.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/lun<number>/latency
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Latency statistics for this LUN. Only available if
+ CONFIG_SCST_MEASURE_LATENCY has been enabled in the kernel
+ configuration. Read-only.
+
+What: /sys/bus/scst_target/devices/*/sessions/<session>/luns
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Soft link to the LUNs exported via this session. That soft
+ link either points to the LUNs associated with the
+ corresponding target or to the LUNs associated with an ACG.
+ Examples:
+
+ $ readlink /sys/devices/scst_local_tgt/sessions/scst_local_host/luns
+ ../../luns
+ $ readlink /sys/devices/ib_srpt_target_0/sessions/0x00000000000000000002c9030005f34b/luns
+../../ini_groups/initiator1/luns
+
+What: /sys/bus/scst_target/devices/*/rel_tgt_id
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ SCSI Relative Target Port Identifier, which is used by e.g.
+ persistent reservation commands. Read-write.
diff --git a/Documentation/ABI/stable/sysfs-devices-scst_target-scst_local b/Documentation/ABI/stable/sysfs-devices-scst_target-scst_local
new file mode 100644
index 0000000..4306ee0
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-devices-scst_target-scst_local
@@ -0,0 +1,23 @@
+What: /sys/bus/scst_target/devices/scst_local/phys_transport_version
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ SCSI physical transport version. Defines which physical
+ interface scst_local will resemble. See also SPC-4 for more
+ information. Read-write.
+
+What: /sys/bus/scst_target/devices/scst_local/scsi_transport_version
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ SCSI transport version. Defines which SCSI transport
+ scst_local will resemble. The default is SAS. See also SPC-4
+ for more information. Read-write.
+
+What: /sys/bus/scst_target/devices/scst_local/sessions/*/transport_id
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ SCSI transport ID in binary format. Necessary e.g. for
+ implementing persistent reservation support. See also SPC-4
+ for more information. Read-write.
diff --git a/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev b/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
new file mode 100644
index 0000000..698249a
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-devices-scst_tgt_dev
@@ -0,0 +1,217 @@
+What: /sys/bus/scst_tgt_dev/device/*/blocksize
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Block size that has been configured for a virtual device. Must
+ be a power of two and equal to or above 512. Read-create.
+
+What: /sys/bus/scst_tgt_dev/device/*/exported/export<nr>
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Zero or more soft links to the LUNs via which this device
+ has been exported. An example:
+
+ $ for f in /sys/bus/scst_tgt_dev/devices/disk01/exported/export*; do echo $f; readlink $f; done
+ /sys/bus/scst_tgt_dev/devices/disk01/exported/export0
+ ../../ib_srpt_target_0/ini_groups/initiator1/luns/0
+ /sys/bus/scst_tgt_dev/devices/disk01/exported/export1
+ ../../ib_srpt_target_0/luns/0
+ /sys/bus/scst_tgt_dev/devices/disk01/exported/export2
+ ../../ib_srpt_target_1/luns/0
+
+What: /sys/bus/scst_tgt_dev/device/*/filename
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ For virtual devices, the absolute path of the associated file
+ or device. Read-create for vdisk_blockio and vdisk_fileio
+ devices and read-only for vcdrom devices. For vcdrom devices
+ this parameter can be modified via the set_filename
+ command. Configuring a non-empty path is interpret as
+ inserting a medium and setting an empty path is interpret as
+ removing a medium. An example of how to add a vcdrom device,
+ how to trigger medium insertion and medium removal:
+
+ # echo "in device_driver/vcdrom add_device vcdrom1" >/sys/devices/scst/mgmt
+ # echo "in device/vcdrom1 set_filename /cdrom.iso" >/sys/devices/scst/mgmt
+ # cat /sys/bus/scst_tgt_dev/devices/vcdrom1/filename
+ /cdrom.iso
+ # echo "in device/vcdrom1 set_filename" >/sys/devices/scst/mgmt
+ # od -c /sys/bus/scst_tgt_dev/devices/vcdrom1/filename
+ 0000000 \n
+ 0000001
+
+What: /sys/bus/scst_tgt_dev/device/*/nv_cache
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Whether or not acknowledging writes early has been enabled for
+ a vdisk_blockio or vdisk_fileio device. The value 1 means that
+ acknowledging writes early has been enabled and the value 0
+ means that acknowledging writes early has been disabled.
+ Warning: while enabling early write acknowledgements does
+ decrease I/O latency, for a storage medium that neither has a
+ non-volatile cache nor an UPS enabling early write
+ acknowledgements may result in data loss in case of a power
+ failure. Read-create.
+
+What: /sys/bus/scst_tgt_dev/device/*/o_direct
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ The value 1 means that all caching has been disabled (direct
+ or non-buffered I/O) for a vdisk_fileio device and the value 0
+ means that caching is enabled (asynchronous or buffered
+ I/O). Read-create.
+
+What: /sys/bus/scst_tgt_dev/device/*/read_only
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ For virtual devices, whether or not to deny write commands. 1
+ stands for read-only and 0 for read-write. The "read_only"
+ file itself is read-create.
+
+What: /sys/bus/scst_tgt_dev/device/*/removable
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ For vdisk_blockio, vdisk_fileio and vdisk_nullio devices,
+ whether or not the underlying storage medium has been
+ configured as removable when the virtual device was
+ created. The value "1" means removable and the value "0" means
+ not removable. Read-create.
+
+What: /sys/bus/scst_tgt_dev/device/*/resync_size
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ For vdisk_fileio and vdisk_blockio devices, writing any data
+ to this file will cause SCST to reexamine the size of the
+ underlying storage medium. Write-only. See also the "filename"
+ and "size_mb" files.
+
+What: /sys/bus/scst_tgt_dev/device/*/scsi_device
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ For SCSI devices, the device identification in H:C:I:L format.
+ Read-only. An example:
+
+ $ cat /sys/bus/scst_tgt_dev/devices/1:0:0:0/scsi_device
+ 1:0:0:0
+
+What: /sys/bus/scst_tgt_dev/device/*/size_mb
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ For virtual devices, the internally cached size in MB of the
+ underlying storage device (1 MB = 1048576 bytes). Read-only.
+ See also the "filename" and "resync_size" files.
+
+What: /sys/bus/scst_tgt_dev/device/*/t10_dev_id
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ SCSI device ID associated with the virtual device. This is the
+ ID reported e.g. via the Device Identification page (0x83) of
+ the INQUIRY command. Read-write.
+
+What: /sys/bus/scst_tgt_dev/device/*/thin_provisioned
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Whether or not thin provisioning support has been enabled (1)
+ or not (0) for a virtual device. If thin provisioning support
+ has been enabled, SCST will report to the SCSI initiator that
+ thin provisioning is supported and SCSI UNMAP commands will be
+ translated to deallocation requests for the underlying
+ storage. See also SBC-3 for further information. Read-create.
+
+What: /sys/bus/scst_tgt_dev/device/*/threads_num
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Zero if the global thread pool is used for processing SCSI
+ commands received for a device or the number of threads of a
+ dedicated thread pool that is used for processing SCSI
+ commands received for this device (any number above zero).
+ Read-create. Modifying this parameter is possible via the
+ set_threads_num command. An example:
+
+ # cat /sys/bus/scst_tgt_dev/devices/disk01/threads_num
+ 2
+ # echo "in device/disk01 set_threads_num 4" >/sys/devices/scst/mgmt
+ # cat /sys/bus/scst_tgt_dev/devices/disk01/threads_num
+ 4
+
+What: /sys/bus/scst_tgt_dev/device/*/threads_pool_type
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Thread pool configuration setting. This file will contain the
+ text "Async" if the global thread pool is used for processing
+ SCSI commands for this device. If a dedicated thread pool has
+ been configured then there is either one thread pool per
+ initiator ("per_initiator") or one thread pool for all
+ initiators ("shared"). Read-create. Modifying this parameter
+ is possible via the set_thread_pool_type command. An example:
+
+ # cat /sys/bus/scst_tgt_dev/devices/disk01/threads_pool_type
+ shared
+ # echo "in device/disk01 set_thread_pool_type per_initiator" >/sys/devices/scst/mgmt
+ # cat /sys/bus/scst_tgt_dev/devices/disk01/threads_pool_type
+ per_initiator
+
+What: /sys/bus/scst_tgt_dev/device/*/type
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ A number in the range 0..17 representing the SCSI peripheral
+ device type as defined in SPC-4. Read-only. The defined types
+ and their meaning are:
+
+ 0 Direct access block device (e.g., magnetic disk)
+ 1 Sequential-access device (e.g., magnetic tape)
+ 2 Printer device
+ 3 Processor device
+ 4 Write-once device (e.g., some optical disks)
+ 5 CD/DVD device
+ 6 Scanner device (obsolete)
+ 7 Optical memory device (e.g., some optical disks)
+ 8 Media changer device (e.g., jukeboxes)
+ 9 Communications device (obsolete)
+ 10 Obsolete
+ 11 Obsolete
+ 12 Storage array controller device (e.g., RAID)
+ 13 Enclosure services device
+ 14 Simplified direct-access device (e.g., magnetic disk)
+ 15 Optical card reader/writer device
+ 16 Bridge Controller Commands
+ 17 Object-based Storage Device
+
+What: /sys/bus/scst_tgt_dev/device/*/type_description
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Textual description of the SCSI peripheral device type as
+ defined in SPC-4. See also the description of the
+ "type" file for a list of descriptions. Read-only.
+
+What: /sys/bus/scst_tgt_dev/device/*/usn
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Unique serial number of a virtual device as reported e.g. by
+ the SCSI INQUIRY response. This number is generated by SCST
+ during creation of the virtual device by hashing the device
+ name and the setup ID. Read-only.
+
+What: /sys/bus/scst_tgt_dev/device/*/write_through
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Whether or not write-back caching has been disabled for a
+ vdisk_fileio device. The value 0 stands for write-back mode
+ and the value 1 stands for write-through mode. Read-create.
diff --git a/Documentation/ABI/stable/sysfs-driver-scst_target b/Documentation/ABI/stable/sysfs-driver-scst_target
new file mode 100644
index 0000000..8592cec
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-driver-scst_target
@@ -0,0 +1,55 @@
+What: /sys/bus/scst_target/drivers/*/add_target
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Whether or not dynamic creation and removal of SCSI targets is
+ supported by a particular SCST target driver. The value 1
+ means that dynamic target creation/removal is supported
+ and the value 0 means that dynamic target creation/removal is
+ not supported. Read-only.
+
+What: /sys/bus/scst_target/drivers/*/add_target_parameters
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Names of the parameters that may be specified at target
+ creation time. Each parameter name appears on a separate
+ line. This file only exists if dynamic target creation and
+ removal is supported. Read-only.
+
+What: /sys/bus/scst_target/drivers/*/driver_attributes
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Names of the SCSI target driver sysfs files that may be created
+ or removed dynamically. Each file name appears on a
+ separate line. This file only exists if dynamic target driver
+ file creation and removal is supported. Read-only.
+
+What: /sys/bus/scst_target/drivers/*/enabled
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Allows to enable or disable the operation of a SCST target
+ driver. The value 1 means enabled and 0 means disabled.
+ Defaults to 0 (disabled). This allows to configure a target
+ driver before it becomes operational. Only exists if disabling
+ the particual target driver is supported. Read-write.
+
+What: /sys/bus/scst_target/drivers/*/target_attributes
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Names of the sysfs files that may be created and/or removed
+ dynamically for a target. Each file name appears on a separate
+ line. This file only exists if dynamic target file creation
+ and removal is supported. Read-only.
+
+What: /sys/bus/scst_target/drivers/*/version
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Target driver version. Read-only. An example:
+
+ $ cat /sys/bus/scst_target/drivers/scst_local/version
+ 1.0.0
diff --git a/Documentation/ABI/stable/sysfs-driver-scst_target-scst_local b/Documentation/ABI/stable/sysfs-driver-scst_target-scst_local
new file mode 100644
index 0000000..3ea28dc
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-driver-scst_target-scst_local
@@ -0,0 +1,20 @@
+What: /sys/bus/scst_target/drivers/scst_local/aborts
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ Number of SCSI commands that have been aborted by the SCSI
+ initiator. Read-only.
+
+What: /sys/bus/scst_target/drivers/scst_local/device_resets
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ Number of SCSI device resets that have been performed by the
+ SCSI initiator. Read-only.
+
+What: /sys/bus/scst_target/drivers/scst_local/target_resets
+Date: December 2010
+Contact: Richard Sharpe <realrichardsharpe@gmail.com>
+Description:
+ Number of SCSI target resets that have been performed by the
+ SCSI initiator. Read-only.
diff --git a/Documentation/ABI/stable/sysfs-driver-scst_tgt_dev b/Documentation/ABI/stable/sysfs-driver-scst_tgt_dev
new file mode 100644
index 0000000..87fc58f
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-driver-scst_tgt_dev
@@ -0,0 +1,51 @@
+What: /sys/bus/scst_tgt_dev/drivers/*/add_device_parameters
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Names of the parameters supported when adding a device. Each
+ parameter name appears on a separate line. Read-only.
+ An example:
+
+ $ cat /sys/bus/scst_tgt_dev/drivers/vdisk_fileio/add_device_parameters
+ filename
+ blocksize
+ write_through
+ nv_cache
+ o_direct
+ read_only
+ removable
+ thin_provisioned
+
+What: /sys/bus/scst_tgt_dev/drivers/*/type
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ A number in the range 0..17 representing the SCSI peripheral
+ device type of the devices managed by this driver as defined
+ in SPC-4. Read-only. The defined types and their meaning are:
+
+ 0 Direct access block device (e.g., magnetic disk)
+ 1 Sequential-access device (e.g., magnetic tape)
+ 2 Printer device
+ 3 Processor device
+ 4 Write-once device (e.g., some optical disks)
+ 5 CD/DVD device
+ 6 Scanner device (obsolete)
+ 7 Optical memory device (e.g., some optical disks)
+ 8 Media changer device (e.g., jukeboxes)
+ 9 Communications device (obsolete)
+ 10 Obsolete
+ 11 Obsolete
+ 12 Storage array controller device (e.g., RAID)
+ 13 Enclosure services device
+ 14 Simplified direct-access device (e.g., magnetic disk)
+ 15 Optical card reader/writer device
+ 16 Bridge Controller Commands
+ 17 Object-based Storage Device
+
+What: /sys/bus/scst_tgt_dev/drivers/*/type_description
+Date: December 2010
+Contact: Bart Van Assche <bvanassche@acm.org>
+Description:
+ Textual description of the SCSI peripheral type of the devices
+ managed by this driver. Read-only.
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 7/8] [SCSI] scst: Correct SCST core version number
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
` (6 preceding siblings ...)
2010-12-27 13:43 ` [PATCH 8/8] Make SCST sysfs documentation more complete Bart Van Assche
@ 2010-12-27 13:46 ` Bart Van Assche
2010-12-28 17:23 ` [PATCH 0/8] Address recent SCST comments Bart Van Assche
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-27 13:46 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
Change the version number of the SCST core from 2.1.0-pre1 into 2.0.0.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
include/scst/scst.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/scst/scst.h b/include/scst/scst.h
index e44547a..9034624 100644
--- a/include/scst/scst.h
+++ b/include/scst/scst.h
@@ -48,7 +48,7 @@
#define SCST_VERSION(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + d)
#define SCST_VERSION_CODE SCST_VERSION(2, 0, 0, 0)
#define SCST_VERSION_STRING_SUFFIX
-#define SCST_VERSION_STRING "2.1.0-pre1" SCST_VERSION_STRING_SUFFIX
+#define SCST_VERSION_STRING "2.0.0" SCST_VERSION_STRING_SUFFIX
#define SCST_INTERFACE_VERSION \
SCST_VERSION_STRING "$Revision: 3139 $" SCST_CONST_VERSION
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 0/8] Address recent SCST comments
2010-12-27 13:35 [PATCH 0/8] Address recent SCST comments Bart Van Assche
` (7 preceding siblings ...)
2010-12-27 13:46 ` [PATCH 7/8] [SCSI] scst: Correct SCST core version number Bart Van Assche
@ 2010-12-28 17:23 ` Bart Van Assche
8 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2010-12-28 17:23 UTC (permalink / raw)
To: linux-scsi
Cc: scst-devel, Greg Kroah-Hartman, Konrad Rzeszutek Wilk,
Vladislav Bolkhovitin, Richard Sharpe
On Monday 27 December 2010 14:35:33 Bart Van Assche wrote:
> The paches in this patch series address the following issues:
> - Make sure that all SCST sysfs attributes have only one value per file.
> [ ... ]
Note: someone was so kind to inform me (via private e-mail) that two more
classes of sysfs files did not yet satisfy the one-value-per-file rule, namely
the SGV cache statistics and the I/O latency statistics. The two patches
below move these sysfs files to debugfs too:
[SCSI] scst: Move SGV cache statistics to debugfs
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
Documentation/ABI/stable/sysfs-devices-scst | 31 -----
drivers/scst/Makefile | 4 +-
drivers/scst/scst_mem.c | 168 +++-----------------------
drivers/scst/scst_mem.h | 22 ++++-
drivers/scst/scst_mem_stats.c | 168 +++++++++++++++++++++++++++
drivers/scst/scst_mem_stats.h | 21 ++++
drivers/scst/scst_priv.h | 2 -
drivers/scst/scst_sysfs.c | 9 --
drivers/scst/scst_tracing.c | 17 +++-
9 files changed, 246 insertions(+), 196 deletions(-)
create mode 100644 drivers/scst/scst_mem_stats.c
create mode 100644 drivers/scst/scst_mem_stats.h
diff --git a/Documentation/ABI/stable/sysfs-devices-scst b/Documentation/ABI/stable/sysfs-devices-scst
index e25d1a4..8e02cff 100644
--- a/Documentation/ABI/stable/sysfs-devices-scst
+++ b/Documentation/ABI/stable/sysfs-devices-scst
@@ -18,37 +18,6 @@ Description:
specific identifier ID and USN of virtual devices. Must be
set before any virtual devices are created. Read-write.
-What: /sys/devices/scst/sgv/global_stats
-Date: December 2010
-Contact: Bart Van Assche <bvanassche@acm.org>
-Description:
- Global SGV (scatter/gather vector) cache statistics. Read-only.
- An example:
-
- $ cat sgv/global_stats
- Inactive/active pages 0/0
- Hi/lo watermarks [pages] 62208/0
- Hi watermark releases/failures 0/0
- Other allocs 0
-
-What: /sys/devices/scst/sgv/sgv/stats
-Date: December 2010
-Contact: Bart Van Assche <bvanassche@acm.org>
-Description:
- Statistics for the regular SGV cache. Read-only.
-
-What: /sys/devices/scst/sgv/sgv-clust/stats
-Date: December 2010
-Contact: Bart Van Assche <bvanassche@acm.org>
-Description:
- Statistics for the clustering SGV cache. Read-only.
-
-What: /sys/devices/scst/sgv/sgv-dma/stats
-Date: December 2010
-Contact: Bart Van Assche <bvanassche@acm.org>
-Description:
- Statistics for the DMA SGV cache. Read-only.
-
What: /sys/devices/scst/threads
Date: December 2010
Contact: Bart Van Assche <bvanassche@acm.org>
diff --git a/drivers/scst/Makefile b/drivers/scst/Makefile
index 38b3f4e..a27cf92 100644
--- a/drivers/scst/Makefile
+++ b/drivers/scst/Makefile
@@ -7,7 +7,7 @@ scst-y += scst_lib.o
scst-y += scst_sysfs.o
scst-y += scst_mem.o
scst-y += scst_debug.o
-scst-$(CONFIG_SCST_DEBUG) += scst_tracing.o
-scst-$(CONFIG_SCST_TRACING) += scst_tracing.o
+scst-$(CONFIG_SCST_DEBUG) += scst_tracing.o scst_mem_stats.o
+scst-$(CONFIG_SCST_TRACING) += scst_tracing.o scst_mem_stats.o
obj-$(CONFIG_SCST) += scst.o dev_handlers/ scst_local/ srpt/
diff --git a/drivers/scst/scst_mem.c b/drivers/scst/scst_mem.c
index 048f848..b9d84f5 100644
--- a/drivers/scst/scst_mem.c
+++ b/drivers/scst/scst_mem.c
@@ -29,6 +29,7 @@
#include <scst/scst.h>
#include "scst_priv.h"
#include "scst_mem.h"
+#include "scst_mem_stats.h"
#define SGV_DEFAULT_PURGE_INTERVAL (60 * HZ)
#define SGV_MIN_SHRINK_INTERVAL (1 * HZ)
@@ -66,12 +67,6 @@ static struct shrinker sgv_shrinker;
*/
static LIST_HEAD(sgv_pools_list);
-static struct kobj_type pool_ktype;
-
-static struct kobject *scst_sgv_kobj;
-static int scst_sgv_sysfs_create(struct sgv_pool *pool, struct kobject *parent);
-static void scst_sgv_sysfs_del(struct sgv_pool *pool);
-
static inline bool sgv_pool_clustered(const struct sgv_pool *pool)
{
return pool->clustering_type != sgv_no_clustering;
@@ -1412,7 +1407,7 @@ static int sgv_pool_init(struct sgv_pool *pool, const char *name,
list_add_tail(&pool->sgv_pools_list_entry, &sgv_pools_list);
spin_unlock_bh(&sgv_pools_lock);
- res = scst_sgv_sysfs_create(pool, scst_sgv_kobj);
+ res = scst_sgv_pool_debugfs_create(pool);
if (res != 0)
goto out_del;
@@ -1486,6 +1481,8 @@ EXPORT_SYMBOL_GPL(sgv_pool_flush);
static void sgv_pool_destroy(struct sgv_pool *pool)
{
+ int i;
+
cancel_delayed_work_sync(&pool->sgv_purge_work);
sgv_pool_flush(pool);
@@ -1496,10 +1493,15 @@ static void sgv_pool_destroy(struct sgv_pool *pool)
spin_unlock_bh(&sgv_pools_lock);
mutex_unlock(&sgv_pools_mutex);
- scst_sgv_sysfs_del(pool);
+ scst_sgv_pool_debugfs_del(pool);
- kobject_put(&pool->sgv_kobj);
- return;
+ for (i = 0; i < pool->max_caches; i++) {
+ if (pool->caches[i])
+ kmem_cache_destroy(pool->caches[i]);
+ pool->caches[i] = NULL;
+ }
+
+ kfree(pool);
}
/**
@@ -1523,17 +1525,6 @@ void sgv_pool_set_allocator(struct sgv_pool *pool,
EXPORT_SYMBOL_GPL(sgv_pool_set_allocator);
/**
- * sgv_kobj_to_pool() - Convert a kobject pointer to a pool pointer.
- *
- * Must be called from inside an sgv pool sysfs .show() or .store() callback
- * function only.
- */
-static inline struct sgv_pool *sgv_kobj_to_pool(struct kobject *kobj)
-{
- return container_of(kobj, struct sgv_pool, sgv_kobj);
-}
-
-/**
* sgv_pool_create - creates and initializes an SGV pool
* @name: the name of the SGV pool
* @clustered: sets type of the pages clustering.
@@ -1591,8 +1582,6 @@ struct sgv_pool *sgv_pool_create(const char *name,
goto out_unlock;
}
- kobject_init(&pool->sgv_kobj, &pool_ktype);
-
rc = sgv_pool_init(pool, name, clustering_type, single_alloc_pages,
purge_interval);
if (rc != 0)
@@ -1603,7 +1592,7 @@ out_unlock:
return pool;
out_free:
- kobject_put(&pool->sgv_kobj);
+ kfree(pool);
goto out_unlock;
}
EXPORT_SYMBOL_GPL(sgv_pool_create);
@@ -1707,15 +1696,13 @@ void scst_sgv_pools_deinit(void)
return;
}
-static ssize_t sgv_sysfs_stat_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+
+ssize_t sgv_pool_stat_show(struct sgv_pool *pool, char *buf)
{
- struct sgv_pool *pool;
int i, total = 0, hit = 0, merged = 0, allocated = 0;
int oa, om, res;
- pool = sgv_kobj_to_pool(kobj);
-
for (i = 0; i < SGV_POOL_ELEMENTS; i++) {
int t;
@@ -1763,14 +1750,10 @@ static ssize_t sgv_sysfs_stat_show(struct kobject *kobj,
return res;
}
-static ssize_t sgv_sysfs_stat_reset(struct kobject *kobj,
- struct kobj_attribute *attr, const char *buf, size_t count)
+void sgv_pool_stat_reset(struct sgv_pool *pool)
{
- struct sgv_pool *pool;
int i;
- pool = sgv_kobj_to_pool(kobj);
-
for (i = 0; i < SGV_POOL_ELEMENTS; i++) {
atomic_set(&pool->cache_acc[i].hit_alloc, 0);
atomic_set(&pool->cache_acc[i].total_alloc, 0);
@@ -1785,11 +1768,9 @@ static ssize_t sgv_sysfs_stat_reset(struct kobject *kobj,
atomic_set(&pool->other_alloc, 0);
PRINT_INFO("Statistics for SGV pool %s reset", pool->name);
- return count;
}
-static ssize_t sgv_sysfs_global_stat_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+ssize_t sgv_global_stat_show(char *buf)
{
struct sgv_pool *pool;
int inactive_pages = 0, res;
@@ -1813,122 +1794,13 @@ static ssize_t sgv_sysfs_global_stat_show(struct kobject *kobj,
return res;
}
-static ssize_t sgv_sysfs_global_stat_reset(struct kobject *kobj,
- struct kobj_attribute *attr, const char *buf, size_t count)
+void sgv_global_stat_reset(void)
{
atomic_set(&sgv_releases_on_hiwmk, 0);
atomic_set(&sgv_releases_on_hiwmk_failed, 0);
atomic_set(&sgv_other_total_alloc, 0);
PRINT_INFO("%s", "Global SGV pool statistics reset");
- return count;
-}
-
-static struct kobj_attribute sgv_stat_attr =
- __ATTR(stats, S_IRUGO | S_IWUSR, sgv_sysfs_stat_show,
- sgv_sysfs_stat_reset);
-
-static struct attribute *sgv_attrs[] = {
- &sgv_stat_attr.attr,
- NULL,
-};
-
-static void scst_release_pool(struct kobject *kobj)
-{
- struct sgv_pool *pool;
- int i;
-
- pool = sgv_kobj_to_pool(kobj);
-
- for (i = 0; i < pool->max_caches; i++) {
- if (pool->caches[i])
- kmem_cache_destroy(pool->caches[i]);
- pool->caches[i] = NULL;
- }
-
- kfree(pool);
-}
-
-static struct kobj_type pool_ktype = {
- .release = scst_release_pool,
- .sysfs_ops = &scst_sysfs_ops,
- .default_attrs = sgv_attrs,
-};
-
-static int scst_sgv_sysfs_create(struct sgv_pool *pool, struct kobject *parent)
-{
- int res;
-
- res = kobject_add(&pool->sgv_kobj, parent, pool->name);
- if (res != 0) {
- PRINT_ERROR("Can't add sgv pool %s to sysfs", pool->name);
- goto out;
- }
-
-out:
- return res;
-}
-
-static void scst_sgv_sysfs_del(struct sgv_pool *pool)
-{
- kobject_del(&pool->sgv_kobj);
-}
-
-/**
- ** SGV directory implementation
- **/
-
-static struct kobj_attribute sgv_global_stat_attr =
- __ATTR(global_stats, S_IRUGO | S_IWUSR, sgv_sysfs_global_stat_show,
- sgv_sysfs_global_stat_reset);
-
-static struct attribute *sgv_default_attrs[] = {
- &sgv_global_stat_attr.attr,
- NULL,
-};
-
-static void scst_sysfs_release(struct kobject *kobj)
-{
- kfree(kobj);
-}
-
-static struct kobj_type sgv_ktype = {
- .sysfs_ops = &scst_sysfs_ops,
- .release = scst_sysfs_release,
- .default_attrs = sgv_default_attrs,
-};
-
-/**
- * scst_add_sgv_kobj() - Initialize and add the root SGV kernel object.
- */
-int scst_add_sgv_kobj(struct kobject *parent, const char *name)
-{
- int res;
-
- WARN_ON(scst_sgv_kobj);
- res = -ENOMEM;
- scst_sgv_kobj = kzalloc(sizeof(*scst_sgv_kobj), GFP_KERNEL);
- if (!scst_sgv_kobj)
- goto out;
- res = kobject_init_and_add(scst_sgv_kobj, &sgv_ktype, parent, name);
- if (res != 0)
- goto out_free;
-out:
- return res;
-out_free:
- kobject_put(scst_sgv_kobj);
- scst_sgv_kobj = NULL;
- goto out;
-}
-
-/**
- * scst_del_put_sgv_kobj() - Remove the root SGV kernel object.
- */
-void scst_del_put_sgv_kobj(void)
-{
- WARN_ON(!scst_sgv_kobj);
- kobject_del(scst_sgv_kobj);
- kobject_put(scst_sgv_kobj);
- scst_sgv_kobj = NULL;
}
+#endif /*defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)*/
diff --git a/drivers/scst/scst_mem.h b/drivers/scst/scst_mem.h
index ea3f549..18b7e8c 100644
--- a/drivers/scst/scst_mem.h
+++ b/drivers/scst/scst_mem.h
@@ -122,7 +122,9 @@ struct sgv_pool {
struct list_head sgv_pools_list_entry;
- struct kobject sgv_kobj;
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+ struct dentry *debugfs_dir;
+#endif
};
static inline struct scatterlist *sgv_pool_sg(struct sgv_pool_obj *obj)
@@ -136,3 +138,21 @@ void scst_sgv_pools_deinit(void);
void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev);
void scst_sgv_pool_use_norm_clust(struct scst_tgt_dev *tgt_dev);
void scst_sgv_pool_use_dma(struct scst_tgt_dev *tgt_dev);
+
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+
+int scst_sgv_debugfs_create(struct dentry *parent);
+void scst_sgv_debugfs_del(void);
+
+#else /*defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)*/
+
+static inline int scst_sgv_debugfs_create(struct dentry *parent)
+{
+ return 0;
+}
+
+static inline void scst_sgv_debugfs_del(void)
+{
+}
+
+#endif /*defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)*/
diff --git a/drivers/scst/scst_mem_stats.c b/drivers/scst/scst_mem_stats.c
new file mode 100644
index 0000000..8095e61
--- /dev/null
+++ b/drivers/scst/scst_mem_stats.c
@@ -0,0 +1,168 @@
+/*
+ * scst_mem.c
+ *
+ * Copyright (C) 2006 - 2010 Vladislav Bolkhovitin <vst@vlnb.net>
+ * Copyright (C) 2007 - 2010 ID7 Ltd.
+ * Copyright (C) 2010 Bart Van Assche <bvanassche@acm.org>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/debugfs.h>
+#include <scst/scst.h>
+#include "scst_priv.h"
+#include "scst_mem.h"
+#include "scst_mem_stats.h"
+
+static struct dentry *scst_debug_sgv;
+
+static int sgv_debugfs_open(struct inode *inode, struct file *file)
+{
+ if (inode->i_private)
+ file->private_data = inode->i_private;
+
+ return 0;
+}
+
+static ssize_t sgv_pool_read_file(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct sgv_pool *pool = file->private_data;
+ unsigned long pg;
+ void *contents;
+ int len;
+ ssize_t res;
+
+ if (*ppos > PAGE_SIZE)
+ return -EINVAL;
+ pg = __get_free_page(GFP_KERNEL);
+ if (!pg)
+ return -ENOMEM;
+ contents = (void *)pg;
+ len = sgv_pool_stat_show(pool, contents);
+ free_page(pg);
+ res = min_t(ssize_t, count, len - *ppos);
+ if (copy_to_user(buf, contents + *ppos, res))
+ return -EFAULT;
+ *ppos += res;
+ return res;
+}
+
+static ssize_t sgv_pool_write_file(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct sgv_pool *pool = file->private_data;
+
+ sgv_pool_stat_reset(pool);
+ return count;
+}
+
+static const struct file_operations sgv_pool_fops = {
+ .read = sgv_pool_read_file,
+ .write = sgv_pool_write_file,
+ .open = sgv_debugfs_open,
+ .llseek = noop_llseek,
+};
+
+int scst_sgv_pool_debugfs_create(struct sgv_pool *pool)
+{
+ struct dentry *file;
+ int res;
+
+ res = -ENOMEM;
+ pool->debugfs_dir = debugfs_create_dir(pool->name, scst_debug_sgv);
+ if (!pool->debugfs_dir)
+ goto out;
+ file = debugfs_create_file("stats", S_IRUGO | S_IWUSR,
+ pool->debugfs_dir, pool, &sgv_pool_fops);
+ if (!file)
+ goto err;
+ res = 0;
+out:
+ return res;
+err:
+ debugfs_remove_recursive(pool->debugfs_dir);
+ pool->debugfs_dir = NULL;
+ goto out;
+}
+
+void scst_sgv_pool_debugfs_del(struct sgv_pool *pool)
+{
+ debugfs_remove_recursive(pool->debugfs_dir);
+ pool->debugfs_dir = NULL;
+}
+
+static ssize_t sgv_global_read_file(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long pg;
+ void *contents;
+ int len;
+ ssize_t res;
+
+ if (*ppos > PAGE_SIZE)
+ return -EINVAL;
+ pg = __get_free_page(GFP_KERNEL);
+ if (!pg)
+ return -ENOMEM;
+ contents = (void *)pg;
+ len = sgv_global_stat_show(contents);
+ free_page(pg);
+ res = min_t(ssize_t, count, len - *ppos);
+ if (copy_to_user(buf, contents + *ppos, res))
+ return -EFAULT;
+ *ppos += res;
+ return res;
+}
+
+static ssize_t sgv_global_write_file(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ sgv_global_stat_reset();
+ return count;
+}
+
+static const struct file_operations sgv_global_fops = {
+ .read = sgv_global_read_file,
+ .write = sgv_global_write_file,
+ .open = sgv_debugfs_open,
+ .llseek = noop_llseek,
+};
+
+int scst_sgv_debugfs_create(struct dentry *parent)
+{
+ struct dentry *file;
+ int res;
+
+ res = -ENOMEM;
+ scst_debug_sgv = debugfs_create_dir("sgv", parent);
+ if (!scst_debug_sgv)
+ goto out;
+ file = debugfs_create_file("global_stats", S_IRUGO | S_IWUSR,
+ scst_debug_sgv, NULL, &sgv_global_fops);
+ if (!file)
+ goto err;
+ res = 0;
+out:
+ return res;
+err:
+ debugfs_remove_recursive(scst_debug_sgv);
+ scst_debug_sgv = NULL;
+ goto out;
+}
+
+void scst_sgv_debugfs_del(void)
+{
+ debugfs_remove_recursive(scst_debug_sgv);
+ scst_debug_sgv = NULL;
+}
diff --git a/drivers/scst/scst_mem_stats.h b/drivers/scst/scst_mem_stats.h
new file mode 100644
index 0000000..b51d294
--- /dev/null
+++ b/drivers/scst/scst_mem_stats.h
@@ -0,0 +1,21 @@
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+
+int scst_sgv_pool_debugfs_create(struct sgv_pool *pool);
+void scst_sgv_pool_debugfs_del(struct sgv_pool *pool);
+ssize_t sgv_pool_stat_show(struct sgv_pool *pool, char *buf);
+void sgv_pool_stat_reset(struct sgv_pool *pool);
+ssize_t sgv_global_stat_show(char *buf);
+void sgv_global_stat_reset(void);
+
+#else /*defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)*/
+
+static inline int scst_sgv_pool_debugfs_create(struct sgv_pool *pool)
+{
+ return 0;
+}
+
+static void scst_sgv_pool_debugfs_del(struct sgv_pool *pool)
+{
+}
+
+#endif /*defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)*/
diff --git a/drivers/scst/scst_priv.h b/drivers/scst/scst_priv.h
index 7a5a815..74e68a4 100644
--- a/drivers/scst/scst_priv.h
+++ b/drivers/scst/scst_priv.h
@@ -376,8 +376,6 @@ void scst_tgt_sysfs_put(struct scst_tgt *tgt);
int scst_sess_sysfs_create(struct scst_session *sess);
void scst_sess_sysfs_del(struct scst_session *sess);
int scst_recreate_sess_luns_link(struct scst_session *sess);
-int scst_add_sgv_kobj(struct kobject *parent, const char *name);
-void scst_del_put_sgv_kobj(void);
int scst_devt_sysfs_init(struct scst_dev_type *devt);
int scst_devt_sysfs_create(struct scst_dev_type *devt);
void scst_devt_sysfs_del(struct scst_dev_type *devt);
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index aadb066..84dc9ee 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -3860,16 +3860,9 @@ int __init scst_sysfs_init(void)
goto out_remove_files;
}
- res = scst_add_sgv_kobj(&scst_device->kobj, "sgv");
- if (res) {
- PRINT_ERROR("%s", "Creation of SCST sgv kernel object failed.");
- goto out_remove_trace_files;
- }
-
out:
return res;
-out_remove_trace_files:
scst_main_remove_trace_files();
out_remove_files:
device_remove_files(scst_device, scst_root_default_attrs);
@@ -3891,8 +3884,6 @@ void scst_sysfs_cleanup(void)
{
PRINT_INFO("%s", "Exiting SCST sysfs hierarchy...");
- scst_del_put_sgv_kobj();
-
scst_main_remove_trace_files();
device_remove_files(scst_device, scst_root_default_attrs);
diff --git a/drivers/scst/scst_tracing.c b/drivers/scst/scst_tracing.c
index 7b97224..9b9aef4 100644
--- a/drivers/scst/scst_tracing.c
+++ b/drivers/scst/scst_tracing.c
@@ -18,6 +18,7 @@
#include <linux/debugfs.h>
#include <scst/scst.h>
#include <scst/scst_debug.h>
+#include "scst_mem.h"
#include "scst_priv.h"
#include "scst_pres.h"
#include "scst_tracing.h"
@@ -230,31 +231,41 @@ int scst_debugfs_init(void)
goto out;
}
+ res = scst_sgv_debugfs_create(scst_debug_root);
+ if (res) {
+ PRINT_ERROR("%s", "Creation of /sys/kernel/debug/scst/sgv"
+ " failed");
+ goto err;
+ }
+
scst_debug_target = debugfs_create_dir("target", scst_debug_root);
if (!scst_debug_target) {
PRINT_ERROR("%s", "Creation of /sys/kernel/debug/scst/target"
" failed");
- goto out;
+ goto err;
}
scst_debug_devt = debugfs_create_dir("device_type", scst_debug_root);
if (!scst_debug_devt) {
PRINT_ERROR("%s", "Creation of /sys/kernel/debug/scst/"
"device_type failed");
- goto out;
+ goto err;
}
scst_debug_dev = debugfs_create_dir("device", scst_debug_root);
if (!scst_debug_dev) {
PRINT_ERROR("%s", "Creation of /sys/kernel/debug/scst/device"
" failed");
- goto out;
+ goto err;
}
res = 0;
out:
return res;
+err:
+ scst_debugfs_cleanup();
+ goto out;
}
void scst_debugfs_cleanup(void)
--
1.7.1
[SCSI] scst: Move latency statistics to debugfs
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
Documentation/ABI/stable/sysfs-devices-scst_target | 16 -
drivers/scst/Kconfig | 2 +-
drivers/scst/Makefile | 1 +
drivers/scst/scst_lat_stats.c | 435 ++++++++++++++++++++
drivers/scst/scst_lat_stats.h | 28 ++
drivers/scst/scst_sysfs.c | 371 ++---------------
drivers/scst/scst_tracing.c | 204 +++++++---
drivers/scst/scst_tracing.h | 57 ++-
include/scst/scst.h | 21 +
9 files changed, 719 insertions(+), 416 deletions(-)
create mode 100644 drivers/scst/scst_lat_stats.c
create mode 100644 drivers/scst/scst_lat_stats.h
diff --git a/Documentation/ABI/stable/sysfs-devices-scst_target b/Documentation/ABI/stable/sysfs-devices-scst_target
index 2d3a388..1792aa3 100644
--- a/Documentation/ABI/stable/sysfs-devices-scst_target
+++ b/Documentation/ABI/stable/sysfs-devices-scst_target
@@ -182,28 +182,12 @@ Description:
Session name. For most target drivers this is a name that
identifies the initiator. Read-only.
-What: /sys/bus/scst_target/devices/*/sessions/<session>/latency
-Date: December 2010
-Contact: Bart Van Assche <bvanassche@acm.org>
-Description:
- Latency statistics for this session. Only available if
- CONFIG_SCST_MEASURE_LATENCY has been enabled in the
- kernel configuration. Read-only.
-
What: /sys/bus/scst_target/devices/*/sessions/<session>/lun<number>/active_commands
Date: December 2010
Contact: Bart Van Assche <bvanassche@acm.org>
Description:
Number of active commands. Read-only.
-What: /sys/bus/scst_target/devices/*/sessions/<session>/lun<number>/latency
-Date: December 2010
-Contact: Bart Van Assche <bvanassche@acm.org>
-Description:
- Latency statistics for this LUN. Only available if
- CONFIG_SCST_MEASURE_LATENCY has been enabled in the kernel
- configuration. Read-only.
-
What: /sys/bus/scst_target/devices/*/sessions/<session>/luns
Date: December 2010
Contact: Bart Van Assche <bvanassche@acm.org>
diff --git a/drivers/scst/Kconfig b/drivers/scst/Kconfig
index 75b0f97..62cb227 100644
--- a/drivers/scst/Kconfig
+++ b/drivers/scst/Kconfig
@@ -228,7 +228,7 @@ config SCST_TM_DBG_GO_OFFLINE
config SCST_MEASURE_LATENCY
bool "Commands processing latency measurement facility"
- depends on SCST
+ depends on SCST && (SCST_DEBUG || SCST_TRACING)
help
This option enables commands processing latency measurement
facility in SCST. It will provide in the sysfs interface
diff --git a/drivers/scst/Makefile b/drivers/scst/Makefile
index a27cf92..f2f9253 100644
--- a/drivers/scst/Makefile
+++ b/drivers/scst/Makefile
@@ -9,5 +9,6 @@ scst-y += scst_mem.o
scst-y += scst_debug.o
scst-$(CONFIG_SCST_DEBUG) += scst_tracing.o scst_mem_stats.o
scst-$(CONFIG_SCST_TRACING) += scst_tracing.o scst_mem_stats.o
+scst-$(CONFIG_SCST_MEASURE_LATENCY) += scst_lat_stats.o
obj-$(CONFIG_SCST) += scst.o dev_handlers/ scst_local/ srpt/
diff --git a/drivers/scst/scst_lat_stats.c b/drivers/scst/scst_lat_stats.c
new file mode 100644
index 0000000..0bee2b9
--- /dev/null
+++ b/drivers/scst/scst_lat_stats.c
@@ -0,0 +1,435 @@
+/*
+ * scst_lat_stats.c
+ *
+ * Copyright (C) 2009 - 2010 Vladislav Bolkhovitin <vst@vlnb.net>
+ * Copyright (C) 2010 Bart Van Assche <bvanassche@acm.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <scst/scst.h>
+#include <scst/scst_debug.h>
+#include "scst_priv.h"
+#include "scst_lat_stats.h"
+
+/* Per LUN latency statistics. */
+
+static char *scst_io_size_names[] = {
+ "<=8K ",
+ "<=32K ",
+ "<=128K",
+ "<=512K",
+ ">512K "
+};
+
+static ssize_t scst_tgt_dev_latency_show(struct scst_tgt_dev *tgt_dev,
+ char *buffer)
+{
+ int res, i;
+ char buf[50];
+
+ res = 0;
+ for (i = 0; i < SCST_LATENCY_STATS_NUM; i++) {
+ uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
+ unsigned int processed_cmds_wr;
+ uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
+ unsigned int processed_cmds_rd;
+ struct scst_ext_latency_stat *latency_stat;
+
+ latency_stat = &tgt_dev->dev_latency_stat[i];
+ scst_time_wr = latency_stat->scst_time_wr;
+ scst_time_rd = latency_stat->scst_time_rd;
+ tgt_time_wr = latency_stat->tgt_time_wr;
+ tgt_time_rd = latency_stat->tgt_time_rd;
+ dev_time_wr = latency_stat->dev_time_wr;
+ dev_time_rd = latency_stat->dev_time_rd;
+ processed_cmds_wr = latency_stat->processed_cmds_wr;
+ processed_cmds_rd = latency_stat->processed_cmds_rd;
+
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-5s %-9s %-15lu ", "Write", scst_io_size_names[i],
+ (unsigned long)processed_cmds_wr);
+ if (processed_cmds_wr == 0)
+ processed_cmds_wr = 1;
+
+ do_div(scst_time_wr, processed_cmds_wr);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_scst_time_wr,
+ (unsigned long)scst_time_wr,
+ (unsigned long)latency_stat->max_scst_time_wr,
+ (unsigned long)latency_stat->scst_time_wr);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
+
+ do_div(tgt_time_wr, processed_cmds_wr);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_tgt_time_wr,
+ (unsigned long)tgt_time_wr,
+ (unsigned long)latency_stat->max_tgt_time_wr,
+ (unsigned long)latency_stat->tgt_time_wr);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
+
+ do_div(dev_time_wr, processed_cmds_wr);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_dev_time_wr,
+ (unsigned long)dev_time_wr,
+ (unsigned long)latency_stat->max_dev_time_wr,
+ (unsigned long)latency_stat->dev_time_wr);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s\n", buf);
+
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-5s %-9s %-15lu ", "Read", scst_io_size_names[i],
+ (unsigned long)processed_cmds_rd);
+ if (processed_cmds_rd == 0)
+ processed_cmds_rd = 1;
+
+ do_div(scst_time_rd, processed_cmds_rd);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_scst_time_rd,
+ (unsigned long)scst_time_rd,
+ (unsigned long)latency_stat->max_scst_time_rd,
+ (unsigned long)latency_stat->scst_time_rd);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
+
+ do_div(tgt_time_rd, processed_cmds_rd);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_tgt_time_rd,
+ (unsigned long)tgt_time_rd,
+ (unsigned long)latency_stat->max_tgt_time_rd,
+ (unsigned long)latency_stat->tgt_time_rd);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
+
+ do_div(dev_time_rd, processed_cmds_rd);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_dev_time_rd,
+ (unsigned long)dev_time_rd,
+ (unsigned long)latency_stat->max_dev_time_rd,
+ (unsigned long)latency_stat->dev_time_rd);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s\n", buf);
+ }
+ return res;
+}
+
+static int scst_debugfs_open(struct inode *inode, struct file *file)
+{
+ if (inode->i_private)
+ file->private_data = inode->i_private;
+
+ return 0;
+}
+
+static ssize_t tgt_dev_lat_read_file(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct scst_tgt_dev *tgt_dev = file->private_data;
+ unsigned long pg;
+ void *contents;
+ int len;
+ ssize_t res;
+
+ if (*ppos > PAGE_SIZE)
+ return -EINVAL;
+ pg = __get_free_page(GFP_KERNEL);
+ if (!pg)
+ return -ENOMEM;
+ contents = (void *)pg;
+ len = scst_tgt_dev_latency_show(tgt_dev, contents);
+ free_page(pg);
+ res = min_t(ssize_t, count, len - *ppos);
+ if (copy_to_user(buf, contents + *ppos, res))
+ return -EFAULT;
+ *ppos += res;
+ return res;
+}
+
+static ssize_t tgt_dev_lat_write_file(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static const struct file_operations tgt_dev_lat_fops = {
+ .read = tgt_dev_lat_read_file,
+ .write = tgt_dev_lat_write_file,
+ .open = scst_debugfs_open,
+ .llseek = noop_llseek,
+};
+
+int scst_tgt_dev_lat_create(struct scst_tgt_dev *tgt_dev)
+{
+ tgt_dev->latency_file = debugfs_create_file("latency",
+ S_IRUGO | S_IWUSR, tgt_dev->debugfs_dir,
+ tgt_dev, &tgt_dev_lat_fops);
+ return tgt_dev->latency_file ? 0 : -ENOMEM;
+}
+
+void scst_tgt_dev_lat_remove(struct scst_tgt_dev *tgt_dev)
+{
+ debugfs_remove(tgt_dev->latency_file);
+ tgt_dev->latency_file = NULL;
+}
+
+/* Per session latency statistics. */
+
+static ssize_t scst_sess_latency_show(struct scst_session *sess, char *buffer)
+{
+ ssize_t res;
+ int i;
+ char buf[50];
+ uint64_t scst_time, tgt_time, dev_time;
+ unsigned int processed_cmds;
+
+ res = 0;
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-15s %-15s %-46s %-46s %-46s\n",
+ "T-L names", "Total commands", "SCST latency",
+ "Target latency", "Dev latency (min/avg/max/all ns)");
+
+ spin_lock_bh(&sess->lat_lock);
+
+ for (i = 0; i < SCST_LATENCY_STATS_NUM ; i++) {
+ uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
+ unsigned int processed_cmds_wr;
+ uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
+ unsigned int processed_cmds_rd;
+ struct scst_ext_latency_stat *latency_stat;
+
+ latency_stat = &sess->sess_latency_stat[i];
+ scst_time_wr = latency_stat->scst_time_wr;
+ scst_time_rd = latency_stat->scst_time_rd;
+ tgt_time_wr = latency_stat->tgt_time_wr;
+ tgt_time_rd = latency_stat->tgt_time_rd;
+ dev_time_wr = latency_stat->dev_time_wr;
+ dev_time_rd = latency_stat->dev_time_rd;
+ processed_cmds_wr = latency_stat->processed_cmds_wr;
+ processed_cmds_rd = latency_stat->processed_cmds_rd;
+
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-5s %-9s %-15lu ",
+ "Write", scst_io_size_names[i],
+ (unsigned long)processed_cmds_wr);
+ if (processed_cmds_wr == 0)
+ processed_cmds_wr = 1;
+
+ do_div(scst_time_wr, processed_cmds_wr);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_scst_time_wr,
+ (unsigned long)scst_time_wr,
+ (unsigned long)latency_stat->max_scst_time_wr,
+ (unsigned long)latency_stat->scst_time_wr);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s", buf);
+
+ do_div(tgt_time_wr, processed_cmds_wr);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_tgt_time_wr,
+ (unsigned long)tgt_time_wr,
+ (unsigned long)latency_stat->max_tgt_time_wr,
+ (unsigned long)latency_stat->tgt_time_wr);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s", buf);
+
+ do_div(dev_time_wr, processed_cmds_wr);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_dev_time_wr,
+ (unsigned long)dev_time_wr,
+ (unsigned long)latency_stat->max_dev_time_wr,
+ (unsigned long)latency_stat->dev_time_wr);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s\n", buf);
+
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-5s %-9s %-15lu ",
+ "Read", scst_io_size_names[i],
+ (unsigned long)processed_cmds_rd);
+ if (processed_cmds_rd == 0)
+ processed_cmds_rd = 1;
+
+ do_div(scst_time_rd, processed_cmds_rd);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_scst_time_rd,
+ (unsigned long)scst_time_rd,
+ (unsigned long)latency_stat->max_scst_time_rd,
+ (unsigned long)latency_stat->scst_time_rd);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s", buf);
+
+ do_div(tgt_time_rd, processed_cmds_rd);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_tgt_time_rd,
+ (unsigned long)tgt_time_rd,
+ (unsigned long)latency_stat->max_tgt_time_rd,
+ (unsigned long)latency_stat->tgt_time_rd);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s", buf);
+
+ do_div(dev_time_rd, processed_cmds_rd);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)latency_stat->min_dev_time_rd,
+ (unsigned long)dev_time_rd,
+ (unsigned long)latency_stat->max_dev_time_rd,
+ (unsigned long)latency_stat->dev_time_rd);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s\n", buf);
+ }
+
+ scst_time = sess->scst_time;
+ tgt_time = sess->tgt_time;
+ dev_time = sess->dev_time;
+ processed_cmds = sess->processed_cmds;
+
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "\n%-15s %-16d", "Overall ", processed_cmds);
+
+ if (processed_cmds == 0)
+ processed_cmds = 1;
+
+ do_div(scst_time, processed_cmds);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)sess->min_scst_time,
+ (unsigned long)scst_time,
+ (unsigned long)sess->max_scst_time,
+ (unsigned long)sess->scst_time);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s", buf);
+
+ do_div(tgt_time, processed_cmds);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)sess->min_tgt_time,
+ (unsigned long)tgt_time,
+ (unsigned long)sess->max_tgt_time,
+ (unsigned long)sess->tgt_time);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s", buf);
+
+ do_div(dev_time, processed_cmds);
+ snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
+ (unsigned long)sess->min_dev_time,
+ (unsigned long)dev_time,
+ (unsigned long)sess->max_dev_time,
+ (unsigned long)sess->dev_time);
+ res += scnprintf(&buffer[res], PAGE_SIZE - res,
+ "%-47s\n\n", buf);
+
+ spin_unlock_bh(&sess->lat_lock);
+ return res;
+}
+
+static int scst_sess_zero_latency(struct scst_session *sess)
+{
+ int res, t;
+
+ res = mutex_lock_interruptible(&scst_mutex);
+ if (res)
+ goto out;
+
+ PRINT_INFO("Zeroing latency statistics for initiator "
+ "%s", sess->initiator_name);
+
+ spin_lock_bh(&sess->lat_lock);
+
+ sess->scst_time = 0;
+ sess->tgt_time = 0;
+ sess->dev_time = 0;
+ sess->min_scst_time = 0;
+ sess->min_tgt_time = 0;
+ sess->min_dev_time = 0;
+ sess->max_scst_time = 0;
+ sess->max_tgt_time = 0;
+ sess->max_dev_time = 0;
+ sess->processed_cmds = 0;
+ memset(sess->sess_latency_stat, 0,
+ sizeof(sess->sess_latency_stat));
+
+ for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) {
+ struct list_head *head = &sess->sess_tgt_dev_list[t];
+ struct scst_tgt_dev *tgt_dev;
+ list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
+ tgt_dev->scst_time = 0;
+ tgt_dev->tgt_time = 0;
+ tgt_dev->dev_time = 0;
+ tgt_dev->processed_cmds = 0;
+ memset(tgt_dev->dev_latency_stat, 0,
+ sizeof(tgt_dev->dev_latency_stat));
+ }
+ }
+
+ spin_unlock_bh(&sess->lat_lock);
+
+ mutex_unlock(&scst_mutex);
+
+out:
+ return res;
+}
+
+static ssize_t sess_lat_read_file(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct scst_session *sess = file->private_data;
+ unsigned long pg;
+ void *contents;
+ int len;
+ ssize_t res;
+
+ if (*ppos > PAGE_SIZE)
+ return -EINVAL;
+ pg = __get_free_page(GFP_KERNEL);
+ if (!pg)
+ return -ENOMEM;
+ contents = (void *)pg;
+ len = scst_sess_latency_show(sess, contents);
+ free_page(pg);
+ res = min_t(ssize_t, count, len - *ppos);
+ if (copy_to_user(buf, contents + *ppos, res))
+ return -EFAULT;
+ *ppos += res;
+ return res;
+}
+
+static ssize_t sess_lat_write_file(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct scst_session *sess = file->private_data;
+ int res;
+
+ res = scst_sess_zero_latency(sess);
+ if (res)
+ goto out;
+ *ppos += count;
+ res = count;
+out:
+ return res;
+}
+
+static const struct file_operations sess_lat_fops = {
+ .read = sess_lat_read_file,
+ .write = sess_lat_write_file,
+ .open = scst_debugfs_open,
+ .llseek = noop_llseek,
+};
+
+int scst_sess_lat_create(struct scst_session *sess)
+{
+ sess->latency_file = debugfs_create_file("latency",
+ S_IRUGO | S_IWUSR, sess->debugfs_dir,
+ sess, &sess_lat_fops);
+ return sess->latency_file ? 0 : -ENOMEM;
+}
+
+void scst_sess_lat_remove(struct scst_session *sess)
+{
+ debugfs_remove(sess->latency_file);
+ sess->latency_file = NULL;
+}
diff --git a/drivers/scst/scst_lat_stats.h b/drivers/scst/scst_lat_stats.h
new file mode 100644
index 0000000..50c89ee
--- /dev/null
+++ b/drivers/scst/scst_lat_stats.h
@@ -0,0 +1,28 @@
+#if defined(CONFIG_SCST_MEASURE_LATENCY)
+
+int scst_tgt_dev_lat_create(struct scst_tgt_dev *tgt_dev);
+void scst_tgt_dev_lat_remove(struct scst_tgt_dev *tgt_dev);
+int scst_sess_lat_create(struct scst_session *sess);
+void scst_sess_lat_remove(struct scst_session *sess);
+
+#else /*defined(CONFIG_SCST_MEASURE_LATENCY)*/
+
+static inline int scst_tgt_dev_lat_create(struct scst_tgt_dev *tgt_dev)
+{
+ return 0;
+}
+
+static inline void scst_tgt_dev_lat_remove(struct scst_tgt_dev *tgt_dev)
+{
+}
+
+static inline int scst_sess_lat_create(struct scst_session *sess)
+{
+ return 0;
+}
+
+static inline void scst_sess_lat_remove(struct scst_session *sess)
+{
+}
+
+#endif /*defined(CONFIG_SCST_MEASURE_LATENCY)*/
diff --git a/drivers/scst/scst_sysfs.c b/drivers/scst/scst_sysfs.c
index 84dc9ee..c9c4c28 100644
--- a/drivers/scst/scst_sysfs.c
+++ b/drivers/scst/scst_sysfs.c
@@ -46,6 +46,7 @@
#include "scst_priv.h"
#include "scst_mem.h"
#include "scst_tracing.h"
+#include "scst_lat_stats.h"
enum mgmt_path_type {
PATH_NOT_RECOGNIZED,
@@ -442,7 +443,7 @@ int scst_tgtt_sysfs_create(struct scst_tgt_template *tgtt)
}
}
- res = scst_tgtt_create_trace_files(tgtt);
+ res = scst_tgtt_debugfs_create(tgtt);
if (res) {
PRINT_ERROR("Can't create tracing files for target driver %s",
tgtt->name);
@@ -459,7 +460,7 @@ out_del:
void scst_tgtt_sysfs_del(struct scst_tgt_template *tgtt)
{
- scst_tgtt_remove_trace_files(tgtt);
+ scst_tgtt_debugfs_remove(tgtt);
driver_unregister(&tgtt->tgtt_drv);
}
@@ -1049,6 +1050,10 @@ int scst_tgt_sysfs_create(struct scst_tgt *tgt)
}
}
+ res = scst_tgt_debugfs_create(tgt);
+ if (res)
+ goto out_err;
+
out:
return res;
@@ -1062,6 +1067,7 @@ out_err:
void scst_tgt_sysfs_del(struct scst_tgt *tgt)
{
+ scst_tgt_debugfs_remove(tgt);
kobject_del(tgt->tgt_sess_kobj);
kobject_del(tgt->tgt_luns_kobj);
kobject_del(tgt->tgt_ini_grp_kobj);
@@ -1502,112 +1508,6 @@ void scst_dev_sysfs_put(struct scst_device *dev)
** Tgt_dev implementation
**/
-#ifdef CONFIG_SCST_MEASURE_LATENCY
-
-static char *scst_io_size_names[] = {
- "<=8K ",
- "<=32K ",
- "<=128K",
- "<=512K",
- ">512K "
-};
-
-static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buffer)
-{
- int res, i;
- char buf[50];
- struct scst_tgt_dev *tgt_dev;
-
- tgt_dev = scst_kobj_to_tgt_dev(kobj);
-
- res = 0;
- for (i = 0; i < SCST_LATENCY_STATS_NUM; i++) {
- uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
- unsigned int processed_cmds_wr;
- uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
- unsigned int processed_cmds_rd;
- struct scst_ext_latency_stat *latency_stat;
-
- latency_stat = &tgt_dev->dev_latency_stat[i];
- scst_time_wr = latency_stat->scst_time_wr;
- scst_time_rd = latency_stat->scst_time_rd;
- tgt_time_wr = latency_stat->tgt_time_wr;
- tgt_time_rd = latency_stat->tgt_time_rd;
- dev_time_wr = latency_stat->dev_time_wr;
- dev_time_rd = latency_stat->dev_time_rd;
- processed_cmds_wr = latency_stat->processed_cmds_wr;
- processed_cmds_rd = latency_stat->processed_cmds_rd;
-
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-5s %-9s %-15lu ", "Write", scst_io_size_names[i],
- (unsigned long)processed_cmds_wr);
- if (processed_cmds_wr == 0)
- processed_cmds_wr = 1;
-
- do_div(scst_time_wr, processed_cmds_wr);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_scst_time_wr,
- (unsigned long)scst_time_wr,
- (unsigned long)latency_stat->max_scst_time_wr,
- (unsigned long)latency_stat->scst_time_wr);
- res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
-
- do_div(tgt_time_wr, processed_cmds_wr);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_tgt_time_wr,
- (unsigned long)tgt_time_wr,
- (unsigned long)latency_stat->max_tgt_time_wr,
- (unsigned long)latency_stat->tgt_time_wr);
- res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
-
- do_div(dev_time_wr, processed_cmds_wr);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_dev_time_wr,
- (unsigned long)dev_time_wr,
- (unsigned long)latency_stat->max_dev_time_wr,
- (unsigned long)latency_stat->dev_time_wr);
- res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s\n", buf);
-
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-5s %-9s %-15lu ", "Read", scst_io_size_names[i],
- (unsigned long)processed_cmds_rd);
- if (processed_cmds_rd == 0)
- processed_cmds_rd = 1;
-
- do_div(scst_time_rd, processed_cmds_rd);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_scst_time_rd,
- (unsigned long)scst_time_rd,
- (unsigned long)latency_stat->max_scst_time_rd,
- (unsigned long)latency_stat->scst_time_rd);
- res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
-
- do_div(tgt_time_rd, processed_cmds_rd);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_tgt_time_rd,
- (unsigned long)tgt_time_rd,
- (unsigned long)latency_stat->max_tgt_time_rd,
- (unsigned long)latency_stat->tgt_time_rd);
- res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s", buf);
-
- do_div(dev_time_rd, processed_cmds_rd);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_dev_time_rd,
- (unsigned long)dev_time_rd,
- (unsigned long)latency_stat->max_dev_time_rd,
- (unsigned long)latency_stat->dev_time_rd);
- res += scnprintf(&buffer[res], PAGE_SIZE - res, "%-47s\n", buf);
- }
- return res;
-}
-
-static struct kobj_attribute tgt_dev_latency_attr =
- __ATTR(latency, S_IRUGO,
- scst_tgt_dev_latency_show, NULL);
-
-#endif /* CONFIG_SCST_MEASURE_LATENCY */
-
static ssize_t scst_tgt_dev_active_commands_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -1627,9 +1527,6 @@ static struct kobj_attribute tgt_dev_active_commands_attr =
struct attribute *scst_tgt_dev_attrs[] = {
&tgt_dev_active_commands_attr.attr,
-#ifdef CONFIG_SCST_MEASURE_LATENCY
- &tgt_dev_latency_attr.attr,
-#endif
NULL,
};
@@ -1645,12 +1542,24 @@ int scst_tgt_dev_sysfs_create(struct scst_tgt_dev *tgt_dev)
goto out;
}
+ res = scst_tgt_dev_debugfs_create(tgt_dev);
+ if (res)
+ goto err;
+
+ res = scst_tgt_dev_lat_create(tgt_dev);
+ if (res)
+ goto err;
out:
return res;
+err:
+ scst_tgt_dev_sysfs_del(tgt_dev);
+ goto out;
}
void scst_tgt_dev_sysfs_del(struct scst_tgt_dev *tgt_dev)
{
+ scst_tgt_dev_lat_remove(tgt_dev);
+ scst_tgt_dev_debugfs_remove(tgt_dev);
kobject_del(&tgt_dev->tgt_dev_kobj);
}
@@ -1658,223 +1567,6 @@ void scst_tgt_dev_sysfs_del(struct scst_tgt_dev *tgt_dev)
** Sessions subdirectory implementation
**/
-#ifdef CONFIG_SCST_MEASURE_LATENCY
-
-static ssize_t scst_sess_latency_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buffer)
-{
- ssize_t res;
- struct scst_session *sess;
- int i;
- char buf[50];
- uint64_t scst_time, tgt_time, dev_time;
- unsigned int processed_cmds;
-
- sess = scst_kobj_to_sess(kobj);
-
- res = 0;
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-15s %-15s %-46s %-46s %-46s\n",
- "T-L names", "Total commands", "SCST latency",
- "Target latency", "Dev latency (min/avg/max/all ns)");
-
- spin_lock_bh(&sess->lat_lock);
-
- for (i = 0; i < SCST_LATENCY_STATS_NUM ; i++) {
- uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
- unsigned int processed_cmds_wr;
- uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
- unsigned int processed_cmds_rd;
- struct scst_ext_latency_stat *latency_stat;
-
- latency_stat = &sess->sess_latency_stat[i];
- scst_time_wr = latency_stat->scst_time_wr;
- scst_time_rd = latency_stat->scst_time_rd;
- tgt_time_wr = latency_stat->tgt_time_wr;
- tgt_time_rd = latency_stat->tgt_time_rd;
- dev_time_wr = latency_stat->dev_time_wr;
- dev_time_rd = latency_stat->dev_time_rd;
- processed_cmds_wr = latency_stat->processed_cmds_wr;
- processed_cmds_rd = latency_stat->processed_cmds_rd;
-
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-5s %-9s %-15lu ",
- "Write", scst_io_size_names[i],
- (unsigned long)processed_cmds_wr);
- if (processed_cmds_wr == 0)
- processed_cmds_wr = 1;
-
- do_div(scst_time_wr, processed_cmds_wr);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_scst_time_wr,
- (unsigned long)scst_time_wr,
- (unsigned long)latency_stat->max_scst_time_wr,
- (unsigned long)latency_stat->scst_time_wr);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s", buf);
-
- do_div(tgt_time_wr, processed_cmds_wr);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_tgt_time_wr,
- (unsigned long)tgt_time_wr,
- (unsigned long)latency_stat->max_tgt_time_wr,
- (unsigned long)latency_stat->tgt_time_wr);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s", buf);
-
- do_div(dev_time_wr, processed_cmds_wr);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_dev_time_wr,
- (unsigned long)dev_time_wr,
- (unsigned long)latency_stat->max_dev_time_wr,
- (unsigned long)latency_stat->dev_time_wr);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s\n", buf);
-
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-5s %-9s %-15lu ",
- "Read", scst_io_size_names[i],
- (unsigned long)processed_cmds_rd);
- if (processed_cmds_rd == 0)
- processed_cmds_rd = 1;
-
- do_div(scst_time_rd, processed_cmds_rd);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_scst_time_rd,
- (unsigned long)scst_time_rd,
- (unsigned long)latency_stat->max_scst_time_rd,
- (unsigned long)latency_stat->scst_time_rd);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s", buf);
-
- do_div(tgt_time_rd, processed_cmds_rd);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_tgt_time_rd,
- (unsigned long)tgt_time_rd,
- (unsigned long)latency_stat->max_tgt_time_rd,
- (unsigned long)latency_stat->tgt_time_rd);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s", buf);
-
- do_div(dev_time_rd, processed_cmds_rd);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)latency_stat->min_dev_time_rd,
- (unsigned long)dev_time_rd,
- (unsigned long)latency_stat->max_dev_time_rd,
- (unsigned long)latency_stat->dev_time_rd);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s\n", buf);
- }
-
- scst_time = sess->scst_time;
- tgt_time = sess->tgt_time;
- dev_time = sess->dev_time;
- processed_cmds = sess->processed_cmds;
-
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "\n%-15s %-16d", "Overall ", processed_cmds);
-
- if (processed_cmds == 0)
- processed_cmds = 1;
-
- do_div(scst_time, processed_cmds);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)sess->min_scst_time,
- (unsigned long)scst_time,
- (unsigned long)sess->max_scst_time,
- (unsigned long)sess->scst_time);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s", buf);
-
- do_div(tgt_time, processed_cmds);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)sess->min_tgt_time,
- (unsigned long)tgt_time,
- (unsigned long)sess->max_tgt_time,
- (unsigned long)sess->tgt_time);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s", buf);
-
- do_div(dev_time, processed_cmds);
- snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
- (unsigned long)sess->min_dev_time,
- (unsigned long)dev_time,
- (unsigned long)sess->max_dev_time,
- (unsigned long)sess->dev_time);
- res += scnprintf(&buffer[res], PAGE_SIZE - res,
- "%-47s\n\n", buf);
-
- spin_unlock_bh(&sess->lat_lock);
- return res;
-}
-
-static int scst_sess_zero_latency(struct scst_session *sess)
-{
- int res, t;
-
- res = mutex_lock_interruptible(&scst_mutex);
- if (res != 0)
- goto out;
-
- PRINT_INFO("Zeroing latency statistics for initiator "
- "%s", sess->initiator_name);
-
- spin_lock_bh(&sess->lat_lock);
-
- sess->scst_time = 0;
- sess->tgt_time = 0;
- sess->dev_time = 0;
- sess->min_scst_time = 0;
- sess->min_tgt_time = 0;
- sess->min_dev_time = 0;
- sess->max_scst_time = 0;
- sess->max_tgt_time = 0;
- sess->max_dev_time = 0;
- sess->processed_cmds = 0;
- memset(sess->sess_latency_stat, 0,
- sizeof(sess->sess_latency_stat));
-
- for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) {
- struct list_head *head = &sess->sess_tgt_dev_list[t];
- struct scst_tgt_dev *tgt_dev;
- list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
- tgt_dev->scst_time = 0;
- tgt_dev->tgt_time = 0;
- tgt_dev->dev_time = 0;
- tgt_dev->processed_cmds = 0;
- memset(tgt_dev->dev_latency_stat, 0,
- sizeof(tgt_dev->dev_latency_stat));
- }
- }
-
- spin_unlock_bh(&sess->lat_lock);
-
- mutex_unlock(&scst_mutex);
-
-out:
- return res;
-}
-
-static ssize_t scst_sess_latency_store(struct kobject *kobj,
- struct kobj_attribute *attr, const char *buf, size_t count)
-{
- int res;
- struct scst_session *sess;
-
- sess = scst_kobj_to_sess(kobj);
-
- res = scst_sess_zero_latency(sess);
- if (res == 0)
- res = count;
- return res;
-}
-
-static struct kobj_attribute session_latency_attr =
- __ATTR(latency, S_IRUGO | S_IWUSR, scst_sess_latency_show,
- scst_sess_latency_store);
-
-#endif /* CONFIG_SCST_MEASURE_LATENCY */
-
static ssize_t scst_sess_sysfs_commands_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -1949,9 +1641,6 @@ struct attribute *scst_session_attrs[] = {
&session_commands_attr.attr,
&session_active_commands_attr.attr,
&session_initiator_name_attr.attr,
-#ifdef CONFIG_SCST_MEASURE_LATENCY
- &session_latency_attr.attr,
-#endif /* CONFIG_SCST_MEASURE_LATENCY */
NULL,
};
@@ -2010,6 +1699,14 @@ int scst_sess_sysfs_create(struct scst_session *sess)
if (res)
goto out_free;
+ res = scst_sess_debugfs_create(sess);
+ if (res)
+ goto out_free;
+
+ res = scst_sess_lat_create(sess);
+ if (res)
+ goto out_free;
+
out:
return res;
out_free:
@@ -2019,6 +1716,8 @@ out_free:
void scst_sess_sysfs_del(struct scst_session *sess)
{
+ scst_sess_lat_remove(sess);
+ scst_sess_debugfs_remove(sess);
kobject_del(&sess->sess_kobj);
}
@@ -3183,7 +2882,7 @@ int scst_devt_sysfs_create(struct scst_dev_type *devt)
}
}
- res = scst_devt_create_trace_files(devt);
+ res = scst_devt_debugfs_create(devt);
if (res) {
PRINT_ERROR("Can't create tracing files for device type %s",
devt->name);
@@ -3200,7 +2899,7 @@ out_err:
void scst_devt_sysfs_del(struct scst_dev_type *devt)
{
- scst_devt_remove_trace_files(devt);
+ scst_devt_debugfs_remove(devt);
}
void scst_devt_sysfs_put(struct scst_dev_type *devt)
@@ -3854,7 +3553,7 @@ int __init scst_sysfs_init(void)
goto out_unregister_device;
}
- res = scst_main_create_trace_files();
+ res = scst_main_debugfs_create();
if (res) {
PRINT_ERROR("%s", "Creating SCST trace files failed.");
goto out_remove_files;
@@ -3863,7 +3562,7 @@ int __init scst_sysfs_init(void)
out:
return res;
- scst_main_remove_trace_files();
+ scst_main_debugfs_remove();
out_remove_files:
device_remove_files(scst_device, scst_root_default_attrs);
out_unregister_device:
@@ -3884,7 +3583,7 @@ void scst_sysfs_cleanup(void)
{
PRINT_INFO("%s", "Exiting SCST sysfs hierarchy...");
- scst_main_remove_trace_files();
+ scst_main_debugfs_remove();
device_remove_files(scst_device, scst_root_default_attrs);
diff --git a/drivers/scst/scst_tracing.c b/drivers/scst/scst_tracing.c
index 9b9aef4..c87597b 100644
--- a/drivers/scst/scst_tracing.c
+++ b/drivers/scst/scst_tracing.c
@@ -24,7 +24,8 @@
#include "scst_tracing.h"
static struct dentry *scst_debug_root;
-static struct dentry *scst_debug_target;
+static struct dentry *scst_debug_tgtt;
+static struct dentry *scst_debug_tgt;
static struct dentry *scst_debug_devt;
static struct dentry *scst_debug_dev;
static struct dentry *scst_main_tracing_dir;
@@ -167,29 +168,21 @@ static const struct file_operations scst_tracing_fops = {
.llseek = noop_llseek,
};
-static struct dentry *scst_create_trace_files(struct dentry *root,
- const char *dir_name,
+static struct dentry *scst_create_trace_files(struct dentry *dir,
struct scst_trace_data *td)
{
int i;
- struct dentry *subdir, *tracing_dir, *file;
+ struct dentry *tracing_dir, *file;
const struct scst_trace_log *p;
const struct scst_trace_log *tracing_table[] = {
scst_trace_tbl,
td->trace_tbl,
};
- BUG_ON(!root);
- BUG_ON(!dir_name);
+ BUG_ON(!dir);
BUG_ON(!td);
- subdir = debugfs_create_dir(dir_name, root);
- if (!subdir) {
- PRINT_ERROR("Creation of directory %s failed", dir_name);
- goto out;
- }
-
- tracing_dir = debugfs_create_dir("tracing", subdir);
+ tracing_dir = debugfs_create_dir("tracing", dir);
if (!tracing_dir) {
PRINT_ERROR("%s", "Creation of tracing dir failed");
goto err;
@@ -208,18 +201,13 @@ static struct dentry *scst_create_trace_files(struct dentry *root,
}
}
out:
- return subdir;
+ return tracing_dir;
err:
- debugfs_remove_recursive(subdir);
- subdir = NULL;
+ debugfs_remove_recursive(tracing_dir);
+ tracing_dir = NULL;
goto out;
}
-static void scst_remove_trace_files(struct dentry *dir)
-{
- debugfs_remove_recursive(dir);
-}
-
int scst_debugfs_init(void)
{
int res;
@@ -238,8 +226,15 @@ int scst_debugfs_init(void)
goto err;
}
- scst_debug_target = debugfs_create_dir("target", scst_debug_root);
- if (!scst_debug_target) {
+ scst_debug_tgtt = debugfs_create_dir("target_driver", scst_debug_root);
+ if (!scst_debug_tgtt) {
+ PRINT_ERROR("%s", "Creation of /sys/kernel/debug/scst/"
+ "target_driver failed");
+ goto err;
+ }
+
+ scst_debug_tgt = debugfs_create_dir("target", scst_debug_root);
+ if (!scst_debug_tgt) {
PRINT_ERROR("%s", "Creation of /sys/kernel/debug/scst/target"
" failed");
goto err;
@@ -273,57 +268,164 @@ void scst_debugfs_cleanup(void)
debugfs_remove_recursive(scst_debug_root);
scst_debug_dev = NULL;
scst_debug_devt = NULL;
- scst_debug_target = NULL;
+ scst_debug_tgt = NULL;
+ scst_debug_tgtt = NULL;
scst_debug_root = NULL;
}
-int scst_main_create_trace_files(void)
+int scst_main_debugfs_create(void)
{
- scst_main_tracing_dir = scst_create_trace_files(scst_debug_root,
- "main",
- &scst_main_trace_data);
- return scst_main_tracing_dir ? 0 : -EINVAL;
+ int res;
+
+ res = -ENOMEM;
+ scst_main_tracing_dir = debugfs_create_dir("main", scst_debug_root);
+ if (!scst_main_tracing_dir)
+ goto out;
+
+ if (!scst_create_trace_files(scst_main_tracing_dir,
+ &scst_main_trace_data)) {
+ goto out;
+ }
+ res = 0;
+out:
+ return res;
}
-void scst_main_remove_trace_files(void)
+void scst_main_debugfs_remove(void)
{
- scst_remove_trace_files(scst_main_tracing_dir);
+ debugfs_remove_recursive(scst_main_tracing_dir);
scst_main_tracing_dir = NULL;
}
-int scst_tgtt_create_trace_files(struct scst_tgt_template *tgtt)
+int scst_tgtt_debugfs_create(struct scst_tgt_template *tgtt)
{
- if (tgtt->trace_data.trace_flags) {
- tgtt->tracing_dir = scst_create_trace_files(scst_debug_target,
- tgtt->name,
- &tgtt->trace_data);
- if (!tgtt->tracing_dir)
- return -EINVAL;
+ int res;
+
+ res = -ENOMEM;
+ tgtt->tracing_dir = debugfs_create_dir(tgtt->name, scst_debug_tgtt);
+ if (!tgtt->tracing_dir) {
+ PRINT_ERROR("Creation of directory %s failed", tgtt->name);
+ goto out;
}
- return 0;
+
+ if (tgtt->trace_data.trace_flags &&
+ !scst_create_trace_files(tgtt->tracing_dir, &tgtt->trace_data)) {
+ res = -ENOMEM;
+ goto out;
+ }
+ res = 0;
+out:
+ return res;
}
-void scst_tgtt_remove_trace_files(struct scst_tgt_template *tgtt)
+void scst_tgtt_debugfs_remove(struct scst_tgt_template *tgtt)
{
- scst_remove_trace_files(tgtt->tracing_dir);
+ debugfs_remove_recursive(tgtt->tracing_dir);
tgtt->tracing_dir = NULL;
}
-int scst_devt_create_trace_files(struct scst_dev_type *devt)
+int scst_tgt_debugfs_create(struct scst_tgt *tgt)
{
- if (devt->trace_data.trace_flags) {
- devt->tracing_dir = scst_create_trace_files(scst_debug_devt,
- devt->name,
- &devt->trace_data);
- if (!devt->tracing_dir)
- return -EINVAL;
+ int res;
+
+ res = -ENOMEM;
+ tgt->debugfs_dir = debugfs_create_dir(tgt->tgt_name, scst_debug_tgt);
+ if (!tgt->debugfs_dir) {
+ PRINT_ERROR("Creation of directory %s failed", tgt->tgt_name);
+ goto out;
}
- return 0;
+ tgt->sessions_dir = debugfs_create_dir("sessions", tgt->debugfs_dir);
+ if (!tgt->sessions_dir) {
+ PRINT_ERROR("Creation of directory %s/sessions failed",
+ tgt->tgt_name);
+ goto out;
+ }
+ res = 0;
+out:
+ return res;
+}
+
+void scst_tgt_debugfs_remove(struct scst_tgt *tgt)
+{
+ debugfs_remove_recursive(tgt->debugfs_dir);
+ tgt->debugfs_dir = NULL;
+}
+
+int scst_sess_debugfs_create(struct scst_session *sess)
+{
+ int res;
+
+ res = -ENOMEM;
+ sess->debugfs_dir = debugfs_create_dir(sess->initiator_name,
+ sess->tgt->sessions_dir);
+ if (!sess->debugfs_dir) {
+ PRINT_ERROR("Creation of directory %s failed",
+ sess->initiator_name);
+ goto out;
+ }
+ sess->luns_dir = debugfs_create_dir("luns", sess->debugfs_dir);
+ if (!sess->luns_dir) {
+ PRINT_ERROR("Creation of directory %s/sessions failed",
+ sess->initiator_name);
+ goto out;
+ }
+ res = 0;
+out:
+ return res;
+}
+
+void scst_sess_debugfs_remove(struct scst_session *sess)
+{
+ debugfs_remove_recursive(sess->debugfs_dir);
+ sess->debugfs_dir = NULL;
+}
+
+int scst_tgt_dev_debugfs_create(struct scst_tgt_dev *tgt_dev)
+{
+ int res;
+ char lun[16];
+
+ res = -ENOMEM;
+ snprintf(lun, sizeof(lun), "%llx", tgt_dev->lun);
+ tgt_dev->debugfs_dir = debugfs_create_dir(lun, tgt_dev->sess->luns_dir);
+ if (!tgt_dev->debugfs_dir) {
+ PRINT_ERROR("Creation of directory %s/luns/%s failed",
+ tgt_dev->sess->initiator_name, lun);
+ goto out;
+ }
+ res = 0;
+out:
+ return res;
+}
+
+void scst_tgt_dev_debugfs_remove(struct scst_tgt_dev *tgt_dev)
+{
+ debugfs_remove_recursive(tgt_dev->debugfs_dir);
+ tgt_dev->debugfs_dir = NULL;
+}
+
+int scst_devt_debugfs_create(struct scst_dev_type *devt)
+{
+ int res;
+
+ res = -ENOMEM;
+ devt->tracing_dir = debugfs_create_dir(devt->name, scst_debug_devt);
+ if (!devt->tracing_dir)
+ goto out;
+ if (devt->trace_data.trace_flags &&
+ !scst_create_trace_files(devt->tracing_dir, &devt->trace_data))
+ goto err;
+ res = 0;
+out:
+ return res;
+err:
+ scst_devt_debugfs_remove(devt);
+ goto out;
}
-void scst_devt_remove_trace_files(struct scst_dev_type *devt)
+void scst_devt_debugfs_remove(struct scst_dev_type *devt)
{
- scst_remove_trace_files(devt->tracing_dir);
+ debugfs_remove_recursive(devt->tracing_dir);
devt->tracing_dir = NULL;
}
diff --git a/drivers/scst/scst_tracing.h b/drivers/scst/scst_tracing.h
index 8fd40bd..23b820b 100644
--- a/drivers/scst/scst_tracing.h
+++ b/drivers/scst/scst_tracing.h
@@ -4,12 +4,18 @@
int scst_debugfs_init(void);
void scst_debugfs_cleanup(void);
-int scst_main_create_trace_files(void);
-void scst_main_remove_trace_files(void);
-int scst_tgtt_create_trace_files(struct scst_tgt_template *tgtt);
-void scst_tgtt_remove_trace_files(struct scst_tgt_template *tgtt);
-int scst_devt_create_trace_files(struct scst_dev_type *devt);
-void scst_devt_remove_trace_files(struct scst_dev_type *devt);
+int scst_main_debugfs_create(void);
+void scst_main_debugfs_remove(void);
+int scst_tgtt_debugfs_create(struct scst_tgt_template *tgtt);
+void scst_tgtt_debugfs_remove(struct scst_tgt_template *tgtt);
+int scst_tgt_debugfs_create(struct scst_tgt *tgtt);
+void scst_tgt_debugfs_remove(struct scst_tgt *tgtt);
+int scst_sess_debugfs_create(struct scst_session *tgtt);
+void scst_sess_debugfs_remove(struct scst_session *tgtt);
+int scst_tgt_dev_debugfs_create(struct scst_tgt_dev *tgtt);
+void scst_tgt_dev_debugfs_remove(struct scst_tgt_dev *tgtt);
+int scst_devt_debugfs_create(struct scst_dev_type *devt);
+void scst_devt_debugfs_remove(struct scst_dev_type *devt);
int scst_dev_create_debug_files(struct scst_device *dev);
void scst_dev_remove_debug_files(struct scst_device *dev);
@@ -24,30 +30,57 @@ static inline void scst_debugfs_cleanup(void)
{
}
-static inline int scst_main_create_trace_files(void)
+static inline int scst_main_debugfs_create(void)
{
return 0;
}
-static inline void scst_main_remove_trace_files(void)
+static inline void scst_main_debugfs_remove(void)
{
}
-static inline int scst_tgtt_create_trace_files(struct scst_tgt_template *tgtt)
+static inline int scst_tgtt_debugfs_create(struct scst_tgt_template *tgtt)
{
return 0;
}
-static inline void scst_tgtt_remove_trace_files(struct scst_tgt_template *tgtt)
+static inline void scst_tgtt_debugfs_remove(struct scst_tgt_template *tgtt)
{
}
-static inline int scst_devt_create_trace_files(struct scst_dev_type *devt)
+static inline int scst_tgt_debugfs_create(struct scst_tgt *tgtt)
{
return 0;
}
-static inline void scst_devt_remove_trace_files(struct scst_dev_type *devt)
+static inline void scst_tgt_debugfs_remove(struct scst_tgt *tgtt)
+{
+}
+
+static inline int scst_sess_debugfs_create(struct scst_session *tgtt)
+{
+ return 0;
+}
+
+static inline void scst_sess_debugfs_remove(struct scst_session *tgtt)
+{
+}
+
+static inline int scst_tgt_dev_debugfs_create(struct scst_tgt_dev *tgtt)
+{
+ return 0;
+}
+
+static inline void scst_tgt_dev_debugfs_remove(struct scst_tgt_dev *tgtt)
+{
+}
+
+static inline int scst_devt_debugfs_create(struct scst_dev_type *devt)
+{
+ return 0;
+}
+
+static inline void scst_devt_debugfs_remove(struct scst_dev_type *devt)
{
}
diff --git a/include/scst/scst.h b/include/scst/scst.h
index 9034624..1f59ec1 100644
--- a/include/scst/scst.h
+++ b/include/scst/scst.h
@@ -1316,6 +1316,11 @@ struct scst_tgt {
struct kobject *tgt_sess_kobj; /* target/sessions/ */
struct kobject *tgt_luns_kobj; /* target/luns/ */
struct kobject *tgt_ini_grp_kobj; /* target/ini_groups/ */
+
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+ struct dentry *debugfs_dir;
+ struct dentry *sessions_dir;
+#endif
};
#ifdef CONFIG_SCST_MEASURE_LATENCY
@@ -1449,6 +1454,10 @@ struct scst_session {
int result);
void (*unreg_done_fn) (struct scst_session *sess);
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+ struct dentry *debugfs_dir;
+ struct dentry *luns_dir;
+#endif
#ifdef CONFIG_SCST_MEASURE_LATENCY
/*
* Must be the last to allow to work with drivers who don't know
@@ -1460,6 +1469,8 @@ struct scst_session {
uint64_t min_scst_time, min_tgt_time, min_dev_time;
uint64_t max_scst_time, max_tgt_time, max_dev_time;
struct scst_ext_latency_stat sess_latency_stat[SCST_LATENCY_STATS_NUM];
+
+ struct dentry *latency_file;
#endif
};
@@ -1813,6 +1824,9 @@ struct scst_cmd {
struct scst_cmd *orig_cmd; /* Used to issue REQUEST SENSE */
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+ struct dentry *debugfs_dir;
+#endif
#ifdef CONFIG_SCST_MEASURE_LATENCY
/*
* Must be the last to allow to work with drivers who don't know
@@ -1822,6 +1836,8 @@ struct scst_cmd {
uint64_t restart_waiting_time, rdy_to_xfer_time;
uint64_t pre_exec_time, exec_time, dev_done_time;
uint64_t xmit_time, tgt_on_free_time, dev_on_free_time;
+
+ struct dentry *latency_file;
#endif
};
@@ -2228,6 +2244,9 @@ struct scst_tgt_dev {
struct kobject tgt_dev_kobj; /* kobject for this struct */
+#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
+ struct dentry *debugfs_dir;
+#endif
#ifdef CONFIG_SCST_MEASURE_LATENCY
/*
* Must be the last to allow to work with drivers who don't know
@@ -2238,6 +2257,8 @@ struct scst_tgt_dev {
uint64_t scst_time, tgt_time, dev_time;
unsigned int processed_cmds;
struct scst_ext_latency_stat dev_latency_stat[SCST_LATENCY_STATS_NUM];
+
+ struct dentry *latency_file;
#endif
};
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread