mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	Two bugfixes for md
both tagged for -stable -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIVAwUAUvxBNjnsnt1WYoG5AQLymhAAnKznI2YhFVqK21mpo1l2JDSkwxqIBvBZ hcW24zF6dNU4cJFmRQqOeL2AkzHWSqX4/J/DGXvI9wFll1CkdNs+UVQJ12Pod3gK gTDmqRCe/x+bQxrOR5VfyKv0slia12vn9mqfDd2mX41wcr7ceHsdHbemPhgIcUCC WLERQi9Yn/Eb2+rltTzZ3XaHwIlIozqZ0yRZ6wH45iyuk+uiholEJjJp8LOWpzTe rKE4s5qd1NAAJsrMHZ11mZWq/4VtgYJ3AcWVXVWqBPxmlI0FnBPU/KVpJkAcrVjB N6tqmR1/nHcrGlaOgWSS6UfNGVMe3L2HJpaIdjTM65Tdb+WFpEPevTy9qYsLC3Ic zV/KmErUtSFMJKYBr9YyRnSpXtnSDo8BeRsWJm9ZaA5UV9yUVBNwWDFNFP/Bkqze v4wLMRj54U5fjRZBq/PaFbk/A2nDCkGHC4uZCgJ+Mwhoo6rxpho/oKBjBBlmpw3q 4Q0yWgZ8F/ZWFUrGzi1TY3tdYrl3yCOpZ3l5aRTtTqlU3aVShIIiKCKDvs2v8l6h C5igUbnW5BtsMMCOwdULc/lHgN3vMbJEA+7YdmeouDEY5QAk0O6nxan3y+cbtC5u F+++tkWzSQZJRGhdAxdAXsABYfHiR7Wnft96+iMpnQYbm35CdYYwlOhhl0iI/+Ec FcpDXOz9faA= =J3I5 -----END PGP SIGNATURE----- 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.
This commit is contained in:
		
						commit
						bd3813d52d
					
				
					 2 changed files with 55 additions and 50 deletions
				
			
		|  | @ -1953,11 +1953,15 @@ static int process_checks(struct r1bio *r1_bio) | |||
| 	for (i = 0; i < conf->raid_disks * 2; i++) { | ||||
| 		int j; | ||||
| 		int size; | ||||
| 		int uptodate; | ||||
| 		struct bio *b = r1_bio->bios[i]; | ||||
| 		if (b->bi_end_io != end_sync_read) | ||||
| 			continue; | ||||
| 		/* fixup the bio for reuse */ | ||||
| 		/* fixup the bio for reuse, but preserve BIO_UPTODATE */ | ||||
| 		uptodate = test_bit(BIO_UPTODATE, &b->bi_flags); | ||||
| 		bio_reset(b); | ||||
| 		if (!uptodate) | ||||
| 			clear_bit(BIO_UPTODATE, &b->bi_flags); | ||||
| 		b->bi_vcnt = vcnt; | ||||
| 		b->bi_iter.bi_size = r1_bio->sectors << 9; | ||||
| 		b->bi_iter.bi_sector = r1_bio->sector + | ||||
|  | @ -1990,11 +1994,14 @@ static int process_checks(struct r1bio *r1_bio) | |||
| 		int j; | ||||
| 		struct bio *pbio = r1_bio->bios[primary]; | ||||
| 		struct bio *sbio = r1_bio->bios[i]; | ||||
| 		int uptodate = test_bit(BIO_UPTODATE, &sbio->bi_flags); | ||||
| 
 | ||||
| 		if (sbio->bi_end_io != end_sync_read) | ||||
| 			continue; | ||||
| 		/* Now we can 'fixup' the BIO_UPTODATE flag */ | ||||
| 		set_bit(BIO_UPTODATE, &sbio->bi_flags); | ||||
| 
 | ||||
| 		if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) { | ||||
| 		if (uptodate) { | ||||
| 			for (j = vcnt; j-- ; ) { | ||||
| 				struct page *p, *s; | ||||
| 				p = pbio->bi_io_vec[j].bv_page; | ||||
|  | @ -2009,7 +2016,7 @@ static int process_checks(struct r1bio *r1_bio) | |||
| 		if (j >= 0) | ||||
| 			atomic64_add(r1_bio->sectors, &mddev->resync_mismatches); | ||||
| 		if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery) | ||||
| 			      && test_bit(BIO_UPTODATE, &sbio->bi_flags))) { | ||||
| 			      && uptodate)) { | ||||
| 			/* No need to write to this device. */ | ||||
| 			sbio->bi_end_io = NULL; | ||||
| 			rdev_dec_pending(conf->mirrors[i].rdev, mddev); | ||||
|  |  | |||
|  | @ -5514,23 +5514,43 @@ raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks) | |||
| 	return sectors * (raid_disks - conf->max_degraded); | ||||
| } | ||||
| 
 | ||||
| static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) | ||||
| { | ||||
| 	safe_put_page(percpu->spare_page); | ||||
| 	kfree(percpu->scribble); | ||||
| 	percpu->spare_page = NULL; | ||||
| 	percpu->scribble = NULL; | ||||
| } | ||||
| 
 | ||||
