@@ -12,6 +12,7 @@ use tracing_subscriber::{fmt::format::FmtSpan, util::SubscriberInitExt};
1212use nix:: libc:: { self , ENOENT } ;
1313use serde:: Deserialize ;
1414use std:: {
15+ collections:: HashMap ,
1516 ffi:: OsStr ,
1617 num:: NonZeroU32 ,
1718 path:: PathBuf ,
@@ -83,6 +84,8 @@ const TTL: Duration = Duration::from_secs(1); // Attribute cache timeout
8384#[ derive( Debug ) ]
8485struct LogrotateFS {
8586 state : Arc < Mutex < model:: State > > ,
87+ open_files : Arc < Mutex < HashMap < u64 , model:: FileHandle > > > ,
88+
8689 start_time : std:: time:: Instant ,
8790 start_time_system : std:: time:: SystemTime ,
8891}
@@ -189,7 +192,7 @@ impl Filesystem for LogrotateFS {
189192 & mut self ,
190193 _req : & Request ,
191194 ino : u64 ,
192- _fh : u64 ,
195+ fh : u64 ,
193196 offset : i64 ,
194197 size : u32 ,
195198 _flags : i32 ,
@@ -199,13 +202,51 @@ impl Filesystem for LogrotateFS {
199202 let tick = self . get_current_tick ( ) ;
200203 let mut state = self . state . lock ( ) . expect ( "lock poisoned" ) ;
201204
202- // NOTE this call to State::read is almost surely allocating. It'd be
203- // pretty slick if we could get the buffer directly from the OS to pass
204- // down for writing but we can't. I suppose we could send up the raw
205- // blocks and then chain them together as needed but absent a compelling
206- // reason to do that the simplicity of this API is nice.
207- if let Some ( data) = state. read ( ino as usize , offset as usize , size as usize , tick) {
208- reply. data ( & data) ;
205+ // Get the FileHandle from fh
206+ let file_handle = {
207+ let open_files = self . open_files . lock ( ) . expect ( "lock poisoned" ) ;
208+ open_files. get ( & fh) . cloned ( )
209+ } ;
210+
211+ if let Some ( file_handle) = file_handle {
212+ assert ! (
213+ file_handle. inode( ) as u64 == ino,
214+ "file handle inode and passed ino do not match"
215+ ) ;
216+ if let Some ( data) = state. read ( file_handle, offset as usize , size as usize , tick) {
217+ reply. data ( & data) ;
218+ } else {
219+ reply. error ( ENOENT ) ;
220+ }
221+ } else {
222+ reply. error ( ENOENT ) ;
223+ }
224+ }
225+
226+ #[ tracing:: instrument( skip( self , _req, reply) ) ]
227+ fn release (
228+ & mut self ,
229+ _req : & Request ,
230+ _ino : u64 ,
231+ fh : u64 ,
232+ _flags : i32 ,
233+ _lock_owner : Option < u64 > ,
234+ _flush : bool ,
235+ reply : fuser:: ReplyEmpty ,
236+ ) {
237+ let tick = self . get_current_tick ( ) ;
238+ let mut state = self . state . lock ( ) . expect ( "lock poisoned" ) ;
239+
240+ // Remove the FileHandle from the mapping
241+ let file_handle = {
242+ let mut open_files = self . open_files . lock ( ) . expect ( "lock poisoned" ) ;
243+ open_files. remove ( & fh)
244+ } ;
245+
246+ if let Some ( file_handle) = file_handle {
247+ // Close the file in the state
248+ state. close_file ( tick, file_handle) ;
249+ reply. ok ( ) ;
209250 } else {
210251 reply. error ( ENOENT ) ;
211252 }
@@ -276,7 +317,19 @@ impl Filesystem for LogrotateFS {
276317
277318 #[ tracing:: instrument( skip( self , _req, reply) ) ]
278319 fn open ( & mut self , _req : & Request , ino : u64 , flags : i32 , reply : fuser:: ReplyOpen ) {
279- reply. opened ( ino, flags as u32 ) ;
320+ let tick = self . get_current_tick ( ) ;
321+ let mut state = self . state . lock ( ) . expect ( "lock poisoned" ) ;
322+
323+ if let Some ( file_handle) = state. open_file ( tick, ino as usize ) {
324+ let fh = file_handle. id ( ) ;
325+ {
326+ let mut open_files = self . open_files . lock ( ) . expect ( "lock poisoned" ) ;
327+ open_files. insert ( fh, file_handle) ;
328+ }
329+ reply. opened ( fh, flags as u32 ) ;
330+ } else {
331+ reply. error ( ENOENT ) ;
332+ }
280333 }
281334}
282335
@@ -321,6 +374,7 @@ fn main() -> Result<(), Error> {
321374 // Initialize the FUSE filesystem
322375 let fs = LogrotateFS {
323376 state : Arc :: new ( Mutex :: new ( state) ) ,
377+ open_files : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
324378 start_time : std:: time:: Instant :: now ( ) ,
325379 start_time_system : std:: time:: SystemTime :: now ( ) ,
326380 } ;
0 commit comments