From 8b2c6f5dbcefe8b0c16e7225800ab2a728982d80 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Tue, 6 Apr 2021 11:09:21 +0200 Subject: [PATCH] tape: make fsf/bsf driver specific Because the virtual tape driver behaves different than LTO drives. --- src/tape/drive/lto/mod.rs | 31 ++++++++-- src/tape/drive/mod.rs | 19 +----- src/tape/drive/virtual_tape.rs | 106 +++++++++++++++++++-------------- 3 files changed, 89 insertions(+), 67 deletions(-) diff --git a/src/tape/drive/lto/mod.rs b/src/tape/drive/lto/mod.rs index a4e0499e..25df897f 100644 --- a/src/tape/drive/lto/mod.rs +++ b/src/tape/drive/lto/mod.rs @@ -179,6 +179,14 @@ impl LtoTapeHandle { Ok(status) } + pub fn forward_space_count_files(&mut self, count: usize) -> Result<(), Error> { + self.sg_tape.space_filemarks(isize::try_from(count)?) + } + + pub fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error> { + self.sg_tape.space_filemarks(-isize::try_from(count)?) + } + pub fn erase_media(&mut self, fast: bool) -> Result<(), Error> { self.sg_tape.erase_media(fast) } @@ -211,12 +219,25 @@ impl TapeDriver for LtoTapeHandle { self.sg_tape.move_to_eom() } - fn forward_space_count_files(&mut self, count: usize) -> Result<(), Error> { - self.sg_tape.space_filemarks(isize::try_from(count)?) - } + fn move_to_last_file(&mut self) -> Result<(), Error> { - fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error> { - self.sg_tape.space_filemarks(-isize::try_from(count)?) + self.move_to_eom()?; + + let pos = self.current_file_number()?; + + if pos == 0 { + bail!("move_to_last_file failed - media contains no data"); + } + + if pos == 1 { + self.rewind()?; + return Ok(()); + } + + self.backward_space_count_files(2)?; + self.forward_space_count_files(1)?; + + Ok(()) } fn rewind(&mut self) -> Result<(), Error> { diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index 061c1cfc..28ff0a3a 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -88,24 +88,7 @@ pub trait TapeDriver { fn move_to_eom(&mut self) -> Result<(), Error>; /// Move to last file - fn move_to_last_file(&mut self) -> Result<(), Error> { - - self.move_to_eom()?; - - if self.current_file_number()? == 0 { - bail!("move_to_last_file failed - media contains no data"); - } - - self.backward_space_count_files(2)?; - - Ok(()) - } - - /// Forward space count files. The tape is positioned on the first block of the next file. - fn forward_space_count_files(&mut self, count: usize) -> Result<(), Error>; - - /// Backward space count files. The tape is positioned on the last block of the previous file. - fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error>; + fn move_to_last_file(&mut self) -> Result<(), Error>; /// Current file number fn current_file_number(&mut self) -> Result; diff --git a/src/tape/drive/virtual_tape.rs b/src/tape/drive/virtual_tape.rs index e4d09c2f..bb4b4e3c 100644 --- a/src/tape/drive/virtual_tape.rs +++ b/src/tape/drive/virtual_tape.rs @@ -181,6 +181,53 @@ impl VirtualTapeHandle { Ok(list) } + #[allow(dead_code)] + fn forward_space_count_files(&mut self, count: usize) -> Result<(), Error> { + let mut status = self.load_status()?; + match status.current_tape { + Some(VirtualTapeStatus { ref name, ref mut pos }) => { + + let index = self.load_tape_index(name) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; + + let new_pos = *pos + count; + if new_pos <= index.files { + *pos = new_pos; + } else { + bail!("forward_space_count_files failed: move beyond EOT"); + } + + self.store_status(&status) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; + + Ok(()) + } + None => bail!("drive is empty (no tape loaded)."), + } + } + + // Note: behavior differs from LTO, because we always position at + // EOT side. + fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error> { + let mut status = self.load_status()?; + match status.current_tape { + Some(VirtualTapeStatus { ref mut pos, .. }) => { + + if count <= *pos { + *pos = *pos - count; + } else { + bail!("backward_space_count_files failed: move before BOT"); + } + + self.store_status(&status) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; + + Ok(()) + } + None => bail!("drive is empty (no tape loaded)."), + } + } + } impl TapeDriver for VirtualTapeHandle { @@ -199,6 +246,21 @@ impl TapeDriver for VirtualTapeHandle { } } + /// Move to last file + fn move_to_last_file(&mut self) -> Result<(), Error> { + + self.move_to_eom()?; + + if self.current_file_number()? == 0 { + bail!("move_to_last_file failed - media contains no data"); + } + + self.backward_space_count_files(1)?; + + Ok(()) + } + + fn read_next_file(&mut self) -> Result>, io::Error> { let mut status = self.load_status() .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; @@ -304,50 +366,6 @@ impl TapeDriver for VirtualTapeHandle { } } - fn forward_space_count_files(&mut self, count: usize) -> Result<(), Error> { - let mut status = self.load_status()?; - match status.current_tape { - Some(VirtualTapeStatus { ref name, ref mut pos }) => { - - let index = self.load_tape_index(name) - .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; - - let new_pos = *pos + count; - if new_pos <= index.files { - *pos = new_pos; - } else { - bail!("forward_space_count_files failed: move beyond EOT"); - } - - self.store_status(&status) - .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; - - Ok(()) - } - None => bail!("drive is empty (no tape loaded)."), - } - } - - fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error> { - let mut status = self.load_status()?; - match status.current_tape { - Some(VirtualTapeStatus { ref mut pos, .. }) => { - - if count <= *pos { - *pos = *pos - count; - } else { - bail!("backward_space_count_files failed: move before BOT"); - } - - self.store_status(&status) - .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; - - Ok(()) - } - None => bail!("drive is empty (no tape loaded)."), - } - } - fn rewind(&mut self) -> Result<(), Error> { let mut status = self.load_status()?; match status.current_tape {