Skip to content

Commit f59589f

Browse files
committed
Merge branch 'md-next' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-5.9/drivers
Pull MD fixes from Song. * 'md-next' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md: md/raid5: Allow degraded raid6 to do rmw md/raid5: Fix Force reconstruct-write io stuck in degraded raid5 raid5: don't duplicate code for different paths in handle_stripe raid5-cache: hold spinlock instead of mutex in r5c_journal_mode_show md: print errno in super_written md/raid5: remove the redundant setting of STRIPE_HANDLE md: register new md sysfs file 'uuid' read-only md: fix max sectors calculation for super 1.0
2 parents a9e8e18 + 45a4d8f commit f59589f

File tree

4 files changed

+71
-29
lines changed

4 files changed

+71
-29
lines changed

Documentation/admin-guide/md.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ All md devices contain:
426426
The accepted values when writing to this file are ``ppl`` and ``resync``,
427427
used to enable and disable PPL.
428428

429+
uuid
430+
This indicates the UUID of the array in the following format:
431+
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
432+
429433

430434
As component devices are added to an md array, they appear in the ``md``
431435
directory as new directories named::

drivers/md/md.c

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,8 @@ static void super_written(struct bio *bio)
978978
struct mddev *mddev = rdev->mddev;
979979

980980
if (bio->bi_status) {
981-
pr_err("md: super_written gets error=%d\n", bio->bi_status);
981+
pr_err("md: %s gets error=%d\n", __func__,
982+
blk_status_to_errno(bio->bi_status));
982983
md_error(mddev, rdev);
983984
if (!test_bit(Faulty, &rdev->flags)
984985
&& (bio->bi_opf & MD_FAILFAST)) {
@@ -2193,6 +2194,24 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
21932194
sb->sb_csum = calc_sb_1_csum(sb);
21942195
}
21952196

2197+
static sector_t super_1_choose_bm_space(sector_t dev_size)
2198+
{
2199+
sector_t bm_space;
2200+
2201+
/* if the device is bigger than 8Gig, save 64k for bitmap
2202+
* usage, if bigger than 200Gig, save 128k
2203+
*/
2204+
if (dev_size < 64*2)
2205+
bm_space = 0;
2206+
else if (dev_size - 64*2 >= 200*1024*1024*2)
2207+
bm_space = 128*2;
2208+
else if (dev_size - 4*2 > 8*1024*1024*2)
2209+
bm_space = 64*2;
2210+
else
2211+
bm_space = 4*2;
2212+
return bm_space;
2213+
}
2214+
21962215
static unsigned long long
21972216
super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)
21982217
{
@@ -2213,13 +2232,22 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)
22132232
return 0;
22142233
} else {
22152234
/* minor version 0; superblock after data */
2216-
sector_t sb_start;
2217-
sb_start = (i_size_read(rdev->bdev->bd_inode) >> 9) - 8*2;
2235+
sector_t sb_start, bm_space;
2236+
sector_t dev_size = i_size_read(rdev->bdev->bd_inode) >> 9;
2237+
2238+
/* 8K is for superblock */
2239+
sb_start = dev_size - 8*2;
22182240
sb_start &= ~(sector_t)(4*2 - 1);
2219-
max_sectors = rdev->sectors + sb_start - rdev->sb_start;
2241+
2242+
bm_space = super_1_choose_bm_space(dev_size);
2243+
2244+
/* Space that can be used to store date needs to decrease
2245+
* superblock bitmap space and bad block space(4K)
2246+
*/
2247+
max_sectors = sb_start - bm_space - 4*2;
2248+
22202249
if (!num_sectors || num_sectors > max_sectors)
22212250
num_sectors = max_sectors;
2222-
rdev->sb_start = sb_start;
22232251
}
22242252
sb = page_address(rdev->sb_page);
22252253
sb->data_size = cpu_to_le64(num_sectors);
@@ -4225,6 +4253,14 @@ raid_disks_store(struct mddev *mddev, const char *buf, size_t len)
42254253
static struct md_sysfs_entry md_raid_disks =
42264254
__ATTR(raid_disks, S_IRUGO|S_IWUSR, raid_disks_show, raid_disks_store);
42274255

4256+
static ssize_t
4257+
uuid_show(struct mddev *mddev, char *page)
4258+
{
4259+
return sprintf(page, "%pU\n", mddev->uuid);
4260+
}
4261+
static struct md_sysfs_entry md_uuid =
4262+
__ATTR(uuid, S_IRUGO, uuid_show, NULL);
4263+
42284264
static ssize_t
42294265
chunk_size_show(struct mddev *mddev, char *page)
42304266
{
@@ -5481,6 +5517,7 @@ static struct attribute *md_default_attrs[] = {
54815517
&md_level.attr,
54825518
&md_layout.attr,
54835519
&md_raid_disks.attr,
5520+
&md_uuid.attr,
54845521
&md_chunk_size.attr,
54855522
&md_size.attr,
54865523
&md_resync_start.attr,

drivers/md/raid5-cache.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,13 +2537,10 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
25372537
struct r5conf *conf;
25382538
int ret;
25392539

2540-
ret = mddev_lock(mddev);
2541-
if (ret)
2542-
return ret;
2543-
2540+
spin_lock(&mddev->lock);
25442541
conf = mddev->private;
25452542
if (!conf || !conf->log) {
2546-
mddev_unlock(mddev);
2543+
spin_unlock(&mddev->lock);
25472544
return 0;
25482545
}
25492546

@@ -2563,7 +2560,7 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
25632560
default:
25642561
ret = 0;
25652562
}
2566-
mddev_unlock(mddev);
2563+
spin_unlock(&mddev->lock);
25672564
return ret;
25682565
}
25692566

