Commit c472273f authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://neil.brown.name/md

* 'for-linus' of git://neil.brown.name/md:
  md: fix input truncation in safe_delay_store()
  md: check for memory allocation failure in faulty personality
  md: build failure due to missing delay.h
  md: Relax minimum size restrictions on chunk_size.
  md: remove space after function name in declaration and call.
  md: Remove unnecessary #includes, #defines, and function declarations.
  md: Convert remaining 1k representations in linear.c to sectors.
  md: linear.c: Make two local variables sector-based.
  md: linear: Represent dev_info->size and dev_info->offset in sectors.
  md: linear.c: Remove broken debug code.
  md: linear.c: Remove pointless initialization of curr_offset.
  md: linear.c: Fix typo in comment.
  md: Don't try to set an array to 'read-auto' if it is already in that state.
  md: Allow metadata_version to be updated for externally managed metadata.
  md: Fix rdev_size_store with size == 0
parents 36ac1d2f 97ce0a7f
...@@ -287,6 +287,8 @@ static int run(mddev_t *mddev) ...@@ -287,6 +287,8 @@ static int run(mddev_t *mddev)
int i; int i;
conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL);
if (!conf)
return -ENOMEM;
for (i=0; i<Modes; i++) { for (i=0; i<Modes; i++) {
atomic_set(&conf->counters[i], 0); atomic_set(&conf->counters[i], 0);
......
...@@ -16,16 +16,8 @@ ...@@ -16,16 +16,8 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/module.h>
#include <linux/raid/md.h>
#include <linux/slab.h>
#include <linux/raid/linear.h> #include <linux/raid/linear.h>
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
/* /*
* find which device holds a particular offset * find which device holds a particular offset
*/ */
...@@ -33,16 +25,15 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) ...@@ -33,16 +25,15 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
{ {
dev_info_t *hash; dev_info_t *hash;
linear_conf_t *conf = mddev_to_conf(mddev); linear_conf_t *conf = mddev_to_conf(mddev);
sector_t block = sector >> 1;
/* /*
* sector_div(a,b) returns the remainer and sets a to a/b * sector_div(a,b) returns the remainer and sets a to a/b
*/ */
block >>= conf->preshift; sector >>= conf->sector_shift;
(void)sector_div(block, conf->hash_spacing); (void)sector_div(sector, conf->spacing);
hash = conf->hash_table[block]; hash = conf->hash_table[sector];
while ((sector>>1) >= (hash->size + hash->offset)) while (sector >= hash->num_sectors + hash->start_sector)
hash++; hash++;
return hash; return hash;
} }
...@@ -65,7 +56,7 @@ static int linear_mergeable_bvec(struct request_queue *q, ...@@ -65,7 +56,7 @@ static int linear_mergeable_bvec(struct request_queue *q,
sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
dev0 = which_dev(mddev, sector); dev0 = which_dev(mddev, sector);
maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); maxsectors = dev0->num_sectors - (sector - dev0->start_sector);
if (maxsectors < bio_sectors) if (maxsectors < bio_sectors)
maxsectors = 0; maxsectors = 0;
...@@ -112,8 +103,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) ...@@ -112,8 +103,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
dev_info_t **table; dev_info_t **table;
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
int i, nb_zone, cnt; int i, nb_zone, cnt;
sector_t min_spacing; sector_t min_sectors;
sector_t curr_offset; sector_t curr_sector;
struct list_head *tmp; struct list_head *tmp;
conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), 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,7 +136,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
mddev->queue->max_sectors > (PAGE_SIZE>>9)) mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
disk->size = rdev->size; disk->num_sectors = rdev->size * 2;
conf->array_sectors += rdev->size * 2; conf->array_sectors += rdev->size * 2;
cnt++; cnt++;
...@@ -155,34 +146,34 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) ...@@ -155,34 +146,34 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
goto out; goto out;
} }
min_spacing = conf->array_sectors / 2; min_sectors = conf->array_sectors;
sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *));
/* min_spacing is the minimum spacing that will fit the hash /* min_sectors is the minimum spacing that will fit the hash
* table in one PAGE. This may be much smaller than needed. * table in one PAGE. This may be much smaller than needed.
* We find the smallest non-terminal set of consecutive devices * We find the smallest non-terminal set of consecutive devices
* that is larger than min_spacing as use the size of that as * that is larger than min_sectors and use the size of that as
* the actual spacing * the actual spacing
*/ */
conf->hash_spacing = conf->array_sectors / 2; conf->spacing = conf->array_sectors;
for (i=0; i < cnt-1 ; i++) { for (i=0; i < cnt-1 ; i++) {
sector_t sz = 0; sector_t tmp = 0;
int j; int j;
for (j = i; j < cnt - 1 && sz < min_spacing; j++) for (j = i; j < cnt - 1 && tmp < min_sectors; j++)
sz += conf->disks[j].size; tmp += conf->disks[j].num_sectors;
if (sz >= min_spacing && sz < conf->hash_spacing) if (tmp >= min_sectors && tmp < conf->spacing)
conf->hash_spacing = sz; conf->spacing = tmp;
} }
/* hash_spacing may be too large for sector_div to work with, /* spacing may be too large for sector_div to work with,
* so we might need to pre-shift * so we might need to pre-shift
*/ */
conf->preshift = 0; conf->sector_shift = 0;
if (sizeof(sector_t) > sizeof(u32)) { if (sizeof(sector_t) > sizeof(u32)) {
sector_t space = conf->hash_spacing; sector_t space = conf->spacing;
while (space > (sector_t)(~(u32)0)) { while (space > (sector_t)(~(u32)0)) {
space >>= 1; space >>= 1;
conf->preshift++; conf->sector_shift++;
} }
} }
/* /*
...@@ -194,9 +185,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) ...@@ -194,9 +185,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
unsigned round; unsigned round;
unsigned long base; unsigned long base;
sz = conf->array_sectors >> (conf->preshift + 1); sz = conf->array_sectors >> conf->sector_shift;
sz += 1; /* force round-up */ sz += 1; /* force round-up */
base = conf->hash_spacing >> conf->preshift; base = conf->spacing >> conf->sector_shift;
round = sector_div(sz, base); round = sector_div(sz, base);
nb_zone = sz + (round ? 1 : 0); nb_zone = sz + (round ? 1 : 0);
} }
...@@ -211,32 +202,31 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) ...@@ -211,32 +202,31 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
* Here we generate the linear hash table * Here we generate the linear hash table
* First calculate the device offsets. * First calculate the device offsets.
*/ */
conf->disks[0].offset = 0; conf->disks[0].start_sector = 0;
for (i = 1; i < raid_disks; i++) for (i = 1; i < raid_disks; i++)
conf->disks[i].offset = conf->disks[i].start_sector =
conf->disks[i-1].offset + conf->disks[i-1].start_sector +
conf->disks[i-1].size; conf->disks[i-1].num_sectors;
table = conf->hash_table; table = conf->hash_table;
curr_offset = 0;
i = 0; i = 0;
for (curr_offset = 0; for (curr_sector = 0;
curr_offset < conf->array_sectors / 2; curr_sector < conf->array_sectors;
curr_offset += conf->hash_spacing) { curr_sector += conf->spacing) {
while (i < raid_disks-1 && while (i < raid_disks-1 &&
curr_offset >= conf->disks[i+1].offset) curr_sector >= conf->disks[i+1].start_sector)
i++; i++;
*table ++ = conf->disks + i; *table ++ = conf->disks + i;
} }
if (conf->preshift) { if (conf->sector_shift) {
conf->hash_spacing >>= conf->preshift; conf->spacing >>= conf->sector_shift;
/* round hash_spacing up so that when we divide by it, /* round spacing up so that when we divide by it,
* we err on the side of "too-low", which is safest. * we err on the side of "too-low", which is safest.
*/ */
conf->hash_spacing++; conf->spacing++;
} }
BUG_ON(table - conf->hash_table > nb_zone); 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,7 +307,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
const int rw = bio_data_dir(bio); const int rw = bio_data_dir(bio);
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
dev_info_t *tmp_dev; dev_info_t *tmp_dev;
sector_t block;
int cpu; int cpu;
if (unlikely(bio_barrier(bio))) { if (unlikely(bio_barrier(bio))) {
...@@ -332,29 +321,33 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) ...@@ -332,29 +321,33 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
part_stat_unlock(); part_stat_unlock();
tmp_dev = which_dev(mddev, bio->bi_sector); tmp_dev = which_dev(mddev, bio->bi_sector);
block = bio->bi_sector >> 1;
if (unlikely(block >= (tmp_dev->size + tmp_dev->offset) if (unlikely(bio->bi_sector >= (tmp_dev->num_sectors +
|| block < tmp_dev->offset)) { tmp_dev->start_sector)
|| (bio->bi_sector <
tmp_dev->start_sector))) {
char b[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE];
printk("linear_make_request: Block %llu out of bounds on " printk("linear_make_request: Sector %llu out of bounds on "
"dev %s size %llu offset %llu\n", "dev %s: %llu sectors, offset %llu\n",
(unsigned long long)block, (unsigned long long)bio->bi_sector,
bdevname(tmp_dev->rdev->bdev, b), bdevname(tmp_dev->rdev->bdev, b),
(unsigned long long)tmp_dev->size, (unsigned long long)tmp_dev->num_sectors,
(unsigned long long)tmp_dev->offset); (unsigned long long)tmp_dev->start_sector);
bio_io_error(bio); bio_io_error(bio);
return 0; return 0;
} }
if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > if (unlikely(bio->bi_sector + (bio->bi_size >> 9) >
(tmp_dev->offset + tmp_dev->size)<<1)) { tmp_dev->start_sector + tmp_dev->num_sectors)) {
/* This bio crosses a device boundary, so we have to /* This bio crosses a device boundary, so we have to
* split it. * split it.
*/ */
struct bio_pair *bp; struct bio_pair *bp;
bp = bio_split(bio, bp = bio_split(bio,
((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector); tmp_dev->start_sector + tmp_dev->num_sectors
- bio->bi_sector);
if (linear_make_request(q, &bp->bio1)) if (linear_make_request(q, &bp->bio1))
generic_make_request(&bp->bio1); generic_make_request(&bp->bio1);
if (linear_make_request(q, &bp->bio2)) if (linear_make_request(q, &bp->bio2))
...@@ -364,7 +357,8 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) ...@@ -364,7 +357,8 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
} }
bio->bi_bdev = tmp_dev->rdev->bdev; bio->bi_bdev = tmp_dev->rdev->bdev;
bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset; bio->bi_sector = bio->bi_sector - tmp_dev->start_sector
+ tmp_dev->rdev->data_offset;
return 1; return 1;
} }
...@@ -372,29 +366,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) ...@@ -372,29 +366,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
static void linear_status (struct seq_file *seq, mddev_t *mddev) static void linear_status (struct seq_file *seq, mddev_t *mddev)
{ {
#undef MD_DEBUG
#ifdef MD_DEBUG
int j;
linear_conf_t *conf = mddev_to_conf(mddev);
sector_t s = 0;
seq_printf(seq, " ");
for (j = 0; j < mddev->raid_disks; j++)
{
char b[BDEVNAME_SIZE];
s += conf->smallest_size;
seq_printf(seq, "[%s",
bdevname(conf->hash_table[j][0].rdev->bdev,b));
while (s > conf->hash_table[j][0].offset +
conf->hash_table[j][0].size)
seq_printf(seq, "/%s] ",
bdevname(conf->hash_table[j][1].rdev->bdev,b));
else
seq_printf(seq, "] ");
}
seq_printf(seq, "\n");
#endif
seq_printf(seq, " %dk rounding", mddev->chunk_size/1024); seq_printf(seq, " %dk rounding", mddev->chunk_size/1024);
} }
......
...@@ -32,31 +32,21 @@ ...@@ -32,31 +32,21 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/linkage.h>
#include <linux/raid/md.h> #include <linux/raid/md.h>
#include <linux/raid/bitmap.h> #include <linux/raid/bitmap.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/buffer_head.h> /* for invalidate_bdev */ #include <linux/buffer_head.h> /* for invalidate_bdev */
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/freezer.h> #include <linux/hdreg.h>
#include <linux/proc_fs.h>
#include <linux/init.h> #include <linux/random.h>
#include <linux/reboot.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/delay.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
#include <asm/unaligned.h>
#define MAJOR_NR MD_MAJOR #define MAJOR_NR MD_MAJOR
#define MD_DRIVER
/* 63 partitions with the alternate major number (mdp) */ /* 63 partitions with the alternate major number (mdp) */
#define MdpMinorShift 6 #define MdpMinorShift 6
...@@ -66,7 +56,7 @@ ...@@ -66,7 +56,7 @@
#ifndef MODULE #ifndef MODULE
static void autostart_arrays (int part); static void autostart_arrays(int part);
#endif #endif
static LIST_HEAD(pers_list); static LIST_HEAD(pers_list);
...@@ -212,7 +202,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock); ...@@ -212,7 +202,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
) )
static int md_fail_request (struct request_queue *q, struct bio *bio) static int md_fail_request(struct request_queue *q, struct bio *bio)
{ {
bio_io_error(bio); bio_io_error(bio);
return 0; return 0;
...@@ -2106,8 +2096,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) ...@@ -2106,8 +2096,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (strict_strtoull(buf, 10, &size) < 0) if (strict_strtoull(buf, 10, &size) < 0)
return -EINVAL; return -EINVAL;
if (size < my_mddev->size)
return -EINVAL;
if (my_mddev->pers && rdev->raid_disk >= 0) { if (my_mddev->pers && rdev->raid_disk >= 0) {
if (my_mddev->persistent) { if (my_mddev->persistent) {
size = super_types[my_mddev->major_version]. 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,9 +2106,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
size = (rdev->bdev->bd_inode->i_size >> 10); size = (rdev->bdev->bd_inode->i_size >> 10);
size -= rdev->data_offset/2; size -= rdev->data_offset/2;
} }
}
if (size < my_mddev->size) if (size < my_mddev->size)
return -EINVAL; /* component must fit device */ return -EINVAL; /* component must fit device */
}
rdev->size = size; rdev->size = size;
if (size > oldsize && my_mddev->external) { if (size > oldsize && my_mddev->external) {
...@@ -2406,12 +2394,11 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) ...@@ -2406,12 +2394,11 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
int i; int i;
unsigned long msec; unsigned long msec;
char buf[30]; char buf[30];
char *e;
/* remove a period, and count digits after it */ /* remove a period, and count digits after it */
if (len >= sizeof(buf)) if (len >= sizeof(buf))
return -EINVAL; return -EINVAL;
strlcpy(buf, cbuf, len); strlcpy(buf, cbuf, sizeof(buf));
buf[len] = 0;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (dot) { if (dot) {
if (isdigit(buf[i])) { if (isdigit(buf[i])) {
...@@ -2424,8 +2411,7 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) ...@@ -2424,8 +2411,7 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
buf[i] = 0; buf[i] = 0;
} }
} }
msec = simple_strtoul(buf, &e, 10); if (strict_strtoul(buf, 10, &msec) < 0)
if (e == buf || (*e && *e != '\n'))
return -EINVAL; return -EINVAL;
msec = (msec * 1000) / scale; msec = (msec * 1000) / scale;
if (msec == 0) if (msec == 0)
...@@ -2727,9 +2713,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) ...@@ -2727,9 +2713,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
break; break;
case read_auto: case read_auto:
if (mddev->pers) { if (mddev->pers) {
if (mddev->ro != 1) if (mddev->ro == 0)
err = do_md_stop(mddev, 1, 0); err = do_md_stop(mddev, 1, 0);
else else if (mddev->ro == 1)
err = restart_array(mddev); err = restart_array(mddev);
if (err == 0) { if (err == 0) {
mddev->ro = 2; mddev->ro = 2;
...@@ -2945,7 +2931,13 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len) ...@@ -2945,7 +2931,13 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
{ {
int major, minor; int major, minor;
char *e; char *e;
if (!list_empty(&mddev->disks)) /* Changing the details of 'external' metadata is
* always permitted. Otherwise there must be
* no devices attached to the array.
*/
if (mddev->external && strncmp(buf, "external:", 9) == 0)
;
else if (!list_empty(&mddev->disks))
return -EBUSY; return -EBUSY;
if (cmd_match(buf, "none")) { if (cmd_match(buf, "none")) {
...@@ -3527,17 +3519,12 @@ static int do_md_run(mddev_t * mddev) ...@@ -3527,17 +3519,12 @@ static int do_md_run(mddev_t * mddev)
return -EINVAL; return -EINVAL;
} }
/* /*
* chunk-size has to be a power of 2 and multiples of PAGE_SIZE * chunk-size has to be a power of 2
*/ */
if ( (1 << ffz(~chunk_size)) != chunk_size) { if ( (1 << ffz(~chunk_size)) != chunk_size) {
printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size); printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size);
return -EINVAL; return -EINVAL;
} }
if (chunk_size < PAGE_SIZE) {
printk(KERN_ERR "too small chunk_size: %d < %ld\n",
chunk_size, PAGE_SIZE);
return -EINVAL;
}
/* devices must have minimum size of one chunk */ /* devices must have minimum size of one chunk */
rdev_for_each(rdev, tmp, mddev) { rdev_for_each(rdev, tmp, mddev) {
...@@ -3555,12 +3542,10 @@ static int do_md_run(mddev_t * mddev) ...@@ -3555,12 +3542,10 @@ static int do_md_run(mddev_t * mddev)
} }
} }
#ifdef CONFIG_KMOD
if (mddev->level != LEVEL_NONE) if (mddev->level != LEVEL_NONE)
request_module("md-level-%d", mddev->level); request_module("md-level-%d", mddev->level);
else if (mddev->clevel[0]) else if (mddev->clevel[0])
request_module("md-%s", mddev->clevel); request_module("md-%s", mddev->clevel);
#endif
/* /*
* Drop all container device buffers, from now on * Drop all container device buffers, from now on
...@@ -3971,10 +3956,10 @@ static void autorun_array(mddev_t *mddev) ...@@ -3971,10 +3956,10 @@ static void autorun_array(mddev_t *mddev)
} }
printk("\n"); printk("\n");
err = do_md_run (mddev); err = do_md_run(mddev);
if (err) { if (err) {
printk(KERN_WARNING "md: do_md_run() returned %d\n", err); printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
do_md_stop (mddev, 0, 0); do_md_stop(mddev, 0, 0);
} }
} }
...@@ -4333,7 +4318,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) ...@@ -4333,7 +4318,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
if (!(info->state & (1<<MD_DISK_FAULTY))) { if (!(info->state & (1<<MD_DISK_FAULTY))) {
int err; int err;
rdev = md_import_device (dev, -1, 0); rdev = md_import_device(dev, -1, 0);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
printk(KERN_WARNING printk(KERN_WARNING
"md: error, md_import_device() returned %ld\n", "md: error, md_import_device() returned %ld\n",
...@@ -4415,7 +4400,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) ...@@ -4415,7 +4400,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
return -EINVAL; return -EINVAL;
} }
rdev = md_import_device (dev, -1, 0); rdev = md_import_device(dev, -1, 0);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
printk(KERN_WARNING printk(KERN_WARNING
"md: error, md_import_device() returned %ld\n", "md: error, md_import_device() returned %ld\n",
...@@ -4934,11 +4919,11 @@ static int md_ioctl(struct inode *inode, struct file *file, ...@@ -4934,11 +4919,11 @@ static int md_ioctl(struct inode *inode, struct file *file,
goto done_unlock; goto done_unlock;
case STOP_ARRAY: case STOP_ARRAY:
err = do_md_stop (mddev, 0, 1); err = do_md_stop(mddev, 0, 1);
goto done_unlock; goto done_unlock;
case STOP_ARRAY_RO: case STOP_ARRAY_RO:
err = do_md_stop (mddev, 1, 1); err = do_md_stop(mddev, 1, 1);
goto done_unlock; goto done_unlock;
} }
...@@ -4987,7 +4972,7 @@ static int md_ioctl(struct inode *inode, struct file *file, ...@@ -4987,7 +4972,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
goto done_unlock; goto done_unlock;
case RUN_ARRAY: case RUN_ARRAY:
err = do_md_run (mddev); err = do_md_run(mddev);
goto done_unlock; goto done_unlock;
case SET_BITMAP_FILE: case SET_BITMAP_FILE:
...@@ -5425,11 +5410,11 @@ static int md_seq_show(struct seq_file *seq, void *v) ...@@ -5425,11 +5410,11 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " super non-persistent"); seq_printf(seq, " super non-persistent");
if (mddev->pers) { if (mddev->pers) {
mddev->pers->status (seq, mddev); mddev->pers->status(seq, mddev);
seq_printf(seq, "\n "); seq_printf(seq, "\n ");
if (mddev->pers->sync_request) { if (mddev->pers->sync_request) {
if (mddev->curr_resync > 2) { if (mddev->curr_resync > 2) {
status_resync (seq, mddev); status_resync(seq, mddev);
seq_printf(seq, "\n "); seq_printf(seq, "\n ");
} else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
seq_printf(seq, "\tresync=DELAYED\n "); seq_printf(seq, "\tresync=DELAYED\n ");
...@@ -6260,7 +6245,7 @@ static int md_notify_reboot(struct notifier_block *this, ...@@ -6260,7 +6245,7 @@ static int md_notify_reboot(struct notifier_block *this,
* appears to still be in use. Hence * appears to still be in use. Hence
* the '100'. * the '100'.
*/ */
do_md_stop (mddev, 1, 100); do_md_stop(mddev, 1, 100);
mddev_unlock(mddev); mddev_unlock(mddev);
} }
/* /*
...@@ -6304,7 +6289,7 @@ static int __init md_init(void) ...@@ -6304,7 +6289,7 @@ static int __init md_init(void)
raid_table_header = register_sysctl_table(raid_root_table); raid_table_header = register_sysctl_table(raid_root_table);
md_geninit(); md_geninit();
return (0); return 0;
} }
......
...@@ -19,16 +19,7 @@ ...@@ -19,16 +19,7 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/raid/multipath.h> #include <linux/raid/multipath.h>
#include <linux/buffer_head.h>
#include <asm/atomic.h>
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
#define MAX_WORK_PER_DISK 128 #define MAX_WORK_PER_DISK 128
......
...@@ -18,13 +18,8 @@ ...@@ -18,13 +18,8 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/module.h>
#include <linux/raid/raid0.h> #include <linux/raid/raid0.h>
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
static void raid0_unplug(struct request_queue *q) static void raid0_unplug(struct request_queue *q)
{ {
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
*/ */
#include "dm-bio-list.h" #include "dm-bio-list.h"
#include <linux/delay.h>
#include <linux/raid/raid1.h> #include <linux/raid/raid1.h>
#include <linux/raid/bitmap.h> #include <linux/raid/bitmap.h>
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include "dm-bio-list.h" #include "dm-bio-list.h"
#include <linux/delay.h>
#include <linux/raid/raid10.h> #include <linux/raid/raid10.h>
#include <linux/raid/bitmap.h> #include <linux/raid/bitmap.h>
...@@ -2028,8 +2029,9 @@ static int run(mddev_t *mddev) ...@@ -2028,8 +2029,9 @@ static int run(mddev_t *mddev)
int nc, fc, fo; int nc, fc, fo;
sector_t stride, size; sector_t stride, size;
if (mddev->chunk_size == 0) { if (mddev->chunk_size < PAGE_SIZE) {
printk(KERN_ERR "md/raid10: non-zero chunk size required.\n"); printk(KERN_ERR "md/raid10: chunk size must be "
"at least PAGE_SIZE(%ld).\n", PAGE_SIZE);
return -EINVAL; return -EINVAL;
} }
......
...@@ -43,12 +43,7 @@ ...@@ -43,12 +43,7 @@
* miss any bits. * miss any bits.
*/ */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/bitops.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <asm/atomic.h>
#include "raid6.h" #include "raid6.h"
#include <linux/raid/bitmap.h> #include <linux/raid/bitmap.h>
...@@ -275,7 +270,7 @@ static int grow_buffers(struct stripe_head *sh, int num) ...@@ -275,7 +270,7 @@ static int grow_buffers(struct stripe_head *sh, int num)
return 0; return 0;
} }
static void raid5_build_block (struct stripe_head *sh, int i); static void raid5_build_block(struct stripe_head *sh, int i);
static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks) static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
{ {
...@@ -1151,7 +1146,7 @@ static void raid5_end_read_request(struct bio * bi, int error) ...@@ -1151,7 +1146,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
release_stripe(sh); release_stripe(sh);
} }
static void raid5_end_write_request (struct bio *bi, int error) static void raid5_end_write_request(struct bio *bi, int error)
{ {
struct stripe_head *sh = bi->bi_private; struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf; raid5_conf_t *conf = sh->raid_conf;
...@@ -1183,7 +1178,7 @@ static void raid5_end_write_request (struct bio *bi, int error) ...@@ -1183,7 +1178,7 @@ static void raid5_end_write_request (struct bio *bi, int error)
static sector_t compute_blocknr(struct stripe_head *sh, int i); static sector_t compute_blocknr(struct stripe_head *sh, int i);
static void raid5_build_block (struct stripe_head *sh, int i) static void raid5_build_block(struct stripe_head *sh, int i)
{ {
struct r5dev *dev = &sh->dev[i]; struct r5dev *dev = &sh->dev[i];
...@@ -1221,7 +1216,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -1221,7 +1216,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
set_bit(MD_RECOVERY_INTR, &mddev->recovery); set_bit(MD_RECOVERY_INTR, &mddev->recovery);
} }
set_bit(Faulty, &rdev->flags); set_bit(Faulty, &rdev->flags);
printk (KERN_ALERT printk(KERN_ALERT
"raid5: Disk failure on %s, disabling device.\n" "raid5: Disk failure on %s, disabling device.\n"
"raid5: Operation continuing on %d devices.\n", "raid5: Operation continuing on %d devices.\n",
bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
...@@ -1320,7 +1315,7 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks, ...@@ -1320,7 +1315,7 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
*dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks; *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
break; break;
default: default:
printk (KERN_CRIT "raid6: unsupported algorithm %d\n", printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
conf->algorithm); conf->algorithm);
} }
break; break;
...@@ -1396,7 +1391,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) ...@@ -1396,7 +1391,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
} }
break; break;
default: default:
printk (KERN_CRIT "raid6: unsupported algorithm %d\n", printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
conf->algorithm); conf->algorithm);
} }
break; break;
...@@ -1405,7 +1400,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i) ...@@ -1405,7 +1400,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
chunk_number = stripe * data_disks + i; chunk_number = stripe * data_disks + i;
r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf); check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) { if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
printk(KERN_ERR "compute_blocknr: map not correct\n"); printk(KERN_ERR "compute_blocknr: map not correct\n");
return 0; return 0;
...@@ -4012,6 +4007,13 @@ static int run(mddev_t *mddev) ...@@ -4012,6 +4007,13 @@ static int run(mddev_t *mddev)
return -EIO; return -EIO;
} }
if (mddev->chunk_size < PAGE_SIZE) {
printk(KERN_ERR "md/raid5: chunk_size must be at least "
"PAGE_SIZE but %d < %ld\n",
mddev->chunk_size, PAGE_SIZE);
return -EINVAL;
}
if (mddev->reshape_position != MaxSector) { if (mddev->reshape_position != MaxSector) {
/* Check that we can continue the reshape. /* Check that we can continue the reshape.
* Currently only disks can change, it must * Currently only disks can change, it must
...@@ -4289,7 +4291,7 @@ static int stop(mddev_t *mddev) ...@@ -4289,7 +4291,7 @@ static int stop(mddev_t *mddev)
} }
#ifdef DEBUG #ifdef DEBUG
static void print_sh (struct seq_file *seq, struct stripe_head *sh) static void print_sh(struct seq_file *seq, struct stripe_head *sh)
{ {
int i; int i;
...@@ -4305,7 +4307,7 @@ static void print_sh (struct seq_file *seq, struct stripe_head *sh) ...@@ -4305,7 +4307,7 @@ static void print_sh (struct seq_file *seq, struct stripe_head *sh)
seq_printf(seq, "\n"); seq_printf(seq, "\n");
} }
static void printall (struct seq_file *seq, raid5_conf_t *conf) static void printall(struct seq_file *seq, raid5_conf_t *conf)
{ {
struct stripe_head *sh; struct stripe_head *sh;
struct hlist_node *hn; struct hlist_node *hn;
...@@ -4323,7 +4325,7 @@ static void printall (struct seq_file *seq, raid5_conf_t *conf) ...@@ -4323,7 +4325,7 @@ static void printall (struct seq_file *seq, raid5_conf_t *conf)
} }
#endif #endif
static void status (struct seq_file *seq, mddev_t *mddev) static void status(struct seq_file *seq, mddev_t *mddev)
{ {
raid5_conf_t *conf = (raid5_conf_t *) mddev->private; raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
int i; int i;
......
...@@ -18,15 +18,6 @@ ...@@ -18,15 +18,6 @@
/* Set to 1 to use kernel-wide empty_zero_page */ /* Set to 1 to use kernel-wide empty_zero_page */
#define RAID6_USE_EMPTY_ZERO_PAGE 0 #define RAID6_USE_EMPTY_ZERO_PAGE 0
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mempool.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/raid/md.h> #include <linux/raid/md.h>
#include <linux/raid/raid5.h> #include <linux/raid/raid5.h>
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
struct dev_info { struct dev_info {
mdk_rdev_t *rdev; mdk_rdev_t *rdev;
sector_t size; sector_t num_sectors;
sector_t offset; sector_t start_sector;
}; };
typedef struct dev_info dev_info_t; typedef struct dev_info dev_info_t;
...@@ -15,9 +15,11 @@ struct linear_private_data ...@@ -15,9 +15,11 @@ struct linear_private_data
{ {
struct linear_private_data *prev; /* earlier version */ struct linear_private_data *prev; /* earlier version */
dev_info_t **hash_table; dev_info_t **hash_table;
sector_t hash_spacing; sector_t spacing;
sector_t array_sectors; sector_t array_sectors;
int preshift; /* shift before dividing by hash_spacing */ int sector_shift; /* shift before dividing
* by spacing
*/
dev_info_t disks[0]; dev_info_t disks[0];
}; };
......
...@@ -19,27 +19,7 @@ ...@@ -19,27 +19,7 @@
#define _MD_H #define _MD_H
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/major.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/hdreg.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <net/checksum.h>
#include <linux/random.h>
#include <linux/kernel_stat.h>
#include <asm/io.h>
#include <linux/completion.h>
#include <linux/mempool.h>
#include <linux/list.h>
#include <linux/reboot.h>
#include <linux/vmalloc.h>
#include <linux/blkpg.h>
#include <linux/bio.h>
/* /*
* 'md_p.h' holds the 'physical' layout of RAID devices * 'md_p.h' holds the 'physical' layout of RAID devices
...@@ -74,19 +54,17 @@ ...@@ -74,19 +54,17 @@
extern int mdp_major; extern int mdp_major;
extern int register_md_personality (struct mdk_personality *p); extern int register_md_personality(struct mdk_personality *p);
extern int unregister_md_personality (struct mdk_personality *p); extern int unregister_md_personality(struct mdk_personality *p);
extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev), extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
mddev_t *mddev, const char *name); mddev_t *mddev, const char *name);
extern void md_unregister_thread (mdk_thread_t *thread); extern void md_unregister_thread(mdk_thread_t *thread);
extern void md_wakeup_thread(mdk_thread_t *thread); extern void md_wakeup_thread(mdk_thread_t *thread);
extern void md_check_recovery(mddev_t *mddev); extern void md_check_recovery(mddev_t *mddev);
extern void md_write_start(mddev_t *mddev, struct bio *bi); extern void md_write_start(mddev_t *mddev, struct bio *bi);
extern void md_write_end(mddev_t *mddev); extern void md_write_end(mddev_t *mddev);
extern void md_handle_safemode(mddev_t *mddev);
extern void md_done_sync(mddev_t *mddev, int blocks, int ok); extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
extern void md_error (mddev_t *mddev, mdk_rdev_t *rdev); extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
extern void md_unplug_mddev(mddev_t *mddev);
extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
sector_t sector, int size, struct page *page); sector_t sector, int size, struct page *page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment