Merge tag 'for-5.4/post-2019-09-24' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Sep 2019 23:31:50 +0000 (16:31 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Sep 2019 23:31:50 +0000 (16:31 -0700)
Pull more block updates from Jens Axboe:
 "Some later additions that weren't quite done for the first pull
  request, and also a few fixes that have arrived since.

  This contains:

   - Kill silly pktcdvd warning on attempting to register a non-scsi
     passthrough device (me)

   - Use symbolic constants for the block t10 protection types, and
     switch to handling it in core rather than in the drivers (Max)

   - libahci platform missing node put fix (Nishka)

   - Small series of fixes for BFQ (Paolo)

   - Fix possible nbd crash (Xiubo)"

* tag 'for-5.4/post-2019-09-24' of git://git.kernel.dk/linux-block:
  block: drop device references in bsg_queue_rq()
  block: t10-pi: fix -Wswitch warning
  pktcdvd: remove warning on attempting to register non-passthrough dev
  ata: libahci_platform: Add of_node_put() before loop exit
  nbd: fix possible page fault for nbd disk
  nbd: rename the runtime flags as NBD_RT_ prefixed
  block, bfq: push up injection only after setting service time
  block, bfq: increase update frequency of inject limit
  block, bfq: reduce upper bound for inject limit to max_rq_in_driver+1
  block, bfq: update inject limit only after injection occurred
  block: centralize PI remapping logic to the block layer
  block: use symbolic constants for t10_pi type

14 files changed:
block/bfq-iosched.c
block/blk-core.c
block/blk-integrity.c
block/blk-mq.c
block/bsg-lib.c
block/t10-pi.c
drivers/ata/libahci_platform.c
drivers/block/nbd.c
drivers/block/pktcdvd.c
drivers/md/dm-integrity.c
drivers/nvme/host/core.c
drivers/scsi/sd.c
include/linux/blkdev.h
include/linux/t10-pi.h

index b33be92..0319d63 100644 (file)
@@ -2016,7 +2016,7 @@ static void bfq_add_request(struct request *rq)
                     (bfqq->last_serv_time_ns > 0 &&
                      bfqd->rqs_injected && bfqd->rq_in_driver > 0)) &&
                    time_is_before_eq_jiffies(bfqq->decrease_time_jif +
-                                             msecs_to_jiffies(100))) {
+                                             msecs_to_jiffies(10))) {
                        bfqd->last_empty_occupied_ns = ktime_get_ns();
                        /*
                         * Start the state machine for measuring the
@@ -2025,7 +2025,21 @@ static void bfq_add_request(struct request *rq)
                         * be set when rq will be dispatched.
                         */
                        bfqd->wait_dispatch = true;
-                       bfqd->rqs_injected = false;
+                       /*
+                        * If there is no I/O in service in the drive,
+                        * then possible injection occurred before the
+                        * arrival of rq will not affect the total
+                        * service time of rq. So the injection limit
+                        * must not be updated as a function of such
+                        * total service time, unless new injection
+                        * occurs before rq is completed. To have the
+                        * injection limit updated only in the latter
+                        * case, reset rqs_injected here (rqs_injected
+                        * will be set in case injection is performed
+                        * on bfqq before rq is completed).
+                        */
+                       if (bfqd->rq_in_driver == 0)
+                               bfqd->rqs_injected = false;
                }
        }
 
