aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter2010-08-11 16:17:49 -0500
committerLinus Torvalds2010-08-12 10:43:30 -0500
commit8d57a98ccd0b4489003473979da8f5a1363ba7a3 (patch)
tree2982997ce66bb6a92c020b7189966c3097095fd7 /block/ioctl.c
parent93caf8e69eac763f6a20cf253ace8e7fc1ab7953 (diff)
downloadkernel-common-8d57a98ccd0b4489003473979da8f5a1363ba7a3.tar.gz
kernel-common-8d57a98ccd0b4489003473979da8f5a1363ba7a3.tar.xz
kernel-common-8d57a98ccd0b4489003473979da8f5a1363ba7a3.zip
block: add secure discard
Secure discard is the same as discard except that all copies of the discarded sectors (perhaps created by garbage collection) must also be erased. Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com> Acked-by: Jens Axboe <axboe@kernel.dk> Cc: Kyungmin Park <kmpark@infradead.org> Cc: Madhusudhan Chikkature <madhu.cr@ti.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Ben Gardiner <bengardiner@nanometrics.ca> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'block/ioctl.c')
-rw-r--r--block/ioctl.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/block/ioctl.c b/block/ioctl.c
index 09fd7f1ef23..d8052f0dabd 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -114,8 +114,10 @@ static int blkdev_reread_part(struct block_device *bdev)
114} 114}
115 115
116static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, 116static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
117 uint64_t len) 117 uint64_t len, int secure)
118{ 118{
119 unsigned long flags = BLKDEV_IFL_WAIT;
120
119 if (start & 511) 121 if (start & 511)
120 return -EINVAL; 122 return -EINVAL;
121 if (len & 511) 123 if (len & 511)
@@ -125,8 +127,9 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
125 127
126 if (start + len > (bdev->bd_inode->i_size >> 9)) 128 if (start + len > (bdev->bd_inode->i_size >> 9))
127 return -EINVAL; 129 return -EINVAL;
128 return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, 130 if (secure)
129 BLKDEV_IFL_WAIT); 131 flags |= BLKDEV_IFL_SECURE;
132 return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
130} 133}
131 134
132static int put_ushort(unsigned long arg, unsigned short val) 135static int put_ushort(unsigned long arg, unsigned short val)
@@ -213,7 +216,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
213 set_device_ro(bdev, n); 216 set_device_ro(bdev, n);
214 return 0; 217 return 0;
215 218
216 case BLKDISCARD: { 219 case BLKDISCARD:
220 case BLKSECDISCARD: {
217 uint64_t range[2]; 221 uint64_t range[2];
218 222
219 if (!(mode & FMODE_WRITE)) 223 if (!(mode & FMODE_WRITE))
@@ -222,7 +226,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
222 if (copy_from_user(range, (void __user *)arg, sizeof(range))) 226 if (copy_from_user(range, (void __user *)arg, sizeof(range)))
223 return -EFAULT; 227 return -EFAULT;
224 228
225 return blk_ioctl_discard(bdev, range[0], range[1]); 229 return blk_ioctl_discard(bdev, range[0], range[1],
230 cmd == BLKSECDISCARD);
226 } 231 }
227 232
228 case HDIO_GETGEO: { 233 case HDIO_GETGEO: {