Re: [patch-2.3.50-pre2] bdget() needs to be exported

From: Mike Galbraith (mikeg@weiden.de)
Date: Tue Mar 07 2000 - 00:23:08 EST


On Mon, 6 Mar 2000, Tigran Aivazian wrote:

> Hi Linus,
>
> Without bdget() being exported ramdisk driver won't load as a module.

Hi Tigran, (and Linus)

Unfortunately, that's not the only problem with ramdisk as module.
Problem #2 is a stale pointer to module address space which causes
an oops upon open after rmmod/re-insmod.

Instead of exporting bdget(), I opted to keep the ramdisk's private
problem internal to that driver as in patch below. Thoughts?

        -Mike

--- linux-2.3.49/drivers/block/rd.c.org Mon Mar 6 04:02:06 2000
+++ linux-2.3.49/drivers/block/rd.c Tue Mar 7 06:05:29 2000
@@ -99,6 +99,7 @@
 static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */
 static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */
 static devfs_handle_t devfs_handle = NULL;
+static struct block_device *rd_dev[NUM_RAMDISKS]; /* Protected devices */
 
 /*
  * Parameters for the boot-loading of the RAM disk. These are set by
@@ -372,6 +373,14 @@
         if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
                 return -ENXIO;
 
+ /*
+ * Immunize device against invalidate_buffers().
+ */
+ if (rd_dev[DEVICE_NR(inode->i_rdev)] == NULL) {
+ rd_dev[DEVICE_NR(inode->i_rdev)] = inode->i_bdev;
+ atomic_inc(&rd_dev[DEVICE_NR(inode->i_rdev)]->bd_openers);
+ }
+
         MOD_INC_USE_COUNT;
 
         return 0;
@@ -395,9 +404,14 @@
         int i;
 
         for (i = 0 ; i < NUM_RAMDISKS; i++) {
- struct block_device *bdev;
- bdev = bdget(kdev_t_to_nr(MKDEV(MAJOR_NR,i)));
- atomic_dec(&bdev->bd_openers);
+ if (rd_dev[i]) {
+ /* withdraw invalidate_buffers() immunity */
+ atomic_dec(&rd_dev[i]->bd_openers);
+#ifdef MODULE
+ /* remove stale pointer to module address space */
+ rd_dev[i]->bd_op = NULL;
+#endif
+ }
                 destroy_buffers(MKDEV(MAJOR_NR, i));
         }
 
@@ -441,21 +455,16 @@
                                S_IFBLK | S_IRUSR | S_IWUSR, 0, 0,
                                &fd_fops, NULL);
 
- hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */
- blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */
-
- for (i = 0; i < NUM_RAMDISKS; i++) {
- struct block_device *bdev;
+ for (i = 0; i < NUM_RAMDISKS; i++)
                 register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &fd_fops, rd_size<<1);
- bdev = bdget(kdev_t_to_nr(MKDEV(MAJOR_NR,i)));
- atomic_inc(&bdev->bd_openers); /* avoid invalidate_buffers() */
- }
 
 #ifdef CONFIG_BLK_DEV_INITRD
         /* We ought to separate initrd operations here */
         register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &fd_fops, rd_size<<1);
 #endif
 
+ hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */
+ blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */
         blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */
 
                 /* rd_size is given in kB */

-
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 Mar 07 2000 - 21:00:21 EST