refactor: separate syscall interfaces from kernel space, into posix compliant structure.
[lunaix-os.git] / lunaix-os / kernel / fs / vfs.c
index df374cdf41ad41fcf3cd15592a8419c1f22c4c3d..e436eba969c1fea7e88a863adf9e518e579b7514 100644 (file)
@@ -44,7 +44,6 @@
 */
 
 #include <klibc/string.h>
-#include <lunaix/dirent.h>
 #include <lunaix/foptions.h>
 #include <lunaix/fs.h>
 #include <lunaix/mm/cake.h>
 #include <lunaix/process.h>
 #include <lunaix/spike.h>
 #include <lunaix/syscall.h>
+#include <lunaix/syscall_utils.h>
 
 #include <lunaix/fs/twifs.h>
 
+#include <usr/sys/dirent_defs.h>
+
 static struct cake_pile* dnode_pile;
 static struct cake_pile* inode_pile;
 static struct cake_pile* file_pile;
@@ -109,13 +111,13 @@ vfs_init()
 }
 
 inline struct hbucket*
-__dcache_hash(struct v_dnode* parent, uint32_t* hash)
+__dcache_hash(struct v_dnode* parent, u32_t* hash)
 {
-    uint32_t _hash = *hash;
-    // 与parent的指针值做加法,来减小碰撞的可能性。
-    _hash += (uint32_t)parent;
+    u32_t _hash = *hash;
     // 确保低位更加随机
     _hash = _hash ^ (_hash >> VFS_HASHBITS);
+    // 与parent的指针值做加法,来减小碰撞的可能性。
+    _hash += (u32_t)parent;
     *hash = _hash;
     return &dnode_cache[_hash & VFS_HASH_MASK];
 }
@@ -130,7 +132,7 @@ vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str)
         return parent->parent;
     }
 
-    uint32_t hash = str->hash;
+    u32_t hash = str->hash;
     struct hbucket* slot = __dcache_hash(parent, &hash);
 
     struct v_dnode *pos, *n;
@@ -266,11 +268,11 @@ vfs_pclose(struct v_file* file, pid_t pid)
         atomic_fetch_sub(&file->dnode->ref_count, 1);
         file->inode->open_count--;
 
-        // Prevent dead lock.
-        // This happened when process is terminated while blocking on read.
-        // In that case, the process is still holding the inode lock and it will
-        // never get released.
         /*
+         * Prevent dead lock.
+         * This happened when process is terminated while blocking on read.
+         * In that case, the process is still holding the inode lock and it
+             will never get released.
          * The unlocking should also include ownership check.
          *
          * To see why, consider two process both open the same file both with
@@ -300,6 +302,12 @@ vfs_close(struct v_file* file)
     return vfs_pclose(file, __current->pid);
 }
 
+void
+vfs_free_fd(struct v_fd* fd)
+{
+    cake_release(fd_pile, fd);
+}
+
 int
 vfs_fsync(struct v_file* file)
 {
@@ -433,7 +441,7 @@ vfs_d_free(struct v_dnode* dnode)
 }
 
 struct v_inode*
-vfs_i_find(struct v_superblock* sb, uint32_t i_id)
+vfs_i_find(struct v_superblock* sb, u32_t i_id)
 {
     struct hbucket* slot = &sb->i_cache[i_id & VFS_HASH_MASK];
     struct v_inode *pos, *n;
@@ -494,7 +502,12 @@ vfs_i_free(struct v_inode* inode)
         pcache_release(inode->pg_cache);
         vfree(inode->pg_cache);
     }
-    inode->ops->sync(inode);
+    // we don't need to sync inode.
+    // If an inode can be free, then it must be properly closed.
+    // Hence it must be synced already!
+    if (inode->destruct) {
+        inode->destruct(inode);
+    }
     hlist_delete(&inode->hash_list);
     cake_release(inode_pile, inode);
 }
@@ -558,19 +571,20 @@ vfs_do_open(const char* path, int options)
 {
     int errno, fd;
     struct v_dnode *dentry, *file;
-    struct v_file* ofile = 0;
+    struct v_file* ofile = NULL;
 
     errno = __vfs_try_locate_file(
       path, &dentry, &file, (options & FO_CREATE) ? FLOCATE_CREATE_EMPTY : 0);
 
-    if (errno || (errno = vfs_open(file, &ofile))) {
-        return errno;
-    }
+    if (!errno && !(errno = vfs_alloc_fdslot(&fd))) {
 
-    struct v_inode* o_inode = ofile->inode;
+        if (errno || (errno = vfs_open(file, &ofile))) {
+            return errno;
+        }
+
+        struct v_fd* fd_s = cake_grab(fd_pile);
+        memset(fd_s, 0, sizeof(*fd_s));
 
-    if (!errno && !(errno = vfs_alloc_fdslot(&fd))) {
-        struct v_fd* fd_s = vzalloc(sizeof(*fd_s));
         ofile->f_pos = ofile->inode->fsize & -((options & FO_APPEND) != 0);
         fd_s->file = ofile;
         fd_s->flags = options;
@@ -599,7 +613,7 @@ __DEFINE_LXSYSCALL1(int, close, int, fd)
         goto done_err;
     }
 
-    vfree(fd_s);
+    cake_release(fd_pile, fd_s);
     __current->fdtable->fds[fd] = 0;
 
 done_err:
@@ -612,13 +626,13 @@ __vfs_readdir_callback(struct dir_context* dctx,
                        const int len,
                        const int dtype)
 {
-    struct dirent* dent = (struct dirent*)dctx->cb_data;
+    struct lx_dirent* dent = (struct lx_dirent*)dctx->cb_data;
     strncpy(dent->d_name, name, DIRENT_NAME_MAX_LEN);
     dent->d_nlen = len;
     dent->d_type = dtype;
 }
 
-__DEFINE_LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent)
+__DEFINE_LXSYSCALL2(int, sys_readdir, int, fd, struct lx_dirent*, dent)
 {
     struct v_fd* fd_s;
     int errno;