diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
commit | b9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch) | |
tree | 42d07b0c7246ae2536a702e7c5de9e2732341116 /fs/devfs | |
parent | 7406b0a326f2d70ade2671c37d1beef62249db97 (diff) |
Merge with 2.3.99-pre6.
Diffstat (limited to 'fs/devfs')
-rw-r--r-- | fs/devfs/base.c | 113 |
1 files changed, 71 insertions, 42 deletions
diff --git a/fs/devfs/base.c b/fs/devfs/base.c index eb38eff34..b934ff9b9 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -432,6 +432,17 @@ <devfs_readdir>. Work sponsored by SGI. v0.93 + 20000413 Richard Gooch <rgooch@atnf.csiro.au> + Set inode->i_size to correct size for symlinks. + 20000414 Richard Gooch <rgooch@atnf.csiro.au> + Only give lookup() method to directories to comply with new VFS + assumptions. + Work sponsored by SGI. + 20000415 Richard Gooch <rgooch@atnf.csiro.au> + Remove unnecessary tests in symlink methods. + Don't kill existing block ops in <devfs_read_inode>. + Work sponsored by SGI. + v0.94 */ #include <linux/types.h> #include <linux/errno.h> @@ -466,7 +477,7 @@ #include <asm/bitops.h> #include <asm/atomic.h> -#define DEVFS_VERSION "0.93 (20000306)" +#define DEVFS_VERSION "0.94 (20000415)" #ifndef DEVFS_NAME # define DEVFS_NAME "devfs" @@ -679,7 +690,9 @@ static unsigned int devfs_debug_init __initdata = DEBUG_NONE; static unsigned int devfs_debug = DEBUG_NONE; # endif #endif -static unsigned int boot_options = OPTION_NONE; + +/* by default, we do not mount devfs on bootup */ +static unsigned int boot_options = OPTION_NOMOUNT; /* Forward function declarations */ static struct devfs_entry *search_for_entry (struct devfs_entry *dir, @@ -1916,6 +1929,11 @@ SETUP_STATIC int __init devfs_setup (char *str) boot_options |= OPTION_ONLY; str += 4; } + else if (strncmp (str, "mount", 5) == 0) + { + boot_options &= ~OPTION_NOMOUNT; + str += 5; + } else if (strncmp (str, "nomount", 7) == 0) { boot_options |= OPTION_NOMOUNT; @@ -2185,6 +2203,7 @@ static int get_removable_partition (struct devfs_entry *dir, const char *name, /* Superblock operations follow */ static struct inode_operations devfs_iops; +static struct inode_operations devfs_dir_iops; static struct file_operations devfs_fops; static struct inode_operations devfs_symlink_iops; @@ -2208,28 +2227,33 @@ static void devfs_read_inode (struct inode *inode) inode->i_blocks = 0; inode->i_blksize = 1024; inode->i_op = &devfs_iops; + inode->i_fop = &devfs_fops; inode->i_rdev = NODEV; - if ( S_ISCHR (di->mode) ) { + if ( S_ISCHR (di->mode) ) + { inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major, di->de->u.fcb.u.device.minor); - inode->i_fop = &devfs_fops; - } else if ( S_ISBLK (di->mode) ) { + } + else if ( S_ISBLK (di->mode) ) + { inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major, di->de->u.fcb.u.device.minor); inode->i_bdev = bdget (inode->i_rdev); - if (inode->i_bdev) inode->i_bdev->bd_op = di->de->u.fcb.ops; + if (inode->i_bdev) + { + if (!inode->i_bdev->bd_op && di->de->u.fcb.ops) + inode->i_bdev->bd_op = di->de->u.fcb.ops; + } else printk ("%s: read_inode(%d): no block device from bdget()\n", DEVFS_NAME, (int) inode->i_ino); - inode->i_fop = &devfs_fops; - } else if ( S_ISFIFO (di->mode) ) { - inode->i_fop = &def_fifo_fops; - } else if ( S_ISREG (di->mode) ) { - inode->i_size = di->de->u.fcb.u.file.size; - inode->i_fop = &devfs_fops; - } else if (S_ISLNK(di->mode)) { + } + else if ( S_ISFIFO (di->mode) ) inode->i_fop = &def_fifo_fops; + else if ( S_ISREG (di->mode) ) inode->i_size = di->de->u.fcb.u.file.size; + else if ( S_ISDIR (di->mode) ) inode->i_op = &devfs_dir_iops; + else if ( S_ISLNK (di->mode) ) + { inode->i_op = &devfs_symlink_iops; - } else { - inode->i_fop = &devfs_fops; + inode->i_size = di->de->u.symlink.length; } inode->i_mode = di->mode; inode->i_uid = di->uid; @@ -2358,7 +2382,7 @@ static struct inode *get_vfs_inode (struct super_block *sb, /* File operations for device entries follow */ -static int devfs_read (struct file *file, char *buf, size_t len, loff_t *ppos) +static ssize_t devfs_read (struct file *file, char *buf, size_t len, loff_t *ppos) { if ( S_ISDIR (file->f_dentry->d_inode->i_mode) ) return -EISDIR; return -EINVAL; @@ -2747,7 +2771,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) de = search_for_entry_in_dir (parent, dentry->d_name.name, dentry->d_name.len, FALSE); } - if ( (de == NULL) || (!de->registered) ) + if ( (de == NULL) || !de->registered ) { /* Try with devfsd. For any kind of failure, leave a negative dentry so someone else can deal with it (in the case where the sysadmin @@ -3083,41 +3107,46 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode, static int devfs_readlink (struct dentry *dentry, char *buffer, int buflen) { - struct devfs_inode *di=get_devfs_inode_from_vfs_inode(dentry->d_inode); - char *name = ERR_PTR(-ENOENT); + struct devfs_inode *di = get_devfs_inode_from_vfs_inode (dentry->d_inode); - if (di && di->de->registered) - name = di->de->u.symlink.linkname; - return vfs_readlink(dentry, buffer, buflen, name); + return vfs_readlink (dentry, buffer, buflen, di->de->u.symlink.linkname); } /* End Function devfs_readlink */ static int devfs_follow_link (struct dentry *dentry, struct nameidata *nd) { - struct devfs_inode *di=get_devfs_inode_from_vfs_inode(dentry->d_inode); - char *name = ERR_PTR(-ENOENT); + struct devfs_inode *di = get_devfs_inode_from_vfs_inode (dentry->d_inode); - if (di && di->de->registered) - name = di->de->u.symlink.linkname; - return vfs_follow_link(nd, name); + return vfs_follow_link (nd, di->de->u.symlink.linkname); } /* End Function devfs_follow_link */ static struct inode_operations devfs_iops = { - lookup: devfs_lookup, - link: devfs_link, - unlink: devfs_unlink, - symlink: devfs_symlink, - mkdir: devfs_mkdir, - rmdir: devfs_rmdir, - mknod: devfs_mknod, - setattr: devfs_notify_change, + link: devfs_link, + unlink: devfs_unlink, + symlink: devfs_symlink, + mkdir: devfs_mkdir, + rmdir: devfs_rmdir, + mknod: devfs_mknod, + setattr: devfs_notify_change, +}; + +static struct inode_operations devfs_dir_iops = +{ + lookup: devfs_lookup, + link: devfs_link, + unlink: devfs_unlink, + symlink: devfs_symlink, + mkdir: devfs_mkdir, + rmdir: devfs_rmdir, + mknod: devfs_mknod, + setattr: devfs_notify_change, }; static struct inode_operations devfs_symlink_iops = { - readlink: devfs_readlink, - follow_link: devfs_follow_link, - setattr: devfs_notify_change, + readlink: devfs_readlink, + follow_link: devfs_follow_link, + setattr: devfs_notify_change, }; static struct super_block *devfs_read_super (struct super_block *sb, @@ -3179,7 +3208,7 @@ out_no_root: } /* End Function devfs_read_super */ -static DECLARE_FSTYPE(devfs_fs_type, DEVFS_NAME, devfs_read_super, 0); +static DECLARE_FSTYPE (devfs_fs_type, DEVFS_NAME, devfs_read_super, 0); /* File operations for devfsd follow */ @@ -3308,7 +3337,7 @@ static int devfsd_ioctl (struct inode *inode, struct file *file, doesn't matter who gets in first, as long as only one gets it */ if (fs_info->devfsd_task == NULL) { -#ifdef __SMP__ +#ifdef CONFIG_SMP /* Looks like no-one has it: check again and grab, with interrupts disabled */ __cli (); @@ -3318,7 +3347,7 @@ static int devfsd_ioctl (struct inode *inode, struct file *file, fs_info->devfsd_event_mask = 0; /* Temporary disable */ fs_info->devfsd_task = current; } -#ifdef __SMP__ +#ifdef CONFIG_SMP __sti (); #endif } @@ -3392,7 +3421,7 @@ void __init mount_devfs_fs (void) { int err; extern long do_sys_mount (char *dev_name, char *dir_name, - char * type, int flags, void * data); + char *type, int flags, void *data); if ( (boot_options & OPTION_NOMOUNT) ) return; err = do_sys_mount ("none", "/dev", "devfs", 0, ""); |