Skip to content

Commit 86a1679

Browse files
committed
Merge tag 'md/4.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md
Pull MD fixes from Shaohua Li: "This includes several bug fixes: - Alexey Obitotskiy fixed a hang for faulty raid5 array with external management - Song Liu fixed two raid5 journal related bugs - Tomasz Majchrzak fixed a bad block recording issue and an accounting issue for raid10 - ZhengYuan Liu fixed an accounting issue for raid5 - I fixed a potential race condition and memory leak with DIF/DIX enabled - other trival fixes" * tag 'md/4.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md: raid5: avoid unnecessary bio data set raid5: fix memory leak of bio integrity data raid10: record correct address of bad block md-cluster: fix error return code in join() r5cache: set MD_JOURNAL_CLEAN correctly md: don't print the same repeated messages about delayed sync operation md: remove obsolete ret in md_start_sync md: do not count journal as spare in GET_ARRAY_INFO md: Prevent IO hold during accessing to faulty raid5 array MD: hold mddev lock to change bitmap location raid5: fix incorrectly counter of conf->empty_inactive_list_nr raid10: increment write counter after bio is split
2 parents 0cf21c6 + 45c91d8 commit 86a1679

File tree

5 files changed

+107
-57
lines changed

5 files changed

+107
-57
lines changed

drivers/md/bitmap.c

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,19 +2183,29 @@ location_show(struct mddev *mddev, char *page)
21832183
static ssize_t
21842184
location_store(struct mddev *mddev, const char *buf, size_t len)
21852185
{
2186+
int rv;
21862187

2188+
rv = mddev_lock(mddev);
2189+
if (rv)
2190+
return rv;
21872191
if (mddev->pers) {
2188-
if (!mddev->pers->quiesce)
2189-
return -EBUSY;
2190-
if (mddev->recovery || mddev->sync_thread)
2191-
return -EBUSY;
2192+
if (!mddev->pers->quiesce) {
2193+
rv = -EBUSY;
2194+
goto out;
2195+
}
2196+
if (mddev->recovery || mddev->sync_thread) {
2197+
rv = -EBUSY;
2198+
goto out;
2199+
}
21922200
}
21932201

21942202
if (mddev->bitmap || mddev->bitmap_info.file ||
21952203
mddev->bitmap_info.offset) {
21962204
/* bitmap already configured. Only option is to clear it */
2197-
if (strncmp(buf, "none", 4) != 0)
2198-
return -EBUSY;
2205+
if (strncmp(buf, "none", 4) != 0) {
2206+
rv = -EBUSY;
2207+
goto out;
2208+
}
21992209
if (mddev->pers) {
22002210
mddev->pers->quiesce(mddev, 1);
22012211
bitmap_destroy(mddev);
@@ -2214,21 +2224,25 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
22142224
/* nothing to be done */;
22152225
else if (strncmp(buf, "file:", 5) == 0) {
22162226
/* Not supported yet */
2217-
return -EINVAL;
2227+
rv = -EINVAL;
2228+
goto out;
22182229
} else {
2219-
int rv;
22202230
if (buf[0] == '+')
22212231
rv = kstrtoll(buf+1, 10, &offset);
22222232
else
22232233
rv = kstrtoll(buf, 10, &offset);
22242234
if (rv)
2225-
return rv;
2226-
if (offset == 0)
2227-
return -EINVAL;
2235+
goto out;
2236+
if (offset == 0) {
2237+
rv = -EINVAL;
2238+
goto out;
2239+
}
22282240
if (mddev->bitmap_info.external == 0 &&
22292241
mddev->major_version == 0 &&
2230-
offset != mddev->bitmap_info.default_offset)
2231-
return -EINVAL;
2242+
offset != mddev->bitmap_info.default_offset) {
2243+
rv = -EINVAL;
2244+
goto out;
2245+
}
22322246
mddev->bitmap_info.offset = offset;
22332247
if (mddev->pers) {
22342248
struct bitmap *bitmap;
@@ -2245,7 +2259,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
22452259
mddev->pers->quiesce(mddev, 0);
22462260
if (rv) {
22472261
bitmap_destroy(mddev);
2248-
return rv;
2262+
goto out;
22492263
}
22502264
}
22512265
}
@@ -2257,6 +2271,11 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
22572271
set_bit(MD_CHANGE_DEVS, &mddev->flags);
22582272
md_wakeup_thread(mddev->thread);
22592273
}
2274+
rv = 0;
2275+
out:
2276+
mddev_unlock(mddev);
2277+
if (rv)
2278+
return rv;
22602279
return len;
22612280
}
22622281

drivers/md/md-cluster.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,10 @@ static int join(struct mddev *mddev, int nodes)
834834
goto err;
835835
}
836836
cinfo->ack_lockres = lockres_init(mddev, "ack", ack_bast, 0);
837-
if (!cinfo->ack_lockres)
837+
if (!cinfo->ack_lockres) {
838+
ret = -ENOMEM;
838839
goto err;
840+
}
839841
/* get sync CR lock on ACK. */
840842
if (dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR))
841843
pr_err("md-cluster: failed to get a sync CR lock on ACK!(%d)\n",
@@ -849,17 +851,21 @@ static int join(struct mddev *mddev, int nodes)
849851
pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number);
850852
snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1);
851853
cinfo->bitmap_lockres = lockres_init(mddev, str, NULL, 1);
852-
if (!cinfo->bitmap_lockres)
854+
if (!cinfo->bitmap_lockres) {
855+
ret = -ENOMEM;
853856
goto err;
857+
}
854858
if (dlm_lock_sync(cinfo->bitmap_lockres, DLM_LOCK_PW)) {
855859
pr_err("Failed to get bitmap lock\n");
856860
ret = -EINVAL;
857861
goto err;
858862
}
859863

