diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go
index 62d61736..13d3b68c 100644
--- a/collector/diskstats_linux.go
+++ b/collector/diskstats_linux.go
@@ -16,23 +16,18 @@
 package collector
 
 import (
-	"bufio"
 	"fmt"
-	"io"
-	"os"
 	"regexp"
-	"strconv"
-	"strings"
 
 	"github.com/go-kit/log"
 	"github.com/go-kit/log/level"
 	"github.com/prometheus/client_golang/prometheus"
+	"github.com/prometheus/procfs/blockdevice"
 	"gopkg.in/alecthomas/kingpin.v2"
 )
 
 const (
-	diskSectorSize    = 512
-	diskstatsFilename = "diskstats"
+	secondsPerTick = 1.0 / 1000.0
 )
 
 var (
@@ -42,18 +37,16 @@ var (
 type typedFactorDesc struct {
 	desc      *prometheus.Desc
 	valueType prometheus.ValueType
-	factor    float64
 }
 
 func (d *typedFactorDesc) mustNewConstMetric(value float64, labels ...string) prometheus.Metric {
-	if d.factor != 0 {
-		value *= d.factor
-	}
 	return prometheus.MustNewConstMetric(d.desc, d.valueType, value, labels...)
 }
 
 type diskstatsCollector struct {
 	ignoredDevicesPattern *regexp.Regexp
+	fs                    blockdevice.FS
+	infoDesc              typedFactorDesc
 	descs                 []typedFactorDesc
 	logger                log.Logger
 }
@@ -66,9 +59,21 @@ func init() {
 // Docs from https://www.kernel.org/doc/Documentation/iostats.txt
 func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 	var diskLabelNames = []string{"device"}
+	fs, err := blockdevice.NewFS(*procPath, *sysPath)
+	if err != nil {
+		return nil, fmt.Errorf("failed to open sysfs: %w", err)
+	}
 
 	return &diskstatsCollector{
 		ignoredDevicesPattern: regexp.MustCompile(*ignoredDevices),
+		fs:                    fs,
+		infoDesc: typedFactorDesc{
+			desc: prometheus.NewDesc(prometheus.BuildFQName(namespace, diskSubsystem, "info"),
+				"Info of /sys/block/<block_device>.",
+				[]string{"device", "major", "minor"},
+				nil,
+			), valueType: prometheus.GaugeValue,
+		},
 		descs: []typedFactorDesc{
 			{
 				desc: readsCompletedDesc, valueType: prometheus.CounterValue,
@@ -83,11 +88,9 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 			},
 			{
 				desc: readBytesDesc, valueType: prometheus.CounterValue,
-				factor: diskSectorSize,
 			},
 			{
 				desc: readTimeSecondsDesc, valueType: prometheus.CounterValue,
-				factor: .001,
 			},
 			{
 				desc: writesCompletedDesc, valueType: prometheus.CounterValue,
@@ -102,11 +105,9 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 			},
 			{
 				desc: writtenBytesDesc, valueType: prometheus.CounterValue,
-				factor: diskSectorSize,
 			},
 			{
 				desc: writeTimeSecondsDesc, valueType: prometheus.CounterValue,
-				factor: .001,
 			},
 			{
 				desc: prometheus.NewDesc(
@@ -118,7 +119,6 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 			},
 			{
 				desc: ioTimeSecondsDesc, valueType: prometheus.CounterValue,
-				factor: .001,
 			},
 			{
 				desc: prometheus.NewDesc(
@@ -127,7 +127,6 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 					diskLabelNames,
 					nil,
 				), valueType: prometheus.CounterValue,
-				factor: .001,
 			},
 			{
 				desc: prometheus.NewDesc(
@@ -160,7 +159,6 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 					diskLabelNames,
 					nil,
 				), valueType: prometheus.CounterValue,
-				factor: .001,
 			},
 			{
 				desc: prometheus.NewDesc(
@@ -177,7 +175,6 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 					diskLabelNames,
 					nil,
 				), valueType: prometheus.CounterValue,
-				factor: .001,
 			},
 		},
 		logger: logger,
@@ -185,56 +182,54 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
 }
 
 func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
-	diskStats, err := getDiskStats()
+	diskStats, err := c.fs.ProcDiskstats()
 	if err != nil {
 		return fmt.Errorf("couldn't get diskstats: %w", err)
 	}
 
-	for dev, stats := range diskStats {
+	for _, stats := range diskStats {
+		dev := stats.DeviceName
 		if c.ignoredDevicesPattern.MatchString(dev) {
-			level.Debug(c.logger).Log("msg", "Ignoring device", "device", dev)
+			level.Debug(c.logger).Log("msg", "Ignoring device", "device", dev, "pattern", c.ignoredDevicesPattern)
 			continue
 		}
 
-		for i, value := range stats {
-			// ignore unrecognized additional stats
-			if i >= len(c.descs) {
+		diskSectorSize := 512.0
+		blockQueue, err := c.fs.SysBlockDeviceQueueStats(dev)
+		if err != nil {
+			level.Debug(c.logger).Log("msg", "Error getting queue stats", "device", dev, "err", err)
+		} else {
+			diskSectorSize = float64(blockQueue.LogicalBlockSize)
+		}
+
+		ch <- c.infoDesc.mustNewConstMetric(1.0, dev, fmt.Sprint(stats.MajorNumber), fmt.Sprint(stats.MinorNumber))
+
+		statCount := stats.IoStatsCount - 3 // Total diskstats record count, less MajorNumber, MinorNumber and DeviceName
+
+		for i, val := range []float64{
+			float64(stats.ReadIOs),
+			float64(stats.ReadMerges),
+			float64(stats.ReadSectors) * diskSectorSize,
+			float64(stats.ReadTicks) * secondsPerTick,
+			float64(stats.WriteIOs),
+			float64(stats.WriteMerges),
+			float64(stats.WriteSectors) * diskSectorSize,
+			float64(stats.WriteTicks) * secondsPerTick,
+			float64(stats.IOsInProgress),
+			float64(stats.IOsTotalTicks) * secondsPerTick,
+			float64(stats.WeightedIOTicks) * secondsPerTick,
+			float64(stats.DiscardIOs),
+			float64(stats.DiscardMerges),
+			float64(stats.DiscardSectors),
+			float64(stats.DiscardTicks) * secondsPerTick,
+			float64(stats.FlushRequestsCompleted),
+			float64(stats.TimeSpentFlushing) * secondsPerTick,
+		} {
+			if i >= statCount {
 				break
 			}
-			v, err := strconv.ParseFloat(value, 64)
-			if err != nil {
-				return fmt.Errorf("invalid value %s in diskstats: %w", value, err)
-			}
-			ch <- c.descs[i].mustNewConstMetric(v, dev)
+			ch <- c.descs[i].mustNewConstMetric(val, dev)
 		}
 	}
 	return nil
 }
-
-func getDiskStats() (map[string][]string, error) {
-	file, err := os.Open(procFilePath(diskstatsFilename))
-	if err != nil {
-		return nil, err
-	}
-	defer file.Close()
-
-	return parseDiskStats(file)
-}
-
-func parseDiskStats(r io.Reader) (map[string][]string, error) {
-	var (
-		diskStats = map[string][]string{}
-		scanner   = bufio.NewScanner(r)
-	)
-
-	for scanner.Scan() {
-		parts := strings.Fields(scanner.Text())
-		if len(parts) < 4 { // we strip major, minor and dev
-			return nil, fmt.Errorf("invalid line in %s: %s", procFilePath(diskstatsFilename), scanner.Text())
-		}
-		dev := parts[2]
-		diskStats[dev] = parts[3:]
-	}
-
-	return diskStats, scanner.Err()
-}
diff --git a/collector/diskstats_linux_test.go b/collector/diskstats_linux_test.go
index 9bfecc58..0e8dc84f 100644
--- a/collector/diskstats_linux_test.go
+++ b/collector/diskstats_linux_test.go
@@ -14,39 +14,293 @@
 package collector
 
 import (
+	"fmt"
 	"os"
+	"strings"
 	"testing"
+
+	"github.com/go-kit/log"
+	"github.com/prometheus/client_golang/prometheus"
+	"github.com/prometheus/client_golang/prometheus/testutil"
 )
 
+type testDiskStatsCollector struct {
+	dsc Collector
+}
+
+func (c testDiskStatsCollector) Collect(ch chan<- prometheus.Metric) {
+	c.dsc.Update(ch)
+}
+
+func (c testDiskStatsCollector) Describe(ch chan<- *prometheus.Desc) {
+	prometheus.DescribeByCollect(c, ch)
+}
+
+func NewTestDiskStatsCollector(logger log.Logger) (prometheus.Collector, error) {
+	dsc, err := NewDiskstatsCollector(logger)
+	if err != nil {
+		return testDiskStatsCollector{}, err
+	}
+	return testDiskStatsCollector{
+		dsc: dsc,
+	}, err
+}
+
 func TestDiskStats(t *testing.T) {
-	file, err := os.Open("fixtures/proc/diskstats")
+	*sysPath = "fixtures/sys"
+	*procPath = "fixtures/proc"
+	*ignoredDevices = "^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"
+	testcase := `# HELP node_disk_discard_time_seconds_total This is the total number of seconds spent by all discards.
+# TYPE node_disk_discard_time_seconds_total counter
+node_disk_discard_time_seconds_total{device="sdb"} 11.13
+node_disk_discard_time_seconds_total{device="sdc"} 11.13
+# HELP node_disk_discarded_sectors_total The total number of sectors discarded successfully.
+# TYPE node_disk_discarded_sectors_total counter
+node_disk_discarded_sectors_total{device="sdb"} 1.925173784e+09
+node_disk_discarded_sectors_total{device="sdc"} 1.25173784e+08
+# HELP node_disk_discards_completed_total The total number of discards completed successfully.
+# TYPE node_disk_discards_completed_total counter
+node_disk_discards_completed_total{device="sdb"} 68851
+node_disk_discards_completed_total{device="sdc"} 18851
+# HELP node_disk_discards_merged_total The total number of discards merged.
+# TYPE node_disk_discards_merged_total counter
+node_disk_discards_merged_total{device="sdb"} 0
+node_disk_discards_merged_total{device="sdc"} 0
+# HELP node_disk_flush_requests_time_seconds_total This is the total number of seconds spent by all flush requests.
+# TYPE node_disk_flush_requests_time_seconds_total counter
+node_disk_flush_requests_time_seconds_total{device="sdc"} 1.944
+# HELP node_disk_flush_requests_total The total number of flush requests completed successfully
+# TYPE node_disk_flush_requests_total counter
+node_disk_flush_requests_total{device="sdc"} 1555
+# HELP node_disk_info Info of /sys/block/<block_device>.
+# TYPE node_disk_info gauge
+node_disk_info{device="dm-0",major="252",minor="0"} 1
+node_disk_info{device="dm-1",major="252",minor="1"} 1
+node_disk_info{device="dm-2",major="252",minor="2"} 1
+node_disk_info{device="dm-3",major="252",minor="3"} 1
+node_disk_info{device="dm-4",major="252",minor="4"} 1
+node_disk_info{device="dm-5",major="252",minor="5"} 1
+node_disk_info{device="mmcblk0",major="179",minor="0"} 1
+node_disk_info{device="mmcblk0p1",major="179",minor="1"} 1
+node_disk_info{device="mmcblk0p2",major="179",minor="2"} 1
+node_disk_info{device="nvme0n1",major="259",minor="0"} 1
+node_disk_info{device="sda",major="8",minor="0"} 1
+node_disk_info{device="sdb",major="8",minor="0"} 1
+node_disk_info{device="sdc",major="8",minor="0"} 1
+node_disk_info{device="sr0",major="11",minor="0"} 1
+node_disk_info{device="vda",major="254",minor="0"} 1
+# HELP node_disk_io_now The number of I/Os currently in progress.
+# TYPE node_disk_io_now gauge
+node_disk_io_now{device="dm-0"} 0
+node_disk_io_now{device="dm-1"} 0
+node_disk_io_now{device="dm-2"} 0
+node_disk_io_now{device="dm-3"} 0
+node_disk_io_now{device="dm-4"} 0
+node_disk_io_now{device="dm-5"} 0
+node_disk_io_now{device="mmcblk0"} 0
+node_disk_io_now{device="mmcblk0p1"} 0
+node_disk_io_now{device="mmcblk0p2"} 0
+node_disk_io_now{device="nvme0n1"} 0
+node_disk_io_now{device="sda"} 0
+node_disk_io_now{device="sdb"} 0
+node_disk_io_now{device="sdc"} 0
+node_disk_io_now{device="sr0"} 0
+node_disk_io_now{device="vda"} 0
+# HELP node_disk_io_time_seconds_total Total seconds spent doing I/Os.
+# TYPE node_disk_io_time_seconds_total counter
+node_disk_io_time_seconds_total{device="dm-0"} 11325.968
+node_disk_io_time_seconds_total{device="dm-1"} 0.076
+node_disk_io_time_seconds_total{device="dm-2"} 65.4
+node_disk_io_time_seconds_total{device="dm-3"} 0.016
+node_disk_io_time_seconds_total{device="dm-4"} 0.024
+node_disk_io_time_seconds_total{device="dm-5"} 58.848
+node_disk_io_time_seconds_total{device="mmcblk0"} 0.136
+node_disk_io_time_seconds_total{device="mmcblk0p1"} 0.024
+node_disk_io_time_seconds_total{device="mmcblk0p2"} 0.068
+node_disk_io_time_seconds_total{device="nvme0n1"} 222.766
+node_disk_io_time_seconds_total{device="sda"} 9653.880000000001
+node_disk_io_time_seconds_total{device="sdb"} 60.730000000000004
+node_disk_io_time_seconds_total{device="sdc"} 10.73
+node_disk_io_time_seconds_total{device="sr0"} 0
+node_disk_io_time_seconds_total{device="vda"} 41614.592000000004
+# HELP node_disk_io_time_weighted_seconds_total The weighted # of seconds spent doing I/Os.
+# TYPE node_disk_io_time_weighted_seconds_total counter
+node_disk_io_time_weighted_seconds_total{device="dm-0"} 1.206301256e+06
+node_disk_io_time_weighted_seconds_total{device="dm-1"} 0.084
+node_disk_io_time_weighted_seconds_total{device="dm-2"} 129.416
+node_disk_io_time_weighted_seconds_total{device="dm-3"} 0.10400000000000001
+node_disk_io_time_weighted_seconds_total{device="dm-4"} 0.044
+node_disk_io_time_weighted_seconds_total{device="dm-5"} 105.632
+node_disk_io_time_weighted_seconds_total{device="mmcblk0"} 0.156
+node_disk_io_time_weighted_seconds_total{device="mmcblk0p1"} 0.024
+node_disk_io_time_weighted_seconds_total{device="mmcblk0p2"} 0.068
+node_disk_io_time_weighted_seconds_total{device="nvme0n1"} 1032.546
+node_disk_io_time_weighted_seconds_total{device="sda"} 82621.804
+node_disk_io_time_weighted_seconds_total{device="sdb"} 67.07000000000001
+node_disk_io_time_weighted_seconds_total{device="sdc"} 17.07
+node_disk_io_time_weighted_seconds_total{device="sr0"} 0
+node_disk_io_time_weighted_seconds_total{device="vda"} 2.0778722280000001e+06
+# HELP node_disk_read_bytes_total The total number of bytes read successfully.
+# TYPE node_disk_read_bytes_total counter
+node_disk_read_bytes_total{device="dm-0"} 5.13708655616e+11
+node_disk_read_bytes_total{device="dm-1"} 1.589248e+06
+node_disk_read_bytes_total{device="dm-2"} 1.578752e+08
+node_disk_read_bytes_total{device="dm-3"} 1.98144e+06
+node_disk_read_bytes_total{device="dm-4"} 529408
+node_disk_read_bytes_total{device="dm-5"} 4.3150848e+07
+node_disk_read_bytes_total{device="mmcblk0"} 798720
+node_disk_read_bytes_total{device="mmcblk0p1"} 81920
+node_disk_read_bytes_total{device="mmcblk0p2"} 389120
+node_disk_read_bytes_total{device="nvme0n1"} 2.377714176e+09
+node_disk_read_bytes_total{device="sda"} 5.13713216512e+11
+node_disk_read_bytes_total{device="sdb"} 4.944782848e+09
+node_disk_read_bytes_total{device="sdc"} 8.48782848e+08
+node_disk_read_bytes_total{device="sr0"} 0
+node_disk_read_bytes_total{device="vda"} 1.6727491584e+10
+# HELP node_disk_read_time_seconds_total The total number of seconds spent by all reads.
+# TYPE node_disk_read_time_seconds_total counter
+node_disk_read_time_seconds_total{device="dm-0"} 46229.572
+node_disk_read_time_seconds_total{device="dm-1"} 0.084
+node_disk_read_time_seconds_total{device="dm-2"} 6.5360000000000005
+node_disk_read_time_seconds_total{device="dm-3"} 0.10400000000000001
+node_disk_read_time_seconds_total{device="dm-4"} 0.028
+node_disk_read_time_seconds_total{device="dm-5"} 0.924
+node_disk_read_time_seconds_total{device="mmcblk0"} 0.156
+node_disk_read_time_seconds_total{device="mmcblk0p1"} 0.024
+node_disk_read_time_seconds_total{device="mmcblk0p2"} 0.068
+node_disk_read_time_seconds_total{device="nvme0n1"} 21.650000000000002
+node_disk_read_time_seconds_total{device="sda"} 18492.372
+node_disk_read_time_seconds_total{device="sdb"} 0.084
+node_disk_read_time_seconds_total{device="sdc"} 0.014
+node_disk_read_time_seconds_total{device="sr0"} 0
+node_disk_read_time_seconds_total{device="vda"} 8655.768
+# HELP node_disk_reads_completed_total The total number of reads completed successfully.
+# TYPE node_disk_reads_completed_total counter
+node_disk_reads_completed_total{device="dm-0"} 5.9910002e+07
+node_disk_reads_completed_total{device="dm-1"} 388
+node_disk_reads_completed_total{device="dm-2"} 11571
+node_disk_reads_completed_total{device="dm-3"} 3870
+node_disk_reads_completed_total{device="dm-4"} 392
+node_disk_reads_completed_total{device="dm-5"} 3729
+node_disk_reads_completed_total{device="mmcblk0"} 192
+node_disk_reads_completed_total{device="mmcblk0p1"} 17
+node_disk_reads_completed_total{device="mmcblk0p2"} 95
+node_disk_reads_completed_total{device="nvme0n1"} 47114
+node_disk_reads_completed_total{device="sda"} 2.5354637e+07
+node_disk_reads_completed_total{device="sdb"} 326552
+node_disk_reads_completed_total{device="sdc"} 126552
+node_disk_reads_completed_total{device="sr0"} 0
+node_disk_reads_completed_total{device="vda"} 1.775784e+06
+# HELP node_disk_reads_merged_total The total number of reads merged.
+# TYPE node_disk_reads_merged_total counter
+node_disk_reads_merged_total{device="dm-0"} 0
+node_disk_reads_merged_total{device="dm-1"} 0
+node_disk_reads_merged_total{device="dm-2"} 0
+node_disk_reads_merged_total{device="dm-3"} 0
+node_disk_reads_merged_total{device="dm-4"} 0
+node_disk_reads_merged_total{device="dm-5"} 0
+node_disk_reads_merged_total{device="mmcblk0"} 3
+node_disk_reads_merged_total{device="mmcblk0p1"} 3
+node_disk_reads_merged_total{device="mmcblk0p2"} 0
+node_disk_reads_merged_total{device="nvme0n1"} 4
+node_disk_reads_merged_total{device="sda"} 3.4367663e+07
+node_disk_reads_merged_total{device="sdb"} 841
+node_disk_reads_merged_total{device="sdc"} 141
+node_disk_reads_merged_total{device="sr0"} 0
+node_disk_reads_merged_total{device="vda"} 15386
+# HELP node_disk_write_time_seconds_total This is the total number of seconds spent by all writes.
+# TYPE node_disk_write_time_seconds_total counter
+node_disk_write_time_seconds_total{device="dm-0"} 1.1585578e+06
+node_disk_write_time_seconds_total{device="dm-1"} 0
+node_disk_write_time_seconds_total{device="dm-2"} 122.884
+node_disk_write_time_seconds_total{device="dm-3"} 0
+node_disk_write_time_seconds_total{device="dm-4"} 0.016
+node_disk_write_time_seconds_total{device="dm-5"} 104.684
+node_disk_write_time_seconds_total{device="mmcblk0"} 0
+node_disk_write_time_seconds_total{device="mmcblk0p1"} 0
+node_disk_write_time_seconds_total{device="mmcblk0p2"} 0
+node_disk_write_time_seconds_total{device="nvme0n1"} 1011.053
+node_disk_write_time_seconds_total{device="sda"} 63877.96
+node_disk_write_time_seconds_total{device="sdb"} 5.007
+node_disk_write_time_seconds_total{device="sdc"} 1.0070000000000001
+node_disk_write_time_seconds_total{device="sr0"} 0
+node_disk_write_time_seconds_total{device="vda"} 2.069221364e+06
+# HELP node_disk_writes_completed_total The total number of writes completed successfully.
+# TYPE node_disk_writes_completed_total counter
+node_disk_writes_completed_total{device="dm-0"} 3.9231014e+07
+node_disk_writes_completed_total{device="dm-1"} 74
+node_disk_writes_completed_total{device="dm-2"} 153522
+node_disk_writes_completed_total{device="dm-3"} 0
+node_disk_writes_completed_total{device="dm-4"} 38
+node_disk_writes_completed_total{device="dm-5"} 98918
+node_disk_writes_completed_total{device="mmcblk0"} 0
+node_disk_writes_completed_total{device="mmcblk0p1"} 0
+node_disk_writes_completed_total{device="mmcblk0p2"} 0
+node_disk_writes_completed_total{device="nvme0n1"} 1.07832e+06
+node_disk_writes_completed_total{device="sda"} 2.8444756e+07
+node_disk_writes_completed_total{device="sdb"} 41822
+node_disk_writes_completed_total{device="sdc"} 11822
+node_disk_writes_completed_total{device="sr0"} 0
+node_disk_writes_completed_total{device="vda"} 6.038856e+06
+# HELP node_disk_writes_merged_total The number of writes merged.
+# TYPE node_disk_writes_merged_total counter
+node_disk_writes_merged_total{device="dm-0"} 0
+node_disk_writes_merged_total{device="dm-1"} 0
+node_disk_writes_merged_total{device="dm-2"} 0
+node_disk_writes_merged_total{device="dm-3"} 0
+node_disk_writes_merged_total{device="dm-4"} 0
+node_disk_writes_merged_total{device="dm-5"} 0
+node_disk_writes_merged_total{device="mmcblk0"} 0
+node_disk_writes_merged_total{device="mmcblk0p1"} 0
+node_disk_writes_merged_total{device="mmcblk0p2"} 0
+node_disk_writes_merged_total{device="nvme0n1"} 43950
+node_disk_writes_merged_total{device="sda"} 1.1134226e+07
+node_disk_writes_merged_total{device="sdb"} 2895
+node_disk_writes_merged_total{device="sdc"} 1895
+node_disk_writes_merged_total{device="sr0"} 0
+node_disk_writes_merged_total{device="vda"} 2.0711856e+07
+# HELP node_disk_written_bytes_total The total number of bytes written successfully.
+# TYPE node_disk_written_bytes_total counter
+node_disk_written_bytes_total{device="dm-0"} 2.5891680256e+11
+node_disk_written_bytes_total{device="dm-1"} 303104
+node_disk_written_bytes_total{device="dm-2"} 2.607828992e+09
+node_disk_written_bytes_total{device="dm-3"} 0
+node_disk_written_bytes_total{device="dm-4"} 70144
+node_disk_written_bytes_total{device="dm-5"} 5.89664256e+08
+node_disk_written_bytes_total{device="mmcblk0"} 0
+node_disk_written_bytes_total{device="mmcblk0p1"} 0
+node_disk_written_bytes_total{device="mmcblk0p2"} 0
+node_disk_written_bytes_total{device="nvme0n1"} 2.0199236096e+10
+node_disk_written_bytes_total{device="sda"} 2.58916880384e+11
+node_disk_written_bytes_total{device="sdb"} 1.01012736e+09
+node_disk_written_bytes_total{device="sdc"} 8.852736e+07
+node_disk_written_bytes_total{device="sr0"} 0
+node_disk_written_bytes_total{device="vda"} 1.0938236928e+11
+`
+
+	logger := log.NewLogfmtLogger(os.Stderr)
+	collector, err := NewDiskstatsCollector(logger)
+	if err != nil {
+		panic(err)
+	}
+	c, err := NewTestDiskStatsCollector(logger)
 	if err != nil {
 		t.Fatal(err)
 	}
-	defer file.Close()
+	reg := prometheus.NewRegistry()
+	reg.MustRegister(c)
 
-	diskStats, err := parseDiskStats(file)
+	sink := make(chan prometheus.Metric)
+	go func() {
+		err = collector.Update(sink)
+		if err != nil {
+			panic(fmt.Errorf("failed to update collector: %s", err))
+		}
+		close(sink)
+	}()
+
+	err = testutil.GatherAndCompare(reg, strings.NewReader(testcase))
 	if err != nil {
 		t.Fatal(err)
 	}
-
-	if want, got := "25353629", diskStats["sda4"][0]; want != got {
-		t.Errorf("want diskstats sda4 %s, got %s", want, got)
-	}
-
-	if want, got := "68", diskStats["mmcblk0p2"][10]; want != got {
-		t.Errorf("want diskstats mmcblk0p2 %s, got %s", want, got)
-	}
-
-	if want, got := "11130", diskStats["sdb"][14]; want != got {
-		t.Errorf("want diskstats sdb %s, got %s", want, got)
-	}
-
-	if want, got := "1555", diskStats["sdc"][15]; want != got {
-		t.Errorf("want diskstats sdc %s, got %s", want, got)
-	}
-
-	if want, got := "1944", diskStats["sdc"][16]; want != got {
-		t.Errorf("want diskstats sdc %s, got %s", want, got)
-	}
 }
diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt
index f892b839..50f32466 100644
--- a/collector/fixtures/e2e-output.txt
+++ b/collector/fixtures/e2e-output.txt
@@ -403,6 +403,23 @@ node_disk_flush_requests_time_seconds_total{device="sdc"} 1.944
 # HELP node_disk_flush_requests_total The total number of flush requests completed successfully
 # TYPE node_disk_flush_requests_total counter
 node_disk_flush_requests_total{device="sdc"} 1555
+# HELP node_disk_info Info of /sys/block/<block_device>.
+# TYPE node_disk_info gauge
+node_disk_info{device="dm-0",major="252",minor="0"} 1
+node_disk_info{device="dm-1",major="252",minor="1"} 1
+node_disk_info{device="dm-2",major="252",minor="2"} 1
+node_disk_info{device="dm-3",major="252",minor="3"} 1
+node_disk_info{device="dm-4",major="252",minor="4"} 1
+node_disk_info{device="dm-5",major="252",minor="5"} 1
+node_disk_info{device="mmcblk0",major="179",minor="0"} 1
+node_disk_info{device="mmcblk0p1",major="179",minor="1"} 1
+node_disk_info{device="mmcblk0p2",major="179",minor="2"} 1
+node_disk_info{device="nvme0n1",major="259",minor="0"} 1
+node_disk_info{device="sda",major="8",minor="0"} 1
+node_disk_info{device="sdb",major="8",minor="0"} 1
+node_disk_info{device="sdc",major="8",minor="0"} 1
+node_disk_info{device="sr0",major="11",minor="0"} 1
+node_disk_info{device="vda",major="254",minor="0"} 1
 # HELP node_disk_io_now The number of I/Os currently in progress.
 # TYPE node_disk_io_now gauge
 node_disk_io_now{device="dm-0"} 0