Commit 4d40f872 authored by Richard Gooch's avatar Richard Gooch

[PATCH] devfs patch for 2.5.8-pre2

- Documentation updates
- BKL removal (devfs doesn't need the BKL)
- Changed <devfs_rmdir> to allow later additions if not yet empty
- Added calls to <devfs_register_partitions> in drivers/block/blkpc.c
  <add_partition> and <del_partition>
- Bug fixes in unique number and devnum allocators.
parent d720d94f
...@@ -1885,3 +1885,23 @@ Changes for patch v208 ...@@ -1885,3 +1885,23 @@ Changes for patch v208
- Cleaned up declaration of <stat_read> - Cleaned up declaration of <stat_read>
- Updated README from master HTML file - Updated README from master HTML file
===============================================================================
Changes for patch v209
- Updated README from master HTML file
- Removed silently introduced calls to lock_kernel() and
unlock_kernel() due to recent VFS locking changes. BKL isn't
required in devfs
- Changed <devfs_rmdir> to allow later additions if not yet empty
- Added calls to <devfs_register_partitions> in drivers/block/blkpc.c
<add_partition> and <del_partition>
- Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
bitfield
- Fixed bitfield data type for <devfs_*alloc_devnum>
- Made major bitfield type and initialiser 64 bit safe
...@@ -3,7 +3,7 @@ Devfs (Device File System) FAQ ...@@ -3,7 +3,7 @@ Devfs (Device File System) FAQ
Linux Devfs (Device File System) FAQ Linux Devfs (Device File System) FAQ
Richard Gooch Richard Gooch
24-JAN-2002 4-APR-2002
Document languages: Document languages:
...@@ -803,12 +803,19 @@ devfsd /dev ...@@ -803,12 +803,19 @@ devfsd /dev
add the following lines to your /etc/devfsd.conf file: add the following lines to your /etc/devfsd.conf file:
REGISTER ^pt[sy]/.* IGNORE REGISTER ^pt[sy] IGNORE
CHANGE ^pt[sy]/.* IGNORE CREATE ^pt[sy] IGNORE
CHANGE ^pt[sy] IGNORE
DELETE ^pt[sy] IGNORE
REGISTER .* COPY /dev-state/$devname $devpath REGISTER .* COPY /dev-state/$devname $devpath
CHANGE .* COPY $devpath /dev-state/$devname
CREATE .* COPY $devpath /dev-state/$devname CREATE .* COPY $devpath /dev-state/$devname
CHANGE .* COPY $devpath /dev-state/$devname
DELETE .* CFUNCTION GLOBAL unlink /dev-state/$devname
RESTORE /dev-state
Note that the sample devfsd.conf file contains these lines,
as well as other sample configurations you may find useful. See the
devfsd distribution
reboot. reboot.
...@@ -872,7 +879,8 @@ You can then slowly migrate your system to using the new device names ...@@ -872,7 +879,8 @@ You can then slowly migrate your system to using the new device names
(for example, by starting with /etc/fstab), and then limiting the (for example, by starting with /etc/fstab), and then limiting the
compatibility entries that devfsd creates. compatibility entries that devfsd creates.
MAKE SURE YOU INSTALL DEVFSD BEFORE YOU BOOT A DEVFS-ENABLED KERNEL! IF YOU CONFIGURE TO MOUNT DEVFS AT BOOT, MAKE SURE YOU INSTALL DEVFSD
BEFORE YOU BOOT A DEVFS-ENABLED KERNEL!
Now that devfs has gone into the 2.3.46 kernel, I'm getting a lot of Now that devfs has gone into the 2.3.46 kernel, I'm getting a lot of
reports back. Many of these are because people are trying to run reports back. Many of these are because people are trying to run
...@@ -1565,6 +1573,24 @@ character device, named pipe, etc.) may change without notice. Only ...@@ -1565,6 +1573,24 @@ character device, named pipe, etc.) may change without notice. Only
the existence of the entry should be relied upon. the existence of the entry should be relied upon.
When I start devfsd, I see the error:
Error opening file: ".devfsd" No such file or directory?
This means that devfs is not mounted. Make sure you have devfs mounted.
How do I mount devfs?
First make sure you have devfs compiled into your kernel (see
above). Then you will either need to:
set CONFIG_DEVFS_MOUNT=y in your kernel config
pass devfs=mount to your boot loader
mount devfs manually in your boot scripts with:
mount -t none devfs /dev
...@@ -1760,6 +1786,15 @@ steps below: ...@@ -1760,6 +1786,15 @@ steps below:
make sure you have enabled debugging output when configuring your
kernel. You will need to set (at least) the following config options:
CONFIG_DEVFS_DEBUG=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SLAB=y
please make sure you have the latest devfs patches applied. The please make sure you have the latest devfs patches applied. The
latest kernel version might not have the latest devfs patches applied latest kernel version might not have the latest devfs patches applied
yet (Linus is very busy) yet (Linus is very busy)
...@@ -1768,7 +1803,10 @@ yet (Linus is very busy) ...@@ -1768,7 +1803,10 @@ yet (Linus is very busy)
save a copy of your complete kernel logs (preferably by save a copy of your complete kernel logs (preferably by
using the dmesg programme) for later inclusion in your bug using the dmesg programme) for later inclusion in your bug
report. You may need to use the -s switch to increase the report. You may need to use the -s switch to increase the
internal buffer size so you can capture all the boot messages internal buffer size so you can capture all the boot messages.
Don't edit or trim the dmesg output
try booting with devfs=dall passed to the kernel boot try booting with devfs=dall passed to the kernel boot
...@@ -1925,7 +1963,7 @@ http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html ...@@ -1925,7 +1963,7 @@ http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html
A Korean translation by viatoris@nownuri.net is available at A Korean translation by viatoris@nownuri.net is available at
http://viatoris.new21.org/devfs/devfs.html http://your.destiny.pe.kr/devfs/devfs.html
......
...@@ -113,6 +113,7 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p) ...@@ -113,6 +113,7 @@ int add_partition(struct block_device *bdev, struct blkpg_partition *p)
g->part[minor].nr_sects = plength; g->part[minor].nr_sects = plength;
if (g->sizes) if (g->sizes)
g->sizes[minor] = (plength >> (BLOCK_SIZE_BITS - 9)); g->sizes[minor] = (plength >> (BLOCK_SIZE_BITS - 9));
devfs_register_partitions (g, first_minor, 0);
return 0; return 0;
} }
...@@ -172,6 +173,7 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p) ...@@ -172,6 +173,7 @@ int del_partition(struct block_device *bdev, struct blkpg_partition *p)
g->part[minor].nr_sects = 0; g->part[minor].nr_sects = 0;
if (g->sizes) if (g->sizes)
g->sizes[minor] = 0; g->sizes[minor] = 0;
devfs_register_partitions (g, first_minor, 0);
bd_release(bdevp); bd_release(bdevp);
bdput(bdevp); bdput(bdevp);
......
...@@ -612,6 +612,14 @@ ...@@ -612,6 +612,14 @@
Added KERN_* to remaining messages. Added KERN_* to remaining messages.
Cleaned up declaration of <stat_read>. Cleaned up declaration of <stat_read>.
v1.11 v1.11
20020219 Richard Gooch <rgooch@atnf.csiro.au>
Changed <devfs_rmdir> to allow later additions if not yet empty.
v1.12
20020406 Richard Gooch <rgooch@atnf.csiro.au>
Removed silently introduced calls to lock_kernel() and
unlock_kernel() due to recent VFS locking changes. BKL isn't
required in devfs.
v1.13
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
...@@ -644,7 +652,7 @@ ...@@ -644,7 +652,7 @@
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#define DEVFS_VERSION "1.11 (20020129)" #define DEVFS_VERSION "1.13 (20020406)"
#define DEVFS_NAME "devfs" #define DEVFS_NAME "devfs"
...@@ -2667,7 +2675,7 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir) ...@@ -2667,7 +2675,7 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
case 0: case 0:
scan_dir_for_removable (parent); scan_dir_for_removable (parent);
err = (*filldir) (dirent, "..", 2, file->f_pos, err = (*filldir) (dirent, "..", 2, file->f_pos,
parent_ino(file->f_dentry), DT_DIR); parent_ino (file->f_dentry), DT_DIR);
if (err == -EINVAL) break; if (err == -EINVAL) break;
if (err < 0) return err; if (err < 0) return err;
file->f_pos++; file->f_pos++;
...@@ -2933,14 +2941,10 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) ...@@ -2933,14 +2941,10 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
up on any error */ up on any error */
dentry->d_op = &devfs_dops; dentry->d_op = &devfs_dops;
/* First try to get the devfs entry for this directory */ /* First try to get the devfs entry for this directory */
lock_kernel();
parent = get_devfs_entry_from_vfs_inode (dir); parent = get_devfs_entry_from_vfs_inode (dir);
DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n", DPRINTK (DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n",
dentry->d_name.name, dentry, parent, current->comm); dentry->d_name.name, dentry, parent, current->comm);
if (parent == NULL) { if (parent == NULL) return ERR_PTR (-ENOENT);
unlock_kernel();
return ERR_PTR (-ENOENT);
}
read_lock (&parent->u.dir.lock); read_lock (&parent->u.dir.lock);
de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len); de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len);
read_unlock (&parent->u.dir.lock); read_unlock (&parent->u.dir.lock);
...@@ -2965,7 +2969,6 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) ...@@ -2965,7 +2969,6 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
if (try_modload (parent, fs_info, if (try_modload (parent, fs_info,
dentry->d_name.name, dentry->d_name.len, &tmp) < 0) dentry->d_name.name, dentry->d_name.len, &tmp) < 0)
{ /* Lookup event was not queued to devfsd */ { /* Lookup event was not queued to devfsd */
unlock_kernel();
d_add (dentry, NULL); d_add (dentry, NULL);
return NULL; return NULL;
} }
...@@ -3008,7 +3011,6 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry) ...@@ -3008,7 +3011,6 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
wake_up (&lookup_info.wait_queue); wake_up (&lookup_info.wait_queue);
write_unlock (&parent->u.dir.lock); write_unlock (&parent->u.dir.lock);
devfs_put (de); devfs_put (de);
unlock_kernel();
return retval; return retval;
} /* End Function devfs_lookup */ } /* End Function devfs_lookup */
...@@ -3019,30 +3021,19 @@ static int devfs_unlink (struct inode *dir, struct dentry *dentry) ...@@ -3019,30 +3021,19 @@ static int devfs_unlink (struct inode *dir, struct dentry *dentry)
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct fs_info *fs_info = dir->i_sb->u.generic_sbp; struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
lock_kernel();
de = get_devfs_entry_from_vfs_inode (inode); de = get_devfs_entry_from_vfs_inode (inode);
DPRINTK (DEBUG_I_UNLINK, "(%s): de: %p\n", dentry->d_name.name, de); DPRINTK (DEBUG_I_UNLINK, "(%s): de: %p\n", dentry->d_name.name, de);
if (de == NULL) { if (de == NULL) return -ENOENT;
unlock_kernel(); if (!de->vfs_deletable) return -EPERM;
return -ENOENT;
}
if (!de->vfs_deletable) {
unlock_kernel();
return -EPERM;
}
write_lock (&de->parent->u.dir.lock); write_lock (&de->parent->u.dir.lock);
unhooked = _devfs_unhook (de); unhooked = _devfs_unhook (de);
write_unlock (&de->parent->u.dir.lock); write_unlock (&de->parent->u.dir.lock);
if (!unhooked) { if (!unhooked) return -ENOENT;
unlock_kernel();
return -ENOENT;
}
if ( !is_devfsd_or_child (fs_info) ) if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode, devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info, 0); inode->i_uid, inode->i_gid, fs_info, 0);
free_dentry (de); free_dentry (de);
devfs_put (de); devfs_put (de);
unlock_kernel();
return 0; return 0;
} /* End Function devfs_unlink */ } /* End Function devfs_unlink */
...@@ -3055,37 +3046,27 @@ static int devfs_symlink (struct inode *dir, struct dentry *dentry, ...@@ -3055,37 +3046,27 @@ static int devfs_symlink (struct inode *dir, struct dentry *dentry,
struct inode *inode; struct inode *inode;
/* First try to get the devfs entry for this directory */ /* First try to get the devfs entry for this directory */
lock_kernel();
parent = get_devfs_entry_from_vfs_inode (dir); parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) { if (parent == NULL) return -ENOENT;
unlock_kernel();
return -ENOENT;
}
err = devfs_do_symlink (parent, dentry->d_name.name, DEVFS_FL_NONE, err = devfs_do_symlink (parent, dentry->d_name.name, DEVFS_FL_NONE,
symname, &de, NULL); symname, &de, NULL);
DPRINTK (DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n", DPRINTK (DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
dentry->d_name.name, err); dentry->d_name.name, err);
if (err < 0) { if (err < 0) return err;
unlock_kernel();
return err;
}
de->vfs_deletable = TRUE; de->vfs_deletable = TRUE;
de->inode.uid = current->euid; de->inode.uid = current->euid;
de->inode.gid = current->egid; de->inode.gid = current->egid;
de->inode.atime = CURRENT_TIME; de->inode.atime = CURRENT_TIME;
de->inode.mtime = CURRENT_TIME; de->inode.mtime = CURRENT_TIME;
de->inode.ctime = CURRENT_TIME; de->inode.ctime = CURRENT_TIME;
if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) { if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
unlock_kernel();
return -ENOMEM; return -ENOMEM;
}
DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n", DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n",
dentry->d_name.name, de->inode.ino, inode, dentry); dentry->d_name.name, de->inode.ino, inode, dentry);
d_instantiate (dentry, inode); d_instantiate (dentry, inode);
if ( !is_devfsd_or_child (fs_info) ) if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode, devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info, 0); inode->i_uid, inode->i_gid, fs_info, 0);
unlock_kernel();
return 0; return 0;
} /* End Function devfs_symlink */ } /* End Function devfs_symlink */
...@@ -3097,38 +3078,26 @@ static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode) ...@@ -3097,38 +3078,26 @@ static int devfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
struct inode *inode; struct inode *inode;
mode = (mode & ~S_IFMT) | S_IFDIR; /* VFS doesn't pass S_IFMT part */ mode = (mode & ~S_IFMT) | S_IFDIR; /* VFS doesn't pass S_IFMT part */
lock_kernel();
parent = get_devfs_entry_from_vfs_inode (dir); parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) { if (parent == NULL) return -ENOENT;
unlock_kernel();
return -ENOENT;
}
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode); de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
if (!de) { if (!de) return -ENOMEM;
unlock_kernel();
return -ENOMEM;
}
de->vfs_deletable = TRUE; de->vfs_deletable = TRUE;
if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 ) { if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
unlock_kernel();
return err; return err;
}
de->inode.uid = current->euid; de->inode.uid = current->euid;
de->inode.gid = current->egid; de->inode.gid = current->egid;
de->inode.atime = CURRENT_TIME; de->inode.atime = CURRENT_TIME;
de->inode.mtime = CURRENT_TIME; de->inode.mtime = CURRENT_TIME;
de->inode.ctime = CURRENT_TIME; de->inode.ctime = CURRENT_TIME;
if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) { if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
unlock_kernel();
return -ENOMEM; return -ENOMEM;
}
DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n", DPRINTK (DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n",
dentry->d_name.name, de->inode.ino, inode, dentry); dentry->d_name.name, de->inode.ino, inode, dentry);
d_instantiate (dentry, inode); d_instantiate (dentry, inode);
if ( !is_devfsd_or_child (fs_info) ) if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode, devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info, 0); inode->i_uid, inode->i_gid, fs_info, 0);
unlock_kernel();
return 0; return 0;
} /* End Function devfs_mkdir */ } /* End Function devfs_mkdir */
...@@ -3139,45 +3108,27 @@ static int devfs_rmdir (struct inode *dir, struct dentry *dentry) ...@@ -3139,45 +3108,27 @@ static int devfs_rmdir (struct inode *dir, struct dentry *dentry)
struct fs_info *fs_info = dir->i_sb->u.generic_sbp; struct fs_info *fs_info = dir->i_sb->u.generic_sbp;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
/* WTF??? */
if (dir->i_sb->u.generic_sbp != inode->i_sb->u.generic_sbp) return -EINVAL; if (dir->i_sb->u.generic_sbp != inode->i_sb->u.generic_sbp) return -EINVAL;
lock_kernel();
de = get_devfs_entry_from_vfs_inode (inode); de = get_devfs_entry_from_vfs_inode (inode);
if (de == NULL) { if (de == NULL) return -ENOENT;
unlock_kernel(); if ( !S_ISDIR (de->mode) ) return -ENOTDIR;
return -ENOENT; if (!de->vfs_deletable) return -EPERM;
} /* First ensure the directory is empty and will stay that way */
if ( !S_ISDIR (de->mode) ) {
unlock_kernel();
return -ENOTDIR;
}
if (!de->vfs_deletable) {
unlock_kernel();
return -EPERM;
}
/* First ensure the directory is empty and will stay thay way */
write_lock (&de->u.dir.lock); write_lock (&de->u.dir.lock);
de->u.dir.no_more_additions = TRUE;
if (de->u.dir.first) err = -ENOTEMPTY; if (de->u.dir.first) err = -ENOTEMPTY;
else de->u.dir.no_more_additions = TRUE;
write_unlock (&de->u.dir.lock); write_unlock (&de->u.dir.lock);
if (err) { if (err) return err;
unlock_kernel();
return err;
}
/* Now unhook the directory from it's parent */ /* Now unhook the directory from it's parent */
write_lock (&de->parent->u.dir.lock); write_lock (&de->parent->u.dir.lock);
if ( !_devfs_unhook (de) ) err = -ENOENT; if ( !_devfs_unhook (de) ) err = -ENOENT;
write_unlock (&de->parent->u.dir.lock); write_unlock (&de->parent->u.dir.lock);
if (err) { if (err) return err;
unlock_kernel();
return err;
}
if ( !is_devfsd_or_child (fs_info) ) if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode, devfsd_notify_de (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info, 0); inode->i_uid, inode->i_gid, fs_info, 0);
free_dentry (de); free_dentry (de);
devfs_put (de); devfs_put (de);
unlock_kernel();
return 0; return 0;
} /* End Function devfs_rmdir */ } /* End Function devfs_rmdir */
...@@ -3191,43 +3142,31 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode, ...@@ -3191,43 +3142,31 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %d\n", DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %d\n",
dentry->d_name.name, mode, rdev); dentry->d_name.name, mode, rdev);
lock_kernel();
parent = get_devfs_entry_from_vfs_inode (dir); parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) { if (parent == NULL) return -ENOENT;
unlock_kernel();
return -ENOENT;
}
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode); de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
if (!de) { if (!de) return -ENOMEM;
unlock_kernel();
return -ENOMEM;
}
de->vfs_deletable = TRUE; de->vfs_deletable = TRUE;
if ( S_ISBLK (mode) || S_ISCHR (mode) ) if ( S_ISBLK (mode) || S_ISCHR (mode) )
{ {
de->u.fcb.u.device.major = MAJOR (rdev); de->u.fcb.u.device.major = MAJOR (rdev);
de->u.fcb.u.device.minor = MINOR (rdev); de->u.fcb.u.device.minor = MINOR (rdev);
} }
if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 ) { if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
unlock_kernel();
return err; return err;
}
de->inode.uid = current->euid; de->inode.uid = current->euid;
de->inode.gid = current->egid; de->inode.gid = current->egid;
de->inode.atime = CURRENT_TIME; de->inode.atime = CURRENT_TIME;
de->inode.mtime = CURRENT_TIME; de->inode.mtime = CURRENT_TIME;
de->inode.ctime = CURRENT_TIME; de->inode.ctime = CURRENT_TIME;
if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL ) { if ( ( inode = _devfs_get_vfs_inode (dir->i_sb, de, dentry) ) == NULL )
unlock_kernel();
return -ENOMEM; return -ENOMEM;
}
DPRINTK (DEBUG_I_MKNOD, ": new VFS inode(%u): %p dentry: %p\n", DPRINTK (DEBUG_I_MKNOD, ": new VFS inode(%u): %p dentry: %p\n",
de->inode.ino, inode, dentry); de->inode.ino, inode, dentry);
d_instantiate (dentry, inode); d_instantiate (dentry, inode);
if ( !is_devfsd_or_child (fs_info) ) if ( !is_devfsd_or_child (fs_info) )
devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode, devfsd_notify_de (de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
inode->i_uid, inode->i_gid, fs_info, 0); inode->i_uid, inode->i_gid, fs_info, 0);
unlock_kernel();
return 0; return 0;
} /* End Function devfs_mknod */ } /* End Function devfs_mknod */
...@@ -3301,15 +3240,16 @@ static int devfs_fill_super (struct super_block *sb, void *data, int silent) ...@@ -3301,15 +3240,16 @@ static int devfs_fill_super (struct super_block *sb, void *data, int silent)
PRINTK ("(): get root inode failed\n"); PRINTK ("(): get root inode failed\n");
if (root_inode) iput (root_inode); if (root_inode) iput (root_inode);
return -EINVAL; return -EINVAL;
} /* End Function devfs_read_super */ } /* End Function devfs_fill_super */
static struct super_block *devfs_get_sb(struct file_system_type *fs_type, static struct super_block *devfs_get_sb (struct file_system_type *fs_type,
int flags, char *dev_name, void *data) int flags, char *dev_name, void *data)
{ {
return get_sb_single(fs_type, flags, data, devfs_fill_super); return get_sb_single (fs_type, flags, data, devfs_fill_super);
} }
static struct file_system_type devfs_fs_type = { static struct file_system_type devfs_fs_type =
{
name: DEVFS_NAME, name: DEVFS_NAME,
get_sb: devfs_get_sb, get_sb: devfs_get_sb,
kill_sb: kill_anon_super, kill_sb: kill_anon_super,
......
/* devfs (Device FileSystem) utilities. /* devfs (Device FileSystem) utilities.
Copyright (C) 1999-2001 Richard Gooch Copyright (C) 1999-2002 Richard Gooch
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -48,6 +48,12 @@ ...@@ -48,6 +48,12 @@
20010818 Richard Gooch <rgooch@atnf.csiro.au> 20010818 Richard Gooch <rgooch@atnf.csiro.au>
Updated major masks up to Linus' "no new majors" proclamation. Updated major masks up to Linus' "no new majors" proclamation.
Block: were 126 now 122 free, char: were 26 now 19 free. Block: were 126 now 122 free, char: were 26 now 19 free.
20020324 Richard Gooch <rgooch@atnf.csiro.au>
Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
bitfield.
20020326 Richard Gooch <rgooch@atnf.csiro.au>
Fixed bitfield data type for <devfs_*alloc_devnum>.
Made major bitfield type and initialiser 64 bit safe.
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -125,8 +131,13 @@ EXPORT_SYMBOL(devfs_register_series); ...@@ -125,8 +131,13 @@ EXPORT_SYMBOL(devfs_register_series);
struct major_list struct major_list
{ {
spinlock_t lock; spinlock_t lock;
__u32 bits[8]; unsigned long bits[256 / BITS_PER_LONG];
}; };
#if BITS_PER_LONG == 32
# define INITIALISER64(low,high) (low), (high)
#else
# define INITIALISER64(low,high) ( (high) << 32 | (low) )
#endif
/* Block majors already assigned: /* Block majors already assigned:
0-3, 7-9, 11-63, 65-99, 101-113, 120-127, 199, 201, 240-255 0-3, 7-9, 11-63, 65-99, 101-113, 120-127, 199, 201, 240-255
...@@ -134,14 +145,11 @@ struct major_list ...@@ -134,14 +145,11 @@ struct major_list
*/ */
static struct major_list block_major_list = static struct major_list block_major_list =
{SPIN_LOCK_UNLOCKED, {SPIN_LOCK_UNLOCKED,
{0xfffffb8f, /* Majors 0 to 31 */ {INITIALISER64 (0xfffffb8f, 0xffffffff), /* Majors 0-31, 32-63 */
0xffffffff, /* Majors 32 to 63 */ INITIALISER64 (0xfffffffe, 0xff03ffef), /* Majors 64-95, 96-127 */
0xfffffffe, /* Majors 64 to 95 */ INITIALISER64 (0x00000000, 0x00000000), /* Majors 128-159, 160-191 */
0xff03ffef, /* Majors 96 to 127 */ INITIALISER64 (0x00000280, 0xffff0000), /* Majors 192-223, 224-255 */
0x00000000, /* Majors 128 to 159 */ }
0x00000000, /* Majors 160 to 191 */
0x00000280, /* Majors 192 to 223 */
0xffff0000} /* Majors 224 to 255 */
}; };
/* Char majors already assigned: /* Char majors already assigned:
...@@ -150,14 +158,11 @@ static struct major_list block_major_list = ...@@ -150,14 +158,11 @@ static struct major_list block_major_list =
*/ */
static struct major_list char_major_list = static struct major_list char_major_list =
{SPIN_LOCK_UNLOCKED, {SPIN_LOCK_UNLOCKED,
{0xfffffeff, /* Majors 0 to 31 */ {INITIALISER64 (0xfffffeff, 0xffffffff), /* Majors 0-31, 32-63 */
0xffffffff, /* Majors 32 to 63 */ INITIALISER64 (0xffffffff, 0xffffffff), /* Majors 64-95, 96-127 */
0xffffffff, /* Majors 64 to 95 */ INITIALISER64 (0x7cffffff, 0xffffffff), /* Majors 128-159, 160-191 */
0xffffffff, /* Majors 96 to 127 */ INITIALISER64 (0x3f0fffff, 0xffff007f), /* Majors 192-223, 224-255 */
0x7cffffff, /* Majors 128 to 159 */ }
0xffffffff, /* Majors 160 to 191 */
0x3f0fffff, /* Majors 192 to 223 */
0xffff007f} /* Majors 224 to 255 */
}; };
...@@ -212,7 +217,7 @@ EXPORT_SYMBOL(devfs_dealloc_major); ...@@ -212,7 +217,7 @@ EXPORT_SYMBOL(devfs_dealloc_major);
struct minor_list struct minor_list
{ {
int major; int major;
__u32 bits[8]; unsigned long bits[256 / BITS_PER_LONG];
struct minor_list *next; struct minor_list *next;
}; };
...@@ -267,7 +272,7 @@ kdev_t devfs_alloc_devnum (char type) ...@@ -267,7 +272,7 @@ kdev_t devfs_alloc_devnum (char type)
if (minor >= 256) continue; if (minor >= 256) continue;
__set_bit (minor, entry->bits); __set_bit (minor, entry->bits);
up (semaphore); up (semaphore);
return mk_kdev(entry->major, minor); return mk_kdev (entry->major, minor);
} }
/* Need to allocate a new major */ /* Need to allocate a new major */
if ( ( entry = kmalloc (sizeof *entry, GFP_KERNEL) ) == NULL ) if ( ( entry = kmalloc (sizeof *entry, GFP_KERNEL) ) == NULL )
...@@ -289,7 +294,7 @@ kdev_t devfs_alloc_devnum (char type) ...@@ -289,7 +294,7 @@ kdev_t devfs_alloc_devnum (char type)
else list->last->next = entry; else list->last->next = entry;
list->last = entry; list->last = entry;
up (semaphore); up (semaphore);
return mk_kdev(entry->major, 0); return mk_kdev (entry->major, 0);
} /* End Function devfs_alloc_devnum */ } /* End Function devfs_alloc_devnum */
EXPORT_SYMBOL(devfs_alloc_devnum); EXPORT_SYMBOL(devfs_alloc_devnum);
...@@ -309,7 +314,7 @@ void devfs_dealloc_devnum (char type, kdev_t devnum) ...@@ -309,7 +314,7 @@ void devfs_dealloc_devnum (char type, kdev_t devnum)
struct device_list *list; struct device_list *list;
struct minor_list *entry; struct minor_list *entry;
if (kdev_none(devnum)) return; if ( kdev_none (devnum) ) return;
if (type == DEVFS_SPECIAL_CHR) if (type == DEVFS_SPECIAL_CHR)
{ {
semaphore = &char_semaphore; semaphore = &char_semaphore;
...@@ -355,7 +360,6 @@ int devfs_alloc_unique_number (struct unique_numspace *space) ...@@ -355,7 +360,6 @@ int devfs_alloc_unique_number (struct unique_numspace *space)
{ {
int number; int number;
unsigned int length; unsigned int length;
__u32 *bits;
/* Get around stupid lack of semaphore initialiser */ /* Get around stupid lack of semaphore initialiser */
spin_lock (&space->init_lock); spin_lock (&space->init_lock);
...@@ -368,6 +372,8 @@ int devfs_alloc_unique_number (struct unique_numspace *space) ...@@ -368,6 +372,8 @@ int devfs_alloc_unique_number (struct unique_numspace *space)
down (&space->semaphore); down (&space->semaphore);
if (space->num_free < 1) if (space->num_free < 1)
{ {
void *bits;
if (space->length < 16) length = 16; if (space->length < 16) length = 16;
else length = space->length << 1; else length = space->length << 1;
if ( ( bits = vmalloc (length) ) == NULL ) if ( ( bits = vmalloc (length) ) == NULL )
......
...@@ -54,7 +54,7 @@ struct unique_numspace ...@@ -54,7 +54,7 @@ struct unique_numspace
unsigned char sem_initialised; unsigned char sem_initialised;
unsigned int num_free; /* Num free in bits */ unsigned int num_free; /* Num free in bits */
unsigned int length; /* Array length in bytes */ unsigned int length; /* Array length in bytes */
__u32 *bits; unsigned long *bits;
struct semaphore semaphore; struct semaphore semaphore;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment