aboutsummaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2021-06-07 15:21:01 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2021-06-07 15:21:01 +0000
commit30363466e3580cae5f428c9bf35caa934cef469b (patch)
tree265f9bd6b4a8ebcf7102908ca0596dc1f42ce28a /testing
parentd65eadbdaa302c7b83c059569a28efd3304947e4 (diff)
downloadsg3_utils-30363466e3580cae5f428c9bf35caa934cef469b.tar.gz
sg_vpd: fix do_hex type on some recent pages; sg_dd: don't close negative file descriptors; pt_linux_nvme: fix fua setting
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@903 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r--testing/sg_mrq_dd.cpp107
-rw-r--r--testing/sgh_dd.cpp87
-rw-r--r--testing/uapi_sg.h3
3 files changed, 117 insertions, 80 deletions
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 00296025..57382f4e 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.29 20210515";
+static const char * version_str = "1.30 20210606";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -189,6 +189,7 @@ struct flags_t {
bool fua;
bool hipri;
bool masync; /* more async sg v4 driver fd flag */
+ bool mout_if; /* META_OUT_IF flag at mrq level */
bool nocreat;
bool no_dur;
bool no_thresh;
@@ -307,6 +308,8 @@ typedef struct request_element
int mrq_id;
int mrq_index;
int mrq_pack_id_off;
+ uint32_t a_mrq_din_blks;
+ uint32_t a_mrq_dout_blks;
int64_t in_follow_on;
int64_t out_follow_on;
int64_t in_local_count;
@@ -579,7 +582,12 @@ sg_flags_str(int flags, int b_len, char * b)
goto fini;
}
if (SGV4_FLAG_REC_ORDER & flags) { /* 0x100000 */
- n += sg_scnpr(b + n, b_len - n, "RECO|");
+ n += sg_scnpr(b + n, b_len - n, "REC_O|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SGV4_FLAG_META_OUT_IF & flags) { /* 0x200000 */
+ n += sg_scnpr(b + n, b_len - n, "MOUT_IF|");
if (n >= b_len)
goto fini;
}
@@ -885,9 +893,9 @@ usage(int pg_num)
" if file or device to read from (def: stdin)\n"
" iflag comma separated list from: [00,coe,dio,"
"direct,dpo,\n"
- " dsync,excl,ff,fua,masync,mmap,nodur,null,"
- "order,\n"
- " qhead,qtail,random,serial,wq_excl]\n"
+ " dsync,excl,ff,fua,masync,mmap,mout_if,nodur,"
+ "null,\n"
+ " order,qhead,qtail,random,serial,wq_excl]\n"
" of file or device to write to (def: /dev/null "
"N.B. different\n"
" from dd it defaults to stdout). If 'of=.' "
@@ -985,6 +993,7 @@ page3:
" masync set 'more async' flag on this sg device\n"
" mmap setup mmap IO on IFILE or OFILE\n"
" mmap,mmap when used twice, doesn't call munmap()\n"
+ " mout_if set META_OUT_IF flag on control object\n"
" nocreat will fail rather than create OFILE\n"
" nodur turns off command duration calculations\n"
" no_thresh skip checking per fd max data xfer size\n"
@@ -1199,11 +1208,9 @@ sig_listen_thread(struct global_collection * clp)
static bool
sg_share_prepare(int write_side_fd, int read_side_fd, int id, bool vb_b)
{
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info sei {};
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_SHARE_FD;
seip->sei_rd_mask |= SG_SEIM_SHARE_FD;
seip->share_fd = read_side_fd;
@@ -1223,11 +1230,9 @@ sg_share_prepare(int write_side_fd, int read_side_fd, int id, bool vb_b)
static void
sg_take_snap(int sg_fd, int id, bool vb_b)
{
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info sei {};
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS;
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_SNAP_DEV;
@@ -1246,7 +1251,7 @@ sg_take_snap(int sg_fd, int id, bool vb_b)
static void
read_write_thread(struct global_collection * clp, int id, bool singleton)
{
- Rq_elem rel;
+ Rq_elem rel {};
Rq_elem * rep = &rel;
int n, sz, fd, vb, err, seg_blks;
int res = 0;
@@ -1266,7 +1271,6 @@ read_write_thread(struct global_collection * clp, int id, bool singleton)
in_mmap = (in_is_sg && (clp->in_flags.mmap > 0));
out_is_sg = (FT_SG == clp->out_type);
out_mmap = (out_is_sg && (clp->out_flags.mmap > 0));
- memset(rep, 0, sizeof(Rq_elem));
rep->clp = clp;
rep->id = id;
@@ -1813,6 +1817,14 @@ process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
ok = true;
f1 = !!(a_v4p->info); /* want to skip n_subm count if info is 0x0 */
if (SG_INFO_CHECK & a_v4p->info) {
+ if ((0 == k) && (SGV4_FLAG_META_OUT_IF & ctl_v4p->flags) &&
+ (UINT32_MAX == a_v4p->info)) {
+ hole_count = 0;
+ n_good = num_mrq;
+ good_inblks = rep->a_mrq_din_blks;
+ good_outblks = rep->a_mrq_dout_blks;
+ break;
+ }
ok = false;
pr2serr_lk("[%d] a_v4[%d]: SG_INFO_CHECK set [%s]\n", id, k,
sg_info_str(a_v4p->info, sizeof(b), b));
@@ -1898,8 +1910,8 @@ sg_half_segment_mrq0(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
int num, kk, lin_blks, cdbsz, err;
uint32_t q_blks = 0;
struct global_collection * clp = rep->clp;
- cdb_arr_t t_cdb = {};
- struct sg_io_v4 t_v4;
+ cdb_arr_t t_cdb {};
+ struct sg_io_v4 t_v4 {};
struct sg_io_v4 * t_v4p = &t_v4;
struct flags_t * flagsp = is_wr ? &clp->out_flags : &clp->in_flags;
int vb = clp->verbose;
@@ -1940,7 +1952,6 @@ sg_half_segment_mrq0(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
} else if (vb > 3)
lk_print_command_len("cdb: ", t_cdb.data(), cdbsz, true);
- memset(t_v4p, 0, sizeof(*t_v4p));
t_v4p->guard = 'Q';
t_v4p->request = (uint64_t)t_cdb.data();
t_v4p->usr_ptr = t_v4p->request;
@@ -1951,9 +1962,11 @@ sg_half_segment_mrq0(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
if (is_wr) {
t_v4p->dout_xfer_len = num * clp->bs;
t_v4p->dout_xferp = (uint64_t)(dp + (q_blks * clp->bs));
+ t_v4p->din_xfer_len = 0;
} else {
t_v4p->din_xfer_len = num * clp->bs;
t_v4p->din_xferp = (uint64_t)(dp + (q_blks * clp->bs));
+ t_v4p->dout_xfer_len = 0;
}
t_v4p->timeout = clp->cmd_timeout;
t_v4p->request_extra = pack_id_base + ++rep->mrq_pack_id_off;
@@ -2005,12 +2018,12 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
uint32_t out_mrq_q_blks = 0;
const int max_cdb_sz = MAX_SCSI_CDB_SZ;
struct sg_io_v4 * a_v4p;
- struct sg_io_v4 ctl_v4; /* MRQ control object */
+ struct sg_io_v4 ctl_v4 {}; /* MRQ control object */
struct global_collection * clp = rep->clp;
const char * iosub_str = "SG_IOSUBMIT(variable blocking)";
char b[80];
- cdb_arr_t t_cdb = {};
- struct sg_io_v4 t_v4;
+ cdb_arr_t t_cdb {};
+ struct sg_io_v4 t_v4 {};
struct sg_io_v4 * t_v4p = &t_v4;
struct flags_t * flagsp = is_wr ? &clp->out_flags : &clp->in_flags;
bool serial = flagsp->serial;
@@ -2024,6 +2037,8 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
a_cdb.clear();
a_v4.clear();
+ rep->a_mrq_din_blks = 0;
+ rep->a_mrq_dout_blks = 0;
mrq_pack_id_base = id * PACK_ID_TID_MULTIPLIER;
rflags = 0;
@@ -2060,7 +2075,6 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
lk_print_command_len("cdb: ", t_cdb.data(), cdbsz, true);
a_cdb.push_back(t_cdb);
- memset(t_v4p, 0, sizeof(*t_v4p));
t_v4p->guard = 'Q';
t_v4p->flags = rflags;
t_v4p->request_len = cdbsz;
@@ -2069,11 +2083,15 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
t_v4p->flags = rflags;
t_v4p->usr_ptr = (uint64_t)&a_cdb[a_cdb.size() - 1];
if (is_wr) {
+ rep->a_mrq_dout_blks += num;
t_v4p->dout_xfer_len = num * clp->bs;
t_v4p->dout_xferp = (uint64_t)(dp + (mrq_q_blks * clp->bs));
+ t_v4p->din_xfer_len = 0;
} else {
+ rep->a_mrq_din_blks += num;
t_v4p->din_xfer_len = num * clp->bs;
t_v4p->din_xferp = (uint64_t)(dp + (mrq_q_blks * clp->bs));
+ t_v4p->dout_xfer_len = 0;
}
t_v4p->timeout = clp->cmd_timeout;
mrq_q_blks += num;
@@ -2095,7 +2113,6 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
num_mrq = a_v4.size();
a_v4p = a_v4.data();
res = 0;
- memset(&ctl_v4, 0, sizeof(ctl_v4));
ctl_v4.guard = 'Q';
ctl_v4.request_len = a_cdb.size() * max_cdb_sz;
ctl_v4.request = (uint64_t)a_cdb.data();
@@ -2106,6 +2123,11 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
ctl_v4.flags |= SGV4_FLAG_STOP_IF;
if (clp->mrq_hipri)
ctl_v4.flags |= SGV4_FLAG_HIPRI;
+ if (clp->in_flags.mout_if || clp->out_flags.mout_if) {
+ ctl_v4.flags |= SGV4_FLAG_META_OUT_IF;
+ if (num_mrq > 0)
+ a_v4[0].info = UINT32_MAX;
+ }
ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */
ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4);
ctl_v4.din_xferp = (uint64_t)a_v4.data(); /* response array */
@@ -2427,8 +2449,8 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it,
uint32_t out_fin_blks = 0;
struct global_collection * clp = rep->clp;
int vb = clp->verbose;
- cdb_arr_t t_cdb = {};
- struct sg_io_v4 t_v4;
+ cdb_arr_t t_cdb {};
+ struct sg_io_v4 t_v4 {};
struct sg_io_v4 * t_v4p = &t_v4;
struct flags_t * iflagsp = &clp->in_flags;
struct flags_t * oflagsp = &clp->out_flags;
@@ -2486,7 +2508,6 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it,
} else if (vb > 3)
lk_print_command_len("input cdb: ", t_cdb.data(), cdbsz, true);
- memset(t_v4p, 0, sizeof(*t_v4p));
t_v4p->guard = 'Q';
t_v4p->request = (uint64_t)t_cdb.data();
t_v4p->usr_ptr = t_v4p->request;
@@ -2495,6 +2516,7 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it,
t_v4p->flags = iflags;
t_v4p->request_len = cdbsz;
t_v4p->din_xfer_len = num * clp->bs;
+ t_v4p->dout_xfer_len = 0;
t_v4p->timeout = clp->cmd_timeout;
t_v4p->request_extra = pack_id_base + ++rep->mrq_pack_id_off;
clp->most_recent_pack_id.store(t_v4p->request_extra);
@@ -2537,7 +2559,6 @@ mrq0_again:
} else if (vb > 3)
lk_print_command_len("output cdb: ", t_cdb.data(), cdbsz, true);
- memset(t_v4p, 0, sizeof(*t_v4p));
t_v4p->guard = 'Q';
t_v4p->request = (uint64_t)t_cdb.data();
t_v4p->usr_ptr = t_v4p->request;
@@ -2545,6 +2566,7 @@ mrq0_again:
t_v4p->max_response_len = sizeof(rep->sb);
t_v4p->flags = oflags;
t_v4p->request_len = cdbsz;
+ t_v4p->din_xfer_len = 0;
t_v4p->dout_xfer_len = num * clp->bs;
t_v4p->timeout = clp->cmd_timeout;
t_v4p->request_extra = pack_id_base + ++rep->mrq_pack_id_off;
@@ -2600,12 +2622,12 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
uint32_t out_mrq_q_blks = 0;
const int max_cdb_sz = MAX_SCSI_CDB_SZ;
struct sg_io_v4 * a_v4p;
- struct sg_io_v4 ctl_v4; /* MRQ control object */
+ struct sg_io_v4 ctl_v4 {}; /* MRQ control object */
struct global_collection * clp = rep->clp;
const char * iosub_str = "SG_IOSUBMIT(svb)";
char b[80];
- cdb_arr_t t_cdb = {};
- struct sg_io_v4 t_v4;
+ cdb_arr_t t_cdb {};
+ struct sg_io_v4 t_v4 {};
struct sg_io_v4 * t_v4p = &t_v4;
struct flags_t * iflagsp = &clp->in_flags;
struct flags_t * oflagsp = &clp->out_flags;
@@ -2616,6 +2638,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
a_cdb.clear();
a_v4.clear();
+ rep->a_mrq_din_blks = 0;
+ rep->a_mrq_dout_blks = 0;
mrq_pack_id_base = id * PACK_ID_TID_MULTIPLIER;
iflags = SGV4_FLAG_SHARE;
@@ -2668,7 +2692,6 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
lk_print_command_len("input cdb: ", t_cdb.data(), cdbsz, true);
a_cdb.push_back(t_cdb);
- memset(t_v4p, 0, sizeof(*t_v4p));
t_v4p->guard = 'Q';
t_v4p->flags = iflags;
t_v4p->request_len = cdbsz;
@@ -2676,6 +2699,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
t_v4p->max_response_len = sizeof(rep->sb);
t_v4p->usr_ptr = (uint64_t)&a_cdb[a_cdb.size() - 1];
t_v4p->din_xfer_len = num * clp->bs;
+ rep->a_mrq_din_blks += num;
+ t_v4p->dout_xfer_len = 0;
t_v4p->timeout = clp->cmd_timeout;
in_mrq_q_blks += num;
t_v4p->request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
@@ -2694,14 +2719,15 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
} else if (vb > 3)
lk_print_command_len("output cdb: ", t_cdb.data(), cdbsz, true);
a_cdb.push_back(t_cdb);
- memset(t_v4p, 0, sizeof(*t_v4p));
t_v4p->guard = 'Q';
t_v4p->flags = oflags;
t_v4p->request_len = cdbsz;
t_v4p->response = (uint64_t)rep->sb;
t_v4p->max_response_len = sizeof(rep->sb);
t_v4p->usr_ptr = (uint64_t)&a_cdb[a_cdb.size() - 1];
+ t_v4p->din_xfer_len = 0;
t_v4p->dout_xfer_len = num * clp->bs;
+ rep->a_mrq_dout_blks += num;
t_v4p->timeout = clp->cmd_timeout;
out_mrq_q_blks += num;
t_v4p->request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
@@ -2728,7 +2754,6 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
num_mrq = a_v4.size();
a_v4p = a_v4.data();
res = 0;
- memset(&ctl_v4, 0, sizeof(ctl_v4));
ctl_v4.guard = 'Q';
ctl_v4.request_len = a_cdb.size() * max_cdb_sz;
ctl_v4.request = (uint64_t)a_cdb.data();
@@ -2741,6 +2766,11 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
ctl_v4.flags |= SGV4_FLAG_ORDERED_WR;
if (clp->mrq_hipri)
ctl_v4.flags |= SGV4_FLAG_HIPRI;
+ if (clp->in_flags.mout_if || clp->out_flags.mout_if) {
+ ctl_v4.flags |= SGV4_FLAG_META_OUT_IF;
+ if (num_mrq > 0)
+ a_v4[0].info = UINT32_MAX;
+ }
ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */
ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4);
ctl_v4.din_xferp = (uint64_t)a_v4.data(); /* response array */
@@ -2851,10 +2881,9 @@ static int
sg_blk_poll(int fd, int num)
{
int res;
- struct sg_extended_info sei;
+ struct sg_extended_info sei {};
struct sg_extended_info * seip = &sei;
- memset(seip, 0, sizeof(*seip));
seip->sei_rd_mask |= SG_SEIM_BLK_POLL;
seip->sei_wr_mask |= SG_SEIM_BLK_POLL;
seip->num = (num < 0) ? 0 : num;
@@ -2882,7 +2911,7 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
int elem_sz = clp->elem_sz;
int res, t, num, err;
uint8_t *mmp;
- struct sg_extended_info sei;
+ struct sg_extended_info sei {};
struct sg_extended_info * seip = &sei;
res = ioctl(fd, SG_GET_VERSION_NUM, &t);
@@ -2899,14 +2928,12 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
goto bypass;
}
if (elem_sz >= 4096) {
- memset(seip, 0, sizeof(*seip));
seip->sei_rd_mask |= SG_SEIM_SGAT_ELEM_SZ;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
pr2serr_lk("sg_mrq_dd: %s: SG_SET_GET_EXTENDED(SGAT_ELEM_SZ) rd "
"error: %s\n", __func__, strerror(errno));
if (elem_sz != (int)seip->sgat_elem_sz) {
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_SGAT_ELEM_SZ;
seip->sgat_elem_sz = elem_sz;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
@@ -2916,7 +2943,6 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
}
}
if (no_dur || masync || skip_thresh) {
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
if (no_dur) {
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_NO_DURATION;
@@ -2975,7 +3001,6 @@ bypass:
if (res < 0)
perror("sg_mrq_dd: SG_SET_FORCE_PACK_ID error");
if (clp->unit_nanosec) {
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_TIME_IN_NS;
seip->ctl_flags |= SG_CTL_FLAGM_TIME_IN_NS;
@@ -3146,6 +3171,8 @@ process_flags(const char * arg, struct flags_t * fp)
fp->qtail = true;
else if (0 == strcmp(cp, "random"))
fp->random = true;
+ else if ((0 == strcmp(cp, "mout_if")) || (0 == strcmp(cp, "mout-if")))
+ fp->mout_if = true;
else if (0 == strcmp(cp, "serial"))
fp->serial = true;
else if (0 == strcmp(cp, "swait"))
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index 62c6a3e0..57158892 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "2.08 20210515";
+static const char * version_str = "2.09 20210605";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -196,6 +196,7 @@ struct flags_t {
bool qhead;
bool qtail;
bool random;
+ bool mout_if; /* META_OUT_IF flag at mrq level */
bool same_fds;
bool swait; /* now ignore; kept for backward compatibility */
bool v3;
@@ -612,7 +613,12 @@ sg_flags_str(int flags, int b_len, char * b)
goto fini;
}
if (SGV4_FLAG_REC_ORDER & flags) { /* 0x100000 */
- n += sg_scnpr(b + n, b_len - n, "RECO|");
+ n += sg_scnpr(b + n, b_len - n, "REC_O|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SGV4_FLAG_META_OUT_IF & flags) { /* 0x200000 */
+ n += sg_scnpr(b + n, b_len - n, "MOUT_IF|");
if (n >= b_len)
goto fini;
}
@@ -935,11 +941,11 @@ usage(int pg_num)
" if file or device to read from (def: stdin)\n"
" iflag comma separated list from: [00,coe,defres,dio,"
"direct,dpo,\n"
- " dsync,excl,ff,fua,hipri,masync,mmap,mrq_immed,"
- "mrq_svb,\n"
- " nocreat,nodur,noxfer,null,qhead,qtail,"
- "random,\n"
- " same_fds,v3,v4,wq_excl]\n"
+ " dsync,excl,ff,fua,hipri,masync,mmap,mout_if,"
+ "mrq_immed,\n"
+ " mrq_svb,nocreat,nodur,noxfer,null,qhead,"
+ "qtail,\n"
+ " random,same_fds,v3,v4,wq_excl]\n"
" of file or device to write to (def: /dev/null "
"N.B. different\n"
" from dd it defaults to stdout). If 'of=.' "
@@ -1050,6 +1056,7 @@ page3:
" mmap setup mmap IO on IFILE or OFILE; OFILE only "
"with noshare\n"
" mmap,mmap when used twice, doesn't call munmap()\n"
+ " mout_if set META_OUT_IF flag on each request\n"
" mrq_immed if mrq active, do submit non-blocking (def: "
"ordered\n"
" blocking)\n"
@@ -1308,7 +1315,7 @@ mrq_abort_thread(void * v_maip)
int seed;
unsigned int rn;
Mrq_abort_info l_mai = *(Mrq_abort_info *)v_maip;
- struct sg_io_v4 ctl_v4;
+ struct sg_io_v4 ctl_v4 {};
#ifdef HAVE_GETRANDOM
{
@@ -1347,7 +1354,6 @@ mrq_abort_thread(void * v_maip)
pr2serr_lk("%s: skipping nanosleep cause delay < 20 usecs\n",
__func__);
- memset(&ctl_v4, 0, sizeof(ctl_v4));
ctl_v4.guard = 'Q';
ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS;
ctl_v4.request_extra = l_mai.mrq_id;
@@ -1374,11 +1380,9 @@ mrq_abort_thread(void * v_maip)
static bool
sg_share_prepare(int write_side_fd, int read_side_fd, int id, bool vb_b)
{
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info sei {};
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_SHARE_FD;
seip->sei_rd_mask |= SG_SEIM_SHARE_FD;
seip->share_fd = read_side_fd;
@@ -1398,11 +1402,9 @@ sg_share_prepare(int write_side_fd, int read_side_fd, int id, bool vb_b)
static void
sg_unshare(int sg_fd, int id, bool vb_b)
{
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info sei {};
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS;
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_UNSHARE;
@@ -1420,11 +1422,9 @@ static void
sg_noshare_enlarge(int sg_fd, bool vb_b)
{
if (sg_version_ge_40045) {
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info sei {};
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
- memset(seip, 0, sizeof(*seip));
sei.sei_wr_mask |= SG_SEIM_TOT_FD_THRESH;
seip->tot_fd_thresh = 96 * 1024 * 1024;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
@@ -1440,11 +1440,9 @@ sg_noshare_enlarge(int sg_fd, bool vb_b)
static void
sg_take_snap(int sg_fd, int id, bool vb_b)
{
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info sei {};
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS;
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_SNAP_DEV;
@@ -1507,7 +1505,7 @@ read_write_thread(void * v_tip)
{
Thread_info * tip;
struct global_collection * clp;
- Rq_elem rel;
+ Rq_elem rel {};
Rq_elem * rep = &rel;
int n, sz, blocks, status, vb, err, res, wr_blks;
int num_sg = 0;
@@ -1528,7 +1526,6 @@ read_write_thread(void * v_tip)
in_mmap = (in_is_sg && (clp->in_flags.mmap > 0));
out_is_sg = (FT_SG == clp->out_type);
out_mmap = (out_is_sg && (clp->out_flags.mmap > 0));
- memset(rep, 0, sizeof(Rq_elem));
/* Following clp members are constant during lifetime of thread */
rep->clp = clp;
rep->id = tip->id;
@@ -2153,13 +2150,12 @@ sg_wr_swap_share(Rq_elem * rep, int to_fd, bool before)
int k;
int read_side_fd = rep->infd;
struct global_collection * clp = rep->clp;
- struct sg_extended_info sei;
+ struct sg_extended_info sei {};
struct sg_extended_info * seip = &sei;
if (rep->clp->verbose > 2)
pr2serr_lk("%s: tid=%d: to_fd=%d, before=%d\n", __func__, rep->id,
to_fd, (int)before);
- memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CHG_SHARE_FD;
seip->sei_rd_mask |= SG_SEIM_CHG_SHARE_FD;
seip->share_fd = to_fd;
@@ -2205,11 +2201,10 @@ sg_out_wr_cmd(Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2, bool prefetch)
struct global_collection * clp = rep->clp;
uint32_t ofsplit = clp->ofsplit;
pthread_mutex_t * mutexp = is_wr2 ? &clp->out2_mutex : &clp->out_mutex;
- struct sg_io_extra xtr;
+ struct sg_io_extra xtr {};
struct sg_io_extra * xtrp = &xtr;
const char * wr_or_ver = clp->verify ? "verify" : "out";
- memset(xtrp, 0, sizeof(*xtrp));
xtrp->is_wr2 = is_wr2;
xtrp->prefetch = prefetch;
nblks = rep->num_blks;
@@ -2423,6 +2418,7 @@ process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
}
}
if (slen > 0) {
+pr2serr(">>>>>>>>>>>> %s: slen=%d\n", __func__, slen);
struct sg_scsi_sense_hdr ssh;
const uint8_t *sbp = (const uint8_t *)
(sb_in_co ? ctl_v4p->response : a_v4p->response);
@@ -2826,7 +2822,7 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
uint32_t in_fin_blks, out_fin_blks;
const int max_cdb_sz = 16;
struct sg_io_v4 * a_v4p;
- struct sg_io_v4 ctl_v4;
+ struct sg_io_v4 ctl_v4 {};
uint8_t * cmd_ap = NULL;
struct global_collection * clp = rep->clp;
const char * iosub_str = "iosub_str";
@@ -2834,7 +2830,6 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
id = rep->id;
b_len = sizeof(b);
- memset(&ctl_v4, 0, sizeof(ctl_v4));
ctl_v4.guard = 'Q';
a_v4p = def_arr.first.data();
nrq = def_arr.first.size();
@@ -3121,6 +3116,7 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
bool qhead = wr ? clp->out_flags.qhead : clp->in_flags.qhead;
bool qtail = wr ? clp->out_flags.qtail : clp->in_flags.qtail;
bool hipri = wr ? clp->out_flags.hipri : clp->in_flags.hipri;
+ bool mout_if = wr ? clp->out_flags.mout_if : clp->in_flags.mout_if;
bool prefetch = xtrp ? xtrp->prefetch : false;
bool is_wr2 = xtrp ? xtrp->is_wr2 : false;
int cdbsz = wr ? clp->cdbsz_out : clp->cdbsz_in;
@@ -3185,6 +3181,8 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
flags |= SG_FLAG_Q_AT_HEAD;
if (qtail)
flags |= SG_FLAG_Q_AT_TAIL;
+ if (mout_if)
+ flags |= SGV4_FLAG_META_OUT_IF;
if (rep->has_share) {
flags |= SGV4_FLAG_SHARE;
if (wr)
@@ -3416,6 +3414,7 @@ sg_finish_io(bool wr, Rq_elem * rep, int pack_id, struct sg_io_extra *xtrp)
{
struct global_collection * clp = rep->clp;
bool v4 = wr ? clp->out_flags.v4 : clp->in_flags.v4;
+ bool mout_if = wr ? clp->out_flags.mout_if : clp->in_flags.mout_if;
bool is_wr2 = xtrp ? xtrp->is_wr2 : false;
bool prefetch = xtrp ? xtrp->prefetch : false;
int res, fd;
@@ -3514,6 +3513,11 @@ do_v4:
}
h4p = &rep->io_hdr4[xtrp ? xtrp->hpv4_ind : 0];
h4p->request_extra = pack_id;
+ if (mout_if) {
+ h4p->info = 0;
+ h4p->din_resid = 0;
+ }
+pr2serr(">>>>> %s: h4p->response: %sNULL, max_slen=%d\n", __func__, h4p->response ? "non-" : "", h4p->max_response_len);
while (((res = ioctl(fd, SG_IORECEIVE, h4p)) < 0) &&
((EINTR == errno) || (EAGAIN == errno) || (EBUSY == errno))) {
if (EAGAIN == errno) {
@@ -3535,6 +3539,11 @@ do_v4:
perror("finishing io [SG_IORECEIVE] on sg device, error");
return -1;
}
+pr2serr(">>>>> %s: h4p->response_len=%d\n", __func__, h4p->response_len);
+ if (mout_if && (0 == h4p->info) && (0 == h4p->din_resid)) {
+pr2serr("%s: META_OUT_IF set plus info and resid are zero, skip\n", __func__);
+ goto all_good;
+ }
if (rep != (Rq_elem *)h4p->usr_ptr)
err_exit(0, "sg_finish_io: bad usr_ptr, request-response mismatch\n");
res = sg_err_category_new(h4p->device_status, h4p->transport_status,
@@ -3591,6 +3600,7 @@ do_v4:
!!(h4p->info & SG_INFO_DEVICE_DETACHING),
!!(h4p->info & SG_INFO_ABORTED));
}
+all_good:
return 0;
}
@@ -3608,10 +3618,9 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp,
clp->out_flags.no_thresh;
int res, t, num;
uint8_t *mmp;
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
+ struct sg_extended_info sei {};
+ struct sg_extended_info * seip = &sei;
- seip = &sei;
res = ioctl(fd, SG_GET_VERSION_NUM, &t);
if ((res < 0) || (t < 40000)) {
if (ioctl(fd, SG_GET_RESERVED_SIZE, &num) < 0) {
@@ -3629,7 +3638,6 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp,
if (! sg_version_ge_40045)
goto bypass;
if (clp->elem_sz >= 4096) {
- memset(seip, 0, sizeof(*seip));
seip->sei_rd_mask |= SG_SEIM_SGAT_ELEM_SZ;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
@@ -3815,6 +3823,8 @@ process_flags(const char * arg, struct flags_t * fp)
fp->qtail = true;
else if (0 == strcmp(cp, "random"))
fp->random = true;
+ else if ((0 == strcmp(cp, "mout_if")) || (0 == strcmp(cp, "mout-if")))
+ fp->mout_if = true;
else if (0 == strcmp(cp, "same_fds"))
fp->same_fds = true;
else if (0 == strcmp(cp, "swait"))
@@ -4390,7 +4400,7 @@ main(int argc, char * argv[])
const char * ccp = NULL;
const char * cc2p;
struct global_collection * clp = &gcoll;
- Thread_info thread_arr[MAX_NUM_THREADS];
+ Thread_info thread_arr[MAX_NUM_THREADS] {};
char ebuff[EBUFF_SZ];
#if SG_LIB_ANDROID
struct sigaction actions;
@@ -4403,7 +4413,6 @@ main(int argc, char * argv[])
sigaction(SIGUSR2, &actions, NULL);
#endif
/* memset(clp, 0, sizeof(*clp)); */
- memset(thread_arr, 0, sizeof(thread_arr));
clp->bpt = DEF_BLOCKS_PER_TRANSFER;
clp->cmd_timeout = DEF_TIMEOUT;
clp->in_type = FT_OTHER;
diff --git a/testing/uapi_sg.h b/testing/uapi_sg.h
index 22ed1e1a..270ad468 100644
--- a/testing/uapi_sg.h
+++ b/testing/uapi_sg.h
@@ -14,7 +14,7 @@
* Later extensions (versions 2, 3 and 4) to driver:
* Copyright (C) 1998 - 2021 Douglas Gilbert
*
- * Version 4.0.46 (20210111)
+ * Version 4.0.47 (20210605)
* This version is for Linux 4 and 5 series kernels.
*
* Documentation
@@ -129,6 +129,7 @@ typedef struct sg_io_hdr {
#define SGV4_FLAG_MULTIPLE_REQS 0x40000 /* 1 or more sg_io_v4-s in data-in */
#define SGV4_FLAG_ORDERED_WR 0x80000 /* svb: issue in-order writes */
#define SGV4_FLAG_REC_ORDER 0x100000 /* receive order in v4:request_priority */
+#define SGV4_FLAG_META_OUT_IF 0x200000 /* ... there is something to report */
/* Output (potentially OR-ed together) in v3::info or v4::info field */
#define SG_INFO_OK_MASK 0x1