Merge tag 'block-5.14-2021-07-08' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 9 Jul 2021 19:05:33 +0000 (12:05 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 9 Jul 2021 19:05:33 +0000 (12:05 -0700)
Pull more block updates from Jens Axboe:
 "A combination of changes that ended up depending on both the driver
  and core branch (and/or the IDE removal), and a few late arriving
  fixes. In detail:

   - Fix io ticks wrap-around issue (Chunguang)

   - nvme-tcp sock locking fix (Maurizio)

   - s390-dasd fixes (Kees, Christoph)

   - blk_execute_rq polling support (Keith)

   - blk-cgroup RCU iteration fix (Yu)

   - nbd backend ID addition (Prasanna)

   - Partition deletion fix (Yufen)

   - Use blk_mq_alloc_disk for mmc, mtip32xx, ubd (Christoph)

   - Removal of now dead block request types due to IDE removal
     (Christoph)

   - Loop probing and control device cleanups (Christoph)

   - Device uevent fix (Christoph)

   - Misc cleanups/fixes (Tetsuo, Christoph)"

* tag 'block-5.14-2021-07-08' of git://git.kernel.dk/linux-block: (34 commits)
  blk-cgroup: prevent rcu_sched detected stalls warnings while iterating blkgs
  block: fix the problem of io_ticks becoming smaller
  nvme-tcp: can't set sk_user_data without write_lock
  loop: remove unused variable in loop_set_status()
  block: remove the bdgrab in blk_drop_partitions
  block: grab a device refcount in disk_uevent
  s390/dasd: Avoid field over-reading memcpy()
  dasd: unexport dasd_set_target_state
  block: check disk exist before trying to add partition
  ubd: remove dead code in ubd_setup_common
  nvme: use return value from blk_execute_rq()
  block: return errors from blk_execute_rq()
  nvme: use blk_execute_rq() for passthrough commands
  block: support polling through blk_execute_rq
  block: remove REQ_OP_SCSI_{IN,OUT}
  block: mark blk_mq_init_queue_data static
  loop: rewrite loop_exit using idr_for_each_entry
  loop: split loop_lookup
  loop: don't allow deleting an unspecified loop device
  loop: move loop_ctl_mutex locking into loop_add
  ...

12 files changed:
1  2 
arch/um/drivers/ubd_kern.c
block/bsg-lib.c
block/bsg.c
block/scsi_ioctl.c
drivers/nvme/host/fc.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/target/target_core_pscsi.c
include/linux/blk_types.h
include/linux/blkdev.h

@@@ -125,9 -125,7 +125,7 @@@ static const struct block_device_operat
  };
  
  /* Protected by ubd_lock */
- static int fake_major = UBD_MAJOR;
  static struct gendisk *ubd_gendisk[MAX_DEV];
- static struct gendisk *fake_gendisk[MAX_DEV];
  
  #ifdef CONFIG_BLK_DEV_UBD_SYNC
  #define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
@@@ -197,54 -195,19 +195,19 @@@ struct ubd 
  /* Protected by ubd_lock */
  static struct ubd ubd_devs[MAX_DEV] = { [0 ... MAX_DEV - 1] = DEFAULT_UBD };
  
- /* Only changed by fake_ide_setup which is a setup */
- static int fake_ide = 0;
- static struct proc_dir_entry *proc_ide_root = NULL;
- static struct proc_dir_entry *proc_ide = NULL;
  static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,
                                 const struct blk_mq_queue_data *bd);
  
- static void make_proc_ide(void)
- {
-       proc_ide_root = proc_mkdir("ide", NULL);
-       proc_ide = proc_mkdir("ide0", proc_ide_root);
- }
- static int fake_ide_media_proc_show(struct seq_file *m, void *v)
- {
-       seq_puts(m, "disk\n");
-       return 0;
- }
- static void make_ide_entries(const char *dev_name)
- {
-       struct proc_dir_entry *dir, *ent;
-       char name[64];
-       if(proc_ide_root == NULL) make_proc_ide();
-       dir = proc_mkdir(dev_name, proc_ide);
-       if(!dir) return;
-       ent = proc_create_single("media", S_IRUGO, dir,
-                       fake_ide_media_proc_show);
-       if(!ent) return;
-       snprintf(name, sizeof(name), "ide0/%s", dev_name);
-       proc_symlink(dev_name, proc_ide_root, name);
- }
  static int fake_ide_setup(char *str)
  {
-       fake_ide = 1;
+       pr_warn("The fake_ide option has been removed\n");
        return 1;
  }
  __setup("fake_ide", fake_ide_setup);
  
  __uml_help(fake_ide_setup,
  "fake_ide\n"
- "    Create ide0 entries that map onto ubd devices.\n\n"
+ "    Obsolete stub.\n\n"
  );
  
  static int parse_unit(char **ptr)
