From 3da0a1d4ed4ac4ff0c31a514d42ec7980027a4d0 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Wed, 12 Apr 2017 15:27:46 +0200 Subject: [PATCH] Correct ids on mount (re #2) --- CHANGELOG.md | 2 +- src/cli/mod.rs | 4 ++-- src/mount.rs | 49 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9cb594..9410ddc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ This project follows [semantic versioning](http://semver.org). ### UNRELEASED - [added] Added CHANGELOG - [added] Locking local repository to avoid index corruption -- [added] Storing user/group names in backup +- [added] Storing user/group names in backups - [modified] No longer trying to upload by rename - [modified] No longer failing restore if setting file attributes fails - [fixed] Creating empty bundle cache on init to avoid warnings diff --git a/src/cli/mod.rs b/src/cli/mod.rs index c24e8f6..a5bf9f3 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -490,9 +490,9 @@ pub fn run() -> Result<(), ErrorCode> { let backup = try!(get_backup(&repo, &backup_name)); if let Some(inode) = inode { let inode = checked!(repo.get_backup_inode(&backup, inode), "load subpath inode", ErrorCode::LoadInode); - checked!(FuseFilesystem::from_inode(&mut repo, inode), "create fuse filesystem", ErrorCode::FuseMount) + checked!(FuseFilesystem::from_inode(&mut repo, backup, inode), "create fuse filesystem", ErrorCode::FuseMount) } else { - checked!(FuseFilesystem::from_backup(&mut repo, &backup), "create fuse filesystem", ErrorCode::FuseMount) + checked!(FuseFilesystem::from_backup(&mut repo, backup), "create fuse filesystem", ErrorCode::FuseMount) } } else { checked!(FuseFilesystem::from_repository(&mut repo), "create fuse filesystem", ErrorCode::FuseMount) diff --git a/src/mount.rs b/src/mount.rs index c36a8ec..ae795c9 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -9,6 +9,7 @@ use std::mem; use std::cmp::min; use fuse; +use users::{self, Users, Groups}; use time::Timespec; use libc; @@ -78,11 +79,26 @@ pub struct FuseInode { inode: Inode, parent: Option, children: HashMap, - chunks: Option + chunks: Option, + name_cache: Rc, + user_names: Rc>, + group_names: Rc> } impl FuseInode { pub fn to_attrs(&self) -> fuse::FileAttr { + let mut uid = self.inode.user; + if let Some(name) = self.user_names.get(&self.inode.user) { + if let Some(user) = self.name_cache.get_user_by_name(name) { + uid = user.uid(); + } + } + let mut gid = self.inode.group; + if let Some(name) = self.group_names.get(&self.inode.group) { + if let Some(group) = self.name_cache.get_group_by_name(name) { + gid = group.gid(); + } + } fuse::FileAttr { ino: self.num, size: self.inode.size, @@ -94,8 +110,8 @@ impl FuseInode { kind: convert_file_type(self.inode.file_type), perm: self.inode.mode as u16, nlink: 1, - uid: self.inode.user, - gid: self.inode.group, + uid: uid, + gid: gid, rdev: 0, flags: 0 } @@ -160,16 +176,16 @@ impl<'a> FuseFilesystem<'a> { Ok(fs) } - pub fn from_backup(repository: &'a mut Repository, backup: &Backup) -> Result { + pub fn from_backup(repository: &'a mut Repository, backup: Backup) -> Result { let inode = try!(repository.get_inode(&backup.root)); let mut fs = try!(FuseFilesystem::new(repository)); - fs.add_inode(inode, None); + fs.add_inode(inode, None, backup.user_names, backup.group_names); Ok(fs) } - pub fn from_inode(repository: &'a mut Repository, inode: Inode) -> Result { + pub fn from_inode(repository: &'a mut Repository, backup: Backup, inode: Inode) -> Result { let mut fs = try!(FuseFilesystem::new(repository)); - fs.add_inode(inode, None); + fs.add_inode(inode, None, backup.user_names, backup.group_names); Ok(fs) } @@ -178,16 +194,19 @@ impl<'a> FuseFilesystem<'a> { name: name, file_type: FileType::Directory, ..Default::default() - }, parent) + }, parent, HashMap::default(), HashMap::default()) } - pub fn add_inode(&mut self, inode: Inode, parent: Option) -> FuseInodeRef { + pub fn add_inode(&mut self, inode: Inode, parent: Option, user_names: HashMap, group_names: HashMap) -> FuseInodeRef { let inode = FuseInode { inode: inode, num: self.next_id, parent: parent.clone(), chunks: None, - children: HashMap::new() + children: HashMap::new(), + user_names: Rc::new(user_names), + group_names: Rc::new(group_names), + name_cache: Rc::new(users::UsersCache::new()) }; let name = inode.inode.name.clone(); let inode = Rc::new(RefCell::new(inode)); @@ -224,7 +243,10 @@ impl<'a> FuseFilesystem<'a> { inode: try!(self.repository.get_inode(chunks)), parent: Some(parent.clone()), children: HashMap::new(), - chunks: None + chunks: None, + user_names: parent_mut.user_names.clone(), + group_names: parent_mut.group_names.clone(), + name_cache: parent_mut.name_cache.clone() })); self.inodes.insert(self.next_id, child.clone()); self.next_id +=1; @@ -247,7 +269,10 @@ impl<'a> FuseFilesystem<'a> { inode: try!(self.repository.get_inode(chunks)), parent: Some(parent.clone()), children: HashMap::new(), - chunks: None + chunks: None, + user_names: parent_mut.user_names.clone(), + group_names: parent_mut.group_names.clone(), + name_cache: parent_mut.name_cache.clone() })); self.inodes.insert(self.next_id, child.clone()); self.next_id +=1;