@@ -5784,14 +5798,14 @@ static void bfq_update_inject_limit(struct bfq_data *bfqd,
        u64 tot_time_ns = ktime_get_ns() - bfqd->last_empty_occupied_ns;
        unsigned int old_limit = bfqq->inject_limit;
 
-       if (bfqq->last_serv_time_ns > 0) {
+       if (bfqq->last_serv_time_ns > 0 && bfqd->rqs_injected) {
                u64 threshold = (bfqq->last_serv_time_ns * 3)>>1;
 
                if (tot_time_ns >= threshold && old_limit > 0) {
                        bfqq->inject_limit--;
                        bfqq->decrease_time_jif = jiffies;
                } else if (tot_time_ns < threshold &&
-                          old_limit < bfqd->max_rq_in_driver<<1)
+                          old_limit <= bfqd->max_rq_in_driver)
                        bfqq->inject_limit++;
        }
 
@@ -5809,12 +5823,14 @@ static void bfq_update_inject_limit(struct bfq_data *bfqd,
         */
        if ((bfqq->last_serv_time_ns == 0 && bfqd->rq_in_driver == 1) ||
            tot_time_ns < bfqq->last_serv_time_ns) {
+               if (bfqq->last_serv_time_ns == 0) {
+                       /*
+                        * Now we certainly have a base value: make sure we
+                        * start trying injection.
+                        */
+                       bfqq->inject_limit = max_t(unsigned int, 1, old_limit);
+               }
                bfqq->last_serv_time_ns = tot_time_ns;
-               /*
-                * Now we certainly have a base value: make sure we
-                * start trying injection.
-                */
-               bfqq->inject_limit = max_t(unsigned int, 1, old_limit);
        } else if (!bfqd->rqs_injected && bfqd->rq_in_driver == 1)
                /*
                 * No I/O injected and no request still in service in
@@ -5830,6 +5846,7 @@ static void bfq_update_inject_limit(struct bfq_data *bfqd,
 
        /* update complete, not waiting for any request completion any longer */
        bfqd->waited_rq = NULL;
+       bfqd->rqs_injected = false;
 }
 
 /*
index 875e8d1..d5e668e 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/ratelimit.h>
 #include <linux/pm_runtime.h>
 #include <linux/blk-cgroup.h>
+#include <linux/t10-pi.h>
 #include <linux/debugfs.h>
 #include <linux/bpf.h>
 #include <linux/psi.h>
@@ -1436,6 +1437,12 @@ bool blk_update_request(struct request *req, blk_status_t error,
        if (!req->bio)
                return false;
 
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+       if (blk_integrity_rq(req) && req_op(req) == REQ_OP_READ &&
+           error == BLK_STS_OK)
+               req->q->integrity.profile->complete_fn(req, nr_bytes);
+#endif
+
        if (unlikely(error && !blk_rq_is_passthrough(req) &&
                     !(req->rq_flags & RQF_QUIET)))
                print_req_error(req, error, __func__);
index ca39b46..ff1070e 100644 (file)
@@ -368,10 +368,21 @@ static blk_status_t blk_integrity_nop_fn(struct blk_integrity_iter *iter)
        return BLK_STS_OK;
 }
 
+static void blk_integrity_nop_prepare(struct request *rq)
+{
+}
+
+static void blk_integrity_nop_complete(struct request *rq,
+               unsigned int nr_bytes)
+{
+}
+
 static const struct blk_integrity_profile nop_profile = {
        .name = "nop",
        .generate_fn = blk_integrity_nop_fn,
        .verify_fn = blk_integrity_nop_fn,
+       .prepare_fn = blk_integrity_nop_prepare,
+       .complete_fn = blk_integrity_nop_complete,
 };
 
 /**
index 20a49be..29275f5 100644 (file)
@@ -30,6 +30,7 @@
 #include <trace/events/block.h>
 
 #include <linux/blk-mq.h>
+#include <linux/t10-pi.h>
 #include "blk.h"
 #include "blk-mq.h"
 #include "blk-mq-debugfs.h"
@@ -700,6 +701,11 @@ void blk_mq_start_request(struct request *rq)
                 */
                rq->nr_phys_segments++;
        }
+
+#ifdef CONFIG_BLK_DEV_INTEGRITY
+       if (blk_integrity_rq(rq) && req_op(rq) == REQ_OP_WRITE)
+               q->integrity.profile->prepare_fn(rq);
+#endif
 }
 EXPORT_SYMBOL(blk_mq_start_request);
 
