xref: /openbmc/linux/drivers/md/dm-sysfs.c (revision 17e149b8)
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>
9784aae73SMilan Broz #include "dm.h"
10784aae73SMilan Broz 
11784aae73SMilan Broz struct dm_sysfs_attr {
12784aae73SMilan Broz 	struct attribute attr;
13784aae73SMilan Broz 	ssize_t (*show)(struct mapped_device *, char *);
14b898320dSMike Snitzer 	ssize_t (*store)(struct mapped_device *, const char *, size_t count);
15784aae73SMilan Broz };
16784aae73SMilan Broz 
17784aae73SMilan Broz #define DM_ATTR_RO(_name) \
18784aae73SMilan Broz struct dm_sysfs_attr dm_attr_##_name = \
19784aae73SMilan Broz 	__ATTR(_name, S_IRUGO, dm_attr_##_name##_show, NULL)
20784aae73SMilan Broz 
21784aae73SMilan Broz static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
22784aae73SMilan Broz 			    char *page)
23784aae73SMilan Broz {
24784aae73SMilan Broz 	struct dm_sysfs_attr *dm_attr;
25784aae73SMilan Broz 	struct mapped_device *md;
26784aae73SMilan Broz 	ssize_t ret;
27784aae73SMilan Broz 
28784aae73SMilan Broz 	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
29784aae73SMilan Broz 	if (!dm_attr->show)
30784aae73SMilan Broz 		return -EIO;
31784aae73SMilan Broz 
32784aae73SMilan Broz 	md = dm_get_from_kobject(kobj);
33784aae73SMilan Broz 	if (!md)
34784aae73SMilan Broz 		return -EINVAL;
35784aae73SMilan Broz 
36784aae73SMilan Broz 	ret = dm_attr->show(md, page);
37784aae73SMilan Broz 	dm_put(md);
38784aae73SMilan Broz 
39784aae73SMilan Broz 	return ret;
40784aae73SMilan Broz }
41784aae73SMilan Broz 
42b898320dSMike Snitzer #define DM_ATTR_RW(_name) \
43b898320dSMike Snitzer struct dm_sysfs_attr dm_attr_##_name = \
44b898320dSMike Snitzer 	__ATTR(_name, S_IRUGO | S_IWUSR, dm_attr_##_name##_show, dm_attr_##_name##_store)
45b898320dSMike Snitzer 
46b898320dSMike Snitzer static ssize_t dm_attr_store(struct kobject *kobj, struct attribute *attr,
47b898320dSMike Snitzer 			     const char *page, size_t count)
48b898320dSMike Snitzer {
49b898320dSMike Snitzer 	struct dm_sysfs_attr *dm_attr;
50b898320dSMike Snitzer 	struct mapped_device *md;
51b898320dSMike Snitzer 	ssize_t ret;
52b898320dSMike Snitzer 
53b898320dSMike Snitzer 	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
54b898320dSMike Snitzer 	if (!dm_attr->store)
55b898320dSMike Snitzer 		return -EIO;
56b898320dSMike Snitzer 
57b898320dSMike Snitzer 	md = dm_get_from_kobject(kobj);
58b898320dSMike Snitzer 	if (!md)
59b898320dSMike Snitzer 		return -EINVAL;
60b898320dSMike Snitzer 
61b898320dSMike Snitzer 	ret = dm_attr->store(md, page, count);
62b898320dSMike Snitzer 	dm_put(md);
63b898320dSMike Snitzer 
64b898320dSMike Snitzer 	return ret;
65b898320dSMike Snitzer }
66b898320dSMike Snitzer 
67784aae73SMilan Broz static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
68784aae73SMilan Broz {
69784aae73SMilan Broz 	if (dm_copy_name_and_uuid(md, buf, NULL))
70784aae73SMilan Broz 		return -EIO;
71784aae73SMilan Broz 
72784aae73SMilan Broz 	strcat(buf, "\n");
73784aae73SMilan Broz 	return strlen(buf);
74784aae73SMilan Broz }
75784aae73SMilan Broz 
76784aae73SMilan Broz static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf)
77784aae73SMilan Broz {
78784aae73SMilan Broz 	if (dm_copy_name_and_uuid(md, NULL, buf))
79784aae73SMilan Broz 		return -EIO;
80784aae73SMilan Broz 
81784aae73SMilan Broz 	strcat(buf, "\n");
82784aae73SMilan Broz 	return strlen(buf);
83784aae73SMilan Broz }
84784aae73SMilan Broz 
85486d220fSPeter Rajnoha static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
86486d220fSPeter Rajnoha {
874f186f8bSKiyoshi Ueda 	sprintf(buf, "%d\n", dm_suspended_md(md));
88486d220fSPeter Rajnoha 
89486d220fSPeter Rajnoha 	return strlen(buf);
90486d220fSPeter Rajnoha }
91486d220fSPeter Rajnoha 
9217e149b8SMike Snitzer static ssize_t dm_attr_use_blk_mq_show(struct mapped_device *md, char *buf)
9317e149b8SMike Snitzer {
9417e149b8SMike Snitzer 	sprintf(buf, "%d\n", dm_use_blk_mq(md));
9517e149b8SMike Snitzer 
9617e149b8SMike Snitzer 	return strlen(buf);
9717e149b8SMike Snitzer }
9817e149b8SMike Snitzer 
99784aae73SMilan Broz static DM_ATTR_RO(name);
100784aae73SMilan Broz static DM_ATTR_RO(uuid);
101486d220fSPeter Rajnoha static DM_ATTR_RO(suspended);
10217e149b8SMike Snitzer static DM_ATTR_RO(use_blk_mq);
1030ce65797SMike Snitzer static DM_ATTR_RW(rq_based_seq_io_merge_deadline);
104784aae73SMilan Broz 
105784aae73SMilan Broz static struct attribute *dm_attrs[] = {
106784aae73SMilan Broz 	&dm_attr_name.attr,
107784aae73SMilan Broz 	&dm_attr_uuid.attr,
108486d220fSPeter Rajnoha 	&dm_attr_suspended.attr,
10917e149b8SMike Snitzer 	&dm_attr_use_blk_mq.attr,
1100ce65797SMike Snitzer 	&dm_attr_rq_based_seq_io_merge_deadline.attr,
111784aae73SMilan Broz 	NULL,
112784aae73SMilan Broz };
113784aae73SMilan Broz 
11452cf25d0SEmese Revfy static const struct sysfs_ops dm_sysfs_ops = {
115784aae73SMilan Broz 	.show	= dm_attr_show,
116b898320dSMike Snitzer 	.store	= dm_attr_store,
117784aae73SMilan Broz };
118784aae73SMilan Broz 
119784aae73SMilan Broz static struct kobj_type dm_ktype = {
120784aae73SMilan Broz 	.sysfs_ops	= &dm_sysfs_ops,
121784aae73SMilan Broz 	.default_attrs	= dm_attrs,
122be35f486SMikulas Patocka 	.release	= dm_kobject_release,
123784aae73SMilan Broz };
124784aae73SMilan Broz 
125784aae73SMilan Broz /*
126784aae73SMilan Broz  * Initialize kobj
127784aae73SMilan Broz  * because nobody using md yet, no need to call explicit dm_get/put
128784aae73SMilan Broz  */
129784aae73SMilan Broz int dm_sysfs_init(struct mapped_device *md)
130784aae73SMilan Broz {
131784aae73SMilan Broz 	return kobject_init_and_add(dm_kobject(md), &dm_ktype,
132784aae73SMilan Broz 				    &disk_to_dev(dm_disk(md))->kobj,
133784aae73SMilan Broz 				    "%s", "dm");
134784aae73SMilan Broz }
135784aae73SMilan Broz 
136784aae73SMilan Broz /*
137784aae73SMilan Broz  * Remove kobj, called after all references removed
138784aae73SMilan Broz  */
139784aae73SMilan Broz void dm_sysfs_exit(struct mapped_device *md)
140784aae73SMilan Broz {
141be35f486SMikulas Patocka 	struct kobject *kobj = dm_kobject(md);
142be35f486SMikulas Patocka 	kobject_put(kobj);
143be35f486SMikulas Patocka 	wait_for_completion(dm_get_completion_from_kobject(kobj));
144784aae73SMilan Broz }
145