Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 03 Jan 2005 22:07:01 -0700
From:      "James E. Flemer" <jflemer@uvm.edu>
To:        freebsd-scsi@freebsd.org
Cc:        jflemer@uvm.edu
Subject:   mtio/sa device response to bad blocks
Message-ID:  <41DA2475.90509@uvm.edu>

next in thread | raw e-mail | index | archive | help
I have a SCSI DAT drive and have had some problems reading tapes with 
bad blocks.  It seems that a read(2) from the sa device returns 0 when a 
bad block is read from the tape.  Note that read(2) also correctly 
returns 0 when a filemark is read.  A userland application (see below) 
can tell the difference between a filemark and a read error by looking 
at the io_sense part of the scsi_tape_errors struct (via the 
MTIOCERRSTAT ioctl).  However this is cumbersome and requires the 
knowledge of the scsi_sense_data struct.  It would seem more appropriate 
for the read to return -1 and set errno to EIO when a bad block is read. 
  With such a change "dd conv=noerror,sync" could be used to dump a tape 
with bad blocks.  Unfortunately, I'm not familiar enough with the 
SCSI/CAM layers to know where make this change, could someone point me 
where to look?

Thanks,
-James

/* This code will check the real reason for read to return 0
  * and change the return code to -1 and set errno to EIO if there
  * was a MEDIUM_ERROR.  Other non-SSD_FILEMARK/SSD_EOM flags
  * should probably also be handled via -1/errno.
  */
num_read = read(mtfd, buf, blk_size);
if (num_read == 0) {
   ioctl(mtfd, MTIOCERRSTAT, &tape_err);
   sense_data = (struct scsi_sense_data *)&tape_err.io_sense;
   if (sense_data->flags & SSD_KEY_MEDIUM_ERROR) {
     num_read = -1;
     errno = EIO;
   }
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?41DA2475.90509>