diff options
Diffstat (limited to 'ayafs-core')
-rw-r--r-- | ayafs-core/src/filesystem/trait_impl.rs | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/ayafs-core/src/filesystem/trait_impl.rs b/ayafs-core/src/filesystem/trait_impl.rs index 1c3c7b3..356cc59 100644 --- a/ayafs-core/src/filesystem/trait_impl.rs +++ b/ayafs-core/src/filesystem/trait_impl.rs @@ -5,7 +5,7 @@ use crate::utils::permissions::{check_access, clear_suid_sgid, get_groups}; use crate::utils::{from_filetype, from_systime, time_now, to_fileattr, to_filetype}; use crate::{AyaFS, TTL}; use fuser::TimeOrNow::{Now, SpecificTime}; -use fuser::{FileType, Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyOpen, ReplyWrite, Request, TimeOrNow, ReplyStatfs}; +use fuser::{FileType, Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyOpen, ReplyWrite, Request, TimeOrNow, ReplyStatfs, FileAttr}; use libc::{ c_int, EACCES, EBADF, EEXIST, EINVAL, EIO, EISDIR, ENAMETOOLONG, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY, EPERM, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY, RENAME_EXCHANGE, @@ -63,18 +63,6 @@ impl Filesystem for AyaFS { } } - // fn getxattr(&mut self, _req: &Request<'_>, ino: u64, name: &OsStr, size: u32, reply: ReplyXattr) { - // if let Some(inode) = self.get_inode(ino as usize) { - // debug!( - // "getattr(ino: {}, incoming_uid: {}, inode_uid: {})", - // ino, _req.uid(), inode.uid, - // ); - // reply.error(ENOENT); - // } else { - // reply.error(ENOENT); - // } - // } - fn getattr(&mut self, _req: &Request<'_>, ino: u64, reply: ReplyAttr) { if let Some(inode) = self.get_inode(ino as usize) { debug!( @@ -944,6 +932,62 @@ impl Filesystem for AyaFS { } } + fn link(&mut self, req: &Request<'_>, ino: u64, new_parent: u64, new_name: &OsStr, reply: ReplyEntry) { + let ino = ino as usize; + let new_parent = new_parent as usize; + + if let Some(parent_inode) = self.get_inode(new_parent) { + if !check_access( + req.uid(), + req.gid(), + parent_inode.uid, + parent_inode.gid, + parent_inode.mode, + W_OK, + ) { + reply.error(EACCES); + return; + } + + if !parent_inode.is_dir() { + reply.error(ENOTDIR); + return; + } + + if new_name.len() > 255 { + reply.error(ENAMETOOLONG); + return; + } + + let filetype: FileType; + let fileattr: FileAttr; + let mut parent_inode = parent_inode.clone(); + if let Some(inode) = self.get_inode_mut(ino) { + inode.n_links += 1; + filetype = inode.file_type(); + fileattr = to_fileattr(ino, inode); + } else { + reply.error(ENOENT); + return; + } + + if let Err(err_code) = self.add_direntry( + new_parent, + &mut parent_inode, + ino as usize, + new_name, + from_filetype(filetype) + ) { + reply.error(err_code); + return; + } + self.update_inode(new_parent, parent_inode); + reply.entry(&TTL, &fileattr, 0); + } else { + reply.error(ENOENT); + } + } + fn open(&mut self, req: &Request<'_>, ino: u64, flags: i32, reply: ReplyOpen) { debug!("open(ino: {:#x?}, flags: {:#x?})", ino, flags); let (access_mask, read, write) = match flags & O_ACCMODE { |