Messages in this thread Patch in this message | | | From | Heinz Mauelshagen <> | Subject | defvs patch v84 for linux 2.2.0-pre9 bugfix | Date | Sat, 23 Jan 1999 14:44:45 MET |
| |
Hi Richard!
Yesterday i gave myself a chance to have a look at your devfs patch for Linux 2.2.0-pre9 8*)
I found a little bug, which seems to cause non standard block devices beeing _not_ mountable any more. In detail, my logical volume manager block devices don't work. The block device specials are created by lvm user commands.
I think any software creating block specials should fail with the v84 code in super.c, where your patch looks like:
@@ -1067,8 +1079,9 @@ if (MAJOR(dev) >= MAX_BLKDEV) goto dput_and_out;
- retval = -ENOTBLK; - dummy.f_op = get_blkfops(MAJOR(dev)); + retval = devfs_fill_file (inode, &dummy, NULL); + if ( !retval && !S_ISBLK (inode->i_mode) ) retval = -ENOTBLK; + if (retval < 0) dummy.f_op = get_blkfops(MAJOR(dev)); if (!dummy.f_op) goto dput_and_out;
Please give me feedback. Best regards and keep up the good work, Heinz
Patch against stock linux-2.2.0-pre9/fs/super.c to fix the problem follows:
--- linux/fs/super.c.orig Thu Jan 7 00:01:25 1999 +++ linux/fs/super.c Sat Jan 23 14:29:27 1999 @@ -15,12 +15,14 @@ * * Added kerneld support: Jacques Gelinas and Bjorn Ekwall * Added change_root: Werner Almesberger & Hans Lermen, Feb '96 + * Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998 */ #include <linux/config.h> #include <linux/malloc.h> #include <linux/locks.h> #include <linux/smp_lock.h> +#include <linux/devfs_fs.h> #include <linux/fd.h> #include <linux/init.h> #include <linux/quotaops.h> @@ -739,7 +741,17 @@ if (!retval) { fsync_dev(dev); if (dev != ROOT_DEV) { - blkdev_release(inode); + int err; + struct file file; + void *handle; + + handle = devfs_find_handle (NULL, 0, + MAJOR (dev), MINOR (dev), + DEVFS_SPECIAL_BLK, 0); + err = devfs_fill_file (inode, &file, handle); + if (!err && file.f_op && file.f_op->release) + file.f_op->release (inode, NULL); + if (err) blkdev_release(inode); put_unnamed_dev(dev); } } @@ -1067,8 +1079,9 @@ if (MAJOR(dev) >= MAX_BLKDEV) goto dput_and_out; - retval = -ENOTBLK; - dummy.f_op = get_blkfops(MAJOR(dev)); + if ( !( retval = devfs_fill_file (inode, &dummy, NULL))) + retval = -ENOTBLK; + if ( retval < 0) dummy.f_op = get_blkfops(MAJOR(dev)); if (!dummy.f_op) goto dput_and_out; @@ -1122,6 +1135,9 @@ struct inode * d_inode = NULL; struct file filp; int retval; + void *handle; + char path[37]; + int path_start = -1; #ifdef CONFIG_ROOT_NFS if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { @@ -1172,20 +1188,46 @@ filp.f_mode = 1; /* read only */ else filp.f_mode = 3; /* read write */ - retval = blkdev_open(d_inode, &filp); + handle = devfs_find_handle (ROOT_DEVICE_NAME, 0, + MAJOR (ROOT_DEV), MINOR (ROOT_DEV), + DEVFS_SPECIAL_BLK, 1); + retval = devfs_fill_file (d_inode, &filp, handle); + if (retval == 0) + { + path_start = devfs_generate_path (handle, path + 5, + sizeof (path) - 5); + if (filp.f_op && filp.f_op->open) + retval = filp.f_op->open (d_inode, &filp); + if (retval == 0) ROOT_DEV = d_inode->i_rdev; + } + if (retval < 0) retval = blkdev_open(d_inode, &filp); if (retval == -EROFS) { root_mountflags |= MS_RDONLY; filp.f_mode = 1; - retval = blkdev_open(d_inode, &filp); + handle = devfs_find_handle (root_device_name, 0, + MAJOR (ROOT_DEV), MINOR (ROOT_DEV), + DEVFS_SPECIAL_BLK, 1); + retval = devfs_fill_file (d_inode, &filp, handle); + if (retval == 0) + { + path_start = devfs_generate_path (handle, path + 5, + sizeof (path) - 5); + if (filp.f_op && filp.f_op->open) + retval = filp.f_op->open (d_inode, &filp); + if (retval == 0) ROOT_DEV = d_inode->i_rdev; + } + if (retval < 0) retval = blkdev_open(d_inode, &filp); } iput(d_inode); - if (retval) + if (retval) { /* * Allow the user to distinguish between failed open * and bad superblock on root device. */ - printk("VFS: Cannot open root device %s\n", - kdevname(ROOT_DEV)); + printk ("VFS: Cannot open root device \"%s\" or %s\n", + root_device_name, kdevname (ROOT_DEV)); + printk ("Please append a correct \"root=\" boot option\n"); + } else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) { if (!(fs_type->fs_flags & FS_REQUIRES_DEV)) continue; @@ -1197,7 +1239,16 @@ printk ("VFS: Mounted root (%s filesystem)%s.\n", fs_type->name, (sb->s_flags & MS_RDONLY) ? " readonly" : ""); - vfsmnt = add_vfsmnt(sb, "/dev/root", "/"); + if (path_start >= 0) { + devfs_mk_symlink (NULL, + "root", 0, DEVFS_FL_DEFAULT, + path + 5 + path_start, 0, + NULL); + memcpy (path + path_start, "/dev/", 5); + vfsmnt = add_vfsmnt (sb, path + path_start, + "/"); + } + else vfsmnt = add_vfsmnt (sb, "/dev/root", "/"); if (vfsmnt) return; panic("VFS: add_vfsmnt failed for root fs"); @@ -1224,6 +1275,18 @@ printk(KERN_CRIT "New root is busy. Staying in initrd.\n"); return -EBUSY; } + /* First unmount devfs if mounted */ + dir_d = lookup_dentry ("/dev", NULL, 1); + if (!IS_ERR(dir_d)) { + struct super_block *sb = dir_d->d_inode->i_sb; + + if (sb && (dir_d->d_inode == sb->s_root->d_inode) && + (sb->s_magic == DEVFS_SUPER_MAGIC)) { + dput (dir_d); + do_umount (sb->s_dev, 0, 0); + } + else dput (dir_d); + } ROOT_DEV = new_root_dev; mount_root(); dput(old_root); @@ -1232,6 +1295,7 @@ shrink_dcache(); printk("change_root: old root has d_count=%d\n", old_root->d_count); #endif + mount_devfs_fs (); /* * Get the new mount directory */ -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Systemmanagement Entwicklungsbereich 2 Deutsche Telekom AG Entwicklungszentrum Darmstadt Heinz Mauelshagen Otto-Roehm-Strasse 71c Postfach 10 05 41 mge@ez-darmstadt.telekom.de 64205 Darmstadt Germany +49 6151 886-425 FAX-386 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- 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/
| |