svn commit: r275865 - in head: sys/cam/ctl usr.sbin/ctladm

Alexander Motin mav at FreeBSD.org
Wed Dec 17 17:30:56 UTC 2014


Author: mav
Date: Wed Dec 17 17:30:54 2014
New Revision: 275865
URL: https://svnweb.freebsd.org/changeset/base/275865

Log:
  Add configuration options to override physical and UNMAP blocks geometry.
  
  While in most cases CTL should correctly fetch those values from backing
  storages, there are some initiators (like MS SQL), that may not like large
  physical block sizes, even if they are true.  For such cases allow override
  fetched values with supported ones (like 4K).
  
  MFC after:	1 week

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/ctl/ctl.h
  head/sys/cam/ctl/ctl_backend.h
  head/sys/cam/ctl/ctl_backend_block.c
  head/usr.sbin/ctladm/ctladm.8

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Wed Dec 17 15:13:21 2014	(r275864)
+++ head/sys/cam/ctl/ctl.c	Wed Dec 17 17:30:54 2014	(r275865)
@@ -3900,7 +3900,7 @@ ctl_copy_io(union ctl_io *src, union ctl
 	dest->io_hdr.flags |= CTL_FLAG_INT_COPY;
 }
 
-static int
+int
 ctl_expand_number(const char *buf, uint64_t *num)
 {
 	char *endptr;
@@ -10146,10 +10146,10 @@ ctl_inquiry_evpd_block_limits(struct ctl
 		if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) {
 			scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt);
 			scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_blk_cnt);
