From owner-freebsd-scsi@FreeBSD.ORG Tue Jan 4 05:06:18 2005 Return-Path: Delivered-To: freebsd-scsi@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EF8BB16A4CE for ; Tue, 4 Jan 2005 05:06:18 +0000 (GMT) Received: from eagle.uvm.edu (eagle.uvm.edu [132.198.101.203]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7869143D2F for ; Tue, 4 Jan 2005 05:06:18 +0000 (GMT) (envelope-from jflemer@uvm.edu) Received: from [192.168.2.15] (c-24-9-89-237.client.comcast.net [24.9.89.237]) (authenticated bits=0) by eagle.uvm.edu (8.12.11/8.12.11) with ESMTP id j0456FBs016500 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 4 Jan 2005 00:06:17 -0500 Message-ID: <41DA2475.90509@uvm.edu> Date: Mon, 03 Jan 2005 22:07:01 -0700 From: "James E. Flemer" User-Agent: Mozilla Thunderbird 0.7.3 (X11/20040918) X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-scsi@freebsd.org Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit cc: jflemer@uvm.edu Subject: mtio/sa device response to bad blocks X-BeenThere: freebsd-scsi@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: SCSI subsystem List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Jan 2005 05:06:19 -0000 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; } }