Author: mav
Date: Wed Dec 24 13:49:40 2014
New Revision: 276179
URL: https://svnweb.freebsd.org/changeset/base/276179

Log:
  MFC r275865:
  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).

Modified:
  stable/10/sys/cam/ctl/ctl.c
  stable/10/sys/cam/ctl/ctl.h
  stable/10/sys/cam/ctl/ctl_backend.h
  stable/10/sys/cam/ctl/ctl_backend_block.c
  stable/10/usr.sbin/ctladm/ctladm.8
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cam/ctl/ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl.c Wed Dec 24 13:25:22 2014        (r276178)
+++ stable/10/sys/cam/ctl/ctl.c Wed Dec 24 13:49:40 2014        (r276179)
@@ -3902,7 +3902,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;
@@ -10148,10 +10148,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: stable/10/sys/cam/ctl/ctl.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl.h Wed Dec 24 13:25:22 2014        (r276178)
+++ stable/10/sys/cam/ctl/ctl.h Wed Dec 24 13:49:40 2014        (r276179)
@@ -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: stable/10/sys/cam/ctl/ctl_backend.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl_backend.h Wed Dec 24 13:25:22 2014        
(r276178)
+++ stable/10/sys/cam/ctl/ctl_backend.h Wed Dec 24 13:49:40 2014        
(r276179)
@@ -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: stable/10/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl_backend_block.c   Wed Dec 24 13:25:22 2014        
(r276178)
+++ stable/10/sys/cam/ctl/ctl_backend_block.c   Wed Dec 24 13:49:40 2014        
(r276179)
@@ -175,6 +175,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;
@@ -1742,8 +1744,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;
@@ -1803,11 +1806,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;
        }
 
        /*
@@ -1830,8 +1858,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;
 
@@ -1945,6 +1974,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) &&
@@ -1953,6 +1991,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);
 }
 
@@ -2165,6 +2217,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;
@@ -2215,6 +2269,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 /
@@ -2594,6 +2650,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: stable/10/usr.sbin/ctladm/ctladm.8
==============================================================================
--- stable/10/usr.sbin/ctladm/ctladm.8  Wed Dec 24 13:25:22 2014        
(r276178)
+++ stable/10/usr.sbin/ctladm/ctladm.8  Wed Dec 24 13:49:40 2014        
(r276179)
@@ -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-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to