diff options
| -rw-r--r-- | drivers/target/target_core_file.c | 86 |
1 files changed, 61 insertions, 25 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 1284fec63db8..f7e6e51aed36 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
| @@ -482,6 +482,56 @@ fd_execute_write_same(struct se_cmd *cmd) | |||
| 482 | return 0; | 482 | return 0; |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | static int | ||
| 486 | fd_do_prot_fill(struct se_device *se_dev, sector_t lba, sector_t nolb, | ||
| 487 | void *buf, size_t bufsize) | ||
| 488 | { | ||
| 489 | struct fd_dev *fd_dev = FD_DEV(se_dev); | ||
| 490 | struct file *prot_fd = fd_dev->fd_prot_file; | ||
| 491 | sector_t prot_length, prot; | ||
| 492 | loff_t pos = lba * se_dev->prot_length; | ||
| 493 | |||
| 494 | if (!prot_fd) { | ||
| 495 | pr_err("Unable to locate fd_dev->fd_prot_file\n"); | ||
| 496 | return -ENODEV; | ||
| 497 | } | ||
| 498 | |||
| 499 | prot_length = nolb * se_dev->prot_length; | ||
| 500 | |||
| 501 | for (prot = 0; prot < prot_length;) { | ||
| 502 | sector_t len = min_t(sector_t, bufsize, prot_length - prot); | ||
| 503 | ssize_t ret = kernel_write(prot_fd, buf, len, pos + prot); | ||
| 504 | |||
| 505 | if (ret != len) { | ||
| 506 | pr_err("vfs_write to prot file failed: %zd\n", ret); | ||
| 507 | return ret < 0 ? ret : -ENODEV; | ||
| 508 | } | ||
| 509 | prot += ret; | ||
| 510 | } | ||
| 511 | |||
| 512 | return 0; | ||
| 513 | } | ||
| 514 | |||
| 515 | static int | ||
| 516 | fd_do_prot_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb) | ||
| 517 | { | ||
| 518 | void *buf; | ||
| 519 | int rc; | ||
| 520 | |||
| 521 | buf = (void *)__get_free_page(GFP_KERNEL); | ||
| 522 | if (!buf) { | ||
| 523 | pr_err("Unable to allocate FILEIO prot buf\n"); | ||
| 524 | return -ENOMEM; | ||
| 525 | } | ||
| 526 | memset(buf, 0xff, PAGE_SIZE); | ||
| 527 | |||
| 528 | rc = fd_do_prot_fill(cmd->se_dev, lba, nolb, buf, PAGE_SIZE); | ||
| 529 | |||
| 530 | free_page((unsigned long)buf); | ||
| 531 | |||
| 532 | return rc; | ||
| 533 | } | ||
| 534 | |||
| 485 | static sense_reason_t | 535 | static sense_reason_t |
| 486 | fd_do_unmap(struct se_cmd *cmd, void *priv, sector_t lba, sector_t nolb) | 536 | fd_do_unmap(struct se_cmd *cmd, void *priv, sector_t lba, sector_t nolb) |
| 487 | { | 537 | { |
| @@ -489,6 +539,12 @@ fd_do_unmap(struct se_cmd *cmd, void *priv, sector_t lba, sector_t nolb) | |||
| 489 | struct inode *inode = file->f_mapping->host; | 539 | struct inode *inode = file->f_mapping->host; |
| 490 | int ret; | 540 | int ret; |
| 491 | 541 | ||
| 542 | if (cmd->se_dev->dev_attrib.pi_prot_type) { | ||
| 543 | ret = fd_do_prot_unmap(cmd, lba, nolb); | ||
| 544 | if (ret) | ||
| 545 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
| 546 | } | ||
| 547 | |||
| 492 | if (S_ISBLK(inode->i_mode)) { | 548 | if (S_ISBLK(inode->i_mode)) { |
| 493 | /* The backend is block device, use discard */ | 549 | /* The backend is block device, use discard */ |
| 494 | struct block_device *bdev = inode->i_bdev; | 550 | struct block_device *bdev = inode->i_bdev; |
| @@ -811,48 +867,28 @@ static int fd_init_prot(struct se_device *dev) | |||
| 811 | 867 | ||
| 812 | static int fd_format_prot(struct se_device *dev) | 868 | static int fd_format_prot(struct se_device *dev) |
| 813 | { | 869 | { |
| 814 | struct fd_dev *fd_dev = FD_DEV(dev); | ||
| 815 | struct file *prot_fd = fd_dev->fd_prot_file; | ||
| 816 | sector_t prot_length, prot; | ||
| 817 | unsigned char *buf; | 870 | unsigned char *buf; |
| 818 | loff_t pos = 0; | ||
| 819 | int unit_size = FDBD_FORMAT_UNIT_SIZE * dev->dev_attrib.block_size; | 871 | int unit_size = FDBD_FORMAT_UNIT_SIZE * dev->dev_attrib.block_size; |
| 820 | int rc, ret = 0, size, len; | 872 | int ret; |
| 821 | 873 | ||
| 822 | if (!dev->dev_attrib.pi_prot_type) { | 874 | if (!dev->dev_attrib.pi_prot_type) { |
| 823 | pr_err("Unable to format_prot while pi_prot_type == 0\n"); | 875 | pr_err("Unable to format_prot while pi_prot_type == 0\n"); |
| 824 | return -ENODEV; | 876 | return -ENODEV; |
| 825 | } | 877 | } |
| 826 | if (!prot_fd) { | ||
| 827 | pr_err("Unable to locate fd_dev->fd_prot_file\n"); | ||
| 828 | return -ENODEV; | ||
| 829 | } | ||
| 830 | 878 | ||
| 831 | buf = vzalloc(unit_size); | 879 | buf = vzalloc(unit_size); |
| 832 | if (!buf) { | 880 | if (!buf) { |
| 833 | pr_err("Unable to allocate FILEIO prot buf\n"); | 881 | pr_err("Unable to allocate FILEIO prot buf\n"); |
| 834 | return -ENOMEM; | 882 | return -ENOMEM; |
| 835 | } | 883 | } |
| 836 | prot_length = (dev->transport->get_blocks(dev) + 1) * dev->prot_length; | ||
| 837 | size = prot_length; | ||
| 838 | 884 | ||
| 839 | pr_debug("Using FILEIO prot_length: %llu\n", | 885 | pr_debug("Using FILEIO prot_length: %llu\n", |
| 840 | (unsigned long long)prot_length); | 886 | (unsigned long long)(dev->transport->get_blocks(dev) + 1) * |
| 887 | dev->prot_length); | ||
| 841 | 888 | ||
| 842 | memset(buf, 0xff, unit_size); | 889 | memset(buf, 0xff, unit_size); |
| 843 | for (prot = 0; prot < prot_length; prot += unit_size) { | 890 | ret = fd_do_prot_fill(dev, 0, dev->transport->get_blocks(dev) + 1, |
| 844 | len = min(unit_size, size); | 891 | buf, unit_size); |
| 845 | rc = kernel_write(prot_fd, buf, len, pos); | ||
| 846 | if (rc != len) { | ||
| 847 | pr_err("vfs_write to prot file failed: %d\n", rc); | ||
| 848 | ret = -ENODEV; | ||
| 849 | goto out; | ||
| 850 | } | ||
| 851 | pos += len; | ||
| 852 | size -= len; | ||
| 853 | } | ||
| 854 | |||
| 855 | out: | ||
| 856 | vfree(buf); | 892 | vfree(buf); |
| 857 | return ret; | 893 | return ret; |
| 858 | } | 894 | } |
