diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-08-10 21:41:14 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-08-22 15:26:25 -0400 |
commit | 7abbe7f3e4243e28a9169ee1b8d76f10a6f5d37c (patch) | |
tree | 7edb86180f5b093cbef210562af8712d2d98d7fa /drivers/target | |
parent | 72f4ba1e32a1e5da31dcf14ea4b8985ae88a8bdb (diff) |
target: Fix SYNCHRONIZE_CACHE zero LBA + range breakage
This patch fixes a SYNCHRONIZE_CACHE CDB handling bug with IBLOCK/FILEIO
backends where transport_cmd_get_valid_sectors() was incorrectly rejecting
a zero LBA + range CDB from being processed, and returning CHECK_CONDITION.
This includes changing transport_cmd_get_valid_sectors() to return '0' on
success and '-EINVAL' on failure (this makes more sense than sectors),
and to only check transport_cmd_get_valid_sectors() when a non zero LBA +
range SYNCHRONIZE_CACHE operation has been receieved for the non passthrough
case.
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_transport.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index d35c2cc779e9..d385c317a7a4 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -2853,12 +2853,10 @@ static int transport_cmd_get_valid_sectors(struct se_cmd *cmd) | |||
2853 | " transport_dev_end_lba(): %llu\n", | 2853 | " transport_dev_end_lba(): %llu\n", |
2854 | cmd->t_task_lba, sectors, | 2854 | cmd->t_task_lba, sectors, |
2855 | transport_dev_end_lba(dev)); | 2855 | transport_dev_end_lba(dev)); |
2856 | pr_err(" We should return CHECK_CONDITION" | 2856 | return -EINVAL; |
2857 | " but we don't yet\n"); | ||
2858 | return 0; | ||
2859 | } | 2857 | } |
2860 | 2858 | ||
2861 | return sectors; | 2859 | return 0; |
2862 | } | 2860 | } |
2863 | 2861 | ||
2864 | static int target_check_write_same_discard(unsigned char *flags, struct se_device *dev) | 2862 | static int target_check_write_same_discard(unsigned char *flags, struct se_device *dev) |
@@ -3350,10 +3348,12 @@ static int transport_generic_cmd_sequencer( | |||
3350 | cmd->se_cmd_flags |= SCF_EMULATE_CDB_ASYNC; | 3348 | cmd->se_cmd_flags |= SCF_EMULATE_CDB_ASYNC; |
3351 | /* | 3349 | /* |
3352 | * Check to ensure that LBA + Range does not exceed past end of | 3350 | * Check to ensure that LBA + Range does not exceed past end of |
3353 | * device. | 3351 | * device for IBLOCK and FILEIO ->do_sync_cache() backend calls |
3354 | */ | 3352 | */ |
3355 | if (!transport_cmd_get_valid_sectors(cmd)) | 3353 | if ((cmd->t_task_lba != 0) || (sectors != 0)) { |
3356 | goto out_invalid_cdb_field; | 3354 | if (transport_cmd_get_valid_sectors(cmd) < 0) |
3355 | goto out_invalid_cdb_field; | ||
3356 | } | ||
3357 | break; | 3357 | break; |
3358 | case UNMAP: | 3358 | case UNMAP: |
3359 | size = get_unaligned_be16(&cdb[7]); | 3359 | size = get_unaligned_be16(&cdb[7]); |