diff -urN linux-2.4.18-pre3/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog --- linux-2.4.18-pre3/Documentation/filesystems/devfs/ChangeLog Fri Dec 21 10:41:53 2001 +++ linux/Documentation/filesystems/devfs/ChangeLog Sun Jan 13 18:53:59 2002 @@ -1845,3 +1845,28 @@ - Improved debugging messages - Fixed unregister bugs in drivers/md/lvm-fs.c +=============================================================================== +Changes for patch v199.6 + +- Corrected (made useful) debugging message in + +- Moved in to + +- Fixed drivers/md/lvm-fs.c to create "lvm" entry + +- Added magic number to guard against scribbling drivers + +- Only return old entry in if a directory + +- Defined macros for error and debug messages + +- Updated README from master HTML file +=============================================================================== +Changes for patch v199.7 + +- Unregister /dev/root symlink prior to creating second one (for + initrd) + +- Added support for multiple Compaq cpqarray controllers + +- Fixed (rare, old) race in diff -urN linux-2.4.18-pre3/Documentation/filesystems/devfs/README linux/Documentation/filesystems/devfs/README --- linux-2.4.18-pre3/Documentation/filesystems/devfs/README Fri Dec 21 10:41:53 2001 +++ linux/Documentation/filesystems/devfs/README Sun Jan 13 18:53:59 2002 @@ -3,7 +3,7 @@ Linux Devfs (Device File System) FAQ Richard Gooch -13-DEC-2001 +21-DEC-2001 ----------------------------------------------------------------------------- @@ -68,6 +68,7 @@ Alternatives to devfs What I don't like about devfs How to report bugs +Strange kernel messages Other resources @@ -1475,6 +1476,7 @@ Alternatives to devfs What I don't like about devfs How to report bugs +Strange kernel messages @@ -1789,6 +1791,42 @@ a bug to report, you should also read http://www.chiark.greenend.org.uk/~sgtatham/bugs.html. + + +Strange kernel messages + +You may see devfs-related messages in your kernel logs. Below are some +messages and what they mean (and what you should do about them, if +anything). + + + +devfs_register(fred): could not append to parent, err: -17 + +You need to check what the error code means, but usually 17 means +EEXIST. This means that a driver attempted to create an entry +fred in a directory, but there already was an entry with that +name. This is often caused by flawed boot scripts which untar a bunch +of inodes into /dev, as a way to restore permissions. This +message is harmless, as the device nodes will still +provide access to the driver (unless you use the devfs=only +boot option, which is only for dedicated souls:-). If you want to get +rid of these annoying messages, upgrade to devfsd-v1.3.20 and use the +recommended RESTORE directive to restore permissions. + + +devfs_mk_dir(bill): using old entry in dir: c1808724 "" + +This is similar to the message above, except that a driver attempted +to create a directory named bill, and the parent directory +has an entry with the same name. In this case, to ensure that drivers +continue to work properly, the old entry is re-used and given to the +driver. In 2.5 kernels, the driver is given a NULL entry, and thus, +under rare circumstances, may not create the require device nodes. +The solution is the same as above. + + + ----------------------------------------------------------------------------- diff -urN linux-2.4.18-pre3/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c --- linux-2.4.18-pre3/drivers/block/cpqarray.c Fri Nov 9 15:28:46 2001 +++ linux/drivers/block/cpqarray.c Sun Jan 13 18:53:59 2002 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,7 @@ static int nr_ctlr; static ctlr_info_t *hba[MAX_CTLR]; +static devfs_handle_t de_arr[MAX_CTLR][NWD]; static int eisa[8]; @@ -338,6 +340,7 @@ del_gendisk(&ida_gendisk[i]); } + devfs_unregister(devfs_find_handle(NULL, "ida", 0, 0, 0, 0)); remove_proc_entry("cpqarray", proc_root_driver); kfree(ida); kfree(ida_sizes); @@ -540,6 +543,8 @@ ida_gendisk[i].part = ida + (i*256); ida_gendisk[i].sizes = ida_sizes + (i*256); ida_gendisk[i].nr_real = 0; + ida_gendisk[i].de_arr = de_arr[i]; + ida_gendisk[i].fops = &ida_fops; /* Get on the disk list */ add_gendisk(&ida_gendisk[i]); @@ -1881,6 +1886,14 @@ kfree(id_ldrive); return; + } + if (!de_arr[ctlr][log_unit]) { + char txt[16]; + + sprintf(txt, "ida/c%dd%d", ctlr, + log_unit); + de_arr[ctlr][log_unit] = + devfs_mk_dir(NULL, txt, NULL); } info_p->phys_drives = sense_config_buf->ctlr_phys_drv; diff -urN linux-2.4.18-pre3/drivers/md/lvm-fs.c linux/drivers/md/lvm-fs.c --- linux-2.4.18-pre3/drivers/md/lvm-fs.c Fri Dec 21 10:41:54 2001 +++ linux/drivers/md/lvm-fs.c Sun Jan 13 18:53:59 2002 @@ -65,9 +65,7 @@ static void _show_uuid(const char *src, char *b, char *e); -#if 0 static devfs_handle_t lvm_devfs_handle; -#endif static devfs_handle_t vg_devfs_handle[MAX_VG]; static devfs_handle_t ch_devfs_handle[MAX_VG]; static devfs_handle_t lv_devfs_handle[MAX_LV]; @@ -81,13 +79,11 @@ void __init lvm_init_fs() { struct proc_dir_entry *pde; -/* User-space has already registered this */ -#if 0 + /* Must create device node. Think about "devfs=only" situation */ lvm_devfs_handle = devfs_register( 0 , "lvm", 0, LVM_CHAR_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &lvm_chr_fops, NULL); -#endif lvm_proc_dir = create_proc_entry(LVM_DIR, S_IFDIR, &proc_root); if (lvm_proc_dir) { lvm_proc_vg_subdir = create+proc_entry(LVM_VG_SUBDIR, S_IFDIR @@ -99,9 +95,7 @@ } void lvm_fin_fs() { -#if 0 devfs_unregister (lvm_devfs_handle); -#endif remove_proc_entry(LVM_GLOBAL, lvm_proc_dir); remove_proc_entry(LVM_VG_SUBDIR, lvm_proc_dir); remove_proc_entry(LVM_DIR, &proc_root); diff -urN linux-2.4.18-pre3/fs/devfs/base.c linux/fs/devfs/base.c --- linux-2.4.18-pre3/fs/devfs/base.c Fri Dec 21 10:41:55 2001 +++ linux/fs/devfs/base.c Sun Jan 13 18:53:59 2002 @@ -592,6 +592,18 @@ Added poisoning to . Improved debugging messages. v1.7 + 20011221 Richard Gooch + Corrected (made useful) debugging message in . + Moved in to + 20011224 Richard Gooch + Added magic number to guard against scribbling drivers. + 20011226 Richard Gooch + Only return old entry in if a directory. + Defined macros for error and debug messages. + v1.8 + 20020113 Richard Gooch + Fixed (rare, old) race in . + v1.9 */ #include #include @@ -624,7 +636,7 @@ #include #include -#define DEVFS_VERSION "1.7 (20011216)" +#define DEVFS_VERSION "1.9 (20020113)" #define DEVFS_NAME "devfs" @@ -633,6 +645,7 @@ #define STRING_LENGTH 256 #define FAKE_BLOCK_SIZE 1024 #define POISON_PTR ( *(void **) poison_array ) +#define MAGIC_VALUE 0x327db823 #ifndef TRUE # define TRUE 1 @@ -669,9 +682,28 @@ #define OPTION_MOUNT 0x01 #define OPTION_ONLY 0x02 -#define OOPS(format, args...) {printk (format, ## args); \ - printk ("Forcing Oops\n"); \ - BUG();} +#define PRINTK(format, args...) \ + {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);} + +#define OOPS(format, args...) \ + {printk (KERN_CRIT "%s" format, __FUNCTION__ , ## args); \ + printk ("Forcing Oops\n"); \ + BUG();} + +#ifdef CONFIG_DEVFS_DEBUG +# define VERIFY_ENTRY(de) \ + {if ((de) && (de)->magic_number != MAGIC_VALUE) \ + OOPS ("(%p): bad magic value: %x\n", (de), (de)->magic_number);} +# define WRITE_ENTRY_MAGIC(de,magic) (de)->magic_number = (magic) +# define DPRINTK(flag, format, args...) \ + {if (devfs_debug & flag) \ + printk (KERN_INFO "%s" format, __FUNCTION__ , ## args);} +#else +# define VERIFY_ENTRY(de) +# define WRITE_ENTRY_MAGIC(de,magic) +# define DPRINTK(flag, format, args...) +#endif + struct directory_type { @@ -728,6 +760,9 @@ struct devfs_entry { +#ifdef CONFIG_DEVFS_DEBUG + unsigned int magic_number; +#endif void *info; atomic_t refcount; /* When this drops to zero, it's unused */ union @@ -837,6 +872,7 @@ static struct devfs_entry *devfs_get (struct devfs_entry *de) { + VERIFY_ENTRY (de); if (de) atomic_inc (&de->refcount); return de; } /* End Function devfs_get */ @@ -849,17 +885,13 @@ void devfs_put (devfs_handle_t de) { if (!de) return; - if (de->info == POISON_PTR) - OOPS ("%s: devfs_put(%p): poisoned pointer\n", DEVFS_NAME, de); + VERIFY_ENTRY (de); + if (de->info == POISON_PTR) OOPS ("(%p): poisoned pointer\n", de); if ( !atomic_dec_and_test (&de->refcount) ) return; - if (de == root_entry) - OOPS ("%s: devfs_put(): root entry being freed\n", DEVFS_NAME); -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_FREE) - printk ("%s: devfs_put(%s): de: %p, parent: %p \"%s\"\n", - DEVFS_NAME, de->name, de, de->parent, - de->parent ? de->parent->name : "no parent"); -#endif + if (de == root_entry) OOPS ("(%p): root entry being freed\n", de); + DPRINTK (DEBUG_FREE, "(%s): de: %p, parent: %p \"%s\"\n", + de->name, de, de->parent, + de->parent ? de->parent->name : "no parent"); if ( S_ISLNK (de->mode) ) kfree (de->u.symlink.linkname); if ( ( S_ISCHR (de->mode) || S_ISBLK (de->mode) ) && de->u.fcb.autogen ) { @@ -868,6 +900,7 @@ MKDEV (de->u.fcb.u.device.major, de->u.fcb.u.device.minor) ); } + WRITE_ENTRY_MAGIC (de, 0); #ifdef CONFIG_DEVFS_DEBUG spin_lock (&stat_lock); --stat_num_entries; @@ -898,7 +931,7 @@ if ( !S_ISDIR (dir->mode) ) { - printk ("%s: search_dir(%s): not a directory\n", DEVFS_NAME,dir->name); + PRINTK ("(%s): not a directory\n", dir->name); return NULL; } for (curr = dir->u.dir.first; curr != NULL; curr = curr->next) @@ -940,6 +973,7 @@ spin_unlock (&counter_lock); if (name) memcpy (new->name, name, namelen); new->namelen = namelen; + WRITE_ENTRY_MAGIC (new, MAGIC_VALUE); #ifdef CONFIG_DEVFS_DEBUG spin_lock (&stat_lock); ++stat_num_entries; @@ -972,8 +1006,7 @@ if (old_de) *old_de = NULL; if ( !S_ISDIR (dir->mode) ) { - printk ("%s: append_entry(%s): dir: \"%s\" is not a directory\n", - DEVFS_NAME, de->name, dir->name); + PRINTK ("(%s): dir: \"%s\" is not a directory\n", de->name, dir->name); devfs_put (de); return -ENOTDIR; } @@ -1143,15 +1176,13 @@ if ( ( *dir = _devfs_make_parent_for_leaf (*dir, name, namelen, &leaf_pos) ) == NULL ) { - printk ("%s: prepare_leaf(%s): could not create parent path\n", - DEVFS_NAME, name); + PRINTK ("(%s): could not create parent path\n", name); return NULL; } if ( ( de = _devfs_alloc_entry (name + leaf_pos, namelen - leaf_pos,mode) ) == NULL ) { - printk ("%s: prepare_leaf(%s): could not allocate entry\n", - DEVFS_NAME, name); + PRINTK ("(%s): could not allocate entry\n", name); devfs_put (*dir); return NULL; } @@ -1198,7 +1229,7 @@ /** - * find_by_dev - Find a devfs entry in a directory. + * _devfs_find_by_dev - Find a devfs entry in a directory. * @dir: The directory where to search * @major: The major number to search for. * @minor: The minor number to search for. @@ -1209,9 +1240,9 @@ * devfs_get() is performed. */ -static struct devfs_entry *find_by_dev (struct devfs_entry *dir, - unsigned int major, unsigned int minor, - char type) +static struct devfs_entry *_devfs_find_by_dev (struct devfs_entry *dir, + unsigned int major, + unsigned int minor, char type) { struct devfs_entry *entry, *de; @@ -1219,7 +1250,7 @@ if (dir == NULL) return NULL; if ( !S_ISDIR (dir->mode) ) { - printk ("%s: find_by_dev(): not a directory\n", DEVFS_NAME); + PRINTK ("(%p): not a directory\n", dir); devfs_put (dir); return NULL; } @@ -1244,7 +1275,7 @@ for (entry = dir->u.dir.first; entry != NULL; entry = entry->next) { if ( !S_ISDIR (entry->mode) ) continue; - de = find_by_dev (entry, major, minor, type); + de = _devfs_find_by_dev (entry, major, minor, type); if (de) { read_unlock (&dir->u.dir.lock); @@ -1255,11 +1286,11 @@ read_unlock (&dir->u.dir.lock); devfs_put (dir); return NULL; -} /* End Function find_by_dev */ +} /* End Function _devfs_find_by_dev */ /** - * find_entry - Find a devfs entry. + * _devfs_find_entry - Find a devfs entry. * @dir: The handle to the parent devfs directory entry. If this is %NULL the * name is relative to the root of the devfs. * @name: The name of the entry. This may be %NULL. @@ -1275,9 +1306,11 @@ * devfs_get() is performed. */ -static struct devfs_entry *find_entry (devfs_handle_t dir, const char *name, - unsigned int major, unsigned int minor, - char type, int traverse_symlink) +static struct devfs_entry *_devfs_find_entry (devfs_handle_t dir, + const char *name, + unsigned int major, + unsigned int minor, + char type, int traverse_symlink) { struct devfs_entry *entry; @@ -1290,14 +1323,14 @@ /* Skip leading pathname component */ if (namelen < 2) { - printk ("%s: find_entry(%s): too short\n", DEVFS_NAME, name); + PRINTK ("(%s): too short\n", name); return NULL; } for (++name, --namelen; (*name != '/') && (namelen > 0); ++name, --namelen); if (namelen < 2) { - printk ("%s: find_entry(%s): too short\n", DEVFS_NAME, name); + PRINTK ("(%s): too short\n", name); return NULL; } ++name; @@ -1308,12 +1341,13 @@ } /* Have to search by major and minor: slow */ if ( (major == 0) && (minor == 0) ) return NULL; - return find_by_dev (root_entry, major, minor, type); -} /* End Function find_entry */ + return _devfs_find_by_dev (root_entry, major, minor, type); +} /* End Function _devfs_find_entry */ static struct devfs_entry *get_devfs_entry_from_vfs_inode (struct inode *inode) { if (inode == NULL) return NULL; + VERIFY_ENTRY ( (struct devfs_entry *) inode->u.generic_ip ); return inode->u.generic_ip; } /* End Function get_devfs_entry_from_vfs_inode */ @@ -1495,7 +1529,7 @@ if (name == NULL) { - printk ("%s: devfs_register(): NULL name pointer\n", DEVFS_NAME); + PRINTK ("(): NULL name pointer\n"); return NULL; } if (ops == NULL) @@ -1503,23 +1537,19 @@ if ( S_ISBLK (mode) ) ops = (void *) get_blkfops (major); if (ops == NULL) { - printk ("%s: devfs_register(%s): NULL ops pointer\n", - DEVFS_NAME, name); + PRINTK ("(%s): NULL ops pointer\n", name); return NULL; } - printk ("%s: devfs_register(%s): NULL ops, got %p from major table\n", - DEVFS_NAME, name, ops); + PRINTK ("(%s): NULL ops, got %p from major table\n", name, ops); } if ( S_ISDIR (mode) ) { - printk("%s: devfs_register(%s): creating directories is not allowed\n", - DEVFS_NAME, name); + PRINTK ("(%s): creating directories is not allowed\n", name); return NULL; } if ( S_ISLNK (mode) ) { - printk ("%s: devfs_register(%s): creating symlinks is not allowed\n", - DEVFS_NAME, name); + PRINTK ("(%s): creating symlinks is not allowed\n", name); return NULL; } if ( ( S_ISCHR (mode) || S_ISBLK (mode) ) && @@ -1527,8 +1557,8 @@ { if ( ( devnum = devfs_alloc_devnum (devtype) ) == NODEV ) { - printk ("%s: devfs_register(%s): exhausted %s device numbers\n", - DEVFS_NAME, name, S_ISCHR (mode) ? "char" : "block"); + PRINTK ("(%s): exhausted %s device numbers\n", + name, S_ISCHR (mode) ? "char" : "block"); return NULL; } major = MAJOR (devnum); @@ -1536,8 +1566,7 @@ } if ( ( de = _devfs_prepare_leaf (&dir, name, mode) ) == NULL ) { - printk ("%s: devfs_register(%s): could not prepare leaf\n", - DEVFS_NAME, name); + PRINTK ("(%s): could not prepare leaf\n", name); if (devnum != NODEV) devfs_dealloc_devnum (devtype, devnum); return NULL; } @@ -1549,8 +1578,7 @@ } else if ( !S_ISREG (mode) ) { - printk ("%s: devfs_register(%s): illegal mode: %x\n", - DEVFS_NAME, name, mode); + PRINTK ("(%s): illegal mode: %x\n", name, mode); devfs_put (de); devfs_put (dir); return (NULL); @@ -1574,17 +1602,13 @@ if ( ( err = _devfs_append_entry (dir, de, de->u.fcb.removable, NULL) ) != 0 ) { - printk("%s: devfs_register(%s): could not append to parent, err: %d\n", - DEVFS_NAME, name, err); + PRINTK ("(%s): could not append to parent, err: %d\n", name, err); devfs_put (dir); if (devnum != NODEV) devfs_dealloc_devnum (devtype, devnum); return NULL; } -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_REGISTER) - printk ("%s: devfs_register(%s): de: %p dir: %p \"%s\" pp: %p\n", - DEVFS_NAME, name, de, dir, dir->name, dir->parent); -#endif + DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\" pp: %p\n", + name, de, dir, dir->name, dir->parent); devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT); devfs_put (dir); return de; @@ -1620,7 +1644,7 @@ /** - * unregister - Unregister a device entry from it's parent. + * _devfs_unregister - Unregister a device entry from it's parent. * @dir: The parent directory. * @de: The entry to unregister. * @@ -1628,7 +1652,7 @@ * unlocked by this function. */ -static void unregister (struct devfs_entry *dir, struct devfs_entry *de) +static void _devfs_unregister (struct devfs_entry *dir, struct devfs_entry *de) { int unhooked = _devfs_unhook (de); @@ -1647,17 +1671,14 @@ write_lock (&de->u.dir.lock); de->u.dir.no_more_additions = TRUE; child = de->u.dir.first; - unregister (de, child); + VERIFY_ENTRY (child); + _devfs_unregister (de, child); if (!child) break; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_UNREGISTER) - printk ( "%s: unregister(%s): child: %p refcount: %d\n", - DEVFS_NAME, child->name, child, - atomic_read (&de->refcount) ); -#endif + DPRINTK (DEBUG_UNREGISTER, "(%s): child: %p refcount: %d\n", + child->name, child, atomic_read (&child->refcount) ); devfs_put (child); } -} /* End Function unregister */ +} /* End Function _devfs_unregister */ /** @@ -1668,14 +1689,12 @@ void devfs_unregister (devfs_handle_t de) { + VERIFY_ENTRY (de); if ( (de == NULL) || (de->parent == NULL) ) return; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_UNREGISTER) - printk ( "%s: devfs_unregister(%s): de: %p refcount: %d\n", - DEVFS_NAME, de->name, de, atomic_read (&de->refcount) ); -#endif + DPRINTK (DEBUG_UNREGISTER, "(%s): de: %p refcount: %d\n", + de->name, de, atomic_read (&de->refcount) ); write_lock (&de->parent->u.dir.lock); - unregister (de->parent, de); + _devfs_unregister (de->parent, de); devfs_put (de); } /* End Function devfs_unregister */ @@ -1691,16 +1710,12 @@ if (handle != NULL) *handle = NULL; if (name == NULL) { - printk ("%s: devfs_do_symlink(): NULL name pointer\n", DEVFS_NAME); + PRINTK ("(): NULL name pointer\n"); return -EINVAL; } -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_REGISTER) - printk ("%s: devfs_do_symlink(%s)\n", DEVFS_NAME, name); -#endif if (link == NULL) { - printk ("%s: devfs_do_symlink(): NULL link pointer\n", DEVFS_NAME); + PRINTK ("(%s): NULL link pointer\n", name); return -EINVAL; } linklength = strlen (link); @@ -1711,8 +1726,7 @@ if ( ( de = _devfs_prepare_leaf (&dir, name, S_IFLNK | S_IRUGO | S_IXUGO) ) == NULL ) { - printk ("%s: devfs_do_symlink(%s): could not prepare leaf\n", - DEVFS_NAME, name); + PRINTK ("(%s): could not prepare leaf\n", name); kfree (newlink); return -ENOTDIR; } @@ -1722,8 +1736,7 @@ de->u.symlink.length = linklength; if ( ( err = _devfs_append_entry (dir, de, FALSE, NULL) ) != 0 ) { - printk ("%s: devfs_do_symlink(%s): could not append to parent, err: %d\n", - DEVFS_NAME, name, err); + PRINTK ("(%s): could not append to parent, err: %d\n", name, err); devfs_put (dir); return err; } @@ -1758,6 +1771,7 @@ devfs_handle_t de; if (handle != NULL) *handle = NULL; + DPRINTK (DEBUG_REGISTER, "(%s)\n", name); err = devfs_do_symlink (dir, name, flags, link, &de, info); if (err) return err; if (handle != NULL) *handle = de; @@ -1787,39 +1801,35 @@ if (name == NULL) { - printk ("%s: devfs_mk_dir(): NULL name pointer\n", DEVFS_NAME); + PRINTK ("(): NULL name pointer\n"); return NULL; } if ( ( de = _devfs_prepare_leaf (&dir, name, MODE_DIR) ) == NULL ) { - printk ("%s: devfs_mk_dir(%s): could not prepare leaf\n", - DEVFS_NAME, name); + PRINTK ("(%s): could not prepare leaf\n", name); return NULL; } de->info = info; if ( ( err = _devfs_append_entry (dir, de, FALSE, &old) ) != 0 ) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,1) - if (old) + if ( old && S_ISDIR (old->mode) ) { - printk("%s: devfs_mk_dir(%s): using old entry in dir: %p \"%s\"\n", - DEVFS_NAME, name, dir, dir->name); + PRINTK ("(%s): using old entry in dir: %p \"%s\"\n", + name, dir, dir->name); old->vfs_created = FALSE; devfs_put (dir); return old; } #endif - printk ("%s: devfs_mk_dir(%s): could not append to dir: %p \"%s\", err: %d\n", - DEVFS_NAME, name, dir, dir->name, err); + PRINTK ("(%s): could not append to dir: %p \"%s\", err: %d\n", + name, dir, dir->name, err); devfs_put (old); devfs_put (dir); return NULL; } -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_REGISTER) - printk ("%s: devfs_mk_dir(%s): de: %p dir: %p \"%s\"\n", - DEVFS_NAME, name, de, dir, dir->name); -#endif + DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\"\n", + name, de, dir, dir->name); devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, 0); devfs_put (dir); return de; @@ -1850,7 +1860,7 @@ char type, int traverse_symlinks) { if ( (name != NULL) && (name[0] == '\0') ) name = NULL; - return find_entry (dir, name, major, minor, type, traverse_symlinks); + return _devfs_find_entry (dir, name, major, minor, type,traverse_symlinks); } /* End Function devfs_get_handle */ @@ -1881,6 +1891,7 @@ unsigned int fl = 0; if (de == NULL) return -EINVAL; + VERIFY_ENTRY (de); if (de->hide) fl |= DEVFS_FL_HIDE; if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) ) { @@ -1904,11 +1915,8 @@ int devfs_set_flags (devfs_handle_t de, unsigned int flags) { if (de == NULL) return -EINVAL; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_SET_FLAGS) - printk ("%s: devfs_set_flags(): de->name: \"%s\"\n", - DEVFS_NAME, de->name); -#endif + VERIFY_ENTRY (de); + DPRINTK (DEBUG_SET_FLAGS, "(%s): flags: %x\n", de->name, flags); de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE; if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) ) { @@ -1932,6 +1940,7 @@ unsigned int *minor) { if (de == NULL) return -EINVAL; + VERIFY_ENTRY (de); if ( S_ISDIR (de->mode) ) return -EISDIR; if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) ) return -EINVAL; if (major != NULL) *major = de->u.fcb.u.device.major; @@ -1972,6 +1981,7 @@ #define NAMEOF(de) ( (de)->mode ? (de)->name : (de)->u.name ) if (de == NULL) return -EINVAL; + VERIFY_ENTRY (de); if (de->namelen >= buflen) return -ENAMETOOLONG; /* Must be first */ path[buflen - 1] = '\0'; if (de->parent == NULL) return buflen - 1; /* Don't prepend root */ @@ -2001,6 +2011,7 @@ struct module *owner; if (de == NULL) return NULL; + VERIFY_ENTRY (de); if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) ) return NULL; if (de->u.fcb.ops == NULL) return NULL; @@ -2031,6 +2042,7 @@ struct module *owner; if (de == NULL) return; + VERIFY_ENTRY (de); if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) ) return; if (de->u.fcb.ops == NULL) return; @@ -2052,6 +2064,7 @@ int devfs_set_file_size (devfs_handle_t de, unsigned long size) { if (de == NULL) return -EINVAL; + VERIFY_ENTRY (de); if ( !S_ISREG (de->mode) ) return -EINVAL; if (de->u.fcb.u.file.size == size) return 0; de->u.fcb.u.file.size = size; @@ -2071,6 +2084,7 @@ void *devfs_get_info (devfs_handle_t de) { if (de == NULL) return NULL; + VERIFY_ENTRY (de); return de->info; } /* End Function devfs_get_info */ @@ -2085,6 +2099,7 @@ int devfs_set_info (devfs_handle_t de, void *info) { if (de == NULL) return -EINVAL; + VERIFY_ENTRY (de); de->info = info; return 0; } /* End Function devfs_set_info */ @@ -2099,6 +2114,7 @@ devfs_handle_t devfs_get_parent (devfs_handle_t de) { if (de == NULL) return NULL; + VERIFY_ENTRY (de); return de->parent; } /* End Function devfs_get_parent */ @@ -2113,6 +2129,7 @@ devfs_handle_t devfs_get_first_child (devfs_handle_t de) { if (de == NULL) return NULL; + VERIFY_ENTRY (de); if ( !S_ISDIR (de->mode) ) return NULL; return de->u.dir.first; } /* End Function devfs_get_first_child */ @@ -2128,6 +2145,7 @@ devfs_handle_t devfs_get_next_sibling (devfs_handle_t de) { if (de == NULL) return NULL; + VERIFY_ENTRY (de); return de->next; } /* End Function devfs_get_next_sibling */ @@ -2143,14 +2161,15 @@ void devfs_auto_unregister (devfs_handle_t master, devfs_handle_t slave) { if (master == NULL) return; + VERIFY_ENTRY (master); + VERIFY_ENTRY (slave); if (master->slave != NULL) { /* Because of the dumbness of the layers above, ignore duplicates */ if (master->slave == slave) return; - printk ("%s: devfs_auto_unregister(): only one slave allowed\n", - DEVFS_NAME); - OOPS (" master: \"%s\" old slave: \"%s\" new slave: \"%s\"\n", - master->name, master->slave->name, slave->name); + PRINTK ("(%s): only one slave allowed\n", master->name); + OOPS ("(): old slave: \"%s\" new slave: \"%s\"\n", + master->slave->name, slave->name); } master->slave = slave; } /* End Function devfs_auto_unregister */ @@ -2166,6 +2185,7 @@ devfs_handle_t devfs_get_unregister_slave (devfs_handle_t master) { if (master == NULL) return NULL; + VERIFY_ENTRY (master); return master->slave; } /* End Function devfs_get_unregister_slave */ @@ -2181,6 +2201,7 @@ const char *devfs_get_name (devfs_handle_t de, unsigned int *namelen) { if (de == NULL) return NULL; + VERIFY_ENTRY (de); if (namelen != NULL) *namelen = de->namelen; return de->name; } /* End Function devfs_get_name */ @@ -2360,7 +2381,7 @@ * @buf: A working area that will be used. This must not go out of scope * until devfsd is idle again. * - * Returns 0 on success, else a negative error code. + * Returns 0 on success (event was queued), else a negative error code. */ static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info, @@ -2375,10 +2396,11 @@ buf->parent = parent; buf->namelen = namelen; buf->u.name = name; + WRITE_ENTRY_MAGIC (buf, MAGIC_VALUE); if ( !devfsd_notify_de (buf, DEVFSD_NOTIFY_LOOKUP, 0, current->euid, current->egid, fs_info, 0) ) return -ENOENT; - /* Possible success */ + /* Possible success: event has been queued */ return 0; } /* End Function try_modload */ @@ -2487,16 +2509,10 @@ if (retval != 0) return retval; retval = inode_setattr (inode, iattr); if (retval != 0) return retval; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_CHANGE) - { - printk ("%s: notify_change(%d): VFS inode: %p devfs_entry: %p\n", - DEVFS_NAME, (int) inode->i_ino, inode, de); - printk ("%s: mode: 0%o uid: %d gid: %d\n", - DEVFS_NAME, (int) inode->i_mode, - (int) inode->i_uid, (int) inode->i_gid); - } -#endif + DPRINTK (DEBUG_I_CHANGE, "(%d): VFS inode: %p devfs_entry: %p\n", + (int) inode->i_ino, inode, de); + DPRINTK (DEBUG_I_CHANGE, "(): mode: 0%o uid: %d gid: %d\n", + (int) inode->i_mode, (int) inode->i_uid, (int) inode->i_gid); /* Inode is not on hash chains, thus must save permissions here rather than in a write_inode() method */ if ( ( !S_ISREG (inode->i_mode) && !S_ISCHR (inode->i_mode) && @@ -2541,7 +2557,7 @@ /** - * get_vfs_inode - Get a VFS inode. + * _devfs_get_vfs_inode - Get a VFS inode. * @sb: The super block. * @de: The devfs inode. * @dentry: The dentry to register with the devfs inode. @@ -2550,9 +2566,9 @@ * performed if the inode is created. */ -static struct inode *get_vfs_inode (struct super_block *sb, - struct devfs_entry *de, - struct dentry *dentry) +static struct inode *_devfs_get_vfs_inode (struct super_block *sb, + struct devfs_entry *de, + struct dentry *dentry) { int is_fcb = FALSE; struct inode *inode; @@ -2560,8 +2576,7 @@ if (de->prev == de) return NULL; /* Quick check to see if unhooked */ if ( ( inode = new_inode (sb) ) == NULL ) { - printk ("%s: get_vfs_inode(%s): new_inode() failed, de: %p\n", - DEVFS_NAME, de->name, de); + PRINTK ("(%s): new_inode() failed, de: %p\n", de->name, de); return NULL; } if (de->parent) @@ -2578,11 +2593,8 @@ } inode->u.generic_ip = devfs_get (de); inode->i_ino = de->inode.ino; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_GET) - printk ("%s: get_vfs_inode(%d): VFS inode: %p devfs_entry: %p\n", - DEVFS_NAME, (int) inode->i_ino, inode, de); -#endif + DPRINTK (DEBUG_I_GET, "(%d): VFS inode: %p devfs_entry: %p\n", + (int) inode->i_ino, inode, de); inode->i_blocks = 0; inode->i_blksize = FAKE_BLOCK_SIZE; inode->i_op = &devfs_iops; @@ -2604,8 +2616,7 @@ if (!inode->i_bdev->bd_op && de->u.fcb.ops) inode->i_bdev->bd_op = de->u.fcb.ops; } - else printk ("%s: get_vfs_inode(%d): no block device from bdget()\n", - DEVFS_NAME, (int) inode->i_ino); + else PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino); is_fcb = TRUE; } else if ( S_ISFIFO (de->mode) ) inode->i_fop = &def_fifo_fops; @@ -2632,14 +2643,10 @@ inode->i_atime = de->inode.atime; inode->i_mtime = de->inode.mtime; inode->i_ctime = de->inode.ctime; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_GET) - printk ("%s: mode: 0%o uid: %d gid: %d\n", - DEVFS_NAME, (int) inode->i_mode, - (int) inode->i_uid, (int) inode->i_gid); -#endif + DPRINTK (DEBUG_I_GET, "(): mode: 0%o uid: %d gid: %d\n", + (int) inode->i_mode, (int) inode->i_uid, (int) inode->i_gid); return inode; -} /* End Function get_vfs_inode */ +} /* End Function _devfs_get_vfs_inode */ /* File operations for device entries follow */ @@ -2655,11 +2662,8 @@ fs_info = inode->i_sb->u.generic_sbp; parent = get_devfs_entry_from_vfs_inode (file->f_dentry->d_inode); if ( (long) file->f_pos < 0 ) return -EINVAL; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_F_READDIR) - printk ("%s: readdir(): fs_info: %p pos: %ld\n", DEVFS_NAME, - fs_info, (long) file->f_pos); -#endif + DPRINTK (DEBUG_F_READDIR, "(%s): fs_info: %p pos: %ld\n", + parent->name, fs_info, (long) file->f_pos); switch ( (long) file->f_pos ) { case 0: @@ -2779,13 +2783,7 @@ static void devfs_d_release (struct dentry *dentry) { -#ifdef CONFIG_DEVFS_DEBUG - struct inode *inode = dentry->d_inode; - - if (devfs_debug & DEBUG_D_RELEASE) - printk ("%s: d_release(): dentry: %p inode: %p\n", - DEVFS_NAME, dentry, inode); -#endif + DPRINTK (DEBUG_D_RELEASE, "(%p): inode: %p\n", dentry, dentry->d_inode); } /* End Function devfs_d_release */ /** @@ -2799,14 +2797,11 @@ struct devfs_entry *de; de = get_devfs_entry_from_vfs_inode (inode); -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_D_IPUT) - printk ("%s: d_iput(): dentry: %p inode: %p de: %p de->dentry: %p\n", - DEVFS_NAME, dentry, inode, de, de->inode.dentry); -#endif + DPRINTK (DEBUG_D_IPUT,"(%s): dentry: %p inode: %p de: %p de->dentry: %p\n", + de->name, dentry, inode, de, de->inode.dentry); if ( de->inode.dentry && (de->inode.dentry != dentry) ) - OOPS ("%s: d_iput(%s): de: %p dentry: %p de->dentry: %p\n", - DEVFS_NAME, de->name, de, dentry, de->inode.dentry); + OOPS ("(%s): de: %p dentry: %p de->dentry: %p\n", + de->name, de, dentry, de->inode.dentry); de->inode.dentry = NULL; iput (inode); devfs_put (de); @@ -2846,20 +2841,13 @@ /* Unhash dentry if negative (has no inode) */ if (inode == NULL) { -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_D_DELETE) - printk ("%s: d_delete(): dropping negative dentry: %p\n", - DEVFS_NAME, dentry); -#endif + DPRINTK (DEBUG_D_DELETE, "(%p): dropping negative dentry\n", dentry); return 1; } fs_info = inode->i_sb->u.generic_sbp; de = get_devfs_entry_from_vfs_inode (inode); -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_D_DELETE) - printk ("%s: d_delete(): dentry: %p inode: %p devfs_entry: %p\n", - DEVFS_NAME, dentry, inode, de); -#endif + DPRINTK (DEBUG_D_DELETE, "(%p): inode: %p devfs_entry: %p\n", + dentry, inode, de); if (de == NULL) return 0; if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) ) return 0; @@ -2876,40 +2864,55 @@ return 0; } /* End Function devfs_d_delete */ +struct devfs_lookup_struct +{ + devfs_handle_t de; + wait_queue_head_t wait_queue; +}; + static int devfs_d_revalidate_wait (struct dentry *dentry, int flags) { struct inode *dir = dentry->d_parent->d_inode; struct fs_info *fs_info = dir->i_sb->u.generic_sbp; + devfs_handle_t parent = get_devfs_entry_from_vfs_inode (dir); + struct devfs_lookup_struct *lookup_info = dentry->d_fsdata; + DECLARE_WAITQUEUE (wait, current); if ( !dentry->d_inode && is_devfsd_or_child (fs_info) ) { - devfs_handle_t de; - devfs_handle_t parent = get_devfs_entry_from_vfs_inode (dir); + devfs_handle_t de = lookup_info->de; struct inode *inode; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_LOOKUP) - printk ("%s: d_revalidate(%s): dentry: %p by: \"%s\"\n", - DEVFS_NAME, dentry->d_name.name, dentry, current->comm); -#endif - 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) return 1; + DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p de: %p by: \"%s\"\n", + dentry->d_name.name, dentry, de, current->comm); + if (de == NULL) + { + 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) return 1; + lookup_info->de = de; + } /* Create an inode, now that the driver information is available */ - inode = get_vfs_inode (dir->i_sb, de, dentry); - devfs_put (de); + inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry); if (!inode) return 1; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_LOOKUP) - printk ("%s: d_revalidate(): new VFS inode(%u): %p devfs_entry: %p\n", - DEVFS_NAME, de->inode.ino, inode, de); -#endif + DPRINTK (DEBUG_I_LOOKUP, + "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n", + de->name, de->inode.ino, inode, de, current->comm); d_instantiate (dentry, inode); return 1; } - if ( wait_for_devfsd_finished (fs_info) ) dentry->d_op = &devfs_dops; + if (lookup_info == NULL) return 1; /* Early termination */ + read_lock (&parent->u.dir.lock); + if (dentry->d_fsdata) + { + add_wait_queue (&lookup_info->wait_queue, &wait); + current->state = TASK_UNINTERRUPTIBLE; + read_unlock (&parent->u.dir.lock); + schedule (); + } + else read_unlock (&parent->u.dir.lock); return 1; } /* End Function devfs_d_revalidate_wait */ @@ -2918,20 +2921,20 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) { + struct devfs_entry tmp; /* Must stay in scope until devfsd idle again */ + struct devfs_lookup_struct lookup_info; struct fs_info *fs_info = dir->i_sb->u.generic_sbp; struct devfs_entry *parent, *de; struct inode *inode; + struct dentry *retval = NULL; /* Set up the dentry operations before anything else, to ensure cleaning up on any error */ dentry->d_op = &devfs_dops; /* First try to get the devfs entry for this directory */ parent = get_devfs_entry_from_vfs_inode (dir); -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_LOOKUP) - printk ("%s: lookup(%s): dentry: %p parent: %p by: \"%s\"\n", - DEVFS_NAME, dentry->d_name.name, dentry, parent,current->comm); -#endif + DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n", + dentry->d_name.name, dentry, parent, current->comm); 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); @@ -2945,63 +2948,61 @@ dentry->d_name.len); read_unlock (&parent->u.dir.lock); } + lookup_info.de = de; + init_waitqueue_head (&lookup_info.wait_queue); + dentry->d_fsdata = &lookup_info; if (de == NULL) { /* 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 does a mknod()). It's important to do this before hashing the dentry, so that the devfsd queue is filled before revalidates can start */ - struct devfs_entry tmp; - if (try_modload (parent, fs_info, dentry->d_name.name, dentry->d_name.len, &tmp) < 0) - { + { /* Lookup event was not queued to devfsd */ d_add (dentry, NULL); return NULL; } - /* devfsd claimed success */ - dentry->d_op = &devfs_wait_dops; - d_add (dentry, NULL); /* Open the floodgates */ - /* Unlock directory semaphore, which will release any waiters. They - will get the hashed dentry, and may be forced to wait for - revalidation */ - up (&dir->i_sem); - devfs_d_revalidate_wait (dentry, 0); /* I might have to wait too */ - down (&dir->i_sem); /* Grab it again because them's the rules */ - /* If someone else has been so kind as to make the inode, we go home - early */ - if (dentry->d_inode) return NULL; + } + dentry->d_op = &devfs_wait_dops; + d_add (dentry, NULL); /* Open the floodgates */ + /* Unlock directory semaphore, which will release any waiters. They + will get the hashed dentry, and may be forced to wait for + revalidation */ + up (&dir->i_sem); + wait_for_devfsd_finished (fs_info); /* If I'm not devfsd, must wait */ + down (&dir->i_sem); /* Grab it again because them's the rules */ + de = lookup_info.de; + /* If someone else has been so kind as to make the inode, we go home + early */ + if (dentry->d_inode) goto out; + if (de == NULL) + { 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) return NULL; + if (de == NULL) goto out; /* OK, there's an entry now, but no VFS inode yet */ } - else + /* Create an inode, now that the driver information is available */ + inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry); + if (!inode) { - dentry->d_op = &devfs_wait_dops; - d_add (dentry, NULL); /* Open the floodgates */ + retval = ERR_PTR (-ENOMEM); + goto out; } - /* Create an inode, now that the driver information is available */ - inode = get_vfs_inode (dir->i_sb, de, dentry); - devfs_put (de); - if (!inode) return ERR_PTR (-ENOMEM); -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_LOOKUP) - printk ("%s: lookup(): new VFS inode(%u): %p devfs_entry: %p\n", - DEVFS_NAME, de->inode.ino, inode, de); -#endif + DPRINTK (DEBUG_I_LOOKUP, "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n", + de->name, de->inode.ino, inode, de, current->comm); d_instantiate (dentry, inode); - if (dentry->d_op == &devfs_wait_dops) - { /* Unlock directory semaphore, which will release any waiters. They - will get the hashed dentry, and may be forced to wait for - revalidation */ - up (&dir->i_sem); - devfs_d_revalidate_wait (dentry, 0); /* I might have to wait too */ - down (&dir->i_sem); /* Grab it again because them's the rules */ - } - return NULL; +out: + dentry->d_op = &devfs_dops; + dentry->d_fsdata = NULL; + write_lock (&parent->u.dir.lock); + wake_up (&lookup_info.wait_queue); + write_unlock (&parent->u.dir.lock); + devfs_put (de); + return retval; } /* End Function devfs_lookup */ static int devfs_unlink (struct inode *dir, struct dentry *dentry) @@ -3011,11 +3012,8 @@ struct inode *inode = dentry->d_inode; struct fs_info *fs_info = dir->i_sb->u.generic_sbp; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_UNLINK) - printk ("%s: unlink(%s)\n", DEVFS_NAME, dentry->d_name.name); -#endif de = get_devfs_entry_from_vfs_inode (inode); + DPRINTK (DEBUG_I_UNLINK, "(%s): de: %p\n", dentry->d_name.name, de); if (de == NULL) return -ENOENT; if (!de->vfs_created) return -EPERM; write_lock (&de->parent->u.dir.lock); @@ -3043,11 +3041,8 @@ if (parent == NULL) return -ENOENT; err = devfs_do_symlink (parent, dentry->d_name.name, DEVFS_FL_NONE, symname, &de, NULL); -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_DISABLED) - printk ("%s: symlink(): errcode from : %d\n", - DEVFS_NAME, err); -#endif + DPRINTK (DEBUG_DISABLED, "(%s): errcode from : %d\n", + dentry->d_name.name, err); if (err < 0) return err; de->vfs_created = TRUE; de->inode.uid = current->euid; @@ -3055,13 +3050,10 @@ de->inode.atime = CURRENT_TIME; de->inode.mtime = CURRENT_TIME; de->inode.ctime = CURRENT_TIME; - if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) + if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) return -ENOMEM; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_DISABLED) - printk ("%s: symlink(): new VFS inode(%u): %p dentry: %p\n", - DEVFS_NAME, de->inode.ino, inode, dentry); -#endif + DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n", + dentry->d_name.name, de->inode.ino, inode, dentry); d_instantiate (dentry, inode); if ( !is_devfsd_or_child (fs_info) ) devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode, @@ -3089,13 +3081,10 @@ de->inode.atime = CURRENT_TIME; de->inode.mtime = CURRENT_TIME; de->inode.ctime = CURRENT_TIME; - if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) + if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) return -ENOMEM; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_DISABLED) - printk ("%s: mkdir(): new VFS inode(%u): %p dentry: %p\n", - DEVFS_NAME, de->inode.ino, inode, dentry); -#endif + DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n", + dentry->d_name.name, de->inode.ino, inode, dentry); d_instantiate (dentry, inode); if ( !is_devfsd_or_child (fs_info) ) devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode, @@ -3142,11 +3131,8 @@ struct devfs_entry *parent, *de; struct inode *inode; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_MKNOD) - printk ("%s: mknod(%s): mode: 0%o dev: %d\n", - DEVFS_NAME, dentry->d_name.name, mode, rdev); -#endif + DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %d\n", + dentry->d_name.name, mode, rdev); parent = get_devfs_entry_from_vfs_inode (dir); if (parent == NULL) return -ENOENT; de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode); @@ -3164,13 +3150,10 @@ de->inode.atime = CURRENT_TIME; de->inode.mtime = CURRENT_TIME; de->inode.ctime = CURRENT_TIME; - if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) + if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) return -ENOMEM; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_I_MKNOD) - printk ("%s: new VFS inode(%u): %p dentry: %p\n", - DEVFS_NAME, de->inode.ino, inode, dentry); -#endif + DPRINTK (DEBUG_I_MKNOD, ": new VFS inode(%u): %p dentry: %p\n", + de->inode.ino, inode, dentry); d_instantiate (dentry, inode); if ( !is_devfsd_or_child (fs_info) ) devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode, @@ -3238,15 +3221,11 @@ sb->s_blocksize_bits = 10; sb->s_magic = DEVFS_SUPER_MAGIC; sb->s_op = &devfs_sops; - if ( ( root_inode = get_vfs_inode (sb, root_entry, NULL) ) == NULL ) + if ( ( root_inode = _devfs_get_vfs_inode (sb, root_entry, NULL) ) == NULL ) goto out_no_root; sb->s_root = d_alloc_root (root_inode); if (!sb->s_root) goto out_no_root; -#ifdef CONFIG_DEVFS_DEBUG - if (devfs_debug & DEBUG_S_READ) - printk ("%s: read super, made devfs ptr: %p\n", - DEVFS_NAME, sb->u.generic_sbp); -#endif + DPRINTK (DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->u.generic_sbp); return sb; out_no_root: @@ -3479,6 +3458,10 @@ printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n", DEVFS_NAME, DEVFS_VERSION); + devfsd_buf_cache = kmem_cache_create ("devfsd_event", + sizeof (struct devfsd_buf_entry), + 0, 0, NULL, NULL); + if (!devfsd_buf_cache) OOPS ("(): unable to allocate event slab\n"); #ifdef CONFIG_DEVFS_DEBUG devfs_debug = devfs_debug_init; printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug); @@ -3498,9 +3481,6 @@ { int err; - devfsd_buf_cache = kmem_cache_create ("devfsd_event", - sizeof (struct devfsd_buf_entry), - 0, 0, NULL, NULL); if ( !(boot_options & OPTION_MOUNT) ) return; err = do_mount ("none", "/dev", "devfs", 0, ""); if (err == 0) printk ("Mounted devfs on /dev\n"); diff -urN linux-2.4.18-pre3/fs/super.c linux/fs/super.c --- linux-2.4.18-pre3/fs/super.c Fri Dec 21 10:42:03 2001 +++ linux/fs/super.c Sun Jan 13 18:53:59 2002 @@ -1056,6 +1056,7 @@ putname(fs_names); if (path_start >= 0) { name = path + path_start; + devfs_unregister (devfs_find_handle(NULL, "root", 0, 0, 0, 0)); devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT, name + 5, NULL, NULL); memcpy (name, "/dev/", 5);