Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d57a98c authored by Adrian Hunter's avatar Adrian Hunter Committed by Linus Torvalds
Browse files

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: default avatarAdrian Hunter <adrian.hunter@nokia.com>
Acked-by: default avatarJens 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 93caf8e6
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1514,7 +1514,10 @@ static inline void __generic_make_request(struct bio *bio)
		if (bio_check_eod(bio, nr_sectors))
			goto end_io;

		if ((bio->bi_rw & REQ_DISCARD) && !blk_queue_discard(q)) {
		if ((bio->bi_rw & REQ_DISCARD) &&
		    (!blk_queue_discard(q) ||
		     ((bio->bi_rw & REQ_SECURE) &&
		      !blk_queue_secdiscard(q)))) {
			err = -EOPNOTSUPP;
			goto end_io;
		}
+6 −0
Original line number Diff line number Diff line
@@ -62,6 +62,12 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
		max_discard_sectors &= ~(disc_sects - 1);
	}

	if (flags & BLKDEV_IFL_SECURE) {
		if (!blk_queue_secdiscard(q))
			return -EOPNOTSUPP;
		type |= DISCARD_SECURE;
	}

	while (nr_sects && !ret) {
		bio = bio_alloc(gfp_mask, 1);
		if (!bio) {
+1 −0
Original line number Diff line number Diff line
@@ -703,6 +703,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
	case BLKFLSBUF:
	case BLKROSET:
	case BLKDISCARD:
	case BLKSECDISCARD:
	/*
	 * the ones below are implemented in blkdev_locked_ioctl,
	 * but we call blkdev_ioctl, which gets the lock for us
+6 −0
Original line number Diff line number Diff line
@@ -82,6 +82,12 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio)
	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
		return 0;

	/*
	 * Don't merge discard requests and secure discard requests
	 */
	if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
		return 0;

	/*
	 * different data direction or already started, don't merge
	 */
+10 −5
Original line number Diff line number Diff line
@@ -114,8 +114,10 @@ static int blkdev_reread_part(struct block_device *bdev)
}

static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
			     uint64_t len)
			     uint64_t len, int secure)
{
	unsigned long flags = BLKDEV_IFL_WAIT;

	if (start & 511)
		return -EINVAL;
	if (len & 511)
@@ -125,8 +127,9 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,

	if (start + len > (bdev->bd_inode->i_size >> 9))
		return -EINVAL;
	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL,
				    BLKDEV_IFL_WAIT);
	if (secure)
		flags |= BLKDEV_IFL_SECURE;
	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
}

static 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,
		set_device_ro(bdev, n);
		return 0;

	case BLKDISCARD: {
	case BLKDISCARD:
	case BLKSECDISCARD: {
		uint64_t range[2];

		if (!(mode & FMODE_WRITE))
@@ -222,7 +226,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
		if (copy_from_user(range, (void __user *)arg, sizeof(range)))
			return -EFAULT;

		return blk_ioctl_discard(bdev, range[0], range[1]);
		return blk_ioctl_discard(bdev, range[0], range[1],
					 cmd == BLKSECDISCARD);
	}

	case HDIO_GETGEO: {
Loading