mtio/sa device response to bad blocks

James E. Flemer jflemer at uvm.edu
Mon Jan 3 21:06:19 PST 2005


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;
   }
}


More information about the freebsd-scsi mailing list