index 785dd58..347dda1 100644 (file)
@@ -266,6 +266,7 @@ static blk_status_t bsg_queue_rq(struct blk_mq_hw_ctx *hctx,
        struct request *req = bd->rq;
        struct bsg_set *bset =
                container_of(q->tag_set, struct bsg_set, tag_set);
+       int sts = BLK_STS_IOERR;
        int ret;
 
        blk_mq_start_request(req);
@@ -274,14 +275,15 @@ static blk_status_t bsg_queue_rq(struct blk_mq_hw_ctx *hctx,
                return BLK_STS_IOERR;
 
        if (!bsg_prepare_job(dev, req))
-               return BLK_STS_IOERR;
+               goto out;
 
        ret = bset->job_fn(blk_mq_rq_to_pdu(req));
-       if (ret)
-               return BLK_STS_IOERR;
+       if (!ret)
+               sts = BLK_STS_OK;
 
+out:
        put_device(dev);
-       return BLK_STS_OK;
+       return sts;
 }
 
 /* called right after the request is allocated for the request_queue */
index 0c00946..9803c7e 100644 (file)
@@ -27,7 +27,7 @@ static __be16 t10_pi_ip_fn(void *data, unsigned int len)
  * tag.
  */
 static blk_status_t t10_pi_generate(struct blk_integrity_iter *iter,
-               csum_fn *fn, unsigned int type)
+               csum_fn *fn, enum t10_dif_type type)
 {
        unsigned int i;
 
@@ -37,7 +37,7 @@ static blk_status_t t10_pi_generate(struct blk_integrity_iter *iter,
                pi->guard_tag = fn(iter->data_buf, iter->interval);
                pi->app_tag = 0;
 
-               if (type == 1)
+               if (type == T10_PI_TYPE1_PROTECTION)
                        pi->ref_tag = cpu_to_be32(lower_32_bits(iter->seed));
                else
                        pi->ref_tag = 0;
@@ -51,17 +51,18 @@ static blk_status_t t10_pi_generate(struct blk_integrity_iter *iter,
 }
 
 static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter,
-               csum_fn *fn, unsigned int type)
+               csum_fn *fn, enum t10_dif_type type)
 {
        unsigned int i;
 
+       BUG_ON(type == T10_PI_TYPE0_PROTECTION);
+
        for (i = 0 ; i < iter->data_size ; i += iter->interval) {
                struct t10_pi_tuple *pi = iter->prot_buf;
                __be16 csum;
 
-               switch (type) {
-               case 1:
-               case 2:
+               if (type == T10_PI_TYPE1_PROTECTION ||
+                   type == T10_PI_TYPE2_PROTECTION) {
                        if (pi->app_tag == T10_PI_APP_ESCAPE)
                                goto next;
 
@@ -73,12 +74,10 @@ static blk_status_t t10_pi_verify(struct blk_integrity_iter *iter,
                                       iter->seed, be32_to_cpu(pi->ref_tag));
                                return BLK_STS_PROTECTION;
                        }
-                       break;
-               case 3:
+               } else if (type == T10_PI_TYPE3_PROTECTION) {
                        if (pi->app_tag == T10_PI_APP_ESCAPE &&
                            pi->ref_tag == T10_PI_REF_ESCAPE)
                                goto next;
-                       break;
                }
 
                csum = fn(iter->data_buf, iter->interval);
@@ -102,94 +101,40 @@ next:
 
 static blk_status_t t10_pi_type1_generate_crc(struct blk_integrity_iter *iter)
 {
-       return t10_pi_generate(iter, t10_pi_crc_fn, 1);
+       return t10_pi_generate(iter, t10_pi_crc_fn, T10_PI_TYPE1_PROTECTION);
 }
 
 static blk_status_t t10_pi_type1_generate_ip(struct blk_integrity_iter *iter)
 {
-       return t10_pi_generate(iter, t10_pi_ip_fn, 1);
+       return t10_pi_generate(iter, t10_pi_ip_fn, T10_PI_TYPE1_PROTECTION);
 }
 
 static blk_status_t t10_pi_type1_verify_crc(struct blk_integrity_iter *iter)
 {
-       return t10_pi_verify(iter, t10_pi_crc_fn, 1);
+       return t10_pi_verify(iter, t10_pi_crc_fn, T10_PI_TYPE1_PROTECTION);
 }
 
 static blk_status_t t10_pi_type1_verify_ip(struct blk_integrity_iter *iter)
 {
-       return t10_pi_verify(iter, t10_pi_ip_fn, 1);
-}
-
-static blk_status_t t10_pi_type3_generate_crc(struct blk_integrity_iter *iter)
-{
-       return t10_pi_generate(iter, t10_pi_crc_fn, 3);
-}
-
-static blk_status_t t10_pi_type3_generate_ip(struct blk_integrity_iter *iter)
-{
-       return t10_pi_generate(iter, t10_pi_ip_fn, 3);
-}
-
-static blk_status_t t10_pi_type3_verify_crc(struct blk_integrity_iter *iter)
-{
-       return t10_pi_verify(iter, t10_pi_crc_fn, 3);
+       return t10_pi_verify(iter, t10_pi_ip_fn, T10_PI_TYPE1_PROTECTION);
 }
 
-static blk_status_t t10_pi_type3_verify_ip(struct blk_integrity_iter *iter)
-{
-       return t10_pi_verify(iter, t10_pi_ip_fn, 3);
-}
-
-const struct blk_integrity_profile t10_pi_type1_crc = {
-       .name                   = "T10-DIF-TYPE1-CRC",
-       .generate_fn            = t10_pi_type1_generate_crc,
-       .verify_fn              = t10_pi_type1_verify_crc,
-};
-EXPORT_SYMBOL(t10_pi_type1_crc);
-
-const struct blk_integrity_profile t10_pi_type1_ip = {
-       .name                   = "T10-DIF-TYPE1-IP",
-       .generate_fn            = t10_pi_type1_generate_ip,
-       .verify_fn              = t10_pi_type1_verify_ip,
-};
-EXPORT_SYMBOL(t10_pi_type1_ip);
-
-const struct blk_integrity_profile t10_pi_type3_crc = {
-       .name                   = "T10-DIF-TYPE3-CRC",
-       .generate_fn            = t10_pi_type3_generate_crc,
-       .verify_fn              = t10_pi_type3_verify_crc,
-};
-EXPORT_SYMBOL(t10_pi_type3_crc);
-
-const struct blk_integrity_profile t10_pi_type3_ip = {
-       .name                   = "T10-DIF-TYPE3-IP",
-       .generate_fn            = t10_pi_type3_generate_ip,
-       .verify_fn              = t10_pi_type3_verify_ip,
-};
-EXPORT_SYMBOL(t10_pi_type3_ip);
-
 /**
- * t10_pi_prepare - prepare PI prior submitting request to device
+ * t10_pi_type1_prepare - prepare PI prior submitting request to device
  * @rq:              request with PI that should be prepared
- * @protection_type: PI type (Type 1/Type 2/Type 3)
  *
  * For Type 1/Type 2, the virtual start sector is the one that was
  * originally submitted by the block layer for the ref_tag usage. Due to
  * partitioning, MD/DM cloning, etc. the actual physical start sector is
  * likely to be different. Remap protection information to match the
  * physical LBA.
- *
- * Type 3 does not have a reference tag so no remapping is required.
  */
-void t10_pi_prepare(struct request *rq, u8 protection_type)
+static void t10_pi_type1_prepare(struct request *rq)
 {
        const int tuple_sz = rq->q->integrity.tuple_size;
        u32 ref_tag = t10_pi_ref_tag(rq);
        struct bio *bio;
 
-       if (protection_type == T10_PI_TYPE3_PROTECTION)
-               return;
-
        __rq_for_each_bio(bio, rq) {
                struct bio_integrity_payload *bip = bio_integrity(bio);
                u32 virt = bip_get_seed(bip) & 0xffffffff;
@@ -222,13 +167,11 @@ void t10_pi_prepare(struct request *rq, u8 protection_type)
                bip->bip_flags |= BIP_MAPPED_INTEGRITY;
        }
 }
-EXPORT_SYMBOL(t10_pi_prepare);
 
 /**
- * t10_pi_complete - prepare PI prior returning request to the block layer
+ * t10_pi_type1_complete - prepare PI prior returning request to the blk layer
  * @rq:              request with PI that should be prepared
- * @protection_type: PI type (Type 1/Type 2/Type 3)
- * @intervals:       total elements to prepare
+ * @nr_bytes:        total bytes to prepare
  *
  * For Type 1/Type 2, the virtual start sector is the one that was
  * originally submitted by the block layer for the ref_tag usage. Due to
@@ -236,19 +179,14 @@ EXPORT_SYMBOL(t10_pi_prepare);
  * likely to be different. Since the physical start sector was submitted
  * to the device, we should remap it back to virtual values expected by the
  * block layer.
- *
- * Type 3 does not have a reference tag so no remapping is required.
  */
-void t10_pi_complete(struct request *rq, u8 protection_type,
-                    unsigned int intervals)
+static void t10_pi_type1_complete(struct request *rq, unsigned int nr_bytes)
 {
+       unsigned intervals = nr_bytes >> rq->q->integrity.interval_exp;
        const int tuple_sz = rq->q->integrity.tuple_size;
        u32 ref_tag = t10_pi_ref_tag(rq);
        struct bio *bio;
 
-       if (protection_type == T10_PI_TYPE3_PROTECTION)
-               return;
-
        __rq_for_each_bio(bio, rq) {
                struct bio_integrity_payload *bip = bio_integrity(bio);
                u32 virt = bip_get_seed(bip) & 0xffffffff;
@@ -276,4 +214,73 @@ void t10_pi_complete(struct request *rq, u8 protection_type,
                }
        }
 }
-EXPORT_SYMBOL(t10_pi_complete);
+
+static blk_status_t t10_pi_type3_generate_crc(struct blk_integrity_iter *iter)
+{
+       return t10_pi_generate(iter, t10_pi_crc_fn, T10_PI_TYPE3_PROTECTION);
+}
+
+static blk_status_t t10_pi_type3_generate_ip(struct blk_integrity_iter *iter)
+{
+       return t10_pi_generate(iter, t10_pi_ip_fn, T10_PI_TYPE3_PROTECTION);
+}
+
+static blk_status_t t10_pi_type3_verify_crc(struct blk_integrity_iter *iter)
+{
+       return t10_pi_verify(iter, t10_pi_crc_fn, T10_PI_TYPE3_PROTECTION);
+}
+
+static blk_status_t t10_pi_type3_verify_ip(struct blk_integrity_iter *iter)
+{
+       return t10_pi_verify(iter, t10_pi_ip_fn, T10_PI_TYPE3_PROTECTION);
+}
+
+/**
+ * Type 3 does not have a reference tag so no remapping is required.
+ */
+static void t10_pi_type3_prepare(struct request *rq)
+{
+}
+
+/**
+ * Type 3 does not have a reference tag so no remapping is required.
+ */
+static void t10_pi_type3_complete(struct request *rq, unsigned int nr_bytes)
+{
+}
+
+const struct blk_integrity_profile t10_pi_type1_crc = {
+       .name                   = "T10-DIF-TYPE1-CRC",
+       .generate_fn            = t10_pi_type1_generate_crc,
+       .verify_fn              = t10_pi_type1_verify_crc,
+       .prepare_fn             = t10_pi_type1_prepare,
+       .complete_fn            = t10_pi_type1_complete,
+};
+EXPORT_SYMBOL(t10_pi_type1_crc);
+
+const struct blk_integrity_profile t10_pi_type1_ip = {
+       .name                   = "T10-DIF-TYPE1-IP",
+       .generate_fn            = t10_pi_type1_generate_ip,
+       .verify_fn              = t10_pi_type1_verify_ip,
+       .prepare_fn             = t10_pi_type1_prepare,
+       .complete_fn            = t10_pi_type1_complete,
+};
+EXPORT_SYMBOL(t10_pi_type1_ip);
+
+const struct blk_integrity_profile t10_pi_type3_crc = {
+       .name                   = "T10-DIF-TYPE3-CRC",
+       .generate_fn            = t10_pi_type3_generate_crc,
+       .verify_fn              = t10_pi_type3_verify_crc,
+       .prepare_fn             = t10_pi_type3_prepare,
+       .complete_fn            = t10_pi_type3_complete,
+};
+EXPORT_SYMBOL(t10_pi_type3_crc);
+
+const struct blk_integrity_profile t10_pi_type3_ip = {
+       .name                   = "T10-DIF-TYPE3-IP",
+       .generate_fn            = t10_pi_type3_generate_ip,
+       .verify_fn              = t10_pi_type3_verify_ip,
+       .prepare_fn             = t10_pi_type3_prepare,
+       .complete_fn            = t10_pi_type3_complete,
+};
+EXPORT_SYMBOL(t10_pi_type3_ip);
index 9e9583a..e742780 100644 (file)
@@ -497,6 +497,7 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
 
                        if (of_property_read_u32(child, "reg", &port)) {
                                rc = -EINVAL;
+                               of_node_put(child);
                                goto err_out;
                        }
 
@@ -514,14 +515,18 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
                        if (port_dev) {
                                rc = ahci_platform_get_regulator(hpriv, port,
                                                                &port_dev->dev);
-                               if (rc == -EPROBE_DEFER)
+                               if (rc == -EPROBE_DEFER) {
+                                       of_node_put(child);
                                        goto err_out;
+                               }
                        }
 #endif
 
                        rc = ahci_platform_get_phy(hpriv, port, dev, child);
-                       if (rc)
+                       if (rc) {
+                               of_node_put(child);
                                goto err_out;
+                       }
 
                        enabled_ports++;
                }
index a8e3815..ac07e8c 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/ioctl.h>
 #include <linux/mutex.h>
 #include <linux/compiler.h>
+#include <linux/completion.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -71,14 +72,17 @@ struct link_dead_args {
        int index;
 };
 
-#define NBD_TIMEDOUT                   0
+#define NBD_RT_TIMEDOUT                        0
+#define NBD_RT_DISCONNECT_REQUESTED    1
+#define NBD_RT_DISCONNECTED            2
+#define NBD_RT_HAS_PID_FILE            3
+#define NBD_RT_HAS_CONFIG_REF          4
+#define NBD_RT_BOUND                   5
+#define NBD_RT_DESTROY_ON_DISCONNECT   6
+#define NBD_RT_DISCONNECT_ON_CLOSE     7
+
+#define NBD_DESTROY_ON_DISCONNECT      0
 #define NBD_DISCONNECT_REQUESTED       1
-#define NBD_DISCONNECTED               2
-#define NBD_HAS_PID_FILE               3
-#define NBD_HAS_CONFIG_REF             4
-#define NBD_BOUND                      5
-#define NBD_DESTROY_ON_DISCONNECT      6
-#define NBD_DISCONNECT_ON_CLOSE        7
 
 struct nbd_config {
        u32 flags;
@@ -113,6 +117,9 @@ struct nbd_device {
        struct list_head list;
        struct task_struct *task_recv;
        struct task_struct *task_setup;
+
+       struct completion *destroy_complete;
+       unsigned long flags;
 };
 
 #define NBD_CMD_REQUEUED       1
@@ -223,6 +230,16 @@ static void nbd_dev_remove(struct nbd_device *nbd)
                disk->private_data = NULL;
                put_disk(disk);
        }
+
+       /*
+        * Place this in the last just before the nbd is freed to
+        * make sure that the disk and the related kobject are also
+        * totally removed to avoid duplicate creation of the same
+        * one.
+        */
+       if (test_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags) && nbd->destroy_complete)
+               complete(nbd->destroy_complete);
+
        kfree(nbd);
 }
 
@@ -238,8 +255,8 @@ static void nbd_put(struct nbd_device *nbd)
 
 static int nbd_disconnected(struct nbd_config *config)
 {
-       return test_bit(NBD_DISCONNECTED, &config->runtime_flags) ||
-               test_bit(NBD_DISCONNECT_REQUESTED, &config->runtime_flags);
+       return test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags) ||
+               test_bit(NBD_RT_DISCONNECT_REQUESTED, &config->runtime_flags);
 }
 
 static void nbd_mark_nsock_dead(struct nbd_device *nbd, struct nbd_sock *nsock,
@@ -257,9 +274,9 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, struct nbd_sock *nsock,
        if (!nsock->dead) {
                kernel_sock_shutdown(nsock->sock, SHUT_RDWR);
                if (atomic_dec_return(&nbd->config->live_connections) == 0) {
-                       if (test_and_clear_bit(NBD_DISCONNECT_REQUESTED,
+                       if (test_and_clear_bit(NBD_RT_DISCONNECT_REQUESTED,
                                               &nbd->config->runtime_flags)) {
-                               set_bit(NBD_DISCONNECTED,
+                               set_bit(NBD_RT_DISCONNECTED,
                                        &nbd->config->runtime_flags);
                                dev_info(nbd_to_dev(nbd),
                                        "Disconnected due to user request.\n");
@@ -333,7 +350,7 @@ static void sock_shutdown(struct nbd_device *nbd)
 
        if (config->num_connections == 0)
                return;
-       if (test_and_set_bit(NBD_DISCONNECTED, &config->runtime_flags))
+       if (test_and_set_bit(NBD_RT_DISCONNECTED, &config->runtime_flags))
                return;
 
        for (i = 0; i < config->num_connections; i++) {
@@ -427,7 +444,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
        }
 
        dev_err_ratelimited(nbd_to_dev(nbd), "Connection timed out\n");
-       set_bit(NBD_TIMEDOUT, &config->runtime_flags);
+       set_bit(NBD_RT_TIMEDOUT, &config->runtime_flags);
        cmd->status = BLK_STS_IOERR;
        mutex_unlock(&cmd->lock);
        sock_shutdown(nbd);
@@ -795,7 +812,7 @@ static int find_fallback(struct nbd_device *nbd, int index)
        struct nbd_sock *nsock = config->socks[index];
        int fallback = nsock->fallback_index;
 
-       if (test_bit(NBD_DISCONNECTED, &config->runtime_flags))
+       if (test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags))
                return new_index;
 
        if (config->num_connections <= 1) {
@@ -836,7 +853,7 @@ static int wait_for_reconnect(struct nbd_device *nbd)
        struct nbd_config *config = nbd->config;
        if (!config->dead_conn_timeout)
                return 0;
-       if (test_bit(NBD_DISCONNECTED, &config->runtime_flags))
+       if (test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags))
                return 0;
        return wait_event_timeout(config->conn_wait,
                                  atomic_read(&config->live_connections) > 0,
@@ -969,12 +986,12 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
                return err;
 
        if (!netlink && !nbd->task_setup &&
-           !test_bit(NBD_BOUND, &config->runtime_flags))
+           !test_bit(NBD_RT_BOUND, &config->runtime_flags))
                nbd->task_setup = current;
 
        if (!netlink &&
            (nbd->task_setup != current ||
-            test_bit(NBD_BOUND, &config->runtime_flags))) {
+            test_bit(NBD_RT_BOUND, &config->runtime_flags))) {
                dev_err(disk_to_dev(nbd->disk),
                        "Device being setup by another task");
                sockfd_put(sock);
@@ -1053,7 +1070,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
                mutex_unlock(&nsock->tx_lock);
                sockfd_put(old);
 
-               clear_bit(NBD_DISCONNECTED, &config->runtime_flags);
+               clear_bit(NBD_RT_DISCONNECTED, &config->runtime_flags);
 
                /* We take the tx_mutex in an error path in the recv_work, so we
                 * need to queue_work outside of the tx_mutex.
@@ -1124,7 +1141,8 @@ static int nbd_disconnect(struct nbd_device *nbd)
        struct nbd_config *config = nbd->config;
 
        dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
-       set_bit(NBD_DISCONNECT_REQUESTED, &config->runtime_flags);
+       set_bit(NBD_RT_DISCONNECT_REQUESTED, &config->runtime_flags);
+       set_bit(NBD_DISCONNECT_REQUESTED, &nbd->flags);
        send_disconnects(nbd);
        return 0;
 }
@@ -1143,7 +1161,7 @@ static void nbd_config_put(struct nbd_device *nbd)
                struct nbd_config *config = nbd->config;
                nbd_dev_dbg_close(nbd);
                nbd_size_clear(nbd);
-               if (test_and_clear_bit(NBD_HAS_PID_FILE,
+               if (test_and_clear_bit(NBD_RT_HAS_PID_FILE,
                                       &config->runtime_flags))
                        device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
                nbd->task_recv = NULL;
@@ -1209,7 +1227,7 @@ static int nbd_start_device(struct nbd_device *nbd)
                dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n");
                return error;
        }
-       set_bit(NBD_HAS_PID_FILE, &config->runtime_flags);
+       set_bit(NBD_RT_HAS_PID_FILE, &config->runtime_flags);
 
        nbd_dev_dbg_init(nbd);
        for (i = 0; i < num_connections; i++) {
@@ -1256,9 +1274,9 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *b
        mutex_lock(&nbd->config_lock);
        nbd_bdev_reset(bdev);
        /* user requested, ignore socket errors */
-       if (test_bit(NBD_DISCONNECT_REQUESTED, &config->runtime_flags))
+       if (test_bit(NBD_RT_DISCONNECT_REQUESTED, &config->runtime_flags))
                ret = 0;
-       if (test_bit(NBD_TIMEDOUT, &config->runtime_flags))
+       if (test_bit(NBD_RT_TIMEDOUT, &config->runtime_flags))
                ret = -ETIMEDOUT;
        return ret;
 }
@@ -1269,7 +1287,7 @@ static void nbd_clear_sock_ioctl(struct nbd_device *nbd,
        sock_shutdown(nbd);
        __invalidate_device(bdev, true);
        nbd_bdev_reset(bdev);
-       if (test_and_clear_bit(NBD_HAS_CONFIG_REF,
+       if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF,
                               &nbd->config->runtime_flags))
                nbd_config_put(nbd);
 }
@@ -1364,7 +1382,7 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
        /* Don't allow ioctl operations on a nbd device that was created with
         * netlink, unless it's DISCONNECT or CLEAR_SOCK, which are fine.
         */
-       if (!test_bit(NBD_BOUND, &config->runtime_flags) ||
+       if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
            (cmd == NBD_DISCONNECT || cmd == NBD_CLEAR_SOCK))
                error = __nbd_ioctl(bdev, nbd, cmd, arg);
        else
@@ -1435,7 +1453,7 @@ static void nbd_release(struct gendisk *disk, fmode_t mode)
        struct nbd_device *nbd = disk->private_data;
        struct block_device *bdev = bdget_disk(disk, 0);
 
-       if (test_bit(NBD_DISCONNECT_ON_CLOSE, &nbd->config->runtime_flags) &&
+       if (test_bit(NBD_RT_DISCONNECT_ON_CLOSE, &nbd->config->runtime_flags) &&
                        bdev->bd_openers == 0)
                nbd_disconnect_and_put(nbd);
 
@@ -1636,6 +1654,7 @@ static int nbd_dev_add(int index)
        nbd->tag_set.flags = BLK_MQ_F_SHOULD_MERGE |
                BLK_MQ_F_BLOCKING;
        nbd->tag_set.driver_data = nbd;
+       nbd->destroy_complete = NULL;
 
        err = blk_mq_alloc_tag_set(&nbd->tag_set);
        if (err)
@@ -1750,6 +1769,7 @@ static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd)
 
 static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
 {
+       DECLARE_COMPLETION_ONSTACK(destroy_complete);
        struct nbd_device *nbd = NULL;
        struct nbd_config *config;
        int index = -1;
@@ -1801,6 +1821,17 @@ again:
                mutex_unlock(&nbd_index_mutex);
                return -EINVAL;
        }
+
+       if (test_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags) &&
+           test_bit(NBD_DISCONNECT_REQUESTED, &nbd->flags)) {
+               nbd->destroy_complete = &destroy_complete;
+               mutex_unlock(&nbd_index_mutex);
+
+               /* Wait untill the the nbd stuff is totally destroyed */
+               wait_for_completion(&destroy_complete);
+               goto again;
+       }
+
        if (!refcount_inc_not_zero(&nbd->refs)) {
                mutex_unlock(&nbd_index_mutex);
                if (index == -1)
@@ -1833,7 +1864,7 @@ again:
                return -ENOMEM;
        }
        refcount_set(&nbd->config_refs, 1);
-       set_bit(NBD_BOUND, &config->runtime_flags);
+       set_bit(NBD_RT_BOUND, &config->runtime_flags);
 
        ret = nbd_genl_size_set(info, nbd);
        if (ret)
@@ -1853,12 +1884,15 @@ again:
        if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) {
                u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]);
                if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) {
-                       set_bit(NBD_DESTROY_ON_DISCONNECT,
+                       set_bit(NBD_RT_DESTROY_ON_DISCONNECT,
                                &config->runtime_flags);
+                       set_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags);
                        put_dev = true;
+               } else {
+                       clear_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags);
                }
                if (flags & NBD_CFLAG_DISCONNECT_ON_CLOSE) {
-                       set_bit(NBD_DISCONNECT_ON_CLOSE,
+                       set_bit(NBD_RT_DISCONNECT_ON_CLOSE,
                                &config->runtime_flags);
                }
        }
@@ -1897,7 +1931,7 @@ again:
 out:
        mutex_unlock(&nbd->config_lock);
        if (!ret) {
-               set_bit(NBD_HAS_CONFIG_REF, &config->runtime_flags);
+               set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags);
                refcount_inc(&nbd->config_refs);
                nbd_connect_reply(info, nbd->index);
        }
@@ -1919,7 +1953,7 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd)
         * queue.
         */
        flush_workqueue(nbd->recv_workq);
-       if (test_and_clear_bit(NBD_HAS_CONFIG_REF,
+       if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF,
                               &nbd->config->runtime_flags))
                nbd_config_put(nbd);
 }
@@ -2003,7 +2037,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
 
        mutex_lock(&nbd->config_lock);
        config = nbd->config;
-       if (!test_bit(NBD_BOUND, &config->runtime_flags) ||
+       if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) ||
            !nbd->task_recv) {
                dev_err(nbd_to_dev(nbd),
                        "not configured, cannot reconfigure\n");
@@ -2026,20 +2060,22 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
        if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) {
                u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]);
                if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) {
-                       if (!test_and_set_bit(NBD_DESTROY_ON_DISCONNECT,
+                       if (!test_and_set_bit(NBD_RT_DESTROY_ON_DISCONNECT,
                                              &config->runtime_flags))
                                put_dev = true;
+                       set_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags);
                } else {
-                       if (test_and_clear_bit(NBD_DESTROY_ON_DISCONNECT,
+                       if (test_and_clear_bit(NBD_RT_DESTROY_ON_DISCONNECT,
                                               &config->runtime_flags))
                                refcount_inc(&nbd->refs);
+                       clear_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags);
                }
 
                if (flags & NBD_CFLAG_DISCONNECT_ON_CLOSE) {
-                       set_bit(NBD_DISCONNECT_ON_CLOSE,
+                       set_bit(NBD_RT_DISCONNECT_ON_CLOSE,
                                        &config->runtime_flags);
                } else {
-                       clear_bit(NBD_DISCONNECT_ON_CLOSE,
+                       clear_bit(NBD_RT_DISCONNECT_ON_CLOSE,
                                        &config->runtime_flags);
                }
        }
index 0240601..7645700 100644 (file)
@@ -2594,7 +2594,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        if (ret)
                return ret;
        if (!blk_queue_scsi_passthrough(bdev_get_queue(bdev))) {
-               WARN_ONCE(true, "Attempt to register a non-SCSI queue\n");
                blkdev_put(bdev, FMODE_READ | FMODE_NDELAY);
                return -EINVAL;
        }
index 9118ab8..dab4446 100644 (file)
@@ -345,6 +345,14 @@ static void __DEBUG_bytes(__u8 *bytes, size_t len, const char *msg, ...)
 #define DEBUG_bytes(bytes, len, msg, ...)      do { } while (0)
 #endif
 
+static void dm_integrity_prepare(struct request *rq)
+{
+}
+
+static void dm_integrity_complete(struct request *rq, unsigned int nr_bytes)
+{
+}
+
 /*
  * DM Integrity profile, protection is performed layer above (dm-crypt)
  */
@@ -352,6 +360,8 @@ static const struct blk_integrity_profile dm_integrity_profile = {
        .name                   = "DM-DIF-EXT-TAG",
        .generate_fn            = NULL,
        .verify_fn              = NULL,
+       .prepare_fn             = dm_integrity_prepare,
+       .complete_fn            = dm_integrity_complete,
 };
 
 static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map);
index 1ede176..108f60b 100644 (file)
@@ -666,8 +666,6 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
                        if (WARN_ON_ONCE(!nvme_ns_has_pi(ns)))
                                return BLK_STS_NOTSUPP;
                        control |= NVME_RW_PRINFO_PRACT;
-               } else if (req_op(req) == REQ_OP_WRITE) {
-                       t10_pi_prepare(req, ns->pi_type);
                }
 
                switch (ns->pi_type) {
@@ -690,13 +688,6 @@ static inline blk_status_t nvme_setup_rw(struct nvme_ns *ns,
 
 void nvme_cleanup_cmd(struct request *req)
 {
-       if (blk_integrity_rq(req) && req_op(req) == REQ_OP_READ &&
-           nvme_req(req)->status == 0) {
-               struct nvme_ns *ns = req->rq_disk->private_data;
-
-               t10_pi_complete(req, ns->pi_type,
-                               blk_rq_bytes(req) >> ns->lba_shift);
-       }
        if (req->rq_flags & RQF_SPECIAL_PAYLOAD) {
                struct nvme_ns *ns = req->rq_disk->private_data;
                struct page *page = req->special_vec.bv_page;
index 7623196..50928bc 100644 (file)
@@ -1211,9 +1211,6 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd)
        dix = scsi_prot_sg_count(cmd);
        dif = scsi_host_dif_capable(cmd->device->host, sdkp->protection_type);
 
-       if (write && dix)
-               t10_pi_prepare(cmd->request, sdkp->protection_type);
-
        if (dif || dix)
                protect = sd_setup_protect_cmnd(cmd, dix, dif);
        else
@@ -2055,11 +2052,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                                           "sd_done: completed %d of %d bytes\n",
                                           good_bytes, scsi_bufflen(SCpnt)));
 
-       if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt) &&
-           good_bytes)
-               t10_pi_complete(SCpnt->request, sdkp->protection_type,
-                               good_bytes / scsi_prot_interval(SCpnt));
-
        return good_bytes;
 }
 
index d9db32f..f3ea78b 100644 (file)
@@ -1524,10 +1524,14 @@ struct blk_integrity_iter {
 };
 
 typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
+typedef void (integrity_prepare_fn) (struct request *);
+typedef void (integrity_complete_fn) (struct request *, unsigned int);
 
 struct blk_integrity_profile {
        integrity_processing_fn         *generate_fn;
        integrity_processing_fn         *verify_fn;
+       integrity_prepare_fn            *prepare_fn;
+       integrity_complete_fn           *complete_fn;
        const char                      *name;
 };
 
index 3e2a80c..96305a6 100644 (file)
@@ -53,18 +53,4 @@ extern const struct blk_integrity_profile t10_pi_type1_ip;
 extern const struct blk_integrity_profile t10_pi_type3_crc;
 extern const struct blk_integrity_profile t10_pi_type3_ip;
 
-#ifdef CONFIG_BLK_DEV_INTEGRITY
-extern void t10_pi_prepare(struct request *rq, u8 protection_type);
-extern void t10_pi_complete(struct request *rq, u8 protection_type,
-                           unsigned int intervals);
-#else
-static inline void t10_pi_complete(struct request *rq, u8 protection_type,
-                                  unsigned int intervals)
-{
-}
-static inline void t10_pi_prepare(struct request *rq, u8 protection_type)
-{
-}
-#endif
-
 #endif