[PATCH] sd: improve logic and efficiecy of media-change detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch (as1415) improves the formerly incomprehensible logic in
sd_media_changed() (the current code refers to "changed" as a state,
whereas in fact it is a relation between two states).  It also adds a
big comment so that everyone can understand what is really going on.

The patch also improves efficiency by not reporting a media change
when no medium was ever present.  If no medium was present the last
time we checked and there's still no medium, it's not necessary to
tell the caller that a change occurred.  Doing so merely causes the
caller to attempt to revalidate a non-existent disk, which is a waste
of time.

Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

---

Index: usb-2.6/drivers/scsi/sd.c
===================================================================
--- usb-2.6.orig/drivers/scsi/sd.c
+++ usb-2.6/drivers/scsi/sd.c
@@ -561,7 +561,7 @@ static int sd_prep_fn(struct request_que
 		 * quietly refuse to do anything to a changed disc until 
 		 * the changed bit has been reset
 		 */
-		/* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
+		/* printk("SCSI disk has been changed or is not present. Prohibiting further I/O.\n"); */
 		goto out;
 	}
 
@@ -1001,7 +1001,6 @@ static int sd_media_changed(struct gendi
 	 */
 	if (!scsi_device_online(sdp)) {
 		set_media_not_present(sdkp);
-		retval = 1;
 		goto out;
 	}
 
@@ -1032,7 +1031,6 @@ static int sd_media_changed(struct gendi
 		       /* 0x3a is medium not present */
 		       sshdr->asc == 0x3a)) {
 		set_media_not_present(sdkp);
-		retval = 1;
 		goto out;
 	}
 
@@ -1043,12 +1041,27 @@ static int sd_media_changed(struct gendi
 	 */
 	sdkp->media_present = 1;
 
-	retval = sdp->changed;
-	sdp->changed = 0;
 out:
-	if (retval != sdkp->previous_state)
+	/*
+	 * Report a media change under the following conditions:
+	 *
+	 *	Medium is present now and wasn't present before.
+	 *	Medium wasn't present before and is present now.
+	 *	Medium was present at all times, but it changed while
+	 *		we weren't looking (sdp->changed is set).
+	 *
+	 * If there was no medium before and there is no medium now then
+	 * don't report a change, even if a medium was inserted and removed
+	 * while we weren't looking.
+	 */
+	retval = (sdkp->media_present != sdkp->previous_state ||
+			(sdkp->media_present && sdp->changed));
+	if (retval)
 		sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
-	sdkp->previous_state = retval;
+	sdkp->previous_state = sdkp->media_present;
+
+	/* sdp->changed indicates medium was changed or is not present */
+	sdp->changed = !sdkp->media_present;
 	kfree(sshdr);
 	return retval;
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux