Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Sep 2013 09:06:32 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r255547 - in stable/9/sys/cam: ata scsi
Message-ID:  <201309140906.r8E96W7s093157@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Sep 14 09:06:32 2013
New Revision: 255547
URL: http://svnweb.freebsd.org/changeset/base/255547

Log:
  MFC r253724:
  Synchronize device cache on close only if there were some write operations.
  While these operations are not really needed otherwise, at least for SCSI
  they may cause extra errors if some other initiator holds write exclusive
  reservation on the LUN (SYNCHRONIZE CACHE handled as "write" operation).

Modified:
  stable/9/sys/cam/ata/ata_da.c
  stable/9/sys/cam/scsi/scsi_da.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/cam/ata/ata_da.c
==============================================================================
--- stable/9/sys/cam/ata/ata_da.c	Sat Sep 14 09:05:03 2013	(r255546)
+++ stable/9/sys/cam/ata/ata_da.c	Sat Sep 14 09:06:32 2013	(r255547)
@@ -88,7 +88,8 @@ typedef enum {
 	ADA_FLAG_SCTX_INIT	= 0x0200,
 	ADA_FLAG_CAN_CFA        = 0x0400,
 	ADA_FLAG_CAN_POWERMGT   = 0x0800,
-	ADA_FLAG_CAN_DMA48	= 0x1000
+	ADA_FLAG_CAN_DMA48	= 0x1000,
+	ADA_FLAG_DIRTY		= 0x2000
 } ada_flags;
 
 typedef enum {
@@ -613,6 +614,7 @@ adaclose(struct disk *dp)
 	struct	cam_periph *periph;
 	struct	ada_softc *softc;
 	union ccb *ccb;
+	int error;
 
 	periph = (struct cam_periph *)dp->d_drv1;
 	cam_periph_lock(periph);
@@ -628,7 +630,8 @@ adaclose(struct disk *dp)
 	    ("adaclose\n"));
 
 	/* We only sync the cache if the drive is capable of it. */
-	if ((softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
+	if ((softc->flags & ADA_FLAG_DIRTY) != 0 &&
+	    (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
 	    (softc->flags & ADA_FLAG_PACK_INVALID) == 0) {
 
 		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
@@ -645,11 +648,13 @@ adaclose(struct disk *dp)
 			ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
 		else
 			ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
-		cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
+		error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
 		    /*sense_flags*/0, softc->disk->d_devstat);
 
-		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+		if (error != 0)
 			xpt_print(periph->path, "Synchronize cache failed\n");
+		else
+			softc->flags &= ~ADA_FLAG_DIRTY;
 		xpt_release_ccb(ccb);
 	}
 
@@ -1498,8 +1503,10 @@ adastart(struct cam_periph *periph, unio
 			tag_code = 1;
 		}
 		switch (bp->bio_cmd) {
-		case BIO_READ:
 		case BIO_WRITE:
+			softc->flags |= ADA_FLAG_DIRTY;
+			/* FALLTHROUGH */
+		case BIO_READ:
 		{
 			uint64_t lba = bp->bio_pblkno;
 			uint16_t count = bp->bio_bcount / softc->params.secsize;

Modified: stable/9/sys/cam/scsi/scsi_da.c
==============================================================================
--- stable/9/sys/cam/scsi/scsi_da.c	Sat Sep 14 09:05:03 2013	(r255546)
+++ stable/9/sys/cam/scsi/scsi_da.c	Sat Sep 14 09:06:32 2013	(r255547)
@@ -90,7 +90,8 @@ typedef enum {
 	DA_FLAG_OPEN		= 0x100,
 	DA_FLAG_SCTX_INIT	= 0x200,
 	DA_FLAG_CAN_RC16	= 0x400,
-	DA_FLAG_PROBED		= 0x800		
+	DA_FLAG_PROBED		= 0x800,
+	DA_FLAG_DIRTY		= 0x1000
 } da_flags;
 
 typedef enum {
@@ -1249,6 +1250,7 @@ daclose(struct disk *dp)
 {
 	struct	cam_periph *periph;
 	struct	da_softc *softc;
+	int error;
 
 	periph = (struct cam_periph *)dp->d_drv1;
 	cam_periph_lock(periph);
@@ -1263,8 +1265,9 @@ daclose(struct disk *dp)
 	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
 	    ("daclose\n"));
 
-	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0
-	 && (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
+	if ((softc->flags & DA_FLAG_DIRTY) != 0 &&
+	    (softc->quirks & DA_Q_NO_SYNC_CACHE) == 0 &&
+	    (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
 		union	ccb *ccb;
 
 		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
@@ -1278,9 +1281,11 @@ daclose(struct disk *dp)
 				       SSD_FULL_SIZE,
 				       5 * 60 * 1000);
 
-		cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
+		error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
 				  /*sense_flags*/SF_RETRY_UA | SF_QUIET_IR,
 				  softc->disk->d_devstat);
+		if (error == 0)
+			softc->flags &= ~DA_FLAG_DIRTY;
 		xpt_release_ccb(ccb);
 
 	}
@@ -2252,8 +2257,10 @@ skipstate:
 		}
 
 		switch (bp->bio_cmd) {
-		case BIO_READ:
 		case BIO_WRITE:
+			softc->flags |= DA_FLAG_DIRTY;
+			/* FALLTHROUGH */
+		case BIO_READ:
 			scsi_read_write(&start_ccb->csio,
 					/*retries*/da_retry_count,
 					/*cbfcnp*/dadone,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309140906.r8E96W7s093157>