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