Parcourir la source

* Increased the sector size to 1 MB, which resulted in a 60x write
performance increase.
* Fixed a bug in the `SectoredBuf::seek_impl` method.

Matthew Carr il y a 2 ans
Parent
commit
95e7bae514

+ 1 - 1
Cargo.toml

@@ -15,4 +15,4 @@ debug = true
 # Uncomment this to build the tests with optimizations. This provides better performance when using
 # the FUSE file system.
 #[profile.test]
-#opt-level = 3
+#opt-level = 2

+ 1 - 1
crates/btlib/src/blocktree.rs

@@ -1081,7 +1081,7 @@ mod private {
             _lock_owner: Option<u64>,
             flags: u32,
         ) -> io::Result<usize> {
-            debug!("Blocktree::read called on inode {inode}");
+            debug!("Blocktree::read, inode {inode}, handle {handle}, offset {offset}, size {size}");
             if (flags as libc::c_int & libc::O_WRONLY) != 0 {
                 return Err(io::Error::new(
                     io::ErrorKind::PermissionDenied,

+ 2 - 2
crates/btlib/src/crypto/merkle_stream.rs

@@ -664,8 +664,8 @@ pub(crate) mod tests {
         *,
     };
     use crate::{
-        test_helpers::{Randomizer, SectoredCursor},
-        Cursor, SECTOR_SZ_DEFAULT,
+        test_helpers::{Randomizer, SectoredCursor, SECTOR_SZ_DEFAULT},
+        Cursor,
     };
 
     #[test]

+ 15 - 4
crates/btlib/src/lib.rs

@@ -79,8 +79,14 @@ impl std::error::Error for BlockError {}
 // foreseeable future.
 // If this assumption is ever to be removed, you'll need to evaluate every occurrence of `as u64`.
 const_assert!(::std::mem::size_of::<usize>() <= ::std::mem::size_of::<u64>());
+
+/// The expected size of the IO blocks for the file system. This is used to calculate
+/// [SECTOR_SZ_DEFAULT].
+pub const EXPECTED_IO_BLOCK: usize = 4096;
+/// The number of IO blocks in each sector.
+pub const IO_BLOCKS_PER_SECTOR: usize = 256;
 /// The default sector size to use for new blocks.
-pub const SECTOR_SZ_DEFAULT: usize = 4096;
+pub const SECTOR_SZ_DEFAULT: usize = EXPECTED_IO_BLOCK * IO_BLOCKS_PER_SECTOR;
 /// `SECTOR_SZ_DEFAULT` converted to a `u64`.
 pub const SECTOR_U64_DEFAULT: u64 = SECTOR_SZ_DEFAULT as u64;
 
@@ -204,7 +210,10 @@ impl<T: Sectored + ?Sized> Sectored for &mut T {
 impl Sectored for ::std::fs::File {
     fn sector_sz(&self) -> usize {
         self.metadata()
-            .map(|e| e.blksize().try_into().bterr().unwrap())
+            .map(|e| {
+                let blksize: usize = e.blksize().try_into().bterr().unwrap();
+                blksize * IO_BLOCKS_PER_SECTOR
+            })
             .unwrap_or(SECTOR_SZ_DEFAULT)
     }
 }
@@ -1370,13 +1379,15 @@ mod tests {
     use crate::{
         crypto::{ConcreteCreds, CredsPriv},
         sectored_buf::SectoredBuf,
-        test_helpers::*,
+        test_helpers::{
+            node_creds, read_check, root_creds, write_fill, SectoredCursor, SECTOR_SZ_DEFAULT,
+        },
         Cursor as PioCursor,
     };
 
     #[test]
     fn brotli_compress_decompress() {
-        const SECT_SZ: usize = SECTOR_U64_DEFAULT as usize;
+        const SECT_SZ: usize = SECTOR_SZ_DEFAULT;
         const SECT_CT: usize = 16;
         let params = BrotliParams::new(SECT_SZ, 8, 20);
         let mut memory = Cursor::new([0u8; SECT_SZ * SECT_CT]);

+ 36 - 11
crates/btlib/src/sectored_buf.rs

@@ -100,7 +100,9 @@ mod private {
 
         /// Returns one more than the last index in the internal buffer which can be read.
         fn buf_end(&self) -> usize {
-            let limit = self.len().min(self.buf_start + self.sector_sz());
+            let len = self.len();
+            let sect_sz = self.sector_sz();
+            let limit = len.min(self.buf_start + sect_sz);
             limit - self.buf_start
         }
     }
@@ -295,20 +297,19 @@ mod private {
             seek_from: SeekFrom,
             pre_seek: F,
         ) -> io::Result<u64> {
-            let inner_pos = self.inner.stream_position()?;
-            let inner_pos_new = seek_from.abs(|| Ok(inner_pos), || self.size_or_err())?;
-            let sect_index = self.sector_index(inner_pos);
-            let sect_index_new = self.sector_index(inner_pos_new);
-            let pos: u64 = self.pos.try_into().box_err()?;
-            if sect_index != sect_index_new || pos == inner_pos {
+            let pos = self.pos as u64;
+            let pos_new = seek_from.abs(|| Ok(pos), || self.size_or_err())?;
+            let sect_index = self.sector_index(pos);
+            let sect_index_new = self.sector_index(pos_new);
+            if sect_index != sect_index_new {
                 pre_seek(self)?;
                 let sect_sz: u64 = self.sector_sz().try_into().box_err()?;
                 let seek_to = sect_index_new * sect_sz;
                 self.inner.seek(SeekFrom::Start(seek_to))?;
                 self.fill_internal_buf()?;
             }
-            self.pos = inner_pos_new.try_into().box_err()?;
-            Ok(inner_pos_new)
+            self.pos = pos_new.try_into().box_err()?;
+            Ok(pos_new)
         }
     }
 
@@ -421,8 +422,8 @@ mod private {
 mod tests {
     use super::*;
 
-    use crate::{
-        test_helpers::{read_check, write_fill, BtCursor, Randomizer, SectoredCursor},
+    use crate::test_helpers::{
+        integer_array, read_check, write_fill, BtCursor, Randomizer, SectoredCursor,
         SECTOR_SZ_DEFAULT,
     };
 
@@ -728,4 +729,28 @@ mod tests {
 
         assert_eq!(&[0, 1, 2, 3, 4], actual.as_slice());
     }
+
+    #[test]
+    fn try_seek_to_second_sector() {
+        const SECT_SZ: usize = 4;
+        const DATA_LEN: usize = 2 * SECT_SZ;
+        const DATA: [u8; DATA_LEN] = integer_array::<DATA_LEN>(0);
+        let mut sectored = SectoredBuf::new()
+            .try_compose(SectoredCursor::new(Vec::new(), SECT_SZ))
+            .unwrap();
+
+        let written = sectored
+            .write_from(BtCursor::new(DATA), DATA.len())
+            .unwrap();
+        assert_eq!(DATA.len(), written);
+        sectored.rewind().unwrap();
+        const OFFSET: u64 = SECT_SZ as u64 + 1;
+        sectored.try_seek(SeekFrom::Start(OFFSET)).unwrap();
+        let mut actual = BtCursor::new(Vec::new());
+        sectored.read_into(&mut actual, SECT_SZ).unwrap();
+
+        const EXPECTED_LEN: usize = SECT_SZ - 1;
+        const EXPECTED: [u8; EXPECTED_LEN] = integer_array::<EXPECTED_LEN>(OFFSET as u8);
+        assert_eq!(&EXPECTED, actual.into_inner().as_slice());
+    }
 }

+ 3 - 0
crates/btlib/src/test_helpers.rs

@@ -16,6 +16,9 @@ use vm_memory::bytes::Bytes;
 use super::*;
 use crate::{crypto::*, sectored_buf::SectoredBuf, Cursor as PioCursor};
 
+/// A smaller default sector size for use in tests.
+pub const SECTOR_SZ_DEFAULT: usize = 4096;
+
 pub const PRINCIPAL: [u8; 32] = [
     0x75, 0x28, 0xA9, 0xE0, 0x9D, 0x24, 0xBA, 0xB3, 0x79, 0x56, 0x15, 0x68, 0xFD, 0xA4, 0xE2, 0xA4,
     0xCF, 0xB2, 0xC0, 0xE3, 0x96, 0xAE, 0xA2, 0x6E, 0x45, 0x15, 0x50, 0xED, 0xA6, 0xBE, 0x6D, 0xEC,