public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: James Bottomley <James.Bottomley@HansenPartnership.com>
To: brace@beardog.cca.cpqcorp.net
Cc: linux-scsi@vger.kernel.org, fujita.tomonori@lab.ntt.co.jp
Subject: Re: Problems adding/removing scsi devices.
Date: Thu, 28 Aug 2008 13:11:44 -0500	[thread overview]
Message-ID: <1219947104.3378.9.camel@localhost.localdomain> (raw)
In-Reply-To: <20080828174623.GA3611@beardog.cca.cpqcorp.net>

On Thu, 2008-08-28 at 12:46 -0500, brace@beardog.cca.cpqcorp.net wrote:
> I am having problems with my scsi driver. There is an application that issues
> configuration changes to my driver to add/remove scsi devices. 
> 
> I am having a problem with the following sequence:
> 	1) Add a drive. 
> 	2) Remove the drive.
> 	3) Add the drive back.
> 
> The first two work correctly, the third works, but the drive's sdev_state is 
> set to SDEV_DEL and can no longer be managed.
> 
> To delete the scsi_device, The driver does the following:
> 
> struct scsi_device *sdev = scsi_device_lookup(sh, removed[i].bus, 
> 					removed[i].target,removed[i].lun);
> if (sdev != NULL) {
> 	scsi_remove_device(sdev);
> 	scsi_device_put(sdev);
> }
> 
> Later on that application adds a scsi_device. (Using the same bus, target, 
> and lun as before).
> 
> rc = scsi_add_device(sh, added[i].bus, added[i].target, added[i].lun);
> if (rc == 0) {
> 	printk(DRIVERNAME "%d: shost[%p] added b%dt%dl%d\n", h->ctlr_num, sh,
> 				added[i].bus, added[i].target, added[i].lun);
> 	struct scsi_device *sdev = scsi_device_lookup(sh, added[i].bus, 
> 						added[i].target, added[i].lun);
> 	printk(DRIVERNAME "%d: shost[%p] looked up sdev[%p]\n", h->ctlr_num,sh,sdev);
> 	continue;
> }
> 
> The scsi_device_lookup() call after the scsi_device_add() fails because the 
> scsi_device.sdev_state is set to SDEV_DEL. 

This means something else still has a reference to the old scsi device.
Until that reference is released, the old structure can't be garbage
collected and removed from the lists.

> I added code to scsi_add_device() and printed out the state just before the 
> return statement, it is SDEV_RUNNING. After returning back to my driver, the 
> scsi_device.sdev_state is set to SDEV_DEL. 
> 
> int scsi_add_device(struct Scsi_Host *host,                     rc = scsi_add_device(sh, added[i].bus,
>                     uint channel, uint target, uint lun)                           added[i].target, added[i].lun);
> {                                                               ==>// Here the state is SDEV_DEL.
> 
> 	struct scsi_device *sdev = __scsi_add_device(host, 
>                                                      channel, 
>                                                      target, 
>                                                      lun, NULL); 
> 	if (IS_ERR(sdev)) 
> 		return PTR_ERR(sdev); 
> 		scsi_device_put(sdev); 
> 		printk("sdev[%p] state = %04x\n", sdev.sdev_state); <===== Here is is running.
> 	return 0;
> }
> 
> Can you not add, remove, and add the same bus, target, lun?

Not and expect it to come back as the same device no.  This is the
essence of the reference counting problems in Linux:  we can't force
other things to give up object references, we can merely put the object
into a dead state and wait for all outstanding references to be
released.

There was a proposal to resurrect devices in SDEV_DEL, but it has quite
a few nasty corner cases.  I thought the replacement proposal was to
make scsi_device_lookup() skip over devices in SDEV_DEL (so it would
find the live one if one were in the list).

However, if, as I suspect, your outstanding reference is say a mounted
filesystem or other user space application, then you're out of luck if
you're expecting scsi_add_device() to magically reconnect the new device
to the filesystem.

James



      reply	other threads:[~2008-08-28 18:11 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-28 17:46 Problems adding/removing scsi devices brace
2008-08-28 18:11 ` 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=1219947104.3378.9.camel@localhost.localdomain \
    --to=james.bottomley@hansenpartnership.com \
    --cc=brace@beardog.cca.cpqcorp.net \
    --cc=fujita.tomonori@lab.ntt.co.jp \
    --cc=linux-scsi@vger.kernel.org \
    /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