

Nobody seems to have any outstanding work against devfs, so...


---

 25-akpm/fs/devfs/base.c                 | 2889 ++++++++++++++++----------------
 25-akpm/fs/devfs/util.c                 |    2 
 25-akpm/include/linux/devfs_fs.h        |   30 
 25-akpm/include/linux/devfs_fs_kernel.h |   26 
 4 files changed, 1482 insertions(+), 1465 deletions(-)

diff -puN fs/devfs/base.c~Lindent-devfs fs/devfs/base.c
--- 25/fs/devfs/base.c~Lindent-devfs	2004-04-03 02:59:45.176485072 -0800
+++ 25-akpm/fs/devfs/base.c	2004-04-03 02:59:45.202481120 -0800
@@ -710,8 +710,8 @@
 #define DEBUG_UNREGISTER   0x0000004
 #define DEBUG_FREE         0x0000008
 #define DEBUG_SET_FLAGS    0x0000010
-#define DEBUG_S_READ       0x0000100        /*  Break  */
-#define DEBUG_I_LOOKUP     0x0001000        /*  Break  */
+#define DEBUG_S_READ       0x0000100	/*  Break  */
+#define DEBUG_I_LOOKUP     0x0001000	/*  Break  */
 #define DEBUG_I_CREATE     0x0002000
 #define DEBUG_I_GET        0x0004000
 #define DEBUG_I_CHANGE     0x0008000
@@ -719,8 +719,8 @@
 #define DEBUG_I_RLINK      0x0020000
 #define DEBUG_I_FLINK      0x0040000
 #define DEBUG_I_MKNOD      0x0080000
-#define DEBUG_F_READDIR    0x0100000        /*  Break  */
-#define DEBUG_D_DELETE     0x1000000        /*  Break  */
+#define DEBUG_F_READDIR    0x0100000	/*  Break  */
+#define DEBUG_D_DELETE     0x1000000	/*  Break  */
 #define DEBUG_D_RELEASE    0x2000000
 #define DEBUG_D_IPUT       0x4000000
 #define DEBUG_ALL          0xfffffff
@@ -753,88 +753,80 @@
 
 typedef struct devfs_entry *devfs_handle_t;
 
