linux/drivers/nvme/target/zns.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * NVMe ZNS-ZBD command implementation.
   4 * Copyright (C) 2021 Western Digital Corporation or its affiliates.
   5 */
   6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   7#include <linux/nvme.h>
   8#include <linux/blkdev.h>
   9#include "nvmet.h"
  10
  11/*
  12 * We set the Memory Page Size Minimum (MPSMIN) for target controller to 0
  13 * which gets added by 12 in the nvme_enable_ctrl() which results in 2^12 = 4k
  14 * as page_shift value. When calculating the ZASL use shift by 12.
  15 */
  16#define NVMET_MPSMIN_SHIFT      12
  17
  18static inline u8 nvmet_zasl(unsigned int zone_append_sects)
  19{
  20        /*
  21         * Zone Append Size Limit (zasl) is expressed as a power of 2 value
  22         * with the minimum memory page size (i.e. 12) as unit.
  23         */
  24        return ilog2(zone_append_sects >> (NVMET_MPSMIN_SHIFT - 9));
  25}
  26
  27static int validate_conv_zones_cb(struct blk_zone *z,
  28                                  unsigned int i, void *data)
  29{
  30        if (z->type == BLK_ZONE_TYPE_CONVENTIONAL)
  31                return -EOPNOTSUPP;
  32        return 0;
  33}
  34
  35bool nvmet_bdev_zns_enable(struct nvmet_ns *ns)
  36{
  37        struct request_queue *q = ns->bdev->bd_disk->queue;
  38        u8 zasl = nvmet_zasl(queue_max_zone_append_sectors(q));
  39        struct gendisk *bd_disk = ns->bdev->bd_disk;
  40        int ret;
  41
  42        if (ns->subsys->zasl) {
  43                if (ns->subsys->zasl > zasl)
  44                        return false;
  45        }
  46        ns->subsys->zasl = zasl;
  47
  48        /*
  49         * Generic zoned block devices may have a smaller last zone which is
  50         * not supported by ZNS. Exclude zoned drives that have such smaller
  51         * last zone.
  52         */
  53        if (get_capacity(bd_disk) & (bdev_zone_sectors(ns->bdev) - 1))
  54                return false;
  55        /*
  56         * ZNS does not define a conventional zone type. If the underlying
  57         * device has a bitmap set indicating the existence of conventional
  58         * zones, reject the device. Otherwise, use report zones to detect if
  59         * the device has conventional zones.
  60         */
  61        if (ns->bdev->bd_disk->queue->conv_zones_bitmap)
  62                return false;
  63
  64        ret = blkdev_report_zones(ns->bdev, 0, blkdev_nr_zones(bd_disk),
  65                                  validate_conv_zones_cb, NULL);
  66        if (ret < 0)
  67                return false;
  68
  69        ns->blksize_shift = blksize_bits(bdev_logical_block_size(ns->bdev));
  70
  71        return true;
  72}
  73
  74void nvmet_execute_identify_cns_cs_ctrl(struct nvmet_req *req)
  75{
  76        u8 zasl = req->sq->ctrl->subsys->zasl;
  77        struct nvmet_ctrl *ctrl = req->sq->ctrl;
  78        struct nvme_id_ctrl_zns *id;
  79        u16 status;
  80
  81        id = kzalloc(sizeof(*id), GFP_KERNEL);
  82        if (!id) {
  83                status = NVME_SC_INTERNAL;
  84                goto out;
  85        }
  86
  87        if (ctrl->ops->get_mdts)
  88                id->zasl = min_t(u8, ctrl->ops->get_mdts(ctrl), zasl);
  89        else
  90                id->zasl = zasl;
  91
  92        status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));
  93
  94        kfree(id);
  95out:
  96        nvmet_req_complete(req, status);
  97}
  98
  99void nvmet_execute_identify_cns_cs_ns(struct nvmet_req *req)
 100{
 101        struct nvme_id_ns_zns *id_zns;
 102        u64 zsze;
 103        u16 status;
 104
 105        if (le32_to_cpu(req->cmd->identify.nsid) == NVME_NSID_ALL) {
 106                req->error_loc = offsetof(struct nvme_identify, nsid);
 107                status = NVME_SC_INVALID_NS | NVME_SC_DNR;
 108                goto out;
 109        }
 110
 111        id_zns = kzalloc(sizeof(*id_zns), GFP_KERNEL);
 112        if (!id_zns) {
 113                status = NVME_SC_INTERNAL;
 114                goto out;
 115        }
 116
 117        status = nvmet_req_find_ns(req);
 118        if (status)
 119                goto done;
 120
 121        if (!bdev_is_zoned(req->ns->bdev)) {
 122                req->error_loc = offsetof(struct nvme_identify, nsid);
 123                goto done;
 124        }
 125
 126        nvmet_ns_revalidate(req->ns);
 127        zsze = (bdev_zone_sectors(req->ns->bdev) << 9) >>
 128                                        req->ns->blksize_shift;
 129        id_zns->lbafe[0].zsze = cpu_to_le64(zsze);
 130        id_zns->mor = cpu_to_le32(bdev_max_open_zones(req->ns->bdev));
 131        id_zns->mar = cpu_to_le32(bdev_max_active_zones(req->ns->bdev));
 132
 133done:
 134        status = nvmet_copy_to_sgl(req, 0, id_zns, sizeof(*id_zns));
 135        kfree(id_zns);
 136out:
 137        nvmet_req_complete(req, status);
 138}
 139
 140static u16 nvmet_bdev_validate_zone_mgmt_recv(struct nvmet_req *req)
 141{
 142        sector_t sect = nvmet_lba_to_sect(req->ns, req->cmd->zmr.slba);
 143        u32 out_bufsize = (le32_to_cpu(req->cmd->zmr.numd) + 1) << 2;
 144
 145        if (sect >= get_capacity(req->ns->bdev->bd_disk)) {
 146                req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, slba);
 147                return NVME_SC_LBA_RANGE | NVME_SC_DNR;
 148        }
 149
 150        if (out_bufsize < sizeof(struct nvme_zone_report)) {
 151                req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, numd);
 152                return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
 153        }
 154
 155        if (req->cmd->zmr.zra != NVME_ZRA_ZONE_REPORT) {
 156                req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, zra);
 157                return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
 158        }
 159
 160        switch (req->cmd->zmr.pr) {
 161        case 0:
 162        case 1:
 163                break;
 164        default:
 165                req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, pr);
 166                return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
 167        }
 168
 169        switch (req->cmd->zmr.zrasf) {
 170        case NVME_ZRASF_ZONE_REPORT_ALL:
 171        case NVME_ZRASF_ZONE_STATE_EMPTY:
 172        case NVME_ZRASF_ZONE_STATE_IMP_OPEN:
 173        case NVME_ZRASF_ZONE_STATE_EXP_OPEN:
 174        case NVME_ZRASF_ZONE_STATE_CLOSED:
 175        case NVME_ZRASF_ZONE_STATE_FULL:
 176        case NVME_ZRASF_ZONE_STATE_READONLY:
 177        case NVME_ZRASF_ZONE_STATE_OFFLINE:
 178                break;
 179        default:
 180                req->error_loc =
 181                        offsetof(struct nvme_zone_mgmt_recv_cmd, zrasf);
 182                return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
 183        }
 184
 185        return NVME_SC_SUCCESS;
 186}
 187
 188struct nvmet_report_zone_data {
 189        struct nvmet_req *req;
 190        u64 out_buf_offset;
 191        u64 out_nr_zones;
 192        u64 nr_zones;
 193        u8 zrasf;
 194};
 195
 196static int nvmet_bdev_report_zone_cb(struct blk_zone *z, unsigned i, void *d)
 197{
 198        static const unsigned int nvme_zrasf_to_blk_zcond[] = {
 199                [NVME_ZRASF_ZONE_STATE_EMPTY]    = BLK_ZONE_COND_EMPTY,
 200                [NVME_ZRASF_ZONE_STATE_IMP_OPEN] = BLK_ZONE_COND_IMP_OPEN,
 201                [NVME_ZRASF_ZONE_STATE_EXP_OPEN] = BLK_ZONE_COND_EXP_OPEN,
 202                [NVME_ZRASF_ZONE_STATE_CLOSED]   = BLK_ZONE_COND_CLOSED,
 203                [NVME_ZRASF_ZONE_STATE_READONLY] = BLK_ZONE_COND_READONLY,
 204                [NVME_ZRASF_ZONE_STATE_FULL]     = BLK_ZONE_COND_FULL,
 205                [NVME_ZRASF_ZONE_STATE_OFFLINE]  = BLK_ZONE_COND_OFFLINE,
 206        };
 207        struct nvmet_report_zone_data *rz = d;
 208
 209        if (rz->zrasf != NVME_ZRASF_ZONE_REPORT_ALL &&
 210            z->cond != nvme_zrasf_to_blk_zcond[rz->zrasf])
 211                return 0;
 212
 213        if (rz->nr_zones < rz->out_nr_zones) {
 214                struct nvme_zone_descriptor zdesc = { };
 215                u16 status;
 216
 217                zdesc.zcap = nvmet_sect_to_lba(rz->req->ns, z->capacity);
 218                zdesc.zslba = nvmet_sect_to_lba(rz->req->ns, z->start);
 219                zdesc.wp = nvmet_sect_to_lba(rz->req->ns, z->wp);
 220                zdesc.za = z->reset ? 1 << 2 : 0;
 221                zdesc.zs = z->cond << 4;
 222                zdesc.zt = z->type;
 223
 224                status = nvmet_copy_to_sgl(rz->req, rz->out_buf_offset, &zdesc,
 225                                           sizeof(zdesc));
 226                if (status)
 227                        return -EINVAL;
 228
 229                rz->out_buf_offset += sizeof(zdesc);
 230        }
 231
 232        rz->nr_zones++;
 233
 234        return 0;
 235}
 236
 237static unsigned long nvmet_req_nr_zones_from_slba(struct nvmet_req *req)
 238{
 239        unsigned int sect = nvmet_lba_to_sect(req->ns, req->cmd->zmr.slba);
 240
 241        return blkdev_nr_zones(req->ns->bdev->bd_disk) -
 242                (sect >> ilog2(bdev_zone_sectors(req->ns->bdev)));
 243}
 244
 245static unsigned long get_nr_zones_from_buf(struct nvmet_req *req, u32 bufsize)
 246{
 247        if (bufsize <= sizeof(struct nvme_zone_report))
 248                return 0;
 249
 250        return (bufsize - sizeof(struct nvme_zone_report)) /
 251                sizeof(struct nvme_zone_descriptor);
 252}
 253
 254static void nvmet_bdev_zone_zmgmt_recv_work(struct work_struct *w)
 255{
 256        struct nvmet_req *req = container_of(w, struct nvmet_req, z.zmgmt_work);
 257        sector_t start_sect = nvmet_lba_to_sect(req->ns, req->cmd->zmr.slba);
 258        unsigned long req_slba_nr_zones = nvmet_req_nr_zones_from_slba(req);
 259        u32 out_bufsize = (le32_to_cpu(req->cmd->zmr.numd) + 1) << 2;
 260        __le64 nr_zones;
 261        u16 status;
 262        int ret;
 263        struct nvmet_report_zone_data rz_data = {
 264                .out_nr_zones = get_nr_zones_from_buf(req, out_bufsize),
 265                /* leave the place for report zone header */
 266                .out_buf_offset = sizeof(struct nvme_zone_report),
 267                .zrasf = req->cmd->zmr.zrasf,
 268                .nr_zones = 0,
 269                .req = req,
 270        };
 271
 272        status = nvmet_bdev_validate_zone_mgmt_recv(req);
 273        if (status)
 274                goto out;
 275
 276        if (!req_slba_nr_zones) {
 277                status = NVME_SC_SUCCESS;
 278                goto out;
 279        }
 280
 281        ret = blkdev_report_zones(req->ns->bdev, start_sect, req_slba_nr_zones,
 282                                 nvmet_bdev_report_zone_cb, &rz_data);
 283        if (ret < 0) {
 284                status = NVME_SC_INTERNAL;
 285                goto out;
 286        }
 287
 288        /*
 289         * When partial bit is set nr_zones must indicate the number of zone
 290         * descriptors actually transferred.
 291         */
 292        if (req->cmd->zmr.pr)
 293                rz_data.nr_zones = min(rz_data.nr_zones, rz_data.out_nr_zones);
 294
 295        nr_zones = cpu_to_le64(rz_data.nr_zones);
 296        status = nvmet_copy_to_sgl(req, 0, &nr_zones, sizeof(nr_zones));
 297
 298out:
 299        nvmet_req_complete(req, status);
 300}
 301
 302void nvmet_bdev_execute_zone_mgmt_recv(struct nvmet_req *req)
 303{
 304        INIT_WORK(&req->z.zmgmt_work, nvmet_bdev_zone_zmgmt_recv_work);
 305        queue_work(zbd_wq, &req->z.zmgmt_work);
 306}
 307
 308static inline enum req_opf zsa_req_op(u8 zsa)
 309{
 310        switch (zsa) {
 311        case NVME_ZONE_OPEN:
 312                return REQ_OP_ZONE_OPEN;
 313        case NVME_ZONE_CLOSE:
 314                return REQ_OP_ZONE_CLOSE;
 315        case NVME_ZONE_FINISH:
 316                return REQ_OP_ZONE_FINISH;
 317        case NVME_ZONE_RESET:
 318                return REQ_OP_ZONE_RESET;
 319        default:
 320                return REQ_OP_LAST;
 321        }
 322}
 323
 324static u16 blkdev_zone_mgmt_errno_to_nvme_status(int ret)
 325{
 326        switch (ret) {
 327        case 0:
 328                return NVME_SC_SUCCESS;
 329        case -EINVAL:
 330        case -EIO:
 331                return NVME_SC_ZONE_INVALID_TRANSITION | NVME_SC_DNR;
 332        default:
 333                return NVME_SC_INTERNAL;
 334        }
 335}
 336
 337struct nvmet_zone_mgmt_send_all_data {
 338        unsigned long *zbitmap;
 339        struct nvmet_req *req;
 340};
 341
 342static int zmgmt_send_scan_cb(struct blk_zone *z, unsigned i, void *d)
 343{
 344        struct nvmet_zone_mgmt_send_all_data *data = d;
 345
 346        switch (zsa_req_op(data->req->cmd->zms.zsa)) {
 347        case REQ_OP_ZONE_OPEN:
 348                switch (z->cond) {
 349                case BLK_ZONE_COND_CLOSED:
 350                        break;
 351                default:
 352                        return 0;
 353                }
 354                break;
 355        case REQ_OP_ZONE_CLOSE:
 356                switch (z->cond) {
 357                case BLK_ZONE_COND_IMP_OPEN:
 358                case BLK_ZONE_COND_EXP_OPEN:
 359                        break;
 360                default:
 361                        return 0;
 362                }
 363                break;
 364        case REQ_OP_ZONE_FINISH:
 365                switch (z->cond) {
 366                case BLK_ZONE_COND_IMP_OPEN:
 367                case BLK_ZONE_COND_EXP_OPEN:
 368                case BLK_ZONE_COND_CLOSED:
 369                        break;
 370                default:
 371                        return 0;
 372                }
 373                break;
 374        default:
 375                return -EINVAL;
 376        }
 377
 378        set_bit(i, data->zbitmap);
 379
 380        return 0;
 381}
 382
 383static u16 nvmet_bdev_zone_mgmt_emulate_all(struct nvmet_req *req)
 384{
 385        struct block_device *bdev = req->ns->bdev;
 386        unsigned int nr_zones = blkdev_nr_zones(bdev->bd_disk);
 387        struct request_queue *q = bdev_get_queue(bdev);
 388        struct bio *bio = NULL;
 389        sector_t sector = 0;
 390        int ret;
 391        struct nvmet_zone_mgmt_send_all_data d = {
 392                .req = req,
 393        };
 394
 395        d.zbitmap = kcalloc_node(BITS_TO_LONGS(nr_zones), sizeof(*(d.zbitmap)),
 396                                 GFP_NOIO, q->node);
 397        if (!d.zbitmap) {
 398                ret = -ENOMEM;
 399                goto out;
 400        }
 401
 402        /* Scan and build bitmap of the eligible zones */
 403        ret = blkdev_report_zones(bdev, 0, nr_zones, zmgmt_send_scan_cb, &d);
 404        if (ret != nr_zones) {
 405                if (ret > 0)
 406                        ret = -EIO;
 407                goto out;
 408        } else {
 409                /* We scanned all the zones */
 410                ret = 0;
 411        }
 412
 413        while (sector < get_capacity(bdev->bd_disk)) {
 414                if (test_bit(blk_queue_zone_no(q, sector), d.zbitmap)) {
 415                        bio = blk_next_bio(bio, 0, GFP_KERNEL);
 416                        bio->bi_opf = zsa_req_op(req->cmd->zms.zsa) | REQ_SYNC;
 417                        bio->bi_iter.bi_sector = sector;
 418                        bio_set_dev(bio, bdev);
 419                        /* This may take a while, so be nice to others */
 420                        cond_resched();
 421                }
 422                sector += blk_queue_zone_sectors(q);
 423        }
 424
 425        if (bio) {
 426                ret = submit_bio_wait(bio);
 427                bio_put(bio);
 428        }
 429
 430out:
 431        kfree(d.zbitmap);
 432
 433        return blkdev_zone_mgmt_errno_to_nvme_status(ret);
 434}
 435
 436static u16 nvmet_bdev_execute_zmgmt_send_all(struct nvmet_req *req)
 437{
 438        int ret;
 439
 440        switch (zsa_req_op(req->cmd->zms.zsa)) {
 441        case REQ_OP_ZONE_RESET:
 442                ret = blkdev_zone_mgmt(req->ns->bdev, REQ_OP_ZONE_RESET, 0,
 443                                       get_capacity(req->ns->bdev->bd_disk),
 444                                       GFP_KERNEL);
 445                if (ret < 0)
 446                        return blkdev_zone_mgmt_errno_to_nvme_status(ret);
 447                break;
 448        case REQ_OP_ZONE_OPEN:
 449        case REQ_OP_ZONE_CLOSE:
 450        case REQ_OP_ZONE_FINISH:
 451                return nvmet_bdev_zone_mgmt_emulate_all(req);
 452        default:
 453                /* this is needed to quiet compiler warning */
 454                req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, zsa);
 455                return NVME_SC_INVALID_FIELD | NVME_SC_DNR;
 456        }
 457
 458        return NVME_SC_SUCCESS;
 459}
 460
 461static void nvmet_bdev_zmgmt_send_work(struct work_struct *w)
 462{
 463        struct nvmet_req *req = container_of(w, struct nvmet_req, z.zmgmt_work);
 464        sector_t sect = nvmet_lba_to_sect(req->ns, req->cmd->zms.slba);
 465        enum req_opf op = zsa_req_op(req->cmd->zms.zsa);
 466        struct block_device *bdev = req->ns->bdev;
 467        sector_t zone_sectors = bdev_zone_sectors(bdev);
 468        u16 status = NVME_SC_SUCCESS;
 469        int ret;
 470
 471        if (op == REQ_OP_LAST) {
 472                req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, zsa);
 473                status = NVME_SC_ZONE_INVALID_TRANSITION | NVME_SC_DNR;
 474                goto out;
 475        }
 476
 477        /* when select all bit is set slba field is ignored */
 478        if (req->cmd->zms.select_all) {
 479                status = nvmet_bdev_execute_zmgmt_send_all(req);
 480                goto out;
 481        }
 482
 483        if (sect >= get_capacity(bdev->bd_disk)) {
 484                req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, slba);
 485                status = NVME_SC_LBA_RANGE | NVME_SC_DNR;
 486                goto out;
 487        }
 488
 489        if (sect & (zone_sectors - 1)) {
 490                req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, slba);
 491                status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
 492                goto out;
 493        }
 494
 495        ret = blkdev_zone_mgmt(bdev, op, sect, zone_sectors, GFP_KERNEL);
 496        if (ret < 0)
 497                status = blkdev_zone_mgmt_errno_to_nvme_status(ret);
 498
 499out:
 500        nvmet_req_complete(req, status);
 501}
 502
 503void nvmet_bdev_execute_zone_mgmt_send(struct nvmet_req *req)
 504{
 505        INIT_WORK(&req->z.zmgmt_work, nvmet_bdev_zmgmt_send_work);
 506        queue_work(zbd_wq, &req->z.zmgmt_work);
 507}
 508
 509static void nvmet_bdev_zone_append_bio_done(struct bio *bio)
 510{
 511        struct nvmet_req *req = bio->bi_private;
 512
 513        if (bio->bi_status == BLK_STS_OK) {
 514                req->cqe->result.u64 =
 515                        nvmet_sect_to_lba(req->ns, bio->bi_iter.bi_sector);
 516        }
 517
 518        nvmet_req_complete(req, blk_to_nvme_status(req, bio->bi_status));
 519        nvmet_req_bio_put(req, bio);
 520}
 521
 522void nvmet_bdev_execute_zone_append(struct nvmet_req *req)
 523{
 524        sector_t sect = nvmet_lba_to_sect(req->ns, req->cmd->rw.slba);
 525        u16 status = NVME_SC_SUCCESS;
 526        unsigned int total_len = 0;
 527        struct scatterlist *sg;
 528        struct bio *bio;
 529        int sg_cnt;
 530
 531        /* Request is completed on len mismatch in nvmet_check_transter_len() */
 532        if (!nvmet_check_transfer_len(req, nvmet_rw_data_len(req)))
 533                return;
 534
 535        if (!req->sg_cnt) {
 536                nvmet_req_complete(req, 0);
 537                return;
 538        }
 539
 540        if (sect >= get_capacity(req->ns->bdev->bd_disk)) {
 541                req->error_loc = offsetof(struct nvme_rw_command, slba);
 542                status = NVME_SC_LBA_RANGE | NVME_SC_DNR;
 543                goto out;
 544        }
 545
 546        if (sect & (bdev_zone_sectors(req->ns->bdev) - 1)) {
 547                req->error_loc = offsetof(struct nvme_rw_command, slba);
 548                status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
 549                goto out;
 550        }
 551
 552        if (nvmet_use_inline_bvec(req)) {
 553                bio = &req->z.inline_bio;
 554                bio_init(bio, req->inline_bvec, ARRAY_SIZE(req->inline_bvec));
 555        } else {
 556                bio = bio_alloc(GFP_KERNEL, req->sg_cnt);
 557        }
 558
 559        bio->bi_opf = REQ_OP_ZONE_APPEND | REQ_SYNC | REQ_IDLE;
 560        bio->bi_end_io = nvmet_bdev_zone_append_bio_done;
 561        bio_set_dev(bio, req->ns->bdev);
 562        bio->bi_iter.bi_sector = sect;
 563        bio->bi_private = req;
 564        if (req->cmd->rw.control & cpu_to_le16(NVME_RW_FUA))
 565                bio->bi_opf |= REQ_FUA;
 566
 567        for_each_sg(req->sg, sg, req->sg_cnt, sg_cnt) {
 568                struct page *p = sg_page(sg);
 569                unsigned int l = sg->length;
 570                unsigned int o = sg->offset;
 571                unsigned int ret;
 572
 573                ret = bio_add_zone_append_page(bio, p, l, o);
 574                if (ret != sg->length) {
 575                        status = NVME_SC_INTERNAL;
 576                        goto out_put_bio;
 577                }
 578                total_len += sg->length;
 579        }
 580
 581        if (total_len != nvmet_rw_data_len(req)) {
 582                status = NVME_SC_INTERNAL | NVME_SC_DNR;
 583                goto out_put_bio;
 584        }
 585
 586        submit_bio(bio);
 587        return;
 588
 589out_put_bio:
 590        nvmet_req_bio_put(req, bio);
 591out:
 592        nvmet_req_complete(req, status);
 593}
 594
 595u16 nvmet_bdev_zns_parse_io_cmd(struct nvmet_req *req)
 596{
 597        struct nvme_command *cmd = req->cmd;
 598
 599        switch (cmd->common.opcode) {
 600        case nvme_cmd_zone_append:
 601                req->execute = nvmet_bdev_execute_zone_append;
 602                return 0;
 603        case nvme_cmd_zone_mgmt_recv:
 604                req->execute = nvmet_bdev_execute_zone_mgmt_recv;
 605                return 0;
 606        case nvme_cmd_zone_mgmt_send:
 607                req->execute = nvmet_bdev_execute_zone_mgmt_send;
 608                return 0;
 609        default:
 610                return nvmet_bdev_parse_io_cmd(req);
 611        }
 612}
 613