summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ayafs-core/src/filesystem/trait_impl.rs70
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 {