Commit 86d7182985d25900929adce14fffd729cc8c6fb8
Committed by
Nicholas Bellinger
1 parent
dbc21c5abb
Exists in
master
and in
20 other branches
target: Add sbc_execute_unmap() helper
iblock_execute_unmap() and fd_execute_unmap share a lot of code. Add sbc_execute_unmap() helper to remove duplicated code for iblock_execute_unmap() and fd_execute_unmap(). Cc: Christoph Hellwig <hch@lst.de> Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Asias He <asias@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Showing 4 changed files with 97 additions and 155 deletions Side-by-side Diff
drivers/target/target_core_file.c
... | ... | @@ -480,8 +480,9 @@ |
480 | 480 | } |
481 | 481 | |
482 | 482 | static sense_reason_t |
483 | -fd_do_unmap(struct se_cmd *cmd, struct file *file, sector_t lba, sector_t nolb) | |
483 | +fd_do_unmap(struct se_cmd *cmd, void *priv, sector_t lba, sector_t nolb) | |
484 | 484 | { |
485 | + struct file *file = priv; | |
485 | 486 | struct inode *inode = file->f_mapping->host; |
486 | 487 | int ret; |
487 | 488 | |
488 | 489 | |
... | ... | @@ -542,84 +543,9 @@ |
542 | 543 | static sense_reason_t |
543 | 544 | fd_execute_unmap(struct se_cmd *cmd) |
544 | 545 | { |
545 | - struct se_device *dev = cmd->se_dev; | |
546 | - struct fd_dev *fd_dev = FD_DEV(dev); | |
547 | - struct file *file = fd_dev->fd_file; | |
548 | - unsigned char *buf, *ptr = NULL; | |
549 | - sector_t lba; | |
550 | - int size; | |
551 | - u32 range; | |
552 | - sense_reason_t ret = 0; | |
553 | - int dl, bd_dl; | |
546 | + struct file *file = FD_DEV(cmd->se_dev)->fd_file; | |
554 | 547 | |
555 | - /* We never set ANC_SUP */ | |
556 | - if (cmd->t_task_cdb[1]) | |
557 | - return TCM_INVALID_CDB_FIELD; | |
558 | - | |
559 | - if (cmd->data_length == 0) { | |
560 | - target_complete_cmd(cmd, SAM_STAT_GOOD); | |
561 | - return 0; | |
562 | - } | |
563 | - | |
564 | - if (cmd->data_length < 8) { | |
565 | - pr_warn("UNMAP parameter list length %u too small\n", | |
566 | - cmd->data_length); | |
567 | - return TCM_PARAMETER_LIST_LENGTH_ERROR; | |
568 | - } | |
569 | - | |
570 | - buf = transport_kmap_data_sg(cmd); | |
571 | - if (!buf) | |
572 | - return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | |
573 | - | |
574 | - dl = get_unaligned_be16(&buf[0]); | |
575 | - bd_dl = get_unaligned_be16(&buf[2]); | |
576 | - | |
577 | - size = cmd->data_length - 8; | |
578 | - if (bd_dl > size) | |
579 | - pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", | |
580 | - cmd->data_length, bd_dl); | |
581 | - else | |
582 | - size = bd_dl; | |
583 | - | |
584 | - if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) { | |
585 | - ret = TCM_INVALID_PARAMETER_LIST; | |
586 | - goto err; | |
587 | - } | |
588 | - | |
589 | - /* First UNMAP block descriptor starts at 8 byte offset */ | |
590 | - ptr = &buf[8]; | |
591 | - pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u" | |
592 | - " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr); | |
593 | - | |
594 | - while (size >= 16) { | |
595 | - lba = get_unaligned_be64(&ptr[0]); | |
596 | - range = get_unaligned_be32(&ptr[8]); | |
597 | - pr_debug("UNMAP: Using lba: %llu and range: %u\n", | |
598 | - (unsigned long long)lba, range); | |
599 | - | |
600 | - if (range > dev->dev_attrib.max_unmap_lba_count) { | |
601 | - ret = TCM_INVALID_PARAMETER_LIST; | |
602 | - goto err; | |
603 | - } | |
604 | - | |
605 | - if (lba + range > dev->transport->get_blocks(dev) + 1) { | |
606 | - ret = TCM_ADDRESS_OUT_OF_RANGE; | |
607 | - goto err; | |
608 | - } | |
609 | - | |
610 | - ret = fd_do_unmap(cmd, file, lba, range); | |
611 | - if (ret) | |
612 | - goto err; | |
613 | - | |
614 | - ptr += 16; | |
615 | - size -= 16; | |
616 | - } | |
617 | - | |
618 | -err: | |
619 | - transport_kunmap_data_sg(cmd); | |
620 | - if (!ret) | |
621 | - target_complete_cmd(cmd, GOOD); | |
622 | - return ret; | |
548 | + return sbc_execute_unmap(cmd, fd_do_unmap, file); | |
623 | 549 | } |
624 | 550 | |
625 | 551 | static sense_reason_t |
drivers/target/target_core_iblock.c
... | ... | @@ -380,9 +380,10 @@ |
380 | 380 | } |
381 | 381 | |
382 | 382 | static sense_reason_t |
383 | -iblock_do_unmap(struct se_cmd *cmd, struct block_device *bdev, | |
383 | +iblock_do_unmap(struct se_cmd *cmd, void *priv, | |
384 | 384 | sector_t lba, sector_t nolb) |
385 | 385 | { |
386 | + struct block_device *bdev = priv; | |
386 | 387 | int ret; |
387 | 388 | |
388 | 389 | ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0); |
389 | 390 | |
... | ... | @@ -397,83 +398,9 @@ |
397 | 398 | static sense_reason_t |
398 | 399 | iblock_execute_unmap(struct se_cmd *cmd) |
399 | 400 | { |
400 | - struct se_device *dev = cmd->se_dev; | |
401 | - struct iblock_dev *ib_dev = IBLOCK_DEV(dev); | |
402 | - unsigned char *buf, *ptr = NULL; | |
403 | - sector_t lba; | |
404 | - int size; | |
405 | - u32 range; | |
406 | - sense_reason_t ret = 0; | |
407 | - int dl, bd_dl; | |
401 | + struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd; | |
408 | 402 | |
409 | - /* We never set ANC_SUP */ | |
410 | - if (cmd->t_task_cdb[1]) | |
411 | - return TCM_INVALID_CDB_FIELD; | |
412 | - | |
413 | - if (cmd->data_length == 0) { | |
414 | - target_complete_cmd(cmd, SAM_STAT_GOOD); | |
415 | - return 0; | |
416 | - } | |
417 | - | |
418 | - if (cmd->data_length < 8) { | |
419 | - pr_warn("UNMAP parameter list length %u too small\n", | |
420 | - cmd->data_length); | |
421 | - return TCM_PARAMETER_LIST_LENGTH_ERROR; | |
422 | - } | |
423 | - | |
424 | - buf = transport_kmap_data_sg(cmd); | |
425 | - if (!buf) | |
426 | - return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | |
427 | - | |
428 | - dl = get_unaligned_be16(&buf[0]); | |
429 | - bd_dl = get_unaligned_be16(&buf[2]); | |
430 | - | |
431 | - size = cmd->data_length - 8; | |
432 | - if (bd_dl > size) | |
433 | - pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", | |
434 | - cmd->data_length, bd_dl); | |
435 | - else | |
436 | - size = bd_dl; | |
437 | - | |
438 | - if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) { | |
439 | - ret = TCM_INVALID_PARAMETER_LIST; | |
440 | - goto err; | |
441 | - } | |
442 | - | |
443 | - /* First UNMAP block descriptor starts at 8 byte offset */ | |
444 | - ptr = &buf[8]; | |
445 | - pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u" | |
446 | - " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr); | |
447 | - | |
448 | - while (size >= 16) { | |
449 | - lba = get_unaligned_be64(&ptr[0]); | |
450 | - range = get_unaligned_be32(&ptr[8]); | |
451 | - pr_debug("UNMAP: Using lba: %llu and range: %u\n", | |
452 | - (unsigned long long)lba, range); | |
453 | - | |
454 | - if (range > dev->dev_attrib.max_unmap_lba_count) { | |
455 | - ret = TCM_INVALID_PARAMETER_LIST; | |
456 | - goto err; | |
457 | - } | |
458 | - | |
459 | - if (lba + range > dev->transport->get_blocks(dev) + 1) { | |
460 | - ret = TCM_ADDRESS_OUT_OF_RANGE; | |
461 | - goto err; | |
462 | - } | |
463 | - | |
464 | - ret = iblock_do_unmap(cmd, ib_dev->ibd_bd, lba, range); | |
465 | - if (ret) | |
466 | - goto err; | |
467 | - | |
468 | - ptr += 16; | |
469 | - size -= 16; | |
470 | - } | |
471 | - | |
472 | -err: | |
473 | - transport_kunmap_data_sg(cmd); | |
474 | - if (!ret) | |
475 | - target_complete_cmd(cmd, GOOD); | |
476 | - return ret; | |
403 | + return sbc_execute_unmap(cmd, iblock_do_unmap, bdev); | |
477 | 404 | } |
478 | 405 | |
479 | 406 | static sense_reason_t |
drivers/target/target_core_sbc.c
... | ... | @@ -596,4 +596,89 @@ |
596 | 596 | return TYPE_DISK; |
597 | 597 | } |
598 | 598 | EXPORT_SYMBOL(sbc_get_device_type); |
599 | + | |
600 | +sense_reason_t | |
601 | +sbc_execute_unmap(struct se_cmd *cmd, | |
602 | + sense_reason_t (*do_unmap_fn)(struct se_cmd *, void *, | |
603 | + sector_t, sector_t), | |
604 | + void *priv) | |
605 | +{ | |
606 | + struct se_device *dev = cmd->se_dev; | |
607 | + unsigned char *buf, *ptr = NULL; | |
608 | + sector_t lba; | |
609 | + int size; | |
610 | + u32 range; | |
611 | + sense_reason_t ret = 0; | |
612 | + int dl, bd_dl; | |
613 | + | |
614 | + /* We never set ANC_SUP */ | |
615 | + if (cmd->t_task_cdb[1]) | |
616 | + return TCM_INVALID_CDB_FIELD; | |
617 | + | |
618 | + if (cmd->data_length == 0) { | |
619 | + target_complete_cmd(cmd, SAM_STAT_GOOD); | |
620 | + return 0; | |
621 | + } | |
622 | + | |
623 | + if (cmd->data_length < 8) { | |
624 | + pr_warn("UNMAP parameter list length %u too small\n", | |
625 | + cmd->data_length); | |
626 | + return TCM_PARAMETER_LIST_LENGTH_ERROR; | |
627 | + } | |
628 | + | |
629 | + buf = transport_kmap_data_sg(cmd); | |
630 | + if (!buf) | |
631 | + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | |
632 | + | |
633 | + dl = get_unaligned_be16(&buf[0]); | |
634 | + bd_dl = get_unaligned_be16(&buf[2]); | |
635 | + | |
636 | + size = cmd->data_length - 8; | |
637 | + if (bd_dl > size) | |
638 | + pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", | |
639 | + cmd->data_length, bd_dl); | |
640 | + else | |
641 | + size = bd_dl; | |
642 | + | |
643 | + if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) { | |
644 | + ret = TCM_INVALID_PARAMETER_LIST; | |
645 | + goto err; | |
646 | + } | |
647 | + | |
648 | + /* First UNMAP block descriptor starts at 8 byte offset */ | |
649 | + ptr = &buf[8]; | |
650 | + pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u" | |
651 | + " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr); | |
652 | + | |
653 | + while (size >= 16) { | |
654 | + lba = get_unaligned_be64(&ptr[0]); | |
655 | + range = get_unaligned_be32(&ptr[8]); | |
656 | + pr_debug("UNMAP: Using lba: %llu and range: %u\n", | |
657 | + (unsigned long long)lba, range); | |
658 | + | |
659 | + if (range > dev->dev_attrib.max_unmap_lba_count) { | |
660 | + ret = TCM_INVALID_PARAMETER_LIST; | |
661 | + goto err; | |
662 | + } | |
663 | + | |
664 | + if (lba + range > dev->transport->get_blocks(dev) + 1) { | |
665 | + ret = TCM_ADDRESS_OUT_OF_RANGE; | |
666 | + goto err; | |
667 | + } | |
668 | + | |
669 | + ret = do_unmap_fn(cmd, priv, lba, range); | |
670 | + if (ret) | |
671 | + goto err; | |
672 | + | |
673 | + ptr += 16; | |
674 | + size -= 16; | |
675 | + } | |
676 | + | |
677 | +err: | |
678 | + transport_kunmap_data_sg(cmd); | |
679 | + if (!ret) | |
680 | + target_complete_cmd(cmd, GOOD); | |
681 | + return ret; | |
682 | +} | |
683 | +EXPORT_SYMBOL(sbc_execute_unmap); |
include/target/target_core_backend.h
... | ... | @@ -60,6 +60,10 @@ |
60 | 60 | u32 sbc_get_device_rev(struct se_device *dev); |
61 | 61 | u32 sbc_get_device_type(struct se_device *dev); |
62 | 62 | sector_t sbc_get_write_same_sectors(struct se_cmd *cmd); |
63 | +sense_reason_t sbc_execute_unmap(struct se_cmd *cmd, | |
64 | + sense_reason_t (*do_unmap_fn)(struct se_cmd *cmd, void *priv, | |
65 | + sector_t lba, sector_t nolb), | |
66 | + void *priv); | |
63 | 67 | |
64 | 68 | void transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *); |
65 | 69 | int transport_set_vpd_assoc(struct t10_vpd *, unsigned char *); |