|
11 | 11 | struct dm_sysfs_attr {
|
12 | 12 | struct attribute attr;
|
13 | 13 | ssize_t (*show)(struct mapped_device *, char *);
|
14 |
| - ssize_t (*store)(struct mapped_device *, char *); |
| 14 | + ssize_t (*store)(struct mapped_device *, const char *, size_t count); |
15 | 15 | };
|
16 | 16 |
|
17 | 17 | #define DM_ATTR_RO(_name) \
|
@@ -39,6 +39,31 @@ static ssize_t dm_attr_show(struct kobject *kobj, struct attribute *attr,
|
39 | 39 | return ret;
|
40 | 40 | }
|
41 | 41 |
|
| 42 | +#define DM_ATTR_RW(_name) \ |
| 43 | +struct dm_sysfs_attr dm_attr_##_name = \ |
| 44 | + __ATTR(_name, S_IRUGO | S_IWUSR, dm_attr_##_name##_show, dm_attr_##_name##_store) |
| 45 | + |
| 46 | +static ssize_t dm_attr_store(struct kobject *kobj, struct attribute *attr, |
| 47 | + const char *page, size_t count) |
| 48 | +{ |
| 49 | + struct dm_sysfs_attr *dm_attr; |
| 50 | + struct mapped_device *md; |
| 51 | + ssize_t ret; |
| 52 | + |
| 53 | + dm_attr = container_of(attr, struct dm_sysfs_attr, attr); |
| 54 | + if (!dm_attr->store) |
| 55 | + return -EIO; |
| 56 | + |
| 57 | + md = dm_get_from_kobject(kobj); |
| 58 | + if (!md) |
| 59 | + return -EINVAL; |
| 60 | + |
| 61 | + ret = dm_attr->store(md, page, count); |
| 62 | + dm_put(md); |
| 63 | + |
| 64 | + return ret; |
| 65 | +} |
| 66 | + |
42 | 67 | static ssize_t dm_attr_name_show(struct mapped_device *md, char *buf)
|
43 | 68 | {
|
44 | 69 | if (dm_copy_name_and_uuid(md, buf, NULL))
|
@@ -77,12 +102,9 @@ static struct attribute *dm_attrs[] = {
|
77 | 102 |
|
78 | 103 | static const struct sysfs_ops dm_sysfs_ops = {
|
79 | 104 | .show = dm_attr_show,
|
| 105 | + .store = dm_attr_store, |
80 | 106 | };
|
81 | 107 |
|
82 |
| -/* |
83 |
| - * dm kobject is embedded in mapped_device structure |
84 |
| - * no need to define release function here |
85 |
| - */ |
86 | 108 | static struct kobj_type dm_ktype = {
|
87 | 109 | .sysfs_ops = &dm_sysfs_ops,
|
88 | 110 | .default_attrs = dm_attrs,
|
|
0 commit comments