-struct directory_type
-{
-    rwlock_t lock;                   /*  Lock for searching(R)/updating(W)   */
-    struct devfs_entry *first;
-    struct devfs_entry *last;
-    unsigned char no_more_additions:1;
+struct directory_type {
+	rwlock_t lock;		/*  Lock for searching(R)/updating(W)   */
+	struct devfs_entry *first;
+	struct devfs_entry *last;
+	unsigned char no_more_additions:1;
 };
 
-struct symlink_type
-{
-    unsigned int length;         /*  Not including the NULL-termimator       */
-    char *linkname;              /*  This is NULL-terminated                 */
+struct symlink_type {
+	unsigned int length;	/*  Not including the NULL-termimator       */
+	char *linkname;		/*  This is NULL-terminated                 */
 };
 
-struct devfs_inode     /*  This structure is for "persistent" inode storage  */
-{
-    struct dentry *dentry;
-    struct timespec atime;
-    struct timespec mtime;
-    struct timespec ctime;
-    unsigned int ino;            /*  Inode number as seen in the VFS         */
-    uid_t uid;
-    gid_t gid;
+struct devfs_inode {		/*  This structure is for "persistent" inode storage  */
+	struct dentry *dentry;
+	struct timespec atime;
+	struct timespec mtime;
+	struct timespec ctime;
+	unsigned int ino;	/*  Inode number as seen in the VFS         */
+	uid_t uid;
+	gid_t gid;
 };
 
-struct devfs_entry
-{
+struct devfs_entry {
 #ifdef CONFIG_DEVFS_DEBUG
-    unsigned int magic_number;
+	unsigned int magic_number;
 #endif
-    void *info;
-    atomic_t refcount;           /*  When this drops to zero, it's unused    */
-    union 
-    {
-	struct directory_type dir;
-	dev_t dev;
-	struct symlink_type symlink;
-	const char *name;        /*  Only used for (mode == 0)               */
-    }
-    u;
-    struct devfs_entry *prev;    /*  Previous entry in the parent directory  */
-    struct devfs_entry *next;    /*  Next entry in the parent directory      */
-    struct devfs_entry *parent;  /*  The parent directory                    */
-    struct devfs_inode inode;
-    umode_t mode;
-    unsigned short namelen;      /*  I think 64k+ filenames are a way off... */
-    unsigned char vfs:1;/*  Whether the VFS may delete the entry   */
-    char name[1];                /*  This is just a dummy: the allocated array
-				     is bigger. This is NULL-terminated      */
+	void *info;
+	atomic_t refcount;	/*  When this drops to zero, it's unused    */
+	union {
+		struct directory_type dir;
+		dev_t dev;
+		struct symlink_type symlink;
+		const char *name;	/*  Only used for (mode == 0)               */
+	} u;
+	struct devfs_entry *prev;	/*  Previous entry in the parent directory  */
+	struct devfs_entry *next;	/*  Next entry in the parent directory      */
+	struct devfs_entry *parent;	/*  The parent directory                    */
+	struct devfs_inode inode;
+	umode_t mode;
+	unsigned short namelen;	/*  I think 64k+ filenames are a way off... */
+	unsigned char vfs:1;	/*  Whether the VFS may delete the entry   */
+	char name[1];		/*  This is just a dummy: the allocated array
+				   is bigger. This is NULL-terminated      */
 };
 
 /*  The root of the device tree  */
 static struct devfs_entry *root_entry;
 
-struct devfsd_buf_entry
-{
-    struct devfs_entry *de;      /*  The name is generated with this         */
-    unsigned short type;         /*  The type of event                       */
-    umode_t mode;
-    uid_t uid;
-    gid_t gid;
-    struct devfsd_buf_entry *next;
+struct devfsd_buf_entry {
+	struct devfs_entry *de;	/*  The name is generated with this         */
+	unsigned short type;	/*  The type of event                       */
+	umode_t mode;
+	uid_t uid;
+	gid_t gid;
+	struct devfsd_buf_entry *next;
 };
 
-struct fs_info                  /*  This structure is for the mounted devfs  */
-{
-    struct super_block *sb;
-    spinlock_t devfsd_buffer_lock;  /*  Lock when inserting/deleting events  */
-    struct devfsd_buf_entry *devfsd_first_event;
-    struct devfsd_buf_entry *devfsd_last_event;
-    volatile int devfsd_sleeping;
-    volatile struct task_struct *devfsd_task;
-    volatile pid_t devfsd_pgrp;
-    volatile struct file *devfsd_file;
-    struct devfsd_notify_struct *devfsd_info;
-    volatile unsigned long devfsd_event_mask;
-    atomic_t devfsd_overrun_count;
-    wait_queue_head_t devfsd_wait_queue;      /*  Wake devfsd on input       */
-    wait_queue_head_t revalidate_wait_queue;  /*  Wake when devfsd sleeps    */
+struct fs_info {		/*  This structure is for the mounted devfs  */
+	struct super_block *sb;
+	spinlock_t devfsd_buffer_lock;	/*  Lock when inserting/deleting events  */
+	struct devfsd_buf_entry *devfsd_first_event;
+	struct devfsd_buf_entry *devfsd_last_event;
+	volatile int devfsd_sleeping;
+	volatile struct task_struct *devfsd_task;
+	volatile pid_t devfsd_pgrp;
+	volatile struct file *devfsd_file;
+	struct devfsd_notify_struct *devfsd_info;
+	volatile unsigned long devfsd_event_mask;
+	atomic_t devfsd_overrun_count;
+	wait_queue_head_t devfsd_wait_queue;	/*  Wake devfsd on input       */
+	wait_queue_head_t revalidate_wait_queue;	/*  Wake when devfsd sleeps    */
 };
 
-static struct fs_info fs_info = {.devfsd_buffer_lock = SPIN_LOCK_UNLOCKED};
+static struct fs_info fs_info = {.devfsd_buffer_lock = SPIN_LOCK_UNLOCKED };
 static kmem_cache_t *devfsd_buf_cache;
 #ifdef CONFIG_DEVFS_DEBUG
 static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
@@ -844,7 +836,7 @@ static unsigned int stat_num_entries;
 static unsigned int stat_num_bytes;
 #endif
 static unsigned char poison_array[8] =
-    {0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a};
+    { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a };
 
 #ifdef CONFIG_DEVFS_MOUNT
 static unsigned int boot_options = OPTION_MOUNT;
@@ -853,75 +845,77 @@ static unsigned int boot_options = OPTIO
 #endif
 
 /*  Forward function declarations  */
-static devfs_handle_t _devfs_walk_path (struct devfs_entry *dir,
-					const char *name, int namelen,
-					int traverse_symlink);
-static ssize_t devfsd_read (struct file *file, char *buf, size_t len,
-			    loff_t *ppos);
-static int devfsd_ioctl (struct inode *inode, struct file *file,
-			 unsigned int cmd, unsigned long arg);
-static int devfsd_close (struct inode *inode, struct file *file);
+static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
+				       const char *name, int namelen,
+				       int traverse_symlink);
+static ssize_t devfsd_read(struct file *file, char *buf, size_t len,
+			   loff_t * ppos);
+static int devfsd_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg);
+static int devfsd_close(struct inode *inode, struct file *file);
 #ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read (struct file *file, char *buf, size_t len,
-			  loff_t *ppos);
-static struct file_operations stat_fops =
-{
-    .read    = stat_read,
+static ssize_t stat_read(struct file *file, char *buf, size_t len,
+			 loff_t * ppos);
+static struct file_operations stat_fops = {
+	.read = stat_read,
 };
 #endif
 
-
 /*  Devfs daemon file operations  */
-static struct file_operations devfsd_fops =
-{
-    .read    = devfsd_read,
-    .ioctl   = devfsd_ioctl,
-    .release = devfsd_close,
+static struct file_operations devfsd_fops = {
+	.read = devfsd_read,
+	.ioctl = devfsd_ioctl,
+	.release = devfsd_close,
 };
 
-
 /*  Support functions follow  */
 
-
 /**
  *	devfs_get - Get a reference to a devfs entry.
  *	@de:  The devfs entry.
  */
 
-static struct devfs_entry *devfs_get (struct devfs_entry *de)
+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  */
+	VERIFY_ENTRY(de);
+	if (de)
+		atomic_inc(&de->refcount);
+	return de;
+}				/*  End Function devfs_get  */
 
 /**
  *	devfs_put - Put (release) a reference to a devfs entry.
  *	@de:  The handle to the devfs entry.
  */
 
-static void devfs_put (devfs_handle_t de)
+static void devfs_put(devfs_handle_t de)
 {
-    if (!de) return;
-    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 ("(%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);
-    WRITE_ENTRY_MAGIC (de, 0);
+	if (!de)
+		return;
+	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("(%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);
+	WRITE_ENTRY_MAGIC(de, 0);
 #ifdef CONFIG_DEVFS_DEBUG
-    spin_lock (&stat_lock);
-    --stat_num_entries;
-    stat_num_bytes -= sizeof *de + de->namelen;
-    if ( S_ISLNK (de->mode) ) stat_num_bytes -= de->u.symlink.length + 1;
-    spin_unlock (&stat_lock);
+	spin_lock(&stat_lock);
+	--stat_num_entries;
+	stat_num_bytes -= sizeof *de + de->namelen;
+	if (S_ISLNK(de->mode))
+		stat_num_bytes -= de->u.symlink.length + 1;
+	spin_unlock(&stat_lock);
 #endif
-    de->info = POISON_PTR;
-    kfree (de);
-}   /*  End Function devfs_put  */
+	de->info = POISON_PTR;
+	kfree(de);
+}				/*  End Function devfs_put  */
 
 /**
  *	_devfs_search_dir - Search for a devfs entry in a directory.
@@ -934,26 +928,25 @@ static void devfs_put (devfs_handle_t de
  *   An implicit devfs_get() is performed on the returned entry.
  */
 
-static struct devfs_entry *_devfs_search_dir (struct devfs_entry *dir,
-					      const char *name,
-					      unsigned int namelen)
-{
-    struct devfs_entry *curr;
-
-    if ( !S_ISDIR (dir->mode) )
-    {
-	PRINTK ("(%s): not a directory\n", dir->name);
-	return NULL;
-    }
-    for (curr = dir->u.dir.first; curr != NULL; curr = curr->next)
-    {
-	if (curr->namelen != namelen) continue;
-	if (memcmp (curr->name, name, namelen) == 0) break;
-	/*  Not found: try the next one  */
-    }
-    return devfs_get (curr);
-}   /*  End Function _devfs_search_dir  */
+static struct devfs_entry *_devfs_search_dir(struct devfs_entry *dir,
+					     const char *name,
+					     unsigned int namelen)
+{
+	struct devfs_entry *curr;
 
+	if (!S_ISDIR(dir->mode)) {
+		PRINTK("(%s): not a directory\n", dir->name);
+		return NULL;
+	}
+	for (curr = dir->u.dir.first; curr != NULL; curr = curr->next) {
+		if (curr->namelen != namelen)
+			continue;
+		if (memcmp(curr->name, name, namelen) == 0)
+			break;
+		/*  Not found: try the next one  */
+	}
+	return devfs_get(curr);
+}				/*  End Function _devfs_search_dir  */
 
 /**
  *	_devfs_alloc_entry - Allocate a devfs entry.
@@ -965,36 +958,38 @@ static struct devfs_entry *_devfs_search
  *   %NULL.
  */
 
-static struct devfs_entry *_devfs_alloc_entry (const char *name,
-					       unsigned int namelen,
-					       umode_t mode)
-{
-    struct devfs_entry *new;
-    static unsigned long inode_counter = FIRST_INODE;
-    static spinlock_t counter_lock = SPIN_LOCK_UNLOCKED;
-
-    if ( name && (namelen < 1) ) namelen = strlen (name);
-    if ( ( new = kmalloc (sizeof *new + namelen, GFP_KERNEL) ) == NULL )
-	return NULL;
-    memset (new, 0, sizeof *new + namelen);  /*  Will set '\0' on name  */
-    new->mode = mode;
-    if ( S_ISDIR (mode) ) rwlock_init (&new->u.dir.lock);
-    atomic_set (&new->refcount, 1);
-    spin_lock (&counter_lock);
-    new->inode.ino = inode_counter++;
-    spin_unlock (&counter_lock);
-    if (name) memcpy (new->name, name, namelen);
-    new->namelen = namelen;
-    WRITE_ENTRY_MAGIC (new, MAGIC_VALUE);
+static struct devfs_entry *_devfs_alloc_entry(const char *name,
+					      unsigned int namelen,
+					      umode_t mode)
+{
+	struct devfs_entry *new;
+	static unsigned long inode_counter = FIRST_INODE;
+	static spinlock_t counter_lock = SPIN_LOCK_UNLOCKED;
+
+	if (name && (namelen < 1))
+		namelen = strlen(name);
+	if ((new = kmalloc(sizeof *new + namelen, GFP_KERNEL)) == NULL)
+		return NULL;
+	memset(new, 0, sizeof *new + namelen);	/*  Will set '\0' on name  */
+	new->mode = mode;
+	if (S_ISDIR(mode))
+		rwlock_init(&new->u.dir.lock);
+	atomic_set(&new->refcount, 1);
+	spin_lock(&counter_lock);
+	new->inode.ino = inode_counter++;
+	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;
-    stat_num_bytes += sizeof *new + namelen;
-    spin_unlock (&stat_lock);
+	spin_lock(&stat_lock);
+	++stat_num_entries;
+	stat_num_bytes += sizeof *new + namelen;
+	spin_unlock(&stat_lock);
 #endif
-    return new;
-}   /*  End Function _devfs_alloc_entry  */
-
+	return new;
+}				/*  End Function _devfs_alloc_entry  */
 
 /**
  *	_devfs_append_entry - Append a devfs entry to a directory's child list.
@@ -1009,43 +1004,48 @@ static struct devfs_entry *_devfs_alloc_
  *   On failure, an implicit devfs_put() is performed on %de.
  */
 
-static int _devfs_append_entry (devfs_handle_t dir, devfs_handle_t de,
-				devfs_handle_t *old_de)
+static int _devfs_append_entry(devfs_handle_t dir, devfs_handle_t de,
+			       devfs_handle_t * old_de)
 {
-    int retval;
+	int retval;
 
-    if (old_de) *old_de = NULL;
-    if ( !S_ISDIR (dir->mode) )
-    {
-	PRINTK ("(%s): dir: \"%s\" is not a directory\n", de->name, dir->name);
-	devfs_put (de);
-	return -ENOTDIR;
-    }
-    write_lock (&dir->u.dir.lock);
-    if (dir->u.dir.no_more_additions) retval = -ENOENT;
-    else
-    {
-	struct devfs_entry *old;
-
-	old = _devfs_search_dir (dir, de->name, de->namelen);
-	if (old_de) *old_de = old;
-	else devfs_put (old);
-	if (old == NULL)
-	{
-	    de->parent = dir;
-	    de->prev = dir->u.dir.last;
-	    /*  Append to the directory's list of children  */
-	    if (dir->u.dir.first == NULL) dir->u.dir.first = de;
-	    else dir->u.dir.last->next = de;
-	    dir->u.dir.last = de;
-	    retval = 0;
-	}
-	else retval = -EEXIST;
-    }
-    write_unlock (&dir->u.dir.lock);
-    if (retval) devfs_put (de);
-    return retval;
-}   /*  End Function _devfs_append_entry  */
+	if (old_de)
+		*old_de = NULL;
+	if (!S_ISDIR(dir->mode)) {
+		PRINTK("(%s): dir: \"%s\" is not a directory\n", de->name,
+		       dir->name);
+		devfs_put(de);
+		return -ENOTDIR;
+	}
+	write_lock(&dir->u.dir.lock);
+	if (dir->u.dir.no_more_additions)
+		retval = -ENOENT;
+	else {
+		struct devfs_entry *old;
+
+		old = _devfs_search_dir(dir, de->name, de->namelen);
+		if (old_de)
+			*old_de = old;
+		else
+			devfs_put(old);
+		if (old == NULL) {
+			de->parent = dir;
+			de->prev = dir->u.dir.last;
+			/*  Append to the directory's list of children  */
+			if (dir->u.dir.first == NULL)
+				dir->u.dir.first = de;
+			else
+				dir->u.dir.last->next = de;
+			dir->u.dir.last = de;
+			retval = 0;
+		} else
+			retval = -EEXIST;
+	}
+	write_unlock(&dir->u.dir.lock);
+	if (retval)
+		devfs_put(de);
+	return retval;
+}				/*  End Function _devfs_append_entry  */
 
 /**
  *	_devfs_get_root_entry - Get the root devfs entry.
@@ -1067,7 +1067,7 @@ static struct devfs_entry *_devfs_get_ro
 		return root_entry;
 
 	new = _devfs_alloc_entry(NULL, 0, MODE_DIR);
-	if (new == NULL )
+	if (new == NULL)
 		return NULL;
 
 	spin_lock(&root_lock);
@@ -1080,7 +1080,7 @@ static struct devfs_entry *_devfs_get_ro
 	spin_unlock(&root_lock);
 
 	return root_entry;
-}   /*  End Function _devfs_get_root_entry  */
+}				/*  End Function _devfs_get_root_entry  */
 
 /**
  *	_devfs_descend - Descend down a tree using the next component name.
@@ -1096,142 +1096,134 @@ static struct devfs_entry *_devfs_get_ro
  *   An implicit devfs_get() is performed on the returned entry.
  */
 
-static struct devfs_entry *_devfs_descend (struct devfs_entry *dir,
-					   const char *name, int namelen,
-					   int *next_pos)
-{
-    const char *stop, *ptr;
-    struct devfs_entry *entry;
-
-    if ( (namelen >= 3) && (strncmp (name, "../", 3) == 0) )
-    {   /*  Special-case going to parent directory  */
-	*next_pos = 3;
-	return devfs_get (dir->parent);
-    }
-    stop = name + namelen;
-    /*  Search for a possible '/'  */
-    for (ptr = name; (ptr < stop) && (*ptr != '/'); ++ptr);
-    *next_pos = ptr - name;
-    read_lock (&dir->u.dir.lock);
-    entry = _devfs_search_dir (dir, name, *next_pos);
-    read_unlock (&dir->u.dir.lock);
-    return entry;
-}   /*  End Function _devfs_descend  */
-
-
-static devfs_handle_t _devfs_make_parent_for_leaf (struct devfs_entry *dir,
-						   const char *name,
-						   int namelen, int *leaf_pos)
-{
-    int next_pos = 0;
-
-    if (dir == NULL) dir = _devfs_get_root_entry ();
-    if (dir == NULL) return NULL;
-    devfs_get (dir);
-    /*  Search for possible trailing component and ignore it  */
-    for (--namelen; (namelen > 0) && (name[namelen] != '/'); --namelen);
-    *leaf_pos = (name[namelen] == '/') ? (namelen + 1) : 0;
-    for (; namelen > 0; name += next_pos, namelen -= next_pos)
-    {
-	struct devfs_entry *de, *old = NULL;
-
-	if ( ( de = _devfs_descend (dir, name, namelen, &next_pos) ) == NULL )
-	{
-	    de = _devfs_alloc_entry (name, next_pos, MODE_DIR);
-	    devfs_get (de);
-	    if ( !de || _devfs_append_entry (dir, de, &old) )
-	    {
-		devfs_put (de);
-		if ( !old || !S_ISDIR (old->mode) )
-		{
-		    devfs_put (old);
-		    devfs_put (dir);
-		    return NULL;
+static struct devfs_entry *_devfs_descend(struct devfs_entry *dir,
+					  const char *name, int namelen,
+					  int *next_pos)
+{
+	const char *stop, *ptr;
+	struct devfs_entry *entry;
+
+	if ((namelen >= 3) && (strncmp(name, "../", 3) == 0)) {	/*  Special-case going to parent directory  */
+		*next_pos = 3;
+		return devfs_get(dir->parent);
+	}
+	stop = name + namelen;
+	/*  Search for a possible '/'  */
+	for (ptr = name; (ptr < stop) && (*ptr != '/'); ++ptr) ;
+	*next_pos = ptr - name;
+	read_lock(&dir->u.dir.lock);
+	entry = _devfs_search_dir(dir, name, *next_pos);
+	read_unlock(&dir->u.dir.lock);
+	return entry;
+}				/*  End Function _devfs_descend  */
+
+static devfs_handle_t _devfs_make_parent_for_leaf(struct devfs_entry *dir,
+						  const char *name,
+						  int namelen, int *leaf_pos)
+{
+	int next_pos = 0;
+
+	if (dir == NULL)
+		dir = _devfs_get_root_entry();
+	if (dir == NULL)
+		return NULL;
+	devfs_get(dir);
+	/*  Search for possible trailing component and ignore it  */
+	for (--namelen; (namelen > 0) && (name[namelen] != '/'); --namelen) ;
+	*leaf_pos = (name[namelen] == '/') ? (namelen + 1) : 0;
+	for (; namelen > 0; name += next_pos, namelen -= next_pos) {
+		struct devfs_entry *de, *old = NULL;
+
+		if ((de =
+		     _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
+			de = _devfs_alloc_entry(name, next_pos, MODE_DIR);
+			devfs_get(de);
+			if (!de || _devfs_append_entry(dir, de, &old)) {
+				devfs_put(de);
+				if (!old || !S_ISDIR(old->mode)) {
+					devfs_put(old);
+					devfs_put(dir);
+					return NULL;
+				}
+				de = old;	/*  Use the existing directory  */
+			}
+		}
+		if (de == dir->parent) {
+			devfs_put(dir);
+			devfs_put(de);
+			return NULL;
 		}
-		de = old;  /*  Use the existing directory  */
-	    }
+		devfs_put(dir);
+		dir = de;
+		if (name[next_pos] == '/')
+			++next_pos;
+	}
+	return dir;
+}				/*  End Function _devfs_make_parent_for_leaf  */
+
+static devfs_handle_t _devfs_prepare_leaf(devfs_handle_t * dir,
+					  const char *name, umode_t mode)
+{
+	int namelen, leaf_pos;
+	struct devfs_entry *de;
+
+	namelen = strlen(name);
+	if ((*dir = _devfs_make_parent_for_leaf(*dir, name, namelen,
+						&leaf_pos)) == NULL) {
+		PRINTK("(%s): could not create parent path\n", name);
+		return NULL;
 	}
-	if (de == dir->parent)
-	{
-	    devfs_put (dir);
-	    devfs_put (de);
-	    return NULL;
-	}
-	devfs_put (dir);
-	dir = de;
-	if (name[next_pos] == '/') ++next_pos;
-    }
-    return dir;
-}   /*  End Function _devfs_make_parent_for_leaf  */
-
-
-static devfs_handle_t _devfs_prepare_leaf (devfs_handle_t *dir,
-					   const char *name, umode_t mode)
-{
-    int namelen, leaf_pos;
-    struct devfs_entry *de;
-
-    namelen = strlen (name);
-    if ( ( *dir = _devfs_make_parent_for_leaf (*dir, name, namelen,
-					       &leaf_pos) ) == NULL )
-    {
-	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): could not allocate entry\n", name);
-	devfs_put (*dir);
-	return NULL;
-    }
-    return de;
-}   /*  End Function _devfs_prepare_leaf  */
-
-
-static devfs_handle_t _devfs_walk_path (struct devfs_entry *dir,
-					const char *name, int namelen,
-					int traverse_symlink)
-{
-    int next_pos = 0;
-
-    if (dir == NULL) dir = _devfs_get_root_entry ();
-    if (dir == NULL) return NULL;
-    devfs_get (dir);
-    for (; namelen > 0; name += next_pos, namelen -= next_pos)
-    {
-	struct devfs_entry *de, *link;
-
-	if (!S_ISDIR (dir->mode))
-	{
-	    devfs_put (dir);
-	    return NULL;
-	}
-
-	if ( ( de = _devfs_descend (dir, name, namelen, &next_pos) ) == NULL )
-	{
-	    devfs_put (dir);
-	    return NULL;
-	}
-	if (S_ISLNK (de->mode) && traverse_symlink)
-	{   /*  Need to follow the link: this is a stack chomper  */
-		/* FIXME what if it puts outside of mounted tree? */
-	    link = _devfs_walk_path (dir, de->u.symlink.linkname,
-				     de->u.symlink.length, TRUE);
-	    devfs_put (de);
-	    if (!link)
-	    {
-		devfs_put (dir);
+	if ((de = _devfs_alloc_entry(name + leaf_pos, namelen - leaf_pos, mode))
+	    == NULL) {
+		PRINTK("(%s): could not allocate entry\n", name);
+		devfs_put(*dir);
 		return NULL;
-	    }
-	    de = link;
 	}
-	devfs_put (dir);
-	dir = de;
-	if (name[next_pos] == '/') ++next_pos;
-    }
-    return dir;
-}   /*  End Function _devfs_walk_path  */
+	return de;
+}				/*  End Function _devfs_prepare_leaf  */
+
+static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
+				       const char *name, int namelen,
+				       int traverse_symlink)
+{
+	int next_pos = 0;
+
+	if (dir == NULL)
+		dir = _devfs_get_root_entry();
+	if (dir == NULL)
+		return NULL;
+	devfs_get(dir);
+	for (; namelen > 0; name += next_pos, namelen -= next_pos) {
+		struct devfs_entry *de, *link;
+
+		if (!S_ISDIR(dir->mode)) {
+			devfs_put(dir);
+			return NULL;
+		}
+
+		if ((de =
+		     _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
+			devfs_put(dir);
+			return NULL;
+		}
+		if (S_ISLNK(de->mode) && traverse_symlink) {	/*  Need to follow the link: this is a stack chomper  */
+			/* FIXME what if it puts outside of mounted tree? */
+			link = _devfs_walk_path(dir, de->u.symlink.linkname,
+						de->u.symlink.length, TRUE);
+			devfs_put(de);
+			if (!link) {
+				devfs_put(dir);
+				return NULL;
+			}
+			de = link;
+		}
+		devfs_put(dir);
+		dir = de;
+		if (name[next_pos] == '/')
+			++next_pos;
+	}
+	return dir;
+}				/*  End Function _devfs_walk_path  */
 
 /**
  *	_devfs_find_entry - Find a devfs entry.
@@ -1244,40 +1236,37 @@ static devfs_handle_t _devfs_walk_path (
  *	devfs_get() is performed.
  */
 
-static struct devfs_entry *_devfs_find_entry (devfs_handle_t dir,
-					      const char *name,
-					      int traverse_symlink)
-{
-    unsigned int namelen = strlen (name);
-
-    if (name[0] == '/')
-    {
-	/*  Skip leading pathname component  */
-	if (namelen < 2)
-	{
-	    PRINTK ("(%s): too short\n", name);
-	    return NULL;
-	}
-	for (++name, --namelen; (*name != '/') && (namelen > 0);
-	     ++name, --namelen);
-	if (namelen < 2)
-	{
-	    PRINTK ("(%s): too short\n", name);
-	    return NULL;
-	}
-	++name;
-	--namelen;
-    }
-    return _devfs_walk_path (dir, name, namelen, traverse_symlink);
-}   /*  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  */
+static struct devfs_entry *_devfs_find_entry(devfs_handle_t dir,
+					     const char *name,
+					     int traverse_symlink)
+{
+	unsigned int namelen = strlen(name);
+
+	if (name[0] == '/') {
+		/*  Skip leading pathname component  */
+		if (namelen < 2) {
+			PRINTK("(%s): too short\n", name);
+			return NULL;
+		}
+		for (++name, --namelen; (*name != '/') && (namelen > 0);
+		     ++name, --namelen) ;
+		if (namelen < 2) {
+			PRINTK("(%s): too short\n", name);
+			return NULL;
+		}
+		++name;
+		--namelen;
+	}
+	return _devfs_walk_path(dir, name, namelen, traverse_symlink);
+}				/*  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  */
 
 /**
  *	free_dentry - Free the dentry for a device entry and invalidate inode.
@@ -1287,20 +1276,21 @@ static struct devfs_entry *get_devfs_ent
  *	 parent directory.
  */
 
-static void free_dentry (struct devfs_entry *de)
+static void free_dentry(struct devfs_entry *de)
 {
-    struct dentry *dentry = de->inode.dentry;
-
-    if (!dentry) return;
-    spin_lock (&dcache_lock);
-    dget_locked (dentry);
-    spin_unlock (&dcache_lock);
-    /*  Forcefully remove the inode  */
-    if (dentry->d_inode != NULL) dentry->d_inode->i_nlink = 0;
-    d_drop (dentry);
-    dput (dentry);
-}   /*  End Function free_dentry  */
+	struct dentry *dentry = de->inode.dentry;
 
+	if (!dentry)
+		return;
+	spin_lock(&dcache_lock);
+	dget_locked(dentry);
+	spin_unlock(&dcache_lock);
+	/*  Forcefully remove the inode  */
+	if (dentry->d_inode != NULL)
+		dentry->d_inode->i_nlink = 0;
+	d_drop(dentry);
+	dput(dentry);
+}				/*  End Function free_dentry  */
 
 /**
  *	is_devfsd_or_child - Test if the current process is devfsd or one of its children.
@@ -1309,25 +1299,24 @@ static void free_dentry (struct devfs_en
  *	Returns %TRUE if devfsd or child, else %FALSE.
  */
 
-static int is_devfsd_or_child (struct fs_info *fs_info)
+static int is_devfsd_or_child(struct fs_info *fs_info)
 {
-    struct task_struct *p = current;
+	struct task_struct *p = current;
 
-    if (p == fs_info->devfsd_task) return (TRUE);
-    if (process_group(p) == fs_info->devfsd_pgrp) return (TRUE);
-    read_lock(&tasklist_lock);
-    for ( ; p != &init_task; p = p->real_parent)
-    {
 	if (p == fs_info->devfsd_task)
-	{
-	    read_unlock (&tasklist_lock);
-	    return (TRUE);
-	}
-    }
-    read_unlock (&tasklist_lock);
-    return (FALSE);
-}   /*  End Function is_devfsd_or_child  */
-
+		return (TRUE);
+	if (process_group(p) == fs_info->devfsd_pgrp)
+		return (TRUE);
+	read_lock(&tasklist_lock);
+	for (; p != &init_task; p = p->real_parent) {
+		if (p == fs_info->devfsd_task) {
+			read_unlock(&tasklist_lock);
+			return (TRUE);
+		}
+	}
+	read_unlock(&tasklist_lock);
+	return (FALSE);
+}				/*  End Function is_devfsd_or_child  */
 
 /**
  *	devfsd_queue_empty - Test if devfsd has work pending in its event queue.
@@ -1336,11 +1325,10 @@ static int is_devfsd_or_child (struct fs
  *	Returns %TRUE if the queue is empty, else %FALSE.
  */
 
-static inline int devfsd_queue_empty (struct fs_info *fs_info)
+static inline int devfsd_queue_empty(struct fs_info *fs_info)
 {
-    return (fs_info->devfsd_last_event) ? FALSE : TRUE;
-}   /*  End Function devfsd_queue_empty  */
-
+	return (fs_info->devfsd_last_event) ? FALSE : TRUE;
+}				/*  End Function devfsd_queue_empty  */
 
 /**
  *	wait_for_devfsd_finished - Wait for devfsd to finish processing its event queue.
@@ -1349,22 +1337,25 @@ static inline int devfsd_queue_empty (st
  *	Returns %TRUE if no more waiting will be required, else %FALSE.
  */
 
-static int wait_for_devfsd_finished (struct fs_info *fs_info)
+static int wait_for_devfsd_finished(struct fs_info *fs_info)
 {
-    DECLARE_WAITQUEUE (wait, current);
-
-    if (fs_info->devfsd_task == NULL) return (TRUE);
-    if (devfsd_queue_empty (fs_info) && fs_info->devfsd_sleeping) return TRUE;
-    if ( is_devfsd_or_child (fs_info) ) return (FALSE);
-    set_current_state (TASK_UNINTERRUPTIBLE);
-    add_wait_queue (&fs_info->revalidate_wait_queue, &wait);
-    if (!devfsd_queue_empty (fs_info) || !fs_info->devfsd_sleeping)
-	if (fs_info->devfsd_task) schedule ();
-    remove_wait_queue (&fs_info->revalidate_wait_queue, &wait);
-    __set_current_state (TASK_RUNNING);
-    return (TRUE);
-}   /*  End Function wait_for_devfsd_finished  */
+	DECLARE_WAITQUEUE(wait, current);
 
+	if (fs_info->devfsd_task == NULL)
+		return (TRUE);
+	if (devfsd_queue_empty(fs_info) && fs_info->devfsd_sleeping)
+		return TRUE;
+	if (is_devfsd_or_child(fs_info))
+		return (FALSE);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(&fs_info->revalidate_wait_queue, &wait);
+	if (!devfsd_queue_empty(fs_info) || !fs_info->devfsd_sleeping)
+		if (fs_info->devfsd_task)
+			schedule();
+	remove_wait_queue(&fs_info->revalidate_wait_queue, &wait);
+	__set_current_state(TASK_RUNNING);
+	return (TRUE);
+}				/*  End Function wait_for_devfsd_finished  */
 
 /**
  *	devfsd_notify_de - Notify the devfsd daemon of a change.
@@ -1379,35 +1370,37 @@ static int wait_for_devfsd_finished (str
  *	Returns %TRUE if an event was queued and devfsd woken up, else %FALSE.
  */
 
-static int devfsd_notify_de (struct devfs_entry *de,
-			     unsigned short type, umode_t mode,
-			     uid_t uid, gid_t gid, struct fs_info *fs_info)
-{
-    struct devfsd_buf_entry *entry;
-    struct devfs_entry *curr;
-
-    if ( !( fs_info->devfsd_event_mask & (1 << type) ) ) return (FALSE);
-    if ( ( entry = kmem_cache_alloc (devfsd_buf_cache, SLAB_KERNEL) ) == NULL )
-    {
-	atomic_inc (&fs_info->devfsd_overrun_count);
-	return (FALSE);
-    }
-    for (curr = de; curr != NULL; curr = curr->parent) devfs_get (curr);
-    entry->de = de;
-    entry->type = type;
-    entry->mode = mode;
-    entry->uid = uid;
-    entry->gid = gid;
-    entry->next = NULL;
-    spin_lock (&fs_info->devfsd_buffer_lock);
-    if (!fs_info->devfsd_first_event) fs_info->devfsd_first_event = entry;
-    if (fs_info->devfsd_last_event) fs_info->devfsd_last_event->next = entry;
-    fs_info->devfsd_last_event = entry;
-    spin_unlock (&fs_info->devfsd_buffer_lock);
-    wake_up_interruptible (&fs_info->devfsd_wait_queue);
-    return (TRUE);
-}   /*  End Function devfsd_notify_de  */
-
+static int devfsd_notify_de(struct devfs_entry *de,
+			    unsigned short type, umode_t mode,
+			    uid_t uid, gid_t gid, struct fs_info *fs_info)
+{
+	struct devfsd_buf_entry *entry;
+	struct devfs_entry *curr;
+
+	if (!(fs_info->devfsd_event_mask & (1 << type)))
+		return (FALSE);
+	if ((entry = kmem_cache_alloc(devfsd_buf_cache, SLAB_KERNEL)) == NULL) {
+		atomic_inc(&fs_info->devfsd_overrun_count);
+		return (FALSE);
+	}
+	for (curr = de; curr != NULL; curr = curr->parent)
+		devfs_get(curr);
+	entry->de = de;
+	entry->type = type;
+	entry->mode = mode;
+	entry->uid = uid;
+	entry->gid = gid;
+	entry->next = NULL;
+	spin_lock(&fs_info->devfsd_buffer_lock);
+	if (!fs_info->devfsd_first_event)
+		fs_info->devfsd_first_event = entry;
+	if (fs_info->devfsd_last_event)
+		fs_info->devfsd_last_event->next = entry;
+	fs_info->devfsd_last_event = entry;
+	spin_unlock(&fs_info->devfsd_buffer_lock);
+	wake_up_interruptible(&fs_info->devfsd_wait_queue);
+	return (TRUE);
+}				/*  End Function devfsd_notify_de  */
 
 /**
  *	devfsd_notify - Notify the devfsd daemon of a change.
@@ -1417,11 +1410,11 @@ static int devfsd_notify_de (struct devf
  *		the event.
  */
 
-static void devfsd_notify (struct devfs_entry *de,unsigned short type)
+static void devfsd_notify(struct devfs_entry *de, unsigned short type)
 {
 	devfsd_notify_de(de, type, de->mode, current->euid,
 			 current->egid, &fs_info);
-} 
+}
 
 static int devfs_mk_dev(dev_t dev, umode_t mode, const char *fmt, va_list args)
 {
@@ -1432,15 +1425,15 @@ static int devfs_mk_dev(dev_t dev, umode
 	n = vsnprintf(buf, sizeof(buf), fmt, args);
 	if (n >= sizeof(buf) || !buf[0]) {
 		printk(KERN_WARNING "%s: invalid format string %s\n",
-				__FUNCTION__, fmt);
+		       __FUNCTION__, fmt);
 		return -EINVAL;
 	}
-	
+
 	de = _devfs_prepare_leaf(&dir, buf, mode);
 	if (!de) {
 		printk(KERN_WARNING "%s: could not prepare leaf for %s\n",
-				__FUNCTION__, buf);
-		return -ENOMEM;		/* could be more accurate... */
+		       __FUNCTION__, buf);
+		return -ENOMEM;	/* could be more accurate... */
 	}
 
 	de->u.dev = dev;
@@ -1448,12 +1441,12 @@ static int devfs_mk_dev(dev_t dev, umode
 	error = _devfs_append_entry(dir, de, NULL);
 	if (error) {
 		printk(KERN_WARNING "%s: could not append to parent for %s\n",
-				__FUNCTION__, buf);
+		       __FUNCTION__, buf);
 		goto out;
 	}
 
 	devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
- out:
+      out:
 	devfs_put(dir);
 	return error;
 }
