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.
This commit is contained in:
@@ -2555,7 +2555,7 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len)
|
||||
return err ? err : len;
|
||||
}
|
||||
static struct rdev_sysfs_entry rdev_state =
|
||||
__ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store);
|
||||
__ATTR_PREALLOC(state, S_IRUGO|S_IWUSR, state_show, state_store);
|
||||
|
||||
static ssize_t
|
||||
errors_show(struct md_rdev *rdev, char *page)
|
||||
@@ -3638,7 +3638,8 @@ resync_start_store(struct mddev *mddev, const char *buf, size_t len)
|
||||
return err ?: len;
|
||||
}
|
||||
static struct md_sysfs_entry md_resync_start =
|
||||
__ATTR(resync_start, S_IRUGO|S_IWUSR, resync_start_show, resync_start_store);
|
||||
__ATTR_PREALLOC(resync_start, S_IRUGO|S_IWUSR,
|
||||
resync_start_show, resync_start_store);
|
||||
|
||||
/*
|
||||
* The array state can be:
|
||||
@@ -3851,7 +3852,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
|
||||
return err ?: len;
|
||||
}
|
||||
static struct md_sysfs_entry md_array_state =
|
||||
__ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
|
||||
__ATTR_PREALLOC(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
|
||||
|
||||
static ssize_t
|
||||
max_corrected_read_errors_show(struct mddev *mddev, char *page) {
|
||||
@@ -4101,7 +4102,7 @@ out_unlock:
|
||||
}
|
||||
|
||||
static struct md_sysfs_entry md_metadata =
|
||||
__ATTR(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
|
||||
__ATTR_PREALLOC(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
|
||||
|
||||
static ssize_t
|
||||
action_show(struct mddev *mddev, char *page)
|
||||
@@ -4189,7 +4190,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
|
||||
}
|
||||
|
||||
static struct md_sysfs_entry md_scan_mode =
|
||||
__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
|
||||
__ATTR_PREALLOC(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
|
||||
|
||||
static ssize_t
|
||||
last_sync_action_show(struct mddev *mddev, char *page)
|
||||
@@ -4335,7 +4336,8 @@ sync_completed_show(struct mddev *mddev, char *page)
|
||||
return sprintf(page, "%llu / %llu\n", resync, max_sectors);
|
||||
}
|
||||
|
||||
static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
|
||||
static struct md_sysfs_entry md_sync_completed =
|
||||
__ATTR_PREALLOC(sync_completed, S_IRUGO, sync_completed_show, NULL);
|
||||
|
||||
static ssize_t
|
||||
min_sync_show(struct mddev *mddev, char *page)
|
||||
|
@@ -560,7 +560,7 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
|
||||
if (test_bit(WriteMostly, &rdev->flags)) {
|
||||
/* Don't balance among write-mostly, just
|
||||
* use the first as a last resort */
|
||||
if (best_disk < 0) {
|
||||
if (best_dist_disk < 0) {
|
||||
if (is_badblock(rdev, this_sector, sectors,
|
||||
&first_bad, &bad_sectors)) {
|
||||
if (first_bad < this_sector)
|
||||
@@ -569,7 +569,8 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
|
||||
best_good_sectors = first_bad - this_sector;
|
||||
} else
|
||||
best_good_sectors = sectors;
|
||||
best_disk = disk;
|
||||
best_dist_disk = disk;
|
||||
best_pending_disk = disk;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@@ -5121,12 +5121,17 @@ static inline sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int
|
||||
schedule_timeout_uninterruptible(1);
|
||||
}
|
||||
/* Need to check if array will still be degraded after recovery/resync
|
||||
* We don't need to check the 'failed' flag as when that gets set,
|
||||
* recovery aborts.
|
||||
* Note in case of > 1 drive failures it's possible we're rebuilding
|
||||
* one drive while leaving another faulty drive in array.
|
||||
*/
|
||||
for (i = 0; i < conf->raid_disks; i++)
|
||||
if (conf->disks[i].rdev == NULL)
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < conf->raid_disks; i++) {
|
||||
struct md_rdev *rdev = ACCESS_ONCE(conf->disks[i].rdev);
|
||||
|
||||
if (rdev == NULL || test_bit(Faulty, &rdev->flags))
|
||||
still_degraded = 1;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded);
|
||||
|
||||
|
Reference in New Issue
Block a user