xref: /openbmc/linux/drivers/md/dm-sysfs.c (revision b0bbd86a)
13bd94003SHeinz Mauelshagen // SPDX-License-Identifier: GPL-2.0-only
2784aae73SMilan Broz /*
3784aae73SMilan Broz  * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
4784aae73SMilan Broz  *
5784aae73SMilan Broz  * This file is released under the GPL.
6784aae73SMilan Broz  */
7784aae73SMilan Broz 
8784aae73SMilan Broz #include <linux/sysfs.h>
9784aae73SMilan Broz #include <linux/dm-ioctl.h>
104cc96131SMike Snitzer #include "dm-core.h"
114cc96131SMike Snitzer #include "dm-rq.h"
12784aae73SMilan Broz 
13784aae73SMilan Broz struct dm_sysfs_attr {
14784aae73SMilan Broz 	struct attribute attr;
1502f10ba1SHeinz Mauelshagen 	ssize_t (*show)(struct mapped_device *md, char *p);
1602f10ba1SHeinz Mauelshagen 	ssize_t (*store)(struct mapped_device *md, const char *p, size_t count);
17784aae73SMilan Broz };
18784aae73SMilan Broz 
19784aae73SMilan Broz #define DM_ATTR_RO(_name) \
20784aae73SMilan Broz struct dm_sysfs_attr dm_attr_##_name = \
216a808034SHeinz Mauelshagen 	__ATTR(_name, 0444, dm_attr_##_name##_show, NULL)
22784aae73SMilan Broz 
dm_attr_show(struct kobject * kobj,struct attribute * attr,char * page)23784aae73SMilan Broz static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
24784aae73SMilan Broz 			    char *page)
25784aae73SMilan Broz {
26784aae73SMilan Broz 	struct dm_sysfs_attr *dm_attr;
27784aae73SMilan Broz 	struct mapped_device *md;
28784aae73SMilan Broz 	ssize_t ret;
29784aae73SMilan Broz 
30784aae73SMilan Broz 	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
31784aae73SMilan Broz 	if (!dm_attr->show)
32784aae73SMilan Broz 		return -EIO;
33784aae73SMilan Broz 
34784aae73SMilan Broz 	md = dm_get_from_kobject(kobj);
35784aae73SMilan Broz 	if (!md)
36784aae73SMilan Broz 		return -EINVAL;
37784aae73SMilan Broz 
38784aae73SMilan Broz 	ret = dm_attr->show(md, page);
39784aae73SMilan Broz 	dm_put(md);
40784aae73SMilan Broz 
41784aae73SMilan Broz 	return ret;
42784aae73SMilan Broz }
43784aae73SMilan Broz 
44b898320dSMike Snitzer #define DM_ATTR_RW(_name) \
45b898320dSMike Snitzer struct dm_sysfs_attr dm_attr_##_name = \
466a808034SHeinz Mauelshagen 	__ATTR(_name, 0644, dm_attr_##_name##_show, dm_attr_##_name##_store)
47b898320dSMike Snitzer 
dm_attr_store(struct kobject * kobj,struct attribute * attr,const char * page,size_t count)48b898320dSMike Snitzer static ssize_t dm_attr_store(struct kobject *kobj, struct attribute *attr,
49b898320dSMike Snitzer 			     const char *page, size_t count)
50b898320dSMike Snitzer {
51b898320dSMike Snitzer 	struct dm_sysfs_attr *dm_attr;
52b898320dSMike Snitzer 	struct mapped_device *md;
53b898320dSMike Snitzer 	ssize_t ret;
54b898320dSMike Snitzer 
55b898320dSMike Snitzer 	dm_attr = container_of(attr, struct dm_sysfs_attr, attr);
56b898320dSMike Snitzer 	if (!dm_attr->store)
57b898320dSMike Snitzer 		return -EIO;
58b898320dSMike Snitzer 
59b898320dSMike Snitzer 	md = dm_get_from_kobject(kobj);
60b898320dSMike Snitzer 	if (!md)
61b898320dSMike Snitzer 		return -EINVAL;
62b898320dSMike Snitzer 
63b898320dSMike Snitzer 	ret = dm_attr->store(md, page, count);
64b898320dSMike Snitzer 	dm_put(md);
65b898320dSMike Snitzer 
66b898320dSMike Snitzer 	return ret;
67b898320dSMike Snitzer }
68b898320dSMike Snitzer 
dm_attr_name_show(struct mapped_device * md,char * buf)69784aae73SMilan Broz static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
70784aae73SMilan Broz {
71784aae73SMilan Broz 	if (dm_copy_name_and_uuid(md, buf, NULL))
72784aae73SMilan Broz 		return -EIO;
73784aae73SMilan Broz 
74784aae73SMilan Broz 	strcat(buf, "\n");
75784aae73SMilan Broz 	return strlen(buf);
76784aae73SMilan Broz }
77784aae73SMilan Broz 
dm_attr_uuid_show(struct mapped_device * md,char * buf)78784aae73SMilan Broz static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf)
79784aae73SMilan Broz {
80784aae73SMilan Broz 	if (dm_copy_name_and_uuid(md, NULL, buf))
81784aae73SMilan Broz 		return -EIO;
82784aae73SMilan Broz 
83784aae73SMilan Broz 	strcat(buf, "\n");
84784aae73SMilan Broz 	return strlen(buf);
85784aae73SMilan Broz }
86784aae73SMilan Broz 
dm_attr_suspended_show(struct mapped_device * md,char * buf)87486d220fSPeter Rajnoha static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf)
88486d220fSPeter Rajnoha {
894f186f8bSKiyoshi Ueda 	sprintf(buf, "%d\n", dm_suspended_md(md));
90486d220fSPeter Rajnoha 
91486d220fSPeter Rajnoha 	return strlen(buf);
92486d220fSPeter Rajnoha }
93486d220fSPeter Rajnoha 
dm_attr_use_blk_mq_show(struct mapped_device * md,char * buf)9417e149b8SMike Snitzer static ssize_t dm_attr_use_blk_mq_show(struct mapped_device *md, char *buf)
9517e149b8SMike Snitzer {
966a23e05cSJens Axboe 	/* Purely for userspace compatibility */
976a23e05cSJens Axboe 	sprintf(buf, "%d\n", true);
9817e149b8SMike Snitzer 
9917e149b8SMike Snitzer 	return strlen(buf);
10017e149b8SMike Snitzer }
10117e149b8SMike Snitzer 
102784aae73SMilan Broz static DM_ATTR_RO(name);
103784aae73SMilan Broz static DM_ATTR_RO(uuid);
104486d220fSPeter Rajnoha static DM_ATTR_RO(suspended);
10517e149b8SMike Snitzer static DM_ATTR_RO(use_blk_mq);
1060ce65797SMike Snitzer static DM_ATTR_RW(rq_based_seq_io_merge_deadline);
107784aae73SMilan Broz 
108784aae73SMilan Broz static struct attribute *dm_attrs[] = {
109784aae73SMilan Broz 	&dm_attr_name.attr,
110784aae73SMilan Broz 	&dm_attr_uuid.attr,
111486d220fSPeter Rajnoha 	&dm_attr_suspended.attr,
11217e149b8SMike Snitzer 	&dm_attr_use_blk_mq.attr,
1130ce65797SMike Snitzer 	&dm_attr_rq_based_seq_io_merge_deadline.attr,
114784aae73SMilan Broz 	NULL,
115784aae73SMilan Broz };
116eaac0b59SGreg Kroah-Hartman ATTRIBUTE_GROUPS(dm);
117784aae73SMilan Broz 
11852cf25d0SEmese Revfy static const struct sysfs_ops dm_sysfs_ops = {
119784aae73SMilan Broz 	.show	= dm_attr_show,
120b898320dSMike Snitzer 	.store	= dm_attr_store,
121784aae73SMilan Broz };
122784aae73SMilan Broz 
123*b0bbd86aSThomas Weißschuh static const struct kobj_type dm_ktype = {
124784aae73SMilan Broz 	.sysfs_ops	= &dm_sysfs_ops,
125eaac0b59SGreg Kroah-Hartman 	.default_groups	= dm_groups,
126be35f486SMikulas Patocka 	.release	= dm_kobject_release,
127784aae73SMilan Broz };
128784aae73SMilan Broz 
129784aae73SMilan Broz /*
130784aae73SMilan Broz  * Initialize kobj
131784aae73SMilan Broz  * because nobody using md yet, no need to call explicit dm_get/put
132784aae73SMilan Broz  */
dm_sysfs_init(struct mapped_device * md)133784aae73SMilan Broz int dm_sysfs_init(struct mapped_device *md)
134784aae73SMilan Broz {
135784aae73SMilan Broz 	return kobject_init_and_add(dm_kobject(md), &dm_ktype,
136784aae73SMilan Broz 				    &disk_to_dev(dm_disk(md))->kobj,
137784aae73SMilan Broz 				    "%s", "dm");
138784aae73SMilan Broz }
139784aae73SMilan Broz 
140784aae73SMilan Broz /*
141784aae73SMilan Broz  * Remove kobj, called after all references removed
142784aae73SMilan Broz  */
dm_sysfs_exit(struct mapped_device * md)143784aae73SMilan Broz void dm_sysfs_exit(struct mapped_device *md)
144784aae73SMilan Broz {
145be35f486SMikulas Patocka 	struct kobject *kobj = dm_kobject(md);
1460ef0b471SHeinz Mauelshagen 
147be35f486SMikulas Patocka 	kobject_put(kobj);
148be35f486SMikulas Patocka 	wait_for_completion(dm_get_completion_from_kobject(kobj));
149784aae73SMilan Broz }
150