On 7/27/19 5:37 AM, Douglas Gilbert wrote:
> Add support for the sg v4 interface based on struct sg_io_v4 found
> in include/uapi/linux/bsg.h and only previously supported by the
> bsg driver. Add ioctl(SG_IOSUBMIT) and ioctl(SG_IORECEIVE) for
> async (non-blocking) usage of the sg v4 interface. Do not accept
> the v3 interface with these ioctls. Do not accept the v4
> interface with this driver's existing write() and read()
> system calls.
> 
> For sync (blocking) usage expand the existing ioctl(SG_IO)
> to additionally accept the sg v4 interface object.
> 
> Signed-off-by: Douglas Gilbert <[email protected]>
> ---
>  drivers/scsi/sg.c      | 489 ++++++++++++++++++++++++++++++++---------
>  include/uapi/scsi/sg.h |  37 +++-
>  2 files changed, 420 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
> index 4d6635af7da7..dd779931ada4 100644
> --- a/drivers/scsi/sg.c
> +++ b/drivers/scsi/sg.c
> @@ -7,8 +7,9 @@
>   *
>   * Original driver (sg.c):
>   *        Copyright (C) 1992 Lawrence Foard
> - * Version 2 and 3 extensions to driver:
> + * Version 2, 3 and 4 extensions to driver:
>   *        Copyright (C) 1998 - 2019 Douglas Gilbert
> + *
>   */
>  
>  static int sg_version_num = 30901;  /* [x]xyyzz where [x] empty when x=0 */
> @@ -40,10 +41,12 @@ static char *sg_version_date = "20190606";
>  #include <linux/atomic.h>
>  #include <linux/ratelimit.h>
>  #include <linux/uio.h>
> -#include <linux/cred.h> /* for sg_check_file_access() */
> +#include <linux/cred.h>                      /* for sg_check_file_access() */
> +#include <linux/bsg.h>
>  #include <linux/proc_fs.h>
>  
> -#include "scsi.h"
> +#include <scsi/scsi.h>
> +#include <scsi/scsi_eh.h>
>  #include <scsi/scsi_dbg.h>
>  #include <scsi/scsi_host.h>
>  #include <scsi/scsi_driver.h>
> @@ -99,6 +102,7 @@ enum sg_rq_state {
>  #define SG_ADD_RQ_MAX_RETRIES 40     /* to stop infinite _trylock(s) */
>  
>  /* Bit positions (flags) for sg_request::frq_bm bitmask follow */
> +#define SG_FRQ_IS_V4I                0       /* true (set) when is v4 
> interface */
>  #define SG_FRQ_IS_ORPHAN     1       /* owner of request gone */
>  #define SG_FRQ_SYNC_INVOC    2       /* synchronous (blocking) invocation */
>  #define SG_FRQ_DIO_IN_USE    3       /* false->indirect_IO,mmap; 1->dio */
> @@ -159,6 +163,15 @@ struct sg_slice_hdr3 {
>       void __user *usr_ptr;
>  };
>  
> +struct sg_slice_hdr4 {       /* parts of sg_io_v4 object needed in async 
> usage */
> +     void __user *sbp;       /* derived from sg_io_v4::response */
> +     u64 usr_ptr;            /* hold sg_io_v4::usr_ptr as given (u64) */
> +     int out_resid;
> +     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 */
> +};
> +
>  struct sg_scatter_hold {     /* holding area for scsi scatter gather info */
>       struct page **pages;    /* num_sgat element array of struct page* */
>       int buflen;             /* capacity in bytes (dlen<=buflen) */
> @@ -175,7 +188,10 @@ struct sg_request {      /* active SCSI command or 
> inactive on free list (fl) */
>       struct list_head fl_entry;      /* member of rq_fl */
>       spinlock_t req_lck;
>       struct sg_scatter_hold sgat_h;  /* hold buffer, perhaps scatter list */
> -     struct sg_slice_hdr3 s_hdr3;  /* subset of sg_io_hdr */
> +     union {
> +             struct sg_slice_hdr3 s_hdr3;  /* subset of sg_io_hdr */
> +             struct sg_slice_hdr4 s_hdr4; /* reduced size struct sg_io_v4 */
> +     };
>       u32 duration;           /* cmd duration in milliseconds */
>       u32 rq_flags;           /* hold user supplied flags */
>       u32 rq_info;            /* info supplied by v3 and v4 interfaces */
> @@ -235,7 +251,10 @@ struct sg_device { /* holds the state of each scsi 
> generic device */
>  struct sg_comm_wr_t {        /* arguments to sg_common_write() */
>       int timeout;
>       unsigned long frq_bm[1];        /* see SG_FRQ_* defines above */
> -     struct sg_io_hdr *h3p;
> +     union {         /* selector is frq_bm.SG_FRQ_IS_V4I */
> +             struct sg_io_hdr *h3p;
> +             struct sg_io_v4 *h4p;
> +     };
>       u8 *cmnd;
>  };
>  
> @@ -244,12 +263,12 @@ static void sg_rq_end_io(struct request *rq, 
> blk_status_t status);
>  /* Declarations of other static functions used before they are defined */
>  static int sg_proc_init(void);
>  static int sg_start_req(struct sg_request *srp, u8 *cmd, int cmd_len,
> -                     int dxfer_dir);
> +                     struct sg_io_v4 *h4p, int dxfer_dir);
>  static void sg_finish_scsi_blk_rq(struct sg_request *srp);
>  static int sg_mk_sgat(struct sg_request *srp, struct sg_fd *sfp, int minlen);
> -static int sg_submit(struct file *filp, struct sg_fd *sfp,
> -                  struct sg_io_hdr *hp, bool sync,
> -                  struct sg_request **o_srp);
> +static int sg_v3_submit(struct file *filp, struct sg_fd *sfp,
> +                     struct sg_io_hdr *hp, bool sync,
> +                     struct sg_request **o_srp);
>  static struct sg_request *sg_common_write(struct sg_fd *sfp,
>                                         struct sg_comm_wr_t *cwp);
>  static int sg_rd_append(struct sg_request *srp, void __user *outp,
> @@ -257,11 +276,11 @@ static int sg_rd_append(struct sg_request *srp, void 
> __user *outp,
>  static void sg_remove_sgat(struct sg_request *srp);
>  static struct sg_fd *sg_add_sfp(struct sg_device *sdp);
>  static void sg_remove_sfp(struct kref *);
> -static struct sg_request *sg_find_srp_by_id(struct sg_fd *sfp, int pack_id);
> +static struct sg_request *sg_find_srp_by_id(struct sg_fd *sfp, int id);
>  static struct sg_request *sg_add_request(struct sg_fd *sfp, int dxfr_len,
>                                        struct sg_comm_wr_t *cwrp);
>  static void sg_deact_request(struct sg_fd *sfp, struct sg_request *srp);
> -static struct sg_device *sg_get_dev(int dev);
> +static struct sg_device *sg_get_dev(int min_dev);
>  static void sg_device_destroy(struct kref *kref);
>  static struct sg_request *sg_mk_srp_sgat(struct sg_fd *sfp, bool first,
>                                        int db_len);
> @@ -274,8 +293,11 @@ static void sg_rep_rq_state_fail(struct sg_fd *sfp,
>  
>  #define SZ_SG_HEADER ((int)sizeof(struct sg_header)) /* v1 and v2 header */
>  #define SZ_SG_IO_HDR ((int)sizeof(struct sg_io_hdr)) /* v3 header */
> +#define SZ_SG_IO_V4 ((int)sizeof(struct sg_io_v4))  /* v4 header (in bsg.h) 
> */
>  #define SZ_SG_REQ_INFO ((int)sizeof(struct sg_req_info))
>  
> +/* There is a assert that SZ_SG_IO_V4 >= SZ_SG_IO_HDR in first function */
> +
>  #define SG_IS_DETACHING(sdp) test_bit(SG_FDEV_DETACHING, (sdp)->fdev_bm)
>  #define SG_HAVE_EXCLUDE(sdp) test_bit(SG_FDEV_EXCLUDE, (sdp)->fdev_bm)
>  #define SG_RS_ACTIVE(srp) (atomic_read(&(srp)->rq_st) != SG_RS_INACTIVE)
> @@ -295,6 +317,7 @@ static void sg_rep_rq_state_fail(struct sg_fd *sfp,
>  
>  #if IS_ENABLED(CONFIG_SCSI_LOGGING) && IS_ENABLED(SG_DEBUG)
>  #define SG_LOG_BUFF_SZ 48
> +#define SG_LOG_ACTIVE 1
>  
>  #define SG_LOG(depth, sfp, fmt, a...)                                        
> \
>       do {                                                            \
> @@ -332,6 +355,10 @@ static void sg_rep_rq_state_fail(struct sg_fd *sfp,
>  static int
>  sg_check_file_access(struct file *filp, const char *caller)
>  {
> +     /* can't put following in declarations where it belongs */
> +     compiletime_assert(SZ_SG_IO_V4 >= SZ_SG_IO_HDR,
> +                        "struct sg_io_v4 should be larger than sg_io_hdr");
> +
>       if (filp->f_cred != current_real_cred()) {
>               pr_err_once("%s: process %d (%s) changed security contexts 
> after opening file descriptor, this is not allowed.\n",
>                       caller, task_tgid_vnr(current), current->comm);
> @@ -347,10 +374,11 @@ sg_check_file_access(struct file *filp, const char 
> *caller)
>  
>  static int
>  sg_wait_open_event(struct sg_device *sdp, bool o_excl)
> +     __must_hold(&sdp->open_rel_lock)

This actually has nothing to do with the sg4 interface support.
Please move out locking annotations into a separate patch.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Teamlead Storage & Networking
[email protected]                                   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)

Reply via email to