svn commit: r260267 - head/sys/cam/scsi

Steven Hartland smh at FreeBSD.org
Sat Jan 4 17:52:43 UTC 2014


Author: smh
Date: Sat Jan  4 17:52:43 2014
New Revision: 260267
URL: http://svnweb.freebsd.org/changeset/base/260267

Log:
  Correct short delete issue in SCSI UNMAP support
  Correct missing \n's in xpt_print's
  Correct incorrect count being passed to short delete xpt_print
  
  MFC after:	1 week

Modified:
  head/sys/cam/scsi/scsi_da.c

Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c	Sat Jan  4 17:36:13 2014	(r260266)
+++ head/sys/cam/scsi/scsi_da.c	Sat Jan  4 17:52:43 2014	(r260267)
@@ -211,7 +211,7 @@ struct da_softc {
 	int	 delete_running;
 	int	 delete_available;	/* Delete methods possibly available */
 	uint32_t		unmap_max_ranges;
-	uint32_t		unmap_max_lba;
+	uint32_t		unmap_max_lba; /* Max LBAs in a single range */
 	uint64_t		ws_max_blks;
 	da_delete_methods	delete_method;
 	da_delete_func_t	*delete_func;
@@ -1246,7 +1246,7 @@ daopen(struct disk *dp)
 	error = cam_periph_sleep(periph, &softc->disk->d_mediasize, PRIBIO,
 	    "dareprobe", 0);
 	if (error != 0)
-		xpt_print(periph->path, "unable to retrieve capacity data");
+		xpt_print(periph->path, "unable to retrieve capacity data\n");
 
 	if (periph->flags & CAM_PERIPH_INVALID)
 		error = ENXIO;
@@ -2525,7 +2525,6 @@ da_delete_unmap(struct cam_periph *perip
 	struct bio *bp1;
 	uint8_t *buf = softc->unmap_buf;
 	uint64_t lba, lastlba = (uint64_t)-1;
-	uint64_t totalcount = 0;
 	uint64_t count;
 	uint32_t lastcount = 0, c;
 	uint32_t off, ranges = 0;
@@ -2559,35 +2558,34 @@ da_delete_unmap(struct cam_periph *perip
 			scsi_ulto4b(lastcount, &buf[off + 8]);
 			count -= c;
 			lba +=c;
-			totalcount += c;
 		}
 
 		while (count > 0) {
-			c = min(count, softc->unmap_max_lba);
-			if (totalcount + c > softc->unmap_max_lba ||
-			    ranges >= softc->unmap_max_ranges) {
+			if (ranges > softc->unmap_max_ranges) {
 				xpt_print(periph->path,
-				    "%s issuing short delete %ld > %ld"
-				    "|| %d >= %d",
+				    "%s issuing short delete %d > %d\n",
 				    da_delete_method_desc[softc->delete_method],
-				    totalcount + c, softc->unmap_max_lba,
 				    ranges, softc->unmap_max_ranges);
 				break;
 			}
+			c = min(count, softc->unmap_max_lba);
 			off = (ranges * UNMAP_RANGE_SIZE) + UNMAP_HEAD_SIZE;
 			scsi_u64to8b(lba, &buf[off + 0]);
 			scsi_ulto4b(c, &buf[off + 8]);
 			lba += c;
-			totalcount += c;
 			ranges++;
 			count -= c;
 			lastcount = c;
 		}
 		lastlba = lba;
 		bp1 = bioq_first(&softc->delete_queue);
+		/*
+		 * Assume no range extension on the next loop iteration to
+		 * avoid issuing a short delete.
+		 */
 		if (bp1 == NULL || ranges >= softc->unmap_max_ranges ||
-		    totalcount + bp1->bio_bcount /
-		    softc->params.secsize > softc->unmap_max_lba)
+		    bp1->bio_bcount / softc->params.secsize >
+		    softc->unmap_max_lba * (softc->unmap_max_ranges - ranges))
 			break;
 	} while (1);
 	scsi_ulto2b(ranges * 16 + 6, &buf[0]);
@@ -2658,7 +2656,7 @@ da_delete_trim(struct cam_periph *periph
 			lastcount = c;
 			if (count != 0 && ranges == softc->trim_max_ranges) {
 				xpt_print(periph->path,
-				    "%s issuing short delete %ld > %ld",
+				    "%s issuing short delete %ld > %ld\n",
 				    da_delete_method_desc[softc->delete_method],
 				    requestcount,
 				    (softc->trim_max_ranges - ranges) *
@@ -2690,7 +2688,7 @@ da_delete_trim(struct cam_periph *periph
 /*
  * We calculate ws_max_blks here based off d_delmaxsize instead
  * of using softc->ws_max_blks as it is absolute max for the
- * device not the protocol max which may well be lower
+ * device not the protocol max which may well be lower.
  */
 static void
 da_delete_ws(struct cam_periph *periph, union ccb *ccb, struct bio *bp)
@@ -2713,11 +2711,11 @@ da_delete_ws(struct cam_periph *periph, 
 			bioq_insert_tail(&softc->delete_run_queue, bp1);
 		count += bp1->bio_bcount / softc->params.secsize;
 		if (count > ws_max_blks) {
-			count = min(count, ws_max_blks);
 			xpt_print(periph->path,
-			    "%s issuing short delete %ld > %ld",
+			    "%s issuing short delete %ld > %ld\n",
 			    da_delete_method_desc[softc->delete_method],
 			    count, ws_max_blks);
+			count = min(count, ws_max_blks);
 			break;
 		}
 		bp1 = bioq_first(&softc->delete_queue);


More information about the svn-src-head mailing list