drivers/md/raid5.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3557,6 +3557,7 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,
35573557
struct r5dev *fdev[2] = { &sh->dev[s->failed_num[0]],
35583558
&sh->dev[s->failed_num[1]] };
35593559
int i;
3560+
bool force_rcw = (sh->raid_conf->rmw_level == PARITY_DISABLE_RMW);
35603561

35613562

35623563
if (test_bit(R5_LOCKED, &dev->flags) ||
@@ -3615,17 +3616,27 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,
36153616
* devices must be read.
36163617
*/
36173618
return 1;
3619+
3620+
if (s->failed >= 2 &&
3621+
(fdev[i]->towrite ||
3622+
s->failed_num[i] == sh->pd_idx ||
3623+
s->failed_num[i] == sh->qd_idx) &&
3624+
!test_bit(R5_UPTODATE, &fdev[i]->flags))
3625+
/* In max degraded raid6, If the failed disk is P, Q,
3626+
* or we want to read the failed disk, we need to do
3627+
* reconstruct-write.
3628+
*/
3629+
force_rcw = true;
36183630
}
36193631

3620-
/* If we are forced to do a reconstruct-write, either because
3621-
* the current RAID6 implementation only supports that, or
3622-
* because parity cannot be trusted and we are currently
3623-
* recovering it, there is extra need to be careful.
3632+
/* If we are forced to do a reconstruct-write, because parity
3633+
* cannot be trusted and we are currently recovering it, there
3634+
* is extra need to be careful.
36243635
* If one of the devices that we would need to read, because
36253636
* it is not being overwritten (and maybe not written at all)
36263637
* is missing/faulty, then we need to read everything we can.
36273638
*/
3628-
if (sh->raid_conf->level != 6 &&
3639+
if (!force_rcw &&
36293640
sh->sector < sh->raid_conf->mddev->recovery_cp)
36303641
/* reconstruct-write isn't being forced */
36313642
return 0;
@@ -3995,10 +4006,8 @@ static int handle_stripe_dirtying(struct r5conf *conf,
39954006
set_bit(R5_LOCKED, &dev->flags);
39964007
set_bit(R5_Wantread, &dev->flags);
39974008
s->locked++;
3998-
} else {
4009+
} else
39994010
set_bit(STRIPE_DELAYED, &sh->state);
4000-
set_bit(STRIPE_HANDLE, &sh->state);
4001-
}
40024011
}
40034012
}
40044013
}
@@ -4023,10 +4032,8 @@ static int handle_stripe_dirtying(struct r5conf *conf,
40234032
set_bit(R5_Wantread, &dev->flags);
40244033
s->locked++;
40254034
qread++;
4026-
} else {
4035+
} else
40274036
set_bit(STRIPE_DELAYED, &sh->state);
4028-
set_bit(STRIPE_HANDLE, &sh->state);
4029-
}
40304037
}
40314038
}
40324039
if (rcw && conf->mddev->queue)
@@ -4866,7 +4873,7 @@ static void handle_stripe(struct stripe_head *sh)
48664873
* or to load a block that is being partially written.
48674874
*/
48684875
if (s.to_read || s.non_overwrite
4869-
|| (conf->level == 6 && s.to_write && s.failed)
4876+
|| (s.to_write && s.failed)
48704877
|| (s.syncing && (s.uptodate + s.compute < disks))
48714878
|| s.replacing
48724879
|| s.expanding)
@@ -4970,14 +4977,11 @@ static void handle_stripe(struct stripe_head *sh)
49704977
if (!test_bit(R5_ReWrite, &dev->flags)) {
49714978
set_bit(R5_Wantwrite, &dev->flags);
49724979
set_bit(R5_ReWrite, &dev->flags);
4973-
set_bit(R5_LOCKED, &dev->flags);
4974-
s.locked++;
4975-
} else {
4980+
} else
49764981
/* let's read it back */
49774982
set_bit(R5_Wantread, &dev->flags);
4978-
set_bit(R5_LOCKED, &dev->flags);
4979-
s.locked++;
4980-
}
4983+
set_bit(R5_LOCKED, &dev->flags);
4984+
s.locked++;
49814985
}
49824986
}
49834987

0 commit comments

Comments
 (0)