1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/vmalloc.h> 3 #include <linux/bitmap.h> 4 #include "null_blk.h" 5 6 #define CREATE_TRACE_POINTS 7 #include "trace.h" 8 9 #undef pr_fmt 10 #define pr_fmt(fmt) "null_blk: " fmt 11 12 #define NULL_ZONE_INVALID_WP ((sector_t)-1) 13 14 static inline sector_t mb_to_sects(unsigned long mb) 15 { 16 return ((sector_t)mb * SZ_1M) >> SECTOR_SHIFT; 17 } 18 19 static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect) 20 { 21 return sect >> ilog2(dev->zone_size_sects); 22 } 23 24 static inline void null_init_zone_lock(struct nullb_device *dev, 25 struct nullb_zone *zone) 26 { 27 if (!dev->memory_backed) 28 spin_lock_init(&zone->spinlock); 29 else 30 mutex_init(&zone->mutex); 31 } 32 33 static inline void null_lock_zone(struct nullb_device *dev, 34 struct nullb_zone *zone) 35 { 36 if (!dev->memory_backed) 37 spin_lock_irq(&zone->spinlock); 38 else 39 mutex_lock(&zone->mutex); 40 } 41 42 static inline void null_unlock_zone(struct nullb_device *dev, 43 struct nullb_zone *zone) 44 { 45 if (!dev->memory_backed) 46 spin_unlock_irq(&zone->spinlock); 47 else 48 mutex_unlock(&zone->mutex); 49 } 50 51 int null_init_zoned_dev(struct nullb_device *dev, 52 struct queue_limits *lim) 53 { 54 sector_t dev_capacity_sects, zone_capacity_sects; 55 struct nullb_zone *zone; 56 sector_t sector = 0; 57 unsigned int i; 58 59 if (!is_power_of_2(dev->zone_size)) { 60 pr_err("zone_size must be power-of-two\n"); 61 return -EINVAL; 62 } 63 if (dev->zone_size > dev->size) { 64 pr_err("Zone size larger than device capacity\n"); 65 return -EINVAL; 66 } 67 68 if (!dev->zone_capacity) 69 dev->zone_capacity = dev->zone_size; 70 71 if (dev->zone_capacity > dev->zone_size) { 72 pr_err("zone capacity (%lu MB) larger than zone size (%lu MB)\n", 73 dev->zone_capacity, dev->zone_size); 74 return -EINVAL; 75 } 76 77 /* 78 * If a smaller zone capacity was requested, do not allow a smaller last 79 * zone at the same time as such zone configuration does not correspond 80 * to any real zoned device. 81 */ 82 if (dev->zone_capacity != dev->zone_size && 83 dev->size & (dev->zone_size - 1)) { 84 pr_err("A smaller last zone is not allowed with zone capacity smaller than zone size.\n"); 85 return -EINVAL; 86 } 87 88 zone_capacity_sects = mb_to_sects(dev->zone_capacity); 89 dev_capacity_sects = mb_to_sects(dev->size); 90 dev->zone_size_sects = mb_to_sects(dev->zone_size); 91 dev->nr_zones = round_up(dev_capacity_sects, dev->zone_size_sects) 92 >> ilog2(dev->zone_size_sects); 93 94 dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct nullb_zone), 95 GFP_KERNEL | __GFP_ZERO); 96 if (!dev->zones) 97 return -ENOMEM; 98 99 spin_lock_init(&dev->zone_res_lock); 100 101 if (dev->zone_nr_conv >= dev->nr_zones) { 102 dev->zone_nr_conv = dev->nr_zones - 1; 103 pr_info("changed the number of conventional zones to %u", 104 dev->zone_nr_conv); 105 } 106 107 dev->zone_append_max_sectors = 108 min(ALIGN_DOWN(dev->zone_append_max_sectors, 109 dev->blocksize >> SECTOR_SHIFT), 110 zone_capacity_sects); 111 112 /* Max active zones has to be < nbr of seq zones in order to be enforceable */ 113 if (dev->zone_max_active >= dev->nr_zones - dev->zone_nr_conv) { 114 dev->zone_max_active = 0; 115 pr_info("zone_max_active limit disabled, limit >= zone count\n"); 116 } 117 118 /* Max open zones has to be <= max active zones */ 119 if (dev->zone_max_active && dev->zone_max_open > dev->zone_max_active) { 120 dev->zone_max_open = dev->zone_max_active; 121 pr_info("changed the maximum number of open zones to %u\n", 122 dev->zone_max_open); 123 } else if (dev->zone_max_open >= dev->nr_zones - dev->zone_nr_conv) { 124 dev->zone_max_open = 0; 125 pr_info("zone_max_open limit disabled, limit >= zone count\n"); 126 } 127 dev->need_zone_res_mgmt = dev->zone_max_active || dev->zone_max_open; 128 dev->imp_close_zone_no = dev->zone_nr_conv; 129 130 for (i = 0; i < dev->zone_nr_conv; i++) { 131 zone = &dev->zones[i]; 132 133 null_init_zone_lock(dev, zone); 134 zone->start = sector; 135 zone->len = dev->zone_size_sects; 136 zone->capacity = zone->len; 137 zone->wp = zone->start + zone->len; 138 zone->type = BLK_ZONE_TYPE_CONVENTIONAL; 139 zone->cond = BLK_ZONE_COND_NOT_WP; 140 141 sector += dev->zone_size_sects; 142 } 143 144 for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) { 145 zone = &dev->zones[i]; 146 147 null_init_zone_lock(dev, zone); 148 zone->start = sector; 149 if (zone->start + dev->zone_size_sects > dev_capacity_sects) 150 zone->len = dev_capacity_sects - zone->start; 151 else 152 zone->len = dev->zone_size_sects; 153 zone->capacity = 154 min_t(sector_t, zone->len, zone_capacity_sects); 155 zone->type = BLK_ZONE_TYPE_SEQWRITE_REQ; 156 if (dev->zone_full) { 157 zone->cond = BLK_ZONE_COND_FULL; 158 zone->wp = zone->start + zone->capacity; 159 } else{ 160 zone->cond = BLK_ZONE_COND_EMPTY; 161 zone->wp = zone->start; 162 } 163 164 sector += dev->zone_size_sects; 165 } 166 167 lim->features |= BLK_FEAT_ZONED; 168 lim->chunk_sectors = dev->zone_size_sects; 169 lim->max_hw_zone_append_sectors = dev->zone_append_max_sectors; 170 lim->max_open_zones = dev->zone_max_open; 171 lim->max_active_zones = dev->zone_max_active; 172 return 0; 173 } 174 175 int null_register_zoned_dev(struct nullb *nullb) 176 { 177 struct request_queue *q = nullb->q; 178 struct gendisk *disk = nullb->disk; 179 180 pr_info("%s: using %s zone append\n", 181 disk->disk_name, 182 queue_emulates_zone_append(q) ? "emulated" : "native"); 183 184 return blk_revalidate_disk_zones(disk); 185 } 186 187 void null_free_zoned_dev(struct nullb_device *dev) 188 { 189 kvfree(dev->zones); 190 dev->zones = NULL; 191 } 192 193 int null_report_zones(struct gendisk *disk, sector_t sector, 194 unsigned int nr_zones, report_zones_cb cb, void *data) 195 { 196 struct nullb *nullb = disk->private_data; 197 struct nullb_device *dev = nullb->dev; 198 unsigned int first_zone, i; 199 struct nullb_zone *zone; 200 struct blk_zone blkz; 201 int error; 202 203 first_zone = null_zone_no(dev, sector); 204 if (first_zone >= dev->nr_zones) 205 return 0; 206 207 nr_zones = min(nr_zones, dev->nr_zones - first_zone); 208 trace_nullb_report_zones(nullb, nr_zones); 209 210 memset(&blkz, 0, sizeof(struct blk_zone)); 211 zone = &dev->zones[first_zone]; 212 for (i = 0; i < nr_zones; i++, zone++) { 213 /* 214 * Stacked DM target drivers will remap the zone information by 215 * modifying the zone information passed to the report callback. 216 * So use a local copy to avoid corruption of the device zone 217 * array. 218 */ 219 null_lock_zone(dev, zone); 220 blkz.start = zone->start; 221 blkz.len = zone->len; 222 blkz.wp = zone->wp; 223 blkz.type = zone->type; 224 blkz.cond = zone->cond; 225 blkz.capacity = zone->capacity; 226 null_unlock_zone(dev, zone); 227 228 error = cb(&blkz, i, data); 229 if (error) 230 return error; 231 } 232 233 return nr_zones; 234 } 235 236 /* 237 * This is called in the case of memory backing from null_process_cmd() 238 * with the target zone already locked. 239 */ 240 size_t null_zone_valid_read_len(struct nullb *nullb, 241 sector_t sector, unsigned int len) 242 { 243 struct nullb_device *dev = nullb->dev; 244 struct nullb_zone *zone = &dev->zones[null_zone_no(dev, sector)]; 245 unsigned int nr_sectors = len >> SECTOR_SHIFT; 246 247 /* Read must be below the write pointer position */ 248 if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL || 249 sector + nr_sectors <= zone->wp) 250 return len; 251 252 if (sector > zone->wp) 253 return 0; 254 255 return (zone->wp - sector) << SECTOR_SHIFT; 256 } 257 258 static void null_close_imp_open_zone(struct nullb_device *dev) 259 { 260 struct nullb_zone *zone; 261 unsigned int zno, i; 262 263 zno = dev->imp_close_zone_no; 264 if (zno >= dev->nr_zones) 265 zno = dev->zone_nr_conv; 266 267 for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) { 268 zone = &dev->zones[zno]; 269 zno++; 270 if (zno >= dev->nr_zones) 271 zno = dev->zone_nr_conv; 272 273 if (zone->cond == BLK_ZONE_COND_IMP_OPEN) { 274 dev->nr_zones_imp_open--; 275 if (zone->wp == zone->start) { 276 zone->cond = BLK_ZONE_COND_EMPTY; 277 } else { 278 zone->cond = BLK_ZONE_COND_CLOSED; 279 dev->nr_zones_closed++; 280 } 281 dev->imp_close_zone_no = zno; 282 return; 283 } 284 } 285 } 286 287 static blk_status_t null_check_active(struct nullb_device *dev) 288 { 289 if (!dev->zone_max_active) 290 return BLK_STS_OK; 291 292 if (dev->nr_zones_exp_open + dev->nr_zones_imp_open + 293 dev->nr_zones_closed < dev->zone_max_active) 294 return BLK_STS_OK; 295 296 return BLK_STS_ZONE_ACTIVE_RESOURCE; 297 } 298 299 static blk_status_t null_check_open(struct nullb_device *dev) 300 { 301 if (!dev->zone_max_open) 302 return BLK_STS_OK; 303 304 if (dev->nr_zones_exp_open + dev->nr_zones_imp_open < dev->zone_max_open) 305 return BLK_STS_OK; 306 307 if (dev->nr_zones_imp_open) { 308 if (null_check_active(dev) == BLK_STS_OK) { 309 null_close_imp_open_zone(dev); 310 return BLK_STS_OK; 311 } 312 } 313 314 return BLK_STS_ZONE_OPEN_RESOURCE; 315 } 316 317 /* 318 * This function matches the manage open zone resources function in the ZBC standard, 319 * with the addition of max active zones support (added in the ZNS standard). 320 * 321 * The function determines if a zone can transition to implicit open or explicit open, 322 * while maintaining the max open zone (and max active zone) limit(s). It may close an 323 * implicit open zone in order to make additional zone resources available. 324 * 325 * ZBC states that an implicit open zone shall be closed only if there is not 326 * room within the open limit. However, with the addition of an active limit, 327 * it is not certain that closing an implicit open zone will allow a new zone 328 * to be opened, since we might already be at the active limit capacity. 329 */ 330 static blk_status_t null_check_zone_resources(struct nullb_device *dev, 331 struct nullb_zone *zone) 332 { 333 blk_status_t ret; 334 335 switch (zone->cond) { 336 case BLK_ZONE_COND_EMPTY: 337 ret = null_check_active(dev); 338 if (ret != BLK_STS_OK) 339 return ret; 340 fallthrough; 341 case BLK_ZONE_COND_CLOSED: 342 return null_check_open(dev); 343 default: 344 /* Should never be called for other states */ 345 WARN_ON(1); 346 return BLK_STS_IOERR; 347 } 348 } 349 350 static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector, 351 unsigned int nr_sectors, bool append) 352 { 353 struct nullb_device *dev = cmd->nq->dev; 354 unsigned int zno = null_zone_no(dev, sector); 355 struct nullb_zone *zone = &dev->zones[zno]; 356 blk_status_t badblocks_ret = BLK_STS_OK; 357 blk_status_t ret; 358 359 trace_nullb_zone_op(cmd, zno, zone->cond); 360 361 if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) { 362 if (append) 363 return BLK_STS_IOERR; 364 return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors); 365 } 366 367 null_lock_zone(dev, zone); 368 369 /* 370 * Regular writes must be at the write pointer position. Zone append 371 * writes are automatically issued at the write pointer and the position 372 * returned using the request sector. Note that we do not check the zone 373 * condition because for FULL, READONLY and OFFLINE zones, the sector 374 * check against the zone write pointer will always result in failing 375 * the command. 376 */ 377 if (append) { 378 if (WARN_ON_ONCE(!dev->zone_append_max_sectors) || 379 zone->wp == NULL_ZONE_INVALID_WP) { 380 ret = BLK_STS_IOERR; 381 goto unlock_zone; 382 } 383 sector = zone->wp; 384 blk_mq_rq_from_pdu(cmd)->__sector = sector; 385 } 386 387 if (sector != zone->wp || 388 zone->wp + nr_sectors > zone->start + zone->capacity) { 389 ret = BLK_STS_IOERR; 390 goto unlock_zone; 391 } 392 393 if (zone->cond == BLK_ZONE_COND_CLOSED || 394 zone->cond == BLK_ZONE_COND_EMPTY) { 395 if (dev->need_zone_res_mgmt) { 396 spin_lock(&dev->zone_res_lock); 397 398 ret = null_check_zone_resources(dev, zone); 399 if (ret != BLK_STS_OK) { 400 spin_unlock(&dev->zone_res_lock); 401 goto unlock_zone; 402 } 403 if (zone->cond == BLK_ZONE_COND_CLOSED) { 404 dev->nr_zones_closed--; 405 dev->nr_zones_imp_open++; 406 } else if (zone->cond == BLK_ZONE_COND_EMPTY) { 407 dev->nr_zones_imp_open++; 408 } 409 410 spin_unlock(&dev->zone_res_lock); 411 } 412 413 zone->cond = BLK_ZONE_COND_IMP_OPEN; 414 } 415 416 if (dev->badblocks.shift != -1) { 417 badblocks_ret = null_handle_badblocks(cmd, sector, &nr_sectors); 418 if (badblocks_ret != BLK_STS_OK && !nr_sectors) { 419 ret = badblocks_ret; 420 goto unlock_zone; 421 } 422 } 423 424 if (dev->memory_backed) { 425 ret = null_handle_memory_backed(cmd, REQ_OP_WRITE, sector, 426 nr_sectors); 427 if (ret != BLK_STS_OK) 428 goto unlock_zone; 429 } 430 431 zone->wp += nr_sectors; 432 if (zone->wp == zone->start + zone->capacity) { 433 if (dev->need_zone_res_mgmt) { 434 spin_lock(&dev->zone_res_lock); 435 if (zone->cond == BLK_ZONE_COND_EXP_OPEN) 436 dev->nr_zones_exp_open--; 437 else if (zone->cond == BLK_ZONE_COND_IMP_OPEN) 438 dev->nr_zones_imp_open--; 439 spin_unlock(&dev->zone_res_lock); 440 } 441 zone->cond = BLK_ZONE_COND_FULL; 442 } 443 444 ret = badblocks_ret; 445 446 unlock_zone: 447 null_unlock_zone(dev, zone); 448 449 return ret; 450 } 451 452 static blk_status_t null_open_zone(struct nullb_device *dev, 453 struct nullb_zone *zone) 454 { 455 blk_status_t ret = BLK_STS_OK; 456 457 if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) 458 return BLK_STS_IOERR; 459 460 switch (zone->cond) { 461 case BLK_ZONE_COND_EXP_OPEN: 462 /* Open operation on exp open is not an error */ 463 return BLK_STS_OK; 464 case BLK_ZONE_COND_EMPTY: 465 case BLK_ZONE_COND_IMP_OPEN: 466 case BLK_ZONE_COND_CLOSED: 467 break; 468 case BLK_ZONE_COND_FULL: 469 default: 470 return BLK_STS_IOERR; 471 } 472 473 if (dev->need_zone_res_mgmt) { 474 spin_lock(&dev->zone_res_lock); 475 476 switch (zone->cond) { 477 case BLK_ZONE_COND_EMPTY: 478 ret = null_check_zone_resources(dev, zone); 479 if (ret != BLK_STS_OK) { 480 spin_unlock(&dev->zone_res_lock); 481 return ret; 482 } 483 break; 484 case BLK_ZONE_COND_IMP_OPEN: 485 dev->nr_zones_imp_open--; 486 break; 487 case BLK_ZONE_COND_CLOSED: 488 ret = null_check_zone_resources(dev, zone); 489 if (ret != BLK_STS_OK) { 490 spin_unlock(&dev->zone_res_lock); 491 return ret; 492 } 493 dev->nr_zones_closed--; 494 break; 495 default: 496 break; 497 } 498 499 dev->nr_zones_exp_open++; 500 501 spin_unlock(&dev->zone_res_lock); 502 } 503 504 zone->cond = BLK_ZONE_COND_EXP_OPEN; 505 506 return BLK_STS_OK; 507 } 508 509 static blk_status_t null_close_zone(struct nullb_device *dev, 510 struct nullb_zone *zone) 511 { 512 if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) 513 return BLK_STS_IOERR; 514 515 switch (zone->cond) { 516 case BLK_ZONE_COND_CLOSED: 517 /* close operation on closed is not an error */ 518 return BLK_STS_OK; 519 case BLK_ZONE_COND_IMP_OPEN: 520 case BLK_ZONE_COND_EXP_OPEN: 521 break; 522 case BLK_ZONE_COND_EMPTY: 523 case BLK_ZONE_COND_FULL: 524 default: 525 return BLK_STS_IOERR; 526 } 527 528 if (dev->need_zone_res_mgmt) { 529 spin_lock(&dev->zone_res_lock); 530 531 switch (zone->cond) { 532 case BLK_ZONE_COND_IMP_OPEN: 533 dev->nr_zones_imp_open--; 534 break; 535 case BLK_ZONE_COND_EXP_OPEN: 536 dev->nr_zones_exp_open--; 537 break; 538 default: 539 break; 540 } 541 542 if (zone->wp > zone->start) 543 dev->nr_zones_closed++; 544 545 spin_unlock(&dev->zone_res_lock); 546 } 547 548 if (zone->wp == zone->start) 549 zone->cond = BLK_ZONE_COND_EMPTY; 550 else 551 zone->cond = BLK_ZONE_COND_CLOSED; 552 553 return BLK_STS_OK; 554 } 555 556 static blk_status_t null_finish_zone(struct nullb_device *dev, 557 struct nullb_zone *zone) 558 { 559 blk_status_t ret = BLK_STS_OK; 560 561 if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) 562 return BLK_STS_IOERR; 563 564 if (dev->need_zone_res_mgmt) { 565 spin_lock(&dev->zone_res_lock); 566 567 switch (zone->cond) { 568 case BLK_ZONE_COND_FULL: 569 /* Finish operation on full is not an error */ 570 spin_unlock(&dev->zone_res_lock); 571 return BLK_STS_OK; 572 case BLK_ZONE_COND_EMPTY: 573 ret = null_check_zone_resources(dev, zone); 574 if (ret != BLK_STS_OK) { 575 spin_unlock(&dev->zone_res_lock); 576 return ret; 577 } 578 break; 579 case BLK_ZONE_COND_IMP_OPEN: 580 dev->nr_zones_imp_open--; 581 break; 582 case BLK_ZONE_COND_EXP_OPEN: 583 dev->nr_zones_exp_open--; 584 break; 585 case BLK_ZONE_COND_CLOSED: 586 ret = null_check_zone_resources(dev, zone); 587 if (ret != BLK_STS_OK) { 588 spin_unlock(&dev->zone_res_lock); 589 return ret; 590 } 591 dev->nr_zones_closed--; 592 break; 593 default: 594 spin_unlock(&dev->zone_res_lock); 595 return BLK_STS_IOERR; 596 } 597 598 spin_unlock(&dev->zone_res_lock); 599 } 600 601 zone->cond = BLK_ZONE_COND_FULL; 602 zone->wp = zone->start + zone->len; 603 604 return BLK_STS_OK; 605 } 606 607 static blk_status_t null_reset_zone(struct nullb_device *dev, 608 struct nullb_zone *zone) 609 { 610 if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) 611 return BLK_STS_IOERR; 612 613 if (dev->need_zone_res_mgmt) { 614 spin_lock(&dev->zone_res_lock); 615 616 switch (zone->cond) { 617 case BLK_ZONE_COND_IMP_OPEN: 618 dev->nr_zones_imp_open--; 619 break; 620 case BLK_ZONE_COND_EXP_OPEN: 621 dev->nr_zones_exp_open--; 622 break; 623 case BLK_ZONE_COND_CLOSED: 624 dev->nr_zones_closed--; 625 break; 626 case BLK_ZONE_COND_EMPTY: 627 case BLK_ZONE_COND_FULL: 628 break; 629 default: 630 spin_unlock(&dev->zone_res_lock); 631 return BLK_STS_IOERR; 632 } 633 634 spin_unlock(&dev->zone_res_lock); 635 } 636 637 zone->cond = BLK_ZONE_COND_EMPTY; 638 zone->wp = zone->start; 639 640 if (dev->memory_backed) 641 return null_handle_discard(dev, zone->start, zone->len); 642 643 return BLK_STS_OK; 644 } 645 646 static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_op op, 647 sector_t sector) 648 { 649 struct nullb_device *dev = cmd->nq->dev; 650 unsigned int zone_no; 651 struct nullb_zone *zone; 652 blk_status_t ret; 653 size_t i; 654 655 if (op == REQ_OP_ZONE_RESET_ALL) { 656 for (i = dev->zone_nr_conv; i < dev->nr_zones; i++) { 657 zone = &dev->zones[i]; 658 null_lock_zone(dev, zone); 659 if (zone->cond != BLK_ZONE_COND_EMPTY && 660 zone->cond != BLK_ZONE_COND_READONLY && 661 zone->cond != BLK_ZONE_COND_OFFLINE) { 662 null_reset_zone(dev, zone); 663 trace_nullb_zone_op(cmd, i, zone->cond); 664 } 665 null_unlock_zone(dev, zone); 666 } 667 return BLK_STS_OK; 668 } 669 670 zone_no = null_zone_no(dev, sector); 671 zone = &dev->zones[zone_no]; 672 673 null_lock_zone(dev, zone); 674 675 if (zone->cond == BLK_ZONE_COND_READONLY || 676 zone->cond == BLK_ZONE_COND_OFFLINE) { 677 ret = BLK_STS_IOERR; 678 goto unlock; 679 } 680 681 switch (op) { 682 case REQ_OP_ZONE_RESET: 683 ret = null_reset_zone(dev, zone); 684 break; 685 case REQ_OP_ZONE_OPEN: 686 ret = null_open_zone(dev, zone); 687 break; 688 case REQ_OP_ZONE_CLOSE: 689 ret = null_close_zone(dev, zone); 690 break; 691 case REQ_OP_ZONE_FINISH: 692 ret = null_finish_zone(dev, zone); 693 break; 694 default: 695 ret = BLK_STS_NOTSUPP; 696 break; 697 } 698 699 if (ret == BLK_STS_OK) 700 trace_nullb_zone_op(cmd, zone_no, zone->cond); 701 702 unlock: 703 null_unlock_zone(dev, zone); 704 705 return ret; 706 } 707 708 blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_op op, 709 sector_t sector, sector_t nr_sectors) 710 { 711 struct nullb_device *dev; 712 struct nullb_zone *zone; 713 blk_status_t sts; 714 715 switch (op) { 716 case REQ_OP_WRITE: 717 return null_zone_write(cmd, sector, nr_sectors, false); 718 case REQ_OP_ZONE_APPEND: 719 return null_zone_write(cmd, sector, nr_sectors, true); 720 case REQ_OP_ZONE_RESET: 721 case REQ_OP_ZONE_RESET_ALL: 722 case REQ_OP_ZONE_OPEN: 723 case REQ_OP_ZONE_CLOSE: 724 case REQ_OP_ZONE_FINISH: 725 return null_zone_mgmt(cmd, op, sector); 726 default: 727 dev = cmd->nq->dev; 728 zone = &dev->zones[null_zone_no(dev, sector)]; 729 if (zone->cond == BLK_ZONE_COND_OFFLINE) 730 return BLK_STS_IOERR; 731 732 null_lock_zone(dev, zone); 733 sts = null_process_cmd(cmd, op, sector, nr_sectors); 734 null_unlock_zone(dev, zone); 735 return sts; 736 } 737 } 738 739 /* 740 * Set a zone in the read-only or offline condition. 741 */ 742 static void null_set_zone_cond(struct nullb_device *dev, 743 struct nullb_zone *zone, enum blk_zone_cond cond) 744 { 745 if (WARN_ON_ONCE(cond != BLK_ZONE_COND_READONLY && 746 cond != BLK_ZONE_COND_OFFLINE)) 747 return; 748 749 null_lock_zone(dev, zone); 750 751 /* 752 * If the read-only condition is requested again to zones already in 753 * read-only condition, restore back normal empty condition. Do the same 754 * if the offline condition is requested for offline zones. Otherwise, 755 * set the specified zone condition to the zones. Finish the zones 756 * beforehand to free up zone resources. 757 */ 758 if (zone->cond == cond) { 759 zone->cond = BLK_ZONE_COND_EMPTY; 760 zone->wp = zone->start; 761 if (dev->memory_backed) 762 null_handle_discard(dev, zone->start, zone->len); 763 } else { 764 if (zone->cond != BLK_ZONE_COND_READONLY && 765 zone->cond != BLK_ZONE_COND_OFFLINE) 766 null_finish_zone(dev, zone); 767 zone->cond = cond; 768 zone->wp = NULL_ZONE_INVALID_WP; 769 } 770 771 null_unlock_zone(dev, zone); 772 } 773 774 /* 775 * Identify a zone from the sector written to configfs file. Then set zone 776 * condition to the zone. 777 */ 778 ssize_t zone_cond_store(struct nullb_device *dev, const char *page, 779 size_t count, enum blk_zone_cond cond) 780 { 781 unsigned long long sector; 782 unsigned int zone_no; 783 int ret; 784 785 if (!dev->zoned) { 786 pr_err("null_blk device is not zoned\n"); 787 return -EINVAL; 788 } 789 790 if (!dev->zones) { 791 pr_err("null_blk device is not yet powered\n"); 792 return -EINVAL; 793 } 794 795 ret = kstrtoull(page, 0, §or); 796 if (ret < 0) 797 return ret; 798 799 zone_no = null_zone_no(dev, sector); 800 if (zone_no >= dev->nr_zones) { 801 pr_err("Sector out of range\n"); 802 return -EINVAL; 803 } 804 805 if (dev->zones[zone_no].type == BLK_ZONE_TYPE_CONVENTIONAL) { 806 pr_err("Can not change condition of conventional zones\n"); 807 return -EINVAL; 808 } 809 810 null_set_zone_cond(dev, &dev->zones[zone_no], cond); 811 812 return count; 813 } 814