From 30363466e3580cae5f428c9bf35caa934cef469b Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Mon, 7 Jun 2021 15:21:01 +0000 Subject: 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 --- testing/sg_mrq_dd.cpp | 107 +++++++++++++++++++++++++++++++------------------- testing/sgh_dd.cpp | 87 ++++++++++++++++++++++------------------ testing/uapi_sg.h | 3 +- 3 files changed, 117 insertions(+), 80 deletions(-) (limited to 'testing') 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 -- cgit v1.2.3