@@ -1464,7 +1457,7 @@ int devfs_mk_bdev(dev_t dev, umode_t mod
 
 	if (!S_ISBLK(mode)) {
 		printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
-				__FUNCTION__, mode, fmt);
+		       __FUNCTION__, mode, fmt);
 		return -EINVAL;
 	}
 
@@ -1474,14 +1467,13 @@ int devfs_mk_bdev(dev_t dev, umode_t mod
 
 EXPORT_SYMBOL(devfs_mk_bdev);
 
-
 int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
 {
 	va_list args;
 
 	if (!S_ISCHR(mode)) {
 		printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
-				__FUNCTION__, mode, fmt);
+		       __FUNCTION__, mode, fmt);
 		return -EINVAL;
 	}
 
@@ -1491,7 +1483,6 @@ int devfs_mk_cdev(dev_t dev, umode_t mod
 
 EXPORT_SYMBOL(devfs_mk_cdev);
 
-
 /**
  *	_devfs_unhook - Unhook a device entry from its parents list
  *	@de: The entry to unhook.
@@ -1501,21 +1492,25 @@ EXPORT_SYMBOL(devfs_mk_cdev);
  *	The caller must have a write lock on the parent directory.
  */
 
-static int _devfs_unhook (struct devfs_entry *de)
+static int _devfs_unhook(struct devfs_entry *de)
 {
-    struct devfs_entry *parent;
-
-    if ( !de || (de->prev == de) ) return FALSE;
-    parent = de->parent;
-    if (de->prev == NULL) parent->u.dir.first = de->next;
-    else de->prev->next = de->next;
-    if (de->next == NULL) parent->u.dir.last = de->prev;
-    else de->next->prev = de->prev;
-    de->prev = de;          /*  Indicate we're unhooked                      */
-    de->next = NULL;        /*  Force early termination for <devfs_readdir>  */
-    return TRUE;
-}   /*  End Function _devfs_unhook  */
+	struct devfs_entry *parent;
 
+	if (!de || (de->prev == de))
+		return FALSE;
+	parent = de->parent;
+	if (de->prev == NULL)
+		parent->u.dir.first = de->next;
+	else
+		de->prev->next = de->next;
+	if (de->next == NULL)
+		parent->u.dir.last = de->prev;
+	else
+		de->next->prev = de->prev;
+	de->prev = de;		/*  Indicate we're unhooked                      */
+	de->next = NULL;	/*  Force early termination for <devfs_readdir>  */
+	return TRUE;
+}				/*  End Function _devfs_unhook  */
 
 /**
  *	_devfs_unregister - Unregister a device entry from its parent.
@@ -1526,83 +1521,83 @@ static int _devfs_unhook (struct devfs_e
  *	unlocked by this function.
  */
 
-static void _devfs_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);
+	int unhooked = _devfs_unhook(de);
 
