Browse Source

feat(syscall): mkdir

greatbridf 1 year ago
parent
commit
d5070d823a
3 changed files with 43 additions and 10 deletions
  1. 2 2
      include/kernel/vfs.hpp
  2. 33 0
      src/kernel/syscall.cpp
  3. 8 8
      src/kernel/vfs.cpp

+ 2 - 2
include/kernel/vfs.hpp

@@ -212,7 +212,7 @@ public:
     virtual int inode_mkfile(dentry* dir, const char* filename, mode_t mode);
     virtual int inode_mknode(dentry* dir, const char* filename, mode_t mode, dev_t sn);
     virtual int inode_rmfile(dentry* dir, const char* filename);
-    virtual int inode_mkdir(dentry* dir, const char* dirname);
+    virtual int inode_mkdir(dentry* dir, const char* dirname, mode_t mode);
     virtual int inode_statx(dentry* dent, statx* buf, unsigned int mask);
     virtual int inode_stat(dentry* dent, struct stat* stat);
     virtual dev_t inode_devid(inode* file);
@@ -330,7 +330,7 @@ size_t vfs_write(inode* file, const char* buf, size_t offset, size_t n);
 int vfs_mkfile(fs::vfs::dentry* dir, const char* filename, mode_t mode);
 int vfs_mknode(fs::vfs::dentry* dir, const char* filename, mode_t mode, dev_t sn);
 int vfs_rmfile(fs::vfs::dentry* dir, const char* filename);
-int vfs_mkdir(fs::vfs::dentry* dir, const char* dirname);
+int vfs_mkdir(fs::vfs::dentry* dir, const char* dirname, mode_t mode);
 int vfs_stat(fs::vfs::dentry* dent, statx* stat, unsigned int mask);
 
 /**

+ 33 - 0
src/kernel/syscall.cpp

@@ -883,6 +883,38 @@ int _syscall_gettid(interrupt_stack* data)
     return current_process->pid;
 }
 
+int _syscall_mkdir(interrupt_stack* data)
+{
+    SYSCALL_ARG1(const char* __user, pathname);
+    SYSCALL_ARG2(mode_t, mode);
+
+    mode &= (~current_process->umask & 0777);
+
+    auto path = types::make_path(pathname, current_process->pwd);
+
+    auto* dent = fs::vfs_open(*current_process->root, path);
+    if (dent)
+        return -EEXIST;
+
+    // get parent path
+    auto dirname = path.last_name();
+    path.remove_last();
+
+    dent = fs::vfs_open(*current_process->root, path);
+    if (!dent)
+        return -ENOENT;
+
+    if (!S_ISDIR(dent->ind->mode))
+        return -ENOTDIR;
+
+    auto ret = fs::vfs_mkdir(dent, dirname.c_str(), mode);
+
+    if (ret != GB_OK)
+        return ret;
+
+    return 0;
+}
+
 extern "C" void syscall_entry(interrupt_stack* data)
 {
     int syscall_no = SYSCALL_NO;
@@ -920,6 +952,7 @@ void init_syscall(void)
     syscall_handlers[0x0c] = _syscall_chdir;
     syscall_handlers[0x14] = _syscall_getpid;
     syscall_handlers[0x25] = _syscall_kill;
+    syscall_handlers[0x27] = _syscall_mkdir;
     syscall_handlers[0x29] = _syscall_dup;
     syscall_handlers[0x2a] = _syscall_pipe;
     syscall_handlers[0x2d] = _syscall_brk;

+ 8 - 8
src/kernel/vfs.cpp

@@ -189,7 +189,7 @@ int fs::vfs::inode_mknode(dentry*, const char*, mode_t, dev_t)
 { return -EINVAL; }
 int fs::vfs::inode_rmfile(dentry*, const char*)
 { return -EINVAL; }
-int fs::vfs::inode_mkdir(dentry*, const char*)
+int fs::vfs::inode_mkdir(dentry*, const char*, mode_t)
 { return -EINVAL; }
 int fs::vfs::inode_statx(dentry*, statx*, unsigned int)
 { return -EINVAL; }
@@ -319,9 +319,9 @@ public:
         return GB_OK;
     }
 
-    virtual int inode_mkdir(dentry* dir, const char* dirname) override
+    virtual int inode_mkdir(dentry* dir, const char* dirname, mode_t mode) override
     {
-        auto new_dir = cache_inode(0, _savedata(mk_fe_vector()), S_IFDIR | 0777, 0, 0);
+        auto new_dir = cache_inode(0, _savedata(mk_fe_vector()), S_IFDIR | (mode & 0777), 0, 0);
         mklink(new_dir, new_dir, ".");
 
         mklink(dir->ind, new_dir, dirname);
@@ -634,9 +634,9 @@ int fs::vfs_rmfile(fs::vfs::dentry* dir, const char* filename)
 {
     return dir->ind->fs->inode_rmfile(dir, filename);
 }
-int fs::vfs_mkdir(fs::vfs::dentry* dir, const char* dirname)
+int fs::vfs_mkdir(fs::vfs::dentry* dir, const char* dirname, mode_t mode)
 {
-    return dir->ind->fs->inode_mkdir(dir, dirname);
+    return dir->ind->fs->inode_mkdir(dir, dirname, mode);
 }
 
 fs::vfs::dentry* fs::vfs_open(fs::vfs::dentry& root, const types::path& path)
@@ -957,9 +957,9 @@ void init_vfs(void)
     fs_es->push_back(rootfs);
     fs_root = rootfs->root();
 
-    vfs_mkdir(fs_root, "dev");
-    vfs_mkdir(fs_root, "root");
-    vfs_mkdir(fs_root, "mnt");
+    vfs_mkdir(fs_root, "dev", 0755);
+    vfs_mkdir(fs_root, "root", 0755);
+    vfs_mkdir(fs_root, "mnt", 0755);
     vfs_mkfile(fs_root, "init", 0755);
 
     auto* init = vfs_open(*fs_root, "/init");