On 03/30/2016 05:37 AM, Shaohua Li wrote:
On Tue, Mar 29, 2016 at 08:22:00AM -0400, Xiao Ni wrote:
Hi all
I encountered one NULL pointer dereference problem.
The environment:
latest linux-stable and mdadm codes
aarch64 platform
the md device is created with loop devices
It's a test case to check date integrity. I added the test script as the attachment.
Could you please try this patch:
From b86d9e1724184c79ad1ea63901aec802492b861c Mon Sep 17 00:00:00 2001
Message-Id: <b86d9e1724184c79ad1ea63901aec802492b861c.1459285706.git.shli@xxxxxx>
From: Shaohua Li <shli@xxxxxx>
Date: Tue, 29 Mar 2016 14:00:19 -0700
Subject: [PATCH] MD: add rdev reference for super write
md_super_write() and corresponding md_super_wait() generally are called
with reconfig_mutex locked, which prevents disk disappears.
Just for curious, I find several paths maybe also don't hold reconfig_mutex,
take the followings as example.
1. md_run -> md_update_sb -> md_super_write/md_super_wait
2. rdev_size_store -> rdev_size_change -> md_super_write/md_super_wait
Thanks,
Guoqing
There is one
case this rule is broken. write_sb_page of bitmap.c doesn't hold the
mutex. next_active_rdev does increase rdev reference, but it decreases
the reference too early (eg, before IO finish). disk can disappear at
the window. We unconditionally increase rdev reference in
md_super_write() to avoid the race.
Reported-by: Xiao Ni <xni@xxxxxxxxxx>
Cc: Neil Brown <neilb@xxxxxxx>
Signed-off-by: Shaohua Li <shli@xxxxxx>
---
drivers/md/md.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c068f17..bcfde333 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -718,6 +718,7 @@ static void super_written(struct bio *bio)
if (atomic_dec_and_test(&mddev->pending_writes))
wake_up(&mddev->sb_wait);
+ rdev_dec_pending(rdev, mddev);
bio_put(bio);
}
@@ -732,6 +733,8 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
*/
struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, mddev);
+ atomic_inc(&rdev->nr_pending);
+
bio->bi_bdev = rdev->meta_bdev ? rdev->meta_bdev : rdev->bdev;
bio->bi_iter.bi_sector = sector;
bio_add_page(bio, page, size, 0);
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html