kern/116539: [fdc] fdc(4) marks /dev/fd0 device busy when it should
not, so does not allow to kldunload fdc.ko
Eugene Grosbein
eugen at grosbein.pp.ru
Fri Sep 21 23:20:01 PDT 2007
>Number: 116539
>Category: kern
>Synopsis: [fdc] fdc(4) marks /dev/fd0 device busy when it should not, so does not allow to kldunload fdc.ko
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Sep 22 06:20:00 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Eugene Grosbein
>Release: FreeBSD 6.2-STABLE i386
>Organization:
Svyaz-Service JSC
>Environment:
System: FreeBSD grosbein.pp.ru 6.2-STABLE FreeBSD 6.2-STABLE #2: Sun Sep 16 16:54:23 KRAST 2007 eu at grosbein.pp.ru:/home/obj/usr/local/src/sys/DADV i386
>Description:
Any access to /dev/fd0 results in call to device_busy(fd->dev)
and should entail appropriate device_unbusy(fd->dev).
However, an attempt to write access to write-protected floppy
leads to device_busy(fd->dev) without corresponding
device_unbusy(fd->dev). This locks fdc.ko from unloading.
>How-To-Repeat:
Boot kernel without fdc(4) compiled-in. Load fdc(4) by means
of loader or kldload having write-protected floppy in the drive
when fdc(4) initializes. Do:
echo -n >/dev/fd0
You'll get 'Read-only file system' error and will not be allowed
to unload fdc.ko after that. One may use following patch to see
what happens inside kernel. You should 'debug.fdc.debugflags=64'
in the /boot/loader.conf to see what happens.
You can also try 'debug.fdc.debugflags=320' to enable
this patch's ability to force device unlocking for such case
but this is not correct solution. It will unbusy device
in cases where it should not: device is mounted read-only
and an attempt to open it for writing is performed. The patch
will call device_unbusy(fd->dev) allowing to unload fdc.ko
while device is still mounted. I do not know correct solution.
--- sys/dev/fdc/fdc.c.orig 2007-09-15 16:53:23.000000000 +0800
+++ sys/dev/fdc/fdc.c 2007-09-16 16:26:07.000000000 +0800
@@ -1389,6 +1393,8 @@
ae = e + pp->ace;
if (ar == 0 && aw == 0 && ae == 0) {
+ if (debugflags & 0x40)
+ device_printf(fdc->fdc_dev, "marked not busy\n");
device_unbusy(fd->dev);
return (0);
}
@@ -1404,11 +1410,20 @@
fd->flags &= ~FD_NEWDISK;
mtx_unlock(&fdc->fdc_mtx);
}
+ if (debugflags & 0x40)
+ device_printf(fdc->fdc_dev, "marked busy\n");
device_busy(fd->dev);
}
- if (w > 0 && (fd->flags & FD_WP))
+ if (w > 0 && (fd->flags & FD_WP)) {
+ if ((debugflags & 0x100) &&
+ (device_get_state(fd->dev) == DS_BUSY)) {
+ if (debugflags & 0x40)
+ device_printf(fdc->fdc_dev, "marked not busy\n");
+ device_unbusy(fd->dev);
+ }
return (EROFS);
+ }
pp->sectorsize = fd->sectorsize;
pp->stripesize = fd->ft->heads * fd->ft->sectrac * fd->sectorsize;
@@ -1749,6 +1764,7 @@
fdc = device_get_softc(dev);
fdc->fdc_dev = dev;
+ TUNABLE_INT_FETCH("debug.fdc.debugflags", &debugflags);
error = fdc_initial_reset(dev, fdc);
if (error) {
device_printf(dev, "does not respond\n");
>Fix:
Unknown.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list