Hi Kai,

Tested with patched kernel 4.5.0-rc2-next-20160202+. It's looking good 
everything partition related passed with DDS5 and LTO6. You can definitely add 
me as a tested-by. I did find one issue below but it's not related to the 
partitioning changes.

# ./mt -f /dev/st0 stsetoption debug
# ./mt -f /dev/st0 stsetoption can-partitions
# ./mt -f /dev/st0 mkpartition 10000

[ 1871.160395] st 3:0:0:0: [st0] Block limits 1 - 16777215 bytes.
[ 1871.160955] st 3:0:0:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8
[ 1871.160958] st 3:0:0:0: [st0] Density 5a, tape length: 0, drv buffer: 1
[ 1871.160962] st 3:0:0:0: [st0] Block size: 0, buffer size: 4096 (1 blocks).
[ 1871.160963] st 3:0:0:0: [st0] Updating partition number in status.
[ 1871.161915] st 3:0:0:0: [st0] Got tape pos. blk 0 part 0.
[ 1871.161942] st 3:0:0:0: [st0] Loading tape.
[ 1871.176784] st 3:0:0:0: [st0] Block limits 1 - 16777215 bytes.
[ 1871.177284] st 3:0:0:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8
[ 1871.177289] st 3:0:0:0: [st0] Density 5a, tape length: 0, drv buffer: 1
[ 1871.177293] st 3:0:0:0: [st0] Block size: 0, buffer size: 4096 (1 blocks).
[ 1871.178632] st 3:0:0:0: [st0] Partition page length is 16 bytes.
[ 1871.178637] st 3:0:0:0: [st0] PP: max 3, add 1, xdp 1, psum 03, pofmetc 4, 
rec 03, units 09, sizes: 38 2543
[ 1871.178642] st 3:0:0:0: [st0] MP: 11 0e 03 01 3c 03 09 00 00 26 09 ef
[ 1871.178645] st 3:0:0:0: [st0] psd_cnt 2, max.parts 3, nbr_parts 1
[ 1871.178648] st 3:0:0:0: [st0] Formatting tape with two partitions (1 = 10000 
MB).
[ 1871.178651] st 3:0:0:0: [st0] Sent partition page length is 12 bytes. 
needs_format: 1
[ 1871.178655] st 3:0:0:0: [st0] PP: max 3, add 1, xdp 1, psum 03, pofmetc 4, 
rec 03, units 09, sizes: 65535 10
[ 1871.178659] st 3:0:0:0: [st0] MP: 11 0a 03 01 3c 03 09 00 ff ff 00 0a
[ 1871.179655] st 3:0:0:0: [st0] Sending FORMAT MEDIUM
[ 1883.702742] st 3:0:0:0: [st0] Rewinding tape.

And we can change to partition 1 and back again. I ran this (I used the tell 
option but that failed more on that below):

# ./mt -f /dev/st0 setpartition 1
# ./mt -f /dev/st0 status
SCSI 2 tape drive:
File number=0, block number=0, partition=1.
Tape block size 0 bytes. Density code 0x5a (no translation).
Soft error count since last status=0
General status bits on (41010000):
 BOT ONLINE IM_REP_EN

Then wrote a tar archive to the drive and changed back to partition 0 and 
confirmed that I couldn't read the archive.

#  ./mt -f /dev/st0 mkpartition -10000

[ 3813.227898] st 3:0:0:0: [st0] Block limits 1 - 16777215 bytes.
[ 3813.228399] st 3:0:0:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8
[ 3813.228404] st 3:0:0:0: [st0] Density 5a, tape length: 0, drv buffer: 1
[ 3813.228408] st 3:0:0:0: [st0] Block size: 0, buffer size: 4096 (1 blocks).
[ 3813.228427] st 3:0:0:0: [st0] Loading tape.
[ 3813.242855] st 3:0:0:0: [st0] Block limits 1 - 16777215 bytes.
[ 3813.243304] st 3:0:0:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8
[ 3813.243310] st 3:0:0:0: [st0] Density 5a, tape length: 0, drv buffer: 1
[ 3813.243313] st 3:0:0:0: [st0] Block size: 0, buffer size: 4096 (1 blocks).
[ 3813.244552] st 3:0:0:0: [st0] Partition page length is 16 bytes.
[ 3813.244559] st 3:0:0:0: [st0] PP: max 3, add 1, xdp 1, psum 03, pofmetc 4, 
rec 03, units 09, sizes: 2543 38
[ 3813.244564] st 3:0:0:0: [st0] MP: 11 0e 03 01 3c 03 09 00 09 ef 00 26
[ 3813.244567] st 3:0:0:0: [st0] psd_cnt 2, max.parts 3, nbr_parts 1
[ 3813.244570] st 3:0:0:0: [st0] Formatting tape with two partitions (0 = 10000 
MB).
[ 3813.244573] st 3:0:0:0: [st0] Sent partition page length is 12 bytes. 
needs_format: 1
[ 3813.244578] st 3:0:0:0: [st0] PP: max 3, add 1, xdp 1, psum 03, pofmetc 4, 
rec 03, units 09, sizes: 10 65535
[ 3813.244582] st 3:0:0:0: [st0] MP: 11 0a 03 01 3c 03 09 00 00 0a ff ff
[ 3813.245907] st 3:0:0:0: [st0] Sending FORMAT MEDIUM
[ 3821.916760] st 3:0:0:0: [st0] Rewinding tape.