860864
cinfo->resync_lockres = lockres_init(mddev, "resync", NULL, 0);
861-
if (!cinfo->resync_lockres)
865+
if (!cinfo->resync_lockres) {
866+
ret = -ENOMEM;
862867
goto err;
868+
}
863869

864870
return 0;
865871
err:

drivers/md/md.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,11 +1604,8 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
16041604
mddev->new_chunk_sectors = mddev->chunk_sectors;
16051605
}
16061606

1607-
if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL) {
1607+
if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL)
16081608
set_bit(MD_HAS_JOURNAL, &mddev->flags);
1609-
if (mddev->recovery_cp == MaxSector)
1610-
set_bit(MD_JOURNAL_CLEAN, &mddev->flags);
1611-
}
16121609
} else if (mddev->pers == NULL) {
16131610
/* Insist of good event counter while assembling, except for
16141611
* spares (which don't need an event count) */
@@ -5851,6 +5848,9 @@ static int get_array_info(struct mddev *mddev, void __user *arg)
58515848
working++;
58525849
if (test_bit(In_sync, &rdev->flags))
58535850
insync++;
5851+
else if (test_bit(Journal, &rdev->flags))
5852+
/* TODO: add journal count to md_u.h */
5853+
;
58545854
else
58555855
spare++;
58565856
}
@@ -7862,6 +7862,7 @@ void md_do_sync(struct md_thread *thread)
78627862
*/
78637863

78647864
do {
7865+
int mddev2_minor = -1;
78657866
mddev->curr_resync = 2;
78667867

78677868
try_again:
@@ -7891,10 +7892,14 @@ void md_do_sync(struct md_thread *thread)
78917892
prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE);
78927893
if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
78937894
mddev2->curr_resync >= mddev->curr_resync) {
7894-
printk(KERN_INFO "md: delaying %s of %s"
7895-
" until %s has finished (they"
7896-
" share one or more physical units)\n",
7897-
desc, mdname(mddev), mdname(mddev2));
7895+
if (mddev2_minor != mddev2->md_minor) {
7896+
mddev2_minor = mddev2->md_minor;
7897+
printk(KERN_INFO "md: delaying %s of %s"
7898+
" until %s has finished (they"
7899+
" share one or more physical units)\n",
7900+
desc, mdname(mddev),
7901+
mdname(mddev2));
7902+
}
78987903
mddev_put(mddev2);
78997904
if (signal_pending(current))
79007905
flush_signals(current);
@@ -8275,16 +8280,13 @@ static int remove_and_add_spares(struct mddev *mddev,
82758280
static void md_start_sync(struct work_struct *ws)
82768281
{
82778282
struct mddev *mddev = container_of(ws, struct mddev, del_work);
8278-
int ret = 0;
82798283

82808284
mddev->sync_thread = md_register_thread(md_do_sync,
82818285
mddev,
82828286
"resync");
82838287
if (!mddev->sync_thread) {
8284-
if (!(mddev_is_clustered(mddev) && ret == -EAGAIN))
8285-
printk(KERN_ERR "%s: could not start resync"
8286-
" thread...\n",
8287-
mdname(mddev));
8288+
printk(KERN_ERR "%s: could not start resync thread...\n",
8289+
mdname(mddev));
82888290
/* leave the spares where they are, it shouldn't hurt */
82898291
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
82908292
clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);

drivers/md/raid10.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,8 @@ static void __make_request(struct mddev *mddev, struct bio *bio)
10641064
int max_sectors;
10651065
int sectors;
10661066

1067+
md_write_start(mddev, bio);
1068+
10671069
/*
10681070
* Register the new request and wait if the reconstruction
10691071
* thread has put up a bar for new requests.
@@ -1445,8 +1447,6 @@ static void raid10_make_request(struct mddev *mddev, struct bio *bio)
14451447
return;
14461448
}
14471449

1448-
md_write_start(mddev, bio);
1449-
14501450
do {
14511451

14521452
/*
@@ -2465,20 +2465,21 @@ static int narrow_write_error(struct r10bio *r10_bio, int i)
24652465

24662466
while (sect_to_write) {
24672467
struct bio *wbio;
2468+
sector_t wsector;
24682469
if (sectors > sect_to_write)
24692470
sectors = sect_to_write;
24702471
/* Write at 'sector' for 'sectors' */
24712472
wbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
24722473
bio_trim(wbio, sector - bio->bi_iter.bi_sector, sectors);
2473-
wbio->bi_iter.bi_sector = (r10_bio->devs[i].addr+
2474-
choose_data_offset(r10_bio, rdev) +
2475-
(sector - r10_bio->sector));
2474+
wsector = r10_bio->devs[i].addr + (sector - r10_bio->sector);
2475+
wbio->bi_iter.bi_sector = wsector +
2476+
choose_data_offset(r10_bio, rdev);
24762477
wbio->bi_bdev = rdev->bdev;
24772478
bio_set_op_attrs(wbio, REQ_OP_WRITE, 0);
24782479

24792480
if (submit_bio_wait(wbio) < 0)
24802481
/* Failure! */
2481-
ok = rdev_set_badblocks(rdev, sector,
2482+
ok = rdev_set_badblocks(rdev, wsector,
24822483
sectors, 0)
24832484
&& ok;
24842485

0 commit comments

Comments
 (0)