Commit 90584fc9 authored by Jonathan Brassow's avatar Jonathan Brassow Committed by NeilBrown

MD: Prevent sysfs operations on uninitialized kobjects

MD: Prevent sysfs operations on uninitialized kobjects

Device-mapper does not use sysfs; but when device-mapper is leveraging
MD's RAID personalities, MD sometimes attempts to update sysfs.  This
patch adds checks for 'mddev-kobj.sd' in sysfs_[un]link_rdev to ensure
it is about to operate on something valid.  This patch also checks for
'mddev->kobj.sd' before calling 'sysfs_notify' in 'remove_and_add_spares'.
Although 'sysfs_notify' already makes this check, doing so in
'remove_and_add_spares' prevents an additional mutex operation.
Signed-off-by: default avatarJonathan Brassow <jbrassow@redhat.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent e3620a3a
...@@ -7663,10 +7663,8 @@ static int remove_and_add_spares(struct mddev *mddev) ...@@ -7663,10 +7663,8 @@ static int remove_and_add_spares(struct mddev *mddev)
removed++; removed++;
} }
} }
if (removed) if (removed && mddev->kobj.sd)
sysfs_notify(&mddev->kobj, NULL, sysfs_notify(&mddev->kobj, NULL, "degraded");
"degraded");
rdev_for_each(rdev, mddev) { rdev_for_each(rdev, mddev) {
if (rdev->raid_disk >= 0 && if (rdev->raid_disk >= 0 &&
......
...@@ -506,7 +506,7 @@ static inline char * mdname (struct mddev * mddev) ...@@ -506,7 +506,7 @@ static inline char * mdname (struct mddev * mddev)
static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
{ {
char nm[20]; char nm[20];
if (!test_bit(Replacement, &rdev->flags)) { if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
sprintf(nm, "rd%d", rdev->raid_disk); sprintf(nm, "rd%d", rdev->raid_disk);
return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
} else } else
...@@ -516,7 +516,7 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) ...@@ -516,7 +516,7 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev)
static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev) static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev)
{ {
char nm[20]; char nm[20];
if (!test_bit(Replacement, &rdev->flags)) { if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) {
sprintf(nm, "rd%d", rdev->raid_disk); sprintf(nm, "rd%d", rdev->raid_disk);
sysfs_remove_link(&mddev->kobj, nm); sysfs_remove_link(&mddev->kobj, nm);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment