diff options
author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-05-17 10:03:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-05-17 10:03:34 -0700 |
commit | fa82a1dad8713f50233150710637981776dcdf3a (patch) | |
tree | 37a452aed9bb5092eb8d53f1befe6f50bfad4ad9 | |
parent | 7dbe32bed2b9103e744ced54d3f3076e5f01028e (diff) | |
parent | a68d9759bd527662bd605a6462a75f3a59907286 (diff) | |
download | history-fa82a1dad8713f50233150710637981776dcdf3a.tar.gz |
Merge bk://bkbits.ras.ucalgary.ca/rgooch-2.5v2.5.16
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r-- | Documentation/filesystems/devfs/ChangeLog | 19 | ||||
-rw-r--r-- | drivers/char/misc.c | 11 | ||||
-rw-r--r-- | fs/devfs/base.c | 119 | ||||
-rw-r--r-- | fs/devfs/util.c | 18 |
4 files changed, 108 insertions, 59 deletions
diff --git a/Documentation/filesystems/devfs/ChangeLog b/Documentation/filesystems/devfs/ChangeLog index 4c4ddd9d2758c..1db800e739c77 100644 --- a/Documentation/filesystems/devfs/ChangeLog +++ b/Documentation/filesystems/devfs/ChangeLog @@ -1912,3 +1912,22 @@ Changes for patch v210 Thanks to Anton Blanchard <anton@samba.org> - Updated README from master HTML file +=============================================================================== +Changes for patch v211 + +- Do not put miscellaneous character devices in /dev/misc if they + specify their own directory (i.e. contain a '/' character) + +- Copied macro for error messages from fs/devfs/base.c to + fs/devfs/util.c and made use of this macro + +- Removed 2.4.x compatibility code from fs/devfs/base.c +=============================================================================== +Changes for patch v212 + +- Added BKL to <devfs_open> because drivers still need it +=============================================================================== +Changes for patch v213 + +- Protected <scan_dir_for_removable> and <get_removable_partition> + from changing directory contents diff --git a/drivers/char/misc.c b/drivers/char/misc.c index bb45e919fc01e..e410c4a65a79b 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -170,7 +170,7 @@ static struct file_operations misc_fops = { int misc_register(struct miscdevice * misc) { - static devfs_handle_t devfs_handle; + static devfs_handle_t devfs_handle, dir; struct miscdevice *c; if (misc->next || misc->prev) @@ -201,11 +201,12 @@ int misc_register(struct miscdevice * misc) misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); if (!devfs_handle) devfs_handle = devfs_mk_dir (NULL, "misc", NULL); + dir = strchr (misc->name, '/') ? NULL : devfs_handle; misc->devfs_handle = - devfs_register (devfs_handle, misc->name, DEVFS_FL_NONE, - MISC_MAJOR, misc->minor, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, - misc->fops, NULL); + devfs_register (dir, misc->name, DEVFS_FL_NONE, + MISC_MAJOR, misc->minor, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, + misc->fops, NULL); /* * Add it to the front, so that later devices can "override" diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 862f7486cc959..f6d4c7125ebfd 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -620,6 +620,19 @@ unlock_kernel() due to recent VFS locking changes. BKL isn't required in devfs. v1.13 + 20020428 Richard Gooch <rgooch@atnf.csiro.au> + Removed 2.4.x compatibility code. + v1.14 + 20020510 Richard Gooch <rgooch@atnf.csiro.au> + Added BKL to <devfs_open> because drivers still need it. + v1.15 + 20020512 Richard Gooch <rgooch@atnf.csiro.au> + Protected <scan_dir_for_removable> and <get_removable_partition> + from changing directory contents. + v1.16 + 20020514 Richard Gooch <rgooch@atnf.csiro.au> + Minor cleanup of <scan_dir_for_removable>. + v1.17 */ #include <linux/types.h> #include <linux/errno.h> @@ -652,7 +665,7 @@ #include <asm/bitops.h> #include <asm/atomic.h> -#define DEVFS_VERSION "1.13 (20020406)" +#define DEVFS_VERSION "1.17 (20020514)" #define DEVFS_NAME "devfs" @@ -1400,16 +1413,8 @@ static void free_dentry (struct devfs_entry *de) static int is_devfsd_or_child (struct fs_info *fs_info) { - struct task_struct *p; - if (current == fs_info->devfsd_task) return (TRUE); if (current->pgrp == fs_info->devfsd_pgrp) return (TRUE); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,1) - for (p = current->p_opptr; p != &init_task; p = p->p_opptr) - { - if (p == fs_info->devfsd_task) return (TRUE); - } -#endif return (FALSE); } /* End Function is_devfsd_or_child */ @@ -1829,16 +1834,6 @@ devfs_handle_t devfs_mk_dir (devfs_handle_t dir, const char *name, void *info) de->info = info; if ( ( err = _devfs_append_entry (dir, de, FALSE, &old) ) != 0 ) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,1) - if ( old && S_ISDIR (old->mode) ) - { - PRINTK ("(%s): using old entry in dir: %p \"%s\"\n", - name, dir, dir->name); - old->vfs_deletable = FALSE; - devfs_put (dir); - return old; - } -#endif PRINTK ("(%s): could not append to dir: %p \"%s\", err: %d\n", name, dir, dir->name, err); devfs_put (old); @@ -2427,6 +2422,9 @@ static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info, * @de: The device. * * Returns 1 if the media was changed, else 0. + * + * This function may block, and may indirectly cause the parent directory + * contents to be changed due to partition re-reading. */ static int check_disc_changed (struct devfs_entry *de) @@ -2461,19 +2459,29 @@ out: /** * scan_dir_for_removable - Scan a directory for removable media devices and check media. * @dir: The directory. + * + * This function may block, and may indirectly cause the directory + * contents to be changed due to partition re-reading. The directory will + * be locked for reading. */ static void scan_dir_for_removable (struct devfs_entry *dir) { struct devfs_entry *de; - if (dir->u.dir.num_removable < 1) return; - for (de = dir->u.dir.first; de != NULL; de = de->next) + read_lock (&dir->u.dir.lock); + if (dir->u.dir.num_removable < 1) de = NULL; + else { - if ( !S_ISBLK (de->mode) ) continue; - if (!de->u.fcb.removable) continue; - check_disc_changed (de); + for (de = dir->u.dir.first; de != NULL; de = de->next) + { + if (S_ISBLK (de->mode) && de->u.fcb.removable) break; + } + devfs_get (de); } + read_unlock (&dir->u.dir.lock); + if (de) check_disc_changed (de); + devfs_put (de); } /* End Function scan_dir_for_removable */ /** @@ -2483,25 +2491,37 @@ static void scan_dir_for_removable (struct devfs_entry *dir) * @namelen: The number of characters in <<name>>. * * Returns 1 if the media was changed, else 0. + * + * This function may block, and may indirectly cause the directory + * contents to be changed due to partition re-reading. The directory must + * be locked for reading upon entry, and will be unlocked upon exit. */ static int get_removable_partition (struct devfs_entry *dir, const char *name, unsigned int namelen) { + int retval; struct devfs_entry *de; + if (dir->u.dir.num_removable < 1) + { + read_unlock (&dir->u.dir.lock); + return 0; + } for (de = dir->u.dir.first; de != NULL; de = de->next) { - if ( !S_ISBLK (de->mode) ) continue; - if (!de->u.fcb.removable) continue; - if (strcmp (de->name, "disc") == 0) return check_disc_changed (de); + if (!S_ISBLK (de->mode) || !de->u.fcb.removable) continue; + if (strcmp (de->name, "disc") == 0) break; /* Support for names where the partition is appended to the disc name */ if (de->namelen >= namelen) continue; - if (strncmp (de->name, name, de->namelen) != 0) continue; - return check_disc_changed (de); + if (strncmp (de->name, name, de->namelen) == 0) break; } - return 0; + devfs_get (de); + read_unlock (&dir->u.dir.lock); + retval = de ? check_disc_changed (de) : 0; + devfs_put (de); + return retval; } /* End Function get_removable_partition */ @@ -2739,15 +2759,22 @@ static int devfs_open (struct inode *inode, struct file *file) { file->f_op = &def_blk_fops; if (df->ops) inode->i_bdev->bd_op = df->ops; + err = def_blk_fops.open (inode, file); } - else file->f_op = fops_get ( (struct file_operations *) df->ops ); - if (file->f_op) - err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0; else { - /* Fallback to legacy scheme */ - if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file); - else err = -ENODEV; + file->f_op = fops_get ( (struct file_operations *) df->ops ); + if (file->f_op) + { + lock_kernel (); + err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0; + unlock_kernel (); + } + else + { /* Fallback to legacy scheme */ + if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file); + else err = -ENODEV; + } } if (err < 0) return err; /* Open was successful */ @@ -2947,15 +2974,17 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) if (parent == NULL) return ERR_PTR (-ENOENT); read_lock (&parent->u.dir.lock); de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len); - read_unlock (&parent->u.dir.lock); - if ( (de == NULL) && (parent->u.dir.num_removable > 0) && - get_removable_partition (parent, dentry->d_name.name, - dentry->d_name.len) ) - { - read_lock (&parent->u.dir.lock); - de = _devfs_search_dir (parent, dentry->d_name.name, - dentry->d_name.len); - read_unlock (&parent->u.dir.lock); + if (de) read_unlock (&parent->u.dir.lock); + else + { /* Try re-reading the partition (media may have changed) */ + if ( get_removable_partition (parent, dentry->d_name.name, + dentry->d_name.len) ) /* Unlocks */ + { /* Media did change */ + read_lock (&parent->u.dir.lock); + de = _devfs_search_dir (parent, dentry->d_name.name, + dentry->d_name.len); + read_unlock (&parent->u.dir.lock); + } } lookup_info.de = de; init_waitqueue_head (&lookup_info.wait_queue); diff --git a/fs/devfs/util.c b/fs/devfs/util.c index f9c955f6b61c3..9431e7d903b2b 100644 --- a/fs/devfs/util.c +++ b/fs/devfs/util.c @@ -56,6 +56,8 @@ Made major bitfield type and initialiser 64 bit safe. 20020413 Richard Gooch <rgooch@atnf.csiro.au> Fixed shift warning on 64 bit machines. + 20020428 Richard Gooch <rgooch@atnf.csiro.au> + Copied and used macro for error messages from fs/devfs/base.c */ #include <linux/module.h> #include <linux/init.h> @@ -65,6 +67,9 @@ #include <asm/bitops.h> +#define PRINTK(format, args...) \ + {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);} + /* Private functions follow */ @@ -209,9 +214,7 @@ void devfs_dealloc_major (char type, int major) spin_lock (&list->lock); was_set = __test_and_clear_bit (major, list->bits); spin_unlock (&list->lock); - if (!was_set) - printk (KERN_ERR __FUNCTION__ "(): major %d was already free\n", - major); + if (!was_set) PRINTK ("(): major %d was already free\n", major); } /* End Function devfs_dealloc_major */ EXPORT_SYMBOL(devfs_dealloc_major); @@ -339,12 +342,11 @@ void devfs_dealloc_devnum (char type, kdev_t devnum) if (was_set) list->none_free = 0; up (semaphore); if (!was_set) - printk ( KERN_ERR __FUNCTION__ "(): device %s was already free\n", - kdevname (devnum) ); + PRINTK ( "(): device %s was already free\n", kdevname (devnum) ); return; } up (semaphore); - printk ( KERN_ERR __FUNCTION__ "(): major for %s not previously allocated\n", + PRINTK ( "(): major for %s not previously allocated\n", kdevname (devnum) ); } /* End Function devfs_dealloc_devnum */ EXPORT_SYMBOL(devfs_dealloc_devnum); @@ -419,8 +421,6 @@ void devfs_dealloc_unique_number (struct unique_numspace *space, int number) was_set = __test_and_clear_bit (number, space->bits); if (was_set) ++space->num_free; up (&space->semaphore); - if (!was_set) - printk (KERN_ERR __FUNCTION__ "(): number %d was already free\n", - number); + if (!was_set) PRINTK ("(): number %d was already free\n", number); } /* End Function devfs_dealloc_unique_number */ EXPORT_SYMBOL(devfs_dealloc_unique_number); |