Add a SG_SET_GET_EXTENDED ioctl control for whether commands
will be queued_at_head or queued_at_tail by the block layer
(together with the scsi mid-level). It has file scope.
Also add a read_value integer the can be used by write a
value from the SG_SEIRV_* group then the corresponding value
will be returned.
Signed-off-by: Douglas Gilbert
---
The user can still override the new file scope setting on a
a per command basis with the SG_FLAG_Q_AT_HEAD and
SG_FLAG_Q_AT_TAIL in the sg v3 and v4 structures.
An example of read_value usage is to write the value
SG_SEIRV_FL_RQS to the read_value field. Then after the
SG_SET_GET_EXTENDED ioctl is run, the number of (inactive)
requests currently on this file descriptor's request free
list is placed in the read_value field.
Added in v3 is SG_SEIRV_DEV_FL_RQS which is an expansion of
SG_SEIRV_FL_RQS. SG_SEIRV_DEV_FL_RQS counts free list entries
on all sg file descriptors currently open on the device that
the file descriptor (given to ioctl()) is associated with.
drivers/scsi/sg.c | 160 +++--
include/scsi/sg.h | 32 ++---
include/uapi/scsi/sg.h | 49 ++---
3 files changed, 150 insertions(+), 91 deletions(-)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 3e89bbd508de..4d6966d40949 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -59,7 +59,7 @@ static int sg_version_num = 30901;/* 2 digits for each
component */
#ifdef CONFIG_SCSI_PROC_FS
#include
-static char *sg_version_date = "20181019";
+static char *sg_version_date = "20181024";
static int sg_proc_init(void);
#endif
@@ -95,6 +95,10 @@ enum sg_rq_state {
#define SG_DEF_TIME_UNIT SG_TIME_UNIT_MS
#define SG_DEFAULT_TIMEOUT mult_frac(SG_DEFAULT_TIMEOUT_USER, HZ, USER_HZ)
+#define SG_FD_Q_AT_TAIL true
+#define SG_FD_Q_AT_HEAD false
+#define SG_DEFAULT_Q_AT SG_FD_Q_AT_HEAD/* for backward compatibility */
+
int sg_big_buff = SG_DEF_RESERVED_SIZE;
/* N.B. This variable is readable and writeable via
/proc/scsi/sg/def_reserved_size . Each time sg_open() is called a buffer
@@ -187,6 +191,7 @@ struct sg_fd { /* holds the state of a file
descriptor */
bool keep_orphan;/* false -> drop (def), true -> keep for read() */
bool mmap_called; /* false -> mmap() never called on this fd */
bool time_in_ns;/* report times in nanoseconds */
+ bool q_at_tail; /* queue at tail if true, head when false */
u8 next_cmd_len;/* 0: automatic, >0: use on next write() */
struct sg_request *reserve_srp; /* allocate on open(), starts on fl */
struct fasync_struct *async_qp; /* used by asynchronous notification */
@@ -238,7 +243,7 @@ static struct sg_request *sg_add_request(struct sg_fd *sfp,
int dxfr_len,
static void sg_remove_request(struct sg_fd *sfp, struct sg_request *srp);
static struct sg_device *sg_get_dev(int min_dev);
static void sg_device_destroy(struct kref *kref);
-static const char *sg_rq_state_str(u8 rq_state, bool long_str);
+static const char *sg_rq_state_str(enum sg_rq_state rq_state, bool long_str);
static struct sg_request *sg_mk_srp(struct sg_fd *sfp, bool first,
rwlock_t *rwlp, unsigned long *iflagsp);
@@ -855,7 +860,7 @@ sg_common_write(struct sg_fd *sfp, const struct sg_io_hdr
*hi_p,
if (h4p || !hi_p)
return ERR_PTR(-EOPNOTSUPP);
- srp = sg_add_request(sfp, hi_p->dxfer_len, false);
+ srp = sg_add_request(sfp, hi_p->dxfer_len, sync);
if (IS_ERR(srp))
return srp;
srp->header = *hi_p;/* structure assignment, could memcpy */
@@ -897,9 +902,13 @@ sg_common_write(struct sg_fd *sfp, const struct sg_io_hdr
*hi_p,
srp->start_ts = ktime_get_with_offset(TK_OFFS_BOOT);
else
hp->duration = jiffies_to_msecs(jiffies);
- /* at tail if v3 or later interface and tail flag set */
- at_head = !(hp->interface_id != '\0' &&
- (SG_FLAG_Q_AT_TAIL & hp->flags));
+
+ if (hp->interface_id == '\0') /* v1 and v2 interface */
+ at_head = true; /* backward compatibility */
+ else if (sfp->q_at_tail) /* cmd flags can override sfd setting */
+ at_head = (hp->flags & SG_FLAG_Q_AT_HEAD);
+ else/* this sfd is defaulting to head */
+ at_head = !(hp->flags & SG_FLAG_Q_AT_TAIL);
srp->rq->timeout = timeout;
kref_get(>f_ref); /* sg_rq_end_io() does kref_put(). */
@@ -1084,30 +1093,30 @@ sg_reserved_sz(struct sg_fd *sfp, struct
sg_extended_info *seip)
{
bool free_n_srp = false;
int result = 0;
- int val, mx_sect_bytes;
+ int new_sz, mx_sect_bytes;
unsigned long iflags;
- struct sg_request *srp; /* prior reserve request */
+ struct sg_request *o_srp; /* prior reserve request */
struct sg_request