diff --git a/collectors/all.h b/collectors/all.h
index 9443ec6b21..d115fdc73c 100644
--- a/collectors/all.h
+++ b/collectors/all.h
@@ -103,16 +103,16 @@
 // Disks
 
 #define NETDATA_CHART_PRIO_DISK_IO                    2000
-#define NETDATA_CHART_PRIO_DISK_OPS                   2001
-#define NETDATA_CHART_PRIO_DISK_QOPS                  2002
-#define NETDATA_CHART_PRIO_DISK_BACKLOG               2003
-#define NETDATA_CHART_PRIO_DISK_BUSY                  2004
-#define NETDATA_CHART_PRIO_DISK_UTIL                  2005
-#define NETDATA_CHART_PRIO_DISK_AWAIT                 2006
-#define NETDATA_CHART_PRIO_DISK_AVGSZ                 2007
-#define NETDATA_CHART_PRIO_DISK_SVCTM                 2008
-#define NETDATA_CHART_PRIO_DISK_MOPS                  2021
-#define NETDATA_CHART_PRIO_DISK_IOTIME                2022
+#define NETDATA_CHART_PRIO_DISK_OPS                   2010
+#define NETDATA_CHART_PRIO_DISK_QOPS                  2015
+#define NETDATA_CHART_PRIO_DISK_BACKLOG               2020
+#define NETDATA_CHART_PRIO_DISK_BUSY                  2030
+#define NETDATA_CHART_PRIO_DISK_UTIL                  2040
+#define NETDATA_CHART_PRIO_DISK_AWAIT                 2050
+#define NETDATA_CHART_PRIO_DISK_AVGSZ                 2060
+#define NETDATA_CHART_PRIO_DISK_SVCTM                 2070
+#define NETDATA_CHART_PRIO_DISK_MOPS                  2080
+#define NETDATA_CHART_PRIO_DISK_IOTIME                2090
 #define NETDATA_CHART_PRIO_BCACHE_CACHE_ALLOC         2120
 #define NETDATA_CHART_PRIO_BCACHE_HIT_RATIO           2120
 #define NETDATA_CHART_PRIO_BCACHE_RATES               2121
diff --git a/collectors/proc.plugin/README.md b/collectors/proc.plugin/README.md
index 065f9a0380..c2d26368ad 100644
--- a/collectors/proc.plugin/README.md
+++ b/collectors/proc.plugin/README.md
@@ -46,8 +46,11 @@ Hopefully, the Linux kernel provides many metrics that can provide deep insights
 
 -   **I/O bandwidth/s (kb/s)**
     The amount of data transferred from and to the disk.
+-   **Amount of discarded data (kb/s)**
 -   **I/O operations/s**
     The number of I/O operations completed.
+-   **Extended I/O operations/s**
+    The number of extended I/O operations completed.
 -   **Queued I/O operations**
     The number of currently queued I/O operations. For traditional disks that execute commands one after another, one of them is being run by the disk and the rest are just waiting in a queue.
 -   **Backlog size (time in ms)**
@@ -57,12 +60,19 @@ Hopefully, the Linux kernel provides many metrics that can provide deep insights
     Of course, for newer disk technologies (like fusion cards) that are capable to execute multiple commands in parallel, this metric is just meaningless.
 -   **Average I/O operation time (ms)**
     The average time for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.
+-   **Average I/O operation time for extended operations (ms)**
+    The average time for extended I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.
 -   **Average I/O operation size (kb)**
     The average amount of data of the completed I/O operations.
+-   **Average amount of discarded data (kb)**
+    The average amount of data of the completed discard operations.
 -   **Average Service Time (ms)**
     The average service time for completed I/O operations. This metric is calculated using the total busy time of the disk and the number of completed operations. If the disk is able to execute multiple parallel operations the reporting average service time will be misleading.
