diff options
-rw-r--r-- | block/blk-settings.c | 2 | ||||
-rw-r--r-- | block/blk-sysfs.c | 11 | ||||
-rw-r--r-- | block/compat_ioctl.c | 2 | ||||
-rw-r--r-- | block/ioctl.c | 2 | ||||
-rw-r--r-- | include/linux/blkdev.h | 14 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
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 | ||
139 | static 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 | |||
139 | static ssize_t | 144 | static ssize_t |
140 | queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) | 145 | queue_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 | ||
321 | static 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 | |||
316 | static struct queue_sysfs_entry queue_nonrot_entry = { | 326 | static 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 | ||
327 | struct request_queue | 328 | struct 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 | ||
1154 | static 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 | |||
1162 | static inline unsigned int bdev_discard_zeroes_data(struct block_device *bdev) | ||
1163 | { | ||
1164 | return queue_discard_zeroes_data(bdev_get_queue(bdev)); | ||
1165 | } | ||
1166 | |||
1153 | static inline int queue_dma_alignment(struct request_queue *q) | 1167 | static 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 */ |