Re: Re: fr1-2.16 patch for 2.6.10 kernel
"Peter T. Breuer" <[email protected]>
| Newsgroups | gmane.linux.enbd.general |
|---|---|
| Message-ID | <[email protected]> |
"Also sprach Peter T. Breuer:"
> and has been reused, so it contains nonsense. Can you see in the dmesg
> output a
>
> "md: export_rdev(%s)\n"
>
> ?? I'd like you to put a printk before every call to export_rdev() in
> md.c, so that we find out which call to export_rdev it is.
Well, looking at the code, I believe that
md.c: hot_remove_disk
calls
kick_rdev_from_array(rdev);
which is
static void kick_rdev_from_array(mdk_rdev_t * rdev)
{
unbind_rdev_from_array(rdev);
export_rdev(rdev);
}
The unbind call merely unhooks rdev from the list of device
list_del_init(&rdev->same_set);
printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
rdev->mddev = NULL;
and looks fairly harmless. The export_rdev call, on the other hand,
looks dangerous:
printk(KERN_INFO "md: export_rdev(%s)\n",
bdevname(rdev->bdev,b));
...
free_disk_sb(rdev);
list_del_init(&rdev->same_set); // harmless - already done
...
unlock_rdev(rdev);
The unlock_rdev call is probably the damage:
static void unlock_rdev(mdk_rdev_t *rdev)
{
struct block_device *bdev = rdev->bdev;
rdev->bdev = NULL;
if (!bdev)
MD_BUG();
bd_release(bdev); // decrements bdev->bd_holders
blkdev_put(bdev, BDEV_RAW); // counts and decs bdev->bd_openers
}
The blkdev_put is the really nasty one.
I believe that those calls have probably liberated the structs involved
back to the kernel - unless there is another reference to them held
somewhere. If you can add printks which prove the theory, that would be
helpful.
The original problem probably is the hot_remove_disk(mddev, dev); in
md.c hot_add_disk, used when we do a hot repair to get rid of the
component before adding it in again.
/*
* Allow "hotrepair" of faulty device. Have rdev->faulty;
*/
printk(KERN_WARNING "%s: repair of faulty disk %x!\n",
mdname(mddev), dev);
rdev->raid_disk = -1;
err = hot_remove_disk(mddev, dev);
if (err < 0) {
printk(KERN_WARNING "%s: remove disk %x errored\n",
mdname(mddev), dev);
return err;
}
It is followed by
rdev = md_import_device (dev, -1, 0); // PTB -1 == don't check sb
which calls
lock_rdev(rdev, [new]dev);
which should reestablish rdev->bdev. Can you add printks to try and
confirm that these calls happen? I would like to know if the
import_device gets run and if after it is run, if rdev->bdev is OK.
Peter