aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-settings.c2
-rw-r--r--block/blk-sysfs.c11
-rw-r--r--block/compat_ioctl.c2
-rw-r--r--block/ioctl.c2
-rw-r--r--include/linux/blkdev.h14
-rw-r--r--include/linux/fs.h1
6 files changed, 32 insertions, 0 deletions
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 1ebc1fdb9144..dd1f1e0e196f 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -101,6 +101,7 @@ void blk_set_default_limits(struct queue_limits *lim)
101 lim->discard_granularity = 0; 101 lim->discard_granularity = 0;
102 lim->discard_alignment = 0; 102 lim->discard_alignment = 0;
103 lim->discard_misaligned = 0; 103 lim->discard_misaligned = 0;
104 lim->discard_zeroes_data = -1;
104 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; 105 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
105 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); 106 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
106 lim->alignment_offset = 0; 107 lim->alignment_offset = 0;
@@ -544,6 +545,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
544 545
545 t->io_min = max(t->io_min, b->io_min); 546 t->io_min = max(t->io_min, b->io_min);
546 t->no_cluster |= b->no_cluster; 547 t->no_cluster |= b->no_cluster;
548 t->discard_zeroes_data &= b->discard_zeroes_data;
547 549
548 /* Bottom device offset aligned? */ 550 /* Bottom device offset aligned? */
549 if (offset && 551 if (offset &&
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 3147145edc15..8606c9543fdd 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -136,6 +136,11 @@ static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
136 return queue_var_show(q->limits.max_discard_sectors << 9, page); 136 return queue_var_show(q->limits.max_discard_sectors << 9, page);
137} 137}
138 138
139static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
140{
141 return queue_var_show(queue_discard_zeroes_data(q), page);
142}
143
139static ssize_t 144static ssize_t
140queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) 145queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
141{ 146{
@@ -313,6 +318,11 @@ static struct queue_sysfs_entry queue_discard_max_entry = {
313 .show = queue_discard_max_show, 318 .show = queue_discard_max_show,
314}; 319};
315 320
321static struct queue_sysfs_entry queue_discard_zeroes_data_entry = {
322 .attr = {.name = "discard_zeroes_data", .mode = S_IRUGO },
323 .show = queue_discard_zeroes_data_show,
324};
325
316static struct queue_sysfs_entry queue_nonrot_entry = { 326static struct queue_sysfs_entry queue_nonrot_entry = {
317 .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR }, 327 .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
318 .show = queue_nonrot_show, 328 .show = queue_nonrot_show,
@@ -350,6 +360,7 @@ static struct attribute *default_attrs[] = {
350 &queue_io_opt_entry.attr, 360 &queue_io_opt_entry.attr,
351 &queue_discard_granularity_entry.attr, 361 &queue_discard_granularity_entry.attr,
352 &queue_discard_max_entry.attr, 362 &queue_discard_max_entry.attr,
363 &queue_discard_zeroes_data_entry.attr,
353 &queue_nonrot_entry.attr, 364 &queue_nonrot_entry.attr,
354 &queue_nomerges_entry.attr, 365 &queue_nomerges_entry.attr,
355 &queue_rq_affinity_entry.attr, 366 &queue_rq_affinity_entry.attr,
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 9bd086c1a4d5..4eb8e9ea4af5 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -747,6 +747,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
747 return compat_put_uint(arg, bdev_io_opt(bdev)); 747 return compat_put_uint(arg, bdev_io_opt(bdev));
748 case BLKALIGNOFF: 748 case BLKALIGNOFF:
749 return compat_put_int(arg, bdev_alignment_offset(bdev)); 749 return compat_put_int(arg, bdev_alignment_offset(bdev));
750 case BLKDISCARDZEROES:
751 return compat_put_uint(arg, bdev_discard_zeroes_data(bdev));
750 case BLKFLSBUF: 752 case BLKFLSBUF:
751 case BLKROSET: 753 case BLKROSET:
752 case BLKDISCARD: 754 case BLKDISCARD:
diff --git a/block/ioctl.c b/block/ioctl.c
index 1f4d1de12b09..be48ea51faee 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -280,6 +280,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
280 return put_uint(arg, bdev_io_opt(bdev)); 280 return put_uint(arg, bdev_io_opt(bdev));
281 case BLKALIGNOFF: 281 case BLKALIGNOFF:
282 return put_int(arg, bdev_alignment_offset(bdev)); 282 return put_int(arg, bdev_alignment_offset(bdev));
283 case BLKDISCARDZEROES:
284 return put_uint(arg, bdev_discard_zeroes_data(bdev));
283 case BLKSECTGET: 285 case BLKSECTGET:
284 return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev))); 286 return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev)));
285 case BLKRASET: 287 case BLKRASET:
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e727f6c44c44..784a919aa0d0 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -322,6 +322,7 @@ struct queue_limits {
322 unsigned char misaligned; 322 unsigned char misaligned;
323 unsigned char discard_misaligned; 323 unsigned char discard_misaligned;
324 unsigned char no_cluster; 324 unsigned char no_cluster;
325 signed char discard_zeroes_data;
325}; 326};
326 327
327struct request_queue 328struct request_queue
@@ -1150,6 +1151,19 @@ static inline int queue_sector_discard_alignment(struct request_queue *q,
1150 & (q->limits.discard_granularity - 1); 1151 & (q->limits.discard_granularity - 1);
1151} 1152}
1152 1153
1154static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
1155{
1156 if (q->limits.discard_zeroes_data == 1)
1157 return 1;
1158
1159 return 0;
1160}
1161
1162static inline unsigned int bdev_discard_zeroes_data(struct block_device *bdev)
1163{
1164 return queue_discard_zeroes_data(bdev_get_queue(bdev));
1165}
1166
1153static inline int queue_dma_alignment(struct request_queue *q) 1167static inline int queue_dma_alignment(struct request_queue *q)
1154{ 1168{
1155 return q ? q->dma_alignment : 511; 1169 return q ? q->dma_alignment : 511;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 79cea8051736..891f7d642e5c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -304,6 +304,7 @@ struct inodes_stat_t {
304#define BLKIOOPT _IO(0x12,121) 304#define BLKIOOPT _IO(0x12,121)
305#define BLKALIGNOFF _IO(0x12,122) 305#define BLKALIGNOFF _IO(0x12,122)
306#define BLKPBSZGET _IO(0x12,123) 306#define BLKPBSZGET _IO(0x12,123)
307#define BLKDISCARDZEROES _IO(0x12,124)
307 308
308#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ 309#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
309#define FIBMAP _IO(0x00,1) /* bmap access */ 310#define FIBMAP _IO(0x00,1) /* bmap access */