Re: Top 10 kernel oopses for the week ending January 5th, 2008

Previous thread: [PATCH] x86_64: move out tick_nohz_stop_sched_tick() call from the loop by Hiroshi Shimamoto on Wednesday, January 9, 2008 - 11:44 pm. (2 messages)

Next thread: Re: sata_nv does not function in kernel > 2.6.20.21 by Jeff Garzik on Thursday, January 10, 2008 - 12:40 am. (4 messages)
To: Al Viro <viro@...>
Cc: Linus Torvalds <torvalds@...>, Kevin Winchester <kjwinchester@...>, J. Bruce Fields <bfields@...>, Arjan van de Ven <arjan@...>, Linux Kernel Mailing List <linux-kernel@...>, Andrew Morton <akpm@...>, NetDev <netdev@...>, <gregkh@...>
Date: Thursday, January 10, 2008 - 12:13 am

Thanks for that analysis.

This is a good argument for sticking "md_" at the from of all my
function names, even if they are static. I'm fairly sure I looked at

Yes, that's bad isn't it :-)

I think I should be using sysfs_schedule_callback here. That makes the
required 'get' and 'put' calls.... but it can fail with -ENOMEM. I
wonder what I do if -ENOMEM??? Maybe I'll just continue to roll my
one :-(

Thanks,
NeilBrown

--

To: Neil Brown <neilb@...>
Cc: Linus Torvalds <torvalds@...>, Kevin Winchester <kjwinchester@...>, J. Bruce Fields <bfields@...>, Arjan van de Ven <arjan@...>, Linux Kernel Mailing List <linux-kernel@...>, Andrew Morton <akpm@...>, NetDev <netdev@...>, <gregkh@...>
Date: Thursday, January 10, 2008 - 1:53 am

How about this instead (completely untested)

* split failure exits
* switch to kick_rdev_from_array()
* fold unbind_rdev_from_array() into it (no other callers anymore)
* take export_rdev() into failure case in bind_rdev_to_array()
* in kick_rdev_from_array() do what export_rdev() does sans
kobject_put() and do that before schedule_work(). Take kobject_put() into
delayed_delete().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/drivers/md/md.c b/drivers/md/md.c
index cef9ebd..116cc5a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1344,6 +1344,39 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)

static LIST_HEAD(pending_raid_disks);

+static void unlock_rdev(mdk_rdev_t *rdev)
+{
+ struct block_device *bdev = rdev->bdev;
+ rdev->bdev = NULL;
+ if (!bdev)
+ MD_BUG();
+ bd_release(bdev);
+ blkdev_put(bdev);
+}
+
+void md_autodetect_dev(dev_t dev);
+
+static void __export_rdev(mdk_rdev_t * rdev)
+{
+ char b[BDEVNAME_SIZE];
+ printk(KERN_INFO "md: export_rdev(%s)\n",
+ bdevname(rdev->bdev,b));
+ if (rdev->mddev)
+ MD_BUG();
+ free_disk_sb(rdev);
+ list_del_init(&rdev->same_set);
+#ifndef MODULE
+ md_autodetect_dev(rdev->bdev->bd_dev);
+#endif
+ unlock_rdev(rdev);
+}
+
+static void export_rdev(mdk_rdev_t * rdev)
+{
+ __export_rdev(rdev);
+ kobject_put(&rdev->kobj);
+}
+
static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
{
char b[BDEVNAME_SIZE];
@@ -1353,7 +1386,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)

if (rdev->mddev) {
MD_BUG();
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* make sure rdev->size exceeds mddev->size */
if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
@@ -1362,8 +1396,10 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
* If mddev->level <= 0, then we don't care
* about aligning sizes (e.g...

Previous thread: [PATCH] x86_64: move out tick_nohz_stop_sched_tick() call from the loop by Hiroshi Shimamoto on Wednesday, January 9, 2008 - 11:44 pm. (2 messages)

Next thread: Re: sata_nv does not function in kernel > 2.6.20.21 by Jeff Garzik on Thursday, January 10, 2008 - 12:40 am. (4 messages)