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/4.0-fixes' of git://neil.brown.name/md

Pull md fixes from Neil Brown:
"Three md fixes:

- fix a read-balance problem that was reported 2 years ago, but that
I never noticed the report :-(

- fix for rare RAID6 problem causing incorrect bitmap updates when
two devices fail.

- add __ATTR_PREALLOC annotation now that it is possible"

* tag 'md/4.0-fixes' of git://neil.brown.name/md:
md: mark some attributes as pre-alloc
raid5: check faulty flag for array status during recovery.
md/raid1: fix read balance when a drive is write-mostly.

+20 -12
+8 -6
drivers/md/md.c
··· 2555 2555 return err ? err : len; 2556 2556 } 2557 2557 static struct rdev_sysfs_entry rdev_state = 2558 - __ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store); 2558 + __ATTR_PREALLOC(state, S_IRUGO|S_IWUSR, state_show, state_store); 2559 2559 2560 2560 static ssize_t 2561 2561 errors_show(struct md_rdev *rdev, char *page) ··· 3638 3638 return err ?: len; 3639 3639 } 3640 3640 static struct md_sysfs_entry md_resync_start = 3641 - __ATTR(resync_start, S_IRUGO|S_IWUSR, resync_start_show, resync_start_store); 3641 + __ATTR_PREALLOC(resync_start, S_IRUGO|S_IWUSR, 3642 + resync_start_show, resync_start_store); 3642 3643 3643 3644 /* 3644 3645 * The array state can be: ··· 3852 3851 return err ?: len; 3853 3852 } 3854 3853 static struct md_sysfs_entry md_array_state = 3855 - __ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store); 3854 + __ATTR_PREALLOC(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store); 3856 3855 3857 3856 static ssize_t 3858 3857 max_corrected_read_errors_show(struct mddev *mddev, char *page) { ··· 4102 4101 } 4103 4102 4104 4103 static struct md_sysfs_entry md_metadata = 4105 - __ATTR(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store); 4104 + __ATTR_PREALLOC(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store); 4106 4105 4107 4106 static ssize_t 4108 4107 action_show(struct mddev *mddev, char *page) ··· 4190 4189 } 4191 4190 4192 4191 static struct md_sysfs_entry md_scan_mode = 4193 - __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store); 4192 + __ATTR_PREALLOC(sync_action, S_IRUGO|S_IWUSR, action_show, action_store); 4194 4193 4195 4194 static ssize_t 4196 4195 last_sync_action_show(struct mddev *mddev, char *page) ··· 4336 4335 return sprintf(page, "%llu / %llu\n", resync, max_sectors); 4337 4336 } 4338 4337 4339 - static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); 4338 + static struct md_sysfs_entry md_sync_completed = 4339 + __ATTR_PREALLOC(sync_completed, S_IRUGO, sync_completed_show, NULL); 4340 4340 4341 4341 static ssize_t 4342 4342 min_sync_show(struct mddev *mddev, char *page)
+3 -2
drivers/md/raid1.c
··· 560 560 if (test_bit(WriteMostly, &rdev->flags)) { 561 561 /* Don't balance among write-mostly, just 562 562 * use the first as a last resort */ 563 - if (best_disk < 0) { 563 + if (best_dist_disk < 0) { 564 564 if (is_badblock(rdev, this_sector, sectors, 565 565 &first_bad, &bad_sectors)) { 566 566 if (first_bad < this_sector) ··· 569 569 best_good_sectors = first_bad - this_sector; 570 570 } else 571 571 best_good_sectors = sectors; 572 - best_disk = disk; 572 + best_dist_disk = disk; 573 + best_pending_disk = disk; 573 574 } 574 575 continue; 575 576 }
+9 -4
drivers/md/raid5.c
··· 5121 5121 schedule_timeout_uninterruptible(1); 5122 5122 } 5123 5123 /* Need to check if array will still be degraded after recovery/resync 5124 - * We don't need to check the 'failed' flag as when that gets set, 5125 - * recovery aborts. 5124 + * Note in case of > 1 drive failures it's possible we're rebuilding 5125 + * one drive while leaving another faulty drive in array. 5126 5126 */ 5127 - for (i = 0; i < conf->raid_disks; i++) 5128 - if (conf->disks[i].rdev == NULL) 5127 + rcu_read_lock(); 5128 + for (i = 0; i < conf->raid_disks; i++) { 5129 + struct md_rdev *rdev = ACCESS_ONCE(conf->disks[i].rdev); 5130 + 5131 + if (rdev == NULL || test_bit(Faulty, &rdev->flags)) 5129 5132 still_degraded = 1; 5133 + } 5134 + rcu_read_unlock(); 5130 5135 5131 5136 bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded); 5132 5137