summaryrefslogtreecommitdiffstats
path: root/fs/devfs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-06-25 01:20:01 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-06-25 01:20:01 +0000
commit3797ba0b62debb71af4606910acacc9896a9ae3b (patch)
tree414eea76253c7871bfdf3bd9d1817771eb40917c /fs/devfs
parent2b6c0c580795a4404f72d2a794214dd9e080709d (diff)
Merge with Linux 2.4.0-test2.
Diffstat (limited to 'fs/devfs')
-rw-r--r--fs/devfs/base.c886
-rw-r--r--fs/devfs/util.c11
2 files changed, 312 insertions, 585 deletions
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 9f1e8b06f..0d3d15177 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -451,6 +451,31 @@
Added CONFIG_DEVFS_MOUNT.
Work sponsored by SGI.
v0.96
+ 20000608 Richard Gooch <rgooch@atnf.csiro.au>
+ Disabled multi-mount capability (use VFS bindings instead).
+ Work sponsored by SGI.
+ v0.97
+ 20000610 Richard Gooch <rgooch@atnf.csiro.au>
+ Switched to FS_SINGLE to disable multi-mounts.
+ 20000612 Richard Gooch <rgooch@atnf.csiro.au>
+ Removed module support.
+ Removed multi-mount code.
+ Removed compatibility macros: VFS has changed too much.
+ Work sponsored by SGI.
+ v0.98
+ 20000614 Richard Gooch <rgooch@atnf.csiro.au>
+ Merged devfs inode into devfs entry.
+ Work sponsored by SGI.
+ v0.99
+ 20000619 Richard Gooch <rgooch@atnf.csiro.au>
+ Removed dead code in <devfs_register> which used to call
+ <free_dentries>.
+ Work sponsored by SGI.
+ v0.100
+ 20000621 Richard Gooch <rgooch@atnf.csiro.au>
+ Changed interface to <devfs_register>.
+ Work sponsored by SGI.
+ v0.101
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -485,29 +510,9 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "0.96 (20000430)"
+#define DEVFS_VERSION "0.101 (20000621)"
-#ifndef DEVFS_NAME
-# define DEVFS_NAME "devfs"
-#endif
-
-/* Compatibility for 2.2.x kernel series */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1))
-# define init_waitqueue_head(p) init_waitqueue(p)
-# define DECLARE_WAITQUEUE(wait, p) struct wait_queue wait = {p, NULL}
-typedef struct wait_queue *wait_queue_head_t;
-#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,6))
-# define D_ALLOC_ROOT(inode) d_alloc_root (inode, NULL)
-#else
-# define D_ALLOC_ROOT(inode) d_alloc_root (inode)
-#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13))
-# define SETUP_STATIC
-# define __setup(a,b)
-#else
-# define SETUP_STATIC static
-#endif
+#define DEVFS_NAME "devfs"
#define INODE_TABLE_INC 250
#define FIRST_INODE 1
@@ -604,6 +609,19 @@ struct fifo_type
gid_t gid;
};
+struct devfs_inode /* This structure is for "persistent" inode storage */
+{
+ time_t atime;
+ time_t mtime;
+ time_t ctime;
+ unsigned int ino; /* Inode number as seen in the VFS */
+ struct dentry *dentry;
+ umode_t mode;
+ uid_t uid;
+ gid_t gid;
+ nlink_t nlink;
+};
+
struct devfs_entry
{
void *info;
@@ -619,8 +637,7 @@ struct devfs_entry
struct devfs_entry *next; /* Next entry in the parent directory */
struct devfs_entry *parent; /* The parent directory */
struct devfs_entry *slave; /* Another entry to unregister */
- struct devfs_inode *first_inode;
- struct devfs_inode *last_inode;
+ struct devfs_inode inode;
umode_t mode;
unsigned short namelen; /* I think 64k+ filenames are a way off... */
unsigned char registered:1;
@@ -634,26 +651,6 @@ struct devfs_entry
/* The root of the device tree */
static struct devfs_entry *root_entry = NULL;
-struct devfs_inode /* This structure is for "persistent" inode storage */
-{
- time_t atime;
- time_t mtime;
- time_t ctime;
- unsigned int ino; /* Inode number as seen in the VFS */
- struct devfs_entry *de;
- struct fs_info *fs_info;
- struct devfs_inode *prev; /* This pair are used to associate a list of */
- struct devfs_inode *next; /* inodes (one per FS) for a devfs entry */
- struct dentry *dentry;
-#ifdef CONFIG_DEVFS_TUNNEL
- struct dentry *covered;
-#endif
- umode_t mode;
- uid_t uid;
- gid_t gid;
- nlink_t nlink;
-};
-
struct devfsd_buf_entry
{
void *data;
@@ -667,7 +664,7 @@ struct fs_info /* This structure is for each mounted devfs */
{
unsigned int num_inodes; /* Number of inodes created */
unsigned int table_size; /* Size of the inode pointer table */
- struct devfs_inode **table;
+ struct devfs_entry **table;
struct super_block *sb;
volatile struct devfsd_buf_entry *devfsd_buffer;
volatile unsigned int devfsd_buf_in;
@@ -680,23 +677,15 @@ struct fs_info /* This structure is for each mounted devfs */
atomic_t devfsd_overrun_count;
wait_queue_head_t devfsd_wait_queue;
wait_queue_head_t revalidate_wait_queue;
- struct fs_info *prev;
- struct fs_info *next;
- unsigned char require_explicit:1;
};
-static struct fs_info *first_fs = NULL;
-static struct fs_info *last_fs = NULL;
+static struct fs_info fs_info;
static unsigned int next_devnum_char = MIN_DEVNUM;
static unsigned int next_devnum_block = MIN_DEVNUM;
static const int devfsd_buf_size = PAGE_SIZE / sizeof(struct devfsd_buf_entry);
#ifdef CONFIG_DEVFS_DEBUG
-# ifdef MODULE
-unsigned int devfs_debug = DEBUG_NONE;
-# else
static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
static unsigned int devfs_debug = DEBUG_NONE;
-# endif
#endif
#ifdef CONFIG_DEVFS_MOUNT
@@ -770,15 +759,40 @@ static struct devfs_entry *search_for_entry_in_dir (struct devfs_entry *parent,
static struct devfs_entry *create_entry (struct devfs_entry *parent,
const char *name,unsigned int namelen)
{
- struct devfs_entry *new;
+ struct devfs_entry *new, **table;
+ /* First ensure table size is enough */
+ if (fs_info.num_inodes >= fs_info.table_size)
+ {
+ if ( ( table = kmalloc (sizeof *table *
+ (fs_info.table_size + INODE_TABLE_INC),
+ GFP_KERNEL) ) == NULL ) return NULL;
+ fs_info.table_size += INODE_TABLE_INC;
+#ifdef CONFIG_DEVFS_DEBUG
+ if (devfs_debug & DEBUG_I_CREATE)
+ printk ("%s: create_entry(): grew inode table to: %u entries\n",
+ DEVFS_NAME, fs_info.table_size);
+#endif
+ if (fs_info.table)
+ {
+ memcpy (table, fs_info.table, sizeof *table *fs_info.num_inodes);
+ kfree (fs_info.table);
+ }
+ fs_info.table = table;
+ }
if ( name && (namelen < 1) ) namelen = strlen (name);
if ( ( new = kmalloc (sizeof *new + namelen, GFP_KERNEL) ) == NULL )
return NULL;
+ /* Magic: this will set the ctime to zero, thus subsequent lookups will
+ trigger the call to <update_devfs_inode_from_entry> */
memset (new, 0, sizeof *new + namelen);
new->parent = parent;
if (name) memcpy (new->name, name, namelen);
new->namelen = namelen;
+ new->inode.ino = fs_info.num_inodes + FIRST_INODE;
+ new->inode.nlink = 1;
+ fs_info.table[fs_info.num_inodes] = new;
+ ++fs_info.num_inodes;
if (parent == NULL) return new;
new->prev = parent->u.dir.last;
/* Insert into the parent directory's list of children */
@@ -788,6 +802,36 @@ static struct devfs_entry *create_entry (struct devfs_entry *parent,
return new;
} /* End Function create_entry */
+static void update_devfs_inode_from_entry (struct devfs_entry *de)
+{
+ if (de == NULL) return;
+ if ( S_ISDIR (de->mode) )
+ {
+ de->inode.mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+ de->inode.uid = 0;
+ de->inode.gid = 0;
+ }
+ else if ( S_ISLNK (de->mode) )
+ {
+ de->inode.mode = S_IFLNK | S_IRUGO | S_IXUGO;
+ de->inode.uid = 0;
+ de->inode.gid = 0;
+ }
+ else if ( S_ISFIFO (de->mode) )
+ {
+ de->inode.mode = de->mode;
+ de->inode.uid = de->u.fifo.uid;
+ de->inode.gid = de->u.fifo.gid;
+ }
+ else
+ {
+ if (de->u.fcb.auto_owner)
+ de->inode.mode = (de->mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO;
+ else de->inode.mode = de->mode;
+ de->inode.uid = de->u.fcb.default_uid;
+ de->inode.gid = de->u.fcb.default_gid;
+ }
+} /* End Function update_devfs_inode_from_entry */
/**
* get_root_entry - Get the root devfs entry.
@@ -804,6 +848,8 @@ static struct devfs_entry *get_root_entry (void)
if ( ( root_entry = create_entry (NULL, NULL, 0) ) == NULL ) return NULL;
root_entry->registered = TRUE;
root_entry->mode = S_IFDIR;
+ /* Force an inode update, because lookup() is never done for the root */
+ update_devfs_inode_from_entry (root_entry);
/* And create the entry for ".devfsd" */
if ( ( new = create_entry (root_entry, ".devfsd", 0) ) == NULL )
return NULL;
@@ -1002,7 +1048,7 @@ static struct devfs_entry *find_entry (devfs_handle_t dir,
return find_by_dev (root_entry, major, minor, type);
} /* End Function find_entry */
-static struct devfs_inode *get_devfs_inode_from_vfs_inode (struct inode *inode)
+static struct devfs_entry *get_devfs_entry_from_vfs_inode (struct inode *inode)
{
struct fs_info *fs_info;
@@ -1012,7 +1058,7 @@ static struct devfs_inode *get_devfs_inode_from_vfs_inode (struct inode *inode)
if (fs_info == NULL) return NULL;
if (inode->i_ino - FIRST_INODE >= fs_info->num_inodes) return NULL;
return fs_info->table[inode->i_ino - FIRST_INODE];
-} /* End Function get_devfs_inode_from_vfs_inode */
+} /* End Function get_devfs_entry_from_vfs_inode */
/**
@@ -1022,21 +1068,17 @@ static struct devfs_inode *get_devfs_inode_from_vfs_inode (struct inode *inode)
static void free_dentries (struct devfs_entry *de)
{
- struct devfs_inode *di;
struct dentry *dentry;
- for (di = de->first_inode; di != NULL; di = di->next)
+ dentry = de->inode.dentry;
+ if (dentry != NULL)
{
- dentry = di->dentry;
- if (dentry != NULL)
- {
- dget (dentry);
- di->dentry = NULL;
- /* Forcefully remove the inode */
- if (dentry->d_inode != NULL) dentry->d_inode->i_nlink = 0;
- d_drop (dentry);
- dput (dentry);
- }
+ dget (dentry);
+ de->inode.dentry = NULL;
+ /* Forcefully remove the inode */
+ if (dentry->d_inode != NULL) dentry->d_inode->i_nlink = 0;
+ d_drop (dentry);
+ dput (dentry);
}
} /* End Function free_dentries */
@@ -1155,14 +1197,9 @@ static int devfsd_notify_one (void *data, unsigned int type, umode_t mode,
static void devfsd_notify (struct devfs_entry *de, unsigned int type, int wait)
{
- struct fs_info *fs_info;
-
- for (fs_info = first_fs; fs_info != NULL; fs_info = fs_info->next)
- {
- if (devfsd_notify_one (de, type, de->mode, current->euid,
- current->egid, fs_info) && wait)
- wait_for_devfsd_finished (fs_info);
- }
+ if (devfsd_notify_one (de, type, de->mode, current->euid,
+ current->egid, &fs_info) && wait)
+ wait_for_devfsd_finished (&fs_info);
} /* End Function devfsd_notify */
@@ -1171,15 +1208,10 @@ static void devfsd_notify (struct devfs_entry *de, unsigned int type, int wait)
* @dir: The handle to the parent devfs directory entry. If this is %NULL the
* new name is relative to the root of the devfs.
* @name: The name of the entry.
- * @namelen: The number of characters in @name, not including a %NULL
- * terminator. If this is 0, then @name must be %NULL-terminated and the
- * length is computed internally.
* @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
* @major: The major number. Not needed for regular files.
* @minor: The minor number. Not needed for regular files.
* @mode: The default file mode.
- * @uid: The default UID of the file.
- * @guid: The default GID of the file.
* @ops: The &file_operations or &block_device_operations structure.
* This must not be externally deallocated.
* @info: An arbitrary pointer which will be written to the @private_data
@@ -1191,12 +1223,10 @@ static void devfsd_notify (struct devfs_entry *de, unsigned int type, int wait)
* On failure %NULL is returned.
*/
-devfs_handle_t devfs_register (devfs_handle_t dir,
- const char *name, unsigned int namelen,
+devfs_handle_t devfs_register (devfs_handle_t dir, const char *name,
unsigned int flags,
unsigned int major, unsigned int minor,
- umode_t mode, uid_t uid, gid_t gid,
- void *ops, void *info)
+ umode_t mode, void *ops, void *info)
{
int is_new;
struct devfs_entry *de;
@@ -1231,7 +1261,6 @@ devfs_handle_t devfs_register (devfs_handle_t dir,
DEVFS_NAME, name);
return NULL;
}
- if (namelen < 1) namelen = strlen (name);
if ( S_ISCHR (mode) && (flags & DEVFS_FL_AUTO_DEVNUM) )
{
if (next_devnum_char >= MAX_DEVNUM)
@@ -1256,7 +1285,8 @@ devfs_handle_t devfs_register (devfs_handle_t dir,
minor = next_devnum_block & 0xff;
++next_devnum_block;
}
- de = search_for_entry (dir, name, namelen, TRUE, TRUE, &is_new, FALSE);
+ de = search_for_entry (dir, name, strlen (name), TRUE, TRUE, &is_new,
+ FALSE);
if (de == NULL)
{
printk ("%s: devfs_register(): could not create entry: \"%s\"\n",
@@ -1284,8 +1314,6 @@ devfs_handle_t devfs_register (devfs_handle_t dir,
DEVFS_NAME, name);
return NULL;
}
- /* If entry already exists free any dentries associated with it */
- if (de->registered) free_dentries (de);
}
de->registered = TRUE;
if ( S_ISCHR (mode) || S_ISBLK (mode) )
@@ -1302,8 +1330,16 @@ devfs_handle_t devfs_register (devfs_handle_t dir,
}
de->info = info;
de->mode = mode;
- de->u.fcb.default_uid = uid;
- de->u.fcb.default_gid = gid;
+ if (flags & DEVFS_FL_CURRENT_OWNER)
+ {
+ de->u.fcb.default_uid = current->uid;
+ de->u.fcb.default_gid = current->gid;
+ }
+ else
+ {
+ de->u.fcb.default_uid = 0;
+ de->u.fcb.default_gid = 0;
+ }
de->registered = TRUE;
de->u.fcb.ops = ops;
de->u.fcb.auto_owner = (flags & DEVFS_FL_AUTO_OWNER) ? TRUE : FALSE;
@@ -1687,13 +1723,9 @@ int devfs_get_maj_min (devfs_handle_t de, unsigned int *major,
devfs_handle_t devfs_get_handle_from_inode (struct inode *inode)
{
- struct devfs_inode *di;
-
if (!inode || !inode->i_sb) return NULL;
if (inode->i_sb->s_magic != DEVFS_SUPER_MAGIC) return NULL;
- di = get_devfs_inode_from_vfs_inode (inode);
- if (!di) return NULL;
- return di->de;
+ return get_devfs_entry_from_vfs_inode (inode);
} /* End Function devfs_get_handle_from_inode */
@@ -1756,19 +1788,14 @@ void *devfs_get_ops (devfs_handle_t de)
int devfs_set_file_size (devfs_handle_t de, unsigned long size)
{
- struct devfs_inode *di;
-
if (de == NULL) return -EINVAL;
if (!de->registered) return -EINVAL;
if ( !S_ISREG (de->mode) ) return -EINVAL;
if (de->u.fcb.u.file.size == size) return 0;
de->u.fcb.u.file.size = size;
- for (di = de->first_inode; di != NULL; di = di->next)
- {
- if (di->dentry == NULL) continue;
- if (di->dentry->d_inode == NULL) continue;
- di->dentry->d_inode->i_size = size;
- }
+ if (de->inode.dentry == NULL) return 0;
+ if (de->inode.dentry->d_inode == NULL) return 0;
+ de->inode.dentry->d_inode->i_size = size;
return 0;
} /* End Function devfs_set_file_size */
@@ -1974,18 +2001,16 @@ int devfs_unregister_blkdev (unsigned int major, const char *name)
return unregister_blkdev (major, name);
} /* End Function devfs_unregister_blkdev */
-#ifndef MODULE
-
/**
* devfs_setup - Process kernel boot options.
* @str: The boot options after the "devfs=".
*/
-SETUP_STATIC int __init devfs_setup (char *str)
+static int __init devfs_setup (char *str)
{
while ( (*str != '\0') && !isspace (*str) )
{
-# ifdef CONFIG_DEVFS_DEBUG
+#ifdef CONFIG_DEVFS_DEBUG
if (strncmp (str, "dall", 4) == 0)
{
devfs_debug_init |= DEBUG_ALL;
@@ -2037,7 +2062,7 @@ SETUP_STATIC int __init devfs_setup (char *str)
str += 8;
}
else
-# endif /* CONFIG_DEVFS_DEBUG */
+#endif /* CONFIG_DEVFS_DEBUG */
if (strncmp (str, "show", 4) == 0)
{
boot_options |= OPTION_SHOW;
@@ -2068,8 +2093,6 @@ SETUP_STATIC int __init devfs_setup (char *str)
__setup("devfs=", devfs_setup);
-#endif /* !MODULE */
-
EXPORT_SYMBOL(devfs_register);
EXPORT_SYMBOL(devfs_unregister);
EXPORT_SYMBOL(devfs_mk_symlink);
@@ -2094,101 +2117,6 @@ EXPORT_SYMBOL(devfs_register_blkdev);
EXPORT_SYMBOL(devfs_unregister_chrdev);
EXPORT_SYMBOL(devfs_unregister_blkdev);
-#ifdef CONFIG_DEVFS_DEBUG
-MODULE_PARM(devfs_debug, "i");
-#endif
-
-static void update_devfs_inode_from_entry (struct devfs_inode *di)
-{
- if (di == NULL) return;
- if (di->de == NULL)
- {
- printk ("%s: update_devfs_inode_from_entry(): NULL entry\n",
- DEVFS_NAME);
- return;
- }
- if ( S_ISDIR (di->de->mode) )
- {
- di->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
- di->uid = 0;
- di->gid = 0;
- }
- else if ( S_ISLNK (di->de->mode) )
- {
- di->mode = S_IFLNK | S_IRUGO | S_IXUGO;
- di->uid = 0;
- di->gid = 0;
- }
- else if ( S_ISFIFO (di->de->mode) )
- {
- di->mode = di->de->mode;
- di->uid = di->de->u.fifo.uid;
- di->gid = di->de->u.fifo.gid;
- }
- else
- {
- if (di->de->u.fcb.auto_owner)
- di->mode = (di->de->mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO;
- else di->mode = di->de->mode;
- di->uid = di->de->u.fcb.default_uid;
- di->gid = di->de->u.fcb.default_gid;
- }
-} /* End Function update_devfs_inode_from_entry */
-
-
-/**
- * create_devfs_inode - Create a devfs inode entry.
- * @de: The devfs entry to associate the new inode with.
- * @fs_info: The FS info.
- *
- * Returns a pointer to the devfs inode on success, else %NULL.
- */
-
-static struct devfs_inode *create_devfs_inode (struct devfs_entry *de,
- struct fs_info *fs_info)
-{
- struct devfs_inode *di, **table;
-
- /* First ensure table size is enough */
- if (fs_info->num_inodes >= fs_info->table_size)
- {
- if ( ( table = kmalloc (sizeof *table *
- (fs_info->table_size + INODE_TABLE_INC),
- GFP_KERNEL) ) == NULL ) return NULL;
- fs_info->table_size += INODE_TABLE_INC;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_CREATE)
- printk ("%s: create_devfs_inode(): grew inode table to: %u entries\n",
- DEVFS_NAME, fs_info->table_size);
-#endif
- if (fs_info->table)
- {
- memcpy (table, fs_info->table, sizeof *table *fs_info->num_inodes);
- kfree (fs_info->table);
- }
- fs_info->table = table;
- }
- if ( ( di = kmalloc (sizeof *di, GFP_KERNEL) ) == NULL ) return NULL;
- memset (di, 0, sizeof *di);
- di->ino = fs_info->num_inodes + FIRST_INODE;
- di->nlink = 1;
- fs_info->table[fs_info->num_inodes] = di;
- ++fs_info->num_inodes;
- di->de = de;
- di->fs_info = fs_info;
- di->prev = de->last_inode;
- if (de->first_inode == NULL) de->first_inode = di;
- else de->last_inode->next = di;
- de->last_inode = di;
- update_devfs_inode_from_entry (di);
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_CREATE)
- printk ("%s: create_devfs_inode(): new di(%u): %p\n",
- DEVFS_NAME, di->ino, di);
-#endif
- return di;
-} /* End Function create_devfs_inode */
-
/**
* try_modload - Notify devfsd of an inode lookup.
@@ -2224,34 +2152,6 @@ static int try_modload (struct devfs_entry *parent, struct fs_info *fs_info,
return 0;
} /* End Function try_modload */
-static void delete_fs (struct fs_info *fs_info)
-{
- unsigned int count;
- struct devfs_inode *di;
- struct devfs_entry *de;
-
- if (fs_info == NULL) return;
- for (count = 0; count < fs_info->num_inodes; ++count)
- {
- /* Unhook this inode from the devfs tree */
- di = fs_info->table[count];
- de = di->de;
- if (di->prev == NULL) de->first_inode = di->next;
- else di->prev->next = di->next;
- if (di->next == NULL) de->last_inode = di->prev;
- else di->next->prev = di->prev;
- memset (di, 0, sizeof *di);
- kfree (di);
- }
- if (fs_info->table) kfree (fs_info->table);
- if (fs_info->prev == NULL) first_fs = fs_info->next;
- else fs_info->prev->next = fs_info->next;
- if (fs_info->next == NULL) last_fs = fs_info->prev;
- else fs_info->next->prev = fs_info->prev;
- memset (fs_info, 0, sizeof *fs_info);
- kfree (fs_info);
-} /* End Function delete_fs */
-
/**
* check_disc_changed - Check if a removable disc was changed.
@@ -2345,19 +2245,19 @@ static struct inode_operations devfs_symlink_iops;
static void devfs_read_inode (struct inode *inode)
{
- struct devfs_inode *di;
+ struct devfs_entry *de;
- di = get_devfs_inode_from_vfs_inode (inode);
- if (di == NULL)
+ de = get_devfs_entry_from_vfs_inode (inode);
+ if (de == NULL)
{
- printk ("%s: read_inode(%d): VFS inode: %p NO devfs_inode\n",
+ printk ("%s: read_inode(%d): VFS inode: %p NO devfs_entry\n",
DEVFS_NAME, (int) inode->i_ino, inode);
return;
}
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_READ)
- printk ("%s: read_inode(%d): VFS inode: %p devfs_inode: %p\n",
- DEVFS_NAME, (int) inode->i_ino, inode, di);
+ printk ("%s: read_inode(%d): VFS inode: %p devfs_entry: %p\n",
+ DEVFS_NAME, (int) inode->i_ino, inode, de);
#endif
inode->i_size = 0;
inode->i_blocks = 0;
@@ -2365,39 +2265,39 @@ static void devfs_read_inode (struct inode *inode)
inode->i_op = &devfs_iops;
inode->i_fop = &devfs_fops;
inode->i_rdev = NODEV;
- if ( S_ISCHR (di->mode) )
+ if ( S_ISCHR (de->inode.mode) )
{
- inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major,
- di->de->u.fcb.u.device.minor);
+ inode->i_rdev = MKDEV (de->u.fcb.u.device.major,
+ de->u.fcb.u.device.minor);
}
- else if ( S_ISBLK (di->mode) )
+ else if ( S_ISBLK (de->inode.mode) )
{
- inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major,
- di->de->u.fcb.u.device.minor);
+ inode->i_rdev = MKDEV (de->u.fcb.u.device.major,
+ de->u.fcb.u.device.minor);
inode->i_bdev = bdget (inode->i_rdev);
if (inode->i_bdev)
{
- if (!inode->i_bdev->bd_op && di->de->u.fcb.ops)
- inode->i_bdev->bd_op = di->de->u.fcb.ops;
+ if (!inode->i_bdev->bd_op && de->u.fcb.ops)
+ inode->i_bdev->bd_op = de->u.fcb.ops;
}
else printk ("%s: read_inode(%d): no block device from bdget()\n",
DEVFS_NAME, (int) inode->i_ino);
}
- else if ( S_ISFIFO (di->mode) ) inode->i_fop = &def_fifo_fops;
- else if ( S_ISREG (di->mode) ) inode->i_size = di->de->u.fcb.u.file.size;
- else if ( S_ISDIR (di->mode) ) inode->i_op = &devfs_dir_iops;
- else if ( S_ISLNK (di->mode) )
+ else if ( S_ISFIFO (de->inode.mode) ) inode->i_fop = &def_fifo_fops;
+ else if ( S_ISREG (de->inode.mode) ) inode->i_size = de->u.fcb.u.file.size;
+ else if ( S_ISDIR (de->inode.mode) ) inode->i_op = &devfs_dir_iops;
+ else if ( S_ISLNK (de->inode.mode) )
{
inode->i_op = &devfs_symlink_iops;
- inode->i_size = di->de->u.symlink.length;
- }
- inode->i_mode = di->mode;
- inode->i_uid = di->uid;
- inode->i_gid = di->gid;
- inode->i_atime = di->atime;
- inode->i_mtime = di->mtime;
- inode->i_ctime = di->ctime;
- inode->i_nlink = di->nlink;
+ inode->i_size = de->u.symlink.length;
+ }
+ inode->i_mode = de->inode.mode;
+ 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;
+ inode->i_nlink = de->inode.nlink;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_READ)
printk ("%s: mode: 0%o uid: %d gid: %d\n",
@@ -2409,7 +2309,7 @@ static void devfs_read_inode (struct inode *inode)
static void devfs_write_inode (struct inode *inode, int unused)
{
int index;
- struct devfs_inode *di;
+ struct devfs_entry *de;
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
if (inode->i_ino < FIRST_INODE) return;
@@ -2420,57 +2320,43 @@ static void devfs_write_inode (struct inode *inode, int unused)
DEVFS_NAME, inode->i_ino);
return;
}
- di = fs_info->table[index];
+ de = fs_info->table[index];
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_WRITE)
{
- printk ("%s: write_inode(%d): VFS inode: %p devfs_inode: %p\n",
- DEVFS_NAME, (int) inode->i_ino, inode, di);
+ printk ("%s: write_inode(%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
- di->mode = inode->i_mode;
- di->uid = inode->i_uid;
- di->gid = inode->i_gid;
- di->atime = inode->i_atime;
- di->mtime = inode->i_mtime;
- di->ctime = inode->i_ctime;
+ de->inode.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;
} /* End Function devfs_write_inode */
static int devfs_notify_change (struct dentry *dentry, struct iattr *iattr)
{
int retval;
- struct devfs_inode *di;
+ struct devfs_entry *de;
struct inode *inode = dentry->d_inode;
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
- di = get_devfs_inode_from_vfs_inode (inode);
- if (di == NULL) return -ENODEV;
+ de = get_devfs_entry_from_vfs_inode (inode);
+ if (de == NULL) return -ENODEV;
retval = inode_change_ok (inode, iattr);
if (retval != 0) return retval;
inode_setattr (inode, iattr);
if ( iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID) )
- devfsd_notify_one (di->de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
+ devfsd_notify_one (de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info);
return 0;
} /* End Function devfs_notify_change */
-static void devfs_put_super (struct super_block *sb)
-{
- struct fs_info *fs_info = sb->u.generic_sbp;
-
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_S_PUT)
- printk ("%s: put_super(): devfs ptr: %p\n", DEVFS_NAME, fs_info);
-#endif
-#ifdef CONFIG_DEVFS_TUNNEL
- dput (fs_info->table[0]->covered);
-#endif
- delete_fs (fs_info);
-} /* End Function devfs_put_super */
-
static int devfs_statfs (struct super_block *sb, struct statfs *buf)
{
buf->f_type = DEVFS_SUPER_MAGIC;
@@ -2486,7 +2372,6 @@ static struct super_operations devfs_sops =
{
read_inode: devfs_read_inode,
write_inode: devfs_write_inode,
- put_super: devfs_put_super,
statfs: devfs_statfs,
};
@@ -2501,21 +2386,22 @@ static struct super_operations devfs_sops =
*/
static struct inode *get_vfs_inode (struct super_block *sb,
- struct devfs_inode *di,
+ struct devfs_entry *de,
struct dentry *dentry)
{
struct inode *inode;
- if (di->dentry != NULL)
+ if (de->inode.dentry != NULL)
{
- printk ("%s: get_vfs_inode(%u): old di->dentry: %p \"%s\" new dentry: %p \"%s\"\n",
- DEVFS_NAME, di->ino, di->dentry, di->dentry->d_name.name,
+ printk ("%s: get_vfs_inode(%u): old de->inode.dentry: %p \"%s\" new dentry: %p \"%s\"\n",
+ DEVFS_NAME, de->inode.ino,
+ de->inode.dentry, de->inode.dentry->d_name.name,
dentry, dentry->d_name.name);
- printk (" old inode: %p\n", di->dentry->d_inode);
+ printk (" old inode: %p\n", de->inode.dentry->d_inode);
return NULL;
}
- if ( ( inode = iget (sb, di->ino) ) == NULL ) return NULL;
- di->dentry = dentry;
+ if ( ( inode = iget (sb, de->inode.ino) ) == NULL ) return NULL;
+ de->inode.dentry = dentry;
return inode;
} /* End Function get_vfs_inode */
@@ -2533,7 +2419,6 @@ 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_inode *di;
struct devfs_entry *parent, *de;
struct inode *inode = file->f_dentry->d_inode;
@@ -2548,8 +2433,7 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
return -ENOTDIR;
}
fs_info = inode->i_sb->u.generic_sbp;
- di = get_devfs_inode_from_vfs_inode (file->f_dentry->d_inode);
- parent = di->de;
+ 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)
@@ -2579,38 +2463,13 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
count = file->f_pos - 2;
for (de = parent->u.dir.first; (de != NULL) && (count > 0);
de = de->next)
- {
- if ( IS_HIDDEN (de) ) continue;
- if (!fs_info->require_explicit)
- {
- --count;
- continue;
- }
- /* Must search for an inode for this FS */
- for (di = de->first_inode; di != NULL; di = di->next)
- {
- if (fs_info == di->fs_info) break;
- }
- if (di != NULL) --count;
- }
+ if ( !IS_HIDDEN (de) ) --count;
/* Now add all remaining entries */
for (; de != NULL; de = de->next)
{
if ( IS_HIDDEN (de) ) continue;
- /* Must search for an inode for this FS */
- for (di = de->first_inode; di != NULL; di = di->next)
- {
- if (fs_info == di->fs_info) break;
- }
- if (di == NULL)
- {
- if (fs_info->require_explicit) continue;
- /* Have to create the inode right now to get the inum */
- di = create_devfs_inode (de, fs_info);
- if (di == NULL) return -ENOMEM;
- }
err = (*filldir) (dirent, de->name, de->namelen,
- file->f_pos, di->ino);
+ file->f_pos, de->inode.ino);
if (err == -EINVAL) break;
if (err < 0) return err;
file->f_pos++;
@@ -2625,16 +2484,15 @@ static int devfs_open (struct inode *inode, struct file *file)
{
int err;
struct fcb_type *df;
- struct devfs_inode *di;
- struct dentry *dentry = file->f_dentry;
+ struct devfs_entry *de;
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
- di = get_devfs_inode_from_vfs_inode (inode);
- if (di == NULL) return -ENODEV;
- if ( S_ISDIR (di->de->mode) ) return 0;
- df = &di->de->u.fcb;
- if (!di->de->registered) return -ENODEV;
- file->private_data = di->de->info;
+ de = get_devfs_entry_from_vfs_inode (inode);
+ if (de == NULL) return -ENODEV;
+ if ( S_ISDIR (de->mode) ) return 0;
+ df = &de->u.fcb;
+ if (!de->registered) return -ENODEV;
+ file->private_data = de->info;
if ( S_ISBLK (inode->i_mode) )
{
file->f_op = &def_blk_fops;
@@ -2651,21 +2509,20 @@ static int devfs_open (struct inode *inode, struct file *file)
}
if (err < 0) return err;
/* Open was successful */
- df->open = TRUE;
- if (dentry->d_count != 1) return 0; /* No fancy operations */
- /* This is the first open */
+ if (df->open) return 0;
+ df->open = TRUE; /* This is the first open */
if (df->auto_owner)
{
/* Change the ownership/protection */
- di->mode = (di->mode & ~S_IALLUGO) | (di->de->mode & S_IRWXUGO);
- di->uid = current->euid;
- di->gid = current->egid;
- inode->i_mode = di->mode;
- inode->i_uid = di->uid;
- inode->i_gid = di->gid;
+ de->inode.mode = (de->inode.mode & ~S_IALLUGO) |(de->mode & S_IRWXUGO);
+ de->inode.uid = current->euid;
+ de->inode.gid = current->egid;
+ inode->i_mode = de->inode.mode;
+ inode->i_uid = de->inode.uid;
+ inode->i_gid = de->inode.gid;
}
if (df->aopen_notify)
- devfsd_notify_one (di->de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode,
+ devfsd_notify_one (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode,
current->euid, current->egid, fs_info);
return 0;
} /* End Function devfs_open */
@@ -2705,21 +2562,17 @@ static void devfs_d_release (struct dentry *dentry)
static void devfs_d_iput (struct dentry *dentry, struct inode *inode)
{
- struct devfs_inode *di;
+ struct devfs_entry *de;
- di = get_devfs_inode_from_vfs_inode (inode);
+ 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 di: %p di->dentry: %p\n",
- DEVFS_NAME, dentry, inode, di, di->dentry);
+ printk ("%s: d_iput(): dentry: %p inode: %p de: %p de->dentry: %p\n",
+ DEVFS_NAME, dentry, inode, de, de->inode.dentry);
#endif
- if (di->dentry == dentry)
+ if (de->inode.dentry == dentry)
{
- di->dentry = NULL;
-#ifdef CONFIG_DEVFS_TUNNEL
- dput (di->covered);
- di->covered = NULL;
-#endif
+ de->inode.dentry = NULL;
}
iput (inode);
} /* End Function devfs_d_iput */
@@ -2751,7 +2604,7 @@ static struct dentry_operations devfs_wait_dops =
static int devfs_d_delete (struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
- struct devfs_inode *di;
+ struct devfs_entry *de;
struct fs_info *fs_info;
if (dentry->d_op == &devfs_wait_dops) dentry->d_op = &devfs_dops;
@@ -2766,29 +2619,28 @@ static int devfs_d_delete (struct dentry *dentry)
return 1;
}
fs_info = inode->i_sb->u.generic_sbp;
- di = get_devfs_inode_from_vfs_inode (inode);
+ 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_inode: %p\n",
- DEVFS_NAME, dentry, inode, di);
+ printk ("%s: d_delete(): dentry: %p inode: %p devfs_entry: %p\n",
+ DEVFS_NAME, dentry, inode, de);
#endif
- if (di == NULL) return 0;
- if (di->de == NULL) return 0;
- if ( !S_ISCHR (di->mode) && !S_ISBLK (di->mode) && !S_ISREG (di->mode) )
+ if (de == NULL) return 0;
+ if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
return 0;
- if (!di->de->u.fcb.open) return 0;
- di->de->u.fcb.open = FALSE;
- if (di->de->u.fcb.aopen_notify)
- devfsd_notify_one (di->de, DEVFSD_NOTIFY_CLOSE, inode->i_mode,
+ if (!de->u.fcb.open) return 0;
+ de->u.fcb.open = FALSE;
+ if (de->u.fcb.aopen_notify)
+ devfsd_notify_one (de, DEVFSD_NOTIFY_CLOSE, inode->i_mode,
current->euid, current->egid, fs_info);
- if (!di->de->u.fcb.auto_owner) return 0;
+ if (!de->u.fcb.auto_owner) return 0;
/* Change the ownership/protection back */
- di->mode = (di->mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO;
- di->uid = di->de->u.fcb.default_uid;
- di->gid = di->de->u.fcb.default_gid;
- inode->i_mode = di->mode;
- inode->i_uid = di->uid;
- inode->i_gid = di->gid;
+ de->inode.mode = (de->inode.mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO;
+ de->inode.uid = de->u.fcb.default_uid;
+ de->inode.gid = de->u.fcb.default_gid;
+ inode->i_mode = de->inode.mode;
+ inode->i_uid = de->inode.uid;
+ inode->i_gid = de->inode.gid;
return 0;
} /* End Function devfs_d_delete */
@@ -2802,7 +2654,6 @@ static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
{
if ( !dentry->d_inode && is_devfsd_or_child (fs_info) )
{
- struct devfs_inode *di = NULL;
struct inode *inode;
#ifdef CONFIG_DEVFS_DEBUG
@@ -2816,36 +2667,27 @@ static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
printk ("%s: d_revalidate(): dentry: %p name: \"%s\" by: \"%s\"\n",
DEVFS_NAME, dentry, txt, current->comm);
#endif
- if (de)
- {
- /* Search for an inode for this FS */
- for (di = de->first_inode; di != NULL; di = di->next)
- if (di->fs_info == fs_info) break;
- }
if (de == NULL)
{
devfs_handle_t parent;
- struct devfs_inode *pi;
- pi = get_devfs_inode_from_vfs_inode (dir);
- parent = pi->de;
+ parent = get_devfs_entry_from_vfs_inode (dir);
de = search_for_entry_in_dir (parent, dentry->d_name.name,
dentry->d_name.len, FALSE);
}
if (de == NULL) return 1;
/* Create an inode, now that the driver information is available
*/
- if (di == NULL) di = create_devfs_inode (de, fs_info);
- else if (de->no_persistence) update_devfs_inode_from_entry (di);
- else if (di->ctime == 0) update_devfs_inode_from_entry (di);
- else di->mode = (de->mode & ~S_IALLUGO) | (di->mode & S_IALLUGO);
- if (di == NULL) return 1;
- if ( ( inode = get_vfs_inode (dir->i_sb, di, dentry) ) == NULL )
+ if (de->no_persistence) update_devfs_inode_from_entry (de);
+ else if (de->inode.ctime == 0) update_devfs_inode_from_entry (de);
+ else de->inode.mode =
+ (de->mode & ~S_IALLUGO) | (de->inode.mode & S_IALLUGO);
+ if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
return 1;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_LOOKUP)
- printk ("%s: d_revalidate(): new VFS inode(%u): %p devfs_inode: %p\n",
- DEVFS_NAME, di->ino, inode, di);
+ printk ("%s: d_revalidate(): new VFS inode(%u): %p devfs_entry: %p\n",
+ DEVFS_NAME, de->inode.ino, inode, de);
#endif
d_instantiate (dentry, inode);
return 1;
@@ -2861,8 +2703,6 @@ static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
{
struct fs_info *fs_info;
- struct devfs_inode *di = NULL;
- struct devfs_inode *pi;
struct devfs_entry *parent, *de;
struct inode *inode;
char txt[STRING_LENGTH];
@@ -2887,32 +2727,13 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
#endif
fs_info = dir->i_sb->u.generic_sbp;
/* First try to get the devfs entry for this directory */
- pi = get_devfs_inode_from_vfs_inode (dir);
- if (pi == NULL) return ERR_PTR (-EINVAL);
- parent = pi->de;
+ parent = get_devfs_entry_from_vfs_inode (dir);
+ if (parent == NULL) return ERR_PTR (-EINVAL);
if (!parent->registered) return ERR_PTR (-ENOENT);
/* Try to reclaim an existing devfs entry */
de = search_for_entry_in_dir (parent,
dentry->d_name.name, dentry->d_name.len,
FALSE);
- if (de)
- {
- /* Search for an inode for this FS */
- for (di = de->first_inode; di != NULL; di = di->next)
- if (di->fs_info == fs_info) break;
- }
- if (fs_info->require_explicit)
- {
- if (di == NULL)
- {
- /* Make the dentry negative so a subsequent operation can deal
- with it (for the benefit of mknod()). Leaving the dentry
- unhashed will cause <lock_parent> to fail which in turns causes
- <do_mknod> to fail */
- d_add (dentry, NULL);
- return NULL;
- }
- }
if ( ( (de == NULL) || !de->registered ) &&
(parent->u.dir.num_removable > 0) &&
get_removable_partition (parent, dentry->d_name.name,
@@ -2961,17 +2782,16 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
d_add (dentry, NULL); /* Open the floodgates */
}
/* Create an inode, now that the driver information is available */
- if (di == NULL) di = create_devfs_inode (de, fs_info);
- else if (de->no_persistence) update_devfs_inode_from_entry (di);
- else if (di->ctime == 0) update_devfs_inode_from_entry (di);
- else di->mode = (de->mode & ~S_IALLUGO) | (di->mode & S_IALLUGO);
- if (di == NULL) return ERR_PTR (-ENOMEM);
- if ( ( inode = get_vfs_inode (dir->i_sb, di, dentry) ) == NULL )
+ if (de->no_persistence) update_devfs_inode_from_entry (de);
+ else if (de->inode.ctime == 0) update_devfs_inode_from_entry (de);
+ else de->inode.mode =
+ (de->mode & ~S_IALLUGO) | (de->inode.mode & S_IALLUGO);
+ if ( ( inode = get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
return ERR_PTR (-ENOMEM);
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_LOOKUP)
- printk ("%s: lookup(): new VFS inode(%u): %p devfs_inode: %p\n",
- DEVFS_NAME, di->ino, inode, di);
+ printk ("%s: lookup(): new VFS inode(%u): %p devfs_entry: %p\n",
+ DEVFS_NAME, de->inode.ino, inode, de);
#endif
d_instantiate (dentry, inode);
/* Unlock directory semaphore, which will release any waiters. They will
@@ -2998,7 +2818,7 @@ static int devfs_link (struct dentry *old_dentry, struct inode *dir,
static int devfs_unlink (struct inode *dir, struct dentry *dentry)
{
- struct devfs_inode *di;
+ struct devfs_entry *de;
#ifdef CONFIG_DEVFS_DEBUG
char txt[STRING_LENGTH];
@@ -3014,12 +2834,12 @@ static int devfs_unlink (struct inode *dir, struct dentry *dentry)
if ( !dir || !S_ISDIR (dir->i_mode) ) return -ENOTDIR;
if (!dentry || !dentry->d_inode) return -ENOENT;
- di = get_devfs_inode_from_vfs_inode (dentry->d_inode);
- if (di == NULL) return -ENOENT;
- if (!di->de->registered) return -ENOENT;
- di->de->registered = FALSE;
- di->de->hide = TRUE;
- free_dentries (di->de);
+ de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
+ if (de == NULL) return -ENOENT;
+ if (!de->registered) return -ENOENT;
+ de->registered = FALSE;
+ de->hide = TRUE;
+ free_dentries (de);
return 0;
} /* End Function devfs_unlink */
@@ -3028,17 +2848,14 @@ static int devfs_symlink (struct inode *dir, struct dentry *dentry,
{
int err;
struct fs_info *fs_info;
- struct devfs_inode *pi;
- struct devfs_inode *di = NULL;
struct devfs_entry *parent, *de;
struct inode *inode;
if ( !dir || !S_ISDIR (dir->i_mode) ) return -ENOTDIR;
fs_info = dir->i_sb->u.generic_sbp;
/* First try to get the devfs entry for this directory */
- pi = get_devfs_inode_from_vfs_inode (dir);
- if (pi == NULL) return -EINVAL;
- parent = pi->de;
+ parent = get_devfs_entry_from_vfs_inode (dir);
+ if (parent == NULL) return -EINVAL;
if (!parent->registered) return -ENOENT;
err = devfs_mk_symlink (parent, dentry->d_name.name, dentry->d_name.len,
DEVFS_FL_NONE, symname, 0, &de, NULL);
@@ -3048,27 +2865,20 @@ static int devfs_symlink (struct inode *dir, struct dentry *dentry,
DEVFS_NAME, err);
#endif
if (err < 0) return err;
- /* Search for an inode for this FS */
- for (di = de->first_inode; di != NULL; di = di->next)
- {
- if (di->fs_info == fs_info) break;
- }
- if (di == NULL) di = create_devfs_inode (de, fs_info);
- if (di == NULL) return -ENOMEM;
- di->mode = de->mode;
- di->atime = CURRENT_TIME;
- di->mtime = CURRENT_TIME;
- di->ctime = CURRENT_TIME;
- if ( ( inode = get_vfs_inode (dir->i_sb, di, dentry) ) == NULL )
+ de->inode.mode = de->mode;
+ 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 )
return -ENOMEM;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_DISABLED)
printk ("%s: symlink(): new VFS inode(%u): %p dentry: %p\n",
- DEVFS_NAME, di->ino, inode, dentry);
+ DEVFS_NAME, de->inode.ino, inode, dentry);
#endif
de->hide = FALSE;
d_instantiate (dentry, inode);
- devfsd_notify_one (di->de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
+ devfsd_notify_one (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info);
return 0;
} /* End Function devfs_symlink */
@@ -3077,8 +2887,6 @@ static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
{
int is_new;
struct fs_info *fs_info;
- struct devfs_inode *di = NULL;
- struct devfs_inode *pi;
struct devfs_entry *parent, *de;
struct inode *inode;
@@ -3087,9 +2895,8 @@ static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
fs_info = dir->i_sb->u.generic_sbp;
/* We are allowed to create the directory */
/* First try to get the devfs entry for this directory */
- pi = get_devfs_inode_from_vfs_inode (dir);
- if (pi == NULL) return -EINVAL;
- parent = pi->de;
+ parent = get_devfs_entry_from_vfs_inode (dir);
+ if (parent == NULL) return -EINVAL;
if (!parent->registered) return -ENOENT;
/* Try to reclaim an existing devfs entry, create if there isn't one */
de = search_for_entry (parent, dentry->d_name.name, dentry->d_name.len,
@@ -3110,28 +2917,21 @@ static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
}
de->mode = mode;
de->u.dir.num_removable = 0;
- /* Search for an inode for this FS */
- for (di = de->first_inode; di != NULL; di = di->next)
- {
- if (di->fs_info == fs_info) break;
- }
- if (di == NULL) di = create_devfs_inode (de, fs_info);
- if (di == NULL) return -ENOMEM;
- di->mode = mode;
- di->uid = current->euid;
- di->gid = current->egid;
- di->atime = CURRENT_TIME;
- di->mtime = CURRENT_TIME;
- di->ctime = CURRENT_TIME;
- if ( ( inode = get_vfs_inode (dir->i_sb, di, dentry) ) == NULL )
+ de->inode.mode = mode;
+ 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 )
return -ENOMEM;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_DISABLED)
printk ("%s: mkdir(): new VFS inode(%u): %p dentry: %p\n",
- DEVFS_NAME, di->ino, inode, dentry);
+ DEVFS_NAME, de->inode.ino, inode, dentry);
#endif
d_instantiate (dentry, inode);
- devfsd_notify_one (di->de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
+ devfsd_notify_one (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info);
return 0;
} /* End Function devfs_mkdir */
@@ -3140,7 +2940,6 @@ static int devfs_rmdir (struct inode *dir, struct dentry *dentry)
{
int has_children = FALSE;
struct fs_info *fs_info;
- struct devfs_inode *di = NULL;
struct devfs_entry *de, *child;
struct inode *inode = dentry->d_inode;
@@ -3148,9 +2947,8 @@ static int devfs_rmdir (struct inode *dir, struct dentry *dentry)
if (dir->i_sb->u.generic_sbp != inode->i_sb->u.generic_sbp) return -EINVAL;
if (inode == dir) return -EPERM;
fs_info = dir->i_sb->u.generic_sbp;
- di = get_devfs_inode_from_vfs_inode (inode);
- if (di == NULL) return -ENOENT;
- de = di->de;
+ de = get_devfs_entry_from_vfs_inode (inode);
+ if (de == NULL) return -ENOENT;
if (!de->registered) return -ENOENT;
if ( !S_ISDIR (de->mode) ) return -ENOTDIR;
for (child = de->u.dir.first; child != NULL; child = child->next)
@@ -3173,8 +2971,6 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
{
int is_new;
struct fs_info *fs_info;
- struct devfs_inode *di = NULL;
- struct devfs_inode *pi;
struct devfs_entry *parent, *de;
struct inode *inode;
@@ -3197,9 +2993,8 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
!S_ISSOCK (mode) ) return -EPERM;
/* We are allowed to create the node */
/* First try to get the devfs entry for this directory */
- pi = get_devfs_inode_from_vfs_inode (dir);
- if (pi == NULL) return -EINVAL;
- parent = pi->de;
+ parent = get_devfs_entry_from_vfs_inode (dir);
+ if (parent == NULL) return -EINVAL;
if (!parent->registered) return -ENOENT;
/* Try to reclaim an existing devfs entry, create if there isn't one */
de = search_for_entry (parent, dentry->d_name.name, dentry->d_name.len,
@@ -3230,44 +3025,37 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
de->registered = TRUE;
de->show_unreg = FALSE;
de->hide = FALSE;
- /* Search for an inode for this FS */
- for (di = de->first_inode; di != NULL; di = di->next)
- {
- if (di->fs_info == fs_info) break;
- }
- if (di == NULL) di = create_devfs_inode (de, fs_info);
- if (di == NULL) return -ENOMEM;
- di->mode = mode;
- di->uid = current->euid;
- di->gid = current->egid;
- di->atime = CURRENT_TIME;
- di->mtime = CURRENT_TIME;
- di->ctime = CURRENT_TIME;
- if ( ( inode = get_vfs_inode (dir->i_sb, di, dentry) ) == NULL )
+ de->inode.mode = mode;
+ 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 )
return -ENOMEM;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_MKNOD)
printk ("%s: new VFS inode(%u): %p dentry: %p\n",
- DEVFS_NAME, di->ino, inode, dentry);
+ DEVFS_NAME, de->inode.ino, inode, dentry);
#endif
d_instantiate (dentry, inode);
- devfsd_notify_one (di->de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
+ devfsd_notify_one (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)
{
- struct devfs_inode *di = get_devfs_inode_from_vfs_inode (dentry->d_inode);
+ struct devfs_entry *de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
- return vfs_readlink (dentry, buffer, buflen, di->de->u.symlink.linkname);
+ return vfs_readlink (dentry, buffer, buflen, de->u.symlink.linkname);
} /* End Function devfs_readlink */
static int devfs_follow_link (struct dentry *dentry, struct nameidata *nd)
{
- struct devfs_inode *di = get_devfs_inode_from_vfs_inode (dentry->d_inode);
+ struct devfs_entry *de = get_devfs_entry_from_vfs_inode (dentry->d_inode);
- return vfs_follow_link (nd, di->de->u.symlink.linkname);
+ return vfs_follow_link (nd, de->u.symlink.linkname);
} /* End Function devfs_follow_link */
static struct inode_operations devfs_iops =
@@ -3303,47 +3091,22 @@ static struct inode_operations devfs_symlink_iops =
static struct super_block *devfs_read_super (struct super_block *sb,
void *data, int silent)
{
- char *aopt = data;
- struct fs_info *fs_info = NULL;
- struct devfs_inode *di;
struct inode *root_inode = NULL;
if (get_root_entry () == NULL) goto out_no_root;
- if ( ( fs_info = kmalloc (sizeof *fs_info, GFP_KERNEL) ) == NULL )
- return NULL;
- memset (fs_info, 0, sizeof *fs_info);
- 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->prev = last_fs;
- if (first_fs == NULL) first_fs = fs_info;
- else last_fs->next = fs_info;
- last_fs = fs_info;
- fs_info->sb = sb;
- if (aopt)
- {
- if (strcmp (aopt, "explicit") == 0) fs_info->require_explicit = TRUE;
- }
- sb->u.generic_sbp = fs_info;
+ 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->u.generic_sbp = &fs_info;
sb->s_blocksize = 1024;
sb->s_blocksize_bits = 10;
sb->s_magic = DEVFS_SUPER_MAGIC;
sb->s_op = &devfs_sops;
- di = create_devfs_inode (root_entry, fs_info);
- if (di == NULL) goto out_no_root;
- if (di->ino != 1)
- {
- printk ("%s: read_super: root inode number is: %d!\n",
- DEVFS_NAME, di->ino);
- goto out_no_root;
- }
- if ( ( root_inode = get_vfs_inode (sb, di, NULL) ) == NULL )
+ if ( ( root_inode = get_vfs_inode (sb, root_entry, NULL) ) == NULL )
goto out_no_root;
- sb->s_root = D_ALLOC_ROOT (root_inode);
+ sb->s_root = d_alloc_root (root_inode);
if (!sb->s_root) goto out_no_root;
-#ifdef CONFIG_DEVFS_TUNNEL
- di->covered = dget (sb->s_root->d_covered);
-#endif
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_DISABLED)
printk ("%s: read super, made devfs ptr: %p\n",
@@ -3353,13 +3116,12 @@ static struct super_block *devfs_read_super (struct super_block *sb,
out_no_root:
printk ("devfs_read_super: get root inode failed\n");
- delete_fs (fs_info);
if (root_inode) iput (root_inode);
return NULL;
} /* End Function devfs_read_super */
-static DECLARE_FSTYPE (devfs_fs_type, DEVFS_NAME, devfs_read_super, 0);
+static DECLARE_FSTYPE (devfs_fs_type, DEVFS_NAME, devfs_read_super, FS_SINGLE);
/* File operations for devfsd follow */
@@ -3549,25 +3311,27 @@ static int devfsd_close (struct inode *inode, struct file *file)
} /* End Function devfsd_close */
-#ifdef MODULE
-int init_module (void)
-#else
int __init init_devfs_fs (void)
-#endif
{
+ int err;
+
printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n",
DEVFS_NAME, DEVFS_VERSION);
-#if defined(CONFIG_DEVFS_DEBUG) && !defined(MODULE)
+#ifdef CONFIG_DEVFS_DEBUG
devfs_debug = devfs_debug_init;
printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
#endif
-#if !defined(MODULE)
printk ("%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
-#endif
- return register_filesystem (&devfs_fs_type);
-}
+ err = register_filesystem (&devfs_fs_type);
+ if (!err)
+ {
+ struct vfsmount *devfs_mnt = kern_mount (&devfs_fs_type);
+ err = PTR_ERR (devfs_mnt);
+ if ( !IS_ERR (devfs_mnt) ) err = 0;
+ }
+ return err;
+} /* End Function init_devfs_fs */
-#ifndef MODULE
void __init mount_devfs_fs (void)
{
int err;
@@ -3577,39 +3341,3 @@ void __init mount_devfs_fs (void)
if (err == 0) printk ("Mounted devfs on /dev\n");
else printk ("Warning: unable to mount devfs, err: %d\n", err);
} /* End Function mount_devfs_fs */
-#endif
-
-#ifdef MODULE
-static void free_entry (struct devfs_entry *parent)
-{
- struct devfs_entry *de, *next;
-
- if (parent == NULL) return;
- for (de = parent->u.dir.first; de != NULL; de = next)
- {
- next = de->next;
- if (de->first_inode != NULL)
- {
- printk ("%s: free_entry(): unfreed inodes!\n", DEVFS_NAME);
- }
- if ( S_ISDIR (de->mode) )
- {
- /* Recursively free the subdirectories: this is a stack chomper */
- free_entry (de);
- }
- else kfree (de);
- }
- kfree (parent);
-} /* End Function free_entry */
-
-void cleanup_module (void)
-{
- unregister_filesystem (&devfs_fs_type);
- if (first_fs != NULL)
- {
- printk ("%s: cleanup_module(): still mounted mounted filesystems!\n",
- DEVFS_NAME);
- }
- free_entry (root_entry);
-}
-#endif /* MODULE */
diff --git a/fs/devfs/util.c b/fs/devfs/util.c
index fe4746448..6e3f2f782 100644
--- a/fs/devfs/util.c
+++ b/fs/devfs/util.c
@@ -28,6 +28,8 @@
Created <_devfs_convert_name> and supported SCSI and IDE CD-ROMs
20000203 Richard Gooch <rgooch@atnf.csiro.au>
Changed operations pointer type to void *.
+ 20000621 Richard Gooch <rgooch@atnf.csiro.au>
+ Changed interface to <devfs_register_series>.
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -134,8 +136,6 @@ EXPORT_SYMBOL(devfs_register_tape);
* @major: The major number. Not needed for regular files.
* @minor_start: The starting minor number. Not needed for regular files.
* @mode: The default file mode.
- * @uid: The default UID of the file.
- * @guid: The default GID of the file.
* @ops: The &file_operations or &block_device_operations structure.
* This must not be externally deallocated.
* @info: An arbitrary pointer which will be written to the private_data
@@ -147,8 +147,7 @@ EXPORT_SYMBOL(devfs_register_tape);
void devfs_register_series (devfs_handle_t dir, const char *format,
unsigned int num_entries, unsigned int flags,
unsigned int major, unsigned int minor_start,
- umode_t mode, uid_t uid, gid_t gid,
- void *ops, void *info)
+ umode_t mode, void *ops, void *info)
{
unsigned int count;
char devname[128];
@@ -156,8 +155,8 @@ void devfs_register_series (devfs_handle_t dir, const char *format,
for (count = 0; count < num_entries; ++count)
{
sprintf (devname, format, count);
- devfs_register (dir, devname, 0, flags, major, minor_start + count,
- mode, uid, gid, ops, info);
+ devfs_register (dir, devname, flags, major, minor_start + count,
+ mode, ops, info);
}
} /* End Function devfs_register_series */
EXPORT_SYMBOL(devfs_register_series);