diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/faulty.c | 2 | ||||
-rw-r--r-- | drivers/md/linear.c | 133 | ||||
-rw-r--r-- | drivers/md/md.c | 81 | ||||
-rw-r--r-- | drivers/md/multipath.c | 9 | ||||
-rw-r--r-- | drivers/md/raid0.c | 5 | ||||
-rw-r--r-- | drivers/md/raid1.c | 1 | ||||
-rw-r--r-- | drivers/md/raid10.c | 6 | ||||
-rw-r--r-- | drivers/md/raid5.c | 42 | ||||
-rw-r--r-- | drivers/md/raid6.h | 9 |
9 files changed, 114 insertions, 174 deletions
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 268547dbfbd3..f26c1f9a475b 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c | |||
@@ -287,6 +287,8 @@ static int run(mddev_t *mddev) | |||
287 | int i; | 287 | int i; |
288 | 288 | ||
289 | conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); | 289 | conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); |
290 | if (!conf) | ||
291 | return -ENOMEM; | ||
290 | 292 | ||
291 | for (i=0; i<Modes; i++) { | 293 | for (i=0; i<Modes; i++) { |
292 | atomic_set(&conf->counters[i], 0); | 294 | atomic_set(&conf->counters[i], 0); |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index b9cbee688fae..190147c79e79 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -16,16 +16,8 @@ | |||
16 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 16 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/module.h> | ||
20 | |||
21 | #include <linux/raid/md.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/raid/linear.h> | 19 | #include <linux/raid/linear.h> |
24 | 20 | ||
25 | #define MAJOR_NR MD_MAJOR | ||
26 | #define MD_DRIVER | ||
27 | #define MD_PERSONALITY | ||
28 | |||
29 | /* | 21 | /* |
30 | * find which device holds a particular offset | 22 | * find which device holds a particular offset |
31 | */ | 23 | */ |
@@ -33,16 +25,15 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) | |||
33 | { | 25 | { |
34 | dev_info_t *hash; | 26 | dev_info_t *hash; |
35 | linear_conf_t *conf = mddev_to_conf(mddev); | 27 | linear_conf_t *conf = mddev_to_conf(mddev); |
36 | sector_t block = sector >> 1; | ||
37 | 28 | ||
38 | /* | 29 | /* |
39 | * sector_div(a,b) returns the remainer and sets a to a/b | 30 | * sector_div(a,b) returns the remainer and sets a to a/b |
40 | */ | 31 | */ |
41 | block >>= conf->preshift; | 32 | sector >>= conf->sector_shift; |
42 | (void)sector_div(block, conf->hash_spacing); | 33 | (void)sector_div(sector, conf->spacing); |
43 | hash = conf->hash_table[block]; | 34 | hash = conf->hash_table[sector]; |
44 | 35 | ||
45 | while ((sector>>1) >= (hash->size + hash->offset)) | 36 | while (sector >= hash->num_sectors + hash->start_sector) |
46 | hash++; | 37 | hash++; |
47 | return hash; | 38 | return hash; |
48 | } | 39 | } |
@@ -65,7 +56,7 @@ static int linear_mergeable_bvec(struct request_queue *q, | |||
65 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); | 56 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
66 | 57 | ||
67 | dev0 = which_dev(mddev, sector); | 58 | dev0 = which_dev(mddev, sector); |
68 | maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); | 59 | maxsectors = dev0->num_sectors - (sector - dev0->start_sector); |
69 | 60 | ||
70 | if (maxsectors < bio_sectors) | 61 | if (maxsectors < bio_sectors) |
71 | maxsectors = 0; | 62 | maxsectors = 0; |
@@ -112,8 +103,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
112 | dev_info_t **table; | 103 | dev_info_t **table; |
113 | mdk_rdev_t *rdev; | 104 | mdk_rdev_t *rdev; |
114 | int i, nb_zone, cnt; | 105 | int i, nb_zone, cnt; |
115 | sector_t min_spacing; | 106 | sector_t min_sectors; |
116 | sector_t curr_offset; | 107 | sector_t curr_sector; |
117 | struct list_head *tmp; | 108 | struct list_head *tmp; |
118 | 109 | ||
119 | conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), | 110 | conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), |
@@ -145,7 +136,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
145 | mddev->queue->max_sectors > (PAGE_SIZE>>9)) | 136 | mddev->queue->max_sectors > (PAGE_SIZE>>9)) |
146 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); | 137 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); |
147 | 138 | ||
148 | disk->size = rdev->size; | 139 | disk->num_sectors = rdev->size * 2; |
149 | conf->array_sectors += rdev->size * 2; | 140 | conf->array_sectors += rdev->size * 2; |
150 | 141 | ||
151 | cnt++; | 142 | cnt++; |
@@ -155,34 +146,34 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
155 | goto out; | 146 | goto out; |
156 | } | 147 | } |
157 | 148 | ||
158 | min_spacing = conf->array_sectors / 2; | 149 | min_sectors = conf->array_sectors; |
159 | sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); | 150 | sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *)); |
160 | 151 | ||
161 | /* min_spacing is the minimum spacing that will fit the hash | 152 | /* min_sectors is the minimum spacing that will fit the hash |
162 | * table in one PAGE. This may be much smaller than needed. | 153 | * table in one PAGE. This may be much smaller than needed. |
163 | * We find the smallest non-terminal set of consecutive devices | 154 | * We find the smallest non-terminal set of consecutive devices |
164 | * that is larger than min_spacing as use the size of that as | 155 | * that is larger than min_sectors and use the size of that as |
165 | * the actual spacing | 156 | * the actual spacing |
166 | */ | 157 | */ |
167 | conf->hash_spacing = conf->array_sectors / 2; | 158 | conf->spacing = conf->array_sectors; |
168 | for (i=0; i < cnt-1 ; i++) { | 159 | for (i=0; i < cnt-1 ; i++) { |
169 | sector_t sz = 0; | 160 | sector_t tmp = 0; |
170 | int j; | 161 | int j; |
171 | for (j = i; j < cnt - 1 && sz < min_spacing; j++) | 162 | for (j = i; j < cnt - 1 && tmp < min_sectors; j++) |
172 | sz += conf->disks[j].size; | 163 | tmp += conf->disks[j].num_sectors; |
173 | if (sz >= min_spacing && sz < conf->hash_spacing) | 164 | if (tmp >= min_sectors && tmp < conf->spacing) |
174 | conf->hash_spacing = sz; | 165 | conf->spacing = tmp; |
175 | } | 166 | } |
176 | 167 | ||
177 | /* hash_spacing may be too large for sector_div to work with, | 168 | /* spacing may be too large for sector_div to work with, |
178 | * so we might need to pre-shift | 169 | * so we might need to pre-shift |
179 | */ | 170 | */ |
180 | conf->preshift = 0; | 171 | conf->sector_shift = 0; |
181 | if (sizeof(sector_t) > sizeof(u32)) { | 172 | if (sizeof(sector_t) > sizeof(u32)) { |
182 | sector_t space = conf->hash_spacing; | 173 | sector_t space = conf->spacing; |
183 | while (space > (sector_t)(~(u32)0)) { | 174 | while (space > (sector_t)(~(u32)0)) { |
184 | space >>= 1; | 175 | space >>= 1; |
185 | conf->preshift++; | 176 | conf->sector_shift++; |
186 | } | 177 | } |
187 | } | 178 | } |
188 | /* | 179 | /* |
@@ -194,9 +185,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
194 | unsigned round; | 185 | unsigned round; |
195 | unsigned long base; | 186 | unsigned long base; |
196 | 187 | ||
197 | sz = conf->array_sectors >> (conf->preshift + 1); | 188 | sz = conf->array_sectors >> conf->sector_shift; |
198 | sz += 1; /* force round-up */ | 189 | sz += 1; /* force round-up */ |
199 | base = conf->hash_spacing >> conf->preshift; | 190 | base = conf->spacing >> conf->sector_shift; |
200 | round = sector_div(sz, base); | 191 | round = sector_div(sz, base); |
201 | nb_zone = sz + (round ? 1 : 0); | 192 | nb_zone = sz + (round ? 1 : 0); |
202 | } | 193 | } |
@@ -211,32 +202,31 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
211 | * Here we generate the linear hash table | 202 | * Here we generate the linear hash table |
212 | * First calculate the device offsets. | 203 | * First calculate the device offsets. |
213 | */ | 204 | */ |
214 | conf->disks[0].offset = 0; | 205 | conf->disks[0].start_sector = 0; |
215 | for (i = 1; i < raid_disks; i++) | 206 | for (i = 1; i < raid_disks; i++) |
216 | conf->disks[i].offset = | 207 | conf->disks[i].start_sector = |
217 | conf->disks[i-1].offset + | 208 | conf->disks[i-1].start_sector + |
218 | conf->disks[i-1].size; | 209 | conf->disks[i-1].num_sectors; |
219 | 210 | ||
220 | table = conf->hash_table; | 211 | table = conf->hash_table; |
221 | curr_offset = 0; | ||
222 | i = 0; | 212 | i = 0; |
223 | for (curr_offset = 0; | 213 | for (curr_sector = 0; |
224 | curr_offset < conf->array_sectors / 2; | 214 | curr_sector < conf->array_sectors; |
225 | curr_offset += conf->hash_spacing) { | 215 | curr_sector += conf->spacing) { |
226 | 216 | ||
227 | while (i < raid_disks-1 && | 217 | while (i < raid_disks-1 && |
228 | curr_offset >= conf->disks[i+1].offset) | 218 | curr_sector >= conf->disks[i+1].start_sector) |
229 | i++; | 219 | i++; |
230 | 220 | ||
231 | *table ++ = conf->disks + i; | 221 | *table ++ = conf->disks + i; |
232 | } | 222 | } |
233 | 223 | ||
234 | if (conf->preshift) { | 224 | if (conf->sector_shift) { |
235 | conf->hash_spacing >>= conf->preshift; | 225 | conf->spacing >>= conf->sector_shift; |
236 | /* round hash_spacing up so that when we divide by it, | 226 | /* round spacing up so that when we divide by it, |
237 | * we err on the side of "too-low", which is safest. | 227 | * we err on the side of "too-low", which is safest. |
238 | */ | 228 | */ |
239 | conf->hash_spacing++; | 229 | conf->spacing++; |
240 | } | 230 | } |
241 | 231 | ||
242 | BUG_ON(table - conf->hash_table > nb_zone); | 232 | BUG_ON(table - conf->hash_table > nb_zone); |
@@ -317,7 +307,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
317 | const int rw = bio_data_dir(bio); | 307 | const int rw = bio_data_dir(bio); |
318 | mddev_t *mddev = q->queuedata; | 308 | mddev_t *mddev = q->queuedata; |
319 | dev_info_t *tmp_dev; | 309 | dev_info_t *tmp_dev; |
320 | sector_t block; | ||
321 | int cpu; | 310 | int cpu; |
322 | 311 | ||
323 | if (unlikely(bio_barrier(bio))) { | 312 | if (unlikely(bio_barrier(bio))) { |
@@ -332,29 +321,33 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
332 | part_stat_unlock(); | 321 | part_stat_unlock(); |
333 | 322 | ||
334 | tmp_dev = which_dev(mddev, bio->bi_sector); | 323 | tmp_dev = which_dev(mddev, bio->bi_sector); |
335 | block = bio->bi_sector >> 1; | ||
336 | 324 | ||
337 | if (unlikely(block >= (tmp_dev->size + tmp_dev->offset) | 325 | if (unlikely(bio->bi_sector >= (tmp_dev->num_sectors + |
338 | || block < tmp_dev->offset)) { | 326 | tmp_dev->start_sector) |
327 | || (bio->bi_sector < | ||
328 | tmp_dev->start_sector))) { | ||
339 | char b[BDEVNAME_SIZE]; | 329 | char b[BDEVNAME_SIZE]; |
340 | 330 | ||
341 | printk("linear_make_request: Block %llu out of bounds on " | 331 | printk("linear_make_request: Sector %llu out of bounds on " |
342 | "dev %s size %llu offset %llu\n", | 332 | "dev %s: %llu sectors, offset %llu\n", |
343 | (unsigned long long)block, | 333 | (unsigned long long)bio->bi_sector, |
344 | bdevname(tmp_dev->rdev->bdev, b), | 334 | bdevname(tmp_dev->rdev->bdev, b), |
345 | (unsigned long long)tmp_dev->size, | 335 | (unsigned long long)tmp_dev->num_sectors, |
346 | (unsigned long long)tmp_dev->offset); | 336 | (unsigned long long)tmp_dev->start_sector); |
347 | bio_io_error(bio); | 337 | bio_io_error(bio); |
348 | return 0; | 338 | return 0; |
349 | } | 339 | } |
350 | if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > | 340 | if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > |
351 | (tmp_dev->offset + tmp_dev->size)<<1)) { | 341 | tmp_dev->start_sector + tmp_dev->num_sectors)) { |
352 | /* This bio crosses a device boundary, so we have to | 342 | /* This bio crosses a device boundary, so we have to |
353 | * split it. | 343 | * split it. |
354 | */ | 344 | */ |
355 | struct bio_pair *bp; | 345 | struct bio_pair *bp; |
346 | |||
356 | bp = bio_split(bio, | 347 | bp = bio_split(bio, |
357 | ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector); | 348 | tmp_dev->start_sector + tmp_dev->num_sectors |
349 | - bio->bi_sector); | ||
350 | |||
358 | if (linear_make_request(q, &bp->bio1)) | 351 | if (linear_make_request(q, &bp->bio1)) |
359 | generic_make_request(&bp->bio1); | 352 | generic_make_request(&bp->bio1); |
360 | if (linear_make_request(q, &bp->bio2)) | 353 | if (linear_make_request(q, &bp->bio2)) |
@@ -364,7 +357,8 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
364 | } | 357 | } |
365 | 358 | ||
366 | bio->bi_bdev = tmp_dev->rdev->bdev; | 359 | bio->bi_bdev = tmp_dev->rdev->bdev; |
367 | bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset; | 360 | bio->bi_sector = bio->bi_sector - tmp_dev->start_sector |
361 | + tmp_dev->rdev->data_offset; | ||
368 | 362 | ||
369 | return 1; | 363 | return 1; |
370 | } | 364 | } |
@@ -372,29 +366,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
372 | static void linear_status (struct seq_file *seq, mddev_t *mddev) | 366 | static void linear_status (struct seq_file *seq, mddev_t *mddev) |
373 | { | 367 | { |
374 | 368 | ||
375 | #undef MD_DEBUG | ||
376 | #ifdef MD_DEBUG | ||
377 | int j; | ||
378 | linear_conf_t *conf = mddev_to_conf(mddev); | ||
379 | sector_t s = 0; | ||
380 | |||
381 | seq_printf(seq, " "); | ||
382 | for (j = 0; j < mddev->raid_disks; j++) | ||
383 | { | ||
384 | char b[BDEVNAME_SIZE]; | ||
385 | s += conf->smallest_size; | ||
386 | seq_printf(seq, "[%s", | ||
387 | bdevname(conf->hash_table[j][0].rdev->bdev,b)); | ||
388 | |||
389 | while (s > conf->hash_table[j][0].offset + | ||
390 | conf->hash_table[j][0].size) | ||
391 | seq_printf(seq, "/%s] ", | ||
392 | bdevname(conf->hash_table[j][1].rdev->bdev,b)); | ||
393 | else | ||
394 | seq_printf(seq, "] "); | ||
395 | } | ||
396 | seq_printf(seq, "\n"); | ||
397 | #endif | ||
398 | seq_printf(seq, " %dk rounding", mddev->chunk_size/1024); | 369 | seq_printf(seq, " %dk rounding", mddev->chunk_size/1024); |
399 | } | 370 | } |
400 | 371 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 0a3a4bdcd4af..aaa3d465de4e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -32,31 +32,21 @@ | |||
32 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 32 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/kthread.h> | 35 | #include <linux/kthread.h> |
38 | #include <linux/linkage.h> | ||
39 | #include <linux/raid/md.h> | 36 | #include <linux/raid/md.h> |
40 | #include <linux/raid/bitmap.h> | 37 | #include <linux/raid/bitmap.h> |
41 | #include <linux/sysctl.h> | 38 | #include <linux/sysctl.h> |
42 | #include <linux/buffer_head.h> /* for invalidate_bdev */ | 39 | #include <linux/buffer_head.h> /* for invalidate_bdev */ |
43 | #include <linux/poll.h> | 40 | #include <linux/poll.h> |
44 | #include <linux/mutex.h> | ||
45 | #include <linux/ctype.h> | 41 | #include <linux/ctype.h> |
46 | #include <linux/freezer.h> | 42 | #include <linux/hdreg.h> |
47 | 43 | #include <linux/proc_fs.h> | |
48 | #include <linux/init.h> | 44 | #include <linux/random.h> |
49 | 45 | #include <linux/reboot.h> | |
50 | #include <linux/file.h> | 46 | #include <linux/file.h> |
51 | 47 | #include <linux/delay.h> | |
52 | #ifdef CONFIG_KMOD | ||
53 | #include <linux/kmod.h> | ||
54 | #endif | ||
55 | |||
56 | #include <asm/unaligned.h> | ||
57 | 48 | ||
58 | #define MAJOR_NR MD_MAJOR | 49 | #define MAJOR_NR MD_MAJOR |
59 | #define MD_DRIVER | ||
60 | 50 | ||
61 | /* 63 partitions with the alternate major number (mdp) */ | 51 | /* 63 partitions with the alternate major number (mdp) */ |
62 | #define MdpMinorShift 6 | 52 | #define MdpMinorShift 6 |
@@ -66,7 +56,7 @@ | |||
66 | 56 | ||
67 | 57 | ||
68 | #ifndef MODULE | 58 | #ifndef MODULE |
69 | static void autostart_arrays (int part); | 59 | static void autostart_arrays(int part); |
70 | #endif | 60 | #endif |
71 | 61 | ||
72 | static LIST_HEAD(pers_list); | 62 | static LIST_HEAD(pers_list); |
@@ -212,7 +202,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock); | |||
212 | ) | 202 | ) |
213 | 203 | ||
214 | 204 | ||
215 | static int md_fail_request (struct request_queue *q, struct bio *bio) | 205 | static int md_fail_request(struct request_queue *q, struct bio *bio) |
216 | { | 206 | { |
217 | bio_io_error(bio); | 207 | bio_io_error(bio); |
218 | return 0; | 208 | return 0; |
@@ -2106,8 +2096,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2106 | 2096 | ||
2107 | if (strict_strtoull(buf, 10, &size) < 0) | 2097 | if (strict_strtoull(buf, 10, &size) < 0) |
2108 | return -EINVAL; | 2098 | return -EINVAL; |
2109 | if (size < my_mddev->size) | ||
2110 | return -EINVAL; | ||
2111 | if (my_mddev->pers && rdev->raid_disk >= 0) { | 2099 | if (my_mddev->pers && rdev->raid_disk >= 0) { |
2112 | if (my_mddev->persistent) { | 2100 | if (my_mddev->persistent) { |
2113 | size = super_types[my_mddev->major_version]. | 2101 | size = super_types[my_mddev->major_version]. |
@@ -2118,9 +2106,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2118 | size = (rdev->bdev->bd_inode->i_size >> 10); | 2106 | size = (rdev->bdev->bd_inode->i_size >> 10); |
2119 | size -= rdev->data_offset/2; | 2107 | size -= rdev->data_offset/2; |
2120 | } | 2108 | } |
2121 | if (size < my_mddev->size) | ||
2122 | return -EINVAL; /* component must fit device */ | ||
2123 | } | 2109 | } |
2110 | if (size < my_mddev->size) | ||
2111 | return -EINVAL; /* component must fit device */ | ||
2124 | 2112 | ||
2125 | rdev->size = size; | 2113 | rdev->size = size; |
2126 | if (size > oldsize && my_mddev->external) { | 2114 | if (size > oldsize && my_mddev->external) { |
@@ -2406,12 +2394,11 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) | |||
2406 | int i; | 2394 | int i; |
2407 | unsigned long msec; | 2395 | unsigned long msec; |
2408 | char buf[30]; | 2396 | char buf[30]; |
2409 | char *e; | 2397 | |
2410 | /* remove a period, and count digits after it */ | 2398 | /* remove a period, and count digits after it */ |
2411 | if (len >= sizeof(buf)) | 2399 | if (len >= sizeof(buf)) |
2412 | return -EINVAL; | 2400 | return -EINVAL; |
2413 | strlcpy(buf, cbuf, len); | 2401 | strlcpy(buf, cbuf, sizeof(buf)); |
2414 | buf[len] = 0; | ||
2415 | for (i=0; i<len; i++) { | 2402 | for (i=0; i<len; i++) { |
2416 | if (dot) { | 2403 | if (dot) { |
2417 | if (isdigit(buf[i])) { | 2404 | if (isdigit(buf[i])) { |
@@ -2424,8 +2411,7 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) | |||
2424 | buf[i] = 0; | 2411 | buf[i] = 0; |
2425 | } | 2412 | } |
2426 | } | 2413 | } |
2427 | msec = simple_strtoul(buf, &e, 10); | 2414 | if (strict_strtoul(buf, 10, &msec) < 0) |
2428 | if (e == buf || (*e && *e != '\n')) | ||
2429 | return -EINVAL; | 2415 | return -EINVAL; |
2430 | msec = (msec * 1000) / scale; | 2416 | msec = (msec * 1000) / scale; |
2431 | if (msec == 0) | 2417 | if (msec == 0) |
@@ -2727,9 +2713,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2727 | break; | 2713 | break; |
2728 | case read_auto: | 2714 | case read_auto: |
2729 | if (mddev->pers) { | 2715 | if (mddev->pers) { |
2730 | if (mddev->ro != 1) | 2716 | if (mddev->ro == 0) |
2731 | err = do_md_stop(mddev, 1, 0); | 2717 | err = do_md_stop(mddev, 1, 0); |
2732 | else | 2718 | else if (mddev->ro == 1) |
2733 | err = restart_array(mddev); | 2719 | err = restart_array(mddev); |
2734 | if (err == 0) { | 2720 | if (err == 0) { |
2735 | mddev->ro = 2; | 2721 | mddev->ro = 2; |
@@ -2945,7 +2931,13 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len) | |||
2945 | { | 2931 | { |
2946 | int major, minor; | 2932 | int major, minor; |
2947 | char *e; | 2933 | char *e; |
2948 | if (!list_empty(&mddev->disks)) | 2934 | /* Changing the details of 'external' metadata is |
2935 | * always permitted. Otherwise there must be | ||
2936 | * no devices attached to the array. | ||
2937 | */ | ||
2938 | if (mddev->external && strncmp(buf, "external:", 9) == 0) | ||
2939 | ; | ||
2940 | else if (!list_empty(&mddev->disks)) | ||
2949 | return -EBUSY; | 2941 | return -EBUSY; |
2950 | 2942 | ||
2951 | if (cmd_match(buf, "none")) { | 2943 | if (cmd_match(buf, "none")) { |
@@ -3527,17 +3519,12 @@ static int do_md_run(mddev_t * mddev) | |||
3527 | return -EINVAL; | 3519 | return -EINVAL; |
3528 | } | 3520 | } |
3529 | /* | 3521 | /* |
3530 | * chunk-size has to be a power of 2 and multiples of PAGE_SIZE | 3522 | * chunk-size has to be a power of 2 |
3531 | */ | 3523 | */ |
3532 | if ( (1 << ffz(~chunk_size)) != chunk_size) { | 3524 | if ( (1 << ffz(~chunk_size)) != chunk_size) { |
3533 | printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size); | 3525 | printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size); |
3534 | return -EINVAL; | 3526 | return -EINVAL; |
3535 | } | 3527 | } |
3536 | if (chunk_size < PAGE_SIZE) { | ||
3537 | printk(KERN_ERR "too small chunk_size: %d < %ld\n", | ||
3538 | chunk_size, PAGE_SIZE); | ||
3539 | return -EINVAL; | ||
3540 | } | ||
3541 | 3528 | ||
3542 | /* devices must have minimum size of one chunk */ | 3529 | /* devices must have minimum size of one chunk */ |
3543 | rdev_for_each(rdev, tmp, mddev) { | 3530 | rdev_for_each(rdev, tmp, mddev) { |
@@ -3555,12 +3542,10 @@ static int do_md_run(mddev_t * mddev) | |||
3555 | } | 3542 | } |
3556 | } | 3543 | } |
3557 | 3544 | ||
3558 | #ifdef CONFIG_KMOD | ||
3559 | if (mddev->level != LEVEL_NONE) | 3545 | if (mddev->level != LEVEL_NONE) |
3560 | request_module("md-level-%d", mddev->level); | 3546 | request_module("md-level-%d", mddev->level); |
3561 | else if (mddev->clevel[0]) | 3547 | else if (mddev->clevel[0]) |
3562 | request_module("md-%s", mddev->clevel); | 3548 | request_module("md-%s", mddev->clevel); |
3563 | #endif | ||
3564 | 3549 | ||
3565 | /* | 3550 | /* |
3566 | * Drop all container device buffers, from now on | 3551 | * Drop all container device buffers, from now on |
@@ -3971,10 +3956,10 @@ static void autorun_array(mddev_t *mddev) | |||
3971 | } | 3956 | } |
3972 | printk("\n"); | 3957 | printk("\n"); |
3973 | 3958 | ||
3974 | err = do_md_run (mddev); | 3959 | err = do_md_run(mddev); |
3975 | if (err) { | 3960 | if (err) { |
3976 | printk(KERN_WARNING "md: do_md_run() returned %d\n", err); | 3961 | printk(KERN_WARNING "md: do_md_run() returned %d\n", err); |
3977 | do_md_stop (mddev, 0, 0); | 3962 | do_md_stop(mddev, 0, 0); |
3978 | } | 3963 | } |
3979 | } | 3964 | } |
3980 | 3965 | ||
@@ -4333,7 +4318,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
4333 | 4318 | ||
4334 | if (!(info->state & (1<<MD_DISK_FAULTY))) { | 4319 | if (!(info->state & (1<<MD_DISK_FAULTY))) { |
4335 | int err; | 4320 | int err; |
4336 | rdev = md_import_device (dev, -1, 0); | 4321 | rdev = md_import_device(dev, -1, 0); |
4337 | if (IS_ERR(rdev)) { | 4322 | if (IS_ERR(rdev)) { |
4338 | printk(KERN_WARNING | 4323 | printk(KERN_WARNING |
4339 | "md: error, md_import_device() returned %ld\n", | 4324 | "md: error, md_import_device() returned %ld\n", |
@@ -4415,7 +4400,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
4415 | return -EINVAL; | 4400 | return -EINVAL; |
4416 | } | 4401 | } |
4417 | 4402 | ||
4418 | rdev = md_import_device (dev, -1, 0); | 4403 | rdev = md_import_device(dev, -1, 0); |
4419 | if (IS_ERR(rdev)) { | 4404 | if (IS_ERR(rdev)) { |
4420 | printk(KERN_WARNING | 4405 | printk(KERN_WARNING |
4421 | "md: error, md_import_device() returned %ld\n", | 4406 | "md: error, md_import_device() returned %ld\n", |
@@ -4934,11 +4919,11 @@ static int md_ioctl(struct inode *inode, struct file *file, | |||
4934 | goto done_unlock; | 4919 | goto done_unlock; |
4935 | 4920 | ||
4936 | case STOP_ARRAY: | 4921 | case STOP_ARRAY: |
4937 | err = do_md_stop (mddev, 0, 1); | 4922 | err = do_md_stop(mddev, 0, 1); |
4938 | goto done_unlock; | 4923 | goto done_unlock; |
4939 | 4924 | ||
4940 | case STOP_ARRAY_RO: | 4925 | case STOP_ARRAY_RO: |
4941 | err = do_md_stop (mddev, 1, 1); | 4926 | err = do_md_stop(mddev, 1, 1); |
4942 | goto done_unlock; | 4927 | goto done_unlock; |
4943 | 4928 | ||
4944 | } | 4929 | } |
@@ -4987,7 +4972,7 @@ static int md_ioctl(struct inode *inode, struct file *file, | |||
4987 | goto done_unlock; | 4972 | goto done_unlock; |
4988 | 4973 | ||
4989 | case RUN_ARRAY: | 4974 | case RUN_ARRAY: |
4990 | err = do_md_run (mddev); | 4975 | err = do_md_run(mddev); |
4991 | goto done_unlock; | 4976 | goto done_unlock; |
4992 | 4977 | ||
4993 | case SET_BITMAP_FILE: | 4978 | case SET_BITMAP_FILE: |
@@ -5425,11 +5410,11 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
5425 | seq_printf(seq, " super non-persistent"); | 5410 | seq_printf(seq, " super non-persistent"); |
5426 | 5411 | ||
5427 | if (mddev->pers) { | 5412 | if (mddev->pers) { |
5428 | mddev->pers->status (seq, mddev); | 5413 | mddev->pers->status(seq, mddev); |
5429 | seq_printf(seq, "\n "); | 5414 | seq_printf(seq, "\n "); |
5430 | if (mddev->pers->sync_request) { | 5415 | if (mddev->pers->sync_request) { |
5431 | if (mddev->curr_resync > 2) { | 5416 | if (mddev->curr_resync > 2) { |
5432 | status_resync (seq, mddev); | 5417 | status_resync(seq, mddev); |
5433 | seq_printf(seq, "\n "); | 5418 | seq_printf(seq, "\n "); |
5434 | } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) | 5419 | } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) |
5435 | seq_printf(seq, "\tresync=DELAYED\n "); | 5420 | seq_printf(seq, "\tresync=DELAYED\n "); |
@@ -6260,7 +6245,7 @@ static int md_notify_reboot(struct notifier_block *this, | |||
6260 | * appears to still be in use. Hence | 6245 | * appears to still be in use. Hence |
6261 | * the '100'. | 6246 | * the '100'. |
6262 | */ | 6247 | */ |
6263 | do_md_stop (mddev, 1, 100); | 6248 | do_md_stop(mddev, 1, 100); |
6264 | mddev_unlock(mddev); | 6249 | mddev_unlock(mddev); |
6265 | } | 6250 | } |
6266 | /* | 6251 | /* |
@@ -6304,7 +6289,7 @@ static int __init md_init(void) | |||
6304 | raid_table_header = register_sysctl_table(raid_root_table); | 6289 | raid_table_header = register_sysctl_table(raid_root_table); |
6305 | 6290 | ||
6306 | md_geninit(); | 6291 | md_geninit(); |
6307 | return (0); | 6292 | return 0; |
6308 | } | 6293 | } |
6309 | 6294 | ||
6310 | 6295 | ||
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 8bb8794129b3..8744014b9d80 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -19,16 +19,7 @@ | |||
19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/raid/multipath.h> | 22 | #include <linux/raid/multipath.h> |
26 | #include <linux/buffer_head.h> | ||
27 | #include <asm/atomic.h> | ||
28 | |||
29 | #define MAJOR_NR MD_MAJOR | ||
30 | #define MD_DRIVER | ||
31 | #define MD_PERSONALITY | ||
32 | 23 | ||
33 | #define MAX_WORK_PER_DISK 128 | 24 | #define MAX_WORK_PER_DISK 128 |
34 | 25 | ||
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 53508a8a981d..8ac6488ad0dc 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -18,13 +18,8 @@ | |||
18 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/raid/raid0.h> | 21 | #include <linux/raid/raid0.h> |
23 | 22 | ||
24 | #define MAJOR_NR MD_MAJOR | ||
25 | #define MD_DRIVER | ||
26 | #define MD_PERSONALITY | ||
27 | |||
28 | static void raid0_unplug(struct request_queue *q) | 23 | static void raid0_unplug(struct request_queue *q) |
29 | { | 24 | { |
30 | mddev_t *mddev = q->queuedata; | 25 | mddev_t *mddev = q->queuedata; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index b9764429d856..9c788e2489b1 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -32,6 +32,7 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include "dm-bio-list.h" | 34 | #include "dm-bio-list.h" |
35 | #include <linux/delay.h> | ||
35 | #include <linux/raid/raid1.h> | 36 | #include <linux/raid/raid1.h> |
36 | #include <linux/raid/bitmap.h> | 37 | #include <linux/raid/bitmap.h> |
37 | 38 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8bdc9bfc2887..da5129a24b18 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "dm-bio-list.h" | 21 | #include "dm-bio-list.h" |
22 | #include <linux/delay.h> | ||
22 | #include <linux/raid/raid10.h> | 23 | #include <linux/raid/raid10.h> |
23 | #include <linux/raid/bitmap.h> | 24 | #include <linux/raid/bitmap.h> |
24 | 25 | ||
@@ -2028,8 +2029,9 @@ static int run(mddev_t *mddev) | |||
2028 | int nc, fc, fo; | 2029 | int nc, fc, fo; |
2029 | sector_t stride, size; | 2030 | sector_t stride, size; |
2030 | 2031 | ||
2031 | if (mddev->chunk_size == 0) { | 2032 | if (mddev->chunk_size < PAGE_SIZE) { |
2032 | printk(KERN_ERR "md/raid10: non-zero chunk size required.\n"); | 2033 | printk(KERN_ERR "md/raid10: chunk size must be " |
2034 | "at least PAGE_SIZE(%ld).\n", PAGE_SIZE); | ||
2033 | return -EINVAL; | 2035 | return -EINVAL; |
2034 | } | 2036 | } |
2035 | 2037 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ae16794bef20..a36a7435edf5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -43,12 +43,7 @@ | |||
43 | * miss any bits. | 43 | * miss any bits. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include <linux/module.h> | ||
47 | #include <linux/slab.h> | ||
48 | #include <linux/highmem.h> | ||
49 | #include <linux/bitops.h> | ||
50 | #include <linux/kthread.h> | 46 | #include <linux/kthread.h> |
51 | #include <asm/atomic.h> | ||
52 | #include "raid6.h" | 47 | #include "raid6.h" |
53 | 48 | ||
54 | #include <linux/raid/bitmap.h> | 49 | #include <linux/raid/bitmap.h> |
@@ -275,7 +270,7 @@ static int grow_buffers(struct stripe_head *sh, int num) | |||
275 | return 0; | 270 | return 0; |
276 | } | 271 | } |
277 | 272 | ||
278 | static void raid5_build_block (struct stripe_head *sh, int i); | 273 | static void raid5_build_block(struct stripe_head *sh, int i); |
279 | 274 | ||
280 | static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks) | 275 | static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks) |
281 | { | 276 | { |
@@ -1151,7 +1146,7 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
1151 | release_stripe(sh); | 1146 | release_stripe(sh); |
1152 | } | 1147 | } |
1153 | 1148 | ||
1154 | static void raid5_end_write_request (struct bio *bi, int error) | 1149 | static void raid5_end_write_request(struct bio *bi, int error) |
1155 | { | 1150 | { |
1156 | struct stripe_head *sh = bi->bi_private; | 1151 | struct stripe_head *sh = bi->bi_private; |
1157 | raid5_conf_t *conf = sh->raid_conf; | 1152 | raid5_conf_t *conf = sh->raid_conf; |
@@ -1183,7 +1178,7 @@ static void raid5_end_write_request (struct bio *bi, int error) | |||
1183 | 1178 | ||
1184 | static sector_t compute_blocknr(struct stripe_head *sh, int i); | 1179 | static sector_t compute_blocknr(struct stripe_head *sh, int i); |
1185 | 1180 | ||
1186 | static void raid5_build_block (struct stripe_head *sh, int i) | 1181 | static void raid5_build_block(struct stripe_head *sh, int i) |
1187 | { | 1182 | { |
1188 | struct r5dev *dev = &sh->dev[i]; | 1183 | struct r5dev *dev = &sh->dev[i]; |
1189 | 1184 | ||
@@ -1221,10 +1216,10 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1221 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 1216 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
1222 | } | 1217 | } |
1223 | set_bit(Faulty, &rdev->flags); | 1218 | set_bit(Faulty, &rdev->flags); |
1224 | printk (KERN_ALERT | 1219 | printk(KERN_ALERT |
1225 | "raid5: Disk failure on %s, disabling device.\n" | 1220 | "raid5: Disk failure on %s, disabling device.\n" |
1226 | "raid5: Operation continuing on %d devices.\n", | 1221 | "raid5: Operation continuing on %d devices.\n", |
1227 | bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); | 1222 | bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); |
1228 | } | 1223 | } |
1229 | } | 1224 | } |
1230 | 1225 | ||
@@ -1320,8 +1315,8 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks, | |||
1320 | *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; | 1315 | *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; |
1321 | break; | 1316 | break; |
1322 | default: | 1317 | default: |
1323 | printk (KERN_CRIT "raid6: unsupported algorithm %d\n", | 1318 | printk(KERN_CRIT "raid6: unsupported algorithm %d\n", |
1324 | conf->algorithm); | 1319 | conf->algorithm); |
1325 | } | 1320 | } |
1326 | break; | 1321 | break; |
1327 | } | 1322 | } |
@@ -1396,8 +1391,8 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) | |||
1396 | } | 1391 | } |
1397 | break; | 1392 | break; |
1398 | default: | 1393 | default: |
1399 | printk (KERN_CRIT "raid6: unsupported algorithm %d\n", | 1394 | printk(KERN_CRIT "raid6: unsupported algorithm %d\n", |
1400 | conf->algorithm); | 1395 | conf->algorithm); |
1401 | } | 1396 | } |
1402 | break; | 1397 | break; |
1403 | } | 1398 | } |
@@ -1405,7 +1400,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) | |||
1405 | chunk_number = stripe * data_disks + i; | 1400 | chunk_number = stripe * data_disks + i; |
1406 | r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; | 1401 | r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; |
1407 | 1402 | ||
1408 | check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); | 1403 | check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); |
1409 | if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { | 1404 | if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { |
1410 | printk(KERN_ERR "compute_blocknr: map not correct\n"); | 1405 | printk(KERN_ERR "compute_blocknr: map not correct\n"); |
1411 | return 0; | 1406 | return 0; |
@@ -4012,6 +4007,13 @@ static int run(mddev_t *mddev) | |||
4012 | return -EIO; | 4007 | return -EIO; |
4013 | } | 4008 | } |
4014 | 4009 | ||
4010 | if (mddev->chunk_size < PAGE_SIZE) { | ||
4011 | printk(KERN_ERR "md/raid5: chunk_size must be at least " | ||
4012 | "PAGE_SIZE but %d < %ld\n", | ||
4013 | mddev->chunk_size, PAGE_SIZE); | ||
4014 | return -EINVAL; | ||
4015 | } | ||
4016 | |||
4015 | if (mddev->reshape_position != MaxSector) { | 4017 | if (mddev->reshape_position != MaxSector) { |
4016 | /* Check that we can continue the reshape. | 4018 | /* Check that we can continue the reshape. |
4017 | * Currently only disks can change, it must | 4019 | * Currently only disks can change, it must |
@@ -4289,7 +4291,7 @@ static int stop(mddev_t *mddev) | |||
4289 | } | 4291 | } |
4290 | 4292 | ||
4291 | #ifdef DEBUG | 4293 | #ifdef DEBUG |
4292 | static void print_sh (struct seq_file *seq, struct stripe_head *sh) | 4294 | static void print_sh(struct seq_file *seq, struct stripe_head *sh) |
4293 | { | 4295 | { |
4294 | int i; | 4296 | int i; |
4295 | 4297 | ||
@@ -4305,7 +4307,7 @@ static void print_sh (struct seq_file *seq, struct stripe_head *sh) | |||
4305 | seq_printf(seq, "\n"); | 4307 | seq_printf(seq, "\n"); |
4306 | } | 4308 | } |
4307 | 4309 | ||
4308 | static void printall (struct seq_file *seq, raid5_conf_t *conf) | 4310 | static void printall(struct seq_file *seq, raid5_conf_t *conf) |
4309 | { | 4311 | { |
4310 | struct stripe_head *sh; | 4312 | struct stripe_head *sh; |
4311 | struct hlist_node *hn; | 4313 | struct hlist_node *hn; |
@@ -4323,7 +4325,7 @@ static void printall (struct seq_file *seq, raid5_conf_t *conf) | |||
4323 | } | 4325 | } |
4324 | #endif | 4326 | #endif |
4325 | 4327 | ||
4326 | static void status (struct seq_file *seq, mddev_t *mddev) | 4328 | static void status(struct seq_file *seq, mddev_t *mddev) |
4327 | { | 4329 | { |
4328 | raid5_conf_t *conf = (raid5_conf_t *) mddev->private; | 4330 | raid5_conf_t *conf = (raid5_conf_t *) mddev->private; |
4329 | int i; | 4331 | int i; |
diff --git a/drivers/md/raid6.h b/drivers/md/raid6.h index 31cbee71365f..98dcde88470e 100644 --- a/drivers/md/raid6.h +++ b/drivers/md/raid6.h | |||
@@ -18,15 +18,6 @@ | |||
18 | /* Set to 1 to use kernel-wide empty_zero_page */ | 18 | /* Set to 1 to use kernel-wide empty_zero_page */ |
19 | #define RAID6_USE_EMPTY_ZERO_PAGE 0 | 19 | #define RAID6_USE_EMPTY_ZERO_PAGE 0 |
20 | 20 | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/stddef.h> | ||
23 | #include <linux/compiler.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/mempool.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/vmalloc.h> | ||
30 | #include <linux/raid/md.h> | 21 | #include <linux/raid/md.h> |
31 | #include <linux/raid/raid5.h> | 22 | #include <linux/raid/raid5.h> |
32 | 23 | ||