aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-crypt.c58
-rw-r--r--drivers/md/dm-io.c2
-rw-r--r--drivers/md/dm-raid1.c4
-rw-r--r--drivers/md/dm-snap.c2
-rw-r--r--drivers/md/kcopyd.c10
-rw-r--r--drivers/md/kcopyd.h4
-rw-r--r--drivers/md/raid5.c51
7 files changed, 70 insertions, 61 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
344static int crypt_convert_block(struct crypt_config *cc, 339static int crypt_convert_block(struct crypt_config *cc,
@@ -411,43 +406,42 @@ static void crypt_alloc_req(struct crypt_config *cc,
411static int crypt_convert(struct crypt_config *cc, 406static 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
453static void dm_crypt_bio_destructor(struct bio *bio) 447static void dm_crypt_bio_destructor(struct bio *bio)
@@ -624,8 +618,10 @@ static void kcryptd_io_read(struct dm_crypt_io *io)
624static void kcryptd_io_write(struct dm_crypt_io *io) 618static 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
631static void kcryptd_io(struct work_struct *work) 627static 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 *---------------------------------------------------------------*/
756static void recovery_complete(int read_err, unsigned int write_err, 756static 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 */
807static void copy_callback(int read_err, unsigned int write_err, void *context) 807static 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
451static void segment_complete(int read_err, 451static 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 */
35typedef void (*kcopyd_notify_fn)(int read_err, 35typedef void (*kcopyd_notify_fn)(int read_err, unsigned long write_err,
36 unsigned int write_err, void *context); 36 void *context);
37 37
38int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from, 38int 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/raid5.c b/drivers/md/raid5.c
index c574cf5efb5c..b162b839a662 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2348,25 +2348,15 @@ static void handle_issuing_new_write_requests6(raid5_conf_t *conf,
2348static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, 2348static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
2349 struct stripe_head_state *s, int disks) 2349 struct stripe_head_state *s, int disks)
2350{ 2350{
2351 int canceled_check = 0;
2352
2351 set_bit(STRIPE_HANDLE, &sh->state); 2353 set_bit(STRIPE_HANDLE, &sh->state);
2352 /* Take one of the following actions:
2353 * 1/ start a check parity operation if (uptodate == disks)
2354 * 2/ finish a check parity operation and act on the result
2355 * 3/ skip to the writeback section if we previously
2356 * initiated a recovery operation
2357 */
2358 if (s->failed == 0 &&
2359 !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
2360 if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) {
2361 BUG_ON(s->uptodate != disks);
2362 clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
2363 sh->ops.count++;
2364 s->uptodate--;
2365 } else if (
2366 test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
2367 clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
2368 clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
2369 2354
2355 /* complete a check operation */
2356 if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
2357 clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
2358 clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
2359 if (s->failed == 0) {
2370 if (sh->ops.zero_sum_result == 0) 2360 if (sh->ops.zero_sum_result == 0)
2371 /* parity is correct (on disc, 2361 /* parity is correct (on disc,
2372 * not in buffer any more) 2362 * not in buffer any more)
@@ -2391,7 +2381,8 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
2391 s->uptodate++; 2381 s->uptodate++;
2392 } 2382 }
2393 } 2383 }
2394 } 2384 } else
2385 canceled_check = 1; /* STRIPE_INSYNC is not set */
2395 } 2386 }
2396 2387
2397 /* check if we can clear a parity disk reconstruct */ 2388 /* check if we can clear a parity disk reconstruct */
@@ -2404,12 +2395,28 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
2404 clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); 2395 clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
2405 } 2396 }
2406 2397
2398 /* start a new check operation if there are no failures, the stripe is
2399 * not insync, and a repair is not in flight
2400 */
2401 if (s->failed == 0 &&
2402 !test_bit(STRIPE_INSYNC, &sh->state) &&
2403 !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
2404 if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) {
2405 BUG_ON(s->uptodate != disks);
2406 clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
2407 sh->ops.count++;
2408 s->uptodate--;
2409 }
2410 }
2411
2407 /* Wait for check parity and compute block operations to complete 2412 /* Wait for check parity and compute block operations to complete
2408 * before write-back 2413 * before write-back. If a failure occurred while the check operation
2414 * was in flight we need to cycle this stripe through handle_stripe
2415 * since the parity block may not be uptodate
2409 */ 2416 */
2410 if (!test_bit(STRIPE_INSYNC, &sh->state) && 2417 if (!canceled_check && !test_bit(STRIPE_INSYNC, &sh->state) &&
2411 !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) && 2418 !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) &&
2412 !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) { 2419 !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) {
2413 struct r5dev *dev; 2420 struct r5dev *dev;
2414 /* either failed parity check, or recovery is happening */ 2421 /* either failed parity check, or recovery is happening */
2415 if (s->failed == 0) 2422 if (s->failed == 0)