tape: make fsf/bsf driver specific
Because the virtual tape driver behaves different than LTO drives.
This commit is contained in:
		| @ -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> { | ||||
|  | ||||
|         self.move_to_eom()?; | ||||
|  | ||||
|         let pos = self.current_file_number()?; | ||||
|  | ||||
|         if pos == 0 { | ||||
|             bail!("move_to_last_file failed - media contains no data"); | ||||
|         } | ||||
|  | ||||
|     fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error> { | ||||
|         self.sg_tape.space_filemarks(-isize::try_from(count)?) | ||||
|         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> { | ||||
|  | ||||
| @ -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<u64, Error>; | ||||
|  | ||||
| @ -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<Option<Box<dyn TapeRead>>, 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 { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user