public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: James Bottomley <James.Bottomley@steeleye.com>
To: Andrew Morton <akpm@osdl.org>
Cc: SCSI Mailing List <linux-scsi@vger.kernel.org>,
	"Brian S. Stephan" <stephanb@msoe.edu>
Subject: Re: Fw: 2.6.4-mm1 and removable USB drive oops
Date: 13 Mar 2004 13:17:06 -0500	[thread overview]
Message-ID: <1079201828.2512.24.camel@mulgrave> (raw)
In-Reply-To: <20040312213831.4b56c469.akpm@osdl.org>

On Sat, 2004-03-13 at 00:38, Andrew Morton wrote:
> James's tree broke.

Well, yes.

The actual problem reported was because there wasn't a corresponding
check on transport_classdev.class in the unregister.

However, on closer inspection I also turned up a nasty thinko in the
reference counting.  For reasons best known to the class code authors,
class devices have to obtain their own references to the devices they're
attached to which they release again in their .release routines, so you
have to remember to do a get_device() in the correct place after the
class_device_add().  I put comments in the code so that, hopefully, we
can avoid the problem in future.

James

===== drivers/scsi/scsi_sysfs.c 1.43 vs edited =====
--- 1.43/drivers/scsi/scsi_sysfs.c	Fri Mar 12 16:50:50 2004
+++ edited/drivers/scsi/scsi_sysfs.c	Sat Mar 13 12:09:30 2004
@@ -367,15 +367,20 @@
 		printk(KERN_INFO "error 2\n");
 		goto clean_device;
 	}
+	/* take a reference for the sdev_classdev; this is
+	 * released by the sdev_class .release */
+	get_device(&sdev->sdev_gendev);
 
 	if (sdev->transport_classdev.class) {
 		error = class_device_add(&sdev->transport_classdev);
 		if (error)
 			goto clean_device2;
+		/* take a reference for the transport_classdev; this
+		 * is released by the transport_class .release */
+		get_device(&sdev->sdev_gendev);
+		
 	}
 
-	get_device(&sdev->sdev_gendev);
-
 	if (sdev->host->hostt->sdev_attrs) {
 		for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
 			error = attr_add(&sdev->sdev_gendev,
@@ -434,7 +439,8 @@
 	if (sdev->sdev_state == SDEV_RUNNING || sdev->sdev_state == SDEV_CANCEL) {
 		scsi_device_set_state(sdev, SDEV_DEL);
 		class_device_unregister(&sdev->sdev_classdev);
-		class_device_unregister(&sdev->transport_classdev);
+		if(sdev->transport_classdev.class)
+			class_device_unregister(&sdev->transport_classdev);
 		device_del(&sdev->sdev_gendev);
 		if (sdev->host->hostt->slave_destroy)
 			sdev->host->hostt->slave_destroy(sdev);


      reply	other threads:[~2004-03-13 18:17 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-13  5:38 Fw: 2.6.4-mm1 and removable USB drive oops Andrew Morton
2004-03-13 18:17 ` James Bottomley [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1079201828.2512.24.camel@mulgrave \
    --to=james.bottomley@steeleye.com \
    --cc=akpm@osdl.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=stephanb@msoe.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox