patch-2.4.7 linux/fs/devfs/base.c
Next file: linux/fs/devfs/util.c
Previous file: linux/fs/dcache.c
Back to the patch index
Back to the overall index
- Lines: 171
- Date:
Wed Jul 11 14:55:41 2001
- Orig file:
v2.4.6/linux/fs/devfs/base.c
- Orig date:
Tue Jul 3 17:08:21 2001
diff -u --recursive --new-file v2.4.6/linux/fs/devfs/base.c linux/fs/devfs/base.c
@@ -507,6 +507,10 @@
Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc.
Simplified locking in <devfsd_ioctl> and fixed memory leak.
v0.106
+ 20010709 Richard Gooch <rgooch@atnf.csiro.au>
+ Removed broken devnum allocation and use <devfs_alloc_devnum>.
+ Fixed old devnum leak by calling new <devfs_dealloc_devnum>.
+ v0.107
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -524,8 +528,6 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/locks.h>
-#include <linux/kdev_t.h>
#include <linux/devfs_fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/smp_lock.h>
@@ -541,7 +543,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "0.106 (20010617)"
+#define DEVFS_VERSION "0.107 (20010709)"
#define DEVFS_NAME "devfs"
@@ -550,9 +552,6 @@
#define STRING_LENGTH 256
-#define MIN_DEVNUM 36864 /* Use major numbers 144 */
-#define MAX_DEVNUM 61439 /* through 239, inclusive */
-
#ifndef TRUE
# define TRUE 1
# define FALSE 0
@@ -626,6 +625,7 @@
unsigned char aopen_notify:1;
unsigned char removable:1; /* Belongs in device_type, but save space */
unsigned char open:1; /* Not entirely correct */
+ unsigned char autogen:1; /* Belongs in device_type, but save space */
};
struct symlink_type
@@ -712,8 +712,6 @@
};
static struct fs_info fs_info = {devfsd_buffer_lock: SPIN_LOCK_UNLOCKED};
-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
static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
@@ -873,6 +871,7 @@
static struct devfs_entry *get_root_entry (void)
{
+ kdev_t devnum;
struct devfs_entry *new;
/* Always ensure the root is created */
@@ -885,9 +884,9 @@
/* And create the entry for ".devfsd" */
if ( ( new = create_entry (root_entry, ".devfsd", 0) ) == NULL )
return NULL;
- new->u.fcb.u.device.major = next_devnum_char >> 8;
- new->u.fcb.u.device.minor = next_devnum_char & 0xff;
- ++next_devnum_char;
+ devnum = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
+ new->u.fcb.u.device.major = MAJOR (devnum);
+ new->u.fcb.u.device.minor = MINOR (devnum);
new->mode = S_IFCHR | S_IRUSR | S_IWUSR;
new->u.fcb.default_uid = 0;
new->u.fcb.default_gid = 0;
@@ -1264,7 +1263,9 @@
unsigned int major, unsigned int minor,
umode_t mode, void *ops, void *info)
{
+ char devtype = S_ISCHR (mode) ? DEVFS_SPECIAL_CHR : DEVFS_SPECIAL_BLK;
int is_new;
+ kdev_t devnum = NODEV;
struct devfs_entry *de;
if (name == NULL)
@@ -1296,29 +1297,17 @@
DEVFS_NAME, name);
return NULL;
}
- if ( S_ISCHR (mode) && (flags & DEVFS_FL_AUTO_DEVNUM) )
- {
- if (next_devnum_char >= MAX_DEVNUM)
- {
- printk ("%s: devfs_register(%s): exhausted char device numbers\n",
- DEVFS_NAME, name);
- return NULL;
- }
- major = next_devnum_char >> 8;
- minor = next_devnum_char & 0xff;
- ++next_devnum_char;
- }
- if ( S_ISBLK (mode) && (flags & DEVFS_FL_AUTO_DEVNUM) )
+ if ( ( S_ISCHR (mode) || S_ISBLK (mode) ) &&
+ (flags & DEVFS_FL_AUTO_DEVNUM) )
{
- if (next_devnum_block >= MAX_DEVNUM)
+ if ( ( devnum = devfs_alloc_devnum (devtype) ) == NODEV )
{
- printk ("%s: devfs_register(%s): exhausted block device numbers\n",
- DEVFS_NAME, name);
+ printk ("%s: devfs_register(%s): exhausted %s device numbers\n",
+ DEVFS_NAME, name, S_ISCHR (mode) ? "char" : "block");
return NULL;
}
- major = next_devnum_block >> 8;
- minor = next_devnum_block & 0xff;
- ++next_devnum_block;
+ major = MAJOR (devnum);
+ minor = MINOR (devnum);
}
de = search_for_entry (dir, name, strlen (name), TRUE, TRUE, &is_new,
FALSE);
@@ -1326,6 +1315,7 @@
{
printk ("%s: devfs_register(): could not create entry: \"%s\"\n",
DEVFS_NAME, name);
+ if (devnum != NODEV) devfs_dealloc_devnum (devtype, devnum);
return NULL;
}
#ifdef CONFIG_DEVFS_DEBUG
@@ -1341,19 +1331,23 @@
{
printk ("%s: devfs_register(): existing non-device/file entry: \"%s\"\n",
DEVFS_NAME, name);
+ if (devnum != NODEV) devfs_dealloc_devnum (devtype, devnum);
return NULL;
}
if (de->registered)
{
printk("%s: devfs_register(): device already registered: \"%s\"\n",
DEVFS_NAME, name);
+ if (devnum != NODEV) devfs_dealloc_devnum (devtype, devnum);
return NULL;
}
}
+ de->u.fcb.autogen = 0;
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) ? 0 : 1;
}
else if ( S_ISREG (mode) ) de->u.fcb.u.file.size = 0;
else
@@ -1417,6 +1411,14 @@
{
de->registered = FALSE;
de->u.fcb.ops = NULL;
+ if (!S_ISREG (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) );
+ }
+ de->u.fcb.autogen = 0;
return;
}
if (S_ISLNK (de->mode) && de->registered)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)