-    write_unlock (&dir->u.dir.lock);
-    if (!unhooked) return;
-    devfs_get (dir);
-    devfsd_notify (de, DEVFSD_NOTIFY_UNREGISTERED);
-    free_dentry (de);
-    devfs_put (dir);
-    if ( !S_ISDIR (de->mode) ) return;
-    while (TRUE)  /*  Recursively unregister: this is a stack chomper  */
-    {
-	struct devfs_entry *child;
-
-	write_lock (&de->u.dir.lock);
-	de->u.dir.no_more_additions = TRUE;
-	child = de->u.dir.first;
-	VERIFY_ENTRY (child);
-	_devfs_unregister (de, child);
-	if (!child) break;
-	DPRINTK (DEBUG_UNREGISTER, "(%s): child: %p  refcount: %d\n",
-		 child->name, child, atomic_read (&child->refcount) );
-	devfs_put (child);
-    }
-}   /*  End Function _devfs_unregister  */
-
-static int devfs_do_symlink (devfs_handle_t dir, const char *name,
-			     const char *link, devfs_handle_t *handle)
-{
-    int err;
-    unsigned int linklength;
-    char *newlink;
-    struct devfs_entry *de;
-
-    if (handle != NULL) *handle = NULL;
-    if (name == NULL)
-    {
-	PRINTK ("(): NULL name pointer\n");
-	return -EINVAL;
-    }
-    if (link == NULL)
-    {
-	PRINTK ("(%s): NULL link pointer\n", name);
-	return -EINVAL;
-    }
-    linklength = strlen (link);
-    if ( ( newlink = kmalloc (linklength + 1, GFP_KERNEL) ) == NULL )
-	return -ENOMEM;
-    memcpy (newlink, link, linklength);
-    newlink[linklength] = '\0';
-    if ( ( de = _devfs_prepare_leaf (&dir, name, S_IFLNK | S_IRUGO | S_IXUGO) )
-	 == NULL )
-    {
-	PRINTK ("(%s): could not prepare leaf\n", name);
-	kfree (newlink);
-	return -ENOTDIR;
-    }
-    de->info = NULL;
-    de->u.symlink.linkname = newlink;
-    de->u.symlink.length = linklength;
-    if ( ( err = _devfs_append_entry (dir, de, NULL) ) != 0 )
-    {
-	PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
-	devfs_put (dir);
-	return err;
-    }
-    devfs_put (dir);
+	write_unlock(&dir->u.dir.lock);
+	if (!unhooked)
+		return;
+	devfs_get(dir);
+	devfsd_notify(de, DEVFSD_NOTIFY_UNREGISTERED);
+	free_dentry(de);
+	devfs_put(dir);
+	if (!S_ISDIR(de->mode))
+		return;
+	while (TRUE) {		/*  Recursively unregister: this is a stack chomper  */
+		struct devfs_entry *child;
+
+		write_lock(&de->u.dir.lock);
+		de->u.dir.no_more_additions = TRUE;
+		child = de->u.dir.first;
+		VERIFY_ENTRY(child);
+		_devfs_unregister(de, child);
+		if (!child)
+			break;
+		DPRINTK(DEBUG_UNREGISTER, "(%s): child: %p  refcount: %d\n",
+			child->name, child, atomic_read(&child->refcount));
+		devfs_put(child);
+	}
+}				/*  End Function _devfs_unregister  */
+
+static int devfs_do_symlink(devfs_handle_t dir, const char *name,
+			    const char *link, devfs_handle_t * handle)
+{
+	int err;
+	unsigned int linklength;
+	char *newlink;
+	struct devfs_entry *de;
+
+	if (handle != NULL)
+		*handle = NULL;
+	if (name == NULL) {
+		PRINTK("(): NULL name pointer\n");
+		return -EINVAL;
+	}
+	if (link == NULL) {
+		PRINTK("(%s): NULL link pointer\n", name);
+		return -EINVAL;
+	}
+	linklength = strlen(link);
+	if ((newlink = kmalloc(linklength + 1, GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memcpy(newlink, link, linklength);
+	newlink[linklength] = '\0';
+	if ((de = _devfs_prepare_leaf(&dir, name, S_IFLNK | S_IRUGO | S_IXUGO))
+	    == NULL) {
+		PRINTK("(%s): could not prepare leaf\n", name);
+		kfree(newlink);
+		return -ENOTDIR;
+	}
+	de->info = NULL;
+	de->u.symlink.linkname = newlink;
+	de->u.symlink.length = linklength;
+	if ((err = _devfs_append_entry(dir, de, NULL)) != 0) {
+		PRINTK("(%s): could not append to parent, err: %d\n", name,
+		       err);
+		devfs_put(dir);
+		return err;
+	}
+	devfs_put(dir);
 #ifdef CONFIG_DEVFS_DEBUG
-    spin_lock (&stat_lock);
-    stat_num_bytes += linklength + 1;
-    spin_unlock (&stat_lock);
+	spin_lock(&stat_lock);
+	stat_num_bytes += linklength + 1;
+	spin_unlock(&stat_lock);
 #endif
-    if (handle != NULL) *handle = de;
-    return 0;
-}   /*  End Function devfs_do_symlink  */
-
+	if (handle != NULL)
+		*handle = de;
+	return 0;
+}				/*  End Function devfs_do_symlink  */
 
 /**
  *	devfs_mk_symlink Create a symbolic link in the devfs namespace.
@@ -1626,7 +1621,6 @@ int devfs_mk_symlink(const char *from, c
 	return err;
 }
 
-
 /**
  *	devfs_mk_dir - Create a directory in the devfs namespace.
  *		new name is relative to the root of the devfs.
@@ -1668,19 +1662,18 @@ int devfs_mk_dir(const char *fmt, ...)
 		goto out_put;
 	} else if (error) {
 		PRINTK("(%s): could not append to dir: %p \"%s\"\n",
-				buf, dir, dir->name);
+		       buf, dir, dir->name);
 		devfs_put(old);
 		goto out_put;
 	}
-	
+
 	devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
 
- out_put:
+      out_put:
 	devfs_put(dir);
 	return error;
 }
 
-
 void devfs_remove(const char *fmt, ...)
 {
 	char buf[64];
@@ -1706,7 +1699,6 @@ void devfs_remove(const char *fmt, ...)
 	}
 }
 
-
 /**
  *	devfs_generate_path - Generate a pathname for an entry, relative to the devfs root.
  *	@de: The devfs entry.
@@ -1718,90 +1710,93 @@ void devfs_remove(const char *fmt, ...)
  *	else a negative error code.
  */
 
-static int devfs_generate_path (devfs_handle_t de, char *path, int buflen)
+static int devfs_generate_path(devfs_handle_t de, char *path, int buflen)
 {
-    int pos;
+	int pos;
 #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  */
-    pos = buflen - de->namelen - 1;
-    memcpy (path + pos, NAMEOF (de), de->namelen);
-    for (de = de->parent; de->parent != NULL; de = de->parent)
-    {
-	if (pos - de->namelen - 1 < 0) return -ENAMETOOLONG;
-	path[--pos] = '/';
-	pos -= de->namelen;
-	memcpy (path + pos, NAMEOF (de), de->namelen);
-    }
-    return pos;
-}   /*  End Function devfs_generate_path  */
+	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  */
+	pos = buflen - de->namelen - 1;
+	memcpy(path + pos, NAMEOF(de), de->namelen);
+	for (de = de->parent; de->parent != NULL; de = de->parent) {
+		if (pos - de->namelen - 1 < 0)
+			return -ENAMETOOLONG;
+		path[--pos] = '/';
+		pos -= de->namelen;
+		memcpy(path + pos, NAMEOF(de), de->namelen);
+	}
+	return pos;
+}				/*  End Function devfs_generate_path  */
 
 /**
  *	devfs_setup - Process kernel boot options.
  *	@str: The boot options after the "devfs=".
  */
 
-static int __init devfs_setup (char *str)
+static int __init devfs_setup(char *str)
 {
-    static struct
-    {
-	char *name;
-	unsigned int mask;
-	unsigned int *opt;
-    } devfs_options_tab[] __initdata =
-    {
+	static struct {
+		char *name;
+		unsigned int mask;
+		unsigned int *opt;
+	} devfs_options_tab[] __initdata = {
 #ifdef CONFIG_DEVFS_DEBUG
-	{"dall",      DEBUG_ALL,          &devfs_debug_init},
-	{"dmod",      DEBUG_MODULE_LOAD,  &devfs_debug_init},
-	{"dreg",      DEBUG_REGISTER,     &devfs_debug_init},
-	{"dunreg",    DEBUG_UNREGISTER,   &devfs_debug_init},
-	{"dfree",     DEBUG_FREE,         &devfs_debug_init},
-	{"diget",     DEBUG_I_GET,        &devfs_debug_init},
-	{"dchange",   DEBUG_SET_FLAGS,    &devfs_debug_init},
-	{"dsread",    DEBUG_S_READ,       &devfs_debug_init},
-	{"dichange",  DEBUG_I_CHANGE,     &devfs_debug_init},
-	{"dimknod",   DEBUG_I_MKNOD,      &devfs_debug_init},
-	{"dilookup",  DEBUG_I_LOOKUP,     &devfs_debug_init},
-	{"diunlink",  DEBUG_I_UNLINK,     &devfs_debug_init},
-#endif  /*  CONFIG_DEVFS_DEBUG  */
-	{"mount",     OPTION_MOUNT,       &boot_options},
-	{NULL,        0,                  NULL}
-    };
-
-    while ( (*str != '\0') && !isspace (*str) )
-    {
-	int i, found = 0, invert = 0;
-
-	if (strncmp (str, "no", 2) == 0)
-	{
-	    invert = 1;
-	    str += 2;
-	}
-	for (i = 0; devfs_options_tab[i].name != NULL; i++)
-	{
-	    int len = strlen (devfs_options_tab[i].name);
-
-	    if (strncmp (str, devfs_options_tab[i].name, len) == 0)
-	    {
-		if (invert)
-		    *devfs_options_tab[i].opt &= ~devfs_options_tab[i].mask;
-		else
-		    *devfs_options_tab[i].opt |= devfs_options_tab[i].mask;
-		str += len;
-		found = 1;
-		break;
-	    }
+		{
+		"dall", DEBUG_ALL, &devfs_debug_init}, {
+		"dmod", DEBUG_MODULE_LOAD, &devfs_debug_init}, {
+		"dreg", DEBUG_REGISTER, &devfs_debug_init}, {
+		"dunreg", DEBUG_UNREGISTER, &devfs_debug_init}, {
+		"dfree", DEBUG_FREE, &devfs_debug_init}, {
+		"diget", DEBUG_I_GET, &devfs_debug_init}, {
+		"dchange", DEBUG_SET_FLAGS, &devfs_debug_init}, {
+		"dsread", DEBUG_S_READ, &devfs_debug_init}, {
+		"dichange", DEBUG_I_CHANGE, &devfs_debug_init}, {
+		"dimknod", DEBUG_I_MKNOD, &devfs_debug_init}, {
+		"dilookup", DEBUG_I_LOOKUP, &devfs_debug_init}, {
+		"diunlink", DEBUG_I_UNLINK, &devfs_debug_init},
+#endif				/*  CONFIG_DEVFS_DEBUG  */
+		{
+		"mount", OPTION_MOUNT, &boot_options}, {
+		NULL, 0, NULL}
+	};
+
+	while ((*str != '\0') && !isspace(*str)) {
+		int i, found = 0, invert = 0;
+
+		if (strncmp(str, "no", 2) == 0) {
+			invert = 1;
+			str += 2;
+		}
+		for (i = 0; devfs_options_tab[i].name != NULL; i++) {
+			int len = strlen(devfs_options_tab[i].name);
+
+			if (strncmp(str, devfs_options_tab[i].name, len) == 0) {
+				if (invert)
+					*devfs_options_tab[i].opt &=
+					    ~devfs_options_tab[i].mask;
+				else
+					*devfs_options_tab[i].opt |=
+					    devfs_options_tab[i].mask;
+				str += len;
+				found = 1;
+				break;
+			}
+		}
+		if (!found)
+			return 0;	/*  No match         */
+		if (*str != ',')
+			return 0;	/*  No more options  */
+		++str;
 	}
-	if (!found) return 0;       /*  No match         */
-	if (*str != ',') return 0;  /*  No more options  */
-	++str;
-    }
-    return 1;
-}   /*  End Function devfs_setup  */
+	return 1;
+}				/*  End Function devfs_setup  */
 
 __setup("devfs=", devfs_setup);
 
@@ -1809,7 +1804,6 @@ EXPORT_SYMBOL(devfs_mk_symlink);
 EXPORT_SYMBOL(devfs_mk_dir);
 EXPORT_SYMBOL(devfs_remove);
 
-
 /**
  *	try_modload - Notify devfsd of an inode lookup by a non-devfsd process.
  *	@parent: The parent devfs entry.
@@ -1822,26 +1816,26 @@ EXPORT_SYMBOL(devfs_remove);
  *	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,
-			const char *name, unsigned namelen,
-			struct devfs_entry *buf)
-{
-    if ( !( fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP) ) )
-	return -ENOENT;
-    if ( is_devfsd_or_child (fs_info) ) return -ENOENT;
-    memset (buf, 0, sizeof *buf);
-    atomic_set (&buf->refcount, 1);
-    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) )
-	return -ENOENT;
-    /*  Possible success: event has been queued  */
-    return 0;
-}   /*  End Function try_modload  */
-
+static int try_modload(struct devfs_entry *parent, struct fs_info *fs_info,
+		       const char *name, unsigned namelen,
+		       struct devfs_entry *buf)
+{
+	if (!(fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP)))
+		return -ENOENT;
+	if (is_devfsd_or_child(fs_info))
+		return -ENOENT;
+	memset(buf, 0, sizeof *buf);
+	atomic_set(&buf->refcount, 1);
+	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))
+		return -ENOENT;
+	/*  Possible success: event has been queued  */
+	return 0;
+}				/*  End Function try_modload  */
 
 /*  Superblock operations follow  */
 
@@ -1851,44 +1845,45 @@ static struct file_operations devfs_fops
 static struct file_operations devfs_dir_fops;
 static struct inode_operations devfs_symlink_iops;
 
-static int devfs_notify_change (struct dentry *dentry, struct iattr *iattr)
+static int devfs_notify_change(struct dentry *dentry, struct iattr *iattr)
 {
-    int retval;
-    struct devfs_entry *de;
-    struct inode *inode = dentry->d_inode;
-    struct fs_info *fs_info = inode->i_sb->s_fs_info;
-
-    de = get_devfs_entry_from_vfs_inode (inode);
-    if (de == NULL) return -ENODEV;
-    retval = inode_change_ok (inode, iattr);
-    if (retval != 0) return retval;
-    retval = inode_setattr (inode, iattr);
-    if (retval != 0) return retval;
-    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  */
-    de->mode = inode->i_mode;
-    de->inode.uid = inode->i_uid;
-    de->inode.gid = inode->i_gid;
-    de->inode.atime = inode->i_atime;
-    de->inode.mtime = inode->i_mtime;
-    de->inode.ctime = inode->i_ctime;
-    if ( ( iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID) ) &&
-	 !is_devfsd_or_child (fs_info) )
-	devfsd_notify_de (de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
-    return 0;
-}   /*  End Function devfs_notify_change  */
-
-static struct super_operations devfs_sops =
-{ 
-    .drop_inode    = generic_delete_inode,
-    .statfs        = simple_statfs,
-};
+	int retval;
+	struct devfs_entry *de;
+	struct inode *inode = dentry->d_inode;
+	struct fs_info *fs_info = inode->i_sb->s_fs_info;
 
+	de = get_devfs_entry_from_vfs_inode(inode);
+	if (de == NULL)
+		return -ENODEV;
+	retval = inode_change_ok(inode, iattr);
+	if (retval != 0)
+		return retval;
+	retval = inode_setattr(inode, iattr);
+	if (retval != 0)
+		return retval;
+	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  */
+	de->mode = inode->i_mode;
+	de->inode.uid = inode->i_uid;
+	de->inode.gid = inode->i_gid;
+	de->inode.atime = inode->i_atime;
+	de->inode.mtime = inode->i_mtime;
+	de->inode.ctime = inode->i_ctime;
+	if ((iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) &&
+	    !is_devfsd_or_child(fs_info))
+		devfsd_notify_de(de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
+				 inode->i_uid, inode->i_gid, fs_info);
+	return 0;
+}				/*  End Function devfs_notify_change  */
+
+static struct super_operations devfs_sops = {
+	.drop_inode = generic_delete_inode,
+	.statfs = simple_statfs,
+};
 
 /**
  *	_devfs_get_vfs_inode - Get a VFS inode.
@@ -1900,39 +1895,38 @@ static struct super_operations devfs_sop
  *       performed if the inode is created.
  */
 
