Commit 288dab8a35a0 ("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.
Unified · Split
| @@ -667,18 +667,19 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, · 666 unmodified lines | ||
| 667 | 667 | bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; |
| 668 | 668 | bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; |
| 669 | 669 | |
| 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: | |
| 674 | 675 | 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; | |
| 676 | 681 | } |
| 677 | 682 | |
| 678 | − bio_for_each_segment(bv, bio_src, iter) | |
| 679 | − bio->bi_io_vec[bio->bi_vcnt++] = bv; | |
| 680 | − | |
| 681 | −integrity_clone: | |
| 682 | 683 | if (bio_integrity(bio_src)) { |
| 683 | 684 | int ret; |
| 684 | 685 | |
| @@ -1788,7 +1789,7 @@ struct bio *bio_split(struct bio *bio, int sectors, · 1103 unmodified lines | ||
| 1788 | 1789 | * Discards need a mutable bio_vec to accommodate the payload |
| 1789 | 1790 | * required by the DSM TRIM and UNMAP commands. |
| 1790 | 1791 | */ |
| 1791 | − if (bio_op(bio) == REQ_OP_DISCARD) | |
| 1792 | + if (bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE) | |
| 1792 | 1793 | split = bio_clone_bioset(bio, gfp, bs); |
| 1793 | 1794 | else |
| 1794 | 1795 | split = bio_clone_fast(bio, gfp, bs); |
| @@ -172,12 +172,18 @@ void blk_queue_split(struct request_queue *q, struct bio **bio, · 171 unmodified lines | ||
| 172 | 172 | struct bio *split, *res; |
| 173 | 173 | unsigned nsegs; |
| 174 | 174 | |
| 175 | − if (bio_op(*bio) == REQ_OP_DISCARD) | |
| 175 | + switch (bio_op(*bio)) { | |
| 176 | + case REQ_OP_DISCARD: | |
| 177 | + case REQ_OP_SECURE_ERASE: | |
| 176 | 178 | 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: | |
| 178 | 181 | split = blk_bio_write_same_split(q, *bio, bs, &nsegs); |
| 179 | − else | |
| 182 | + break; | |
| 183 | + default: | |
| 180 | 184 | split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs); |
| 185 | + break; | |
| 186 | + } | |
| 181 | 187 | |
| 182 | 188 | /* physical segments can be figured out during splitting */ |
| 183 | 189 | res = split ? split : *bio; |
| @@ -213,7 +219,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q, · 29 unmodified lines | ||
| 213 | 219 | * This should probably be returning 0, but blk_add_request_payload() |
| 214 | 220 | * (Christoph!!!!) |
| 215 | 221 | */ |
| 216 | − if (bio_op(bio) == REQ_OP_DISCARD) | |
| 222 | + if (bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_SECURE_ERASE) | |
| 217 | 223 | return 1; |
| 218 | 224 | |
| 219 | 225 | if (bio_op(bio) == REQ_OP_WRITE_SAME) |
| @@ -385,7 +391,9 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio, · 165 unmodified lines | ||
| 385 | 391 | nsegs = 0; |
| 386 | 392 | cluster = blk_queue_cluster(q); |
| 387 | 393 | |
| 388 | − if (bio_op(bio) == REQ_OP_DISCARD) { | |
| 394 | + switch (bio_op(bio)) { | |
| 395 | + case REQ_OP_DISCARD: | |
| 396 | + case REQ_OP_SECURE_ERASE: | |
| 389 | 397 | /* |
| 390 | 398 | * This is a hack - drivers should be neither modifying the |
| 391 | 399 | * biovec, nor relying on bi_vcnt - but because of |
| @@ -393,19 +401,16 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio, · 1 unmodified line | ||
| 393 | 401 | * a payload we need to set up here (thank you Christoph) and |
| 394 | 402 | * bi_vcnt is really the only way of telling if we need to. |
| 395 | 403 | */ |
| 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: | |
| 405 | 408 | *sg = sglist; |
| 406 | 409 | bvec = bio_iovec(bio); |
| 407 | 410 | sg_set_page(*sg, bvec.bv_page, bvec.bv_len, bvec.bv_offset); |
| 408 | 411 | return 1; |
| 412 | + default: | |
| 413 | + break; | |
| 409 | 414 | } |
| 410 | 415 | |
| 411 | 416 | for_each_bio(bio) |
| @@ -366,7 +366,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) · 365 unmodified lines | ||
| 366 | 366 | list_for_each_prev(entry, &q->queue_head) { |
| 367 | 367 | struct request *pos = list_entry_rq(entry); |
| 368 | 368 | |
| 369 | − if ((req_op(rq) == REQ_OP_DISCARD) != (req_op(pos) == REQ_OP_DISCARD)) | |
| 369 | + if (req_op(rq) != req_op(pos)) | |
| 370 | 370 | break; |
| 371 | 371 | if (rq_data_dir(rq) != rq_data_dir(pos)) |
| 372 | 372 | break; |
| @@ -1726,6 +1726,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req) · 1725 unmodified lines | ||
| 1726 | 1726 | break; |
| 1727 | 1727 | |
| 1728 | 1728 | if (req_op(next) == REQ_OP_DISCARD || |
| 1729 | + req_op(next) == REQ_OP_SECURE_ERASE || | |
| 1729 | 1730 | req_op(next) == REQ_OP_FLUSH) |
| 1730 | 1731 | break; |
| 1731 | 1732 | |
| @@ -33,7 +33,8 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) · 32 unmodified lines | ||
| 33 | 33 | /* |
| 34 | 34 | * We only like normal block requests and discards. |
| 35 | 35 | */ |
| 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) { | |
| 37 | 38 | blk_dump_rq_flags(req, "MMC bad request"); |
| 38 | 39 | return BLKPREP_KILL; |
| 39 | 40 | } |
| @@ -4,7 +4,9 @@ · 3 unmodified lines | ||
| 4 | 4 | static inline bool mmc_req_is_special(struct request *req) |
| 5 | 5 | { |
| 6 | 6 | 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); | |
| 8 | 10 | } |
| 9 | 11 | |
| 10 | 12 | struct request; |
| @@ -71,7 +71,8 @@ static inline bool bio_has_data(struct bio *bio) · 70 unmodified lines | ||
| 71 | 71 | { |
| 72 | 72 | if (bio && |
| 73 | 73 | 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) | |
| 75 | 76 | return true; |
| 76 | 77 | |
| 77 | 78 | return false; |
| @@ -79,7 +80,9 @@ static inline bool bio_has_data(struct bio *bio) · 1 unmodified line | ||
| 79 | 80 | |
| 80 | 81 | static inline bool bio_no_advance_iter(struct bio *bio) |
| 81 | 82 | { |
| 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; | |
| 83 | 86 | } |
| 84 | 87 | |
| 85 | 88 | static inline bool bio_is_rw(struct bio *bio) |
| @@ -199,6 +202,9 @@ static inline unsigned bio_segments(struct bio *bio) · 113 unmodified lines | ||
| 199 | 202 | if (bio_op(bio) == REQ_OP_DISCARD) |
| 200 | 203 | return 1; |
| 201 | 204 | |
| 205 | + if (bio_op(bio) == REQ_OP_SECURE_ERASE) | |
| 206 | + return 1; | |
| 207 | + | |
| 202 | 208 | if (bio_op(bio) == REQ_OP_WRITE_SAME) |
| 203 | 209 | return 1; |
| 204 | 210 | |
| @@ -882,7 +882,7 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq) · 881 unmodified lines | ||
| 882 | 882 | static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q, |
| 883 | 883 | int op) |
| 884 | 884 | { |
| 885 | − if (unlikely(op == REQ_OP_DISCARD)) | |
| 885 | + if (unlikely(op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE)) | |
| 886 | 886 | return min(q->limits.max_discard_sectors, UINT_MAX >> 9); |
| 887 | 887 | |
| 888 | 888 | if (unlikely(op == REQ_OP_WRITE_SAME)) |
| @@ -913,7 +913,9 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq, · 24 unmodified lines | ||
| 913 | 913 | if (unlikely(rq->cmd_type != REQ_TYPE_FS)) |
| 914 | 914 | return q->limits.max_hw_sectors; |
| 915 | 915 | |
| 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) | |
| 917 | 919 | return blk_queue_get_max_sectors(q, req_op(rq)); |
| 918 | 920 | |
| 919 | 921 | return min(blk_max_size_offset(q, offset), |
| @@ -223,7 +223,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, · 222 unmodified lines | ||
| 223 | 223 | what |= MASK_TC_BIT(op_flags, META); |
| 224 | 224 | what |= MASK_TC_BIT(op_flags, PREFLUSH); |
| 225 | 225 | what |= MASK_TC_BIT(op_flags, FUA); |
| 226 | − if (op == REQ_OP_DISCARD) | |
| 226 | + if (op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE) | |
| 227 | 227 | what |= BLK_TC_ACT(BLK_TC_DISCARD); |
| 228 | 228 | if (op == REQ_OP_FLUSH) |
| 229 | 229 | what |= BLK_TC_ACT(BLK_TC_FLUSH); |