chore: fix almost *ALL* warnings.
[lunaix-os.git] / lunaix-os / kernel / fs / vfs.c
index d0fbb1cbb6ded93406770d38894873da4faf4f49..988be639b242c4e048948c96fb4e3a5436baa20c 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 <sys/dirent_defs.h>
+
 static struct cake_pile* dnode_pile;
 static struct cake_pile* inode_pile;
 static struct cake_pile* file_pile;
@@ -108,14 +110,14 @@ vfs_init()
     atomic_fetch_add(&vfs_sysroot->ref_count, 1);
 }
 
-inline struct hbucket*
-__dcache_hash(struct v_dnode* parent, uint32_t* hash)
+static inline struct hbucket*
+__dcache_hash(struct v_dnode* parent, u32_t* hash)
 {
-    uint32_t _hash = *hash;
+    u32_t _hash = *hash;
     // 确保低位更加随机
     _hash = _hash ^ (_hash >> VFS_HASHBITS);
     // 与parent的指针值做加法,来减小碰撞的可能性。
-    _hash += (uint32_t)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)
 {
@@ -428,12 +436,12 @@ vfs_d_free(struct v_dnode* dnode)
         vfs_dcache_remove(pos);
     }
 
-    vfree(dnode->name.value);
+    vfree((void*)dnode->name.value);
     cake_release(dnode_pile, 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;
@@ -482,7 +490,6 @@ vfs_i_alloc(struct v_superblock* sb)
     inode->atime = inode->ctime;
     inode->mtime = inode->ctime;
 
-done:
     lru_use_one(inode_lru, &inode->lru);
     return inode;
 }
@@ -494,7 +501,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);
 }
@@ -502,6 +514,7 @@ vfs_i_free(struct v_inode* inode)
 /* ---- System call definition and support ---- */
 
 #define FLOCATE_CREATE_EMPTY 1
+#define FLOCATE_CREATE_ONLY 2
 
 int
 vfs_getfd(int fd, struct v_fd** fd_s)
@@ -528,7 +541,13 @@ __vfs_try_locate_file(const char* path,
     }
 
     errno = vfs_walk(*fdir, name.value, file, NULL, 0);
-    if (errno != ENOENT || !(options & FLOCATE_CREATE_EMPTY)) {
+
+    if (errno != ENOENT && (options & FLOCATE_CREATE_ONLY)) {
+        return EEXIST;
+    }
+
+    if (errno != ENOENT ||
+        !(options & (FLOCATE_CREATE_EMPTY | FLOCATE_CREATE_ONLY))) {
         return errno;
     }
 
@@ -558,19 +577,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 +619,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 +632,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;
@@ -1033,8 +1053,6 @@ __vfs_do_unlink(struct v_dnode* dnode)
     if (inode->open_count) {
         errno = EBUSY;
     } else if (!(inode->itype & VFS_IFDIR)) {
-        // The underlying unlink implementation should handle
-        //  symlink case
         errno = inode->ops->unlink(inode);
         if (!errno) {
             vfs_d_free(dnode);
@@ -1087,10 +1105,8 @@ __DEFINE_LXSYSCALL2(int, link, const char*, oldpath, const char*, newpath)
     errno = __vfs_try_locate_file(oldpath, &dentry, &to_link, 0);
     if (!errno) {
         errno = __vfs_try_locate_file(
-          newpath, &name_dentry, &name_file, FLOCATE_CREATE_EMPTY);
+          newpath, &name_dentry, &name_file, FLOCATE_CREATE_ONLY);
         if (!errno) {
-            errno = EEXIST;
-        } else if (name_file) {
             errno = vfs_link(to_link, name_file);
         }
     }
@@ -1187,30 +1203,37 @@ __DEFINE_LXSYSCALL2(int,
                     link_target)
 {
     int errno;
-    struct v_dnode* dnode;
-    if ((errno = vfs_walk_proc(pathname, &dnode, NULL, 0))) {
+    struct v_dnode *dnode, *file;
+    if ((errno = __vfs_try_locate_file(
+           pathname, &dnode, &file, FLOCATE_CREATE_ONLY))) {
         goto done;
     }
 
-    if (errno = vfs_check_writable(dnode)) {
+    if ((errno = vfs_check_writable(file))) {
         goto done;
     }
 
-    if (!dnode->inode->ops->set_symlink) {
+    if (!file->inode->ops->set_symlink) {
         errno = ENOTSUP;
         goto done;
     }
 
-    lock_inode(dnode->inode);
+    lock_inode(file->inode);
 
-    errno = dnode->inode->ops->set_symlink(dnode->inode, link_target);
+    errno = file->inode->ops->set_symlink(file->inode, link_target);
 
-    unlock_inode(dnode->inode);
+    unlock_inode(file->inode);
 
 done:
     return DO_STATUS(errno);
 }
 
+void
+vfs_ref_file(struct v_file* file)
+{
+    atomic_fetch_add(&file->ref_count, 1);
+}
+
 void
 vfs_ref_dnode(struct v_dnode* dnode)
 {
@@ -1259,7 +1282,7 @@ __DEFINE_LXSYSCALL1(int, chdir, const char*, path)
         goto done;
     }
 
-    errno = vfs_do_chdir(__current, dnode);
+    errno = vfs_do_chdir((struct proc_info*)__current, dnode);
 
 done:
     return DO_STATUS(errno);
@@ -1274,7 +1297,7 @@ __DEFINE_LXSYSCALL1(int, fchdir, int, fd)
         goto done;
     }
 
-    errno = vfs_do_chdir(__current, fd_s->file->dnode);
+    errno = vfs_do_chdir((struct proc_info*)__current, fd_s->file->dnode);
 
 done:
     return DO_STATUS(errno);
@@ -1302,7 +1325,7 @@ __DEFINE_LXSYSCALL2(char*, getcwd, char*, buf, size_t, size)
         }
     }
 
-    buf[len + 1] = '\0';
+    buf[len] = '\0';
 
     ret_ptr = buf;
 
@@ -1320,7 +1343,7 @@ vfs_do_rename(struct v_dnode* current, struct v_dnode* target)
         return 0;
     }
 
-    if (errno = vfs_check_writable(current)) {
+    if ((errno = vfs_check_writable(current))) {
         return errno;
     }
 
@@ -1404,6 +1427,6 @@ __DEFINE_LXSYSCALL2(int, rename, const char*, oldpath, const char*, newpath)
     errno = vfs_do_rename(cur, target);
 
 done:
-    vfree(name.value);
+    vfree((void*)name.value);
     return DO_STATUS(errno);
 }
\ No newline at end of file