| Milan Broz | 784aae7 | 2009-01-06 03:05:12 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2008 Red Hat, Inc. All rights reserved. | 
|  | 3 | * | 
|  | 4 | * This file is released under the GPL. | 
|  | 5 | */ | 
|  | 6 |  | 
|  | 7 | #include <linux/sysfs.h> | 
|  | 8 | #include <linux/dm-ioctl.h> | 
|  | 9 | #include "dm.h" | 
|  | 10 |  | 
|  | 11 | struct dm_sysfs_attr { | 
|  | 12 | struct attribute attr; | 
|  | 13 | ssize_t (*show)(struct mapped_device *, char *); | 
|  | 14 | ssize_t (*store)(struct mapped_device *, char *); | 
|  | 15 | }; | 
|  | 16 |  | 
|  | 17 | #define DM_ATTR_RO(_name) \ | 
|  | 18 | struct dm_sysfs_attr dm_attr_##_name = \ | 
|  | 19 | __ATTR(_name, S_IRUGO, dm_attr_##_name##_show, NULL) | 
|  | 20 |  | 
|  | 21 | static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr, | 
|  | 22 | char *page) | 
|  | 23 | { | 
|  | 24 | struct dm_sysfs_attr *dm_attr; | 
|  | 25 | struct mapped_device *md; | 
|  | 26 | ssize_t ret; | 
|  | 27 |  | 
|  | 28 | dm_attr = container_of(attr, struct dm_sysfs_attr, attr); | 
|  | 29 | if (!dm_attr->show) | 
|  | 30 | return -EIO; | 
|  | 31 |  | 
|  | 32 | md = dm_get_from_kobject(kobj); | 
|  | 33 | if (!md) | 
|  | 34 | return -EINVAL; | 
|  | 35 |  | 
|  | 36 | ret = dm_attr->show(md, page); | 
|  | 37 | dm_put(md); | 
|  | 38 |  | 
|  | 39 | return ret; | 
|  | 40 | } | 
|  | 41 |  | 
|  | 42 | static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf) | 
|  | 43 | { | 
|  | 44 | if (dm_copy_name_and_uuid(md, buf, NULL)) | 
|  | 45 | return -EIO; | 
|  | 46 |  | 
|  | 47 | strcat(buf, "\n"); | 
|  | 48 | return strlen(buf); | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf) | 
|  | 52 | { | 
|  | 53 | if (dm_copy_name_and_uuid(md, NULL, buf)) | 
|  | 54 | return -EIO; | 
|  | 55 |  | 
|  | 56 | strcat(buf, "\n"); | 
|  | 57 | return strlen(buf); | 
|  | 58 | } | 
|  | 59 |  | 
| Peter Rajnoha | 486d220 | 2009-06-22 10:12:29 +0100 | [diff] [blame] | 60 | static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf) | 
|  | 61 | { | 
|  | 62 | sprintf(buf, "%d\n", dm_suspended(md)); | 
|  | 63 |  | 
|  | 64 | return strlen(buf); | 
|  | 65 | } | 
|  | 66 |  | 
| Milan Broz | 784aae7 | 2009-01-06 03:05:12 +0000 | [diff] [blame] | 67 | static DM_ATTR_RO(name); | 
|  | 68 | static DM_ATTR_RO(uuid); | 
| Peter Rajnoha | 486d220 | 2009-06-22 10:12:29 +0100 | [diff] [blame] | 69 | static DM_ATTR_RO(suspended); | 
| Milan Broz | 784aae7 | 2009-01-06 03:05:12 +0000 | [diff] [blame] | 70 |  | 
|  | 71 | static struct attribute *dm_attrs[] = { | 
|  | 72 | &dm_attr_name.attr, | 
|  | 73 | &dm_attr_uuid.attr, | 
| Peter Rajnoha | 486d220 | 2009-06-22 10:12:29 +0100 | [diff] [blame] | 74 | &dm_attr_suspended.attr, | 
| Milan Broz | 784aae7 | 2009-01-06 03:05:12 +0000 | [diff] [blame] | 75 | NULL, | 
|  | 76 | }; | 
|  | 77 |  | 
|  | 78 | static struct sysfs_ops dm_sysfs_ops = { | 
|  | 79 | .show	= dm_attr_show, | 
|  | 80 | }; | 
|  | 81 |  | 
|  | 82 | /* | 
|  | 83 | * dm kobject is embedded in mapped_device structure | 
|  | 84 | * no need to define release function here | 
|  | 85 | */ | 
|  | 86 | static struct kobj_type dm_ktype = { | 
|  | 87 | .sysfs_ops	= &dm_sysfs_ops, | 
|  | 88 | .default_attrs	= dm_attrs, | 
|  | 89 | }; | 
|  | 90 |  | 
|  | 91 | /* | 
|  | 92 | * Initialize kobj | 
|  | 93 | * because nobody using md yet, no need to call explicit dm_get/put | 
|  | 94 | */ | 
|  | 95 | int dm_sysfs_init(struct mapped_device *md) | 
|  | 96 | { | 
|  | 97 | return kobject_init_and_add(dm_kobject(md), &dm_ktype, | 
|  | 98 | &disk_to_dev(dm_disk(md))->kobj, | 
|  | 99 | "%s", "dm"); | 
|  | 100 | } | 
|  | 101 |  | 
|  | 102 | /* | 
|  | 103 | * Remove kobj, called after all references removed | 
|  | 104 | */ | 
|  | 105 | void dm_sysfs_exit(struct mapped_device *md) | 
|  | 106 | { | 
|  | 107 | kobject_put(dm_kobject(md)); | 
|  | 108 | } |