| static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) | ||||
| { | ||||
| 	if (conf->level == 6 && !percpu->spare_page) | ||||
| 		percpu->spare_page = alloc_page(GFP_KERNEL); | ||||
| 	if (!percpu->scribble) | ||||
| 		percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); | ||||
| 
 | ||||
| 	if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { | ||||
| 		free_scratch_buffer(conf, percpu); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void raid5_free_percpu(struct r5conf *conf) | ||||
| { | ||||
| 	struct raid5_percpu *percpu; | ||||
| 	unsigned long cpu; | ||||
| 
 | ||||
| 	if (!conf->percpu) | ||||
| 		return; | ||||
| 
 | ||||
| 	get_online_cpus(); | ||||
| 	for_each_possible_cpu(cpu) { | ||||
| 		percpu = per_cpu_ptr(conf->percpu, cpu); | ||||
| 		safe_put_page(percpu->spare_page); | ||||
| 		kfree(percpu->scribble); | ||||
| 	} | ||||
| #ifdef CONFIG_HOTPLUG_CPU | ||||
| 	unregister_cpu_notifier(&conf->cpu_notify); | ||||
| #endif | ||||
| 
 | ||||
| 	get_online_cpus(); | ||||
| 	for_each_possible_cpu(cpu) | ||||
| 		free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); | ||||
| 	put_online_cpus(); | ||||
| 
 | ||||
| 	free_percpu(conf->percpu); | ||||
|  | @ -5557,15 +5577,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, | |||
| 	switch (action) { | ||||
| 	case CPU_UP_PREPARE: | ||||
| 	case CPU_UP_PREPARE_FROZEN: | ||||
| 		if (conf->level == 6 && !percpu->spare_page) | ||||
| 			percpu->spare_page = alloc_page(GFP_KERNEL); | ||||
| 		if (!percpu->scribble) | ||||
| 			percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); | ||||
| 
 | ||||
| 		if (!percpu->scribble || | ||||
| 		    (conf->level == 6 && !percpu->spare_page)) { | ||||
| 			safe_put_page(percpu->spare_page); | ||||
| 			kfree(percpu->scribble); | ||||
| 		if (alloc_scratch_buffer(conf, percpu)) { | ||||
| 			pr_err("%s: failed memory allocation for cpu%ld\n", | ||||
| 			       __func__, cpu); | ||||
| 			return notifier_from_errno(-ENOMEM); | ||||
|  | @ -5573,10 +5585,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, | |||
| 		break; | ||||
| 	case CPU_DEAD: | ||||
| 	case CPU_DEAD_FROZEN: | ||||
| 		safe_put_page(percpu->spare_page); | ||||
| 		kfree(percpu->scribble); | ||||
| 		percpu->spare_page = NULL; | ||||
| 		percpu->scribble = NULL; | ||||
| 		free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
|  | @ -5588,40 +5597,29 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, | |||
| static int raid5_alloc_percpu(struct r5conf *conf) | ||||
| { | ||||
| 	unsigned long cpu; | ||||
| 	struct page *spare_page; | ||||
| 	struct raid5_percpu __percpu *allcpus; | ||||
| 	void *scribble; | ||||
| 	int err; | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	allcpus = alloc_percpu(struct raid5_percpu); | ||||
| 	if (!allcpus) | ||||
| 	conf->percpu = alloc_percpu(struct raid5_percpu); | ||||
| 	if (!conf->percpu) | ||||
| 		return -ENOMEM; | ||||
| 	conf->percpu = allcpus; | ||||
| 
 | ||||
| 	get_online_cpus(); | ||||
| 	err = 0; | ||||
| 	for_each_present_cpu(cpu) { | ||||
| 		if (conf->level == 6) { | ||||
| 			spare_page = alloc_page(GFP_KERNEL); | ||||
| 			if (!spare_page) { | ||||
| 				err = -ENOMEM; | ||||
| 				break; | ||||
| 			} | ||||
| 			per_cpu_ptr(conf->percpu, cpu)->spare_page = spare_page; | ||||
| 		} | ||||
| 		scribble = kmalloc(conf->scribble_len, GFP_KERNEL); | ||||
| 		if (!scribble) { | ||||
| 			err = -ENOMEM; | ||||
| 			break; | ||||
| 		} | ||||
| 		per_cpu_ptr(conf->percpu, cpu)->scribble = scribble; | ||||
| 	} | ||||
| #ifdef CONFIG_HOTPLUG_CPU | ||||
| 	conf->cpu_notify.notifier_call = raid456_cpu_notify; | ||||
| 	conf->cpu_notify.priority = 0; | ||||
| 	if (err == 0) | ||||
| 		err = register_cpu_notifier(&conf->cpu_notify); | ||||
| 	err = register_cpu_notifier(&conf->cpu_notify); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| #endif | ||||
| 
 | ||||
| 	get_online_cpus(); | ||||
| 	for_each_present_cpu(cpu) { | ||||
| 		err = alloc_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); | ||||
| 		if (err) { | ||||
| 			pr_err("%s: failed memory allocation for cpu%ld\n", | ||||
| 			       __func__, cpu); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	put_online_cpus(); | ||||
| 
 | ||||
| 	return err; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Linus Torvalds
						Linus Torvalds