NetBSD Problem Report #53890
From www@NetBSD.org Fri Jan 18 15:17:48 2019
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 8B7757A177
for <gnats-bugs@gnats.NetBSD.org>; Fri, 18 Jan 2019 15:17:48 +0000 (UTC)
Message-Id: <20190118151746.9874D7A270@mollari.NetBSD.org>
Date: Fri, 18 Jan 2019 15:17:46 +0000 (UTC)
From: pa0gri@amsat.org
Reply-To: pa0gri@amsat.org
To: gnats-bugs@NetBSD.org
Subject: st(4) driver for tapes not working o variable block size
X-Send-Pr-Version: www-1.0
>Number: 53890
>Category: port-amd64
>Synopsis: st(4) driver for tapes not working o variable block size
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-amd64-maintainer
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jan 18 15:20:00 +0000 2019
>Closed-Date: Fri Apr 10 13:11:32 +0000 2020
>Last-Modified: Fri Apr 10 13:11:32 +0000 2020
>Originator: Gerard J van der Grinten
>Release: NetBSD 5.x 6.x 7.x 8.0
>Organization:
private
>Environment:
uname -a
NetBSD plato.net27.gri 8.0 NetBSD 8.0 (GENERIC) #0: Tue Jul 17 14:59:51 UTC 2018 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
I have tried my problem under various versions of NetBSD AMD65 and I386.
I want to read and write .TAP files (SIMH containers)on various Tape drive
models (currently a DDS4 Drive.
To my great disappointment It works flawlessly under Debian Linux.
Here a sample session:
plato# ./mt2tap xxz
Converting tape to tap file xxz
rc NOP ioctl = 0
rc on set block size = 0
rc on set density = 0
rc on set compression = 0
len1 = 00486 rc NOP ioctl = 0
len2 = 00486
Reading block: Invalid argument
blocks = 00002
plato# ls -l xx*
-rw-r--r-- 1 root wheel 35670660 Jan 11 14:55 xx
-rw-r--r-- 1 root wheel 35670660 Jan 11 17:11 xx.tap
-rw-r--r-- 1 root wheel 10260 Jan 13 14:26 xx1
-rw-r--r-- 1 root wheel 2068 Jan 11 16:41 xxx
-rw-r--r-- 1 root wheel 35670660 Jan 12 13:32 xxx.tap
-rw-r--r-- 1 root wheel 35670660 Jan 11 14:31 xxxx
-rw-r--r-- 1 root wheel 20008 Jan 13 14:18 xxxx.t
-rw-r--r-- 1 root wheel 0 Jan 13 13:53 xxxx.tap
-rw-r--r-- 1 root wheel 494 Jan 18 14:14 xxz
plato# ./tap2mt xx.tap
3584 65536
rc on MTREW = 0
rc on set block size = 0
rc on set density = 0
rc on set compression = 0
len = 00486
len = 00930
Error writing tape (end?) act -1 exp 930.
plato# ./tap2mt -t /dev/rst0 xx.tap
3584 65536
rc on MTREW = 0
rc on set block size = 0
rc on set density = 0
rc on set compression = 0
len = 00486
len = 00930
Error writing tape (end?) act -1 exp 930.
plato#
Linux correctly reads and writes the tap files.
The ST I/O read and write give up after the fist record.
My record sizes vary fro 80 to 386
My mt2tap.c and tap2mt.c follow:
===============================================
/*
* tap2mt.c - Write a .tap file to a magnetic tape.
*
* Copyright 1998,1999,2000,2002,2015,2019 - G. J. van der Grinten
* All rights reserved by G. J. van der Grinten
* Pater L.A. Bleysstraat 7
* 5684 TR Best
* Netherlands
densityCode Format
0 Device default
1 1/2" 800 bpi
2 1/2" 1600 bpi
3 1/2" 6250 bpi
4 QIC-11
5 QIC-24
15 QIC-120
16 QIC-150
17 QIC-320/525
18 QIC-1320/1350
19 DDS
28 QIC-385M
29 QIC-410M
30 QIC-1000C
31 QIC-2100C
32 QIC-6GB
33 QIC-20GB
34 QIC-2GB
35 QIC-875M
36 DDS-2
37 DDS-3
38 DDS-4
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#if !defined(_WIN32)
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#if defined(_WIN32)
#include "getopt.c"
#define TAPE "\\\\.\\TAPE0"
#else
#if defined(__linux__) || defined(__gnu_linux__) || defined(linux)
#define TAPE "/dev/st0"
#elif ((defined __NetBSD__) || defined (__FreeBSD__))
#define TAPE "/dev/rst0"
#endif
#endif
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define MTSETBLK MTSETBSIZ
#define MTSETDENSITY MTSETDNSTY
#define MTCOMPRESSION MTCMPRESS
#endif
unsigned char buf[100000];
static union {
int number;
char bytes[4];
} endianCheck;
int endian = 0;
void init_endian()
{
endianCheck.number = 0;
endianCheck.bytes[3] = 1;
endian = endianCheck.number == 1 ? 1 : 0;
}
int to_intel(int a)
{
int _tmp;
if (endian) {
_tmp = a;
((char *)(void *)&a)[0] = ((char *)(void *)&_tmp)[3];
((char *)(void *)&a)[1] = ((char *)(void *)&_tmp)[2];
((char *)(void *)&a)[2] = ((char *)(void *)&_tmp)[1];
((char *)(void *)&a)[3] = ((char *)(void *)&_tmp)[0];
}
return a;
}
void usage()
{
fprintf(stderr, "Usage: tap2mt [[-d <density>] [-t <tape device>]] <tap_file> \n");
exit(1);
}
int main(int argc, char **argv)
{
FILE *infile;
int mt;
int recLen1;
int recLen2;
int len;
int rc;
int ch;
int dens = 0;
char *dev = TAPE;
struct stat stbuf;
struct mtop op;
init_endian();
while(( ch = getopt(argc, argv, "d:t:")) != -1) {
switch(ch) {
case 'd':
dens = atoi(optarg);
break;
case 't':
dev = optarg;
break;
default :
usage();
}
}
#if !defined(_WIN32)
argc -= optind;
argv += optind;
#endif
if (argc != 1) {
usage();
}
#if !defined(_WIN32)
#if defined __linux__
if (!stat(dev, &stbuf) && !S_ISCHR(stbuf.st_mode)) {
#elif ((defined __NetBSD__) || defined (__FreeBSD__))
if (!stat(dev, &stbuf) && !S_ISCHR(stbuf.st_mode)) {
#endif
fprintf(stderr, "The tape drive '%s' is not an expected device.\n", dev);
// exit( 1);
}
#endif
printf("%d %d\n", stbuf.st_rdev, stbuf.st_blksize);
if ((mt = open(dev, O_RDWR, 0)) < 0)
{
perror("could not open tape drive");
exit(1);
}
op.mt_op = MTREW;
op.mt_count = 1;
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc on MTREW = %d\n",rc);
#if ((defined __NetBSD__) || defined (__FreeBSD__))
op.mt_op = MTSETBSIZ;
#else
op.mt_op = MTSETBLK;
#endif
op.mt_count = 0; /* blockize = 0 (variable) */
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc on set block size = %d\n",rc);
#if ((defined __NetBSD__) || defined (__FreeBSD__))
op.mt_op = MTSETDNSTY;
#else
op.mt_op = MTSETDENSITY;
#endif
op.mt_count = dens; /* 1600 BPI */
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc on set density = %d\n",rc);
#if ((defined __NetBSD__) || defined (__FreeBSD__))
op.mt_op = MTCMPRESS;
#elif defined __linux__
op.mt_op = MTCOMPRESSION;
#endif
op.mt_count = 0; /* no compression */
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc on set compression = %d\n",rc);
if ((infile = fopen(argv[0], "rb")) == NULL) {
perror("could not open input file");
exit(1);
}
while(1) {
len = fread(&recLen1, sizeof(recLen1), 1, infile);
if (len <= 0) {
fprintf(stderr, "End of Information\n");
break;
}
recLen1 = to_intel(recLen1);
if (recLen1 > 0) {
len = fread(buf, 1, recLen1, infile);
if (recLen1 != len) {
fprintf(stderr, "Read %d bytes, expected %d\n",len,recLen1);
break;
}
len = fread(&recLen2, sizeof(recLen2), 1, infile);
recLen2 = to_intel(recLen2);
if (len <= 0 || recLen2 != recLen1) {
fprintf(stderr, "Mismatch in TAP record\n");
break;
}
}
#if 1
fprintf(stdout, "len = %05d\n", recLen1);
fflush(stdout);
#endif
if (recLen1 == 0) {
op.mt_op = MTWEOF;
op.mt_count = 1;
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
fprintf(stderr, "zero length %d\n", rc);
} else {
if((rc = write(mt, buf, recLen1)) != recLen1) {
fprintf(stderr,"Error writing tape (end?) act %d exp %d.\n",rc, recLen1);
exit(1);
}
}
}
op.mt_op = MTWEOF;
op.mt_count = 2;
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
fclose(infile);
close(mt);
return(0);
}
#else
int main(int argc, char **argv)
{
printf("this program is not supported under a MsWindows OS\n");
return(0);
}
#endif
======================================================================
/*
* mt2tap.c - Read a magntic tape to a .tap file.
*
* Copyright 1998,1999,2000,2002,2015,2019 - G. J. van der Grinten
* All rights reserved by G. J. van der Grinten
* Pater L.A. Bleysstraat 7
* 5684 TR Best
* Netherlands
*/
// #elif defined(__GNUC__) && (defined(__linux__) || defined(__SunOS) || defined (__FreeBSD__))
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#if !defined(_WIN32)
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/mtio.h>
#include <fcntl.h>
#if defined(_WIN32)
#include "getopt.c"
#define TAPE "\\\\.\\TAPE0"
#else
#if defined(__linux__) || defined(__gnu_linux__) || defined(linux)
#define TAPE "/dev/st0"
#elif ((defined __NetBSD__) || defined (__FreeBSD__)) || defined(__OpenBSD__)
#define TAPE "/dev/rst0"
#endif
#endif
unsigned char buf[20000];
static union {
int number;
char bytes[4];
} endianCheck;
int endian = 0;
void init_endian()
{
endianCheck.number = 0;
endianCheck.bytes[3] = 1;
endian = endianCheck.number == 1 ? 1 : 0;
}
int to_intel(a)
int a;
{
int _tmp;
if (endian) {
_tmp = a;
((char *)(void *)&a)[0] = ((char *)(void *)&_tmp)[3];
((char *)(void *)&a)[1] = ((char *)(void *)&_tmp)[2];
((char *)(void *)&a)[2] = ((char *)(void *)&_tmp)[1];
((char *)(void *)&a)[3] = ((char *)(void *)&_tmp)[0];
}
return a;
}
void usage()
{
fprintf(stderr, "Usage: mt2tap [[-d <density>] [-t <tape device>]] <tap_file> \n");
exit(1);
}
int main(int argc, char **argv)
{
FILE *tapfile;
int mt;
int ic;
int oc;
int zero = 0;
int ch;
int rc;
int blocks = 0;
int dens = 38;
char *dev = TAPE;
struct stat stbuf;
struct mtop op;
init_endian();
while(( ch = getopt(argc, argv, "d:t:")) != -1) {
switch(ch) {
case 'd':
dens = atoi(optarg);
break;
case 't':
dev = optarg;
break;
default :
usage();
}
}
#if !defined(_WIN32)
argc -= optind;
argv += optind;
#endif
if (argc != 1) {
usage();
}
printf("Converting tape to tap file %s \n",argv[0]);
#if !defined(_WIN32)
#if defined __linux__
if (!stat(dev, &stbuf) && !S_ISCHR(stbuf.st_mode)) {
#elif ((defined __NetBSD__) || defined (__FreeBSD__))
if (!stat(dev, &stbuf) && !S_ISCHR(stbuf.st_mode)) {
#endif
fprintf(stderr, "The tape drive '%s' is not an expected device.\n", dev);
// exit( 1);
}
#endif
if ((mt = open(dev, O_RDONLY | O_NONBLOCK ,0)) < 0)
{
perror("could not open tape device");
exit(1);
}
if ((tapfile = fopen(argv[0], "wb")) == NULL)
{
perror("open TAP file");
exit(1);
}
#if !defined(_WIN32)
op.mt_op = MTNOP;
op.mt_count = 0; /* no compression */
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc NOP ioctl = %d\n",rc);
#endif
op.mt_op = MTREW;
op.mt_count = 1;
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
#if ((defined __NetBSD__) || defined (__FreeBSD__))
op.mt_op = MTSETBSIZ;
#else
op.mt_op = MTSETBLK;
#endif
op.mt_count = 0; /* blockize = 0 (variable) */
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc on set block size = %d\n",rc);
#if ((defined __NetBSD__) || defined (__FreeBSD__))
op.mt_op = MTSETDNSTY;
#else
op.mt_op = MTSETDENSITY;
#endif
op.mt_count = dens; /* 1600 BPI */
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc on set density = %d\n",rc);
#if ((defined __NetBSD__) || defined (__FreeBSD__))
op.mt_op = MTCMPRESS;
#elif defined __linux__
op.mt_op = MTCOMPRESSION;
#endif
op.mt_count = 0; /* no compression */
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc on set compression = %d\n",rc);
while ((ic = read(mt, buf, sizeof(buf))) >= 0) {
#if 1
fprintf(stdout, "len1 = %05d ", ic);
fflush(stdout);
op.mt_op = MTNOP;
op.mt_count = 0;
rc = ioctl(mt, MTIOCTOP, &op, sizeof(op));
printf("rc NOP ioctl = %d\n",rc);
#endif
blocks++;
if (ic == 0) {
zero += 1;
if (zero >= 2) { /* write trailing EOF's */
oc = 0;
for (ic = 0 ; ic < 2; ic++) { /* write 2 EOF markers */
if (fwrite(&oc, sizeof(oc), 1, tapfile) != 1) {
perror("fwrite eoi");
exit(1);
}
}
break;
}
} else {
zero = 0;
}
oc = to_intel(ic);
if (fwrite(&oc, sizeof(oc), 1, tapfile) != 1) {
perror("fwrite1");
exit(1);
}
if (ic > 0) {
if (fwrite(&buf, 1, ic, tapfile) != ic) {
perror("fwrite2");
exit(1);
}
#if 1
fprintf(stdout, "len2 = %05d\n", ic);
fflush(stdout);
#endif
if (fwrite(&oc, sizeof(oc), 1, tapfile) != 1) {
perror("fwrite3");
exit(1);
}
}
blocks++;
}
if (ic < 0) {
perror("Reading block");
#if 1
fprintf(stdout, "blocks = %05d\n", blocks);
fflush(stdout);
#endif
}
fclose(tapfile);
close(mt);
return(0);
}
#else
int main(int argc, char **argv)
{
printf("this program is not supported under a MsWindows OS\n");
return(0);
}
#endif
=========================================================
Gerard.
>How-To-Repeat:
create a few blocks and try the programs.
If I did miss somthtig , please tell me.
>Fix:
Unknown
>Release-Note:
>Audit-Trail:
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable block size
Date: Fri, 18 Jan 2019 19:19:57 -0000 (UTC)
pa0gri@amsat.org writes:
>>Description:
>I have tried my problem under various versions of NetBSD AMD65 and I386.
>I want to read and write .TAP files (SIMH containers)on various Tape drive
>models (currently a DDS4 Drive.
>To my great disappointment It works flawlessly under Debian Linux.
The driver probably logs some messages that may explain why it fails.
N.B. st_blocksize is not the blocksize of the device. NetBSD just
returns MAXBSIZE (==MAXPHYS) for a character device which is pretty
useless. But that's not your problem here.
--
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: "G J van der Grinten" <pa0gri@amsat.org>
To: <gnats-bugs@NetBSD.org>
Cc: <port-amd64-maintainer@netbsd.org>,
<gnats-admin@netbsd.org>,
<netbsd-bugs@netbsd.org>
Subject: RE: port-amd64/53890: st(4) driver for tapes not working o variable block size
Date: Fri, 18 Jan 2019 20:52:36 +0100
Hallo Michael,
I know the character block size is 2048. When I use that I get 2 blocks and some
ot the 3rd.
I use the raw device and that should do the variable bock size (as advertized)
But on the recond read for a block I get an " Invalid argument" and that is
invalid by itself.
Program works on IRIX, MIPSOS and linux.
No informative message found in DMESG output.
Here a (partial) log on a working (linux, uch)
Converting tape to tap file xxz
rc NOP ioctl = 0
rc on set block size = 0
rc on set density = 0
rc on set compression = 0
len1 = 00486 rc NOP ioctl = 0
len2 = 00486
len1 = 00930 rc NOP ioctl = 0
len2 = 00930
len1 = 00936 rc NOP ioctl = 0
len2 = 00936
len1 = 00826 rc NOP ioctl = 0
len2 = 00826
len1 = 00946 rc NOP ioctl = 0
len2 = 00946
len1 = 00960 rc NOP ioctl = 0
len2 = 00960
len1 = 00930 rc NOP ioctl = 0
len2 = 00930
len1 = 00952 rc NOP ioctl = 0
len2 = 00952
len1 = 00142 rc NOP ioctl = 0
len2 = 00142
len1 = 00486 rc NOP ioctl = 0
len2 = 00486
Regards, Gerard.
-----Original Message-----
From: Michael van Elst [mailto:mlelstv@serpens.de]
Sent: Friday, January 18, 2019 8:25 PM
To: port-amd64-maintainer@netbsd.org; gnats-admin@netbsd.org;
netbsd-bugs@netbsd.org; pa0gri@amsat.org
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable
block size
The following reply was made to PR port-amd64/53890; it has been noted by GNATS.
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable
block size
Date: Fri, 18 Jan 2019 19:19:57 -0000 (UTC)
pa0gri@amsat.org writes:
>>Description:
>I have tried my problem under various versions of NetBSD AMD65 and I386.
>I want to read and write .TAP files (SIMH containers)on various Tape drive
>models (currently a DDS4 Drive.
>To my great disappointment It works flawlessly under Debian Linux.
The driver probably logs some messages that may explain why it fails.
N.B. st_blocksize is not the blocksize of the device. NetBSD just
returns MAXBSIZE (==MAXPHYS) for a character device which is pretty
useless. But that's not your problem here.
--
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable block size
Date: Sat, 19 Jan 2019 14:42:42 -0000 (UTC)
pa0gri@amsat.org ("G J van der Grinten") writes:
>But on the recond read for a block I get an " Invalid argument" and that is
>invalid by itself.
Looks like this is not the tape driver itself. The kernel physio() routine
does a sanity check on the I/O byte offset to be a multiple of DEV_BSIZE
(== 512 bytes) and returns EINVAL if that's false. That's why the
second read or write fails (the first starts at offset 0).
That sanity check doesn't make sense for a tape and might not even be needed
for e.g. a disk, the disk drivers do their own checks.
--
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: "G J van der Grinten" <pa0gri@amsat.org>
To: <gnats-bugs@NetBSD.org>,
<port-amd64-maintainer@netbsd.org>,
<gnats-admin@netbsd.org>,
<netbsd-bugs@netbsd.org>
Cc:
Subject: RE: port-amd64/53890: st(4) driver for tapes not working o variable block size
Date: Sat, 19 Jan 2019 15:57:49 +0100
Hello Michael,
That is a very logical explanation.
For TAPE files -as long a I worked with them (52 years) they Always are odd
sized.
(besides the inter-system tapes - they had precise formats)
Now a patch and I will be happy.
I am and long time standing - 386BSD user.
Regards, Gerard.
PS, being careful is fine but not always...
-----Original Message-----
From: Michael van Elst [mailto:mlelstv@serpens.de]
Sent: Saturday, January 19, 2019 3:45 PM
To: port-amd64-maintainer@netbsd.org; gnats-admin@netbsd.org;
netbsd-bugs@netbsd.org; pa0gri@amsat.org
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable
block size
The following reply was made to PR port-amd64/53890; it has been noted by GNATS.
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable
block size
Date: Sat, 19 Jan 2019 14:42:42 -0000 (UTC)
pa0gri@amsat.org ("G J van der Grinten") writes:
>But on the recond read for a block I get an " Invalid argument" and that is
>invalid by itself.
Looks like this is not the tape driver itself. The kernel physio() routine
does a sanity check on the I/O byte offset to be a multiple of DEV_BSIZE
(== 512 bytes) and returns EINVAL if that's false. That's why the
second read or write fails (the first starts at offset 0).
That sanity check doesn't make sense for a tape and might not even be needed
for e.g. a disk, the disk drivers do their own checks.
--
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable block size
Date: Sat, 19 Jan 2019 16:27:38 -0000 (UTC)
mlelstv@serpens.de (Michael van Elst) writes:
> Looks like this is not the tape driver itself. The kernel physio() routine
> does a sanity check on the I/O byte offset to be a multiple of DEV_BSIZE
> (== 512 bytes) and returns EINVAL if that's false. That's why the
> second read or write fails (the first starts at offset 0).
The sanity check is done because physio() may issue concurrent
partial I/O requests and keeps track of the individual parts
by their block number. The block number addresses DEV_BSIZE
blocks, so the algorithm only works for multiples of 512 bytes.
A simple solution would be to not track absolute but relative
offsets. This would still fail when physio has to handle I/O of
multiple memory blocks (the second might be unaligned again),
but the tape driver only starts I/O for a single block.
--
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: "G J van der Grinten" <pa0gri@amsat.org>
To: <gnats-bugs@NetBSD.org>,
<port-amd64-maintainer@netbsd.org>,
<gnats-admin@netbsd.org>,
<netbsd-bugs@netbsd.org>
Cc:
Subject: RE: port-amd64/53890: st(4) driver for tapes not working o variable block size
Date: Sat, 19 Jan 2019 19:03:13 +0100
Hello Michael,
That is why TAR and family work as they use 20 *DEV_BSIZE blocks.
The check could thus be skipped for real reel tape devices.
But indeed if tape i/o is a single operation and does not conflict with other
operations.
Thanks for the update.
Regards, Gerard
-----Original Message-----
From: Michael van Elst [mailto:mlelstv@serpens.de]
Sent: Saturday, January 19, 2019 5:30 PM
To: port-amd64-maintainer@netbsd.org; gnats-admin@netbsd.org;
netbsd-bugs@netbsd.org; pa0gri@amsat.org
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable
block size
The following reply was made to PR port-amd64/53890; it has been noted by GNATS.
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890: st(4) driver for tapes not working o variable
block size
Date: Sat, 19 Jan 2019 16:27:38 -0000 (UTC)
mlelstv@serpens.de (Michael van Elst) writes:
> Looks like this is not the tape driver itself. The kernel physio() routine
> does a sanity check on the I/O byte offset to be a multiple of DEV_BSIZE
> (== 512 bytes) and returns EINVAL if that's false. That's why the
> second read or write fails (the first starts at offset 0).
The sanity check is done because physio() may issue concurrent
partial I/O requests and keeps track of the individual parts
by their block number. The block number addresses DEV_BSIZE
blocks, so the algorithm only works for multiples of 512 bytes.
A simple solution would be to not track absolute but relative
offsets. This would still fail when physio has to handle I/O of
multiple memory blocks (the second might be unaligned again),
but the tape driver only starts I/O for a single block.
--
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: Michael van Elst <mlelstv@serpens.de>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890 st(4) driver for tapes not working o variable
block size
Date: Sat, 23 Mar 2019 12:23:33 +0100
I've prepared a patch for the physio routine:
http://ftp.netbsd.org/pub/NetBSD/misc/mlelstv/kern_physio.diff
With this patch I can read and write tapes with e.g. 128 byte blocks.
Greetings,
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
From: "G J van der Grinten" <pa0gri@amsat.org>
To: <gnats-bugs@netbsd.org>,
<mlelstv@serpens.de>
Cc:
Subject: RE: port-amd64/53890 st(4) driver for tapes not working o variable block size
Date: Sat, 23 Mar 2019 13:29:29 +0100
Hello Michael,
I applied the patch and tested the tape drive.
Both reading and writing all kinds of block sizes worked.
Thanks, Gerard.
-----Original Message-----
From: Michael van Elst [mailto:mlelstv@serpens.de]
Sent: Saturday, March 23, 2019 12:25 PM
To: port-amd64-maintainer@netbsd.org; gnats-admin@netbsd.org;
netbsd-bugs@netbsd.org; pa0gri@amsat.org
Subject: Re: port-amd64/53890 st(4) driver for tapes not working o variable
block size
The following reply was made to PR port-amd64/53890; it has been noted by GNATS.
From: Michael van Elst <mlelstv@serpens.de>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/53890 st(4) driver for tapes not working o variable
block size
Date: Sat, 23 Mar 2019 12:23:33 +0100
I've prepared a patch for the physio routine:
http://ftp.netbsd.org/pub/NetBSD/misc/mlelstv/kern_physio.diff
With this patch I can read and write tapes with e.g. 128 byte blocks.
Greetings,
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."
State-Changed-From-To: open->closed
State-Changed-By: mlelstv@NetBSD.org
State-Changed-When: Fri, 10 Apr 2020 13:11:32 +0000
State-Changed-Why:
Issue fixed in kern_physio.c 1.95.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.