xref: /openbmc/linux/drivers/md/dm-sysfs.c (revision 6a23e05c)
1784aae73SMilan Broz /*
2784aae73SMilan Broz  * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
3784aae73SMilan Broz  *
4784aae73SMilan Broz  * This file is released under the GPL.
5784aae73SMilan Broz  */
6784aae73SMilan Broz 
7784aae73SMilan Broz #include <linux/sysfs.h>
8784aae73SMilan Broz #include <linux/dm-ioctl.h>
94cc96131SMike Snitzer #include "dm-core.h"
104cc96131SMike Snitzer #include "dm-rq.h"
11784aae73SMilan Broz 
12784aae73SMilan Broz struct dm_sysfs_attr {
13784aae73SMilan Broz 	struct attribute attr;
14784aae73SMilan Broz 	ssize_t (*show)(struct mapped_device *, char *);
15b898320dSMike Snitzer 	ssize_t (*store)(struct mapped_device *, const char *, size_t count);
16784aae73SMilan Broz };
17784aae73SMilan Broz 
18784aae73SMilan Broz #define DM_ATTR_RO(_name) \
19784aae73SMilan Broz struct dm_sysfs_attr dm_attr_##_name = \
20784aae73SMilan Broz 	__ATTR(_name, S_IRUGO, dm_attr_##_name##_show, NULL)
21784aae73SMilan Broz 
22784aae73SMilan Broz static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
23784aae73SMilan Broz 			    char *page)
24784aae73SMilan Broz {
25784aae73SMilan Broz 	struct dm_sysfs_attr *dm_attr;
26784aae73SMilan Broz 	struct mapped_device *md;
27784aae73SMilan Broz 	ssize_t ret;
28784aae73SMilan Broz 
29784aae73SMilan Broz 	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
30784aae73SMilan Broz 	if (!dm_attr->show)
31784aae73SMilan Broz 		return -EIO;
32784aae73SMilan Broz 
33784aae73SMilan Broz 	md = dm_get_from_kobject(kobj);
34784aae73SMilan Broz 	if (!md)
35784aae73SMilan Broz 		return -EINVAL;
36784aae73SMilan Broz 
37784aae73SMilan Broz 	ret = dm_attr->show(md, page);
38784aae73SMilan Broz 	dm_put(md);
39784aae73SMilan Broz 
40784aae73SMilan Broz 	return ret;
41784aae73SMilan Broz }
42784aae73SMilan Broz 
43b898320dSMike Snitzer #define DM_ATTR_RW(_name) \
44b898320dSMike Snitzer struct dm_sysfs_attr dm_attr_##_name = \
45b898320dSMike Snitzer 	__ATTR(_name, S_IRUGO | S_IWUSR, dm_attr_##_name##_show, dm_attr_##_name##_store)
46b898320dSMike Snitzer 
47b898320dSMike Snitzer static ssize_t dm_attr_store(struct kobject *kobj, struct attribute *attr,
48b898320dSMike Snitzer 			     const char *page, size_t count)
49b898320dSMike Snitzer {
50b898320dSMike Snitzer 	struct dm_sysfs_attr *dm_attr;
51b898320dSMike Snitzer 	struct mapped_device *md;
52b898320dSMike Snitzer 	ssize_t ret;
53b898320dSMike Snitzer 
54b898320dSMike Snitzer 	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
55b898320dSMike Snitzer 	if (!dm_attr->store)
56b898320dSMike Snitzer 		return -EIO;
57b898320dSMike Snitzer 
58b898320dSMike Snitzer 	md = dm_get_from_kobject(kobj);
59b898320dSMike Snitzer 	if (!md)
60b898320dSMike Snitzer 		return -EINVAL;
61b898320dSMike Snitzer 
62b898320dSMike Snitzer 	ret = dm_attr->store(md, page, count);
63b898320dSMike Snitzer 	dm_put(md);
64b898320dSMike Snitzer 
65b898320dSMike Snitzer 	return ret;
66b898320dSMike Snitzer }
67b898320dSMike Snitzer 
68784aae73SMilan Broz static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
69784aae73SMilan Broz {
70784aae73SMilan Broz 	if (dm_copy_name_and_uuid(md, buf, NULL))
71784aae73SMilan Broz 		return -EIO;
72784aae73SMilan Broz 
73784aae73SMilan Broz 	strcat(buf, "\n");
74784aae73SMilan Broz 	return strlen(buf);
75784aae73SMilan Broz }
76784aae73SMilan Broz 
77784aae73SMilan Broz static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf)
78784aae73SMilan Broz {
79784aae73SMilan Broz 	if (dm_copy_name_and_uuid(md, NULL, buf))
80784aae73SMilan Broz 		return -EIO;
81784aae73SMilan Broz 
82784aae73SMilan Broz 	strcat(buf, "\n");
83784aae73SMilan Broz 	return strlen(buf);
84784aae73SMilan Broz }
85784aae73SMilan Broz 
86486d220fSPeter Rajnoha static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
87486d220fSPeter Rajnoha {
884f186f8bSKiyoshi Ueda 	sprintf(buf, "%d\n", dm_suspended_md(md));
89486d220fSPeter Rajnoha 
90486d220fSPeter Rajnoha 	return strlen(buf);
91486d220fSPeter Rajnoha }
92486d220fSPeter Rajnoha 
9317e149b8SMike Snitzer static ssize_t dm_attr_use_blk_mq_show(struct mapped_device *md, char *buf)
9417e149b8SMike Snitzer {
956a23e05cSJens Axboe 	/* Purely for userspace compatibility */
966a23e05cSJens Axboe 	sprintf(buf, "%d\n", true);
9717e149b8SMike Snitzer 
9817e149b8SMike Snitzer 	return strlen(buf);
9917e149b8SMike Snitzer }
10017e149b8SMike Snitzer 
101784aae73SMilan Broz static DM_ATTR_RO(name);
102784aae73SMilan Broz static DM_ATTR_RO(uuid);
103486d220fSPeter Rajnoha static DM_ATTR_RO(suspended);
10417e149b8SMike Snitzer static DM_ATTR_RO(use_blk_mq);
1050ce65797SMike Snitzer static DM_ATTR_RW(rq_based_seq_io_merge_deadline);
106784aae73SMilan Broz 
107784aae73SMilan Broz static struct attribute *dm_attrs[] = {
108784aae73SMilan Broz 	&dm_attr_name.attr,
109784aae73SMilan Broz 	&dm_attr_uuid.attr,
110486d220fSPeter Rajnoha 	&dm_attr_suspended.attr,
11117e149b8SMike Snitzer 	&dm_attr_use_blk_mq.attr,
1120ce65797SMike Snitzer 	&dm_attr_rq_based_seq_io_merge_deadline.attr,
113784aae73SMilan Broz 	NULL,
114784aae73SMilan Broz };
115784aae73SMilan Broz 
11652cf25d0SEmese Revfy static const struct sysfs_ops dm_sysfs_ops = {
117784aae73SMilan Broz 	.show	= dm_attr_show,
118b898320dSMike Snitzer 	.store	= dm_attr_store,
119784aae73SMilan Broz };
120784aae73SMilan Broz 
121784aae73SMilan Broz static struct kobj_type dm_ktype = {
122784aae73SMilan Broz 	.sysfs_ops	= &dm_sysfs_ops,
123784aae73SMilan Broz 	.default_attrs	= dm_attrs,
124be35f486SMikulas Patocka 	.release	= dm_kobject_release,
125784aae73SMilan Broz };
126784aae73SMilan Broz 
127784aae73SMilan Broz /*
128784aae73SMilan Broz  * Initialize kobj
129784aae73SMilan Broz  * because nobody using md yet, no need to call explicit dm_get/put
130784aae73SMilan Broz  */
131784aae73SMilan Broz int dm_sysfs_init(struct mapped_device *md)
132784aae73SMilan Broz {
133784aae73SMilan Broz 	return kobject_init_and_add(dm_kobject(md), &dm_ktype,
134784aae73SMilan Broz 				    &disk_to_dev(dm_disk(md))->kobj,
135784aae73SMilan Broz 				    "%s", "dm");
136784aae73SMilan Broz }
137784aae73SMilan Broz 
138784aae73SMilan Broz /*
139784aae73SMilan Broz  * Remove kobj, called after all references removed
140784aae73SMilan Broz  */
141784aae73SMilan Broz void dm_sysfs_exit(struct mapped_device *md)
142784aae73SMilan Broz {
143be35f486SMikulas Patocka 	struct kobject *kobj = dm_kobject(md);
144be35f486SMikulas Patocka 	kobject_put(kobj);
145be35f486SMikulas Patocka 	wait_for_completion(dm_get_completion_from_kobject(kobj));
146784aae73SMilan Broz }
147