[stopgap PATCH] Oopses in 2.3.99p8 blkdev_open

From: Andries Brouwer (aeb@veritas.com)
Date: Tue May 23 2000 - 06:27:54 EST


If one has accessed a device and later removes the module,
and then accesses the device again, this produces an Oops
(or kernel hang, or spontaneous reboot...).

In blkdev_open() the nonsense patch

--- /g1/linux/linux-2.3.99p8/linux/fs/block_dev.c Sun Apr 30 21:49:32 2000
+++ ./block_dev.c Tue May 23 12:22:49 2000
@@ -608,9 +615,16 @@
 {
        int ret = -ENODEV;
        struct block_device *bdev = inode->i_bdev;
+ struct block_device_operations *bd_op;
+
+ bd_op = get_blkfops(MAJOR(inode->i_rdev));
+ if (bd_op == NULL && bdev->bd_op != NULL) {
+ printk("Oops detected in blkdev_open: bd_op is NULL\n");
+ return -ENODEV;
+ }
        down(&bdev->bd_sem);
        if (!bdev->bd_op)
- bdev->bd_op = get_blkfops(MAJOR(inode->i_rdev));
+ bdev->bd_op = bd_op;
        if (bdev->bd_op) {
                ret = 0;
                if (bdev->bd_op->open)

[I have other stuff here, line numbers may differ a bit.
 Copied from another window, tabs will have become spaces.]

prevents this Oops. But of course the right thing to do
is to invalidate dentries and inodes when the module is
removed. Most modules do devfs_unregister_blkdev(), and
in case CONFIG_DEVFS_FS is defined, this does free_dentries().
But in case CONFIG_DEVFS_FS is not defined, we only do
        blkdevs[major].bdops = NULL;
and that is not good enough.

In other words, some of the code of devfs must be moved
to the general environment.

Andries

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue May 23 2000 - 21:00:23 EST