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.
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to