[stgt] [PATCH 12/15] ssc: add variable-length block read support

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Wed Nov 26 07:55:41 CET 2008


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.


> >> # 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?
--
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