Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

target/file: Remove fd_prot bounce buffer

The reason this bounce buffer exists is to allow code
reuse between rd_mcp and fileio in DIF mode. But the fact is,
that this bounce is really not needed at all, we can simply call
sbc_dif_verify on cmd->t_prot_sg and use it for file IO.

This also removes fd_do_prot_rw as fd_do_rw was generalised
to receive file pointer, block size (8 bytes for DIF data) and
total data length.

(Fix apply breakage from commit c836777 - nab)

Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

authored by

Sagi Grimberg and committed by
Nicholas Bellinger
8287fa5f f75b6fae

+34 -112
+34 -106
drivers/target/target_core_file.c
··· 258 258 kfree(fd_dev); 259 259 } 260 260 261 - static int fd_do_prot_rw(struct se_cmd *cmd, struct fd_prot *fd_prot, 262 - int is_write) 261 + static int fd_do_rw(struct se_cmd *cmd, struct file *fd, 262 + u32 block_size, struct scatterlist *sgl, 263 + u32 sgl_nents, u32 data_length, int is_write) 263 264 { 264 - struct se_device *se_dev = cmd->se_dev; 265 - struct fd_dev *dev = FD_DEV(se_dev); 266 - struct file *prot_fd = dev->fd_prot_file; 267 - loff_t pos = (cmd->t_task_lba * se_dev->prot_length); 268 - unsigned char *buf; 269 - u32 prot_size; 270 - int rc, ret = 1; 271 - 272 - prot_size = (cmd->data_length / se_dev->dev_attrib.block_size) * 273 - se_dev->prot_length; 274 - 275 - if (!is_write) { 276 - fd_prot->prot_buf = kzalloc(prot_size, GFP_KERNEL); 277 - if (!fd_prot->prot_buf) { 278 - pr_err("Unable to allocate fd_prot->prot_buf\n"); 279 - return -ENOMEM; 280 - } 281 - buf = fd_prot->prot_buf; 282 - 283 - fd_prot->prot_sg_nents = 1; 284 - fd_prot->prot_sg = kzalloc(sizeof(struct scatterlist), 285 - GFP_KERNEL); 286 - if (!fd_prot->prot_sg) { 287 - pr_err("Unable to allocate fd_prot->prot_sg\n"); 288 - kfree(fd_prot->prot_buf); 289 - return -ENOMEM; 290 - } 291 - sg_init_table(fd_prot->prot_sg, fd_prot->prot_sg_nents); 292 - sg_set_buf(fd_prot->prot_sg, buf, prot_size); 293 - } 294 - 295 - if (is_write) { 296 - rc = kernel_write(prot_fd, fd_prot->prot_buf, prot_size, pos); 297 - if (rc < 0 || prot_size != rc) { 298 - pr_err("kernel_write() for fd_do_prot_rw failed:" 299 - " %d\n", rc); 300 - ret = -EINVAL; 301 - } 302 - } else { 303 - rc = kernel_read(prot_fd, pos, fd_prot->prot_buf, prot_size); 304 - if (rc < 0) { 305 - pr_err("kernel_read() for fd_do_prot_rw failed:" 306 - " %d\n", rc); 307 - ret = -EINVAL; 308 - } 309 - } 310 - 311 - if (is_write || ret < 0) { 312 - kfree(fd_prot->prot_sg); 313 - kfree(fd_prot->prot_buf); 314 - } 315 - 316 - return ret; 317 - } 318 - 319 - static int fd_do_rw(struct se_cmd *cmd, struct scatterlist *sgl, 320 - u32 sgl_nents, int is_write) 321 - { 322 - struct se_device *se_dev = cmd->se_dev; 323 - struct fd_dev *dev = FD_DEV(se_dev); 324 - struct file *fd = dev->fd_file; 325 265 struct scatterlist *sg; 326 266 struct iov_iter iter; 327 267 struct bio_vec *bvec; 328 268 ssize_t len = 0; 329 - loff_t pos = (cmd->t_task_lba * se_dev->dev_attrib.block_size); 269 + loff_t pos = (cmd->t_task_lba * block_size); 330 270 int ret = 0, i; 331 271 332 272 bvec = kcalloc(sgl_nents, sizeof(struct bio_vec), GFP_KERNEL); ··· 292 352 kfree(bvec); 293 353 294 354 if (is_write) { 295 - if (ret < 0 || ret != cmd->data_length) { 355 + if (ret < 0 || ret != data_length) { 296 356 pr_err("%s() write returned %d\n", __func__, ret); 297 357 return (ret < 0 ? ret : -EINVAL); 298 358 } ··· 303 363 * block_device. 304 364 */ 305 365 if (S_ISBLK(file_inode(fd)->i_mode)) { 306 - if (ret < 0 || ret != cmd->data_length) { 366 + if (ret < 0 || ret != data_length) { 307 367 pr_err("%s() returned %d, expecting %u for " 308 368 "S_ISBLK\n", __func__, ret, 309 - cmd->data_length); 369 + data_length); 310 370 return (ret < 0 ? ret : -EINVAL); 311 371 } 312 372 } else { ··· 552 612 enum dma_data_direction data_direction) 553 613 { 554 614 struct se_device *dev = cmd->se_dev; 555 - struct fd_prot fd_prot; 615 + struct fd_dev *fd_dev = FD_DEV(dev); 616 + struct file *file = fd_dev->fd_file; 617 + struct file *pfile = fd_dev->fd_prot_file; 556 618 sense_reason_t rc; 557 619 int ret = 0; 558 620 /* ··· 572 630 * physical memory addresses to struct iovec virtual memory. 573 631 */ 574 632 if (data_direction == DMA_FROM_DEVICE) { 575 - memset(&fd_prot, 0, sizeof(struct fd_prot)); 576 - 577 633 if (cmd->prot_type && dev->dev_attrib.pi_prot_type) { 578 - ret = fd_do_prot_rw(cmd, &fd_prot, false); 634 + ret = fd_do_rw(cmd, pfile, dev->prot_length, 635 + cmd->t_prot_sg, cmd->t_prot_nents, 636 + cmd->prot_length, 0); 579 637 if (ret < 0) 580 638 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 581 639 } 582 640 583 - ret = fd_do_rw(cmd, sgl, sgl_nents, 0); 641 + ret = fd_do_rw(cmd, file, dev->dev_attrib.block_size, 642 + sgl, sgl_nents, cmd->data_length, 0); 584 643 585 644 if (ret > 0 && cmd->prot_type && dev->dev_attrib.pi_prot_type) { 586 - u32 sectors = cmd->data_length / dev->dev_attrib.block_size; 587 - 588 - rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 589 - 0, fd_prot.prot_sg, 0); 590 - if (rc) { 591 - kfree(fd_prot.prot_sg); 592 - kfree(fd_prot.prot_buf); 593 - return rc; 594 - } 595 - sbc_dif_copy_prot(cmd, sectors, true, fd_prot.prot_sg, 0); 596 - kfree(fd_prot.prot_sg); 597 - kfree(fd_prot.prot_buf); 598 - } 599 - } else { 600 - memset(&fd_prot, 0, sizeof(struct fd_prot)); 601 - 602 - if (cmd->prot_type && dev->dev_attrib.pi_prot_type) { 603 - u32 sectors = cmd->data_length / dev->dev_attrib.block_size; 604 - 605 - ret = fd_do_prot_rw(cmd, &fd_prot, false); 606 - if (ret < 0) 607 - return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 645 + u32 sectors = cmd->data_length >> 646 + ilog2(dev->dev_attrib.block_size); 608 647 609 648 rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 610 649 0, cmd->t_prot_sg, 0); 611 - if (rc) { 612 - kfree(fd_prot.prot_sg); 613 - kfree(fd_prot.prot_buf); 650 + if (rc) 614 651 return rc; 615 - } 616 - sbc_dif_copy_prot(cmd, sectors, false, fd_prot.prot_sg, 0); 652 + } 653 + } else { 654 + if (cmd->prot_type && dev->dev_attrib.pi_prot_type) { 655 + u32 sectors = cmd->data_length >> 656 + ilog2(dev->dev_attrib.block_size); 657 + 658 + rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 659 + 0, cmd->t_prot_sg, 0); 660 + if (rc) 661 + return rc; 617 662 } 618 663 619 - ret = fd_do_rw(cmd, sgl, sgl_nents, 1); 664 + ret = fd_do_rw(cmd, file, dev->dev_attrib.block_size, 665 + sgl, sgl_nents, cmd->data_length, 1); 620 666 /* 621 667 * Perform implicit vfs_fsync_range() for fd_do_writev() ops 622 668 * for SCSI WRITEs with Forced Unit Access (FUA) set. ··· 613 683 if (ret > 0 && 614 684 dev->dev_attrib.emulate_fua_write > 0 && 615 685 (cmd->se_cmd_flags & SCF_FUA)) { 616 - struct fd_dev *fd_dev = FD_DEV(dev); 617 686 loff_t start = cmd->t_task_lba * 618 687 dev->dev_attrib.block_size; 619 688 loff_t end; ··· 626 697 } 627 698 628 699 if (ret > 0 && cmd->prot_type && dev->dev_attrib.pi_prot_type) { 629 - ret = fd_do_prot_rw(cmd, &fd_prot, true); 700 + ret = fd_do_rw(cmd, pfile, dev->prot_length, 701 + cmd->t_prot_sg, cmd->t_prot_nents, 702 + cmd->prot_length, 1); 630 703 if (ret < 0) 631 704 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 632 705 } 633 706 } 634 707 635 - if (ret < 0) { 636 - kfree(fd_prot.prot_sg); 637 - kfree(fd_prot.prot_buf); 708 + if (ret < 0) 638 709 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 639 - } 640 710 641 711 if (ret) 642 712 target_complete_cmd(cmd, SAM_STAT_GOOD);
-6
drivers/target/target_core_file.h
··· 21 21 #define FDBD_HAS_BUFFERED_IO_WCE 0x04 22 22 #define FDBD_FORMAT_UNIT_SIZE 2048 23 23 24 - struct fd_prot { 25 - unsigned char *prot_buf; 26 - struct scatterlist *prot_sg; 27 - u32 prot_sg_nents; 28 - }; 29 - 30 24 struct fd_dev { 31 25 struct se_device dev; 32 26