Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / lunaix-os / kernel / fs / vfs.c
index fbb0f9fddd9d6e3c32bab6054f6ee3f302dbe779..c59584ac57b51b4dea0c53660d5ebb589d2d7134 100644 (file)
@@ -664,11 +664,10 @@ __DEFINE_LXSYSCALL2(int, sys_readdir, int, fd, struct lx_dirent*, dent)
     if ((inode->itype & F_FILE)) {
         errno = ENOTDIR;
     } else {
-        struct dir_context dctx =
-          (struct dir_context){ .cb_data = dent,
-                                .index = dent->d_offset,
-                                .read_complete_callback =
-                                  __vfs_readdir_callback };
+        struct dir_context dctx = (struct dir_context){
+          .cb_data = dent,
+          .index = dent->d_offset,
+          .read_complete_callback = __vfs_readdir_callback};
         errno = 1;
         if (dent->d_offset == 0) {
             __vfs_readdir_callback(&dctx, vfs_dot.value, vfs_dot.len, DT_DIR);
@@ -788,11 +787,10 @@ __DEFINE_LXSYSCALL3(int, lseek, int, fd, int, offset, int, options)
     int fpos = file->f_pos;
     switch (options) {
         case FSEEK_CUR:
-            overflow = __builtin_sadd_overflow((int)file->f_pos, offset, &fpos);
+            overflow = sadd_overflow((int)file->f_pos, offset, &fpos);
             break;
         case FSEEK_END:
-            overflow =
-              __builtin_sadd_overflow((int)file->inode->fsize, offset, &fpos);
+            overflow = sadd_overflow((int)file->inode->fsize, offset, &fpos);
             break;
         case FSEEK_SET:
             fpos = offset;
@@ -862,7 +860,7 @@ vfs_readlink(struct v_dnode* dnode, char* buf, size_t size)
 int
 vfs_get_dtype(int itype)
 {
-    if ((itype & VFS_IFSYMLINK)) {
+    if ((itype & VFS_IFSYMLINK) == VFS_IFSYMLINK) {
         return DT_SYMLINK;
     } else if (!(itype & VFS_IFFILE)) {
         return DT_DIR;
@@ -905,16 +903,8 @@ __DEFINE_LXSYSCALL3(int, readlink, const char*, path, char*, buf, size_t, size)
     return DO_STATUS(errno);
 }
 
-__DEFINE_LXSYSCALL4(int,
-                    readlinkat,
-                    int,
-                    dirfd,
-                    const char*,
-                    pathname,
-                    char*,
-                    buf,
-                    size_t,
-                    size)
+__DEFINE_LXSYSCALL4(
+  int, readlinkat, int, dirfd, const char*, pathname, char*, buf, size_t, size)
 {
     int errno;
     struct v_fd* fd_s;
@@ -1013,6 +1003,11 @@ __DEFINE_LXSYSCALL1(int, mkdir, const char*, path)
         goto done;
     }
 
+    if (!(errno = vfs_walk(parent, name_value, &dir, NULL, 0))) {
+        errno = EEXIST;
+        goto done;
+    }
+
     if ((errno = vfs_check_writable(parent))) {
         goto done;
     }
@@ -1206,12 +1201,8 @@ done:
     return DO_STATUS(errno);
 }
 
-__DEFINE_LXSYSCALL2(int,
-                    symlink,
-                    const char*,
-                    pathname,
-                    const char*,
-                    link_target)
+__DEFINE_LXSYSCALL2(
+  int, symlink, const char*, pathname, const char*, link_target)
 {
     int errno;
     struct v_dnode *dnode, *file;
@@ -1249,14 +1240,19 @@ void
 vfs_ref_dnode(struct v_dnode* dnode)
 {
     atomic_fetch_add(&dnode->ref_count, 1);
-    mnt_mkbusy(dnode->mnt);
+    
+    if (dnode->mnt) {
+        mnt_mkbusy(dnode->mnt);
+    }
 }
 
 void
 vfs_unref_dnode(struct v_dnode* dnode)
 {
     atomic_fetch_sub(&dnode->ref_count, 1);
-    mnt_chillax(dnode->mnt);
+    if (dnode->mnt) {
+        mnt_chillax(dnode->mnt);
+    }
 }
 
 int
@@ -1341,7 +1337,7 @@ __DEFINE_LXSYSCALL2(char*, getcwd, char*, buf, size_t, size)
     ret_ptr = buf;
 
 done:
-    __current->k_status = errno;
+    syscall_result(errno);
     return ret_ptr;
 }
 
@@ -1454,29 +1450,29 @@ __DEFINE_LXSYSCALL2(int, fstat, int, fd, struct file_stat*, stat)
     struct v_inode* vino = fds->file->inode;
     struct device* fdev = vino->sb->dev;
 
-    *stat = (struct file_stat){ .st_ino = vino->id,
-                                .st_blocks = vino->lb_usage,
-                                .st_size = vino->fsize,
-                                .mode = vino->itype,
-                                .st_ioblksize = PG_SIZE,
-                                .st_blksize = vino->sb->blksize };
+    *stat = (struct file_stat){.st_ino = vino->id,
+                               .st_blocks = vino->lb_usage,
+                               .st_size = vino->fsize,
+                               .mode = vino->itype,
+                               .st_ioblksize = PG_SIZE,
+                               .st_blksize = vino->sb->blksize};
 
     if (VFS_DEVFILE(vino->itype)) {
-        struct device* rdev = (struct device*)vino->data;
+        struct device* rdev = resolve_device(vino->data);
         if (!rdev || rdev->magic != DEV_STRUCT_MAGIC) {
             errno = EINVAL;
             goto done;
         }
 
-        stat->st_rdev = (dev_t){ .meta = rdev->ident.fn_grp,
-                                 .unique = rdev->ident.unique,
-                                 .index = rdev->dev_uid };
+        stat->st_rdev = (dev_t){.meta = rdev->ident.fn_grp,
+                                .unique = rdev->ident.unique,
+                                .index = rdev->dev_uid};
     }
 
     if (fdev) {
-        stat->st_dev = (dev_t){ .meta = fdev->ident.fn_grp,
-                                .unique = fdev->ident.unique,
-                                .index = fdev->dev_uid };
+        stat->st_dev = (dev_t){.meta = fdev->ident.fn_grp,
+                               .unique = fdev->ident.unique,
+                               .index = fdev->dev_uid};
     }
 
 done: