diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-16 15:36:39 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-16 15:36:39 -0400 |
| commit | 11efae3506d882a8782bc89493a32e467defd6b9 (patch) | |
| tree | 4671e72e14bb5f03e484ade6526ccfd1a40f75b8 | |
| parent | 465c209db83e2cdaeb4a52f4e107a9fc636704db (diff) | |
| parent | f6d85f04e29859dd3ea65395c05925da352dae89 (diff) | |
Merge tag 'for-5.1/block-post-20190315' of git://git.kernel.dk/linux-block
Pull more block layer changes from Jens Axboe:
"This is a collection of both stragglers, and fixes that came in after
I finalized the initial pull. This contains:
- An MD pull request from Song, with a few minor fixes
- Set of NVMe patches via Christoph
- Pull request from Konrad, with a few fixes for xen/blkback
- pblk fix IO calculation fix (Javier)
- Segment calculation fix for pass-through (Ming)
- Fallthrough annotation for blkcg (Mathieu)"
* tag 'for-5.1/block-post-20190315' of git://git.kernel.dk/linux-block: (25 commits)
blkcg: annotate implicit fall through
nvme-tcp: support C2HData with SUCCESS flag
nvmet: ignore EOPNOTSUPP for discard
nvme: add proper write zeroes setup for the multipath device
nvme: add proper discard setup for the multipath device
nvme: remove nvme_ns_config_oncs
nvme: disable Write Zeroes for qemu controllers
nvmet-fc: bring Disconnect into compliance with FC-NVME spec
nvmet-fc: fix issues with targetport assoc_list list walking
nvme-fc: reject reconnect if io queue count is reduced to zero
nvme-fc: fix numa_node when dev is null
nvme-fc: use nr_phys_segments to determine existence of sgl
nvme-loop: init nvmet_ctrl fatal_err_work when allocate
nvme: update comment to make the code easier to read
nvme: put ns_head ref if namespace fails allocation
nvme-trace: fix cdw10 buffer overrun
nvme: don't warn on block content change effects
nvme: add get-feature to admin cmds tracer
md: Fix failed allocation of md_register_thread
It's wrong to add len to sector_nr in raid10 reshape twice
...
| -rw-r--r-- | Documentation/admin-guide/md.rst | 3 | ||||
| -rw-r--r-- | block/blk-merge.c | 15 | ||||
| -rw-r--r-- | drivers/block/xen-blkback/xenbus.c | 99 | ||||
| -rw-r--r-- | drivers/lightnvm/pblk-rl.c | 7 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 3 | ||||
| -rw-r--r-- | drivers/md/raid5-log.h | 1 | ||||
| -rw-r--r-- | drivers/md/raid5-ppl.c | 63 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 3 | ||||
| -rw-r--r-- | drivers/nvme/host/core.c | 28 | ||||
| -rw-r--r-- | drivers/nvme/host/fc.c | 36 | ||||
| -rw-r--r-- | drivers/nvme/host/nvme.h | 5 | ||||
| -rw-r--r-- | drivers/nvme/host/pci.c | 3 | ||||
| -rw-r--r-- | drivers/nvme/host/tcp.c | 32 | ||||
| -rw-r--r-- | drivers/nvme/host/trace.c | 14 | ||||
| -rw-r--r-- | drivers/nvme/host/trace.h | 2 | ||||
| -rw-r--r-- | drivers/nvme/target/core.c | 20 | ||||
| -rw-r--r-- | drivers/nvme/target/fc.c | 42 | ||||
| -rw-r--r-- | drivers/nvme/target/io-cmd-bdev.c | 8 | ||||
| -rw-r--r-- | drivers/nvme/target/io-cmd-file.c | 2 | ||||
| -rw-r--r-- | kernel/trace/blktrace.c | 1 |
20 files changed, 259 insertions, 128 deletions
diff --git a/Documentation/admin-guide/md.rst b/Documentation/admin-guide/md.rst index 84de718f24a4..3c51084ffd37 100644 --- a/Documentation/admin-guide/md.rst +++ b/Documentation/admin-guide/md.rst | |||
| @@ -756,3 +756,6 @@ These currently include: | |||
| 756 | The cache mode for raid5. raid5 could include an extra disk for | 756 | The cache mode for raid5. raid5 could include an extra disk for |
| 757 | caching. The mode can be "write-throuth" and "write-back". The | 757 | caching. The mode can be "write-throuth" and "write-back". The |
| 758 | default is "write-through". | 758 | default is "write-through". |
| 759 | |||
| 760 | ppl_write_hint | ||
| 761 | NVMe stream ID to be set for each PPL write request. | ||
diff --git a/block/blk-merge.c b/block/blk-merge.c index 22467f475ab4..1c9d4f0f96ea 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
| @@ -180,7 +180,7 @@ static unsigned get_max_segment_size(struct request_queue *q, | |||
| 180 | */ | 180 | */ |
| 181 | static bool bvec_split_segs(struct request_queue *q, struct bio_vec *bv, | 181 | static bool bvec_split_segs(struct request_queue *q, struct bio_vec *bv, |
| 182 | unsigned *nsegs, unsigned *last_seg_size, | 182 | unsigned *nsegs, unsigned *last_seg_size, |
| 183 | unsigned *front_seg_size, unsigned *sectors) | 183 | unsigned *front_seg_size, unsigned *sectors, unsigned max_segs) |
| 184 | { | 184 | { |
| 185 | unsigned len = bv->bv_len; | 185 | unsigned len = bv->bv_len; |
| 186 | unsigned total_len = 0; | 186 | unsigned total_len = 0; |
| @@ -190,7 +190,7 @@ static bool bvec_split_segs(struct request_queue *q, struct bio_vec *bv, | |||
| 190 | * Multi-page bvec may be too big to hold in one segment, so the | 190 | * Multi-page bvec may be too big to hold in one segment, so the |
| 191 | * current bvec has to be splitted as multiple segments. | 191 | * current bvec has to be splitted as multiple segments. |
| 192 | */ | 192 | */ |
| 193 | while (len && new_nsegs + *nsegs < queue_max_segments(q)) { | 193 | while (len && new_nsegs + *nsegs < max_segs) { |
| 194 | seg_size = get_max_segment_size(q, bv->bv_offset + total_len); | 194 | seg_size = get_max_segment_size(q, bv->bv_offset + total_len); |
| 195 | seg_size = min(seg_size, len); | 195 | seg_size = min(seg_size, len); |
| 196 | 196 | ||
| @@ -240,6 +240,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, | |||
| 240 | bool do_split = true; | 240 | bool do_split = true; |
| 241 | struct bio *new = NULL; | 241 | struct bio *new = NULL; |
| 242 | const unsigned max_sectors = get_max_io_size(q, bio); | 242 | const unsigned max_sectors = get_max_io_size(q, bio); |
| 243 | const unsigned max_segs = queue_max_segments(q); | ||
| 243 | 244 | ||
| 244 | bio_for_each_bvec(bv, bio, iter) { | 245 | bio_for_each_bvec(bv, bio, iter) { |
| 245 | /* | 246 | /* |
| @@ -254,14 +255,14 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, | |||
| 254 | * Consider this a new segment if we're splitting in | 255 | * Consider this a new segment if we're splitting in |
| 255 | * the middle of this vector. | 256 | * the middle of this vector. |
| 256 | */ | 257 | */ |
| 257 | if (nsegs < queue_max_segments(q) && | 258 | if (nsegs < max_segs && |
| 258 | sectors < max_sectors) { | 259 | sectors < max_sectors) { |
| 259 | /* split in the middle of bvec */ | 260 | /* split in the middle of bvec */ |
| 260 | bv.bv_len = (max_sectors - sectors) << 9; | 261 | bv.bv_len = (max_sectors - sectors) << 9; |
| 261 | bvec_split_segs(q, &bv, &nsegs, | 262 | bvec_split_segs(q, &bv, &nsegs, |
| 262 | &seg_size, | 263 | &seg_size, |
| 263 | &front_seg_size, | 264 | &front_seg_size, |
| 264 | §ors); | 265 | §ors, max_segs); |
| 265 | } | 266 | } |
| 266 | goto split; | 267 | goto split; |
| 267 | } | 268 | } |
| @@ -283,7 +284,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, | |||
| 283 | continue; | 284 | continue; |
| 284 | } | 285 | } |
| 285 | new_segment: | 286 | new_segment: |
| 286 | if (nsegs == queue_max_segments(q)) | 287 | if (nsegs == max_segs) |
| 287 | goto split; | 288 | goto split; |
| 288 | 289 | ||
| 289 | bvprv = bv; | 290 | bvprv = bv; |
| @@ -296,7 +297,7 @@ new_segment: | |||
| 296 | if (nsegs == 1 && seg_size > front_seg_size) | 297 | if (nsegs == 1 && seg_size > front_seg_size) |
| 297 | front_seg_size = seg_size; | 298 | front_seg_size = seg_size; |
| 298 | } else if (bvec_split_segs(q, &bv, &nsegs, &seg_size, | 299 | } else if (bvec_split_segs(q, &bv, &nsegs, &seg_size, |
| 299 | &front_seg_size, §ors)) { | 300 | &front_seg_size, §ors, max_segs)) { |
| 300 | goto split; | 301 | goto split; |
| 301 | } | 302 | } |
| 302 | } | 303 | } |
| @@ -415,7 +416,7 @@ new_segment: | |||
| 415 | bvprv = bv; | 416 | bvprv = bv; |
| 416 | prev = 1; | 417 | prev = 1; |
| 417 | bvec_split_segs(q, &bv, &nr_phys_segs, &seg_size, | 418 | bvec_split_segs(q, &bv, &nr_phys_segs, &seg_size, |
| 418 | &front_seg_size, NULL); | 419 | &front_seg_size, NULL, UINT_MAX); |
| 419 | } | 420 | } |
| 420 | bbio = bio; | 421 | bbio = bio; |
| 421 | } | 422 | } |
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index a4bc74e72c39..24896ffb04ed 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
| @@ -926,7 +926,7 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) | |||
| 926 | int err, i, j; | 926 | int err, i, j; |
| 927 | struct xen_blkif *blkif = ring->blkif; | 927 | struct xen_blkif *blkif = ring->blkif; |
| 928 | struct xenbus_device *dev = blkif->be->dev; | 928 | struct xenbus_device *dev = blkif->be->dev; |
| 929 | unsigned int ring_page_order, nr_grefs, evtchn; | 929 | unsigned int nr_grefs, evtchn; |
| 930 | 930 | ||
| 931 | err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u", | 931 | err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u", |
| 932 | &evtchn); | 932 | &evtchn); |
| @@ -936,43 +936,42 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) | |||
| 936 | return err; | 936 | return err; |
| 937 | } | 937 | } |
| 938 | 938 | ||
| 939 | err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", | 939 | nr_grefs = blkif->nr_ring_pages; |
| 940 | &ring_page_order); | 940 | |
| 941 | if (err != 1) { | 941 | if (unlikely(!nr_grefs)) { |
| 942 | err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", &ring_ref[0]); | 942 | WARN_ON(true); |
| 943 | return -EINVAL; | ||
| 944 | } | ||
| 945 | |||
| 946 | for (i = 0; i < nr_grefs; i++) { | ||
| 947 | char ring_ref_name[RINGREF_NAME_LEN]; | ||
| 948 | |||
| 949 | snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); | ||
| 950 | err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, | ||
| 951 | "%u", &ring_ref[i]); | ||
| 952 | |||
| 943 | if (err != 1) { | 953 | if (err != 1) { |
| 954 | if (nr_grefs == 1) | ||
| 955 | break; | ||
| 956 | |||
| 944 | err = -EINVAL; | 957 | err = -EINVAL; |
| 945 | xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir); | 958 | xenbus_dev_fatal(dev, err, "reading %s/%s", |
| 959 | dir, ring_ref_name); | ||
| 946 | return err; | 960 | return err; |
| 947 | } | 961 | } |
| 948 | nr_grefs = 1; | 962 | } |
| 949 | } else { | ||
| 950 | unsigned int i; | ||
| 951 | 963 | ||
| 952 | if (ring_page_order > xen_blkif_max_ring_order) { | 964 | if (err != 1) { |
| 965 | WARN_ON(nr_grefs != 1); | ||
| 966 | |||
| 967 | err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", | ||
| 968 | &ring_ref[0]); | ||
| 969 | if (err != 1) { | ||
| 953 | err = -EINVAL; | 970 | err = -EINVAL; |
| 954 | xenbus_dev_fatal(dev, err, "%s/request %d ring page order exceed max:%d", | 971 | xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir); |
| 955 | dir, ring_page_order, | ||
| 956 | xen_blkif_max_ring_order); | ||
| 957 | return err; | 972 | return err; |
| 958 | } | 973 | } |
| 959 | |||
| 960 | nr_grefs = 1 << ring_page_order; | ||
| 961 | for (i = 0; i < nr_grefs; i++) { | ||
| 962 | char ring_ref_name[RINGREF_NAME_LEN]; | ||
| 963 | |||
| 964 | snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); | ||
| 965 | err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, | ||
| 966 | "%u", &ring_ref[i]); | ||
| 967 | if (err != 1) { | ||
| 968 | err = -EINVAL; | ||
| 969 | xenbus_dev_fatal(dev, err, "reading %s/%s", | ||
| 970 | dir, ring_ref_name); | ||
| 971 | return err; | ||
| 972 | } | ||
| 973 | } | ||
| 974 | } | 974 | } |
| 975 | blkif->nr_ring_pages = nr_grefs; | ||
| 976 | 975 | ||
| 977 | for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) { | 976 | for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) { |
| 978 | req = kzalloc(sizeof(*req), GFP_KERNEL); | 977 | req = kzalloc(sizeof(*req), GFP_KERNEL); |
| @@ -1023,6 +1022,7 @@ fail: | |||
| 1023 | static int connect_ring(struct backend_info *be) | 1022 | static int connect_ring(struct backend_info *be) |
| 1024 | { | 1023 | { |
| 1025 | struct xenbus_device *dev = be->dev; | 1024 | struct xenbus_device *dev = be->dev; |
| 1025 | struct xen_blkif *blkif = be->blkif; | ||
| 1026 | unsigned int pers_grants; | 1026 | unsigned int pers_grants; |
| 1027 | char protocol[64] = ""; | 1027 | char protocol[64] = ""; |
| 1028 | int err, i; | 1028 | int err, i; |
| @@ -1030,28 +1030,29 @@ static int connect_ring(struct backend_info *be) | |||
| 1030 | size_t xspathsize; | 1030 | size_t xspathsize; |
| 1031 | const size_t xenstore_path_ext_size = 11; /* sufficient for "/queue-NNN" */ | 1031 | const size_t xenstore_path_ext_size = 11; /* sufficient for "/queue-NNN" */ |
| 1032 | unsigned int requested_num_queues = 0; | 1032 | unsigned int requested_num_queues = 0; |
| 1033 | unsigned int ring_page_order; | ||
| 1033 | 1034 | ||
| 1034 | pr_debug("%s %s\n", __func__, dev->otherend); | 1035 | pr_debug("%s %s\n", __func__, dev->otherend); |
| 1035 | 1036 | ||
| 1036 | be->blkif->blk_protocol = BLKIF_PROTOCOL_DEFAULT; | 1037 | blkif->blk_protocol = BLKIF_PROTOCOL_DEFAULT; |
| 1037 | err = xenbus_scanf(XBT_NIL, dev->otherend, "protocol", | 1038 | err = xenbus_scanf(XBT_NIL, dev->otherend, "protocol", |
| 1038 | "%63s", protocol); | 1039 | "%63s", protocol); |
| 1039 | if (err <= 0) | 1040 | if (err <= 0) |
| 1040 | strcpy(protocol, "unspecified, assuming default"); | 1041 | strcpy(protocol, "unspecified, assuming default"); |
| 1041 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) | 1042 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) |
| 1042 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; | 1043 | blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; |
| 1043 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) | 1044 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) |
| 1044 | be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32; | 1045 | blkif->blk_protocol = BLKIF_PROTOCOL_X86_32; |
| 1045 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64)) | 1046 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64)) |
| 1046 | be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64; | 1047 | blkif->blk_protocol = BLKIF_PROTOCOL_X86_64; |
| 1047 | else { | 1048 | else { |
| 1048 | xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol); | 1049 | xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol); |
| 1049 | return -ENOSYS; | 1050 | return -ENOSYS; |
| 1050 | } | 1051 | } |
| 1051 | pers_grants = xenbus_read_unsigned(dev->otherend, "feature-persistent", | 1052 | pers_grants = xenbus_read_unsigned(dev->otherend, "feature-persistent", |
| 1052 | 0); | 1053 | 0); |
| 1053 | be->blkif->vbd.feature_gnt_persistent = pers_grants; | 1054 | blkif->vbd.feature_gnt_persistent = pers_grants; |
| 1054 | be->blkif->vbd.overflow_max_grants = 0; | 1055 | blkif->vbd.overflow_max_grants = 0; |
| 1055 | 1056 | ||
| 1056 | /* | 1057 | /* |
| 1057 | * Read the number of hardware queues from frontend. | 1058 | * Read the number of hardware queues from frontend. |
| @@ -1067,16 +1068,30 @@ static int connect_ring(struct backend_info *be) | |||
| 1067 | requested_num_queues, xenblk_max_queues); | 1068 | requested_num_queues, xenblk_max_queues); |
| 1068 | return -ENOSYS; | 1069 | return -ENOSYS; |
| 1069 | } | 1070 | } |
| 1070 | be->blkif->nr_rings = requested_num_queues; | 1071 | blkif->nr_rings = requested_num_queues; |
| 1071 | if (xen_blkif_alloc_rings(be->blkif)) | 1072 | if (xen_blkif_alloc_rings(blkif)) |
| 1072 | return -ENOMEM; | 1073 | return -ENOMEM; |
| 1073 | 1074 | ||
| 1074 | pr_info("%s: using %d queues, protocol %d (%s) %s\n", dev->nodename, | 1075 | pr_info("%s: using %d queues, protocol %d (%s) %s\n", dev->nodename, |
| 1075 | be->blkif->nr_rings, be->blkif->blk_protocol, protocol, | 1076 | blkif->nr_rings, blkif->blk_protocol, protocol, |
| 1076 | pers_grants ? "persistent grants" : ""); | 1077 | pers_grants ? "persistent grants" : ""); |
| 1077 | 1078 | ||
| 1078 | if (be->blkif->nr_rings == 1) | 1079 | ring_page_order = xenbus_read_unsigned(dev->otherend, |
| 1079 | return read_per_ring_refs(&be->blkif->rings[0], dev->otherend); | 1080 | "ring-page-order", 0); |
| 1081 | |||
| 1082 | if (ring_page_order > xen_blkif_max_ring_order) { | ||
| 1083 | err = -EINVAL; | ||
| 1084 | xenbus_dev_fatal(dev, err, | ||
| 1085 | "requested ring page order %d exceed max:%d", | ||
| 1086 | ring_page_order, | ||
| 1087 | xen_blkif_max_ring_order); | ||
| 1088 | return err; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | blkif->nr_ring_pages = 1 << ring_page_order; | ||
| 1092 | |||
| 1093 | if (blkif->nr_rings == 1) | ||
| 1094 | return read_per_ring_refs(&blkif->rings[0], dev->otherend); | ||
| 1080 | else { | 1095 | else { |
| 1081 | xspathsize = strlen(dev->otherend) + xenstore_path_ext_size; | 1096 | xspathsize = strlen(dev->otherend) + xenstore_path_ext_size; |
| 1082 | xspath = kmalloc(xspathsize, GFP_KERNEL); | 1097 | xspath = kmalloc(xspathsize, GFP_KERNEL); |
| @@ -1085,10 +1100,10 @@ static int connect_ring(struct backend_info *be) | |||
| 1085 | return -ENOMEM; | 1100 | return -ENOMEM; |
| 1086 | } | 1101 | } |
| 1087 | 1102 | ||
| 1088 | for (i = 0; i < be->blkif->nr_rings; i++) { | 1103 | for (i = 0; i < blkif->nr_rings; i++) { |
| 1089 | memset(xspath, 0, xspathsize); | 1104 | memset(xspath, 0, xspathsize); |
| 1090 | snprintf(xspath, xspathsize, "%s/queue-%u", dev->otherend, i); | 1105 | snprintf(xspath, xspathsize, "%s/queue-%u", dev->otherend, i); |
| 1091 | err = read_per_ring_refs(&be->blkif->rings[i], xspath); | 1106 | err = read_per_ring_refs(&blkif->rings[i], xspath); |
| 1092 | if (err) { | 1107 | if (err) { |
| 1093 | kfree(xspath); | 1108 | kfree(xspath); |
| 1094 | return err; | 1109 | return err; |
diff --git a/drivers/lightnvm/pblk-rl.c b/drivers/lightnvm/pblk-rl.c index b014957dde0b..a5f8bc2defbc 100644 --- a/drivers/lightnvm/pblk-rl.c +++ b/drivers/lightnvm/pblk-rl.c | |||
| @@ -233,10 +233,15 @@ void pblk_rl_init(struct pblk_rl *rl, int budget, int threshold) | |||
| 233 | /* To start with, all buffer is available to user I/O writers */ | 233 | /* To start with, all buffer is available to user I/O writers */ |
| 234 | rl->rb_budget = budget; | 234 | rl->rb_budget = budget; |
| 235 | rl->rb_user_max = budget; | 235 | rl->rb_user_max = budget; |
| 236 | rl->rb_max_io = threshold ? (budget - threshold) : (budget - 1); | ||
| 237 | rl->rb_gc_max = 0; | 236 | rl->rb_gc_max = 0; |
| 238 | rl->rb_state = PBLK_RL_HIGH; | 237 | rl->rb_state = PBLK_RL_HIGH; |
| 239 | 238 | ||
| 239 | /* Maximize I/O size and ansure that back threshold is respected */ | ||
| 240 | if (threshold) | ||
| 241 | rl->rb_max_io = budget - pblk->min_write_pgs_data - threshold; | ||
| 242 | else | ||
| 243 | rl->rb_max_io = budget - pblk->min_write_pgs_data - 1; | ||
| 244 | |||
| 240 | atomic_set(&rl->rb_user_cnt, 0); | 245 | atomic_set(&rl->rb_user_cnt, 0); |
| 241 | atomic_set(&rl->rb_gc_cnt, 0); | 246 | atomic_set(&rl->rb_gc_cnt, 0); |
| 242 | atomic_set(&rl->rb_space, -1); | 247 | atomic_set(&rl->rb_space, -1); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index abb5d382f64d..3b6880dd648d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -3939,6 +3939,8 @@ static int raid10_run(struct mddev *mddev) | |||
| 3939 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 3939 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
| 3940 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, | 3940 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, |
| 3941 | "reshape"); | 3941 | "reshape"); |
| 3942 | if (!mddev->sync_thread) | ||
| 3943 | goto out_free_conf; | ||
| 3942 | } | 3944 | } |
| 3943 | 3945 | ||
| 3944 | return 0; | 3946 | return 0; |
| @@ -4670,7 +4672,6 @@ read_more: | |||
| 4670 | atomic_inc(&r10_bio->remaining); | 4672 | atomic_inc(&r10_bio->remaining); |
| 4671 | read_bio->bi_next = NULL; | 4673 | read_bio->bi_next = NULL; |
| 4672 | generic_make_request(read_bio); | 4674 | generic_make_request(read_bio); |
| 4673 | sector_nr += nr_sectors; | ||
| 4674 | sectors_done += nr_sectors; | 4675 | sectors_done += nr_sectors; |
| 4675 | if (sector_nr <= last) | 4676 | if (sector_nr <= last) |
| 4676 | goto read_more; | 4677 | goto read_more; |
diff --git a/drivers/md/raid5-log.h b/drivers/md/raid5-log.h index bfb811407061..43c714a8798c 100644 --- a/drivers/md/raid5-log.h +++ b/drivers/md/raid5-log.h | |||
| @@ -45,6 +45,7 @@ extern void ppl_stripe_write_finished(struct stripe_head *sh); | |||
| 45 | extern int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add); | 45 | extern int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add); |
| 46 | extern void ppl_quiesce(struct r5conf *conf, int quiesce); | 46 | extern void ppl_quiesce(struct r5conf *conf, int quiesce); |
| 47 | extern int ppl_handle_flush_request(struct r5l_log *log, struct bio *bio); | 47 | extern int ppl_handle_flush_request(struct r5l_log *log, struct bio *bio); |
| 48 | extern struct md_sysfs_entry ppl_write_hint; | ||
| 48 | 49 | ||
| 49 | static inline bool raid5_has_log(struct r5conf *conf) | 50 | static inline bool raid5_has_log(struct r5conf *conf) |
| 50 | { | 51 | { |
diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c index 0b096ddc9c1e..17e9e7d51097 100644 --- a/drivers/md/raid5-ppl.c +++ b/drivers/md/raid5-ppl.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/raid/md_p.h> | 20 | #include <linux/raid/md_p.h> |
| 21 | #include "md.h" | 21 | #include "md.h" |
| 22 | #include "raid5.h" | 22 | #include "raid5.h" |
| 23 | #include "raid5-log.h" | ||
| 23 | 24 | ||
| 24 | /* | 25 | /* |
| 25 | * PPL consists of a 4KB header (struct ppl_header) and at least 128KB for | 26 | * PPL consists of a 4KB header (struct ppl_header) and at least 128KB for |
| @@ -115,6 +116,8 @@ struct ppl_conf { | |||
| 115 | /* stripes to retry if failed to allocate io_unit */ | 116 | /* stripes to retry if failed to allocate io_unit */ |
| 116 | struct list_head no_mem_stripes; | 117 | struct list_head no_mem_stripes; |
| 117 | spinlock_t no_mem_stripes_lock; | 118 | spinlock_t no_mem_stripes_lock; |
| 119 | |||
| 120 | unsigned short write_hint; | ||
| 118 | }; | 121 | }; |
| 119 | 122 | ||
| 120 | struct ppl_log { | 123 | struct ppl_log { |
| @@ -474,6 +477,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io) | |||
| 474 | bio_set_dev(bio, log->rdev->bdev); | 477 | bio_set_dev(bio, log->rdev->bdev); |
| 475 | bio->bi_iter.bi_sector = log->next_io_sector; | 478 | bio->bi_iter.bi_sector = log->next_io_sector; |
| 476 | bio_add_page(bio, io->header_page, PAGE_SIZE, 0); | 479 | bio_add_page(bio, io->header_page, PAGE_SIZE, 0); |
| 480 | bio->bi_write_hint = ppl_conf->write_hint; | ||
| 477 | 481 | ||
| 478 | pr_debug("%s: log->current_io_sector: %llu\n", __func__, | 482 | pr_debug("%s: log->current_io_sector: %llu\n", __func__, |
| 479 | (unsigned long long)log->next_io_sector); | 483 | (unsigned long long)log->next_io_sector); |
| @@ -503,6 +507,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io) | |||
| 503 | bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, | 507 | bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, |
| 504 | &ppl_conf->bs); | 508 | &ppl_conf->bs); |
| 505 | bio->bi_opf = prev->bi_opf; | 509 | bio->bi_opf = prev->bi_opf; |
| 510 | bio->bi_write_hint = prev->bi_write_hint; | ||
| 506 | bio_copy_dev(bio, prev); | 511 | bio_copy_dev(bio, prev); |
| 507 | bio->bi_iter.bi_sector = bio_end_sector(prev); | 512 | bio->bi_iter.bi_sector = bio_end_sector(prev); |
| 508 | bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0); | 513 | bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0); |
| @@ -1407,6 +1412,7 @@ int ppl_init_log(struct r5conf *conf) | |||
| 1407 | atomic64_set(&ppl_conf->seq, 0); | 1412 | atomic64_set(&ppl_conf->seq, 0); |
| 1408 | INIT_LIST_HEAD(&ppl_conf->no_mem_stripes); | 1413 | INIT_LIST_HEAD(&ppl_conf->no_mem_stripes); |
| 1409 | spin_lock_init(&ppl_conf->no_mem_stripes_lock); | 1414 | spin_lock_init(&ppl_conf->no_mem_stripes_lock); |
| 1415 | ppl_conf->write_hint = RWF_WRITE_LIFE_NOT_SET; | ||
| 1410 | 1416 | ||
| 1411 | if (!mddev->external) { | 1417 | if (!mddev->external) { |
| 1412 | ppl_conf->signature = ~crc32c_le(~0, mddev->uuid, sizeof(mddev->uuid)); | 1418 | ppl_conf->signature = ~crc32c_le(~0, mddev->uuid, sizeof(mddev->uuid)); |
| @@ -1501,3 +1507,60 @@ int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add) | |||
| 1501 | 1507 | ||
| 1502 | return ret; | 1508 | return ret; |
| 1503 | } | 1509 | } |
| 1510 | |||
| 1511 | static ssize_t | ||
| 1512 | ppl_write_hint_show(struct mddev *mddev, char *buf) | ||
| 1513 | { | ||
| 1514 | size_t ret = 0; | ||
| 1515 | struct r5conf *conf; | ||
| 1516 | struct ppl_conf *ppl_conf = NULL; | ||
| 1517 | |||
| 1518 | spin_lock(&mddev->lock); | ||
| 1519 | conf = mddev->private; | ||
| 1520 | if (conf && raid5_has_ppl(conf)) | ||
| 1521 | ppl_conf = conf->log_private; | ||
| 1522 | ret = sprintf(buf, "%d\n", ppl_conf ? ppl_conf->write_hint : 0); | ||
| 1523 | spin_unlock(&mddev->lock); | ||
| 1524 | |||
| 1525 | return ret; | ||
| 1526 | } | ||
| 1527 | |||
| 1528 | static ssize_t | ||
| 1529 | ppl_write_hint_store(struct mddev *mddev, const char *page, size_t len) | ||
| 1530 | { | ||
| 1531 | struct r5conf *conf; | ||
| 1532 | struct ppl_conf *ppl_conf; | ||
| 1533 | int err = 0; | ||
| 1534 | unsigned short new; | ||
| 1535 | |||
| 1536 | if (len >= PAGE_SIZE) | ||
| 1537 | return -EINVAL; | ||
| 1538 | if (kstrtou16(page, 10, &new)) | ||
| 1539 | return -EINVAL; | ||
| 1540 | |||
| 1541 | err = mddev_lock(mddev); | ||
| 1542 | if (err) | ||
| 1543 | return err; | ||
| 1544 | |||
| 1545 | conf = mddev->private; | ||
| 1546 | if (!conf) { | ||
| 1547 | err = -ENODEV; | ||
| 1548 | } else if (raid5_has_ppl(conf)) { | ||
| 1549 | ppl_conf = conf->log_private; | ||
| 1550 | if (!ppl_conf) | ||
| 1551 | err = -EINVAL; | ||
| 1552 | else | ||
| 1553 | ppl_conf->write_hint = new; | ||
| 1554 | } else { | ||
| 1555 | err = -EINVAL; | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | mddev_unlock(mddev); | ||
| 1559 | |||
| 1560 | return err ?: len; | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | struct md_sysfs_entry | ||
| 1564 | ppl_write_hint = __ATTR(ppl_write_hint, S_IRUGO | S_IWUSR, | ||
| 1565 | ppl_write_hint_show, | ||
| 1566 | ppl_write_hint_store); | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 77ffd09be486..c033bfcb209e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -6650,6 +6650,7 @@ static struct attribute *raid5_attrs[] = { | |||
| 6650 | &raid5_skip_copy.attr, | 6650 | &raid5_skip_copy.attr, |
| 6651 | &raid5_rmw_level.attr, | 6651 | &raid5_rmw_level.attr, |
| 6652 | &r5c_journal_mode.attr, | 6652 | &r5c_journal_mode.attr, |
| 6653 | &ppl_write_hint.attr, | ||
| 6653 | NULL, | 6654 | NULL, |
| 6654 | }; | 6655 | }; |
| 6655 | static struct attribute_group raid5_attrs_group = { | 6656 | static struct attribute_group raid5_attrs_group = { |
| @@ -7393,6 +7394,8 @@ static int raid5_run(struct mddev *mddev) | |||
| 7393 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 7394 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
| 7394 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, | 7395 | mddev->sync_thread = md_register_thread(md_do_sync, mddev, |
| 7395 | "reshape"); | 7396 | "reshape"); |
| 7397 | if (!mddev->sync_thread) | ||
| 7398 | goto abort; | ||
| 7396 | } | 7399 | } |
| 7397 | 7400 | ||
| 7398 | /* Ok, everything is just fine now */ | 7401 | /* Ok, everything is just fine now */ |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 07bf2bff3a76..470601980794 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -179,8 +179,8 @@ static int nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl) | |||
| 179 | int ret = 0; | 179 | int ret = 0; |
| 180 | 180 | ||
| 181 | /* | 181 | /* |
| 182 | * Keep a reference until the work is flushed since ->delete_ctrl | 182 | * Keep a reference until nvme_do_delete_ctrl() complete, |
| 183 | * can free the controller. | 183 | * since ->delete_ctrl can free the controller. |
| 184 | */ | 184 | */ |
| 185 | nvme_get_ctrl(ctrl); | 185 | nvme_get_ctrl(ctrl); |
| 186 | if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING)) | 186 | if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING)) |
| @@ -1250,7 +1250,7 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, | |||
| 1250 | if (ns) { | 1250 | if (ns) { |
| 1251 | if (ctrl->effects) | 1251 | if (ctrl->effects) |
| 1252 | effects = le32_to_cpu(ctrl->effects->iocs[opcode]); | 1252 | effects = le32_to_cpu(ctrl->effects->iocs[opcode]); |
| 1253 | if (effects & ~NVME_CMD_EFFECTS_CSUPP) | 1253 | if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC)) |
| 1254 | dev_warn(ctrl->device, | 1254 | dev_warn(ctrl->device, |
| 1255 | "IO command:%02x has unhandled effects:%08x\n", | 1255 | "IO command:%02x has unhandled effects:%08x\n", |
| 1256 | opcode, effects); | 1256 | opcode, effects); |
| @@ -1495,10 +1495,10 @@ static void nvme_set_chunk_size(struct nvme_ns *ns) | |||
| 1495 | blk_queue_chunk_sectors(ns->queue, rounddown_pow_of_two(chunk_size)); | 1495 | blk_queue_chunk_sectors(ns->queue, rounddown_pow_of_two(chunk_size)); |
| 1496 | } | 1496 | } |
| 1497 | 1497 | ||
| 1498 | static void nvme_config_discard(struct nvme_ns *ns) | 1498 | static void nvme_config_discard(struct gendisk *disk, struct nvme_ns *ns) |
| 1499 | { | 1499 | { |
| 1500 | struct nvme_ctrl *ctrl = ns->ctrl; | 1500 | struct nvme_ctrl *ctrl = ns->ctrl; |
| 1501 | struct request_queue *queue = ns->queue; | 1501 | struct request_queue *queue = disk->queue; |
| 1502 | u32 size = queue_logical_block_size(queue); | 1502 | u32 size = queue_logical_block_size(queue); |
| 1503 | 1503 | ||
| 1504 | if (!(ctrl->oncs & NVME_CTRL_ONCS_DSM)) { | 1504 | if (!(ctrl->oncs & NVME_CTRL_ONCS_DSM)) { |
| @@ -1526,12 +1526,13 @@ static void nvme_config_discard(struct nvme_ns *ns) | |||
| 1526 | blk_queue_max_write_zeroes_sectors(queue, UINT_MAX); | 1526 | blk_queue_max_write_zeroes_sectors(queue, UINT_MAX); |
| 1527 | } | 1527 | } |
| 1528 | 1528 | ||
| 1529 | static inline void nvme_config_write_zeroes(struct nvme_ns *ns) | 1529 | static void nvme_config_write_zeroes(struct gendisk *disk, struct nvme_ns *ns) |
| 1530 | { | 1530 | { |
| 1531 | u32 max_sectors; | 1531 | u32 max_sectors; |
| 1532 | unsigned short bs = 1 << ns->lba_shift; | 1532 | unsigned short bs = 1 << ns->lba_shift; |
| 1533 | 1533 | ||
| 1534 | if (!(ns->ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES)) | 1534 | if (!(ns->ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES) || |
| 1535 | (ns->ctrl->quirks & NVME_QUIRK_DISABLE_WRITE_ZEROES)) | ||
| 1535 | return; | 1536 | return; |
| 1536 | /* | 1537 | /* |
| 1537 | * Even though NVMe spec explicitly states that MDTS is not | 1538 | * Even though NVMe spec explicitly states that MDTS is not |
| @@ -1548,13 +1549,7 @@ static inline void nvme_config_write_zeroes(struct nvme_ns *ns) | |||
| 1548 | else | 1549 | else |
| 1549 | max_sectors = ((u32)(ns->ctrl->max_hw_sectors + 1) * bs) >> 9; | 1550 | max_sectors = ((u32)(ns->ctrl->max_hw_sectors + 1) * bs) >> 9; |
| 1550 | 1551 | ||
| 1551 | blk_queue_max_write_zeroes_sectors(ns->queue, max_sectors); | 1552 | blk_queue_max_write_zeroes_sectors(disk->queue, max_sectors); |
| 1552 | } | ||
| 1553 | |||
| 1554 | static inline void nvme_ns_config_oncs(struct nvme_ns *ns) | ||
| 1555 | { | ||
| 1556 | nvme_config_discard(ns); | ||
| 1557 | nvme_config_write_zeroes(ns); | ||
| 1558 | } | 1553 | } |
| 1559 | 1554 | ||
| 1560 | static void nvme_report_ns_ids(struct nvme_ctrl *ctrl, unsigned int nsid, | 1555 | static void nvme_report_ns_ids(struct nvme_ctrl *ctrl, unsigned int nsid, |
| @@ -1610,7 +1605,9 @@ static void nvme_update_disk_info(struct gendisk *disk, | |||
| 1610 | capacity = 0; | 1605 | capacity = 0; |
| 1611 | 1606 | ||
| 1612 | set_capacity(disk, capacity); | 1607 | set_capacity(disk, capacity); |
| 1613 | nvme_ns_config_oncs(ns); | 1608 | |
| 1609 | nvme_config_discard(disk, ns); | ||
| 1610 | nvme_config_write_zeroes(disk, ns); | ||
| 1614 | 1611 | ||
| 1615 | if (id->nsattr & (1 << 0)) | 1612 | if (id->nsattr & (1 << 0)) |
| 1616 | set_disk_ro(disk, true); | 1613 | set_disk_ro(disk, true); |
| @@ -3304,6 +3301,7 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) | |||
| 3304 | mutex_lock(&ctrl->subsys->lock); | 3301 | mutex_lock(&ctrl->subsys->lock); |
| 3305 | list_del_rcu(&ns->siblings); | 3302 | list_del_rcu(&ns->siblings); |
| 3306 | mutex_unlock(&ctrl->subsys->lock); | 3303 | mutex_unlock(&ctrl->subsys->lock); |
| 3304 | nvme_put_ns_head(ns->head); | ||
| 3307 | out_free_id: | 3305 | out_free_id: |
| 3308 | kfree(id); | 3306 | kfree(id); |
| 3309 | out_free_queue: | 3307 | out_free_queue: |
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index b29b12498a1a..f3b9d91ba0df 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
| @@ -2107,7 +2107,7 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq, | |||
| 2107 | 2107 | ||
| 2108 | freq->sg_cnt = 0; | 2108 | freq->sg_cnt = 0; |
| 2109 | 2109 | ||
| 2110 | if (!blk_rq_payload_bytes(rq)) | 2110 | if (!blk_rq_nr_phys_segments(rq)) |
| 2111 | return 0; | 2111 | return 0; |
| 2112 | 2112 | ||
| 2113 | freq->sg_table.sgl = freq->first_sgl; | 2113 | freq->sg_table.sgl = freq->first_sgl; |
| @@ -2304,12 +2304,23 @@ nvme_fc_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
| 2304 | if (ret) | 2304 | if (ret) |
| 2305 | return ret; | 2305 | return ret; |
| 2306 | 2306 | ||
| 2307 | data_len = blk_rq_payload_bytes(rq); | 2307 | /* |
| 2308 | if (data_len) | 2308 | * nvme core doesn't quite treat the rq opaquely. Commands such |
| 2309 | * as WRITE ZEROES will return a non-zero rq payload_bytes yet | ||
| 2310 | * there is no actual payload to be transferred. | ||
| 2311 | * To get it right, key data transmission on there being 1 or | ||
| 2312 | * more physical segments in the sg list. If there is no | ||
| 2313 | * physical segments, there is no payload. | ||
| 2314 | */ | ||
| 2315 | if (blk_rq_nr_phys_segments(rq)) { | ||
| 2316 | data_len = blk_rq_payload_bytes(rq); | ||
| 2309 | io_dir = ((rq_data_dir(rq) == WRITE) ? | 2317 | io_dir = ((rq_data_dir(rq) == WRITE) ? |
| 2310 | NVMEFC_FCP_WRITE : NVMEFC_FCP_READ); | 2318 | NVMEFC_FCP_WRITE : NVMEFC_FCP_READ); |
| 2311 | else | 2319 | } else { |
| 2320 | data_len = 0; | ||
| 2312 | io_dir = NVMEFC_FCP_NODATA; | 2321 | io_dir = NVMEFC_FCP_NODATA; |
| 2322 | } | ||
| 2323 | |||
| 2313 | 2324 | ||
| 2314 | return nvme_fc_start_fcp_op(ctrl, queue, op, data_len, io_dir); | 2325 | return nvme_fc_start_fcp_op(ctrl, queue, op, data_len, io_dir); |
| 2315 | } | 2326 | } |
| @@ -2464,6 +2475,7 @@ static int | |||
| 2464 | nvme_fc_recreate_io_queues(struct nvme_fc_ctrl *ctrl) | 2475 | nvme_fc_recreate_io_queues(struct nvme_fc_ctrl *ctrl) |
| 2465 | { | 2476 | { |
| 2466 | struct nvmf_ctrl_options *opts = ctrl->ctrl.opts; | 2477 | struct nvmf_ctrl_options *opts = ctrl->ctrl.opts; |
| 2478 | u32 prior_ioq_cnt = ctrl->ctrl.queue_count - 1; | ||
| 2467 | unsigned int nr_io_queues; | 2479 | unsigned int nr_io_queues; |
| 2468 | int ret; | 2480 | int ret; |
| 2469 | 2481 | ||
| @@ -2476,6 +2488,13 @@ nvme_fc_recreate_io_queues(struct nvme_fc_ctrl *ctrl) | |||
| 2476 | return ret; | 2488 | return ret; |
| 2477 | } | 2489 | } |
| 2478 | 2490 | ||
| 2491 | if (!nr_io_queues && prior_ioq_cnt) { | ||
| 2492 | dev_info(ctrl->ctrl.device, | ||
| 2493 | "Fail Reconnect: At least 1 io queue " | ||
| 2494 | "required (was %d)\n", prior_ioq_cnt); | ||
| 2495 | return -ENOSPC; | ||
| 2496 | } | ||
| 2497 | |||
| 2479 | ctrl->ctrl.queue_count = nr_io_queues + 1; | 2498 | ctrl->ctrl.queue_count = nr_io_queues + 1; |
| 2480 | /* check for io queues existing */ | 2499 | /* check for io queues existing */ |
| 2481 | if (ctrl->ctrl.queue_count == 1) | 2500 | if (ctrl->ctrl.queue_count == 1) |
| @@ -2489,6 +2508,10 @@ nvme_fc_recreate_io_queues(struct nvme_fc_ctrl *ctrl) | |||
| 2489 | if (ret) | 2508 | if (ret) |
| 2490 | goto out_delete_hw_queues; | 2509 | goto out_delete_hw_queues; |
| 2491 | 2510 | ||
| 2511 | if (prior_ioq_cnt != nr_io_queues) | ||
| 2512 | dev_info(ctrl->ctrl.device, | ||
| 2513 | "reconnect: revising io queue count from %d to %d\n", | ||
| 2514 | prior_ioq_cnt, nr_io_queues); | ||
| 2492 | blk_mq_update_nr_hw_queues(&ctrl->tag_set, nr_io_queues); | 2515 | blk_mq_update_nr_hw_queues(&ctrl->tag_set, nr_io_queues); |
| 2493 | 2516 | ||
| 2494 | return 0; | 2517 | return 0; |
| @@ -3006,7 +3029,10 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, | |||
| 3006 | 3029 | ||
| 3007 | ctrl->ctrl.opts = opts; | 3030 | ctrl->ctrl.opts = opts; |
| 3008 | ctrl->ctrl.nr_reconnects = 0; | 3031 | ctrl->ctrl.nr_reconnects = 0; |
| 3009 | ctrl->ctrl.numa_node = dev_to_node(lport->dev); | 3032 | if (lport->dev) |
| 3033 | ctrl->ctrl.numa_node = dev_to_node(lport->dev); | ||
| 3034 | else | ||
| 3035 | ctrl->ctrl.numa_node = NUMA_NO_NODE; | ||
| 3010 | INIT_LIST_HEAD(&ctrl->ctrl_list); | 3036 | INIT_LIST_HEAD(&ctrl->ctrl_list); |
| 3011 | ctrl->lport = lport; | 3037 | ctrl->lport = lport; |
| 3012 | ctrl->rport = rport; | 3038 | ctrl->rport = rport; |
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index b91f1838bbd5..527d64545023 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
| @@ -87,6 +87,11 @@ enum nvme_quirks { | |||
| 87 | * Ignore device provided subnqn. | 87 | * Ignore device provided subnqn. |
| 88 | */ | 88 | */ |
| 89 | NVME_QUIRK_IGNORE_DEV_SUBNQN = (1 << 8), | 89 | NVME_QUIRK_IGNORE_DEV_SUBNQN = (1 << 8), |
| 90 | |||
| 91 | /* | ||
| 92 | * Broken Write Zeroes. | ||
| 93 | */ | ||
| 94 | NVME_QUIRK_DISABLE_WRITE_ZEROES = (1 << 9), | ||
| 90 | }; | 95 | }; |
| 91 | 96 | ||
| 92 | /* | 97 | /* |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 92bad1c810ac..a90cf5d63aac 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
| @@ -2937,7 +2937,8 @@ static const struct pci_device_id nvme_id_table[] = { | |||
| 2937 | { PCI_VDEVICE(INTEL, 0xf1a6), /* Intel 760p/Pro 7600p */ | 2937 | { PCI_VDEVICE(INTEL, 0xf1a6), /* Intel 760p/Pro 7600p */ |
| 2938 | .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, | 2938 | .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, |
| 2939 | { PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */ | 2939 | { PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */ |
| 2940 | .driver_data = NVME_QUIRK_IDENTIFY_CNS, }, | 2940 | .driver_data = NVME_QUIRK_IDENTIFY_CNS | |
| 2941 | NVME_QUIRK_DISABLE_WRITE_ZEROES, }, | ||
| 2941 | { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ | 2942 | { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ |
| 2942 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, | 2943 | .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, |
| 2943 | { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ | 2944 | { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ |
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 208ee518af65..e7e08889865e 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c | |||
| @@ -463,6 +463,15 @@ static int nvme_tcp_handle_c2h_data(struct nvme_tcp_queue *queue, | |||
| 463 | 463 | ||
| 464 | queue->data_remaining = le32_to_cpu(pdu->data_length); | 464 | queue->data_remaining = le32_to_cpu(pdu->data_length); |
| 465 | 465 | ||
| 466 | if (pdu->hdr.flags & NVME_TCP_F_DATA_SUCCESS && | ||
| 467 | unlikely(!(pdu->hdr.flags & NVME_TCP_F_DATA_LAST))) { | ||
| 468 | dev_err(queue->ctrl->ctrl.device, | ||
| 469 | "queue %d tag %#x SUCCESS set but not last PDU\n", | ||
| 470 | nvme_tcp_queue_id(queue), rq->tag); | ||
| 471 | nvme_tcp_error_recovery(&queue->ctrl->ctrl); | ||
| 472 | return -EPROTO; | ||
| 473 | } | ||
| 474 | |||
| 466 | return 0; | 475 | return 0; |
| 467 | 476 | ||
| 468 | } | 477 | } |
| @@ -618,6 +627,14 @@ static int nvme_tcp_recv_pdu(struct nvme_tcp_queue *queue, struct sk_buff *skb, | |||
| 618 | return ret; | 627 | return ret; |
| 619 | } | 628 | } |
| 620 | 629 | ||
| 630 | static inline void nvme_tcp_end_request(struct request *rq, __le16 status) | ||
| 631 | { | ||
| 632 | union nvme_result res = {}; | ||
| 633 | |||
| 634 | nvme_end_request(rq, cpu_to_le16(status << 1), res); | ||
| 635 | } | ||
| 636 | |||
| 637 | |||
| 621 | static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, | 638 | static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, |
| 622 | unsigned int *offset, size_t *len) | 639 | unsigned int *offset, size_t *len) |
| 623 | { | 640 | { |
| @@ -685,6 +702,8 @@ static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, | |||
| 685 | nvme_tcp_ddgst_final(queue->rcv_hash, &queue->exp_ddgst); | 702 | nvme_tcp_ddgst_final(queue->rcv_hash, &queue->exp_ddgst); |
| 686 | queue->ddgst_remaining = NVME_TCP_DIGEST_LENGTH; | 703 | queue->ddgst_remaining = NVME_TCP_DIGEST_LENGTH; |
| 687 | } else { | 704 | } else { |
| 705 | if (pdu->hdr.flags & NVME_TCP_F_DATA_SUCCESS) | ||
| 706 | nvme_tcp_end_request(rq, NVME_SC_SUCCESS); | ||
| 688 | nvme_tcp_init_recv_ctx(queue); | 707 | nvme_tcp_init_recv_ctx(queue); |
| 689 | } | 708 | } |
| 690 | } | 709 | } |
| @@ -695,6 +714,7 @@ static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, | |||
| 695 | static int nvme_tcp_recv_ddgst(struct nvme_tcp_queue *queue, | 714 | static int nvme_tcp_recv_ddgst(struct nvme_tcp_queue *queue, |
| 696 | struct sk_buff *skb, unsigned int *offset, size_t *len) | 715 | struct sk_buff *skb, unsigned int *offset, size_t *len) |
| 697 | { | 716 | { |
| 717 | struct nvme_tcp_data_pdu *pdu = (void *)queue->pdu; | ||
| 698 | char *ddgst = (char *)&queue->recv_ddgst; | 718 | char *ddgst = (char *)&queue->recv_ddgst; |
| 699 | size_t recv_len = min_t(size_t, *len, queue->ddgst_remaining); | 719 | size_t recv_len = min_t(size_t, *len, queue->ddgst_remaining); |
| 700 | off_t off = NVME_TCP_DIGEST_LENGTH - queue->ddgst_remaining; | 720 | off_t off = NVME_TCP_DIGEST_LENGTH - queue->ddgst_remaining; |
| @@ -718,6 +738,13 @@ static int nvme_tcp_recv_ddgst(struct nvme_tcp_queue *queue, | |||
| 718 | return -EIO; | 738 | return -EIO; |
| 719 | } | 739 | } |
| 720 | 740 | ||
| 741 | if (pdu->hdr.flags & NVME_TCP_F_DATA_SUCCESS) { | ||
| 742 | struct request *rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), | ||
| 743 | pdu->command_id); | ||
| 744 | |||
| 745 | nvme_tcp_end_request(rq, NVME_SC_SUCCESS); | ||
| 746 | } | ||
| 747 | |||
| 721 | nvme_tcp_init_recv_ctx(queue); | 748 | nvme_tcp_init_recv_ctx(queue); |
| 722 | return 0; | 749 | return 0; |
| 723 | } | 750 | } |
| @@ -815,10 +842,7 @@ static inline void nvme_tcp_done_send_req(struct nvme_tcp_queue *queue) | |||
| 815 | 842 | ||
| 816 | static void nvme_tcp_fail_request(struct nvme_tcp_request *req) | 843 | static void nvme_tcp_fail_request(struct nvme_tcp_request *req) |
| 817 | { | 844 | { |
| 818 | union nvme_result res = {}; | 845 | nvme_tcp_end_request(blk_mq_rq_from_pdu(req), NVME_SC_DATA_XFER_ERROR); |
| 819 | |||
| 820 | nvme_end_request(blk_mq_rq_from_pdu(req), | ||
| 821 | cpu_to_le16(NVME_SC_DATA_XFER_ERROR), res); | ||
| 822 | } | 846 | } |
| 823 | 847 | ||
| 824 | static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) | 848 | static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) |
diff --git a/drivers/nvme/host/trace.c b/drivers/nvme/host/trace.c index 58456de78bb2..5f24ea7a28eb 100644 --- a/drivers/nvme/host/trace.c +++ b/drivers/nvme/host/trace.c | |||
| @@ -50,7 +50,19 @@ static const char *nvme_trace_admin_identify(struct trace_seq *p, u8 *cdw10) | |||
| 50 | return ret; | 50 | return ret; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | static const char *nvme_trace_admin_get_features(struct trace_seq *p, | ||
| 54 | u8 *cdw10) | ||
| 55 | { | ||
| 56 | const char *ret = trace_seq_buffer_ptr(p); | ||
| 57 | u8 fid = cdw10[0]; | ||
| 58 | u8 sel = cdw10[1] & 0x7; | ||
| 59 | u32 cdw11 = get_unaligned_le32(cdw10 + 4); | ||
| 60 | |||
| 61 | trace_seq_printf(p, "fid=0x%x sel=0x%x cdw11=0x%x", fid, sel, cdw11); | ||
| 62 | trace_seq_putc(p, 0); | ||
| 53 | 63 | ||
| 64 | return ret; | ||
| 65 | } | ||
| 54 | 66 | ||
| 55 | static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10) | 67 | static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10) |
| 56 | { | 68 | { |
| @@ -101,6 +113,8 @@ const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, | |||
| 101 | return nvme_trace_create_cq(p, cdw10); | 113 | return nvme_trace_create_cq(p, cdw10); |
| 102 | case nvme_admin_identify: | 114 | case nvme_admin_identify: |
| 103 | return nvme_trace_admin_identify(p, cdw10); | 115 | return nvme_trace_admin_identify(p, cdw10); |
| 116 | case nvme_admin_get_features: | ||
| 117 | return nvme_trace_admin_get_features(p, cdw10); | ||
| 104 | default: | 118 | default: |
| 105 | return nvme_trace_common(p, cdw10); | 119 | return nvme_trace_common(p, cdw10); |
| 106 | } | 120 | } |
diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h index 244d7c177e5a..97d3c77365b8 100644 --- a/drivers/nvme/host/trace.h +++ b/drivers/nvme/host/trace.h | |||
| @@ -108,7 +108,7 @@ TRACE_EVENT(nvme_setup_cmd, | |||
| 108 | __entry->metadata = le64_to_cpu(cmd->common.metadata); | 108 | __entry->metadata = le64_to_cpu(cmd->common.metadata); |
| 109 | __assign_disk_name(__entry->disk, req->rq_disk); | 109 | __assign_disk_name(__entry->disk, req->rq_disk); |
| 110 | memcpy(__entry->cdw10, &cmd->common.cdw10, | 110 | memcpy(__entry->cdw10, &cmd->common.cdw10, |
| 111 | 6 * sizeof(__entry->cdw10)); | 111 | sizeof(__entry->cdw10)); |
| 112 | ), | 112 | ), |
| 113 | TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%llx, cmd=(%s %s)", | 113 | TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%llx, cmd=(%s %s)", |
| 114 | __entry->ctrl_id, __print_disk_name(__entry->disk), | 114 | __entry->ctrl_id, __print_disk_name(__entry->disk), |
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index d44ede147263..2d73b66e3686 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c | |||
| @@ -1163,6 +1163,15 @@ static void nvmet_release_p2p_ns_map(struct nvmet_ctrl *ctrl) | |||
| 1163 | put_device(ctrl->p2p_client); | 1163 | put_device(ctrl->p2p_client); |
| 1164 | } | 1164 | } |
| 1165 | 1165 | ||
| 1166 | static void nvmet_fatal_error_handler(struct work_struct *work) | ||
| 1167 | { | ||
| 1168 | struct nvmet_ctrl *ctrl = | ||
| 1169 | container_of(work, struct nvmet_ctrl, fatal_err_work); | ||
| 1170 | |||
| 1171 | pr_err("ctrl %d fatal error occurred!\n", ctrl->cntlid); | ||
| 1172 | ctrl->ops->delete_ctrl(ctrl); | ||
| 1173 | } | ||
| 1174 | |||
| 1166 | u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, | 1175 | u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, |
| 1167 | struct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp) | 1176 | struct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp) |
| 1168 | { | 1177 | { |
| @@ -1205,6 +1214,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, | |||
| 1205 | INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); | 1214 | INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); |
| 1206 | INIT_LIST_HEAD(&ctrl->async_events); | 1215 | INIT_LIST_HEAD(&ctrl->async_events); |
| 1207 | INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); | 1216 | INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); |
| 1217 | INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler); | ||
| 1208 | 1218 | ||
| 1209 | memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE); | 1219 | memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE); |
| 1210 | memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE); | 1220 | memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE); |
| @@ -1308,21 +1318,11 @@ void nvmet_ctrl_put(struct nvmet_ctrl *ctrl) | |||
| 1308 | kref_put(&ctrl->ref, nvmet_ctrl_free); | 1318 | kref_put(&ctrl->ref, nvmet_ctrl_free); |
| 1309 | } | 1319 | } |
| 1310 | 1320 | ||
| 1311 | static void nvmet_fatal_error_handler(struct work_struct *work) | ||
| 1312 | { | ||
| 1313 | struct nvmet_ctrl *ctrl = | ||
| 1314 | container_of(work, struct nvmet_ctrl, fatal_err_work); | ||
| 1315 | |||
| 1316 | pr_err("ctrl %d fatal error occurred!\n", ctrl->cntlid); | ||
| 1317 | ctrl->ops->delete_ctrl(ctrl); | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl) | 1321 | void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl) |
| 1321 | { | 1322 | { |
| 1322 | mutex_lock(&ctrl->lock); | 1323 | mutex_lock(&ctrl->lock); |
| 1323 | if (!(ctrl->csts & NVME_CSTS_CFS)) { | 1324 | if (!(ctrl->csts & NVME_CSTS_CFS)) { |
| 1324 | ctrl->csts |= NVME_CSTS_CFS; | 1325 | ctrl->csts |= NVME_CSTS_CFS; |
| 1325 | INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler); | ||
| 1326 | schedule_work(&ctrl->fatal_err_work); | 1326 | schedule_work(&ctrl->fatal_err_work); |
| 1327 | } | 1327 | } |
| 1328 | mutex_unlock(&ctrl->lock); | 1328 | mutex_unlock(&ctrl->lock); |
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c index 1e9654f04c60..98b7b1f4ee96 100644 --- a/drivers/nvme/target/fc.c +++ b/drivers/nvme/target/fc.c | |||
| @@ -1143,10 +1143,8 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport) | |||
| 1143 | &tgtport->assoc_list, a_list) { | 1143 | &tgtport->assoc_list, a_list) { |
| 1144 | if (!nvmet_fc_tgt_a_get(assoc)) | 1144 | if (!nvmet_fc_tgt_a_get(assoc)) |
| 1145 | continue; | 1145 | continue; |
| 1146 | spin_unlock_irqrestore(&tgtport->lock, flags); | 1146 | if (!schedule_work(&assoc->del_work)) |
| 1147 | nvmet_fc_delete_target_assoc(assoc); | 1147 | nvmet_fc_tgt_a_put(assoc); |
| 1148 | nvmet_fc_tgt_a_put(assoc); | ||
| 1149 | spin_lock_irqsave(&tgtport->lock, flags); | ||
| 1150 | } | 1148 | } |
| 1151 | spin_unlock_irqrestore(&tgtport->lock, flags); | 1149 | spin_unlock_irqrestore(&tgtport->lock, flags); |
| 1152 | } | 1150 | } |
| @@ -1185,7 +1183,8 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) | |||
| 1185 | nvmet_fc_tgtport_put(tgtport); | 1183 | nvmet_fc_tgtport_put(tgtport); |
| 1186 | 1184 | ||
| 1187 | if (found_ctrl) { | 1185 | if (found_ctrl) { |
| 1188 | schedule_work(&assoc->del_work); | 1186 | if (!schedule_work(&assoc->del_work)) |
| 1187 | nvmet_fc_tgt_a_put(assoc); | ||
| 1189 | return; | 1188 | return; |
| 1190 | } | 1189 | } |
| 1191 | 1190 | ||
| @@ -1503,10 +1502,8 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, | |||
| 1503 | (struct fcnvme_ls_disconnect_rqst *)iod->rqstbuf; | 1502 | (struct fcnvme_ls_disconnect_rqst *)iod->rqstbuf; |
| 1504 | struct fcnvme_ls_disconnect_acc *acc = | 1503 | struct fcnvme_ls_disconnect_acc *acc = |
| 1505 | (struct fcnvme_ls_disconnect_acc *)iod->rspbuf; | 1504 | (struct fcnvme_ls_disconnect_acc *)iod->rspbuf; |
| 1506 | struct nvmet_fc_tgt_queue *queue = NULL; | ||
| 1507 | struct nvmet_fc_tgt_assoc *assoc; | 1505 | struct nvmet_fc_tgt_assoc *assoc; |
| 1508 | int ret = 0; | 1506 | int ret = 0; |
| 1509 | bool del_assoc = false; | ||
| 1510 | 1507 | ||
| 1511 | memset(acc, 0, sizeof(*acc)); | 1508 | memset(acc, 0, sizeof(*acc)); |
| 1512 | 1509 | ||
| @@ -1537,18 +1534,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, | |||
| 1537 | assoc = nvmet_fc_find_target_assoc(tgtport, | 1534 | assoc = nvmet_fc_find_target_assoc(tgtport, |
| 1538 | be64_to_cpu(rqst->associd.association_id)); | 1535 | be64_to_cpu(rqst->associd.association_id)); |
| 1539 | iod->assoc = assoc; | 1536 | iod->assoc = assoc; |
| 1540 | if (assoc) { | 1537 | if (!assoc) |
| 1541 | if (rqst->discon_cmd.scope == | ||
| 1542 | FCNVME_DISCONN_CONNECTION) { | ||
| 1543 | queue = nvmet_fc_find_target_queue(tgtport, | ||
| 1544 | be64_to_cpu( | ||
| 1545 | rqst->discon_cmd.id)); | ||
| 1546 | if (!queue) { | ||
| 1547 | nvmet_fc_tgt_a_put(assoc); | ||
| 1548 | ret = VERR_NO_CONN; | ||
| 1549 | } | ||
| 1550 | } | ||
| 1551 | } else | ||
| 1552 | ret = VERR_NO_ASSOC; | 1538 | ret = VERR_NO_ASSOC; |
| 1553 | } | 1539 | } |
| 1554 | 1540 | ||
| @@ -1576,26 +1562,10 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, | |||
| 1576 | sizeof(struct fcnvme_ls_disconnect_acc)), | 1562 | sizeof(struct fcnvme_ls_disconnect_acc)), |
| 1577 | FCNVME_LS_DISCONNECT); | 1563 | FCNVME_LS_DISCONNECT); |
| 1578 | 1564 | ||
| 1579 | |||
| 1580 | /* are we to delete a Connection ID (queue) */ | ||
| 1581 | if (queue) { | ||
| 1582 | int qid = queue->qid; | ||
| 1583 | |||
| 1584 | nvmet_fc_delete_target_queue(queue); | ||
| 1585 | |||
| 1586 | /* release the get taken by find_target_queue */ | ||
| 1587 | nvmet_fc_tgt_q_put(queue); | ||
| 1588 | |||
| 1589 | /* tear association down if io queue terminated */ | ||
| 1590 | if (!qid) | ||
| 1591 | del_assoc = true; | ||
| 1592 | } | ||
| 1593 | |||
| 1594 | /* release get taken in nvmet_fc_find_target_assoc */ | 1565 | /* release get taken in nvmet_fc_find_target_assoc */ |
| 1595 | nvmet_fc_tgt_a_put(iod->assoc); | 1566 | nvmet_fc_tgt_a_put(iod->assoc); |
| 1596 | 1567 | ||
| 1597 | if (del_assoc) | 1568 | nvmet_fc_delete_target_assoc(iod->assoc); |
| 1598 | nvmet_fc_delete_target_assoc(iod->assoc); | ||
| 1599 | } | 1569 | } |
| 1600 | 1570 | ||
| 1601 | 1571 | ||
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 71dfedbadc26..a065dbfc43b1 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c | |||
| @@ -194,11 +194,11 @@ static u16 nvmet_bdev_discard_range(struct nvmet_req *req, | |||
| 194 | le64_to_cpu(range->slba) << (ns->blksize_shift - 9), | 194 | le64_to_cpu(range->slba) << (ns->blksize_shift - 9), |
| 195 | le32_to_cpu(range->nlb) << (ns->blksize_shift - 9), | 195 | le32_to_cpu(range->nlb) << (ns->blksize_shift - 9), |
| 196 | GFP_KERNEL, 0, bio); | 196 | GFP_KERNEL, 0, bio); |
| 197 | 197 | if (ret && ret != -EOPNOTSUPP) { | |
| 198 | if (ret) | ||
| 199 | req->error_slba = le64_to_cpu(range->slba); | 198 | req->error_slba = le64_to_cpu(range->slba); |
| 200 | 199 | return blk_to_nvme_status(req, errno_to_blk_status(ret)); | |
| 201 | return blk_to_nvme_status(req, errno_to_blk_status(ret)); | 200 | } |
| 201 | return NVME_SC_SUCCESS; | ||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static void nvmet_bdev_execute_discard(struct nvmet_req *req) | 204 | static void nvmet_bdev_execute_discard(struct nvmet_req *req) |
diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c index 517522305e5c..3e43212d3c1c 100644 --- a/drivers/nvme/target/io-cmd-file.c +++ b/drivers/nvme/target/io-cmd-file.c | |||
| @@ -297,7 +297,7 @@ static void nvmet_file_execute_discard(struct nvmet_req *req) | |||
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | ret = vfs_fallocate(req->ns->file, mode, offset, len); | 299 | ret = vfs_fallocate(req->ns->file, mode, offset, len); |
| 300 | if (ret) { | 300 | if (ret && ret != -EOPNOTSUPP) { |
| 301 | req->error_slba = le64_to_cpu(range.slba); | 301 | req->error_slba = le64_to_cpu(range.slba); |
| 302 | status = errno_to_nvme_status(req, ret); | 302 | status = errno_to_nvme_status(req, ret); |
| 303 | break; | 303 | break; |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index fac0ddf8a8e2..e1c6d79fb4cc 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -723,6 +723,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) | |||
| 723 | #endif | 723 | #endif |
| 724 | case BLKTRACESTART: | 724 | case BLKTRACESTART: |
| 725 | start = 1; | 725 | start = 1; |
| 726 | /* fall through */ | ||
| 726 | case BLKTRACESTOP: | 727 | case BLKTRACESTOP: |
| 727 | ret = __blk_trace_startstop(q, start); | 728 | ret = __blk_trace_startstop(q, start); |
| 728 | break; | 729 | break; |