-static struct inode *_devfs_get_vfs_inode (struct super_block *sb,
-					   struct devfs_entry *de,
-					   struct dentry *dentry)
-{
-    struct inode *inode;
-
-    if (de->prev == de) return NULL;  /*  Quick check to see if unhooked  */
-    if ( ( inode = new_inode (sb) ) == NULL )
-    {
-	PRINTK ("(%s): new_inode() failed, de: %p\n", de->name, de);
-	return NULL;
-    }
-    if (de->parent)
-    {
-	read_lock (&de->parent->u.dir.lock);
-	if (de->prev != de) de->inode.dentry = dentry; /*      Not unhooked  */
-	read_unlock (&de->parent->u.dir.lock);
-    }
-    else de->inode.dentry = dentry;             /*  Root: no locking needed  */
-    if (de->inode.dentry != dentry)
-    {   /*  Must have been unhooked  */
-	iput (inode);
-	return NULL;
-    }
-    /* FIXME where is devfs_put? */
-    inode->u.generic_ip = devfs_get (de);
-    inode->i_ino = de->inode.ino;
-    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;
-    inode->i_mode = de->mode;
+static struct inode *_devfs_get_vfs_inode(struct super_block *sb,
+					  struct devfs_entry *de,
+					  struct dentry *dentry)
+{
+	struct inode *inode;
+
+	if (de->prev == de)
+		return NULL;	/*  Quick check to see if unhooked  */
+	if ((inode = new_inode(sb)) == NULL) {
+		PRINTK("(%s): new_inode() failed, de: %p\n", de->name, de);
+		return NULL;
+	}
+	if (de->parent) {
+		read_lock(&de->parent->u.dir.lock);
+		if (de->prev != de)
+			de->inode.dentry = dentry;	/*      Not unhooked  */
+		read_unlock(&de->parent->u.dir.lock);
+	} else
+		de->inode.dentry = dentry;	/*  Root: no locking needed  */
+	if (de->inode.dentry != dentry) {	/*  Must have been unhooked  */
+		iput(inode);
+		return NULL;
+	}
+	/* FIXME where is devfs_put? */
+	inode->u.generic_ip = devfs_get(de);
+	inode->i_ino = de->inode.ino;
+	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;
+	inode->i_mode = de->mode;
 	if (S_ISDIR(de->mode)) {
 		inode->i_op = &devfs_dir_iops;
 		inode->i_fop = &devfs_dir_fops;
@@ -1945,100 +1939,107 @@ static struct inode *_devfs_get_vfs_inod
 		init_special_inode(inode, de->mode, 0);
 	} else {
 		PRINTK("(%s): unknown mode %o de: %p\n",
-			de->name, de->mode, de);
+		       de->name, de->mode, de);
 		iput(inode);
 		devfs_put(de);
 		return NULL;
 	}
 
-    inode->i_uid = de->inode.uid;
-    inode->i_gid = de->inode.gid;
-    inode->i_atime = de->inode.atime;
-    inode->i_mtime = de->inode.mtime;
-    inode->i_ctime = de->inode.ctime;
-    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 _devfs_get_vfs_inode  */
-
+	inode->i_uid = de->inode.uid;
+	inode->i_gid = de->inode.gid;
+	inode->i_atime = de->inode.atime;
+	inode->i_mtime = de->inode.mtime;
+	inode->i_ctime = de->inode.ctime;
+	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 _devfs_get_vfs_inode  */
 
 /*  File operations for device entries follow  */
 
-static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
+static int devfs_readdir(struct file *file, void *dirent, filldir_t filldir)
 {
-    int err, count;
-    int stored = 0;
-    struct fs_info *fs_info;
-    struct devfs_entry *parent, *de, *next = NULL;
-    struct inode *inode = file->f_dentry->d_inode;
-
-    fs_info = inode->i_sb->s_fs_info;
-    parent = get_devfs_entry_from_vfs_inode (file->f_dentry->d_inode);
-    if ( (long) file->f_pos < 0 ) return -EINVAL;
-    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:
-	err = (*filldir) (dirent, "..", 2, file->f_pos,
-			  parent_ino (file->f_dentry), DT_DIR);
-	if (err == -EINVAL) break;
-	if (err < 0) return err;
-	file->f_pos++;
-	++stored;
-	/*  Fall through  */
-      case 1:
-	err = (*filldir) (dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR);
-	if (err == -EINVAL) break;
-	if (err < 0) return err;
-	file->f_pos++;
-	++stored;
-	/*  Fall through  */
-      default:
-	/*  Skip entries  */
-	count = file->f_pos - 2;
-	read_lock (&parent->u.dir.lock);
-	for (de = parent->u.dir.first; de && (count > 0); de = de->next)
-	    --count;
-	devfs_get (de);
-	read_unlock (&parent->u.dir.lock);
-	/*  Now add all remaining entries  */
-	while (de)
-	{
-	    err = (*filldir) (dirent, de->name, de->namelen,
-				file->f_pos, de->inode.ino, de->mode >> 12);
-	    if (err < 0) devfs_put (de);
-	    else
-	    {
-	        file->f_pos++;
-	        ++stored;
-	    }
-	    if (err == -EINVAL) break;
-	    if (err < 0) return err;
-	    read_lock (&parent->u.dir.lock);
-	    next = devfs_get (de->next);
-	    read_unlock (&parent->u.dir.lock);
-	    devfs_put (de);
-	    de = next;
-	}
-	break;
-    }
-    return stored;
-}   /*  End Function devfs_readdir  */
+	int err, count;
+	int stored = 0;
+	struct fs_info *fs_info;
+	struct devfs_entry *parent, *de, *next = NULL;
+	struct inode *inode = file->f_dentry->d_inode;
+
+	fs_info = inode->i_sb->s_fs_info;
+	parent = get_devfs_entry_from_vfs_inode(file->f_dentry->d_inode);
+	if ((long)file->f_pos < 0)
+		return -EINVAL;
+	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:
+		err = (*filldir) (dirent, "..", 2, file->f_pos,
+				  parent_ino(file->f_dentry), DT_DIR);
+		if (err == -EINVAL)
+			break;
+		if (err < 0)
+			return err;
+		file->f_pos++;
+		++stored;
+		/*  Fall through  */
+	case 1:
+		err =
+		    (*filldir) (dirent, ".", 1, file->f_pos, inode->i_ino,
+				DT_DIR);
+		if (err == -EINVAL)
+			break;
+		if (err < 0)
+			return err;
+		file->f_pos++;
+		++stored;
+		/*  Fall through  */
+	default:
+		/*  Skip entries  */
+		count = file->f_pos - 2;
+		read_lock(&parent->u.dir.lock);
+		for (de = parent->u.dir.first; de && (count > 0); de = de->next)
+			--count;
+		devfs_get(de);
+		read_unlock(&parent->u.dir.lock);
+		/*  Now add all remaining entries  */
+		while (de) {
+			err = (*filldir) (dirent, de->name, de->namelen,
+					  file->f_pos, de->inode.ino,
+					  de->mode >> 12);
+			if (err < 0)
+				devfs_put(de);
+			else {
+				file->f_pos++;
+				++stored;
+			}
+			if (err == -EINVAL)
+				break;
+			if (err < 0)
+				return err;
+			read_lock(&parent->u.dir.lock);
+			next = devfs_get(de->next);
+			read_unlock(&parent->u.dir.lock);
+			devfs_put(de);
+			de = next;
+		}
+		break;
+	}
+	return stored;
+}				/*  End Function devfs_readdir  */
 
 /* Open devfs specific special files */
-static int devfs_open (struct inode *inode, struct file *file)
+static int devfs_open(struct inode *inode, struct file *file)
 {
 	int err;
 	int minor = MINOR(inode->i_rdev);
 	struct file_operations *old_fops, *new_fops;
 
 	switch (minor) {
-	case 0: /* /dev/.devfsd */
+	case 0:		/* /dev/.devfsd */
 		new_fops = fops_get(&devfsd_fops);
 		break;
 #ifdef CONFIG_DEVFS_DEBUG
-	case 1: /* /dev/.stat */
+	case 1:		/* /dev/.stat */
 		new_fops = fops_get(&stat_fops);
 		break;
 #endif
@@ -2057,32 +2058,28 @@ static int devfs_open (struct inode *ino
 	} else
 		fops_put(old_fops);
 	return err;
-}   /*  End Function devfs_open  */
+}				/*  End Function devfs_open  */
 
-static struct file_operations devfs_fops =
-{
-    .open    = devfs_open,
+static struct file_operations devfs_fops = {
+	.open = devfs_open,
 };
 
-static struct file_operations devfs_dir_fops =
-{
-    .read    = generic_read_dir,
-    .readdir = devfs_readdir,
+static struct file_operations devfs_dir_fops = {
+	.read = generic_read_dir,
+	.readdir = devfs_readdir,
 };
 
-
 /*  Dentry operations for device entries follow  */
 
-
 /**
  *	devfs_d_release - Callback for when a dentry is freed.
  *	@dentry: The dentry.
  */
 
-static void devfs_d_release (struct dentry *dentry)
+static void devfs_d_release(struct dentry *dentry)
 {
-    DPRINTK (DEBUG_D_RELEASE, "(%p): inode: %p\n", dentry, dentry->d_inode);
-}   /*  End Function devfs_d_release  */
+	DPRINTK(DEBUG_D_RELEASE, "(%p): inode: %p\n", dentry, dentry->d_inode);
+}				/*  End Function devfs_d_release  */
 
 /**
  *	devfs_d_iput - Callback for when a dentry loses its inode.
@@ -2090,38 +2087,37 @@ static void devfs_d_release (struct dent
  *	@inode:	The inode.
  */
 
-static void devfs_d_iput (struct dentry *dentry, struct inode *inode)
+static void devfs_d_iput(struct dentry *dentry, struct inode *inode)
 {
-    struct devfs_entry *de;
+	struct devfs_entry *de;
 
-    de = get_devfs_entry_from_vfs_inode (inode);
-    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): de: %p dentry: %p de->dentry: %p\n",
-	      de->name, de, dentry, de->inode.dentry);
-    de->inode.dentry = NULL;
-    iput (inode);
-    devfs_put (de);
-}   /*  End Function devfs_d_iput  */
-
-static int devfs_d_delete (struct dentry *dentry);
-
-static struct dentry_operations devfs_dops =
-{
-    .d_delete     = devfs_d_delete,
-    .d_release    = devfs_d_release,
-    .d_iput       = devfs_d_iput,
+	de = get_devfs_entry_from_vfs_inode(inode);
+	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): de: %p dentry: %p de->dentry: %p\n",
+		     de->name, de, dentry, de->inode.dentry);
+	de->inode.dentry = NULL;
+	iput(inode);
+	devfs_put(de);
+}				/*  End Function devfs_d_iput  */
+
+static int devfs_d_delete(struct dentry *dentry);
+
+static struct dentry_operations devfs_dops = {
+	.d_delete = devfs_d_delete,
+	.d_release = devfs_d_release,
+	.d_iput = devfs_d_iput,
 };
 
-static int devfs_d_revalidate_wait (struct dentry *dentry, struct nameidata *);
+static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *);
 
-static struct dentry_operations devfs_wait_dops =
-{
-    .d_delete     = devfs_d_delete,
-    .d_release    = devfs_d_release,
-    .d_iput       = devfs_d_iput,
-    .d_revalidate = devfs_d_revalidate_wait,
+static struct dentry_operations devfs_wait_dops = {
+	.d_delete = devfs_d_delete,
+	.d_release = devfs_d_release,
+	.d_iput = devfs_d_iput,
+	.d_revalidate = devfs_d_revalidate_wait,
 };
 
 /**
@@ -2129,653 +2125,673 @@ static struct dentry_operations devfs_wa
  *	@dentry: The dentry.
  */
 
-static int devfs_d_delete (struct dentry *dentry)
+static int devfs_d_delete(struct dentry *dentry)
 {
-    struct inode *inode = dentry->d_inode;
+	struct inode *inode = dentry->d_inode;
 
-    if (dentry->d_op == &devfs_wait_dops) dentry->d_op = &devfs_dops;
-    /*  Unhash dentry if negative (has no inode)  */
-    if (inode == NULL)
-    {
-	DPRINTK (DEBUG_D_DELETE, "(%p): dropping negative dentry\n", dentry);
-	return 1;
-    }
-    return 0;
-}   /*  End Function devfs_d_delete  */
+	if (dentry->d_op == &devfs_wait_dops)
+		dentry->d_op = &devfs_dops;
+	/*  Unhash dentry if negative (has no inode)  */
+	if (inode == NULL) {
+		DPRINTK(DEBUG_D_DELETE, "(%p): dropping negative dentry\n",
+			dentry);
+		return 1;
+	}
+	return 0;
+}				/*  End Function devfs_d_delete  */
 