-			if (lun->be_lun->pblockexp != 0) {
-				scsi_ulto4b((1 << lun->be_lun->pblockexp),
+			if (lun->be_lun->ublockexp != 0) {
+				scsi_ulto4b((1 << lun->be_lun->ublockexp),
 				    bl_ptr->opt_unmap_grain);
-				scsi_ulto4b(0x80000000 | lun->be_lun->pblockoff,
+				scsi_ulto4b(0x80000000 | lun->be_lun->ublockoff,
 				    bl_ptr->unmap_grain_align);
 			}
 		}

Modified: head/sys/cam/ctl/ctl.h
==============================================================================
--- head/sys/cam/ctl/ctl.h	Wed Dec 17 15:13:21 2014	(r275864)
+++ head/sys/cam/ctl/ctl.h	Wed Dec 17 17:30:54 2014	(r275865)
@@ -206,6 +206,7 @@ struct ctl_be_arg;
 void ctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args);
 void ctl_free_opts(ctl_options_t *opts);
 char * ctl_get_opt(ctl_options_t *opts, const char *name);
+int ctl_expand_number(const char *buf, uint64_t *num);
 
 #endif	/* _KERNEL */
 

Modified: head/sys/cam/ctl/ctl_backend.h
==============================================================================
--- head/sys/cam/ctl/ctl_backend.h	Wed Dec 17 15:13:21 2014	(r275864)
+++ head/sys/cam/ctl/ctl_backend.h	Wed Dec 17 17:30:54 2014	(r275865)
@@ -194,6 +194,8 @@ struct ctl_be_lun {
 	uint32_t		blocksize;	/* passed to CTL */
 	uint16_t		pblockexp;	/* passed to CTL */
 	uint16_t		pblockoff;	/* passed to CTL */
+	uint16_t		ublockexp;	/* passed to CTL */
+	uint16_t		ublockoff;	/* passed to CTL */
 	uint32_t		atomicblock;	/* passed to CTL */
 	uint32_t		req_lun_id;	/* passed to CTL */
 	uint32_t		lun_id;		/* returned from CTL */

Modified: head/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend_block.c	Wed Dec 17 15:13:21 2014	(r275864)
+++ head/sys/cam/ctl/ctl_backend_block.c	Wed Dec 17 17:30:54 2014	(r275865)
@@ -173,6 +173,8 @@ struct ctl_be_block_lun {
 	int blocksize_shift;
 	uint16_t pblockexp;
 	uint16_t pblockoff;
+	uint16_t ublockexp;
+	uint16_t ublockoff;
 	struct ctl_be_block_softc *softc;
 	struct devstat *disk_stats;
 	ctl_be_block_lun_flags flags;
@@ -1739,8 +1741,9 @@ ctl_be_block_open_file(struct ctl_be_blo
 {
 	struct ctl_be_block_filedata *file_data;
 	struct ctl_lun_create_params *params;
+	char			     *value;
 	struct vattr		      vattr;
-	off_t			      pss;
+	off_t			      ps, pss, po, pos, us, uss, uo, uos;
 	int			      error;
 
 	error = 0;
@@ -1800,11 +1803,36 @@ ctl_be_block_open_file(struct ctl_be_blo
 		be_lun->blocksize = params->blocksize_bytes;
 	else
 		be_lun->blocksize = 512;
-	pss = vattr.va_blocksize / be_lun->blocksize;
-	if ((pss > 0) && (pss * be_lun->blocksize == vattr.va_blocksize) &&
-	    ((pss & (pss - 1)) == 0)) {
+
+	us = ps = vattr.va_blocksize;
+	uo = po = 0;
+
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblocksize");
+	if (value != NULL)
+		ctl_expand_number(value, &ps);
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblockoffset");
+	if (value != NULL)
+		ctl_expand_number(value, &po);
+	pss = ps / be_lun->blocksize;
+	pos = po / be_lun->blocksize;
+	if ((pss > 0) && (pss * be_lun->blocksize == ps) && (pss >= pos) &&
+	    ((pss & (pss - 1)) == 0) && (pos * be_lun->blocksize == po)) {
 		be_lun->pblockexp = fls(pss) - 1;
-		be_lun->pblockoff = 0;
+		be_lun->pblockoff = (pss - pos) % pss;
+	}
+
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublocksize");
+	if (value != NULL)
+		ctl_expand_number(value, &us);
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublockoffset");
+	if (value != NULL)
+		ctl_expand_number(value, &uo);
+	uss = us / be_lun->blocksize;
+	uos = uo / be_lun->blocksize;
+	if ((uss > 0) && (uss * be_lun->blocksize == us) && (uss >= uos) &&
+	    ((uss & (uss - 1)) == 0) && (uos * be_lun->blocksize == uo)) {
+		be_lun->ublockexp = fls(uss) - 1;
+		be_lun->ublockoff = (uss - uos) % uss;
 	}
 
 	/*
@@ -1827,8 +1855,9 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 	struct vattr		      vattr;
 	struct cdev		     *dev;
 	struct cdevsw		     *devsw;
+	char			     *value;
 	int			      error;
-	off_t			      ps, pss, po, pos;
+	off_t			      ps, pss, po, pos, us, uss, uo, uos;
 
 	params = &be_lun->params;
 
@@ -1942,6 +1971,15 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 		if (error)
 			po = 0;
 	}
+	us = ps;
+	uo = po;
+
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblocksize");
+	if (value != NULL)
+		ctl_expand_number(value, &ps);
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "pblockoffset");
+	if (value != NULL)
+		ctl_expand_number(value, &po);
 	pss = ps / be_lun->blocksize;
 	pos = po / be_lun->blocksize;
 	if ((pss > 0) && (pss * be_lun->blocksize == ps) && (pss >= pos) &&
@@ -1950,6 +1988,20 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 		be_lun->pblockoff = (pss - pos) % pss;
 	}
 
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublocksize");
+	if (value != NULL)
+		ctl_expand_number(value, &us);
+	value = ctl_get_opt(&be_lun->ctl_be_lun.options, "ublockoffset");
+	if (value != NULL)
+		ctl_expand_number(value, &uo);
+	uss = us / be_lun->blocksize;
+	uos = uo / be_lun->blocksize;
+	if ((uss > 0) && (uss * be_lun->blocksize == us) && (uss >= uos) &&
+	    ((uss & (uss - 1)) == 0) && (uos * be_lun->blocksize == uo)) {
+		be_lun->ublockexp = fls(uss) - 1;
+		be_lun->ublockoff = (uss - uos) % uss;
+	}
+
 	return (0);
 }
 
@@ -2162,6 +2214,8 @@ ctl_be_block_create(struct ctl_be_block_
 		be_lun->blocksize = 0;
 		be_lun->pblockexp = 0;
 		be_lun->pblockoff = 0;
+		be_lun->ublockexp = 0;
+		be_lun->ublockoff = 0;
 		be_lun->size_blocks = 0;
 		be_lun->size_bytes = 0;
 		be_lun->ctl_be_lun.maxlba = 0;
@@ -2212,6 +2266,8 @@ ctl_be_block_create(struct ctl_be_block_
 	be_lun->ctl_be_lun.blocksize = be_lun->blocksize;
 	be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp;
 	be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
+	be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp;
+	be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff;
 	if (be_lun->dispatch == ctl_be_block_dispatch_zvol &&
 	    be_lun->blocksize != 0)
 		be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE /
@@ -2591,6 +2647,8 @@ ctl_be_block_modify(struct ctl_be_block_
 		be_lun->ctl_be_lun.blocksize = be_lun->blocksize;
 		be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp;
 		be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
+		be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp;
+		be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff;
 		if (be_lun->dispatch == ctl_be_block_dispatch_zvol &&
 		    be_lun->blocksize != 0)
 			be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE /

Modified: head/usr.sbin/ctladm/ctladm.8
==============================================================================
--- head/usr.sbin/ctladm/ctladm.8	Wed Dec 17 15:13:21 2014	(r275864)
+++ head/usr.sbin/ctladm/ctladm.8	Wed Dec 17 17:30:54 2014	(r275865)
@@ -34,7 +34,7 @@
 .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
 .\" $FreeBSD$
 .\"
-.Dd December 6, 2014
+.Dd December 17, 2014
 .Dt CTLADM 8
 .Os
 .Sh NAME
@@ -1002,6 +1002,13 @@ Set to "off" to allow them be issued in 
 Parallel issue of consecutive operations may confuse logic of the
 backing file system, hurting performance; but it may improve performance
 of backing stores without prefetch/write-back.
+.It Va psectorsize
+.It Va psectoroffset
+Specify physical block size and offset of the device.
+.It Va usectorsize
+.It Va usectoroffset
+Specify UNMAP block size and offset of the device.
+.It Va rpm
 .It Va rpm
 Specifies medium rotation rate of the device: 0 -- not reported,
 1 -- non-rotating (SSD), >1024 -- value in revolutions per minute.


More information about the svn-src-all mailing list