History

block: add a separate operation type for secure erase

Instead of overloading the discard support with the REQ_SECURE flag. Use the opportunity to rename the queue flag as well, and remove the dead checks for this flag in the RAID 1 and RAID 10 drivers that don't claim support for secure erase.

Christoph Hellwig committed 10 years ago

Commit 288dab81 parent 56332f012 files · +63 −65Browse files

Unified · Split

12 files
  1. block/blk-core.c +17 −10
  2. block/blk-lib.c +14 −11
  3. block/blk-merge.c +2 −4
  4. drivers/block/xen-blkback/xenbus.c +1 −1
  5. drivers/block/xen-blkfront.c +9 −5
  6. drivers/md/raid1.c +1 −2
  7. drivers/md/raid10.c +2 −3
  8. drivers/mmc/card/block.c +6 −4
  9. drivers/mmc/card/queue.c +1 −1
  10. include/linux/blk_types.h +2 −3
  11. include/linux/blkdev.h +4 −19
  12. kernel/trace/blktrace.c +4 −2
block/blk-core.c+17−10
@@ -1977,16 +1977,21 @@ generic_make_request_checks(struct bio *bio) · 1976 unmodified lines
19771977 }
19781978 }
19791979
1980− if ((bio_op(bio) == REQ_OP_DISCARD) &&
1981− (!blk_queue_discard(q) ||
1982− ((bio->bi_rw & REQ_SECURE) && !blk_queue_secdiscard(q)))) {
1983− err = -EOPNOTSUPP;
1984− goto end_io;
1985− }
1986−
1987− if (bio_op(bio) == REQ_OP_WRITE_SAME && !bdev_write_same(bio->bi_bdev)) {
1988− err = -EOPNOTSUPP;
1989− goto end_io;
1980+ switch (bio_op(bio)) {
1981+ case REQ_OP_DISCARD:
1982+ if (!blk_queue_discard(q))
1983+ goto not_supported;
1984+ break;
1985+ case REQ_OP_SECURE_ERASE:
1986+ if (!blk_queue_secure_erase(q))
1987+ goto not_supported;
1988+ break;
1989+ case REQ_OP_WRITE_SAME:
1990+ if (!bdev_write_same(bio->bi_bdev))
1991+ goto not_supported;
1992+ break;
1993+ default:
1994+ break;
19901995 }
19911996
19921997 /*
@@ -2003,6 +2008,8 @@ generic_make_request_checks(struct bio *bio) · 10 unmodified lines
20032008 trace_block_bio_queue(q, bio);
20042009 return true;
20052010
2011+not_supported:
2012+ err = -EOPNOTSUPP;
20062013 end_io:
20072014 bio->bi_error = err;
20082015 bio_endio(bio);
block/blk-lib.c+14−11
@@ -23,20 +23,27 @@ static struct bio *next_bio(struct bio *bio, unsigned int nr_pages, · 22 unmodified lines
2323 }
2424
2525 int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
26− sector_t nr_sects, gfp_t gfp_mask, int op_flags,
26+ sector_t nr_sects, gfp_t gfp_mask, int flags,
2727 struct bio **biop)
2828 {
2929 struct request_queue *q = bdev_get_queue(bdev);
3030 struct bio *bio = *biop;
3131 unsigned int granularity;
32+ enum req_op op;
3233 int alignment;
3334
3435 if (!q)
3536 return -ENXIO;
36− if (!blk_queue_discard(q))
37− return -EOPNOTSUPP;
38− if ((op_flags & REQ_SECURE) && !blk_queue_secdiscard(q))
39− return -EOPNOTSUPP;
37+
38+ if (flags & BLKDEV_DISCARD_SECURE) {
39+ if (!blk_queue_secure_erase(q))
40+ return -EOPNOTSUPP;
41+ op = REQ_OP_SECURE_ERASE;
42+ } else {
43+ if (!blk_queue_discard(q))
44+ return -EOPNOTSUPP;
45+ op = REQ_OP_DISCARD;
46+ }
4047
4148 /* Zero-sector (unknown) and one-sector granularities are the same. */
4249 granularity = max(q->limits.discard_granularity >> 9, 1U);
@@ -66,7 +73,7 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, · 23 unmodified lines
6673 bio = next_bio(bio, 1, gfp_mask);
6774 bio->bi_iter.bi_sector = sector;
6875 bio->bi_bdev = bdev;
69− bio_set_op_attrs(bio, REQ_OP_DISCARD, op_flags);
76+ bio_set_op_attrs(bio, op, 0);
7077
7178 bio->bi_iter.bi_size = req_sects << 9;
7279 nr_sects -= req_sects;
@@ -100,16 +107,12 @@ EXPORT_SYMBOL(__blkdev_issue_discard); · 27 unmodified lines
100107 int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
101108 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags)
102109 {
103− int op_flags = 0;
104110 struct bio *bio = NULL;
105111 struct blk_plug plug;
106112 int ret;
107113
108− if (flags & BLKDEV_DISCARD_SECURE)
109− op_flags |= REQ_SECURE;
110−
111114 blk_start_plug(&plug);
112− ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, op_flags,
115+ ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, flags,
113116 &bio);
114117 if (!ret && bio) {
115118 ret = submit_bio_wait(bio);
block/blk-merge.c+2−4
@@ -649,8 +649,7 @@ static int attempt_merge(struct request_queue *q, struct request *req, · 648 unmodified lines
649649 if (!rq_mergeable(req) || !rq_mergeable(next))
650650 return 0;
651651
652− if (!blk_check_merge_flags(req->cmd_flags, req_op(req), next->cmd_flags,
653− req_op(next)))
652+ if (req_op(req) != req_op(next))
654653 return 0;
655654
656655 /*
@@ -752,8 +751,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio) · 95 unmodified lines
752751 if (!rq_mergeable(rq) || !bio_mergeable(bio))
753752 return false;
754753
755− if (!blk_check_merge_flags(rq->cmd_flags, req_op(rq), bio->bi_rw,
756− bio_op(bio)))
754+ if (req_op(rq) != bio_op(bio))
757755 return false;
758756
759757 /* different data direction or already started, don't merge */
drivers/block/xen-blkback/xenbus.c+1−1
@@ -480,7 +480,7 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, · 479 unmodified lines
480480 if (q && test_bit(QUEUE_FLAG_WC, &q->queue_flags))
481481 vbd->flush_support = true;
482482
483− if (q && blk_queue_secdiscard(q))
483+ if (q && blk_queue_secure_erase(q))
484484 vbd->discard_secure = true;
485485
486486 pr_debug("Successful creation of handle=%04x (dom=%u)\n",
drivers/block/xen-blkfront.c+9−5
@@ -545,7 +545,7 @@ static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_inf · 544 unmodified lines
545545 ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
546546 ring_req->u.discard.id = id;
547547 ring_req->u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
548− if ((req->cmd_flags & REQ_SECURE) && info->feature_secdiscard)
548+ if (req_op(req) == REQ_OP_SECURE_ERASE && info->feature_secdiscard)
549549 ring_req->u.discard.flag = BLKIF_DISCARD_SECURE;
550550 else
551551 ring_req->u.discard.flag = 0;
@@ -841,7 +841,7 @@ static int blkif_queue_request(struct request *req, struct blkfront_ring_info *r · 289 unmodified lines
841841 return 1;
842842
843843 if (unlikely(req_op(req) == REQ_OP_DISCARD ||
844− req->cmd_flags & REQ_SECURE))
844+ req_op(req) == REQ_OP_SECURE_ERASE))
845845 return blkif_queue_discard_req(req, rinfo);
846846 else
847847 return blkif_queue_rw_req(req, rinfo);
@@ -955,7 +955,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, · 107 unmodified lines
955955 rq->limits.discard_granularity = info->discard_granularity;
956956 rq->limits.discard_alignment = info->discard_alignment;
957957 if (info->feature_secdiscard)
958− queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, rq);
958+ queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, rq);
959959 }
960960
961961 /* Hard sector size and max sectors impersonate the equiv. hardware. */
@@ -1595,7 +1595,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) · 633 unmodified lines
15951595 info->feature_discard = 0;
15961596 info->feature_secdiscard = 0;
15971597 queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
1598− queue_flag_clear(QUEUE_FLAG_SECDISCARD, rq);
1598+ queue_flag_clear(QUEUE_FLAG_SECERASE, rq);
15991599 }
16001600 blk_mq_complete_request(req, error);
16011601 break;
@@ -2052,10 +2052,14 @@ static int blkif_recover(struct blkfront_info *info) · 450 unmodified lines
20522052 */
20532053 if (req_op(copy[i].request) == REQ_OP_FLUSH ||
20542054 req_op(copy[i].request) == REQ_OP_DISCARD ||
2055− copy[i].request->cmd_flags & (REQ_FUA | REQ_SECURE)) {
2055+ req_op(copy[i].request) == REQ_OP_SECURE_ERASE ||
2056+ copy[i].request->cmd_flags & REQ_FUA) {
20562057 /*
20572058 * Flush operations don't contain bios, so
20582059 * we need to requeue the whole request
2060+ *
2061+ * XXX: but this doesn't make any sense for a
2062+ * write with the FUA flag set..
20592063 */
20602064 list_add(&copy[i].request->queuelist, &requests);
20612065 continue;
drivers/md/raid1.c+1−2
@@ -1058,7 +1058,6 @@ static void raid1_make_request(struct mddev *mddev, struct bio * bio) · 1057 unmodified lines
10581058 const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
10591059 const unsigned long do_flush_fua = (bio->bi_rw &
10601060 (REQ_PREFLUSH | REQ_FUA));
1061− const unsigned long do_sec = (bio->bi_rw & REQ_SECURE);
10621061 struct md_rdev *blocked_rdev;
10631062 struct blk_plug_cb *cb;
10641063 struct raid1_plug_cb *plug = NULL;
@@ -1376,7 +1375,7 @@ read_again: · 311 unmodified lines
13761375 conf->mirrors[i].rdev->data_offset);
13771376 mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
13781377 mbio->bi_end_io = raid1_end_write_request;
1379− bio_set_op_attrs(mbio, op, do_flush_fua | do_sync | do_sec);
1378+ bio_set_op_attrs(mbio, op, do_flush_fua | do_sync);
13801379 mbio->bi_private = r1_bio;
13811380
13821381 atomic_inc(&r1_bio->remaining);
drivers/md/raid10.c+2−3
@@ -1062,7 +1062,6 @@ static void __make_request(struct mddev *mddev, struct bio *bio) · 1061 unmodified lines
10621062 const int rw = bio_data_dir(bio);
10631063 const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
10641064 const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
1065− const unsigned long do_sec = (bio->bi_rw & REQ_SECURE);
10661065 unsigned long flags;
10671066 struct md_rdev *blocked_rdev;
10681067 struct blk_plug_cb *cb;
@@ -1362,7 +1361,7 @@ retry_write: · 293 unmodified lines
13621361 rdev));
13631362 mbio->bi_bdev = rdev->bdev;
13641363 mbio->bi_end_io = raid10_end_write_request;
1365− bio_set_op_attrs(mbio, op, do_sync | do_fua | do_sec);
1364+ bio_set_op_attrs(mbio, op, do_sync | do_fua);
13661365 mbio->bi_private = r10_bio;
13671366
13681367 atomic_inc(&r10_bio->remaining);
@@ -1404,7 +1403,7 @@ retry_write: · 35 unmodified lines
14041403 r10_bio, rdev));
14051404 mbio->bi_bdev = rdev->bdev;
14061405 mbio->bi_end_io = raid10_end_write_request;
1407− bio_set_op_attrs(mbio, op, do_sync | do_fua | do_sec);
1406+ bio_set_op_attrs(mbio, op, do_sync | do_fua);
14081407 mbio->bi_private = r10_bio;
14091408
14101409 atomic_inc(&r10_bio->remaining);
drivers/mmc/card/block.c+6−4
@@ -2167,10 +2167,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) · 2166 unmodified lines
21672167 /* complete ongoing async transfer before issuing discard */
21682168 if (card->host->areq)
21692169 mmc_blk_issue_rw_rq(mq, NULL);
2170− if (req->cmd_flags & REQ_SECURE)
2171− ret = mmc_blk_issue_secdiscard_rq(mq, req);
2172− else
2173− ret = mmc_blk_issue_discard_rq(mq, req);
2170+ ret = mmc_blk_issue_discard_rq(mq, req);
2171+ } else if (req && req_op(req) == REQ_OP_SECURE_ERASE) {
2172+ /* complete ongoing async transfer before issuing secure erase*/
2173+ if (card->host->areq)
2174+ mmc_blk_issue_rw_rq(mq, NULL);
2175+ ret = mmc_blk_issue_secdiscard_rq(mq, req);
21742176 } else if (req && req_op(req) == REQ_OP_FLUSH) {
21752177 /* complete ongoing async transfer before issuing flush */
21762178 if (card->host->areq)
drivers/mmc/card/queue.c+1−1
@@ -171,7 +171,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, · 170 unmodified lines
171171 if (card->pref_erase > max_discard)
172172 q->limits.discard_granularity = 0;
173173 if (mmc_can_secure_erase_trim(card))
174− queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
174+ queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q);
175175 }
176176
177177 /**
include/linux/blk_types.h+2−3
@@ -163,7 +163,6 @@ enum rq_flag_bits { · 162 unmodified lines
163163 __REQ_SYNC, /* request is sync (sync write or read) */
164164 __REQ_META, /* metadata io request */
165165 __REQ_PRIO, /* boost priority in cfq */
166− __REQ_SECURE, /* secure discard (used with REQ_OP_DISCARD) */
167166
168167 __REQ_NOIDLE, /* don't anticipate more IO after this one */
169168 __REQ_INTEGRITY, /* I/O includes block integrity payload */
@@ -212,7 +211,7 @@ enum rq_flag_bits { · 42 unmodified lines
212211 (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
213212 #define REQ_COMMON_MASK \
214213 (REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | REQ_NOIDLE | \
215− REQ_PREFLUSH | REQ_FUA | REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE)
214+ REQ_PREFLUSH | REQ_FUA | REQ_INTEGRITY | REQ_NOMERGE)
216215 #define REQ_CLONE_MASK REQ_COMMON_MASK
217216
218217 /* This mask is used for both bio and request merge checking */
@@ -239,7 +238,6 @@ enum rq_flag_bits { · 20 unmodified lines
239238 #define REQ_FLUSH_SEQ (1ULL << __REQ_FLUSH_SEQ)
240239 #define REQ_IO_STAT (1ULL << __REQ_IO_STAT)
241240 #define REQ_MIXED_MERGE (1ULL << __REQ_MIXED_MERGE)
242−#define REQ_SECURE (1ULL << __REQ_SECURE)
243241 #define REQ_PM (1ULL << __REQ_PM)
244242 #define REQ_HASHED (1ULL << __REQ_HASHED)
245243 #define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT)
@@ -248,6 +246,7 @@ enum req_op { · 2 unmodified lines
248246 REQ_OP_READ,
249247 REQ_OP_WRITE,
250248 REQ_OP_DISCARD, /* request to discard sectors */
249+ REQ_OP_SECURE_ERASE, /* request to securely erase sectors */
251250 REQ_OP_WRITE_SAME, /* write same block many times */
252251 REQ_OP_FLUSH, /* request for cache flush */
253252 };
include/linux/blkdev.h+4−19
@@ -497,7 +497,7 @@ struct request_queue { · 496 unmodified lines
497497 #define QUEUE_FLAG_DISCARD 14 /* supports DISCARD */
498498 #define QUEUE_FLAG_NOXMERGES 15 /* No extended merges */
499499 #define QUEUE_FLAG_ADD_RANDOM 16 /* Contributes to random pool */
500−#define QUEUE_FLAG_SECDISCARD 17 /* supports SECDISCARD */
500+#define QUEUE_FLAG_SECERASE 17 /* supports secure erase */
501501 #define QUEUE_FLAG_SAME_FORCE 18 /* force complete on same CPU */
502502 #define QUEUE_FLAG_DEAD 19 /* queue tear-down finished */
503503 #define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */
@@ -593,8 +593,8 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) · 89 unmodified lines
593593 #define blk_queue_stackable(q) \
594594 test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
595595 #define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
596−#define blk_queue_secdiscard(q) (blk_queue_discard(q) && \
597− test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags))
596+#define blk_queue_secure_erase(q) \
597+ (test_bit(QUEUE_FLAG_SECERASE, &(q)->queue_flags))
598598
599599 #define blk_noretry_request(rq) \
600600 ((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
@@ -675,21 +675,6 @@ static inline bool rq_mergeable(struct request *rq) · 74 unmodified lines
675675 return true;
676676 }
677677
678−static inline bool blk_check_merge_flags(unsigned int flags1, unsigned int op1,
679− unsigned int flags2, unsigned int op2)
680−{
681− if ((op1 == REQ_OP_DISCARD) != (op2 == REQ_OP_DISCARD))
682− return false;
683−
684− if ((flags1 & REQ_SECURE) != (flags2 & REQ_SECURE))
685− return false;
686−
687− if ((op1 == REQ_OP_WRITE_SAME) != (op2 == REQ_OP_WRITE_SAME))
688− return false;
689−
690− return true;
691−}
692−
693678 static inline bool blk_write_same_mergeable(struct bio *a, struct bio *b)
694679 {
695680 if (bio_data(a) == bio_data(b))
@@ -1158,7 +1143,7 @@ extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *); · 462 unmodified lines
11581143 extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
11591144 sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
11601145 extern int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
1161− sector_t nr_sects, gfp_t gfp_mask, int op_flags,
1146+ sector_t nr_sects, gfp_t gfp_mask, int flags,
11621147 struct bio **biop);
11631148 extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
11641149 sector_t nr_sects, gfp_t gfp_mask, struct page *page);
kernel/trace/blktrace.c+4−2
@@ -1791,6 +1791,10 @@ void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes) · 1790 unmodified lines
17911791 case REQ_OP_DISCARD:
17921792 rwbs[i++] = 'D';
17931793 break;
1794+ case REQ_OP_SECURE_ERASE:
1795+ rwbs[i++] = 'D';
1796+ rwbs[i++] = 'E';
1797+ break;
17941798 case REQ_OP_FLUSH:
17951799 rwbs[i++] = 'F';
17961800 break;
@@ -1809,8 +1813,6 @@ void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes) · 12 unmodified lines
18091813 rwbs[i++] = 'S';
18101814 if (rw & REQ_META)
18111815 rwbs[i++] = 'M';
1812− if (rw & REQ_SECURE)
1813− rwbs[i++] = 'E';
18141816
18151817 rwbs[i] = '\0';
18161818 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t