+-   **Average Service Time for extended I/O operations (ms)**
+    The average service time for completed extended I/O operations.
 -   **Merged I/O operations/s**
     The Linux kernel is capable of merging I/O operations. So, if two requests to read data from the disk are adjacent, the Linux kernel may merge them to one before giving them to disk. This metric measures the number of operations that have been merged by the Linux kernel.
+-   **Merged discard operations/s**
 -   **Total I/O time**
     The sum of the duration of all completed I/O operations. This number can exceed the interval if the disk is able to execute multiple I/O operations in parallel.
 -   **Space usage**
@@ -116,6 +126,7 @@ Then edit `netdata.conf` and find the following section. This is the basic plugi
   # i/o time for all disks = auto
   # queued operations for all disks = auto
   # utilization percentage for all disks = auto
+  # extended operations for all disks = auto
   # backlog for all disks = auto
   # bcache for all disks = auto
   # bcache priority stats update every = 0
@@ -147,6 +158,7 @@ For each virtual disk, physical disk and partition you will have a section like
 	# i/o time = auto
 	# queued operations = auto
 	# utilization percentage = auto
+    # extended operations = auto
 	# backlog = auto
 ```
 
diff --git a/collectors/proc.plugin/proc_diskstats.c b/collectors/proc.plugin/proc_diskstats.c
index b5d02f329d..cfaf2134a4 100644
--- a/collectors/proc.plugin/proc_diskstats.c
+++ b/collectors/proc.plugin/proc_diskstats.c
@@ -32,6 +32,7 @@ static struct disk {
     int do_iotime;
     int do_qops;
     int do_util;
+    int do_ext;
     int do_backlog;
     int do_bcache;
 
@@ -64,10 +65,17 @@ static struct disk {
     RRDDIM *rd_io_reads;
     RRDDIM *rd_io_writes;
 
+    RRDSET *st_ext_io;
+    RRDDIM *rd_io_discards;
+
     RRDSET *st_ops;
     RRDDIM *rd_ops_reads;
     RRDDIM *rd_ops_writes;
 
+    RRDSET *st_ext_ops;
+    RRDDIM *rd_ops_discards;
+    RRDDIM *rd_ops_flushes;
+
     RRDSET *st_qops;
     RRDDIM *rd_qops_operations;
 
@@ -84,18 +92,32 @@ static struct disk {
     RRDDIM *rd_mops_reads;
     RRDDIM *rd_mops_writes;
 
+    RRDSET *st_ext_mops;
+    RRDDIM *rd_mops_discards;
+
     RRDSET *st_iotime;
     RRDDIM *rd_iotime_reads;
     RRDDIM *rd_iotime_writes;
 
+    RRDSET *st_ext_iotime;
+    RRDDIM *rd_iotime_discards;
+    RRDDIM *rd_iotime_flushes;
+
     RRDSET *st_await;
     RRDDIM *rd_await_reads;
     RRDDIM *rd_await_writes;
 
+    RRDSET *st_ext_await;
+    RRDDIM *rd_await_discards;
+    RRDDIM *rd_await_flushes;
+
     RRDSET *st_avgsz;
     RRDDIM *rd_avgsz_reads;
     RRDDIM *rd_avgsz_writes;
 
+    RRDSET *st_ext_avgsz;
+    RRDDIM *rd_avgsz_discards;
+
     RRDSET *st_svctm;
     RRDDIM *rd_svctm_svctm;
 
@@ -164,6 +186,7 @@ static int  global_enable_new_disks_detected_at_runtime = CONFIG_BOOLEAN_YES,
         global_do_iotime = CONFIG_BOOLEAN_AUTO,
         global_do_qops = CONFIG_BOOLEAN_AUTO,
         global_do_util = CONFIG_BOOLEAN_AUTO,
+        global_do_ext = CONFIG_BOOLEAN_AUTO,
         global_do_backlog = CONFIG_BOOLEAN_AUTO,
         global_do_bcache = CONFIG_BOOLEAN_AUTO,
         globals_initialized = 0,
@@ -463,6 +486,7 @@ static void get_disk_config(struct disk *d) {
         d->do_iotime = CONFIG_BOOLEAN_NO;
         d->do_qops = CONFIG_BOOLEAN_NO;
         d->do_util = CONFIG_BOOLEAN_NO;
+        d->do_ext = CONFIG_BOOLEAN_NO;
         d->do_backlog = CONFIG_BOOLEAN_NO;
         d->do_bcache = CONFIG_BOOLEAN_NO;
     }
@@ -513,6 +537,7 @@ static void get_disk_config(struct disk *d) {
                 ddo_iotime = CONFIG_BOOLEAN_NO,
                 ddo_qops = CONFIG_BOOLEAN_NO,
                 ddo_util = CONFIG_BOOLEAN_NO,
+                ddo_ext = CONFIG_BOOLEAN_NO,
                 ddo_backlog = CONFIG_BOOLEAN_NO,
                 ddo_bcache = CONFIG_BOOLEAN_NO;
 
@@ -524,6 +549,7 @@ static void get_disk_config(struct disk *d) {
             ddo_iotime = global_do_iotime,
             ddo_qops = global_do_qops,
             ddo_util = global_do_util,
+            ddo_ext = global_do_ext,
             ddo_backlog = global_do_backlog,
             ddo_bcache = global_do_bcache;
         }
@@ -534,6 +560,7 @@ static void get_disk_config(struct disk *d) {
         d->do_iotime  = config_get_boolean_ondemand(var_name, "i/o time", ddo_iotime);
         d->do_qops    = config_get_boolean_ondemand(var_name, "queued operations", ddo_qops);
         d->do_util    = config_get_boolean_ondemand(var_name, "utilization percentage", ddo_util);
+        d->do_ext     = config_get_boolean_ondemand(var_name, "extended operations", ddo_ext);
         d->do_backlog = config_get_boolean_ondemand(var_name, "backlog", ddo_backlog);
 
         if(d->device_is_bcache)
@@ -820,6 +847,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         global_do_iotime  = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_DISKSTATS, "i/o time for all disks", global_do_iotime);
         global_do_qops    = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_DISKSTATS, "queued operations for all disks", global_do_qops);
         global_do_util    = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_DISKSTATS, "utilization percentage for all disks", global_do_util);
+        global_do_ext     = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_DISKSTATS, "extended operations for all disks", global_do_ext);
         global_do_backlog = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_DISKSTATS, "backlog for all disks", global_do_backlog);
         global_do_bcache  = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_DISKSTATS, "bcache for all disks", global_do_bcache);
         global_bcache_priority_stats_update_every = (int)config_get_number(CONFIG_SECTION_PLUGIN_PROC_DISKSTATS, "bcache priority stats update every", global_bcache_priority_stats_update_every);
@@ -889,6 +917,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
 
     collected_number system_read_kb = 0, system_write_kb = 0;
 
+    int do_dc_stats = 0, do_fl_stats = 0;
+
     for(l = 0; l < lines ;l++) {
         // --------------------------------------------------------------------------
         // Read parameters
@@ -898,11 +928,16 @@ int do_proc_diskstats(int update_every, usec_t dt) {
 
         collected_number    reads = 0,  mreads = 0,  readsectors = 0,  readms = 0,
                             writes = 0, mwrites = 0, writesectors = 0, writems = 0,
-                            queued_ios = 0, busy_ms = 0, backlog_ms = 0;
+                            queued_ios = 0, busy_ms = 0, backlog_ms = 0,
+                            discards = 0, mdiscards = 0, discardsectors = 0, discardms = 0,
+                            flushes = 0, flushms = 0;
+
 
         collected_number    last_reads = 0,  last_readsectors = 0,  last_readms = 0,
                             last_writes = 0, last_writesectors = 0, last_writems = 0,
-                            last_busy_ms = 0;
+                            last_busy_ms = 0,
+                            last_discards = 0, last_discardsectors = 0, last_discardms = 0,
+                            last_flushes = 0, last_flushms = 0;
 
         size_t words = procfile_linewords(ff, l);
         if(unlikely(words < 14)) continue;
@@ -951,6 +986,40 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         // I/O completion time and the backlog that may be accumulating.
         backlog_ms      = str2ull(procfile_lineword(ff, l, 13)); // rq_ticks
 
+        if (unlikely(words > 13)) {
+            do_dc_stats = 1;
+
+            // # of discards completed
+            // This is the total number of discards completed successfully.
+            discards       = str2ull(procfile_lineword(ff, l, 14)); // dc_ios
+
+            // # of discards merged
+            // See the description of mreads/mwrites
+            mdiscards      = str2ull(procfile_lineword(ff, l, 15)); // dc_merges
+
+            // # of sectors discarded
+            // This is the total number of sectors discarded successfully.
+            discardsectors = str2ull(procfile_lineword(ff, l, 16)); // dc_sec
+
+            // # of milliseconds spent discarding
+            // This is the total number of milliseconds spent by all discards (as
+            // measured from __make_request() to end_that_request_last()).
+            discardms      = str2ull(procfile_lineword(ff, l, 17)); // dc_ticks
+        }
+
+        if (unlikely(words > 17)) {
+            do_fl_stats = 1;
+
+            // number of flush I/Os processed
+            // These values increment when an flush I/O request completes.
+            // Block layer combines flush requests and executes at most one at a time.
+            // This counts flush requests executed by disk. Not tracked for partitions.
+            flushes        = str2ull(procfile_lineword(ff, l, 18)); // fl_ios
+
+            // total wait time for flush requests
+            flushms        = str2ull(procfile_lineword(ff, l, 19)); // fl_ticks
+        }
+
         // --------------------------------------------------------------------------
         // get a disk structure for the disk
 
@@ -976,7 +1045,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         // Do performance metrics
 
         if(d->do_io == CONFIG_BOOLEAN_YES || (d->do_io == CONFIG_BOOLEAN_AUTO &&
-                                              (readsectors || writesectors ||
+                                              (readsectors || writesectors || discardsectors ||
                                                netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
             d->do_io = CONFIG_BOOLEAN_YES;
 
@@ -1008,8 +1077,37 @@ int do_proc_diskstats(int update_every, usec_t dt) {
 
         // --------------------------------------------------------------------
 
+        if (do_dc_stats && d->do_io == CONFIG_BOOLEAN_YES && d->do_ext != CONFIG_BOOLEAN_NO) {
+            if (unlikely(!d->st_ext_io)) {
+                d->st_ext_io = rrdset_create_localhost(
+                        "disk_ext"
+                        , d->device
+                        , d->disk
+                        , family
+                        , "disk_ext.io"
+                        , "Amount of Discarded Data"
+                        , "KiB/s"
+                        , PLUGIN_PROC_NAME
+                        , PLUGIN_PROC_MODULE_DISKSTATS_NAME
+                        , NETDATA_CHART_PRIO_DISK_IO + 1
+                        , update_every
+                        , RRDSET_TYPE_AREA
+                );
+
+                d->rd_io_discards =
+                    rrddim_add(d->st_ext_io, "discards", NULL, d->sector_size, 1024, RRD_ALGORITHM_INCREMENTAL);
+            } else
+                rrdset_next(d->st_ext_io);
+
+            last_discardsectors = rrddim_set_by_pointer(d->st_ext_io, d->rd_io_discards, discardsectors);
+            rrdset_done(d->st_ext_io);
+        }
+
+        // --------------------------------------------------------------------
+
         if(d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO &&
-                                               (reads || writes || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
+                                               (reads || writes || discards || flushes ||
+                                                netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
             d->do_ops = CONFIG_BOOLEAN_YES;
 
             if(unlikely(!d->st_ops)) {
@@ -1042,6 +1140,39 @@ int do_proc_diskstats(int update_every, usec_t dt) {
 
         // --------------------------------------------------------------------
 
+        if (do_dc_stats && d->do_ops == CONFIG_BOOLEAN_YES && d->do_ext != CONFIG_BOOLEAN_NO) {
+            if (unlikely(!d->st_ext_ops)) {
+                d->st_ext_ops = rrdset_create_localhost(
+                        "disk_ext_ops"
+                        , d->device
+                        , d->disk
+                        , family
+                        , "disk_ext.ops"
+                        , "Disk Completed Extended I/O Operations"
+                        , "operations/s"
+                        , PLUGIN_PROC_NAME
+                        , PLUGIN_PROC_MODULE_DISKSTATS_NAME
+                        , NETDATA_CHART_PRIO_DISK_OPS + 1
+                        , update_every
+                        , RRDSET_TYPE_LINE
+                );
+
+                rrdset_flag_set(d->st_ext_ops, RRDSET_FLAG_DETAIL);
+
+                d->rd_ops_discards = rrddim_add(d->st_ext_ops, "discards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+                if (do_fl_stats)
+                    d->rd_ops_flushes = rrddim_add(d->st_ext_ops, "flushes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+            } else
+                rrdset_next(d->st_ext_ops);
+
+            last_discards = rrddim_set_by_pointer(d->st_ext_ops, d->rd_ops_discards, discards);
+            if (do_fl_stats)
+                last_flushes = rrddim_set_by_pointer(d->st_ext_ops, d->rd_ops_flushes, flushes);
+            rrdset_done(d->st_ext_ops);
+        }
+
+        // --------------------------------------------------------------------
+
         if(d->do_qops == CONFIG_BOOLEAN_YES || (d->do_qops == CONFIG_BOOLEAN_AUTO &&
                                                 (queued_ios || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
             d->do_qops = CONFIG_BOOLEAN_YES;
@@ -1171,7 +1302,8 @@ int do_proc_diskstats(int update_every, usec_t dt) {
         // --------------------------------------------------------------------
 
         if(d->do_mops == CONFIG_BOOLEAN_YES || (d->do_mops == CONFIG_BOOLEAN_AUTO &&
-                                                (mreads || mwrites || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
+                                                (mreads || mwrites || mdiscards ||
+                                                 netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
             d->do_mops = CONFIG_BOOLEAN_YES;
 
             if(unlikely(!d->st_mops)) {
@@ -1204,8 +1336,39 @@ int do_proc_diskstats(int update_every, usec_t dt) {
 
         // --------------------------------------------------------------------
 
+        if(do_dc_stats && d->do_mops == CONFIG_BOOLEAN_YES && d->do_ext != CONFIG_BOOLEAN_NO) {
+            d->do_mops = CONFIG_BOOLEAN_YES;
+
+            if(unlikely(!d->st_ext_mops)) {
+                d->st_ext_mops = rrdset_create_localhost(
+                        "disk_ext_mops"
+                        , d->device
+                        , d->disk
+                        , family
+                        , "disk_ext.mops"
+                        , "Disk Merged Discard Operations"
+                        , "merged operations/s"
+                        , PLUGIN_PROC_NAME
+                        , PLUGIN_PROC_MODULE_DISKSTATS_NAME
+                        , NETDATA_CHART_PRIO_DISK_MOPS + 1
+                        , update_every
+                        , RRDSET_TYPE_LINE
+                );
+
+                rrdset_flag_set(d->st_ext_mops, RRDSET_FLAG_DETAIL);
+
+                d->rd_mops_discards = rrddim_add(d->st_ext_mops, "discards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+            } else
+                rrdset_next(d->st_ext_mops);
+
+            rrddim_set_by_pointer(d->st_ext_mops, d->rd_mops_discards, mdiscards);
+            rrdset_done(d->st_ext_mops);
+        }
+
+        // --------------------------------------------------------------------
+
         if(d->do_iotime == CONFIG_BOOLEAN_YES || (d->do_iotime == CONFIG_BOOLEAN_AUTO &&
-                                                  (readms || writems || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
+                                                  (readms || writems || discardms || flushms || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
             d->do_iotime = CONFIG_BOOLEAN_YES;
 
             if(unlikely(!d->st_iotime)) {
@@ -1236,6 +1399,40 @@ int do_proc_diskstats(int update_every, usec_t dt) {
             rrdset_done(d->st_iotime);
         }
 
+        // --------------------------------------------------------------------
+
+        if(do_dc_stats && d->do_iotime == CONFIG_BOOLEAN_YES && d->do_ext != CONFIG_BOOLEAN_NO) {
+            if(unlikely(!d->st_ext_iotime)) {
+                d->st_ext_iotime = rrdset_create_localhost(
+                        "disk_ext_iotime"
+                        , d->device
+                        , d->disk
+                        , family
+                        , "disk_ext.iotime"
+                        , "Disk Total I/O Time for Extended Operations"
+                        , "milliseconds/s"
+                        , PLUGIN_PROC_NAME
+                        , PLUGIN_PROC_MODULE_DISKSTATS_NAME
+                        , NETDATA_CHART_PRIO_DISK_IOTIME + 1 
+                        , update_every
+                        , RRDSET_TYPE_LINE
+                );
+
+                rrdset_flag_set(d->st_ext_iotime, RRDSET_FLAG_DETAIL);
+
+                d->rd_iotime_discards = rrddim_add(d->st_ext_iotime, "discards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+                if (do_fl_stats)
+                    d->rd_iotime_flushes =
+                        rrddim_add(d->st_ext_iotime, "flushes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+            } else
+                rrdset_next(d->st_ext_iotime);
+
+            last_discardms = rrddim_set_by_pointer(d->st_ext_iotime, d->rd_iotime_discards, discardms);
+            if (do_fl_stats)
+                last_flushms = rrddim_set_by_pointer(d->st_ext_iotime, d->rd_iotime_flushes, flushms);
+            rrdset_done(d->st_ext_iotime);
+        }
+
         // --------------------------------------------------------------------
         // calculate differential charts
         // only if this is not the first time we run
@@ -1276,6 +1473,42 @@ int do_proc_diskstats(int update_every, usec_t dt) {
                 rrdset_done(d->st_await);
             }
 
+            if (do_dc_stats && d->do_iotime == CONFIG_BOOLEAN_YES && d->do_ops == CONFIG_BOOLEAN_YES && d->do_ext != CONFIG_BOOLEAN_NO) {
+                if(unlikely(!d->st_ext_await)) {
+                    d->st_ext_await = rrdset_create_localhost(
+                            "disk_ext_await"
+                            , d->device
+                            , d->disk
+                            , family
+                            , "disk_ext.await"
+                            , "Average Completed Extended I/O Operation Time"
+                            , "milliseconds/operation"
+                            , PLUGIN_PROC_NAME
+                            , PLUGIN_PROC_MODULE_DISKSTATS_NAME
+                            , NETDATA_CHART_PRIO_DISK_AWAIT + 1
+                            , update_every
+                            , RRDSET_TYPE_LINE
+                    );
+
+                    rrdset_flag_set(d->st_ext_await, RRDSET_FLAG_DETAIL);
+
+                    d->rd_await_discards = rrddim_add(d->st_ext_await, "discards", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+                    if (do_fl_stats)
+                        d->rd_await_flushes =
+                            rrddim_add(d->st_ext_await, "flushes", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+                } else
+                    rrdset_next(d->st_ext_await);
+
+                rrddim_set_by_pointer(
+                    d->st_ext_await, d->rd_await_discards,
+                    (discards - last_discards) ? (discardms - last_discardms) / (discards - last_discards) : 0);
+                if (do_fl_stats)
+                    rrddim_set_by_pointer(
+                        d->st_ext_await, d->rd_await_flushes,
+                        (flushes - last_flushes) ? (flushms - last_flushms) / (flushes - last_flushes) : 0);
+                rrdset_done(d->st_ext_await);
+            }
+
             if( (d->do_io  == CONFIG_BOOLEAN_YES || (d->do_io  == CONFIG_BOOLEAN_AUTO &&
                                                      (readsectors || writesectors || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) &&
                 (d->do_ops == CONFIG_BOOLEAN_YES || (d->do_ops == CONFIG_BOOLEAN_AUTO &&
@@ -1309,6 +1542,37 @@ int do_proc_diskstats(int update_every, usec_t dt) {
                 rrdset_done(d->st_avgsz);
             }
 
+            if(do_dc_stats && d->do_io  == CONFIG_BOOLEAN_YES && d->do_ops == CONFIG_BOOLEAN_YES && d->do_ext != CONFIG_BOOLEAN_NO) {
+                if(unlikely(!d->st_ext_avgsz)) {
+                    d->st_ext_avgsz = rrdset_create_localhost(
+                            "disk_ext_avgsz"
+                            , d->device
+                            , d->disk
+                            , family
+                            , "disk_ext.avgsz"
+                            , "Average Amount of Discarded Data"
+                            , "KiB/operation"
+                            , PLUGIN_PROC_NAME
+                            , PLUGIN_PROC_MODULE_DISKSTATS_NAME
+                            , NETDATA_CHART_PRIO_DISK_AVGSZ
+                            , update_every
+                            , RRDSET_TYPE_AREA
+                    );
+
+                    rrdset_flag_set(d->st_ext_avgsz, RRDSET_FLAG_DETAIL);
+
+                    d->rd_avgsz_discards =
+                        rrddim_add(d->st_ext_avgsz, "discards", NULL, d->sector_size, 1024, RRD_ALGORITHM_ABSOLUTE);
+                } else
+                    rrdset_next(d->st_ext_avgsz);
+
+                rrddim_set_by_pointer(
+                    d->st_ext_avgsz, d->rd_avgsz_discards,
+                    (discards - last_discards) ? (discardsectors - last_discardsectors) / (discards - last_discards) :
+                                                 0);
+                rrdset_done(d->st_ext_avgsz);
+            }
+
             if( (d->do_util == CONFIG_BOOLEAN_YES || (d->do_util == CONFIG_BOOLEAN_AUTO &&
                                                       (busy_ms ||
                                                        netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) &&
diff --git a/web/gui/dashboard_info.js b/web/gui/dashboard_info.js
index d5d7c693ce..81a7827044 100644
--- a/web/gui/dashboard_info.js
+++ b/web/gui/dashboard_info.js
@@ -1424,10 +1424,16 @@ netdataDashboard.context = {
         height: 0.5,
         info: 'The sum of the duration of all completed I/O operations. This number can exceed the interval if the disk is able to execute I/O operations in parallel.'
     },
+    'disk_ext.iotime': {
+        height: 0.5
+    },
     'disk.mops': {
         height: 0.5,
         info: 'The number of merged disk operations. The system is able to merge adjacent I/O operations, for example two 4KB reads can become one 8KB read before given to disk.'
     },
+    'disk_ext.mops': {
+        height: 0.5
+    },
     'disk.svctm': {
         height: 0.5,
         info: 'The average service time for completed I/O operations. This metric is calculated using the total busy time of the disk and the number of completed operations. If the disk is able to execute multiple parallel operations the reporting average service time will be misleading.'
@@ -1436,10 +1442,17 @@ netdataDashboard.context = {
         height: 0.5,
         info: 'The average I/O operation size.'
     },
+    'disk_ext.avgsz': {
+        height: 0.5
+    },
     'disk.await': {
         height: 0.5,
         info: 'The average time for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.'
     },
+    'disk_ext.await': {
+        height: 0.5,
+        info: 'The average time for extended I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.'
+    },
 
     'disk.space': {
         info: 'Disk space utilization. reserved for root is automatically reserved by the system to prevent the root user from getting out of space.'