On Wed, Mar 19, 2003 at 02:14:50PM -0500, Matthew Harrell wrote:
>
> Once the jaz drive spins down and then I try to access it again it either
> doesn't respond ever, hangs the process permenantly, or generates the
> attached oops. If anyone wants more info let me know and I'll reboot back
> with devfs turned on
This looks like the devfs (mis-)feature to reread partition tables at
inappropinquate places is biting us again.
Could you try the following patch (posted to lkml two times already)?
--- 1.27/arch/um/drivers/ubd_kern.c Sat Mar 8 17:50:21 2003
+++ edited/arch/um/drivers/ubd_kern.c Wed Mar 12 10:35:30 2003
@@ -507,7 +507,7 @@
/* /dev/ubd/N style names */
sprintf(devfs_name, "%d", unit);
*handle_out = devfs_register(dir_handle, devfs_name,
- DEVFS_FL_REMOVABLE, major, minor,
+ 0, major, minor,
S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |
S_IWGRP, &ubd_blops, NULL);
disk->private_data = &ubd_dev[unit];
--- 1.73/fs/devfs/base.c Tue Mar 11 09:42:24 2003
+++ edited/fs/devfs/base.c Wed Mar 12 11:10:01 2003
@@ -758,7 +758,6 @@
rwlock_t lock; /* Lock for searching(R)/updating(W) */
struct devfs_entry *first;
struct devfs_entry *last;
- unsigned short num_removable; /* Lock for writing but not reading */
unsigned char no_more_additions:1;
};
@@ -766,7 +765,6 @@
{
struct block_device_operations *ops;
dev_t dev;
- unsigned char removable:1;
};
struct cdev_type
@@ -1017,7 +1015,6 @@
* _devfs_append_entry - Append a devfs entry to a directory's child list.
* @dir: The directory to add to.
* @de: The devfs entry to append.
- * @removable: If TRUE, increment the count of removable devices for %dir.
* @old_de: If an existing entry exists, it will be written here. This may
* be %NULL. An implicit devfs_get() is performed on this entry.
*
@@ -1028,7 +1025,7 @@
*/
static int _devfs_append_entry (devfs_handle_t dir, devfs_handle_t de,
- int removable, devfs_handle_t *old_de)
+ devfs_handle_t *old_de)
{
int retval;
@@ -1056,7 +1053,6 @@
if (dir->u.dir.first == NULL) dir->u.dir.first = de;
else dir->u.dir.last->next = de;
dir->u.dir.last = de;
- if (removable) ++dir->u.dir.num_removable;
retval = 0;
}
else retval = -EEXIST;
@@ -1095,13 +1091,13 @@
== NULL ) return NULL;
new->u.cdev.dev = devfs_alloc_devnum (S_IFCHR |S_IRUSR |S_IWUSR);
new->u.cdev.ops = &devfsd_fops;
- _devfs_append_entry (root_entry, new, FALSE, NULL);
+ _devfs_append_entry (root_entry, new, NULL);
#ifdef CONFIG_DEVFS_DEBUG
if ( ( new = _devfs_alloc_entry (".stat", 0, S_IFCHR | S_IRUGO | S_IWUGO) )
== NULL ) return NULL;
new->u.cdev.dev = devfs_alloc_devnum (S_IFCHR | S_IRUGO | S_IWUGO);
new->u.cdev.ops = &stat_fops;
- _devfs_append_entry (root_entry, new, FALSE, NULL);
+ _devfs_append_entry (root_entry, new, NULL);
#endif
return root_entry;
} /* End Function _devfs_get_root_entry */
@@ -1164,7 +1160,7 @@
{
de = _devfs_alloc_entry (name, next_pos, MODE_DIR);
devfs_get (de);
- if ( !de || _devfs_append_entry (dir, de, FALSE, &old) )
+ if ( !de || _devfs_append_entry (dir, de, &old) )
{
devfs_put (de);
if ( !old || !S_ISDIR (old->mode) )
@@ -1498,7 +1494,6 @@
de->u.bdev.dev = dev;
de->u.cdev.autogen = devnum != 0;
de->u.bdev.ops = ops;
- if (flags & DEVFS_FL_REMOVABLE) de->u.bdev.removable = TRUE;
} else {
PRINTK ("(%s): illegal mode: %x\n", name, mode);
devfs_put (de);
@@ -1516,7 +1511,7 @@
de->inode.uid = 0;
de->inode.gid = 0;
}
- err = _devfs_append_entry(dir, de, flags & DEVFS_FL_REMOVABLE, NULL);
+ err = _devfs_append_entry(dir, de, NULL);
if (err)
{
PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
@@ -1553,8 +1548,6 @@
else de->next->prev = de->prev;
de->prev = de; /* Indicate we're unhooked */
de->next = NULL; /* Force early termination for <devfs_readdir> */
- if (S_ISBLK (de->mode) && de->u.bdev.removable )
- --parent->u.dir.num_removable;
return TRUE;
} /* End Function _devfs_unhook */
@@ -1648,7 +1641,7 @@
de->info = info;
de->u.symlink.linkname = newlink;
de->u.symlink.length = linklength;
- if ( ( err = _devfs_append_entry (dir, de, FALSE, NULL) ) != 0 )
+ if ( ( err = _devfs_append_entry (dir, de, NULL) ) != 0 )
{
PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
devfs_put (dir);
@@ -1725,7 +1718,7 @@
return NULL;
}
de->info = info;
- if ( ( err = _devfs_append_entry (dir, de, FALSE, &old) ) != 0 )
+ if ( ( err = _devfs_append_entry (dir, de, &old) ) != 0 )
{
PRINTK ("(%s): could not append to dir: %p \"%s\", err: %d\n",
name, dir, dir->name, err);
@@ -1921,102 +1914,6 @@
} /* End Function try_modload */
-/**
- * check_disc_changed - Check if a removable disc was changed.
- * @de: The device.
- *
- * Returns 1 if the media was changed, else 0.
- *
- * This function may block, and may indirectly cause the parent directory
- * contents to be changed due to partition re-reading.
- */
-
-static int check_disc_changed (struct devfs_entry *de)
-{
- int tmp;
- int retval = 0;
- dev_t dev = de->u.bdev.dev;
- extern int warn_no_part;
-
- if (!S_ISBLK(de->mode))
- return 0;
- /* Ugly hack to disable messages about unable to read partition table */
- tmp = warn_no_part;
- warn_no_part = 0;
- retval = __check_disk_change(dev);
- warn_no_part = tmp;
- return retval;
-} /* End Function check_disc_changed */
-
-/**
- * scan_dir_for_removable - Scan a directory for removable media devices and check media.
- * @dir: The directory.
- *
- * This function may block, and may indirectly cause the directory
- * contents to be changed due to partition re-reading. The directory will
- * be locked for reading.
- */
-
-static void scan_dir_for_removable (struct devfs_entry *dir)
-{
- struct devfs_entry *de;
-
- read_lock (&dir->u.dir.lock);
- if (dir->u.dir.num_removable < 1) de = NULL;
- else
- {
- for (de = dir->u.dir.first; de != NULL; de = de->next)
- {
- if (S_ISBLK (de->mode) && de->u.bdev.removable) break;
- }
- devfs_get (de);
- }
- read_unlock (&dir->u.dir.lock);
- if (de) check_disc_changed (de);
- devfs_put (de);
-} /* End Function scan_dir_for_removable */
-
-/**
- * get_removable_partition - Get removable media partition.
- * @dir: The parent directory.
- * @name: The name of the entry.
- * @namelen: The number of characters in <<name>>.
- *
- * Returns 1 if the media was changed, else 0.
- *
- * This function may block, and may indirectly cause the directory
- * contents to be changed due to partition re-reading. The directory must
- * be locked for reading upon entry, and will be unlocked upon exit.
- */
-
-static int get_removable_partition (struct devfs_entry *dir, const char *name,
- unsigned int namelen)
-{
- int retval;
- struct devfs_entry *de;
-
- if (dir->u.dir.num_removable < 1)
- {
- read_unlock (&dir->u.dir.lock);
- return 0;
- }
- for (de = dir->u.dir.first; de != NULL; de = de->next)
- {
- if (!S_ISBLK (de->mode) || !de->u.bdev.removable) continue;
- if (strcmp (de->name, "disc") == 0) break;
- /* Support for names where the partition is appended to the disc name
- */
- if (de->namelen >= namelen) continue;
- if (strncmp (de->name, name, de->namelen) == 0) break;
- }
- devfs_get (de);
- read_unlock (&dir->u.dir.lock);
- retval = de ? check_disc_changed (de) : 0;
- devfs_put (de);
- return retval;
-} /* End Function get_removable_partition */
-
-
/* Superblock operations follow */
static struct inode_operations devfs_iops;
@@ -2166,7 +2063,6 @@
switch ( (long) file->f_pos )
{
case 0:
- scan_dir_for_removable (parent);
err = (*filldir) (dirent, "..", 2, file->f_pos,
parent_ino (file->f_dentry), DT_DIR);
if (err == -EINVAL) break;
@@ -2404,18 +2300,7 @@
if (parent == NULL) return ERR_PTR (-ENOENT);
read_lock (&parent->u.dir.lock);
de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len);
- if (de) read_unlock (&parent->u.dir.lock);
- else
- { /* Try re-reading the partition (media may have changed) */
- if ( get_removable_partition (parent, dentry->d_name.name,
- dentry->d_name.len) ) /* Unlocks */
- { /* Media did change */
- read_lock (&parent->u.dir.lock);
- de = _devfs_search_dir (parent, dentry->d_name.name,
- dentry->d_name.len);
- read_unlock (&parent->u.dir.lock);
- }
- }
+ read_unlock (&parent->u.dir.lock);
lookup_info.de = de;
init_waitqueue_head (&lookup_info.wait_queue);
dentry->d_fsdata = &lookup_info;
@@ -2542,7 +2427,7 @@
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
if (!de) return -ENOMEM;
de->vfs_deletable = TRUE;
- if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
+ if ( ( err = _devfs_append_entry (parent, de, NULL) ) != 0 )
return err;
de->inode.uid = current->euid;
de->inode.gid = current->egid;
@@ -2610,7 +2495,7 @@
de->u.cdev.dev = rdev;
else if (S_ISBLK (mode))
de->u.bdev.dev = rdev;
- if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
+ if ( ( err = _devfs_append_entry (parent, de, NULL) ) != 0 )
return err;
de->inode.uid = current->euid;
de->inode.gid = current->egid;
===== fs/partitions/check.c 1.96 vs edited =====
--- 1.96/fs/partitions/check.c Sat Mar 8 17:50:30 2003
+++ edited/fs/partitions/check.c Wed Mar 12 10:35:00 2003
@@ -156,7 +156,6 @@
{
#ifdef CONFIG_DEVFS_FS
devfs_handle_t dir;
- unsigned int devfs_flags = DEVFS_FL_DEFAULT;
struct hd_struct *p = dev->part;
char devname[16];
@@ -165,10 +164,8 @@
dir = dev->de;
if (!dir)
return;
- if (dev->flags & GENHD_FL_REMOVABLE)
- devfs_flags |= DEVFS_FL_REMOVABLE;
sprintf(devname, "part%d", part);
- p[part-1].de = devfs_register (dir, devname, devfs_flags,
+ p[part-1].de = devfs_register (dir, devname, 0,
dev->major, dev->first_minor + part,
S_IFBLK | S_IRUSR | S_IWUSR,
dev->fops, NULL);
@@ -185,11 +182,8 @@
#ifdef CONFIG_DEVFS_FS
int pos = 0;
devfs_handle_t dir, slave;
- unsigned int devfs_flags = DEVFS_FL_DEFAULT;
char dirname[64], symlink[16];
- if (dev->flags & GENHD_FL_REMOVABLE)
- devfs_flags |= DEVFS_FL_REMOVABLE;
if (dev->flags & GENHD_FL_DEVFS) {
dir = dev->de;
if (!dir) /* Aware driver wants to block disc management */
@@ -209,7 +203,7 @@
sprintf(symlink, "discs/disc%d", dev->number);
devfs_mk_symlink(NULL, symlink, DEVFS_FL_DEFAULT,
dirname + pos, &slave, NULL);
- dev->disk_de = devfs_register(dir, "disc", devfs_flags,
+ dev->disk_de = devfs_register(dir, "disc", 0,
dev->major, dev->first_minor,
S_IFBLK | S_IRUSR | S_IWUSR, dev->fops, NULL);
#endif
--- 1.30/include/linux/devfs_fs_kernel.h Tue Mar 11 08:58:19 2003
+++ edited/include/linux/devfs_fs_kernel.h Wed Mar 12 10:51:40 2003
@@ -13,7 +13,6 @@
#define DEVFS_FL_NONE 0x000 /* This helps to make code more readable
*/
-#define DEVFS_FL_REMOVABLE 0x008 /* This is a removable media device */
#define DEVFS_FL_WAIT 0x010 /* Wait for devfsd to finish */
#define DEVFS_FL_CURRENT_OWNER 0x020 /* Set initial ownership to current */
#define DEVFS_FL_DEFAULT DEVFS_FL_NONE
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun Mar 23 2003 - 22:00:27 EST