-struct devfs_lookup_struct
-{
-    devfs_handle_t de;
-    wait_queue_head_t wait_queue;
+struct devfs_lookup_struct {
+	devfs_handle_t de;
+	wait_queue_head_t wait_queue;
 };
 
 /* XXX: this doesn't handle the case where we got a negative dentry
         but a devfs entry has been registered in the meanwhile */
-static int devfs_d_revalidate_wait (struct dentry *dentry, struct nameidata *nd)
+static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *nd)
 {
-    struct inode *dir = dentry->d_parent->d_inode;
-    struct fs_info *fs_info = dir->i_sb->s_fs_info;
-    devfs_handle_t parent = get_devfs_entry_from_vfs_inode (dir);
-    struct devfs_lookup_struct *lookup_info = dentry->d_fsdata;
-    DECLARE_WAITQUEUE (wait, current);
-    int need_lock;
-
-    /*
-     * FIXME HACK
-     *
-     * make sure that
-     *   d_instantiate always runs under lock
-     *   we release i_sem lock before going to sleep
-     *
-     * unfortunately sometimes d_revalidate is called with
-     * and sometimes without i_sem lock held. The following checks
-     * attempt to deduce when we need to add (and drop resp.) lock
-     * here. This relies on current (2.6.2) calling coventions:
-     *
-     *   lookup_hash is always run under i_sem and is passing NULL
-     *   as nd
-     *
-     *   open(...,O_CREATE,...) calls _lookup_hash under i_sem
-     *   and sets flags to LOOKUP_OPEN|LOOKUP_CREATE
-     *
-     *   all other invocations of ->d_revalidate seem to happen
-     *   outside of i_sem
-     */
-    need_lock = nd &&
-		(!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT));
-
-    if (need_lock)
-	down(&dir->i_sem);
-
-    if ( is_devfsd_or_child (fs_info) )
-    {
-	devfs_handle_t de = lookup_info->de;
+	struct inode *dir = dentry->d_parent->d_inode;
+	struct fs_info *fs_info = dir->i_sb->s_fs_info;
+	devfs_handle_t parent = get_devfs_entry_from_vfs_inode(dir);
+	struct devfs_lookup_struct *lookup_info = dentry->d_fsdata;
+	DECLARE_WAITQUEUE(wait, current);
+	int need_lock;
+
+	/*
+	 * FIXME HACK
+	 *
+	 * make sure that
+	 *   d_instantiate always runs under lock
+	 *   we release i_sem lock before going to sleep
+	 *
+	 * unfortunately sometimes d_revalidate is called with
+	 * and sometimes without i_sem lock held. The following checks
+	 * attempt to deduce when we need to add (and drop resp.) lock
+	 * here. This relies on current (2.6.2) calling coventions:
+	 *
+	 *   lookup_hash is always run under i_sem and is passing NULL
+	 *   as nd
+	 *
+	 *   open(...,O_CREATE,...) calls _lookup_hash under i_sem
+	 *   and sets flags to LOOKUP_OPEN|LOOKUP_CREATE
+	 *
+	 *   all other invocations of ->d_revalidate seem to happen
+	 *   outside of i_sem
+	 */
+	need_lock = nd &&
+	    (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT));
+
+	if (need_lock)
+		down(&dir->i_sem);
+
+	if (is_devfsd_or_child(fs_info)) {
+		devfs_handle_t de = lookup_info->de;
+		struct inode *inode;
+
+		DPRINTK(DEBUG_I_LOOKUP,
+			"(%s): dentry: %p inode: %p de: %p by: \"%s\"\n",
+			dentry->d_name.name, dentry, dentry->d_inode, de,
+			current->comm);
+		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)
+				goto out;
+			lookup_info->de = de;
+		}
+		/*  Create an inode, now that the driver information is available  */
+		inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
+		if (!inode)
+			goto out;
+		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);
+		goto out;
+	}
+	if (lookup_info == NULL)
+		goto out;	/*  Early termination  */
+	read_lock(&parent->u.dir.lock);
+	if (dentry->d_fsdata) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&lookup_info->wait_queue, &wait);
+		read_unlock(&parent->u.dir.lock);
+		/* at this point it is always (hopefully) locked */
+		up(&dir->i_sem);
+		schedule();
+		down(&dir->i_sem);
+		/*
+		 * This does not need nor should remove wait from wait_queue.
+		 * Wait queue head is never reused - nothing is ever added to it
+		 * after all waiters have been waked up and head itself disappears
+		 * very soon after it. Moreover it is local variable on stack that
+		 * is likely to have already disappeared so any reference to it
+		 * at this point is buggy.
+		 */
+
+	} else
+		read_unlock(&parent->u.dir.lock);
+
+      out:
+	if (need_lock)
+		up(&dir->i_sem);
+	return 1;
+}				/*  End Function devfs_d_revalidate_wait  */
+
+/*  Inode operations for device entries follow  */
+
+static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry,
+				   struct nameidata *nd)
+{
+	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->s_fs_info;
+	struct devfs_entry *parent, *de;
 	struct inode *inode;
+	struct dentry *retval = NULL;
 
-	DPRINTK (DEBUG_I_LOOKUP,
-		 "(%s): dentry: %p inode: %p de: %p by: \"%s\"\n",
-		 dentry->d_name.name, dentry, dentry->d_inode, de,
-		 current->comm);
+	/*  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);
+	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);
+	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  */
+		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;
+		}
+	}
+	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)
 		goto out;
-	    lookup_info->de = de;
+	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)
+			goto out;
+		/*  OK, there's an entry now, but no VFS inode yet  */
 	}
 	/*  Create an inode, now that the driver information is available  */
-	inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry);
-	if (!inode)
-	    goto out;
-	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);
-	goto out;
-    }
-    if (lookup_info == NULL)
-	goto out;  /*  Early termination  */
-    read_lock (&parent->u.dir.lock);
-    if (dentry->d_fsdata)
-    {
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	add_wait_queue (&lookup_info->wait_queue, &wait);
-	read_unlock (&parent->u.dir.lock);
-	/* at this point it is always (hopefully) locked */
-	up(&dir->i_sem);
-	schedule ();
-	down(&dir->i_sem);
-	/*
-	 * This does not need nor should remove wait from wait_queue.
-	 * Wait queue head is never reused - nothing is ever added to it
-	 * after all waiters have been waked up and head itself disappears
-	 * very soon after it. Moreover it is local variable on stack that
-	 * is likely to have already disappeared so any reference to it
-	 * at this point is buggy.
-	 */
+	inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
+	if (!inode) {
+		retval = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+	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);
+      out:
+	write_lock(&parent->u.dir.lock);
+	dentry->d_op = &devfs_dops;
+	dentry->d_fsdata = NULL;
+	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)
+{
+	int unhooked;
+	struct devfs_entry *de;
+	struct inode *inode = dentry->d_inode;
+	struct fs_info *fs_info = dir->i_sb->s_fs_info;
 
-    }
-    else read_unlock (&parent->u.dir.lock);
+	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)
+		return -EPERM;
+	write_lock(&de->parent->u.dir.lock);
+	unhooked = _devfs_unhook(de);
+	write_unlock(&de->parent->u.dir.lock);
+	if (!unhooked)
+		return -ENOENT;
+	if (!is_devfsd_or_child(fs_info))
+		devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
+				 inode->i_uid, inode->i_gid, fs_info);
+	free_dentry(de);
+	devfs_put(de);
+	return 0;
+}				/*  End Function devfs_unlink  */
 
-out:
-    if (need_lock)
-	up(&dir->i_sem);
-    return 1;
-}   /*  End Function devfs_d_revalidate_wait  */
+static int devfs_symlink(struct inode *dir, struct dentry *dentry,
+			 const char *symname)
+{
+	int err;
+	struct fs_info *fs_info = dir->i_sb->s_fs_info;
+	struct devfs_entry *parent, *de;
+	struct inode *inode;
 
+	/*  First try to get the devfs entry for this directory  */
+	parent = get_devfs_entry_from_vfs_inode(dir);
+	if (parent == NULL)
+		return -ENOENT;
+	err = devfs_do_symlink(parent, dentry->d_name.name, symname, &de);
+	DPRINTK(DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
+		dentry->d_name.name, err);
+	if (err < 0)
+		return err;
+	de->vfs = TRUE;
+	de->inode.uid = current->euid;
+	de->inode.gid = current->egid;
+	de->inode.atime = CURRENT_TIME;
+	de->inode.mtime = CURRENT_TIME;
+	de->inode.ctime = CURRENT_TIME;
+	if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
+		return -ENOMEM;
+	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,
+				 inode->i_uid, inode->i_gid, fs_info);
+	return 0;
+}				/*  End Function devfs_symlink  */
 
-/*  Inode operations for device entries follow  */
+static int devfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	int err;
+	struct fs_info *fs_info = dir->i_sb->s_fs_info;
+	struct devfs_entry *parent, *de;
+	struct inode *inode;
 
-static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+	mode = (mode & ~S_IFMT) | S_IFDIR;	/*  VFS doesn't pass S_IFMT part  */
+	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);
+	if (!de)
+		return -ENOMEM;
+	de->vfs = TRUE;
+	if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
+		return err;
+	de->inode.uid = current->euid;
+	de->inode.gid = current->egid;
+	de->inode.atime = CURRENT_TIME;
+	de->inode.mtime = CURRENT_TIME;
+	de->inode.ctime = CURRENT_TIME;
+	if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
+		return -ENOMEM;
+	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,
+				 inode->i_uid, inode->i_gid, fs_info);
+	return 0;
+}				/*  End Function devfs_mkdir  */
+
+static int devfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	int err = 0;
+	struct devfs_entry *de;
+	struct fs_info *fs_info = dir->i_sb->s_fs_info;
+	struct inode *inode = dentry->d_inode;
+
+	if (dir->i_sb->s_fs_info != inode->i_sb->s_fs_info)
+		return -EINVAL;
+	de = get_devfs_entry_from_vfs_inode(inode);
+	if (de == NULL)
+		return -ENOENT;
+	if (!S_ISDIR(de->mode))
+		return -ENOTDIR;
+	if (!de->vfs)
+		return -EPERM;
+	/*  First ensure the directory is empty and will stay that way  */
+	write_lock(&de->u.dir.lock);
+	if (de->u.dir.first)
+		err = -ENOTEMPTY;
+	else
+		de->u.dir.no_more_additions = TRUE;
+	write_unlock(&de->u.dir.lock);
+	if (err)
+		return err;
+	/*  Now unhook the directory from its parent  */
+	write_lock(&de->parent->u.dir.lock);
+	if (!_devfs_unhook(de))
+		err = -ENOENT;
+	write_unlock(&de->parent->u.dir.lock);
+	if (err)
+		return err;
+	if (!is_devfsd_or_child(fs_info))
+		devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
+				 inode->i_uid, inode->i_gid, fs_info);
+	free_dentry(de);
+	devfs_put(de);
+	return 0;
+}				/*  End Function devfs_rmdir  */
+
+static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
+		       dev_t rdev)
 {
-    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->s_fs_info;
-    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);
-    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);
-    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  */
-	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;
-	}
-    }
-    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) goto out;
-	/*  OK, there's an entry now, but no VFS inode yet  */
-    }
-    /*  Create an inode, now that the driver information is available  */
-    inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry);
-    if (!inode)
-    {
-	retval = ERR_PTR (-ENOMEM);
-	goto out;
-    }
-    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);
-out:
-    write_lock (&parent->u.dir.lock);
-    dentry->d_op = &devfs_dops;
-    dentry->d_fsdata = NULL;
-    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)
-{
-    int unhooked;
-    struct devfs_entry *de;
-    struct inode *inode = dentry->d_inode;
-    struct fs_info *fs_info = dir->i_sb->s_fs_info;
-
-    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) return -EPERM;
-    write_lock (&de->parent->u.dir.lock);
-    unhooked = _devfs_unhook (de);
-    write_unlock (&de->parent->u.dir.lock);
-    if (!unhooked) return -ENOENT;
-    if ( !is_devfsd_or_child (fs_info) )
-	devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
-    free_dentry (de);
-    devfs_put (de);
-    return 0;
-}   /*  End Function devfs_unlink  */
-
-static int devfs_symlink (struct inode *dir, struct dentry *dentry,
-			  const char *symname)
-{
-    int err;
-    struct fs_info *fs_info = dir->i_sb->s_fs_info;
-    struct devfs_entry *parent, *de;
-    struct inode *inode;
-
-    /*  First try to get the devfs entry for this directory  */
-    parent = get_devfs_entry_from_vfs_inode (dir);
-    if (parent == NULL) return -ENOENT;
-    err = devfs_do_symlink (parent, dentry->d_name.name, symname, &de);
-    DPRINTK (DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
-	     dentry->d_name.name, err);
-    if (err < 0) return err;
-    de->vfs = TRUE;
-    de->inode.uid = current->euid;
-    de->inode.gid = current->egid;
-    de->inode.atime = CURRENT_TIME;
-    de->inode.mtime = CURRENT_TIME;
-    de->inode.ctime = CURRENT_TIME;
-    if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
-	return -ENOMEM;
-    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,
-			  inode->i_uid, inode->i_gid, fs_info);
-    return 0;
-}   /*  End Function devfs_symlink  */
-
-static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
-{
-    int err;
-    struct fs_info *fs_info = dir->i_sb->s_fs_info;
-    struct devfs_entry *parent, *de;
-    struct inode *inode;
-
-    mode = (mode & ~S_IFMT) | S_IFDIR;  /*  VFS doesn't pass S_IFMT part  */
-    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);
-    if (!de) return -ENOMEM;
-    de->vfs = TRUE;
-    if ( ( err = _devfs_append_entry (parent, de, NULL) ) != 0 )
-	return err;
-    de->inode.uid = current->euid;
-    de->inode.gid = current->egid;
-    de->inode.atime = CURRENT_TIME;
-    de->inode.mtime = CURRENT_TIME;
-    de->inode.ctime = CURRENT_TIME;
-    if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
-	return -ENOMEM;
-    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,
-			  inode->i_uid, inode->i_gid, fs_info);
-    return 0;
-}   /*  End Function devfs_mkdir  */
-
-static int devfs_rmdir (struct inode *dir, struct dentry *dentry)
-{
-    int err = 0;
-    struct devfs_entry *de;
-    struct fs_info *fs_info = dir->i_sb->s_fs_info;
-    struct inode *inode = dentry->d_inode;
-
-    if (dir->i_sb->s_fs_info != inode->i_sb->s_fs_info) return -EINVAL;
-    de = get_devfs_entry_from_vfs_inode (inode);
-    if (de == NULL) return -ENOENT;
-    if ( !S_ISDIR (de->mode) ) return -ENOTDIR;
-    if (!de->vfs) return -EPERM;
-    /*  First ensure the directory is empty and will stay that way  */
-    write_lock (&de->u.dir.lock);
-    if (de->u.dir.first) err = -ENOTEMPTY;
-    else de->u.dir.no_more_additions = TRUE;
-    write_unlock (&de->u.dir.lock);
-    if (err) return err;
-    /*  Now unhook the directory from its parent  */
-    write_lock (&de->parent->u.dir.lock);
-    if ( !_devfs_unhook (de) ) err = -ENOENT;
-    write_unlock (&de->parent->u.dir.lock);
-    if (err) return err;
-    if ( !is_devfsd_or_child (fs_info) )
-	devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
-			  inode->i_uid, inode->i_gid, fs_info);
-    free_dentry (de);
-    devfs_put (de);
-    return 0;
-}   /*  End Function devfs_rmdir  */
-
-static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
-			dev_t rdev)
-{
-    int err;
-    struct fs_info *fs_info = dir->i_sb->s_fs_info;
-    struct devfs_entry *parent, *de;
-    struct inode *inode;
-
-    DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o  dev: %u:%u\n",
-	     dentry->d_name.name, mode, MAJOR(rdev), MINOR(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);
-    if (!de) return -ENOMEM;
-    de->vfs = TRUE;
-    if (S_ISCHR(mode) || S_ISBLK(mode))
-	de->u.dev = rdev;
-    if ( ( err = _devfs_append_entry (parent, de, NULL) ) != 0 )
+	int err;
+	struct fs_info *fs_info = dir->i_sb->s_fs_info;
+	struct devfs_entry *parent, *de;
+	struct inode *inode;
+
+	DPRINTK(DEBUG_I_MKNOD, "(%s): mode: 0%o  dev: %u:%u\n",
+		dentry->d_name.name, mode, MAJOR(rdev), MINOR(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);
+	if (!de)
+		return -ENOMEM;
+	de->vfs = TRUE;
+	if (S_ISCHR(mode) || S_ISBLK(mode))
+		de->u.dev = rdev;
+	if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
+		return err;
+	de->inode.uid = current->euid;
+	de->inode.gid = current->egid;
+	de->inode.atime = CURRENT_TIME;
+	de->inode.mtime = CURRENT_TIME;
+	de->inode.ctime = CURRENT_TIME;
+	if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
+		return -ENOMEM;
+	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,
+				 inode->i_uid, inode->i_gid, fs_info);
+	return 0;
+}				/*  End Function devfs_mknod  */
+
+static int devfs_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+	int err;
+	struct devfs_entry *de;
+
+	de = get_devfs_entry_from_vfs_inode(dentry->d_inode);
+	if (!de)
+		return -ENODEV;
+	err = vfs_readlink(dentry, buffer, buflen, de->u.symlink.linkname);
 	return err;
