From eugen@grosbein.pp.ru  Sat Sep 22 06:13:27 2007
Return-Path: <eugen@grosbein.pp.ru>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id C723C16A420
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 22 Sep 2007 06:13:27 +0000 (UTC)
	(envelope-from eugen@grosbein.pp.ru)
Received: from grosbein.pp.ru (grgw.svzserv.kemerovo.su [213.184.64.166])
	by mx1.freebsd.org (Postfix) with ESMTP id 1816A13C459
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 22 Sep 2007 06:13:26 +0000 (UTC)
	(envelope-from eugen@grosbein.pp.ru)
Received: from grosbein.pp.ru (localhost [127.0.0.1])
	by grosbein.pp.ru (8.14.1/8.14.1) with ESMTP id l8M6DP09002459
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 22 Sep 2007 14:13:25 +0800 (KRAST)
	(envelope-from eugen@grosbein.pp.ru)
Received: (from eugen@localhost)
	by grosbein.pp.ru (8.14.1/8.14.1/Submit) id l8M6DPGw002458;
	Sat, 22 Sep 2007 14:13:25 +0800 (KRAST)
	(envelope-from eugen)
Message-Id: <200709220613.l8M6DPGw002458@grosbein.pp.ru>
Date: Sat, 22 Sep 2007 14:13:25 +0800 (KRAST)
From: Eugene Grosbein <eugen@grosbein.pp.ru>
Reply-To: Eugene Grosbein <eugen@grosbein.pp.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [fdc] fdc(4) marks /dev/fd0 device busy when it should not, so does not allow to kldunload fdc.ko 
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>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:    kib
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 22 06:20:00 GMT 2007
>Closed-Date:    Fri May 16 11:53:52 UTC 2008
>Last-Modified:  Fri May 16 11:53:52 UTC 2008
>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@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:

From: Kostik Belousov <kostikbel@gmail.com>
To: bug-followup@FreeBSD.org
Cc: eugen@grosbein.pp.ru
Subject: Re: kern/116539: [fdc] fdc(4) marks /dev/fd0 device busy when it should not, so does not allow to kldunload fdc.ko
Date: Tue, 6 Nov 2007 15:25:58 +0200

 device_busy() is counted. Try the following patch:
 
 diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
 index ea033a5..812823a 100644
 --- a/sys/dev/fdc/fdc.c
 +++ b/sys/dev/fdc/fdc.c
 @@ -1383,6 +1383,7 @@ fd_access(struct g_provider *pp, int r, int w, int e)
  	struct fd_data *fd;
  	struct fdc_data *fdc;
  	int ar, aw, ae;
 +	int busy;
  
  	fd = pp->geom->softc;
  	fdc = fd->fdc;
 @@ -1403,6 +1404,7 @@ fd_access(struct g_provider *pp, int r, int w, int e)
  		return (0);
  	}
  
 +	busy = 0;
  	if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) {
  		if (fdmisccmd(fd, BIO_PROBE, NULL))
  			return (ENXIO);
 @@ -1415,10 +1417,14 @@ fd_access(struct g_provider *pp, int r, int w, int e)
  			mtx_unlock(&fdc->fdc_mtx);
  		}
  		device_busy(fd->dev);
 +		busy = 1;
  	}
  
 -	if (w > 0 && (fd->flags & FD_WP))
 +	if (w > 0 && (fd->flags & FD_WP)) {
 +		if (busy)
 +			device_unbusy(fd->dev);
  		return (EROFS);
 +	}
  
  	pp->sectorsize = fd->sectorsize;
  	pp->stripesize = fd->ft->heads * fd->ft->sectrac * fd->sectorsize;

From: System Administrator <root@www.svzserv.kemerovo.su>
To: Kostik Belousov <kostikbel@gmail.com>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/116539: [fdc] fdc(4) marks /dev/fd0 device busy when it should not, so does not allow to kldunload fdc.ko
Date: Sat, 10 Nov 2007 01:03:45 +0700

 On Tue, Nov 06, 2007 at 03:25:58PM +0200, Kostik Belousov wrote:
 
 > device_busy() is counted. Try the following patch:
 
 Hi!
 
 Your patch basically works but next problem is still actual
 for RELENG_6 & RELENG_7:
 http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/116537
 
 Your patch combined with a patch from kern/116537 solve the problem at last.
 
 Thank you!
 Please commit both patches.
 
 Eugene Grosbein
Responsible-Changed-From-To: freebsd-bugs->kib 
Responsible-Changed-By: kib 
Responsible-Changed-When: Fri Jan 11 11:27:01 UTC 2008 
Responsible-Changed-Why:  
Take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116539 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116539: commit references a PR
Date: Fri, 11 Jan 2008 11:53:11 +0000 (UTC)

 kib         2008-01-11 11:53:04 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/dev/fdc          fdc.c 
   Log:
   Fix unload of the fdc.ko:
   
   Wakeup the thread doing the fdc_detach() when the fdc worker thread exits [1].
   Write access to the write-protected floppy shall call device_unbusy() to
   pair the device_busy() in the fd_access() [2].
   
   PR:     116537 [1], 116539 [2]
   MFC after:      1 week
   
   Revision  Changes    Path
   1.319     +8 -1      src/sys/dev/fdc/fdc.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: kib 
State-Changed-When: Fri Jan 11 18:11:07 UTC 2008 
State-Changed-Why:  
Patch is committed. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116539 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116539: commit references a PR
Date: Fri, 16 May 2008 10:33:02 +0000 (UTC)

 kib         2008-05-16 10:32:52 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_6)
     sys/dev/fdc          fdc.c 
   Log:
   MFC rev. 1.320:
   
   The wakeup() line from the rev. 1.319 is wrong and reintroduces
   a panic race on module unload. The wakeup() is internal to
   kproc_exit/kthread_exit. The correct fix is to fix the msleep() in
   detach to sleep on fdc->fdc_thread instead of &fdc->fdc_thread.
   
   MFC rev. 1.319:
   Wakeup the thread doing the fdc_detach() when the fdc worker thread exits [1].
   Write access to the write-protected floppy shall call device_unbusy() to
   pair the device_busy() in the fd_access() [2].
   
   PR:     116537 [1], 116539 [2]
   
   Revision   Changes    Path
   1.307.2.5  +8 -2      src/sys/dev/fdc/fdc.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: kib 
State-Changed-When: Fri May 16 11:53:27 UTC 2008 
State-Changed-Why:  
MFC to the RELENG_6 done. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=116539 
>Unformatted:
