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 v6 12/37] sg: ioctl handling
Date: Mon, 13 Jan 2020 00:57:30 +0100 [thread overview]
Message-ID: <20200112235755.14197-13-dgilbert@interlog.com> (raw)
In-Reply-To: <20200112235755.14197-1-dgilbert@interlog.com>
Shorten sg_ioctl() by adding some helper functions. sg_ioctl()
is the main entry point for ioctls used on this driver's
devices.
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
---
drivers/scsi/sg.c | 334 ++++++++++++++++++++++++++++------------------
1 file changed, 205 insertions(+), 129 deletions(-)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index a60b02b65392..86634596dcf8 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1018,6 +1018,56 @@ sg_fill_request_table(struct sg_fd *sfp, struct sg_req_info *rinfo)
}
}
+/*
+ * Handles ioctl(SG_IO) for blocking (sync) usage of v3 or v4 interface.
+ * Returns 0 on success else a negated errno.
+ */
+static int
+sg_ctl_sg_io(struct file *filp, struct sg_device *sdp, struct sg_fd *sfp,
+ void __user *p)
+{
+ bool read_only = O_RDWR != (filp->f_flags & O_ACCMODE);
+ int res;
+ struct sg_request *srp;
+
+ res = sg_allow_if_err_recovery(sdp, false);
+ if (res)
+ return res;
+ res = sg_submit(sfp, filp, p, SZ_SG_IO_HDR, true, read_only,
+ true, &srp);
+ if (res < 0)
+ return res;
+ res = wait_event_interruptible
+ (sfp->read_wait, (srp_done(sfp, srp) || SG_IS_DETACHING(sdp)));
+ if (SG_IS_DETACHING(sdp))
+ return -ENODEV;
+ spin_lock_irq(&sfp->rq_list_lock);
+ if (srp->done) {
+ srp->done = 2;
+ spin_unlock_irq(&sfp->rq_list_lock);
+ res = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp);
+ return (res < 0) ? res : 0;
+ }
+ srp->orphan = 1;
+ spin_unlock_irq(&sfp->rq_list_lock);
+ return res; /* -ERESTARTSYS because signal hit process */
+}
+
+static int
+sg_set_reserved_sz(struct sg_fd *sfp, int want_rsv_sz)
+{
+ if (want_rsv_sz != sfp->reserve.buflen) {
+ if (sfp->mmap_called ||
+ sfp->res_in_use) {
+ return -EBUSY;
+ }
+
+ sg_remove_scat(sfp, &sfp->reserve);
+ sg_build_reserve(sfp, want_rsv_sz);
+ }
+ return 0;
+}
+
#ifdef CONFIG_COMPAT
struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
char req_state;
@@ -1045,16 +1095,69 @@ static int put_compat_request_table(struct compat_sg_req_info __user *o,
}
#endif
+static int
+sg_ctl_req_tbl(struct sg_fd *sfp, void __user *p)
+{
+ int result;
+ unsigned long iflags;
+ sg_req_info_t *rinfo;
+
+ rinfo = kcalloc(SG_MAX_QUEUE, SZ_SG_REQ_INFO,
+ GFP_KERNEL);
+ if (!rinfo)
+ return -ENOMEM;
+ spin_lock_irqsave(&sfp->rq_list_lock, iflags);
+ sg_fill_request_table(sfp, rinfo);
+ spin_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ result = put_compat_request_table(p, rinfo);
+ else
+ result = copy_to_user(p, rinfo,
+ SZ_SG_REQ_INFO * SG_MAX_QUEUE);
+#else
+ result = copy_to_user(p, rinfo,
+ SZ_SG_REQ_INFO * SG_MAX_QUEUE);
+#endif
+ result = result ? -EFAULT : 0;
+ kfree(rinfo);
+ return result;
+}
+
+static int
+sg_ctl_scsi_id(struct scsi_device *sdev, struct sg_fd *sfp, void __user *p)
+{
+ struct sg_scsi_id ss_id;
+
+ SG_LOG(3, sfp, "%s: SG_GET_SCSI_ID\n", __func__);
+ ss_id.host_no = sdev->host->host_no;
+ ss_id.channel = sdev->channel;
+ ss_id.scsi_id = sdev->id;
+ ss_id.lun = sdev->lun;
+ ss_id.scsi_type = sdev->type;
+ ss_id.h_cmd_per_lun = sdev->host->cmd_per_lun;
+ ss_id.d_queue_depth = sdev->queue_depth;
+ ss_id.unused[0] = 0;
+ ss_id.unused[1] = 0;
+ if (copy_to_user(p, &ss_id, sizeof(struct sg_scsi_id)))
+ return -EFAULT;
+ return 0;
+}
+
static long
sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
{
- void __user *p = (void __user *)arg;
+ bool read_only = O_RDWR != (filp->f_flags & O_ACCMODE);
+ int val;
+ int result = 0;
+ void __user *p = ((void __user *)(uintptr_t)arg);
int __user *ip = p;
- int result, val, read_only;
struct sg_device *sdp;
struct sg_fd *sfp;
struct sg_request *srp;
+ struct scsi_device *sdev;
unsigned long iflags;
+ __maybe_unused const char *pmlp = ", pass to mid-level";
sfp = filp->private_data;
sdp = sfp->parentdp;
@@ -1062,137 +1165,117 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
!!(filp->f_flags & O_NONBLOCK));
if (!sdp)
return -ENXIO;
- read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
+ if (unlikely(SG_IS_DETACHING(sdp)))
+ return -ENODEV;
+ sdev = sdp->device;
switch (cmd_in) {
case SG_IO:
- result = sg_allow_if_err_recovery(sdp, false);
- if (result)
- return result;
- result = sg_submit(sfp, filp, p, SZ_SG_IO_HDR, true, read_only,
- true, &srp);
- if (result < 0)
- return result;
- result = wait_event_interruptible(sfp->read_wait,
- (srp_done(sfp, srp) || SG_IS_DETACHING(sdp)));
- if (SG_IS_DETACHING(sdp))
- return -ENODEV;
- spin_lock_irq(&sfp->rq_list_lock);
- if (srp->done) {
- srp->done = 2;
- spin_unlock_irq(&sfp->rq_list_lock);
- result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp);
- return (result < 0) ? result : 0;
- }
- srp->orphan = 1;
- spin_unlock_irq(&sfp->rq_list_lock);
- return result; /* -ERESTARTSYS because signal hit process */
- case SG_SET_TIMEOUT:
- result = get_user(val, ip);
- if (result)
- return result;
- if (val < 0)
- return -EIO;
- if (val >= mult_frac((s64)INT_MAX, USER_HZ, HZ))
- val = min_t(s64, mult_frac((s64)INT_MAX, USER_HZ, HZ),
- INT_MAX);
- sfp->timeout_user = val;
- sfp->timeout = mult_frac(val, HZ, USER_HZ);
-
- return 0;
- case SG_GET_TIMEOUT: /* N.B. User receives timeout as return value */
- /* strange ..., for backward compatibility */
- return sfp->timeout_user;
- case SG_SET_FORCE_LOW_DMA:
- /*
- * N.B. This ioctl never worked properly, but failed to
- * return an error value. So returning '0' to keep compability
- * with legacy applications.
- */
- return 0;
- case SG_GET_LOW_DMA:
- return put_user((int) sdp->device->host->unchecked_isa_dma, ip);
+ return sg_ctl_sg_io(filp, sdp, sfp, p);
case SG_GET_SCSI_ID:
- {
- sg_scsi_id_t v;
-
- if (SG_IS_DETACHING(sdp))
- return -ENODEV;
- memset(&v, 0, sizeof(v));
- v.host_no = sdp->device->host->host_no;
- v.channel = sdp->device->channel;
- v.scsi_id = sdp->device->id;
- v.lun = sdp->device->lun;
- v.scsi_type = sdp->device->type;
- v.h_cmd_per_lun = sdp->device->host->cmd_per_lun;
- v.d_queue_depth = sdp->device->queue_depth;
- if (copy_to_user(p, &v, sizeof(sg_scsi_id_t)))
- return -EFAULT;
- return 0;
- }
+ return sg_ctl_scsi_id(sdev, sfp, p);
case SG_SET_FORCE_PACK_ID:
+ SG_LOG(3, sfp, "%s: SG_SET_FORCE_PACK_ID\n", __func__);
result = get_user(val, ip);
if (result)
return result;
sfp->force_packid = val ? 1 : 0;
return 0;
case SG_GET_PACK_ID:
+ val = -1;
spin_lock_irqsave(&sfp->rq_list_lock, iflags);
list_for_each_entry(srp, &sfp->rq_list, entry) {
if ((1 == srp->done) && (!srp->sg_io_owned)) {
- spin_unlock_irqrestore(&sfp->rq_list_lock,
- iflags);
- return put_user(srp->header.pack_id, ip);
+ val = srp->header.pack_id;
+ break;
}
}
spin_unlock_irqrestore(&sfp->rq_list_lock, iflags);
- return put_user(-1, ip);
+ SG_LOG(3, sfp, "%s: SG_GET_PACK_ID=%d\n", __func__, val);
+ return put_user(val, ip);
case SG_GET_NUM_WAITING:
return put_user(atomic_read(&sfp->waiting), ip);
case SG_GET_SG_TABLESIZE:
+ SG_LOG(3, sfp, "%s: SG_GET_SG_TABLESIZE=%d\n", __func__,
+ sdp->max_sgat_sz);
return put_user(sdp->max_sgat_sz, ip);
case SG_SET_RESERVED_SIZE:
- result = get_user(val, ip);
- if (result)
- return result;
- if (val < 0)
- return -EINVAL;
- val = min_t(int, val,
- max_sectors_bytes(sdp->device->request_queue));
mutex_lock(&sfp->f_mutex);
- if (val != sfp->reserve.buflen) {
- if (sfp->mmap_called ||
- sfp->res_in_use) {
- mutex_unlock(&sfp->f_mutex);
- return -EBUSY;
+ result = get_user(val, ip);
+ if (!result) {
+ if (val >= 0 && val <= (1024 * 1024 * 1024)) {
+ result = sg_set_reserved_sz(sfp, val);
+ } else {
+ SG_LOG(3, sfp, "%s: invalid size\n", __func__);
+ result = -EINVAL;
}
-
- sg_remove_scat(sfp, &sfp->reserve);
- sg_build_reserve(sfp, val);
}
mutex_unlock(&sfp->f_mutex);
- return 0;
+ return result;
case SG_GET_RESERVED_SIZE:
val = min_t(int, sfp->reserve.buflen,
- max_sectors_bytes(sdp->device->request_queue));
+ max_sectors_bytes(sdev->request_queue));
+ SG_LOG(3, sfp, "%s: SG_GET_RESERVED_SIZE=%d\n",
+ __func__, val);
return put_user(val, ip);
case SG_SET_COMMAND_Q:
+ SG_LOG(3, sfp, "%s: SG_SET_COMMAND_Q\n", __func__);
result = get_user(val, ip);
if (result)
return result;
sfp->cmd_q = val ? 1 : 0;
return 0;
case SG_GET_COMMAND_Q:
+ SG_LOG(3, sfp, "%s: SG_GET_COMMAND_Q\n", __func__);
return put_user((int) sfp->cmd_q, ip);
case SG_SET_KEEP_ORPHAN:
+ SG_LOG(3, sfp, "%s: SG_SET_KEEP_ORPHAN\n", __func__);
result = get_user(val, ip);
if (result)
return result;
sfp->keep_orphan = val;
return 0;
case SG_GET_KEEP_ORPHAN:
+ SG_LOG(3, sfp, "%s: SG_GET_KEEP_ORPHAN\n", __func__);
return put_user((int) sfp->keep_orphan, ip);
+ case SG_GET_VERSION_NUM:
+ SG_LOG(3, sfp, "%s: SG_GET_VERSION_NUM\n", __func__);
+ return put_user(sg_version_num, ip);
+ case SG_GET_REQUEST_TABLE:
+ return sg_ctl_req_tbl(sfp, p);
+ case SG_SCSI_RESET:
+ SG_LOG(3, sfp, "%s: SG_SCSI_RESET\n", __func__);
+ break;
+ case SG_SET_TIMEOUT:
+ SG_LOG(3, sfp, "%s: SG_SET_TIMEOUT\n", __func__);
+ result = get_user(val, ip);
+ if (result)
+ return result;
+ if (val < 0)
+ return -EIO;
+ if (val >= mult_frac((s64)INT_MAX, USER_HZ, HZ))
+ val = min_t(s64, mult_frac((s64)INT_MAX, USER_HZ, HZ),
+ INT_MAX);
+ sfp->timeout_user = val;
+ sfp->timeout = mult_frac(val, HZ, USER_HZ);
+ return 0;
+ case SG_GET_TIMEOUT: /* N.B. User receives timeout as return value */
+ /* strange ..., for backward compatibility */
+ SG_LOG(3, sfp, "%s: SG_GET_TIMEOUT\n", __func__);
+ return sfp->timeout_user;
+ case SG_SET_FORCE_LOW_DMA:
+ /*
+ * N.B. This ioctl never worked properly, but failed to
+ * return an error value. So returning '0' to keep
+ * compatibility with legacy applications.
+ */
+ SG_LOG(3, sfp, "%s: SG_SET_FORCE_LOW_DMA\n", __func__);
+ return 0;
+ case SG_GET_LOW_DMA:
+ SG_LOG(3, sfp, "%s: SG_GET_LOW_DMA\n", __func__);
+ return put_user((int)sdev->host->unchecked_isa_dma, ip);
case SG_NEXT_CMD_LEN:
+ SG_LOG(3, sfp, "%s: SG_NEXT_CMD_LEN\n", __func__);
result = get_user(val, ip);
if (result)
return result;
@@ -1200,80 +1283,73 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
return -ENOMEM;
sfp->next_cmd_len = (val > 0) ? val : 0;
return 0;
- case SG_GET_VERSION_NUM:
- return put_user(sg_version_num, ip);
case SG_GET_ACCESS_COUNT:
+ SG_LOG(3, sfp, "%s: SG_GET_ACCESS_COUNT\n", __func__);
/* faked - we don't have a real access count anymore */
- val = (sdp->device ? 1 : 0);
+ val = (sdev ? 1 : 0);
return put_user(val, ip);
- case SG_GET_REQUEST_TABLE:
- {
- sg_req_info_t *rinfo;
-
- rinfo = kcalloc(SG_MAX_QUEUE, SZ_SG_REQ_INFO,
- GFP_KERNEL);
- if (!rinfo)
- return -ENOMEM;
- spin_lock_irqsave(&sfp->rq_list_lock, iflags);
- sg_fill_request_table(sfp, rinfo);
- spin_unlock_irqrestore(&sfp->rq_list_lock, iflags);
- #ifdef CONFIG_COMPAT
- if (in_compat_syscall())
- result = put_compat_request_table(p, rinfo);
- else
- #endif
- result = copy_to_user(p, rinfo,
- SZ_SG_REQ_INFO * SG_MAX_QUEUE);
- result = result ? -EFAULT : 0;
- kfree(rinfo);
- return result;
- }
case SG_EMULATED_HOST:
- if (SG_IS_DETACHING(sdp))
- return -ENODEV;
- return put_user(sdp->device->host->hostt->emulated, ip);
+ SG_LOG(3, sfp, "%s: SG_EMULATED_HOST\n", __func__);
+ return put_user(sdev->host->hostt->emulated, ip);
case SCSI_IOCTL_SEND_COMMAND:
- if (SG_IS_DETACHING(sdp))
- return -ENODEV;
- return sg_scsi_ioctl(sdp->device->request_queue, NULL, filp->f_mode, p);
+ SG_LOG(3, sfp, "%s: SCSI_IOCTL_SEND_COMMAND\n", __func__);
+ return sg_scsi_ioctl(sdev->request_queue, NULL, filp->f_mode,
+ p);
case SG_SET_DEBUG:
+ SG_LOG(3, sfp, "%s: SG_SET_DEBUG\n", __func__);
result = get_user(val, ip);
if (result)
return result;
assign_bit(SG_FDEV_LOG_SENSE, sdp->fdev_bm, val);
return 0;
case BLKSECTGET:
- return put_user(max_sectors_bytes(sdp->device->request_queue),
- ip);
+ SG_LOG(3, sfp, "%s: BLKSECTGET\n", __func__);
+ return put_user(max_sectors_bytes(sdev->request_queue), ip);
case BLKTRACESETUP:
- return blk_trace_setup(sdp->device->request_queue,
+ SG_LOG(3, sfp, "%s: BLKTRACESETUP\n", __func__);
+ return blk_trace_setup(sdev->request_queue,
sdp->disk->disk_name,
MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
NULL, p);
case BLKTRACESTART:
- return blk_trace_startstop(sdp->device->request_queue, 1);
+ SG_LOG(3, sfp, "%s: BLKTRACESTART\n", __func__);
+ return blk_trace_startstop(sdev->request_queue, 1);
case BLKTRACESTOP:
- return blk_trace_startstop(sdp->device->request_queue, 0);
+ SG_LOG(3, sfp, "%s: BLKTRACESTOP\n", __func__);
+ return blk_trace_startstop(sdev->request_queue, 0);
case BLKTRACETEARDOWN:
- return blk_trace_remove(sdp->device->request_queue);
+ SG_LOG(3, sfp, "%s: BLKTRACETEARDOWN\n", __func__);
+ return blk_trace_remove(sdev->request_queue);
case SCSI_IOCTL_GET_IDLUN:
+ SG_LOG(3, sfp, "%s: SCSI_IOCTL_GET_IDLUN %s\n", __func__,
+ pmlp);
+ break;
case SCSI_IOCTL_GET_BUS_NUMBER:
+ SG_LOG(3, sfp, "%s: SCSI_IOCTL_GET_BUS_NUMBER%s\n",
+ __func__, pmlp);
+ break;
case SCSI_IOCTL_PROBE_HOST:
+ SG_LOG(3, sfp, "%s: SCSI_IOCTL_PROBE_HOST%s",
+ __func__, pmlp);
+ break;
case SG_GET_TRANSFORM:
- case SG_SCSI_RESET:
- if (SG_IS_DETACHING(sdp))
- return -ENODEV;
+ SG_LOG(3, sfp, "%s: SG_GET_TRANSFORM%s\n", __func__, pmlp);
+ break;
+ case SG_SET_TRANSFORM:
+ SG_LOG(3, sfp, "%s: SG_SET_TRANSFORM%s\n", __func__, pmlp);
break;
default:
+ SG_LOG(3, sfp, "%s: unrecognized ioctl [0x%x]%s\n",
+ __func__, cmd_in, pmlp);
if (read_only)
- return -EPERM; /* don't know so take safe approach */
+ return -EPERM; /* don't know, so take safer approach */
break;
}
result = sg_allow_if_err_recovery(sdp, filp->f_flags & O_NDELAY);
if (result)
return result;
- return scsi_ioctl(sdp->device, cmd_in, p);
+ return scsi_ioctl(sdev, cmd_in, p);
}
#if IS_ENABLED(CONFIG_COMPAT)
--
2.24.1
next prev parent reply other threads:[~2020-01-12 23:58 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-12 23:57 [PATCH v6 00/37] sg: add v4 interface Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 01/37] sg: move functions around Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 02/37] sg: remove typedefs, type+formatting cleanup Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 03/37] sg: sg_log and is_enabled Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 04/37] sg: rework sg_poll(), minor changes Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 05/37] sg: bitops in sg_device Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 06/37] sg: make open count an atomic Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 07/37] sg: move header to uapi section Douglas Gilbert
2020-01-13 5:34 ` kbuild test robot
2020-01-14 9:16 ` Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 08/37] sg: speed sg_poll and sg_get_num_waiting Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 09/37] sg: sg_allow_if_err_recovery and renames Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 10/37] sg: improve naming Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 11/37] sg: change rwlock to spinlock Douglas Gilbert
2020-01-12 23:57 ` Douglas Gilbert [this message]
2020-01-12 23:57 ` [PATCH v6 13/37] sg: split sg_read Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 14/37] sg: sg_common_write add structure for arguments Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 15/37] sg: rework sg_vma_fault Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 16/37] sg: rework sg_mmap Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 17/37] sg: replace sg_allow_access Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 18/37] sg: rework scatter gather handling Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 19/37] sg: introduce request state machine Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 20/37] sg: sg_find_srp_by_id Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 21/37] sg: sg_fill_request_element Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 22/37] sg: printk change %p to %pK Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 23/37] sg: xarray for fds in device Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 24/37] sg: xarray for reqs in fd Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 25/37] sg: replace rq array with lists Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 26/37] sg: sense buffer rework Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 27/37] sg: add sg v4 interface support Douglas Gilbert
2020-01-13 8:28 ` kbuild test robot
2020-01-14 10:21 ` Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 28/37] sg: rework debug info Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 29/37] sg: add 8 byte SCSI LUN to sg_scsi_id Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 30/37] sg: expand sg_comm_wr_t Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 31/37] sg: add sg_iosubmit_v3 and sg_ioreceive_v3 ioctls Douglas Gilbert
2020-01-13 0:50 ` Bart Van Assche
2020-01-13 10:39 ` Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 32/37] sg: add some __must_hold macros Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 33/37] sg: move procfs objects to avoid forward decls Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 34/37] sg: protect multiple receivers Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 35/37] sg: first debugfs support Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 36/37] sg: warn v3 write system call users Douglas Gilbert
2020-01-12 23:57 ` [PATCH v6 37/37] sg: bump version to 4.0.08 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=20200112235755.14197-13-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;
as well as URLs for NNTP newsgroup(s).