pxar::fuse: refactor HashMap to store child parent inode relation.
By moving the HashMap into `Context`, the use of lazy_static as well as the additional Mutex can be avoided (`Context` is already guarded by a Mutex). Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
		
				
					committed by
					
						
						Dietmar Maurer
					
				
			
			
				
	
			
			
			
						parent
						
							90fc97af6a
						
					
				
				
					commit
					c7257c5539
				
			@ -12,7 +12,6 @@ use std::path::Path;
 | 
				
			|||||||
use std::sync::Mutex;
 | 
					use std::sync::Mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use failure::{bail, format_err, Error};
 | 
					use failure::{bail, format_err, Error};
 | 
				
			||||||
use lazy_static::lazy_static;
 | 
					 | 
				
			||||||
use libc;
 | 
					use libc;
 | 
				
			||||||
use libc::{c_char, c_int, c_void, size_t};
 | 
					use libc::{c_char, c_int, c_void, size_t};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,15 +31,6 @@ use super::format_definition::{PxarAttributes, PxarEntry, PxarGoodbyeItem};
 | 
				
			|||||||
const FUSE_ROOT_ID: u64 = 1;
 | 
					const FUSE_ROOT_ID: u64 = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
 | 
					const GOODBYE_ITEM_SIZE: u64 = std::mem::size_of::<PxarGoodbyeItem>() as u64;
 | 
				
			||||||
lazy_static! {
 | 
					 | 
				
			||||||
    /// HashMap holding the mapping from the child offsets to their parent
 | 
					 | 
				
			||||||
    /// offsets.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// In order to include the parent directory entry '..' in the response for
 | 
					 | 
				
			||||||
    /// readdir callback, this mapping is needed.
 | 
					 | 
				
			||||||
    /// Calling the lookup callback will insert the offsets into the HashMap.
 | 
					 | 
				
			||||||
    static ref CHILD_PARENT: Mutex<HashMap<u64, u64>> = Mutex::new(HashMap::new());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Inode = u64;
 | 
					type Inode = u64;
 | 
				
			||||||
type Offset = u64;
 | 
					type Offset = u64;
 | 
				
			||||||
@ -90,6 +80,13 @@ struct Context {
 | 
				
			|||||||
    goodbye_cache: HashMap<Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>>,
 | 
					    goodbye_cache: HashMap<Inode, Vec<(PxarGoodbyeItem, Offset, Offset)>>,
 | 
				
			||||||
    attr_cache: Option<(Inode, PxarAttributes)>,
 | 
					    attr_cache: Option<(Inode, PxarAttributes)>,
 | 
				
			||||||
    ino_offset: Offset,
 | 
					    ino_offset: Offset,
 | 
				
			||||||
 | 
					    /// HashMap holding the mapping from the child offsets to their parent
 | 
				
			||||||
 | 
					    /// offsets.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// In order to include the parent directory entry '..' in the response for
 | 
				
			||||||
 | 
					    /// readdir callback, this mapping is needed.
 | 
				
			||||||
 | 
					    /// Calling the lookup callback will insert the offsets into the HashMap.
 | 
				
			||||||
 | 
					    child_parent: HashMap<u64, u64>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Context {
 | 
					impl Context {
 | 
				
			||||||
@ -249,6 +246,7 @@ impl Session  {
 | 
				
			|||||||
            goodbye_cache,
 | 
					            goodbye_cache,
 | 
				
			||||||
            attr_cache: None,
 | 
					            attr_cache: None,
 | 
				
			||||||
            ino_offset: 0,
 | 
					            ino_offset: 0,
 | 
				
			||||||
 | 
					            child_parent: HashMap::new(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let session_ctx = Box::new(Mutex::new(ctx));
 | 
					        let session_ctx = Box::new(Mutex::new(ctx));
 | 
				
			||||||
@ -433,10 +431,7 @@ impl Session  {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // Update the parent for this child entry. Used to get parent offset if
 | 
					            // Update the parent for this child entry. Used to get parent offset if
 | 
				
			||||||
            // only child offset is known.
 | 
					            // only child offset is known.
 | 
				
			||||||
            CHILD_PARENT
 | 
					            ctx.child_parent.insert(child_offset, ctx.ino_offset);
 | 
				
			||||||
                .lock()
 | 
					 | 
				
			||||||
                .map_err(|_| libc::EIO)?
 | 
					 | 
				
			||||||
            .insert(child_offset, ctx.ino_offset);
 | 
					 | 
				
			||||||
            let _res = unsafe { fuse_reply_entry(req, Some(&e)) };
 | 
					            let _res = unsafe { fuse_reply_entry(req, Some(&e)) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Ok(())
 | 
					            Ok(())
 | 
				
			||||||
@ -571,8 +566,7 @@ impl Session  {
 | 
				
			|||||||
                let parent_off = if inode == FUSE_ROOT_ID {
 | 
					                let parent_off = if inode == FUSE_ROOT_ID {
 | 
				
			||||||
                    ctx.decoder.root_end_offset() - GOODBYE_ITEM_SIZE
 | 
					                    ctx.decoder.root_end_offset() - GOODBYE_ITEM_SIZE
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    let guard = CHILD_PARENT.lock().map_err(|_| libc::EIO)?;
 | 
					                    *ctx.child_parent.get(&ctx.ino_offset).ok_or_else(|| libc::EIO)?
 | 
				
			||||||
                    *guard.get(&ctx.ino_offset).ok_or_else(|| libc::EIO)?
 | 
					 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                let (_, entry, _, payload_size) =
 | 
					                let (_, entry, _, payload_size) =
 | 
				
			||||||
                    ctx.decoder.attributes(parent_off).map_err(|_| libc::EIO)?;
 | 
					                    ctx.decoder.attributes(parent_off).map_err(|_| libc::EIO)?;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user