Commit 86d7182985d25900929adce14fffd729cc8c6fb8

Authored by Asias He
Committed by Nicholas Bellinger
1 parent dbc21c5abb

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 *);