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 55/83] sg: mrq abort
Date: Tue, 27 Apr 2021 17:57:05 -0400 [thread overview]
Message-ID: <20210427215733.417746-57-dgilbert@interlog.com> (raw)
In-Reply-To: <20210427215733.417746-1-dgilbert@interlog.com>
Add ability to abort current and remaining (unsubmitted) part
of a multiple requests invocation. Any multiple requests
invocation that the user may want to abort later must be given
a non-zero mrq pack_id (in the request_extra field of the
control object). There can only be one of these non-zero
mrq pack_ids outstanding at a time per file descriptor.
Any requests in a multiple request invocation that have already
reached their internal completion point when the mrq abort is
issued must be processed in the normal fashion. Any inflight
requests will have blk_abort_request() called on them. Those
remaining requests that have not yet been submitted will be
dropped. The ctl_obj.info field is set to number of received
requests that have been processed. The ctl_obj.resid_out field
in the number of requests given less the number actually
submitted. The ctl_obj.resid_in field in the number of given
requests less the number actually received and processed
(i.e. given - ctl_obj.info).
ioctl(sg_fd, SG_IOABORT, &ctl_obj) is used to issue a mrq abort.
The flags field must have SGV4_FLAG_MULTIPLE_REQS set and the
request_extra field must be set to the non-zero mrq pack_id.
SG_PACK_ID_WILDCARD can be given for the mrq pack_id.
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
---
drivers/scsi/sg.c | 274 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 237 insertions(+), 37 deletions(-)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 27d9ac801f11..3d659ff90788 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -152,6 +152,7 @@ enum sg_shr_var {
#define SG_FFD_RELEASE 8 /* release (close) underway */
#define SG_FFD_NO_DURATION 9 /* don't do command duration calc */
#define SG_FFD_MORE_ASYNC 10 /* yield EBUSY more often */
+#define SG_FFD_MRQ_ABORT 11 /* SG_IOABORT + FLAG_MULTIPLE_REQS */
/* Bit positions (flags) for sg_device::fdev_bm bitmask follow */
#define SG_FDEV_EXCLUDE 0 /* have fd open with O_EXCL */
@@ -215,7 +216,8 @@ struct sg_slice_hdr4 { /* parts of sg_io_v4 object needed in async usage */
s16 dir; /* data xfer direction; SG_DXFER_* */
u16 cmd_len; /* truncated of sg_io_v4::request_len */
u16 max_sb_len; /* truncated of sg_io_v4::max_response_len */
- u16 mrq_ind; /* position in parentfp->mrq_arr */
+ u16 mrq_ind; /* mrq submit order, origin 0 */
+ atomic_t pack_id_of_mrq; /* mrq pack_id, active when > 0 */
};
struct sg_scatter_hold { /* holding area for scsi scatter gather info */
@@ -271,6 +273,7 @@ struct sg_fd { /* holds the state of a file descriptor */
atomic_t waiting; /* number of requests awaiting receive */
atomic_t inactives; /* number of inactive requests */
atomic_t sum_fd_dlens; /* when tot_fd_thresh>0 this is sum_of(dlen) */
+ atomic_t mrq_id_abort; /* inactive when 0, else id if aborted */
int tot_fd_thresh; /* E2BIG if sum_of(dlen) > this, 0: ignore */
int sgat_elem_sz; /* initialized to scatter_elem_sz */
int mmap_sz; /* byte size of previous mmap() call */
@@ -410,7 +413,6 @@ static const char *sg_shr_str(enum sg_shr_var sh_var, bool long_str);
#define SG_LOG(depth, sfp, fmt, a...) do { } while (0)
#endif /* end of CONFIG_SCSI_LOGGING && SG_DEBUG conditional */
-
/*
* The SCSI interfaces that use read() and write() as an asynchronous variant of
* ioctl(..., SG_IO, ...) are fundamentally unsafe, since there are lots of ways
@@ -944,7 +946,7 @@ sg_mrq_1complet(struct sg_io_v4 *cop, struct sg_io_v4 *a_hds,
struct sg_fd *w_sfp, int tot_reqs, struct sg_request *srp)
{
int s_res, indx;
- struct sg_io_v4 *siv4p;
+ struct sg_io_v4 *hp;
SG_LOG(3, w_sfp, "%s: start, tot_reqs=%d\n", __func__, tot_reqs);
if (unlikely(!srp))
@@ -952,12 +954,12 @@ sg_mrq_1complet(struct sg_io_v4 *cop, struct sg_io_v4 *a_hds,
indx = srp->s_hdr4.mrq_ind;
if (unlikely(indx < 0 || indx >= tot_reqs))
return -EPROTO;
- siv4p = a_hds + indx;
- s_res = sg_receive_v4(w_sfp, srp, NULL, siv4p);
+ hp = a_hds + indx;
+ s_res = sg_receive_v4(w_sfp, srp, NULL, hp);
if (unlikely(s_res == -EFAULT))
return s_res;
- siv4p->info |= SG_INFO_MRQ_FINI;
- if (w_sfp->async_qp && (siv4p->flags & SGV4_FLAG_SIGNAL)) {
+ hp->info |= SG_INFO_MRQ_FINI;
+ if (w_sfp->async_qp && (hp->flags & SGV4_FLAG_SIGNAL)) {
s_res = sg_mrq_arr_flush(cop, a_hds, tot_reqs, s_res);
if (unlikely(s_res)) /* can only be -EFAULT */
return s_res;
@@ -1123,16 +1125,19 @@ sg_mrq_sanity(struct sg_device *sdp, struct sg_io_v4 *cop,
static int
sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
{
- bool immed, stop_if, f_non_block;
+ bool chk_abort = false;
+ bool set_this, set_other, immed, stop_if, f_non_block;
int res = 0;
int s_res = 0; /* for secondary error: some-good-then-error, case */
int other_fp_sent = 0;
int this_fp_sent = 0;
+ int num_subm = 0;
int num_cmpl = 0;
const int shr_complet_b4 = SGV4_FLAG_SHARE | SGV4_FLAG_COMPLETE_B4;
+ int id_of_mrq, existing_id;
+ u32 n, flags, cdb_mxlen;
unsigned long ul_timeout;
- struct sg_io_v4 *cop = cwrp->h4p;
- u32 k, n, flags, cdb_mxlen;
+ struct sg_io_v4 *cop = cwrp->h4p; /* controlling object */
u32 blen = cop->dout_xfer_len;
u32 cdb_alen = cop->request_len;
u32 tot_reqs = blen / SZ_SG_IO_V4;
@@ -1148,6 +1153,17 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
f_non_block = !!(fp->filp->f_flags & O_NONBLOCK);
immed = !!(cop->flags & SGV4_FLAG_IMMED);
stop_if = !!(cop->flags & SGV4_FLAG_STOP_IF);
+ id_of_mrq = (int)cop->request_extra;
+ if (id_of_mrq) {
+ existing_id = atomic_cmpxchg(&fp->mrq_id_abort, 0, id_of_mrq);
+ if (existing_id && existing_id != id_of_mrq) {
+ SG_LOG(1, fp, "%s: existing id=%d id_of_mrq=%d\n",
+ __func__, existing_id, id_of_mrq);
+ return -EDOM;
+ }
+ clear_bit(SG_FFD_MRQ_ABORT, fp->ffd_bm);
+ chk_abort = true;
+ }
if (blocking) { /* came from ioctl(SG_IO) */
if (unlikely(immed)) {
SG_LOG(1, fp, "%s: ioctl(SG_IO) %s contradicts\n",
@@ -1162,9 +1178,10 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
}
if (!immed && f_non_block)
immed = true;
- SG_LOG(3, fp, "%s: %s, tot_reqs=%u, cdb_alen=%u\n", __func__,
+ SG_LOG(3, fp, "%s: %s, tot_reqs=%u, id_of_mrq=%d\n", __func__,
(immed ? "IMMED" : (blocking ? "ordered blocking" :
- "variable blocking")), tot_reqs, cdb_alen);
+ "variable blocking")),
+ tot_reqs, id_of_mrq);
sg_sgv4_out_zero(cop);
if (unlikely(tot_reqs > U16_MAX)) {
@@ -1216,17 +1233,32 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
res = sg_mrq_sanity(sdp, cop, a_hds, cdb_ap, fp, immed, tot_reqs);
if (unlikely(res))
goto fini;
- /* override cmd queuing setting to allow */
- set_bit(SG_FFD_CMD_Q, fp->ffd_bm);
- if (o_sfp)
- set_bit(SG_FFD_CMD_Q, o_sfp->ffd_bm);
-
+ set_this = false;
+ set_other = false;
/* Dispatch (submit) requests and optionally wait for response */
- for (hp = a_hds, k = 0; num_cmpl < tot_reqs; ++hp, ++k) {
+ for (hp = a_hds; num_subm < tot_reqs; ++hp) {
+ if (chk_abort && test_and_clear_bit(SG_FFD_MRQ_ABORT,
+ fp->ffd_bm)) {
+ SG_LOG(1, fp, "%s: id_of_mrq=%d aborting at ind=%d\n",
+ __func__, id_of_mrq, num_subm);
+ break; /* N.B. rest not submitted */
+ }
flags = hp->flags;
- rq_sfp = (flags & SGV4_FLAG_DO_ON_OTHER) ? o_sfp : fp;
+ if (flags & SGV4_FLAG_DO_ON_OTHER) {
+ rq_sfp = o_sfp;
+ if (!set_other) {
+ set_other = true;
+ set_bit(SG_FFD_CMD_Q, rq_sfp->ffd_bm);
+ }
+ } else {
+ rq_sfp = fp;
+ if (!set_this) {
+ set_this = true;
+ set_bit(SG_FFD_CMD_Q, rq_sfp->ffd_bm);
+ }
+ }
if (cdb_ap) { /* already have array of cdbs */
- cwrp->cmdp = cdb_ap + (k * cdb_mxlen);
+ cwrp->cmdp = cdb_ap + (num_subm * cdb_mxlen);
cwrp->u_cmdp = NULL;
} else { /* fetch each cdb from user space */
cwrp->cmdp = NULL;
@@ -1245,7 +1277,9 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
s_res = PTR_ERR(srp);
break;
}
- srp->s_hdr4.mrq_ind = k;
+ srp->s_hdr4.mrq_ind = num_subm++;
+ if (chk_abort)
+ atomic_set(&srp->s_hdr4.pack_id_of_mrq, id_of_mrq);
if (immed || (!(blocking || (flags & shr_complet_b4)))) {
if (fp == rq_sfp)
++this_fp_sent;
@@ -1278,8 +1312,8 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
kill_fasync(&rq_sfp->async_qp, SIGPOLL, POLL_IN);
}
} /* end of dispatch request and optionally wait response loop */
- cop->dout_resid = tot_reqs - num_cmpl;
- cop->info = num_cmpl;
+ cop->dout_resid = tot_reqs - num_subm;
+ cop->info = num_cmpl; /* number received */
if (cop->din_xfer_len > 0) {
cop->din_resid = tot_reqs - num_cmpl;
cop->spare_out = -s_res;
@@ -1294,6 +1328,8 @@ sg_do_multi_req(struct sg_comm_wr_t *cwrp, bool blocking)
if (unlikely(s_res == -EFAULT || s_res == -ERESTARTSYS))
res = s_res; /* this may leave orphans */
}
+ if (id_of_mrq) /* can no longer do a mrq abort */
+ atomic_set(&fp->mrq_id_abort, 0);
fini:
if (likely(res == 0) && !immed)
res = sg_mrq_arr_flush(cop, a_hds, tot_reqs, s_res);
@@ -2032,7 +2068,7 @@ sg_mrq_ioreceive(struct sg_fd *sfp, struct sg_io_v4 *cop, void __user *p,
if (unlikely(res < 0))
goto fini;
cop->din_resid -= res;
- cop->info = res;
+ cop->info = res; /* number received */
if (copy_to_user(p, cop, sizeof(*cop)))
return -EFAULT;
res = 0;
@@ -2914,7 +2950,6 @@ sg_ctl_sg_io(struct sg_device *sdp, struct sg_fd *sfp, void __user *p)
*/
static struct sg_request *
sg_match_request(struct sg_fd *sfp, bool use_tag, int id)
- __must_hold(&sfp->rq_list_lock)
{
int num_waiting = atomic_read(&sfp->waiting);
unsigned long idx;
@@ -2942,6 +2977,48 @@ sg_match_request(struct sg_fd *sfp, bool use_tag, int id)
return NULL;
}
+/*
+ * Looks for first request following 'after_rp' (or the start if after_rp is
+ * NULL) whose pack_id_of_mrq matches the given pack_id. If after_rp is
+ * non-NULL and it is not found, then the search restarts from the beginning
+ * of the list. If no match is found then NULL is returned.
+ */
+static struct sg_request *
+sg_match_first_mrq_after(struct sg_fd *sfp, int pack_id,
+ struct sg_request *after_rp)
+{
+ bool found = false;
+ bool look_for_after = after_rp ? true : false;
+ int id;
+ unsigned long idx;
+ struct sg_request *srp;
+
+ if (atomic_read(&sfp->waiting) < 1)
+ return NULL;
+once_more:
+ xa_for_each_marked(&sfp->srp_arr, idx, srp, SG_XA_RQ_AWAIT) {
+ if (unlikely(!srp))
+ continue;
+ if (look_for_after) {
+ if (after_rp == srp)
+ look_for_after = false;
+ continue;
+ }
+ id = atomic_read(&srp->s_hdr4.pack_id_of_mrq);
+ if (id == 0) /* mrq_pack_ids cannot be zero */
+ continue;
+ if (pack_id == SG_PACK_ID_WILDCARD || pack_id == id) {
+ found = true;
+ break;
+ }
+ }
+ if (look_for_after) { /* after_rp may now be on free list */
+ look_for_after = false;
+ goto once_more;
+ }
+ return found ? srp : NULL;
+}
+
static int
sg_abort_req(struct sg_fd *sfp, struct sg_request *srp)
__must_hold(&sfp->srp_arr->xa_lock)
@@ -2990,6 +3067,117 @@ sg_abort_req(struct sg_fd *sfp, struct sg_request *srp)
return res;
}
+static int
+sg_mrq_abort_inflight(struct sg_fd *sfp, int pack_id)
+{
+ bool got_ebusy = false;
+ int res = 0;
+ unsigned long iflags;
+ struct sg_request *srp;
+ struct sg_request *prev_srp;
+
+ xa_lock_irqsave(&sfp->srp_arr, iflags);
+ for (prev_srp = NULL; true; prev_srp = srp) {
+ srp = sg_match_first_mrq_after(sfp, pack_id, prev_srp);
+ if (!srp)
+ break;
+ res = sg_abort_req(sfp, srp);
+ if (res == -EBUSY) /* check rest of active list */
+ got_ebusy = true;
+ else if (res)
+ break;
+ }
+ xa_unlock_irqrestore(&sfp->srp_arr, iflags);
+ if (res)
+ return res;
+ return got_ebusy ? -EBUSY : 0;
+}
+
+/*
+ * Implements ioctl(SG_IOABORT) when SGV4_FLAG_MULTIPLE_REQS set. pack_id is
+ * non-zero and is from the request_extra field. dev_scope is set when
+ * SGV4_FLAG_DEV_SCOPE is given; in that case there is one level of recursion
+ * if there is no match or clash with given sfp. Will abort the first
+ * mrq that matches then exit. Can only do mrq abort if the mrq submission
+ * used a non-zero ctl_obj.request_extra (pack_id).
+ */
+static int
+sg_mrq_abort(struct sg_fd *sfp, int pack_id, bool dev_scope)
+ __must_hold(sfp->f_mutex)
+{
+ int existing_id;
+ int res = 0;
+ unsigned long idx;
+ struct sg_device *sdp;
+ struct sg_fd *o_sfp;
+ struct sg_fd *s_sfp;
+
+ if (pack_id != SG_PACK_ID_WILDCARD)
+ SG_LOG(3, sfp, "%s: pack_id=%d, dev_scope=%s\n", __func__,
+ pack_id, (dev_scope ? "true" : "false"));
+ existing_id = atomic_read(&sfp->mrq_id_abort);
+ if (existing_id == 0) {
+ if (dev_scope)
+ goto check_whole_dev;
+ SG_LOG(1, sfp, "%s: sfp->mrq_id_abort is 0, nothing to do\n",
+ __func__);
+ return -EADDRNOTAVAIL;
+ }
+ if (pack_id == SG_PACK_ID_WILDCARD) {
+ pack_id = existing_id;
+ SG_LOG(3, sfp, "%s: wildcard becomes pack_id=%d\n", __func__,
+ pack_id);
+ } else if (pack_id != existing_id) {
+ if (dev_scope)
+ goto check_whole_dev;
+ SG_LOG(1, sfp, "%s: want id=%d, got sfp->mrq_id_abort=%d\n",
+ __func__, pack_id, existing_id);
+ return -EADDRINUSE;
+ }
+ if (test_and_set_bit(SG_FFD_MRQ_ABORT, sfp->ffd_bm))
+ SG_LOG(2, sfp, "%s: repeated SG_IOABORT on mrq_id=%d\n",
+ __func__, pack_id);
+
+ /* now look for inflight requests matching that mrq pack_id */
+ xa_lock(&sfp->srp_arr);
+ res = sg_mrq_abort_inflight(sfp, pack_id);
+ if (res == -EBUSY) {
+ res = sg_mrq_abort_inflight(sfp, pack_id);
+ if (res)
+ goto fini;
+ }
+ s_sfp = sg_fd_share_ptr(sfp);
+ if (s_sfp) { /* SGV4_FLAG_DO_ON_OTHER may have been used */
+ xa_unlock(&sfp->srp_arr);
+ sfp = s_sfp; /* if share, check other fd */
+ xa_lock(&sfp->srp_arr);
+ if (sg_fd_is_shared(sfp))
+ goto fini;
+ /* tough luck if other fd used same mrq pack_id */
+ res = sg_mrq_abort_inflight(sfp, pack_id);
+ if (res == -EBUSY)
+ res = sg_mrq_abort_inflight(sfp, pack_id);
+ }
+fini:
+ xa_unlock(&sfp->srp_arr);
+ return res;
+
+check_whole_dev:
+ res = -ENODATA;
+ sdp = sfp->parentdp;
+ xa_for_each(&sdp->sfp_arr, idx, o_sfp) {
+ if (o_sfp == sfp)
+ continue; /* already checked */
+ xa_lock(&o_sfp->srp_arr);
+ /* recurse, dev_scope==false is stopping condition */
+ res = sg_mrq_abort(o_sfp, pack_id, false);
+ xa_unlock(&o_sfp->srp_arr);
+ if (res == 0)
+ break;
+ }
+ return res;
+}
+
/*
* Tries to abort an inflight request/command. First it checks the current fd
* for a match on pack_id or tag. If there is a match, aborts that match.
@@ -3001,8 +3189,8 @@ static int
sg_ctl_abort(struct sg_device *sdp, struct sg_fd *sfp, void __user *p)
__must_hold(sfp->f_mutex)
{
- bool use_tag;
- int pack_id, tag, id;
+ bool use_tag, dev_scope;
+ int pack_id, id;
int res = 0;
unsigned long iflags, idx;
struct sg_fd *o_sfp;
@@ -3014,16 +3202,21 @@ sg_ctl_abort(struct sg_device *sdp, struct sg_fd *sfp, void __user *p)
return -EFAULT;
if (h4p->guard != 'Q' || h4p->protocol != 0 || h4p->subprotocol != 0)
return -EPERM;
+ dev_scope = !!(h4p->flags & SGV4_FLAG_DEV_SCOPE);
pack_id = h4p->request_extra;
- tag = h4p->request_tag;
+ if (h4p->flags & SGV4_FLAG_MULTIPLE_REQS) {
+ if (pack_id == 0)
+ return -ENOSTR;
+ return sg_mrq_abort(sfp, pack_id, dev_scope);
+ }
use_tag = test_bit(SG_FFD_PREFER_TAG, sfp->ffd_bm);
- id = use_tag ? tag : pack_id;
+ id = use_tag ? (int)h4p->request_tag : pack_id;
xa_lock_irqsave(&sfp->srp_arr, iflags);
srp = sg_match_request(sfp, use_tag, id);
if (!srp) { /* assume device (not just fd) scope */
xa_unlock_irqrestore(&sfp->srp_arr, iflags);
- if (!(h4p->flags & SGV4_FLAG_DEV_SCOPE))
+ if (!dev_scope)
return -ENODATA;
xa_for_each(&sdp->sfp_arr, idx, o_sfp) {
if (o_sfp == sfp)
@@ -3430,13 +3623,16 @@ static bool
sg_any_persistent_orphans(struct sg_fd *sfp)
{
if (test_bit(SG_FFD_KEEP_ORPHAN, sfp->ffd_bm)) {
- int num_waiting = atomic_read_acquire(&sfp->waiting);
+ int num_waiting = atomic_read(&sfp->waiting);
unsigned long idx;
struct sg_request *srp;
struct xarray *xafp = &sfp->srp_arr;
- if (num_waiting < 1)
- return false;
+ if (num_waiting < 1) {
+ num_waiting = atomic_read_acquire(&sfp->waiting);
+ if (num_waiting < 1)
+ return false;
+ }
xa_for_each_marked(xafp, idx, srp, SG_XA_RQ_AWAIT) {
if (test_bit(SG_FRQ_IS_ORPHAN, srp->frq_bm))
return true;
@@ -3902,7 +4098,8 @@ sg_ioctl_common(struct file *filp, struct sg_device *sdp, struct sg_fd *sfp,
return -ENODEV;
if (unlikely(read_only))
return -EPERM;
- mutex_lock(&sfp->f_mutex);
+ if (!mutex_trylock(&sfp->f_mutex))
+ return -EAGAIN;
res = sg_ctl_abort(sdp, sfp, p);
mutex_unlock(&sfp->f_mutex);
return res;
@@ -5451,9 +5648,12 @@ sg_mrq_get_ready_srp(struct sg_fd *sfp, struct sg_request **srpp)
*srpp = ERR_PTR(-ENODATA);
return true;
}
- num_waiting = atomic_read_acquire(&sfp->waiting);
- if (num_waiting < 1)
- goto fini;
+ num_waiting = atomic_read(&sfp->waiting);
+ if (num_waiting < 1) {
+ num_waiting = atomic_read_acquire(&sfp->waiting);
+ if (num_waiting < 1)
+ goto fini;
+ }
s_idx = (l_await_idx < 0) ? 0 : l_await_idx;
idx = s_idx;
--
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 ` Douglas Gilbert [this message]
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 ` [PATCH v18 71/83] sg: add mmap IO option for mrq metadata Douglas Gilbert
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-57-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