@@@ -280,36 -243,14 +243,14 @@@ static int ubd_setup_common(char *str, 
        if(index_out) *index_out = -1;
        n = *str;
        if(n == '='){
-               char *end;
-               int major;
                str++;
                if(!strcmp(str, "sync")){
                        global_openflags = of_sync(global_openflags);
                        return err;
                }
  
-               err = -EINVAL;
-               major = simple_strtoul(str, &end, 0);
-               if((*end != '\0') || (end == str)){
-                       *error_out = "Didn't parse major number";
-                       return err;
-               }
-               mutex_lock(&ubd_lock);
-               if (fake_major != UBD_MAJOR) {
-                       *error_out = "Can't assign a fake major twice";
-                       goto out1;
-               }
-               fake_major = major;
-               printk(KERN_INFO "Setting extra ubd major number to %d\n",
-                      major);
-               err = 0;
-       out1:
-               mutex_unlock(&ubd_lock);
-               return err;
+               pr_warn("fake major not supported any more\n");
+               return 0;
        }
  
        n = parse_unit(&str);
@@@ -874,7 -815,6 +815,6 @@@ static void ubd_device_release(struct d
  {
        struct ubd *ubd_dev = dev_get_drvdata(dev);
  
-       blk_cleanup_queue(ubd_dev->queue);
        blk_mq_free_tag_set(&ubd_dev->tag_set);
        *ubd_dev = ((struct ubd) DEFAULT_UBD);
  }
@@@ -914,41 -854,25 +854,25 @@@ static const struct attribute_group *ub
        NULL,
  };
  
- static int ubd_disk_register(int major, u64 size, int unit,
-                            struct gendisk **disk_out)
+ static void ubd_disk_register(int major, u64 size, int unit,
+                             struct gendisk *disk)
  {
-       struct device *parent = NULL;
-       struct gendisk *disk;
-       disk = alloc_disk(1 << UBD_SHIFT);
-       if(disk == NULL)
-               return -ENOMEM;
        disk->major = major;
        disk->first_minor = unit << UBD_SHIFT;
+       disk->minors = 1 << UBD_SHIFT;
        disk->fops = &ubd_blops;
        set_capacity(disk, size / 512);
-       if (major == UBD_MAJOR)
-               sprintf(disk->disk_name, "ubd%c", 'a' + unit);
-       else
-               sprintf(disk->disk_name, "ubd_fake%d", unit);
-       /* sysfs register (not for ide fake devices) */
-       if (major == UBD_MAJOR) {
-               ubd_devs[unit].pdev.id   = unit;
-               ubd_devs[unit].pdev.name = DRIVER_NAME;
-               ubd_devs[unit].pdev.dev.release = ubd_device_release;
-               dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
-               platform_device_register(&ubd_devs[unit].pdev);
-               parent = &ubd_devs[unit].pdev.dev;
-       }
+       sprintf(disk->disk_name, "ubd%c", 'a' + unit);
+       ubd_devs[unit].pdev.id   = unit;
+       ubd_devs[unit].pdev.name = DRIVER_NAME;
+       ubd_devs[unit].pdev.dev.release = ubd_device_release;
+       dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
+       platform_device_register(&ubd_devs[unit].pdev);
  
        disk->private_data = &ubd_devs[unit];
        disk->queue = ubd_devs[unit].queue;
-       device_add_disk(parent, disk, ubd_attr_groups);
-       *disk_out = disk;
-       return 0;
+       device_add_disk(&ubd_devs[unit].pdev.dev, disk, ubd_attr_groups);
  }
  
  #define ROUND_BLOCK(n) ((n + (SECTOR_SIZE - 1)) & (-SECTOR_SIZE))
@@@ -960,6 -884,7 +884,7 @@@ static const struct blk_mq_ops ubd_mq_o
  static int ubd_add(int n, char **error_out)
  {
        struct ubd *ubd_dev = &ubd_devs[n];
+       struct gendisk *disk;
        int err = 0;
  
        if(ubd_dev->file == NULL)
        if (err)
                goto out;
  
-       ubd_dev->queue = blk_mq_init_queue(&ubd_dev->tag_set);
-       if (IS_ERR(ubd_dev->queue)) {
-               err = PTR_ERR(ubd_dev->queue);
+       disk = blk_mq_alloc_disk(&ubd_dev->tag_set, ubd_dev);
+       if (IS_ERR(disk)) {
+               err = PTR_ERR(disk);
                goto out_cleanup_tags;
        }
+       ubd_dev->queue = disk->queue;
  
-       ubd_dev->queue->queuedata = ubd_dev;
        blk_queue_write_cache(ubd_dev->queue, true, false);
        blk_queue_max_segments(ubd_dev->queue, MAX_SG);
        blk_queue_segment_boundary(ubd_dev->queue, PAGE_SIZE - 1);
-       err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
-       if(err){
-               *error_out = "Failed to register device";
-               goto out_cleanup_tags;
-       }
-       if (fake_major != UBD_MAJOR)
-               ubd_disk_register(fake_major, ubd_dev->size, n,
-                                 &fake_gendisk[n]);
-       /*
-        * Perhaps this should also be under the "if (fake_major)" above
-        * using the fake_disk->disk_name
-        */
-       if (fake_ide)
-               make_ide_entries(ubd_gendisk[n]->disk_name);
-       err = 0;
- out:
-       return err;
+       ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, disk);
+       ubd_gendisk[n] = disk;
+       return 0;
  
  out_cleanup_tags:
        blk_mq_free_tag_set(&ubd_dev->tag_set);
-       if (!(IS_ERR(ubd_dev->queue)))
-               blk_cleanup_queue(ubd_dev->queue);
-       goto out;
+ out:
+       return err;
  }
  
  static int ubd_config(char *str, char **error_out)
@@@ -1123,13 -1029,7 +1029,7 @@@ static int ubd_remove(int n, char **err
        ubd_gendisk[n] = NULL;
        if(disk != NULL){
                del_gendisk(disk);
-               put_disk(disk);
-       }
-       if(fake_gendisk[n] != NULL){
-               del_gendisk(fake_gendisk[n]);
-               put_disk(fake_gendisk[n]);
-               fake_gendisk[n] = NULL;
+               blk_cleanup_disk(disk);
        }
  
        err = 0;
@@@ -1188,14 -1088,6 +1088,6 @@@ static int __init ubd_init(void
        if (register_blkdev(UBD_MAJOR, "ubd"))
                return -1;
  
-       if (fake_major != UBD_MAJOR) {
-               char name[sizeof("ubd_nnn\0")];
-               snprintf(name, sizeof(name), "ubd_%d", fake_major);
-               if (register_blkdev(fake_major, "ubd"))
-                       return -1;
-       }
        irq_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE,
                                       sizeof(struct io_thread_req *),
                                       GFP_KERNEL
@@@ -1242,7 -1134,8 +1134,7 @@@ static int __init ubd_driver_init(void)
                 * enough. So use anyway the io thread. */
        }
        stack = alloc_stack(0, 0);
 -      io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
 -                               &thread_fd);
 +      io_pid = start_io_thread(stack + PAGE_SIZE, &thread_fd);
        if(io_pid < 0){
                printk(KERN_ERR
                       "ubd : Failed to start I/O thread (errno = %d) - "
diff --combined block/bsg-lib.c
@@@ -45,7 -45,7 +45,7 @@@ static int bsg_transport_fill_hdr(struc
                return PTR_ERR(job->request);
  
        if (hdr->dout_xfer_len && hdr->din_xfer_len) {
-               job->bidi_rq = blk_get_request(rq->q, REQ_OP_SCSI_IN, 0);
+               job->bidi_rq = blk_get_request(rq->q, REQ_OP_DRV_IN, 0);
                if (IS_ERR(job->bidi_rq)) {
                        ret = PTR_ERR(job->bidi_rq);
                        goto out;
@@@ -84,7 -84,7 +84,7 @@@ static int bsg_transport_complete_rq(st
         */
        hdr->device_status = job->result & 0xff;
        hdr->transport_status = host_byte(job->result);
 -      hdr->driver_status = driver_byte(job->result);
 +      hdr->driver_status = 0;
        hdr->info = 0;
        if (hdr->device_status || hdr->transport_status || hdr->driver_status)
                hdr->info |= SG_INFO_CHECK;
diff --combined block/bsg.c
@@@ -96,9 -96,7 +96,9 @@@ static int bsg_scsi_complete_rq(struct 
         */
        hdr->device_status = sreq->result & 0xff;
        hdr->transport_status = host_byte(sreq->result);
 -      hdr->driver_status = driver_byte(sreq->result);
 +      hdr->driver_status = 0;
 +      if (scsi_status_is_check_condition(sreq->result))
 +              hdr->driver_status = DRIVER_SENSE;
        hdr->info = 0;
        if (hdr->device_status || hdr->transport_status || hdr->driver_status)
                hdr->info |= SG_INFO_CHECK;
@@@ -154,7 -152,7 +154,7 @@@ static int bsg_sg_io(struct request_que
                return ret;
  
        rq = blk_get_request(q, hdr.dout_xfer_len ?
-                       REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
+                       REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
  
diff --combined block/scsi_ioctl.c
@@@ -254,11 -254,9 +254,11 @@@ static int blk_complete_sghdr_rq(struc
         */
        hdr->status = req->result & 0xff;
        hdr->masked_status = status_byte(req->result);
 -      hdr->msg_status = msg_byte(req->result);
 +      hdr->msg_status = COMMAND_COMPLETE;
        hdr->host_status = host_byte(req->result);
 -      hdr->driver_status = driver_byte(req->result);
 +      hdr->driver_status = 0;
 +      if (scsi_status_is_check_condition(hdr->status))
 +              hdr->driver_status = DRIVER_SENSE;
        hdr->info = 0;
        if (hdr->masked_status || hdr->host_status || hdr->driver_status)
                hdr->info |= SG_INFO_CHECK;
@@@ -313,7 -311,7 +313,7 @@@ static int sg_io(struct request_queue *
                at_head = 1;
  
        ret = -ENOMEM;
-       rq = blk_get_request(q, writing ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
+       rq = blk_get_request(q, writing ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
        req = scsi_req(rq);
@@@ -435,7 -433,7 +435,7 @@@ int sg_scsi_ioctl(struct request_queue 
  
        }
  
-       rq = blk_get_request(q, in_len ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
+       rq = blk_get_request(q, in_len ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
        if (IS_ERR(rq)) {
                err = PTR_ERR(rq);
                goto error_free_buffer;
                break;
        }
  
 -      if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO)) {
 -              err = DRIVER_ERROR << 24;
 -              goto error;
 +      if (bytes) {
 +              err = blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO);
 +              if (err)
 +                      goto error;
        }
  
        blk_execute_rq(disk, rq, 0);
@@@ -524,7 -521,7 +524,7 @@@ static int __blk_send_generic(struct re
        struct request *rq;
        int err;
  
-       rq = blk_get_request(q, REQ_OP_SCSI_OUT, 0);
+       rq = blk_get_request(q, REQ_OP_DRV_OUT, 0);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
        rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
diff --combined drivers/nvme/host/fc.c
@@@ -9,7 -9,7 +9,7 @@@
  #include <uapi/scsi/fc/fc_els.h>
  #include <linux/delay.h>
  #include <linux/overflow.h>
 -
 +#include <linux/blk-cgroup.h>
  #include "nvme.h"
  #include "fabrics.h"
  #include <linux/nvme-fc-driver.h>
@@@ -2346,7 -2346,7 +2346,7 @@@ nvme_fc_connect_io_queues(struct nvme_f
                                        (qsize / 5));
                if (ret)
                        break;
-               ret = nvmf_connect_io_queue(&ctrl->ctrl, i, false);
+               ret = nvmf_connect_io_queue(&ctrl->ctrl, i);
                if (ret)
                        break;
  
@@@ -3808,80 -3808,10 +3808,80 @@@ process_local_list
  
        return count;
  }
 +
 +/* Parse the cgroup id from a buf and return the length of cgrpid */
 +static int fc_parse_cgrpid(const char *buf, u64 *id)
 +{
 +      char cgrp_id[16+1];
 +      int cgrpid_len, j;
 +
 +      memset(cgrp_id, 0x0, sizeof(cgrp_id));
 +      for (cgrpid_len = 0, j = 0; cgrpid_len < 17; cgrpid_len++) {
 +              if (buf[cgrpid_len] != ':')
 +                      cgrp_id[cgrpid_len] = buf[cgrpid_len];
 +              else {
 +                      j = 1;
 +                      break;
 +              }
 +      }
 +      if (!j)
 +              return -EINVAL;
 +      if (kstrtou64(cgrp_id, 16, id) < 0)
 +              return -EINVAL;
 +      return cgrpid_len;
 +}
 +
 +/*
 + * fc_update_appid: Parse and update the appid in the blkcg associated with
 + * cgroupid.
 + * @buf: buf contains both cgrpid and appid info
 + * @count: size of the buffer
 + */
 +static int fc_update_appid(const char *buf, size_t count)
 +{
 +      u64 cgrp_id;
 +      int appid_len = 0;
 +      int cgrpid_len = 0;
 +      char app_id[FC_APPID_LEN];
 +      int ret = 0;
 +
 +      if (buf[count-1] == '\n')
 +              count--;
 +
 +      if ((count > (16+1+FC_APPID_LEN)) || (!strchr(buf, ':')))
 +              return -EINVAL;
 +
 +      cgrpid_len = fc_parse_cgrpid(buf, &cgrp_id);
 +      if (cgrpid_len < 0)
 +              return -EINVAL;
 +      appid_len = count - cgrpid_len - 1;
 +      if (appid_len > FC_APPID_LEN)
 +              return -EINVAL;
 +
 +      memset(app_id, 0x0, sizeof(app_id));
 +      memcpy(app_id, &buf[cgrpid_len+1], appid_len);
 +      ret = blkcg_set_fc_appid(app_id, cgrp_id, sizeof(app_id));
 +      if (ret < 0)
 +              return ret;
 +      return count;
 +}
 +
 +static ssize_t fc_appid_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t count)
 +{
 +      int ret  = 0;
 +
 +      ret = fc_update_appid(buf, count);
 +      if (ret < 0)
 +              return -EINVAL;
 +      return count;
 +}
  static DEVICE_ATTR(nvme_discovery, 0200, NULL, nvme_fc_nvme_discovery_store);
 +static DEVICE_ATTR(appid_store, 0200, NULL, fc_appid_store);
  
  static struct attribute *nvme_fc_attrs[] = {
        &dev_attr_nvme_discovery.attr,
 +      &dev_attr_appid_store.attr,
        NULL
  };
  
@@@ -742,35 -742,41 +742,35 @@@ static enum scsi_disposition scsi_eh_co
                return FAILED;
  
        /*
 -       * next, check the message byte.
 -       */
 -      if (msg_byte(scmd->result) != COMMAND_COMPLETE)
 -              return FAILED;
 -
 -      /*
         * now, check the status byte to see if this indicates
         * anything special.
         */
 -      switch (status_byte(scmd->result)) {
 -      case GOOD:
 +      switch (get_status_byte(scmd)) {
 +      case SAM_STAT_GOOD:
                scsi_handle_queue_ramp_up(scmd->device);
                fallthrough;
 -      case COMMAND_TERMINATED:
 +      case SAM_STAT_COMMAND_TERMINATED:
                return SUCCESS;
 -      case CHECK_CONDITION:
 +      case SAM_STAT_CHECK_CONDITION:
                return scsi_check_sense(scmd);
 -      case CONDITION_GOOD:
 -      case INTERMEDIATE_GOOD:
 -      case INTERMEDIATE_C_GOOD:
 +      case SAM_STAT_CONDITION_MET:
 +      case SAM_STAT_INTERMEDIATE:
 +      case SAM_STAT_INTERMEDIATE_CONDITION_MET:
                /*
                 * who knows?  FIXME(eric)
                 */
                return SUCCESS;
 -      case RESERVATION_CONFLICT:
 +      case SAM_STAT_RESERVATION_CONFLICT:
                if (scmd->cmnd[0] == TEST_UNIT_READY)
                        /* it is a success, we probed the device and
                         * found it */
                        return SUCCESS;
                /* otherwise, we failed to send the command */
                return FAILED;
 -      case QUEUE_FULL:
 +      case SAM_STAT_TASK_SET_FULL:
                scsi_handle_queue_full(scmd->device);
                fallthrough;
 -      case BUSY:
 +      case SAM_STAT_BUSY:
                return NEEDS_RETRY;
        default:
                return FAILED;
@@@ -1252,7 -1258,7 +1252,7 @@@ int scsi_eh_get_sense(struct list_head 
                                             current->comm));
                        break;
                }
 -              if (status_byte(scmd->result) != CHECK_CONDITION)
 +              if (!scsi_status_is_check_condition(scmd->result))
                        /*
                         * don't request sense if there's no check condition
                         * status because the error we're processing isn't one
@@@ -1760,14 -1766,15 +1760,14 @@@ int scsi_noretry_cmd(struct scsi_cmnd *
        case DID_PARITY:
                return (scmd->request->cmd_flags & REQ_FAILFAST_DEV);
        case DID_ERROR:
 -              if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
 -                  status_byte(scmd->result) == RESERVATION_CONFLICT)
 +              if (get_status_byte(scmd) == SAM_STAT_RESERVATION_CONFLICT)
                        return 0;
                fallthrough;
        case DID_SOFT_ERROR:
                return (scmd->request->cmd_flags & REQ_FAILFAST_DRIVER);
        }
  
 -      if (status_byte(scmd->result) != CHECK_CONDITION)
 +      if (!scsi_status_is_check_condition(scmd->result))
                return 0;
  
  check_type:
@@@ -1876,7 -1883,8 +1876,7 @@@ enum scsi_disposition scsi_decide_dispo
                 */
                return SUCCESS;
        case DID_ERROR:
 -              if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
 -                  status_byte(scmd->result) == RESERVATION_CONFLICT)
 +              if (get_status_byte(scmd) == SAM_STAT_RESERVATION_CONFLICT)
                        /*
                         * execute reservation conflict processing code
                         * lower down
        }
  
        /*
 -       * next, check the message byte.
 -       */
 -      if (msg_byte(scmd->result) != COMMAND_COMPLETE)
 -              return FAILED;
 -
 -      /*
         * check the status byte to see if this indicates anything special.
         */
 -      switch (status_byte(scmd->result)) {
 -      case QUEUE_FULL:
 +      switch (get_status_byte(scmd)) {
 +      case SAM_STAT_TASK_SET_FULL:
                scsi_handle_queue_full(scmd->device);
                /*
                 * the case of trying to send too many commands to a
                 * tagged queueing device.
                 */
                fallthrough;
 -      case BUSY:
 +      case SAM_STAT_BUSY:
                /*
                 * device can't talk to us at the moment.  Should only
                 * occur (SAM-3) when the task queue is empty, so will cause
                 * device.
                 */
                return ADD_TO_MLQUEUE;
 -      case GOOD:
 +      case SAM_STAT_GOOD:
                if (scmd->cmnd[0] == REPORT_LUNS)
                        scmd->device->sdev_target->expecting_lun_change = 0;
                scsi_handle_queue_ramp_up(scmd->device);
                fallthrough;
 -      case COMMAND_TERMINATED:
 +      case SAM_STAT_COMMAND_TERMINATED:
                return SUCCESS;
 -      case TASK_ABORTED:
 +      case SAM_STAT_TASK_ABORTED:
                goto maybe_retry;
 -      case CHECK_CONDITION:
 +      case SAM_STAT_CHECK_CONDITION:
                rtn = scsi_check_sense(scmd);
                if (rtn == NEEDS_RETRY)
                        goto maybe_retry;
                 * to collect the sense and redo the decide
                 * disposition */
                return rtn;
 -      case CONDITION_GOOD:
 -      case INTERMEDIATE_GOOD:
 -      case INTERMEDIATE_C_GOOD:
 -      case ACA_ACTIVE:
 +      case SAM_STAT_CONDITION_MET:
 +      case SAM_STAT_INTERMEDIATE:
 +      case SAM_STAT_INTERMEDIATE_CONDITION_MET:
 +      case SAM_STAT_ACA_ACTIVE:
                /*
                 * who knows?  FIXME(eric)
                 */
                return SUCCESS;
  
 -      case RESERVATION_CONFLICT:
 +      case SAM_STAT_RESERVATION_CONFLICT:
                sdev_printk(KERN_INFO, scmd->device,
                            "reservation conflict\n");
                set_host_byte(scmd, DID_NEXUS_FAILURE);
@@@ -1997,7 -2011,7 +1997,7 @@@ static void scsi_eh_lock_door(struct sc
        struct request *req;
        struct scsi_request *rq;
  
-       req = blk_get_request(sdev->request_queue, REQ_OP_SCSI_IN, 0);
+       req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN, 0);
        if (IS_ERR(req))
                return;
        rq = scsi_req(req);
@@@ -2123,10 -2137,10 +2123,10 @@@ void scsi_eh_flush_done_q(struct list_h
                        /*
                         * If just we got sense for the device (called
                         * scsi_eh_get_sense), scmd->result is already
 -                       * set, do not set DRIVER_TIMEOUT.
 +                       * set, do not set DID_TIME_OUT.
                         */
                        if (!scmd->result)
 -                              scmd->result |= (DRIVER_TIMEOUT << 24);
 +                              scmd->result |= (DID_TIME_OUT << 16);
                        SCSI_LOG_ERROR_RECOVERY(3,
                                scmd_printk(KERN_INFO, scmd,
                                             "%s: flush finish cmd\n",
diff --combined drivers/scsi/scsi_lib.c
@@@ -211,23 -211,20 +211,23 @@@ int __scsi_execute(struct scsi_device *
  {
        struct request *req;
        struct scsi_request *rq;
 -      int ret = DRIVER_ERROR << 24;
 +      int ret;
  
        req = blk_get_request(sdev->request_queue,
                        data_direction == DMA_TO_DEVICE ?
-                       REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
+                       REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
                        rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
        if (IS_ERR(req))
 -              return ret;
 -      rq = scsi_req(req);
 +              return PTR_ERR(req);
  
 -      if (bufflen &&  blk_rq_map_kern(sdev->request_queue, req,
 -                                      buffer, bufflen, GFP_NOIO))
 -              goto out;
 +      rq = scsi_req(req);
  
 +      if (bufflen) {
 +              ret = blk_rq_map_kern(sdev->request_queue, req,
 +                                    buffer, bufflen, GFP_NOIO);
 +              if (ret)
 +                      goto out;
 +      }
        rq->cmd_len = COMMAND_SIZE(cmd[0]);
        memcpy(rq->cmd, cmd, rq->cmd_len);
        rq->retries = retries;
@@@ -543,7 -540,7 +543,7 @@@ static bool scsi_end_request(struct req
        if (blk_queue_add_random(q))
                add_disk_randomness(req->rq_disk);
  
-       if (!blk_rq_is_scsi(req)) {
+       if (!blk_rq_is_passthrough(req)) {
                WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
                cmd->flags &= ~SCMD_INITIALIZED;
        }
@@@ -591,7 -588,12 +591,7 @@@ static blk_status_t scsi_result_to_blk_
  {
        switch (host_byte(result)) {
        case DID_OK:
 -              /*
 -               * Also check the other bytes than the status byte in result
 -               * to handle the case when a SCSI LLD sets result to
 -               * DRIVER_SENSE << 24 without setting SAM_STAT_CHECK_CONDITION.
 -               */
 -              if (scsi_status_is_good(result) && (result & ~0xff) == 0)
 +              if (scsi_status_is_good(result))
                        return BLK_STS_OK;
                return BLK_STS_IOERR;
        case DID_TRANSPORT_FAILFAST:
@@@ -785,7 -787,7 +785,7 @@@ static void scsi_io_completion_action(s
                         */
                        if (!level && __ratelimit(&_rs)) {
                                scsi_print_result(cmd, NULL, FAILED);
 -                              if (driver_byte(result) == DRIVER_SENSE)
 +                              if (sense_valid)
                                        scsi_print_sense(cmd);
                                scsi_print_command(cmd);
                        }
@@@ -873,7 -875,7 +873,7 @@@ static int scsi_io_completion_nz_result
         * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related
         * intermediate statuses (both obsolete in SAM-4) as good.
         */
 -      if (status_byte(result) && scsi_status_is_good(result)) {
 +      if ((result & 0xff) && scsi_status_is_good(result)) {
                result = 0;
                *blk_statp = BLK_STS_OK;
        }
@@@ -1113,7 -1115,7 +1113,7 @@@ void scsi_init_command(struct scsi_devi
        bool in_flight;
        int budget_token = cmd->budget_token;
  
-       if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) {
+       if (!blk_rq_is_passthrough(rq) && !(flags & SCMD_INITIALIZED)) {
                flags |= SCMD_INITIALIZED;
                scsi_initialize_rq(rq);
        }
@@@ -1554,7 -1556,7 +1554,7 @@@ static blk_status_t scsi_prepare_cmd(st
         * Special handling for passthrough commands, which don't go to the ULP
         * at all:
         */
-       if (blk_rq_is_scsi(req))
+       if (blk_rq_is_passthrough(req))
                return scsi_setup_scsi_cmnd(sdev, req);
  
        if (sdev->handler && sdev->handler->prep_fn) {
@@@ -2091,7 -2093,9 +2091,7 @@@ EXPORT_SYMBOL_GPL(scsi_mode_select)
   *    @sshdr: place to put sense data (or NULL if no sense to be collected).
   *            must be SCSI_SENSE_BUFFERSIZE big.
   *
 - *    Returns zero if unsuccessful, or the header offset (either 4
 - *    or 8 depending on whether a six or ten byte command was
 - *    issued) if successful.
 + *    Returns zero if successful, or a negative error number on failure
   */
  int
  scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
  
        result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
                                  sshdr, timeout, retries, NULL);
 +      if (result < 0)
 +              return result;
  
        /* This code looks awful: what it's doing is making sure an
         * ILLEGAL REQUEST sense return identifies the actual command
         * byte as the problem.  MODE_SENSE commands can return
         * ILLEGAL REQUEST if the code page isn't supported */
  
 -      if (use_10_for_ms && !scsi_status_is_good(result) &&
 -          driver_byte(result) == DRIVER_SENSE) {
 +      if (!scsi_status_is_good(result)) {
                if (scsi_sense_valid(sshdr)) {
                        if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
                            (sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
                                /*
                                 * Invalid command operation code
                                 */
 -                              sdev->use_10_for_ms = 0;
 +                              if (use_10_for_ms) {
 +                                      sdev->use_10_for_ms = 0;
 +                                      goto retry;
 +                              }
 +                      }
 +                      if (scsi_status_is_check_condition(result) &&
 +                          sshdr->sense_key == UNIT_ATTENTION &&
 +                          retry_count) {
 +                              retry_count--;
                                goto retry;
                        }
                }
 +              return -EIO;
 +      }
 +      if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b &&
 +                   (modepage == 6 || modepage == 8))) {
 +              /* Initio breakage? */
 +              header_length = 0;
 +              data->length = 13;
 +              data->medium_type = 0;
 +              data->device_specific = 0;
 +              data->longlba = 0;
 +              data->block_descriptor_length = 0;
 +      } else if (use_10_for_ms) {
 +              data->length = buffer[0]*256 + buffer[1] + 2;
 +              data->medium_type = buffer[2];
 +              data->device_specific = buffer[3];
 +              data->longlba = buffer[4] & 0x01;
 +              data->block_descriptor_length = buffer[6]*256
 +                      + buffer[7];
 +      } else {
 +              data->length = buffer[0] + 1;
 +              data->medium_type = buffer[1];
 +              data->device_specific = buffer[2];
 +              data->block_descriptor_length = buffer[3];
        }
 +      data->header_length = header_length;
  
 -      if (scsi_status_is_good(result)) {
 -              if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b &&
 -                           (modepage == 6 || modepage == 8))) {
 -                      /* Initio breakage? */
 -                      header_length = 0;
 -                      data->length = 13;
 -                      data->medium_type = 0;
 -                      data->device_specific = 0;
 -                      data->longlba = 0;
 -                      data->block_descriptor_length = 0;
 -              } else if (use_10_for_ms) {
 -                      data->length = buffer[0]*256 + buffer[1] + 2;
 -                      data->medium_type = buffer[2];
 -                      data->device_specific = buffer[3];
 -                      data->longlba = buffer[4] & 0x01;
 -                      data->block_descriptor_length = buffer[6]*256
 -                              + buffer[7];
 -              } else {
 -                      data->length = buffer[0] + 1;
 -                      data->medium_type = buffer[1];
 -                      data->device_specific = buffer[2];
 -                      data->block_descriptor_length = buffer[3];
 -              }
 -              data->header_length = header_length;
 -      } else if ((status_byte(result) == CHECK_CONDITION) &&
 -                 scsi_sense_valid(sshdr) &&
 -                 sshdr->sense_key == UNIT_ATTENTION && retry_count) {
 -              retry_count--;
 -              goto retry;
 -      }
 -
 -      return result;
 +      return 0;
  }
  EXPORT_SYMBOL(scsi_mode_sense);
  
@@@ -3216,20 -3218,3 +3216,20 @@@ int scsi_vpd_tpg_id(struct scsi_device 
        return group_id;
  }
  EXPORT_SYMBOL(scsi_vpd_tpg_id);
 +
 +/**
 + * scsi_build_sense - build sense data for a command
 + * @scmd:     scsi command for which the sense should be formatted
 + * @desc:     Sense format (non-zero == descriptor format,
 + *              0 == fixed format)
 + * @key:      Sense key
 + * @asc:      Additional sense code
 + * @ascq:     Additional sense code qualifier
 + *
 + **/
 +void scsi_build_sense(struct scsi_cmnd *scmd, int desc, u8 key, u8 asc, u8 ascq)
 +{
 +      scsi_build_sense_buffer(desc, scmd->sense_buffer, key, asc, ascq);
 +      scmd->result = SAM_STAT_CHECK_CONDITION;
 +}
 +EXPORT_SYMBOL_GPL(scsi_build_sense);
diff --combined drivers/scsi/sg.c
@@@ -498,11 -498,9 +498,11 @@@ sg_read(struct file *filp, char __user 
        old_hdr->host_status = hp->host_status;
        old_hdr->driver_status = hp->driver_status;
        if ((CHECK_CONDITION & hp->masked_status) ||
 -          (DRIVER_SENSE & hp->driver_status))
 +          (srp->sense_b[0] & 0x70) == 0x70) {
 +              old_hdr->driver_status = DRIVER_SENSE;
                memcpy(old_hdr->sense_buffer, srp->sense_b,
                       sizeof (old_hdr->sense_buffer));
 +      }
        switch (hp->host_status) {
        /* This setup of 'result' is for backward compatibility and is best
           ignored by the user who should use target, host + driver status */
@@@ -576,7 -574,7 +576,7 @@@ sg_new_read(Sg_fd * sfp, char __user *b
        hp->sb_len_wr = 0;
        if ((hp->mx_sb_len > 0) && hp->sbp) {
                if ((CHECK_CONDITION & hp->masked_status) ||
 -                  (DRIVER_SENSE & hp->driver_status)) {
 +                  (srp->sense_b[0] & 0x70) == 0x70) {
                        int sb_len = SCSI_SENSE_BUFFERSIZE;
                        sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
                        len = 8 + (int) srp->sense_b[7];        /* Additional sense length field */
                                err = -EFAULT;
                                goto err_out;
                        }
 +                      hp->driver_status = DRIVER_SENSE;
                        hp->sb_len_wr = len;
                }
        }
@@@ -1376,7 -1373,7 +1376,7 @@@ sg_rq_end_io(struct request *rq, blk_st
  
                srp->header.status = 0xff & result;
                srp->header.masked_status = status_byte(result);
 -              srp->header.msg_status = msg_byte(result);
 +              srp->header.msg_status = COMMAND_COMPLETE;
                srp->header.host_status = host_byte(result);
                srp->header.driver_status = driver_byte(result);
                if ((sdp->sgdebug > 0) &&
@@@ -1759,7 -1756,7 +1759,7 @@@ sg_start_req(Sg_request *srp, unsigned 
         * not expect an EWOULDBLOCK from this condition.
         */
        rq = blk_get_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ?
-                       REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
+                       REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
        if (IS_ERR(rq)) {
                kfree(long_cmdp);
                return PTR_ERR(rq);
diff --combined drivers/scsi/st.c
@@@ -390,8 -390,8 +390,8 @@@ static int st_chk_result(struct scsi_ta
        if (!debugging) { /* Abnormal conditions for tape */
                if (!cmdstatp->have_sense)
                        st_printk(KERN_WARNING, STp,
 -                             "Error %x (driver bt 0x%x, host bt 0x%x).\n",
 -                             result, driver_byte(result), host_byte(result));
 +                             "Error %x (driver bt 0, host bt 0x%x).\n",
 +                             result, host_byte(result));
                else if (cmdstatp->have_sense &&
                         scode != NO_SENSE &&
                         scode != RECOVERED_ERROR &&
@@@ -549,9 -549,9 +549,9 @@@ static int st_scsi_execute(struct st_re
  
        req = blk_get_request(SRpnt->stp->device->request_queue,
                        data_direction == DMA_TO_DEVICE ?
-                       REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
+                       REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
        if (IS_ERR(req))
 -              return DRIVER_ERROR << 24;
 +              return PTR_ERR(req);
        rq = scsi_req(req);
        req->rq_flags |= RQF_QUIET;
  
                                      GFP_KERNEL);
                if (err) {
                        blk_put_request(req);
 -                      return DRIVER_ERROR << 24;
 +                      return err;
                }
        }
  
@@@ -982,7 -982,7 +982,7 @@@ pscsi_execute_cmd(struct se_cmd *cmd
  
        req = blk_get_request(pdv->pdv_sd->request_queue,
                        cmd->data_direction == DMA_TO_DEVICE ?
-                       REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
+                       REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
        if (IS_ERR(req)) {
                pr_err("PSCSI: blk_get_request() failed\n");
                ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@@ -1044,7 -1044,7 +1044,7 @@@ static void pscsi_req_done(struct reque
        struct se_cmd *cmd = req->end_io_data;
        struct pscsi_plugin_task *pt = cmd->priv;
        int result = scsi_req(req)->result;
 -      u8 scsi_status = status_byte(result) << 1;
 +      enum sam_status scsi_status = result & 0xff;
  
        if (scsi_status != SAM_STAT_GOOD) {
                pr_debug("PSCSI Status Byte exception at cmd: %p CDB:"
@@@ -300,7 -300,6 +300,7 @@@ enum 
        BIO_CGROUP_ACCT,        /* has been accounted to a cgroup */
        BIO_TRACKED,            /* set if bio goes through the rq_qos path */
        BIO_REMAPPED,
 +      BIO_ZONE_WRITE_LOCKED,  /* Owns a zoned device zone write lock */
        BIO_FLAG_LAST
  };
  
@@@ -351,9 -350,6 +351,6 @@@ enum req_opf 
        /* reset all the zone present on the device */
        REQ_OP_ZONE_RESET_ALL   = 17,
  
-       /* SCSI passthrough using struct scsi_request */
-       REQ_OP_SCSI_IN          = 32,
-       REQ_OP_SCSI_OUT         = 33,
        /* Driver private requests */
        REQ_OP_DRV_IN           = 34,
        REQ_OP_DRV_OUT          = 35,
diff --combined include/linux/blkdev.h
@@@ -240,42 -240,15 +240,15 @@@ struct request 
        void *end_io_data;
  };
  
- static inline bool blk_op_is_scsi(unsigned int op)
- {
-       return op == REQ_OP_SCSI_IN || op == REQ_OP_SCSI_OUT;
- }
- static inline bool blk_op_is_private(unsigned int op)
+ static inline bool blk_op_is_passthrough(unsigned int op)
  {
+       op &= REQ_OP_MASK;
        return op == REQ_OP_DRV_IN || op == REQ_OP_DRV_OUT;
  }
  
- static inline bool blk_rq_is_scsi(struct request *rq)
- {
-       return blk_op_is_scsi(req_op(rq));
- }
- static inline bool blk_rq_is_private(struct request *rq)
- {
-       return blk_op_is_private(req_op(rq));
- }
  static inline bool blk_rq_is_passthrough(struct request *rq)
  {
-       return blk_rq_is_scsi(rq) || blk_rq_is_private(rq);
- }
- static inline bool bio_is_passthrough(struct bio *bio)
- {
-       unsigned op = bio_op(bio);
-       return blk_op_is_scsi(op) || blk_op_is_private(op);
- }
- static inline bool blk_op_is_passthrough(unsigned int op)
- {
-       return (blk_op_is_scsi(op & REQ_OP_MASK) ||
-                       blk_op_is_private(op & REQ_OP_MASK));
+       return blk_op_is_passthrough(req_op(rq));
  }
  
  static inline unsigned short req_get_ioprio(struct request *req)
@@@ -936,10 -909,12 +909,12 @@@ extern int blk_rq_map_kern(struct reque
  extern int blk_rq_map_user_iov(struct request_queue *, struct request *,
                               struct rq_map_data *, const struct iov_iter *,
                               gfp_t);
- extern void blk_execute_rq(struct gendisk *, struct request *, int);
  extern void blk_execute_rq_nowait(struct gendisk *,
                                  struct request *, int, rq_end_io_fn *);
  
+ blk_status_t blk_execute_rq(struct gendisk *bd_disk, struct request *rq,
+                           int at_head);
  /* Helper to convert REQ_OP_XXX to its string format XXX */
  extern const char *blk_op_str(unsigned int op);
  
@@@ -1012,18 -987,6 +987,18 @@@ static inline unsigned int blk_rq_stats
  /* Helper to convert BLK_ZONE_ZONE_XXX to its string format XXX */
  const char *blk_zone_cond_str(enum blk_zone_cond zone_cond);
  
 +static inline unsigned int bio_zone_no(struct bio *bio)
 +{
 +      return blk_queue_zone_no(bdev_get_queue(bio->bi_bdev),
 +                               bio->bi_iter.bi_sector);
 +}
 +
 +static inline unsigned int bio_zone_is_seq(struct bio *bio)
 +{
 +      return blk_queue_zone_is_seq(bdev_get_queue(bio->bi_bdev),
 +                                   bio->bi_iter.bi_sector);
 +}
 +
  static inline unsigned int blk_rq_zone_no(struct request *rq)
  {
        return blk_queue_zone_no(rq->q, blk_rq_pos(rq));