Linux Devfs (Device File System) FAQ
Richard Gooch
-7-APR-2002
+21-JUL-2002
Document languages:
make sure the kernel does not mount devfs at boot time
+make sure you have a correct /dev/console entry in your
+root file-system (where your disc-based /dev lives)
+
create the /dev-state directory
SCSI Generic Devices
-All SCSI CD-ROMs are placed under /dev/sg. A similar naming
-scheme is used as for SCSI discs. A SCSI generic device with the
-parameters:c=1,b=2,t=3,u=4 would appear as:
+The generic (aka. raw) interface for all SCSI devices are placed under
+/dev/sg. A similar naming scheme is used as for SCSI discs. A
+SCSI generic device with the parameters:c=1,b=2,t=3,u=4 would appear
+as:
/dev/sg/c1b2t3u4
do that.
+I have extra or incorrect entries in /dev
+
+You may have stale entries in your dev-state area. Check for a
+RESTORE configuration line in your devfsd configuration
+(typically /etc/devfsd.conf). If you have this line, check
+the contents of the specified directory for stale entries. Remove
+any entries which are incorrect, then reboot.
+
+
+I get "Unable to open initial console" messages at boot
+
+This usually happens when you don't have devfs automounted onto
+/dev at boot time, and there is no valid
+/dev/console entry on your root file-system. Create a valid
+/dev/console device node.
+
+
20020514 Richard Gooch <rgooch@atnf.csiro.au>
Minor cleanup of <scan_dir_for_removable>.
v1.17
+ 20020721 Richard Gooch <rgooch@atnf.csiro.au>
+ Switched to ISO C structure field initialisers.
+ 20020722 Richard Gooch <rgooch@atnf.csiro.au>
+ Fixed devfs entry leak in <devfs_readdir> when *readdir fails.
+ v1.18
*/
#include <linux/types.h>
#include <linux/errno.h>
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "1.17 (20020514)"
+#define DEVFS_VERSION "1.18 (20020722)"
#define DEVFS_NAME "devfs"
loff_t *ppos);
static struct file_operations stat_fops =
{
- read: stat_read,
+ .read = stat_read,
};
#endif
/* Devfs daemon file operations */
static struct file_operations devfsd_fops =
{
- read: devfsd_read,
- ioctl: devfsd_ioctl,
- release: devfsd_close,
+ .read = devfsd_read,
+ .ioctl = devfsd_ioctl,
+ .release = devfsd_close,
};
if (fs_info->devfsd_task == NULL) return (TRUE);
if (devfsd_queue_empty (fs_info) && fs_info->devfsd_sleeping) return TRUE;
if ( is_devfsd_or_child (fs_info) ) return (FALSE);
+ set_current_state (TASK_UNINTERRUPTIBLE);
add_wait_queue (&fs_info->revalidate_wait_queue, &wait);
- current->state = TASK_UNINTERRUPTIBLE;
if (!devfsd_queue_empty (fs_info) || !fs_info->devfsd_sleeping)
if (fs_info->devfsd_task) schedule ();
remove_wait_queue (&fs_info->revalidate_wait_queue, &wait);
- current->state = TASK_RUNNING;
+ __set_current_state (TASK_RUNNING);
return (TRUE);
} /* End Function wait_for_devfsd_finished */
static struct super_operations devfs_sops =
{
- drop_inode: generic_delete_inode,
- clear_inode: devfs_clear_inode,
- statfs: simple_statfs,
+ .drop_inode = generic_delete_inode,
+ .clear_inode = devfs_clear_inode,
+ .statfs = simple_statfs,
};
{
err = (*filldir) (dirent, de->name, de->namelen,
file->f_pos, de->inode.ino, de->mode >> 12);
- if (err >= 0)
+ if (err < 0) devfs_put (de);
+ else
{
file->f_pos++;
++stored;
}
}
+ if (err == -EINVAL) break;
+ if (err < 0) return err;
read_lock (&parent->u.dir.lock);
next = devfs_get (de->next);
read_unlock (&parent->u.dir.lock);
devfs_put (de);
de = next;
- if (err == -EINVAL) break;
- if (err < 0) return err;
}
break;
}
static struct file_operations devfs_fops =
{
- open: devfs_open,
+ .open = devfs_open,
};
static struct file_operations devfs_dir_fops =
{
- read: generic_read_dir,
- readdir: devfs_readdir,
- open: devfs_open,
+ .read = generic_read_dir,
+ .readdir = devfs_readdir,
+ .open = devfs_open,
};
static struct dentry_operations devfs_dops =
{
- d_delete: devfs_d_delete,
- d_release: devfs_d_release,
- d_iput: devfs_d_iput,
+ .d_delete = devfs_d_delete,
+ .d_release = devfs_d_release,
+ .d_iput = devfs_d_iput,
};
static int devfs_d_revalidate_wait (struct dentry *dentry, int flags);
static struct dentry_operations devfs_wait_dops =
{
- d_delete: devfs_d_delete,
- d_release: devfs_d_release,
- d_iput: devfs_d_iput,
- d_revalidate: devfs_d_revalidate_wait,
+ .d_delete = devfs_d_delete,
+ .d_release = devfs_d_release,
+ .d_iput = devfs_d_iput,
+ .d_revalidate = devfs_d_revalidate_wait,
};
/**
read_lock (&parent->u.dir.lock);
if (dentry->d_fsdata)
{
+ set_current_state (TASK_UNINTERRUPTIBLE);
add_wait_queue (&lookup_info->wait_queue, &wait);
- current->state = TASK_UNINTERRUPTIBLE;
read_unlock (&parent->u.dir.lock);
schedule ();
}
static struct inode_operations devfs_iops =
{
- setattr: devfs_notify_change,
+ .setattr = devfs_notify_change,
};
static struct inode_operations devfs_dir_iops =
{
- lookup: devfs_lookup,
- unlink: devfs_unlink,
- symlink: devfs_symlink,
- mkdir: devfs_mkdir,
- rmdir: devfs_rmdir,
- mknod: devfs_mknod,
- setattr: devfs_notify_change,
+ .lookup = devfs_lookup,
+ .unlink = devfs_unlink,
+ .symlink = devfs_symlink,
+ .mkdir = devfs_mkdir,
+ .rmdir = devfs_rmdir,
+ .mknod = devfs_mknod,
+ .setattr = devfs_notify_change,
};
static struct inode_operations devfs_symlink_iops =
{
- readlink: devfs_readlink,
- follow_link: devfs_follow_link,
- setattr: devfs_notify_change,
+ .readlink = devfs_readlink,
+ .follow_link = devfs_follow_link,
+ .setattr = devfs_notify_change,
};
static int devfs_fill_super (struct super_block *sb, void *data, int silent)
static struct file_system_type devfs_fs_type =
{
- name: DEVFS_NAME,
- get_sb: devfs_get_sb,
- kill_sb: kill_anon_super,
+ .name = DEVFS_NAME,
+ .get_sb = devfs_get_sb,
+ .kill_sb = kill_anon_super,
};
/* File operations for devfsd follow */
info->major = 0;
info->minor = 0;
/* Block for a new entry */
+ set_current_state (TASK_INTERRUPTIBLE);
add_wait_queue (&fs_info->devfsd_wait_queue, &wait);
- current->state = TASK_INTERRUPTIBLE;
while ( devfsd_queue_empty (fs_info) )
{
fs_info->devfsd_sleeping = TRUE;
if ( signal_pending (current) )
{
remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
- current->state = TASK_RUNNING;
+ __set_current_state (TASK_RUNNING);
return -EINTR;
}
set_current_state (TASK_INTERRUPTIBLE);
}
remove_wait_queue (&fs_info->devfsd_wait_queue, &wait);
- current->state = TASK_RUNNING;
+ __set_current_state (TASK_RUNNING);
/* Now play with the data */
ival = atomic_read (&fs_info->devfsd_overrun_count);
info->overrun_count = ival;