hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/block/virtio_blk.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 //#define DEBUG
23 #include <linux/spinlock.h>
34 #include <linux/slab.h>
....@@ -10,14 +11,15 @@
1011 #include <linux/virtio_blk.h>
1112 #include <linux/scatterlist.h>
1213 #include <linux/string_helpers.h>
13
-#include <scsi/scsi_cmnd.h>
1414 #include <linux/idr.h>
1515 #include <linux/blk-mq.h>
1616 #include <linux/blk-mq-virtio.h>
1717 #include <linux/numa.h>
18
+#include <uapi/linux/virtio_ring.h>
1819
1920 #define PART_BITS 4
2021 #define VQ_NAME_LEN 16
22
+#define MAX_DISCARD_SEGMENTS 256u
2123
2224 static int major;
2325 static DEFINE_IDA(vd_index_ida);
....@@ -70,11 +72,6 @@
7072 };
7173
7274 struct virtblk_req {
73
-#ifdef CONFIG_VIRTIO_BLK_SCSI
74
- struct scsi_request sreq; /* for SCSI passthrough, must be first */
75
- u8 sense[SCSI_SENSE_BUFFERSIZE];
76
- struct virtio_scsi_inhdr in_hdr;
77
-#endif
7875 struct virtio_blk_outhdr out_hdr;
7976 u8 status;
8077 struct scatterlist sg[];
....@@ -91,80 +88,6 @@
9188 return BLK_STS_IOERR;
9289 }
9390 }
94
-
95
-/*
96
- * If this is a packet command we need a couple of additional headers. Behind
97
- * the normal outhdr we put a segment with the scsi command block, and before
98
- * the normal inhdr we put the sense data and the inhdr with additional status
99
- * information.
100
- */
101
-#ifdef CONFIG_VIRTIO_BLK_SCSI
102
-static int virtblk_add_req_scsi(struct virtqueue *vq, struct virtblk_req *vbr,
103
- struct scatterlist *data_sg, bool have_data)
104
-{
105
- struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6];
106
- unsigned int num_out = 0, num_in = 0;
107
-
108
- sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr));
109
- sgs[num_out++] = &hdr;
110
- sg_init_one(&cmd, vbr->sreq.cmd, vbr->sreq.cmd_len);
111
- sgs[num_out++] = &cmd;
112
-
113
- if (have_data) {
114
- if (vbr->out_hdr.type & cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT))
115
- sgs[num_out++] = data_sg;
116
- else
117
- sgs[num_out + num_in++] = data_sg;
118
- }
119
-
120
- sg_init_one(&sense, vbr->sense, SCSI_SENSE_BUFFERSIZE);
121
- sgs[num_out + num_in++] = &sense;
122
- sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr));
123
- sgs[num_out + num_in++] = &inhdr;
124
- sg_init_one(&status, &vbr->status, sizeof(vbr->status));
125
- sgs[num_out + num_in++] = &status;
126
-
127
- return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC);
128
-}
129
-
130
-static inline void virtblk_scsi_request_done(struct request *req)
131
-{
132
- struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
133
- struct virtio_blk *vblk = req->q->queuedata;
134
- struct scsi_request *sreq = &vbr->sreq;
135
-
136
- sreq->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual);
137
- sreq->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
138
- sreq->result = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
139
-}
140
-
141
-static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
142
- unsigned int cmd, unsigned long data)
143
-{
144
- struct gendisk *disk = bdev->bd_disk;
145
- struct virtio_blk *vblk = disk->private_data;
146
-
147
- /*
148
- * Only allow the generic SCSI ioctls if the host can support it.
149
- */
150
- if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
151
- return -ENOTTY;
152
-
153
- return scsi_cmd_blk_ioctl(bdev, mode, cmd,
154
- (void __user *)data);
155
-}
156
-#else
157
-static inline int virtblk_add_req_scsi(struct virtqueue *vq,
158
- struct virtblk_req *vbr, struct scatterlist *data_sg,
159
- bool have_data)
160
-{
161
- return -EIO;
162
-}
163
-static inline void virtblk_scsi_request_done(struct request *req)
164
-{
165
-}
166
-#define virtblk_ioctl NULL
167
-#endif /* CONFIG_VIRTIO_BLK_SCSI */
16891
16992 static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr,
17093 struct scatterlist *data_sg, bool have_data)
....@@ -188,15 +111,61 @@
188111 return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC);
189112 }
190113
114
+static int virtblk_setup_discard_write_zeroes(struct request *req, bool unmap)
115
+{
116
+ unsigned short segments = blk_rq_nr_discard_segments(req);
117
+ unsigned short n = 0;
118
+ struct virtio_blk_discard_write_zeroes *range;
119
+ struct bio *bio;
120
+ u32 flags = 0;
121
+
122
+ if (unmap)
123
+ flags |= VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP;
124
+
125
+ range = kmalloc_array(segments, sizeof(*range), GFP_ATOMIC);
126
+ if (!range)
127
+ return -ENOMEM;
128
+
129
+ /*
130
+ * Single max discard segment means multi-range discard isn't
131
+ * supported, and block layer only runs contiguity merge like
132
+ * normal RW request. So we can't reply on bio for retrieving
133
+ * each range info.
134
+ */
135
+ if (queue_max_discard_segments(req->q) == 1) {
136
+ range[0].flags = cpu_to_le32(flags);
137
+ range[0].num_sectors = cpu_to_le32(blk_rq_sectors(req));
138
+ range[0].sector = cpu_to_le64(blk_rq_pos(req));
139
+ n = 1;
140
+ } else {
141
+ __rq_for_each_bio(bio, req) {
142
+ u64 sector = bio->bi_iter.bi_sector;
143
+ u32 num_sectors = bio->bi_iter.bi_size >> SECTOR_SHIFT;
144
+
145
+ range[n].flags = cpu_to_le32(flags);
146
+ range[n].num_sectors = cpu_to_le32(num_sectors);
147
+ range[n].sector = cpu_to_le64(sector);
148
+ n++;
149
+ }
150
+ }
151
+
152
+ WARN_ON_ONCE(n != segments);
153
+
154
+ req->special_vec.bv_page = virt_to_page(range);
155
+ req->special_vec.bv_offset = offset_in_page(range);
156
+ req->special_vec.bv_len = sizeof(*range) * segments;
157
+ req->rq_flags |= RQF_SPECIAL_PAYLOAD;
158
+
159
+ return 0;
160
+}
161
+
191162 static inline void virtblk_request_done(struct request *req)
192163 {
193164 struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
194165
195
- switch (req_op(req)) {
196
- case REQ_OP_SCSI_IN:
197
- case REQ_OP_SCSI_OUT:
198
- virtblk_scsi_request_done(req);
199
- break;
166
+ if (req->rq_flags & RQF_SPECIAL_PAYLOAD) {
167
+ kfree(page_address(req->special_vec.bv_page) +
168
+ req->special_vec.bv_offset);
200169 }
201170
202171 blk_mq_end_request(req, virtblk_result(vbr));
....@@ -217,7 +186,8 @@
217186 while ((vbr = virtqueue_get_buf(vblk->vqs[qid].vq, &len)) != NULL) {
218187 struct request *req = blk_mq_rq_from_pdu(vbr);
219188
220
- blk_mq_complete_request(req);
189
+ if (likely(!blk_should_fake_timeout(req->q)))
190
+ blk_mq_complete_request(req);
221191 req_done = true;
222192 }
223193 if (unlikely(virtqueue_is_broken(vq)))
....@@ -228,6 +198,20 @@
228198 if (req_done)
229199 blk_mq_start_stopped_hw_queues(vblk->disk->queue, true);
230200 spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
201
+}
202
+
203
+static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx)
204
+{
205
+ struct virtio_blk *vblk = hctx->queue->queuedata;
206
+ struct virtio_blk_vq *vq = &vblk->vqs[hctx->queue_num];
207
+ bool kick;
208
+
209
+ spin_lock_irq(&vq->lock);
210
+ kick = virtqueue_kick_prepare(vq->vq);
211
+ spin_unlock_irq(&vq->lock);
212
+
213
+ if (kick)
214
+ virtqueue_notify(vq->vq);
231215 }
232216
233217 static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
....@@ -241,9 +225,8 @@
241225 int qid = hctx->queue_num;
242226 int err;
243227 bool notify = false;
228
+ bool unmap = false;
244229 u32 type;
245
-
246
- BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
247230
248231 switch (req_op(req)) {
249232 case REQ_OP_READ:
....@@ -253,9 +236,12 @@
253236 case REQ_OP_FLUSH:
254237 type = VIRTIO_BLK_T_FLUSH;
255238 break;
256
- case REQ_OP_SCSI_IN:
257
- case REQ_OP_SCSI_OUT:
258
- type = VIRTIO_BLK_T_SCSI_CMD;
239
+ case REQ_OP_DISCARD:
240
+ type = VIRTIO_BLK_T_DISCARD;
241
+ break;
242
+ case REQ_OP_WRITE_ZEROES:
243
+ type = VIRTIO_BLK_T_WRITE_ZEROES;
244
+ unmap = !(req->cmd_flags & REQ_NOUNMAP);
259245 break;
260246 case REQ_OP_DRV_IN:
261247 type = VIRTIO_BLK_T_GET_ID;
....@@ -265,12 +251,22 @@
265251 return BLK_STS_IOERR;
266252 }
267253
254
+ BUG_ON(type != VIRTIO_BLK_T_DISCARD &&
255
+ type != VIRTIO_BLK_T_WRITE_ZEROES &&
256
+ (req->nr_phys_segments + 2 > vblk->sg_elems));
257
+
268258 vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, type);
269259 vbr->out_hdr.sector = type ?
270260 0 : cpu_to_virtio64(vblk->vdev, blk_rq_pos(req));
271261 vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(req));
272262
273263 blk_mq_start_request(req);
264
+
265
+ if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES) {
266
+ err = virtblk_setup_discard_write_zeroes(req, unmap);
267
+ if (err)
268
+ return BLK_STS_RESOURCE;
269
+ }
274270
275271 num = blk_rq_map_sg(hctx->queue, req, vbr->sg);
276272 if (num) {
....@@ -281,10 +277,7 @@
281277 }
282278
283279 spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
284
- if (blk_rq_is_scsi(req))
285
- err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num);
286
- else
287
- err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
280
+ err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
288281 if (err) {
289282 virtqueue_kick(vblk->vqs[qid].vq);
290283 /* Don't stop the queue if -ENOMEM: we may have failed to
....@@ -406,7 +399,6 @@
406399 }
407400
408401 static const struct block_device_operations virtblk_fops = {
409
- .ioctl = virtblk_ioctl,
410402 .owner = THIS_MODULE,
411403 .open = virtblk_open,
412404 .release = virtblk_release,
....@@ -423,8 +415,8 @@
423415 return minor >> PART_BITS;
424416 }
425417
426
-static ssize_t virtblk_serial_show(struct device *dev,
427
- struct device_attribute *attr, char *buf)
418
+static ssize_t serial_show(struct device *dev,
419
+ struct device_attribute *attr, char *buf)
428420 {
429421 struct gendisk *disk = dev_to_disk(dev);
430422 int err;
....@@ -443,7 +435,7 @@
443435 return err;
444436 }
445437
446
-static DEVICE_ATTR(serial, 0444, virtblk_serial_show, NULL);
438
+static DEVICE_ATTR_RO(serial);
447439
448440 /* The queue's logical block size must be set before calling this */
449441 static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize)
....@@ -480,18 +472,15 @@
480472 cap_str_10,
481473 cap_str_2);
482474
483
- set_capacity(vblk->disk, capacity);
475
+ set_capacity_revalidate_and_notify(vblk->disk, capacity, true);
484476 }
485477
486478 static void virtblk_config_changed_work(struct work_struct *work)
487479 {
488480 struct virtio_blk *vblk =
489481 container_of(work, struct virtio_blk, config_work);
490
- char *envp[] = { "RESIZE=1", NULL };
491482
492483 virtblk_update_capacity(vblk, true);
493
- revalidate_disk(vblk->disk);
494
- kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp);
495484 }
496485
497486 static void virtblk_config_changed(struct virtio_device *vdev)
....@@ -611,7 +600,7 @@
611600 struct virtio_blk *vblk = vdev->priv;
612601
613602 blk_queue_write_cache(vblk->disk->queue, writeback, false);
614
- revalidate_disk(vblk->disk);
603
+ revalidate_disk_size(vblk->disk, true);
615604 }
616605
617606 static const char *const virtblk_cache_types[] = {
....@@ -619,8 +608,8 @@
619608 };
620609
621610 static ssize_t
622
-virtblk_cache_type_store(struct device *dev, struct device_attribute *attr,
623
- const char *buf, size_t count)
611
+cache_type_store(struct device *dev, struct device_attribute *attr,
612
+ const char *buf, size_t count)
624613 {
625614 struct gendisk *disk = dev_to_disk(dev);
626615 struct virtio_blk *vblk = disk->private_data;
....@@ -638,8 +627,7 @@
638627 }
639628
640629 static ssize_t
641
-virtblk_cache_type_show(struct device *dev, struct device_attribute *attr,
642
- char *buf)
630
+cache_type_show(struct device *dev, struct device_attribute *attr, char *buf)
643631 {
644632 struct gendisk *disk = dev_to_disk(dev);
645633 struct virtio_blk *vblk = disk->private_data;
....@@ -649,12 +637,38 @@
649637 return snprintf(buf, 40, "%s\n", virtblk_cache_types[writeback]);
650638 }
651639
652
-static const struct device_attribute dev_attr_cache_type_ro =
653
- __ATTR(cache_type, 0444,
654
- virtblk_cache_type_show, NULL);
655
-static const struct device_attribute dev_attr_cache_type_rw =
656
- __ATTR(cache_type, 0644,
657
- virtblk_cache_type_show, virtblk_cache_type_store);
640
+static DEVICE_ATTR_RW(cache_type);
641
+
642
+static struct attribute *virtblk_attrs[] = {
643
+ &dev_attr_serial.attr,
644
+ &dev_attr_cache_type.attr,
645
+ NULL,
646
+};
647
+
648
+static umode_t virtblk_attrs_are_visible(struct kobject *kobj,
649
+ struct attribute *a, int n)
650
+{
651
+ struct device *dev = kobj_to_dev(kobj);
652
+ struct gendisk *disk = dev_to_disk(dev);
653
+ struct virtio_blk *vblk = disk->private_data;
654
+ struct virtio_device *vdev = vblk->vdev;
655
+
656
+ if (a == &dev_attr_cache_type.attr &&
657
+ !virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE))
658
+ return S_IRUGO;
659
+
660
+ return a->mode;
661
+}
662
+
663
+static const struct attribute_group virtblk_attr_group = {
664
+ .attrs = virtblk_attrs,
665
+ .is_visible = virtblk_attrs_are_visible,
666
+};
667
+
668
+static const struct attribute_group *virtblk_attr_groups[] = {
669
+ &virtblk_attr_group,
670
+ NULL,
671
+};
658672
659673 static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq,
660674 unsigned int hctx_idx, unsigned int numa_node)
....@@ -662,9 +676,6 @@
662676 struct virtio_blk *vblk = set->driver_data;
663677 struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
664678
665
-#ifdef CONFIG_VIRTIO_BLK_SCSI
666
- vbr->sreq.sense = vbr->sense;
667
-#endif
668679 sg_init_table(vbr->sg, vblk->sg_elems);
669680 return 0;
670681 }
....@@ -673,25 +684,15 @@
673684 {
674685 struct virtio_blk *vblk = set->driver_data;
675686
676
- return blk_mq_virtio_map_queues(set, vblk->vdev, 0);
687
+ return blk_mq_virtio_map_queues(&set->map[HCTX_TYPE_DEFAULT],
688
+ vblk->vdev, 0);
677689 }
678
-
679
-#ifdef CONFIG_VIRTIO_BLK_SCSI
680
-static void virtblk_initialize_rq(struct request *req)
681
-{
682
- struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
683
-
684
- scsi_req_init(&vbr->sreq);
685
-}
686
-#endif
687690
688691 static const struct blk_mq_ops virtio_mq_ops = {
689692 .queue_rq = virtio_queue_rq,
693
+ .commit_rqs = virtio_commit_rqs,
690694 .complete = virtblk_request_done,
691695 .init_request = virtblk_init_request,
692
-#ifdef CONFIG_VIRTIO_BLK_SCSI
693
- .initialize_rq_fn = virtblk_initialize_rq,
694
-#endif
695696 .map_queues = virtblk_map_queues,
696697 };
697698
....@@ -704,7 +705,7 @@
704705 struct request_queue *q;
705706 int err, index;
706707
707
- u32 v, blk_size, sg_elems, opt_io_size;
708
+ u32 v, blk_size, max_size, sg_elems, opt_io_size;
708709 u16 min_io_size;
709710 u8 physical_block_exp, alignment_offset;
710711
....@@ -811,22 +812,32 @@
811812 /* No real sector limit. */
812813 blk_queue_max_hw_sectors(q, -1U);
813814
815
+ max_size = virtio_max_dma_size(vdev);
816
+
814817 /* Host can optionally specify maximum segment size and number of
815818 * segments. */
816819 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SIZE_MAX,
817820 struct virtio_blk_config, size_max, &v);
818821 if (!err)
819
- blk_queue_max_segment_size(q, v);
820
- else
821
- blk_queue_max_segment_size(q, -1U);
822
+ max_size = min(max_size, v);
823
+
824
+ blk_queue_max_segment_size(q, max_size);
822825
823826 /* Host can optionally specify the block size of the device */
824827 err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE,
825828 struct virtio_blk_config, blk_size,
826829 &blk_size);
827
- if (!err)
830
+ if (!err) {
831
+ err = blk_validate_block_size(blk_size);
832
+ if (err) {
833
+ dev_err(&vdev->dev,
834
+ "virtio_blk: invalid block size: 0x%x\n",
835
+ blk_size);
836
+ goto out_cleanup_disk;
837
+ }
838
+
828839 blk_queue_logical_block_size(q, blk_size);
829
- else
840
+ } else
830841 blk_size = queue_logical_block_size(q);
831842
832843 /* Use topology information if available */
....@@ -855,26 +866,46 @@
855866 if (!err && opt_io_size)
856867 blk_queue_io_opt(q, blk_size * opt_io_size);
857868
869
+ if (virtio_has_feature(vdev, VIRTIO_BLK_F_DISCARD)) {
870
+ virtio_cread(vdev, struct virtio_blk_config,
871
+ discard_sector_alignment, &v);
872
+ if (v)
873
+ q->limits.discard_granularity = v << SECTOR_SHIFT;
874
+ else
875
+ q->limits.discard_granularity = blk_size;
876
+
877
+ virtio_cread(vdev, struct virtio_blk_config,
878
+ max_discard_sectors, &v);
879
+ blk_queue_max_discard_sectors(q, v ? v : UINT_MAX);
880
+
881
+ virtio_cread(vdev, struct virtio_blk_config, max_discard_seg,
882
+ &v);
883
+
884
+ /*
885
+ * max_discard_seg == 0 is out of spec but we always
886
+ * handled it.
887
+ */
888
+ if (!v)
889
+ v = sg_elems - 2;
890
+ blk_queue_max_discard_segments(q,
891
+ min(v, MAX_DISCARD_SEGMENTS));
892
+
893
+ blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
894
+ }
895
+
896
+ if (virtio_has_feature(vdev, VIRTIO_BLK_F_WRITE_ZEROES)) {
897
+ virtio_cread(vdev, struct virtio_blk_config,
898
+ max_write_zeroes_sectors, &v);
899
+ blk_queue_max_write_zeroes_sectors(q, v ? v : UINT_MAX);
900
+ }
901
+
858902 virtblk_update_capacity(vblk, false);
859903 virtio_device_ready(vdev);
860904
861
- device_add_disk(&vdev->dev, vblk->disk);
862
- err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial);
863
- if (err)
864
- goto out_del_disk;
865
-
866
- if (virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE))
867
- err = device_create_file(disk_to_dev(vblk->disk),
868
- &dev_attr_cache_type_rw);
869
- else
870
- err = device_create_file(disk_to_dev(vblk->disk),
871
- &dev_attr_cache_type_ro);
872
- if (err)
873
- goto out_del_disk;
905
+ device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);
874906 return 0;
875907
876
-out_del_disk:
877
- del_gendisk(vblk->disk);
908
+out_cleanup_disk:
878909 blk_cleanup_queue(vblk->disk->queue);
879910 out_free_tags:
880911 blk_mq_free_tag_set(&vblk->tag_set);
....@@ -963,18 +994,15 @@
963994 static unsigned int features_legacy[] = {
964995 VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
965996 VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
966
-#ifdef CONFIG_VIRTIO_BLK_SCSI
967
- VIRTIO_BLK_F_SCSI,
968
-#endif
969997 VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
970
- VIRTIO_BLK_F_MQ,
998
+ VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
971999 }
9721000 ;
9731001 static unsigned int features[] = {
9741002 VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
9751003 VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
9761004 VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
977
- VIRTIO_BLK_F_MQ,
1005
+ VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
9781006 };
9791007
9801008 static struct virtio_driver virtio_blk = {