[stgt] [PATCH 12/15] ssc: add variable-length block read support
Mark Harvey
markh794 at gmail.com
Wed Nov 26 11:01:43 CET 2008
FUJITA Tomonori wrote:
> On Wed, 26 Nov 2008 17:46:38 +1100
> "Mark Harvey" <markh794 at gmail.com> wrote:
>
>>>> An attempt to read 128k from a 256k block results with an error message:
>>>> # dd if=/dev/st1 bs=128k count=1 of=/tmp/block0
>>>> dd: reading `/dev/st1': Cannot allocate memory
>>>> 0+0 records in
>>>> 0+0 records out
>>>> 0 bytes (0 B) copied, 0.01287 seconds, 0.0 kB/s
>>>>
>>>> And /var/log/messages:
>>>> kernel: st1: Failed to read 262144 byte block with 131072 byte transfer.
>>> I think that this is a kernel message that st driver gives when the
>>> INFORMATION field has a negative value. In this case, the INFORMATION
>>> field had -128K.
>>>
>>> I've attached a new patch. The difference from the previous one is
>>> just one line, it sets a negative value to the INFORMATION field when
>>> the requested transfer length is smaller than the actual logical block
>>> length.
>>>
>>>
>>>> Disclaimer...
>>>> I'm 99.99% positive, last time I tried this I received a different
>>>> message and did in fact read 128k of data. This may be an
>>>> implementation of dd used..
>>> With the same tape drive?
>> Yeah, same tape drive.
>>
>> I need to get hold of the 'other' linux box (Ubuntu x86_64bit I think)
>> - where the above was from an SLES-10
>
> I see. Please let me know if you see a different message.
OK, re-tested using Ubuntu - Same message as above - 'Can not allocate memory'..
Must be my faulty memory at play ;)
>
>
>>>> # rpm -qf `which dd`
>>>> coreutils-5.93-22.14
>>>> # uname -a
>>>> Linux dpg-markh 2.6.16.46-0.12-smp #1 SMP Thu May 17 14:00:09 UTC 2007
>>>> i686 i686 i386 GNU/Linux
>>>>
>>>>>
>>>>>>>> Now test if we can read in a more then a block (this fails returning
>>>>>>>> no data - we should have read in the 256k)
>>>>>>>> # dd if=/dev/st0 of=/tmp/block0 bs=512k count=1
>>>>>>>> dd: reading `/dev/st0': Input/output error
>>>>>>>> 0+0 records in
>>>>>>>> 0+0 records out
>>>>>>>> 0 bytes (0 B) copied, 0.00705821 s, 0.0 kB/s
>>>>>>> stgt should return the whole first block without sense, right?
>>>>>>>
>>>>>> The amount of data successfully read should be returned. In this example, 128k.
>>>>>>
>>>>>> The sense returned should be :NO SENSE | VALID | ILI (Illegal Length
>>>>>> Indicator) and the amount of data NOT successfully returned -> filled
>>>>>> in sense_buffer[3] -> sense_buffer[7]
>>>>> With the patch, stgt returns CHECK CONDITION with a sense (NO SENSE |
>>>>> VALID | ILI ) and the information field sets to 256K.
>>>>>
>>>>> nemo:/home/fujita# dd if=/dev/st0 of=/tmp/block0 bs=512k count=1
>>>>> 0+1 records in
>>>>> 0+1 records out
>>>>> 262144 bytes (262 kB) copied, 0.019265 seconds, 13.6 MB/s
>>>>>
>>>>> This is the right response?
>>>> This is the correct response...
>>>>
>>>>
>>>> Many thanks for having a look at this.
>>> No problem at all. Thanks!
>>>
>>>
>>> diff --git a/usr/bs_ssc.c b/usr/bs_ssc.c
>>> index 0b9fedb..9ed9e65 100644
>>> --- a/usr/bs_ssc.c
>>> +++ b/usr/bs_ssc.c
>>> @@ -317,15 +317,27 @@ static int resp_var_read(struct scsi_cmd *cmd, uint8_t *buf, uint32_t length,
>>> *transferred = 0;
>>>
>>> if (length != h->blk_sz) {
>>> + uint8_t info[4];
>>> + int val = length - h->blk_sz;
>>> +
>>> + put_unaligned_be32(val, info);
>>> +
>>> if (h->blk_type == BLK_EOD)
>>> sense_data_build(cmd, 0x40 | BLANK_CHECK,
>>> NO_ADDITIONAL_SENSE);
>>> else
>>> - sense_data_build(cmd, NO_SENSE, NO_ADDITIONAL_SENSE);
>>> + ssc_sense_data_build(cmd, NO_SENSE | 0x20,
>>> + NO_ADDITIONAL_SENSE,
>>> + info, sizeof(info));
>>> +
>>> + if (length > h->blk_sz)
>>> + scsi_set_in_resid_by_actual(cmd, length - h->blk_sz);
>>> + else
>>> + scsi_set_in_resid_by_actual(cmd, 0);
>>>
>>> length = min(length, h->blk_sz);
>>> +
>>> result = SAM_STAT_CHECK_CONDITION;
>>> - scsi_set_in_resid_by_actual(cmd, length);
>>>
>>> if (!length)
>>> goto out;
>>>
>> Success with above patch :)
>>
>> Write 2 x 128k blocks to tape...
>> # dd if=/dev/zero of=/dev/st8 bs=128k count=2
>> 2+0 records in
>> 2+0 records out
>> 262144 bytes (262 kB) copied, 0.138255 seconds, 1.9 MB/s
>>
>> Attempt to read a single 256k block. (correctly returns complete 128k block)..
>> # dd if=/dev/st8 bs=256k count=1 of=/tmp/b1
>> 0+1 records in
>> 0+1 records out
>> 131072 bytes (131 kB) copied, 0.017385 seconds, 7.5 MB/s
>
> With this patch, I think that if the requested transfer length is
> smaller than the actual logical block length, you get the same 'Cannot
> allocate memory' message. As we have done so far, the following
> commands give the same message with this patch:
>
> # dd if=/dev/zero of=/dev/st0 bs=256k count=1
> # dd if=/dev/st0 of=/tmp/block0 bs=128k count=1
>
>
> Anyway, seems that this patch does the correct thing, right?
>
Yes, this patch is doing the right thing.
Cheers
Mark
--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list