patch-2.4.18 linux/fs/devfs/base.c
Next file: linux/fs/efs/dir.c
Previous file: linux/fs/dcache.c
Back to the patch index
Back to the overall index
- Lines: 1298
- Date:
Mon Jan 21 20:27:04 2002
- Orig file:
linux.orig/fs/devfs/base.c
- Orig date:
Mon Feb 18 20:18:40 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/fs/devfs/base.c linux/fs/devfs/base.c
@@ -1,6 +1,6 @@
/* devfs (Device FileSystem) driver.
- Copyright (C) 1998-2001 Richard Gooch
+ Copyright (C) 1998-2002 Richard Gooch
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -592,6 +592,22 @@
Added poisoning to <devfs_put>.
Improved debugging messages.
v1.7
+ 20011221 Richard Gooch <rgooch@atnf.csiro.au>
+ Corrected (made useful) debugging message in <unregister>.
+ Moved <kmem_cache_create> in <mount_devfs_fs> to <init_devfs_fs>
+ 20011224 Richard Gooch <rgooch@atnf.csiro.au>
+ Added magic number to guard against scribbling drivers.
+ 20011226 Richard Gooch <rgooch@atnf.csiro.au>
+ Only return old entry in <devfs_mk_dir> if a directory.
+ Defined macros for error and debug messages.
+ v1.8
+ 20020113 Richard Gooch <rgooch@atnf.csiro.au>
+ Fixed (rare, old) race in <devfs_lookup>.
+ v1.9
+ 20020120 Richard Gooch <rgooch@atnf.csiro.au>
+ Fixed deadlock bug in <devfs_d_revalidate_wait>.
+ Tag VFS deletable in <devfs_mk_symlink> if handle ignored.
+ v1.10
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -624,7 +640,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "1.7 (20011216)"
+#define DEVFS_VERSION "1.10 (20020120)"
#define DEVFS_NAME "devfs"
@@ -633,6 +649,7 @@
#define STRING_LENGTH 256
#define FAKE_BLOCK_SIZE 1024
#define POISON_PTR ( *(void **) poison_array )
+#define MAGIC_VALUE 0x327db823
#ifndef TRUE
# define TRUE 1
@@ -669,9 +686,28 @@
#define OPTION_MOUNT 0x01
#define OPTION_ONLY 0x02
-#define OOPS(format, args...) {printk (format, ## args); \
- printk ("Forcing Oops\n"); \
- BUG();}
+#define PRINTK(format, args...) \
+ {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);}
+
+#define OOPS(format, args...) \
+ {printk (KERN_CRIT "%s" format, __FUNCTION__ , ## args); \
+ printk ("Forcing Oops\n"); \
+ BUG();}
+
+#ifdef CONFIG_DEVFS_DEBUG
+# define VERIFY_ENTRY(de) \
+ {if ((de) && (de)->magic_number != MAGIC_VALUE) \
+ OOPS ("(%p): bad magic value: %x\n", (de), (de)->magic_number);}
+# define WRITE_ENTRY_MAGIC(de,magic) (de)->magic_number = (magic)
+# define DPRINTK(flag, format, args...) \
+ {if (devfs_debug & flag) \
+ printk (KERN_INFO "%s" format, __FUNCTION__ , ## args);}
+#else
+# define VERIFY_ENTRY(de)
+# define WRITE_ENTRY_MAGIC(de,magic)
+# define DPRINTK(flag, format, args...)
+#endif
+
struct directory_type
{
@@ -728,6 +764,9 @@
struct devfs_entry
{
+#ifdef CONFIG_DEVFS_DEBUG
+ unsigned int magic_number;
+#endif
void *info;
atomic_t refcount; /* When this drops to zero, it's unused */
union
@@ -746,7 +785,7 @@
umode_t mode;
unsigned short namelen; /* I think 64k+ filenames are a way off... */
unsigned char hide:1;
- unsigned char vfs_created:1; /* Whether created by driver or VFS */
+ unsigned char vfs_deletable: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 */
};
@@ -837,6 +876,7 @@
static struct devfs_entry *devfs_get (struct devfs_entry *de)
{
+ VERIFY_ENTRY (de);
if (de) atomic_inc (&de->refcount);
return de;
} /* End Function devfs_get */
@@ -849,25 +889,22 @@
void devfs_put (devfs_handle_t de)
{
if (!de) return;
- if (de->info == POISON_PTR)
- OOPS ("%s: devfs_put(%p): poisoned pointer\n", DEVFS_NAME, de);
+ VERIFY_ENTRY (de);
+ if (de->info == POISON_PTR) OOPS ("(%p): poisoned pointer\n", de);
if ( !atomic_dec_and_test (&de->refcount) ) return;
- if (de == root_entry)
- OOPS ("%s: devfs_put(): root entry being freed\n", DEVFS_NAME);
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_FREE)
- printk ("%s: devfs_put(%s): de: %p, parent: %p \"%s\"\n",
- DEVFS_NAME, de->name, de, de->parent,
- de->parent ? de->parent->name : "no parent");
-#endif
+ if (de == root_entry) OOPS ("(%p): root entry being freed\n", de);
+ DPRINTK (DEBUG_FREE, "(%s): de: %p, parent: %p \"%s\"\n",
+ de->name, de, de->parent,
+ de->parent ? de->parent->name : "no parent");
if ( S_ISLNK (de->mode) ) kfree (de->u.symlink.linkname);
if ( ( S_ISCHR (de->mode) || S_ISBLK (de->mode) ) && de->u.fcb.autogen )
{
devfs_dealloc_devnum ( S_ISCHR (de->mode) ? DEVFS_SPECIAL_CHR :
DEVFS_SPECIAL_BLK,
- MKDEV (de->u.fcb.u.device.major,
- de->u.fcb.u.device.minor) );
+ mk_kdev (de->u.fcb.u.device.major,
+ de->u.fcb.u.device.minor) );
}
+ WRITE_ENTRY_MAGIC (de, 0);
#ifdef CONFIG_DEVFS_DEBUG
spin_lock (&stat_lock);
--stat_num_entries;
@@ -898,7 +935,7 @@
if ( !S_ISDIR (dir->mode) )
{
- printk ("%s: search_dir(%s): not a directory\n", DEVFS_NAME,dir->name);
+ PRINTK ("(%s): not a directory\n", dir->name);
return NULL;
}
for (curr = dir->u.dir.first; curr != NULL; curr = curr->next)
@@ -940,6 +977,7 @@
spin_unlock (&counter_lock);
if (name) memcpy (new->name, name, namelen);
new->namelen = namelen;
+ WRITE_ENTRY_MAGIC (new, MAGIC_VALUE);
#ifdef CONFIG_DEVFS_DEBUG
spin_lock (&stat_lock);
++stat_num_entries;
@@ -972,8 +1010,7 @@
if (old_de) *old_de = NULL;
if ( !S_ISDIR (dir->mode) )
{
- printk ("%s: append_entry(%s): dir: \"%s\" is not a directory\n",
- DEVFS_NAME, de->name, dir->name);
+ PRINTK ("(%s): dir: \"%s\" is not a directory\n", de->name, dir->name);
devfs_put (de);
return -ENOTDIR;
}
@@ -1033,16 +1070,16 @@
if ( ( new = _devfs_alloc_entry (".devfsd", 0, S_IFCHR |S_IRUSR |S_IWUSR) )
== NULL ) return NULL;
devnum = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
- new->u.fcb.u.device.major = MAJOR (devnum);
- new->u.fcb.u.device.minor = MINOR (devnum);
+ new->u.fcb.u.device.major = major (devnum);
+ new->u.fcb.u.device.minor = minor (devnum);
new->u.fcb.ops = &devfsd_fops;
_devfs_append_entry (root_entry, new, FALSE, NULL);
#ifdef CONFIG_DEVFS_DEBUG
if ( ( new = _devfs_alloc_entry (".stat", 0, S_IFCHR | S_IRUGO | S_IWUGO) )
== NULL ) return NULL;
devnum = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
- new->u.fcb.u.device.major = MAJOR (devnum);
- new->u.fcb.u.device.minor = MINOR (devnum);
+ new->u.fcb.u.device.major = major (devnum);
+ new->u.fcb.u.device.minor = minor (devnum);
new->u.fcb.ops = &stat_fops;
_devfs_append_entry (root_entry, new, FALSE, NULL);
#endif
@@ -1143,15 +1180,13 @@
if ( ( *dir = _devfs_make_parent_for_leaf (*dir, name, namelen,
&leaf_pos) ) == NULL )
{
- printk ("%s: prepare_leaf(%s): could not create parent path\n",
- DEVFS_NAME, name);
+ PRINTK ("(%s): could not create parent path\n", name);
return NULL;
}
if ( ( de = _devfs_alloc_entry (name + leaf_pos, namelen - leaf_pos,mode) )
== NULL )
{
- printk ("%s: prepare_leaf(%s): could not allocate entry\n",
- DEVFS_NAME, name);
+ PRINTK ("(%s): could not allocate entry\n", name);
devfs_put (*dir);
return NULL;
}
@@ -1198,7 +1233,7 @@
/**
- * find_by_dev - Find a devfs entry in a directory.
+ * _devfs_find_by_dev - Find a devfs entry in a directory.
* @dir: The directory where to search
* @major: The major number to search for.
* @minor: The minor number to search for.
@@ -1209,9 +1244,9 @@
* devfs_get() is performed.
*/
-static struct devfs_entry *find_by_dev (struct devfs_entry *dir,
- unsigned int major, unsigned int minor,
- char type)
+static struct devfs_entry *_devfs_find_by_dev (struct devfs_entry *dir,
+ unsigned int major,
+ unsigned int minor, char type)
{
struct devfs_entry *entry, *de;
@@ -1219,7 +1254,7 @@
if (dir == NULL) return NULL;
if ( !S_ISDIR (dir->mode) )
{
- printk ("%s: find_by_dev(): not a directory\n", DEVFS_NAME);
+ PRINTK ("(%p): not a directory\n", dir);
devfs_put (dir);
return NULL;
}
@@ -1244,7 +1279,7 @@
for (entry = dir->u.dir.first; entry != NULL; entry = entry->next)
{
if ( !S_ISDIR (entry->mode) ) continue;
- de = find_by_dev (entry, major, minor, type);
+ de = _devfs_find_by_dev (entry, major, minor, type);
if (de)
{
read_unlock (&dir->u.dir.lock);
@@ -1255,11 +1290,11 @@
read_unlock (&dir->u.dir.lock);
devfs_put (dir);
return NULL;
-} /* End Function find_by_dev */
+} /* End Function _devfs_find_by_dev */
/**
- * find_entry - Find a devfs entry.
+ * _devfs_find_entry - Find a devfs entry.
* @dir: The handle to the parent devfs directory entry. If this is %NULL the
* name is relative to the root of the devfs.
* @name: The name of the entry. This may be %NULL.
@@ -1275,9 +1310,11 @@
* devfs_get() is performed.
*/
-static struct devfs_entry *find_entry (devfs_handle_t dir, const char *name,
- unsigned int major, unsigned int minor,
- char type, int traverse_symlink)
+static struct devfs_entry *_devfs_find_entry (devfs_handle_t dir,
+ const char *name,
+ unsigned int major,
+ unsigned int minor,
+ char type, int traverse_symlink)
{
struct devfs_entry *entry;
@@ -1290,14 +1327,14 @@
/* Skip leading pathname component */
if (namelen < 2)
{
- printk ("%s: find_entry(%s): too short\n", DEVFS_NAME, name);
+ PRINTK ("(%s): too short\n", name);
return NULL;
}
for (++name, --namelen; (*name != '/') && (namelen > 0);
++name, --namelen);
if (namelen < 2)
{
- printk ("%s: find_entry(%s): too short\n", DEVFS_NAME, name);
+ PRINTK ("(%s): too short\n", name);
return NULL;
}
++name;
@@ -1308,12 +1345,13 @@
}
/* Have to search by major and minor: slow */
if ( (major == 0) && (minor == 0) ) return NULL;
- return find_by_dev (root_entry, major, minor, type);
-} /* End Function find_entry */
+ return _devfs_find_by_dev (root_entry, major, minor, type);
+} /* End Function _devfs_find_entry */
static struct devfs_entry *get_devfs_entry_from_vfs_inode (struct inode *inode)
{
if (inode == NULL) return NULL;
+ VERIFY_ENTRY ( (struct devfs_entry *) inode->u.generic_ip );
return inode->u.generic_ip;
} /* End Function get_devfs_entry_from_vfs_inode */
@@ -1495,7 +1533,7 @@
if (name == NULL)
{
- printk ("%s: devfs_register(): NULL name pointer\n", DEVFS_NAME);
+ PRINTK ("(): NULL name pointer\n");
return NULL;
}
if (ops == NULL)
@@ -1503,54 +1541,48 @@
if ( S_ISBLK (mode) ) ops = (void *) get_blkfops (major);
if (ops == NULL)
{
- printk ("%s: devfs_register(%s): NULL ops pointer\n",
- DEVFS_NAME, name);
+ PRINTK ("(%s): NULL ops pointer\n", name);
return NULL;
}
- printk ("%s: devfs_register(%s): NULL ops, got %p from major table\n",
- DEVFS_NAME, name, ops);
+ PRINTK ("(%s): NULL ops, got %p from major table\n", name, ops);
}
if ( S_ISDIR (mode) )
{
- printk("%s: devfs_register(%s): creating directories is not allowed\n",
- DEVFS_NAME, name);
+ PRINTK ("(%s): creating directories is not allowed\n", name);
return NULL;
}
if ( S_ISLNK (mode) )
{
- printk ("%s: devfs_register(%s): creating symlinks is not allowed\n",
- DEVFS_NAME, name);
+ PRINTK ("(%s): creating symlinks is not allowed\n", name);
return NULL;
}
if ( ( S_ISCHR (mode) || S_ISBLK (mode) ) &&
(flags & DEVFS_FL_AUTO_DEVNUM) )
{
- if ( ( devnum = devfs_alloc_devnum (devtype) ) == NODEV )
+ if ( kdev_none ( devnum = devfs_alloc_devnum (devtype) ) )
{
- printk ("%s: devfs_register(%s): exhausted %s device numbers\n",
- DEVFS_NAME, name, S_ISCHR (mode) ? "char" : "block");
+ PRINTK ("(%s): exhausted %s device numbers\n",
+ name, S_ISCHR (mode) ? "char" : "block");
return NULL;
}
- major = MAJOR (devnum);
- minor = MINOR (devnum);
+ major = major (devnum);
+ minor = minor (devnum);
}
if ( ( de = _devfs_prepare_leaf (&dir, name, mode) ) == NULL )
{
- printk ("%s: devfs_register(%s): could not prepare leaf\n",
- DEVFS_NAME, name);
- if (devnum != NODEV) devfs_dealloc_devnum (devtype, devnum);
+ PRINTK ("(%s): could not prepare leaf\n", name);
+ if ( !kdev_none (devnum) ) devfs_dealloc_devnum (devtype, devnum);
return NULL;
}
if ( S_ISCHR (mode) || S_ISBLK (mode) )
{
de->u.fcb.u.device.major = major;
de->u.fcb.u.device.minor = minor;
- de->u.fcb.autogen = (devnum == NODEV) ? FALSE : TRUE;
+ de->u.fcb.autogen = kdev_none (devnum) ? FALSE : TRUE;
}
else if ( !S_ISREG (mode) )
{
- printk ("%s: devfs_register(%s): illegal mode: %x\n",
- DEVFS_NAME, name, mode);
+ PRINTK ("(%s): illegal mode: %x\n", name, mode);
devfs_put (de);
devfs_put (dir);
return (NULL);
@@ -1574,17 +1606,13 @@
if ( ( err = _devfs_append_entry (dir, de, de->u.fcb.removable, NULL) )
!= 0 )
{
- printk("%s: devfs_register(%s): could not append to parent, err: %d\n",
- DEVFS_NAME, name, err);
+ PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
devfs_put (dir);
- if (devnum != NODEV) devfs_dealloc_devnum (devtype, devnum);
+ if ( !kdev_none (devnum) ) devfs_dealloc_devnum (devtype, devnum);
return NULL;
}
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_REGISTER)
- printk ("%s: devfs_register(%s): de: %p dir: %p \"%s\" pp: %p\n",
- DEVFS_NAME, name, de, dir, dir->name, dir->parent);
-#endif
+ DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\" pp: %p\n",
+ name, de, dir, dir->name, dir->parent);
devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT);
devfs_put (dir);
return de;
@@ -1620,7 +1648,7 @@
/**
- * unregister - Unregister a device entry from it's parent.
+ * _devfs_unregister - Unregister a device entry from it's parent.
* @dir: The parent directory.
* @de: The entry to unregister.
*
@@ -1628,7 +1656,7 @@
* unlocked by this function.
*/
-static void unregister (struct devfs_entry *dir, struct devfs_entry *de)
+static void _devfs_unregister (struct devfs_entry *dir, struct devfs_entry *de)
{
int unhooked = _devfs_unhook (de);
@@ -1647,17 +1675,14 @@
write_lock (&de->u.dir.lock);
de->u.dir.no_more_additions = TRUE;
child = de->u.dir.first;
- unregister (de, child);
+ VERIFY_ENTRY (child);
+ _devfs_unregister (de, child);
if (!child) break;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_UNREGISTER)
- printk ( "%s: unregister(%s): child: %p refcount: %d\n",
- DEVFS_NAME, child->name, child,
- atomic_read (&de->refcount) );
-#endif
+ DPRINTK (DEBUG_UNREGISTER, "(%s): child: %p refcount: %d\n",
+ child->name, child, atomic_read (&child->refcount) );
devfs_put (child);
}
-} /* End Function unregister */
+} /* End Function _devfs_unregister */
/**
@@ -1668,14 +1693,12 @@
void devfs_unregister (devfs_handle_t de)
{
+ VERIFY_ENTRY (de);
if ( (de == NULL) || (de->parent == NULL) ) return;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_UNREGISTER)
- printk ( "%s: devfs_unregister(%s): de: %p refcount: %d\n",
- DEVFS_NAME, de->name, de, atomic_read (&de->refcount) );
-#endif
+ DPRINTK (DEBUG_UNREGISTER, "(%s): de: %p refcount: %d\n",
+ de->name, de, atomic_read (&de->refcount) );
write_lock (&de->parent->u.dir.lock);
- unregister (de->parent, de);
+ _devfs_unregister (de->parent, de);
devfs_put (de);
} /* End Function devfs_unregister */
@@ -1691,16 +1714,12 @@
if (handle != NULL) *handle = NULL;
if (name == NULL)
{
- printk ("%s: devfs_do_symlink(): NULL name pointer\n", DEVFS_NAME);
+ PRINTK ("(): NULL name pointer\n");
return -EINVAL;
}
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_REGISTER)
- printk ("%s: devfs_do_symlink(%s)\n", DEVFS_NAME, name);
-#endif
if (link == NULL)
{
- printk ("%s: devfs_do_symlink(): NULL link pointer\n", DEVFS_NAME);
+ PRINTK ("(%s): NULL link pointer\n", name);
return -EINVAL;
}
linklength = strlen (link);
@@ -1711,8 +1730,7 @@
if ( ( de = _devfs_prepare_leaf (&dir, name, S_IFLNK | S_IRUGO | S_IXUGO) )
== NULL )
{
- printk ("%s: devfs_do_symlink(%s): could not prepare leaf\n",
- DEVFS_NAME, name);
+ PRINTK ("(%s): could not prepare leaf\n", name);
kfree (newlink);
return -ENOTDIR;
}
@@ -1722,8 +1740,7 @@
de->u.symlink.length = linklength;
if ( ( err = _devfs_append_entry (dir, de, FALSE, NULL) ) != 0 )
{
- printk ("%s: devfs_do_symlink(%s): could not append to parent, err: %d\n",
- DEVFS_NAME, name, err);
+ PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
devfs_put (dir);
return err;
}
@@ -1758,9 +1775,11 @@
devfs_handle_t de;
if (handle != NULL) *handle = NULL;
+ DPRINTK (DEBUG_REGISTER, "(%s)\n", name);
err = devfs_do_symlink (dir, name, flags, link, &de, info);
if (err) return err;
- if (handle != NULL) *handle = de;
+ if (handle == NULL) de->vfs_deletable = TRUE;
+ else *handle = de;
devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT);
return 0;
} /* End Function devfs_mk_symlink */
@@ -1787,39 +1806,35 @@
if (name == NULL)
{
- printk ("%s: devfs_mk_dir(): NULL name pointer\n", DEVFS_NAME);
+ PRINTK ("(): NULL name pointer\n");
return NULL;
}
if ( ( de = _devfs_prepare_leaf (&dir, name, MODE_DIR) ) == NULL )
{
- printk ("%s: devfs_mk_dir(%s): could not prepare leaf\n",
- DEVFS_NAME, name);
+ PRINTK ("(%s): could not prepare leaf\n", name);
return NULL;
}
de->info = info;
if ( ( err = _devfs_append_entry (dir, de, FALSE, &old) ) != 0 )
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,1)
- if (old)
+ if ( old && S_ISDIR (old->mode) )
{
- printk("%s: devfs_mk_dir(%s): using old entry in dir: %p \"%s\"\n",
- DEVFS_NAME, name, dir, dir->name);
- old->vfs_created = FALSE;
+ PRINTK ("(%s): using old entry in dir: %p \"%s\"\n",
+ name, dir, dir->name);
+ old->vfs_deletable = FALSE;
devfs_put (dir);
return old;
}
#endif
- printk ("%s: devfs_mk_dir(%s): could not append to dir: %p \"%s\", err: %d\n",
- DEVFS_NAME, name, dir, dir->name, err);
+ PRINTK ("(%s): could not append to dir: %p \"%s\", err: %d\n",
+ name, dir, dir->name, err);
devfs_put (old);
devfs_put (dir);
return NULL;
}
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_REGISTER)
- printk ("%s: devfs_mk_dir(%s): de: %p dir: %p \"%s\"\n",
- DEVFS_NAME, name, de, dir, dir->name);
-#endif
+ DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\"\n",
+ name, de, dir, dir->name);
devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, 0);
devfs_put (dir);
return de;
@@ -1850,7 +1865,7 @@
char type, int traverse_symlinks)
{
if ( (name != NULL) && (name[0] == '\0') ) name = NULL;
- return find_entry (dir, name, major, minor, type, traverse_symlinks);
+ return _devfs_find_entry (dir, name, major, minor, type,traverse_symlinks);
} /* End Function devfs_get_handle */
@@ -1881,6 +1896,7 @@
unsigned int fl = 0;
if (de == NULL) return -EINVAL;
+ VERIFY_ENTRY (de);
if (de->hide) fl |= DEVFS_FL_HIDE;
if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
{
@@ -1904,11 +1920,8 @@
int devfs_set_flags (devfs_handle_t de, unsigned int flags)
{
if (de == NULL) return -EINVAL;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_SET_FLAGS)
- printk ("%s: devfs_set_flags(): de->name: \"%s\"\n",
- DEVFS_NAME, de->name);
-#endif
+ VERIFY_ENTRY (de);
+ DPRINTK (DEBUG_SET_FLAGS, "(%s): flags: %x\n", de->name, flags);
de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
{
@@ -1932,6 +1945,7 @@
unsigned int *minor)
{
if (de == NULL) return -EINVAL;
+ VERIFY_ENTRY (de);
if ( S_ISDIR (de->mode) ) return -EISDIR;
if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) ) return -EINVAL;
if (major != NULL) *major = de->u.fcb.u.device.major;
@@ -1972,6 +1986,7 @@
#define NAMEOF(de) ( (de)->mode ? (de)->name : (de)->u.name )
if (de == NULL) return -EINVAL;
+ VERIFY_ENTRY (de);
if (de->namelen >= buflen) return -ENAMETOOLONG; /* Must be first */
path[buflen - 1] = '\0';
if (de->parent == NULL) return buflen - 1; /* Don't prepend root */
@@ -2001,6 +2016,7 @@
struct module *owner;
if (de == NULL) return NULL;
+ VERIFY_ENTRY (de);
if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
return NULL;
if (de->u.fcb.ops == NULL) return NULL;
@@ -2031,6 +2047,7 @@
struct module *owner;
if (de == NULL) return;
+ VERIFY_ENTRY (de);
if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
return;
if (de->u.fcb.ops == NULL) return;
@@ -2052,6 +2069,7 @@
int devfs_set_file_size (devfs_handle_t de, unsigned long size)
{
if (de == NULL) return -EINVAL;
+ VERIFY_ENTRY (de);
if ( !S_ISREG (de->mode) ) return -EINVAL;
if (de->u.fcb.u.file.size == size) return 0;
de->u.fcb.u.file.size = size;
@@ -2071,6 +2089,7 @@
void *devfs_get_info (devfs_handle_t de)
{
if (de == NULL) return NULL;
+ VERIFY_ENTRY (de);
return de->info;
} /* End Function devfs_get_info */
@@ -2085,6 +2104,7 @@
int devfs_set_info (devfs_handle_t de, void *info)
{
if (de == NULL) return -EINVAL;
+ VERIFY_ENTRY (de);
de->info = info;
return 0;
} /* End Function devfs_set_info */
@@ -2099,6 +2119,7 @@
devfs_handle_t devfs_get_parent (devfs_handle_t de)
{
if (de == NULL) return NULL;
+ VERIFY_ENTRY (de);
return de->parent;
} /* End Function devfs_get_parent */
@@ -2113,6 +2134,7 @@
devfs_handle_t devfs_get_first_child (devfs_handle_t de)
{
if (de == NULL) return NULL;
+ VERIFY_ENTRY (de);
if ( !S_ISDIR (de->mode) ) return NULL;
return de->u.dir.first;
} /* End Function devfs_get_first_child */
@@ -2128,6 +2150,7 @@
devfs_handle_t devfs_get_next_sibling (devfs_handle_t de)
{
if (de == NULL) return NULL;
+ VERIFY_ENTRY (de);
return de->next;
} /* End Function devfs_get_next_sibling */
@@ -2143,14 +2166,15 @@
void devfs_auto_unregister (devfs_handle_t master, devfs_handle_t slave)
{
if (master == NULL) return;
+ VERIFY_ENTRY (master);
+ VERIFY_ENTRY (slave);
if (master->slave != NULL)
{
/* Because of the dumbness of the layers above, ignore duplicates */
if (master->slave == slave) return;
- printk ("%s: devfs_auto_unregister(): only one slave allowed\n",
- DEVFS_NAME);
- OOPS (" master: \"%s\" old slave: \"%s\" new slave: \"%s\"\n",
- master->name, master->slave->name, slave->name);
+ PRINTK ("(%s): only one slave allowed\n", master->name);
+ OOPS ("(): old slave: \"%s\" new slave: \"%s\"\n",
+ master->slave->name, slave->name);
}
master->slave = slave;
} /* End Function devfs_auto_unregister */
@@ -2166,6 +2190,7 @@
devfs_handle_t devfs_get_unregister_slave (devfs_handle_t master)
{
if (master == NULL) return NULL;
+ VERIFY_ENTRY (master);
return master->slave;
} /* End Function devfs_get_unregister_slave */
@@ -2181,6 +2206,7 @@
const char *devfs_get_name (devfs_handle_t de, unsigned int *namelen)
{
if (de == NULL) return NULL;
+ VERIFY_ENTRY (de);
if (namelen != NULL) *namelen = de->namelen;
return de->name;
} /* End Function devfs_get_name */
@@ -2360,7 +2386,7 @@
* @buf: A working area that will be used. This must not go out of scope
* until devfsd is idle again.
*
- * Returns 0 on success, else a negative error code.
+ * Returns 0 on success (event was queued), else a negative error code.
*/
static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info,
@@ -2375,10 +2401,11 @@
buf->parent = parent;
buf->namelen = namelen;
buf->u.name = name;
+ WRITE_ENTRY_MAGIC (buf, MAGIC_VALUE);
if ( !devfsd_notify_de (buf, DEVFSD_NOTIFY_LOOKUP, 0,
current->euid, current->egid, fs_info, 0) )
return -ENOENT;
- /* Possible success */
+ /* Possible success: event has been queued */
return 0;
} /* End Function try_modload */
@@ -2394,7 +2421,7 @@
{
int tmp;
int retval = 0;
- kdev_t dev = MKDEV (de->u.fcb.u.device.major, de->u.fcb.u.device.minor);
+ kdev_t dev = mk_kdev (de->u.fcb.u.device.major, de->u.fcb.u.device.minor);
struct block_device_operations *bdops;
extern int warn_no_part;
@@ -2487,16 +2514,10 @@
if (retval != 0) return retval;
retval = inode_setattr (inode, iattr);
if (retval != 0) return retval;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_CHANGE)
- {
- printk ("%s: notify_change(%d): VFS inode: %p devfs_entry: %p\n",
- DEVFS_NAME, (int) inode->i_ino, inode, de);
- printk ("%s: mode: 0%o uid: %d gid: %d\n",
- DEVFS_NAME, (int) inode->i_mode,
- (int) inode->i_uid, (int) inode->i_gid);
- }
-#endif
+ DPRINTK (DEBUG_I_CHANGE, "(%d): VFS inode: %p devfs_entry: %p\n",
+ (int) inode->i_ino, inode, de);
+ DPRINTK (DEBUG_I_CHANGE, "(): mode: 0%o uid: %d gid: %d\n",
+ (int) inode->i_mode, (int) inode->i_uid, (int) inode->i_gid);
/* Inode is not on hash chains, thus must save permissions here rather
than in a write_inode() method */
if ( ( !S_ISREG (inode->i_mode) && !S_ISCHR (inode->i_mode) &&
@@ -2541,7 +2562,7 @@
/**
- * get_vfs_inode - Get a VFS inode.
+ * _devfs_get_vfs_inode - Get a VFS inode.
* @sb: The super block.
* @de: The devfs inode.
* @dentry: The dentry to register with the devfs inode.
@@ -2550,9 +2571,9 @@
* performed if the inode is created.
*/
-static struct inode *get_vfs_inode (struct super_block *sb,
- struct devfs_entry *de,
- struct dentry *dentry)
+static struct inode *_devfs_get_vfs_inode (struct super_block *sb,
+ struct devfs_entry *de,
+ struct dentry *dentry)
{
int is_fcb = FALSE;
struct inode *inode;
@@ -2560,8 +2581,7 @@
if (de->prev == de) return NULL; /* Quick check to see if unhooked */
if ( ( inode = new_inode (sb) ) == NULL )
{
- printk ("%s: get_vfs_inode(%s): new_inode() failed, de: %p\n",
- DEVFS_NAME, de->name, de);
+ PRINTK ("(%s): new_inode() failed, de: %p\n", de->name, de);
return NULL;
}
if (de->parent)
@@ -2578,11 +2598,8 @@
}
inode->u.generic_ip = devfs_get (de);
inode->i_ino = de->inode.ino;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_GET)
- printk ("%s: get_vfs_inode(%d): VFS inode: %p devfs_entry: %p\n",
- DEVFS_NAME, (int) inode->i_ino, inode, de);
-#endif
+ DPRINTK (DEBUG_I_GET, "(%d): VFS inode: %p devfs_entry: %p\n",
+ (int) inode->i_ino, inode, de);
inode->i_blocks = 0;
inode->i_blksize = FAKE_BLOCK_SIZE;
inode->i_op = &devfs_iops;
@@ -2590,22 +2607,21 @@
inode->i_rdev = NODEV;
if ( S_ISCHR (de->mode) )
{
- inode->i_rdev = MKDEV (de->u.fcb.u.device.major,
- de->u.fcb.u.device.minor);
+ inode->i_rdev = mk_kdev (de->u.fcb.u.device.major,
+ de->u.fcb.u.device.minor);
inode->i_cdev = cdget ( kdev_t_to_nr (inode->i_rdev) );
is_fcb = TRUE;
}
else if ( S_ISBLK (de->mode) )
{
- inode->i_rdev = MKDEV (de->u.fcb.u.device.major,
- de->u.fcb.u.device.minor);
+ inode->i_rdev = mk_kdev (de->u.fcb.u.device.major,
+ de->u.fcb.u.device.minor);
if (bd_acquire (inode) == 0)
{
if (!inode->i_bdev->bd_op && de->u.fcb.ops)
inode->i_bdev->bd_op = de->u.fcb.ops;
}
- else printk ("%s: get_vfs_inode(%d): no block device from bdget()\n",
- DEVFS_NAME, (int) inode->i_ino);
+ else PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino);
is_fcb = TRUE;
}
else if ( S_ISFIFO (de->mode) ) inode->i_fop = &def_fifo_fops;
@@ -2632,14 +2648,10 @@
inode->i_atime = de->inode.atime;
inode->i_mtime = de->inode.mtime;
inode->i_ctime = de->inode.ctime;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_GET)
- printk ("%s: mode: 0%o uid: %d gid: %d\n",
- DEVFS_NAME, (int) inode->i_mode,
- (int) inode->i_uid, (int) inode->i_gid);
-#endif
+ DPRINTK (DEBUG_I_GET, "(): mode: 0%o uid: %d gid: %d\n",
+ (int) inode->i_mode, (int) inode->i_uid, (int) inode->i_gid);
return inode;
-} /* End Function get_vfs_inode */
+} /* End Function _devfs_get_vfs_inode */
/* File operations for device entries follow */
@@ -2655,11 +2667,8 @@
fs_info = inode->i_sb->u.generic_sbp;
parent = get_devfs_entry_from_vfs_inode (file->f_dentry->d_inode);
if ( (long) file->f_pos < 0 ) return -EINVAL;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_F_READDIR)
- printk ("%s: readdir(): fs_info: %p pos: %ld\n", DEVFS_NAME,
- fs_info, (long) file->f_pos);
-#endif
+ DPRINTK (DEBUG_F_READDIR, "(%s): fs_info: %p pos: %ld\n",
+ parent->name, fs_info, (long) file->f_pos);
switch ( (long) file->f_pos )
{
case 0:
@@ -2779,13 +2788,7 @@
static void devfs_d_release (struct dentry *dentry)
{
-#ifdef CONFIG_DEVFS_DEBUG
- struct inode *inode = dentry->d_inode;
-
- if (devfs_debug & DEBUG_D_RELEASE)
- printk ("%s: d_release(): dentry: %p inode: %p\n",
- DEVFS_NAME, dentry, inode);
-#endif
+ DPRINTK (DEBUG_D_RELEASE, "(%p): inode: %p\n", dentry, dentry->d_inode);
} /* End Function devfs_d_release */
/**
@@ -2799,14 +2802,11 @@
struct devfs_entry *de;
de = get_devfs_entry_from_vfs_inode (inode);
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_D_IPUT)
- printk ("%s: d_iput(): dentry: %p inode: %p de: %p de->dentry: %p\n",
- DEVFS_NAME, dentry, inode, de, de->inode.dentry);
-#endif
+ DPRINTK (DEBUG_D_IPUT,"(%s): dentry: %p inode: %p de: %p de->dentry: %p\n",
+ de->name, dentry, inode, de, de->inode.dentry);
if ( de->inode.dentry && (de->inode.dentry != dentry) )
- OOPS ("%s: d_iput(%s): de: %p dentry: %p de->dentry: %p\n",
- DEVFS_NAME, de->name, de, dentry, de->inode.dentry);
+ OOPS ("(%s): de: %p dentry: %p de->dentry: %p\n",
+ de->name, de, dentry, de->inode.dentry);
de->inode.dentry = NULL;
iput (inode);
devfs_put (de);
@@ -2846,20 +2846,13 @@
/* Unhash dentry if negative (has no inode) */
if (inode == NULL)
{
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_D_DELETE)
- printk ("%s: d_delete(): dropping negative dentry: %p\n",
- DEVFS_NAME, dentry);
-#endif
+ DPRINTK (DEBUG_D_DELETE, "(%p): dropping negative dentry\n", dentry);
return 1;
}
fs_info = inode->i_sb->u.generic_sbp;
de = get_devfs_entry_from_vfs_inode (inode);
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_D_DELETE)
- printk ("%s: d_delete(): dentry: %p inode: %p devfs_entry: %p\n",
- DEVFS_NAME, dentry, inode, de);
-#endif
+ DPRINTK (DEBUG_D_DELETE, "(%p): inode: %p devfs_entry: %p\n",
+ dentry, inode, de);
if (de == NULL) return 0;
if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
return 0;
@@ -2876,40 +2869,58 @@
return 0;
} /* End Function devfs_d_delete */
+struct devfs_lookup_struct
+{
+ devfs_handle_t de;
+ wait_queue_head_t wait_queue;
+};
+
static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
{
struct inode *dir = dentry->d_parent->d_inode;
struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
+ devfs_handle_t parent = get_devfs_entry_from_vfs_inode (dir);
+ struct devfs_lookup_struct *lookup_info = dentry->d_fsdata;
+ DECLARE_WAITQUEUE (wait, current);
- if ( !dentry->d_inode && is_devfsd_or_child (fs_info) )
+ if ( is_devfsd_or_child (fs_info) )
{
- devfs_handle_t de;
- devfs_handle_t parent = get_devfs_entry_from_vfs_inode (dir);
+ devfs_handle_t de = lookup_info->de;
struct inode *inode;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_LOOKUP)
- printk ("%s: d_revalidate(%s): dentry: %p by: \"%s\"\n",
- DEVFS_NAME, dentry->d_name.name, dentry, current->comm);
-#endif
- read_lock (&parent->u.dir.lock);
- de = _devfs_search_dir (parent, dentry->d_name.name,
- dentry->d_name.len);
- read_unlock (&parent->u.dir.lock);
- if (de == NULL) return 1;
+ DPRINTK (DEBUG_I_LOOKUP,
+ "(%s): dentry: %p inode: %p de: %p by: \"%s\"\n",
+ dentry->d_name.name, dentry, dentry->d_inode, de,
+ current->comm);
+ if (dentry->d_inode) return 1;
+ if (de == NULL)
+ {
+ read_lock (&parent->u.dir.lock);
+ de = _devfs_search_dir (parent, dentry->d_name.name,
+ dentry->d_name.len);
+ read_unlock (&parent->u.dir.lock);
+ if (de == NULL) return 1;
+ lookup_info->de = de;
+ }
/* Create an inode, now that the driver information is available */
- inode = get_vfs_inode (dir->i_sb, de, dentry);
- devfs_put (de);
+ inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry);
if (!inode) return 1;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_LOOKUP)
- printk ("%s: d_revalidate(): new VFS inode(%u): %p devfs_entry: %p\n",
- DEVFS_NAME, de->inode.ino, inode, de);
-#endif
+ DPRINTK (DEBUG_I_LOOKUP,
+ "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n",
+ de->name, de->inode.ino, inode, de, current->comm);
d_instantiate (dentry, inode);
return 1;
}
- if ( wait_for_devfsd_finished (fs_info) ) dentry->d_op = &devfs_dops;
+ if (lookup_info == NULL) return 1; /* Early termination */
+ read_lock (&parent->u.dir.lock);
+ if (dentry->d_fsdata)
+ {
+ add_wait_queue (&lookup_info->wait_queue, &wait);
+ current->state = TASK_UNINTERRUPTIBLE;
+ read_unlock (&parent->u.dir.lock);
+ schedule ();
+ }
+ else read_unlock (&parent->u.dir.lock);
return 1;
} /* End Function devfs_d_revalidate_wait */
@@ -2918,20 +2929,20 @@
static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
{
+ struct devfs_entry tmp; /* Must stay in scope until devfsd idle again */
+ struct devfs_lookup_struct lookup_info;
struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
struct devfs_entry *parent, *de;
struct inode *inode;
+ struct dentry *retval = NULL;
/* Set up the dentry operations before anything else, to ensure cleaning
up on any error */
dentry->d_op = &devfs_dops;
/* First try to get the devfs entry for this directory */
parent = get_devfs_entry_from_vfs_inode (dir);
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_LOOKUP)
- printk ("%s: lookup(%s): dentry: %p parent: %p by: \"%s\"\n",
- DEVFS_NAME, dentry->d_name.name, dentry, parent,current->comm);
-#endif
+ DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n",
+ dentry->d_name.name, dentry, parent, current->comm);
if (parent == NULL) return ERR_PTR (-ENOENT);
read_lock (&parent->u.dir.lock);
de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len);
@@ -2945,63 +2956,61 @@
dentry->d_name.len);
read_unlock (&parent->u.dir.lock);
}
+ lookup_info.de = de;
+ init_waitqueue_head (&lookup_info.wait_queue);
+ dentry->d_fsdata = &lookup_info;
if (de == NULL)
{ /* Try with devfsd. For any kind of failure, leave a negative dentry
so someone else can deal with it (in the case where the sysadmin
does a mknod()). It's important to do this before hashing the
dentry, so that the devfsd queue is filled before revalidates
can start */
- struct devfs_entry tmp;
-
if (try_modload (parent, fs_info,
dentry->d_name.name, dentry->d_name.len, &tmp) < 0)
- {
+ { /* Lookup event was not queued to devfsd */
d_add (dentry, NULL);
return NULL;
}
- /* devfsd claimed success */
- dentry->d_op = &devfs_wait_dops;
- d_add (dentry, NULL); /* Open the floodgates */
- /* Unlock directory semaphore, which will release any waiters. They
- will get the hashed dentry, and may be forced to wait for
- revalidation */
- up (&dir->i_sem);
- devfs_d_revalidate_wait (dentry, 0); /* I might have to wait too */
- down (&dir->i_sem); /* Grab it again because them's the rules */
- /* If someone else has been so kind as to make the inode, we go home
- early */
- if (dentry->d_inode) return NULL;
+ }
+ dentry->d_op = &devfs_wait_dops;
+ d_add (dentry, NULL); /* Open the floodgates */
+ /* Unlock directory semaphore, which will release any waiters. They
+ will get the hashed dentry, and may be forced to wait for
+ revalidation */
+ up (&dir->i_sem);
+ wait_for_devfsd_finished (fs_info); /* If I'm not devfsd, must wait */
+ down (&dir->i_sem); /* Grab it again because them's the rules */
+ de = lookup_info.de;
+ /* If someone else has been so kind as to make the inode, we go home
+ early */
+ if (dentry->d_inode) goto out;
+ if (de == NULL)
+ {
read_lock (&parent->u.dir.lock);
de = _devfs_search_dir (parent, dentry->d_name.name,
dentry->d_name.len);
read_unlock (&parent->u.dir.lock);
- if (de == NULL) return NULL;
+ if (de == NULL) goto out;
/* OK, there's an entry now, but no VFS inode yet */
}
- else
+ /* Create an inode, now that the driver information is available */
+ inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry);
+ if (!inode)
{
- dentry->d_op = &devfs_wait_dops;
- d_add (dentry, NULL); /* Open the floodgates */
+ retval = ERR_PTR (-ENOMEM);
+ goto out;
}
- /* Create an inode, now that the driver information is available */
- inode = get_vfs_inode (dir->i_sb, de, dentry);
- devfs_put (de);
- if (!inode) return ERR_PTR (-ENOMEM);
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_LOOKUP)
- printk ("%s: lookup(): new VFS inode(%u): %p devfs_entry: %p\n",
- DEVFS_NAME, de->inode.ino, inode, de);
-#endif
+ DPRINTK (DEBUG_I_LOOKUP, "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n",
+ de->name, de->inode.ino, inode, de, current->comm);
d_instantiate (dentry, inode);
- if (dentry->d_op == &devfs_wait_dops)
- { /* Unlock directory semaphore, which will release any waiters. They
- will get the hashed dentry, and may be forced to wait for
- revalidation */
- up (&dir->i_sem);
- devfs_d_revalidate_wait (dentry, 0); /* I might have to wait too */
- down (&dir->i_sem); /* Grab it again because them's the rules */
- }
- return NULL;
+out:
+ dentry->d_op = &devfs_dops;
+ dentry->d_fsdata = NULL;
+ write_lock (&parent->u.dir.lock);
+ wake_up (&lookup_info.wait_queue);
+ write_unlock (&parent->u.dir.lock);
+ devfs_put (de);
+ return retval;
} /* End Function devfs_lookup */
static int devfs_unlink (struct inode *dir, struct dentry *dentry)
@@ -3011,13 +3020,10 @@
struct inode *inode = dentry->d_inode;
struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_UNLINK)
- printk ("%s: unlink(%s)\n", DEVFS_NAME, dentry->d_name.name);
-#endif
de = get_devfs_entry_from_vfs_inode (inode);
+ DPRINTK (DEBUG_I_UNLINK, "(%s): de: %p\n", dentry->d_name.name, de);
if (de == NULL) return -ENOENT;
- if (!de->vfs_created) return -EPERM;
+ if (!de->vfs_deletable) return -EPERM;
write_lock (&de->parent->u.dir.lock);
unhooked = _devfs_unhook (de);
write_unlock (&de->parent->u.dir.lock);
@@ -3043,25 +3049,19 @@
if (parent == NULL) return -ENOENT;
err = devfs_do_symlink (parent, dentry->d_name.name, DEVFS_FL_NONE,
symname, &de, NULL);
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_DISABLED)
- printk ("%s: symlink(): errcode from <devfs_do_symlink>: %d\n",
- DEVFS_NAME, err);
-#endif
+ DPRINTK (DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
+ dentry->d_name.name, err);
if (err < 0) return err;
- de->vfs_created = TRUE;
+ de->vfs_deletable = 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 = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
+ if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
return -ENOMEM;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_DISABLED)
- printk ("%s: symlink(): new VFS inode(%u): %p dentry: %p\n",
- DEVFS_NAME, de->inode.ino, inode, dentry);
-#endif
+ DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n",
+ dentry->d_name.name, de->inode.ino, inode, dentry);
d_instantiate (dentry, inode);
if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
@@ -3081,7 +3081,7 @@
if (parent == NULL) return -ENOENT;
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
if (!de) return -ENOMEM;
- de->vfs_created = TRUE;
+ de->vfs_deletable = TRUE;
if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
return err;
de->inode.uid = current->euid;
@@ -3089,13 +3089,10 @@
de->inode.atime = CURRENT_TIME;
de->inode.mtime = CURRENT_TIME;
de->inode.ctime = CURRENT_TIME;
- if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
+ if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
return -ENOMEM;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_DISABLED)
- printk ("%s: mkdir(): new VFS inode(%u): %p dentry: %p\n",
- DEVFS_NAME, de->inode.ino, inode, dentry);
-#endif
+ DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n",
+ dentry->d_name.name, de->inode.ino, inode, dentry);
d_instantiate (dentry, inode);
if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
@@ -3114,7 +3111,7 @@
de = get_devfs_entry_from_vfs_inode (inode);
if (de == NULL) return -ENOENT;
if ( !S_ISDIR (de->mode) ) return -ENOTDIR;
- if (!de->vfs_created) return -EPERM;
+ if (!de->vfs_deletable) return -EPERM;
/* First ensure the directory is empty and will stay thay way */
write_lock (&de->u.dir.lock);
de->u.dir.no_more_additions = TRUE;
@@ -3142,16 +3139,13 @@
struct devfs_entry *parent, *de;
struct inode *inode;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_MKNOD)
- printk ("%s: mknod(%s): mode: 0%o dev: %d\n",
- DEVFS_NAME, dentry->d_name.name, mode, rdev);
-#endif
+ DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %d\n",
+ dentry->d_name.name, mode, rdev);
parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) return -ENOENT;
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
if (!de) return -ENOMEM;
- de->vfs_created = TRUE;
+ de->vfs_deletable = TRUE;
if ( S_ISBLK (mode) || S_ISCHR (mode) )
{
de->u.fcb.u.device.major = MAJOR (rdev);
@@ -3164,13 +3158,10 @@
de->inode.atime = CURRENT_TIME;
de->inode.mtime = CURRENT_TIME;
de->inode.ctime = CURRENT_TIME;
- if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
+ if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
return -ENOMEM;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_MKNOD)
- printk ("%s: new VFS inode(%u): %p dentry: %p\n",
- DEVFS_NAME, de->inode.ino, inode, dentry);
-#endif
+ DPRINTK (DEBUG_I_MKNOD, ": new VFS inode(%u): %p dentry: %p\n",
+ de->inode.ino, inode, dentry);
d_instantiate (dentry, inode);
if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
@@ -3238,15 +3229,11 @@
sb->s_blocksize_bits = 10;
sb->s_magic = DEVFS_SUPER_MAGIC;
sb->s_op = &devfs_sops;
- if ( ( root_inode = get_vfs_inode (sb, root_entry, NULL) ) == NULL )
+ if ( ( root_inode = _devfs_get_vfs_inode (sb, root_entry, NULL) ) == NULL )
goto out_no_root;
sb->s_root = d_alloc_root (root_inode);
if (!sb->s_root) goto out_no_root;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_S_READ)
- printk ("%s: read super, made devfs ptr: %p\n",
- DEVFS_NAME, sb->u.generic_sbp);
-#endif
+ DPRINTK (DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->u.generic_sbp);
return sb;
out_no_root:
@@ -3479,6 +3466,10 @@
printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n",
DEVFS_NAME, DEVFS_VERSION);
+ devfsd_buf_cache = kmem_cache_create ("devfsd_event",
+ sizeof (struct devfsd_buf_entry),
+ 0, 0, NULL, NULL);
+ if (!devfsd_buf_cache) OOPS ("(): unable to allocate event slab\n");
#ifdef CONFIG_DEVFS_DEBUG
devfs_debug = devfs_debug_init;
printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
@@ -3498,9 +3489,6 @@
{
int err;
- devfsd_buf_cache = kmem_cache_create ("devfsd_event",
- sizeof (struct devfsd_buf_entry),
- 0, 0, NULL, NULL);
if ( !(boot_options & OPTION_MOUNT) ) return;
err = do_mount ("none", "/dev", "devfs", 0, "");
if (err == 0) printk ("Mounted devfs on /dev\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)