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