git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
vserver 1.9.5.x5
[linux-2.6.git]
/
drivers
/
md
/
linear.c
diff --git
a/drivers/md/linear.c
b/drivers/md/linear.c
index
0f57e5e
..
161e9aa
100644
(file)
--- a/
drivers/md/linear.c
+++ b/
drivers/md/linear.c
@@
-31,7
+31,7
@@
*/
static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
{
*/
static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
{
-
struct linear_hash
*hash;
+
dev_info_t
*hash;
linear_conf_t *conf = mddev_to_conf(mddev);
sector_t block = sector >> 1;
linear_conf_t *conf = mddev_to_conf(mddev);
sector_t block = sector >> 1;
@@
-39,12
+39,11
@@
static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
* sector_div(a,b) returns the remainer and sets a to a/b
*/
(void)sector_div(block, conf->smallest->size);
* sector_div(a,b) returns the remainer and sets a to a/b
*/
(void)sector_div(block, conf->smallest->size);
- hash = conf->hash_table
+ block
;
+ hash = conf->hash_table
[block]
;
- if ((sector>>1) >= (hash->dev0->size + hash->dev0->offset))
- return hash->dev1;
- else
- return hash->dev0;
+ while ((sector>>1) >= (hash->size + hash->offset))
+ hash++;
+ return hash;
}
/**
}
/**
@@
-99,17
+98,14
@@
static int linear_issue_flush(request_queue_t *q, struct gendisk *disk,
linear_conf_t *conf = mddev_to_conf(mddev);
int i, ret = 0;
linear_conf_t *conf = mddev_to_conf(mddev);
int i, ret = 0;
- for (i=0; i < mddev->raid_disks; i++) {
+ for (i=0; i < mddev->raid_disks
&& ret == 0
; i++) {
struct block_device *bdev = conf->disks[i].rdev->bdev;
request_queue_t *r_queue = bdev_get_queue(bdev);
struct block_device *bdev = conf->disks[i].rdev->bdev;
request_queue_t *r_queue = bdev_get_queue(bdev);
- if (!r_queue->issue_flush_fn)
{
+ if (!r_queue->issue_flush_fn)
ret = -EOPNOTSUPP;
ret = -EOPNOTSUPP;
- break;
- }
- ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
- if (ret)
- break;
+ else
+ ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
}
return ret;
}
}
return ret;
}
@@
-117,10
+113,11
@@
static int linear_issue_flush(request_queue_t *q, struct gendisk *disk,
static int linear_run (mddev_t *mddev)
{
linear_conf_t *conf;
static int linear_run (mddev_t *mddev)
{
linear_conf_t *conf;
-
struct linear_hash
*table;
+
dev_info_t *
*table;
mdk_rdev_t *rdev;
mdk_rdev_t *rdev;
- int size, i, nb_zone, cnt;
- unsigned int curr_offset;
+ int i, nb_zone, cnt;
+ sector_t start;
+ sector_t curr_offset;
struct list_head *tmp;
conf = kmalloc (sizeof (*conf) + mddev->raid_disks*sizeof(dev_info_t),
struct list_head *tmp;
conf = kmalloc (sizeof (*conf) + mddev->raid_disks*sizeof(dev_info_t),
@@
-186,7
+183,7
@@
static int linear_run (mddev_t *mddev)
nb_zone = conf->nr_zones = sz + (round ? 1 : 0);
}
nb_zone = conf->nr_zones = sz + (round ? 1 : 0);
}
- conf->hash_table = kmalloc (sizeof (
struct linear_hash
) * nb_zone,
+ conf->hash_table = kmalloc (sizeof (
dev_info_t*
) * nb_zone,
GFP_KERNEL);
if (!conf->hash_table)
goto out;
GFP_KERNEL);
if (!conf->hash_table)
goto out;
@@
-195,7
+192,7
@@
static int linear_run (mddev_t *mddev)
* Here we generate the linear hash table
*/
table = conf->hash_table;
* Here we generate the linear hash table
*/
table = conf->hash_table;
- s
ize
= 0;
+ s
tart
= 0;
curr_offset = 0;
for (i = 0; i < cnt; i++) {
dev_info_t *disk = conf->disks + i;
curr_offset = 0;
for (i = 0; i < cnt; i++) {
dev_info_t *disk = conf->disks + i;
@@
-203,16
+200,12
@@
static int linear_run (mddev_t *mddev)
disk->offset = curr_offset;
curr_offset += disk->size;
disk->offset = curr_offset;
curr_offset += disk->size;
- if (size < 0) {
- table[-1].dev1 = disk;
- }
- size += disk->size;
-
- while (size>0) {
- table->dev0 = disk;
- table->dev1 = NULL;
- size -= conf->smallest->size;
- table++;
+ /* 'curr_offset' is the end of this disk
+ * 'start' is the start of table
+ */
+ while (start < curr_offset) {
+ *table++ = disk;
+ start += conf->smallest->size;
}
}
if (table-conf->hash_table != nb_zone)
}
}
if (table-conf->hash_table != nb_zone)
@@
-233,6
+226,7
@@
static int linear_stop (mddev_t *mddev)
{
linear_conf_t *conf = mddev_to_conf(mddev);
{
linear_conf_t *conf = mddev_to_conf(mddev);
+ blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
kfree(conf->hash_table);
kfree(conf);
kfree(conf->hash_table);
kfree(conf);
@@
-255,23
+249,17
@@
static int linear_make_request (request_queue_t *q, struct bio *bio)
tmp_dev = which_dev(mddev, bio->bi_sector);
block = bio->bi_sector >> 1;
tmp_dev = which_dev(mddev, bio->bi_sector);
block = bio->bi_sector >> 1;
-
- if (unlikely(!tmp_dev)) {
- printk("linear_make_request: hash->dev1==NULL for block %llu\n",
- (unsigned long long)block);
- bio_io_error(bio, bio->bi_size);
- return 0;
- }
if (unlikely(block >= (tmp_dev->size + tmp_dev->offset)
|| block < tmp_dev->offset)) {
char b[BDEVNAME_SIZE];
printk("linear_make_request: Block %llu out of bounds on "
if (unlikely(block >= (tmp_dev->size + tmp_dev->offset)
|| block < tmp_dev->offset)) {
char b[BDEVNAME_SIZE];
printk("linear_make_request: Block %llu out of bounds on "
- "dev %s size %l
d offset %ld
\n",
+ "dev %s size %l
lu offset %llu
\n",
(unsigned long long)block,
bdevname(tmp_dev->rdev->bdev, b),
(unsigned long long)block,
bdevname(tmp_dev->rdev->bdev, b),
- tmp_dev->size, tmp_dev->offset);
+ (unsigned long long)tmp_dev->size,
+ (unsigned long long)tmp_dev->offset);
bio_io_error(bio, bio->bi_size);
return 0;
}
bio_io_error(bio, bio->bi_size);
return 0;
}
@@
-305,17
+293,20
@@
static void linear_status (struct seq_file *seq, mddev_t *mddev)
#ifdef MD_DEBUG
int j;
linear_conf_t *conf = mddev_to_conf(mddev);
#ifdef MD_DEBUG
int j;
linear_conf_t *conf = mddev_to_conf(mddev);
+ sector_t s = 0;
seq_printf(seq, " ");
for (j = 0; j < conf->nr_zones; j++)
{
char b[BDEVNAME_SIZE];
seq_printf(seq, " ");
for (j = 0; j < conf->nr_zones; j++)
{
char b[BDEVNAME_SIZE];
+ s += conf->smallest_size;
seq_printf(seq, "[%s",
seq_printf(seq, "[%s",
- bdevname(conf->hash_table[j]
.dev0->
rdev->bdev,b));
+ bdevname(conf->hash_table[j]
[0].
rdev->bdev,b));
- if (conf->hash_table[j].dev1)
+ while (s > conf->hash_table[j][0].offset +
+ conf->hash_table[j][0].size)
seq_printf(seq, "/%s] ",
seq_printf(seq, "/%s] ",
- bdevname(conf->hash_table[j]
.dev1->
rdev->bdev,b));
+ bdevname(conf->hash_table[j]
[1].
rdev->bdev,b));
else
seq_printf(seq, "] ");
}
else
seq_printf(seq, "] ");
}