diff --git a/src/bin/pmt.rs b/src/bin/pmt.rs index 3595e3ea..a097df2c 100644 --- a/src/bin/pmt.rs +++ b/src/bin/pmt.rs @@ -180,7 +180,7 @@ fn get_tape_handle(param: &Value) -> Result { /// /// Positioning is done by first rewinding the tape and then spacing /// forward over count file marks. -fn asf(count: i32, param: Value) -> Result<(), Error> { +fn asf(count: usize, param: Value) -> Result<(), Error> { let mut handle = get_tape_handle(¶m)?; @@ -212,7 +212,7 @@ fn asf(count: i32, param: Value) -> Result<(), Error> { /// Backward space count files (position before file mark). /// /// The tape is positioned on the last block of the previous file. -fn bsf(count: i32, param: Value) -> Result<(), Error> { +fn bsf(count: usize, param: Value) -> Result<(), Error> { let mut handle = get_tape_handle(¶m)?; @@ -478,7 +478,7 @@ fn erase(fast: Option, param: Value) -> Result<(), Error> { /// Forward space count files (position after file mark). /// /// The tape is positioned on the first block of the next file. -fn fsf(count: i32, param: Value) -> Result<(), Error> { +fn fsf(count: usize, param: Value) -> Result<(), Error> { let mut handle = get_tape_handle(¶m)?; diff --git a/src/tape/drive/linux_tape.rs b/src/tape/drive/linux_tape.rs index 7f18295d..f8949196 100644 --- a/src/tape/drive/linux_tape.rs +++ b/src/tape/drive/linux_tape.rs @@ -242,32 +242,6 @@ impl LinuxTapeHandle { Ok(()) } - pub fn forward_space_count_files(&mut self, count: i32) -> Result<(), Error> { - - let cmd = mtop { mt_op: MTCmd::MTFSF, mt_count: count, }; - - unsafe { - mtioctop(self.file.as_raw_fd(), &cmd) - }.map_err(|err| { - format_err!("forward space {} files failed - {}", count, err) - })?; - - Ok(()) - } - - pub fn backward_space_count_files(&mut self, count: i32) -> Result<(), Error> { - - let cmd = mtop { mt_op: MTCmd::MTBSF, mt_count: count, }; - - unsafe { - mtioctop(self.file.as_raw_fd(), &cmd) - }.map_err(|err| { - format_err!("backward space {} files failed - {}", count, err) - })?; - - Ok(()) - } - /// Set tape compression feature pub fn set_compression(&self, on: bool) -> Result<(), Error> { @@ -467,19 +441,28 @@ impl TapeDriver for LinuxTapeHandle { Ok(()) } - fn move_to_last_file(&mut self) -> Result<(), Error> { + fn forward_space_count_files(&mut self, count: usize) -> Result<(), Error> { - let cmd = mtop { mt_op: MTCmd::MTEOM, mt_count: 1, }; + let cmd = mtop { mt_op: MTCmd::MTFSF, mt_count: i32::try_from(count)? }; unsafe { mtioctop(self.file.as_raw_fd(), &cmd) - }.map_err(|err| format_err!("MTEOM failed - {}", err))?; + }.map_err(|err| { + format_err!("forward space {} files failed - {}", count, err) + })?; - let cmd = mtop { mt_op: MTCmd::MTBSFM, mt_count: 2, }; + Ok(()) + } + + fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error> { + + let cmd = mtop { mt_op: MTCmd::MTBSF, mt_count: i32::try_from(count)? }; unsafe { mtioctop(self.file.as_raw_fd(), &cmd) - }.map_err(|err| format_err!("MTBSFM failed - {}", err))?; + }.map_err(|err| { + format_err!("backward space {} files failed - {}", count, err) + })?; Ok(()) } diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index afc0218c..5509728c 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -88,7 +88,24 @@ pub trait TapeDriver { fn move_to_eom(&mut self) -> Result<(), Error>; /// Move to last file - fn move_to_last_file(&mut self) -> Result<(), Error>; + 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>; /// 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 7617c062..0adb67cb 100644 --- a/src/tape/drive/virtual_tape.rs +++ b/src/tape/drive/virtual_tape.rs @@ -296,6 +296,7 @@ impl TapeDriver for VirtualTapeHandle { .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; *pos = index.files; + self.store_status(&status) .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; @@ -305,7 +306,7 @@ impl TapeDriver for VirtualTapeHandle { } } - fn move_to_last_file(&mut self) -> Result<(), Error> { + 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 }) => { @@ -313,11 +314,35 @@ impl TapeDriver for VirtualTapeHandle { let index = self.load_tape_index(name) .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; - if index.files == 0 { - bail!("move_to_last_file failed - media contains no data"); + let new_pos = *pos + count; + if new_pos <= index.files { + *pos = new_pos; + } else { + bail!("forward_space_count_files failed: move beyond EOT"); } - *pos = index.files - 1; + 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 name, ref mut pos }) => { + + let index = self.load_tape_index(name) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; + + 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()))?;