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
This commit is contained in:
parent
fe9781bb78
commit
7582ed74ee
@ -3900,7 +3900,7 @@ ctl_copy_io(union ctl_io *src, union ctl_io *dest)
|
||||
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_scsiio *ctsio, int alloc_len)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
{
|
||||
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_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
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_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
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_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
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_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
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_softc *softc, struct ctl_lun_req *req)
|
||||
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_softc *softc, struct ctl_lun_req *req)
|
||||
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_softc *softc, struct ctl_lun_req *req)
|
||||
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 /
|
||||
|
@ -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.
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user