33
44use super :: * ;
55
6+ use aligned_vec:: { AVec , ConstAlign } ;
67use anyhow:: Context ;
78use core:: ffi:: c_char;
89use nix:: fcntl:: { FallocateFlags , fallocate} ;
@@ -34,69 +35,30 @@ impl SystemAccessible for DiskStorage {}
3435const ZERO_BUF_SIZE : usize = 16 * 1024 * 1024 ; // 16MB
3536const PAGE_SIZE : usize = 4096 ; // Standard page size for O_DIRECT alignment
3637
37- /// A page-aligned buffer for O_DIRECT I/O operations.
38+ // Type alias for 4096-byte (page size) aligned vectors
39+ type Align4096 = ConstAlign < 4096 > ;
40+
41+ /// Create a page-aligned zero-filled buffer for O_DIRECT I/O operations.
3842/// On filesystems like Lustre, O_DIRECT requires both buffer address and I/O size
3943/// to be aligned to the filesystem block size (typically page size).
40- struct AlignedBuffer {
41- ptr : * mut u8 ,
42- layout : std:: alloc:: Layout ,
43- len : usize ,
44- }
45-
46- impl AlignedBuffer {
47- /// Create a new page-aligned zero-filled buffer.
48- /// Size will be rounded up to the nearest page boundary.
49- fn new ( size : usize ) -> anyhow:: Result < Self > {
50- // Round up to nearest page size to ensure alignment requirements
51- let aligned_size = size. div_ceil ( PAGE_SIZE ) * PAGE_SIZE ;
52-
53- let layout = std:: alloc:: Layout :: from_size_align ( aligned_size, PAGE_SIZE )
54- . context ( "Failed to create aligned layout" ) ?;
55-
56- let ptr = unsafe { std:: alloc:: alloc_zeroed ( layout) } ;
57-
58- if ptr. is_null ( ) {
59- anyhow:: bail!(
60- "Failed to allocate aligned buffer of {} bytes" ,
61- aligned_size
62- ) ;
63- }
64-
65- tracing:: trace!(
66- "Allocated aligned buffer: size={}, aligned_size={}, align={}" ,
67- size,
68- aligned_size,
69- PAGE_SIZE
70- ) ;
71-
72- Ok ( Self {
73- ptr,
74- layout,
75- len : aligned_size,
76- } )
77- }
78-
79- fn as_slice ( & self ) -> & [ u8 ] {
80- unsafe { std:: slice:: from_raw_parts ( self . ptr , self . len ) }
81- }
82-
83- fn len ( & self ) -> usize {
84- self . len
85- }
44+ fn create_aligned_buffer ( size : usize ) -> anyhow:: Result < AVec < u8 , Align4096 > > {
45+ // Round up to nearest page size to ensure alignment requirements
46+ let aligned_size = size. div_ceil ( PAGE_SIZE ) * PAGE_SIZE ;
47+
48+ // Create aligned vector with compile-time PAGE_SIZE alignment
49+ let mut buf = AVec :: < u8 , Align4096 > :: new ( PAGE_SIZE ) ;
50+ buf. resize ( aligned_size, 0u8 ) ; // Zero-fill
51+
52+ tracing:: trace!(
53+ "Allocated aligned buffer: size={}, aligned_size={}, align={}" ,
54+ size,
55+ aligned_size,
56+ PAGE_SIZE
57+ ) ;
58+
59+ Ok ( buf)
8660}
8761
88- impl Drop for AlignedBuffer {
89- fn drop ( & mut self ) {
90- unsafe {
91- std:: alloc:: dealloc ( self . ptr , self . layout ) ;
92- }
93- }
94- }
95-
96- // Safety: AlignedBuffer owns its memory and is safe to send between threads
97- unsafe impl Send for AlignedBuffer { }
98- unsafe impl Sync for AlignedBuffer { }
99-
10062fn allocate_file ( fd : RawFd , size : u64 ) -> anyhow:: Result < ( ) > {
10163 match fallocate ( fd, FallocateFlags :: empty ( ) , 0 , size as i64 ) {
10264 Ok ( _) => {
@@ -115,9 +77,8 @@ fn allocate_file(fd: RawFd, size: u64) -> anyhow::Result<()> {
11577 ) ;
11678
11779 // Use page-aligned buffer for O_DIRECT compatibility (required on Lustre)
118- let buf = AlignedBuffer :: new ( ZERO_BUF_SIZE )
80+ let buf = create_aligned_buffer ( ZERO_BUF_SIZE )
11981 . context ( "Failed to allocate aligned zero buffer" ) ?;
120- let buf_slice = buf. as_slice ( ) ;
12182
12283 let mut file =
12384 unsafe { File :: from_raw_fd ( nix:: unistd:: dup ( fd) . context ( "dup error" ) ?) } ;
@@ -137,7 +98,7 @@ fn allocate_file(fd: RawFd, size: u64) -> anyhow::Result<()> {
13798 std:: cmp:: min ( aligned, buf. len ( ) )
13899 } ;
139100
140- match file. write ( & buf_slice [ ..to_write] ) {
101+ match file. write ( & buf [ ..to_write] ) {
141102 Ok ( n) => {
142103 if n != to_write {
143104 tracing:: error!(
@@ -177,7 +138,7 @@ fn allocate_file(fd: RawFd, size: u64) -> anyhow::Result<()> {
177138 to_write,
178139 written,
179140 size,
180- buf_slice . as_ptr( ) ,
141+ buf . as_ptr( ) ,
181142 PAGE_SIZE
182143 ) ;
183144
@@ -524,7 +485,7 @@ mod tests {
524485 }
525486 }
526487
527- /// Test that AlignedBuffer satisfies strict O_DIRECT requirements.
488+ /// Test that aligned buffers satisfy strict O_DIRECT requirements.
528489 #[ test]
529490 fn test_aligned_buffer_with_strict_writer ( ) {
530491 let test_sizes = vec ! [
@@ -536,16 +497,17 @@ mod tests {
536497 ] ;
537498
538499 for requested_size in test_sizes {
539- let buf = AlignedBuffer :: new ( requested_size) . expect ( "Failed to create aligned buffer" ) ;
500+ let buf =
501+ create_aligned_buffer ( requested_size) . expect ( "Failed to create aligned buffer" ) ;
540502
541503 let mut writer = StrictODirectWriter :: new ( ) ;
542504
543- // This should succeed - AlignedBuffer meets strict requirements
544- let result = writer. write ( buf. as_slice ( ) ) ;
505+ // This should succeed - aligned buffer meets strict requirements
506+ let result = writer. write ( & buf[ .. ] ) ;
545507
546508 assert ! (
547509 result. is_ok( ) ,
548- "AlignedBuffer write failed for size {}: {:?}" ,
510+ "Aligned buffer write failed for size {}: {:?}" ,
549511 requested_size,
550512 result. err( )
551513 ) ;
@@ -593,7 +555,7 @@ mod tests {
593555 ] ;
594556
595557 for total_size in test_sizes {
596- let buf = AlignedBuffer :: new ( ZERO_BUF_SIZE ) . expect ( "Failed to create buffer" ) ;
558+ let buf = create_aligned_buffer ( ZERO_BUF_SIZE ) . expect ( "Failed to create buffer" ) ;
597559
598560 let mut writer = StrictODirectWriter :: new ( ) ;
599561 let mut written: u64 = 0 ;
@@ -609,14 +571,12 @@ mod tests {
609571 } ;
610572
611573 // This should always succeed with our aligned buffer
612- writer
613- . write_all ( & buf. as_slice ( ) [ ..to_write] )
614- . unwrap_or_else ( |e| {
615- panic ! (
616- "Write failed at offset {} for total size {}: {:?}" ,
617- written, total_size, e
618- )
619- } ) ;
574+ writer. write_all ( & buf[ ..to_write] ) . unwrap_or_else ( |e| {
575+ panic ! (
576+ "Write failed at offset {} for total size {}: {:?}" ,
577+ written, total_size, e
578+ )
579+ } ) ;
620580
621581 written += to_write as u64 ;
622582 }
0 commit comments