Re: [PARPORT] Tape backup with mt & tar


J. Scott Berg (jsberg@earthlink.net)
Tue, 24 Aug 1999 07:38:48 -0500 (EST)


On Tue, 24 Aug 1999, Art Wildman wrote:

> # mt -f /dev/npt0 fsf 1
> pt0: HP COLORADO 8GBe, master, blocksize 512, 4007 MB
> pt0: Unimplemented mt_op 1
> /dev/pt0: Invalid argument
> ... how do I skip forward to next archive???
>
> This makes storing multiple tar files on a tape useless, if you
> can't retrieve them. Please explain what's going on.

Pretty much what it says: "unimplemented mt_op." The only mt
operation implemented at this point is rewind, as you discovered.
I've implemented the filemark-related mt ops, but there are a couple
issues to get settled before releasing it to prime time:

1) This is the first time I've written anything into the kernel
proper, so there's a substantive chance that it will crash your
kernel. It doesn't crash mine, but YMMV. Actually, what I've done is
virtually identical to what is done for a rewind, so I would hope it
would be harmless, but I'm waiting for feedback to make sure.

2) As far as I can tell, the SCSI tape driver and the IDE tape driver
both have different conventions for writing filemarks. I've adopted a
third one B~). I think (?) the different conventions are irrelevant if
you never make a weof mt ioctl.

Since I sent this to Grant 1-1/2 weeks ago and haven't heard back,
I'll post the kernel patch (against 2.2.11) with the cavaet that you
don't complain when it trashes your hard drive and that you promise
not to try to write filemarks. Please send me any feedback.

-- 
J. Scott Berg                      jsberg@earthlink.net
3025 E. Amy Ln.                    (812) 339-8368
Bloomington, IN  47408-4220

--- linux-2.2.11/drivers/block/paride/pt.c Tue Dec 22 11:29:00 1998 +++ linux-2.2.11-dev/drivers/block/paride/pt.c Fri Aug 13 21:31:38 1999 @@ -202,6 +202,7 @@ #define ATAPI_READ_6 0x08 #define ATAPI_WRITE_6 0x0a #define ATAPI_WFM 0x10 +#define ATAPI_SPC 0x11 #define ATAPI_IDENTIFY 0x12 #define ATAPI_MODE_SENSE 0x1a #define ATAPI_LOG_SENSE 0x4d @@ -231,6 +232,8 @@ #define PT_WRITING 8 #define PT_READING 16 #define PT_EOF 32 +#define PT_SPREV 64 +#define PT_WROTE_MARK 128 #define PT_NAMELEN 8 #define PT_BUFSIZE 16384 @@ -515,6 +518,42 @@ pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark"); } +static void pt_space( int unit, int count ) + +{ + /* No sane person has 8M filemarks on their tape. My tape probably + won't even hold 8M filemarks. But being a stickler for + standards... */ + while (count != 0) { + unsigned cmd_count; + /* Really, I could put this outside the loop. But for some reason, + pt_media_access_cmd and everything it calls take char * instead + of const char * */ + unsigned char sp_cmd[12] = {ATAPI_SPC,1,0,0,0,0,0,0,0,0,0,0}; + if (count > 0x7fffff) { + cmd_count = 0x7fffff; + count -= 0x7fffff; + } + else if (count >= 0) { + cmd_count = count; + count = 0; + } + else if (count < -0x7fffff) { + cmd_count = 0x800001; + count += 0x7fffff; + } + else { + cmd_count = -count; + cmd_count = (cmd_count^0xffffff)+1; + count = 0; + } + sp_cmd[2] = (cmd_count & 0xff0000) >> 16; + sp_cmd[3] = (cmd_count & 0xff00) >> 8; + sp_cmd[4] = cmd_count & 0xff; + pt_media_access_cmd(unit,PT_TMO,(char *)sp_cmd,"space"); + } +} + #define DBMSG(msg) ((verbose>1)?(msg):NULL) static int pt_reset( int unit ) @@ -616,6 +655,10 @@ if (!pt_atapi(unit,ms_cmd,36,buf,"mode sense")) { if (!(buf[2] & 0x80)) PT.flags |= PT_WRITE_OK; + if (buf[buf[3]+8] & 0x20) PT.flags |= PT_SPREV; + /* Strictly speaking, QIC-157 doesn't require any block + descriptors. If we ran into one of those animals, the + following will fail */ PT.bs = xn(buf,10,2); } @@ -753,6 +796,49 @@ pt_rewind(unit); return 0; + case MTWEOF: + while (mtop.mt_count--) + pt_write_fm(unit); + PT.flags |= PT_WROTE_MARK; + return 0; + + case MTFSF: + pt_space(unit,mtop.mt_count); + return 0; + + case MTBSF: + if (PT.flags & PT_SPREV) { + pt_space(unit,-mtop.mt_count); + return 0; + } + else { + printk("%s: Device cannot space in reverse\n",PT.name); + return -EIO; + } + + case MTFSFM: + if (PT.flags & PT_SPREV) { + pt_space(unit,mtop.mt_count); + pt_space(unit,-1); + return 0; + } + else { + printk("%s: Device cannot space in reverse\n",PT.name); + return -EIO; + } + + + case MTBSFM: + if (PT.flags & PT_SPREV) { + pt_space(unit,-mtop.mt_count); + pt_space(unit,1); + return 0; + } + else { + printk("%s: Device cannot space in reverse\n",PT.name); + return -EIO; + } + default: printk("%s: Unimplemented mt_op %d\n",PT.name, mtop.mt_op); @@ -774,7 +860,8 @@ if ((unit >= PT_UNITS) || (PT.access <= 0)) return -EINVAL; - if (PT.flags & PT_WRITING) pt_write_fm(unit); + if ((PT.flags & (PT_WRITING|PT_WROTE_MARK)) == PT_WRITING) + pt_write_fm(unit); if (PT.flags & PT_REWIND) pt_rewind(unit); @@ -885,6 +972,7 @@ if (!(PT.flags & (PT_READING|PT_WRITING))) { PT.flags |= PT_WRITING; + PT.flags &= ~PT_WROTE_MARK; if (pt_atapi(unit,wr_cmd,0,NULL,"start buffer-available mode")) return -EIO; } else if (PT.flags&PT_READING) return -EIO; N‹§²æìr¸›zǧvf¢–Ú%Š{±¥ªé¢»kz«ž²Ûh®«žÂ+a¶¬Šx%{ +véì¹»®&ÞŠ{ayºʇí…鞲Ơ



This archive was generated by hypermail 2.0b3 on Tue 24 Aug 1999 - 08:41:47 EDT