Pull block fixes from Jens Axboe: "A few fixes that should go into this round. This pull request contains two NVMe fixes via Keith, removal of a dead function, and a fix for the bio op for read truncates (Ming)" * tag 'block-5.5-2020-01-10' of git://git.kernel.dk/linux-block: nvmet: fix per feat data len for get_feature nvme: Translate more status codes to blk_status_t fs: move guard_bio_eod() after bio_set_op_attrs block: remove unused mp_bvec_last_segment
Unified · Split
| @@ -538,6 +538,16 @@ void zero_fill_bio_iter(struct bio *bio, struct bvec_iter start) · 537 unmodified lines | ||
| 538 | 538 | } |
| 539 | 539 | EXPORT_SYMBOL(zero_fill_bio_iter); |
| 540 | 540 | |
| 541 | +/** | |
| 542 | + * bio_truncate - truncate the bio to small size of @new_size | |
| 543 | + * @bio: the bio to be truncated | |
| 544 | + * @new_size: new size for truncating the bio | |
| 545 | + * | |
| 546 | + * Description: | |
| 547 | + * Truncate the bio to new size of @new_size. If bio_op(bio) is | |
| 548 | + * REQ_OP_READ, zero the truncated part. This function should only | |
| 549 | + * be used for handling corner cases, such as bio eod. | |
| 550 | + */ | |
| 541 | 551 | void bio_truncate(struct bio *bio, unsigned new_size) |
| 542 | 552 | { |
| 543 | 553 | struct bio_vec bv; |
| @@ -548,7 +558,7 @@ void bio_truncate(struct bio *bio, unsigned new_size) · 4 unmodified lines | ||
| 548 | 558 | if (new_size >= bio->bi_iter.bi_size) |
| 549 | 559 | return; |
| 550 | 560 | |
| 551 | − if (bio_data_dir(bio) != READ) | |
| 561 | + if (bio_op(bio) != REQ_OP_READ) | |
| 552 | 562 | goto exit; |
| 553 | 563 | |
| 554 | 564 | bio_for_each_segment(bv, bio, iter) { |
| @@ -222,6 +222,8 @@ static blk_status_t nvme_error_status(u16 status) · 221 unmodified lines | ||
| 222 | 222 | case NVME_SC_CAP_EXCEEDED: |
| 223 | 223 | return BLK_STS_NOSPC; |
| 224 | 224 | case NVME_SC_LBA_RANGE: |
| 225 | + case NVME_SC_CMD_INTERRUPTED: | |
| 226 | + case NVME_SC_NS_NOT_READY: | |
| 225 | 227 | return BLK_STS_TARGET; |
| 226 | 228 | case NVME_SC_BAD_ATTRIBUTES: |
| 227 | 229 | case NVME_SC_ONCS_NOT_SUPPORTED: |
| @@ -24,6 +24,16 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd) · 23 unmodified lines | ||
| 24 | 24 | return len; |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | +static u32 nvmet_feat_data_len(struct nvmet_req *req, u32 cdw10) | |
| 28 | +{ | |
| 29 | + switch (cdw10 & 0xff) { | |
| 30 | + case NVME_FEAT_HOST_ID: | |
| 31 | + return sizeof(req->sq->ctrl->hostid); | |
| 32 | + default: | |
| 33 | + return 0; | |
| 34 | + } | |
| 35 | +} | |
| 36 | + | |
| 27 | 37 | u64 nvmet_get_log_page_offset(struct nvme_command *cmd) |
| 28 | 38 | { |
| 29 | 39 | return le64_to_cpu(cmd->get_log_page.lpo); |
| @@ -778,7 +788,7 @@ static void nvmet_execute_get_features(struct nvmet_req *req) · 748 unmodified lines | ||
| 778 | 788 | u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10); |
| 779 | 789 | u16 status = 0; |
| 780 | 790 | |
| 781 | − if (!nvmet_check_data_len(req, 0)) | |
| 791 | + if (!nvmet_check_data_len(req, nvmet_feat_data_len(req, cdw10))) | |
| 782 | 792 | return; |
| 783 | 793 | |
| 784 | 794 | switch (cdw10 & 0xff) { |
| @@ -3031,7 +3031,7 @@ static void end_bio_bh_io_sync(struct bio *bio) · 3030 unmodified lines | ||
| 3031 | 3031 | * errors, this only handles the "we need to be able to |
| 3032 | 3032 | * do IO at the final sector" case. |
| 3033 | 3033 | */ |
| 3034 | −void guard_bio_eod(int op, struct bio *bio) | |
| 3034 | +void guard_bio_eod(struct bio *bio) | |
| 3035 | 3035 | { |
| 3036 | 3036 | sector_t maxsector; |
| 3037 | 3037 | struct hd_struct *part; |
| @@ -3095,15 +3095,15 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, · 57 unmodified lines | ||
| 3095 | 3095 | bio->bi_end_io = end_bio_bh_io_sync; |
| 3096 | 3096 | bio->bi_private = bh; |
| 3097 | 3097 | |
| 3098 | − /* Take care of bh's that straddle the end of the device */ | |
| 3099 | − guard_bio_eod(op, bio); | |
| 3100 | − | |
| 3101 | 3098 | if (buffer_meta(bh)) |
| 3102 | 3099 | op_flags |= REQ_META; |
| 3103 | 3100 | if (buffer_prio(bh)) |
| 3104 | 3101 | op_flags |= REQ_PRIO; |
| 3105 | 3102 | bio_set_op_attrs(bio, op, op_flags); |
| 3106 | 3103 | |
| 3104 | + /* Take care of bh's that straddle the end of the device */ | |
| 3105 | + guard_bio_eod(bio); | |
| 3106 | + | |
| 3107 | 3107 | if (wbc) { |
| 3108 | 3108 | wbc_init_bio(wbc, bio); |
| 3109 | 3109 | wbc_account_cgroup_owner(wbc, bh->b_page, bh->b_size); |
| @@ -38,7 +38,7 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait) · 37 unmodified lines | ||
| 38 | 38 | /* |
| 39 | 39 | * buffer.c |
| 40 | 40 | */ |
| 41 | −extern void guard_bio_eod(int rw, struct bio *bio); | |
| 41 | +extern void guard_bio_eod(struct bio *bio); | |
| 42 | 42 | extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len, |
| 43 | 43 | get_block_t *get_block, struct iomap *iomap); |
| 44 | 44 | |
| @@ -62,7 +62,7 @@ static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio) · 61 unmodified lines | ||
| 62 | 62 | { |
| 63 | 63 | bio->bi_end_io = mpage_end_io; |
| 64 | 64 | bio_set_op_attrs(bio, op, op_flags); |
| 65 | − guard_bio_eod(op, bio); | |
| 65 | + guard_bio_eod(bio); | |
| 66 | 66 | submit_bio(bio); |
| 67 | 67 | return NULL; |
| 68 | 68 | } |
| @@ -153,26 +153,4 @@ static inline void bvec_advance(const struct bio_vec *bvec, · 152 unmodified lines | ||
| 153 | 153 | } |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | −/* | |
| 157 | − * Get the last single-page segment from the multi-page bvec and store it | |
| 158 | − * in @seg | |
| 159 | − */ | |
| 160 | −static inline void mp_bvec_last_segment(const struct bio_vec *bvec, | |
| 161 | − struct bio_vec *seg) | |
| 162 | −{ | |
| 163 | − unsigned total = bvec->bv_offset + bvec->bv_len; | |
| 164 | − unsigned last_page = (total - 1) / PAGE_SIZE; | |
| 165 | − | |
| 166 | − seg->bv_page = bvec->bv_page + last_page; | |
| 167 | − | |
| 168 | − /* the whole segment is inside the last page */ | |
| 169 | − if (bvec->bv_offset >= last_page * PAGE_SIZE) { | |
| 170 | − seg->bv_offset = bvec->bv_offset % PAGE_SIZE; | |
| 171 | − seg->bv_len = bvec->bv_len; | |
| 172 | − } else { | |
| 173 | − seg->bv_offset = 0; | |
| 174 | − seg->bv_len = total - last_page * PAGE_SIZE; | |
| 175 | − } | |
| 176 | −} | |
| 177 | − | |
| 178 | 156 | #endif /* __LINUX_BVEC_ITER_H */ |