Page MenuHomeFreeBSD

D21708.id62278.diff
No OneTemporary

D21708.id62278.diff

Index: sys/dev/virtio/block/virtio_blk.h
===================================================================
--- sys/dev/virtio/block/virtio_blk.h
+++ sys/dev/virtio/block/virtio_blk.h
@@ -34,16 +34,20 @@
#define _VIRTIO_BLK_H
/* Feature bits */
-#define VIRTIO_BLK_F_BARRIER 0x0001 /* Does host support barriers? */
-#define VIRTIO_BLK_F_SIZE_MAX 0x0002 /* Indicates maximum segment size */
-#define VIRTIO_BLK_F_SEG_MAX 0x0004 /* Indicates maximum # of segments */
-#define VIRTIO_BLK_F_GEOMETRY 0x0010 /* Legacy geometry available */
-#define VIRTIO_BLK_F_RO 0x0020 /* Disk is read-only */
-#define VIRTIO_BLK_F_BLK_SIZE 0x0040 /* Block size of disk is available*/
-#define VIRTIO_BLK_F_SCSI 0x0080 /* Supports scsi command passthru */
-#define VIRTIO_BLK_F_WCE 0x0200 /* Writeback mode enabled after reset */
-#define VIRTIO_BLK_F_TOPOLOGY 0x0400 /* Topology information is available */
-#define VIRTIO_BLK_F_CONFIG_WCE 0x0800 /* Writeback mode available in config */
+#define VIRTIO_BLK_F_BARRIER (1 << 0) /* Does host support barriers? */
+#define VIRTIO_BLK_F_SIZE_MAX (1 << 1) /* Indicates maximum segment size */
+#define VIRTIO_BLK_F_SEG_MAX (1 << 2) /* Indicates maximum # of segments */
+#define VIRTIO_BLK_F_GEOMETRY (1 << 4) /* Legacy geometry available */
+#define VIRTIO_BLK_F_RO (1 << 5) /* Disk is read-only */
+#define VIRTIO_BLK_F_BLK_SIZE (1 << 6) /* Block size of disk is available*/
+#define VIRTIO_BLK_F_SCSI (1 << 7) /* Supports scsi command passthru */
+#define VIRTIO_BLK_F_FLUSH (1 << 9) /* Writeback mode enabled after reset */
+#define VIRTIO_BLK_F_WCE (1 << 9) /* Legacy alias for FLUSH */
+#define VIRTIO_BLK_F_TOPOLOGY (1 << 10) /* Topology information is available */
+#define VIRTIO_BLK_F_CONFIG_WCE (1 << 11) /* Writeback mode available in config */
+#define VIRTIO_BLK_F_MQ (1 << 12) /* Multi-Queue */
+#define VIRTIO_BLK_F_DISCARD (1 << 13) /* Trim blocks */
+#define VIRTIO_BLK_F_WRITE_ZEROES (1 << 14) /* Write zeros */
#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
@@ -74,7 +78,15 @@
/* Writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
uint8_t writeback;
-
+ uint8_t unused0[1];
+ uint16_t num_queues;
+ uint32_t max_discard_sectors;
+ uint32_t max_discard_seg;
+ uint32_t discard_sector_alignment;
+ uint32_t max_write_zeroes_sectors;
+ uint32_t max_write_zeroes_seg;
+ uint8_t write_zeroes_may_unmap;
+ uint8_t unused1[3];
} __packed;
/*
@@ -89,23 +101,34 @@
*/
/* These two define direction. */
-#define VIRTIO_BLK_T_IN 0
-#define VIRTIO_BLK_T_OUT 1
+#define VIRTIO_BLK_T_IN 0
+#define VIRTIO_BLK_T_OUT 1
/* This bit says it's a scsi command, not an actual read or write. */
-#define VIRTIO_BLK_T_SCSI_CMD 2
+#define VIRTIO_BLK_T_SCSI_CMD 2
+#define VIRTIO_BLK_T_SCSI_CMD_OUT 3
/* Cache flush command */
-#define VIRTIO_BLK_T_FLUSH 4
+#define VIRTIO_BLK_T_FLUSH 4
+#define VIRTIO_BLK_T_FLUSH_OUT 5
/* Get device ID command */
-#define VIRTIO_BLK_T_GET_ID 8
+#define VIRTIO_BLK_T_GET_ID 8
+
+/* Discard command */
+#define VIRTIO_BLK_T_DISCARD 11
+
+/* Write zeros command */
+#define VIRTIO_BLK_T_WRITE_ZEROES 13
/* Barrier before this op. */
-#define VIRTIO_BLK_T_BARRIER 0x80000000
+#define VIRTIO_BLK_T_BARRIER 0x80000000
/* ID string length */
-#define VIRTIO_BLK_ID_BYTES 20
+#define VIRTIO_BLK_ID_BYTES 20
+
+/* Unmap this range (only valid for write zeroes command) */
+#define VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP 0x00000001
/* This is the first element of the read scatter-gather list. */
struct virtio_blk_outhdr {
@@ -117,6 +140,15 @@
uint64_t sector;
};
+struct virtio_blk_discard_write_zeroes {
+ uint64_t sector;
+ uint32_t num_sectors;
+ struct {
+ uint32_t unmap:1;
+ uint32_t reserved:31;
+ } flags;
+};
+
struct virtio_scsi_inhdr {
uint32_t errors;
uint32_t data_len;
Index: sys/dev/virtio/block/virtio_blk.c
===================================================================
--- sys/dev/virtio/block/virtio_blk.c
+++ sys/dev/virtio/block/virtio_blk.c
@@ -81,6 +81,7 @@
#define VTBLK_FLAG_SUSPEND 0x0008
#define VTBLK_FLAG_BARRIER 0x0010
#define VTBLK_FLAG_WC_CONFIG 0x0020
+#define VTBLK_FLAG_DISCARD 0x0040
struct virtqueue *vtblk_vq;
struct sglist *vtblk_sglist;
@@ -112,6 +113,7 @@
{ VIRTIO_BLK_F_WCE, "WriteCache" },
{ VIRTIO_BLK_F_TOPOLOGY, "Topology" },
{ VIRTIO_BLK_F_CONFIG_WCE, "ConfigWCE" },
+ { VIRTIO_BLK_F_DISCARD, "Discard" },
{ 0, NULL }
};
@@ -210,6 +212,7 @@
VIRTIO_BLK_F_WCE | \
VIRTIO_BLK_F_TOPOLOGY | \
VIRTIO_BLK_F_CONFIG_WCE | \
+ VIRTIO_BLK_F_DISCARD | \
VIRTIO_RING_F_INDIRECT_DESC)
#define VTBLK_MTX(_sc) &(_sc)->vtblk_mtx
@@ -544,7 +547,8 @@
* be a better way to report our readonly'ness to GEOM above.
*/
if (sc->vtblk_flags & VTBLK_FLAG_READONLY &&
- (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_FLUSH)) {
+ (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_FLUSH ||
+ bp->bio_cmd == BIO_DELETE)) {
vtblk_bio_done(sc, bp, EROFS);
return;
}
@@ -592,6 +596,8 @@
sc->vtblk_flags |= VTBLK_FLAG_BARRIER;
if (virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE))
sc->vtblk_flags |= VTBLK_FLAG_WC_CONFIG;
+ if (virtio_with_feature(dev, VIRTIO_BLK_F_DISCARD))
+ sc->vtblk_flags |= VTBLK_FLAG_DISCARD;
}
static int
@@ -720,6 +726,12 @@
dp->d_stripesize;
}
+ if (virtio_with_feature(dev, VIRTIO_BLK_F_DISCARD)) {
+ dp->d_flags |= DISKFLAG_CANDELETE;
+ dp->d_delmaxsize = blkcfg->max_discard_sectors *
+ dp->d_sectorsize;
+ }
+
if (vtblk_write_cache_enabled(sc, blkcfg) != 0)
sc->vtblk_write_cache = VTBLK_CACHE_WRITEBACK;
else
@@ -876,6 +888,9 @@
req->vbr_hdr.type = VIRTIO_BLK_T_OUT;
req->vbr_hdr.sector = bp->bio_offset / 512;
break;
+ case BIO_DELETE:
+ req->vbr_hdr.type = VIRTIO_BLK_T_DISCARD;
+ break;
default:
panic("%s: bio with unhandled cmd: %d", __func__, bp->bio_cmd);
}
@@ -929,6 +944,16 @@
/* BIO_READ means the host writes into our buffer. */
if (bp->bio_cmd == BIO_READ)
writable = sg->sg_nseg - 1;
+ } else if (bp->bio_cmd == BIO_DELETE) {
+ struct virtio_blk_discard_write_zeroes discard;
+
+ discard.sector = bp->bio_offset / 512;
+ discard.num_sectors = bp->bio_bcount / 512;
+ error = sglist_append(sg, &discard, sizeof(discard));
+ if (error || sg->sg_nseg == sg->sg_maxseg) {
+ panic("%s: bio %p data buffer too big %d",
+ __func__, bp, error);
+ }
}
writable++;
@@ -1119,6 +1144,11 @@
VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_BLK_SIZE, blk_size, blkcfg);
VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_TOPOLOGY, topology, blkcfg);
VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_CONFIG_WCE, writeback, blkcfg);
+ VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_DISCARD, max_discard_sectors,
+ blkcfg);
+ VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_DISCARD, max_discard_seg, blkcfg);
+ VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_DISCARD, discard_sector_alignment,
+ blkcfg);
}
#undef VTBLK_GET_CONFIG

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 1, 3:39 AM (16 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16897193
Default Alt Text
D21708.id62278.diff (6 KB)

Event Timeline