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) |         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> { |     pub fn erase_media(&mut self, fast: bool) -> Result<(), Error> { | ||||||
|         self.sg_tape.erase_media(fast) |         self.sg_tape.erase_media(fast) | ||||||
|     } |     } | ||||||
| @ -211,12 +219,25 @@ impl TapeDriver for LtoTapeHandle { | |||||||
|         self.sg_tape.move_to_eom() |         self.sg_tape.move_to_eom() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn forward_space_count_files(&mut self, count: usize) -> Result<(), Error> { |     fn move_to_last_file(&mut self) -> Result<(), Error> { | ||||||
|         self.sg_tape.space_filemarks(isize::try_from(count)?) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn backward_space_count_files(&mut self, count: usize) -> Result<(), Error> { |         self.move_to_eom()?; | ||||||
|         self.sg_tape.space_filemarks(-isize::try_from(count)?) |  | ||||||
|  |         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> { |     fn rewind(&mut self) -> Result<(), Error> { | ||||||
|  | |||||||
| @ -88,24 +88,7 @@ pub trait TapeDriver { | |||||||
|     fn move_to_eom(&mut self) -> Result<(), Error>; |     fn move_to_eom(&mut self) -> Result<(), Error>; | ||||||
|  |  | ||||||
|     /// Move to last file |     /// 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 |     /// Current file number | ||||||
|     fn current_file_number(&mut self) -> Result<u64, Error>; |     fn current_file_number(&mut self) -> Result<u64, Error>; | ||||||
|  | |||||||
| @ -181,6 +181,53 @@ impl VirtualTapeHandle { | |||||||
|         Ok(list) |         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 { | 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> { |     fn read_next_file(&mut self) -> Result<Option<Box<dyn TapeRead>>, io::Error> { | ||||||
|         let mut status = self.load_status() |         let mut status = self.load_status() | ||||||
|             .map_err(|err| io::Error::new(io::ErrorKind::Other, err.to_string()))?; |             .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> { |     fn rewind(&mut self) -> Result<(), Error> { | ||||||
|         let mut status = self.load_status()?; |         let mut status = self.load_status()?; | ||||||
|         match status.current_tape { |         match status.current_tape { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user