aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAsias He <asias@redhat.com>2013-02-25 01:03:44 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2013-04-25 04:05:24 -0400
commit43f55bbb144acca55cea50326388d1b648b6fd0f (patch)
treed38bf42231db5c1b946ba89c405c039ad7c51c25
parent506427628afeb5d70eefdac1fe4c2a1ffb27df5f (diff)
target/file: Add fd_do_unmap() helper
Add helper fd_do_unmap() to remove duplicated code in fd_execute_write_same_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>
-rw-r--r--drivers/target/target_core_file.c72
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 7e02304a1024..d5b84fac31c7 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -480,25 +480,16 @@ fd_execute_write_same(struct se_cmd *cmd)
480} 480}
481 481
482static sense_reason_t 482static sense_reason_t
483fd_execute_write_same_unmap(struct se_cmd *cmd) 483fd_do_unmap(struct se_cmd *cmd, struct file *file, sector_t lba, sector_t nolb)
484{ 484{
485 struct se_device *se_dev = cmd->se_dev;
486 struct fd_dev *fd_dev = FD_DEV(se_dev);
487 struct file *file = fd_dev->fd_file;
488 struct inode *inode = file->f_mapping->host; 485 struct inode *inode = file->f_mapping->host;
489 sector_t nolb = sbc_get_write_same_sectors(cmd);
490 int ret; 486 int ret;
491 487
492 if (!nolb) {
493 target_complete_cmd(cmd, SAM_STAT_GOOD);
494 return 0;
495 }
496
497 if (S_ISBLK(inode->i_mode)) { 488 if (S_ISBLK(inode->i_mode)) {
498 /* The backend is block device, use discard */ 489 /* The backend is block device, use discard */
499 struct block_device *bdev = inode->i_bdev; 490 struct block_device *bdev = inode->i_bdev;
500 491
501 ret = blkdev_issue_discard(bdev, cmd->t_task_lba, 492 ret = blkdev_issue_discard(bdev, lba,
502 nolb, GFP_KERNEL, 0); 493 nolb, GFP_KERNEL, 0);
503 if (ret < 0) { 494 if (ret < 0) {
504 pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n", 495 pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n",
@@ -507,7 +498,8 @@ fd_execute_write_same_unmap(struct se_cmd *cmd)
507 } 498 }
508 } else { 499 } else {
509 /* The backend is normal file, use fallocate */ 500 /* The backend is normal file, use fallocate */
510 loff_t pos = cmd->t_task_lba * se_dev->dev_attrib.block_size; 501 struct se_device *se_dev = cmd->se_dev;
502 loff_t pos = lba * se_dev->dev_attrib.block_size;
511 unsigned int len = nolb * se_dev->dev_attrib.block_size; 503 unsigned int len = nolb * se_dev->dev_attrib.block_size;
512 int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE; 504 int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
513 505
@@ -521,6 +513,28 @@ fd_execute_write_same_unmap(struct se_cmd *cmd)
521 } 513 }
522 } 514 }
523 515
516 return 0;
517}
518
519static sense_reason_t
520fd_execute_write_same_unmap(struct se_cmd *cmd)
521{
522 struct se_device *se_dev = cmd->se_dev;
523 struct fd_dev *fd_dev = FD_DEV(se_dev);
524 struct file *file = fd_dev->fd_file;
525 sector_t lba = cmd->t_task_lba;
526 sector_t nolb = sbc_get_write_same_sectors(cmd);
527 int ret;
528
529 if (!nolb) {
530 target_complete_cmd(cmd, SAM_STAT_GOOD);
531 return 0;
532 }
533
534 ret = fd_do_unmap(cmd, file, lba, nolb);
535 if (ret)
536 return ret;
537
524 target_complete_cmd(cmd, GOOD); 538 target_complete_cmd(cmd, GOOD);
525 return 0; 539 return 0;
526} 540}
@@ -531,13 +545,12 @@ fd_execute_unmap(struct se_cmd *cmd)
531 struct se_device *dev = cmd->se_dev; 545 struct se_device *dev = cmd->se_dev;
532 struct fd_dev *fd_dev = FD_DEV(dev); 546 struct fd_dev *fd_dev = FD_DEV(dev);
533 struct file *file = fd_dev->fd_file; 547 struct file *file = fd_dev->fd_file;
534 struct inode *inode = file->f_mapping->host;
535 unsigned char *buf, *ptr = NULL; 548 unsigned char *buf, *ptr = NULL;
536 sector_t lba; 549 sector_t lba;
537 int size; 550 int size;
538 u32 range; 551 u32 range;
539 sense_reason_t ret = 0; 552 sense_reason_t ret = 0;
540 int dl, bd_dl, err; 553 int dl, bd_dl;
541 554
542 /* We never set ANC_SUP */ 555 /* We never set ANC_SUP */
543 if (cmd->t_task_cdb[1]) 556 if (cmd->t_task_cdb[1])
@@ -594,34 +607,9 @@ fd_execute_unmap(struct se_cmd *cmd)
594 goto err; 607 goto err;
595 } 608 }
596 609
597 if (S_ISBLK(inode->i_mode)) { 610 ret = fd_do_unmap(cmd, file, lba, range);
598 /* The backend is block device, use discard */ 611 if (ret)
599 struct block_device *bdev = inode->i_bdev; 612 goto err;
600
601 err = blkdev_issue_discard(bdev, lba, range, GFP_KERNEL, 0);
602 if (err < 0) {
603 pr_err("FILEIO: blkdev_issue_discard() failed: %d\n",
604 err);
605 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
606 goto err;
607 }
608 } else {
609 /* The backend is normal file, use fallocate */
610 loff_t pos = lba * dev->dev_attrib.block_size;
611 unsigned int len = range * dev->dev_attrib.block_size;
612 int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
613
614 if (!file->f_op->fallocate) {
615 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
616 goto err;
617 }
618 err = file->f_op->fallocate(file, mode, pos, len);
619 if (err < 0) {
620 pr_warn("FILEIO: fallocate() failed: %d\n", err);
621 ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
622 goto err;
623 }
624 }
625 613
626 ptr += 16; 614 ptr += 16;
627 size -= 16; 615 size -= 16;