Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'md/3.14-fixes' of git://neil.brown.name/md

Pull md fixes from Neil Brown:
"Two bugfixes for md

both tagged for -stable"

* tag 'md/3.14-fixes' of git://neil.brown.name/md:
md/raid5: Fix CPU hotplug callback registration
md/raid1: restore ability for check and repair to fix read errors.

+55 -50
+10 -3
drivers/md/raid1.c
··· 1953 1953 for (i = 0; i < conf->raid_disks * 2; i++) { 1954 1954 int j; 1955 1955 int size; 1956 + int uptodate; 1956 1957 struct bio *b = r1_bio->bios[i]; 1957 1958 if (b->bi_end_io != end_sync_read) 1958 1959 continue; 1959 - /* fixup the bio for reuse */ 1960 + /* fixup the bio for reuse, but preserve BIO_UPTODATE */ 1961 + uptodate = test_bit(BIO_UPTODATE, &b->bi_flags); 1960 1962 bio_reset(b); 1963 + if (!uptodate) 1964 + clear_bit(BIO_UPTODATE, &b->bi_flags); 1961 1965 b->bi_vcnt = vcnt; 1962 1966 b->bi_iter.bi_size = r1_bio->sectors << 9; 1963 1967 b->bi_iter.bi_sector = r1_bio->sector + ··· 1994 1990 int j; 1995 1991 struct bio *pbio = r1_bio->bios[primary]; 1996 1992 struct bio *sbio = r1_bio->bios[i]; 1993 + int uptodate = test_bit(BIO_UPTODATE, &sbio->bi_flags); 1997 1994 1998 1995 if (sbio->bi_end_io != end_sync_read) 1999 1996 continue; 1997 + /* Now we can 'fixup' the BIO_UPTODATE flag */ 1998 + set_bit(BIO_UPTODATE, &sbio->bi_flags); 2000 1999 2001 - if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) { 2000 + if (uptodate) { 2002 2001 for (j = vcnt; j-- ; ) { 2003 2002 struct page *p, *s; 2004 2003 p = pbio->bi_io_vec[j].bv_page; ··· 2016 2009 if (j >= 0) 2017 2010 atomic64_add(r1_bio->sectors, &mddev->resync_mismatches); 2018 2011 if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery) 2019 - && test_bit(BIO_UPTODATE, &sbio->bi_flags))) { 2012 + && uptodate)) { 2020 2013 /* No need to write to this device. */ 2021 2014 sbio->bi_end_io = NULL; 2022 2015 rdev_dec_pending(conf->mirrors[i].rdev, mddev);
+45 -47
drivers/md/raid5.c
··· 5514 5514 return sectors * (raid_disks - conf->max_degraded); 5515 5515 } 5516 5516 5517 + static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) 5518 + { 5519 + safe_put_page(percpu->spare_page); 5520 + kfree(percpu->scribble); 5521 + percpu->spare_page = NULL; 5522 + percpu->scribble = NULL; 5523 + } 5524 + 5525 + static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) 5526 + { 5527 + if (conf->level == 6 && !percpu->spare_page) 5528 + percpu->spare_page = alloc_page(GFP_KERNEL); 5529 + if (!percpu->scribble) 5530 + percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); 5531 + 5532 + if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { 5533 + free_scratch_buffer(conf, percpu); 5534 + return -ENOMEM; 5535 + } 5536 + 5537 + return 0; 5538 + } 5539 + 5517 5540 static void raid5_free_percpu(struct r5conf *conf) 5518 5541 { 5519 - struct raid5_percpu *percpu; 5520 5542 unsigned long cpu; 5521 5543 5522 5544 if (!conf->percpu) 5523 5545 return; 5524 5546 5525 - get_online_cpus(); 5526 - for_each_possible_cpu(cpu) { 5527 - percpu = per_cpu_ptr(conf->percpu, cpu); 5528 - safe_put_page(percpu->spare_page); 5529 - kfree(percpu->scribble); 5530 - } 5531 5547 #ifdef CONFIG_HOTPLUG_CPU 5532 5548 unregister_cpu_notifier(&conf->cpu_notify); 5533 5549 #endif 5550 + 5551 + get_online_cpus(); 5552 + for_each_possible_cpu(cpu) 5553 + free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); 5534 5554 put_online_cpus(); 5535 5555 5536 5556 free_percpu(conf->percpu); ··· 5577 5557 switch (action) { 5578 5558 case CPU_UP_PREPARE: 5579 5559 case CPU_UP_PREPARE_FROZEN: 5580 - if (conf->level == 6 && !percpu->spare_page) 5581 - percpu->spare_page = alloc_page(GFP_KERNEL); 5582 - if (!percpu->scribble) 5583 - percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); 5584 - 5585 - if (!percpu->scribble || 5586 - (conf->level == 6 && !percpu->spare_page)) { 5587 - safe_put_page(percpu->spare_page); 5588 - kfree(percpu->scribble); 5560 + if (alloc_scratch_buffer(conf, percpu)) { 5589 5561 pr_err("%s: failed memory allocation for cpu%ld\n", 5590 5562 __func__, cpu); 5591 5563 return notifier_from_errno(-ENOMEM); ··· 5585 5573 break; 5586 5574 case CPU_DEAD: 5587 5575 case CPU_DEAD_FROZEN: 5588 - safe_put_page(percpu->spare_page); 5589 - kfree(percpu->scribble); 5590 - percpu->spare_page = NULL; 5591 - percpu->scribble = NULL; 5576 + free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); 5592 5577 break; 5593 5578 default: 5594 5579 break; ··· 5597 5588 static int raid5_alloc_percpu(struct r5conf *conf) 5598 5589 { 5599 5590 unsigned long cpu; 5600 - struct page *spare_page; 5601 - struct raid5_percpu __percpu *allcpus; 5602 - void *scribble; 5603 - int err; 5591 + int err = 0; 5604 5592 5605 - allcpus = alloc_percpu(struct raid5_percpu); 5606 - if (!allcpus) 5593 + conf->percpu = alloc_percpu(struct raid5_percpu); 5594 + if (!conf->percpu) 5607 5595 return -ENOMEM; 5608 - conf->percpu = allcpus; 5609 5596 5610 - get_online_cpus(); 5611 - err = 0; 5612 - for_each_present_cpu(cpu) { 5613 - if (conf->level == 6) { 5614 - spare_page = alloc_page(GFP_KERNEL); 5615 - if (!spare_page) { 5616 - err = -ENOMEM; 5617 - break; 5618 - } 5619 - per_cpu_ptr(conf->percpu, cpu)->spare_page = spare_page; 5620 - } 5621 - scribble = kmalloc(conf->scribble_len, GFP_KERNEL); 5622 - if (!scribble) { 5623 - err = -ENOMEM; 5624 - break; 5625 - } 5626 - per_cpu_ptr(conf->percpu, cpu)->scribble = scribble; 5627 - } 5628 5597 #ifdef CONFIG_HOTPLUG_CPU 5629 5598 conf->cpu_notify.notifier_call = raid456_cpu_notify; 5630 5599 conf->cpu_notify.priority = 0; 5631 - if (err == 0) 5632 - err = register_cpu_notifier(&conf->cpu_notify); 5600 + err = register_cpu_notifier(&conf->cpu_notify); 5601 + if (err) 5602 + return err; 5633 5603 #endif 5604 + 5605 + get_online_cpus(); 5606 + for_each_present_cpu(cpu) { 5607 + err = alloc_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); 5608 + if (err) { 5609 + pr_err("%s: failed memory allocation for cpu%ld\n", 5610 + __func__, cpu); 5611 + break; 5612 + } 5613 + } 5634 5614 put_online_cpus(); 5635 5615 5636 5616 return err;