tape: use LOCATE(16) SCSI command
Turns out this works on LTO4 and newer.
This commit is contained in:
parent
25d78b1068
commit
bbbf662d20
@ -215,31 +215,8 @@ impl LtoTapeHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Position the tape after filemark count. Count 0 means BOT.
|
/// Position the tape after filemark count. Count 0 means BOT.
|
||||||
///
|
|
||||||
/// Note: we dont use LOCATE(10), because that needs LTO5
|
|
||||||
pub fn locate_file(&mut self, position: u64) -> Result<(), Error> {
|
pub fn locate_file(&mut self, position: u64) -> Result<(), Error> {
|
||||||
|
self.sg_tape.locate_file(position)
|
||||||
if position == 0 {
|
|
||||||
return self.rewind();
|
|
||||||
}
|
|
||||||
|
|
||||||
let current_position = self.current_file_number()?;
|
|
||||||
|
|
||||||
if current_position == position {
|
|
||||||
// make sure we are immediated afer the filemark
|
|
||||||
self.sg_tape.space_filemarks(-1)?;
|
|
||||||
self.sg_tape.space_filemarks(1)?;
|
|
||||||
} else if current_position < position {
|
|
||||||
let diff = position - current_position;
|
|
||||||
self.sg_tape.space_filemarks(diff.try_into()?)?;
|
|
||||||
} else {
|
|
||||||
let diff = current_position - position + 1;
|
|
||||||
self.sg_tape.space_filemarks(-diff.try_into()?)?;
|
|
||||||
// move to EOT side of filemark
|
|
||||||
self.sg_tape.space_filemarks(1)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn erase_media(&mut self, fast: bool) -> Result<(), Error> {
|
pub fn erase_media(&mut self, fast: bool) -> Result<(), Error> {
|
||||||
|
@ -295,6 +295,32 @@ impl SgTape {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locate_file(&mut self, position: u64) -> Result<(), Error> {
|
||||||
|
if position == 0 {
|
||||||
|
return self.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
|
||||||
|
sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
|
||||||
|
let mut cmd = Vec::new();
|
||||||
|
// Note: LOCATE(16) works for LTO4 or newer
|
||||||
|
cmd.extend(&[0x92, 0b000_01_000, 0, 0]); // LOCATE(16) filemarks
|
||||||
|
cmd.extend(&position.to_be_bytes());
|
||||||
|
cmd.extend(&[0, 0, 0, 0]);
|
||||||
|
|
||||||
|
sg_raw.do_command(&cmd)
|
||||||
|
.map_err(|err| format_err!("locate file {} failed - {}", position, err))?;
|
||||||
|
|
||||||
|
// move to other side of filemark
|
||||||
|
cmd.truncate(0);
|
||||||
|
cmd.extend(&[0x11, 0x01, 0, 0, 1, 0]); // SPACE(6) one filemarks
|
||||||
|
|
||||||
|
sg_raw.do_command(&cmd)
|
||||||
|
.map_err(|err| format_err!("locate file {} (space) failed - {}", position, err))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn position(&mut self) -> Result<ReadPositionLongPage, Error> {
|
pub fn position(&mut self) -> Result<ReadPositionLongPage, Error> {
|
||||||
|
|
||||||
let expected_size = std::mem::size_of::<ReadPositionLongPage>();
|
let expected_size = std::mem::size_of::<ReadPositionLongPage>();
|
||||||
|
Loading…
Reference in New Issue
Block a user