0001
0002
0003
0004
0005
0006
0007 #include <linux/sysfs.h>
0008 #include <linux/dm-ioctl.h>
0009 #include "dm-core.h"
0010 #include "dm-rq.h"
0011
0012 struct dm_sysfs_attr {
0013 struct attribute attr;
0014 ssize_t (*show)(struct mapped_device *, char *);
0015 ssize_t (*store)(struct mapped_device *, const char *, size_t count);
0016 };
0017
0018 #define DM_ATTR_RO(_name) \
0019 struct dm_sysfs_attr dm_attr_##_name = \
0020 __ATTR(_name, S_IRUGO, dm_attr_##_name##_show, NULL)
0021
0022 static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
0023 char *page)
0024 {
0025 struct dm_sysfs_attr *dm_attr;
0026 struct mapped_device *md;
0027 ssize_t ret;
0028
0029 dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
0030 if (!dm_attr->show)
0031 return -EIO;
0032
0033 md = dm_get_from_kobject(kobj);
0034 if (!md)
0035 return -EINVAL;
0036
0037 ret = dm_attr->show(md, page);
0038 dm_put(md);
0039
0040 return ret;
0041 }
0042
0043 #define DM_ATTR_RW(_name) \
0044 struct dm_sysfs_attr dm_attr_##_name = \
0045 __ATTR(_name, S_IRUGO | S_IWUSR, dm_attr_##_name##_show, dm_attr_##_name##_store)
0046
0047 static ssize_t dm_attr_store(struct kobject *kobj, struct attribute *attr,
0048 const char *page, size_t count)
0049 {
0050 struct dm_sysfs_attr *dm_attr;
0051 struct mapped_device *md;
0052 ssize_t ret;
0053
0054 dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
0055 if (!dm_attr->store)
0056 return -EIO;
0057
0058 md = dm_get_from_kobject(kobj);
0059 if (!md)
0060 return -EINVAL;
0061
0062 ret = dm_attr->store(md, page, count);
0063 dm_put(md);
0064
0065 return ret;
0066 }
0067
0068 static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
0069 {
0070 if (dm_copy_name_and_uuid(md, buf, NULL))
0071 return -EIO;
0072
0073 strcat(buf, "\n");
0074 return strlen(buf);
0075 }
0076
0077 static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf)
0078 {
0079 if (dm_copy_name_and_uuid(md, NULL, buf))
0080 return -EIO;
0081
0082 strcat(buf, "\n");
0083 return strlen(buf);
0084 }
0085
0086 static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
0087 {
0088 sprintf(buf, "%d\n", dm_suspended_md(md));
0089
0090 return strlen(buf);
0091 }
0092
0093 static ssize_t dm_attr_use_blk_mq_show(struct mapped_device *md, char *buf)
0094 {
0095
0096 sprintf(buf, "%d\n", true);
0097
0098 return strlen(buf);
0099 }
0100
0101 static DM_ATTR_RO(name);
0102 static DM_ATTR_RO(uuid);
0103 static DM_ATTR_RO(suspended);
0104 static DM_ATTR_RO(use_blk_mq);
0105 static DM_ATTR_RW(rq_based_seq_io_merge_deadline);
0106
0107 static struct attribute *dm_attrs[] = {
0108 &dm_attr_name.attr,
0109 &dm_attr_uuid.attr,
0110 &dm_attr_suspended.attr,
0111 &dm_attr_use_blk_mq.attr,
0112 &dm_attr_rq_based_seq_io_merge_deadline.attr,
0113 NULL,
0114 };
0115 ATTRIBUTE_GROUPS(dm);
0116
0117 static const struct sysfs_ops dm_sysfs_ops = {
0118 .show = dm_attr_show,
0119 .store = dm_attr_store,
0120 };
0121
0122 static struct kobj_type dm_ktype = {
0123 .sysfs_ops = &dm_sysfs_ops,
0124 .default_groups = dm_groups,
0125 .release = dm_kobject_release,
0126 };
0127
0128
0129
0130
0131
0132 int dm_sysfs_init(struct mapped_device *md)
0133 {
0134 return kobject_init_and_add(dm_kobject(md), &dm_ktype,
0135 &disk_to_dev(dm_disk(md))->kobj,
0136 "%s", "dm");
0137 }
0138
0139
0140
0141
0142 void dm_sysfs_exit(struct mapped_device *md)
0143 {
0144 struct kobject *kobj = dm_kobject(md);
0145 kobject_put(kobj);
0146 wait_for_completion(dm_get_completion_from_kobject(kobj));
0147 }