Received: (from majordomo@localhost) by oss.sgi.com (8.11.3/8.11.3) id f3JGXcD16426 for linux-xfs-outgoing; Thu, 19 Apr 2001 09:33:38 -0700 Received: from mail15.jump.net (mail15.jump.net [206.196.91.15]) by oss.sgi.com (8.11.3/8.11.3) with ESMTP id f3JGXUM16422 for ; Thu, 19 Apr 2001 09:33:30 -0700 Received: from sgi.com (aus-dsl-dhcp1-26.customer.jump.net [63.163.168.26]) by mail15.jump.net (8.10.2/) with ESMTP id f3JGXQB28997; Thu, 19 Apr 2001 11:33:26 -0500 (CDT) Message-ID: <3ADF13AE.3A336975@sgi.com> Date: Thu, 19 Apr 2001 11:34:55 -0500 From: Eric Sandeen X-Mailer: Mozilla 4.76 [en] (X11; U; Linux 2.4.2-XFS i686) X-Accept-Language: en MIME-Version: 1.0 To: Caleb Land CC: linux-xfs@oss.sgi.com Subject: Re: /dev/cdrom problems (ide-cd being unloaded by cron) References: <20010419121319.B23527@deepthought.granfalloon.com> Content-Type: multipart/mixed; boundary="------------B5E9E4F6B8B057E30D6E8398" Sender: owner-linux-xfs@oss.sgi.com Precedence: bulk This is a multi-part message in MIME format. --------------B5E9E4F6B8B057E30D6E8398 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Caleb Land wrote: > > Hello, > Recently I installed Red Hat 7.1 from the SGI XFS disc (very > nice work BTW) and when I first used the system, I had problems with > ide-cd not loading (as others have), but after running `depmod -a > ` everything seemed to be solved, Hm, we still need to look into that... > but then as I used the computer past > 10 minutes, I noticed that if I didn't have any CDROM drives in > use/mounted during that time, I would lose my /dev/hd[ac] entries, and > the cdrom entries (those are my cdrom devices). I found that cron was > unloading unused modules every 10 minutes. Yep... > Now, if I put something like: > > alias /dev/ide* /dev/ide (/dev/ide is a probeall module in > modules.devfsd) > > alias /dev/cdroms* /dev/ide > > and > > alias /dev/hd* /dev/ide > > in my modules.conf, the ide-cd module is loaded whenever these devices > are accessed, but for some reason, the entries in /dev/cdroms keep > incrementing the cdromX number (IE the second time the module is > loaded, I have cdrom2 and cdrom3) Yep, this is a buglet. Attached is a patch from Jens to fix this incrementing behavior. We will probably include it in the final kernel RPMS. This patch should fix the incrementing problem, and I think the devfsd.conf will work as it was originally installed, but let me know if you find holes in it, or if you think your lines above still need to be adde. Thanks, -Eric -- Eric Sandeen XFS for Linux http://oss.sgi.com/projects/xfs sandeen@sgi.com SGI, Inc. --------------B5E9E4F6B8B057E30D6E8398 Content-Type: text/plain; charset=us-ascii; name="cd-244p4-2" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="cd-244p4-2" diff -ur --exclude-from /home/axboe/exclude /opt/kernel/linux-2.4.4-pre4/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- /opt/kernel/linux-2.4.4-pre4/drivers/cdrom/cdrom.c Thu Mar 29 21:56:07 2001 +++ linux/drivers/cdrom/cdrom.c Wed Apr 18 13:27:36 2001 @@ -279,6 +279,9 @@ static int lockdoor = 1; /* will we ever get to use this... sigh. */ static int check_media_type; +static unsigned long *cdrom_numbers; +static DECLARE_MUTEX(cdrom_sem); + MODULE_PARM(debug, "i"); MODULE_PARM(autoclose, "i"); MODULE_PARM(autoeject, "i"); @@ -340,6 +343,38 @@ check_media_change: cdrom_media_changed, }; +/* + * get or clear a new cdrom number, run under cdrom_sem + */ +static int cdrom_get_entry(void) +{ + int i, nr, foo; + + nr = 0; + foo = -1; + for (i = 0; i < CDROM_MAX_CDROMS / (sizeof(unsigned long) * 8); i++) { + if (cdrom_numbers[i] == ~0UL) { + nr += sizeof(unsigned long) * 8; + continue; + } + foo = ffz(cdrom_numbers[i]); + set_bit(foo, &cdrom_numbers[i]); + nr += foo; + break; + } + + return foo == -1 ? foo : nr; +} + +static void cdrom_clear_entry(struct cdrom_device_info *cdi) +{ + int bit_nr = cdi->nr & ~(sizeof(unsigned long) * 8); + int cd_index = cdi->nr / (sizeof(unsigned long) * 8); + + clear_bit(bit_nr, &cdrom_numbers[cd_index]); +} + + /* This macro makes sure we don't have to check on cdrom_device_ops * existence in the run-time routines below. Change_capability is a * hack to have the capability flags defined const, while we can still @@ -354,7 +389,6 @@ struct cdrom_device_ops *cdo = cdi->ops; int *change_capability = (int *)&cdo->capability; /* hack */ char vname[16]; - static unsigned int cdrom_counter; cdinfo(CD_OPEN, "entering register_cdrom\n"); @@ -395,7 +429,17 @@ if (!devfs_handle) devfs_handle = devfs_mk_dir (NULL, "cdroms", NULL); - sprintf (vname, "cdrom%u", cdrom_counter++); + + /* + * get new cdrom number + */ + down(&cdrom_sem); + cdi->nr = cdrom_get_entry(); + up(&cdrom_sem); + if (cdi->nr == -1) + return -ENOMEM; + + sprintf(vname, "cdrom%u", cdi->nr); if (cdi->de) { int pos; devfs_handle_t slave; @@ -418,9 +462,13 @@ S_IFBLK | S_IRUGO | S_IWUGO, &cdrom_fops, NULL); } - cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); + + down(&cdrom_sem); cdi->next = topCdromPtr; topCdromPtr = cdi; + up(&cdrom_sem); + + cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); return 0; } #undef ENSURE @@ -429,12 +477,14 @@ { struct cdrom_device_info *cdi, *prev; int major = MAJOR(unreg->dev); + int bit_nr, cd_index; cdinfo(CD_OPEN, "entering unregister_cdrom\n"); if (major < 0 || major >= MAX_BLKDEV) return -1; + down(&cdrom_sem); prev = NULL; cdi = topCdromPtr; while (cdi != NULL && cdi->dev != unreg->dev) { @@ -442,14 +492,20 @@ cdi = cdi->next; } - if (cdi == NULL) + if (cdi == NULL) { + up(&cdrom_sem); return -2; + } + + cdrom_clear_entry(cdi); + if (prev) prev->next = cdi->next; else topCdromPtr = cdi->next; + up(&cdrom_sem); cdi->ops->n_minors--; - devfs_unregister (cdi->de); + devfs_unregister(cdi->de); cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); return 0; } @@ -458,10 +514,14 @@ { struct cdrom_device_info *cdi; + down(&cdrom_sem); + cdi = topCdromPtr; while (cdi != NULL && cdi->dev != dev) cdi = cdi->next; + up(&cdrom_sem); + return cdi; } @@ -2418,6 +2478,8 @@ } pos = sprintf(info, "CD-ROM information, " VERSION "\n"); + + down(&cdrom_sem); pos += sprintf(info+pos, "\ndrive name:\t"); for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) @@ -2487,6 +2549,8 @@ for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0); + up(&cdrom_sem); + strcpy(info+pos,"\n\n"); return proc_dostring(ctl, write, filp, buffer, lenp); @@ -2633,6 +2697,10 @@ static int __init cdrom_init(void) { + int n_entries = CDROM_MAX_CDROMS / (sizeof(unsigned long) * 8); + + cdrom_numbers = kmalloc(n_entries * sizeof(unsigned long), GFP_KERNEL); + #ifdef CONFIG_SYSCTL cdrom_sysctl_register(); #endif @@ -2643,6 +2711,7 @@ static void __exit cdrom_exit(void) { printk(KERN_INFO "Uniform CD-ROM driver unloaded\n"); + kfree(cdrom_numbers); #ifdef CONFIG_SYSCTL cdrom_sysctl_unregister(); #endif diff -ur --exclude-from /home/axboe/exclude /opt/kernel/linux-2.4.4-pre4/include/linux/cdrom.h linux/include/linux/cdrom.h --- /opt/kernel/linux-2.4.4-pre4/include/linux/cdrom.h Wed Apr 18 14:37:43 2001 +++ linux/include/linux/cdrom.h Wed Apr 18 13:02:10 2001 @@ -577,6 +577,8 @@ struct dvd_manufact manufact; } dvd_struct; +#define CDROM_MAX_CDROMS 256 + /* * DVD authentication ioctl */ @@ -732,6 +734,7 @@ devfs_handle_t de; /* real driver creates this */ /* specifications */ kdev_t dev; /* device number */ + int nr; /* cdrom entry */ int mask; /* mask of capability: disables them */ int speed; /* maximum speed for reading data */ int capacity; /* number of discs in jukebox */ --------------B5E9E4F6B8B057E30D6E8398--