Skip to content

Commit 7afafc8

Browse files
ahunter6axboe
authored andcommitted
block: Fix secure erase
Commit 288dab8 ("block: add a separate operation type for secure erase") split REQ_OP_SECURE_ERASE from REQ_OP_DISCARD without considering all the places REQ_OP_DISCARD was being used to mean either. Fix those. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Fixes: 288dab8 ("block: add a separate operation type for secure erase") Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent f6b6a28 commit 7afafc8

9 files changed

Lines changed: 50 additions & 32 deletions

File tree

block/bio.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -667,18 +667,19 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
667667
bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
668668
bio->bi_iter.bi_size = bio_src->bi_iter.bi_size;
669669

670-
if (bio_op(bio) == REQ_OP_DISCARD)
671-
goto integrity_clone;
672-
673-
if (bio_op(bio) == REQ_OP_WRITE_SAME) {
670+
switch (bio_op(bio)) {
671+
case REQ_OP_DISCARD:
672+
case REQ_OP_SECURE_ERASE:
673+
break;
674+
case REQ_OP_WRITE_SAME:
674675
bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
675-
goto integrity_clone;
676+
break;
677+
default:
678+
bio_for_each_segment(bv, bio_src, iter)
679+
bio->bi_io_vec[bio->bi_vcnt++] = bv;
680+
break;
676681
}
677682

678-
bio_for_each_segment(bv, bio_src, iter)
679-
bio->bi_io_vec[bio->bi_vcnt++] = bv;
680-
681-
integrity_clone:
682683
if (bio_integrity(bio_src)) {
683684
int ret;
684685

@@ -1788,7 +1789,7 @@ struct bio *bio_split(struct bio *bio, int sectors,
17881789
* Discards need a mutable bio_vec to accommodate the payload
17891790
* required by the DSM TRIM and UNMAP commands.
17901791
*/
1791-
if (bio_op(bio) == REQ_OP_DISCARD)
1792+
if (bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE)
17921793
split = bio_clone_bioset(bio, gfp, bs);
17931794
else
17941795
split = bio_clone_fast(bio, gfp, bs);

block/blk-merge.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,18 @@ void blk_queue_split(struct request_queue *q, struct bio **bio,
172172
struct bio *split, *res;
173173
unsigned nsegs;
174174

175-
if (bio_op(*bio) == REQ_OP_DISCARD)
175+
switch (bio_op(*bio)) {
176+
case REQ_OP_DISCARD:
177+
case REQ_OP_SECURE_ERASE:
176178
split = blk_bio_discard_split(q, *bio, bs, &nsegs);
177-
else if (bio_op(*bio) == REQ_OP_WRITE_SAME)
179+
break;
180+
case REQ_OP_WRITE_SAME:
178181
split = blk_bio_write_same_split(q, *bio, bs, &nsegs);
179-
else
182+
break;
183+
default:
180184
split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs);
185+
break;
186+
}
181187

182188
/* physical segments can be figured out during splitting */
183189
res = split ? split : *bio;
@@ -213,7 +219,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
213219
* This should probably be returning 0, but blk_add_request_payload()
214220
* (Christoph!!!!)
215221
*/
216-
if (bio_op(bio) == REQ_OP_DISCARD)
222+
if (bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE)
217223
return 1;
218224

219225
if (bio_op(bio) == REQ_OP_WRITE_SAME)
@@ -385,27 +391,26 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
385391
nsegs = 0;
386392
cluster = blk_queue_cluster(q);
387393

388-
if (bio_op(bio) == REQ_OP_DISCARD) {
394+
switch (bio_op(bio)) {
395+
case REQ_OP_DISCARD:
396+
case REQ_OP_SECURE_ERASE:
389397
/*
390398
* This is a hack - drivers should be neither modifying the
391399
* biovec, nor relying on bi_vcnt - but because of
392400
* blk_add_request_payload(), a discard bio may or may not have
393401
* a payload we need to set up here (thank you Christoph) and
394402
* bi_vcnt is really the only way of telling if we need to.
395403
*/
396-
397-
if (bio->bi_vcnt)
398-
goto single_segment;
399-
400-
return 0;
401-
}
402-
403-
if (bio_op(bio) == REQ_OP_WRITE_SAME) {
404-
single_segment:
404+
if (!bio->bi_vcnt)
405+
return 0;
406+
/* Fall through */
407+
case REQ_OP_WRITE_SAME:
405408
*sg = sglist;
406409
bvec = bio_iovec(bio);
407410
sg_set_page(*sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
408411
return 1;
412+
default:
413+
break;
409414
}
410415

411416
for_each_bio(bio)

block/elevator.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq)
366366
list_for_each_prev(entry, &q->queue_head) {
367367
struct request *pos = list_entry_rq(entry);
368368

369-
if ((req_op(rq) == REQ_OP_DISCARD) != (req_op(pos) == REQ_OP_DISCARD))
369+
if (req_op(rq) != req_op(pos))
370370
break;
371371
if (rq_data_dir(rq) != rq_data_dir(pos))
372372
break;

drivers/mmc/card/block.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
17261726
break;
17271727

17281728
if (req_op(next) == REQ_OP_DISCARD ||
1729+
req_op(next) == REQ_OP_SECURE_ERASE ||
17291730
req_op(next) == REQ_OP_FLUSH)
17301731
break;
17311732

drivers/mmc/card/queue.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
3333
/*
3434
* We only like normal block requests and discards.
3535
*/
36-
if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD) {
36+
if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD &&
37+
req_op(req) != REQ_OP_SECURE_ERASE) {
3738
blk_dump_rq_flags(req, "MMC bad request");
3839
return BLKPREP_KILL;
3940
}

drivers/mmc/card/queue.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
static inline bool mmc_req_is_special(struct request *req)
55
{
66
return req &&
7-
(req_op(req) == REQ_OP_FLUSH || req_op(req) == REQ_OP_DISCARD);
7+
(req_op(req) == REQ_OP_FLUSH ||
8+
req_op(req) == REQ_OP_DISCARD ||
9+
req_op(req) == REQ_OP_SECURE_ERASE);
810
}
911

1012
struct request;

include/linux/bio.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,18 @@ static inline bool bio_has_data(struct bio *bio)
7171
{
7272
if (bio &&
7373
bio->bi_iter.bi_size &&
74-
bio_op(bio) != REQ_OP_DISCARD)
74+
bio_op(bio) != REQ_OP_DISCARD &&
75+
bio_op(bio) != REQ_OP_SECURE_ERASE)
7576
return true;
7677

7778
return false;
7879
}
7980

8081
static inline bool bio_no_advance_iter(struct bio *bio)
8182
{
82-
return bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_WRITE_SAME;
83+
return bio_op(bio) == REQ_OP_DISCARD ||
84+
bio_op(bio) == REQ_OP_SECURE_ERASE ||
85+
bio_op(bio) == REQ_OP_WRITE_SAME;
8386
}
8487

8588
static inline bool bio_is_rw(struct bio *bio)
@@ -199,6 +202,9 @@ static inline unsigned bio_segments(struct bio *bio)
199202
if (bio_op(bio) == REQ_OP_DISCARD)
200203
return 1;
201204

205+
if (bio_op(bio) == REQ_OP_SECURE_ERASE)
206+
return 1;
207+
202208
if (bio_op(bio) == REQ_OP_WRITE_SAME)
203209
return 1;
204210

include/linux/blkdev.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
882882
static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
883883
int op)
884884
{
885-
if (unlikely(op == REQ_OP_DISCARD))
885+
if (unlikely(op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE))
886886
return min(q->limits.max_discard_sectors, UINT_MAX >> 9);
887887

888888
if (unlikely(op == REQ_OP_WRITE_SAME))
@@ -913,7 +913,9 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq,
913913
if (unlikely(rq->cmd_type != REQ_TYPE_FS))
914914
return q->limits.max_hw_sectors;
915915

916-
if (!q->limits.chunk_sectors || (req_op(rq) == REQ_OP_DISCARD))
916+
if (!q->limits.chunk_sectors ||
917+
req_op(rq) == REQ_OP_DISCARD ||
918+
req_op(rq) == REQ_OP_SECURE_ERASE)
917919
return blk_queue_get_max_sectors(q, req_op(rq));
918920

919921
return min(blk_max_size_offset(q, offset),

kernel/trace/blktrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
223223
what |= MASK_TC_BIT(op_flags, META);
224224
what |= MASK_TC_BIT(op_flags, PREFLUSH);
225225
what |= MASK_TC_BIT(op_flags, FUA);
226-
if (op == REQ_OP_DISCARD)
226+
if (op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE)
227227
what |= BLK_TC_ACT(BLK_TC_DISCARD);
228228
if (op == REQ_OP_FLUSH)
229229
what |= BLK_TC_ACT(BLK_TC_FLUSH);

0 commit comments

Comments
 (0)