-    de->inode.uid = current->euid;
-    de->inode.gid = current->egid;
-    de->inode.atime = CURRENT_TIME;
-    de->inode.mtime = CURRENT_TIME;
-    de->inode.ctime = CURRENT_TIME;
-    if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
-	return -ENOMEM;
-    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,
-			  inode->i_uid, inode->i_gid, fs_info);
-    return 0;
-}   /*  End Function devfs_mknod  */
-
-static int devfs_readlink (struct dentry *dentry, char *buffer, int buflen)
-{
-    int err;
-    struct devfs_entry *de;
-
-    de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
-    if (!de) return -ENODEV;
-    err = vfs_readlink (dentry, buffer, buflen, de->u.symlink.linkname);
-    return err;
-}   /*  End Function devfs_readlink  */
-
-static int devfs_follow_link (struct dentry *dentry, struct nameidata *nd)
-{
-    int err;
-    struct devfs_entry *de;
-
-    de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
-    if (!de) return -ENODEV;
-    err = vfs_follow_link (nd, de->u.symlink.linkname);
-    return err;
-}   /*  End Function devfs_follow_link  */
+}				/*  End Function devfs_readlink  */
 
-static struct inode_operations devfs_iops =
+static int devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-    .setattr        = devfs_notify_change,
+	int err;
+	struct devfs_entry *de;
+
+	de = get_devfs_entry_from_vfs_inode(dentry->d_inode);
+	if (!de)
+		return -ENODEV;
+	err = vfs_follow_link(nd, de->u.symlink.linkname);
+	return err;
+}				/*  End Function devfs_follow_link  */
+
+static struct inode_operations devfs_iops = {
+	.setattr = devfs_notify_change,
 };
 
-static struct inode_operations devfs_dir_iops =
-{
-    .lookup         = devfs_lookup,
-    .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,
+	.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,
+static struct inode_operations devfs_symlink_iops = {
+	.readlink = devfs_readlink,
+	.follow_link = devfs_follow_link,
+	.setattr = devfs_notify_change,
 };
 
-static int devfs_fill_super (struct super_block *sb, void *data, int silent)
+static int devfs_fill_super(struct super_block *sb, void *data, int silent)
 {
-    struct inode *root_inode = NULL;
+	struct inode *root_inode = NULL;
+
+	if (_devfs_get_root_entry() == NULL)
+		goto out_no_root;
+	atomic_set(&fs_info.devfsd_overrun_count, 0);
+	init_waitqueue_head(&fs_info.devfsd_wait_queue);
+	init_waitqueue_head(&fs_info.revalidate_wait_queue);
+	fs_info.sb = sb;
+	sb->s_fs_info = &fs_info;
+	sb->s_blocksize = 1024;
+	sb->s_blocksize_bits = 10;
+	sb->s_magic = DEVFS_SUPER_MAGIC;
+	sb->s_op = &devfs_sops;
+	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;
+	DPRINTK(DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->s_fs_info);
+	return 0;
+
+      out_no_root:
+	PRINTK("(): get root inode failed\n");
+	if (root_inode)
+		iput(root_inode);
+	return -EINVAL;
+}				/*  End Function devfs_fill_super  */
 
-    if (_devfs_get_root_entry () == NULL) goto out_no_root;
-    atomic_set (&fs_info.devfsd_overrun_count, 0);
-    init_waitqueue_head (&fs_info.devfsd_wait_queue);
-    init_waitqueue_head (&fs_info.revalidate_wait_queue);
-    fs_info.sb = sb;
-    sb->s_fs_info = &fs_info;
-    sb->s_blocksize = 1024;
-    sb->s_blocksize_bits = 10;
-    sb->s_magic = DEVFS_SUPER_MAGIC;
-    sb->s_op = &devfs_sops;
-    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;
-    DPRINTK (DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->s_fs_info);
-    return 0;
-
-out_no_root:
-    PRINTK ("(): get root inode failed\n");
-    if (root_inode) iput (root_inode);
-    return -EINVAL;
-}   /*  End Function devfs_fill_super  */
-
-static struct super_block *
-devfs_get_sb (struct file_system_type *fs_type, int flags,
-	      const char *dev_name, void *data)
+static struct super_block *devfs_get_sb(struct file_system_type *fs_type,
+					int flags, const char *dev_name,
+					void *data)
 {
-    return get_sb_single (fs_type, flags, data, devfs_fill_super);
+	return get_sb_single(fs_type, flags, data, devfs_fill_super);
 }
 
-static struct file_system_type devfs_fs_type =
-{
-    .name	= DEVFS_NAME,
-    .get_sb	= devfs_get_sb,
-    .kill_sb	= kill_anon_super,
+static struct file_system_type devfs_fs_type = {
+	.name = DEVFS_NAME,
+	.get_sb = devfs_get_sb,
+	.kill_sb = kill_anon_super,
 };
 
 /*  File operations for devfsd follow  */
 
-static ssize_t devfsd_read (struct file *file, char *buf, size_t len,
-			    loff_t *ppos)
+static ssize_t devfsd_read(struct file *file, char *buf, size_t len,
+			   loff_t * ppos)
 {
-    int done = FALSE;
-    int ival;
-    loff_t pos, devname_offset, tlen, rpos;
-    devfs_handle_t de;
-    struct devfsd_buf_entry *entry;
-    struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->s_fs_info;
-    struct devfsd_notify_struct *info = fs_info->devfsd_info;
-    DECLARE_WAITQUEUE (wait, current);
-
-    /*  Can't seek (pread) on this device  */
-    if (ppos != &file->f_pos) return -ESPIPE;
-    /*  Verify the task has grabbed the queue  */
-    if (fs_info->devfsd_task != current) return -EPERM;
-    info->major = 0;
-    info->minor = 0;
-    /*  Block for a new entry  */
-    set_current_state (TASK_INTERRUPTIBLE);
-    add_wait_queue (&fs_info->devfsd_wait_queue, &wait);
-    while ( devfsd_queue_empty (fs_info) )
-    {
-	fs_info->devfsd_sleeping = TRUE;
-	wake_up (&fs_info->revalidate_wait_queue);
-	schedule ();
-	fs_info->devfsd_sleeping = FALSE;
-	if ( signal_pending (current) )
-	{
-	    remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
-	    __set_current_state (TASK_RUNNING);
-	    return -EINTR;
-	}
-	set_current_state (TASK_INTERRUPTIBLE);
-    }
-    remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
-    __set_current_state (TASK_RUNNING);
-    /*  Now play with the data  */
-    ival = atomic_read (&fs_info->devfsd_overrun_count);
-    info->overrun_count = ival;
-    entry = fs_info->devfsd_first_event;
-    info->type = entry->type;
-    info->mode = entry->mode;
-    info->uid = entry->uid;
-    info->gid = entry->gid;
-    de = entry->de;
-    if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
-	info->major = MAJOR(de->u.dev);
-	info->minor = MINOR(de->u.dev);
-    }
-    pos = devfs_generate_path (de, info->devname, DEVFS_PATHLEN);
-    if (pos < 0) return pos;
-    info->namelen = DEVFS_PATHLEN - pos - 1;
-    if (info->mode == 0) info->mode = de->mode;
-    devname_offset = info->devname - (char *) info;
-    rpos = *ppos;
-    if (rpos < devname_offset)
-    {
-	/*  Copy parts of the header  */
-	tlen = devname_offset - rpos;
-	if (tlen > len) tlen = len;
-	if ( copy_to_user (buf, (char *) info + rpos, tlen) )
-	{
-	    return -EFAULT;
-	}
-	rpos += tlen;
-	buf += tlen;
-	len -= tlen;
-    }
-    if ( (rpos >= devname_offset) && (len > 0) )
-    {
-	/*  Copy the name  */
-	tlen = info->namelen + 1;
-	if (tlen > len) tlen = len;
-	else done = TRUE;
-	if ( copy_to_user (buf, info->devname + pos + rpos - devname_offset,
-			   tlen) )
-	{
-	    return -EFAULT;
-	}
-	rpos += tlen;
-    }
-    tlen = rpos - *ppos;
-    if (done)
-    {
-	devfs_handle_t parent;
-
-	spin_lock (&fs_info->devfsd_buffer_lock);
-	fs_info->devfsd_first_event = entry->next;
-	if (entry->next == NULL) fs_info->devfsd_last_event = NULL;
-	spin_unlock (&fs_info->devfsd_buffer_lock);
-	for (; de != NULL; de = parent)
-	{
-	    parent = de->parent;
-	    devfs_put (de);
-	}
-	kmem_cache_free (devfsd_buf_cache, entry);
-	if (ival > 0) atomic_sub (ival, &fs_info->devfsd_overrun_count);
-	*ppos = 0;
-    }
-    else *ppos = rpos;
-    return tlen;
-}   /*  End Function devfsd_read  */
-
-static int devfsd_ioctl (struct inode *inode, struct file *file,
-			 unsigned int cmd, unsigned long arg)
-{
-    int ival;
-    struct fs_info *fs_info = inode->i_sb->s_fs_info;
-
-    switch (cmd)
-    {
-      case DEVFSDIOC_GET_PROTO_REV:
-	ival = DEVFSD_PROTOCOL_REVISION_KERNEL;
-	if ( copy_to_user ( (void *)arg, &ival, sizeof ival ) ) return -EFAULT;
-	break;
-      case DEVFSDIOC_SET_EVENT_MASK:
-	/*  Ensure only one reader has access to the queue. This scheme will
-	    work even if the global kernel lock were to be removed, because it
-	    doesn't matter who gets in first, as long as only one gets it  */
-	if (fs_info->devfsd_task == NULL)
-	{
-	    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
-
-	    if ( !spin_trylock (&lock) ) return -EBUSY;
-	    if (fs_info->devfsd_task != NULL)
-	    {   /*  We lost the race...  */
-		spin_unlock (&lock);
-		return -EBUSY;
-	    }
-	    fs_info->devfsd_task = current;
-	    spin_unlock (&lock);
-	    fs_info->devfsd_pgrp = (process_group(current) == current->pid) ?
-		process_group(current) : 0;
-	    fs_info->devfsd_file = file;
-	    fs_info->devfsd_info = kmalloc (sizeof *fs_info->devfsd_info,
-					    GFP_KERNEL);
-	    if (!fs_info->devfsd_info)
-	    {
-		devfsd_close (inode, file);
-		return -ENOMEM;
-	    }
+	int done = FALSE;
+	int ival;
+	loff_t pos, devname_offset, tlen, rpos;
+	devfs_handle_t de;
+	struct devfsd_buf_entry *entry;
+	struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->s_fs_info;
+	struct devfsd_notify_struct *info = fs_info->devfsd_info;
+	DECLARE_WAITQUEUE(wait, current);
+
+	/*  Can't seek (pread) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	/*  Verify the task has grabbed the queue  */
+	if (fs_info->devfsd_task != current)
+		return -EPERM;
+	info->major = 0;
+	info->minor = 0;
+	/*  Block for a new entry  */
+	set_current_state(TASK_INTERRUPTIBLE);
+	add_wait_queue(&fs_info->devfsd_wait_queue, &wait);
+	while (devfsd_queue_empty(fs_info)) {
+		fs_info->devfsd_sleeping = TRUE;
+		wake_up(&fs_info->revalidate_wait_queue);
+		schedule();
+		fs_info->devfsd_sleeping = FALSE;
+		if (signal_pending(current)) {
+			remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
+			__set_current_state(TASK_RUNNING);
+			return -EINTR;
+		}
+		set_current_state(TASK_INTERRUPTIBLE);
 	}
-	else if (fs_info->devfsd_task != current) return -EBUSY;
-	fs_info->devfsd_event_mask = arg;  /*  Let the masses come forth  */
-	break;
-      case DEVFSDIOC_RELEASE_EVENT_QUEUE:
-	if (fs_info->devfsd_file != file) return -EPERM;
-	return devfsd_close (inode, file);
-	/*break;*/
+	remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
+	__set_current_state(TASK_RUNNING);
+	/*  Now play with the data  */
+	ival = atomic_read(&fs_info->devfsd_overrun_count);
+	info->overrun_count = ival;
+	entry = fs_info->devfsd_first_event;
+	info->type = entry->type;
+	info->mode = entry->mode;
+	info->uid = entry->uid;
+	info->gid = entry->gid;
+	de = entry->de;
+	if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
+		info->major = MAJOR(de->u.dev);
+		info->minor = MINOR(de->u.dev);
+	}
+	pos = devfs_generate_path(de, info->devname, DEVFS_PATHLEN);
+	if (pos < 0)
+		return pos;
+	info->namelen = DEVFS_PATHLEN - pos - 1;
+	if (info->mode == 0)
+		info->mode = de->mode;
+	devname_offset = info->devname - (char *)info;
+	rpos = *ppos;
+	if (rpos < devname_offset) {
+		/*  Copy parts of the header  */
+		tlen = devname_offset - rpos;
+		if (tlen > len)
+			tlen = len;
+		if (copy_to_user(buf, (char *)info + rpos, tlen)) {
+			return -EFAULT;
+		}
+		rpos += tlen;
+		buf += tlen;
+		len -= tlen;
+	}
+	if ((rpos >= devname_offset) && (len > 0)) {
+		/*  Copy the name  */
+		tlen = info->namelen + 1;
+		if (tlen > len)
+			tlen = len;
+		else
+			done = TRUE;
+		if (copy_to_user
+		    (buf, info->devname + pos + rpos - devname_offset, tlen)) {
+			return -EFAULT;
+		}
+		rpos += tlen;
+	}
+	tlen = rpos - *ppos;
+	if (done) {
+		devfs_handle_t parent;
+
+		spin_lock(&fs_info->devfsd_buffer_lock);
+		fs_info->devfsd_first_event = entry->next;
+		if (entry->next == NULL)
+			fs_info->devfsd_last_event = NULL;
+		spin_unlock(&fs_info->devfsd_buffer_lock);
+		for (; de != NULL; de = parent) {
+			parent = de->parent;
+			devfs_put(de);
+		}
+		kmem_cache_free(devfsd_buf_cache, entry);
+		if (ival > 0)
+			atomic_sub(ival, &fs_info->devfsd_overrun_count);
+		*ppos = 0;
+	} else
+		*ppos = rpos;
+	return tlen;
+}				/*  End Function devfsd_read  */
+
+static int devfsd_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	int ival;
+	struct fs_info *fs_info = inode->i_sb->s_fs_info;
+
+	switch (cmd) {
+	case DEVFSDIOC_GET_PROTO_REV:
+		ival = DEVFSD_PROTOCOL_REVISION_KERNEL;
+		if (copy_to_user((void *)arg, &ival, sizeof ival))
+			return -EFAULT;
+		break;
+	case DEVFSDIOC_SET_EVENT_MASK:
+		/*  Ensure only one reader has access to the queue. This scheme will
+		   work even if the global kernel lock were to be removed, because it
+		   doesn't matter who gets in first, as long as only one gets it  */
+		if (fs_info->devfsd_task == NULL) {
+			static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+
+			if (!spin_trylock(&lock))
+				return -EBUSY;
+			if (fs_info->devfsd_task != NULL) {	/*  We lost the race...  */
+				spin_unlock(&lock);
+				return -EBUSY;
+			}
+			fs_info->devfsd_task = current;
+			spin_unlock(&lock);
+			fs_info->devfsd_pgrp =
+			    (process_group(current) ==
+			     current->pid) ? process_group(current) : 0;
+			fs_info->devfsd_file = file;
+			fs_info->devfsd_info =
+			    kmalloc(sizeof *fs_info->devfsd_info, GFP_KERNEL);
+			if (!fs_info->devfsd_info) {
+				devfsd_close(inode, file);
+				return -ENOMEM;
+			}
+		} else if (fs_info->devfsd_task != current)
+			return -EBUSY;
+		fs_info->devfsd_event_mask = arg;	/*  Let the masses come forth  */
+		break;
+	case DEVFSDIOC_RELEASE_EVENT_QUEUE:
+		if (fs_info->devfsd_file != file)
+			return -EPERM;
+		return devfsd_close(inode, file);
+		/*break; */
 #ifdef CONFIG_DEVFS_DEBUG
-      case DEVFSDIOC_SET_DEBUG_MASK:
-	if ( copy_from_user (&ival, (void *) arg, sizeof ival) )return -EFAULT;
-	devfs_debug = ival;
-	break;
+	case DEVFSDIOC_SET_DEBUG_MASK:
+		if (copy_from_user(&ival, (void *)arg, sizeof ival))
+			return -EFAULT;
+		devfs_debug = ival;
+		break;
 #endif
-      default:
-	return -ENOIOCTLCMD;
-    }
-    return 0;
-}   /*  End Function devfsd_ioctl  */
-
-static int devfsd_close (struct inode *inode, struct file *file)
-{
-    struct devfsd_buf_entry *entry, *next;
-    struct fs_info *fs_info = inode->i_sb->s_fs_info;
-
-    if (fs_info->devfsd_file != file) return 0;
-    fs_info->devfsd_event_mask = 0;
-    fs_info->devfsd_file = NULL;
-    spin_lock (&fs_info->devfsd_buffer_lock);
-    entry = fs_info->devfsd_first_event;
-    fs_info->devfsd_first_event = NULL;
-    fs_info->devfsd_last_event = NULL;
-    if (fs_info->devfsd_info)
-    {
-	kfree (fs_info->devfsd_info);
-	fs_info->devfsd_info = NULL;
-    }
-    spin_unlock (&fs_info->devfsd_buffer_lock);
-    fs_info->devfsd_pgrp = 0;
-    fs_info->devfsd_task = NULL;
-    wake_up (&fs_info->revalidate_wait_queue);
-    for (; entry; entry = next)
-    {
-	next = entry->next;
-	kmem_cache_free (devfsd_buf_cache, entry);
-    }
-    return 0;
-}   /*  End Function devfsd_close  */
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}				/*  End Function devfsd_ioctl  */
+
+static int devfsd_close(struct inode *inode, struct file *file)
+{
+	struct devfsd_buf_entry *entry, *next;
+	struct fs_info *fs_info = inode->i_sb->s_fs_info;
+
+	if (fs_info->devfsd_file != file)
+		return 0;
+	fs_info->devfsd_event_mask = 0;
+	fs_info->devfsd_file = NULL;
+	spin_lock(&fs_info->devfsd_buffer_lock);
+	entry = fs_info->devfsd_first_event;
+	fs_info->devfsd_first_event = NULL;
+	fs_info->devfsd_last_event = NULL;
+	if (fs_info->devfsd_info) {
+		kfree(fs_info->devfsd_info);
+		fs_info->devfsd_info = NULL;
+	}
+	spin_unlock(&fs_info->devfsd_buffer_lock);
+	fs_info->devfsd_pgrp = 0;
+	fs_info->devfsd_task = NULL;
+	wake_up(&fs_info->revalidate_wait_queue);
+	for (; entry; entry = next) {
+		next = entry->next;
+		kmem_cache_free(devfsd_buf_cache, entry);
+	}
+	return 0;
+}				/*  End Function devfsd_close  */
 
 #ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read (struct file *file, char *buf, size_t len,