That worked and I did the same tar test after changing partitions to make sure 
that I couldn't read it back after changing back to partition 0.

I retested the DDS5 drive it still works as expected.

I did find one issue in testing unrelated to the changes, the tell option 
didn't work with my LTO-6 drive:

# ./mt -f /dev/st0 tell
/dev/st0: Input/output error

[ 2045.974642] st 3:0:0:0: [st0] Block limits 1 - 16777215 bytes.
[ 2045.975221] st 3:0:0:0: [st0] Mode sense. Length 11, medium 0, WBS 10, BLL 8
[ 2045.975224] st 3:0:0:0: [st0] Density 5a, tape length: 0, drv buffer: 1
[ 2045.975226] st 3:0:0:0: [st0] Block size: 0, buffer size: 4096 (1 blocks).
[ 2045.975718] st 3:0:0:0: [st0] Error: 8000002, cmd: 34 1 0 0 0 0
[ 2045.975723] st 3:0:0:0: [st0] Sense Key : Illegal Request [current]
[ 2045.975726] st 3:0:0:0: [st0] Add. Sense: Invalid field in cdb
[ 2045.975729] st 3:0:0:0: [st0]  Can't read tape position.
[ 2045.975857] st 3:0:0:0: [st0] Rewinding tape.

I believe that in get_location() we're doing this:

static int get_location(struct scsi_tape *STp, unsigned int *block, int 
*partition,
                        int logical)
{
        int result;
        unsigned char scmd[MAX_COMMAND_SIZE];
        struct st_request *SRpnt;

        if (STp->ready != ST_READY)
                return (-EIO);

        memset(scmd, 0, MAX_COMMAND_SIZE);
        if ((STp->device)->scsi_level < SCSI_2) {
                scmd[0] = QFA_REQUEST_BLOCK;
                scmd[4] = 3;
        } else {
                scmd[0] = READ_POSITION;
                if (!logical && !STp->scsi2_logical)
                        scmd[1] = 1; <<<<<<<<<<<<<<
        }

When called from the ioctl that the tell option uses the variable logical is 
passed in as 0 (from what I could see everything else sets it to 1). For a 
READ_POSITION the drive I'm using only supports 0, 6, or 8 in the service 
action field of the second byte:

https://docs.oracle.com/cd/E38452_01/en/LTO6_Vol3_E1_D20/LTO6_Vol3_E1_D20.pdf

For SSC-3 (e.g. http://www.13thmonkey.org/documentation/SCSI/ssc3r01c.pdf) it 
looks like service action 1 is vendor specific and optional so it may not be 
implemented. SSC-2 defines that bit separately 
(http://www.staff.uni-mainz.de/tacke/scsi/SCSI2-10.html) as "A block address 
type (BT) bit of one requests the target to return its current first block 
location and last block location as a device-specific value.". 

It may need a test on scsi3 like in partition_tape so it would look like:

static int get_location(struct scsi_tape *STp, unsigned int *block, int 
*partition,
                        int logical)
{
        int result;
        unsigned char scmd[MAX_COMMAND_SIZE];
        struct st_request *SRpnt;
+       bool scsi3 = STp->device->scsi_level >= SCSI_3;

        if (STp->ready != ST_READY)
                return (-EIO);

        memset(scmd, 0, MAX_COMMAND_SIZE);
        if ((STp->device)->scsi_level < SCSI_2) {
                scmd[0] = QFA_REQUEST_BLOCK;
                scmd[4] = 3;
        } else {
                scmd[0] = READ_POSITION;
-               if (!logical && !STp->scsi2_logical)
+               if (!logical && !STp->scsi2_logical && !scsi3)
                        scmd[1] = 1;
        }

If you're fine with that and you don't believe it will have any side effects I 
can post a patch for that.

Thanks
Shane
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to