raid_class.c (b1081ea6f000dee6dba288f9fab9df902802b25b) | raid_class.c (8c65b4a60450590e79a28e9717ceffa9e4debb3f) |
---|---|
1/* | 1/* |
2 * raid_class.c - implementation of a simple raid visualisation class 3 * 4 * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com> 5 * 6 * This file is licensed under GPLv2 7 * 8 * This class is designed to allow raid attributes to be visualised and 9 * manipulated in a form independent of the underlying raid. Ultimately this 10 * should work for both hardware and software raids. | 2 * RAID Attributes |
11 */ 12#include <linux/init.h> 13#include <linux/module.h> 14#include <linux/list.h> | 3 */ 4#include <linux/init.h> 5#include <linux/module.h> 6#include <linux/list.h> |
7#include <linux/slab.h> 8#include <linux/string.h> |
|
15#include <linux/raid_class.h> 16#include <scsi/scsi_device.h> 17#include <scsi/scsi_host.h> 18 19#define RAID_NUM_ATTRS 3 20 21struct raid_internal { 22 struct raid_template r; 23 struct raid_function_template *f; 24 /* The actual attributes */ 25 struct class_device_attribute private_attrs[RAID_NUM_ATTRS]; 26 /* The array of null terminated pointers to attributes 27 * needed by scsi_sysfs.c */ 28 struct class_device_attribute *attrs[RAID_NUM_ATTRS + 1]; 29}; 30 31struct raid_component { 32 struct list_head node; | 9#include <linux/raid_class.h> 10#include <scsi/scsi_device.h> 11#include <scsi/scsi_host.h> 12 13#define RAID_NUM_ATTRS 3 14 15struct raid_internal { 16 struct raid_template r; 17 struct raid_function_template *f; 18 /* The actual attributes */ 19 struct class_device_attribute private_attrs[RAID_NUM_ATTRS]; 20 /* The array of null terminated pointers to attributes 21 * needed by scsi_sysfs.c */ 22 struct class_device_attribute *attrs[RAID_NUM_ATTRS + 1]; 23}; 24 25struct raid_component { 26 struct list_head node; |
33 struct class_device cdev; | 27 struct device *dev; |
34 int num; 35}; 36 37#define to_raid_internal(tmpl) container_of(tmpl, struct raid_internal, r) 38 39#define tc_to_raid_internal(tcont) ({ \ 40 struct raid_template *r = \ 41 container_of(tcont, struct raid_template, raid_attrs); \ --- 33 unchanged lines hidden (view full) --- 75 76static int raid_setup(struct transport_container *tc, struct device *dev, 77 struct class_device *cdev) 78{ 79 struct raid_data *rd; 80 81 BUG_ON(class_get_devdata(cdev)); 82 | 28 int num; 29}; 30 31#define to_raid_internal(tmpl) container_of(tmpl, struct raid_internal, r) 32 33#define tc_to_raid_internal(tcont) ({ \ 34 struct raid_template *r = \ 35 container_of(tcont, struct raid_template, raid_attrs); \ --- 33 unchanged lines hidden (view full) --- 69 70static int raid_setup(struct transport_container *tc, struct device *dev, 71 struct class_device *cdev) 72{ 73 struct raid_data *rd; 74 75 BUG_ON(class_get_devdata(cdev)); 76 |
83 rd = kzalloc(sizeof(*rd), GFP_KERNEL); | 77 rd = kmalloc(sizeof(*rd), GFP_KERNEL); |
84 if (!rd) 85 return -ENOMEM; 86 | 78 if (!rd) 79 return -ENOMEM; 80 |
81 memset(rd, 0, sizeof(*rd)); |
|
87 INIT_LIST_HEAD(&rd->component_list); 88 class_set_devdata(cdev, rd); 89 90 return 0; 91} 92 93static int raid_remove(struct transport_container *tc, struct device *dev, 94 struct class_device *cdev) 95{ 96 struct raid_data *rd = class_get_devdata(cdev); 97 struct raid_component *rc, *next; | 82 INIT_LIST_HEAD(&rd->component_list); 83 class_set_devdata(cdev, rd); 84 85 return 0; 86} 87 88static int raid_remove(struct transport_container *tc, struct device *dev, 89 struct class_device *cdev) 90{ 91 struct raid_data *rd = class_get_devdata(cdev); 92 struct raid_component *rc, *next; |
98 dev_printk(KERN_ERR, dev, "RAID REMOVE\n"); | |
99 class_set_devdata(cdev, NULL); 100 list_for_each_entry_safe(rc, next, &rd->component_list, node) { | 93 class_set_devdata(cdev, NULL); 94 list_for_each_entry_safe(rc, next, &rd->component_list, node) { |
95 char buf[40]; 96 snprintf(buf, sizeof(buf), "component-%d", rc->num); |
|
101 list_del(&rc->node); | 97 list_del(&rc->node); |
102 dev_printk(KERN_ERR, rc->cdev.dev, "RAID COMPONENT REMOVE\n"); 103 class_device_unregister(&rc->cdev); | 98 sysfs_remove_link(&cdev->kobj, buf); 99 kfree(rc); |
104 } | 100 } |
105 dev_printk(KERN_ERR, dev, "RAID REMOVE DONE\n"); 106 kfree(rd); | 101 kfree(class_get_devdata(cdev)); |
107 return 0; 108} 109 110static DECLARE_TRANSPORT_CLASS(raid_class, 111 "raid_devices", 112 raid_setup, 113 raid_remove, 114 NULL); 115 116static struct { 117 enum raid_state value; 118 char *name; 119} raid_states[] = { | 102 return 0; 103} 104 105static DECLARE_TRANSPORT_CLASS(raid_class, 106 "raid_devices", 107 raid_setup, 108 raid_remove, 109 NULL); 110 111static struct { 112 enum raid_state value; 113 char *name; 114} raid_states[] = { |
120 { RAID_STATE_UNKNOWN, "unknown" }, 121 { RAID_STATE_ACTIVE, "active" }, 122 { RAID_STATE_DEGRADED, "degraded" }, 123 { RAID_STATE_RESYNCING, "resyncing" }, 124 { RAID_STATE_OFFLINE, "offline" }, | 115 { RAID_ACTIVE, "active" }, 116 { RAID_DEGRADED, "degraded" }, 117 { RAID_RESYNCING, "resyncing" }, 118 { RAID_OFFLINE, "offline" }, |
125}; 126 127static const char *raid_state_name(enum raid_state state) 128{ 129 int i; 130 char *name = NULL; 131 132 for (i = 0; i < sizeof(raid_states)/sizeof(raid_states[0]); i++) { 133 if (raid_states[i].value == state) { 134 name = raid_states[i].name; 135 break; 136 } 137 } 138 return name; 139} 140 | 119}; 120 121static const char *raid_state_name(enum raid_state state) 122{ 123 int i; 124 char *name = NULL; 125 126 for (i = 0; i < sizeof(raid_states)/sizeof(raid_states[0]); i++) { 127 if (raid_states[i].value == state) { 128 name = raid_states[i].name; 129 break; 130 } 131 } 132 return name; 133} 134 |
141static struct { 142 enum raid_level value; 143 char *name; 144} raid_levels[] = { 145 { RAID_LEVEL_UNKNOWN, "unknown" }, 146 { RAID_LEVEL_LINEAR, "linear" }, 147 { RAID_LEVEL_0, "raid0" }, 148 { RAID_LEVEL_1, "raid1" }, 149 { RAID_LEVEL_3, "raid3" }, 150 { RAID_LEVEL_4, "raid4" }, 151 { RAID_LEVEL_5, "raid5" }, 152 { RAID_LEVEL_6, "raid6" }, 153}; | |
154 | 135 |
155static const char *raid_level_name(enum raid_level level) 156{ 157 int i; 158 char *name = NULL; 159 160 for (i = 0; i < sizeof(raid_levels)/sizeof(raid_levels[0]); i++) { 161 if (raid_levels[i].value == level) { 162 name = raid_levels[i].name; 163 break; 164 } 165 } 166 return name; 167} 168 | |
169#define raid_attr_show_internal(attr, fmt, var, code) \ 170static ssize_t raid_show_##attr(struct class_device *cdev, char *buf) \ 171{ \ 172 struct raid_data *rd = class_get_devdata(cdev); \ 173 code \ 174 return snprintf(buf, 20, #fmt "\n", var); \ 175} 176 --- 12 unchanged lines hidden (view full) --- 189 190#define ATTR_CODE(attr) \ 191 struct raid_internal *i = class_device_to_raid_internal(cdev); \ 192 if (i->f->get_##attr) \ 193 i->f->get_##attr(cdev->dev); 194 195#define raid_attr_ro(attr) raid_attr_ro_internal(attr, ) 196#define raid_attr_ro_fn(attr) raid_attr_ro_internal(attr, ATTR_CODE(attr)) | 136#define raid_attr_show_internal(attr, fmt, var, code) \ 137static ssize_t raid_show_##attr(struct class_device *cdev, char *buf) \ 138{ \ 139 struct raid_data *rd = class_get_devdata(cdev); \ 140 code \ 141 return snprintf(buf, 20, #fmt "\n", var); \ 142} 143 --- 12 unchanged lines hidden (view full) --- 156 157#define ATTR_CODE(attr) \ 158 struct raid_internal *i = class_device_to_raid_internal(cdev); \ 159 if (i->f->get_##attr) \ 160 i->f->get_##attr(cdev->dev); 161 162#define raid_attr_ro(attr) raid_attr_ro_internal(attr, ) 163#define raid_attr_ro_fn(attr) raid_attr_ro_internal(attr, ATTR_CODE(attr)) |
197#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, ) 198#define raid_attr_ro_state_fn(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr)) | 164#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr)) |
199 | 165 |
200 201raid_attr_ro_state(level); | 166raid_attr_ro(level); |
202raid_attr_ro_fn(resync); | 167raid_attr_ro_fn(resync); |
203raid_attr_ro_state_fn(state); | 168raid_attr_ro_state(state); |
204 | 169 |
205static void raid_component_release(struct class_device *cdev) 206{ 207 struct raid_component *rc = container_of(cdev, struct raid_component, 208 cdev); 209 dev_printk(KERN_ERR, rc->cdev.dev, "COMPONENT RELEASE\n"); 210 put_device(rc->cdev.dev); 211 kfree(rc); 212} 213 | |
214void raid_component_add(struct raid_template *r,struct device *raid_dev, 215 struct device *component_dev) 216{ 217 struct class_device *cdev = 218 attribute_container_find_class_device(&r->raid_attrs.ac, 219 raid_dev); 220 struct raid_component *rc; 221 struct raid_data *rd = class_get_devdata(cdev); | 170void raid_component_add(struct raid_template *r,struct device *raid_dev, 171 struct device *component_dev) 172{ 173 struct class_device *cdev = 174 attribute_container_find_class_device(&r->raid_attrs.ac, 175 raid_dev); 176 struct raid_component *rc; 177 struct raid_data *rd = class_get_devdata(cdev); |
178 char buf[40]; |
|
222 | 179 |
223 rc = kzalloc(sizeof(*rc), GFP_KERNEL); | 180 rc = kmalloc(sizeof(*rc), GFP_KERNEL); |
224 if (!rc) 225 return; 226 227 INIT_LIST_HEAD(&rc->node); | 181 if (!rc) 182 return; 183 184 INIT_LIST_HEAD(&rc->node); |
228 class_device_initialize(&rc->cdev); 229 rc->cdev.release = raid_component_release; 230 rc->cdev.dev = get_device(component_dev); | 185 rc->dev = component_dev; |
231 rc->num = rd->component_count++; 232 | 186 rc->num = rd->component_count++; 187 |
233 snprintf(rc->cdev.class_id, sizeof(rc->cdev.class_id), 234 "component-%d", rc->num); | 188 snprintf(buf, sizeof(buf), "component-%d", rc->num); |
235 list_add_tail(&rc->node, &rd->component_list); | 189 list_add_tail(&rc->node, &rd->component_list); |
236 rc->cdev.parent = cdev; 237 rc->cdev.class = &raid_class.class; 238 class_device_add(&rc->cdev); | 190 sysfs_create_link(&cdev->kobj, &component_dev->kobj, buf); |
239} 240EXPORT_SYMBOL(raid_component_add); 241 242struct raid_template * 243raid_class_attach(struct raid_function_template *ft) 244{ | 191} 192EXPORT_SYMBOL(raid_component_add); 193 194struct raid_template * 195raid_class_attach(struct raid_function_template *ft) 196{ |
245 struct raid_internal *i = kzalloc(sizeof(struct raid_internal), | 197 struct raid_internal *i = kmalloc(sizeof(struct raid_internal), |
246 GFP_KERNEL); 247 int count = 0; 248 249 if (unlikely(!i)) 250 return NULL; 251 | 198 GFP_KERNEL); 199 int count = 0; 200 201 if (unlikely(!i)) 202 return NULL; 203 |
204 memset(i, 0, sizeof(*i)); 205 |
|
252 i->f = ft; 253 254 i->r.raid_attrs.ac.class = &raid_class.class; 255 i->r.raid_attrs.ac.match = raid_match; 256 i->r.raid_attrs.ac.attrs = &i->attrs[0]; 257 258 attribute_container_register(&i->r.raid_attrs.ac); 259 --- 39 unchanged lines hidden --- | 206 i->f = ft; 207 208 i->r.raid_attrs.ac.class = &raid_class.class; 209 i->r.raid_attrs.ac.match = raid_match; 210 i->r.raid_attrs.ac.attrs = &i->attrs[0]; 211 212 attribute_container_register(&i->r.raid_attrs.ac); 213 --- 39 unchanged lines hidden --- |