-			  loff_t *ppos)
+static ssize_t stat_read(struct file *file, char *buf, size_t len,
+			 loff_t * ppos)
 {
-    ssize_t num;
-    char txt[80];
+	ssize_t num;
+	char txt[80];
 
-    num = sprintf (txt, "Number of entries: %u  number of bytes: %u\n",
-		   stat_num_entries, stat_num_bytes) + 1;
-    /*  Can't seek (pread) on this device  */
-    if (ppos != &file->f_pos) return -ESPIPE;
-    if (*ppos >= num) return 0;
-    if (*ppos + len > num) len = num - *ppos;
-    if ( copy_to_user (buf, txt + *ppos, len) ) return -EFAULT;
-    *ppos += len;
-    return len;
-}   /*  End Function stat_read  */
+	num = sprintf(txt, "Number of entries: %u  number of bytes: %u\n",
+		      stat_num_entries, stat_num_bytes) + 1;
+	/*  Can't seek (pread) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (*ppos >= num)
+		return 0;
+	if (*ppos + len > num)
+		len = num - *ppos;
+	if (copy_to_user(buf, txt + *ppos, len))
+		return -EFAULT;
+	*ppos += len;
+	return len;
+}				/*  End Function stat_read  */
 #endif
 
 static int __init init_devfs_fs(void)
@@ -2793,8 +2809,8 @@ static int __init init_devfs_fs(void)
 	printk(KERN_INFO "%s: %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);
+					     sizeof(struct devfsd_buf_entry),
+					     0, 0, NULL, NULL);
 	if (!devfsd_buf_cache)
 		OOPS("(): unable to allocate event slab\n");
 #ifdef CONFIG_DEVFS_DEBUG
@@ -2809,32 +2825,35 @@ static int __init init_devfs_fs(void)
 		return major;
 
 	/*  And create the entry for ".devfsd"  */
-	devfsd = _devfs_alloc_entry(".devfsd", 0, S_IFCHR|S_IRUSR|S_IWUSR);
-	if (devfsd == NULL )
+	devfsd = _devfs_alloc_entry(".devfsd", 0, S_IFCHR | S_IRUSR | S_IWUSR);
+	if (devfsd == NULL)
 		return -ENOMEM;
 	devfsd->u.dev = MKDEV(major, 0);
 	_devfs_append_entry(root_entry, devfsd, NULL);
 
 #ifdef CONFIG_DEVFS_DEBUG
-	stat = _devfs_alloc_entry(".stat", 0, S_IFCHR|S_IRUGO);
-	if (stat == NULL )
+	stat = _devfs_alloc_entry(".stat", 0, S_IFCHR | S_IRUGO);
+	if (stat == NULL)
 		return -ENOMEM;
 	stat->u.dev = MKDEV(major, 1);
-	_devfs_append_entry (root_entry, stat, NULL);
+	_devfs_append_entry(root_entry, stat, NULL);
 #endif
 
 	err = register_filesystem(&devfs_fs_type);
 	return err;
-}   /*  End Function init_devfs_fs  */
+}				/*  End Function init_devfs_fs  */
 
-void __init mount_devfs_fs (void)
+void __init mount_devfs_fs(void)
 {
-    int err;
+	int err;
 
-    if ( !(boot_options & OPTION_MOUNT) ) return;
-    err = do_mount ("none", "/dev", "devfs", 0, NULL);
-    if (err == 0) printk (KERN_INFO "Mounted devfs on /dev\n");
-    else PRINTK ("(): unable to mount devfs, err: %d\n", err);
-}   /*  End Function mount_devfs_fs  */
+	if (!(boot_options & OPTION_MOUNT))
+		return;
+	err = do_mount("none", "/dev", "devfs", 0, NULL);
+	if (err == 0)
+		printk(KERN_INFO "Mounted devfs on /dev\n");
+	else
+		PRINTK("(): unable to mount devfs, err: %d\n", err);
+}				/*  End Function mount_devfs_fs  */
 
 module_init(init_devfs_fs)
diff -puN fs/devfs/util.c~Lindent-devfs fs/devfs/util.c
--- 25/fs/devfs/util.c~Lindent-devfs	2004-04-03 02:59:45.178484768 -0800
+++ 25-akpm/fs/devfs/util.c	2004-04-03 02:59:45.203480968 -0800
@@ -73,7 +73,6 @@
 #include <linux/genhd.h>
 #include <asm/bitops.h>
 
-
 int devfs_register_tape(const char *name)
 {
 	char tname[32], dest[64];
@@ -86,6 +85,7 @@ int devfs_register_tape(const char *name
 
 	return n;
 }
+
 EXPORT_SYMBOL(devfs_register_tape);
 
 void devfs_unregister_tape(int num)
diff -puN include/linux/devfs_fs.h~Lindent-devfs include/linux/devfs_fs.h
--- 25/include/linux/devfs_fs.h~Lindent-devfs	2004-04-03 02:59:45.180484464 -0800
+++ 25-akpm/include/linux/devfs_fs.h	2004-04-03 02:59:45.203480968 -0800
@@ -22,22 +22,20 @@
 #define DEVFSD_NOTIFY_CREATE        6
 #define DEVFSD_NOTIFY_DELETE        7
 
-#define DEVFS_PATHLEN               1024  /*  Never change this otherwise the
-					      binary interface will change   */
+#define DEVFS_PATHLEN               1024	/*  Never change this otherwise the
+						   binary interface will change   */
 
-struct devfsd_notify_struct
-{   /*  Use native C types to ensure same types in kernel and user space     */
-    unsigned int type;           /*  DEVFSD_NOTIFY_* value                   */
-    unsigned int mode;           /*  Mode of the inode or device entry       */
-    unsigned int major;          /*  Major number of device entry            */
-    unsigned int minor;          /*  Minor number of device entry            */
-    unsigned int uid;            /*  Uid of process, inode or device entry   */
-    unsigned int gid;            /*  Gid of process, inode or device entry   */
-    unsigned int overrun_count;  /*  Number of lost events                   */
-    unsigned int namelen;        /*  Number of characters not including '\0' */
-    /*  The device name MUST come last                                       */
-    char devname[DEVFS_PATHLEN]; /*  This will be '\0' terminated            */
+struct devfsd_notify_struct {	/*  Use native C types to ensure same types in kernel and user space     */
+	unsigned int type;	/*  DEVFSD_NOTIFY_* value                   */
+	unsigned int mode;	/*  Mode of the inode or device entry       */
+	unsigned int major;	/*  Major number of device entry            */
+	unsigned int minor;	/*  Minor number of device entry            */
+	unsigned int uid;	/*  Uid of process, inode or device entry   */
+	unsigned int gid;	/*  Gid of process, inode or device entry   */
+	unsigned int overrun_count;	/*  Number of lost events                   */
+	unsigned int namelen;	/*  Number of characters not including '\0' */
+	/*  The device name MUST come last                                       */
+	char devname[DEVFS_PATHLEN];	/*  This will be '\0' terminated            */
 };
 
-
-#endif  /*  _LINUX_DEVFS_FS_H  */
+#endif				/*  _LINUX_DEVFS_FS_H  */
diff -puN include/linux/devfs_fs_kernel.h~Lindent-devfs include/linux/devfs_fs_kernel.h
--- 25/include/linux/devfs_fs_kernel.h~Lindent-devfs	2004-04-03 02:59:45.181484312 -0800
+++ 25-akpm/include/linux/devfs_fs_kernel.h	2004-04-03 02:59:45.204480816 -0800
@@ -12,18 +12,18 @@
 
 #ifdef CONFIG_DEVFS_FS
 extern int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
-	__attribute__((format (printf, 3, 4)));
+    __attribute__ ((format(printf, 3, 4)));
 extern int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
-	__attribute__((format (printf, 3, 4)));
+    __attribute__ ((format(printf, 3, 4)));
 extern int devfs_mk_symlink(const char *name, const char *link);
 extern int devfs_mk_dir(const char *fmt, ...)
-	__attribute__((format (printf, 1, 2)));
+    __attribute__ ((format(printf, 1, 2)));
 extern void devfs_remove(const char *fmt, ...)
-	__attribute__((format (printf, 1, 2)));
+    __attribute__ ((format(printf, 1, 2)));
 extern int devfs_register_tape(const char *name);
 extern void devfs_unregister_tape(int num);
 extern void mount_devfs_fs(void);
-#else  /*  CONFIG_DEVFS_FS  */
+#else				/*  CONFIG_DEVFS_FS  */
 static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
 {
 	return 0;
@@ -32,9 +32,9 @@ static inline int devfs_mk_cdev(dev_t de
 {
 	return 0;
 }
-static inline int devfs_mk_symlink (const char *name, const char *link)
+static inline int devfs_mk_symlink(const char *name, const char *link)
 {
-    return 0;
+	return 0;
 }
 static inline int devfs_mk_dir(const char *fmt, ...)
 {
@@ -43,16 +43,16 @@ static inline int devfs_mk_dir(const cha
 static inline void devfs_remove(const char *fmt, ...)
 {
 }
-static inline int devfs_register_tape (const char *name)
+static inline int devfs_register_tape(const char *name)
 {
-    return -1;
+	return -1;
 }
 static inline void devfs_unregister_tape(int num)
 {
 }
-static inline void mount_devfs_fs (void)
+static inline void mount_devfs_fs(void)
 {
-    return;
+	return;
 }
-#endif  /*  CONFIG_DEVFS_FS  */
-#endif  /*  _LINUX_DEVFS_FS_KERNEL_H  */
+#endif				/*  CONFIG_DEVFS_FS  */
+#endif				/*  _LINUX_DEVFS_FS_KERNEL_H  */

_
