diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-crypt.c | 58 | ||||
-rw-r--r-- | drivers/md/dm-io.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-raid1.c | 4 | ||||
-rw-r--r-- | drivers/md/dm-snap.c | 2 | ||||
-rw-r--r-- | drivers/md/kcopyd.c | 10 | ||||
-rw-r--r-- | drivers/md/kcopyd.h | 4 | ||||
-rw-r--r-- | drivers/md/md.c | 12 | ||||
-rw-r--r-- | drivers/md/raid5.c | 6 |
8 files changed, 44 insertions, 54 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index b04f98df94ea..835def11419d 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2003 Christophe Saout <christophe@saout.de> | 2 | * Copyright (C) 2003 Christophe Saout <christophe@saout.de> |
3 | * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> | 3 | * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> |
4 | * Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. | 4 | * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. |
5 | * | 5 | * |
6 | * This file is released under the GPL. | 6 | * This file is released under the GPL. |
7 | */ | 7 | */ |
@@ -93,6 +93,8 @@ struct crypt_config { | |||
93 | 93 | ||
94 | struct workqueue_struct *io_queue; | 94 | struct workqueue_struct *io_queue; |
95 | struct workqueue_struct *crypt_queue; | 95 | struct workqueue_struct *crypt_queue; |
96 | wait_queue_head_t writeq; | ||
97 | |||
96 | /* | 98 | /* |
97 | * crypto related data | 99 | * crypto related data |
98 | */ | 100 | */ |
@@ -331,14 +333,7 @@ static void crypt_convert_init(struct crypt_config *cc, | |||
331 | ctx->idx_out = bio_out ? bio_out->bi_idx : 0; | 333 | ctx->idx_out = bio_out ? bio_out->bi_idx : 0; |
332 | ctx->sector = sector + cc->iv_offset; | 334 | ctx->sector = sector + cc->iv_offset; |
333 | init_completion(&ctx->restart); | 335 | init_completion(&ctx->restart); |
334 | /* | 336 | atomic_set(&ctx->pending, 1); |
335 | * Crypto operation can be asynchronous, | ||
336 | * ctx->pending is increased after request submission. | ||
337 | * We need to ensure that we don't call the crypt finish | ||
338 | * operation before pending got incremented | ||
339 | * (dependent on crypt submission return code). | ||
340 | */ | ||
341 | atomic_set(&ctx->pending, 2); | ||
342 | } | 337 | } |
343 | 338 | ||
344 | static int crypt_convert_block(struct crypt_config *cc, | 339 | static int crypt_convert_block(struct crypt_config *cc, |
@@ -411,43 +406,42 @@ static void crypt_alloc_req(struct crypt_config *cc, | |||
411 | static int crypt_convert(struct crypt_config *cc, | 406 | static int crypt_convert(struct crypt_config *cc, |
412 | struct convert_context *ctx) | 407 | struct convert_context *ctx) |
413 | { | 408 | { |
414 | int r = 0; | 409 | int r; |
415 | 410 | ||
416 | while(ctx->idx_in < ctx->bio_in->bi_vcnt && | 411 | while(ctx->idx_in < ctx->bio_in->bi_vcnt && |
417 | ctx->idx_out < ctx->bio_out->bi_vcnt) { | 412 | ctx->idx_out < ctx->bio_out->bi_vcnt) { |
418 | 413 | ||
419 | crypt_alloc_req(cc, ctx); | 414 | crypt_alloc_req(cc, ctx); |
420 | 415 | ||
416 | atomic_inc(&ctx->pending); | ||
417 | |||
421 | r = crypt_convert_block(cc, ctx, cc->req); | 418 | r = crypt_convert_block(cc, ctx, cc->req); |
422 | 419 | ||
423 | switch (r) { | 420 | switch (r) { |
421 | /* async */ | ||
424 | case -EBUSY: | 422 | case -EBUSY: |
425 | wait_for_completion(&ctx->restart); | 423 | wait_for_completion(&ctx->restart); |
426 | INIT_COMPLETION(ctx->restart); | 424 | INIT_COMPLETION(ctx->restart); |
427 | /* fall through*/ | 425 | /* fall through*/ |
428 | case -EINPROGRESS: | 426 | case -EINPROGRESS: |
429 | atomic_inc(&ctx->pending); | ||
430 | cc->req = NULL; | 427 | cc->req = NULL; |
431 | r = 0; | 428 | ctx->sector++; |
432 | /* fall through*/ | 429 | continue; |
430 | |||
431 | /* sync */ | ||
433 | case 0: | 432 | case 0: |
433 | atomic_dec(&ctx->pending); | ||
434 | ctx->sector++; | 434 | ctx->sector++; |
435 | continue; | 435 | continue; |
436 | } | ||
437 | 436 | ||
438 | break; | 437 | /* error */ |
438 | default: | ||
439 | atomic_dec(&ctx->pending); | ||
440 | return r; | ||
441 | } | ||
439 | } | 442 | } |
440 | 443 | ||
441 | /* | 444 | return 0; |
442 | * If there are pending crypto operation run async | ||
443 | * code. Otherwise process return code synchronously. | ||
444 | * The step of 2 ensures that async finish doesn't | ||
445 | * call crypto finish too early. | ||
446 | */ | ||
447 | if (atomic_sub_return(2, &ctx->pending)) | ||
448 | return -EINPROGRESS; | ||
449 | |||
450 | return r; | ||
451 | } | 445 | } |
452 | 446 | ||
453 | static void dm_crypt_bio_destructor(struct bio *bio) | 447 | static void dm_crypt_bio_destructor(struct bio *bio) |
@@ -624,8 +618,10 @@ static void kcryptd_io_read(struct dm_crypt_io *io) | |||
624 | static void kcryptd_io_write(struct dm_crypt_io *io) | 618 | static void kcryptd_io_write(struct dm_crypt_io *io) |
625 | { | 619 | { |
626 | struct bio *clone = io->ctx.bio_out; | 620 | struct bio *clone = io->ctx.bio_out; |
621 | struct crypt_config *cc = io->target->private; | ||
627 | 622 | ||
628 | generic_make_request(clone); | 623 | generic_make_request(clone); |
624 | wake_up(&cc->writeq); | ||
629 | } | 625 | } |
630 | 626 | ||
631 | static void kcryptd_io(struct work_struct *work) | 627 | static void kcryptd_io(struct work_struct *work) |
@@ -698,7 +694,8 @@ static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io) | |||
698 | 694 | ||
699 | r = crypt_convert(cc, &io->ctx); | 695 | r = crypt_convert(cc, &io->ctx); |
700 | 696 | ||
701 | if (r != -EINPROGRESS) { | 697 | if (atomic_dec_and_test(&io->ctx.pending)) { |
698 | /* processed, no running async crypto */ | ||
702 | kcryptd_crypt_write_io_submit(io, r, 0); | 699 | kcryptd_crypt_write_io_submit(io, r, 0); |
703 | if (unlikely(r < 0)) | 700 | if (unlikely(r < 0)) |
704 | return; | 701 | return; |
@@ -706,8 +703,12 @@ static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io) | |||
706 | atomic_inc(&io->pending); | 703 | atomic_inc(&io->pending); |
707 | 704 | ||
708 | /* out of memory -> run queues */ | 705 | /* out of memory -> run queues */ |
709 | if (unlikely(remaining)) | 706 | if (unlikely(remaining)) { |
707 | /* wait for async crypto then reinitialize pending */ | ||
708 | wait_event(cc->writeq, !atomic_read(&io->ctx.pending)); | ||
709 | atomic_set(&io->ctx.pending, 1); | ||
710 | congestion_wait(WRITE, HZ/100); | 710 | congestion_wait(WRITE, HZ/100); |
711 | } | ||
711 | } | 712 | } |
712 | } | 713 | } |
713 | 714 | ||
@@ -746,7 +747,7 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) | |||
746 | 747 | ||
747 | r = crypt_convert(cc, &io->ctx); | 748 | r = crypt_convert(cc, &io->ctx); |
748 | 749 | ||
749 | if (r != -EINPROGRESS) | 750 | if (atomic_dec_and_test(&io->ctx.pending)) |
750 | kcryptd_crypt_read_done(io, r); | 751 | kcryptd_crypt_read_done(io, r); |
751 | 752 | ||
752 | crypt_dec_pending(io); | 753 | crypt_dec_pending(io); |
@@ -1047,6 +1048,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1047 | goto bad_crypt_queue; | 1048 | goto bad_crypt_queue; |
1048 | } | 1049 | } |
1049 | 1050 | ||
1051 | init_waitqueue_head(&cc->writeq); | ||
1050 | ti->private = cc; | 1052 | ti->private = cc; |
1051 | return 0; | 1053 | return 0; |
1052 | 1054 | ||
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index b8e342fe7586..8f25f628ef16 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -114,7 +114,7 @@ static void dec_count(struct io *io, unsigned int region, int error) | |||
114 | wake_up_process(io->sleeper); | 114 | wake_up_process(io->sleeper); |
115 | 115 | ||
116 | else { | 116 | else { |
117 | int r = io->error; | 117 | unsigned long r = io->error; |
118 | io_notify_fn fn = io->callback; | 118 | io_notify_fn fn = io->callback; |
119 | void *context = io->context; | 119 | void *context = io->context; |
120 | 120 | ||
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 51605870f898..762cb086bb7f 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -753,7 +753,7 @@ out: | |||
753 | * are in the no-sync state. We have to recover these by | 753 | * are in the no-sync state. We have to recover these by |
754 | * recopying from the default mirror to all the others. | 754 | * recopying from the default mirror to all the others. |
755 | *---------------------------------------------------------------*/ | 755 | *---------------------------------------------------------------*/ |
756 | static void recovery_complete(int read_err, unsigned int write_err, | 756 | static void recovery_complete(int read_err, unsigned long write_err, |
757 | void *context) | 757 | void *context) |
758 | { | 758 | { |
759 | struct region *reg = (struct region *)context; | 759 | struct region *reg = (struct region *)context; |
@@ -767,7 +767,7 @@ static void recovery_complete(int read_err, unsigned int write_err, | |||
767 | } | 767 | } |
768 | 768 | ||
769 | if (write_err) { | 769 | if (write_err) { |
770 | DMERR_LIMIT("Write error during recovery (error = 0x%x)", | 770 | DMERR_LIMIT("Write error during recovery (error = 0x%lx)", |
771 | write_err); | 771 | write_err); |
772 | /* | 772 | /* |
773 | * Bits correspond to devices (excluding default mirror). | 773 | * Bits correspond to devices (excluding default mirror). |
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index ae24eab8cd81..4dc8a43c034b 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -804,7 +804,7 @@ static void commit_callback(void *context, int success) | |||
804 | * Called when the copy I/O has finished. kcopyd actually runs | 804 | * Called when the copy I/O has finished. kcopyd actually runs |
805 | * this code so don't block. | 805 | * this code so don't block. |
806 | */ | 806 | */ |
807 | static void copy_callback(int read_err, unsigned int write_err, void *context) | 807 | static void copy_callback(int read_err, unsigned long write_err, void *context) |
808 | { | 808 | { |
809 | struct dm_snap_pending_exception *pe = context; | 809 | struct dm_snap_pending_exception *pe = context; |
810 | struct dm_snapshot *s = pe->snap; | 810 | struct dm_snapshot *s = pe->snap; |
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index f3831f31223e..e76b52ade690 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c | |||
@@ -169,7 +169,7 @@ struct kcopyd_job { | |||
169 | * Error state of the job. | 169 | * Error state of the job. |
170 | */ | 170 | */ |
171 | int read_err; | 171 | int read_err; |
172 | unsigned int write_err; | 172 | unsigned long write_err; |
173 | 173 | ||
174 | /* | 174 | /* |
175 | * Either READ or WRITE | 175 | * Either READ or WRITE |
@@ -293,7 +293,7 @@ static int run_complete_job(struct kcopyd_job *job) | |||
293 | { | 293 | { |
294 | void *context = job->context; | 294 | void *context = job->context; |
295 | int read_err = job->read_err; | 295 | int read_err = job->read_err; |
296 | unsigned int write_err = job->write_err; | 296 | unsigned long write_err = job->write_err; |
297 | kcopyd_notify_fn fn = job->fn; | 297 | kcopyd_notify_fn fn = job->fn; |
298 | struct kcopyd_client *kc = job->kc; | 298 | struct kcopyd_client *kc = job->kc; |
299 | 299 | ||
@@ -396,7 +396,7 @@ static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) | |||
396 | if (r < 0) { | 396 | if (r < 0) { |
397 | /* error this rogue job */ | 397 | /* error this rogue job */ |
398 | if (job->rw == WRITE) | 398 | if (job->rw == WRITE) |
399 | job->write_err = (unsigned int) -1; | 399 | job->write_err = (unsigned long) -1L; |
400 | else | 400 | else |
401 | job->read_err = 1; | 401 | job->read_err = 1; |
402 | push(&_complete_jobs, job); | 402 | push(&_complete_jobs, job); |
@@ -448,8 +448,8 @@ static void dispatch_job(struct kcopyd_job *job) | |||
448 | } | 448 | } |
449 | 449 | ||
450 | #define SUB_JOB_SIZE 128 | 450 | #define SUB_JOB_SIZE 128 |
451 | static void segment_complete(int read_err, | 451 | static void segment_complete(int read_err, unsigned long write_err, |
452 | unsigned int write_err, void *context) | 452 | void *context) |
453 | { | 453 | { |
454 | /* FIXME: tidy this function */ | 454 | /* FIXME: tidy this function */ |
455 | sector_t progress = 0; | 455 | sector_t progress = 0; |
diff --git a/drivers/md/kcopyd.h b/drivers/md/kcopyd.h index 4621ea055c0e..4845f2a0c676 100644 --- a/drivers/md/kcopyd.h +++ b/drivers/md/kcopyd.h | |||
@@ -32,8 +32,8 @@ void kcopyd_client_destroy(struct kcopyd_client *kc); | |||
32 | * read_err is a boolean, | 32 | * read_err is a boolean, |
33 | * write_err is a bitset, with 1 bit for each destination region | 33 | * write_err is a bitset, with 1 bit for each destination region |
34 | */ | 34 | */ |
35 | typedef void (*kcopyd_notify_fn)(int read_err, | 35 | typedef void (*kcopyd_notify_fn)(int read_err, unsigned long write_err, |
36 | unsigned int write_err, void *context); | 36 | void *context); |
37 | 37 | ||
38 | int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, | 38 | int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, |
39 | unsigned int num_dests, struct io_region *dests, | 39 | unsigned int num_dests, struct io_region *dests, |
diff --git a/drivers/md/md.c b/drivers/md/md.c index ccbbf63727cc..61ccbd2683fa 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1864,17 +1864,6 @@ static struct rdev_sysfs_entry rdev_state = | |||
1864 | __ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store); | 1864 | __ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store); |
1865 | 1865 | ||
1866 | static ssize_t | 1866 | static ssize_t |
1867 | super_show(mdk_rdev_t *rdev, char *page) | ||
1868 | { | ||
1869 | if (rdev->sb_loaded && rdev->sb_size) { | ||
1870 | memcpy(page, page_address(rdev->sb_page), rdev->sb_size); | ||
1871 | return rdev->sb_size; | ||
1872 | } else | ||
1873 | return 0; | ||
1874 | } | ||
1875 | static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super); | ||
1876 | |||
1877 | static ssize_t | ||
1878 | errors_show(mdk_rdev_t *rdev, char *page) | 1867 | errors_show(mdk_rdev_t *rdev, char *page) |
1879 | { | 1868 | { |
1880 | return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors)); | 1869 | return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors)); |
@@ -2060,7 +2049,6 @@ __ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store); | |||
2060 | 2049 | ||
2061 | static struct attribute *rdev_default_attrs[] = { | 2050 | static struct attribute *rdev_default_attrs[] = { |
2062 | &rdev_state.attr, | 2051 | &rdev_state.attr, |
2063 | &rdev_super.attr, | ||
2064 | &rdev_errors.attr, | 2052 | &rdev_errors.attr, |
2065 | &rdev_slot.attr, | 2053 | &rdev_slot.attr, |
2066 | &rdev_offset.attr, | 2054 | &rdev_offset.attr, |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 2d6f1a51359c..c574cf5efb5c 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1143,7 +1143,7 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
1143 | rdev = conf->disks[i].rdev; | 1143 | rdev = conf->disks[i].rdev; |
1144 | printk(KERN_INFO "raid5:%s: read error corrected (%lu sectors at %llu on %s)\n", | 1144 | printk(KERN_INFO "raid5:%s: read error corrected (%lu sectors at %llu on %s)\n", |
1145 | mdname(conf->mddev), STRIPE_SECTORS, | 1145 | mdname(conf->mddev), STRIPE_SECTORS, |
1146 | (unsigned long long)sh->sector + rdev->data_offset, | 1146 | (unsigned long long)(sh->sector + rdev->data_offset), |
1147 | bdevname(rdev->bdev, b)); | 1147 | bdevname(rdev->bdev, b)); |
1148 | clear_bit(R5_ReadError, &sh->dev[i].flags); | 1148 | clear_bit(R5_ReadError, &sh->dev[i].flags); |
1149 | clear_bit(R5_ReWrite, &sh->dev[i].flags); | 1149 | clear_bit(R5_ReWrite, &sh->dev[i].flags); |
@@ -1160,13 +1160,13 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
1160 | if (conf->mddev->degraded) | 1160 | if (conf->mddev->degraded) |
1161 | printk(KERN_WARNING "raid5:%s: read error not correctable (sector %llu on %s).\n", | 1161 | printk(KERN_WARNING "raid5:%s: read error not correctable (sector %llu on %s).\n", |
1162 | mdname(conf->mddev), | 1162 | mdname(conf->mddev), |
1163 | (unsigned long long)sh->sector + rdev->data_offset, | 1163 | (unsigned long long)(sh->sector + rdev->data_offset), |
1164 | bdn); | 1164 | bdn); |
1165 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) | 1165 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) |
1166 | /* Oh, no!!! */ | 1166 | /* Oh, no!!! */ |
1167 | printk(KERN_WARNING "raid5:%s: read error NOT corrected!! (sector %llu on %s).\n", | 1167 | printk(KERN_WARNING "raid5:%s: read error NOT corrected!! (sector %llu on %s).\n", |
1168 | mdname(conf->mddev), | 1168 | mdname(conf->mddev), |
1169 | (unsigned long long)sh->sector + rdev->data_offset, | 1169 | (unsigned long long)(sh->sector + rdev->data_offset), |
1170 | bdn); | 1170 | bdn); |
1171 | else if (atomic_read(&rdev->read_errors) | 1171 | else if (atomic_read(&rdev->read_errors) |
1172 | > conf->max_nr_stripes) | 1172 | > conf->max_nr_stripes) |