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 |