From: Douglas Gilbert <dgilbert@interlog.com>
To: linux-scsi@vger.kernel.org
Cc: martin.petersen@oracle.com, jejb@linux.vnet.ibm.com, hare@suse.de
Subject: [PATCH v18 71/83] sg: add mmap IO option for mrq metadata
Date: Tue, 27 Apr 2021 17:57:21 -0400 [thread overview]
Message-ID: <20210427215733.417746-73-dgilbert@interlog.com> (raw)
In-Reply-To: <20210427215733.417746-1-dgilbert@interlog.com>
The SG_FLAG_MMAP_IO is not very useful on individual elements in a
multiple request invocation. That is because a mrq invocation involves
one or maybe two file descriptors. mmap()-ed IO buffers are bound to a
single file descriptor. And one or possibly two is not enough IO data
buffers for mrq to be practical.
This patch adds SG_FLAG_MMAP_IO functionality to the control object in
a mrq request. When set on a mrq control object, then instead of the
returning metadata being send to din_xferp, it is sent, one element at
a time (on its completion) to the mmap(2)-ed buffer. So the user space
program must call mmap(2) before using the SG_FLAG_MMAP_IO (and that
now applies to all usages of that flag, the code was too lenient in
that area prior to this).
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
---
drivers/scsi/sg.c | 202 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 172 insertions(+), 30 deletions(-)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index bdb9b3dbf970..48bf5ccca5b5 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -338,13 +338,15 @@ struct sg_mrq_hold { /* for passing context between mrq functions */
bool chk_abort;
bool immed;
bool stop_if;
+ bool co_mmap;
int id_of_mrq;
int s_res; /* secondary error: some-good-then-error */
u32 cdb_mxlen; /* cdb length in cdb_ap, actual be may less */
u32 tot_reqs; /* total number of requests and cdb_s */
- struct sg_comm_wr_t *cwrp;
+ struct sg_comm_wr_t *cwrp; /* cwrp->h4p is mrq control object */
u8 *cdb_ap; /* array of commands */
struct sg_io_v4 *a_hds; /* array of request to execute */
+ struct sg_scatter_hold *co_mmap_sgatp;
};
/* tasklet or soft irq callback */
@@ -966,6 +968,109 @@ sg_v4h_partial_zero(struct sg_io_v4 *h4p)
memset((u8 *)h4p + off, 0, SZ_SG_IO_V4 - off);
}
+static void
+sg_sgat_zero(struct sg_scatter_hold *sgatp, int off, int nbytes)
+{
+ int k, rem, off_pl_nbyt;
+ int ind = 0;
+ int pg_ind = 0;
+ int num_sgat = sgatp->num_sgat;
+ int elem_sz = PAGE_SIZE * (1 << sgatp->page_order);
+ struct page *pg_ep = sgatp->pages[pg_ind];
+
+ if (off >= sgatp->dlen)
+ return;
+ off_pl_nbyt = off + nbytes;
+ if (off_pl_nbyt >= sgatp->dlen) {
+ nbytes = sgatp->dlen - off;
+ off_pl_nbyt = off + nbytes;
+ }
+ /* first loop steps over off bytes, second loop zeros nbytes */
+ for (k = 0; k < off; k += rem) {
+ rem = off - k;
+ if (rem >= elem_sz) {
+ ++pg_ind;
+ if (pg_ind >= num_sgat)
+ return;
+ rem = elem_sz;
+ ind = 0;
+ } else {
+ ind = elem_sz - rem;
+ }
+ }
+ pg_ep = sgatp->pages[pg_ind];
+ for ( ; k < off_pl_nbyt; k += rem) {
+ rem = off_pl_nbyt - k;
+ if (rem >= elem_sz) {
+ memset((u8 *)pg_ep + ind, 0, elem_sz - ind);
+ if (++pg_ind >= num_sgat)
+ return;
+ pg_ep = sgatp->pages[pg_ind];
+ rem = elem_sz;
+ ind = 0;
+ } else {
+ memset((u8 *)pg_ep + ind, 0, rem - ind);
+ ind = elem_sz - rem;
+ }
+ }
+}
+
+/*
+ * Copies nbytes from the start of 'fromp' into sgatp (this driver's scatter
+ * gather list representation) starting at byte offset 'off'. If nbytes is
+ * too long then it is trimmed.
+ */
+static void
+sg_sgat_cp_into(struct sg_scatter_hold *sgatp, int off, const u8 *fromp,
+ int nbytes)
+{
+ int k, rem, off_pl_nbyt;
+ int ind = 0;
+ int from_off = 0;
+ int pg_ind = 0;
+ int num_sgat = sgatp->num_sgat;
+ int elem_sz = PAGE_SIZE * (1 << sgatp->page_order);
+ struct page *pg_ep = sgatp->pages[pg_ind];
+
+ if (off >= sgatp->dlen)
+ return;
+ off_pl_nbyt = off + nbytes;
+ if (off_pl_nbyt >= sgatp->dlen) {
+ nbytes = sgatp->dlen - off;
+ off_pl_nbyt = off + nbytes;
+ }
+ /* first loop steps over off bytes, second loop zeros nbytes */
+ for (k = 0; k < off; k += rem) {
+ rem = off - k;
+ if (rem >= elem_sz) {
+ ++pg_ind;
+ if (pg_ind >= num_sgat)
+ return;
+ rem = elem_sz;
+ ind = 0;
+ } else {
+ ind = elem_sz - rem;
+ }
+ }
+ pg_ep = sgatp->pages[pg_ind];
+ for ( ; k < off_pl_nbyt; k += rem) {
+ rem = off_pl_nbyt - k;
+ if (rem >= elem_sz) {
+ memcpy((u8 *)pg_ep + ind, fromp + from_off,
+ elem_sz - ind);
+ if (++pg_ind >= num_sgat)
+ return;
+ pg_ep = sgatp->pages[pg_ind];
+ rem = elem_sz;
+ ind = 0;
+ from_off += elem_sz - ind;
+ } else {
+ memcpy((u8 *)pg_ep + ind, fromp + from_off, rem - ind);
+ /* last time around, no need to update indexes */
+ }
+ }
+}
+
/*
* Takes a pointer (cop) to the multiple request (mrq) control object and
* a pointer to the command array. The command array (with tot_reqs elements)
@@ -1018,7 +1123,12 @@ sg_mrq_1complet(struct sg_mrq_hold *mhp, struct sg_fd *do_on_sfp,
if (unlikely(s_res == -EFAULT))
return s_res;
hp->info |= SG_INFO_MRQ_FINI;
- if (do_on_sfp->async_qp && (hp->flags & SGV4_FLAG_SIGNAL)) {
+ if (mhp->co_mmap) {
+ sg_sgat_cp_into(mhp->co_mmap_sgatp, indx * SZ_SG_IO_V4,
+ (const u8 *)hp, SZ_SG_IO_V4);
+ if (do_on_sfp->async_qp && (hp->flags & SGV4_FLAG_SIGNAL))
+ kill_fasync(&do_on_sfp->async_qp, SIGPOLL, POLL_IN);
+ } else if (do_on_sfp->async_qp && (hp->flags & SGV4_FLAG_SIGNAL)) {
s_res = sg_mrq_arr_flush(mhp);
if (unlikely(s_res)) /* can only be -EFAULT */
return s_res;
@@ -1124,23 +1234,24 @@ sg_mrq_complets(struct sg_mrq_hold *mhp, struct sg_fd *sfp,
}
static int
-sg_mrq_sanity(struct sg_device *sdp, struct sg_io_v4 *cop,
- struct sg_io_v4 *a_hds, u8 *cdb_ap, struct sg_fd *sfp,
- bool immed, u32 tot_reqs, bool *share_on_othp)
+sg_mrq_sanity(struct sg_mrq_hold *mhp)
{
- bool have_mrq_sense = (cop->response && cop->max_response_len);
- bool share_on_oth = false;
bool last_is_keep_share = false;
- bool share;
+ bool share, have_mrq_sense;
int k;
+ struct sg_io_v4 *cop = mhp->cwrp->h4p;
u32 cdb_alen = cop->request_len;
- u32 cdb_mxlen = cdb_alen / tot_reqs;
+ u32 cdb_mxlen = cdb_alen / mhp->tot_reqs;
u32 flags;
+ struct sg_fd *sfp = mhp->cwrp->sfp;
+ struct sg_io_v4 *a_hds = mhp->a_hds;
+ u8 *cdb_ap = mhp->cdb_ap;
struct sg_io_v4 *hp;
__maybe_unused const char *rip = "request index";
+ have_mrq_sense = (cop->response && cop->max_response_len);
/* Pre-check each request for anomalies, plus some preparation */
- for (k = 0, hp = a_hds; k < tot_reqs; ++k, ++hp) {
+ for (k = 0, hp = a_hds; k < mhp->tot_reqs; ++k, ++hp) {
flags = hp->flags;
sg_v4h_partial_zero(hp);
if (unlikely(hp->guard != 'Q' || hp->protocol != 0 ||
@@ -1156,7 +1267,7 @@ sg_mrq_sanity(struct sg_device *sdp, struct sg_io_v4 *cop,
return -ERANGE;
}
share = !!(flags & SGV4_FLAG_SHARE);
- if (immed) { /* only accept async submits on current fd */
+ if (mhp->immed) {/* only accept async submits on current fd */
if (unlikely(flags & SGV4_FLAG_DO_ON_OTHER)) {
SG_LOG(1, sfp, "%s: %s %u, %s\n", __func__,
rip, k, "no IMMED with ON_OTHER");
@@ -1171,10 +1282,12 @@ sg_mrq_sanity(struct sg_device *sdp, struct sg_io_v4 *cop,
return -ERANGE;
}
}
- if (sg_fd_is_shared(sfp)) {
- if (!share_on_oth && share)
- share_on_oth = true;
- } else {
+ if (mhp->co_mmap && (flags & SGV4_FLAG_MMAP_IO)) {
+ SG_LOG(1, sfp, "%s: %s %u, MMAP in co AND here\n",
+ __func__, rip, k);
+ return -ERANGE;
+ }
+ if (!sg_fd_is_shared(sfp)) {
if (unlikely(share)) {
SG_LOG(1, sfp, "%s: %s %u, no share\n",
__func__, rip, k);
@@ -1204,8 +1317,6 @@ sg_mrq_sanity(struct sg_device *sdp, struct sg_io_v4 *cop,
__func__);
return -ERANGE;
}
- if (share_on_othp)
- *share_on_othp = share_on_othp;
return 0;
}
@@ -1229,7 +1340,7 @@ sg_mrq_svb_chk(struct sg_io_v4 *a_hds, u32 tot_reqs)
/* expect read-write pairs, all with SGV4_FLAG_NO_DXFER set */
for (k = 0, hp = a_hds; k < tot_reqs; ++k, ++hp) {
flags = hp->flags;
- if (flags & (SGV4_FLAG_COMPLETE_B4))
+ if (flags & SGV4_FLAG_COMPLETE_B4)
return false;
if (!seen_wr) {
if (hp->dout_xfer_len > 0)
@@ -1357,7 +1468,14 @@ sg_process_most_mrq(struct sg_fd *fp, struct sg_fd *o_sfp,
hp->device_status);
break; /* cop->driver_status <-- 0 in this case */
}
- if (rq_sfp->async_qp && (hp->flags & SGV4_FLAG_SIGNAL)) {
+ if (mhp->co_mmap) {
+ sg_sgat_cp_into(mhp->co_mmap_sgatp, j * SZ_SG_IO_V4,
+ (const u8 *)hp, SZ_SG_IO_V4);
+ if (rq_sfp->async_qp && (hp->flags & SGV4_FLAG_SIGNAL))
+ kill_fasync(&rq_sfp->async_qp, SIGPOLL,
+ POLL_IN);
+ } else if (rq_sfp->async_qp &&
+ (hp->flags & SGV4_FLAG_SIGNAL)) {
res = sg_mrq_arr_flush(mhp);
if (unlikely(res))
break;
@@ -1653,14 +1771,15 @@ sg_mrq_name(bool blocking, u32 flags)
static int
sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
{
- bool f_non_block, share_on_oth;
+ bool f_non_block, co_share;
int res = 0;
int existing_id;
u32 cdb_mxlen;
struct sg_io_v4 *cop = cwrp->h4p; /* controlling object */
- u32 blen = cop->dout_xfer_len;
+ u32 dout_len = cop->dout_xfer_len;
+ u32 din_len = cwrp->dlen;
u32 cdb_alen = cop->request_len;
- u32 tot_reqs = blen / SZ_SG_IO_V4;
+ u32 tot_reqs = dout_len / SZ_SG_IO_V4;
u8 *cdb_ap = NULL;
struct sg_io_v4 *a_hds; /* array of request objects */
struct sg_fd *fp = cwrp->sfp;
@@ -1678,8 +1797,12 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
mrq_name = sg_mrq_name(blocking, cop->flags);
#endif
f_non_block = !!(fp->filp->f_flags & O_NONBLOCK);
+ co_share = !!(cop->flags & SGV4_FLAG_SHARE);
mhp->immed = !!(cop->flags & SGV4_FLAG_IMMED);
mhp->stop_if = !!(cop->flags & SGV4_FLAG_STOP_IF);
+ mhp->co_mmap = !!(cop->flags & SGV4_FLAG_MMAP_IO);
+ if (mhp->co_mmap)
+ mhp->co_mmap_sgatp = fp->rsv_arr[0]->sgatp;
mhp->id_of_mrq = (int)cop->request_extra;
mhp->tot_reqs = tot_reqs;
mhp->s_res = 0;
@@ -1702,6 +1825,11 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
__func__, "with SGV4_FLAG_IMMED");
return -ERANGE;
}
+ if (unlikely(co_share)) {
+ SG_LOG(1, fp, "%s: ioctl(SG_IO) %s contradicts\n",
+ __func__, "with SGV4_FLAG_SHARE");
+ return -ERANGE;
+ }
if (unlikely(f_non_block)) {
SG_LOG(6, fp, "%s: ioctl(SG_IO) %s O_NONBLOCK\n",
__func__, "ignoring");
@@ -1714,9 +1842,25 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
mrq_name, tot_reqs, mhp->id_of_mrq);
sg_v4h_partial_zero(cop);
+ if (mhp->co_mmap) {
+ struct sg_request *srp = fp->rsv_arr[0];
+
+ if (unlikely(fp->mmap_sz == 0))
+ return -EBADFD; /* want mmap() active on fd */
+ if ((int)din_len > fp->mmap_sz)
+ return -E2BIG;
+ if (cop->din_xferp)
+ pr_info_once("%s: co::din_xferp ignored due to SGV4_FLAG_MMAP_IO\n",
+ __func__);
+ if (srp)
+ sg_sgat_zero(srp->sgatp, 0 /* offset */, fp->mmap_sz);
+ else
+ return -EPROTO;
+ }
if (unlikely(tot_reqs > U16_MAX)) {
return -ERANGE;
- } else if (unlikely(blen > SG_MAX_MULTI_REQ_SZ ||
+ } else if (unlikely(dout_len > SG_MAX_MULTI_REQ_SZ ||
+ din_len > SG_MAX_MULTI_REQ_SZ ||
cdb_alen > SG_MAX_MULTI_REQ_SZ)) {
return -E2BIG;
} else if (unlikely(mhp->immed && mhp->stop_if)) {
@@ -1757,9 +1901,11 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
goto fini;
}
}
+ mhp->cdb_ap = cdb_ap;
+ mhp->a_hds = a_hds;
+ mhp->cdb_mxlen = cdb_mxlen;
/* do sanity checks on all requests before starting */
- res = sg_mrq_sanity(sdp, cop, a_hds, cdb_ap, fp, mhp->immed,
- tot_reqs, &share_on_oth);
+ res = sg_mrq_sanity(mhp);
if (unlikely(res))
goto fini;
@@ -1768,11 +1914,7 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
if (o_sfp)
clear_bit(SG_FFD_NO_CMD_Q, o_sfp->ffd_bm);
- mhp->cdb_ap = cdb_ap;
- mhp->a_hds = a_hds;
- mhp->cdb_mxlen = cdb_mxlen;
-
- if (!mhp->immed && !blocking && share_on_oth) {
+ if (co_share) {
bool ok;
/* check for 'shared' variable blocking (svb) */
--
2.25.1
next prev parent reply other threads:[~2021-04-27 21:59 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-27 21:56 [PATCH v18 00/83] sg: add v4 interface, request sharing Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 00/45] sg: add v4 interface Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 01/83] sg: move functions around Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 02/83] sg: remove typedefs, type+formatting cleanup Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 03/83] sg: sg_log and is_enabled Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 04/83] sg: rework sg_poll(), minor changes Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 05/83] sg: bitops in sg_device Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 06/83] sg: make open count an atomic Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 07/83] sg: move header to uapi section Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 08/83] sg: speed sg_poll and sg_get_num_waiting Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 09/83] sg: sg_allow_if_err_recovery and renames Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 10/83] sg: improve naming Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 11/83] sg: change rwlock to spinlock Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 12/83] sg: ioctl handling Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 13/83] sg: split sg_read Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 14/83] sg: sg_common_write add structure for arguments Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 15/83] sg: rework sg_vma_fault Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 16/83] sg: rework sg_mmap Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 17/83] sg: replace sg_allow_access Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 18/83] sg: rework scatter gather handling Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 19/83] sg: introduce request state machine Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 20/83] sg: sg_find_srp_by_id Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 21/83] sg: sg_fill_request_element Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 22/83] sg: printk change %p to %pK Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 23/83] sg: xarray for fds in device Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 24/83] sg: xarray for reqs in fd Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 25/83] sg: replace rq array with xarray Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 26/83] sg: sense buffer rework Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 27/83] sg: add sg v4 interface support Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 28/83] sg: rework debug info Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 29/83] sg: add 8 byte SCSI LUN to sg_scsi_id Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 30/83] sg: expand sg_comm_wr_t Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 31/83] sg: add sg_iosubmit_v3 and sg_ioreceive_v3 ioctls Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 32/83] sg: add some __must_hold macros Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 33/83] sg: move procfs objects to avoid forward decls Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 34/83] sg: protect multiple receivers Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 35/83] sg: first debugfs support Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 36/83] sg: rework mmap support Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 37/83] sg: defang allow_dio Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 38/83] sg: warn v3 write system call users Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 39/83] sg: add mmap_sz tracking Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 40/83] sg: remove rcv_done request state Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 41/83] sg: track lowest inactive and await indexes Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 42/83] sg: remove unit attention check for device changed Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 43/83] sg: no_dxfer: move to/from kernel buffers Douglas Gilbert
2021-04-28 7:07 ` Hannes Reinecke
2021-04-27 21:56 ` [PATCH v18 44/83] sg: add blk_poll support Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 45/83] sg: bump version to 4.0.12 Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 46/83] sg: add sg_ioabort ioctl Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 47/83] sg: add sg_set_get_extended ioctl Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 48/83] sg: sgat_elem_sz and sum_fd_dlens Douglas Gilbert
2021-04-27 21:56 ` [PATCH v18 49/83] sg: tag and more_async Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 50/83] sg: add fd sharing , change, unshare Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 51/83] sg: add shared requests Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 52/83] sg: add multiple request support Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 53/83] sg: rename some mrq variables Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 54/83] sg: unlikely likely Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 55/83] sg: mrq abort Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 56/83] sg: reduce atomic operations Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 57/83] sg: add excl_wait flag Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 58/83] sg: tweak sg_find_sfp_by_fd() Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 59/83] sg: add snap_dev flag and snapped in debugfs Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 60/83] sg: compress usercontext to uc Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 61/83] sg: optionally output sg_request.frq_bm flags Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 62/83] sg: work on sg_mrq_sanity() Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 63/83] sg: shared variable blocking Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 64/83] sg: device timestamp Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 65/83] sg: condition met is not an error Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 66/83] sg: split sg_setup_req Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 67/83] sg: finish after read-side request Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 68/83] sg: keep share and dout offset flags Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 69/83] sg: add dlen to sg_comm_wr_t Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 70/83] sg: make use of struct sg_mrq_hold Douglas Gilbert
2021-04-27 21:57 ` Douglas Gilbert [this message]
2021-04-27 21:57 ` [PATCH v18 72/83] sg: add eventfd support Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 73/83] sg: table of error number explanations Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 74/83] sg: add ordered write flag Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 75/83] sg: expand source line length to 100 characters Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 76/83] sg: add no_attach_msg parameter Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 77/83] sg: add SGV4_FLAG_REC_ORDER Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 78/83] sg: max to read for mrq sg_ioreceive Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 79/83] sg: mrq: if uniform svb then re-use bio_s Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 80/83] sg: expand bvec usage; " Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 81/83] sg: blk_poll/hipri work for mrq Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 82/83] sg: pollable and non-pollable requests Douglas Gilbert
2021-04-27 21:57 ` [PATCH v18 83/83] sg: bump version to 4.0.47 Douglas Gilbert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210427215733.417746-73-dgilbert@interlog.com \
--to=dgilbert@interlog.com \
--cc=hare@suse.de \
--cc=jejb@linux.vnet.ibm.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox