diff options
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/bcache/request.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-snap-persistent.c | 18 | ||||
| -rw-r--r-- | drivers/md/md.c | 5 | ||||
| -rw-r--r-- | drivers/md/raid1.c | 1 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 1 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 20 |
6 files changed, 38 insertions, 9 deletions
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index b6a74bcbb08f..2a7f0dd6abab 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
| @@ -1000,7 +1000,7 @@ static void request_write(struct cached_dev *dc, struct search *s) | |||
| 1000 | 1000 | ||
| 1001 | if (bio->bi_rw & REQ_FLUSH) { | 1001 | if (bio->bi_rw & REQ_FLUSH) { |
| 1002 | /* Also need to send a flush to the backing device */ | 1002 | /* Also need to send a flush to the backing device */ |
| 1003 | struct bio *flush = bio_alloc_bioset(0, GFP_NOIO, | 1003 | struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0, |
| 1004 | dc->disk.bio_split); | 1004 | dc->disk.bio_split); |
| 1005 | 1005 | ||
| 1006 | flush->bi_rw = WRITE_FLUSH; | 1006 | flush->bi_rw = WRITE_FLUSH; |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 4caa8e6d59d7..2d2b1b7588d7 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
| @@ -269,6 +269,14 @@ static chunk_t area_location(struct pstore *ps, chunk_t area) | |||
| 269 | return NUM_SNAPSHOT_HDR_CHUNKS + ((ps->exceptions_per_area + 1) * area); | 269 | return NUM_SNAPSHOT_HDR_CHUNKS + ((ps->exceptions_per_area + 1) * area); |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | static void skip_metadata(struct pstore *ps) | ||
| 273 | { | ||
| 274 | uint32_t stride = ps->exceptions_per_area + 1; | ||
| 275 | chunk_t next_free = ps->next_free; | ||
| 276 | if (sector_div(next_free, stride) == NUM_SNAPSHOT_HDR_CHUNKS) | ||
| 277 | ps->next_free++; | ||
| 278 | } | ||
| 279 | |||
| 272 | /* | 280 | /* |
| 273 | * Read or write a metadata area. Remembering to skip the first | 281 | * Read or write a metadata area. Remembering to skip the first |
| 274 | * chunk which holds the header. | 282 | * chunk which holds the header. |
| @@ -502,6 +510,8 @@ static int read_exceptions(struct pstore *ps, | |||
| 502 | 510 | ||
| 503 | ps->current_area--; | 511 | ps->current_area--; |
| 504 | 512 | ||
| 513 | skip_metadata(ps); | ||
| 514 | |||
| 505 | return 0; | 515 | return 0; |
| 506 | } | 516 | } |
| 507 | 517 | ||
| @@ -616,8 +626,6 @@ static int persistent_prepare_exception(struct dm_exception_store *store, | |||
| 616 | struct dm_exception *e) | 626 | struct dm_exception *e) |
| 617 | { | 627 | { |
| 618 | struct pstore *ps = get_info(store); | 628 | struct pstore *ps = get_info(store); |
| 619 | uint32_t stride; | ||
| 620 | chunk_t next_free; | ||
| 621 | sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); | 629 | sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); |
| 622 | 630 | ||
| 623 | /* Is there enough room ? */ | 631 | /* Is there enough room ? */ |
| @@ -630,10 +638,8 @@ static int persistent_prepare_exception(struct dm_exception_store *store, | |||
| 630 | * Move onto the next free pending, making sure to take | 638 | * Move onto the next free pending, making sure to take |
| 631 | * into account the location of the metadata chunks. | 639 | * into account the location of the metadata chunks. |
| 632 | */ | 640 | */ |
| 633 | stride = (ps->exceptions_per_area + 1); | 641 | ps->next_free++; |
| 634 | next_free = ++ps->next_free; | 642 | skip_metadata(ps); |
| 635 | if (sector_div(next_free, stride) == 1) | ||
| 636 | ps->next_free++; | ||
| 637 | 643 | ||
| 638 | atomic_inc(&ps->pending_count); | 644 | atomic_inc(&ps->pending_count); |
| 639 | return 0; | 645 | return 0; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index adf4d7e1d5e1..561a65f82e26 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -8111,6 +8111,7 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, | |||
| 8111 | u64 *p; | 8111 | u64 *p; |
| 8112 | int lo, hi; | 8112 | int lo, hi; |
| 8113 | int rv = 1; | 8113 | int rv = 1; |
| 8114 | unsigned long flags; | ||
| 8114 | 8115 | ||
| 8115 | if (bb->shift < 0) | 8116 | if (bb->shift < 0) |
| 8116 | /* badblocks are disabled */ | 8117 | /* badblocks are disabled */ |
| @@ -8125,7 +8126,7 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, | |||
| 8125 | sectors = next - s; | 8126 | sectors = next - s; |
| 8126 | } | 8127 | } |
| 8127 | 8128 | ||
| 8128 | write_seqlock_irq(&bb->lock); | 8129 | write_seqlock_irqsave(&bb->lock, flags); |
| 8129 | 8130 | ||
| 8130 | p = bb->page; | 8131 | p = bb->page; |
| 8131 | lo = 0; | 8132 | lo = 0; |
| @@ -8241,7 +8242,7 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, | |||
| 8241 | bb->changed = 1; | 8242 | bb->changed = 1; |
| 8242 | if (!acknowledged) | 8243 | if (!acknowledged) |
| 8243 | bb->unacked_exist = 1; | 8244 | bb->unacked_exist = 1; |
| 8244 | write_sequnlock_irq(&bb->lock); | 8245 | write_sequnlock_irqrestore(&bb->lock, flags); |
| 8245 | 8246 | ||
| 8246 | return rv; | 8247 | return rv; |
| 8247 | } | 8248 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d60412c7f995..aacf6bf352d8 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -1479,6 +1479,7 @@ static int raid1_spare_active(struct mddev *mddev) | |||
| 1479 | } | 1479 | } |
| 1480 | } | 1480 | } |
| 1481 | if (rdev | 1481 | if (rdev |
| 1482 | && rdev->recovery_offset == MaxSector | ||
| 1482 | && !test_bit(Faulty, &rdev->flags) | 1483 | && !test_bit(Faulty, &rdev->flags) |
| 1483 | && !test_and_set_bit(In_sync, &rdev->flags)) { | 1484 | && !test_and_set_bit(In_sync, &rdev->flags)) { |
| 1484 | count++; | 1485 | count++; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index df7b0a06b0ea..73dc8a377522 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -1782,6 +1782,7 @@ static int raid10_spare_active(struct mddev *mddev) | |||
| 1782 | } | 1782 | } |
| 1783 | sysfs_notify_dirent_safe(tmp->replacement->sysfs_state); | 1783 | sysfs_notify_dirent_safe(tmp->replacement->sysfs_state); |
| 1784 | } else if (tmp->rdev | 1784 | } else if (tmp->rdev |
| 1785 | && tmp->rdev->recovery_offset == MaxSector | ||
| 1785 | && !test_bit(Faulty, &tmp->rdev->flags) | 1786 | && !test_bit(Faulty, &tmp->rdev->flags) |
| 1786 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { | 1787 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { |
| 1787 | count++; | 1788 | count++; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7ff4f252ca1a..f8b906843926 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -778,6 +778,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) | |||
| 778 | bi->bi_io_vec[0].bv_len = STRIPE_SIZE; | 778 | bi->bi_io_vec[0].bv_len = STRIPE_SIZE; |
| 779 | bi->bi_io_vec[0].bv_offset = 0; | 779 | bi->bi_io_vec[0].bv_offset = 0; |
| 780 | bi->bi_size = STRIPE_SIZE; | 780 | bi->bi_size = STRIPE_SIZE; |
| 781 | /* | ||
| 782 | * If this is discard request, set bi_vcnt 0. We don't | ||
| 783 | * want to confuse SCSI because SCSI will replace payload | ||
| 784 | */ | ||
| 785 | if (rw & REQ_DISCARD) | ||
| 786 | bi->bi_vcnt = 0; | ||
| 781 | if (rrdev) | 787 | if (rrdev) |
| 782 | set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); | 788 | set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); |
| 783 | 789 | ||
| @@ -816,6 +822,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) | |||
| 816 | rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; | 822 | rbi->bi_io_vec[0].bv_len = STRIPE_SIZE; |
| 817 | rbi->bi_io_vec[0].bv_offset = 0; | 823 | rbi->bi_io_vec[0].bv_offset = 0; |
| 818 | rbi->bi_size = STRIPE_SIZE; | 824 | rbi->bi_size = STRIPE_SIZE; |
| 825 | /* | ||
| 826 | * If this is discard request, set bi_vcnt 0. We don't | ||
| 827 | * want to confuse SCSI because SCSI will replace payload | ||
| 828 | */ | ||
| 829 | if (rw & REQ_DISCARD) | ||
| 830 | rbi->bi_vcnt = 0; | ||
| 819 | if (conf->mddev->gendisk) | 831 | if (conf->mddev->gendisk) |
| 820 | trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), | 832 | trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), |
| 821 | rbi, disk_devt(conf->mddev->gendisk), | 833 | rbi, disk_devt(conf->mddev->gendisk), |
| @@ -2910,6 +2922,14 @@ static void handle_stripe_clean_event(struct r5conf *conf, | |||
| 2910 | } | 2922 | } |
| 2911 | /* now that discard is done we can proceed with any sync */ | 2923 | /* now that discard is done we can proceed with any sync */ |
| 2912 | clear_bit(STRIPE_DISCARD, &sh->state); | 2924 | clear_bit(STRIPE_DISCARD, &sh->state); |
| 2925 | /* | ||
| 2926 | * SCSI discard will change some bio fields and the stripe has | ||
| 2927 | * no updated data, so remove it from hash list and the stripe | ||
| 2928 | * will be reinitialized | ||
| 2929 | */ | ||
| 2930 | spin_lock_irq(&conf->device_lock); | ||
| 2931 | remove_hash(sh); | ||
| 2932 | spin_unlock_irq(&conf->device_lock); | ||
| 2913 | if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) | 2933 | if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) |
| 2914 | set_bit(STRIPE_HANDLE, &sh->state); | 2934 | set_bit(STRIPE_HANDLE, &sh->state); |
| 2915 | 2935 | ||
