浏览代码

[dfs] Add DFS v2.0 (#7606)

Bernard Xiong 1 年之前
父节点
当前提交
99e80f8d33
共有 68 个文件被更改,包括 5202 次插入11414 次删除
  1. 141 2
      components/dfs/Kconfig
  2. 0 138
      components/dfs/dfs_v1/Kconfig
  3. 2 0
      components/dfs/dfs_v1/include/dfs_file.h
  4. 14 0
      components/dfs/dfs_v1/src/dfs_file.c
  5. 0 35
      components/dfs/dfs_v2/Kconfig
  6. 14 9
      components/dfs/dfs_v2/SConscript
  7. 336 234
      components/dfs/dfs_v2/filesystems/devfs/devfs.c
  8. 1 3
      components/dfs/dfs_v2/filesystems/devfs/devfs.h
  9. 188 77
      components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c
  10. 1 3
      components/dfs/dfs_v2/filesystems/elmfat/ff.c
  11. 0 13
      components/dfs/dfs_v2/filesystems/nfs/SConscript
  12. 0 1192
      components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.c
  13. 0 15
      components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.h
  14. 0 131
      components/dfs/dfs_v2/filesystems/nfs/mount.h
  15. 0 68
      components/dfs/dfs_v2/filesystems/nfs/mount.x
  16. 0 78
      components/dfs/dfs_v2/filesystems/nfs/mount_clnt.c
  17. 0 142
      components/dfs/dfs_v2/filesystems/nfs/mount_xdr.c
  18. 0 1110
      components/dfs/dfs_v2/filesystems/nfs/nfs.h
  19. 0 774
      components/dfs/dfs_v2/filesystems/nfs/nfs.x
  20. 0 172
      components/dfs/dfs_v2/filesystems/nfs/nfs_auth.c
  21. 0 222
      components/dfs/dfs_v2/filesystems/nfs/nfs_clnt.c
  22. 0 1622
      components/dfs/dfs_v2/filesystems/nfs/nfs_xdr.c
  23. 0 112
      components/dfs/dfs_v2/filesystems/nfs/rpc/auth.h
  24. 0 135
      components/dfs/dfs_v2/filesystems/nfs/rpc/auth_none.c
  25. 0 330
      components/dfs/dfs_v2/filesystems/nfs/rpc/clnt.h
  26. 0 95
      components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_generic.c
  27. 0 406
      components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_udp.c
  28. 0 62
      components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.c
  29. 0 66
      components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.h
  30. 0 62
      components/dfs/dfs_v2/filesystems/nfs/rpc/rpc.h
  31. 0 203
      components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_msg.h
  32. 0 267
      components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_prot.c
  33. 0 89
      components/dfs/dfs_v2/filesystems/nfs/rpc/types.h
  34. 0 784
      components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.c
  35. 0 369
      components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.h
  36. 0 172
      components/dfs/dfs_v2/filesystems/nfs/rpc/xdr_mem.c
  37. 145 132
      components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c
  38. 2 1
      components/dfs/dfs_v2/filesystems/romfs/romfs.c
  39. 0 1
      components/dfs/dfs_v2/filesystems/skeleton/skeleton.c
  40. 231 179
      components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c
  41. 30 33
      components/dfs/dfs_v2/include/dfs.h
  42. 64 0
      components/dfs/dfs_v2/include/dfs_dentry.h
  43. 118 44
      components/dfs/dfs_v2/include/dfs_file.h
  44. 56 57
      components/dfs/dfs_v2/include/dfs_fs.h
  45. 65 0
      components/dfs/dfs_v2/include/dfs_mnt.h
  46. 32 0
      components/dfs/dfs_v2/include/dfs_posix.h
  47. 0 28
      components/dfs/dfs_v2/include/dfs_private.h
  48. 270 453
      components/dfs/dfs_v2/src/dfs.c
  49. 368 0
      components/dfs/dfs_v2/src/dfs_dentry.c
  50. 1274 479
      components/dfs/dfs_v2/src/dfs_file.c
  51. 363 533
      components/dfs/dfs_v2/src/dfs_fs.c
  52. 386 0
      components/dfs/dfs_v2/src/dfs_mnt.c
  53. 379 179
      components/dfs/dfs_v2/src/dfs_posix.c
  54. 19 0
      components/dfs/dfs_v2/src/dfs_private.h
  55. 134 0
      components/dfs/dfs_v2/src/dfs_vnode.c
  56. 14 9
      components/drivers/ipc/pipe.c
  57. 14 9
      components/drivers/serial/serial.c
  58. 15 10
      components/drivers/tty/tty.c
  59. 14 2
      components/finsh/msh.c
  60. 359 7
      components/finsh/msh_file.c
  61. 7 3
      components/libc/compilers/common/include/dirent.h
  62. 23 1
      components/libc/compilers/common/include/unistd.h
  63. 14 2
      components/libc/compilers/newlib/fcntl.h
  64. 3 3
      components/libc/posix/io/stdio/libc.c
  65. 10 22
      components/lwp/lwp_ipc.c
  66. 70 4
      components/lwp/lwp_syscall.c
  67. 16 9
      components/net/sal/dfs_net/dfs_net.c
  68. 10 22
      components/net/sal/socket/net_sockets.c

+ 141 - 2
components/dfs/Kconfig

@@ -16,6 +16,7 @@ if RT_USING_DFS
         bool "Using working directory"
         default y
 
+if RT_USING_DFS_V1
     config RT_USING_DFS_MNTTABLE
         bool "Using mount table for file system"
         default n
@@ -27,6 +28,7 @@ if RT_USING_DFS
                     {0}
                 };
             The mount_table must be terminated with NULL.
+endif
 
     config DFS_FD_MAX
         int "The maximal number of opened files"
@@ -44,8 +46,145 @@ if RT_USING_DFS
             bool "DFS v2.0"
     endchoice
 
-source "$RTT_DIR/components/dfs/dfs_v1/Kconfig"
-source "$RTT_DIR/components/dfs/dfs_v2/Kconfig"
+if RT_USING_DFS_V1
+    config DFS_FILESYSTEMS_MAX
+        int "The maximal number of mounted file system"
+        default 4
+
+    config DFS_FILESYSTEM_TYPES_MAX
+        int "The maximal number of file system type"
+        default 4
+endif
+
+    config RT_USING_DFS_ELMFAT
+        bool "Enable elm-chan fatfs"
+        default n
+        help
+            FatFs is a generic FAT/exFAT file system module for small embedded systems.
+
+    if RT_USING_DFS_ELMFAT
+        menu "elm-chan's FatFs, Generic FAT Filesystem Module"
+        config RT_DFS_ELM_CODE_PAGE
+            int "OEM code page"
+            default 437
+
+        config RT_DFS_ELM_WORD_ACCESS
+            bool "Using RT_DFS_ELM_WORD_ACCESS"
+            default y
+
+        choice
+            prompt "Support long file name"
+            default RT_DFS_ELM_USE_LFN_3
+
+            config RT_DFS_ELM_USE_LFN_0
+                bool "0: LFN disable"
+
+            config RT_DFS_ELM_USE_LFN_1
+                bool "1: LFN with static LFN working buffer"
+
+            config RT_DFS_ELM_USE_LFN_2
+                bool "2: LFN with dynamic LFN working buffer on the stack"
+
+            config RT_DFS_ELM_USE_LFN_3
+                bool "3: LFN with dynamic LFN working buffer on the heap"
+        endchoice
+
+        config RT_DFS_ELM_USE_LFN
+            int
+            default 0 if RT_DFS_ELM_USE_LFN_0
+            default 1 if RT_DFS_ELM_USE_LFN_1
+            default 2 if RT_DFS_ELM_USE_LFN_2
+            default 3 if RT_DFS_ELM_USE_LFN_3
+
+        choice
+            prompt "Support unicode for long file name"
+            default RT_DFS_ELM_LFN_UNICODE_0
+
+            config RT_DFS_ELM_LFN_UNICODE_0
+                bool "0: ANSI/OEM in current CP (TCHAR = char)"
+
+            config RT_DFS_ELM_LFN_UNICODE_1
+                bool "1: Unicode in UTF-16 (TCHAR = WCHAR)"
+
+            config RT_DFS_ELM_LFN_UNICODE_2
+                bool "2: Unicode in UTF-8 (TCHAR = char)"
+
+            config RT_DFS_ELM_LFN_UNICODE_3
+                bool "3: Unicode in UTF-32 (TCHAR = DWORD)"
+        endchoice
+
+        config RT_DFS_ELM_LFN_UNICODE
+            int
+            default 0 if RT_DFS_ELM_LFN_UNICODE_0
+            default 1 if RT_DFS_ELM_LFN_UNICODE_1
+            default 2 if RT_DFS_ELM_LFN_UNICODE_2
+            default 3 if RT_DFS_ELM_LFN_UNICODE_3
+
+        config RT_DFS_ELM_MAX_LFN
+            int "Maximal size of file name length"
+            range 12 255
+            default 255
+
+        config RT_DFS_ELM_DRIVES
+            int "Number of volumes (logical drives) to be used."
+            default 2
+
+        config RT_DFS_ELM_MAX_SECTOR_SIZE
+            int "Maximum sector size to be handled."
+            default 512
+            help
+                If you use some spi nor flash for fatfs, please set this the erase sector size, for example 4096.
+
+        config RT_DFS_ELM_USE_ERASE
+            bool "Enable sector erase feature"
+            default n
+
+        config RT_DFS_ELM_REENTRANT
+            bool "Enable the reentrancy (thread safe) of the FatFs module"
+            default y
+
+        config RT_DFS_ELM_MUTEX_TIMEOUT
+            int "Timeout of thread-safe protection mutex"
+            range 0 1000000
+            default 3000
+            depends on RT_DFS_ELM_REENTRANT
+        endmenu
+    endif
+
+    config RT_USING_DFS_DEVFS
+        bool "Using devfs for device objects"
+        default y
+
+    config RT_USING_DFS_ROMFS
+        bool "Enable ReadOnly file system on flash"
+        default n
+if RT_USING_DFS_V1
+    config RT_USING_DFS_CROMFS
+        bool "Enable ReadOnly compressed file system on flash"
+        default n
+        # select PKG_USING_ZLIB
+
+    config RT_USING_DFS_RAMFS
+        bool "Enable RAM file system"
+        select RT_USING_MEMHEAP
+        default n
+endif
+    config RT_USING_DFS_TMPFS
+        bool "Enable TMP file system"
+        default n
+
+if RT_USING_DFS_V1
+    config RT_USING_DFS_NFS
+        bool "Using NFS v3 client file system"
+        depends on RT_USING_LWIP
+        default n
+
+    if RT_USING_DFS_NFS
+        config RT_NFS_HOST_EXPORT
+            string "NFSv3 host export"
+            default "192.168.1.5:/"
+    endif
+endif
 
 endif
 

+ 0 - 138
components/dfs/dfs_v1/Kconfig

@@ -1,138 +0,0 @@
-if RT_USING_DFS_V1
-    config DFS_FILESYSTEMS_MAX
-        int "The maximal number of mounted file system"
-        default 4
-
-    config DFS_FILESYSTEM_TYPES_MAX
-        int "The maximal number of file system type"
-        default 4
-
-    config RT_USING_DFS_ELMFAT
-        bool "Enable elm-chan fatfs"
-        default n
-        help
-            FatFs is a generic FAT/exFAT file system module for small embedded systems.
-
-    if RT_USING_DFS_ELMFAT
-        menu "elm-chan's FatFs, Generic FAT Filesystem Module"
-        config RT_DFS_ELM_CODE_PAGE
-            int "OEM code page"
-            default 437
-
-        config RT_DFS_ELM_WORD_ACCESS
-            bool "Using RT_DFS_ELM_WORD_ACCESS"
-            default y
-
-        choice
-            prompt "Support long file name"
-            default RT_DFS_ELM_USE_LFN_3
-
-            config RT_DFS_ELM_USE_LFN_0
-                bool "0: LFN disable"
-
-            config RT_DFS_ELM_USE_LFN_1
-                bool "1: LFN with static LFN working buffer"
-
-            config RT_DFS_ELM_USE_LFN_2
-                bool "2: LFN with dynamic LFN working buffer on the stack"
-
-            config RT_DFS_ELM_USE_LFN_3
-                bool "3: LFN with dynamic LFN working buffer on the heap"
-        endchoice
-
-        config RT_DFS_ELM_USE_LFN
-            int
-            default 0 if RT_DFS_ELM_USE_LFN_0
-            default 1 if RT_DFS_ELM_USE_LFN_1
-            default 2 if RT_DFS_ELM_USE_LFN_2
-            default 3 if RT_DFS_ELM_USE_LFN_3
-
-        choice
-            prompt "Support unicode for long file name"
-            default RT_DFS_ELM_LFN_UNICODE_0
-
-            config RT_DFS_ELM_LFN_UNICODE_0
-                bool "0: ANSI/OEM in current CP (TCHAR = char)"
-
-            config RT_DFS_ELM_LFN_UNICODE_1
-                bool "1: Unicode in UTF-16 (TCHAR = WCHAR)"
-
-            config RT_DFS_ELM_LFN_UNICODE_2
-                bool "2: Unicode in UTF-8 (TCHAR = char)"
-
-            config RT_DFS_ELM_LFN_UNICODE_3
-                bool "3: Unicode in UTF-32 (TCHAR = DWORD)"
-        endchoice
-
-        config RT_DFS_ELM_LFN_UNICODE
-            int
-            default 0 if RT_DFS_ELM_LFN_UNICODE_0
-            default 1 if RT_DFS_ELM_LFN_UNICODE_1
-            default 2 if RT_DFS_ELM_LFN_UNICODE_2
-            default 3 if RT_DFS_ELM_LFN_UNICODE_3
-
-        config RT_DFS_ELM_MAX_LFN
-            int "Maximal size of file name length"
-            range 12 255
-            default 255
-
-        config RT_DFS_ELM_DRIVES
-            int "Number of volumes (logical drives) to be used."
-            default 2
-
-        config RT_DFS_ELM_MAX_SECTOR_SIZE
-            int "Maximum sector size to be handled."
-            default 512
-            help
-                If you use some spi nor flash for fatfs, please set this the erase sector size, for example 4096.
-
-        config RT_DFS_ELM_USE_ERASE
-            bool "Enable sector erase feature"
-            default n
-
-        config RT_DFS_ELM_REENTRANT
-            bool "Enable the reentrancy (thread safe) of the FatFs module"
-            default y
-
-        config RT_DFS_ELM_MUTEX_TIMEOUT
-            int "Timeout of thread-safe protection mutex"
-            range 0 1000000
-            default 3000
-            depends on RT_DFS_ELM_REENTRANT
-        endmenu
-    endif
-
-    config RT_USING_DFS_DEVFS
-        bool "Using devfs for device objects"
-        default y
-
-    config RT_USING_DFS_ROMFS
-        bool "Enable ReadOnly file system on flash"
-        default n
-
-    config RT_USING_DFS_CROMFS
-        bool "Enable ReadOnly compressed file system on flash"
-        default n
-        # select PKG_USING_ZLIB
-
-    config RT_USING_DFS_RAMFS
-        bool "Enable RAM file system"
-        select RT_USING_MEMHEAP
-        default n
-
-    config RT_USING_DFS_TMPFS
-        bool "Enable TMP file system"
-        default n
-
-    config RT_USING_DFS_NFS
-        bool "Using NFS v3 client file system"
-        depends on RT_USING_LWIP
-        default n
-
-    if RT_USING_DFS_NFS
-        config RT_NFS_HOST_EXPORT
-            string "NFSv3 host export"
-            default "192.168.1.5:/"
-    endif
-
-endif

+ 2 - 0
components/dfs/dfs_v1/include/dfs_file.h

@@ -76,6 +76,8 @@ struct dfs_mmap2_args
 };
 
 void dfs_vnode_mgr_init(void);
+int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops);
+
 int dfs_file_is_open(const char *pathname);
 int dfs_file_open(struct dfs_file *fd, const char *path, int flags);
 int dfs_file_close(struct dfs_file *fd);

+ 14 - 0
components/dfs/dfs_v1/src/dfs_file.c

@@ -47,6 +47,20 @@ void dfs_vnode_mgr_init(void)
     }
 }
 
+int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops)
+{
+    if (vnode)
+    {
+        rt_memset(vnode, 0, sizeof(struct dfs_vnode));
+        vnode->type = type;
+        vnode->fops = fops;
+
+        rt_list_init(&(vnode->list));
+        vnode->ref_count = 1;
+    }
+    return 0;
+}
+
 /* BKDR Hash Function */
 static unsigned int bkdr_hash(const char *str)
 {

+ 0 - 35
components/dfs/dfs_v2/Kconfig

@@ -1,35 +0,0 @@
-if RT_USING_DFS_V2
-    config RT_USING_DFS_DEVFS
-        bool "Using devfs for device objects"
-        default y
-
-    config RT_USING_DFS_ROMFS
-        bool "Enable ReadOnly file system on flash"
-        default n
-
-    config RT_USING_DFS_CROMFS
-        bool "Enable ReadOnly compressed file system on flash"
-        default n
-        # select PKG_USING_ZLIB
-
-    config RT_USING_DFS_RAMFS
-        bool "Enable RAM file system"
-        select RT_USING_MEMHEAP
-        default n
-
-    config RT_USING_DFS_TMPFS
-        bool "Enable TMP file system"
-        default n
-
-    config RT_USING_DFS_NFS
-        bool "Using NFS v3 client file system"
-        depends on RT_USING_LWIP
-        default n
-
-    if RT_USING_DFS_NFS
-        config RT_NFS_HOST_EXPORT
-            string "NFSv3 host export"
-            default "192.168.1.5:/"
-    endif
-
-endif

+ 14 - 9
components/dfs/dfs_v2/SConscript

@@ -2,19 +2,24 @@ from building import *
 import os
 
 # The set of source files associated with this SConscript file.
-src     = []
-cwd     = GetCurrentDir()
+src = Split('''
+src/dfs.c
+src/dfs_file.c
+src/dfs_fs.c
+src/dfs_dentry.c
+src/dfs_vnode.c
+src/dfs_mnt.c
+src/dfs_posix.c
+''')
+cwd = GetCurrentDir()
 CPPPATH = [cwd + "/include"]
-group   = []
 
-if GetDepend('RT_USING_DFS') and GetDepend('RT_USING_DFS_V2'):
-    src = ['src/dfs.c', 'src/dfs_file.c', 'src/dfs_fs.c']
-
-    if GetDepend('DFS_USING_POSIX'):
-        src += ['src/dfs_posix.c']
+if GetDepend('RT_USING_POSIX'):
+    src += ['src/poll.c', 'src/select.c']
 
-    group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH)
+group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_V2'], CPPPATH = CPPPATH)
 
+if GetDepend('RT_USING_DFS') and GetDepend('RT_USING_DFS_V2'):
     # search in the file system implementation
     list = os.listdir(cwd)
 

+ 336 - 234
components/dfs/dfs_v2/filesystems/devfs/devfs.c

@@ -8,38 +8,252 @@
  * 2018-02-11     Bernard      Ignore O_CREAT flag in open.
  */
 #include <rthw.h>
-#include <rtthread.h>
+#include <rtdbg.h>
 #include <rtdevice.h>
 
+#include <fcntl.h>
+#include <errno.h>
+
 #include <dfs.h>
 #include <dfs_fs.h>
 #include <dfs_file.h>
+#include <dfs_dentry.h>
+#include <dfs_mnt.h>
 
 #include "devfs.h"
 
 struct device_dirent
 {
-    rt_device_t *devices;
-    rt_uint16_t read_index;
-    rt_uint16_t device_count;
+    struct rt_device **devices;
+    uint32_t device_count;
+};
+
+int dfs_devfs_open(struct dfs_file *file);
+int dfs_devfs_close(struct dfs_file *file);
+int generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence);
+int dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos);
+int dfs_devfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos);
+int dfs_devfs_ioctl(struct dfs_file *file, int cmd, void *args);
+int dfs_devfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count);
+static int dfs_devfs_poll(struct dfs_file *file, struct rt_pollreq *req);
+
+int dfs_devfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data);
+int dfs_devfs_umount(struct dfs_mnt *mnt);
+int dfs_devfs_unlink(struct dfs_dentry *dentry);
+int dfs_devfs_stat(struct dfs_dentry *dentry, struct stat *st);
+int dfs_devfs_statfs(struct dfs_mnt *mnt, struct statfs *buf);
+static struct dfs_vnode *dfs_devfs_lookup(struct dfs_dentry *dentry);
+struct dfs_vnode *dfs_devfs_create_vnode(struct dfs_dentry *dentry, int type, mode_t mode);
+static int dfs_devfs_free_vnode(struct dfs_vnode *vnode);
+
+static const struct dfs_file_ops _dev_fops =
+{
+    .open = dfs_devfs_open,
+    .close = dfs_devfs_close,
+    .lseek = generic_dfs_lseek,
+    .read = dfs_devfs_read,
+    .write = dfs_devfs_write,
+    .ioctl = dfs_devfs_ioctl,
+    .getdents = dfs_devfs_getdents,
+    .poll = dfs_devfs_poll,
+};
+
+static const struct dfs_filesystem_ops _devfs_ops =
+{
+    .name = "devfs",
+
+    .default_fops = &_dev_fops,
+    .mount = dfs_devfs_mount,
+    .umount = dfs_devfs_umount,
+    .unlink = dfs_devfs_unlink,
+    .stat = dfs_devfs_stat,
+    .statfs = dfs_devfs_statfs,
+    .lookup = dfs_devfs_lookup,
+    .create_vnode = dfs_devfs_create_vnode,
+    .free_vnode = dfs_devfs_free_vnode,
+};
+
+static struct dfs_filesystem_type _devfs =
+{
+    .fs_ops = &_devfs_ops,
 };
 
-int dfs_device_fs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
+static int _device_to_mode(struct rt_device *device)
+{
+    int mode = 0;
+
+    switch (device->type)
+    {
+    case RT_Device_Class_Char:
+        mode = S_IFCHR | 0777;
+        break;
+    case RT_Device_Class_Block:
+        mode = S_IFBLK | 0777;
+        break;
+    case RT_Device_Class_Pipe:
+        mode = S_IFIFO | 0777;
+        break;
+    default:
+        mode = S_IFCHR | 0777;
+        break;
+    }
+
+    return mode;
+}
+
+static int _devfs_root_dirent_update(struct dfs_vnode *vnode)
+{
+    rt_err_t result = RT_EOK;
+
+    if (vnode)
+    {
+        // result = rt_mutex_take(&vnode->lock, RT_WAITING_FOREVER);
+        result = dfs_file_lock();
+        if (result == RT_EOK)
+        {
+            rt_uint32_t count = 0;
+            struct device_dirent *root_dirent = (struct device_dirent*) vnode->data;
+            if (root_dirent) rt_free(root_dirent);
+
+            count = rt_object_get_length(RT_Object_Class_Device);
+            root_dirent = (struct device_dirent *)rt_malloc(sizeof(struct device_dirent) + count * sizeof(rt_device_t));
+            if (root_dirent != RT_NULL)
+            {
+                root_dirent->device_count = count;
+                if (count != 0)
+                {
+                    root_dirent->devices = (rt_device_t *)(root_dirent + 1);
+                    rt_object_get_pointers(RT_Object_Class_Device, (rt_object_t *)root_dirent->devices, count);
+                }
+                else
+                {
+                    root_dirent->devices = RT_NULL;
+                }
+            }
+
+            vnode->data = root_dirent;
+            result = count;
+            dfs_file_unlock();
+        }
+    }
+
+    return result;
+}
+
+static struct dfs_vnode *dfs_devfs_lookup(struct dfs_dentry *dentry)
 {
+    rt_device_t device = RT_NULL;
+    struct dfs_vnode *vnode = RT_NULL;
+    const char *pathname = dentry->pathname;
+
+    DLOG(msg, "devfs", "vnode", DLOG_MSG, "dfs_vnode_create");
+    vnode = dfs_vnode_create();
+    if (vnode)
+    {
+        if (pathname[0] == '/' && pathname[1] == '\0')
+        {
+            int count = _devfs_root_dirent_update(vnode);
+
+            vnode->mode = S_IFDIR | 0644;
+            vnode->size = count;
+            vnode->nlink = 1;
+            vnode->fops = &_dev_fops;
+            vnode->mnt = dentry->mnt;
+            vnode->type = FT_DIRECTORY;
+        }
+        else
+        {
+            device = rt_device_find(&pathname[1]);
+            if (!device)
+            {
+                DLOG(msg, "devfs", "vnode", DLOG_MSG, "dfs_vnode_destroy(vnode), no-device");
+                dfs_vnode_destroy(vnode);
+                vnode = RT_NULL;
+            }
+            else
+            {
+                vnode->mode = _device_to_mode(device);
+                vnode->size = device->ref_count;
+                vnode->nlink = 1;
+                if (device->fops)
+                {
+                    vnode->fops = device->fops;
+                }
+                else
+                {
+                    vnode->fops = &_dev_fops;
+                }
+                vnode->data = device;
+                vnode->mnt = dentry->mnt;
+                vnode->type = FT_DEVICE;
+            }
+        }
+    }
+
+    return vnode;
+}
+
+struct dfs_vnode *dfs_devfs_create_vnode(struct dfs_dentry *dentry, int type, mode_t mode)
+{
+#ifdef RT_USING_DEV_BUS
+    if (dentry && type == FT_DIRECTORY)
+    {
+        /* regester bus device */
+        if (rt_device_bus_create(&dentry->pathname[1], 0))
+        {
+            return dfs_devfs_lookup(dentry);
+        }
+    }
+#endif
+
+    return RT_NULL;
+}
+
+int dfs_devfs_free_vnode(struct dfs_vnode *vnode)
+{
+    if (S_ISDIR(vnode->mode))
+    {
+        struct device_dirent *root_dirent;
+
+        root_dirent = (struct device_dirent *)vnode->data;
+        RT_ASSERT(root_dirent != RT_NULL);
+
+        /* release dirent */
+        DLOG(msg, "devfs", "devfs", DLOG_MSG, "free root_dirent");
+        rt_free(root_dirent);
+        return RT_EOK;
+    }
+
+    /* which is a device */
+    vnode->data = RT_NULL;
+    return 0;
+}
+
+int dfs_devfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
+{
+    RT_ASSERT(mnt != RT_NULL);
     return RT_EOK;
 }
 
-int dfs_device_fs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
+int dfs_devfs_umount(struct dfs_mnt *mnt)
 {
-    buf->f_bsize  = 512;
-    buf->f_blocks = 2048 * 64; // 64M
-    buf->f_bfree  = buf->f_blocks;
-    buf->f_bavail = buf->f_bfree;
+    return RT_EOK;
+}
+
+int dfs_devfs_statfs(struct dfs_mnt *mnt, struct statfs *buf)
+{
+    if (mnt && buf)
+    {
+        buf->f_bsize  = 512;
+        buf->f_blocks = 2048 * 64; // 64M
+        buf->f_bfree  = buf->f_blocks;
+        buf->f_bavail = buf->f_bfree;
+    }
 
     return RT_EOK;
 }
 
-int dfs_device_fs_ioctl(struct dfs_file *file, int cmd, void *args)
+int dfs_devfs_ioctl(struct dfs_file *file, int cmd, void *args)
 {
     rt_err_t result;
     rt_device_t dev_id;
@@ -50,7 +264,7 @@ int dfs_device_fs_ioctl(struct dfs_file *file, int cmd, void *args)
     dev_id = (rt_device_t)file->vnode->data;
     RT_ASSERT(dev_id != RT_NULL);
 
-    if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
+    if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
         return -RT_ENOSYS;
 
     /* close device handler */
@@ -61,7 +275,7 @@ int dfs_device_fs_ioctl(struct dfs_file *file, int cmd, void *args)
     return result;
 }
 
-int dfs_device_fs_read(struct dfs_file *file, void *buf, size_t count)
+int dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
 {
     int result;
     rt_device_t dev_id;
@@ -72,17 +286,17 @@ int dfs_device_fs_read(struct dfs_file *file, void *buf, size_t count)
     dev_id = (rt_device_t)file->vnode->data;
     RT_ASSERT(dev_id != RT_NULL);
 
-    if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
+    if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
         return -RT_ENOSYS;
 
     /* read device data */
-    result = rt_device_read(dev_id, file->pos, buf, count);
-    file->pos += result;
+    result = rt_device_read(dev_id, *pos, buf, count);
+    *pos += result;
 
     return result;
 }
 
-int dfs_device_fs_write(struct dfs_file *file, const void *buf, size_t count)
+int dfs_devfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
 {
     int result;
     rt_device_t dev_id;
@@ -93,184 +307,93 @@ int dfs_device_fs_write(struct dfs_file *file, const void *buf, size_t count)
     dev_id = (rt_device_t)file->vnode->data;
     RT_ASSERT(dev_id != RT_NULL);
 
-    if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
+    if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
         return -RT_ENOSYS;
 
     /* read device data */
-    result = rt_device_write(dev_id, file->pos, buf, count);
-    file->pos += result;
+    result = rt_device_write(dev_id, *pos, buf, count);
+    *pos += result;
 
     return result;
 }
 
-int dfs_device_fs_close(struct dfs_file *file)
+int dfs_devfs_close(struct dfs_file *file)
 {
-    rt_err_t result;
-    rt_device_t dev_id;
+    rt_err_t result = RT_EOK;
+    rt_device_t device;
 
     RT_ASSERT(file != RT_NULL);
-    RT_ASSERT(file->vnode->ref_count > 0);
-
-    if (file->vnode->ref_count > 1)
-    {
-        return 0;
-    }
 
-    if (file->vnode->type == FT_DIRECTORY && (file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
+    if (!S_ISDIR(file->vnode->mode))
     {
-        struct device_dirent *root_dirent;
+        /* get device handler */
+        device = (rt_device_t)file->vnode->data;
+        RT_ASSERT(device != RT_NULL);
 
-        root_dirent = (struct device_dirent *)file->vnode->data;
-        RT_ASSERT(root_dirent != RT_NULL);
-
-        /* release dirent */
-        rt_free(root_dirent);
-        return RT_EOK;
+        /* close device handler */
+        result = rt_device_close(device);
     }
 
-    /* get device handler */
-    dev_id = (rt_device_t)file->vnode->data;
-    RT_ASSERT(dev_id != RT_NULL);
-
-    /* close device handler */
-    result = rt_device_close(dev_id);
-    if (result == RT_EOK)
-    {
-        file->vnode->data = RT_NULL;
-
-        return RT_EOK;
-    }
-
-    return -EIO;
+    return result;
 }
 
-int dfs_device_fs_open(struct dfs_file *file)
+int dfs_devfs_open(struct dfs_file *file)
 {
-    rt_err_t result;
-    rt_device_t device;
+    rt_err_t result = RT_EOK;
 
-    RT_ASSERT(file->vnode->ref_count > 0);
-    if (file->vnode->ref_count > 1)
+    /* open root directory */
+    if ((file->dentry->pathname[0] == '/' && file->dentry->pathname[1] == '\0') ||
+        (S_ISDIR(file->vnode->mode)))
     {
-        file->pos = 0;
-        return 0;
+        /* re-open the root directory for re-scan devices */
+        _devfs_root_dirent_update(file->vnode);
+        return RT_EOK;
     }
-    /* open root directory */
-    if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0') &&
-        (file->flags & O_DIRECTORY))
+    else
     {
-        struct rt_object *object;
-        struct rt_list_node *node;
-        struct rt_object_information *information;
-        struct device_dirent *root_dirent;
-        rt_uint32_t count = 0;
-
-        /* lock scheduler */
-        rt_enter_critical();
+        rt_device_t device = RT_NULL;
 
-        /* traverse device object */
-        information = rt_object_get_information(RT_Object_Class_Device);
-        RT_ASSERT(information != RT_NULL);
-        for (node = information->object_list.next; node != &(information->object_list); node = node->next)
+        device = (struct rt_device *)file->vnode->data;
+        if (device)
         {
-            count ++;
-        }
-        rt_exit_critical();
-
-        root_dirent = (struct device_dirent *)rt_malloc(sizeof(struct device_dirent) +
-                      count * sizeof(rt_device_t));
-        if (root_dirent != RT_NULL)
-        {
-            /* lock scheduler */
-            rt_enter_critical();
-
-            root_dirent->devices = (rt_device_t *)(root_dirent + 1);
-            root_dirent->read_index = 0;
-            root_dirent->device_count = count;
-            count = 0;
-            /* get all device node */
-            for (node = information->object_list.next; node != &(information->object_list); node = node->next)
+#ifdef RT_USING_POSIX_DEVIO
+            if (device->fops)
             {
-                /* avoid memory write through */
-                if (count == root_dirent->device_count)
+                /* use device fops */
+                file->fops = device->fops;
+                /* use fops->open */
+                if (file->vnode->fops->open)
                 {
-                    rt_kprintf("warning: There are newly added devices that are not displayed!");
-                    break;
+                    result = file->vnode->fops->open(file);
+                    if (result == RT_EOK || result == -RT_ENOSYS)
+                    {
+                        return RT_EOK;
+                    }
                 }
-                object = rt_list_entry(node, struct rt_object, list);
-                root_dirent->devices[count] = (rt_device_t)object;
-                count ++;
             }
-            rt_exit_critical();
-        }
-
-        /* set data */
-        file->vnode->data = root_dirent;
-
-        return RT_EOK;
-    }
-#ifdef RT_USING_DEV_BUS
-    else if (file->flags & O_CREAT)
-    {
-        if (!(file->flags & O_DIRECTORY))
-        {
-            return -ENOSYS;
-        }
-        /* regester bus device */
-        if (rt_device_bus_create(&file->vnode->path[1], 0) == RT_NULL)
-        {
-            return -EEXIST;
-        }
-    }
-#endif
-
-    device = rt_device_find(&file->vnode->path[1]);
-    if (device == RT_NULL)
-    {
-        return -ENODEV;
-    }
-
-#ifdef RT_USING_POSIX_DEVIO
-    if (device->fops)
-    {
-        /* use device fops */
-        file->vnode->fops = device->fops;
-        file->vnode->data = (void *)device;
-
-        /* use fops */
-        if (file->vnode->fops->open)
-        {
-            result = file->vnode->fops->open(file);
-            if (result == RT_EOK || result == -RT_ENOSYS)
+            else
+#endif /* RT_USING_POSIX_DEVIO */
             {
-                file->vnode->type = FT_DEVICE;
-                return 0;
+                result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
+                if (result == RT_EOK || result == -RT_ENOSYS)
+                {
+                    file->fops = &_dev_fops;
+                    return RT_EOK;
+                }
             }
         }
     }
-    else
-#endif /* RT_USING_POSIX_DEVIO */
-    {
-        result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
-        if (result == RT_EOK || result == -RT_ENOSYS)
-        {
-            file->vnode->data = device;
-            file->vnode->type = FT_DEVICE;
-            return RT_EOK;
-        }
-    }
 
-    file->vnode->data = RT_NULL;
     /* open device failed. */
     return -EIO;
 }
 
-int dfs_device_fs_unlink(struct dfs_filesystem *fs, const char *path)
+int dfs_devfs_unlink(struct dfs_dentry *dentry)
 {
 #ifdef RT_USING_DEV_BUS
     rt_device_t dev_id;
 
-    dev_id = rt_device_find(&path[1]);
+    dev_id = rt_device_find(&dentry->pathname[1]);
     if (dev_id == RT_NULL)
     {
         return -1;
@@ -284,57 +407,66 @@ int dfs_device_fs_unlink(struct dfs_filesystem *fs, const char *path)
     return RT_EOK;
 }
 
-int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
+int dfs_devfs_stat(struct dfs_dentry *dentry, struct stat *st)
 {
-    /* stat root directory */
-    if ((path[0] == '/') && (path[1] == '\0'))
-    {
-        st->st_dev = 0;
-
-        st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
-                      S_IWUSR | S_IWGRP | S_IWOTH;
-        st->st_mode &= ~S_IFREG;
-        st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+    int ret = RT_EOK;
+    const char *path = RT_NULL;
+    struct dfs_vnode *vnode = RT_NULL;
 
-        st->st_size  = 0;
-        st->st_mtime = 0;
-
-        return RT_EOK;
-    }
-    else
+    if (dentry && dentry->vnode)
     {
-        rt_device_t dev_id;
+        path = dentry->pathname;
+        vnode = dentry->vnode;
 
-        dev_id = rt_device_find(&path[1]);
-        if (dev_id != RT_NULL)
+        /* stat root directory */
+        if ((path[0] == '/') && (path[1] == '\0'))
         {
             st->st_dev = 0;
+            st->st_gid = vnode->gid;
+            st->st_uid = vnode->uid;
+            st->st_ino = 0;
+            st->st_mode  = vnode->mode;
+            st->st_nlink = vnode->nlink;
+            st->st_size  = vnode->size;
+            st->st_mtim.tv_nsec = vnode->mtime.tv_nsec;
+            st->st_mtim.tv_sec  = vnode->mtime.tv_sec;
+            st->st_ctim.tv_nsec = vnode->ctime.tv_nsec;
+            st->st_ctim.tv_sec  = vnode->ctime.tv_sec;
+            st->st_atim.tv_nsec = vnode->atime.tv_nsec;
+            st->st_atim.tv_sec  = vnode->atime.tv_sec;
+        }
+        else
+        {
+            rt_device_t dev_id;
 
-            st->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
-                          S_IWUSR | S_IWGRP | S_IWOTH;
-
-            if (dev_id->type == RT_Device_Class_Char)
-                st->st_mode |= S_IFCHR;
-            else if (dev_id->type == RT_Device_Class_Block)
-                st->st_mode |= S_IFBLK;
-            else if (dev_id->type == RT_Device_Class_Pipe)
-                st->st_mode |= S_IFIFO;
-            else if (dev_id->type == RT_Device_Class_Bus)
-                st->st_mode |= S_IFDIR;
+            dev_id = rt_device_find(&path[1]);
+            if (dev_id != RT_NULL)
+            {
+                st->st_dev = 0;
+                st->st_gid = vnode->gid;
+                st->st_uid = vnode->uid;
+                st->st_ino = 0;
+                st->st_mode  = vnode->mode;
+                st->st_nlink = vnode->nlink;
+                st->st_size  = vnode->size;
+                st->st_mtim.tv_nsec = vnode->mtime.tv_nsec;
+                st->st_mtim.tv_sec  = vnode->mtime.tv_sec;
+                st->st_ctim.tv_nsec = vnode->ctime.tv_nsec;
+                st->st_ctim.tv_sec  = vnode->ctime.tv_sec;
+                st->st_atim.tv_nsec = vnode->atime.tv_nsec;
+                st->st_atim.tv_sec  = vnode->atime.tv_sec;
+            }
             else
-                st->st_mode |= S_IFREG;
-
-            st->st_size  = 0;
-            st->st_mtime = 0;
-
-            return RT_EOK;
+            {
+                ret = -ENOENT;
+            }
         }
     }
 
-    return -ENOENT;
+    return ret;
 }
 
-int dfs_device_fs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
+int dfs_devfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
 {
     rt_uint32_t index;
     rt_object_t object;
@@ -349,68 +481,38 @@ int dfs_device_fs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t
     if (count == 0)
         return -EINVAL;
 
-    for (index = 0; index < count && index + root_dirent->read_index < root_dirent->device_count;
-        index ++)
+    for (index = 0; index < count && index + file->fpos < root_dirent->device_count; index ++)
     {
-        object = (rt_object_t)root_dirent->devices[root_dirent->read_index + index];
+        object = (rt_object_t)root_dirent->devices[file->fpos + index];
 
         d = dirp + index;
-        if ((((rt_device_t)object)->type) == RT_Device_Class_Bus)
-        {
-            d->d_type = DT_DIR;
-        }
-        else
-        {
-            d->d_type = DT_REG;
-        }
+        d->d_type = DT_REG;
         d->d_namlen = RT_NAME_MAX;
         d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
         rt_strncpy(d->d_name, object->name, RT_NAME_MAX);
+        d->d_name[RT_NAME_MAX] = '\0';
     }
 
-    root_dirent->read_index += index;
+    file->fpos += index;
 
     return index * sizeof(struct dirent);
 }
 
-static int dfs_device_fs_poll(struct dfs_file *fd, struct rt_pollreq *req)
+static int dfs_devfs_poll(struct dfs_file *file, struct rt_pollreq *req)
 {
     int mask = 0;
 
     return mask;
 }
 
-static const struct dfs_file_ops _device_fops =
+int dfs_devfs_init(void)
 {
-    dfs_device_fs_open,
-    dfs_device_fs_close,
-    dfs_device_fs_ioctl,
-    dfs_device_fs_read,
-    dfs_device_fs_write,
-    RT_NULL,                    /* flush */
-    RT_NULL,                    /* lseek */
-    dfs_device_fs_getdents,
-    dfs_device_fs_poll,
-};
+    /* register devfs file system */
+    dfs_register(&_devfs);
 
-static const struct dfs_filesystem_ops _device_fs =
-{
-    "devfs",
-    DFS_FS_FLAG_DEFAULT,
-    &_device_fops,
-    dfs_device_fs_mount,
-    RT_NULL, /*unmount*/
-    RT_NULL, /*mkfs*/
-    dfs_device_fs_statfs,
-    dfs_device_fs_unlink,
-    dfs_device_fs_stat,
-    RT_NULL, /*rename*/
-};
-
-int devfs_init(void)
-{
-    /* register device file system */
-    dfs_register(&_device_fs);
+    dfs_mount(RT_NULL, "/dev", "devfs", 0, RT_NULL);
 
     return 0;
 }
+INIT_COMPONENT_EXPORT(dfs_devfs_init);
+

+ 1 - 3
components/dfs/dfs_v2/filesystems/devfs/devfs.h

@@ -10,8 +10,6 @@
 #ifndef __DEVICE_FS_H__
 #define __DEVICE_FS_H__
 
-#include <rtthread.h>
-
-int devfs_init(void);
+int dfs_devfs_init(void);
 
 #endif

+ 188 - 77
components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c

@@ -26,8 +26,11 @@
 /* ELM FatFs provide a DIR struct */
 #define HAVE_DIR_STRUCTURE
 
+#include <dfs.h>
 #include <dfs_fs.h>
+#include <dfs_dentry.h>
 #include <dfs_file.h>
+#include <dfs_mnt.h>
 
 #undef SS
 #if FF_MAX_SS == FF_MIN_SS
@@ -38,6 +41,8 @@
 
 static rt_device_t disk[FF_VOLUMES] = {0};
 
+int dfs_elm_unmount(struct dfs_mnt *mnt);
+
 static int elm_result_to_dfs(FRESULT result)
 {
     int status = RT_EOK;
@@ -102,7 +107,7 @@ static int get_disk(rt_device_t id)
     return -1;
 }
 
-int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
+static int dfs_elm_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
 {
     FATFS *fat;
     FRESULT result;
@@ -110,20 +115,31 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
     struct rt_device_blk_geometry geometry;
     char logic_nbr[3] = {'0',':', 0};
 
+    /* open device, but do not check the status of device */
+    if (mnt->dev_id == RT_NULL
+        || rt_device_open(mnt->dev_id, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
+    {
+        return -ENODEV;
+    }
+
     /* get an empty position */
     index = get_disk(RT_NULL);
     if (index == -1)
+    {
+        rt_device_close(mnt->dev_id);
         return -ENOENT;
+    }
     logic_nbr[0] = '0' + index;
 
     /* save device */
-    disk[index] = fs->dev_id;
+    disk[index] = mnt->dev_id;
     /* check sector size */
-    if (rt_device_control(fs->dev_id, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry) == RT_EOK)
+    if (rt_device_control(mnt->dev_id, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry) == RT_EOK)
     {
         if (geometry.bytes_per_sector > FF_MAX_SS)
         {
             rt_kprintf("The sector size of device is greater than the sector size of FAT.\n");
+            rt_device_close(mnt->dev_id);
             return -EINVAL;
         }
     }
@@ -132,6 +148,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
     if (fat == RT_NULL)
     {
         disk[index] = RT_NULL;
+        rt_device_close(mnt->dev_id);
         return -ENOMEM;
     }
 
@@ -149,6 +166,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
             f_mount(RT_NULL, (const TCHAR *)logic_nbr, 1);
             disk[index] = RT_NULL;
             rt_free(fat);
+            rt_device_close(mnt->dev_id);
             return -ENOMEM;
         }
 
@@ -158,31 +176,32 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
             goto __err;
 
         /* mount succeed! */
-        fs->data = fat;
+        mnt->data = fat;
         rt_free(dir);
-        return 0;
+        return RT_EOK;
     }
 
 __err:
     f_mount(RT_NULL, (const TCHAR *)logic_nbr, 1);
     disk[index] = RT_NULL;
     rt_free(fat);
+    rt_device_close(mnt->dev_id);
     return elm_result_to_dfs(result);
 }
 
-int dfs_elm_unmount(struct dfs_filesystem *fs)
+int dfs_elm_unmount(struct dfs_mnt *mnt)
 {
     FATFS *fat;
     FRESULT result;
     int  index;
     char logic_nbr[3] = {'0',':', 0};
 
-    fat = (FATFS *)fs->data;
+    fat = (FATFS *)mnt->data;
 
     RT_ASSERT(fat != RT_NULL);
 
     /* find the device index and then umount it */
-    index = get_disk(fs->dev_id);
+    index = get_disk(mnt->dev_id);
     if (index == -1) /* not found */
         return -ENOENT;
 
@@ -191,9 +210,10 @@ int dfs_elm_unmount(struct dfs_filesystem *fs)
     if (result != FR_OK)
         return elm_result_to_dfs(result);
 
-    fs->data = RT_NULL;
+    mnt->data = RT_NULL;
     disk[index] = RT_NULL;
     rt_free(fat);
+    rt_device_close(mnt->dev_id);
 
     return RT_EOK;
 }
@@ -296,17 +316,17 @@ int dfs_elm_mkfs(rt_device_t dev_id, const char *fs_name)
     return RT_EOK;
 }
 
-int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf)
+int dfs_elm_statfs(struct dfs_mnt *mnt, struct statfs *buf)
 {
     FATFS *f;
     FRESULT res;
     char driver[4];
     DWORD fre_clust, fre_sect, tot_sect;
 
-    RT_ASSERT(fs != RT_NULL);
+    RT_ASSERT(mnt != RT_NULL);
     RT_ASSERT(buf != RT_NULL);
 
-    f = (FATFS *)fs->data;
+    f = (FATFS *)mnt->data;
 
     rt_snprintf(driver, sizeof(driver), "%d:", f->pdrv);
     res = f_getfree(driver, &fre_clust, &f);
@@ -337,7 +357,7 @@ int dfs_elm_open(struct dfs_file *file)
 
 #if (FF_VOLUMES > 1)
     int vol;
-    struct dfs_filesystem *fs = file->vnode->fs;
+    struct dfs_mnt *mnt = file->vnode->mnt;
     extern int elm_get_vol(FATFS * fat);
 
     RT_ASSERT(file->vnode->ref_count > 0);
@@ -348,24 +368,24 @@ int dfs_elm_open(struct dfs_file *file)
         {
             return -ENOENT;
         }
-        file->pos = 0;
+        file->fpos = 0;
         return 0;
     }
 
-    if (fs == NULL)
+    if (mnt == NULL)
         return -ENOENT;
 
     /* add path for ELM FatFS driver support */
-    vol = elm_get_vol((FATFS *)fs->data);
+    vol = elm_get_vol((FATFS *)mnt->data);
     if (vol < 0)
         return -ENOENT;
     drivers_fn = (char *)rt_malloc(256);
     if (drivers_fn == RT_NULL)
         return -ENOMEM;
 
-    rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->vnode->path);
+    rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->dentry->pathname);
 #else
-    drivers_fn = file->vnode->path;
+    drivers_fn = file->dentry->pathname;
 #endif
 
     if (file->flags & O_DIRECTORY)
@@ -404,7 +424,7 @@ int dfs_elm_open(struct dfs_file *file)
             return elm_result_to_dfs(result);
         }
 
-        file->data = dir;
+        file->vnode->data = dir;
         return RT_EOK;
     }
     else
@@ -441,16 +461,16 @@ int dfs_elm_open(struct dfs_file *file)
 #endif
         if (result == FR_OK)
         {
-            file->pos  = fd->fptr;
+            file->fpos  = fd->fptr;
             file->vnode->size = f_size(fd);
             file->vnode->type = FT_REGULAR;
-            file->data = fd;
+            file->vnode->data = fd;
 
             if (file->flags & O_APPEND)
             {
                 /* seek to the end of file */
                 f_lseek(fd, f_size(fd));
-                file->pos = fd->fptr;
+                file->fpos = fd->fptr;
             }
         }
         else
@@ -478,7 +498,7 @@ int dfs_elm_close(struct dfs_file *file)
     {
         DIR *dir = RT_NULL;
 
-        dir = (DIR *)(file->data);
+        dir = (DIR *)(file->vnode->data);
         RT_ASSERT(dir != RT_NULL);
 
         /* release memory */
@@ -487,7 +507,7 @@ int dfs_elm_close(struct dfs_file *file)
     else if (file->vnode->type == FT_REGULAR)
     {
         FIL *fd = RT_NULL;
-        fd = (FIL *)(file->data);
+        fd = (FIL *)(file->vnode->data);
         RT_ASSERT(fd != RT_NULL);
 
         result = f_close(fd);
@@ -510,7 +530,7 @@ int dfs_elm_ioctl(struct dfs_file *file, int cmd, void *args)
             FIL *fd;
             FSIZE_t fptr, length;
             FRESULT result = FR_OK;
-            fd = (FIL *)(file->data);
+            fd = (FIL *)(file->vnode->data);
             RT_ASSERT(fd != RT_NULL);
 
             /* save file read/write point */
@@ -537,7 +557,7 @@ int dfs_elm_ioctl(struct dfs_file *file, int cmd, void *args)
     return -ENOSYS;
 }
 
-int dfs_elm_read(struct dfs_file *file, void *buf, size_t len)
+int dfs_elm_read(struct dfs_file *file, void *buf, size_t len, off_t *pos)
 {
     FIL *fd;
     FRESULT result;
@@ -548,19 +568,20 @@ int dfs_elm_read(struct dfs_file *file, void *buf, size_t len)
         return -EISDIR;
     }
 
-    fd = (FIL *)(file->data);
+    fd = (FIL *)(file->vnode->data);
     RT_ASSERT(fd != RT_NULL);
 
     result = f_read(fd, buf, len, &byte_read);
     /* update position */
-    file->pos  = fd->fptr;
+    file->fpos  = fd->fptr;
+    *pos = file->fpos;
     if (result == FR_OK)
         return byte_read;
 
     return elm_result_to_dfs(result);
 }
 
-int dfs_elm_write(struct dfs_file *file, const void *buf, size_t len)
+int dfs_elm_write(struct dfs_file *file, const void *buf, size_t len, off_t *pos)
 {
     FIL *fd;
     FRESULT result;
@@ -571,12 +592,13 @@ int dfs_elm_write(struct dfs_file *file, const void *buf, size_t len)
         return -EISDIR;
     }
 
-    fd = (FIL *)(file->data);
+    fd = (FIL *)(file->vnode->data);
     RT_ASSERT(fd != RT_NULL);
 
     result = f_write(fd, buf, len, &byte_write);
     /* update position and file size */
-    file->pos  = fd->fptr;
+    file->fpos  = fd->fptr;
+    *pos = file->fpos;
     file->vnode->size = f_size(fd);
     if (result == FR_OK)
         return byte_write;
@@ -589,14 +611,14 @@ int dfs_elm_flush(struct dfs_file *file)
     FIL *fd;
     FRESULT result;
 
-    fd = (FIL *)(file->data);
+    fd = (FIL *)(file->vnode->data);
     RT_ASSERT(fd != RT_NULL);
 
     result = f_sync(fd);
     return elm_result_to_dfs(result);
 }
 
-int dfs_elm_lseek(struct dfs_file *file, off_t offset)
+int dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
 {
     FRESULT result = FR_OK;
     if (file->vnode->type == FT_REGULAR)
@@ -604,14 +626,14 @@ int dfs_elm_lseek(struct dfs_file *file, off_t offset)
         FIL *fd;
 
         /* regular file type */
-        fd = (FIL *)(file->data);
+        fd = (FIL *)(file->vnode->data);
         RT_ASSERT(fd != RT_NULL);
 
         result = f_lseek(fd, offset);
         if (result == FR_OK)
         {
             /* return current position */
-            file->pos = fd->fptr;
+            file->fpos = fd->fptr;
             return fd->fptr;
         }
     }
@@ -620,15 +642,15 @@ int dfs_elm_lseek(struct dfs_file *file, off_t offset)
         /* which is a directory */
         DIR *dir = RT_NULL;
 
-        dir = (DIR *)(file->data);
+        dir = (DIR *)(file->vnode->data);
         RT_ASSERT(dir != RT_NULL);
 
         result = f_seekdir(dir, offset / sizeof(struct dirent));
         if (result == FR_OK)
         {
             /* update file position */
-            file->pos = offset;
-            return file->pos;
+            file->fpos = offset;
+            return file->fpos;
         }
     }
 
@@ -643,7 +665,7 @@ int dfs_elm_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
     rt_uint32_t index;
     struct dirent *d;
 
-    dir = (DIR *)(file->data);
+    dir = (DIR *)(file->vnode->data);
     RT_ASSERT(dir != RT_NULL);
 
     /* make integer count */
@@ -686,12 +708,12 @@ int dfs_elm_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
     if (index == 0)
         return elm_result_to_dfs(result);
 
-    file->pos += index * sizeof(struct dirent);
+    file->fpos += index * sizeof(struct dirent);
 
     return index * sizeof(struct dirent);
 }
 
-int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
+int dfs_elm_unlink(struct dfs_dentry *dentry)
 {
     FRESULT result;
 
@@ -701,14 +723,14 @@ int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
     extern int elm_get_vol(FATFS * fat);
 
     /* add path for ELM FatFS driver support */
-    vol = elm_get_vol((FATFS *)fs->data);
+    vol = elm_get_vol((FATFS *)dentry->mnt->data);
     if (vol < 0)
         return -ENOENT;
     drivers_fn = (char *)rt_malloc(256);
     if (drivers_fn == RT_NULL)
         return -ENOMEM;
 
-    rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
+    rt_snprintf(drivers_fn, 256, "%d:%s", vol, dentry->pathname);
 #else
     const char *drivers_fn;
     drivers_fn = path;
@@ -721,7 +743,7 @@ int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
     return elm_result_to_dfs(result);
 }
 
-int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *newpath)
+int dfs_elm_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *new_dentry)
 {
     FRESULT result;
 
@@ -732,21 +754,21 @@ int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *n
     extern int elm_get_vol(FATFS * fat);
 
     /* add path for ELM FatFS driver support */
-    vol = elm_get_vol((FATFS *)fs->data);
+    vol = elm_get_vol((FATFS *)old_dentry->mnt->data);
     if (vol < 0)
         return -ENOENT;
 
     drivers_oldfn = (char *)rt_malloc(256);
     if (drivers_oldfn == RT_NULL)
         return -ENOMEM;
-    drivers_newfn = newpath;
+    drivers_newfn = new_dentry->pathname;
 
-    rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
+    rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, old_dentry->pathname);
 #else
     const char *drivers_oldfn, *drivers_newfn;
 
-    drivers_oldfn = oldpath;
-    drivers_newfn = newpath;
+    drivers_oldfn = old_dentry->pathname;
+    drivers_newfn = new_dentry->pathname;
 #endif
 
     result = f_rename(drivers_oldfn, drivers_newfn);
@@ -756,13 +778,13 @@ int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *n
     return elm_result_to_dfs(result);
 }
 
-int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
+int dfs_elm_stat(struct dfs_dentry *dentry, struct stat *st)
 {
-    FATFS  *f;
+    FATFS  *fat;
     FILINFO file_info;
     FRESULT result;
 
-    f = (FATFS *)fs->data;
+    fat = (FATFS *)dentry->mnt->data;
 
 #if FF_VOLUMES > 1
     int vol;
@@ -770,17 +792,17 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
     extern int elm_get_vol(FATFS * fat);
 
     /* add path for ELM FatFS driver support */
-    vol = elm_get_vol((FATFS *)fs->data);
+    vol = elm_get_vol(fat);
     if (vol < 0)
         return -ENOENT;
     drivers_fn = (char *)rt_malloc(256);
     if (drivers_fn == RT_NULL)
         return -ENOMEM;
 
-    rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
+    rt_snprintf(drivers_fn, 256, "%d:%s", vol, dentry->pathname);
 #else
     const char *drivers_fn;
-    drivers_fn = path;
+    drivers_fn = dentry->pathname;
 #endif
 
     result = f_stat(drivers_fn, &file_info);
@@ -790,7 +812,8 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
     if (result == FR_OK)
     {
         /* convert to dfs stat structure */
-        st->st_dev = 0;
+        st->st_dev = (dev_t)(size_t)(dentry->mnt->dev_id);
+        st->st_ino = (ino_t)dfs_dentry_full_path_crc32(dentry);
 
         st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
                       S_IWUSR | S_IWGRP | S_IWOTH;
@@ -803,15 +826,15 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
             st->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
 
         st->st_size  = file_info.fsize;
-        st->st_blksize = f->csize * SS(f);
+        st->st_blksize = fat->csize * SS(fat);
         if (file_info.fattrib & AM_ARC)
         {
-            st->st_blocks = file_info.fsize ? ((file_info.fsize - 1) / SS(f) / f->csize + 1) : 0;
+            st->st_blocks = file_info.fsize ? ((file_info.fsize - 1) / SS(f) / fat->csize + 1) : 0;
             st->st_blocks *= (st->st_blksize / 512);  // man say st_blocks is number of 512B blocks allocated
         }
         else
         {
-            st->st_blocks = f->csize;
+            st->st_blocks = fat->csize;
         }
         /* get st_mtime. */
         {
@@ -848,39 +871,127 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
     return elm_result_to_dfs(result);
 }
 
+static struct dfs_vnode *dfs_elm_lookup(struct dfs_dentry *dentry)
+{
+    struct stat st;
+    struct dfs_vnode *vnode = RT_NULL;
+
+    if (dentry == NULL || dentry->mnt == NULL || dentry->mnt->data == NULL)
+    {
+        return NULL;
+    }
+
+    if (dfs_elm_stat(dentry, &st) != 0)
+    {
+        return vnode;
+    }
+
+    vnode = dfs_vnode_create();
+    if (vnode)
+    {
+        if (S_ISDIR(st.st_mode))
+        {
+            vnode->mode = S_IFDIR | (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+            vnode->type = FT_DIRECTORY;
+        }
+        else
+        {
+            vnode->mode = S_IFREG | (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+            vnode->type = FT_REGULAR;
+        }
+
+        vnode->mnt = dentry->mnt;
+        vnode->data = NULL;
+        vnode->size = 0;
+    }
+
+    return vnode;
+}
+
+static struct dfs_vnode *dfs_elm_create_vnode(struct dfs_dentry *dentry, int type, mode_t mode)
+{
+    struct dfs_vnode *vnode = RT_NULL;
+
+    if (dentry == NULL || dentry->mnt == NULL || dentry->mnt->data == NULL)
+    {
+        return NULL;
+    }
+
+    vnode = dfs_vnode_create();
+    if (vnode)
+    {
+        if (type == FT_DIRECTORY)
+        {
+            vnode->mode = S_IFDIR | mode;
+            vnode->type = FT_DIRECTORY;
+        }
+        else
+        {
+
+            vnode->mode = S_IFREG | mode;
+            vnode->type = FT_REGULAR;
+        }
+
+        vnode->mnt = dentry->mnt;
+        vnode->data = NULL;
+        vnode->size = 0;
+    }
+
+    return vnode;
+}
+
+static int dfs_elm_free_vnode(struct dfs_vnode *vnode)
+{
+    /* nothing to be freed */
+    if (vnode && vnode->ref_count <= 1)
+    {
+        vnode->data = NULL;
+    }
+
+    return 0;
+}
+
 static const struct dfs_file_ops dfs_elm_fops =
 {
-    dfs_elm_open,
-    dfs_elm_close,
-    dfs_elm_ioctl,
-    dfs_elm_read,
-    dfs_elm_write,
-    dfs_elm_flush,
-    dfs_elm_lseek,
-    dfs_elm_getdents,
-    RT_NULL, /* poll interface */
+    .open = dfs_elm_open,
+    .close = dfs_elm_close,
+    .ioctl = dfs_elm_ioctl,
+    .read = dfs_elm_read,
+    .write = dfs_elm_write,
+    .flush = dfs_elm_flush,
+    .lseek = dfs_elm_lseek,
+    .getdents = dfs_elm_getdents,
 };
 
 static const struct dfs_filesystem_ops dfs_elm =
 {
     "elm",
-    DFS_FS_FLAG_DEFAULT,
+    FS_NEED_DEVICE,
     &dfs_elm_fops,
 
-    dfs_elm_mount,
-    dfs_elm_unmount,
-    dfs_elm_mkfs,
-    dfs_elm_statfs,
+    .mount = dfs_elm_mount,
+    .umount = dfs_elm_unmount,
+    .mkfs = dfs_elm_mkfs,
+    .statfs = dfs_elm_statfs,
+
+    .unlink = dfs_elm_unlink,
+    .stat = dfs_elm_stat,
+    .rename = dfs_elm_rename,
 
-    dfs_elm_unlink,
-    dfs_elm_stat,
-    dfs_elm_rename,
+    .lookup = dfs_elm_lookup,
+    .create_vnode = dfs_elm_create_vnode,
+    .free_vnode = dfs_elm_free_vnode
+};
+
+static struct dfs_filesystem_type _elmfs =
+{
+    .fs_ops = &dfs_elm,
 };
 
 int elm_init(void)
 {
     /* register fatfs file system */
-    dfs_register(&dfs_elm);
+    dfs_register(&_elmfs);
 
     return 0;
 }

+ 1 - 3
components/dfs/dfs_v2/filesystems/elmfat/ff.c

@@ -4077,7 +4077,6 @@ FRESULT f_sync (
 	DWORD tm;
 	BYTE *dir;
 
-
 	res = validate(&fp->obj, &fs);	/* Check validity of the file object */
 	if (res == FR_OK) {
 		if (fp->flag & FA_MODIFIED) {	/* Is there any change to the file? */
@@ -4201,7 +4200,6 @@ FRESULT f_chdrive (
 }
 
 
-
 FRESULT f_chdir (
 	const TCHAR* path	/* Pointer to the directory path */
 )
@@ -4746,7 +4744,7 @@ FRESULT f_stat (
 		res = follow_path(&dj, path);	/* Follow the file path */
 		if (res == FR_OK) {				/* Follow completed */
 			if (dj.fn[NSFLAG] & NS_NONAME) {	/* It is origin directory */
-				res = FR_INVALID_NAME;
+				fno->fattrib = AM_DIR;
 			} else {							/* Found an object */
 				if (fno) get_fileinfo(&dj, fno);
 			}

+ 0 - 13
components/dfs/dfs_v2/filesystems/nfs/SConscript

@@ -1,13 +0,0 @@
-# RT-Thread building script for component
-
-from building import *
-
-cwd = GetCurrentDir()
-src = Glob('*.c') + Glob('rpc/*.c')
-CPPPATH = [cwd]
-
-SrcRemove(src, ['rpc/auth_none.c'])
-
-group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_NFS'], CPPPATH = CPPPATH)
-
-Return('group')

+ 0 - 1192
components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.c

@@ -1,1192 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-
-#include <stdio.h>
-#include <rtthread.h>
-#include <dfs_fs.h>
-#include <dfs.h>
-#include <dfs_file.h>
-
-#include <rpc/rpc.h>
-
-#include "mount.h"
-#include "nfs.h"
-
-#define NAME_MAX    64
-#define DFS_NFS_MAX_MTU  1024
-
-#ifdef _WIN32
-#define strtok_r strtok_s
-#endif
-
-struct nfs_file
-{
-    nfs_fh3 handle;     /* handle */
-    size_t offset;      /* current offset */
-
-    size_t size;        /* total size */
-    bool_t eof;         /* end of file */
-};
-
-struct nfs_dir
-{
-    nfs_fh3 handle;
-    cookie3 cookie;
-    cookieverf3 cookieverf;
-    entry3 *entry;
-    bool_t eof;
-    READDIR3res res;
-};
-
-#define HOST_LENGTH         32
-#define EXPORT_PATH_LENGTH  32
-
-struct nfs_filesystem
-{
-    nfs_fh3 root_handle;
-    nfs_fh3 current_handle;
-    CLIENT *nfs_client;
-    CLIENT *mount_client;
-
-    char host[HOST_LENGTH];
-    char export[EXPORT_PATH_LENGTH];
-    void *data;             /* nfs_file or nfs_dir */
-};
-
-typedef struct nfs_filesystem nfs_filesystem;
-typedef struct nfs_file nfs_file;
-typedef struct nfs_dir nfs_dir;
-
-nfs_dir *nfs_opendir(nfs_filesystem *nfs, const char *path);
-
-static int nfs_parse_host_export(const char *host_export,
-                                 char       *host,
-                                 size_t      host_len,
-                                 char       *export,
-                                 size_t      export_len)
-{
-    int index;
-
-    for (index = 0; index < host_len; index ++)
-    {
-        /* it's end of string, failed */
-        if (host_export[index] == 0)
-            return -1;
-
-        /* copy to host buffer */
-        if (host_export[index] != ':')
-            host[index] = host_export[index];
-        else
-            break;
-    }
-
-    /* host buffer is not enough, failed */
-    if (index == host_len)
-        return -1;
-
-    /* make NULL */
-    host_len = index;
-    host[host_len] = '\0';
-
-    host_len ++;
-
-    /* copy export path */
-    for (index = host_len; index < host_len + export_len; index ++)
-    {
-        if (host_export[index] == 0)
-        {
-            export[index - host_len] = '\0';
-
-            return 0;
-        }
-
-        export[index - host_len] = host_export[index];
-    }
-
-    return -1;
-}
-
-static void copy_handle(nfs_fh3 *dest, const nfs_fh3 *source)
-{
-    dest->data.data_len = source->data.data_len;
-    dest->data.data_val = rt_malloc(dest->data.data_len);
-    if (dest->data.data_val == NULL)
-    {
-        dest->data.data_len = 0;
-
-        return;
-    }
-
-    memcpy(dest->data.data_val, source->data.data_val, dest->data.data_len);
-}
-
-static nfs_fh3 *get_handle(nfs_filesystem *nfs, const char *name)
-{
-    nfs_fh3 *handle = NULL;
-    char *file;
-    char *path;
-    char *init;
-
-    init = path = rt_malloc(strlen(name) + 1);
-    if (init == NULL)
-        return NULL;
-
-    memcpy(init, name, strlen(name) + 1);
-
-    handle = rt_malloc(sizeof(nfs_fh3));
-    if (handle == NULL)
-    {
-        rt_free(init);
-
-        return NULL;
-    }
-
-    if (path[0] == '/')
-    {
-        path ++;
-        copy_handle(handle, &nfs->root_handle);
-    }
-    else
-    {
-        copy_handle(handle, &nfs->current_handle);
-    }
-
-    while ((file = strtok_r(NULL, "/", &path)) != NULL)
-    {
-        LOOKUP3args args;
-        LOOKUP3res res;
-        memset(&res, 0, sizeof(res));
-        copy_handle(&args.what.dir, handle);
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-        args.what.name = file;
-
-        if (nfsproc3_lookup_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-        {
-            rt_kprintf("Lookup failed\n");
-            rt_free(init);
-            rt_free(handle);
-            xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
-
-            return NULL;
-        }
-        else if (res.status != NFS3_OK)
-        {
-            rt_kprintf("Lookup failed: %d\n", res.status);
-            rt_free(init);
-            rt_free(handle);
-            xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
-            xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
-
-            return NULL;
-        }
-        copy_handle(handle, &res.LOOKUP3res_u.resok.object);
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
-        xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
-    }
-
-    rt_free(init);
-
-    return handle;
-}
-
-static nfs_fh3 *get_dir_handle(nfs_filesystem *nfs, const char *name)
-{
-    nfs_fh3 *handle = NULL;
-    char *file;
-    char *path;
-    char *init;
-
-    init = path = rt_malloc(strlen(name) + 1);
-    if (init == NULL)
-        return NULL;
-    memcpy(init, name, strlen(name) + 1);
-
-    handle = rt_malloc(sizeof(nfs_fh3));
-    if (handle == NULL)
-    {
-        rt_free(init);
-
-        return NULL;
-    }
-
-    if (path[0] == '/')
-    {
-        path ++;
-        copy_handle(handle, &nfs->root_handle);
-    }
-    else
-    {
-        copy_handle(handle, &nfs->current_handle);
-    }
-
-    while ((file = strtok_r(NULL, "/", &path)) != NULL && path && path[0] != 0)
-    {
-        LOOKUP3args args;
-        LOOKUP3res res;
-        memset(&res, 0, sizeof(res));
-        copy_handle(&args.what.dir, handle);
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-        args.what.name = file;
-
-        if (nfsproc3_lookup_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-        {
-            rt_kprintf("Lookup failed\n");
-            rt_free(init);
-            rt_free(handle);
-            xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
-
-            return NULL;
-        }
-        else if (res.status != NFS3_OK)
-        {
-            rt_kprintf("Lookup failed: %d\n", res.status);
-            rt_free(init);
-            rt_free(handle);
-            xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
-            xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
-
-            return NULL;
-        }
-        copy_handle(handle, &res.LOOKUP3res_u.resok.object);
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&args.what.dir);
-        xdr_free((xdrproc_t)xdr_LOOKUP3res, (char *)&res);
-    }
-
-    rt_free(init);
-
-    return handle;
-}
-
-static size_t nfs_get_filesize(nfs_filesystem *nfs, nfs_fh3 *handle)
-{
-    GETATTR3args args;
-    GETATTR3res res;
-    fattr3 *info;
-    size_t size;
-
-    args.object = *handle;
-
-    memset(&res, '\0', sizeof(res));
-
-    if ((nfsproc3_getattr_3(args, &res, nfs->nfs_client) != RPC_SUCCESS) ||
-        res.status != NFS3_OK)
-    {
-        rt_kprintf("GetAttr failed: %d\n", res.status);
-
-        return 0;
-    }
-
-    info = &res.GETATTR3res_u.resok.obj_attributes;
-    size = info->size;
-    xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res);
-
-    return size;
-}
-
-rt_bool_t nfs_is_directory(nfs_filesystem *nfs, const char *name)
-{
-    GETATTR3args args;
-    GETATTR3res res;
-    fattr3 *info;
-    nfs_fh3 *handle;
-    rt_bool_t result;
-
-    result = RT_FALSE;
-    handle = get_handle(nfs, name);
-    if (handle == NULL)
-        return RT_FALSE;
-
-    args.object = *handle;
-
-    memset(&res, '\0', sizeof(res));
-
-    if (nfsproc3_getattr_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-    {
-        rt_kprintf("GetAttr failed\n");
-
-        return RT_FALSE;
-    }
-    else if (res.status != NFS3_OK)
-    {
-        rt_kprintf("Getattr failed: %d\n", res.status);
-
-        return RT_FALSE;
-    }
-
-    info = &res.GETATTR3res_u.resok.obj_attributes;
-
-    if (info->type == NFS3DIR)
-        result = RT_TRUE;
-
-    xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res);
-    xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-    rt_free(handle);
-
-    return result;
-}
-
-int nfs_create(nfs_filesystem *nfs, const char *name, mode_t mode)
-{
-    CREATE3args args;
-    CREATE3res res;
-    int ret = 0;
-    nfs_fh3 *handle;
-
-    if (nfs->nfs_client == NULL)
-    {
-        return -1;
-    }
-
-    handle = get_dir_handle(nfs, name);
-    if (handle == NULL)
-    {
-        return -1;
-    }
-    args.where.dir = *handle;
-    args.where.name = strrchr(name, '/') + 1;
-    if (args.where.name == NULL)
-    {
-        args.where.name = (char *)name;
-    }
-    args.how.mode = GUARDED;
-
-    args.how.createhow3_u.obj_attributes.mode.set_it = TRUE;
-    args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = mode;
-    args.how.createhow3_u.obj_attributes.uid.set_it = FALSE;
-    args.how.createhow3_u.obj_attributes.gid.set_it = FALSE;
-    args.how.createhow3_u.obj_attributes.size.set_it = FALSE;
-    args.how.createhow3_u.obj_attributes.atime.set_it = DONT_CHANGE;
-    args.how.createhow3_u.obj_attributes.mtime.set_it = DONT_CHANGE;
-
-    memset(&res, 0, sizeof(res));
-
-    if (nfsproc3_create_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-    {
-        rt_kprintf("Create failed\n");
-        ret = -1;
-    }
-    else if (res.status != NFS3_OK)
-    {
-        rt_kprintf("Create failed: %d\n", res.status);
-        ret = -1;
-    }
-    xdr_free((xdrproc_t)xdr_CREATE3res, (char *)&res);
-    xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-    rt_free(handle);
-
-    return ret;
-}
-
-int nfs_mkdir(nfs_filesystem *nfs, const char *name, mode_t mode)
-{
-    MKDIR3args args;
-    MKDIR3res res;
-    int ret = 0;
-    nfs_fh3 *handle;
-
-    if (nfs->nfs_client == NULL)
-        return -1;
-
-    handle = get_dir_handle(nfs, name);
-    if (handle == NULL)
-        return -1;
-
-    args.where.dir = *handle;
-    args.where.name = strrchr(name, '/') + 1;
-    if (args.where.name == NULL)
-    {
-        args.where.name = (char *)name;
-    }
-
-    args.attributes.mode.set_it = TRUE;
-    args.attributes.mode.set_mode3_u.mode = mode;
-    args.attributes.uid.set_it = FALSE;
-    args.attributes.gid.set_it = FALSE;
-    args.attributes.size.set_it = FALSE;
-    args.attributes.atime.set_it = DONT_CHANGE;
-    args.attributes.mtime.set_it = DONT_CHANGE;
-
-    memset(&res, 0, sizeof(res));
-
-    if (nfsproc3_mkdir_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-    {
-        rt_kprintf("Mkdir failed\n");
-        ret = -1;
-    }
-    else if (res.status != NFS3_OK)
-    {
-        rt_kprintf("Mkdir failed: %d\n", res.status);
-        ret = -1;
-    }
-    xdr_free((xdrproc_t)xdr_MKDIR3res, (char *)&res);
-    xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-    rt_free(handle);
-
-    return ret;
-}
-
-/* mount(NULL, "/mnt", "nfs", 0, "192.168.1.1:/export") */
-int nfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
-{
-    mountres3 res;
-    nfs_filesystem *nfs;
-
-    nfs = (nfs_filesystem *)rt_malloc(sizeof(nfs_filesystem));
-    memset(nfs, 0, sizeof(nfs_filesystem));
-
-    if (nfs_parse_host_export((const char *)data, nfs->host, HOST_LENGTH,
-                              nfs->export, EXPORT_PATH_LENGTH) < 0)
-    {
-        rt_kprintf("host or export path error\n");
-        goto __return;
-    }
-
-    nfs->mount_client = clnt_create((char *)nfs->host, MOUNT_PROGRAM, MOUNT_V3, "udp");
-    if (nfs->mount_client == NULL)
-    {
-        rt_kprintf("create mount client failed\n");
-        goto __return;
-    }
-
-    memset(&res, '\0', sizeof(mountres3));
-    if (mountproc3_mnt_3((char *)nfs->export, &res, nfs->mount_client) != RPC_SUCCESS)
-    {
-        rt_kprintf("nfs mount failed\n");
-        goto __return;
-    }
-    else if (res.fhs_status != MNT3_OK)
-    {
-        rt_kprintf("nfs mount failed\n");
-        goto __return;
-    }
-    nfs->nfs_client = clnt_create((char *)nfs->host, NFS_PROGRAM, NFS_V3, "udp");
-    if (nfs->nfs_client == NULL)
-    {
-        rt_kprintf("creat nfs client failed\n");
-        goto __return;
-    }
-    copy_handle(&nfs->root_handle, (nfs_fh3 *)&res.mountres3_u.mountinfo.fhandle);
-    copy_handle(&nfs->current_handle, &nfs->root_handle);
-
-    nfs->nfs_client->cl_auth = authnone_create();
-    fs->data = nfs;
-
-    return 0;
-
-__return:
-    if (nfs != NULL)
-    {
-        if (nfs->mount_client != NULL)
-        {
-            clnt_destroy(nfs->mount_client);
-        }
-        if (nfs->nfs_client != NULL)
-        {
-            if (nfs->nfs_client->cl_auth != NULL)
-            {
-                auth_destroy(nfs->nfs_client->cl_auth);
-            }
-            clnt_destroy(nfs->nfs_client);
-        }
-        rt_free(nfs);
-    }
-
-    return -1;
-}
-
-int nfs_unmount(struct dfs_filesystem *fs)
-{
-    nfs_filesystem *nfs;
-
-    RT_ASSERT(fs != NULL);
-    RT_ASSERT(fs->data != NULL);
-    nfs = (nfs_filesystem *)fs->data;
-
-    if (nfs->mount_client != NULL &&
-        mountproc3_umnt_3((char *)nfs->export, NULL, nfs->mount_client) != RPC_SUCCESS)
-    {
-        rt_kprintf("unmount failed\n");
-
-        return -1;
-    }
-
-    /* destroy nfs client */
-    if (nfs->nfs_client != NULL)
-    {
-        if (nfs->nfs_client->cl_auth != NULL)
-        {
-            auth_destroy(nfs->nfs_client->cl_auth);
-            nfs->nfs_client->cl_auth = NULL;
-        }
-        clnt_destroy(nfs->nfs_client);
-        nfs->nfs_client = NULL;
-    }
-
-    /* destroy mount client */
-    if (nfs->mount_client != NULL)
-    {
-        if (nfs->mount_client->cl_auth != NULL)
-        {
-            auth_destroy(nfs->mount_client->cl_auth);
-            nfs->mount_client->cl_auth = NULL;
-        }
-        clnt_destroy(nfs->mount_client);
-        nfs->mount_client = NULL;
-    }
-
-    rt_free(nfs);
-    fs->data = NULL;
-
-    return 0;
-}
-
-int nfs_ioctl(struct dfs_file *file, int cmd, void *args)
-{
-    return -ENOSYS;
-}
-
-int nfs_read(struct dfs_file *file, void *buf, size_t count)
-{
-    READ3args args;
-    READ3res res;
-    ssize_t bytes, total = 0;
-    nfs_file *fd;
-    nfs_filesystem *nfs;
-
-    if (file->vnode->type == FT_DIRECTORY)
-        return -EISDIR;
-
-    RT_ASSERT(file->vnode->fs != NULL);
-    struct dfs_filesystem *dfs_nfs  = ((struct dfs_filesystem *)(file->vnode->fs));
-    nfs = (struct nfs_filesystem *)(dfs_nfs->data);
-    fd = (nfs_file *)(nfs->data);
-    RT_ASSERT(fd != NULL);
-
-    if (nfs->nfs_client == NULL)
-        return -1;
-
-    /* end of file */
-    if (fd->eof == TRUE)
-        return 0;
-
-    args.file = fd->handle;
-    do
-    {
-        args.offset = fd->offset;
-        args.count = count > DFS_NFS_MAX_MTU ? DFS_NFS_MAX_MTU : count;
-        count -= args.count;
-
-        memset(&res, 0, sizeof(res));
-        if (nfsproc3_read_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-        {
-            rt_kprintf("Read failed\n");
-            total = 0;
-            break;
-        }
-        else if (res.status != NFS3_OK)
-        {
-            rt_kprintf("Read failed: %d\n", res.status);
-            total = 0;
-            break;
-        }
-        else
-        {
-            bytes = res.READ3res_u.resok.count;
-            total += bytes;
-            fd->offset += bytes;
-            /* update current position */
-            file->pos = fd->offset;
-            memcpy(buf, res.READ3res_u.resok.data.data_val, bytes);
-            buf = (void *)((char *)buf + args.count);
-            if (res.READ3res_u.resok.eof)
-            {
-                /* something should probably be here */
-                fd->eof = TRUE;
-                break;
-            }
-        }
-        xdr_free((xdrproc_t)xdr_READ3res, (char *)&res);
-    }
-    while (count > 0);
-
-    xdr_free((xdrproc_t)xdr_READ3res, (char *)&res);
-
-    return total;
-}
-
-int nfs_write(struct dfs_file *file, const void *buf, size_t count)
-{
-    WRITE3args args;
-    WRITE3res res;
-    ssize_t bytes, total = 0;
-    nfs_file *fd;
-    nfs_filesystem *nfs;
-
-    if (file->vnode->type == FT_DIRECTORY)
-        return -EISDIR;
-
-    RT_ASSERT(file->vnode->fs != NULL);
-    struct dfs_filesystem *dfs_nfs  = ((struct dfs_filesystem *)(file->vnode->fs));
-    nfs = (struct nfs_filesystem *)(dfs_nfs->data);
-    fd = (nfs_file *)(nfs->data);
-    RT_ASSERT(fd != NULL);
-
-    if (nfs->nfs_client == NULL)
-        return -1;
-
-    args.file = fd->handle;
-    args.stable = FILE_SYNC;
-
-    do
-    {
-        args.offset = fd->offset;
-
-        memset(&res, 0, sizeof(res));
-        args.data.data_val = (void *)buf;
-        args.count = count > DFS_NFS_MAX_MTU ? DFS_NFS_MAX_MTU : count;
-        args.data.data_len = args.count;
-        count -= args.count;
-        buf = (const void *)((char *)buf + args.count);
-
-        if (nfsproc3_write_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-        {
-            rt_kprintf("Write failed\n");
-            total = 0;
-            break;
-        }
-        else if (res.status != NFS3_OK)
-        {
-            rt_kprintf("Write failed: %d\n", res.status);
-            total = 0;
-            break;
-        }
-        else
-        {
-            bytes = res.WRITE3res_u.resok.count;
-            fd->offset += bytes;
-            total += bytes;
-            /* update current position */
-            file->pos = fd->offset;
-            /* update file size */
-            if (fd->size < fd->offset) fd->size = fd->offset;
-            file->vnode->size = fd->size;
-        }
-        xdr_free((xdrproc_t)xdr_WRITE3res, (char *)&res);
-    } while (count > 0);
-
-    xdr_free((xdrproc_t)xdr_WRITE3res, (char *)&res);
-
-    return total;
-}
-
-int nfs_lseek(struct dfs_file *file, off_t offset)
-{
-    nfs_file *fd;
-    nfs_filesystem *nfs;
-
-    if (file->vnode->type == FT_DIRECTORY)
-        return -EISDIR;
-
-    RT_ASSERT(file->vnode->fs != NULL);
-    struct dfs_filesystem *dfs_nfs  = ((struct dfs_filesystem *)(file->vnode->fs));
-    nfs = (struct nfs_filesystem *)(dfs_nfs->data);
-    fd = (nfs_file *)(nfs->data);
-    RT_ASSERT(fd != NULL);
-
-    if (offset <= fd->size)
-    {
-        fd->offset = offset;
-
-        return offset;
-    }
-
-    return -EIO;
-}
-
-int nfs_close(struct dfs_file *file)
-{
-    nfs_filesystem *nfs;
-    RT_ASSERT(file->vnode->fs != NULL);
-    struct dfs_filesystem *dfs_nfs  = ((struct dfs_filesystem *)(file->vnode->fs));
-
-    RT_ASSERT(file->vnode->ref_count > 0);
-    if (file->vnode->ref_count > 1)
-    {
-        return 0;
-    }
-
-    nfs = (struct nfs_filesystem *)(dfs_nfs->data);
-
-    if (file->vnode->type == FT_DIRECTORY)
-    {
-        struct nfs_dir *dir;
-
-        dir = (struct nfs_dir *)nfs->data;
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&dir->handle);
-        xdr_free((xdrproc_t)xdr_READDIR3res, (char *)&dir->res);
-        rt_free(dir);
-    }
-    else if (file->vnode->type == FT_REGULAR)
-    {
-        struct nfs_file *fd;
-
-        fd = (struct nfs_file *)nfs->data;
-
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)&fd->handle);
-        rt_free(fd);
-    }
-
-    nfs->data = NULL;
-    return 0;
-}
-
-int nfs_open(struct dfs_file *file)
-{
-    nfs_filesystem *nfs;
-    RT_ASSERT(file->vnode->fs != NULL);
-    struct dfs_filesystem *dfs_nfs  = file->vnode->fs;
-    nfs = (struct nfs_filesystem *)(dfs_nfs->data);
-    RT_ASSERT(nfs != NULL);
-
-    RT_ASSERT(file->vnode->ref_count > 0);
-    if (file->vnode->ref_count > 1)
-    {
-        if (file->vnode->type == FT_DIRECTORY
-                && !(file->flags & O_DIRECTORY))
-        {
-            return -ENOENT;
-        }
-        file->pos = 0;
-        return 0;
-    }
-
-    if (file->flags & O_DIRECTORY)
-    {
-        nfs_dir *dir;
-
-        if (file->flags & O_CREAT)
-        {
-            if (nfs_mkdir(nfs, file->vnode->path, 0755) < 0)
-            {
-                return -EAGAIN;
-            }
-        }
-
-        /* open directory */
-        dir = nfs_opendir(nfs, file->vnode->path);
-        if (dir == NULL)
-        {
-            return -ENOENT;
-        }
-        file->vnode->type = FT_DIRECTORY;
-        nfs->data = dir;
-    }
-    else
-    {
-        nfs_file *fp;
-        nfs_fh3 *handle;
-
-        /* create file */
-        if (file->flags & O_CREAT)
-        {
-            if (nfs_create(nfs, file->vnode->path, 0664) < 0)
-            {
-                return -EAGAIN;
-            }
-        }
-
-        /* open file (get file handle ) */
-        fp = rt_malloc(sizeof(nfs_file));
-        if (fp == NULL)
-            return -ENOMEM;
-
-        handle = get_handle(nfs, file->vnode->path);
-        if (handle == NULL)
-        {
-            rt_free(fp);
-
-            return -ENOENT;
-        }
-
-        /* get size of file */
-        fp->size = nfs_get_filesize(nfs, handle);
-        fp->offset = 0;
-        fp->eof = FALSE;
-
-        copy_handle(&fp->handle, handle);
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-        rt_free(handle);
-
-        if (file->flags & O_APPEND)
-        {
-            fp->offset = fp->size;
-        }
-
-        /* set private file */
-        nfs->data = fp;
-        file->vnode->size = fp->size;
-        file->vnode->type = FT_REGULAR;
-    }
-
-    return 0;
-}
-
-int nfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
-{
-    GETATTR3args args;
-    GETATTR3res res;
-    fattr3 *info;
-    nfs_fh3 *handle;
-    nfs_filesystem *nfs;
-
-    RT_ASSERT(fs != NULL);
-    RT_ASSERT(fs->data != NULL);
-    nfs = (nfs_filesystem *)fs->data;
-
-    handle = get_handle(nfs, path);
-    if (handle == NULL)
-        return -1;
-
-    args.object = *handle;
-
-    memset(&res, '\0', sizeof(res));
-
-    if (nfsproc3_getattr_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-    {
-        rt_kprintf("GetAttr failed\n");
-        return -1;
-    }
-    else if (res.status != NFS3_OK)
-    {
-        rt_kprintf("Getattr failed: %d\n", res.status);
-        return -1;
-    }
-
-    info = &res.GETATTR3res_u.resok.obj_attributes;
-
-    st->st_dev = 0;
-
-    st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
-    if (info->type == NFS3DIR)
-    {
-        st->st_mode &= ~S_IFREG;
-        st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
-    }
-
-    st->st_size  = info->size;
-    st->st_mtime = info->mtime.seconds;
-
-    xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res);
-    xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-    rt_free(handle);
-
-    return 0;
-}
-
-nfs_dir *nfs_opendir(nfs_filesystem *nfs, const char *path)
-{
-    nfs_dir *dir;
-    nfs_fh3 *handle;
-
-    dir = rt_malloc(sizeof(nfs_dir));
-    if (dir == NULL)
-    {
-        return NULL;
-    }
-
-    handle = get_handle(nfs, path);
-    if (handle == NULL)
-    {
-        rt_free(dir);
-        return NULL;
-    }
-
-    copy_handle(&dir->handle, handle);
-    xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-    rt_free(handle);
-
-    dir->cookie = 0;
-    memset(&dir->cookieverf, '\0', sizeof(cookieverf3));
-    dir->entry = NULL;
-    dir->eof = FALSE;
-    memset(&dir->res, '\0', sizeof(dir->res));
-
-    return dir;
-}
-
-char *nfs_readdir(nfs_filesystem *nfs, nfs_dir *dir)
-{
-    static char name[NAME_MAX];
-
-    if (nfs->nfs_client == NULL || dir == NULL)
-        return NULL;
-
-    if (dir->entry == NULL)
-    {
-        READDIR3args args;
-
-        xdr_free((xdrproc_t)xdr_READDIR3res, (char *)&dir->res);
-        memset(&dir->res, '\0', sizeof(dir->res));
-
-        args.dir = dir->handle;
-        args.cookie = dir->cookie;
-        memcpy(&args.cookieverf, &dir->cookieverf, sizeof(cookieverf3));
-        args.count = 1024;
-
-        if (nfsproc3_readdir_3(args, &dir->res, nfs->nfs_client) != RPC_SUCCESS)
-        {
-            rt_kprintf("Readdir failed\n");
-
-            return NULL;
-        }
-        else if (dir->res.status != NFS3_OK)
-        {
-            rt_kprintf("Readdir failed: %d\n", dir->res.status);
-
-            return NULL;
-        }
-
-        memcpy(&dir->cookieverf, &dir->res.READDIR3res_u.resok.cookieverf, sizeof(cookieverf3));
-        dir->eof = dir->res.READDIR3res_u.resok.reply.eof;
-        dir->entry = dir->res.READDIR3res_u.resok.reply.entries;
-    }
-    if (dir->eof == TRUE && dir->entry == NULL)
-        return NULL;
-
-    dir->cookie = dir->entry->cookie;
-    strncpy(name, dir->entry->name, NAME_MAX - 1);
-    dir->entry = dir->entry->nextentry;
-    name[NAME_MAX - 1] = '\0';
-
-    return name;
-}
-
-int nfs_unlink(struct dfs_filesystem *fs, const char *path)
-{
-    int ret = 0;
-    nfs_filesystem *nfs;
-
-    RT_ASSERT(fs != NULL);
-    RT_ASSERT(fs->data != NULL);
-    nfs = (nfs_filesystem *)fs->data;
-
-    if (nfs_is_directory(nfs, path) == RT_FALSE)
-    {
-        /* remove file */
-        REMOVE3args args;
-        REMOVE3res res;
-        nfs_fh3 *handle;
-
-        handle = get_dir_handle(nfs, path);
-        if (handle == NULL)
-            return -1;
-
-        args.object.dir = *handle;
-        args.object.name = strrchr(path, '/') + 1;
-        if (args.object.name == NULL)
-        {
-            args.object.name = (char *)path;
-        }
-
-        memset(&res, 0, sizeof(res));
-
-        if (nfsproc3_remove_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-        {
-            rt_kprintf("Remove failed\n");
-            ret = -1;
-        }
-        else if (res.status != NFS3_OK)
-        {
-            rt_kprintf("Remove failed: %d\n", res.status);
-            ret = -1;
-        }
-        xdr_free((xdrproc_t)xdr_REMOVE3res, (char *)&res);
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-        rt_free(handle);
-    }
-    else
-    {
-        /* remove directory */
-        RMDIR3args args;
-        RMDIR3res res;
-        nfs_fh3 *handle;
-
-        handle = get_dir_handle(nfs, path);
-        if (handle == NULL)
-            return -1;
-
-        args.object.dir = *handle;
-        args.object.name = strrchr(path, '/') + 1;
-        if (args.object.name == NULL)
-        {
-            args.object.name = (char *)path;
-        }
-
-        memset(&res, 0, sizeof(res));
-
-        if (nfsproc3_rmdir_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-        {
-            rt_kprintf("Rmdir failed\n");
-            ret = -1;
-        }
-        else if (res.status != NFS3_OK)
-        {
-            rt_kprintf("Rmdir failed: %d\n", res.status);
-            ret = -1;
-        }
-
-        xdr_free((xdrproc_t)xdr_RMDIR3res, (char *)&res);
-        xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
-        rt_free(handle);
-    }
-
-    return ret;
-}
-
-int nfs_rename(struct dfs_filesystem *fs, const char *src, const char *dest)
-{
-    RENAME3args args;
-    RENAME3res res;
-    nfs_fh3 *sHandle;
-    nfs_fh3 *dHandle;
-    int ret = 0;
-    nfs_filesystem *nfs;
-
-    RT_ASSERT(fs != NULL);
-    RT_ASSERT(fs->data != NULL);
-    nfs = (nfs_filesystem *)fs->data;
-
-    if (nfs->nfs_client == NULL)
-        return -1;
-
-    sHandle = get_dir_handle(nfs, src);
-    if (sHandle == NULL)
-        return -1;
-
-    dHandle = get_dir_handle(nfs, dest);
-    if (dHandle == NULL)
-        return -1;
-
-    args.from.dir = *sHandle;
-    args.from.name = strrchr(src, '/') + 1;
-    if (args.from.name == NULL)
-        args.from.name = (char *)src;
-
-    args.to.dir = *dHandle;
-    args.to.name = strrchr(src, '/') + 1;
-    if (args.to.name == NULL)
-        args.to.name = (char *)dest;
-
-    memset(&res, '\0', sizeof(res));
-
-    if (nfsproc3_rename_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
-    {
-        rt_kprintf("Rename failed\n");
-        ret = -1;
-    }
-    else if (res.status != NFS3_OK)
-    {
-        rt_kprintf("Rename failed: %d\n", res.status);
-        ret = -1;
-    }
-
-    xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)sHandle);
-    xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)dHandle);
-    xdr_free((xdrproc_t)xdr_RENAME3res, (char *)&res);
-
-    return ret;
-}
-
-int nfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
-{
-    nfs_dir *dir;
-    rt_uint32_t index;
-    struct dirent *d;
-    nfs_filesystem *nfs;
-    char *name;
-
-    RT_ASSERT(file->vnode->fs != NULL);
-    struct dfs_filesystem *dfs_nfs  = ((struct dfs_filesystem *)(file->vnode->fs));
-    nfs = (struct nfs_filesystem *)(dfs_nfs->data);
-    dir = (nfs_dir *)(nfs->data);
-    RT_ASSERT(dir != NULL);
-
-    /* make integer count */
-    count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
-    if (count == 0)
-        return -EINVAL;
-
-    index = 0;
-    while (1)
-    {
-        d = dirp + index;
-
-        name = nfs_readdir(nfs, dir);
-        if (name == NULL)
-            break;
-
-        if (rt_strcmp(name, ".") == 0)
-        {
-            continue;
-        }
-        else if (rt_strcmp(name, "..") == 0)
-        {
-            continue;
-        }
-
-        d->d_type = DT_REG;
-
-        d->d_namlen = rt_strlen(name);
-        d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
-        rt_strncpy(d->d_name, name, DFS_PATH_MAX);
-
-        index ++;
-        if (index * sizeof(struct dirent) >= count)
-            break;
-    }
-
-    return index * sizeof(struct dirent);
-}
-
-static const struct dfs_file_ops nfs_fops =
-{
-    nfs_open,
-    nfs_close,
-    nfs_ioctl,
-    nfs_read,
-    nfs_write,
-    NULL, /* flush */
-    nfs_lseek,
-    nfs_getdents,
-    NULL, /* poll */
-};
-
-static const struct dfs_filesystem_ops _nfs =
-{
-    "nfs",
-    DFS_FS_FLAG_DEFAULT,
-    &nfs_fops,
-    nfs_mount,
-    nfs_unmount,
-    NULL, /* mkfs */
-    NULL, /* statfs */
-    nfs_unlink,
-    nfs_stat,
-    nfs_rename,
-};
-
-int nfs_init(void)
-{
-    /* register nfs file system */
-    dfs_register(&_nfs);
-
-    return RT_EOK;
-}
-INIT_COMPONENT_EXPORT(nfs_init);
-

+ 0 - 15
components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.h

@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-
-#ifndef __NFS_H__
-#define __NFS_H__
-
-int nfs_init(void);
-
-#endif

+ 0 - 131
components/dfs/dfs_v2/filesystems/nfs/mount.h

@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#ifndef _MOUNT_H_RPCGEN
-#define _MOUNT_H_RPCGEN
-
-#include <rpc/rpc.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This file is copied from RFC1813
- * Copyright 1995 Sun Micrososystems (I assume)
- */
-#define MNTPATHLEN 1024
-#define MNTNAMLEN 255
-#define FHSIZE3 64
-
-typedef struct {
-    unsigned int fhandle3_len;
-    char *fhandle3_val;
-} fhandle3;
-
-typedef char *dirpath;
-
-typedef char *name;
-
-typedef struct exportnode *exports;
-
-typedef struct groupnode *groups;
-
-typedef struct mountbody *mountlist;
-
-enum mountstat3 {
-    MNT3_OK = 0,
-    MNT3ERR_PERM = 1,
-    MNT3ERR_NOENT = 2,
-    MNT3ERR_IO = 5,
-    MNT3ERR_ACCES = 13,
-    MNT3ERR_NOTDIR = 20,
-    MNT3ERR_INVAL = 22,
-    MNT3ERR_NAMETOOLONG = 63,
-    MNT3ERR_NOTSUPP = 10004,
-    MNT3ERR_SERVERFAULT = 10006
-};
-typedef enum mountstat3 mountstat3;
-
-struct mountres3_ok {
-    fhandle3 fhandle;
-    struct {
-        unsigned int auth_flavors_len;
-        int *auth_flavors_val;
-    } auth_flavors;
-};
-typedef struct mountres3_ok mountres3_ok;
-
-struct mountres3 {
-    mountstat3 fhs_status;
-    union {
-        mountres3_ok mountinfo;
-    } mountres3_u;
-};
-typedef struct mountres3 mountres3;
-
-struct mountbody {
-    name ml_hostname;
-    dirpath ml_directory;
-    mountlist ml_next;
-};
-typedef struct mountbody mountbody;
-
-struct groupnode {
-    name gr_name;
-    groups gr_next;
-};
-typedef struct groupnode groupnode;
-
-struct exportnode {
-    dirpath ex_dir;
-    groups ex_groups;
-    exports ex_next;
-};
-typedef struct exportnode exportnode;
-
-#define MOUNT_PROGRAM   100005
-#define MOUNT_V3    3
-
-#define MOUNTPROC3_NULL 0
-extern  enum clnt_stat mountproc3_null_3(void *, CLIENT *);
-#define MOUNTPROC3_MNT  1
-extern  enum clnt_stat mountproc3_mnt_3(dirpath , mountres3 *, CLIENT *);
-#define MOUNTPROC3_DUMP 2
-extern  enum clnt_stat mountproc3_dump_3(mountlist *, CLIENT *);
-#define MOUNTPROC3_UMNT 3
-extern  enum clnt_stat mountproc3_umnt_3(dirpath , void *, CLIENT *);
-#define MOUNTPROC3_UMNTALL  4
-extern  enum clnt_stat mountproc3_umntall_3(void *, CLIENT *);
-#define MOUNTPROC3_EXPORT   5
-extern  enum clnt_stat mountproc3_export_3(exports *, CLIENT *);
-
-/* the xdr functions */
-
-extern  bool_t xdr_fhandle3(XDR *, fhandle3*);
-extern  bool_t xdr_dirpath(XDR *, dirpath*);
-extern  bool_t xdr_name(XDR *, name*);
-extern  bool_t xdr_exports(XDR *, exports*);
-extern  bool_t xdr_groups(XDR *, groups*);
-extern  bool_t xdr_mountlist(XDR *, mountlist*);
-extern  bool_t xdr_mountstat3(XDR *, mountstat3*);
-extern  bool_t xdr_mountres3_ok(XDR *, mountres3_ok*);
-extern  bool_t xdr_mountres3(XDR *, mountres3*);
-extern  bool_t xdr_mountbody(XDR *, mountbody*);
-extern  bool_t xdr_groupnode(XDR *, groupnode*);
-extern  bool_t xdr_exportnode(XDR *, exportnode*);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_MOUNT_H_RPCGEN */

+ 0 - 68
components/dfs/dfs_v2/filesystems/nfs/mount.x

@@ -1,68 +0,0 @@
-%/* This file is copied from RFC1813
-% * Copyright 1995 Sun Micrososystems (I assume)
-% */
-
-const MNTPATHLEN = 1024;  /* Maximum bytes in a path name */
-const MNTNAMLEN = 255;   /* Maximum bytes in a name */
-const FHSIZE3 = 64;    /* Maximum bytes in a V3 file handle */
-
-typedef opaque fhandle3<FHSIZE3>;
-typedef string dirpath<MNTPATHLEN>;
-typedef string name<MNTNAMLEN>;
-
-typedef struct exportnode *exports;
-typedef struct groupnode *groups;
-typedef struct mountbody *mountlist;
-
-enum mountstat3 {
-	MNT3_OK = 0,                 /* no error */
-	MNT3ERR_PERM = 1,            /* Not owner */
-	MNT3ERR_NOENT = 2,           /* No such file or directory */
-	MNT3ERR_IO = 5,              /* I/O error */
-	MNT3ERR_ACCES = 13,          /* Permission denied */
-	MNT3ERR_NOTDIR = 20,         /* Not a directory */
-	MNT3ERR_INVAL = 22,          /* Invalid argument */
-	MNT3ERR_NAMETOOLONG = 63,    /* Filename too long */
-	MNT3ERR_NOTSUPP = 10004,     /* Operation not supported */
-	MNT3ERR_SERVERFAULT = 10006  /* A failure on the server */
-};
-
-struct mountres3_ok {
-	fhandle3 fhandle;
-	int auth_flavors<>;
-};
-
-union mountres3 switch (mountstat3 fhs_status) {
-case MNT3_OK:
-	mountres3_ok  mountinfo;
-default:
-	void;
-};
-
-struct mountbody {
-	name ml_hostname;
-	dirpath ml_directory;
-	mountlist ml_next;
-};
-
-struct groupnode {
-	name gr_name;
-	groups gr_next;
-};
-
-struct exportnode {
-	dirpath ex_dir;
-	groups ex_groups;
- 	exports ex_next;
-};
-
-program MOUNT_PROGRAM {
-	version MOUNT_V3 {
-		void MOUNTPROC3_NULL(void) = 0;
-		mountres3 MOUNTPROC3_MNT(dirpath) = 1;
-		mountlist MOUNTPROC3_DUMP(void) = 2;
-		void MOUNTPROC3_UMNT(dirpath) = 3;
-		void MOUNTPROC3_UMNTALL(void) = 4;
-		exports MOUNTPROC3_EXPORT(void)  = 5;
-	} = 3;
-} = 100005;

+ 0 - 78
components/dfs/dfs_v2/filesystems/nfs/mount_clnt.c

@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include <string.h> /* for memset */
-#include "mount.h"
-
-/* This file is copied from RFC1813
- * Copyright 1995 Sun Micrososystems (I assume)
- */
-
-typedef char* caddr_t;
-
-/* Default timeout can be changed using clnt_control() */
-static struct timeval TIMEOUT = { 25, 0 };
-
-enum clnt_stat
-mountproc3_null_3(void *clnt_res, CLIENT *clnt)
-{
-     return (clnt_call(clnt, MOUNTPROC3_NULL,
-        (xdrproc_t) xdr_void, (caddr_t) NULL,
-        (xdrproc_t) xdr_void, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-mountproc3_mnt_3(dirpath arg1, mountres3 *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, MOUNTPROC3_MNT,
-        (xdrproc_t) xdr_dirpath, (caddr_t) &arg1,
-        (xdrproc_t) xdr_mountres3, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-mountproc3_dump_3(mountlist *clnt_res, CLIENT *clnt)
-{
-     return (clnt_call(clnt, MOUNTPROC3_DUMP,
-        (xdrproc_t) xdr_void, (caddr_t) NULL,
-        (xdrproc_t) xdr_mountlist, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-mountproc3_umnt_3(dirpath arg1, void *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, MOUNTPROC3_UMNT,
-        (xdrproc_t) xdr_dirpath, (caddr_t) &arg1,
-        (xdrproc_t) xdr_void, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-mountproc3_umntall_3(void *clnt_res, CLIENT *clnt)
-{
-     return (clnt_call(clnt, MOUNTPROC3_UMNTALL,
-        (xdrproc_t) xdr_void, (caddr_t) NULL,
-        (xdrproc_t) xdr_void, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-mountproc3_export_3(exports *clnt_res, CLIENT *clnt)
-{
-     return (clnt_call(clnt, MOUNTPROC3_EXPORT,
-        (xdrproc_t) xdr_void, (caddr_t) NULL,
-        (xdrproc_t) xdr_exports, (caddr_t) clnt_res,
-        TIMEOUT));
-}

+ 0 - 142
components/dfs/dfs_v2/filesystems/nfs/mount_xdr.c

@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include "mount.h"
-/* This file is copied from RFC1813
- * Copyright 1995 Sun Micrososystems (I assume)
- */
-
-bool_t
-xdr_fhandle3(register XDR *xdrs, fhandle3 *objp)
-{
-    if (!xdr_bytes(xdrs, (char **)&objp->fhandle3_val, (unsigned int *) &objp->fhandle3_len, FHSIZE3))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_dirpath(register XDR *xdrs, dirpath *objp)
-{
-    if (!xdr_string(xdrs, objp, MNTPATHLEN))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_name(register XDR *xdrs, name *objp)
-{
-    if (!xdr_string(xdrs, objp, MNTNAMLEN))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_exports(register XDR *xdrs, exports *objp)
-{
-    if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_groups(register XDR *xdrs, groups *objp)
-{
-    if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_mountlist(register XDR *xdrs, mountlist *objp)
-{
-    if (!xdr_pointer(xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_mountstat3(register XDR *xdrs, mountstat3 *objp)
-{
-    int enum_objp;
-
-    enum_objp = *objp;
-
-    if (!xdr_enum(xdrs, (enum_t *)&enum_objp))
-    {
-        *objp = (mountstat3)enum_objp;
-        return (FALSE);
-    }
-
-    return (TRUE);
-}
-
-bool_t
-xdr_mountres3_ok(register XDR *xdrs, mountres3_ok *objp)
-{
-    if (!xdr_fhandle3(xdrs, &objp->fhandle))
-        return (FALSE);
-    if (!xdr_array(xdrs, (char **)&objp->auth_flavors.auth_flavors_val, (unsigned int *) &objp->auth_flavors.auth_flavors_len, ~0,
-        sizeof (int), (xdrproc_t) xdr_int))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_mountres3(register XDR *xdrs, mountres3 *objp)
-{
-    if (!xdr_mountstat3(xdrs, &objp->fhs_status))
-        return (FALSE);
-    switch (objp->fhs_status) {
-    case MNT3_OK:
-        if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo))
-            return (FALSE);
-        break;
-    default :
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_mountbody(register XDR *xdrs, mountbody *objp)
-{
-    if (!xdr_name(xdrs, &objp->ml_hostname))
-        return (FALSE);
-    if (!xdr_dirpath(xdrs, &objp->ml_directory))
-        return (FALSE);
-    if (!xdr_mountlist(xdrs, &objp->ml_next))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_groupnode(register XDR *xdrs, groupnode *objp)
-{
-    if (!xdr_name(xdrs, &objp->gr_name))
-        return (FALSE);
-    if (!xdr_groups(xdrs, &objp->gr_next))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_exportnode(register XDR *xdrs, exportnode *objp)
-{
-    if (!xdr_dirpath(xdrs, &objp->ex_dir))
-        return (FALSE);
-    if (!xdr_groups(xdrs, &objp->ex_groups))
-        return (FALSE);
-    if (!xdr_exports(xdrs, &objp->ex_next))
-        return (FALSE);
-    return (TRUE);
-}

+ 0 - 1110
components/dfs/dfs_v2/filesystems/nfs/nfs.h

@@ -1,1110 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#ifndef _NFS_H_RPCGEN
-#define _NFS_H_RPCGEN
-
-#include <rpc/rpc.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This file is copied from RFC1813
- * Copyright 1995 Sun Micrososystems (I assume)
- */
-#define NFS3_FHSIZE 64
-#define NFS3_COOKIEVERFSIZE 8
-#define NFS3_CREATEVERFSIZE 8
-#define NFS3_WRITEVERFSIZE 8
-#define ACCESS3_READ 0x0001
-#define ACCESS3_LOOKUP 0x0002
-#define ACCESS3_MODIFY 0x0004
-#define ACCESS3_EXTEND 0x0008
-#define ACCESS3_DELETE 0x0010
-#define ACCESS3_EXECUTE 0x0020
-#define FSF3_LINK 0x0001
-#define FSF3_SYMLINK 0x0002
-#define FSF3_HOMOGENEOUS 0x0008
-#define FSF3_CANSETTIME 0x0010
-
-typedef unsigned long long uint64;
-
-typedef long long int64;
-
-typedef u_long uint32;
-
-typedef long int32;
-
-typedef char *filename3;
-
-typedef char *nfspath3;
-
-typedef uint64 fileid3;
-
-typedef uint64 cookie3;
-
-typedef char cookieverf3[NFS3_COOKIEVERFSIZE];
-
-typedef char createverf3[NFS3_CREATEVERFSIZE];
-
-typedef char writeverf3[NFS3_WRITEVERFSIZE];
-
-typedef uint32 uid3;
-
-typedef uint32 gid3;
-
-typedef uint64 size3;
-
-typedef uint64 offset3;
-
-typedef uint32 mode3;
-
-typedef uint32 count3;
-
-enum nfsstat3 {
-    NFS3_OK = 0,
-    NFS3ERR_PERM = 1,
-    NFS3ERR_NOENT = 2,
-    NFS3ERR_IO = 5,
-    NFS3ERR_NXIO = 6,
-    NFS3ERR_ACCES = 13,
-    NFS3ERR_EXIST = 17,
-    NFS3ERR_XDEV = 18,
-    NFS3ERR_NODEV = 19,
-    NFS3ERR_NOTDIR = 20,
-    NFS3ERR_ISDIR = 21,
-    NFS3ERR_INVAL = 22,
-    NFS3ERR_FBIG = 27,
-    NFS3ERR_NOSPC = 28,
-    NFS3ERR_ROFS = 30,
-    NFS3ERR_MLINK = 31,
-    NFS3ERR_NAMETOOLONG = 63,
-    NFS3ERR_NOTEMPTY = 66,
-    NFS3ERR_DQUOT = 69,
-    NFS3ERR_STALE = 70,
-    NFS3ERR_REMOTE = 71,
-    NFS3ERR_BADHANDLE = 10001,
-    NFS3ERR_NOT_SYNC = 10002,
-    NFS3ERR_BAD_COOKIE = 10003,
-    NFS3ERR_NOTSUPP = 10004,
-    NFS3ERR_TOOSMALL = 10005,
-    NFS3ERR_SERVERFAULT = 10006,
-    NFS3ERR_BADTYPE = 10007,
-    NFS3ERR_JUKEBOX = 10008
-};
-typedef enum nfsstat3 nfsstat3;
-
-enum ftype3 {
-    NFS3REG = 1,
-    NFS3DIR = 2,
-    NFS3BLK = 3,
-    NFS3CHR = 4,
-    NFS3LNK = 5,
-    NFS3SOCK = 6,
-    NFS3FIFO = 7
-};
-typedef enum ftype3 ftype3;
-
-enum stable_how {
-    UNSTABLE = 0,
-    DATA_SYNC = 1,
-    FILE_SYNC = 2
-};
-typedef enum stable_how stable_how;
-
-enum createmode3 {
-    UNCHECKED = 0,
-    GUARDED = 1,
-    EXCLUSIVE = 2
-};
-typedef enum createmode3 createmode3;
-
-struct specdata3 {
-    uint32 specdata1;
-    uint32 specdata2;
-};
-typedef struct specdata3 specdata3;
-
-struct nfs_fh3 {
-    struct {
-        unsigned int data_len;
-        char *data_val;
-    } data;
-};
-typedef struct nfs_fh3 nfs_fh3;
-
-struct nfstime3 {
-    uint32 seconds;
-    uint32 nseconds;
-};
-typedef struct nfstime3 nfstime3;
-
-struct fattr3 {
-    ftype3 type;
-    mode3 mode;
-    uint32 nlink;
-    uid3 uid;
-    gid3 gid;
-    size3 size;
-    size3 used;
-    specdata3 rdev;
-    uint64 fsid;
-    fileid3 fileid;
-    nfstime3 atime;
-    nfstime3 mtime;
-    nfstime3 ctime;
-};
-typedef struct fattr3 fattr3;
-
-struct post_op_attr {
-    bool_t attributes_follow;
-    union {
-        fattr3 attributes;
-    } post_op_attr_u;
-};
-typedef struct post_op_attr post_op_attr;
-
-struct wcc_attr {
-    size3 size;
-    nfstime3 mtime;
-    nfstime3 ctime;
-};
-typedef struct wcc_attr wcc_attr;
-
-struct pre_op_attr {
-    bool_t attributes_follow;
-    union {
-        wcc_attr attributes;
-    } pre_op_attr_u;
-};
-typedef struct pre_op_attr pre_op_attr;
-
-struct wcc_data {
-    pre_op_attr before;
-    post_op_attr after;
-};
-typedef struct wcc_data wcc_data;
-
-struct post_op_fh3 {
-    bool_t handle_follows;
-    union {
-        nfs_fh3 handle;
-    } post_op_fh3_u;
-};
-typedef struct post_op_fh3 post_op_fh3;
-
-enum time_how {
-    DONT_CHANGE = 0,
-    SET_TO_SERVER_TIME = 1,
-    SET_TO_CLIENT_TIME = 2
-};
-typedef enum time_how time_how;
-
-struct set_mode3 {
-    bool_t set_it;
-    union {
-        mode3 mode;
-    } set_mode3_u;
-};
-typedef struct set_mode3 set_mode3;
-
-struct set_uid3 {
-    bool_t set_it;
-    union {
-        uid3 uid;
-    } set_uid3_u;
-};
-typedef struct set_uid3 set_uid3;
-
-struct set_gid3 {
-    bool_t set_it;
-    union {
-        gid3 gid;
-    } set_gid3_u;
-};
-typedef struct set_gid3 set_gid3;
-
-struct set_size3 {
-    bool_t set_it;
-    union {
-        size3 size;
-    } set_size3_u;
-};
-typedef struct set_size3 set_size3;
-
-struct set_atime {
-    time_how set_it;
-    union {
-        nfstime3 atime;
-    } set_atime_u;
-};
-typedef struct set_atime set_atime;
-
-struct set_mtime {
-    time_how set_it;
-    union {
-        nfstime3 mtime;
-    } set_mtime_u;
-};
-typedef struct set_mtime set_mtime;
-
-struct sattr3 {
-    set_mode3 mode;
-    set_uid3 uid;
-    set_gid3 gid;
-    set_size3 size;
-    set_atime atime;
-    set_mtime mtime;
-};
-typedef struct sattr3 sattr3;
-
-struct diropargs3 {
-    nfs_fh3 dir;
-    filename3 name;
-};
-typedef struct diropargs3 diropargs3;
-
-struct GETATTR3args {
-    nfs_fh3 object;
-};
-typedef struct GETATTR3args GETATTR3args;
-
-struct GETATTR3resok {
-    fattr3 obj_attributes;
-};
-typedef struct GETATTR3resok GETATTR3resok;
-
-struct GETATTR3res {
-    nfsstat3 status;
-    union {
-        GETATTR3resok resok;
-    } GETATTR3res_u;
-};
-typedef struct GETATTR3res GETATTR3res;
-
-struct sattrguard3 {
-    bool_t check;
-    union {
-        nfstime3 obj_ctime;
-    } sattrguard3_u;
-};
-typedef struct sattrguard3 sattrguard3;
-
-struct SETATTR3args {
-    nfs_fh3 object;
-    sattr3 new_attributes;
-    sattrguard3 guard;
-};
-typedef struct SETATTR3args SETATTR3args;
-
-struct SETATTR3resok {
-    wcc_data obj_wcc;
-};
-typedef struct SETATTR3resok SETATTR3resok;
-
-struct SETATTR3resfail {
-    wcc_data obj_wcc;
-};
-typedef struct SETATTR3resfail SETATTR3resfail;
-
-struct SETATTR3res {
-    nfsstat3 status;
-    union {
-        SETATTR3resok resok;
-        SETATTR3resfail resfail;
-    } SETATTR3res_u;
-};
-typedef struct SETATTR3res SETATTR3res;
-
-struct LOOKUP3args {
-    diropargs3 what;
-};
-typedef struct LOOKUP3args LOOKUP3args;
-
-struct LOOKUP3resok {
-    nfs_fh3 object;
-    post_op_attr obj_attributes;
-    post_op_attr dir_attributes;
-};
-typedef struct LOOKUP3resok LOOKUP3resok;
-
-struct LOOKUP3resfail {
-    post_op_attr dir_attributes;
-};
-typedef struct LOOKUP3resfail LOOKUP3resfail;
-
-struct LOOKUP3res {
-    nfsstat3 status;
-    union {
-        LOOKUP3resok resok;
-        LOOKUP3resfail resfail;
-    } LOOKUP3res_u;
-};
-typedef struct LOOKUP3res LOOKUP3res;
-
-struct ACCESS3args {
-    nfs_fh3 object;
-    uint32 access;
-};
-typedef struct ACCESS3args ACCESS3args;
-
-struct ACCESS3resok {
-    post_op_attr obj_attributes;
-    uint32 access;
-};
-typedef struct ACCESS3resok ACCESS3resok;
-
-struct ACCESS3resfail {
-    post_op_attr obj_attributes;
-};
-typedef struct ACCESS3resfail ACCESS3resfail;
-
-struct ACCESS3res {
-    nfsstat3 status;
-    union {
-        ACCESS3resok resok;
-        ACCESS3resfail resfail;
-    } ACCESS3res_u;
-};
-typedef struct ACCESS3res ACCESS3res;
-
-struct READLINK3args {
-    nfs_fh3 symlink;
-};
-typedef struct READLINK3args READLINK3args;
-
-struct READLINK3resok {
-    post_op_attr symlink_attributes;
-    nfspath3 data;
-};
-typedef struct READLINK3resok READLINK3resok;
-
-struct READLINK3resfail {
-    post_op_attr symlink_attributes;
-};
-typedef struct READLINK3resfail READLINK3resfail;
-
-struct READLINK3res {
-    nfsstat3 status;
-    union {
-        READLINK3resok resok;
-        READLINK3resfail resfail;
-    } READLINK3res_u;
-};
-typedef struct READLINK3res READLINK3res;
-
-struct READ3args {
-    nfs_fh3 file;
-    offset3 offset;
-    count3 count;
-};
-typedef struct READ3args READ3args;
-
-struct READ3resok {
-    post_op_attr file_attributes;
-    count3 count;
-    bool_t eof;
-    struct {
-        unsigned int data_len;
-        char *data_val;
-    } data;
-};
-typedef struct READ3resok READ3resok;
-
-struct READ3resfail {
-    post_op_attr file_attributes;
-};
-typedef struct READ3resfail READ3resfail;
-
-struct READ3res {
-    nfsstat3 status;
-    union {
-        READ3resok resok;
-        READ3resfail resfail;
-    } READ3res_u;
-};
-typedef struct READ3res READ3res;
-
-struct WRITE3args {
-    nfs_fh3 file;
-    offset3 offset;
-    count3 count;
-    stable_how stable;
-    struct {
-        unsigned int data_len;
-        char *data_val;
-    } data;
-};
-typedef struct WRITE3args WRITE3args;
-
-struct WRITE3resok {
-    wcc_data file_wcc;
-    count3 count;
-    stable_how committed;
-    writeverf3 verf;
-};
-typedef struct WRITE3resok WRITE3resok;
-
-struct WRITE3resfail {
-    wcc_data file_wcc;
-};
-typedef struct WRITE3resfail WRITE3resfail;
-
-struct WRITE3res {
-    nfsstat3 status;
-    union {
-        WRITE3resok resok;
-        WRITE3resfail resfail;
-    } WRITE3res_u;
-};
-typedef struct WRITE3res WRITE3res;
-
-struct createhow3 {
-    createmode3 mode;
-    union {
-        sattr3 obj_attributes;
-        createverf3 verf;
-    } createhow3_u;
-};
-typedef struct createhow3 createhow3;
-
-struct CREATE3args {
-    diropargs3 where;
-    createhow3 how;
-};
-typedef struct CREATE3args CREATE3args;
-
-struct CREATE3resok {
-    post_op_fh3 obj;
-    post_op_attr obj_attributes;
-    wcc_data dir_wcc;
-};
-typedef struct CREATE3resok CREATE3resok;
-
-struct CREATE3resfail {
-    wcc_data dir_wcc;
-};
-typedef struct CREATE3resfail CREATE3resfail;
-
-struct CREATE3res {
-    nfsstat3 status;
-    union {
-        CREATE3resok resok;
-        CREATE3resfail resfail;
-    } CREATE3res_u;
-};
-typedef struct CREATE3res CREATE3res;
-
-struct MKDIR3args {
-    diropargs3 where;
-    sattr3 attributes;
-};
-typedef struct MKDIR3args MKDIR3args;
-
-struct MKDIR3resok {
-    post_op_fh3 obj;
-    post_op_attr obj_attributes;
-    wcc_data dir_wcc;
-};
-typedef struct MKDIR3resok MKDIR3resok;
-
-struct MKDIR3resfail {
-    wcc_data dir_wcc;
-};
-typedef struct MKDIR3resfail MKDIR3resfail;
-
-struct MKDIR3res {
-    nfsstat3 status;
-    union {
-        MKDIR3resok resok;
-        MKDIR3resfail resfail;
-    } MKDIR3res_u;
-};
-typedef struct MKDIR3res MKDIR3res;
-
-struct symlinkdata3 {
-    sattr3 symlink_attributes;
-    nfspath3 symlink_data;
-};
-typedef struct symlinkdata3 symlinkdata3;
-
-struct SYMLINK3args {
-    diropargs3 where;
-    symlinkdata3 symlink;
-};
-typedef struct SYMLINK3args SYMLINK3args;
-
-struct SYMLINK3resok {
-    post_op_fh3 obj;
-    post_op_attr obj_attributes;
-    wcc_data dir_wcc;
-};
-typedef struct SYMLINK3resok SYMLINK3resok;
-
-struct SYMLINK3resfail {
-    wcc_data dir_wcc;
-};
-typedef struct SYMLINK3resfail SYMLINK3resfail;
-
-struct SYMLINK3res {
-    nfsstat3 status;
-    union {
-        SYMLINK3resok resok;
-        SYMLINK3resfail resfail;
-    } SYMLINK3res_u;
-};
-typedef struct SYMLINK3res SYMLINK3res;
-
-struct devicedata3 {
-    sattr3 dev_attributes;
-    specdata3 spec;
-};
-typedef struct devicedata3 devicedata3;
-
-struct mknoddata3 {
-    ftype3 type;
-    union {
-        devicedata3 device;
-        sattr3 pipe_attributes;
-    } mknoddata3_u;
-};
-typedef struct mknoddata3 mknoddata3;
-
-struct MKNOD3args {
-    diropargs3 where;
-    mknoddata3 what;
-};
-typedef struct MKNOD3args MKNOD3args;
-
-struct MKNOD3resok {
-    post_op_fh3 obj;
-    post_op_attr obj_attributes;
-    wcc_data dir_wcc;
-};
-typedef struct MKNOD3resok MKNOD3resok;
-
-struct MKNOD3resfail {
-    wcc_data dir_wcc;
-};
-typedef struct MKNOD3resfail MKNOD3resfail;
-
-struct MKNOD3res {
-    nfsstat3 status;
-    union {
-        MKNOD3resok resok;
-        MKNOD3resfail resfail;
-    } MKNOD3res_u;
-};
-typedef struct MKNOD3res MKNOD3res;
-
-struct REMOVE3args {
-    diropargs3 object;
-};
-typedef struct REMOVE3args REMOVE3args;
-
-struct REMOVE3resok {
-    wcc_data dir_wcc;
-};
-typedef struct REMOVE3resok REMOVE3resok;
-
-struct REMOVE3resfail {
-    wcc_data dir_wcc;
-};
-typedef struct REMOVE3resfail REMOVE3resfail;
-
-struct REMOVE3res {
-    nfsstat3 status;
-    union {
-        REMOVE3resok resok;
-        REMOVE3resfail resfail;
-    } REMOVE3res_u;
-};
-typedef struct REMOVE3res REMOVE3res;
-
-struct RMDIR3args {
-    diropargs3 object;
-};
-typedef struct RMDIR3args RMDIR3args;
-
-struct RMDIR3resok {
-    wcc_data dir_wcc;
-};
-typedef struct RMDIR3resok RMDIR3resok;
-
-struct RMDIR3resfail {
-    wcc_data dir_wcc;
-};
-typedef struct RMDIR3resfail RMDIR3resfail;
-
-struct RMDIR3res {
-    nfsstat3 status;
-    union {
-        RMDIR3resok resok;
-        RMDIR3resfail resfail;
-    } RMDIR3res_u;
-};
-typedef struct RMDIR3res RMDIR3res;
-
-struct RENAME3args {
-    diropargs3 from;
-    diropargs3 to;
-};
-typedef struct RENAME3args RENAME3args;
-
-struct RENAME3resok {
-    wcc_data fromdir_wcc;
-    wcc_data todir_wcc;
-};
-typedef struct RENAME3resok RENAME3resok;
-
-struct RENAME3resfail {
-    wcc_data fromdir_wcc;
-    wcc_data todir_wcc;
-};
-typedef struct RENAME3resfail RENAME3resfail;
-
-struct RENAME3res {
-    nfsstat3 status;
-    union {
-        RENAME3resok resok;
-        RENAME3resfail resfail;
-    } RENAME3res_u;
-};
-typedef struct RENAME3res RENAME3res;
-
-struct LINK3args {
-    nfs_fh3 file;
-    diropargs3 link;
-};
-typedef struct LINK3args LINK3args;
-
-struct LINK3resok {
-    post_op_attr file_attributes;
-    wcc_data linkdir_wcc;
-};
-typedef struct LINK3resok LINK3resok;
-
-struct LINK3resfail {
-    post_op_attr file_attributes;
-    wcc_data linkdir_wcc;
-};
-typedef struct LINK3resfail LINK3resfail;
-
-struct LINK3res {
-    nfsstat3 status;
-    union {
-        LINK3resok resok;
-        LINK3resfail resfail;
-    } LINK3res_u;
-};
-typedef struct LINK3res LINK3res;
-
-struct READDIR3args {
-    nfs_fh3 dir;
-    cookie3 cookie;
-    cookieverf3 cookieverf;
-    count3 count;
-};
-typedef struct READDIR3args READDIR3args;
-
-struct entry3 {
-    fileid3 fileid;
-    filename3 name;
-    cookie3 cookie;
-    struct entry3 *nextentry;
-};
-typedef struct entry3 entry3;
-
-struct dirlist3 {
-    entry3 *entries;
-    bool_t eof;
-};
-typedef struct dirlist3 dirlist3;
-
-struct READDIR3resok {
-    post_op_attr dir_attributes;
-    cookieverf3 cookieverf;
-    dirlist3 reply;
-};
-typedef struct READDIR3resok READDIR3resok;
-
-struct READDIR3resfail {
-    post_op_attr dir_attributes;
-};
-typedef struct READDIR3resfail READDIR3resfail;
-
-struct READDIR3res {
-    nfsstat3 status;
-    union {
-        READDIR3resok resok;
-        READDIR3resfail resfail;
-    } READDIR3res_u;
-};
-typedef struct READDIR3res READDIR3res;
-
-struct READDIRPLUS3args {
-    nfs_fh3 dir;
-    cookie3 cookie;
-    cookieverf3 cookieverf;
-    count3 dircount;
-    count3 maxcount;
-};
-typedef struct READDIRPLUS3args READDIRPLUS3args;
-
-struct entryplus3 {
-    fileid3 fileid;
-    filename3 name;
-    cookie3 cookie;
-    post_op_attr name_attributes;
-    post_op_fh3 name_handle;
-    struct entryplus3 *nextentry;
-};
-typedef struct entryplus3 entryplus3;
-
-struct dirlistplus3 {
-    entryplus3 *entries;
-    bool_t eof;
-};
-typedef struct dirlistplus3 dirlistplus3;
-
-struct READDIRPLUS3resok {
-    post_op_attr dir_attributes;
-    cookieverf3 cookieverf;
-    dirlistplus3 reply;
-};
-typedef struct READDIRPLUS3resok READDIRPLUS3resok;
-
-struct READDIRPLUS3resfail {
-    post_op_attr dir_attributes;
-};
-typedef struct READDIRPLUS3resfail READDIRPLUS3resfail;
-
-struct READDIRPLUS3res {
-    nfsstat3 status;
-    union {
-        READDIRPLUS3resok resok;
-        READDIRPLUS3resfail resfail;
-    } READDIRPLUS3res_u;
-};
-typedef struct READDIRPLUS3res READDIRPLUS3res;
-
-struct FSSTAT3args {
-    nfs_fh3 fsroot;
-};
-typedef struct FSSTAT3args FSSTAT3args;
-
-struct FSSTAT3resok {
-    post_op_attr obj_attributes;
-    size3 tbytes;
-    size3 fbytes;
-    size3 abytes;
-    size3 tfiles;
-    size3 ffiles;
-    size3 afiles;
-    uint32 invarsec;
-};
-typedef struct FSSTAT3resok FSSTAT3resok;
-
-struct FSSTAT3resfail {
-    post_op_attr obj_attributes;
-};
-typedef struct FSSTAT3resfail FSSTAT3resfail;
-
-struct FSSTAT3res {
-    nfsstat3 status;
-    union {
-        FSSTAT3resok resok;
-        FSSTAT3resfail resfail;
-    } FSSTAT3res_u;
-};
-typedef struct FSSTAT3res FSSTAT3res;
-
-struct FSINFO3args {
-    nfs_fh3 fsroot;
-};
-typedef struct FSINFO3args FSINFO3args;
-
-struct FSINFO3resok {
-    post_op_attr obj_attributes;
-    uint32 rtmax;
-    uint32 rtpref;
-    uint32 rtmult;
-    uint32 wtmax;
-    uint32 wtpref;
-    uint32 wtmult;
-    uint32 dtpref;
-    size3 maxfilesize;
-    nfstime3 time_delta;
-    uint32 properties;
-};
-typedef struct FSINFO3resok FSINFO3resok;
-
-struct FSINFO3resfail {
-    post_op_attr obj_attributes;
-};
-typedef struct FSINFO3resfail FSINFO3resfail;
-
-struct FSINFO3res {
-    nfsstat3 status;
-    union {
-        FSINFO3resok resok;
-        FSINFO3resfail resfail;
-    } FSINFO3res_u;
-};
-typedef struct FSINFO3res FSINFO3res;
-
-struct PATHCONF3args {
-    nfs_fh3 object;
-};
-typedef struct PATHCONF3args PATHCONF3args;
-
-struct PATHCONF3resok {
-    post_op_attr obj_attributes;
-    uint32 linkmax;
-    uint32 name_max;
-    bool_t no_trunc;
-    bool_t chown_restricted;
-    bool_t case_insensitive;
-    bool_t case_preserving;
-};
-typedef struct PATHCONF3resok PATHCONF3resok;
-
-struct PATHCONF3resfail {
-    post_op_attr obj_attributes;
-};
-typedef struct PATHCONF3resfail PATHCONF3resfail;
-
-struct PATHCONF3res {
-    nfsstat3 status;
-    union {
-        PATHCONF3resok resok;
-        PATHCONF3resfail resfail;
-    } PATHCONF3res_u;
-};
-typedef struct PATHCONF3res PATHCONF3res;
-
-struct COMMIT3args {
-    nfs_fh3 file;
-    offset3 offset;
-    count3 count;
-};
-typedef struct COMMIT3args COMMIT3args;
-
-struct COMMIT3resok {
-    wcc_data file_wcc;
-    writeverf3 verf;
-};
-typedef struct COMMIT3resok COMMIT3resok;
-
-struct COMMIT3resfail {
-    wcc_data file_wcc;
-};
-typedef struct COMMIT3resfail COMMIT3resfail;
-
-struct COMMIT3res {
-    nfsstat3 status;
-    union {
-        COMMIT3resok resok;
-        COMMIT3resfail resfail;
-    } COMMIT3res_u;
-};
-typedef struct COMMIT3res COMMIT3res;
-
-#define NFS_PROGRAM 100003
-#define NFS_V3  3
-
-#define NFSPROC3_NULL   0
-extern  enum clnt_stat nfsproc3_null_3(void *, CLIENT *);
-#define NFSPROC3_GETATTR    1
-extern  enum clnt_stat nfsproc3_getattr_3(GETATTR3args , GETATTR3res *, CLIENT *);
-#define NFSPROC3_SETATTR    2
-extern  enum clnt_stat nfsproc3_setattr_3(SETATTR3args , SETATTR3res *, CLIENT *);
-#define NFSPROC3_LOOKUP 3
-extern  enum clnt_stat nfsproc3_lookup_3(LOOKUP3args , LOOKUP3res *, CLIENT *);
-#define NFSPROC3_ACCESS 4
-extern  enum clnt_stat nfsproc3_access_3(ACCESS3args , ACCESS3res *, CLIENT *);
-#define NFSPROC3_READLINK   5
-extern  enum clnt_stat nfsproc3_readlink_3(READLINK3args , READLINK3res *, CLIENT *);
-#define NFSPROC3_READ   6
-extern  enum clnt_stat nfsproc3_read_3(READ3args , READ3res *, CLIENT *);
-#define NFSPROC3_WRITE  7
-extern  enum clnt_stat nfsproc3_write_3(WRITE3args , WRITE3res *, CLIENT *);
-#define NFSPROC3_CREATE 8
-extern  enum clnt_stat nfsproc3_create_3(CREATE3args , CREATE3res *, CLIENT *);
-#define NFSPROC3_MKDIR  9
-extern  enum clnt_stat nfsproc3_mkdir_3(MKDIR3args , MKDIR3res *, CLIENT *);
-#define NFSPROC3_SYMLINK    10
-extern  enum clnt_stat nfsproc3_symlink_3(SYMLINK3args , SYMLINK3res *, CLIENT *);
-#define NFSPROC3_MKNOD  11
-extern  enum clnt_stat nfsproc3_mknod_3(MKNOD3args , MKNOD3res *, CLIENT *);
-#define NFSPROC3_REMOVE 12
-extern  enum clnt_stat nfsproc3_remove_3(REMOVE3args , REMOVE3res *, CLIENT *);
-#define NFSPROC3_RMDIR  13
-extern  enum clnt_stat nfsproc3_rmdir_3(RMDIR3args , RMDIR3res *, CLIENT *);
-#define NFSPROC3_RENAME 14
-extern  enum clnt_stat nfsproc3_rename_3(RENAME3args , RENAME3res *, CLIENT *);
-#define NFSPROC3_LINK   15
-extern  enum clnt_stat nfsproc3_link_3(LINK3args , LINK3res *, CLIENT *);
-#define NFSPROC3_READDIR    16
-extern  enum clnt_stat nfsproc3_readdir_3(READDIR3args , READDIR3res *, CLIENT *);
-#define NFSPROC3_READDIRPLUS    17
-extern  enum clnt_stat nfsproc3_readdirplus_3(READDIRPLUS3args , READDIRPLUS3res *, CLIENT *);
-#define NFSPROC3_FSSTAT 18
-extern  enum clnt_stat nfsproc3_fsstat_3(FSSTAT3args , FSSTAT3res *, CLIENT *);
-#define NFSPROC3_FSINFO 19
-extern  enum clnt_stat nfsproc3_fsinfo_3(FSINFO3args , FSINFO3res *, CLIENT *);
-#define NFSPROC3_PATHCONF   20
-extern  enum clnt_stat nfsproc3_pathconf_3(PATHCONF3args , PATHCONF3res *, CLIENT *);
-#define NFSPROC3_COMMIT 21
-extern  enum clnt_stat nfsproc3_commit_3(COMMIT3args , COMMIT3res *, CLIENT *);
-
-/* the xdr functions */
-
-extern  bool_t xdr_uint64(XDR *, uint64*);
-extern  bool_t xdr_int64(XDR *, int64*);
-extern  bool_t xdr_uint32(XDR *, uint32*);
-extern  bool_t xdr_int32(XDR *, int32*);
-extern  bool_t xdr_filename3(XDR *, filename3*);
-extern  bool_t xdr_nfspath3(XDR *, nfspath3*);
-extern  bool_t xdr_fileid3(XDR *, fileid3*);
-extern  bool_t xdr_cookie3(XDR *, cookie3*);
-extern  bool_t xdr_cookieverf3(XDR *, cookieverf3);
-extern  bool_t xdr_createverf3(XDR *, createverf3);
-extern  bool_t xdr_writeverf3(XDR *, writeverf3);
-extern  bool_t xdr_uid3(XDR *, uid3*);
-extern  bool_t xdr_gid3(XDR *, gid3*);
-extern  bool_t xdr_size3(XDR *, size3*);
-extern  bool_t xdr_offset3(XDR *, offset3*);
-extern  bool_t xdr_mode3(XDR *, mode3*);
-extern  bool_t xdr_count3(XDR *, count3*);
-extern  bool_t xdr_nfsstat3(XDR *, nfsstat3*);
-extern  bool_t xdr_ftype3(XDR *, ftype3*);
-extern  bool_t xdr_stable_how(XDR *, stable_how*);
-extern  bool_t xdr_createmode3(XDR *, createmode3*);
-extern  bool_t xdr_specdata3(XDR *, specdata3*);
-extern  bool_t xdr_nfs_fh3(XDR *, nfs_fh3*);
-extern  bool_t xdr_nfstime3(XDR *, nfstime3*);
-extern  bool_t xdr_fattr3(XDR *, fattr3*);
-extern  bool_t xdr_post_op_attr(XDR *, post_op_attr*);
-extern  bool_t xdr_wcc_attr(XDR *, wcc_attr*);
-extern  bool_t xdr_pre_op_attr(XDR *, pre_op_attr*);
-extern  bool_t xdr_wcc_data(XDR *, wcc_data*);
-extern  bool_t xdr_post_op_fh3(XDR *, post_op_fh3*);
-extern  bool_t xdr_time_how(XDR *, time_how*);
-extern  bool_t xdr_set_mode3(XDR *, set_mode3*);
-extern  bool_t xdr_set_uid3(XDR *, set_uid3*);
-extern  bool_t xdr_set_gid3(XDR *, set_gid3*);
-extern  bool_t xdr_set_size3(XDR *, set_size3*);
-extern  bool_t xdr_set_atime(XDR *, set_atime*);
-extern  bool_t xdr_set_mtime(XDR *, set_mtime*);
-extern  bool_t xdr_sattr3(XDR *, sattr3*);
-extern  bool_t xdr_diropargs3(XDR *, diropargs3*);
-extern  bool_t xdr_GETATTR3args(XDR *, GETATTR3args*);
-extern  bool_t xdr_GETATTR3resok(XDR *, GETATTR3resok*);
-extern  bool_t xdr_GETATTR3res(XDR *, GETATTR3res*);
-extern  bool_t xdr_sattrguard3(XDR *, sattrguard3*);
-extern  bool_t xdr_SETATTR3args(XDR *, SETATTR3args*);
-extern  bool_t xdr_SETATTR3resok(XDR *, SETATTR3resok*);
-extern  bool_t xdr_SETATTR3resfail(XDR *, SETATTR3resfail*);
-extern  bool_t xdr_SETATTR3res(XDR *, SETATTR3res*);
-extern  bool_t xdr_LOOKUP3args(XDR *, LOOKUP3args*);
-extern  bool_t xdr_LOOKUP3resok(XDR *, LOOKUP3resok*);
-extern  bool_t xdr_LOOKUP3resfail(XDR *, LOOKUP3resfail*);
-extern  bool_t xdr_LOOKUP3res(XDR *, LOOKUP3res*);
-extern  bool_t xdr_ACCESS3args(XDR *, ACCESS3args*);
-extern  bool_t xdr_ACCESS3resok(XDR *, ACCESS3resok*);
-extern  bool_t xdr_ACCESS3resfail(XDR *, ACCESS3resfail*);
-extern  bool_t xdr_ACCESS3res(XDR *, ACCESS3res*);
-extern  bool_t xdr_READLINK3args(XDR *, READLINK3args*);
-extern  bool_t xdr_READLINK3resok(XDR *, READLINK3resok*);
-extern  bool_t xdr_READLINK3resfail(XDR *, READLINK3resfail*);
-extern  bool_t xdr_READLINK3res(XDR *, READLINK3res*);
-extern  bool_t xdr_READ3args(XDR *, READ3args*);
-extern  bool_t xdr_READ3resok(XDR *, READ3resok*);
-extern  bool_t xdr_READ3resfail(XDR *, READ3resfail*);
-extern  bool_t xdr_READ3res(XDR *, READ3res*);
-extern  bool_t xdr_WRITE3args(XDR *, WRITE3args*);
-extern  bool_t xdr_WRITE3resok(XDR *, WRITE3resok*);
-extern  bool_t xdr_WRITE3resfail(XDR *, WRITE3resfail*);
-extern  bool_t xdr_WRITE3res(XDR *, WRITE3res*);
-extern  bool_t xdr_createhow3(XDR *, createhow3*);
-extern  bool_t xdr_CREATE3args(XDR *, CREATE3args*);
-extern  bool_t xdr_CREATE3resok(XDR *, CREATE3resok*);
-extern  bool_t xdr_CREATE3resfail(XDR *, CREATE3resfail*);
-extern  bool_t xdr_CREATE3res(XDR *, CREATE3res*);
-extern  bool_t xdr_MKDIR3args(XDR *, MKDIR3args*);
-extern  bool_t xdr_MKDIR3resok(XDR *, MKDIR3resok*);
-extern  bool_t xdr_MKDIR3resfail(XDR *, MKDIR3resfail*);
-extern  bool_t xdr_MKDIR3res(XDR *, MKDIR3res*);
-extern  bool_t xdr_symlinkdata3(XDR *, symlinkdata3*);
-extern  bool_t xdr_SYMLINK3args(XDR *, SYMLINK3args*);
-extern  bool_t xdr_SYMLINK3resok(XDR *, SYMLINK3resok*);
-extern  bool_t xdr_SYMLINK3resfail(XDR *, SYMLINK3resfail*);
-extern  bool_t xdr_SYMLINK3res(XDR *, SYMLINK3res*);
-extern  bool_t xdr_devicedata3(XDR *, devicedata3*);
-extern  bool_t xdr_mknoddata3(XDR *, mknoddata3*);
-extern  bool_t xdr_MKNOD3args(XDR *, MKNOD3args*);
-extern  bool_t xdr_MKNOD3resok(XDR *, MKNOD3resok*);
-extern  bool_t xdr_MKNOD3resfail(XDR *, MKNOD3resfail*);
-extern  bool_t xdr_MKNOD3res(XDR *, MKNOD3res*);
-extern  bool_t xdr_REMOVE3args(XDR *, REMOVE3args*);
-extern  bool_t xdr_REMOVE3resok(XDR *, REMOVE3resok*);
-extern  bool_t xdr_REMOVE3resfail(XDR *, REMOVE3resfail*);
-extern  bool_t xdr_REMOVE3res(XDR *, REMOVE3res*);
-extern  bool_t xdr_RMDIR3args(XDR *, RMDIR3args*);
-extern  bool_t xdr_RMDIR3resok(XDR *, RMDIR3resok*);
-extern  bool_t xdr_RMDIR3resfail(XDR *, RMDIR3resfail*);
-extern  bool_t xdr_RMDIR3res(XDR *, RMDIR3res*);
-extern  bool_t xdr_RENAME3args(XDR *, RENAME3args*);
-extern  bool_t xdr_RENAME3resok(XDR *, RENAME3resok*);
-extern  bool_t xdr_RENAME3resfail(XDR *, RENAME3resfail*);
-extern  bool_t xdr_RENAME3res(XDR *, RENAME3res*);
-extern  bool_t xdr_LINK3args(XDR *, LINK3args*);
-extern  bool_t xdr_LINK3resok(XDR *, LINK3resok*);
-extern  bool_t xdr_LINK3resfail(XDR *, LINK3resfail*);
-extern  bool_t xdr_LINK3res(XDR *, LINK3res*);
-extern  bool_t xdr_READDIR3args(XDR *, READDIR3args*);
-extern  bool_t xdr_entry3(XDR *, entry3*);
-extern  bool_t xdr_dirlist3(XDR *, dirlist3*);
-extern  bool_t xdr_READDIR3resok(XDR *, READDIR3resok*);
-extern  bool_t xdr_READDIR3resfail(XDR *, READDIR3resfail*);
-extern  bool_t xdr_READDIR3res(XDR *, READDIR3res*);
-extern  bool_t xdr_READDIRPLUS3args(XDR *, READDIRPLUS3args*);
-extern  bool_t xdr_entryplus3(XDR *, entryplus3*);
-extern  bool_t xdr_dirlistplus3(XDR *, dirlistplus3*);
-extern  bool_t xdr_READDIRPLUS3resok(XDR *, READDIRPLUS3resok*);
-extern  bool_t xdr_READDIRPLUS3resfail(XDR *, READDIRPLUS3resfail*);
-extern  bool_t xdr_READDIRPLUS3res(XDR *, READDIRPLUS3res*);
-extern  bool_t xdr_FSSTAT3args(XDR *, FSSTAT3args*);
-extern  bool_t xdr_FSSTAT3resok(XDR *, FSSTAT3resok*);
-extern  bool_t xdr_FSSTAT3resfail(XDR *, FSSTAT3resfail*);
-extern  bool_t xdr_FSSTAT3res(XDR *, FSSTAT3res*);
-extern  bool_t xdr_FSINFO3args(XDR *, FSINFO3args*);
-extern  bool_t xdr_FSINFO3resok(XDR *, FSINFO3resok*);
-extern  bool_t xdr_FSINFO3resfail(XDR *, FSINFO3resfail*);
-extern  bool_t xdr_FSINFO3res(XDR *, FSINFO3res*);
-extern  bool_t xdr_PATHCONF3args(XDR *, PATHCONF3args*);
-extern  bool_t xdr_PATHCONF3resok(XDR *, PATHCONF3resok*);
-extern  bool_t xdr_PATHCONF3resfail(XDR *, PATHCONF3resfail*);
-extern  bool_t xdr_PATHCONF3res(XDR *, PATHCONF3res*);
-extern  bool_t xdr_COMMIT3args(XDR *, COMMIT3args*);
-extern  bool_t xdr_COMMIT3resok(XDR *, COMMIT3resok*);
-extern  bool_t xdr_COMMIT3resfail(XDR *, COMMIT3resfail*);
-extern  bool_t xdr_COMMIT3res(XDR *, COMMIT3res*);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_NFS_H_RPCGEN */

+ 0 - 774
components/dfs/dfs_v2/filesystems/nfs/nfs.x

@@ -1,774 +0,0 @@
-%/* This file is copied from RFC1813
-% * Copyright 1995 Sun Micrososystems (I assume)
-% */
-
-const NFS3_FHSIZE = 64;
-const NFS3_COOKIEVERFSIZE = 8;
-const NFS3_CREATEVERFSIZE = 8;
-const NFS3_WRITEVERFSIZE = 8;
-
-const ACCESS3_READ = 0x0001;
-const ACCESS3_LOOKUP = 0x0002;
-const ACCESS3_MODIFY = 0x0004;
-const ACCESS3_EXTEND = 0x0008;
-const ACCESS3_DELETE = 0x0010;
-const ACCESS3_EXECUTE = 0x0020;
-
-const FSF3_LINK = 0x0001;
-const FSF3_SYMLINK = 0x0002;
-const FSF3_HOMOGENEOUS = 0x0008;
-const FSF3_CANSETTIME = 0x0010;
-
-typedef unsigned hyper uint64;
-typedef hyper int64;
-typedef unsigned long uint32;
-typedef long int32;
-typedef string filename3<>;
-typedef string nfspath3<>;
-typedef uint64 fileid3;
-typedef uint64 cookie3;
-typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
-typedef opaque createverf3[NFS3_CREATEVERFSIZE];
-typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
-typedef uint32 uid3;
-typedef uint32 gid3;
-typedef uint64 size3;
-typedef uint64 offset3;
-typedef uint32 mode3;
-typedef uint32 count3;
-
-enum nfsstat3 {
-	NFS3_OK = 0,
-	NFS3ERR_PERM = 1,
-	NFS3ERR_NOENT = 2,
-	NFS3ERR_IO = 5,
-	NFS3ERR_NXIO = 6,
-	NFS3ERR_ACCES = 13,
-	NFS3ERR_EXIST = 17,
-	NFS3ERR_XDEV = 18,
-	NFS3ERR_NODEV = 19,
-	NFS3ERR_NOTDIR = 20,
-	NFS3ERR_ISDIR = 21,
-	NFS3ERR_INVAL = 22,
-	NFS3ERR_FBIG = 27,
-	NFS3ERR_NOSPC = 28,
-	NFS3ERR_ROFS = 30,
-	NFS3ERR_MLINK = 31,
-	NFS3ERR_NAMETOOLONG = 63,
-	NFS3ERR_NOTEMPTY = 66,
-	NFS3ERR_DQUOT = 69,
-	NFS3ERR_STALE = 70,
-	NFS3ERR_REMOTE = 71,
-	NFS3ERR_BADHANDLE = 10001,
-	NFS3ERR_NOT_SYNC = 10002,
-	NFS3ERR_BAD_COOKIE = 10003,
-	NFS3ERR_NOTSUPP = 10004,
-	NFS3ERR_TOOSMALL = 10005,
-	NFS3ERR_SERVERFAULT = 10006,
-	NFS3ERR_BADTYPE = 10007,
-	NFS3ERR_JUKEBOX = 10008
-};
-
-enum ftype3 {
-	NFS3REG = 1,
-	NFS3DIR = 2,
-	NFS3BLK = 3,
-	NFS3CHR = 4,
-	NFS3LNK = 5,
-	NFS3SOCK = 6,
-	NFS3FIFO = 7
-};
-enum stable_how {
-	UNSTABLE = 0,
-	DATA_SYNC = 1,
-	FILE_SYNC = 2
-};
-
-enum createmode3 {
-	UNCHECKED = 0,
-	GUARDED = 1,
-	EXCLUSIVE = 2
-};
-
-struct specdata3 {
-	uint32 specdata1;
-	uint32 specdata2;
-};
-
-struct nfs_fh3 {
-	opaque data<NFS3_FHSIZE>;
-};
-
-struct nfstime3 {
-	uint32 seconds;
-	uint32 nseconds;
-};
-
-struct fattr3 {
-	ftype3 type;
-	mode3 mode;
-	uint32 nlink;
-	uid3 uid;
-	gid3 gid;
-	size3 size;
-	size3 used;
-	specdata3 rdev;
-	uint64 fsid;
-	fileid3 fileid;
-	nfstime3 atime;
-	nfstime3 mtime;
-	nfstime3 ctime;
-};
-
-union post_op_attr switch (bool attributes_follow) {
-case TRUE:
-	fattr3 attributes;
-case FALSE:
-	void;
-};
-
-struct wcc_attr {
-	size3 size;
-	nfstime3 mtime;
-	nfstime3 ctime;
-};
-
-union pre_op_attr switch (bool attributes_follow) {
-case TRUE:
-	wcc_attr attributes;
-case FALSE:
-	void;
-};
-
-struct wcc_data {
-	pre_op_attr before;
-	post_op_attr after;
-};
-
-union post_op_fh3 switch (bool handle_follows) {
-case TRUE:
-	nfs_fh3 handle;
-case FALSE:
-	void;
-};
-
-enum time_how {
-	DONT_CHANGE = 0,
-	SET_TO_SERVER_TIME = 1,
-	SET_TO_CLIENT_TIME = 2
-};
-
-union set_mode3 switch (bool set_it) {
-case TRUE:
-	mode3 mode;
-default:
-	void;
-};
-
-union set_uid3 switch (bool set_it) {
-case TRUE:
-	uid3 uid;
-default:
-	void;
-};
-
-union set_gid3 switch (bool set_it) {
-case TRUE:
-	gid3 gid;
-default:
-	void;
-};
-
-union set_size3 switch (bool set_it) {
-case TRUE:
-	size3 size;
-default:
-	void;
-};
-
-union set_atime switch (time_how set_it) {
-case SET_TO_CLIENT_TIME:
-	nfstime3 atime;
-default:
-	void;
-};
-
-union set_mtime switch (time_how set_it) {
-case SET_TO_CLIENT_TIME:
-	nfstime3 mtime;
-default:
-	void;
-};
-
-struct sattr3 {
-	set_mode3 mode;
-	set_uid3 uid;
-	set_gid3 gid;
-	set_size3 size;
-	set_atime atime;
-	set_mtime mtime;
-};
-
-struct diropargs3 {
-	nfs_fh3 dir;
-	filename3 name;
-};
-
-
-struct GETATTR3args {
-	nfs_fh3 object;
-};
-
-struct GETATTR3resok {
-	fattr3 obj_attributes;
-};
-
-union GETATTR3res switch (nfsstat3 status) {
-case NFS3_OK:
-	GETATTR3resok resok;
-default:
-	void;
-};
-
-union sattrguard3 switch (bool check) {
-case TRUE:
-	nfstime3 obj_ctime;
-case FALSE:
-	void;
-};
-
-struct SETATTR3args {
-	nfs_fh3 object;
-	sattr3 new_attributes;
-	sattrguard3 guard;
-};
-
-struct SETATTR3resok {
-	wcc_data obj_wcc;
-};
-
-struct SETATTR3resfail {
-	wcc_data obj_wcc;
-};
-
-union SETATTR3res switch (nfsstat3 status) {
-case NFS3_OK:
-	SETATTR3resok resok;
-default:
-	SETATTR3resfail resfail;
-};
-
-struct LOOKUP3args {
-	diropargs3 what;
-};
-
-struct LOOKUP3resok {
-	nfs_fh3 object;
-	post_op_attr obj_attributes;
-	post_op_attr dir_attributes;
-};
-
-struct LOOKUP3resfail {
-	post_op_attr dir_attributes;
-};
-
-union LOOKUP3res switch (nfsstat3 status) {
-case NFS3_OK:
-	LOOKUP3resok resok;
-default:
-	LOOKUP3resfail resfail;
-};
-
-struct ACCESS3args {
-	nfs_fh3 object;
-	uint32 access;
-};
-
-struct ACCESS3resok {
-	post_op_attr obj_attributes;
-	uint32 access;
-};
-
-struct ACCESS3resfail {
-	post_op_attr obj_attributes;
-};
-
-union ACCESS3res switch (nfsstat3 status) {
-case NFS3_OK:
-	ACCESS3resok resok;
-default:
-	ACCESS3resfail resfail;
-};
-
-struct READLINK3args {
-	nfs_fh3 symlink;
-};
-
-struct READLINK3resok {
-	post_op_attr symlink_attributes;
-	nfspath3 data;
-};
-
-struct READLINK3resfail {
-	post_op_attr symlink_attributes;
-};
-
-union READLINK3res switch (nfsstat3 status) {
-case NFS3_OK:
-	READLINK3resok resok;
-default:
-	READLINK3resfail resfail;
-};
-
-struct READ3args {
-	nfs_fh3 file;
-	offset3 offset;
-	count3 count;
-};
-
-struct READ3resok {
-	post_op_attr file_attributes;
-	count3 count;
-	bool eof;
-	opaque data<>;
-};
-
-struct READ3resfail {
-	post_op_attr file_attributes;
-};
-
-union READ3res switch (nfsstat3 status) {
-case NFS3_OK:
-	READ3resok resok;
-default:
-	READ3resfail resfail;
-};
-
-struct WRITE3args {
-	nfs_fh3	file;
-	offset3	offset;
-	count3 count;
-	stable_how stable;
-	opaque data<>;
-};
-
-struct WRITE3resok {
-	wcc_data file_wcc;
-	count3 count;
-	stable_how committed;
-	writeverf3 verf;
-};
-
-struct WRITE3resfail {
-	wcc_data file_wcc;
-};
-
-union WRITE3res switch (nfsstat3 status) {
-case NFS3_OK:
-	WRITE3resok resok;
-default:
-	WRITE3resfail resfail;
-};
-
-
-union createhow3 switch (createmode3 mode) {
-case UNCHECKED:
-case GUARDED:
-	sattr3 obj_attributes;
-case EXCLUSIVE:
-	createverf3 verf;
-};
-
-struct CREATE3args {
-	diropargs3 where;
-	createhow3 how;
-};
-
-struct CREATE3resok {
-	post_op_fh3 obj;
-	post_op_attr obj_attributes;
-	wcc_data dir_wcc;
-};
-
-struct CREATE3resfail {
-	wcc_data dir_wcc;
-};
-
-union CREATE3res switch (nfsstat3 status) {
-case NFS3_OK:
-	CREATE3resok resok;
-default:
-	CREATE3resfail resfail;
-};
-
-struct MKDIR3args {
-	diropargs3 where;
-	sattr3 attributes;
-};
-
-struct MKDIR3resok {
-	post_op_fh3 obj;
-	post_op_attr obj_attributes;
-	wcc_data dir_wcc;
-};
-
-struct MKDIR3resfail {
-	wcc_data dir_wcc;
-};
-
-union MKDIR3res switch (nfsstat3 status) {
-case NFS3_OK:
-	MKDIR3resok resok;
-default:
-	MKDIR3resfail resfail;
-};
-
-struct symlinkdata3 {
-	sattr3 symlink_attributes;
-	nfspath3 symlink_data;
-};
-
-struct SYMLINK3args {
-	diropargs3 where;
-	symlinkdata3 symlink;
-};
-
-struct SYMLINK3resok {
-	post_op_fh3 obj;
-	post_op_attr obj_attributes;
-	wcc_data dir_wcc;
-};
-
-struct SYMLINK3resfail {
-	wcc_data dir_wcc;
-};
-
-union SYMLINK3res switch (nfsstat3 status) {
-case NFS3_OK:
-	SYMLINK3resok resok;
-default:
-	SYMLINK3resfail resfail;
-};
-
-struct devicedata3 {
-	sattr3 dev_attributes;
-	specdata3 spec;
-};
-
-union mknoddata3 switch (ftype3 type) {
-case NFS3CHR:
-case NFS3BLK:
-	devicedata3 device;
-case NFS3SOCK:
-case NFS3FIFO:
-	sattr3 pipe_attributes;
-default:
-	void;
-};
-
-struct MKNOD3args {
-	diropargs3 where;
-	mknoddata3 what;
-};
-
-struct MKNOD3resok {
-	post_op_fh3 obj;
-	post_op_attr obj_attributes;
-	wcc_data dir_wcc;
-};
-
-struct MKNOD3resfail {
-	wcc_data dir_wcc;
-};
-
-union MKNOD3res switch (nfsstat3 status) {
-case NFS3_OK:
-	MKNOD3resok resok;
-default:
-	MKNOD3resfail resfail;
-};
-
-struct REMOVE3args {
-	diropargs3 object;
-};
-
-struct REMOVE3resok {
-	wcc_data dir_wcc;
-};
-
-struct REMOVE3resfail {
-	wcc_data dir_wcc;
-};
-
-union REMOVE3res switch (nfsstat3 status) {
-case NFS3_OK:
-	REMOVE3resok resok;
-default:
-	REMOVE3resfail resfail;
-};
-
-struct RMDIR3args {
-	diropargs3 object;
-};
-
-struct RMDIR3resok {
-	wcc_data dir_wcc;
-};
-
-struct RMDIR3resfail {
-	wcc_data dir_wcc;
-};
-
-union RMDIR3res switch (nfsstat3 status) {
-case NFS3_OK:
-	RMDIR3resok resok;
-default:
-	RMDIR3resfail resfail;
-};
-
-struct RENAME3args {
-	diropargs3 from;
-	diropargs3 to;
-};
-
-struct RENAME3resok {
-	wcc_data fromdir_wcc;
-	wcc_data todir_wcc;
-};
-
-struct RENAME3resfail {
-	wcc_data fromdir_wcc;
-	wcc_data todir_wcc;
-};
-
-union RENAME3res switch (nfsstat3 status) {
-case NFS3_OK:
-	RENAME3resok resok;
-default:
-	RENAME3resfail resfail;
-};
-struct LINK3args {
-	nfs_fh3	file;
-	diropargs3 link;
-};
-
-struct LINK3resok {
-	post_op_attr file_attributes;
-	wcc_data linkdir_wcc;
-};
-
-struct LINK3resfail {
-	post_op_attr file_attributes;
-	wcc_data linkdir_wcc;
-};
-
-union LINK3res switch (nfsstat3 status) {
-case NFS3_OK:
-	LINK3resok resok;
-default:
-	LINK3resfail resfail;
-};
-
-struct READDIR3args {
-	nfs_fh3 dir;
-	cookie3 cookie;
-	cookieverf3 cookieverf;
-	count3 count;
-};
-
-struct entry3 {
-	fileid3 fileid;
-	filename3 name;
-	cookie3 cookie;
-	entry3 *nextentry;
-};
-
-struct dirlist3 {
-	entry3 *entries;
-	bool eof;
-};
-
-struct READDIR3resok {
-	post_op_attr dir_attributes;
-	cookieverf3 cookieverf;
-	dirlist3 reply;
-};
-
-struct READDIR3resfail {
-	post_op_attr dir_attributes;
-};
-
-union READDIR3res switch (nfsstat3 status) {
-case NFS3_OK:
-	READDIR3resok resok;
-default:
-	READDIR3resfail resfail;
-};
-
-struct READDIRPLUS3args {
-	nfs_fh3 dir;
-	cookie3 cookie;
-	cookieverf3 cookieverf;
-	count3 dircount;
-	count3 maxcount;
-};
-
-struct entryplus3 {
-	fileid3 fileid;
-	filename3 name;
-	cookie3 cookie;
-	post_op_attr name_attributes;
-	post_op_fh3 name_handle;
-	entryplus3 *nextentry;
-};
-
-struct dirlistplus3 {
-	entryplus3 *entries;
-	bool eof;
-};
-
-struct READDIRPLUS3resok {
-	post_op_attr dir_attributes;
-	cookieverf3 cookieverf;
-	dirlistplus3 reply;
-};
-
-struct READDIRPLUS3resfail {
-	post_op_attr dir_attributes;
-};
-
-union READDIRPLUS3res switch (nfsstat3 status) {
-case NFS3_OK:
-	READDIRPLUS3resok resok;
-default:
-	READDIRPLUS3resfail resfail;
-};
-
-struct FSSTAT3args {
-	nfs_fh3 fsroot;
-};
-
-struct FSSTAT3resok {
-	post_op_attr obj_attributes;
-	size3 tbytes;
-	size3 fbytes;
-	size3 abytes;
-	size3 tfiles;
-	size3 ffiles;
-	size3 afiles;
-	uint32 invarsec;
-};
-
-struct FSSTAT3resfail {
-	post_op_attr obj_attributes;
-};
-
-union FSSTAT3res switch (nfsstat3 status) {
-case NFS3_OK:
-	FSSTAT3resok resok;
-default:
-	FSSTAT3resfail resfail;
-};
-
-struct FSINFO3args {
-	nfs_fh3 fsroot;
-};
-
-struct FSINFO3resok {
-	post_op_attr obj_attributes;
-	uint32 rtmax;
-	uint32 rtpref;
-	uint32 rtmult;
-	uint32 wtmax;
-	uint32 wtpref;
-	uint32 wtmult;
-	uint32 dtpref;
-	size3 maxfilesize;
-	nfstime3 time_delta;
-	uint32 properties;
-};
-
-struct FSINFO3resfail {
-	post_op_attr obj_attributes;
-};
-
-union FSINFO3res switch (nfsstat3 status) {
-case NFS3_OK:
-	FSINFO3resok resok;
-default:
-	FSINFO3resfail resfail;
-};
-
-struct PATHCONF3args {
-	nfs_fh3 object;
-};
-
-struct PATHCONF3resok {
-	post_op_attr obj_attributes;
-	uint32 linkmax;
-	uint32 name_max;
-	bool no_trunc;
-	bool chown_restricted;
-	bool case_insensitive;
-	bool case_preserving;
-};
-
-struct PATHCONF3resfail {
-	post_op_attr obj_attributes;
-};
-
-union PATHCONF3res switch (nfsstat3 status) {
-case NFS3_OK:
-	PATHCONF3resok resok;
-default:
-	PATHCONF3resfail resfail;
-};
-
-struct COMMIT3args {
-	nfs_fh3 file;
-	offset3 offset;
-	count3 count;
-};
-
-struct COMMIT3resok {
-	wcc_data file_wcc;
-	writeverf3 verf;
-};
-
-struct COMMIT3resfail {
-	wcc_data file_wcc;
-};
-
-union COMMIT3res switch (nfsstat3 status) {
-case NFS3_OK:
-	COMMIT3resok resok;
-default:
-	COMMIT3resfail resfail;
-};
-
-program NFS_PROGRAM {
-	version NFS_V3 {
-		void NFSPROC3_NULL(void) = 0;
-		GETATTR3res NFSPROC3_GETATTR(GETATTR3args) = 1;
-		SETATTR3res NFSPROC3_SETATTR(SETATTR3args) = 2;
-		LOOKUP3res NFSPROC3_LOOKUP(LOOKUP3args) = 3;
-		ACCESS3res NFSPROC3_ACCESS(ACCESS3args) = 4;
-		READLINK3res NFSPROC3_READLINK(READLINK3args) = 5;
-		READ3res NFSPROC3_READ(READ3args) = 6;
-		WRITE3res NFSPROC3_WRITE(WRITE3args) = 7;
-		CREATE3res NFSPROC3_CREATE(CREATE3args) = 8;
-		MKDIR3res NFSPROC3_MKDIR(MKDIR3args) = 9;
-		SYMLINK3res NFSPROC3_SYMLINK(SYMLINK3args) = 10;
-		MKNOD3res NFSPROC3_MKNOD(MKNOD3args) = 11;
-		REMOVE3res NFSPROC3_REMOVE(REMOVE3args) = 12;
-		RMDIR3res NFSPROC3_RMDIR(RMDIR3args) = 13;
-		RENAME3res NFSPROC3_RENAME(RENAME3args) = 14;
-		LINK3res NFSPROC3_LINK(LINK3args) = 15;
-		READDIR3res NFSPROC3_READDIR(READDIR3args) = 16;
-		READDIRPLUS3res NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17;
-		FSSTAT3res NFSPROC3_FSSTAT(FSSTAT3args) = 18;
-		FSINFO3res NFSPROC3_FSINFO(FSINFO3args) = 19;
-		PATHCONF3res NFSPROC3_PATHCONF(PATHCONF3args) = 20;
-		COMMIT3res NFSPROC3_COMMIT(COMMIT3args) = 21;
-	} = 3;
-} = 100003;

+ 0 - 172
components/dfs/dfs_v2/filesystems/nfs/nfs_auth.c

@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <rpc/auth.h>
-
-#define MAX_MARSHEL_SIZE 64
-
-struct nfs_credentia
-{
-    rt_uint32_t stamp;
-    char *name;
-    rt_uint32_t uid;
-    rt_uint32_t gid;
-    rt_uint32_t *auxi;
-    rt_uint32_t auxi_count;
-};
-
-static void authnone_verf(AUTH *);
-static bool_t authnone_validate(AUTH *, struct opaque_auth *);
-static bool_t authnone_refresh(AUTH *);
-static void authnone_destroy(AUTH *);
-static bool_t authnone_marshal(AUTH *client, XDR *xdrs);
-
-static struct nfs_credentia _credentia = {
-    .stamp = 0,
-    .name = "rt-thread",
-    .uid = 0,
-    .gid = 0,
-    .auxi = NULL,
-    .auxi_count = 0,
-};
-
-struct opaque_auth _null_auth;
-
-static struct auth_ops ops =
-{
-    authnone_verf,
-    authnone_marshal,
-    authnone_validate,
-    authnone_refresh,
-    authnone_destroy
-};
-
-static struct authnone_private
-{
-    AUTH no_client;
-    char marshalled_client[MAX_MARSHEL_SIZE];
-    unsigned int mcnt;
-} *authnone_private;
-
-AUTH *authnone_create(void)
-{
-    register struct authnone_private *ap = authnone_private;
-    XDR xdr_stream;
-    register XDR *xdrs;
-    extern bool_t xdr_opaque_auth(XDR * xdrs, struct opaque_auth * ap);
-    struct opaque_auth auth;
-    rt_uint32_t *auth_buf, *auth_base;
-    int buf_len = 0, str_len = 0;
-
-    if (_credentia.name)
-    {
-        str_len = strlen(_credentia.name);
-    }
-    if (str_len == 0)
-    {
-        _credentia.name = "unknown";
-        str_len = strlen(_credentia.name);
-    }
-    buf_len = ((str_len) + (sizeof(rt_uint32_t)) - 1) & ~((sizeof(rt_uint32_t)) - 1);
-    buf_len += sizeof(struct nfs_credentia);
-    if (_credentia.auxi && _credentia.auxi_count)
-    {
-        buf_len += sizeof(rt_uint32_t) * _credentia.auxi_count;
-    }
-    auth_buf = auth_base = rt_malloc(buf_len);
-    if (auth_buf == NULL)
-    {
-        return NULL;
-    }
-    memset(auth_buf, 0, buf_len);
-    *auth_buf++ = htonl(rt_tick_get());
-    *auth_buf++ = htonl(str_len);
-    memcpy(auth_buf, _credentia.name, str_len);
-    auth_buf += (str_len + sizeof(rt_uint32_t) - 1) >> 2;
-    *auth_buf++ = htonl(_credentia.uid);
-    *auth_buf++ = htonl(_credentia.gid);
-    if (_credentia.auxi && _credentia.auxi_count)
-    {
-        rt_uint32_t tmp_cnt = 0;
-        *auth_buf++ = htonl(_credentia.auxi_count);
-        while (tmp_cnt < _credentia.auxi_count)
-        {
-            *auth_buf++ = htonl(_credentia.auxi[tmp_cnt]);
-        }
-    }
-    else
-    {
-        *auth_buf++ = htonl(0);
-    }
-
-    if (ap == 0)
-    {
-        ap = (struct authnone_private *) rt_malloc(sizeof(*ap));
-        if (ap == 0)
-        {
-            rt_free(auth_base);
-            return NULL;
-        }
-        memset(ap, 0, sizeof(*ap));
-        authnone_private = ap;
-    }
-
-    if (!ap->mcnt)
-    {
-        memset(&auth, 0, sizeof(auth));
-        auth.oa_flavor = 1;
-        auth.oa_base = (char *)auth_base;
-        auth.oa_length = (auth_buf - auth_base) * sizeof(rt_uint32_t);
-        ap->no_client.ah_cred = auth;
-        ap->no_client.ah_verf = _null_auth;
-        ap->no_client.ah_ops = &ops;
-        xdrs = &xdr_stream;
-        xdrmem_create(xdrs, ap->marshalled_client,
-                      (unsigned int) MAX_MARSHEL_SIZE, XDR_ENCODE);
-        (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
-        (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
-        ap->mcnt = XDR_GETPOS(xdrs);
-        XDR_DESTROY(xdrs);
-    }
-    rt_free(auth_base);
-    return (&ap->no_client);
-}
-
-/*ARGSUSED*/
-static bool_t authnone_marshal(AUTH *client, XDR *xdrs)
-{
-    register struct authnone_private *ap = authnone_private;
-
-    if (ap == 0)
-        return (0);
-    return ((*xdrs->x_ops->x_putbytes)(xdrs,
-                                       ap->marshalled_client, ap->mcnt));
-}
-
-static void authnone_verf(AUTH *x)
-{
-}
-
-static bool_t authnone_validate(AUTH *x, struct opaque_auth *x1)
-{
-
-    return (TRUE);
-}
-
-static bool_t authnone_refresh(AUTH *x)
-{
-
-    return (FALSE);
-}
-
-static void authnone_destroy(AUTH *x)
-{
-}

+ 0 - 222
components/dfs/dfs_v2/filesystems/nfs/nfs_clnt.c

@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include <string.h> /* for memset */
-#include "nfs.h"
-
-/* This file is copied from RFC1813
- * Copyright 1995 Sun Micrososystems (I assume)
- */
-
-typedef char* caddr_t;
-
-/* Default timeout can be changed using clnt_control() */
-static struct timeval TIMEOUT = { 25, 0 };
-
-enum clnt_stat
-nfsproc3_null_3(void *clnt_res, CLIENT *clnt)
-{
-     return (clnt_call(clnt, NFSPROC3_NULL,
-        (xdrproc_t) xdr_void, (caddr_t) NULL,
-        (xdrproc_t) xdr_void, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_getattr_3(GETATTR3args arg1, GETATTR3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_GETATTR,
-        (xdrproc_t) xdr_GETATTR3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_GETATTR3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_setattr_3(SETATTR3args arg1, SETATTR3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_SETATTR,
-        (xdrproc_t) xdr_SETATTR3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_SETATTR3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_lookup_3(LOOKUP3args arg1, LOOKUP3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_LOOKUP,
-        (xdrproc_t) xdr_LOOKUP3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_LOOKUP3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_access_3(ACCESS3args arg1, ACCESS3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_ACCESS,
-        (xdrproc_t) xdr_ACCESS3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_ACCESS3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_readlink_3(READLINK3args arg1, READLINK3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_READLINK,
-        (xdrproc_t) xdr_READLINK3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_READLINK3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_read_3(READ3args arg1, READ3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_READ,
-        (xdrproc_t) xdr_READ3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_READ3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_write_3(WRITE3args arg1, WRITE3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_WRITE,
-        (xdrproc_t) xdr_WRITE3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_WRITE3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_create_3(CREATE3args arg1, CREATE3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_CREATE,
-        (xdrproc_t) xdr_CREATE3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_CREATE3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_mkdir_3(MKDIR3args arg1, MKDIR3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_MKDIR,
-        (xdrproc_t) xdr_MKDIR3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_MKDIR3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_symlink_3(SYMLINK3args arg1, SYMLINK3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_SYMLINK,
-        (xdrproc_t) xdr_SYMLINK3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_SYMLINK3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_mknod_3(MKNOD3args arg1, MKNOD3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_MKNOD,
-        (xdrproc_t) xdr_MKNOD3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_MKNOD3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_remove_3(REMOVE3args arg1, REMOVE3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_REMOVE,
-        (xdrproc_t) xdr_REMOVE3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_REMOVE3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_rmdir_3(RMDIR3args arg1, RMDIR3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_RMDIR,
-        (xdrproc_t) xdr_RMDIR3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_RMDIR3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_rename_3(RENAME3args arg1, RENAME3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_RENAME,
-        (xdrproc_t) xdr_RENAME3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_RENAME3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_link_3(LINK3args arg1, LINK3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_LINK,
-        (xdrproc_t) xdr_LINK3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_LINK3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_readdir_3(READDIR3args arg1, READDIR3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_READDIR,
-        (xdrproc_t) xdr_READDIR3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_READDIR3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_readdirplus_3(READDIRPLUS3args arg1, READDIRPLUS3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_READDIRPLUS,
-        (xdrproc_t) xdr_READDIRPLUS3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_READDIRPLUS3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_fsstat_3(FSSTAT3args arg1, FSSTAT3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_FSSTAT,
-        (xdrproc_t) xdr_FSSTAT3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_FSSTAT3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_fsinfo_3(FSINFO3args arg1, FSINFO3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_FSINFO,
-        (xdrproc_t) xdr_FSINFO3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_FSINFO3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_pathconf_3(PATHCONF3args arg1, PATHCONF3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_PATHCONF,
-        (xdrproc_t) xdr_PATHCONF3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_PATHCONF3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}
-
-enum clnt_stat
-nfsproc3_commit_3(COMMIT3args arg1, COMMIT3res *clnt_res, CLIENT *clnt)
-{
-    return (clnt_call(clnt, NFSPROC3_COMMIT,
-        (xdrproc_t) xdr_COMMIT3args, (caddr_t) &arg1,
-        (xdrproc_t) xdr_COMMIT3res, (caddr_t) clnt_res,
-        TIMEOUT));
-}

+ 0 - 1622
components/dfs/dfs_v2/filesystems/nfs/nfs_xdr.c

@@ -1,1622 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include "nfs.h"
-/* This file is copied from RFC1813
- * Copyright 1995 Sun Micrososystems (I assume)
- */
-
-bool_t
-xdr_uint64(register XDR *xdrs, uint64 *objp)
-{
-    if (!xdr_u_longlong_t(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_int64(register XDR *xdrs, int64 *objp)
-{
-    if (!xdr_longlong_t(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_uint32(register XDR *xdrs, uint32 *objp)
-{
-    if (!xdr_u_long(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_int32(register XDR *xdrs, int32 *objp)
-{
-    if (!xdr_long(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_filename3(register XDR *xdrs, filename3 *objp)
-{
-    if (!xdr_string(xdrs, objp, ~0))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_nfspath3(register XDR *xdrs, nfspath3 *objp)
-{
-    if (!xdr_string(xdrs, objp, ~0))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_fileid3(register XDR *xdrs, fileid3 *objp)
-{
-    if (!xdr_uint64(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_cookie3(register XDR *xdrs, cookie3 *objp)
-{
-    if (!xdr_uint64(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_cookieverf3(register XDR *xdrs, cookieverf3 objp)
-{
-    if (!xdr_opaque(xdrs, objp, NFS3_COOKIEVERFSIZE))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_createverf3(register XDR *xdrs, createverf3 objp)
-{
-    if (!xdr_opaque(xdrs, objp, NFS3_CREATEVERFSIZE))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_writeverf3(register XDR *xdrs, writeverf3 objp)
-{
-    if (!xdr_opaque(xdrs, objp, NFS3_WRITEVERFSIZE))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_uid3(register XDR *xdrs, uid3 *objp)
-{
-    if (!xdr_uint32(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_gid3(register XDR *xdrs, gid3 *objp)
-{
-    if (!xdr_uint32(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_size3(register XDR *xdrs, size3 *objp)
-{
-    if (!xdr_uint64(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_offset3(register XDR *xdrs, offset3 *objp)
-{
-    if (!xdr_uint64(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_mode3(register XDR *xdrs, mode3 *objp)
-{
-    if (!xdr_uint32(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_count3(register XDR *xdrs, count3 *objp)
-{
-    if (!xdr_uint32(xdrs, objp))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_nfsstat3(register XDR *xdrs, nfsstat3 *objp)
-{
-    int enum_objp;
-    enum_objp = *objp;
-    if (!xdr_enum(xdrs, (enum_t *)objp))
-    {
-        *objp = (nfsstat3)enum_objp;
-        return (FALSE);
-    }
-
-    return (TRUE);
-}
-
-bool_t
-xdr_ftype3(register XDR *xdrs, ftype3 *objp)
-{
-    int enum_objp;
-    enum_objp = *objp;
-    if (!xdr_enum(xdrs, (enum_t *)objp))
-    {
-        *objp = (ftype3)enum_objp;
-        return (FALSE);
-    }
-
-    return (TRUE);
-}
-
-bool_t
-xdr_stable_how(register XDR *xdrs, stable_how *objp)
-{
-    int enum_objp;
-    enum_objp = *objp;
-    if (!xdr_enum(xdrs, (enum_t *)objp))
-    {
-        *objp = (stable_how)enum_objp;
-        return (FALSE);
-    }
-
-    return (TRUE);
-}
-
-bool_t
-xdr_createmode3(register XDR *xdrs, createmode3 *objp)
-{
-    int enum_objp;
-    enum_objp = *objp;
-    if (!xdr_enum(xdrs, (enum_t *)objp))
-    {
-        *objp = (createmode3)enum_objp;
-        return (FALSE);
-    }
-
-    return (TRUE);
-}
-
-bool_t
-xdr_specdata3(register XDR *xdrs, specdata3 *objp)
-{
-    if (!xdr_uint32(xdrs, &objp->specdata1))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->specdata2))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_nfs_fh3(register XDR *xdrs, nfs_fh3 *objp)
-{
-    if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (unsigned int *) &objp->data.data_len, NFS3_FHSIZE))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_nfstime3(register XDR *xdrs, nfstime3 *objp)
-{
-    if (!xdr_uint32(xdrs, &objp->seconds))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->nseconds))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_fattr3(register XDR *xdrs, fattr3 *objp)
-{
-    if (!xdr_ftype3(xdrs, &objp->type))
-        return (FALSE);
-    if (!xdr_mode3(xdrs, &objp->mode))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->nlink))
-        return (FALSE);
-    if (!xdr_uid3(xdrs, &objp->uid))
-        return (FALSE);
-    if (!xdr_gid3(xdrs, &objp->gid))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->size))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->used))
-        return (FALSE);
-    if (!xdr_specdata3(xdrs, &objp->rdev))
-        return (FALSE);
-    if (!xdr_uint64(xdrs, &objp->fsid))
-        return (FALSE);
-    if (!xdr_fileid3(xdrs, &objp->fileid))
-        return (FALSE);
-    if (!xdr_nfstime3(xdrs, &objp->atime))
-        return (FALSE);
-    if (!xdr_nfstime3(xdrs, &objp->mtime))
-        return (FALSE);
-    if (!xdr_nfstime3(xdrs, &objp->ctime))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_post_op_attr(register XDR *xdrs, post_op_attr *objp)
-{
-    if (!xdr_bool(xdrs, &objp->attributes_follow))
-        return (FALSE);
-    switch (objp->attributes_follow) {
-    case TRUE:
-        if (!xdr_fattr3(xdrs, &objp->post_op_attr_u.attributes))
-            return (FALSE);
-        break;
-    case FALSE:
-        break;
-    default:
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_wcc_attr(register XDR *xdrs, wcc_attr *objp)
-{
-    if (!xdr_size3(xdrs, &objp->size))
-        return (FALSE);
-    if (!xdr_nfstime3(xdrs, &objp->mtime))
-        return (FALSE);
-    if (!xdr_nfstime3(xdrs, &objp->ctime))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_pre_op_attr(register XDR *xdrs, pre_op_attr *objp)
-{
-    if (!xdr_bool(xdrs, &objp->attributes_follow))
-        return (FALSE);
-    switch (objp->attributes_follow) {
-    case TRUE:
-        if (!xdr_wcc_attr(xdrs, &objp->pre_op_attr_u.attributes))
-            return (FALSE);
-        break;
-    case FALSE:
-        break;
-    default:
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_wcc_data(register XDR *xdrs, wcc_data *objp)
-{
-    if (!xdr_pre_op_attr(xdrs, &objp->before))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->after))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_post_op_fh3(register XDR *xdrs, post_op_fh3 *objp)
-{
-    if (!xdr_bool(xdrs, &objp->handle_follows))
-        return (FALSE);
-    switch (objp->handle_follows) {
-    case TRUE:
-        if (!xdr_nfs_fh3(xdrs, &objp->post_op_fh3_u.handle))
-            return (FALSE);
-        break;
-    case FALSE:
-        break;
-    default:
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_time_how(register XDR *xdrs, time_how *objp)
-{
-    int enum_objp;
-    enum_objp = *objp;
-    if (!xdr_enum(xdrs, (enum_t *)objp))
-    {
-        *objp = (time_how)enum_objp;
-        return (FALSE);
-    }
-
-    return (TRUE);
-}
-
-bool_t
-xdr_set_mode3(register XDR *xdrs, set_mode3 *objp)
-{
-    if (!xdr_bool(xdrs, &objp->set_it))
-        return (FALSE);
-    switch (objp->set_it) {
-    case TRUE:
-        if (!xdr_mode3(xdrs, &objp->set_mode3_u.mode))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_set_uid3(register XDR *xdrs, set_uid3 *objp)
-{
-    if (!xdr_bool(xdrs, &objp->set_it))
-        return (FALSE);
-    switch (objp->set_it) {
-    case TRUE:
-        if (!xdr_uid3(xdrs, &objp->set_uid3_u.uid))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_set_gid3(register XDR *xdrs, set_gid3 *objp)
-{
-    if (!xdr_bool(xdrs, &objp->set_it))
-        return (FALSE);
-    switch (objp->set_it) {
-    case TRUE:
-        if (!xdr_gid3(xdrs, &objp->set_gid3_u.gid))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_set_size3(register XDR *xdrs, set_size3 *objp)
-{
-    if (!xdr_bool(xdrs, &objp->set_it))
-        return (FALSE);
-    switch (objp->set_it) {
-    case TRUE:
-        if (!xdr_size3(xdrs, &objp->set_size3_u.size))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_set_atime(register XDR *xdrs, set_atime *objp)
-{
-    if (!xdr_time_how(xdrs, &objp->set_it))
-        return (FALSE);
-    switch (objp->set_it) {
-    case SET_TO_CLIENT_TIME:
-        if (!xdr_nfstime3(xdrs, &objp->set_atime_u.atime))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_set_mtime(register XDR *xdrs, set_mtime *objp)
-{
-    if (!xdr_time_how(xdrs, &objp->set_it))
-        return (FALSE);
-    switch (objp->set_it) {
-    case SET_TO_CLIENT_TIME:
-        if (!xdr_nfstime3(xdrs, &objp->set_mtime_u.mtime))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_sattr3(register XDR *xdrs, sattr3 *objp)
-{
-    if (!xdr_set_mode3(xdrs, &objp->mode))
-        return (FALSE);
-    if (!xdr_set_uid3(xdrs, &objp->uid))
-        return (FALSE);
-    if (!xdr_set_gid3(xdrs, &objp->gid))
-        return (FALSE);
-    if (!xdr_set_size3(xdrs, &objp->size))
-        return (FALSE);
-    if (!xdr_set_atime(xdrs, &objp->atime))
-        return (FALSE);
-    if (!xdr_set_mtime(xdrs, &objp->mtime))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_diropargs3(register XDR *xdrs, diropargs3 *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->dir))
-        return (FALSE);
-    if (!xdr_filename3(xdrs, &objp->name))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_GETATTR3args(register XDR *xdrs, GETATTR3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->object))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_GETATTR3resok(register XDR *xdrs, GETATTR3resok *objp)
-{
-    if (!xdr_fattr3(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_GETATTR3res(register XDR *xdrs, GETATTR3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_GETATTR3resok(xdrs, &objp->GETATTR3res_u.resok))
-            return (FALSE);
-        break;
-    default :
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_sattrguard3(register XDR *xdrs, sattrguard3 *objp)
-{
-    if (!xdr_bool(xdrs, &objp->check))
-        return (FALSE);
-    switch (objp->check) {
-    case TRUE:
-        if (!xdr_nfstime3(xdrs, &objp->sattrguard3_u.obj_ctime))
-            return (FALSE);
-        break;
-    case FALSE:
-        break;
-    default:
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_SETATTR3args(register XDR *xdrs, SETATTR3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->object))
-        return (FALSE);
-    if (!xdr_sattr3(xdrs, &objp->new_attributes))
-        return (FALSE);
-    if (!xdr_sattrguard3(xdrs, &objp->guard))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_SETATTR3resok(register XDR *xdrs, SETATTR3resok *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->obj_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_SETATTR3resfail(register XDR *xdrs, SETATTR3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->obj_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_SETATTR3res(register XDR *xdrs, SETATTR3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_SETATTR3resok(xdrs, &objp->SETATTR3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_SETATTR3resfail(xdrs, &objp->SETATTR3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_LOOKUP3args(register XDR *xdrs, LOOKUP3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->what))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_LOOKUP3resok(register XDR *xdrs, LOOKUP3resok *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->object))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_LOOKUP3resfail(register XDR *xdrs, LOOKUP3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_LOOKUP3res(register XDR *xdrs, LOOKUP3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_LOOKUP3resok(xdrs, &objp->LOOKUP3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_LOOKUP3resfail(xdrs, &objp->LOOKUP3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_ACCESS3args(register XDR *xdrs, ACCESS3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->object))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->access))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_ACCESS3resok(register XDR *xdrs, ACCESS3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->access))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_ACCESS3resfail(register XDR *xdrs, ACCESS3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_ACCESS3res(register XDR *xdrs, ACCESS3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_ACCESS3resok(xdrs, &objp->ACCESS3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_ACCESS3resfail(xdrs, &objp->ACCESS3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_READLINK3args(register XDR *xdrs, READLINK3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->symlink))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READLINK3resok(register XDR *xdrs, READLINK3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->symlink_attributes))
-        return (FALSE);
-    if (!xdr_nfspath3(xdrs, &objp->data))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READLINK3resfail(register XDR *xdrs, READLINK3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->symlink_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READLINK3res(register XDR *xdrs, READLINK3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_READLINK3resok(xdrs, &objp->READLINK3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_READLINK3resfail(xdrs, &objp->READLINK3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_READ3args(register XDR *xdrs, READ3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->file))
-        return (FALSE);
-    if (!xdr_offset3(xdrs, &objp->offset))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->count))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READ3resok(register XDR *xdrs, READ3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->count))
-        return (FALSE);
-    if (!xdr_bool(xdrs, &objp->eof))
-        return (FALSE);
-    if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (unsigned int *) &objp->data.data_len, ~0))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READ3resfail(register XDR *xdrs, READ3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READ3res(register XDR *xdrs, READ3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_READ3resok(xdrs, &objp->READ3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_READ3resfail(xdrs, &objp->READ3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_WRITE3args(register XDR *xdrs, WRITE3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->file))
-        return (FALSE);
-    if (!xdr_offset3(xdrs, &objp->offset))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->count))
-        return (FALSE);
-    if (!xdr_stable_how(xdrs, &objp->stable))
-        return (FALSE);
-    if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (unsigned int *) &objp->data.data_len, ~0))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_WRITE3resok(register XDR *xdrs, WRITE3resok *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->file_wcc))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->count))
-        return (FALSE);
-    if (!xdr_stable_how(xdrs, &objp->committed))
-        return (FALSE);
-    if (!xdr_writeverf3(xdrs, objp->verf))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_WRITE3resfail(register XDR *xdrs, WRITE3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->file_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_WRITE3res(register XDR *xdrs, WRITE3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_WRITE3resok(xdrs, &objp->WRITE3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_WRITE3resfail(xdrs, &objp->WRITE3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_createhow3(register XDR *xdrs, createhow3 *objp)
-{
-    if (!xdr_createmode3(xdrs, &objp->mode))
-        return (FALSE);
-    switch (objp->mode) {
-    case UNCHECKED:
-    case GUARDED:
-        if (!xdr_sattr3(xdrs, &objp->createhow3_u.obj_attributes))
-            return (FALSE);
-        break;
-    case EXCLUSIVE:
-        if (!xdr_createverf3(xdrs, objp->createhow3_u.verf))
-            return (FALSE);
-        break;
-    default:
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_CREATE3args(register XDR *xdrs, CREATE3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->where))
-        return (FALSE);
-    if (!xdr_createhow3(xdrs, &objp->how))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_CREATE3resok(register XDR *xdrs, CREATE3resok *objp)
-{
-    if (!xdr_post_op_fh3(xdrs, &objp->obj))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_CREATE3resfail(register XDR *xdrs, CREATE3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_CREATE3res(register XDR *xdrs, CREATE3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_CREATE3resok(xdrs, &objp->CREATE3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_CREATE3resfail(xdrs, &objp->CREATE3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_MKDIR3args(register XDR *xdrs, MKDIR3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->where))
-        return (FALSE);
-    if (!xdr_sattr3(xdrs, &objp->attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_MKDIR3resok(register XDR *xdrs, MKDIR3resok *objp)
-{
-    if (!xdr_post_op_fh3(xdrs, &objp->obj))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_MKDIR3resfail(register XDR *xdrs, MKDIR3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_MKDIR3res(register XDR *xdrs, MKDIR3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_MKDIR3resok(xdrs, &objp->MKDIR3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_MKDIR3resfail(xdrs, &objp->MKDIR3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_symlinkdata3(register XDR *xdrs, symlinkdata3 *objp)
-{
-    if (!xdr_sattr3(xdrs, &objp->symlink_attributes))
-        return (FALSE);
-    if (!xdr_nfspath3(xdrs, &objp->symlink_data))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_SYMLINK3args(register XDR *xdrs, SYMLINK3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->where))
-        return (FALSE);
-    if (!xdr_symlinkdata3(xdrs, &objp->symlink))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_SYMLINK3resok(register XDR *xdrs, SYMLINK3resok *objp)
-{
-    if (!xdr_post_op_fh3(xdrs, &objp->obj))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_SYMLINK3resfail(register XDR *xdrs, SYMLINK3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_SYMLINK3res(register XDR *xdrs, SYMLINK3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_SYMLINK3resok(xdrs, &objp->SYMLINK3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_SYMLINK3resfail(xdrs, &objp->SYMLINK3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_devicedata3(register XDR *xdrs, devicedata3 *objp)
-{
-    if (!xdr_sattr3(xdrs, &objp->dev_attributes))
-        return (FALSE);
-    if (!xdr_specdata3(xdrs, &objp->spec))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_mknoddata3(register XDR *xdrs, mknoddata3 *objp)
-{
-    if (!xdr_ftype3(xdrs, &objp->type))
-        return (FALSE);
-    switch (objp->type) {
-    case NFS3CHR:
-    case NFS3BLK:
-        if (!xdr_devicedata3(xdrs, &objp->mknoddata3_u.device))
-            return (FALSE);
-        break;
-    case NFS3SOCK:
-    case NFS3FIFO:
-        if (!xdr_sattr3(xdrs, &objp->mknoddata3_u.pipe_attributes))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_MKNOD3args(register XDR *xdrs, MKNOD3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->where))
-        return (FALSE);
-    if (!xdr_mknoddata3(xdrs, &objp->what))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_MKNOD3resok(register XDR *xdrs, MKNOD3resok *objp)
-{
-    if (!xdr_post_op_fh3(xdrs, &objp->obj))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_MKNOD3resfail(register XDR *xdrs, MKNOD3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_MKNOD3res(register XDR *xdrs, MKNOD3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_MKNOD3resok(xdrs, &objp->MKNOD3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_MKNOD3resfail(xdrs, &objp->MKNOD3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_REMOVE3args(register XDR *xdrs, REMOVE3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->object))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_REMOVE3resok(register XDR *xdrs, REMOVE3resok *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_REMOVE3resfail(register XDR *xdrs, REMOVE3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_REMOVE3res(register XDR *xdrs, REMOVE3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_REMOVE3resok(xdrs, &objp->REMOVE3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_REMOVE3resfail(xdrs, &objp->REMOVE3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_RMDIR3args(register XDR *xdrs, RMDIR3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->object))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_RMDIR3resok(register XDR *xdrs, RMDIR3resok *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_RMDIR3resfail(register XDR *xdrs, RMDIR3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_RMDIR3res(register XDR *xdrs, RMDIR3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_RMDIR3resok(xdrs, &objp->RMDIR3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_RMDIR3resfail(xdrs, &objp->RMDIR3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_RENAME3args(register XDR *xdrs, RENAME3args *objp)
-{
-    if (!xdr_diropargs3(xdrs, &objp->from))
-        return (FALSE);
-    if (!xdr_diropargs3(xdrs, &objp->to))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_RENAME3resok(register XDR *xdrs, RENAME3resok *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->fromdir_wcc))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->todir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_RENAME3resfail(register XDR *xdrs, RENAME3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->fromdir_wcc))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->todir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_RENAME3res(register XDR *xdrs, RENAME3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_RENAME3resok(xdrs, &objp->RENAME3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_RENAME3resfail(xdrs, &objp->RENAME3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_LINK3args(register XDR *xdrs, LINK3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->file))
-        return (FALSE);
-    if (!xdr_diropargs3(xdrs, &objp->link))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_LINK3resok(register XDR *xdrs, LINK3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->linkdir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_LINK3resfail(register XDR *xdrs, LINK3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
-        return (FALSE);
-    if (!xdr_wcc_data(xdrs, &objp->linkdir_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_LINK3res(register XDR *xdrs, LINK3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_LINK3resok(xdrs, &objp->LINK3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_LINK3resfail(xdrs, &objp->LINK3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIR3args(register XDR *xdrs, READDIR3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->dir))
-        return (FALSE);
-    if (!xdr_cookie3(xdrs, &objp->cookie))
-        return (FALSE);
-    if (!xdr_cookieverf3(xdrs, objp->cookieverf))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->count))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_entry3(register XDR *xdrs, entry3 *objp)
-{
-    if (!xdr_fileid3(xdrs, &objp->fileid))
-        return (FALSE);
-    if (!xdr_filename3(xdrs, &objp->name))
-        return (FALSE);
-    if (!xdr_cookie3(xdrs, &objp->cookie))
-        return (FALSE);
-    if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof (entry3), (xdrproc_t) xdr_entry3))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_dirlist3(register XDR *xdrs, dirlist3 *objp)
-{
-    if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof (entry3), (xdrproc_t) xdr_entry3))
-        return (FALSE);
-    if (!xdr_bool(xdrs, &objp->eof))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIR3resok(register XDR *xdrs, READDIR3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
-        return (FALSE);
-    if (!xdr_cookieverf3(xdrs, objp->cookieverf))
-        return (FALSE);
-    if (!xdr_dirlist3(xdrs, &objp->reply))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIR3resfail(register XDR *xdrs, READDIR3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIR3res(register XDR *xdrs, READDIR3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_READDIR3resok(xdrs, &objp->READDIR3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_READDIR3resfail(xdrs, &objp->READDIR3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIRPLUS3args(register XDR *xdrs, READDIRPLUS3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->dir))
-        return (FALSE);
-    if (!xdr_cookie3(xdrs, &objp->cookie))
-        return (FALSE);
-    if (!xdr_cookieverf3(xdrs, objp->cookieverf))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->dircount))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->maxcount))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_entryplus3(register XDR *xdrs, entryplus3 *objp)
-{
-    if (!xdr_fileid3(xdrs, &objp->fileid))
-        return (FALSE);
-    if (!xdr_filename3(xdrs, &objp->name))
-        return (FALSE);
-    if (!xdr_cookie3(xdrs, &objp->cookie))
-        return (FALSE);
-    if (!xdr_post_op_attr(xdrs, &objp->name_attributes))
-        return (FALSE);
-    if (!xdr_post_op_fh3(xdrs, &objp->name_handle))
-        return (FALSE);
-    if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof (entryplus3), (xdrproc_t) xdr_entryplus3))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_dirlistplus3(register XDR *xdrs, dirlistplus3 *objp)
-{
-    if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof (entryplus3), (xdrproc_t) xdr_entryplus3))
-        return (FALSE);
-    if (!xdr_bool(xdrs, &objp->eof))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIRPLUS3resok(register XDR *xdrs, READDIRPLUS3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
-        return (FALSE);
-    if (!xdr_cookieverf3(xdrs, objp->cookieverf))
-        return (FALSE);
-    if (!xdr_dirlistplus3(xdrs, &objp->reply))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIRPLUS3resfail(register XDR *xdrs, READDIRPLUS3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_READDIRPLUS3res(register XDR *xdrs, READDIRPLUS3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_READDIRPLUS3resok(xdrs, &objp->READDIRPLUS3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_READDIRPLUS3resfail(xdrs, &objp->READDIRPLUS3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_FSSTAT3args(register XDR *xdrs, FSSTAT3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->fsroot))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_FSSTAT3resok(register XDR *xdrs, FSSTAT3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->tbytes))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->fbytes))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->abytes))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->tfiles))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->ffiles))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->afiles))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->invarsec))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_FSSTAT3resfail(register XDR *xdrs, FSSTAT3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_FSSTAT3res(register XDR *xdrs, FSSTAT3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_FSSTAT3resok(xdrs, &objp->FSSTAT3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_FSSTAT3resfail(xdrs, &objp->FSSTAT3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_FSINFO3args(register XDR *xdrs, FSINFO3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->fsroot))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_FSINFO3resok(register XDR *xdrs, FSINFO3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->rtmax))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->rtpref))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->rtmult))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->wtmax))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->wtpref))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->wtmult))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->dtpref))
-        return (FALSE);
-    if (!xdr_size3(xdrs, &objp->maxfilesize))
-        return (FALSE);
-    if (!xdr_nfstime3(xdrs, &objp->time_delta))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->properties))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_FSINFO3resfail(register XDR *xdrs, FSINFO3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_FSINFO3res(register XDR *xdrs, FSINFO3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_FSINFO3resok(xdrs, &objp->FSINFO3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_FSINFO3resfail(xdrs, &objp->FSINFO3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_PATHCONF3args(register XDR *xdrs, PATHCONF3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->object))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_PATHCONF3resok(register XDR *xdrs, PATHCONF3resok *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->linkmax))
-        return (FALSE);
-    if (!xdr_uint32(xdrs, &objp->name_max))
-        return (FALSE);
-    if (!xdr_bool(xdrs, &objp->no_trunc))
-        return (FALSE);
-    if (!xdr_bool(xdrs, &objp->chown_restricted))
-        return (FALSE);
-    if (!xdr_bool(xdrs, &objp->case_insensitive))
-        return (FALSE);
-    if (!xdr_bool(xdrs, &objp->case_preserving))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_PATHCONF3resfail(register XDR *xdrs, PATHCONF3resfail *objp)
-{
-    if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_PATHCONF3res(register XDR *xdrs, PATHCONF3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_PATHCONF3resok(xdrs, &objp->PATHCONF3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_PATHCONF3resfail(xdrs, &objp->PATHCONF3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}
-
-bool_t
-xdr_COMMIT3args(register XDR *xdrs, COMMIT3args *objp)
-{
-    if (!xdr_nfs_fh3(xdrs, &objp->file))
-        return (FALSE);
-    if (!xdr_offset3(xdrs, &objp->offset))
-        return (FALSE);
-    if (!xdr_count3(xdrs, &objp->count))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_COMMIT3resok(register XDR *xdrs, COMMIT3resok *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->file_wcc))
-        return (FALSE);
-    if (!xdr_writeverf3(xdrs, objp->verf))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_COMMIT3resfail(register XDR *xdrs, COMMIT3resfail *objp)
-{
-    if (!xdr_wcc_data(xdrs, &objp->file_wcc))
-        return (FALSE);
-    return (TRUE);
-}
-
-bool_t
-xdr_COMMIT3res(register XDR *xdrs, COMMIT3res *objp)
-{
-    if (!xdr_nfsstat3(xdrs, &objp->status))
-        return (FALSE);
-    switch (objp->status) {
-    case NFS3_OK:
-        if (!xdr_COMMIT3resok(xdrs, &objp->COMMIT3res_u.resok))
-            return (FALSE);
-        break;
-    default:
-        if (!xdr_COMMIT3resfail(xdrs, &objp->COMMIT3res_u.resfail))
-            return (FALSE);
-        break;
-    }
-    return (TRUE);
-}

+ 0 - 112
components/dfs/dfs_v2/filesystems/nfs/rpc/auth.h

@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-#ifndef __AUTH_H__
-#define __AUTH_H__
-
-#include <rpc/xdr.h>
-
-/*
- * Status returned from authentication check
- */
-enum auth_stat {
-    AUTH_OK=0,
-    /*
-     * failed at remote end
-     */
-    AUTH_BADCRED=1,         /* bogus credentials (seal broken) */
-    AUTH_REJECTEDCRED=2,        /* client should begin new session */
-    AUTH_BADVERF=3,         /* bogus verifier (seal broken) */
-    AUTH_REJECTEDVERF=4,        /* verifier expired or was replayed */
-    AUTH_TOOWEAK=5,         /* rejected due to security reasons */
-    /*
-     * failed locally
-    */
-    AUTH_INVALIDRESP=6,     /* bogus response verifier */
-    AUTH_FAILED=7           /* some unknown reason */
-};
-
-union des_block {
-    struct {
-        uint32_t high;
-        uint32_t low;
-    } key;
-    char c[8];
-};
-typedef union des_block des_block;
-
-/*
- * Authentication info.  Opaque to client.
- */
-struct opaque_auth {
-    enum_t  oa_flavor;      /* flavor of auth */
-    char*   oa_base;        /* address of more auth stuff */
-    unsigned int    oa_length;      /* not to exceed MAX_AUTH_BYTES */
-};
-
-/*
- * Auth handle, interface to client side authenticators.
- */
-typedef struct AUTH AUTH;
-struct AUTH {
-  struct opaque_auth ah_cred;
-  struct opaque_auth ah_verf;
-  union des_block ah_key;
-  struct auth_ops {
-    void (*ah_nextverf) (AUTH *);
-    int  (*ah_marshal) (AUTH *, XDR *);     /* nextverf & serialize */
-    int  (*ah_validate) (AUTH *, struct opaque_auth *);
-                        /* validate verifier */
-    int  (*ah_refresh) (AUTH *);        /* refresh credentials */
-    void (*ah_destroy) (AUTH *);            /* destroy this structure */
-  } *ah_ops;
-  char* ah_private;
-};
-
-extern struct opaque_auth _null_auth;
-
-
-/*
- * Authentication ops.
- * The ops and the auth handle provide the interface to the authenticators.
- *
- * AUTH *auth;
- * XDR  *xdrs;
- * struct opaque_auth verf;
- */
-#define AUTH_NEXTVERF(auth)     \
-        ((*((auth)->ah_ops->ah_nextverf))(auth))
-#define auth_nextverf(auth)     \
-        ((*((auth)->ah_ops->ah_nextverf))(auth))
-
-#define AUTH_MARSHALL(auth, xdrs)   \
-        ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
-#define auth_marshall(auth, xdrs)   \
-        ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
-
-#define AUTH_VALIDATE(auth, verfp)  \
-        ((*((auth)->ah_ops->ah_validate))((auth), verfp))
-#define auth_validate(auth, verfp)  \
-        ((*((auth)->ah_ops->ah_validate))((auth), verfp))
-
-#define AUTH_REFRESH(auth)      \
-        ((*((auth)->ah_ops->ah_refresh))(auth))
-#define auth_refresh(auth)      \
-        ((*((auth)->ah_ops->ah_refresh))(auth))
-
-#define AUTH_DESTROY(auth)      \
-        ((*((auth)->ah_ops->ah_destroy))(auth))
-#define auth_destroy(auth)      \
-        ((*((auth)->ah_ops->ah_destroy))(auth))
-
-#define MAX_AUTH_BYTES  400
-#define MAXNETNAMELEN   255 /* maximum length of network user's name */
-
-AUTH *authnone_create(void);
-
-#endif

+ 0 - 135
components/dfs/dfs_v2/filesystems/nfs/rpc/auth_none.c

@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)auth_none.c  2.1 88/07/29 4.0 RPCSRC */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] =
-
-    "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
-#endif
-
-/*
- * auth_none.c
- * Creates a client authentication handle for passing "null"
- * credentials and verifiers to remote systems.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <rpc/auth.h>
-#define MAX_MARSHEL_SIZE 20
-
-static void authnone_verf(AUTH *);
-static bool_t authnone_validate(AUTH *, struct opaque_auth *);
-static bool_t authnone_refresh(AUTH *);
-static void authnone_destroy(AUTH *);
-static bool_t authnone_marshal(AUTH *client, XDR *xdrs);
-
-struct opaque_auth _null_auth;
-
-static struct auth_ops ops = {
-    authnone_verf,
-    authnone_marshal,
-    authnone_validate,
-    authnone_refresh,
-    authnone_destroy
-};
-
-static struct authnone_private {
-    AUTH no_client;
-    char marshalled_client[MAX_MARSHEL_SIZE];
-    unsigned int mcnt;
-} *authnone_private;
-
-AUTH *authnone_create()
-{
-    register struct authnone_private *ap = authnone_private;
-    XDR xdr_stream;
-    register XDR *xdrs;
-    extern bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap);
-
-    if (ap == 0) {
-        ap = (struct authnone_private *) rt_malloc (sizeof(*ap));
-        if (ap == 0) return NULL;
-        memset(ap, 0, sizeof(*ap));
-        authnone_private = ap;
-    }
-    if (!ap->mcnt) {
-        ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
-        ap->no_client.ah_ops = &ops;
-        xdrs = &xdr_stream;
-        xdrmem_create(xdrs, ap->marshalled_client,
-                      (unsigned int) MAX_MARSHEL_SIZE, XDR_ENCODE);
-        (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
-        (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
-        ap->mcnt = XDR_GETPOS(xdrs);
-        XDR_DESTROY(xdrs);
-    }
-    return (&ap->no_client);
-}
-
-/*ARGSUSED*/
-static bool_t authnone_marshal(AUTH *client, XDR *xdrs)
-{
-    register struct authnone_private *ap = authnone_private;
-
-    if (ap == 0)
-        return (0);
-    return ((*xdrs->x_ops->x_putbytes) (xdrs,
-                                        ap->marshalled_client, ap->mcnt));
-}
-
-static void authnone_verf(AUTH *x)
-{
-}
-
-static bool_t authnone_validate(AUTH *x, struct opaque_auth *x1)
-{
-
-    return (TRUE);
-}
-
-static bool_t authnone_refresh(AUTH *x)
-{
-
-    return (FALSE);
-}
-
-static void authnone_destroy(AUTH *x)
-{
-}

+ 0 - 330
components/dfs/dfs_v2/filesystems/nfs/rpc/clnt.h

@@ -1,330 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)clnt.h   2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-
-/*
- * clnt.h - Client side remote procedure call interface.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
-#ifndef _RPC_CLNT_H
-#define _RPC_CLNT_H 1
-
-#include <rpc/types.h>
-#include <rpc/auth.h>
-#include <lwip/sockets.h>
-
-/*
- * Rpc calls return an enum clnt_stat.  This should be looked at more,
- * since each implementation is required to live with this (implementation
- * independent) list of errors.
- */
-enum clnt_stat {
-    RPC_SUCCESS=0,          /* call succeeded */
-    /*
-     * local errors
-     */
-    RPC_CANTENCODEARGS=1,       /* can't encode arguments */
-    RPC_CANTDECODERES=2,        /* can't decode results */
-    RPC_CANTSEND=3,         /* failure in sending call */
-    RPC_CANTRECV=4,         /* failure in receiving result */
-    RPC_TIMEDOUT=5,         /* call timed out */
-    /*
-     * remote errors
-     */
-    RPC_VERSMISMATCH=6,     /* rpc versions not compatible */
-    RPC_AUTHERROR=7,        /* authentication error */
-    RPC_PROGUNAVAIL=8,      /* program not available */
-    RPC_PROGVERSMISMATCH=9,     /* program version mismatched */
-    RPC_PROCUNAVAIL=10,     /* procedure unavailable */
-    RPC_CANTDECODEARGS=11,      /* decode arguments error */
-    RPC_SYSTEMERROR=12,     /* generic "other problem" */
-    RPC_NOBROADCAST = 21,       /* Broadcasting not supported */
-    /*
-     * callrpc & clnt_create errors
-     */
-    RPC_UNKNOWNHOST=13,     /* unknown host name */
-    RPC_UNKNOWNPROTO=17,        /* unknown protocol */
-    RPC_UNKNOWNADDR = 19,       /* Remote address unknown */
-
-    /*
-     * rpcbind errors
-     */
-    RPC_RPCBFAILURE=14,     /* portmapper failed in its call */
-#define RPC_PMAPFAILURE RPC_RPCBFAILURE
-    RPC_PROGNOTREGISTERED=15,   /* remote program is not registered */
-    RPC_N2AXLATEFAILURE = 22,   /* Name to addr translation failed */
-    /*
-     * unspecified error
-     */
-    RPC_FAILED=16,
-    RPC_INTR=18,
-    RPC_TLIERROR=20,
-    RPC_UDERROR=23,
-        /*
-         * asynchronous errors
-         */
-        RPC_INPROGRESS = 24,
-        RPC_STALERACHANDLE = 25
-};
-
-
-/*
- * Error info.
- */
-struct rpc_err {
-  int re_status;
-  union {
-    int RE_errno;       /* related system error */
-    int RE_why; /* why the auth error occurred */
-    struct {
-      unsigned long low;        /* lowest verion supported */
-      unsigned long high;       /* highest verion supported */
-    } RE_vers;
-    struct {            /* maybe meaningful if RPC_FAILED */
-      long s1;
-      long s2;
-    } RE_lb;            /* life boot & debugging only */
-  } ru;
-#define re_errno    ru.RE_errno
-#define re_why      ru.RE_why
-#define re_vers     ru.RE_vers
-#define re_lb       ru.RE_lb
-};
-
-
-/*
- * Client rpc handle.
- * Created by individual implementations, see e.g. rpc_udp.c.
- * Client is responsible for initializing auth, see e.g. auth_none.c.
- */
-typedef struct CLIENT CLIENT;
-struct CLIENT {
-  AUTH  *cl_auth;        /* authenticator */
-  struct clnt_ops {
-    enum clnt_stat (*cl_call) (CLIENT *, unsigned long, xdrproc_t, char*, xdrproc_t,
-                   char*, struct timeval);
-                    /* call remote procedure */
-    void (*cl_abort) (void);    /* abort a call */
-    void (*cl_geterr) (CLIENT *, struct rpc_err *);
-                /* get specific error code */
-    bool_t (*cl_freeres) (CLIENT *, xdrproc_t, char*);
-                /* frees results */
-    void (*cl_destroy) (CLIENT *); /* destroy this structure */
-    bool_t (*cl_control) (CLIENT *, int, char *);
-                /* the ioctl() of rpc */
-  } *cl_ops;
-  char* cl_private;     /* private stuff */
-};
-
-
-/*
- * client side rpc interface ops
- *
- * Parameter types are:
- *
- */
-
-/*
- * enum clnt_stat
- * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
- *  CLIENT *rh;
- *  unsigned long proc;
- *  xdrproc_t xargs;
- *  char* argsp;
- *  xdrproc_t xres;
- *  char* resp;
- *  struct timeval timeout;
- */
-#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
-    ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
-#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
-    ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
-
-/*
- * void
- * CLNT_ABORT(rh);
- *  CLIENT *rh;
- */
-#define CLNT_ABORT(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
-#define clnt_abort(rh)  ((*(rh)->cl_ops->cl_abort)(rh))
-
-/*
- * struct rpc_err
- * CLNT_GETERR(rh);
- *  CLIENT *rh;
- */
-#define CLNT_GETERR(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
-#define clnt_geterr(rh,errp)    ((*(rh)->cl_ops->cl_geterr)(rh, errp))
-
-
-/*
- * bool_t
- * CLNT_FREERES(rh, xres, resp);
- *  CLIENT *rh;
- *  xdrproc_t xres;
- *  char* resp;
- */
-#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
-#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
-
-/*
- * bool_t
- * CLNT_CONTROL(cl, request, info)
- *      CLIENT *cl;
- *      unsigned int request;
- *      char *info;
- */
-#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
-#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
-
-/*
- * control operations that apply to all transports
- *
- * Note: options marked XXX are no-ops in this implementation of RPC.
- * The are present in TI-RPC but can't be implemented here since they
- * depend on the presence of STREAMS/TLI, which we don't have.
- */
-#define CLSET_TIMEOUT        1    /* set timeout (timeval) */
-#define CLGET_TIMEOUT        2    /* get timeout (timeval) */
-#define CLGET_SERVER_ADDR    3    /* get server's address (sockaddr) */
-#define CLGET_FD             6    /* get connections file descriptor */
-#define CLGET_SVC_ADDR       7    /* get server's address (netbuf)      XXX */
-#define CLSET_FD_CLOSE       8    /* close fd while clnt_destroy */
-#define CLSET_FD_NCLOSE      9    /* Do not close fd while clnt_destroy*/
-#define CLGET_XID            10   /* Get xid */
-#define CLSET_XID            11   /* Set xid */
-#define CLGET_VERS           12   /* Get version number */
-#define CLSET_VERS           13   /* Set version number */
-#define CLGET_PROG           14   /* Get program number */
-#define CLSET_PROG           15   /* Set program number */
-#define CLSET_SVC_ADDR       16   /* get server's address (netbuf)      XXX */
-#define CLSET_PUSH_TIMOD     17   /* push timod if not already present  XXX */
-#define CLSET_POP_TIMOD      18   /* pop timod                          XXX */
-/*
- * Connectionless only control operations
- */
-#define CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
-#define CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */
-
-/*
- * void
- * CLNT_DESTROY(rh);
- *  CLIENT *rh;
- */
-#define CLNT_DESTROY(rh)    ((*(rh)->cl_ops->cl_destroy)(rh))
-#define clnt_destroy(rh)    ((*(rh)->cl_ops->cl_destroy)(rh))
-
-
-/*
- * RPCTEST is a test program which is accessible on every rpc
- * transport/port.  It is used for testing, performance evaluation,
- * and network administration.
- */
-
-#define RPCTEST_PROGRAM     ((unsigned long)1)
-#define RPCTEST_VERSION     ((unsigned long)1)
-#define RPCTEST_NULL_PROC   ((unsigned long)2)
-#define RPCTEST_NULL_BATCH_PROC ((unsigned long)3)
-
-/*
- * By convention, procedure 0 takes null arguments and returns them
- */
-
-#define NULLPROC ((unsigned long)0)
-
-/*
- * Below are the client handle creation routines for the various
- * implementations of client side rpc.  They can return NULL if a
- * creation failure occurs.
- */
-
-/*
- * Generic client creation routine. Supported protocols are "udp", "tcp" and
- * "unix"
- * CLIENT *
- * clnt_create(host, prog, vers, prot)
- *  char *host;     -- hostname
- *  unsigned long prog; -- program number
- *  u_ong vers; -- version number
- *  char *prot; -- protocol
- */
-extern CLIENT *clnt_create (const char *__host, const unsigned long __prog,
-                const unsigned long __vers, const char *__prot)
-    ;
-
-/*
- * UDP based rpc.
- * CLIENT *
- * clntudp_create(raddr, program, version, wait, sockp)
- *  struct sockaddr_in *raddr;
- *  unsigned long program;
- *  unsigned long version;
- *  struct timeval wait_resend;
- *  int *sockp;
- *
- * Same as above, but you specify max packet sizes.
- * CLIENT *
- * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
- *  struct sockaddr_in *raddr;
- *  unsigned long program;
- *  unsigned long version;
- *  struct timeval wait_resend;
- *  int *sockp;
- *  unsigned int sendsz;
- *  unsigned int recvsz;
- */
-extern CLIENT *clntudp_create (struct sockaddr_in *__raddr, unsigned long __program,
-                   unsigned long __version, struct timeval __wait_resend,
-                   int *__sockp);
-extern CLIENT *clntudp_bufcreate (struct sockaddr_in *__raddr,
-                  unsigned long __program, unsigned long __version,
-                  struct timeval __wait_resend, int *__sockp,
-                  unsigned int __sendsz, unsigned int __recvsz);
-
-extern int callrpc (const char *__host, const unsigned long __prognum,
-            const unsigned long __versnum, const unsigned long __procnum,
-            const xdrproc_t __inproc, const char *__in,
-            const xdrproc_t __outproc, char *__out);
-
-#define UDPMSGSIZE  8800    /* rpc imposed limit on udp msg size */
-#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
-
-void clnt_perror(CLIENT *rpch, const char *s);
-
-#endif /* rpc/clnt.h */

+ 0 - 95
components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_generic.c

@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)clnt_generic.c   2.2 88/08/01 4.0 RPCSRC */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";
-#endif
-/*
- * Copyright (C) 1987, Sun Microsystems, Inc.
- */
-#include <rpc/rpc.h>
-#include <string.h>
-
-/*
- * Generic client creation: takes (hostname, program-number, protocol) and
- * returns client handle. Default options are set, which the user can
- * change using the rpc equivalent of ioctl()'s.
- */
-CLIENT *clnt_create(const char *hostname, const unsigned long prog,
-                    const unsigned long vers, const char *proto)
-{
-    int sock;
-    struct sockaddr_in server;
-    struct addrinfo hint, *res = NULL;
-    struct timeval tv;
-    CLIENT *client;
-    int ret;
-
-    memset(&hint, 0, sizeof(hint));
-    ret = getaddrinfo(hostname, NULL, &hint, &res);
-    if (ret != 0)
-    {
-        rt_kprintf("getaddrinfo err: %d '%s'\n", ret, hostname);
-        return NULL;
-    }
-
-    memcpy(&server, res->ai_addr, sizeof(struct sockaddr_in));
-    freeaddrinfo(res);
-
-    sock = -1;
-    if (strcmp(proto, "udp") == 0)
-    {
-        tv.tv_sec = 5;
-        tv.tv_usec = 0;
-        client = clntudp_create(&server, prog, vers, tv, &sock);
-        if (client == NULL) return NULL;
-        tv.tv_sec = 1;
-        clnt_control(client, CLSET_TIMEOUT, (char *)&tv);
-    }
-    else
-    {
-        rt_kprintf("unknow protocol\n");
-        return NULL;
-    }
-
-    return (client);
-}
-
-void clnt_perror(CLIENT *rpch, const char *s)
-{
-    rt_kprintf("rpc client error:%s\n", s);
-}

+ 0 - 406
components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_udp.c

@@ -1,406 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)clnt_udp.c   2.2 88/08/01 4.0 RPCSRC */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
-#endif
-
-/*
- * clnt_udp.c, Implements a UDP/IP based, client side RPC.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
-#include <stdio.h>
-#include <rpc/rpc.h>
-#include <rtthread.h>
-
-/*
- * UDP bases client side rpc operations
- */
-static enum clnt_stat clntudp_call(register CLIENT *cl,         /* client handle */
-    unsigned long proc,          /* procedure number */
-    xdrproc_t xargs,             /* xdr routine for args */
-    char* argsp,                 /* pointer to args */
-    xdrproc_t xresults,          /* xdr routine for results */
-    char* resultsp,              /* pointer to results */
-    struct timeval utimeout);
-
-static void clntudp_abort(void);
-static void clntudp_geterr(CLIENT *, struct rpc_err *);
-static bool_t clntudp_freeres(CLIENT *, xdrproc_t, char*);
-static bool_t clntudp_control(CLIENT *, int, char *);
-static void clntudp_destroy(CLIENT *);
-
-static struct clnt_ops udp_ops =
-{
-    clntudp_call,
-    clntudp_abort,
-    clntudp_geterr,
-    clntudp_freeres,
-    clntudp_destroy,
-    clntudp_control
-};
-
-/*
- * Private data kept per client handle
- */
-struct cu_data
-{
-    int cu_sock;
-    bool_t cu_closeit;
-    struct sockaddr_in cu_raddr;
-    int cu_rlen;
-    struct timeval cu_wait;
-    struct timeval cu_total;
-    struct rpc_err cu_error;
-    XDR cu_outxdrs;
-    unsigned int cu_xdrpos;
-    unsigned int cu_sendsz;
-    char *cu_outbuf;
-    unsigned int cu_recvsz;
-    char cu_inbuf[1];
-};
-
-/*
- * Create a UDP based client handle.
- * If *sockp<0, *sockp is set to a newly created UPD socket.
- * If raddr->sin_port is 0 a binder on the remote machine
- * is consulted for the correct port number.
- * NB: It is the clients responsibility to close *sockp.
- * NB: The rpch->cl_auth is initialized to null authentication.
- *     Caller may wish to set this something more useful.
- *
- * wait is the amount of time used between retransmitting a call if
- * no response has been heard;  retransmition occurs until the actual
- * rpc call times out.
- *
- * sendsz and recvsz are the maximum allowable packet sizes that can be
- * sent and received.
- */
-CLIENT *clntudp_bufcreate(struct sockaddr_in *raddr,
-    unsigned long program,
-    unsigned long version,
-    struct timeval wait,
-    int *sockp,
-    unsigned int sendsz,
-    unsigned int recvsz)
-{
-    CLIENT *cl;
-    register struct cu_data *cu = NULL;
-    struct rpc_msg call_msg;
-    static int xid_count = 0;
-
-    cl = (CLIENT *) rt_malloc (sizeof(CLIENT));
-    if (cl == NULL)
-    {
-        rt_kprintf("clntudp_create: out of memory\n");
-        goto fooy;
-    }
-    sendsz = ((sendsz + 3) / 4) * 4;
-    recvsz = ((recvsz + 3) / 4) * 4;
-    cu = (struct cu_data *) rt_malloc (sizeof(*cu) + sendsz + recvsz);
-    if (cu == NULL)
-    {
-        rt_kprintf("clntudp_create: out of memory\n");
-        goto fooy;
-    }
-    cu->cu_outbuf = &cu->cu_inbuf[recvsz];
-
-    if (raddr->sin_port == 0) {
-        unsigned short port;
-        extern unsigned short pmap_getport(struct sockaddr_in *address,
-            unsigned long program,
-            unsigned long version,
-            unsigned int protocol);
-
-        if ((port =
-             pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
-            rt_kprintf("pmap_getport failure\n");
-            goto fooy;
-        }
-        raddr->sin_port = htons(port);
-    }
-
-    cl->cl_ops = &udp_ops;
-    cl->cl_private = (char*) cu;
-    cu->cu_raddr = *raddr;
-    cu->cu_rlen = sizeof(cu->cu_raddr);
-    cu->cu_wait = wait;
-    cu->cu_total.tv_sec = -1;
-    cu->cu_total.tv_usec = -1;
-    cu->cu_sendsz = sendsz;
-    cu->cu_recvsz = recvsz;
-    call_msg.rm_xid = (uint32_t)(((unsigned long)rt_thread_self()) ^ ((unsigned long)rt_tick_get()) ^ (xid_count++));
-    call_msg.rm_direction = CALL;
-    call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
-    call_msg.rm_call.cb_prog = program;
-    call_msg.rm_call.cb_vers = version;
-    xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
-    if (!xdr_callhdr(&(cu->cu_outxdrs), &call_msg))
-    {
-        rt_kprintf("xdr_callhdr failure\n");
-        goto fooy;
-    }
-    cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
-    if (*sockp < 0)
-    {
-        *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-        if (*sockp < 0)
-        {
-            rt_kprintf("create socket error\n");
-            goto fooy;
-        }
-        cu->cu_closeit = TRUE;
-    }
-    else
-    {
-        cu->cu_closeit = FALSE;
-    }
-    cu->cu_sock = *sockp;
-    cl->cl_auth = authnone_create();
-    return (cl);
-
-fooy:
-    if (cu) rt_free(cu);
-    if (cl) rt_free(cl);
-
-    return ((CLIENT *) NULL);
-}
-
-CLIENT *clntudp_create(struct sockaddr_in *raddr,
-    unsigned long program,
-    unsigned long version,
-    struct timeval wait,
-    int *sockp)
-{
-    return (clntudp_bufcreate(raddr, program, version, wait, sockp,
-                              UDPMSGSIZE, UDPMSGSIZE));
-}
-
-static enum clnt_stat clntudp_call(CLIENT *cl, unsigned long proc,
-    xdrproc_t xargs, char* argsp,
-    xdrproc_t xresults, char* resultsp,
-    struct timeval utimeout)
-{
-    register struct cu_data *cu = (struct cu_data *) cl->cl_private;
-    register XDR *xdrs;
-    register int outlen;
-    register int inlen;
-    socklen_t fromlen;
-
-    struct sockaddr_in from;
-    struct rpc_msg reply_msg;
-    XDR reply_xdrs;
-    bool_t ok;
-    int nrefreshes = 2;         /* number of times to refresh cred */
-
-call_again:
-    xdrs = &(cu->cu_outxdrs);
-    xdrs->x_op = XDR_ENCODE;
-    XDR_SETPOS(xdrs, cu->cu_xdrpos);
-
-    /*
-     * the transaction is the first thing in the out buffer
-     */
-    (*(unsigned long *) (cu->cu_outbuf))++;
-
-    if ((!XDR_PUTLONG(xdrs, (long *) &proc)) ||
-            (!AUTH_MARSHALL(cl->cl_auth, xdrs)) || (!(*xargs) (xdrs, argsp)))
-    {
-        cu->cu_error.re_status = RPC_CANTENCODEARGS;
-        return RPC_CANTENCODEARGS;
-    }
-    outlen = (int) XDR_GETPOS(xdrs);
-
-send_again:
-    if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
-               (struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)
-            != outlen)
-    {
-        cu->cu_error.re_errno = errno;
-        cu->cu_error.re_status = RPC_CANTSEND;
-
-        return RPC_CANTSEND;
-    }
-
-    /*
-     * sub-optimal code appears here because we have
-     * some clock time to spare while the packets are in flight.
-     * (We assume that this is actually only executed once.)
-     */
-    reply_msg.acpted_rply.ar_verf = _null_auth;
-    reply_msg.acpted_rply.ar_results.where = resultsp;
-    reply_msg.acpted_rply.ar_results.proc = xresults;
-
-    /* do recv */
-    do
-    {
-        fromlen = sizeof(struct sockaddr);
-
-        inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
-                         (int) cu->cu_recvsz, 0,
-                         (struct sockaddr *) &from, &fromlen);
-    }while (inlen < 0 && errno == EINTR);
-
-    if (inlen < 4)
-    {
-        rt_kprintf("recv error, len %d\n", inlen);
-        cu->cu_error.re_errno = errno;
-        cu->cu_error.re_status = RPC_CANTRECV;
-
-        return RPC_CANTRECV;
-    }
-
-    /* see if reply transaction id matches sent id */
-    if (*((uint32_t *) (cu->cu_inbuf)) != *((uint32_t *) (cu->cu_outbuf)))
-        goto send_again;
-
-    /* we now assume we have the proper reply */
-
-    /*
-     * now decode and validate the response
-     */
-    xdrmem_create(&reply_xdrs, cu->cu_inbuf, (unsigned int) inlen, XDR_DECODE);
-    ok = xdr_replymsg(&reply_xdrs, &reply_msg);
-    /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
-    if (ok)
-    {
-        _seterr_reply(&reply_msg, &(cu->cu_error));
-        if (cu->cu_error.re_status == RPC_SUCCESS)
-        {
-            if (!AUTH_VALIDATE(cl->cl_auth,
-                               &reply_msg.acpted_rply.ar_verf))
-            {
-                cu->cu_error.re_status = RPC_AUTHERROR;
-                cu->cu_error.re_why = AUTH_INVALIDRESP;
-            }
-            if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
-            {
-                extern bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap);
-
-                xdrs->x_op = XDR_FREE;
-                (void) xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
-            }
-        } /* end successful completion */
-        else
-        {
-            /* maybe our credentials need to be refreshed ... */
-            if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth))
-            {
-                nrefreshes--;
-                goto call_again;
-            }
-        } /* end of unsuccessful completion */
-    } /* end of valid reply message */
-    else
-    {
-        cu->cu_error.re_status = RPC_CANTDECODERES;
-    }
-
-    return (enum clnt_stat)(cu->cu_error.re_status);
-}
-
-static void clntudp_geterr(CLIENT *cl, struct rpc_err *errp)
-{
-    register struct cu_data *cu = (struct cu_data *) cl->cl_private;
-
-    *errp = cu->cu_error;
-}
-
-static bool_t clntudp_freeres(CLIENT *cl, xdrproc_t xdr_res, char* res_ptr)
-{
-    register struct cu_data *cu = (struct cu_data *) cl->cl_private;
-    register XDR *xdrs = &(cu->cu_outxdrs);
-
-    xdrs->x_op = XDR_FREE;
-    return ((*xdr_res) (xdrs, res_ptr));
-}
-
-static void clntudp_abort()
-{
-}
-
-static bool_t clntudp_control(CLIENT *cl, int request, char *info)
-{
-    register struct cu_data *cu = (struct cu_data *) cl->cl_private;
-
-    switch (request)
-    {
-    case CLSET_TIMEOUT:
-        {
-        int mtimeout;
-
-        cu->cu_total = *(struct timeval *) info;
-        mtimeout = ((cu->cu_total.tv_sec * 1000) + ((cu->cu_total.tv_usec + 500)/1000));
-
-        /* set socket option, note: lwip only support msecond timeout */
-        setsockopt(cu->cu_sock, SOL_SOCKET, SO_RCVTIMEO,
-            &mtimeout, sizeof(mtimeout));
-        }
-        break;
-    case CLGET_TIMEOUT:
-        *(struct timeval *) info = cu->cu_total;
-        break;
-    case CLSET_RETRY_TIMEOUT:
-        cu->cu_wait = *(struct timeval *) info;
-        break;
-    case CLGET_RETRY_TIMEOUT:
-        *(struct timeval *) info = cu->cu_wait;
-        break;
-    case CLGET_SERVER_ADDR:
-        *(struct sockaddr_in *) info = cu->cu_raddr;
-        break;
-    default:
-        return (FALSE);
-    }
-    return (TRUE);
-}
-
-static void clntudp_destroy(CLIENT *cl)
-{
-    register struct cu_data *cu = (struct cu_data *) cl->cl_private;
-
-    if (cu->cu_closeit)
-    {
-        lwip_close(cu->cu_sock);
-    }
-
-    XDR_DESTROY(&(cu->cu_outxdrs));
-    rt_free(cu);
-    rt_free(cl);
-}

+ 0 - 62
components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.c

@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-#include "pmap.h"
-#include "clnt.h"
-#include <rpc/rpc.h>
-
-static struct timeval timeout = { 5, 0 };
-static struct timeval tottimeout = { 60, 0 };
-
-
-bool_t xdr_pmap(XDR *xdrs, struct pmap *regs)
-{
-    if (xdr_u_long(xdrs, &regs->pm_prog) &&
-        xdr_u_long(xdrs, &regs->pm_vers) &&
-        xdr_u_long(xdrs, &regs->pm_prot))
-            return (xdr_u_long(xdrs, &regs->pm_port));
-    return (FALSE);
-}
-
-/*
- * Find the mapped port for program,version.
- * Calls the pmap service remotely to do the lookup.
- * Returns 0 if no map exists.
- */
-unsigned short pmap_getport(struct sockaddr_in *address, unsigned long program, unsigned long version, unsigned int protocol)
-{
-    unsigned short port = 0;
-    int socket = -1;
-    register CLIENT *client = RT_NULL;
-    struct pmap parms;
-
-    address->sin_port = htons((unsigned short)PMAPPORT);
-    if (protocol == IPPROTO_UDP)
-      client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout,
-                                  &socket, RPCSMALLMSGSIZE,
-                               RPCSMALLMSGSIZE);
-
-    if (client != (CLIENT *) NULL)
-    {
-        parms.pm_prog = program;
-        parms.pm_vers = version;
-        parms.pm_prot = protocol;
-        parms.pm_port = 0;      /* not needed or used */
-        if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, (char*)&parms,
-                      (xdrproc_t)xdr_u_short, (char*)&port, tottimeout) != RPC_SUCCESS)
-        {
-            rt_kprintf("pmap failure\n");
-        }
-        CLNT_DESTROY(client);
-    }
-
-    (void) lwip_close(socket);
-    address->sin_port = 0;
-
-    return (port);
-}

+ 0 - 66
components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.h

@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-#ifndef __RPC_PMAP_PROT_H__
-#define __RPC_PMAP_PROT_H__
-
-#include <rpc/xdr.h>
-
-/* The following procedures are supported by the protocol:
- *
- * PMAPPROC_NULL() returns ()
- *  takes nothing, returns nothing
- *
- * PMAPPROC_SET(struct pmap) returns (bool_t)
- *  TRUE is success, FALSE is failure.  Registers the tuple
- *  [prog, vers, prot, port].
- *
- * PMAPPROC_UNSET(struct pmap) returns (bool_t)
- *  TRUE is success, FALSE is failure.  Un-registers pair
- *  [prog, vers].  prot and port are ignored.
- *
- * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
- *  0 is failure.  Otherwise returns the port number where the pair
- *  [prog, vers] is registered.  It may lie!
- *
- * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
- *
- * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
- *  RETURNS (port, string<>);
- * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
- *  Calls the procedure on the local machine.  If it is not registered,
- *  this procedure is quite; ie it does not return error information!!!
- *  This procedure only is supported on rpc/udp and calls via
- *  rpc/udp.  This routine only passes null authentication parameters.
- *  This file has no interface to xdr routines for PMAPPROC_CALLIT.
- *
- * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
- */
-
-#define PMAPPORT        ((unsigned short)111)
-#define PMAPPROG        ((unsigned long)100000)
-#define PMAPVERS        ((unsigned long)2)
-#define PMAPVERS_PROTO      ((unsigned long)2)
-#define PMAPVERS_ORIG       ((unsigned long)1)
-#define PMAPPROC_NULL       ((unsigned long)0)
-#define PMAPPROC_SET        ((unsigned long)1)
-#define PMAPPROC_UNSET      ((unsigned long)2)
-#define PMAPPROC_GETPORT    ((unsigned long)3)
-#define PMAPPROC_DUMP       ((unsigned long)4)
-#define PMAPPROC_CALLIT     ((unsigned long)5)
-
-struct pmap {
-    long unsigned pm_prog;
-    long unsigned pm_vers;
-    long unsigned pm_prot;
-    long unsigned pm_port;
-};
-
-extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs);
-
-#endif

+ 0 - 62
components/dfs/dfs_v2/filesystems/nfs/rpc/rpc.h

@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)rpc.h    2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-
-/*
- * rpc.h, Just includes the billions of rpc header files necessary to
- * do remote procedure calling.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
-#ifndef _RPC_RPC_H
-#define _RPC_RPC_H 1
-
-#include <rpc/types.h>      /* some typedefs */
-
-/* external data representation interfaces */
-#include <rpc/xdr.h>        /* generic (de)serializer */
-
-#include <rpc/auth.h>
-
-/* Client side (mostly) remote procedure call */
-#include <rpc/clnt.h>       /* generic rpc stuff */
-
-/* semi-private protocol headers */
-#include <rpc/rpc_msg.h>    /* protocol for rpc messages */
-
-#endif

+ 0 - 203
components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_msg.h

@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)rpc_msg.h    2.1 88/07/29 4.0 RPCSRC */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-/*      @(#)rpc_msg.h 1.7 86/07/16 SMI      */
-
-#ifndef _RPC_MSG_H
-#define _RPC_MSG_H 1
-
-#include <rpc/xdr.h>
-#include <rpc/clnt.h>
-
-/*
- * rpc_msg.h
- * rpc message definition
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
-#define RPC_MSG_VERSION     ((unsigned long) 2)
-#define RPC_SERVICE_PORT    ((unsigned short) 2048)
-
-/*
- * Bottom up definition of an rpc message.
- * NOTE: call and reply use the same overall struct but
- * different parts of unions within it.
- */
-
-enum msg_type {
-    CALL=0,
-    REPLY=1
-};
-
-enum reply_stat {
-    MSG_ACCEPTED=0,
-    MSG_DENIED=1
-};
-
-enum accept_stat {
-    SUCCESS=0,
-    PROG_UNAVAIL=1,
-    PROG_MISMATCH=2,
-    PROC_UNAVAIL=3,
-    GARBAGE_ARGS=4,
-    SYSTEM_ERR=5
-};
-
-enum reject_stat {
-    RPC_MISMATCH=0,
-    AUTH_ERROR=1
-};
-
-/*
- * Reply part of an rpc exchange
- */
-
-/*
- * Reply to an rpc request that was accepted by the server.
- * Note: there could be an error even though the request was
- * accepted.
- */
-struct accepted_reply {
-    struct opaque_auth  ar_verf;
-    int                 ar_stat;
-    union {
-        struct {
-            unsigned long   low;
-            unsigned long   high;
-        } AR_versions;
-        struct {
-            char*   where;
-            xdrproc_t proc;
-        } AR_results;
-        /* and many other null cases */
-    } ru;
-#define ar_results  ru.AR_results
-#define ar_vers     ru.AR_versions
-};
-
-/*
- * Reply to an rpc request that was rejected by the server.
- */
-struct rejected_reply {
-    int rj_stat;
-    union {
-        struct {
-            unsigned long low;
-            unsigned long high;
-        } RJ_versions;
-        int RJ_why;  /* why authentication did not work */
-    } ru;
-#define rj_vers ru.RJ_versions
-#define rj_why  ru.RJ_why
-};
-
-/*
- * Body of a reply to an rpc request.
- */
-struct reply_body {
-    int rp_stat;
-    union {
-        struct accepted_reply RP_ar;
-        struct rejected_reply RP_dr;
-    } ru;
-#define rp_acpt ru.RP_ar
-#define rp_rjct ru.RP_dr
-};
-
-/*
- * Body of an rpc request call.
- */
-struct call_body {
-    unsigned long cb_rpcvers;   /* must be equal to two */
-    unsigned long cb_prog;
-    unsigned long cb_vers;
-    unsigned long cb_proc;
-    struct opaque_auth cb_cred;
-    struct opaque_auth cb_verf; /* protocol specific - provided by client */
-};
-
-/*
- * The rpc message
- */
-struct rpc_msg {
-    unsigned long   rm_xid;
-    int             rm_direction;
-    union {
-        struct call_body RM_cmb;
-        struct reply_body RM_rmb;
-    } ru;
-#define rm_call     ru.RM_cmb
-#define rm_reply    ru.RM_rmb
-};
-#define acpted_rply ru.RM_rmb.ru.RP_ar
-#define rjcted_rply ru.RM_rmb.ru.RP_dr
-
-
-/*
- * XDR routine to handle a rpc message.
- * xdr_callmsg(xdrs, cmsg)
- *  XDR *xdrs;
- *  struct rpc_msg *cmsg;
- */
-extern bool_t   xdr_callmsg (XDR *__xdrs, struct rpc_msg *__cmsg);
-
-/*
- * XDR routine to pre-serialize the static part of a rpc message.
- * xdr_callhdr(xdrs, cmsg)
- *  XDR *xdrs;
- *  struct rpc_msg *cmsg;
- */
-extern bool_t   xdr_callhdr (XDR *__xdrs, struct rpc_msg *__cmsg);
-
-/*
- * XDR routine to handle a rpc reply.
- * xdr_replymsg(xdrs, rmsg)
- *  XDR *xdrs;
- *  struct rpc_msg *rmsg;
- */
-extern bool_t   xdr_replymsg (XDR *__xdrs, struct rpc_msg *__rmsg);
-
-/*
- * Fills in the error part of a reply message.
- * _seterr_reply(msg, error)
- *  struct rpc_msg *msg;
- *  struct rpc_err *error;
- */
-extern void _seterr_reply (struct rpc_msg *__msg, struct rpc_err *__error);
-
-#endif /* rpc/rpc_msg.h */

+ 0 - 267
components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_prot.c

@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)rpc_prot.c   2.3 88/08/07 4.0 RPCSRC */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
-#endif
-
-/*
- * rpc_prot.c
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- *
- * This set of routines implements the rpc message definition,
- * its serializer and some common rpc utility routines.
- * The routines are meant for various implementations of rpc -
- * they are NOT for the rpc client or rpc service implementations!
- * Because authentication stuff is easy and is part of rpc, the opaque
- * routines are also in this program.
- */
-
-#include <rpc/rpc.h>
-
-/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
-
-/*
- * XDR an opaque authentication struct
- * (see auth.h)
- */
-bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap)
-{
-
-    if (xdr_enum(xdrs, &(ap->oa_flavor)))
-        return (xdr_bytes(xdrs, &ap->oa_base,
-                          &ap->oa_length, MAX_AUTH_BYTES));
-    return (FALSE);
-}
-
-/*
- * XDR a DES block
- */
-bool_t xdr_des_block(XDR *xdrs, des_block *blkp)
-{
-    return (xdr_opaque(xdrs, (char*) blkp, sizeof(des_block)));
-}
-
-/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
-
-/*
- * XDR the MSG_ACCEPTED part of a reply message union
- */
-static bool_t xdr_accepted_reply(XDR *xdrs, struct accepted_reply *ar)
-{
-
-    /* personalized union, rather than calling xdr_union */
-    if (!xdr_opaque_auth(xdrs, &(ar->ar_verf)))
-        return (FALSE);
-    if (!xdr_enum(xdrs, (enum_t *) & (ar->ar_stat)))
-        return (FALSE);
-    switch (ar->ar_stat) {
-
-    case SUCCESS:
-        return ((*(ar->ar_results.proc)) (xdrs, ar->ar_results.where));
-
-    case PROG_MISMATCH:
-        if (!xdr_u_long(xdrs, &(ar->ar_vers.low)))
-            return (FALSE);
-        return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
-    }
-    return (TRUE);              /* TRUE => open ended set of problems */
-}
-
-/*
- * XDR the MSG_DENIED part of a reply message union
- */
-static bool_t xdr_rejected_reply(XDR *xdrs, struct rejected_reply *rr)
-{
-
-    /* personalized union, rather than calling xdr_union */
-    if (!xdr_enum(xdrs, (enum_t *) & (rr->rj_stat)))
-        return (FALSE);
-    switch (rr->rj_stat) {
-
-    case RPC_MISMATCH:
-        if (!xdr_u_long(xdrs, &(rr->rj_vers.low)))
-            return (FALSE);
-        return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
-
-    case AUTH_ERROR:
-        return (xdr_enum(xdrs, (enum_t *) & (rr->rj_why)));
-    }
-    return (FALSE);
-}
-
-static struct xdr_discrim reply_dscrm[3] = {
-    {(int) MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply},
-    {(int) MSG_DENIED, (xdrproc_t)xdr_rejected_reply},
-    {__dontcare__, NULL_xdrproc_t}
-};
-
-/*
- * XDR a reply message
- */
-bool_t xdr_replymsg(XDR *xdrs, struct rpc_msg *rmsg)
-{
-    if (xdr_u_long(xdrs, &(rmsg->rm_xid)) &&
-        xdr_enum(xdrs, (enum_t *) & (rmsg->rm_direction)) &&
-        (rmsg->rm_direction == REPLY))
-        return (xdr_union(xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
-                          (char*) & (rmsg->rm_reply.ru), reply_dscrm,
-                          NULL_xdrproc_t));
-    return (FALSE);
-}
-
-
-/*
- * Serializes the "static part" of a call message header.
- * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
- * The rm_xid is not really static, but the user can easily munge on the fly.
- */
-bool_t xdr_callhdr(XDR *xdrs, struct rpc_msg *cmsg)
-{
-
-    cmsg->rm_direction = CALL;
-    cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
-    if (
-        (xdrs->x_op == XDR_ENCODE) &&
-        xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
-        xdr_enum(xdrs, (enum_t *) & (cmsg->rm_direction)) &&
-        xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
-        xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)))
-            return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
-    return (FALSE);
-}
-
-/* ************************** Client utility routine ************* */
-
-static void accepted(enum accept_stat acpt_stat, struct rpc_err *error)
-{
-
-    switch (acpt_stat) {
-
-    case PROG_UNAVAIL:
-        error->re_status = RPC_PROGUNAVAIL;
-        return;
-
-    case PROG_MISMATCH:
-        error->re_status = RPC_PROGVERSMISMATCH;
-        return;
-
-    case PROC_UNAVAIL:
-        error->re_status = RPC_PROCUNAVAIL;
-        return;
-
-    case GARBAGE_ARGS:
-        error->re_status = RPC_CANTDECODEARGS;
-        return;
-
-    case SYSTEM_ERR:
-        error->re_status = RPC_SYSTEMERROR;
-        return;
-
-    case SUCCESS:
-        error->re_status = RPC_SUCCESS;
-        return;
-    }
-    /* something's wrong, but we don't know what ... */
-    error->re_status = RPC_FAILED;
-    error->re_lb.s1 = (long) MSG_ACCEPTED;
-    error->re_lb.s2 = (long) acpt_stat;
-}
-
-static void rejected(enum reject_stat rjct_stat, struct rpc_err *error)
-{
-
-    switch (rjct_stat) {
-
-    case RPC_VERSMISMATCH:
-        error->re_status = RPC_VERSMISMATCH;
-        return;
-
-    case AUTH_ERROR:
-        error->re_status = RPC_AUTHERROR;
-        return;
-    }
-    /* something's wrong, but we don't know what ... */
-    error->re_status = RPC_FAILED;
-    error->re_lb.s1 = (long) MSG_DENIED;
-    error->re_lb.s2 = (long) rjct_stat;
-}
-
-/*
- * given a reply message, fills in the error
- */
-void _seterr_reply(struct rpc_msg *msg, struct rpc_err *error)
-{
-
-    /* optimized for normal, SUCCESSful case */
-    switch (msg->rm_reply.rp_stat) {
-
-    case MSG_ACCEPTED:
-        if (msg->acpted_rply.ar_stat == SUCCESS) {
-            error->re_status = RPC_SUCCESS;
-            return;
-        };
-        accepted((enum accept_stat)msg->acpted_rply.ar_stat, error);
-        break;
-
-    case MSG_DENIED:
-        rejected((enum reject_stat)msg->rjcted_rply.rj_stat, error);
-        break;
-
-    default:
-        error->re_status = RPC_FAILED;
-        error->re_lb.s1 = (long) (msg->rm_reply.rp_stat);
-        break;
-    }
-    switch (error->re_status) {
-
-    case RPC_VERSMISMATCH:
-        error->re_vers.low = msg->rjcted_rply.rj_vers.low;
-        error->re_vers.high = msg->rjcted_rply.rj_vers.high;
-        break;
-
-    case RPC_AUTHERROR:
-        error->re_why = msg->rjcted_rply.rj_why;
-        break;
-
-    case RPC_PROGVERSMISMATCH:
-        error->re_vers.low = msg->acpted_rply.ar_vers.low;
-        error->re_vers.high = msg->acpted_rply.ar_vers.high;
-        break;
-    }
-}

+ 0 - 89
components/dfs/dfs_v2/filesystems/nfs/rpc/types.h

@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-/* fixincludes should not add extern "C" to this file */
-/*
- * Rpc additions to <sys/types.h>
- */
-#ifndef _RPC_TYPES_H
-#define _RPC_TYPES_H 1
-
-#include <rtthread.h>
-#include <lwip/netdb.h>
-#include <lwip/sockets.h>
-
-#include <string.h>
-#include <stdint.h>
-
-#ifndef RT_USING_MINILIBC
-typedef unsigned int u_int;
-typedef unsigned char u_char;
-typedef unsigned long u_long;
-#else
-#include <sys/types.h>
-#include <stdint.h>
-#endif
-
-typedef int bool_t;
-typedef int enum_t;
-
-#if !defined(RT_USING_NEWLIB) && !defined(RT_USING_MUSL)
-typedef unsigned long dev_t;
-#endif
-
-
-/* This needs to be changed to uint32_t in the future */
-typedef unsigned long rpcprog_t;
-typedef unsigned long rpcvers_t;
-typedef unsigned long rpcproc_t;
-typedef unsigned long rpcprot_t;
-typedef unsigned long rpcport_t;
-
-#define        __dontcare__    -1
-
-#ifndef FALSE
-# define  FALSE   (0)
-#endif
-
-#ifndef TRUE
-# define  TRUE    (1)
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN  64
-#endif
-
-#endif /* rpc/types.h */

+ 0 - 784
components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.c

@@ -1,784 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)xdr.c    2.1 88/07/29 4.0 RPCSRC */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
-#endif
-
-/*
- * xdr.c, Generic XDR routines implementation.
- *
- * Copyright (C) 1986, Sun Microsystems, Inc.
- *
- * These are the "generic" xdr routines used to serialize and de-serialize
- * most common data items.  See xdr.h for more info on the interface to
- * xdr.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <string.h>
-
-/*
- * constants specific to the xdr "protocol"
- */
-#define XDR_FALSE       ((long) 0)
-#define XDR_TRUE        ((long) 1)
-#define LASTUNSIGNED    ((unsigned int) 0-1)
-
-/*
- * for unit alignment
- */
-static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
-
-/*
- * Free a data structure using XDR
- * Not a filter, but a convenient utility nonetheless
- */
-void xdr_free(xdrproc_t proc, char* objp)
-{
-    XDR x;
-
-    x.x_op = XDR_FREE;
-    (*proc) (&x, objp);
-}
-
-/*
- * XDR nothing
- */
-bool_t xdr_void( /* xdrs, addr */ )
-    /* XDR *xdrs; */
-    /* char* addr; */
-{
-
-    return (TRUE);
-}
-
-/*
- * XDR integers
- */
-bool_t xdr_int(XDR* xdrs, int* ip)
-{
-    if (sizeof(int) == sizeof(long)) {
-        return (xdr_long(xdrs, (long *) ip));
-    } else if (sizeof(int) < sizeof(long)) {
-      long l;
-      switch (xdrs->x_op) {
-      case XDR_ENCODE:
-        l = (long) *ip;
-        return XDR_PUTLONG(xdrs, &l);
-      case XDR_DECODE:
-        if (!XDR_GETLONG(xdrs, &l))
-          return FALSE;
-        *ip = (int) l;
-      case XDR_FREE:
-        return TRUE;
-      }
-      return FALSE;
-    } else {
-        return (xdr_short(xdrs, (short *) ip));
-    }
-}
-
-/*
- * XDR unsigned integers
- */
-bool_t xdr_u_int(XDR* xdrs, unsigned int* up)
-{
-    if (sizeof(unsigned int) == sizeof(unsigned long)) {
-        return (xdr_u_long(xdrs, (unsigned long *) up));
-    } else if (sizeof(unsigned int) < sizeof(unsigned long)) {
-      unsigned long l;
-      switch (xdrs->x_op) {
-      case XDR_ENCODE:
-        l = (unsigned long) *up;
-        return XDR_PUTLONG(xdrs, (long*)&l);
-      case XDR_DECODE:
-        if (!XDR_GETLONG(xdrs, (long*)&l))
-          return FALSE;
-        *up = (unsigned int) l;
-      case XDR_FREE:
-        return TRUE;
-      }
-      return FALSE;
-    } else {
-        return (xdr_short(xdrs, (short *) up));
-    }
-}
-
-/*
- * XDR long integers
- * same as xdr_u_long - open coded to save a proc call!
- */
-bool_t xdr_long(XDR* xdrs, long* lp)
-{
-
-    if (xdrs->x_op == XDR_ENCODE
-        && (sizeof(int32_t) == sizeof(long)
-            || (int32_t) *lp == *lp))
-        return (XDR_PUTLONG(xdrs, lp));
-
-    if (xdrs->x_op == XDR_DECODE)
-        return (XDR_GETLONG(xdrs, lp));
-
-    if (xdrs->x_op == XDR_FREE)
-        return (TRUE);
-
-    return (FALSE);
-}
-
-/*
- * XDR unsigned long integers
- * same as xdr_long - open coded to save a proc call!
- */
-bool_t xdr_u_long(XDR* xdrs, unsigned long* ulp)
-{
-
-  if (xdrs->x_op == XDR_DECODE) {
-    long l;
-    if (XDR_GETLONG(xdrs, &l) == FALSE)
-      return FALSE;
-    *ulp = (uint32_t) l;
-    return TRUE;
-  }
-
-  if (xdrs->x_op == XDR_ENCODE) {
-    if (sizeof(uint32_t) != sizeof(unsigned long)
-        && (uint32_t) *ulp != *ulp)
-      return FALSE;
-
-        return (XDR_PUTLONG(xdrs, (long *) ulp));
-  }
-
-    if (xdrs->x_op == XDR_FREE)
-        return (TRUE);
-
-    return (FALSE);
-}
-
-
-/*
- * XDR long long integers
- */
-bool_t xdr_longlong_t (XDR * xdrs, int64_t* llp)
-{
-  int32_t t1, t2;
-
-  switch (xdrs->x_op)
-    {
-    case XDR_ENCODE:
-      t1 = (int32_t) ((*llp) >> 32);
-      t2 = (int32_t) (*llp);
-      return (XDR_PUTLONG (xdrs, &t1) && XDR_PUTLONG (xdrs, &t2));
-
-    case XDR_DECODE:
-      if (!XDR_GETLONG (xdrs, &t1) || !XDR_GETLONG (xdrs, &t2))
-        return FALSE;
-      *llp = ((int64_t) t1) << 32;
-      *llp |= (uint32_t) t2;
-      return TRUE;
-
-    case XDR_FREE:
-      return TRUE;
-    }
-  return FALSE;
-}
-
-/*
- * XDR unsigned long long integers
- */
-bool_t xdr_u_longlong_t (XDR * xdrs, uint64_t* ullp)
-{
-  uint32_t t1, t2;
-
-  switch (xdrs->x_op)
-    {
-    case XDR_ENCODE:
-      t1 = (uint32_t) ((*ullp) >> 32);
-      t2 = (uint32_t) (*ullp);
-      return (XDR_PUTLONG (xdrs, (int32_t *)&t1) &&
-              XDR_PUTLONG (xdrs, (int32_t *)&t2));
-
-    case XDR_DECODE:
-      if (!XDR_GETLONG (xdrs, (int32_t *)&t1) ||
-          !XDR_GETLONG (xdrs, (int32_t *)&t2))
-        return FALSE;
-      *ullp = ((uint64_t) t1) << 32;
-      *ullp |= t2;
-      return TRUE;
-
-    case XDR_FREE:
-      return TRUE;
-    }
-  return FALSE;
-}
-
-/*
- * XDR short integers
- */
-bool_t xdr_short(XDR* xdrs, short* sp)
-{
-    long l;
-
-    switch (xdrs->x_op) {
-
-    case XDR_ENCODE:
-        l = (long) *sp;
-        return (XDR_PUTLONG(xdrs, &l));
-
-    case XDR_DECODE:
-        if (!XDR_GETLONG(xdrs, &l)) {
-            return (FALSE);
-        }
-        *sp = (short) l;
-        return (TRUE);
-
-    case XDR_FREE:
-        return (TRUE);
-    }
-    return (FALSE);
-}
-
-/*
- * XDR unsigned short integers
- */
-bool_t xdr_u_short(XDR* xdrs, unsigned short* usp)
-{
-    unsigned long l;
-
-    switch (xdrs->x_op) {
-
-    case XDR_ENCODE:
-        l = (unsigned long) * usp;
-        return (XDR_PUTLONG(xdrs, (long*)&l));
-
-    case XDR_DECODE:
-        if (!XDR_GETLONG(xdrs, (long*)&l)) {
-            return (FALSE);
-        }
-        *usp = (unsigned short) l;
-        return (TRUE);
-
-    case XDR_FREE:
-        return (TRUE);
-    }
-    return (FALSE);
-}
-
-
-/*
- * XDR a char
- */
-bool_t xdr_char(XDR* xdrs, char* cp)
-{
-    int i;
-
-    i = (*cp);
-    if (!xdr_int(xdrs, &i)) {
-        return (FALSE);
-    }
-    *cp = i;
-    return (TRUE);
-}
-
-/*
- * XDR an unsigned char
- */
-bool_t xdr_u_char(XDR* xdrs, unsigned char* cp)
-{
-    unsigned int u;
-
-    u = (*cp);
-    if (!xdr_u_int(xdrs, &u)) {
-        return (FALSE);
-    }
-    *cp = u;
-    return (TRUE);
-}
-
-/*
- * XDR booleans
- */
-bool_t xdr_bool(XDR *xdrs, bool_t *bp)
-{
-    long lb;
-
-    switch (xdrs->x_op) {
-
-    case XDR_ENCODE:
-        lb = *bp ? XDR_TRUE : XDR_FALSE;
-        return (XDR_PUTLONG(xdrs, &lb));
-
-    case XDR_DECODE:
-        if (!XDR_GETLONG(xdrs, &lb)) {
-            return (FALSE);
-        }
-        *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
-        return (TRUE);
-
-    case XDR_FREE:
-        return (TRUE);
-    }
-    return (FALSE);
-}
-
-/*
- * XDR enumerations
- */
-bool_t xdr_enum(XDR *xdrs, enum_t *ep)
-{
-    enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
-
-    /*
-     * enums are treated as ints
-     */
-    /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
-        return (xdr_long(xdrs, (long *)(void *)ep));
-    } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
-        return (xdr_int(xdrs, (int *)(void *)ep));
-    } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
-        return (xdr_short(xdrs, (short *)(void *)ep));
-    } else {
-        return (FALSE);
-    }
-}
-
-/*
- * XDR opaque data
- * Allows the specification of a fixed size sequence of opaque bytes.
- * cp points to the opaque object and cnt gives the byte length.
- */
-bool_t xdr_opaque(XDR *xdrs, char* cp, unsigned int cnt)
-{
-    register unsigned int rndup;
-    static char crud[BYTES_PER_XDR_UNIT];
-
-    /*
-     * if no data we are done
-     */
-    if (cnt == 0)
-        return (TRUE);
-
-    /*
-     * round byte count to full xdr units
-     */
-    rndup = cnt % BYTES_PER_XDR_UNIT;
-    if (rndup > 0)
-        rndup = BYTES_PER_XDR_UNIT - rndup;
-
-    if (xdrs->x_op == XDR_DECODE) {
-        if (!XDR_GETBYTES(xdrs, cp, cnt)) {
-            return (FALSE);
-        }
-        if (rndup == 0)
-            return (TRUE);
-        return (XDR_GETBYTES(xdrs, crud, rndup));
-    }
-
-    if (xdrs->x_op == XDR_ENCODE) {
-        if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
-            return (FALSE);
-        }
-        if (rndup == 0)
-            return (TRUE);
-        return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
-    }
-
-    if (xdrs->x_op == XDR_FREE) {
-        return (TRUE);
-    }
-
-    return (FALSE);
-}
-
-/*
- * XDR counted bytes
- * *cpp is a pointer to the bytes, *sizep is the count.
- * If *cpp is NULL maxsize bytes are allocated
- */
-bool_t xdr_bytes(XDR *xdrs, char** cpp, unsigned int *sizep, unsigned int maxsize)
-{
-    register char *sp = *cpp;   /* sp is the actual string pointer */
-    register unsigned int nodesize;
-
-    /*
-     * first deal with the length since xdr bytes are counted
-     */
-    if (!xdr_u_int(xdrs, sizep)) {
-        return (FALSE);
-    }
-    nodesize = *sizep;
-    if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
-        return (FALSE);
-    }
-
-    /*
-     * now deal with the actual bytes
-     */
-    switch (xdrs->x_op) {
-
-    case XDR_DECODE:
-        if (nodesize == 0) {
-            return (TRUE);
-        }
-        if (sp == NULL) {
-            *cpp = sp = (char *) rt_malloc(nodesize);
-        }
-        if (sp == NULL) {
-            rt_kprintf("xdr_bytes: out of memory\n");
-            return (FALSE);
-        }
-        /* fall into ... */
-
-    case XDR_ENCODE:
-        return (xdr_opaque(xdrs, sp, nodesize));
-
-    case XDR_FREE:
-        if (sp != NULL) {
-            rt_free(sp);
-            *cpp = NULL;
-        }
-        return (TRUE);
-    }
-    return (FALSE);
-}
-
-/*
- * Implemented here due to commonality of the object.
- */
-bool_t xdr_netobj(XDR *xdrs, struct netobj *np)
-{
-    return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
-}
-
-/*
- * XDR a descriminated union
- * Support routine for discriminated unions.
- * You create an array of xdrdiscrim structures, terminated with
- * an entry with a null procedure pointer.  The routine gets
- * the discriminant value and then searches the array of xdrdiscrims
- * looking for that value.  It calls the procedure given in the xdrdiscrim
- * to handle the discriminant.  If there is no specific routine a default
- * routine may be called.
- * If there is no specific or default routine an error is returned.
- */
-bool_t xdr_union(XDR* xdrs, enum_t* dscmp, char* unp, const struct xdr_discrim* choices, xdrproc_t dfault)
-{
-    register enum_t dscm;
-
-    /*
-     * we deal with the discriminator;  it's an enum
-     */
-    if (!xdr_enum(xdrs, dscmp)) {
-        return (FALSE);
-    }
-    dscm = *dscmp;
-
-    /*
-     * search choices for a value that matches the discriminator.
-     * if we find one, execute the xdr routine for that value.
-     */
-    for (; choices->proc != NULL_xdrproc_t; choices++) {
-        if (choices->value == dscm)
-            return ((*(choices->proc)) (xdrs, unp, LASTUNSIGNED));
-    }
-
-    /*
-     * no match - execute the default xdr routine if there is one
-     */
-    return ((dfault == NULL_xdrproc_t) ? FALSE :
-            (*dfault) (xdrs, unp, LASTUNSIGNED));
-}
-
-
-/*
- * Non-portable xdr primitives.
- * Care should be taken when moving these routines to new architectures.
- */
-
-
-/*
- * XDR null terminated ASCII strings
- * xdr_string deals with "C strings" - arrays of bytes that are
- * terminated by a NULL character.  The parameter cpp references a
- * pointer to storage; If the pointer is null, then the necessary
- * storage is allocated.  The last parameter is the max allowed length
- * of the string as specified by a protocol.
- */
-bool_t xdr_string(XDR *xdrs, char **cpp, unsigned int maxsize)
-{
-    register char *sp = *cpp;   /* sp is the actual string pointer */
-    unsigned int size;
-    unsigned int nodesize;
-
-    /*
-     * first deal with the length since xdr strings are counted-strings
-     */
-    switch (xdrs->x_op) {
-    case XDR_FREE:
-        if (sp == NULL) {
-            return (TRUE);      /* already free */
-        }
-        /* fall through... */
-    case XDR_ENCODE:
-        size = strlen(sp);
-        break;
-    }
-    if (!xdr_u_int(xdrs, &size)) {
-        return (FALSE);
-    }
-    if (size > maxsize) {
-        return (FALSE);
-    }
-    nodesize = size + 1;
-
-    /*
-     * now deal with the actual bytes
-     */
-    switch (xdrs->x_op) {
-
-    case XDR_DECODE:
-        if (nodesize == 0) {
-            return (TRUE);
-        }
-        if (sp == NULL)
-            *cpp = sp = (char *) rt_malloc(nodesize);
-        if (sp == NULL) {
-            rt_kprintf("xdr_string: out of memory\n");
-            return (FALSE);
-        }
-        sp[size] = 0;
-        /* fall into ... */
-
-    case XDR_ENCODE:
-        return (xdr_opaque(xdrs, sp, size));
-
-    case XDR_FREE:
-        rt_free(sp);
-        *cpp = NULL;
-        return (TRUE);
-    }
-    return (FALSE);
-}
-
-/*
- * Wrapper for xdr_string that can be called directly from
- * routines like clnt_call
- */
-bool_t xdr_wrapstring(XDR *xdrs, char **cpp)
-{
-    if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
-        return (TRUE);
-    }
-    return (FALSE);
-}
-
-/*
- * XDR an array of arbitrary elements
- * *addrp is a pointer to the array, *sizep is the number of elements.
- * If addrp is NULL (*sizep * elsize) bytes are allocated.
- * elsize is the size (in bytes) of each element, and elproc is the
- * xdr procedure to call to handle each element of the array.
- */
-bool_t xdr_array(XDR *xdrs, char **addrp, unsigned int *sizep, unsigned int maxsize, unsigned int elsize, xdrproc_t elproc)
-{
-    register unsigned int i;
-    register char* target = *addrp;
-    register unsigned int c;            /* the actual element count */
-    register bool_t stat = TRUE;
-    register unsigned int nodesize;
-
-    /* like strings, arrays are really counted arrays */
-    if (!xdr_u_int(xdrs, sizep)) {
-        return (FALSE);
-    }
-    c = *sizep;
-    if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
-        return (FALSE);
-    }
-    /* duh, look for integer overflow (fefe) */
-    {
-      unsigned int i;
-      nodesize = 0;
-      for (i=c; i; --i) {
-        unsigned int tmp=nodesize+elsize;
-        if (tmp<nodesize)   /* overflow */
-          return FALSE;
-        nodesize=tmp;
-      }
-    }
-
-    /*
-     * if we are deserializing, we may need to allocate an array.
-     * We also save time by checking for a null array if we are freeing.
-     */
-    if (target == NULL)
-        switch (xdrs->x_op) {
-        case XDR_DECODE:
-            if (c == 0)
-                return (TRUE);
-            *addrp = target = rt_malloc(nodesize);
-            if (target == NULL) {
-                rt_kprintf("xdr_array: out of memory\n");
-                return (FALSE);
-            }
-            memset(target, 0, nodesize);
-            break;
-
-        case XDR_FREE:
-            return (TRUE);
-        }
-
-    /*
-     * now we xdr each element of array
-     */
-    for (i = 0; (i < c) && stat; i++) {
-        stat = (*elproc) (xdrs, target, LASTUNSIGNED);
-        target += elsize;
-    }
-
-    /*
-     * the array may need freeing
-     */
-    if (xdrs->x_op == XDR_FREE) {
-        rt_free(*addrp);
-        *addrp = NULL;
-    }
-    return (stat);
-}
-
-/*
- * xdr_vector():
- *
- * XDR a fixed length array. Unlike variable-length arrays,
- * the storage of fixed length arrays is static and unfreeable.
- * > basep: base of the array
- * > size: size of the array
- * > elemsize: size of each element
- * > xdr_elem: routine to XDR each element
- */
-bool_t xdr_vector(XDR *xdrs, char *basep, unsigned int nelem, unsigned int elemsize, xdrproc_t xdr_elem)
-{
-    register unsigned int i;
-    register char *elptr;
-
-    elptr = basep;
-    for (i = 0; i < nelem; i++) {
-        if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED)) {
-            return (FALSE);
-        }
-        elptr += elemsize;
-    }
-    return (TRUE);
-}
-
-
-/*
- * XDR an indirect pointer
- * xdr_reference is for recursively translating a structure that is
- * referenced by a pointer inside the structure that is currently being
- * translated.  pp references a pointer to storage. If *pp is null
- * the  necessary storage is allocated.
- * size is the sizeof the referneced structure.
- * proc is the routine to handle the referenced structure.
- */
-bool_t xdr_reference(XDR *xdrs, char **pp, unsigned int size, xdrproc_t proc)
-{
-    register char* loc = *pp;
-    register bool_t stat;
-
-    if (loc == NULL)
-        switch (xdrs->x_op) {
-        case XDR_FREE:
-            return (TRUE);
-
-        case XDR_DECODE:
-            *pp = loc = (char*) rt_malloc(size);
-            if (loc == NULL) {
-                rt_kprintf("xdr_reference: out of memory\n");
-                return (FALSE);
-            }
-            memset(loc, 0, (int) size);
-            break;
-        }
-
-    stat = (*proc) (xdrs, loc, LASTUNSIGNED);
-
-    if (xdrs->x_op == XDR_FREE) {
-        rt_free(loc);
-        *pp = NULL;
-    }
-    return (stat);
-}
-
-
-/*
- * xdr_pointer():
- *
- * XDR a pointer to a possibly recursive data structure. This
- * differs with xdr_reference in that it can serialize/deserialiaze
- * trees correctly.
- *
- *  What's sent is actually a union:
- *
- *  union object_pointer switch (boolean b) {
- *  case TRUE: object_data data;
- *  case FALSE: void nothing;
- *  }
- *
- * > objpp: Pointer to the pointer to the object.
- * > obj_size: size of the object.
- * > xdr_obj: routine to XDR an object.
- *
- */
-bool_t xdr_pointer(XDR *xdrs, char **objpp, unsigned int obj_size, xdrproc_t xdr_obj)
-{
-
-    bool_t more_data;
-
-    more_data = (*objpp != NULL);
-    if (!xdr_bool(xdrs, &more_data)) {
-        return (FALSE);
-    }
-    if (!more_data) {
-        *objpp = NULL;
-        return (TRUE);
-    }
-    return (xdr_reference(xdrs, objpp, obj_size, xdr_obj));
-}

+ 0 - 369
components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.h

@@ -1,369 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-
-/*
- * xdr.h, External Data Representation Serialization Routines.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- */
-
-#ifndef _RPC_XDR_H
-#define _RPC_XDR_H
-
-#include <rpc/types.h>
-
-/* We need FILE.  */
-#include <stdio.h>
-
-/*
- * XDR provides a conventional way for converting between C data
- * types and an external bit-string representation.  Library supplied
- * routines provide for the conversion on built-in C data types.  These
- * routines and utility routines defined here are used to help implement
- * a type encode/decode routine for each user-defined type.
- *
- * Each data type provides a single procedure which takes two arguments:
- *
- *      bool_t
- *      xdrproc(xdrs, argresp)
- *              XDR *xdrs;
- *              <type> *argresp;
- *
- * xdrs is an instance of a XDR handle, to which or from which the data
- * type is to be converted.  argresp is a pointer to the structure to be
- * converted.  The XDR handle contains an operation field which indicates
- * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
- *
- * XDR_DECODE may allocate space if the pointer argresp is null.  This
- * data can be freed with the XDR_FREE operation.
- *
- * We write only one procedure per data type to make it easy
- * to keep the encode and decode procedures for a data type consistent.
- * In many cases the same code performs all operations on a user defined type,
- * because all the hard work is done in the component type routines.
- * decode as a series of calls on the nested data types.
- */
-
-/*
- * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
- * stream.  XDR_DECODE causes the type to be extracted from the stream.
- * XDR_FREE can be used to release the space allocated by an XDR_DECODE
- * request.
- */
-enum xdr_op {
-  XDR_ENCODE = 0,
-  XDR_DECODE = 1,
-  XDR_FREE = 2
-};
-
-/*
- * This is the number of bytes per unit of external data.
- */
-#define BYTES_PER_XDR_UNIT  (4)
-/*
- * This only works if the above is a power of 2.  But it's defined to be
- * 4 by the appropriate RFCs.  So it will work.  And it's normally quicker
- * than the old routine.
- */
-#define RNDUP(x)  (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1))
-
-/*
- * The XDR handle.
- * Contains operation which is being applied to the stream,
- * an operations vector for the particular implementation (e.g. see xdr_mem.c),
- * and two private fields for the use of the particular implementation.
- */
-typedef struct XDR XDR;
-struct XDR
-  {
-    enum xdr_op x_op;       /* operation; fast additional param */
-    struct xdr_ops
-      {
-    bool_t (*x_getlong) (XDR *__xdrs, long *__lp);
-    /* get a long from underlying stream */
-    bool_t (*x_putlong) (XDR *__xdrs, const long *__lp);
-    /* put a long to " */
-    bool_t (*x_getbytes) (XDR *__xdrs, char* __addr, unsigned int __len);
-    /* get some bytes from " */
-    bool_t (*x_putbytes) (XDR *__xdrs, const char *__addr, unsigned int __len);
-    /* put some bytes to " */
-    unsigned int (*x_getpostn) (const XDR *__xdrs);
-    /* returns bytes off from beginning */
-    bool_t (*x_setpostn) (XDR *__xdrs, unsigned int __pos);
-    /* lets you reposition the stream */
-    int32_t *(*x_inline) (XDR *__xdrs, unsigned int __len);
-    /* buf quick ptr to buffered data */
-    void (*x_destroy) (XDR *__xdrs);
-    /* free privates of this xdr_stream */
-    bool_t (*x_getint32) (XDR *__xdrs, int32_t *__ip);
-    /* get a int from underlying stream */
-    bool_t (*x_putint32) (XDR *__xdrs, const int32_t *__ip);
-    /* put a int to " */
-      }
-     *x_ops;
-    char* x_public;     /* users' data */
-    char* x_private;        /* pointer to private data */
-    char* x_base;       /* private used for position info */
-    unsigned int x_handy;   /* extra private word */
-  };
-
-/*
- * A xdrproc_t exists for each data type which is to be encoded or decoded.
- *
- * The second argument to the xdrproc_t is a pointer to an opaque pointer.
- * The opaque pointer generally points to a structure of the data type
- * to be decoded.  If this pointer is 0, then the type routines should
- * allocate dynamic storage of the appropriate size and return it.
- * bool_t       (*xdrproc_t)(XDR *, char* *);
- */
-typedef bool_t (*xdrproc_t) (XDR *, void *,...);
-
-
-/*
- * Operations defined on a XDR handle
- *
- * XDR          *xdrs;
- * int32_t      *int32p;
- * long         *longp;
- * char*       addr;
- * unsigned int         len;
- * unsigned int         pos;
- */
-#define XDR_GETINT32(xdrs, int32p)                      \
-        (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
-#define xdr_getint32(xdrs, int32p)                      \
-        (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
-
-#define XDR_PUTINT32(xdrs, int32p)                      \
-        (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
-#define xdr_putint32(xdrs, int32p)                      \
-        (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
-
-#define XDR_GETLONG(xdrs, longp)            \
-    (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
-#define xdr_getlong(xdrs, longp)            \
-    (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
-
-#define XDR_PUTLONG(xdrs, longp)            \
-    (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
-#define xdr_putlong(xdrs, longp)            \
-    (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
-
-#define XDR_GETBYTES(xdrs, addr, len)           \
-    (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
-#define xdr_getbytes(xdrs, addr, len)           \
-    (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
-
-#define XDR_PUTBYTES(xdrs, addr, len)           \
-    (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
-#define xdr_putbytes(xdrs, addr, len)           \
-    (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
-
-#define XDR_GETPOS(xdrs)                \
-    (*(xdrs)->x_ops->x_getpostn)(xdrs)
-#define xdr_getpos(xdrs)                \
-    (*(xdrs)->x_ops->x_getpostn)(xdrs)
-
-#define XDR_SETPOS(xdrs, pos)               \
-    (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
-#define xdr_setpos(xdrs, pos)               \
-    (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
-
-#define XDR_INLINE(xdrs, len)               \
-    (*(xdrs)->x_ops->x_inline)(xdrs, len)
-#define xdr_inline(xdrs, len)               \
-    (*(xdrs)->x_ops->x_inline)(xdrs, len)
-
-#define XDR_DESTROY(xdrs)                   \
-    do {                            \
-        if ((xdrs)->x_ops->x_destroy)           \
-            (*(xdrs)->x_ops->x_destroy)(xdrs);  \
-    } while (0)
-#define xdr_destroy(xdrs)                   \
-    do {                            \
-        if ((xdrs)->x_ops->x_destroy)           \
-            (*(xdrs)->x_ops->x_destroy)(xdrs);  \
-    } while (0)
-
-/*
- * Support struct for discriminated unions.
- * You create an array of xdrdiscrim structures, terminated with
- * a entry with a null procedure pointer.  The xdr_union routine gets
- * the discriminant value and then searches the array of structures
- * for a matching value.  If a match is found the associated xdr routine
- * is called to handle that part of the union.  If there is
- * no match, then a default routine may be called.
- * If there is no match and no default routine it is an error.
- */
-#define NULL_xdrproc_t ((xdrproc_t)0)
-struct xdr_discrim
-{
-  int value;
-  xdrproc_t proc;
-};
-
-/*
- * Inline routines for fast encode/decode of primitive data types.
- * Caveat emptor: these use single memory cycles to get the
- * data from the underlying buffer, and will fail to operate
- * properly if the data is not aligned.  The standard way to use these
- * is to say:
- *      if ((buf = XDR_INLINE(xdrs, count)) == NULL)
- *              return (FALSE);
- *      <<< macro calls >>>
- * where ``count'' is the number of bytes of data occupied
- * by the primitive data types.
- *
- * N.B. and frozen for all time: each data type here uses 4 bytes
- * of external representation.
- */
-
-#define IXDR_GET_INT32(buf)           ((int32_t)ntohl((uint32_t)*(buf)++))
-#define IXDR_PUT_INT32(buf, v)        (*(buf)++ = (int32_t)htonl((uint32_t)(v)))
-#define IXDR_GET_U_INT32(buf)         ((uint32_t)IXDR_GET_INT32(buf))
-#define IXDR_PUT_U_INT32(buf, v)      IXDR_PUT_INT32(buf, (int32_t)(v))
-
-/* WARNING: The IXDR_*_LONG defines are removed by Sun for new platforms
- * and shouldn't be used any longer. Code which use this defines or longs
- * in the RPC code will not work on 64bit Solaris platforms !
- */
-#define IXDR_GET_LONG(buf)        ((long)IXDR_GET_U_INT32(buf))
-#define IXDR_PUT_LONG(buf, v)         ((long)IXDR_PUT_INT32(buf, (long)(v)))
-#define IXDR_GET_U_LONG(buf)          ((unsigned long)IXDR_GET_LONG(buf))
-#define IXDR_PUT_U_LONG(buf, v)       IXDR_PUT_LONG(buf, (long)(v))
-
-
-#define IXDR_GET_BOOL(buf)            ((bool_t)IXDR_GET_LONG(buf))
-#define IXDR_GET_ENUM(buf, t)         ((t)IXDR_GET_LONG(buf))
-#define IXDR_GET_SHORT(buf)           ((short)IXDR_GET_LONG(buf))
-#define IXDR_GET_U_SHORT(buf)         ((unsigned short)IXDR_GET_LONG(buf))
-
-#define IXDR_PUT_BOOL(buf, v)         IXDR_PUT_LONG(buf, (long)(v))
-#define IXDR_PUT_ENUM(buf, v)         IXDR_PUT_LONG(buf, (long)(v))
-#define IXDR_PUT_SHORT(buf, v)        IXDR_PUT_LONG(buf, (long)(v))
-#define IXDR_PUT_U_SHORT(buf, v)      IXDR_PUT_LONG(buf, (long)(v))
-
-/*
- * These are the "generic" xdr routines.
- * None of these can have const applied because it's not possible to
- * know whether the call is a read or a write to the passed parameter
- * also, the XDR structure is always updated by some of these calls.
- */
-extern bool_t xdr_void (void);
-extern bool_t xdr_short (XDR *__xdrs, short *__sp);
-extern bool_t xdr_u_short (XDR *__xdrs, unsigned short *__usp);
-extern bool_t xdr_int (XDR *__xdrs, int *__ip);
-extern bool_t xdr_u_int (XDR *__xdrs, unsigned int *__up);
-extern bool_t xdr_long (XDR *__xdrs, long *__lp);
-extern bool_t xdr_u_long (XDR *__xdrs, unsigned long *__ulp);
-extern bool_t xdr_hyper (XDR *__xdrs, int64_t *__llp);
-extern bool_t xdr_u_hyper (XDR *__xdrs, uint64_t *__ullp);
-extern bool_t xdr_longlong_t (XDR *__xdrs, int64_t *__llp);
-extern bool_t xdr_u_longlong_t (XDR *__xdrs, uint64_t *__ullp);
-extern bool_t xdr_int8_t (XDR *__xdrs, int8_t *__ip);
-extern bool_t xdr_uint8_t (XDR *__xdrs, uint8_t *__up);
-extern bool_t xdr_int16_t (XDR *__xdrs, int16_t *__ip);
-extern bool_t xdr_uint16_t (XDR *__xdrs, uint16_t *__up);
-extern bool_t xdr_int32_t (XDR *__xdrs, int32_t *__ip);
-extern bool_t xdr_uint32_t (XDR *__xdrs, uint32_t *__up);
-extern bool_t xdr_int64_t (XDR *__xdrs, int64_t *__ip);
-extern bool_t xdr_uint64_t (XDR *__xdrs, uint64_t *__up);
-extern bool_t xdr_bool (XDR *__xdrs, bool_t *__bp);
-extern bool_t xdr_enum (XDR *__xdrs, enum_t *__ep);
-extern bool_t xdr_array (XDR * _xdrs, char* *__addrp, unsigned int *__sizep,
-             unsigned int __maxsize, unsigned int __elsize, xdrproc_t __elproc);
-extern bool_t xdr_bytes (XDR *xdrs, char **cpp, unsigned int *sizep,
-             unsigned int maxsize);
-extern bool_t xdr_opaque (XDR *__xdrs, char* __cp, unsigned int __cnt);
-extern bool_t xdr_string (XDR *xdrs, char **cpp, unsigned int maxsize);
-extern bool_t xdr_union (XDR *__xdrs, enum_t *__dscmp, char *__unp,
-             const struct xdr_discrim *__choices,
-             xdrproc_t dfault);
-extern bool_t xdr_char (XDR *__xdrs, char *__cp);
-extern bool_t xdr_u_char (XDR *__xdrs, unsigned char *__cp);
-extern bool_t xdr_vector (XDR *__xdrs, char *__basep, unsigned int __nelem,
-              unsigned int __elemsize, xdrproc_t __xdr_elem);
-extern bool_t xdr_float (XDR *__xdrs, float *__fp);
-extern bool_t xdr_double (XDR *__xdrs, double *__dp);
-extern bool_t xdr_reference (XDR *__xdrs, char* *__xpp, unsigned int __size,
-                 xdrproc_t __proc);
-extern bool_t xdr_pointer (XDR *__xdrs, char **__objpp,
-               unsigned int __obj_size, xdrproc_t __xdr_obj);
-extern bool_t xdr_wrapstring (XDR *__xdrs, char **cpp);
-extern unsigned long xdr_sizeof (xdrproc_t, void *);
-
-/*
- * Common opaque bytes objects used by many rpc protocols;
- * declared here due to commonality.
- */
-#define MAX_NETOBJ_SZ 1024
-struct netobj
-{
-  unsigned int n_len;
-  char *n_bytes;
-};
-typedef struct netobj netobj;
-extern bool_t xdr_netobj (XDR *__xdrs, struct netobj *__np);
-
-/*
- * These are the public routines for the various implementations of
- * xdr streams.
- */
-
-/* XDR using memory buffers */
-extern void xdrmem_create (XDR *__xdrs, const char* __addr,
-               unsigned int __size, enum xdr_op __xop);
-
-/* XDR pseudo records for tcp */
-extern void xdrrec_create (XDR *__xdrs, unsigned int __sendsize,
-               unsigned int __recvsize, char* __tcp_handle,
-               int (*__readit) (char *, char *, int),
-               int (*__writeit) (char *, char *, int));
-
-/* make end of xdr record */
-extern bool_t xdrrec_endofrecord (XDR *__xdrs, bool_t __sendnow);
-
-/* move to beginning of next record */
-extern bool_t xdrrec_skiprecord (XDR *__xdrs);
-
-/* true if no more input */
-extern bool_t xdrrec_eof (XDR *__xdrs);
-
-/* free memory buffers for xdr */
-extern void xdr_free (xdrproc_t __proc, char *__objp);
-
-#endif /* rpc/xdr.h */

+ 0 - 172
components/dfs/dfs_v2/filesystems/nfs/rpc/xdr_mem.c

@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-/* @(#)xdr_mem.c    2.1 88/07/29 4.0 RPCSRC */
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
-#endif
-
-/*
- * xdr_mem.h, XDR implementation using memory buffers.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
- *
- * If you have some data to be interpreted as external data representation
- * or to be converted to external data representation in a memory buffer,
- * then this is the package for you.
- *
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <string.h>
-#include <limits.h>
-
-static bool_t xdrmem_getlong (XDR *, long *);
-static bool_t xdrmem_putlong (XDR *, const long *);
-static bool_t xdrmem_getbytes (XDR *, char *, unsigned int);
-static bool_t xdrmem_putbytes (XDR *, const char *, unsigned int);
-static unsigned int xdrmem_getpos (const XDR *);
-static bool_t xdrmem_setpos (XDR *, unsigned int);
-static int32_t *xdrmem_inline (XDR *, unsigned int);
-static void xdrmem_destroy (XDR *);
-
-static struct xdr_ops xdrmem_ops = {
-    xdrmem_getlong,
-    xdrmem_putlong,
-    xdrmem_getbytes,
-    xdrmem_putbytes,
-    xdrmem_getpos,
-    xdrmem_setpos,
-    xdrmem_inline,
-    xdrmem_destroy,
-    NULL,
-    NULL
-};
-
-
-/*
- * The procedure xdrmem_create initializes a stream descriptor for a
- * memory buffer.
- */
-void
-xdrmem_create (XDR *xdrs, const char* addr, unsigned int size, enum xdr_op op)
-{
-    xdrs->x_op = op;
-    xdrs->x_ops = &xdrmem_ops;
-    xdrs->x_private = xdrs->x_base = (char*)addr;
-    xdrs->x_handy = size;
-}
-
-static void
-xdrmem_destroy (XDR *xdrs)
-{
-}
-
-static bool_t
-xdrmem_getlong (XDR *xdrs, long *lp)
-{
-  if (xdrs->x_handy < 4) return FALSE;
-  xdrs->x_handy -= 4;
-
-  *lp = (int32_t) ntohl((*((int32_t *) (xdrs->x_private))));
-  xdrs->x_private += 4;
-  return TRUE;
-}
-
-static bool_t
-xdrmem_putlong (XDR *xdrs, const long *lp)
-{
-  if (xdrs->x_handy < 4) return FALSE;
-  xdrs->x_handy -= 4;
-
-  *(int32_t *) xdrs->x_private = htonl(*lp);
-  xdrs->x_private += 4;
-  return (TRUE);
-}
-
-static bool_t
-xdrmem_getbytes (XDR *xdrs, char *addr, unsigned int len)
-{
-  if (xdrs->x_handy < len) return FALSE;
-  xdrs->x_handy -= len;
-  memmove(addr, xdrs->x_private, len);
-  xdrs->x_private += len;
-  return TRUE;
-}
-
-static bool_t
-xdrmem_putbytes (XDR *xdrs, const char *addr, unsigned int len)
-{
-  if (xdrs->x_handy < len) return FALSE;
-  xdrs->x_handy -= len;
-  memmove(xdrs->x_private, addr, len);
-  xdrs->x_private += len;
-  return (TRUE);
-}
-
-static unsigned int xdrmem_getpos (const XDR *xdrs)
-{
-    return ((unsigned long) xdrs->x_private - (unsigned long) xdrs->x_base);
-}
-
-static bool_t xdrmem_setpos(XDR *xdrs, unsigned int pos)
-{
-  register char* newaddr = xdrs->x_base + pos;
-  register char* lastaddr = xdrs->x_private + xdrs->x_handy;
-
-  if ((long) newaddr > (long) lastaddr
-      || (UINT_MAX < LONG_MAX
-          && (long) UINT_MAX < (long) lastaddr - (long) newaddr))
-      return (FALSE);
-  xdrs->x_private = newaddr;
-  xdrs->x_handy = (long) lastaddr - (long) newaddr;
-  return (TRUE);
-}
-
-static int32_t *
-xdrmem_inline (XDR *xdrs, unsigned int len)
-{
-    int32_t *buf = 0;
-
-    if (xdrs->x_handy >= len) {
-        xdrs->x_handy -= len;
-        buf = (int32_t *) xdrs->x_private;
-        xdrs->x_private += len;
-    }
-    return (buf);
-}
-

+ 145 - 132
components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -10,24 +10,44 @@
 #include <rtthread.h>
 #include <dfs.h>
 #include <dfs_fs.h>
+#include <dfs_dentry.h>
 #include <dfs_file.h>
+#include <dfs_mnt.h>
 
 #include "dfs_romfs.h"
+#include <errno.h>
+#include <fcntl.h>
 
-int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
+#include <rtdbg.h>
+
+static const struct dfs_file_ops _rom_fops;
+
+static const mode_t romfs_modemap[] =
+{
+    S_IFREG  | 0644,    /* regular file */
+    S_IFDIR  | 0644,    /* directory */
+    0,                  /* hard link */
+    S_IFLNK  | 0777,    /* symlink */
+    S_IFBLK  | 0600,    /* blockdev */
+    S_IFCHR  | 0600,    /* chardev */
+    S_IFSOCK | 0644,    /* socket */
+    S_IFIFO  | 0644     /* FIFO */
+};
+
+static int dfs_romfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
 {
     struct romfs_dirent *root_dirent;
 
     if (data == NULL)
-        return -EIO;
+        return -1;
 
     root_dirent = (struct romfs_dirent *)data;
-    fs->data = root_dirent;
+    mnt->data = root_dirent;
 
-    return RT_EOK;
+    return 0;
 }
 
-int dfs_romfs_unmount(struct dfs_filesystem *fs)
+static int dfs_romfs_umount(struct dfs_mnt *fs)
 {
     return RT_EOK;
 }
@@ -37,7 +57,7 @@ int dfs_romfs_ioctl(struct dfs_file *file, int cmd, void *args)
     int ret = RT_EOK;
     struct romfs_dirent *dirent;
 
-    dirent = (struct romfs_dirent *)file->vnode->data;
+    dirent = (struct romfs_dirent *)file->data;
     RT_ASSERT(dirent != NULL);
 
     switch (cmd)
@@ -60,13 +80,14 @@ int dfs_romfs_ioctl(struct dfs_file *file, int cmd, void *args)
 
 rt_inline int check_dirent(struct romfs_dirent *dirent)
 {
-    if ((dirent->type != ROMFS_DIRENT_FILE && dirent->type != ROMFS_DIRENT_DIR)
-        || dirent->size == ~0U)
+    if (dirent == NULL
+        ||(dirent->type != ROMFS_DIRENT_FILE && dirent->type != ROMFS_DIRENT_DIR)
+        || dirent->size == ~0)
         return -1;
     return 0;
 }
 
-struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
+struct romfs_dirent *__dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
 {
     rt_size_t index, found;
     const char *subpath, *subpath_end;
@@ -83,7 +104,7 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch
         return root_dirent;
     }
 
-    /* goto root directory entries */
+    /* goto root directy entries */
     dirent = (struct romfs_dirent *)root_dirent->data;
     dirent_size = root_dirent->size;
 
@@ -105,7 +126,7 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch
         {
             if (check_dirent(&dirent[index]) != 0)
                 return NULL;
-            if (rt_strlen(dirent[index].name) ==  (rt_size_t)(subpath_end - subpath) &&
+            if (rt_strlen(dirent[index].name) == (subpath_end - subpath) &&
                     rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
             {
                 dirent_size = dirent[index].size;
@@ -146,7 +167,68 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch
     return NULL;
 }
 
-int dfs_romfs_read(struct dfs_file *file, void *buf, size_t count)
+static struct dfs_vnode *dfs_romfs_lookup (struct dfs_dentry *dentry)
+{
+    rt_size_t size;
+    struct dfs_vnode *vnode = RT_NULL;
+    struct romfs_dirent *root_dirent = RT_NULL, *dirent = RT_NULL;
+
+    RT_ASSERT(dentry != RT_NULL);
+    RT_ASSERT(dentry->mnt != RT_NULL);
+
+    root_dirent = (struct romfs_dirent *)dentry->mnt->data;
+    if (check_dirent(root_dirent) == 0)
+    {
+        /* create a vnode */
+        DLOG(msg, "rom", "vnode", DLOG_MSG, "dfs_vnode_create()");
+        vnode = dfs_vnode_create();
+        if (vnode)
+        {
+            dirent = __dfs_romfs_lookup(root_dirent, dentry->pathname, &size);
+            if (dirent)
+            {
+                vnode->nlink = 1;
+                vnode->size = dirent->size;
+                if (dirent->type == ROMFS_DIRENT_DIR)
+                {
+                    vnode->mode = romfs_modemap[ROMFS_DIRENT_DIR] | S_IRUSR;
+                    vnode->type = FT_DIRECTORY;
+                }
+                else if (dirent->type == ROMFS_DIRENT_FILE)
+                {
+                    vnode->mode = romfs_modemap[ROMFS_DIRENT_FILE] | S_IRUSR | S_IXUSR;
+                    vnode->type = FT_REGULAR;
+                }
+
+                DLOG(msg, "rom", "rom", DLOG_MSG, "vnode->data = dirent");
+                vnode->data = dirent;
+                vnode->mnt = dentry->mnt;
+            }
+            else
+            {
+                /* no-entry */
+                DLOG(msg, "rom", "vnode", DLOG_MSG, "dfs_vnode_destroy, no-dentry");
+                dfs_vnode_destroy(vnode);
+                vnode = RT_NULL;
+            }
+        }
+    }
+
+    return vnode;
+}
+
+static int dfs_romfs_free_vnode(struct dfs_vnode *vnode)
+{
+    /* nothing to be freed */
+    if (vnode->ref_count <= 1)
+    {
+        vnode->data = NULL;
+    }
+
+    return 0;
+}
+
+static int dfs_romfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
 {
     rt_size_t length;
     struct romfs_dirent *dirent;
@@ -159,39 +241,22 @@ int dfs_romfs_read(struct dfs_file *file, void *buf, size_t count)
         return -EIO;
     }
 
-    if (count < file->vnode->size - file->pos)
+    if (count < file->vnode->size - *pos)
         length = count;
     else
-        length = file->vnode->size - file->pos;
+        length = file->vnode->size - *pos;
 
     if (length > 0)
-        rt_memcpy(buf, &(dirent->data[file->pos]), length);
+        memcpy(buf, &(dirent->data[*pos]), length);
 
     /* update file current position */
-    file->pos += length;
+    *pos += length;
 
     return length;
 }
 
-int dfs_romfs_lseek(struct dfs_file *file, off_t offset)
-{
-    if (offset <= file->vnode->size)
-    {
-        file->pos = offset;
-        return file->pos;
-    }
-
-    return -EIO;
-}
-
-int dfs_romfs_close(struct dfs_file *file)
+static int dfs_romfs_close(struct dfs_file *file)
 {
-    RT_ASSERT(file->vnode->ref_count > 0);
-    if (file->vnode->ref_count > 1)
-    {
-        return RT_EOK;
-    }
-    file->vnode->data = NULL;
     return RT_EOK;
 }
 
@@ -200,104 +265,56 @@ int dfs_romfs_open(struct dfs_file *file)
     rt_size_t size;
     struct romfs_dirent *dirent;
     struct romfs_dirent *root_dirent;
-    struct dfs_filesystem *fs;
+    struct dfs_mnt *mnt;
 
     if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
     {
         return -EINVAL;
     }
 
-    RT_ASSERT(file->vnode->ref_count > 0);
-    if (file->vnode->ref_count > 1)
-    {
-        if (file->vnode->type == FT_DIRECTORY
-                && !(file->flags & O_DIRECTORY))
-        {
-            return -ENOENT;
-        }
-        file->pos = 0;
-        return 0;
-    }
-
-    fs = file->vnode->fs;
-    root_dirent = (struct romfs_dirent *)fs->data;
+    mnt = file->dentry->mnt;
+    RT_ASSERT(mnt != RT_NULL);
 
+    root_dirent = (struct romfs_dirent *)mnt->data;
     if (check_dirent(root_dirent) != 0)
     {
         return -EIO;
     }
 
-    if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
-    {
-        return -EINVAL;
-    }
-
-    dirent = dfs_romfs_lookup(root_dirent, file->vnode->path, &size);
+    /* get rom dirent */
+    dirent = __dfs_romfs_lookup(root_dirent, file->dentry->pathname, &size);
     if (dirent == NULL)
     {
         return -ENOENT;
     }
 
-    /* entry is a directory file type */
-    if (dirent->type == ROMFS_DIRENT_DIR)
-    {
-        if (!(file->flags & O_DIRECTORY))
-        {
-            return -ENOENT;
-        }
-        file->vnode->type = FT_DIRECTORY;
-    }
-    else
-    {
-        /* entry is a file, but open it as a directory */
-        if (file->flags & O_DIRECTORY)
-        {
-            return -ENOENT;
-        }
-        file->vnode->type = FT_REGULAR;
-    }
-
-    file->vnode->data = dirent;
-    file->vnode->size = size;
-    file->pos = 0;
+    file->data = dirent;
+    file->fops = &_rom_fops;
+    file->fpos = 0;
 
     return RT_EOK;
 }
 
-int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
+static int dfs_romfs_stat(struct dfs_dentry *dentry, struct stat *st)
 {
-    rt_size_t size;
-    struct romfs_dirent *dirent;
-    struct romfs_dirent *root_dirent;
-
-    root_dirent = (struct romfs_dirent *)fs->data;
-    dirent = dfs_romfs_lookup(root_dirent, path, &size);
-
-    if (dirent == NULL)
+    rt_err_t ret = dfs_file_lock();
+    if (ret == RT_EOK)
     {
-        return -ENOENT;
-    }
-
-    st->st_dev = 0;
-    st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
-                  S_IWUSR | S_IWGRP | S_IWOTH;
+        st->st_dev = 0;
+        st->st_mode = dentry->vnode->mode;
+        st->st_size = dentry->vnode->size;
+        st->st_nlink = dentry->vnode->nlink;
+        st->st_mtime = 0;
 
-    if (dirent->type == ROMFS_DIRENT_DIR)
-    {
-        st->st_mode &= ~S_IFREG;
-        st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+        dfs_file_unlock();
     }
 
-    st->st_size = dirent->size;
-    st->st_mtime = 0;
-
     return RT_EOK;
 }
 
-int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
+static int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
 {
     rt_size_t index;
-    rt_size_t len;
     const char *name;
     struct dirent *d;
     struct romfs_dirent *dirent, *sub_dirent;
@@ -320,11 +337,11 @@ int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t coun
     }
 
     index = 0;
-    for (index = 0; index < count && file->pos < file->vnode->size; index++)
+    for (index = 0; index < count && file->fpos < file->vnode->size; index++)
     {
         d = dirp + index;
 
-        sub_dirent = &dirent[file->pos];
+        sub_dirent = &dirent[file->fpos];
         name = sub_dirent->name;
 
         /* fill dirent */
@@ -333,14 +350,12 @@ int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t coun
         else
             d->d_type = DT_REG;
 
-        len = rt_strlen(name);
-        RT_ASSERT(len <= RT_UINT8_MAX);
-        d->d_namlen = (rt_uint8_t)len;
+        d->d_namlen = rt_strlen(name);
         d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
-        rt_strncpy(d->d_name, name, DFS_PATH_MAX);
+        rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
 
         /* move to next position */
-        ++ file->pos;
+        ++ file->fpos;
     }
 
     return index * sizeof(struct dirent);
@@ -348,37 +363,35 @@ int dfs_romfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t coun
 
 static const struct dfs_file_ops _rom_fops =
 {
-    dfs_romfs_open,
-    dfs_romfs_close,
-    dfs_romfs_ioctl,
-    dfs_romfs_read,
-    NULL,
-    NULL,
-    dfs_romfs_lseek,
-    dfs_romfs_getdents,
-    NULL,
+    .open             = dfs_romfs_open,
+    .close            = dfs_romfs_close,
+    .lseek            = generic_dfs_lseek,
+    .read             = dfs_romfs_read,
+    .getdents         = dfs_romfs_getdents,
+};
+
+static const struct dfs_filesystem_ops _romfs_ops =
+{
+    .name             ="rom",
+    .flags            = 0,
+    .default_fops     = &_rom_fops,
+    .mount            = dfs_romfs_mount,
+    .umount           = dfs_romfs_umount,
+    .stat             = dfs_romfs_stat,
+    .lookup           = dfs_romfs_lookup,
+    .free_vnode       = dfs_romfs_free_vnode
 };
-static const struct dfs_filesystem_ops _romfs =
+
+static struct dfs_filesystem_type _romfs =
 {
-    "rom",
-    DFS_FS_FLAG_DEFAULT,
-    &_rom_fops,
-
-    dfs_romfs_mount,
-    dfs_romfs_unmount,
-    NULL,
-    NULL,
-
-    NULL,
-    dfs_romfs_stat,
-    NULL,
+    .fs_ops           = &_romfs_ops,
 };
 
 int dfs_romfs_init(void)
 {
     /* register rom file system */
     dfs_register(&_romfs);
+
     return 0;
 }
 INIT_COMPONENT_EXPORT(dfs_romfs_init);
-

+ 2 - 1
components/dfs/dfs_v2/filesystems/romfs/romfs.c

@@ -27,6 +27,8 @@ static const unsigned char _dummy_txt[] =
 
 rt_weak const struct romfs_dirent _root_dirent[] =
 {
+    {ROMFS_DIRENT_DIR, "dev", RT_NULL, 0},
+    {ROMFS_DIRENT_DIR, "mnt", RT_NULL, 0},
     {ROMFS_DIRENT_DIR, "dummy", (rt_uint8_t *)_dummy, sizeof(_dummy) / sizeof(_dummy[0])},
     {ROMFS_DIRENT_FILE, "dummy.txt", _dummy_txt, sizeof(_dummy_txt)},
 };
@@ -35,4 +37,3 @@ rt_weak const struct romfs_dirent romfs_root =
 {
     ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_root_dirent, sizeof(_root_dirent) / sizeof(_root_dirent[0])
 };
-

+ 0 - 1
components/dfs/dfs_v2/filesystems/skeleton/skeleton.c

@@ -94,4 +94,3 @@ int dfs_skt_init(void)
     return 0;
 }
 INIT_COMPONENT_EXPORT(dfs_skt_init);
-

+ 231 - 179
components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -13,7 +13,9 @@
 #include <rtthread.h>
 #include <dfs.h>
 #include <dfs_fs.h>
+#include <dfs_dentry.h>
 #include <dfs_file.h>
+#include <dfs_mnt.h>
 
 #ifdef RT_USING_SMART
 #include <lwp.h>
@@ -109,48 +111,55 @@ static int _free_subdir(struct tmpfs_file *dfile)
     return 0;
 }
 
-int dfs_tmpfs_mount(struct dfs_filesystem *fs,
-                    unsigned long          rwflag,
-                    const void            *data)
+static int dfs_tmpfs_mount(struct dfs_mnt    *mnt,
+                                            unsigned long   rwflag,
+                                            const void      *data)
 {
     struct tmpfs_sb *superblock;
 
     superblock = rt_calloc(1, sizeof(struct tmpfs_sb));
-    superblock->df_size = sizeof(struct tmpfs_sb);
-    superblock->magic = TMPFS_MAGIC;
-    rt_list_init(&superblock->sibling);
+    if (superblock)
+    {
+        superblock->df_size = sizeof(struct tmpfs_sb);
+        superblock->magic = TMPFS_MAGIC;
+        rt_list_init(&superblock->sibling);
 
-    superblock->root.name[0] = '/';
-    superblock->root.sb = superblock;
-    superblock->root.type = TMPFS_TYPE_DIR;
-    rt_list_init(&superblock->root.sibling);
-    rt_list_init(&superblock->root.subdirs);
+        superblock->root.name[0] = '/';
+        superblock->root.sb = superblock;
+        superblock->root.type = TMPFS_TYPE_DIR;
+        rt_list_init(&superblock->root.sibling);
+        rt_list_init(&superblock->root.subdirs);
 
-    fs->data = superblock;
+        mnt->data = superblock;
+    }
+    else
+    {
+        return -1;
+    }
 
-    return RT_EOK;
+    return 0;
 }
 
-int dfs_tmpfs_unmount(struct dfs_filesystem *fs)
+static int dfs_tmpfs_unmount(struct dfs_mnt *mnt)
 {
     struct tmpfs_sb *superblock;
 
-    superblock = (struct tmpfs_sb *)fs->data;
+    superblock = (struct tmpfs_sb *)mnt->data;
     RT_ASSERT(superblock != NULL);
 
     _free_subdir(&(superblock->root));
     rt_free(superblock);
 
-    fs->data = NULL;
+    mnt->data = NULL;
 
     return RT_EOK;
 }
 
-int dfs_tmpfs_statfs(struct dfs_filesystem *fs, struct statfs *buf)
+int dfs_tmpfs_statfs(struct dfs_mnt *mnt, struct statfs *buf)
 {
     struct tmpfs_sb *superblock;
 
-    superblock = (struct tmpfs_sb *)fs->data;
+    superblock = (struct tmpfs_sb *)mnt->data;
     RT_ASSERT(superblock != NULL);
     RT_ASSERT(buf != NULL);
 
@@ -263,7 +272,7 @@ find_subpath:
     return NULL;
 }
 
-int dfs_tmpfs_read(struct dfs_file *file, void *buf, size_t count)
+static int dfs_tmpfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
 {
     rt_size_t length;
     struct tmpfs_file *d_file;
@@ -271,66 +280,68 @@ int dfs_tmpfs_read(struct dfs_file *file, void *buf, size_t count)
     d_file = (struct tmpfs_file *)file->vnode->data;
     RT_ASSERT(d_file != NULL);
 
-    if (count < file->vnode->size - file->pos)
+    if (count < file->vnode->size - file->fpos)
         length = count;
     else
-        length = file->vnode->size - file->pos;
+        length = file->vnode->size - file->fpos;
 
     if (length > 0)
-        memcpy(buf, &(d_file->data[file->pos]), length);
+        memcpy(buf, &(d_file->data[file->fpos]), length);
 
     /* update file current position */
-    file->pos += length;
+    file->fpos += length;
+    *pos = file->fpos;
 
     return length;
 }
 
 
-int dfs_tmpfs_write(struct dfs_file *fd, const void *buf, size_t count)
+static int dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
 {
     struct tmpfs_file *d_file;
     struct tmpfs_sb *superblock;
 
-    d_file = (struct tmpfs_file *)fd->vnode->data;
+    d_file = (struct tmpfs_file *)file->vnode->data;
     RT_ASSERT(d_file != NULL);
 
     superblock = d_file->sb;
     RT_ASSERT(superblock != NULL);
 
-    if (count + fd->pos > fd->vnode->size)
+    if (count + file->fpos > file->vnode->size)
     {
         rt_uint8_t *ptr;
-        ptr = rt_realloc(d_file->data, fd->pos + count);
+        ptr = rt_realloc(d_file->data, file->fpos + count);
         if (ptr == NULL)
         {
             rt_set_errno(-ENOMEM);
             return 0;
         }
 
-        superblock->df_size += (fd->pos - d_file->size + count);
+        superblock->df_size += (file->fpos - d_file->size + count);
         /* update d_file and file size */
         d_file->data = ptr;
-        d_file->size = fd->pos + count;
-        fd->vnode->size = d_file->size;
+        d_file->size = file->fpos + count;
+        file->vnode->size = d_file->size;
         LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size);
     }
 
     if (count > 0)
-        memcpy(d_file->data + fd->pos, buf, count);
+        memcpy(d_file->data + file->fpos, buf, count);
 
     /* update file current position */
-    fd->pos += count;
+    file->fpos += count;
+    *pos = file->fpos;
 
     return count;
 }
 
-int dfs_tmpfs_lseek(struct dfs_file *file, off_t offset)
+static int dfs_tmpfs_lseek(struct dfs_file *file, off_t offset, int wherece)
 {
     if (offset <= (off_t)file->vnode->size)
     {
-        file->pos = offset;
+        file->fpos = offset;
 
-        return file->pos;
+        return file->fpos;
     }
 
     return -EIO;
@@ -339,97 +350,23 @@ int dfs_tmpfs_lseek(struct dfs_file *file, off_t offset)
 int dfs_tmpfs_close(struct dfs_file *file)
 {
     RT_ASSERT(file->vnode->ref_count > 0);
-    if (file->vnode->ref_count > 1)
-    {
-        return 0;
-    }
-
-    file->vnode->data = NULL;
-
     return RT_EOK;
 }
 
 int dfs_tmpfs_open(struct dfs_file *file)
 {
-    rt_size_t size;
-    struct tmpfs_sb *superblock;
-    struct tmpfs_file *d_file, *p_file;
-    struct dfs_filesystem *fs;
-    char parent_path[DFS_PATH_MAX],file_name[TMPFS_NAME_MAX];
-
-    RT_DEFINE_SPINLOCK(lock);
-
-    RT_ASSERT(file->vnode->ref_count > 0);
-    if (file->vnode->ref_count > 1)
-    {
-        if (file->vnode->type == FT_DIRECTORY
-                && !(file->flags & O_DIRECTORY))
-        {
-            return -ENOENT;
-        }
-        file->pos = 0;
-        return 0;
-    }
-
-    fs = file->vnode->fs;
-
-    superblock = (struct tmpfs_sb *)fs->data;
-    RT_ASSERT(superblock != NULL);
-
-    /* find file */
-    d_file = dfs_tmpfs_lookup(superblock, file->vnode->path, &size);
-    if (d_file == NULL && !(file->flags & O_CREAT))
-        return -ENOENT;
-
-    /* Creates a new file. */
-    if (file->flags & O_CREAT)
-    {
-        if (d_file == NULL)
-        {
-            /* find parent file */
-            _path_separate(file->vnode->path, parent_path, file_name);
-            if (file_name[0] == '\0') /* it's root dir */
-                return -ENOENT;
-
-            /* open parent directory */
-            p_file = dfs_tmpfs_lookup(superblock, parent_path, &size);
-            if (p_file == NULL)
-                return -ENOENT;
-
-            /* create a file entry */
-            d_file = (struct tmpfs_file *)rt_calloc(1, sizeof(struct tmpfs_file));
-            if (d_file == NULL)
-            {
-                return -ENOMEM;
-            }
-            superblock->df_size += sizeof(struct tmpfs_file);
-
-            strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
+    struct tmpfs_file *d_file;
 
-            rt_list_init(&(d_file->subdirs));
-            rt_list_init(&(d_file->sibling));
-            d_file->data = NULL;
-            d_file->size = 0;
-            d_file->sb   = superblock;
-            if (file->flags & O_DIRECTORY)
-            {
-                d_file->type = TMPFS_TYPE_DIR;
-            }
-            else
-            {
-                d_file->type = TMPFS_TYPE_FILE;
-            }
-            rt_hw_spin_lock(&lock);
-            rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
-            rt_hw_spin_unlock(&lock);
-        }
-    }
+    d_file = (struct tmpfs_file *)file->vnode->data;
+    RT_ASSERT(d_file != RT_NULL);
     /* Creates a new file.
-        * If the file is existing, it is truncated and overwritten.
-        */
+     * If the file is existing, it is truncated and overwritten.
+     */
     if (file->flags & O_TRUNC)
     {
         d_file->size = 0;
+        file->vnode->size = d_file->size;
+        file->fpos = file->vnode->size;
         if (d_file->data != NULL)
         {
             /* ToDo: fix for rt-smart. */
@@ -438,52 +375,33 @@ int dfs_tmpfs_open(struct dfs_file *file)
         }
     }
 
-    /* fill file */
-    if (d_file->type == TMPFS_TYPE_DIR)
-    {
-        if (file->flags & O_DIRECTORY)
-            file->vnode->type = FT_DIRECTORY;
-        else
-            return -ENOMEM;
-    }
-    else
-    {
-        if (file->flags & O_DIRECTORY)
-        {
-            return -ENOMEM;
-        }
-        file->vnode->type = FT_DEVICE;
-    }
-
-    file->vnode->data = d_file;
-    file->vnode->size = d_file->size;
     if (file->flags & O_APPEND)
     {
-        file->pos = file->vnode->size;
+        file->fpos = file->vnode->size;
     }
     else
     {
-        file->pos = 0;
+        file->fpos = 0;
     }
 
     return 0;
 }
 
-int dfs_tmpfs_stat(struct dfs_filesystem *fs,
-                   const char            *path,
-                   struct stat           *st)
+static int dfs_tmpfs_stat(struct dfs_dentry *dentry, struct stat *st)
 {
     rt_size_t size;
     struct tmpfs_file *d_file;
     struct tmpfs_sb *superblock;
 
-    superblock = (struct tmpfs_sb *)fs->data;
-    d_file = dfs_tmpfs_lookup(superblock, path, &size);
+    superblock = (struct tmpfs_sb *)dentry->mnt->data;
+    d_file = dfs_tmpfs_lookup(superblock, dentry->pathname, &size);
 
     if (d_file == NULL)
         return -ENOENT;
 
-    st->st_dev = 0;
+    st->st_dev = (dev_t)(size_t)(dentry->mnt->dev_id);
+    st->st_ino = (ino_t)dfs_dentry_full_path_crc32(dentry);
+
     st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
                   S_IWUSR | S_IWGRP | S_IWOTH;
     if (d_file->type == TMPFS_TYPE_DIR)
@@ -518,14 +436,14 @@ int dfs_tmpfs_getdents(struct dfs_file *file,
     if (count == 0)
         return -EINVAL;
 
-    end = file->pos + count;
+    end = file->fpos + count;
     index = 0;
     count = 0;
 
     rt_list_for_each(list, &d_file->subdirs)
     {
         n_file = rt_list_entry(list, struct tmpfs_file, sibling);
-        if (index >= (rt_size_t)file->pos)
+        if (index >= (rt_size_t)file->fpos)
         {
             d = dirp + count;
             if (d_file->type == TMPFS_TYPE_FILE)
@@ -541,7 +459,7 @@ int dfs_tmpfs_getdents(struct dfs_file *file,
             rt_strncpy(d->d_name, n_file->name, TMPFS_NAME_MAX);
 
             count += 1;
-            file->pos += 1;
+            file->fpos += 1;
         }
         index += 1;
         if (index >= end)
@@ -553,7 +471,7 @@ int dfs_tmpfs_getdents(struct dfs_file *file,
     return count * sizeof(struct dirent);
 }
 
-int dfs_tmpfs_unlink(struct dfs_filesystem *fs, const char *path)
+int dfs_tmpfs_unlink(struct dfs_dentry *dentry)
 {
     rt_size_t size;
     struct tmpfs_sb *superblock;
@@ -561,10 +479,10 @@ int dfs_tmpfs_unlink(struct dfs_filesystem *fs, const char *path)
 
     RT_DEFINE_SPINLOCK(lock);
 
-    superblock = (struct tmpfs_sb *)fs->data;
+    superblock = (struct tmpfs_sb *)dentry->mnt->data;
     RT_ASSERT(superblock != NULL);
 
-    d_file = dfs_tmpfs_lookup(superblock, path, &size);
+    d_file = dfs_tmpfs_lookup(superblock, dentry->pathname, &size);
     if (d_file == NULL)
         return -ENOENT;
 
@@ -579,30 +497,28 @@ int dfs_tmpfs_unlink(struct dfs_filesystem *fs, const char *path)
     return RT_EOK;
 }
 
-int dfs_tmpfs_rename(struct dfs_filesystem *fs,
-                     const char            *oldpath,
-                     const char            *newpath)
+int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *new_dentry)
 {
     struct tmpfs_file *d_file, *p_file;
     struct tmpfs_sb *superblock;
     rt_size_t size;
-    char parent_path[DFS_PATH_MAX],file_name[TMPFS_NAME_MAX];
+    char parent_path[DFS_PATH_MAX], file_name[TMPFS_NAME_MAX];
 
     RT_DEFINE_SPINLOCK(lock);
 
-    superblock = (struct tmpfs_sb *)fs->data;
+    superblock = (struct tmpfs_sb *)old_dentry->mnt->data;
     RT_ASSERT(superblock != NULL);
 
-    d_file = dfs_tmpfs_lookup(superblock, newpath, &size);
+    d_file = dfs_tmpfs_lookup(superblock, new_dentry->pathname, &size);
     if (d_file != NULL)
         return -EEXIST;
 
-    d_file = dfs_tmpfs_lookup(superblock, oldpath, &size);
+    d_file = dfs_tmpfs_lookup(superblock, old_dentry->pathname, &size);
     if (d_file == NULL)
         return -ENOENT;
 
     /* find parent file */
-    _path_separate(newpath, parent_path, file_name);
+    _path_separate(new_dentry->pathname, parent_path, file_name);
     if (file_name[0] == '\0') /* it's root dir */
         return -ENOENT;
     /* open parent directory */
@@ -622,32 +538,167 @@ int dfs_tmpfs_rename(struct dfs_filesystem *fs,
     return RT_EOK;
 }
 
+
+static struct dfs_vnode *_dfs_tmpfs_lookup(struct dfs_dentry *dentry)
+{
+    struct dfs_vnode *vnode = RT_NULL;
+    rt_size_t size;
+    struct tmpfs_sb *superblock;
+    struct tmpfs_file *d_file;
+
+    if (dentry == NULL || dentry->mnt == NULL || dentry->mnt->data == NULL)
+    {
+        return NULL;
+    }
+
+    superblock = (struct tmpfs_sb *)dentry->mnt->data;
+
+    d_file = dfs_tmpfs_lookup(superblock, dentry->pathname, &size);
+    if (d_file)
+    {
+        vnode = dfs_vnode_create();
+        if (vnode)
+        {
+            if (d_file->type == TMPFS_TYPE_DIR)
+            {
+                vnode->mode = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR;
+                vnode->type = FT_DIRECTORY;
+            }
+            else
+            {
+                vnode->mode = S_IFREG | S_IRUSR | S_IWUSR | S_IXUSR;
+                vnode->type = FT_REGULAR;
+            }
+
+            vnode->mnt = dentry->mnt;
+            vnode->data = d_file;
+            vnode->size = d_file->size;
+        }
+    }
+
+    return vnode;
+}
+
+static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int type, mode_t mode)
+{
+    struct dfs_vnode *vnode = RT_NULL;
+    rt_size_t size;
+    struct tmpfs_sb *superblock;
+    struct tmpfs_file *d_file, *p_file;
+    char parent_path[DFS_PATH_MAX], file_name[TMPFS_NAME_MAX];
+
+    RT_DEFINE_SPINLOCK(lock);
+
+    if (dentry == NULL || dentry->mnt == NULL || dentry->mnt->data == NULL)
+    {
+        return NULL;
+    }
+
+    superblock = (struct tmpfs_sb *)dentry->mnt->data;
+
+    vnode = dfs_vnode_create();
+    if (vnode)
+    {
+        /* find parent file */
+        _path_separate(dentry->pathname, parent_path, file_name);
+        if (file_name[0] == '\0') /* it's root dir */
+        {
+            dfs_vnode_destroy(vnode);
+            return NULL;
+        }
+
+        /* open parent directory */
+        p_file = dfs_tmpfs_lookup(superblock, parent_path, &size);
+        if (p_file == NULL)
+        {
+            dfs_vnode_destroy(vnode);
+            return NULL;
+        }
+
+        /* create a file entry */
+        d_file = (struct tmpfs_file *)rt_calloc(1, sizeof(struct tmpfs_file));
+        if (d_file == NULL)
+        {
+            dfs_vnode_destroy(vnode);
+            return NULL;
+        }
+
+        superblock->df_size += sizeof(struct tmpfs_file);
+
+        strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
+
+        rt_list_init(&(d_file->subdirs));
+        rt_list_init(&(d_file->sibling));
+        d_file->data = NULL;
+        d_file->size = 0;
+        d_file->sb = superblock;
+        if (type == FT_DIRECTORY)
+        {
+            d_file->type = TMPFS_TYPE_DIR;
+            vnode->mode = S_IFDIR | mode;
+            vnode->type = FT_DIRECTORY;
+        }
+        else
+        {
+            d_file->type = TMPFS_TYPE_FILE;
+            vnode->mode = S_IFREG | mode;
+            vnode->type = FT_REGULAR;
+        }
+        rt_hw_spin_lock(&lock);
+        rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
+        rt_hw_spin_unlock(&lock);
+
+        vnode->mnt = dentry->mnt;
+        vnode->data = d_file;
+        vnode->size = d_file->size;
+    }
+
+    return vnode;
+}
+
+static int dfs_tmpfs_free_vnode(struct dfs_vnode *vnode)
+{
+    /* nothing to be freed */
+    if (vnode && vnode->ref_count <= 1)
+    {
+        vnode->data = NULL;
+    }
+
+    return 0;
+}
+
 static const struct dfs_file_ops _tmp_fops =
 {
-    dfs_tmpfs_open,
-    dfs_tmpfs_close,
-    dfs_tmpfs_ioctl,
-    dfs_tmpfs_read,
-    dfs_tmpfs_write,
-    NULL, /* flush */
-    dfs_tmpfs_lseek,
-    dfs_tmpfs_getdents,
+    .open = dfs_tmpfs_open,
+    .close = dfs_tmpfs_close,
+    .ioctl = dfs_tmpfs_ioctl,
+    .read = dfs_tmpfs_read,
+    .write = dfs_tmpfs_write,
+    .lseek = dfs_tmpfs_lseek,
+    .getdents = dfs_tmpfs_getdents,
+};
+
+static const struct dfs_filesystem_ops _tmpfs_ops =
+{
+    .name = "tmp",
+    .flags = DFS_FS_FLAG_DEFAULT,
+    .default_fops = &_tmp_fops,
+
+    .mount = dfs_tmpfs_mount,
+    .umount = dfs_tmpfs_unmount,
+    .statfs = dfs_tmpfs_statfs,
+
+    .unlink = dfs_tmpfs_unlink,
+    .stat = dfs_tmpfs_stat,
+    .rename = dfs_tmpfs_rename,
+    .lookup = _dfs_tmpfs_lookup,
+    .create_vnode = dfs_tmpfs_create_vnode,
+    .free_vnode = dfs_tmpfs_free_vnode
 };
 
-static const struct dfs_filesystem_ops _tmpfs =
+static struct dfs_filesystem_type _tmpfs =
 {
-    "tmp",
-    DFS_FS_FLAG_DEFAULT,
-    &_tmp_fops,
-
-    dfs_tmpfs_mount,
-    dfs_tmpfs_unmount,
-    NULL, /* mkfs */
-    dfs_tmpfs_statfs,
-
-    dfs_tmpfs_unlink,
-    dfs_tmpfs_stat,
-    dfs_tmpfs_rename,
+    .fs_ops = &_tmpfs_ops,
 };
 
 int dfs_tmpfs_init(void)
@@ -657,3 +708,4 @@ int dfs_tmpfs_init(void)
 
     return 0;
 }
+INIT_COMPONENT_EXPORT(dfs_tmpfs_init);

+ 30 - 33
components/dfs/dfs_v2/include/dfs.h

@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2005-02-22     Bernard      The first version.
+ * 2023-05-05     Bernard      change to dfs v2.0
  */
 
 #ifndef __DFS_H__
@@ -15,21 +16,15 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
-#include <dirent.h>
+#include "../../libc/compilers/common/include/dirent.h"
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/statfs.h>
 #include <sys/time.h>
+#include <sys/errno.h>
+#include <rtatomic.h>
 #include <rtdevice.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef DFS_FILESYSTEMS_MAX
-#define DFS_FILESYSTEMS_MAX     4
-#endif
-
 #ifndef DFS_FD_MAX
 #define DFS_FD_MAX              16
 #endif
@@ -49,25 +44,32 @@ extern "C" {
 #define SECTOR_SIZE              512
 #endif
 
-#ifndef DFS_FILESYSTEM_TYPES_MAX
-#define DFS_FILESYSTEM_TYPES_MAX 2
-#endif
-
 #define DFS_FS_FLAG_DEFAULT     0x00    /* default flag */
 #define DFS_FS_FLAG_FULLPATH    0x01    /* set full path to underlaying file system */
 
-/* File types */
-#define FT_REGULAR               0   /* regular file */
-#define FT_SOCKET                1   /* socket file  */
-#define FT_DIRECTORY             2   /* directory    */
-#define FT_USER                  3   /* user defined */
-#define FT_DEVICE                4   /* device */
-
 /* File flags */
-#define DFS_F_OPEN              0x01000000
-#define DFS_F_DIRECTORY         0x02000000
-#define DFS_F_EOF               0x04000000
-#define DFS_F_ERR               0x08000000
+#define DFS_F_FREAD     0x01
+#define DFS_F_FWRITE    0x02
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+rt_inline int dfs_fflags(int oflags)
+{
+    int rw = oflags & O_ACCMODE;
+
+    oflags &= ~O_ACCMODE;
+    return (rw + 1) | oflags;
+}
+
+rt_inline int dfs_oflags(int fflags)
+{
+    int rw = fflags & (DFS_F_FREAD | DFS_F_FWRITE);
+
+    fflags &= ~(DFS_F_FREAD | DFS_F_FWRITE);
+    return (rw - 1) | fflags;
+}
 
 struct dfs_fdtable
 {
@@ -81,18 +83,12 @@ int dfs_init(void);
 char *dfs_normalize_path(const char *directory, const char *filename);
 const char *dfs_subdir(const char *directory, const char *filename);
 
-int fd_is_open(const char *pathname);
-struct dfs_fdtable *dfs_fdtable_get(void);
-
-void dfs_lock(void);
+rt_err_t dfs_lock(void);
 void dfs_unlock(void);
 
-void dfs_file_lock(void);
+rt_err_t dfs_file_lock(void);
 void dfs_file_unlock(void);
 
-void dfs_fm_lock(void);
-void dfs_fm_unlock(void);
-
 #ifdef DFS_USING_POSIX
 /* FD APIs */
 int fdt_fd_new(struct dfs_fdtable *fdt);
@@ -108,6 +104,7 @@ void fd_init(struct dfs_file *fd);
 
 struct dfs_fdtable *dfs_fdtable_get(void);
 struct dfs_fdtable *dfs_fdtable_get_global(void);
+int dfs_dup(int oldfd, int startfd);
 #endif /* DFS_USING_POSIX */
 
 #ifdef __cplusplus

+ 64 - 0
components/dfs/dfs_v2/include/dfs_dentry.h

@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-05-05     Bernard      Implement dentry in dfs v2.0
+ */
+
+#ifndef __DFS_DENTRY_H__
+#define __DFS_DENTRY_H__
+
+#include "dfs_file.h"
+#include "dfs_fs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct dfs_mnt;
+struct dfs_vnode;
+
+struct dfs_dentry
+{
+    rt_list_t hashlist;
+
+    uint32_t flags;
+
+#define DENTRY_IS_MOUNTED   0x1 /* dentry is mounted */
+#define DENTRY_IS_ALLOCED   0x2 /* dentry is allocated */
+#define DENTRY_IS_ADDHASH   0x4 /* dentry was added into hash table */
+#define DENTRY_IS_OPENED    0x8 /* dentry was opened. */
+    char *pathname;             /* the pathname under mounted file sytem */
+
+    struct dfs_vnode *vnode;    /* the vnode of this dentry */
+    struct dfs_mnt *mnt;        /* which mounted file system does this dentry belong to */
+
+    rt_atomic_t ref_count;    /* the reference count */
+};
+
+struct dfs_dentry *dfs_dentry_create(struct dfs_mnt *mnt, char *fullpath);
+struct dfs_dentry *dfs_dentry_unref(struct dfs_dentry *dentry);
+struct dfs_dentry *dfs_dentry_ref(struct dfs_dentry *dentry);
+void dfs_dentry_insert(struct dfs_dentry *dentry);
+struct dfs_dentry *dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint32_t flags);
+
+/* get full path of a dentry */
+char* dfs_dentry_full_path(struct dfs_dentry* dentry);
+
+/* get pathname (with mnt path) of a dentry */
+char* dfs_dentry_pathname(struct dfs_dentry* dentry);
+
+/* get full path crc32 */
+uint32_t dfs_dentry_full_path_crc32(struct dfs_dentry* dentry);
+
+int dfs_dentry_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__DFS_DENTRY_H__*/

+ 118 - 44
components/dfs/dfs_v2/include/dfs_file.h

@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2005-01-26     Bernard      The first version.
+ * 2023-05-05     Bernard      Change to dfs v2.0
  */
 
 #ifndef __DFS_FILE_H__
@@ -15,55 +16,113 @@
 #include <dfs_fs.h>
 
 #ifdef __cplusplus
-extern "C" {
+extern "C"
+{
 #endif
 
+#define STDIN_FILENO  0     /* standard input file descriptor */
+#define STDOUT_FILENO 1     /* standard output file descriptor */
+#define STDERR_FILENO 2     /* standard error file descriptor */
+
+struct dfs_file;
+struct dfs_vnode;
+struct dfs_dentry;
+struct dfs_attr;
+
 struct rt_pollreq;
+struct dirent;
+struct lwp_avl_struct;
+struct file_lock;
 
 struct dfs_file_ops
 {
-    int (*open)     (struct dfs_file *fd);
-    int (*close)    (struct dfs_file *fd);
-    int (*ioctl)    (struct dfs_file *fd, int cmd, void *args);
-    int (*read)     (struct dfs_file *fd, void *buf, size_t count);
-    int (*write)    (struct dfs_file *fd, const void *buf, size_t count);
-    int (*flush)    (struct dfs_file *fd);
-    int (*lseek)    (struct dfs_file *fd, off_t offset);
-    int (*getdents) (struct dfs_file *fd, struct dirent *dirp, uint32_t count);
-
-    int (*poll)     (struct dfs_file *fd, struct rt_pollreq *req);
+    int (*open)(struct dfs_file *file);
+    int (*close)(struct dfs_file *file);
+    int (*ioctl)(struct dfs_file *file, int cmd, void *arg);
+    int (*read)(struct dfs_file *file, void *buf, size_t count, off_t *pos);
+    int (*write)(struct dfs_file *file, const void *buf, size_t count, off_t *pos);
+    int (*flush)(struct dfs_file *file);
+    int (*lseek)(struct dfs_file *file, off_t offset, int wherece);
+    int (*truncate)(struct dfs_file *file, off_t offset);
+    int (*getdents)(struct dfs_file *file, struct dirent *dirp, uint32_t count);
+    int (*poll)(struct dfs_file *file, struct rt_pollreq *req);
+
+    int (*mmap)(struct dfs_file *file, struct lwp_avl_struct *mmap);
+    int (*lock)(struct dfs_file *file, struct file_lock *flock);
+    int (*flock)(struct dfs_file *file, int, struct file_lock *flock);
 };
 
-/* file descriptor */
-#define DFS_FD_MAGIC     0xfdfd
-
 struct dfs_vnode
 {
-    uint16_t type;               /* Type (regular or socket) */
+    uint32_t flags;
+    uint32_t mode;
+    int type;               /* node type */
 
-    char *path;                  /* Name (below mount point) */
-    char *fullpath;              /* Full path is hash key */
-    int ref_count;               /* Descriptor reference count */
-    rt_list_t list;              /* The node of vnode hash table */
+    rt_atomic_t ref_count;  /* reference count */
+
+    struct dfs_mnt *mnt;    /* which mounted file system does this vnode belong to */
+
+    size_t size;
+    uint32_t nlink;
 
-    struct dfs_filesystem *fs;
     const struct dfs_file_ops *fops;
-    uint32_t flags;              /* self flags, is dir etc.. */
 
-    size_t   size;               /* Size in bytes */
-    void *data;                  /* Specific file system data */
+    unsigned int uid;
+    unsigned int gid;
+    struct timespec atime;
+    struct timespec mtime;
+    struct timespec ctime;
+
+    void *data;             /* private data of this file system */
 };
 
+/* file descriptor */
+#define DFS_FD_MAGIC 0xfdfd
 struct dfs_file
 {
-    uint16_t magic;              /* file descriptor magic number */
-    uint32_t flags;              /* Descriptor flags */
-    int ref_count;               /* Descriptor reference count */
-    off_t    pos;                /* Current file position */
-    struct dfs_vnode *vnode;     /* file node struct */
-    void *data;                  /* Specific fd data */
+    uint16_t magic;
+    uint16_t mode;
+
+    uint32_t flags;
+    rt_atomic_t ref_count;
+
+    off_t fpos;
+    struct rt_mutex pos_lock;
+
+    const struct dfs_file_ops *fops;
+    struct dfs_dentry *dentry;  /* dentry of this file */
+    struct dfs_vnode *vnode;    /* vnode of this file */
+
+    void *data;
 };
 
+/* file is open for reading */
+#define FMODE_READ 0x1
+/* file is open for writing */
+#define FMODE_WRITE 0x2
+/* file is seekable */
+#define FMODE_LSEEK 0x4
+/* file can be accessed using pread */
+#define FMODE_PREAD 0x8
+/* file can be accessed using pwrite */
+#define FMODE_PWRITE 0x10
+/* File is opened for execution with sys_execve / sys_uselib */
+#define FMODE_EXEC 0x20
+/* File is opened with O_NDELAY (only set for block devices) */
+#define FMODE_NDELAY 0x40
+/* File is opened with O_EXCL (only set for block devices) */
+#define FMODE_EXCL 0x80
+
+/* dfs_vnode.c */
+int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops);
+struct dfs_vnode *dfs_vnode_create(void);
+int dfs_vnode_destroy(struct dfs_vnode* vnode);
+
+struct dfs_vnode *dfs_vnode_ref(struct dfs_vnode *vnode);
+void dfs_vnode_unref(struct dfs_vnode *vnode);
+
+/*dfs_file.c*/
+
 struct dfs_mmap2_args
 {
     void *addr;
@@ -75,22 +134,37 @@ struct dfs_mmap2_args
     void *ret;
 };
 
-void dfs_vnode_mgr_init(void);
-int dfs_file_is_open(const char *pathname);
-int dfs_file_open(struct dfs_file *fd, const char *path, int flags);
-int dfs_file_close(struct dfs_file *fd);
-int dfs_file_ioctl(struct dfs_file *fd, int cmd, void *args);
-int dfs_file_read(struct dfs_file *fd, void *buf, size_t len);
-int dfs_file_getdents(struct dfs_file *fd, struct dirent *dirp, size_t nbytes);
-int dfs_file_unlink(const char *path);
-int dfs_file_write(struct dfs_file *fd, const void *buf, size_t len);
-int dfs_file_flush(struct dfs_file *fd);
-int dfs_file_lseek(struct dfs_file *fd, off_t offset);
+void dfs_file_init(struct dfs_file *file);
+void dfs_file_deinit(struct dfs_file *file);
 
+int dfs_file_open(struct dfs_file *file, const char *path, int flags, mode_t mode);
+int dfs_file_close(struct dfs_file *file);
+
+ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len);
+ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len);
+int generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence);
+off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece);
 int dfs_file_stat(const char *path, struct stat *buf);
-int dfs_file_rename(const char *oldpath, const char *newpath);
-int dfs_file_ftruncate(struct dfs_file *fd, off_t length);
-int dfs_file_mmap2(struct dfs_file *fd, struct dfs_mmap2_args *mmap2);
+int dfs_file_lstat(const char *path, struct stat *buf);
+int dfs_file_setattr(const char *path, struct dfs_attr *attr);
+int dfs_file_fstat(struct dfs_file *file, struct stat *buf);
+int dfs_file_ioctl(struct dfs_file *file, int cmd, void *args);
+int dfs_file_fcntl(int fd, int cmd, unsigned long arg);
+int dfs_file_fsync(struct dfs_file *file);
+int dfs_file_unlink(const char *path);
+int dfs_file_link(const char *oldname, const char *newname);
+int dfs_file_symlink(const char *oldname, const char *name);
+int dfs_file_readlink(const char *path, char *buf, int bufsize);
+int dfs_file_rename(const char *old_file, const char *new_file);
+int dfs_file_ftruncate(struct dfs_file *file, off_t length);
+int dfs_file_getdents(struct dfs_file *file, struct dirent *dirp, size_t nbytes);
+int dfs_file_mkdir(const char *path, mode_t mode);
+int dfs_file_rmdir(const char *pathname);
+int dfs_file_isdir(const char *path);
+int dfs_file_access(const char *path, mode_t mode);
+int dfs_file_chdir(const char *path);
+char *dfs_file_getcwd(char *buf, size_t size);
+int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2);
 
 /* 0x5254 is just a magic number to make these relatively unique ("RT") */
 #define RT_FIOFTRUNCATE  0x52540000U

+ 56 - 57
components/dfs/dfs_v2/include/dfs_fs.h

@@ -1,99 +1,98 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2005-02-22     Bernard      The first version.
+ * 2023-05-05     Bernard      Change to dfs v2.0
  */
 
 #ifndef __DFS_FS_H__
 #define __DFS_FS_H__
 
 #include <dfs.h>
-#include <sys/types.h>
-#include <sys/errno.h>
+#include <dfs_file.h>
 
 #ifdef __cplusplus
-extern "C" {
+extern "C"
+{
 #endif
 
-/* Pre-declaration */
-struct dfs_filesystem;
-struct dfs_file;
+/* file system partition table */
+struct dfs_partition
+{
+    uint8_t type; /* file system type */
+    off_t offset; /* partition start offset */
+    size_t size;  /* partition size */
+    rt_sem_t lock;
+};
+
+struct dfs_attr
+{
+    mode_t  st_mode;
+};
+
+struct dfs_mnt;
+struct dfs_dentry;
+struct dfs_vnode;
+
+struct statfs;
 
-/* File system operations */
 struct dfs_filesystem_ops
 {
-    char *name;
-    uint32_t flags;      /* flags for file system operations */
+    const char *name;
+    uint32_t flags;
+#define FS_NEED_DEVICE 0x1
 
-    /* operations for file */
-    const struct dfs_file_ops *fops;
+    const struct dfs_file_ops *default_fops;
 
-    /* mount and unmount file system */
-    int (*mount)    (struct dfs_filesystem *fs, unsigned long rwflag, const void *data);
-    int (*unmount)  (struct dfs_filesystem *fs);
+    int (*mount)(struct dfs_mnt *mnt, unsigned long rwflag, const void *data);
+    int (*umount)(struct dfs_mnt *mnt);
 
-    /* make a file system */
-    int (*mkfs)     (rt_device_t dev_id, const char *fs_name);
-    int (*statfs)   (struct dfs_filesystem *fs, struct statfs *buf);
+    int (*mkfs)(rt_device_t devid, const char *fs_name);
 
-    int (*unlink)   (struct dfs_filesystem *fs, const char *pathname);
-    int (*stat)     (struct dfs_filesystem *fs, const char *filename, struct stat *buf);
-    int (*rename)   (struct dfs_filesystem *fs, const char *oldpath, const char *newpath);
-};
+    int (*readlink)(struct dfs_dentry *dentry, char *buf, int len);
+    int (*link)(struct dfs_dentry *src_dentry, struct dfs_dentry *dst_dentry); /*hard link interface */
+    int (*unlink)(struct dfs_dentry *dentry);
+    int (*symlink)(struct dfs_dentry *parent_dentry, const char *target, const char *newpath); /*soft link interface*/
 
-/* Mounted file system */
-struct dfs_filesystem
-{
-    rt_device_t dev_id;     /* Attached device */
+    int (*rename)(struct dfs_dentry *old_dentry, struct dfs_dentry *new_dentry);
+    int (*stat)(struct dfs_dentry *dentry, struct stat *buf);
 
-    char *path;             /* File system mount point */
-    const struct dfs_filesystem_ops *ops; /* Operations for file system type */
+    int (*statfs)(struct dfs_mnt *mnt, struct statfs *buf);
 
-    void *data;             /* Specific file system data */
-};
+    int (*setattr) (struct dfs_dentry *dentry, struct dfs_attr *attr);
 
-/* file system partition table */
-struct dfs_partition
-{
-    uint8_t type;        /* file system type */
-    off_t  offset;       /* partition start offset */
-    size_t size;         /* partition size */
-    rt_sem_t lock;
+    struct dfs_vnode* (*lookup)(struct dfs_dentry *dentry);
+
+    struct dfs_vnode* (*create_vnode)(struct dfs_dentry *dentry, int type, mode_t mode);
+    int (*free_vnode)(struct dfs_vnode* vnode);
 };
 
-/* mount table */
-struct dfs_mount_tbl
+struct dfs_filesystem_type
 {
-    const char   *device_name;
-    const char   *path;
-    const char   *filesystemtype;
-    unsigned long rwflag;
-    const void   *data;
+    const struct dfs_filesystem_ops *fs_ops;
+    struct dfs_filesystem_type *next;
 };
 
-int dfs_register(const struct dfs_filesystem_ops *ops);
-struct dfs_filesystem *dfs_filesystem_lookup(const char *path);
+int dfs_unregister(struct dfs_filesystem_type *fs);
+int dfs_register(struct dfs_filesystem_type *fs);
 const char *dfs_filesystem_get_mounted_path(struct rt_device *device);
 
-int dfs_filesystem_get_partition(struct dfs_partition *part,
-                                 uint8_t         *buf,
-                                 uint32_t        pindex);
-
 int dfs_mount(const char *device_name,
-              const char *path,
-              const char *filesystemtype,
-              unsigned long rwflag,
-              const void *data);
+            const char *path,
+            const char *filesystemtype,
+            unsigned long rwflag,
+            const void *data);
+int dfs_umount(const char *specialfile);
 int dfs_unmount(const char *specialfile);
-
 int dfs_mkfs(const char *fs_name, const char *device_name);
 int dfs_statfs(const char *path, struct statfs *buffer);
-int dfs_mount_device(rt_device_t dev);
-int dfs_unmount_device(rt_device_t dev);
+int dfs_filesystem_get_partition(struct dfs_partition *part,
+                                uint8_t *buf,
+                                uint32_t pindex);
 
 #ifdef __cplusplus
 }

+ 65 - 0
components/dfs/dfs_v2/include/dfs_mnt.h

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-05-05     Bernard      Implement dentry in dfs v2.0
+ */
+
+#ifndef DFS_MNT_H__
+#define DFS_MNT_H__
+
+#include <rtservice.h>
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct dfs_mnt;
+struct dfs_dentry;
+struct dfs_filesystem_ops;
+
+struct dfs_mnt
+{
+    struct dfs_mnt *parent;         /* the parent mounted file system */
+
+    rt_list_t sibling;              /* the sibling node for mounted list */
+    rt_list_t child;                /* the child node for mounted list */
+
+    char *fullpath;                 /* the fullpath of this mounted file system */
+    int flags;                      /* the falgs of this mounted file system */
+
+#define MNT_IS_ALLOCED 0x1          /* the mnt struct is allocated */
+#define MNT_IS_ADDLIST 0x2          /* the mnt struct is added into list */
+#define MNT_IS_MOUNTED 0x4          /* the mnt struct is mounted */
+
+    rt_atomic_t ref_count;          /* reference count */
+
+    rt_device_t dev_id;             /* the mounted device id */
+    const struct dfs_filesystem_ops *fs_ops;
+
+    void *data;
+};
+
+struct dfs_mnt *dfs_mnt_create(const char *path);
+int dfs_mnt_destroy(struct dfs_mnt* mnt);
+int dfs_mnt_list(struct dfs_mnt* mnt);
+int dfs_mnt_insert(struct dfs_mnt* mnt, struct dfs_mnt* child);
+
+struct dfs_mnt *dfs_mnt_lookup(const char *path);
+const char *dfs_mnt_get_mounted_path(struct rt_device *device);
+
+struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt);
+int dfs_mnt_unref(struct dfs_mnt* mnt);
+
+rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char* fullpath);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 32 - 0
components/dfs/dfs_v2/include/dfs_posix.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-05-27     Yi.qiu       The first version.
+ * 2010-07-18     Bernard      add stat and statfs structure definitions.
+ * 2011-05-16     Yi.qiu       Change parameter name of rename, "new" is C++ key word.
+ * 2017-12-27     Bernard      Add fcntl API.
+ * 2018-02-07     Bernard      Change the 3rd parameter of open/fcntl/ioctl to '...'
+ */
+
+#ifndef __DFS_POSIX_H__
+#define __DFS_POSIX_H__
+
+#include <fcntl.h>
+#include <errno.h>
+
+#include <dfs.h>
+#include <dfs_file.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 0 - 28
components/dfs/dfs_v2/include/dfs_private.h

@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date           Author       Notes
- */
-
-#ifndef DFS_PRIVATE_H__
-#define DFS_PRIVATE_H__
-
-#include <dfs.h>
-
-#define DBG_TAG    "DFS"
-#define DBG_LVL    DBG_INFO
-#include <rtdbg.h>
-
-#define NO_WORKING_DIR  "system does not support working directory\n"
-
-/* extern variable */
-extern const struct dfs_filesystem_ops *filesystem_operation_table[];
-extern struct dfs_filesystem filesystem_table[];
-extern const struct dfs_mount_tbl mount_table[];
-
-extern char working_directory[];
-
-#endif

+ 270 - 453
components/dfs/dfs_v2/src/dfs.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -12,121 +12,66 @@
 
 #include <dfs.h>
 #include <dfs_fs.h>
+#include <dfs_dentry.h>
 #include <dfs_file.h>
+#include <dfs_mnt.h>
+
+#include <rtservice.h>
+
 #include "dfs_private.h"
+
+#define DBG_TAG    "DFS"
+#define DBG_LVL    DBG_INFO
+#include <rtdbg.h>
+
 #ifdef RT_USING_SMART
 #include <lwp.h>
 #endif
 
-#ifdef RT_USING_POSIX_STDIO
-#include <libc.h>
-#endif /* RT_USING_POSIX_STDIO */
-
-/* Global variables */
-const struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
-struct dfs_filesystem filesystem_table[DFS_FILESYSTEMS_MAX];
-
-/* device filesystem lock */
-static struct rt_mutex fslock;
-static struct rt_mutex fdlock;
-
 #ifdef DFS_USING_WORKDIR
 char working_directory[DFS_PATH_MAX] = {"/"};
 #endif
 
-static struct dfs_fdtable _fdtab;
-static int  fd_alloc(struct dfs_fdtable *fdt, int startfd);
-
-/**
- * @addtogroup DFS
- * @{
- */
+/* device filesystem lock */
+static struct rt_mutex fslock;
+static struct rt_mutex fdlock;
+static struct dfs_fdtable _fdtab = {0};
+static int fd_alloc(struct dfs_fdtable *fdt, int startfd);
 
 /**
- * this function will initialize device file system.
+ * this function will lock device file system.
+ *
+ * @note please don't invoke it on ISR.
  */
-int dfs_init(void)
+rt_err_t dfs_lock(void)
 {
-    static rt_bool_t init_ok = RT_FALSE;
-
-    if (init_ok)
-    {
-        rt_kprintf("dfs already init.\n");
-        return 0;
-    }
-
-    /* init vnode hash table */
-    dfs_vnode_mgr_init();
-
-    /* clear filesystem operations table */
-    rt_memset((void *)filesystem_operation_table, 0, sizeof(filesystem_operation_table));
-    /* clear filesystem table */
-    rt_memset(filesystem_table, 0, sizeof(filesystem_table));
-    /* clean fd table */
-    rt_memset(&_fdtab, 0, sizeof(_fdtab));
-
-    /* create device filesystem lock */
-    rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_PRIO);
-    rt_mutex_init(&fdlock, "fdlock", RT_IPC_FLAG_PRIO);
-
-#ifdef DFS_USING_WORKDIR
-    /* set current working directory */
-    rt_memset(working_directory, 0, sizeof(working_directory));
-    working_directory[0] = '/';
-#endif
-
-#ifdef RT_USING_DFS_TMPFS
-    {
-        extern int dfs_tmpfs_init(void);
-        dfs_tmpfs_init();
-    }
-#endif
-
-#ifdef RT_USING_DFS_DEVFS
-    {
-        extern int devfs_init(void);
-
-        /* if enable devfs, initialize and mount it as soon as possible */
-        devfs_init();
+    rt_err_t result = -RT_EBUSY;
 
-        dfs_mount(NULL, "/dev", "devfs", 0, 0);
-    }
-#if defined(RT_USING_DEV_BUS) && defined(RT_USING_DFS_TMPFS)
-    mkdir("/dev/shm", 0x777);
-    if (dfs_mount(RT_NULL, "/dev/shm", "tmp", 0, 0) != 0)
+    while (result == -RT_EBUSY)
     {
-        rt_kprintf("Dir /dev/shm mount failed!\n");
+        result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
     }
-#endif
-#endif
 
-    init_ok = RT_TRUE;
-
-    return 0;
+    return result;
 }
-INIT_PREV_EXPORT(dfs_init);
 
 /**
  * this function will lock device file system.
  *
  * @note please don't invoke it on ISR.
  */
-void dfs_lock(void)
+void dfs_unlock(void)
 {
-    rt_err_t result = -RT_EBUSY;
+    rt_mutex_release(&fslock);
+}
 
-    while (result == -RT_EBUSY)
-    {
-        result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
-    }
+/**
+ * @addtogroup DFS
+ */
 
-    if (result != RT_EOK)
-    {
-        RT_ASSERT(0);
-    }
-}
+/*@{*/
 
-void dfs_file_lock(void)
+rt_err_t dfs_file_lock(void)
 {
     rt_err_t result = -RT_EBUSY;
 
@@ -135,28 +80,38 @@ void dfs_file_lock(void)
         result = rt_mutex_take(&fdlock, RT_WAITING_FOREVER);
     }
 
-    if (result != RT_EOK)
-    {
-        RT_ASSERT(0);
-    }
+    return result;
+}
+
+void dfs_file_unlock(void)
+{
+    rt_mutex_release(&fdlock);
 }
 
 /**
- * this function will lock device file system.
- *
- * @note please don't invoke it on ISR.
+ * this function will initialize device file system.
  */
-void dfs_unlock(void)
+int dfs_init(void)
 {
-    rt_mutex_release(&fslock);
-}
+    static rt_bool_t init_ok = RT_FALSE;
+    if (init_ok)
+    {
+        LOG_E("DFS was already initialized.\n");
+        return 0;
+    }
 
-#ifdef DFS_USING_POSIX
+    /* create device filesystem lock */
+    rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
+    rt_mutex_init(&fdlock, "fdlock", RT_IPC_FLAG_FIFO);
 
-void dfs_file_unlock(void)
-{
-    rt_mutex_release(&fdlock);
+    /* clean fd table */
+    dfs_dentry_init();
+
+    init_ok = RT_TRUE;
+
+    return 0;
 }
+INIT_PREV_EXPORT(dfs_init);
 
 static int fd_slot_expand(struct dfs_fdtable *fdt, int fd)
 {
@@ -189,7 +144,7 @@ static int fd_slot_expand(struct dfs_fdtable *fdt, int fd)
     {
         fds[index] = NULL;
     }
-    fdt->fds   = fds;
+    fdt->fds = fds;
     fdt->maxfd = nr;
 
     return fd;
@@ -219,28 +174,12 @@ static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd)
     }
     return idx;
 }
+
 static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
 {
     int idx;
-    struct dfs_file *fd = NULL;
 
     idx = fd_slot_alloc(fdt, startfd);
-
-    /* allocate  'struct dfs_file' */
-    if (idx < 0)
-    {
-        return -1;
-    }
-    fd = (struct dfs_file *)rt_calloc(1, sizeof(struct dfs_file));
-    if (!fd)
-    {
-        return -1;
-    }
-    fd->ref_count = 1;
-    fd->magic = DFS_FD_MAGIC;
-    fd->vnode = NULL;
-    fdt->fds[idx] = fd;
-
     return idx;
 }
 
@@ -259,14 +198,34 @@ int fdt_fd_new(struct dfs_fdtable *fdt)
 
     /* find an empty fd entry */
     idx = fd_alloc(fdt, DFS_STDIO_OFFSET);
-
     /* can't find an empty fd entry */
     if (idx < 0)
     {
         LOG_E("DFS fd new is failed! Could not found an empty fd entry.");
     }
+    else
+    {
+        struct dfs_file *file;
+
+        file = (struct dfs_file *)rt_calloc(1, sizeof(struct dfs_file));
+        if (file)
+        {
+            file->magic = DFS_FD_MAGIC;
+            file->ref_count = 1;
+            rt_mutex_init(&file->pos_lock, "fpos", RT_IPC_FLAG_PRIO);
+            RT_ASSERT(fdt->fds[idx] == NULL);
+            fdt->fds[idx] = file;
+            LOG_D("allocate a new fd @ %d", idx);
+        }
+        else
+        {
+            fdt->fds[idx] = RT_NULL;
+            idx = -1;
+        }
+    }
 
     dfs_file_unlock();
+
     return idx;
 }
 
@@ -288,28 +247,24 @@ int fd_new(void)
  * pointer.
  */
 
-struct dfs_file *fdt_fd_get(struct dfs_fdtable* fdt, int fd)
+struct dfs_file *fdt_fd_get(struct dfs_fdtable *fdt, int fd)
 {
-    struct dfs_file *d;
+    struct dfs_file *f;
 
     if (fd < 0 || fd >= (int)fdt->maxfd)
     {
         return NULL;
     }
 
-    dfs_file_lock();
-    d = fdt->fds[fd];
+    f = fdt->fds[fd];
 
-    /* check dfs_file valid or not */
-    if ((d == NULL) || (d->magic != DFS_FD_MAGIC))
+    /* check file valid or not */
+    if ((f == NULL) || (f->magic != DFS_FD_MAGIC))
     {
-        dfs_file_unlock();
         return NULL;
     }
 
-    dfs_file_unlock();
-
-    return d;
+    return f;
 }
 
 struct dfs_file *fd_get(int fd)
@@ -325,149 +280,185 @@ struct dfs_file *fd_get(int fd)
  *
  * This function will put the file descriptor.
  */
-void fdt_fd_release(struct dfs_fdtable* fdt, int fd)
+void fd_release(int fd)
 {
-    struct dfs_file *fd_slot = NULL;
-
-    RT_ASSERT(fdt != NULL);
+    struct dfs_fdtable *fdt;
 
-    dfs_file_lock();
+    fdt = dfs_fdtable_get();
+    fdt_fd_release(fdt, fd);
+}
 
-    if ((fd < 0) || (fd >= fdt->maxfd))
+void fdt_fd_release(struct dfs_fdtable *fdt, int fd)
+{
+    if (fd < fdt->maxfd)
     {
-        dfs_file_unlock();
-        return;
+        struct dfs_file *file = fdt_fd_get(fdt, fd);
+        if (file && file->ref_count == 1)
+        {
+            rt_mutex_detach(&file->pos_lock);
+            rt_free(file);
+        }
+        else
+        {
+            rt_atomic_sub(&(file->ref_count), 1);
+        }
+        fdt->fds[fd] = RT_NULL;
     }
+}
 
-    fd_slot = fdt->fds[fd];
-    if (fd_slot == NULL)
+static int fd_get_fd_index_form_fdt(struct dfs_fdtable *fdt, struct dfs_file *file)
+{
+    int fd = -1;
+
+    if (file == RT_NULL)
     {
-        dfs_file_unlock();
-        return;
+        return -1;
     }
-    fdt->fds[fd] = NULL;
-
-    /* check fd */
-    RT_ASSERT(fd_slot->magic == DFS_FD_MAGIC);
 
-    fd_slot->ref_count--;
+    dfs_file_lock();
 
-    /* clear this fd entry */
-    if (fd_slot->ref_count == 0)
+    for (int index = 0; index < (int)fdt->maxfd; index++)
     {
-        struct dfs_vnode *vnode = fd_slot->vnode;
-        if (vnode)
+        if (fdt->fds[index] == file)
         {
-            vnode->ref_count--;
-            if(vnode->ref_count == 0)
-            {
-                rt_free(vnode);
-                fd_slot->vnode = RT_NULL;
-            }
+            fd = index;
+            break;
         }
-        rt_free(fd_slot);
     }
+
     dfs_file_unlock();
+
+    return fd;
 }
 
-void fd_release(int fd)
+int fd_get_fd_index(struct dfs_file *file)
 {
     struct dfs_fdtable *fdt;
 
     fdt = dfs_fdtable_get();
-    fdt_fd_release(fdt, fd);
+    return fd_get_fd_index_form_fdt(fdt, file);
 }
 
-rt_err_t sys_dup(int oldfd)
+int fd_associate(struct dfs_fdtable *fdt, int fd, struct dfs_file *file)
 {
-    int newfd = -1;
-    struct dfs_fdtable *fdt = NULL;
+    int retfd = -1;
+
+    if (!file)
+    {
+        return retfd;
+    }
+    if (!fdt)
+    {
+        return retfd;
+    }
 
     dfs_file_lock();
     /* check old fd */
-    fdt = dfs_fdtable_get();
-    if ((oldfd < 0) || (oldfd >= fdt->maxfd))
+    if ((fd < 0) || (fd >= fdt->maxfd))
     {
         goto exit;
     }
-    if (!fdt->fds[oldfd])
+
+    if (fdt->fds[fd])
     {
         goto exit;
     }
-    /* get a new fd */
-    newfd = fd_slot_alloc(fdt, DFS_STDIO_OFFSET);
-    if (newfd >= 0)
-    {
-        fdt->fds[newfd] = fdt->fds[oldfd];
-        /* inc ref_count */
-        fdt->fds[newfd]->ref_count++;
-    }
+
+    /* inc ref_count */
+    rt_atomic_add(&(file->ref_count), 1);
+    fdt->fds[fd] = file;
+    retfd = fd;
+
 exit:
     dfs_file_unlock();
-    return newfd;
+    return retfd;
 }
 
-#endif /* DFS_USING_POSIX */
-
 /**
- * @ingroup Fd
- *
- * This function will return whether this file has been opend.
- *
- * @param pathname the file path name.
- *
- * @return 0 on file has been open successfully, -1 on open failed.
+ * This function will get the file descriptor table of current process.
  */
-int fd_is_open(const char *pathname)
+struct dfs_fdtable *dfs_fdtable_get(void)
 {
-    char *fullpath;
-    unsigned int index;
-    struct dfs_filesystem *fs;
-    struct dfs_file *fd;
     struct dfs_fdtable *fdt;
+#ifdef RT_USING_SMART
+    struct rt_lwp *lwp;
 
-    fdt = dfs_fdtable_get();
-    fullpath = dfs_normalize_path(NULL, pathname);
-    if (fullpath != NULL)
-    {
-        char *mountpath;
-        fs = dfs_filesystem_lookup(fullpath);
-        if (fs == NULL)
-        {
-            /* can't find mounted file system */
-            rt_free(fullpath);
+    lwp = (struct rt_lwp *)rt_thread_self()->lwp;
+    if (lwp)
+        fdt = &lwp->fdt;
+    else
+        fdt = &_fdtab;
+#else
+    fdt = &_fdtab;
+#endif
 
-            return -1;
-        }
+    return fdt;
+}
 
-        /* get file path name under mounted file system */
-        if (fs->path[0] == '/' && fs->path[1] == '\0')
-            mountpath = fullpath;
-        else
-            mountpath = fullpath + strlen(fs->path);
+#ifdef RT_USING_SMART
+struct dfs_fdtable *dfs_fdtable_get_pid(int pid)
+{
+    struct rt_lwp *lwp = RT_NULL;
+    struct dfs_fdtable *fdt = RT_NULL;
 
-        dfs_lock();
+    lwp = lwp_from_pid(pid);
+    if (lwp)
+    {
+        fdt = &lwp->fdt;
+    }
 
-        for (index = 0; index < fdt->maxfd; index++)
-        {
-            fd = fdt->fds[index];
-            if (fd == NULL || fd->vnode->fops == NULL || fd->vnode->path == NULL) continue;
+    return fdt;
+}
+#endif
 
-            if (fd->vnode->fs == fs && strcmp(fd->vnode->path, mountpath) == 0)
-            {
-                /* found file in file descriptor table */
-                rt_free(fullpath);
-                dfs_unlock();
+struct dfs_fdtable *dfs_fdtable_get_global(void)
+{
+    return &_fdtab;
+}
 
-                return 0;
-            }
-        }
-        dfs_unlock();
+int dfs_dup(int oldfd, int startfd)
+{
+    int newfd = -1;
+    struct dfs_fdtable *fdt = NULL;
 
-        rt_free(fullpath);
+    dfs_file_lock();
+    /* check old fd */
+    fdt = dfs_fdtable_get();
+    if ((oldfd < 0) || (oldfd >= fdt->maxfd))
+    {
+        goto exit;
     }
+    if (!fdt->fds[oldfd])
+    {
+        goto exit;
+    }
+    /* get a new fd */
+    newfd = fd_slot_alloc(fdt, startfd);
+    if (newfd >= 0)
+    {
+        fdt->fds[newfd] = fdt->fds[oldfd];
 
-    return -1;
+        /* inc ref_count */
+        rt_atomic_add(&(fdt->fds[newfd]->ref_count), 1);
+    }
+exit:
+    dfs_file_unlock();
+    return newfd;
+}
+
+#ifdef RT_USING_SMART
+sysret_t sys_dup(int oldfd)
+#else
+int sys_dup(int oldfd)
+#endif
+{
+    int newfd = dfs_dup(oldfd, DFS_STDIO_OFFSET);
+
+#ifdef RT_USING_SMART
+    return (sysret_t)newfd;
+#else
+    return newfd;
+#endif
 }
 
 rt_err_t sys_dup2(int oldfd, int newfd)
@@ -518,91 +509,13 @@ rt_err_t sys_dup2(int oldfd, int newfd)
 
     fdt->fds[newfd] = fdt->fds[oldfd];
     /* inc ref_count */
-    fdt->fds[newfd]->ref_count++;
+    rt_atomic_add(&(fdt->fds[newfd]->ref_count), 1);
     retfd = newfd;
 exit:
     dfs_file_unlock();
     return retfd;
 }
 
-static int fd_get_fd_index_form_fdt(struct dfs_fdtable *fdt, struct dfs_file *file)
-{
-    int fd = -1;
-
-    if (file == RT_NULL)
-    {
-        return -1;
-    }
-
-    dfs_file_lock();
-
-    for(int index = 0; index < (int)fdt->maxfd; index++)
-    {
-        if(fdt->fds[index] == file)
-        {
-            fd = index;
-            break;
-        }
-    }
-
-    dfs_file_unlock();
-
-    return fd;
-}
-
-int fd_get_fd_index(struct dfs_file *file)
-{
-    struct dfs_fdtable *fdt;
-
-    fdt = dfs_fdtable_get();
-    return fd_get_fd_index_form_fdt(fdt, file);
-}
-
-int fd_associate(struct dfs_fdtable *fdt, int fd, struct dfs_file *file)
-{
-    int retfd = -1;
-
-    if (!file)
-    {
-        return retfd;
-    }
-    if (!fdt)
-    {
-        return retfd;
-    }
-
-    dfs_file_lock();
-    /* check old fd */
-    if ((fd < 0) || (fd >= fdt->maxfd))
-    {
-        goto exit;
-    }
-
-    if (fdt->fds[fd])
-    {
-        goto exit;
-    }
-    /* inc ref_count */
-    file->ref_count++;
-    fdt->fds[fd] = file;
-    retfd = fd;
-exit:
-    dfs_file_unlock();
-    return retfd;
-}
-
-void fd_init(struct dfs_file *fd)
-{
-    if (fd)
-    {
-        fd->magic = DFS_FD_MAGIC;
-        fd->ref_count = 1;
-        fd->pos = 0;
-        fd->vnode = NULL;
-        fd->data = NULL;
-    }
-}
-
 /**
  * this function will return a sub-path name under directory.
  *
@@ -621,7 +534,7 @@ const char *dfs_subdir(const char *directory, const char *filename)
     dir = filename + strlen(directory);
     if ((*dir != '/') && (dir != filename))
     {
-        dir --;
+        dir--;
     }
 
     return dir;
@@ -692,7 +605,8 @@ char *dfs_normalize_path(const char *directory, const char *filename)
 
         if (c == '.')
         {
-            if (!src[1]) src++; /* '.' and ends */
+            if (!src[1])
+                src++; /* '.' and ends */
             else if (src[1] == '/')
             {
                 /* './' case */
@@ -739,17 +653,12 @@ char *dfs_normalize_path(const char *directory, const char *filename)
 
         continue;
 
-up_one:
-        /* keep the topmost root directory */
-        if (dst - dst0 != 1 || dst[-1] != '/')
+    up_one:
+        dst--;
+        if (dst < dst0)
         {
-            dst--;
-
-            if (dst < dst0)
-            {
-                rt_free(fullpath);
-                return NULL;
-            }
+            rt_free(fullpath);
+            return NULL;
         }
         while (dst0 < dst && dst[-1] != '/')
             dst--;
@@ -773,49 +682,8 @@ up_one:
 }
 RTM_EXPORT(dfs_normalize_path);
 
-/**
- * This function will get the file descriptor table of current process.
- */
-struct dfs_fdtable *dfs_fdtable_get(void)
-{
-    struct dfs_fdtable *fdt;
-#ifdef RT_USING_SMART
-    struct rt_lwp *lwp;
-
-    lwp = (struct rt_lwp *)rt_thread_self()->lwp;
-    if (lwp)
-        fdt = &lwp->fdt;
-    else
-        fdt = &_fdtab;
-#else
-    fdt = &_fdtab;
-#endif
-
-    return fdt;
-}
-
-#ifdef RT_USING_SMART
-struct dfs_fdtable *dfs_fdtable_get_pid(int pid)
-{
-    struct rt_lwp *lwp = RT_NULL;
-    struct dfs_fdtable *fdt = RT_NULL;
-
-    lwp = lwp_from_pid(pid);
-    if (lwp)
-    {
-        fdt = &lwp->fdt;
-    }
-
-    return fdt;
-}
-#endif
-
-struct dfs_fdtable *dfs_fdtable_get_global(void)
-{
-    return &_fdtab;
-}
-
 #ifdef RT_USING_FINSH
+#include <finsh.h>
 int list_fd(void)
 {
     int index;
@@ -824,28 +692,29 @@ int list_fd(void)
     fd_table = dfs_fdtable_get();
     if (!fd_table) return -1;
 
-    dfs_lock();
+    rt_enter_critical();
 
     rt_kprintf("fd type    ref magic  path\n");
     rt_kprintf("-- ------  --- ----- ------\n");
     for (index = 0; index < (int)fd_table->maxfd; index++)
     {
-        struct dfs_file *fd = fd_table->fds[index];
+        struct dfs_file *file = fd_table->fds[index];
 
-        if (fd && fd->vnode->fops)
+        if (file && file->vnode)
         {
             rt_kprintf("%2d ", index);
-            if (fd->vnode->type == FT_DIRECTORY)    rt_kprintf("%-7.7s ", "dir");
-            else if (fd->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
-            else if (fd->vnode->type == FT_SOCKET)  rt_kprintf("%-7.7s ", "socket");
-            else if (fd->vnode->type == FT_USER)    rt_kprintf("%-7.7s ", "user");
-            else if (fd->vnode->type == FT_DEVICE)  rt_kprintf("%-7.7s ", "device");
+            if (file->vnode->type == FT_DIRECTORY)    rt_kprintf("%-7.7s ", "dir");
+            else if (file->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
+            else if (file->vnode->type == FT_SOCKET)  rt_kprintf("%-7.7s ", "socket");
+            else if (file->vnode->type == FT_USER)    rt_kprintf("%-7.7s ", "user");
+            else if (file->vnode->type == FT_DEVICE)  rt_kprintf("%-7.7s ", "device");
             else rt_kprintf("%-8.8s ", "unknown");
-            rt_kprintf("%3d ", fd->vnode->ref_count);
-            rt_kprintf("%04x  ", fd->magic);
-            if (fd->vnode->path)
+            rt_kprintf("%3d ", file->ref_count);
+            rt_kprintf("%04x  ", file->magic);
+
+            if (file->dentry)
             {
-                rt_kprintf("%s\n", fd->vnode->path);
+                rt_kprintf("%s%s\n", file->dentry->mnt->fullpath, file->dentry->pathname);
             }
             else
             {
@@ -853,122 +722,70 @@ int list_fd(void)
             }
         }
     }
-    dfs_unlock();
+    rt_exit_critical();
 
     return 0;
 }
+MSH_CMD_EXPORT(list_fd, list file descriptor);
 
-#ifdef RT_USING_SMART
-static int lsofp(int pid)
+int dfs_fd_dump(int argc, char** argv)
 {
     int index;
-    struct dfs_fdtable *fd_table = RT_NULL;
 
-    if (pid == (-1))
-    {
-        fd_table = dfs_fdtable_get();
-        if (!fd_table) return -1;
-    }
-    else
-    {
-        fd_table = dfs_fdtable_get_pid(pid);
-        if (!fd_table)
-        {
-            rt_kprintf("PID %s is not a applet(lwp)\n", pid);
-            return -1;
-        }
-    }
-
-    rt_kprintf("--- -- ------  ------ ----- ---------- ---------- ---------- ------\n");
-
-    rt_enter_critical();
-    for (index = 0; index < (int)fd_table->maxfd; index++)
+    dfs_file_lock();
+    for (index = 0; index < _fdtab.maxfd; index++)
     {
-        struct dfs_file *fd = fd_table->fds[index];
-
-        if (fd && fd->vnode->fops)
+        struct dfs_file *file = _fdtab.fds[index];
+        if (file)
         {
-            if(pid == (-1))
-            {
-                rt_kprintf("  K ");
-            }
-            else
-            {
-                rt_kprintf("%3d ", pid);
-            }
-
-            rt_kprintf("%2d ", index);
-            if (fd->vnode->type == FT_DIRECTORY)    rt_kprintf("%-7.7s ", "dir");
-            else if (fd->vnode->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
-            else if (fd->vnode->type == FT_SOCKET)  rt_kprintf("%-7.7s ", "socket");
-            else if (fd->vnode->type == FT_USER)    rt_kprintf("%-7.7s ", "user");
-            else if (fd->vnode->type == FT_DEVICE)  rt_kprintf("%-7.7s ", "device");
-            else rt_kprintf("%-8.8s ", "unknown");
-            rt_kprintf("%6d ", fd->vnode->ref_count);
-            rt_kprintf("%04x  0x%.8x ", fd->magic, (int)(size_t)fd->vnode);
-
-            if(fd->vnode == RT_NULL)
-            {
-                rt_kprintf("0x%.8x 0x%.8x ", (int)0x00000000, (int)(size_t)fd);
-            }
-            else
+            char* fullpath = dfs_dentry_full_path(file->dentry);
+            if (fullpath)
             {
-                rt_kprintf("0x%.8x 0x%.8x ", (int)(size_t)(fd->vnode->data), (int)(size_t)fd);
-            }
-
-            if (fd->vnode->path)
-            {
-                rt_kprintf("%s \n", fd->vnode->path);
+                printf("[%d] - %s, ref_count %zd\n", index,
+                    fullpath, (size_t)rt_atomic_load(&(file->ref_count)));
+                rt_free(fullpath);
             }
             else
             {
-                rt_kprintf("\n");
+                printf("[%d] - %s, ref_count %zd\n", index,
+                    file->dentry->pathname, (size_t)rt_atomic_load(&(file->ref_count)));
             }
         }
     }
-    rt_exit_critical();
+    dfs_file_unlock();
 
     return 0;
 }
+MSH_CMD_EXPORT_ALIAS(dfs_fd_dump, fd_dump, fd dump);
 
-int lsof(int argc, char *argv[])
-{
-    rt_kprintf("PID fd type    fd-ref magic vnode      vnode/data addr       path  \n");
+#ifdef PKG_USING_DLOG
 
-    if (argc == 1)
+int dfs_dlog(int argc, char** argv)
+{
+    if (argc == 2)
     {
-        struct rt_list_node *node, *list;
-        struct lwp_avl_struct *pids = lwp_get_pid_ary();
-
-        lsofp(-1);
-
-        for (int index = 0; index < RT_LWP_MAX_NR; index++)
+        if (strcmp(argv[1], "on") == 0)
         {
-            struct rt_lwp *lwp = (struct rt_lwp *)pids[index].data;
-
-            if (lwp)
-            {
-                list = &lwp->t_grp;
-                for (node = list->next; node != list; node = node->next)
-                {
-                    lsofp(lwp_to_pid(lwp));
-                }
-            }
+            dlog_session_start();
+            dlog_participant("dfs");
+            dlog_participant("dfs_file");
+            dlog_participant("dentry");
+            dlog_participant("vnode");
+            dlog_participant("mnt");
+            dlog_participant("rom");
+            dlog_participant("devfs");
         }
-    }
-    else if (argc == 3)
-    {
-        if (argv[1][0] == '-' && argv[1][1] == 'p')
+        else if (strcmp(argv[1], "off") == 0)
         {
-            int pid = atoi(argv[2]);
-            lsofp(pid);
+            dlog_session_stop();
         }
     }
 
     return 0;
 }
-MSH_CMD_EXPORT(lsof, list open files);
-#endif /* RT_USING_SMART */
+MSH_CMD_EXPORT(dfs_dlog, dfs dlog on|off);
+
+#endif
 
 #endif
 /**@}*/

+ 368 - 0
components/dfs/dfs_v2/src/dfs_dentry.c

@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-10-10     Bernard      The first version of rewrite dfs
+ */
+#include <rtthread.h>
+
+#include "dfs.h"
+#include "dfs_file.h"
+#include "dfs_private.h"
+#include "dfs_dentry.h"
+#include "dfs_mnt.h"
+
+#define DBG_TAG "DFS.dentry"
+#define DBG_LVL DBG_WARNING
+#include <rtdbg.h>
+
+#define DFS_DENTRY_HASH_NR 32
+struct dentry_hash_head
+{
+    rt_list_t head[DFS_DENTRY_HASH_NR];
+};
+static struct dentry_hash_head hash_head;
+
+static uint32_t _dentry_hash(struct dfs_mnt *mnt, const char *path)
+{
+    uint32_t val = 0;
+
+    if (path)
+    {
+        while (*path)
+        {
+            val = ((val << 5) + val) + *path++;
+        }
+    }
+    return (val ^ (unsigned long) mnt) & (DFS_DENTRY_HASH_NR - 1);
+}
+
+struct dfs_dentry *dfs_dentry_create(struct dfs_mnt *mnt, char *fullpath)
+{
+    struct dfs_dentry *dentry = RT_NULL;
+
+    if (mnt == RT_NULL || fullpath == RT_NULL)
+    {
+        return dentry;
+    }
+
+    dentry = (struct dfs_dentry *)rt_calloc(1, sizeof(struct dfs_dentry));
+    if (dentry)
+    {
+        char *dentry_path = fullpath;
+        int mntpoint_len = strlen(mnt->fullpath);
+
+        if (rt_strncmp(mnt->fullpath, dentry_path, mntpoint_len) == 0)
+        {
+            dentry_path += mntpoint_len;
+        }
+
+        dentry->pathname = strlen(dentry_path) ? rt_strdup(dentry_path) : rt_strdup(fullpath);
+        dentry->mnt = dfs_mnt_ref(mnt);
+
+        rt_atomic_store(&(dentry->ref_count), 1);
+        dentry->flags |= DENTRY_IS_ALLOCED;
+
+        LOG_I("create a dentry:%p for %s", dentry, fullpath);
+    }
+
+    return dentry;
+}
+
+struct dfs_dentry * dfs_dentry_ref(struct dfs_dentry *dentry)
+{
+    if (dentry)
+    {
+        int ret = dfs_file_lock();
+        if (ret == RT_EOK)
+        {
+            rt_atomic_add(&(dentry->ref_count), 1);
+            if (dentry->vnode)
+            {
+                rt_atomic_add(&(dentry->vnode->ref_count), 1);
+            }
+            dfs_file_unlock();
+        }
+    }
+
+    return dentry;
+}
+
+struct dfs_dentry *dfs_dentry_unref(struct dfs_dentry *dentry)
+{
+    rt_err_t ret = RT_EOK;
+
+    if (dentry)
+    {
+        ret = dfs_file_lock();
+        if (ret == RT_EOK)
+        {
+            if (dentry->flags & DENTRY_IS_ALLOCED)
+            {
+                rt_atomic_sub(&(dentry->ref_count), 1);
+            }
+
+            if (rt_atomic_load(&(dentry->ref_count)) == 0)
+            {
+                DLOG(msg, "dentry", "dentry", DLOG_MSG, "free dentry, ref_count=0");
+                if (dentry->flags & DENTRY_IS_ADDHASH)
+                {
+                    rt_list_remove(&dentry->hashlist);
+                }
+
+                /* release vnode */
+                if (dentry->vnode)
+                {
+                    dfs_vnode_unref(dentry->vnode);
+                }
+
+                /* release mnt */
+                DLOG(msg, "dentry", "mnt", DLOG_MSG, "dfs_mnt_unref(dentry->mnt)");
+                if (dentry->mnt)
+                {
+                    dfs_mnt_unref(dentry->mnt);
+                }
+
+                dfs_file_unlock();
+
+                LOG_I("free a dentry: %p", dentry);
+                rt_free(dentry->pathname);
+                rt_free(dentry);
+            }
+            else
+            {
+                if (dentry->vnode)
+                {
+                    rt_atomic_sub(&(dentry->vnode->ref_count), 1);
+                }
+                dfs_file_unlock();
+                DLOG(note, "dentry", "dentry ref_count=%d", rt_atomic_load(&(dentry->ref_count)));
+            }
+        }
+    }
+
+    return dentry;
+}
+
+static struct dfs_dentry *_dentry_hash_lookup(struct dfs_mnt *mnt, const char *path)
+{
+    rt_err_t ret = RT_EOK;
+    struct dfs_dentry *entry = RT_NULL;
+    int path_len = strlen(path);
+
+    ret = dfs_file_lock();
+    if (ret == RT_EOK)
+    {
+        rt_list_for_each_entry(entry, &hash_head.head[_dentry_hash(mnt, path)], hashlist)
+        {
+            if (entry->mnt == mnt && !strncmp(entry->pathname, path, path_len))
+            {
+                dfs_dentry_ref(entry);
+                dfs_file_unlock();
+                return entry;
+            }
+        }
+
+        dfs_file_unlock();
+    }
+
+    return RT_NULL;
+}
+
+void dfs_dentry_insert(struct dfs_dentry *dentry)
+{
+    dfs_file_lock();
+    rt_list_insert_after(&hash_head.head[_dentry_hash(dentry->mnt, dentry->pathname)], &dentry->hashlist);
+    dentry->flags |= DENTRY_IS_ADDHASH;
+    dfs_file_unlock();
+}
+
+/*
+ * lookup a dentry, return this dentry and increase refcount if exist, otherwise return NULL
+ */
+struct dfs_dentry *dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint32_t flags)
+{
+    struct dfs_dentry *dentry;
+    struct dfs_vnode *vnode;
+    int mntpoint_len = strlen(mnt->fullpath);
+
+    if (rt_strncmp(mnt->fullpath, path, mntpoint_len) == 0)
+    {
+        path += mntpoint_len;
+        if ((*path) == '\0')
+        {
+            /* root */
+            path = "/";
+        }
+    }
+
+    dentry = _dentry_hash_lookup(mnt, path);
+    if (!dentry)
+    {
+        if (mnt->fs_ops->lookup)
+        {
+            DLOG(activate, "dentry");
+            /* not in hash table, create it */
+            DLOG(msg, "dentry", "dentry", DLOG_MSG, "dfs_dentry_create(%s)", path);
+            dentry = dfs_dentry_create(mnt, (char*)path);
+            if (dentry)
+            {
+                DLOG(msg, "dentry", mnt->fs_ops->name, DLOG_MSG, "vnode=fs_ops->lookup(dentry)");
+                vnode = mnt->fs_ops->lookup(dentry);
+                if (vnode)
+                {
+                    DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "return vnode");
+                    dentry->vnode = vnode; /* the refcount of created vnode is 1. no need to reference */
+                    dfs_file_lock();
+                    rt_list_insert_after(&hash_head.head[_dentry_hash(mnt, path)], &dentry->hashlist);
+                    dentry->flags |= DENTRY_IS_ADDHASH;
+                    dfs_file_unlock();
+
+                    if (dentry->flags & (DENTRY_IS_ALLOCED | DENTRY_IS_ADDHASH)
+                        && !(dentry->flags & DENTRY_IS_OPENED))
+                    {
+                        rt_err_t ret = dfs_file_lock();
+                        if (ret == RT_EOK)
+                        {
+                            dentry->flags |= DENTRY_IS_OPENED;
+                            dfs_file_unlock();
+                        }
+                    }
+                }
+                else
+                {
+                    DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "no dentry");
+
+                    DLOG(msg, "dentry", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)");
+                    dfs_dentry_unref(dentry);
+                    dentry = RT_NULL;
+                }
+            }
+            DLOG(deactivate, "dentry");
+        }
+    }
+    else
+    {
+        DLOG(note, "dentry", "found dentry");
+    }
+
+    return dentry;
+}
+
+char* dfs_dentry_full_path(struct dfs_dentry* dentry)
+{
+    char *path = NULL;
+
+    if (dentry && dentry->mnt)
+    {
+        int mnt_len = strlen(dentry->mnt->fullpath);
+        int path_len = strlen(dentry->pathname);
+
+        path = (char *) rt_malloc(mnt_len + path_len + 3);
+        if (path)
+        {
+            if (dentry->pathname[0] == '/')
+            {
+                rt_snprintf(path, mnt_len + path_len + 2, "%s%s", dentry->mnt->fullpath,
+                    dentry->pathname);
+            }
+            else
+            {
+                rt_snprintf(path, mnt_len + path_len + 2, "%s/%s", dentry->mnt->fullpath,
+                    dentry->pathname);
+            }
+        }
+    }
+
+    return path;
+}
+
+char* dfs_dentry_pathname(struct dfs_dentry* dentry)
+{
+    char *pathname = RT_NULL;
+    char *index = RT_NULL;
+
+    index = strrchr(dentry->pathname, '/');
+    if (index)
+    {
+        int length = index - dentry->pathname;
+        int path_length = strlen(dentry->mnt->fullpath) + length + 3;
+
+        pathname = (char*) rt_malloc(path_length);
+        if (pathname)
+        {
+            if (dentry->pathname[0] == '/')
+            {
+                rt_snprintf(pathname, path_length - 1, "%s%.*s", dentry->mnt->fullpath,
+                    length, dentry->pathname);
+            }
+            else
+            {
+                rt_snprintf(pathname, path_length - 1, "%s/%.*s", dentry->mnt->fullpath,
+                    length, dentry->pathname);
+            }
+        }
+    }
+    else
+    {
+        pathname = rt_strdup(dentry->mnt->fullpath);
+    }
+
+    return pathname;
+}
+
+uint32_t dfs_dentry_full_path_crc32(struct dfs_dentry* dentry)
+{
+    uint32_t crc32 = 0xFFFFFFFF;
+    char *fullpath = dfs_dentry_full_path(dentry);
+    if (fullpath)
+    {
+        int i = 0;
+
+        while(fullpath[i] != '\0')
+        {
+            for (uint8_t b = 1; b; b <<= 1)
+            {
+                crc32 ^= (fullpath[i] & b) ? 1 : 0;
+                crc32 = (crc32 & 1) ? crc32 >> 1 ^ 0xEDB88320 : crc32 >> 1;
+            }
+            i ++;
+        }
+        rt_free(fullpath);
+    }
+    return crc32;
+}
+
+int dfs_dentry_init(void)
+{
+    int i = 0;
+
+    for(i = 0; i < DFS_DENTRY_HASH_NR; i++)
+    {
+        rt_list_init(&hash_head.head[i]);
+    }
+
+    return 0;
+}
+
+int dfs_dentry_dump(int argc, char** argv)
+{
+    int index = 0;
+    struct dfs_dentry *entry = RT_NULL;
+
+    dfs_lock();
+    for (index = 0; index < DFS_DENTRY_HASH_NR; index ++)
+    {
+        rt_list_for_each_entry(entry, &hash_head.head[index], hashlist)
+        {
+            printf("dentry:%s @ %p, ref_count = %zd\n", entry->pathname, entry, (size_t)rt_atomic_load(&entry->ref_count));
+        }
+    }
+    dfs_unlock();
+
+    return 0;
+}
+MSH_CMD_EXPORT_ALIAS(dfs_dentry_dump, dentry_dump, dump dentry in the system);

文件差异内容过多而无法显示
+ 1274 - 479
components/dfs/dfs_v2/src/dfs_file.c


+ 363 - 533
components/dfs/dfs_v2/src/dfs_fs.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -10,648 +10,478 @@
  * 2011-03-12     Bernard      fix the filesystem lookup issue.
  * 2017-11-30     Bernard      fix the filesystem_operation_table issue.
  * 2017-12-05     Bernard      fix the fs type search issue in mkfs.
+ * 2023-05-05     Bernard      change to dfs v2.0
  */
 
 #include <dfs_fs.h>
 #include <dfs_file.h>
+#include <dfs_dentry.h>
+#include <dfs_mnt.h>
 #include "dfs_private.h"
 
+#define DBG_TAG "DFS.fs"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+static struct dfs_filesystem_type *file_systems = NULL;
+extern rt_list_t _mnt_list;
+
 /**
  * @addtogroup FsApi
- * @{
  */
+/*@{*/
 
-/**
- * this function will register a file system instance to device file system.
- *
- * @param ops the file system instance to be registered.
- *
- * @return 0 on successful, -1 on failed.
- */
-int dfs_register(const struct dfs_filesystem_ops *ops)
+static struct dfs_filesystem_type **_find_filesystem(const char *name)
 {
-    int ret = RT_EOK;
-    const struct dfs_filesystem_ops **empty = NULL;
-    const struct dfs_filesystem_ops **iter;
-
-    /* lock filesystem */
-    dfs_lock();
-    /* check if this filesystem was already registered */
-    for (iter = &filesystem_operation_table[0];
-            iter < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; iter ++)
+    struct dfs_filesystem_type **type;
+    for (type = &file_systems; *type; type = &(*type)->next)
     {
-        /* find out an empty filesystem type entry */
-        if (*iter == NULL)
-            (empty == NULL) ? (empty = iter) : 0;
-        else if (strcmp((*iter)->name, ops->name) == 0)
-        {
-            rt_set_errno(-EEXIST);
-            ret = -1;
+        if (strcmp((*type)->fs_ops->name, name) == 0)
             break;
-        }
     }
 
-    /* save the filesystem's operations */
-    if (empty == NULL)
-    {
-        rt_set_errno(-ENOSPC);
-        LOG_E("There is no space to register this file system (%s).", ops->name);
-        ret = -1;
-    }
-    else if (ret == RT_EOK)
-    {
-        *empty = ops;
-    }
-
-    dfs_unlock();
-    return ret;
+    return type;
 }
 
-/**
- * this function will return the file system mounted on specified path.
- *
- * @param path the specified path string.
- *
- * @return the found file system or NULL if no file system mounted on
- * specified path
- */
-struct dfs_filesystem *dfs_filesystem_lookup(const char *path)
+int dfs_register(struct dfs_filesystem_type *fs)
 {
-    struct dfs_filesystem *iter;
-    struct dfs_filesystem *fs = NULL;
-    uint32_t fspath, prefixlen;
-
-    prefixlen = 0;
-
-    RT_ASSERT(path);
+    int ret = 0;
+    struct dfs_filesystem_type **type = _find_filesystem(fs->fs_ops->name);
 
-    /* lock filesystem */
-    dfs_lock();
+    LOG_D("register %s file system.", fs->fs_ops->name);
 
-    /* lookup it in the filesystem table */
-    for (iter = &filesystem_table[0];
-            iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
+    if (*type)
     {
-        if ((iter->path == NULL) || (iter->ops == NULL))
-            continue;
-
-        fspath = strlen(iter->path);
-        if ((fspath < prefixlen)
-            || (strncmp(iter->path, path, fspath) != 0))
-            continue;
-
-        /* check next path separator */
-        if (fspath > 1 && (strlen(path) > fspath) && (path[fspath] != '/'))
-            continue;
-
-        fs = iter;
-        prefixlen = fspath;
+        ret = -EBUSY;
     }
-
-    dfs_unlock();
-
-    return fs;
-}
-
-/**
- * this function will return the mounted path for specified device.
- *
- * @param device the device object which is mounted.
- *
- * @return the mounted path or NULL if none device mounted.
- */
-const char *dfs_filesystem_get_mounted_path(struct rt_device *device)
-{
-    const char *path = NULL;
-    struct dfs_filesystem *iter;
-
-    dfs_lock();
-    for (iter = &filesystem_table[0];
-            iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
+    else
     {
-        /* find the mounted device */
-        if (iter->ops == NULL) continue;
-        else if (iter->dev_id == device)
-        {
-            path = iter->path;
-            break;
-        }
+        *type = fs;
     }
 
-    /* release filesystem_table lock */
-    dfs_unlock();
-
-    return path;
+    return ret;
 }
 
-/**
- * this function will fetch the partition table on specified buffer.
- *
- * @param part the returned partition structure.
- * @param buf the buffer contains partition table.
- * @param pindex the index of partition table to fetch.
- *
- * @return RT_EOK on successful or -RT_ERROR on failed.
- */
-int dfs_filesystem_get_partition(struct dfs_partition *part,
-                                 uint8_t         *buf,
-                                 uint32_t        pindex)
+int dfs_unregister(struct dfs_filesystem_type *fs)
 {
-#define DPT_ADDRESS     0x1be       /* device partition offset in Boot Sector */
-#define DPT_ITEM_SIZE   16          /* partition item size */
+    int ret = 0;
+    struct dfs_filesystem_type **type;
 
-    uint8_t *dpt;
-    uint8_t type;
-
-    RT_ASSERT(part != NULL);
-    RT_ASSERT(buf != NULL);
-
-    dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
-
-    /* check if it is a valid partition table */
-    if ((*dpt != 0x80) && (*dpt != 0x00))
-        return -EIO;
-
-    /* get partition type */
-    type = *(dpt + 4);
-    if (type == 0)
-        return -EIO;
+    if (fs)
+    {
+        LOG_D("unregister %s file system.", fs->fs_ops->name);
 
-    /* set partition information
-     *    size is the number of 512-Byte */
-    part->type = type;
-    part->offset = *(dpt + 8) | *(dpt + 9) << 8 | *(dpt + 10) << 16 | *(dpt + 11) << 24;
-    part->size = *(dpt + 12) | *(dpt + 13) << 8 | *(dpt + 14) << 16 | *(dpt + 15) << 24;
+        for (type = &file_systems; *type; type = &(*type)->next)
+        {
+            if (strcmp((*type)->fs_ops->name, fs->fs_ops->name) == 0)
+            {
+                *type = (*type)->next;
+                break;
+            }
+        }
 
-    rt_kprintf("found part[%d], begin: %d, size: ",
-               pindex, part->offset * 512);
-    if ((part->size >> 11) == 0)
-        rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */
-    else
-    {
-        unsigned int part_size;
-        part_size = part->size >> 11;                /* MB */
-        if ((part_size >> 10) == 0)
-            rt_kprintf("%d.%d%s", part_size, (part->size >> 1) & 0x3FF, "MB\n");
-        else
-            rt_kprintf("%d.%d%s", part_size >> 10, part_size & 0x3FF, "GB\n");
+        if (!*type) ret = -EINVAL;
     }
 
-    return RT_EOK;
+    return ret;
 }
 
-/**
- * this function will mount a file system on a specified path.
- *
- * @param device_name the name of device which includes a file system.
- * @param path the path to mount a file system
- * @param filesystemtype the file system type
- * @param rwflag the read/write etc. flag.
- * @param data the private data(parameter) for this file system.
- *
- * @return 0 on successful or -1 on failed.
+/*
+ *    parent(mount path)
+ *    mnt_parent <- - - - - - -  +
+ *         |                     |
+ *         |- mnt_child <- - - - - -+ (1 refcount)
+ *                 |             |
+ *                 |- parent - - + (1 refcount)
  */
-int dfs_mount(const char   *device_name,
-              const char   *path,
-              const char   *filesystemtype,
+int dfs_mount(const char *device_name,
+              const char *path,
+              const char *filesystemtype,
               unsigned long rwflag,
-              const void   *data)
+              const void *data)
 {
-    const struct dfs_filesystem_ops **ops;
-    struct dfs_filesystem *iter;
-    struct dfs_filesystem *fs = NULL;
-    char *fullpath = NULL;
-    rt_device_t dev_id;
-
-    /* open specific device */
-    if (device_name == NULL)
-    {
-        /* which is a non-device filesystem mount */
-        dev_id = NULL;
-    }
-    else if ((dev_id = rt_device_find(device_name)) == NULL)
-    {
-        /* no this device */
-        rt_set_errno(-ENODEV);
-        return -1;
-    }
-
-    /* find out the specific filesystem */
-    dfs_lock();
-
-    for (ops = &filesystem_operation_table[0];
-            ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++)
-        if ((*ops != NULL) && (strncmp((*ops)->name, filesystemtype, strlen((*ops)->name)) == 0))
-            break;
-
-    dfs_unlock();
+    int ret = RT_EOK;
+    char *fullpath = RT_NULL;
+    rt_device_t dev_id = RT_NULL;
+    struct dfs_mnt *mnt_parent = RT_NULL, *mnt_child = RT_NULL;
+    struct dfs_dentry *mntpoint_dentry = RT_NULL;
+    struct dfs_filesystem_type *type = *_find_filesystem(filesystemtype);
 
-    if (ops == &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX])
+    if (type)
     {
-        /* can't find filesystem */
-        rt_set_errno(-ENODEV);
-        return -1;
+        fullpath = dfs_normalize_path(RT_NULL, path);
+        if (!fullpath)
+        {
+            rt_set_errno(EPERM);
+            ret = -1;
+        }
     }
-
-    /* check if there is mount implementation */
-    if ((*ops == NULL) || ((*ops)->mount == NULL))
+    else
     {
-        rt_set_errno(-ENOSYS);
-        return -1;
+        rt_set_errno(ENOENT);
+        ret = -1;
     }
 
-    /* make full path for special file */
-    fullpath = dfs_normalize_path(NULL, path);
-    if (fullpath == NULL) /* not an abstract path */
+    if (fullpath)
     {
-        rt_set_errno(-ENOTDIR);
-        return -1;
-    }
+        DLOG(note, "mnt", "mount %s(%s) on path: %s", device_name, filesystemtype, fullpath);
 
-    /* Check if the path exists or not, raw APIs call, fixme */
-    if ((strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0))
-    {
-        struct dfs_file fd;
+        /* open specific device */
+        if (device_name) dev_id = rt_device_find(device_name);
 
-        fd_init(&fd);
-        if (dfs_file_open(&fd, fullpath, O_RDONLY | O_DIRECTORY) < 0)
+        if (!(type->fs_ops->flags & FS_NEED_DEVICE) ||
+            ((type->fs_ops->flags & FS_NEED_DEVICE) && dev_id))
         {
-            rt_free(fullpath);
-            rt_set_errno(-ENOTDIR);
-
-            return -1;
+            DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt_parent = dfs_mnt_lookup(%s)", fullpath);
+            mnt_parent = dfs_mnt_lookup(fullpath);
+            if ((!mnt_parent && (strcmp(fullpath, "/") == 0 || strcmp(fullpath, "/dev") == 0))
+                || (mnt_parent && strcmp(fullpath, "/") == 0 && strcmp(mnt_parent->fullpath, fullpath) != 0))
+            {
+                LOG_D("no mnt found @ mount point %s, should be root.", fullpath);
+                DLOG(msg, "mnt", "dfs", DLOG_MSG_RET, "no mnt");
+
+                /* it's the root file system */
+                /* the mount point dentry is the same as root dentry. */
+
+                DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt_parent = dfs_mnt_create(path)");
+                mnt_parent = dfs_mnt_create(fullpath); /* mnt->ref_count should be 1. */
+                if (mnt_parent)
+                {
+                    DLOG(msg, "mnt", "dfs", DLOG_MSG_RET, "return mnt, ref_count=1");
+
+                    mnt_parent->fs_ops = type->fs_ops;
+                    mnt_parent->dev_id = dev_id;
+                    if (mnt_parent->fs_ops->mount)
+                    {
+                        DLOG(msg, "dfs", type->fs_ops->name, DLOG_MSG, "fs_ops->mount(mnt_parent, rwflag, data)");
+                        ret = mnt_parent->fs_ops->mount(mnt_parent, rwflag, data);
+                        if (ret == RT_EOK)
+                        {
+                            DLOG(msg, type->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK, ret root_dentry");
+
+                            mnt_child = mnt_parent;
+                            DLOG(note_right, "mnt", "mount sucessfully");
+                            DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_insert(, mnt_child)");
+                            dfs_mnt_insert(RT_NULL, mnt_child);
+
+                            /* unref it, because the ref_count = 1 when create */
+                            DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_unref(mnt_parent)");
+                            dfs_mnt_unref(mnt_parent);
+
+                            /*
+                             * About root mnt:
+                             * There are two ref_count:
+                             * 1. the gobal root reference.
+                             * 1. the mnt->parent reference.
+                             */
+                        }
+                        else
+                        {
+                            LOG_W("mount %s failed with file system type: %s", fullpath, type->fs_ops->name);
+                            DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_destroy(mnt_parent)");
+                            dfs_mnt_destroy(mnt_parent);
+                            mnt_parent = RT_NULL;
+                            rt_set_errno(EPERM);
+                            ret = -1;
+                        }
+                    }
+                    else
+                    {
+                        LOG_W("no mount method on file system type: %s", type->fs_ops->name);
+                        DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_destroy(mnt_parent), no mount method");
+                        dfs_mnt_destroy(mnt_parent);
+                        mnt_parent = RT_NULL;
+                        rt_set_errno(EIO);
+                        ret = -1;
+                    }
+                }
+                else
+                {
+                    LOG_E("create a mnt point failed.");
+                    rt_set_errno(ENOMEM);
+                    ret = -1;
+                }
+            }
+            else if (strcmp(mnt_parent->fullpath, fullpath) != 0)
+            {
+                DLOG(msg, "dfs", "dentry", DLOG_MSG, "mntpoint_dentry = dfs_dentry_lookup(mnt_parent, %s, 0)", fullpath);
+                mntpoint_dentry = dfs_dentry_lookup(mnt_parent, fullpath, 0);
+                if (mntpoint_dentry)
+                {
+                    DLOG(msg, "dentry", "dfs", DLOG_MSG_RET, "dentry exist");
+                    DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt_child = dfs_mnt_create(path)");
+                    mnt_child = dfs_mnt_create(fullpath);
+                    if (mnt_child)
+                    {
+                        LOG_D("create mnt point %p", mnt_child);
+
+                        mnt_child->fs_ops = type->fs_ops;
+                        mnt_child->dev_id = dev_id;
+
+                        if (mnt_child->fs_ops->mount)
+                        {
+                            DLOG(msg, "dfs", type->fs_ops->name, DLOG_MSG, "root_dentry = fs_ops->mount(mnt_child, rwflag, data)");
+                            ret = mnt_child->fs_ops->mount(mnt_child, rwflag, data);
+                            if (ret == RT_EOK)
+                            {
+                                LOG_D("mount %s sucessfully", fullpath);
+                                DLOG(msg, mnt_child->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK");
+
+                                DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_insert(mnt_parent, mnt_child)");
+                                dfs_mnt_insert(mnt_parent, mnt_child);
+
+                                /* unref it, because the ref_count = 1 when create */
+                                DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_unref(mnt_child)");
+                                dfs_mnt_unref(mnt_child);
+                            }
+                            else
+                            {
+                                LOG_W("mount %s failed with file system type: %s", fullpath, type->fs_ops->name);
+                                DLOG(msg, mnt_child->fs_ops->name, "dfs", DLOG_MSG_RET, "mount failed");
+                                dfs_mnt_destroy(mnt_child);
+                                rt_set_errno(EPERM);
+                                ret = -1;
+                            }
+                        }
+                        else
+                        {
+                            LOG_W("no mount method on file system type: %s", type->fs_ops->name);
+                            dfs_mnt_destroy(mnt_child);
+                            rt_set_errno(EIO);
+                            ret = -1;
+                        }
+                    }
+                    else
+                    {
+                        LOG_E("create a mnt point failed.");
+                        rt_set_errno(ENOMEM);
+                        ret = -1;
+                    }
+                    dfs_dentry_unref(mntpoint_dentry);
+                }
+                else
+                {
+                    LOG_W("no mount point (%s) in file system: %s", fullpath, mnt_parent->fullpath);
+                    rt_set_errno(ENOTDIR);
+                    ret = -1;
+                }
+            }
+            else
+            {
+                LOG_E("mount point (%s) already mounted!", fullpath);
+                rt_set_errno(EEXIST);
+                ret = -1;
+            }
         }
-        dfs_file_close(&fd);
-    }
-
-    /* check whether the file system mounted or not  in the filesystem table
-     * if it is unmounted yet, find out an empty entry */
-    dfs_lock();
-
-    for (iter = &filesystem_table[0];
-            iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
-    {
-        /* check if it is an empty filesystem table entry? if it is, save fs */
-        if (iter->ops == NULL)
-            (fs == NULL) ? (fs = iter) : 0;
-        /* check if the PATH is mounted */
-        else if (strcmp(iter->path, path) == 0)
+        else
         {
-            rt_set_errno(-EINVAL);
-            goto err1;
+            LOG_E("No device found for this file system.");
+            rt_set_errno(ENODEV);
+            ret = -1;
         }
+        rt_free(fullpath);
     }
 
-    if ((fs == NULL) && (iter == &filesystem_table[DFS_FILESYSTEMS_MAX]))
-    {
-        rt_set_errno(-ENOSPC);
-        LOG_E("There is no space to mount this file system (%s).", filesystemtype);
-        goto err1;
-    }
-
-    /* register file system */
-    fs->path   = fullpath;
-    fs->ops    = *ops;
-    fs->dev_id = dev_id;
-    /* For UFS, record the real filesystem name */
-    fs->data = (void *) filesystemtype;
+    return ret;
+}
 
-    /* release filesystem_table lock */
-    dfs_unlock();
+int dfs_umount(const char *specialfile)
+{
+    int ret = -RT_ERROR;
+    char *fullpath = RT_NULL;
+    struct dfs_mnt *mnt = RT_NULL;
 
-    /* open device, but do not check the status of device */
-    if (dev_id != NULL)
+    fullpath = dfs_normalize_path(NULL, specialfile);
+    if (fullpath)
     {
-        if (rt_device_open(fs->dev_id,
-                           RT_DEVICE_OFLAG_RDWR) != RT_EOK)
+        DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt = dfs_mnt_lookup(%s)", fullpath);
+        mnt = dfs_mnt_lookup(fullpath);
+        if (mnt)
         {
-            /* The underlying device has error, clear the entry. */
-            dfs_lock();
-            rt_memset(fs, 0, sizeof(struct dfs_filesystem));
-
-            goto err1;
+            if (strcmp(mnt->fullpath, fullpath) == 0)
+            {
+                /* is the mount point */
+
+                if (rt_atomic_load(&(mnt->ref_count)) == 1 && rt_list_isempty(&mnt->child))
+                {
+                    DLOG(msg, "dfs", mnt->fs_ops->name, DLOG_MSG, "fs_ops->umount(mnt)");
+                    ret = mnt->fs_ops->umount(mnt);
+                    if (ret == 0)
+                    {
+                        DLOG(msg, mnt->fs_ops->name, "dfs", DLOG_MSG_RET, "return OK");
+                        /* destroy this mount point */
+                        DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_destroy(mnt)");
+                        dfs_mnt_destroy(mnt);
+                    }
+                    else
+                    {
+                        LOG_E("umount file system: %s failed.", fullpath);
+                    }
+                }
+                else
+                {
+                    LOG_E("the file system is busy!");
+                }
+            }
+            else
+            {
+                LOG_E("the path:%s is not a mountpoint!", fullpath);
+            }
         }
+        else
+        {
+            LOG_E("no filesystem found.");
+        }
+        rt_free(fullpath);
     }
-
-    /* call mount of this filesystem */
-    if ((*ops)->mount(fs, rwflag, data) < 0)
+    else
     {
-        /* close device */
-        if (dev_id != NULL)
-            rt_device_close(fs->dev_id);
-
-        /* mount failed */
-        dfs_lock();
-        /* clear filesystem table entry */
-        rt_memset(fs, 0, sizeof(struct dfs_filesystem));
-
-        goto err1;
+        rt_set_errno(-ENOTDIR);
     }
 
-    return 0;
-
-err1:
-    dfs_unlock();
-    rt_free(fullpath);
-
-    return -1;
+    return ret;
 }
 
-/**
- * this function will unmount a file system on specified path.
- *
- * @param specialfile the specified path which mounted a file system.
- *
- * @return 0 on successful or -1 on failed.
- */
+/* for compatibility */
 int dfs_unmount(const char *specialfile)
 {
-    char *fullpath;
-    struct dfs_filesystem *iter;
-    struct dfs_filesystem *fs = NULL;
+    return dfs_umount(specialfile);
+}
 
-    fullpath = dfs_normalize_path(NULL, specialfile);
-    if (fullpath == NULL)
-    {
-        rt_set_errno(-ENOTDIR);
+int dfs_mkfs(const char *fs_name, const char *device_name)
+{
+    rt_device_t dev_id = NULL;
+    struct dfs_filesystem_type *type;
+    int ret = -RT_ERROR;
 
-        return -1;
+    type = *_find_filesystem(fs_name);
+    if (!type)
+    {
+        rt_kprintf("no file system: %s found!\n", fs_name);
+        return ret;
     }
-
-    /* lock filesystem */
-    dfs_lock();
-
-    for (iter = &filesystem_table[0];
-            iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
+    else
     {
-        /* check if the PATH is mounted */
-        if ((iter->path != NULL) && (strcmp(iter->path, fullpath) == 0))
+        if (type->fs_ops->flags & FS_NEED_DEVICE)
         {
-            fs = iter;
-            break;
+            /* check device name, and it should not be NULL */
+            if (device_name != NULL)
+                dev_id = rt_device_find(device_name);
+
+            if (dev_id == NULL)
+            {
+                rt_set_errno(-ENODEV);
+                rt_kprintf("Device (%s) was not found", device_name);
+                return ret;
+            }
+        }
+        else
+        {
+            dev_id = RT_NULL;
         }
     }
 
-    if (fs == NULL ||
-        fs->ops->unmount == NULL ||
-        fs->ops->unmount(fs) < 0)
+    if (type->fs_ops->mkfs)
     {
-        goto err1;
+        ret = type->fs_ops->mkfs(dev_id, type->fs_ops->name);
     }
 
-    /* close device, but do not check the status of device */
-    if (fs->dev_id != NULL)
-        rt_device_close(fs->dev_id);
-
-    if (fs->path != NULL)
-        rt_free(fs->path);
-
-    /* clear this filesystem table entry */
-    rt_memset(fs, 0, sizeof(struct dfs_filesystem));
-
-    dfs_unlock();
-    rt_free(fullpath);
-
-    return 0;
-
-err1:
-    dfs_unlock();
-    rt_free(fullpath);
-
-    return -1;
+    return ret;
 }
 
-/**
- * make a file system on the special device
- *
- * @param fs_name the file system name
- * @param device_name the special device name
- *
- * @return 0 on successful, otherwise failed.
- */
-int dfs_mkfs(const char *fs_name, const char *device_name)
+int dfs_statfs(const char *path, struct statfs *buffer)
 {
-    int index;
-    rt_device_t dev_id = NULL;
-
-    /* check device name, and it should not be NULL */
-    if (device_name != NULL)
-        dev_id = rt_device_find(device_name);
-
-    if (dev_id == NULL)
-    {
-        rt_set_errno(-ENODEV);
-        LOG_E("Device (%s) was not found", device_name);
-        return -1;
-    }
+    struct dfs_mnt *mnt;
+    char *fullpath;
+    int ret = -RT_ERROR;
 
-    /* lock file system */
-    dfs_lock();
-    /* find the file system operations */
-    for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index ++)
+    fullpath = dfs_normalize_path(NULL, path);
+    if (!fullpath)
     {
-        if (filesystem_operation_table[index] != NULL &&
-            strncmp(filesystem_operation_table[index]->name, fs_name,
-                strlen(filesystem_operation_table[index]->name)) == 0)
-            break;
+        return ret;
     }
-    dfs_unlock();
 
-    if (index < DFS_FILESYSTEM_TYPES_MAX)
+    DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath);
+    mnt = dfs_mnt_lookup(fullpath);
+    if (mnt)
     {
-        /* find file system operation */
-        const struct dfs_filesystem_ops *ops = filesystem_operation_table[index];
-        if (ops->mkfs == NULL)
+        if (mnt->fs_ops->statfs)
         {
-            LOG_E("The file system (%s) mkfs function was not implement", fs_name);
-            rt_set_errno(-ENOSYS);
-            return -1;
+            ret = mnt->fs_ops->statfs(mnt, buffer);
         }
-
-        return ops->mkfs(dev_id, fs_name);
     }
 
-    LOG_E("File system (%s) was not found.", fs_name);
-
-    return -1;
+    return ret;
 }
 
 /**
- * this function will return the information about a mounted file system.
+ * this function will return the mounted path for specified device.
  *
- * @param path the path which mounted file system.
- * @param buffer the buffer to save the returned information.
+ * @param device the device object which is mounted.
  *
- * @return 0 on successful, others on failed.
+ * @return the mounted path or NULL if none device mounted.
  */
-int dfs_statfs(const char *path, struct statfs *buffer)
-{
-    struct dfs_filesystem *fs;
-
-    fs = dfs_filesystem_lookup(path);
-    if (fs != NULL)
-    {
-        if (fs->ops->statfs != NULL)
-            return fs->ops->statfs(fs, buffer);
-    }
-
-    rt_set_errno(-ENOSYS);
-    return -1;
-}
-
-#ifdef RT_USING_DFS_MNTTABLE
-int dfs_mount_table(void)
-{
-    int index = 0;
-
-    while (1)
-    {
-        if (mount_table[index].path == NULL) break;
-
-        if (dfs_mount(mount_table[index].device_name,
-                      mount_table[index].path,
-                      mount_table[index].filesystemtype,
-                      mount_table[index].rwflag,
-                      mount_table[index].data) != 0)
-        {
-            LOG_E("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype,
-                       mount_table[index].path);
-            return -RT_ERROR;
-        }
-
-        index ++;
-    }
-    return 0;
-}
-INIT_ENV_EXPORT(dfs_mount_table);
-
-int dfs_mount_device(rt_device_t dev)
+const char *dfs_filesystem_get_mounted_path(struct rt_device *device)
 {
-  int index = 0;
-
-  if(dev == RT_NULL) {
-    rt_kprintf("the device is NULL to be mounted.\n");
-    return -RT_ERROR;
-  }
-
-  while (1)
-  {
-    if (mount_table[index].path == NULL) break;
-
-    if(strcmp(mount_table[index].device_name, dev->parent.name) == 0) {
-      if (dfs_mount(mount_table[index].device_name,
-                    mount_table[index].path,
-                    mount_table[index].filesystemtype,
-                    mount_table[index].rwflag,
-                    mount_table[index].data) != 0)
-      {
-        LOG_E("mount fs[%s] device[%s] to %s failed.\n", mount_table[index].filesystemtype, dev->parent.name,
-                   mount_table[index].path);
-        return -RT_ERROR;
-      } else {
-        LOG_D("mount fs[%s] device[%s] to %s ok.\n", mount_table[index].filesystemtype, dev->parent.name,
-                   mount_table[index].path);
-        return RT_EOK;
-      }
-    }
-
-    index ++;
-  }
+    const char *path = NULL;
 
-  rt_kprintf("can't find device:%s to be mounted.\n", dev->parent.name);
-  return -RT_ERROR;
+    return path;
 }
 
-int dfs_unmount_device(rt_device_t dev)
+/**
+ * this function will fetch the partition table on specified buffer.
+ *
+ * @param part the returned partition structure.
+ * @param buf the buffer contains partition table.
+ * @param pindex the index of partition table to fetch.
+ *
+ * @return RT_EOK on successful or -RT_ERROR on failed.
+ */
+int dfs_filesystem_get_partition(struct dfs_partition *part,
+                                 uint8_t *buf,
+                                 uint32_t pindex)
 {
-    struct dfs_filesystem *iter;
-    struct dfs_filesystem *fs = NULL;
-
-    /* lock filesystem */
-    dfs_lock();
-
-    for (iter = &filesystem_table[0];
-            iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++)
-    {
-        /* check if the PATH is mounted */
-        if (strcmp(iter->dev_id->parent.name, dev->parent.name) == 0)
-        {
-            fs = iter;
-            break;
-        }
-    }
-
-    if (fs == NULL ||
-        fs->ops->unmount == NULL ||
-        fs->ops->unmount(fs) < 0)
-    {
-        goto err1;
-    }
-
-    /* close device, but do not check the status of device */
-    if (fs->dev_id != NULL)
-        rt_device_close(fs->dev_id);
-
-    if (fs->path != NULL)
-        rt_free(fs->path);
-
-    /* clear this filesystem table entry */
-    rt_memset(fs, 0, sizeof(struct dfs_filesystem));
-
-    dfs_unlock();
-
-    return 0;
+#define DPT_ADDRESS     0x1be       /* device partition offset in Boot Sector */
+#define DPT_ITEM_SIZE   16          /* partition item size */
 
-err1:
-    dfs_unlock();
+    uint8_t *dpt;
+    uint8_t type;
 
-    return -1;
-}
+    RT_ASSERT(part != NULL);
+    RT_ASSERT(buf != NULL);
 
-#endif
+    dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
 
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-void mkfs(const char *fs_name, const char *device_name)
-{
-    dfs_mkfs(fs_name, device_name);
-}
-FINSH_FUNCTION_EXPORT(mkfs, make a file system);
+    /* check if it is a valid partition table */
+    if ((*dpt != 0x80) && (*dpt != 0x00))
+        return -EIO;
 
-int df(const char *path)
-{
-    int result;
-    int minor = 0;
-    long long cap;
-    struct statfs buffer;
+    /* get partition type */
+    type = *(dpt + 4);
+    if (type == 0)
+        return -EIO;
 
-    int unit_index = 0;
-    char *unit_str[] = {"KB", "MB", "GB"};
+    /* set partition information
+     *    size is the number of 512-Byte */
+    part->type = type;
+    part->offset = *(dpt + 8) | *(dpt + 9) << 8 | *(dpt + 10) << 16 | *(dpt + 11) << 24;
+    part->size = *(dpt + 12) | *(dpt + 13) << 8 | *(dpt + 14) << 16 | *(dpt + 15) << 24;
 
-    result = dfs_statfs(path ? path : NULL, &buffer);
-    if (result != 0)
+    rt_kprintf("found part[%d], begin: %ld, size: ",
+               pindex, part->offset * 512);
+    if ((part->size >> 11) == 0)
+        rt_kprintf("%ld%s", part->size >> 1, "KB\n"); /* KB */
+    else
     {
-        if (rt_get_errno() == -ENOSYS)
-            rt_kprintf("The function is not implemented.\n");
+        unsigned int part_size;
+        part_size = part->size >> 11;                /* MB */
+        if ((part_size >> 10) == 0)
+            rt_kprintf("%d.%ld%s", part_size, (part->size >> 1) & 0x3FF, "MB\n");
         else
-            rt_kprintf("statfs failed: errno=%d.\n", rt_get_errno());
-        return -1;
-    }
-
-    cap = ((long long)buffer.f_bsize) * ((long long)buffer.f_bfree) / 1024LL;
-    for (unit_index = 0; unit_index < 2; unit_index ++)
-    {
-        if (cap < 1024) break;
-
-        minor = (cap % 1024) * 10 / 1024; /* only one decimal point */
-        cap = cap / 1024;
+            rt_kprintf("%d.%d%s", part_size >> 10, part_size & 0x3FF, "GB\n");
     }
 
-    rt_kprintf("disk free: %d.%d %s [ %d block, %d bytes per block ]\n",
-               (unsigned long)cap, minor, unit_str[unit_index], buffer.f_bfree, buffer.f_bsize);
-    return 0;
+    return RT_EOK;
 }
-FINSH_FUNCTION_EXPORT(df, get disk free);
-#endif
 
-/**@}*/
+/* @} */

+ 386 - 0
components/dfs/dfs_v2/src/dfs_mnt.c

@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-05-05     Bernard      Implement mnt in dfs v2.0
+ */
+
+#include <rtthread.h>
+
+#include "dfs.h"
+#include "dfs_mnt.h"
+#include "dfs_dentry.h"
+#include "dfs_private.h"
+
+#define DBG_TAG "DFS.mnt"
+#define DBG_LVL DBG_WARNING
+#include <rtdbg.h>
+
+static struct dfs_mnt *_root_mnt = RT_NULL;
+
+/*
+ * mnt tree structure
+ *
+ * mnt_root <----------------------------------------+
+ *   | (child)                +----------+           |
+ *   v          (sibling)     v          |           |
+ *   mnt_child0     ->    mnt_child1     |           |
+ *                            | (child)  |           |
+ *                            v         / (parent)   | (root)
+ *                            mnt_child10         ---/
+ *
+ */
+
+struct dfs_mnt *dfs_mnt_create(const char *path)
+{
+    struct dfs_mnt *mnt = rt_calloc(1, sizeof(struct dfs_mnt));
+    if (mnt)
+    {
+        LOG_I("create mnt at %s", path);
+
+        mnt->fullpath = rt_strdup(path);
+        rt_list_init(&mnt->sibling);
+        rt_list_init(&mnt->child);
+        mnt->flags |= MNT_IS_ALLOCED;
+        rt_atomic_store(&(mnt->ref_count), 1);
+    }
+    else
+    {
+        rt_set_errno(-ENOMEM);
+    }
+
+    return mnt;
+}
+
+int dfs_mnt_insert(struct dfs_mnt* mnt, struct dfs_mnt* child)
+{
+    if (child)
+    {
+        if (mnt == RT_NULL)
+        {
+            /* insert into root */
+            mnt = dfs_mnt_lookup(child->fullpath);
+            if (mnt == RT_NULL || (strcmp(child->fullpath, "/") == 0))
+            {
+                /* it's root mnt */
+                mnt = child;
+
+                /* ref to gobal root */
+                if (_root_mnt)
+                {
+                    child = _root_mnt;
+                    rt_atomic_sub(&(_root_mnt->parent->ref_count), 1);
+                    rt_atomic_sub(&(_root_mnt->ref_count), 1);
+
+                    _root_mnt = dfs_mnt_ref(mnt);
+                    mnt->parent = dfs_mnt_ref(mnt);
+                    mnt->flags |= MNT_IS_ADDLIST;
+
+                    mkdir("/dev", 0777);
+                }
+                else
+                {
+                    _root_mnt = dfs_mnt_ref(mnt);
+                }
+            }
+        }
+
+        if (mnt)
+        {
+            child->flags |= MNT_IS_ADDLIST;
+            if (child != mnt)
+            {
+                /* not the root, insert into the child list */
+                rt_list_insert_before(&mnt->child, &child->sibling);
+                /* child ref self */
+                dfs_mnt_ref(child);
+            }
+            /* parent ref parent */
+            child->parent = dfs_mnt_ref(mnt);
+        }
+    }
+
+    return 0;
+}
+
+/* remove mnt from mnt_tree */
+int dfs_mnt_remove(struct dfs_mnt* mnt)
+{
+    int ret = -RT_ERROR;
+
+    if (rt_list_isempty(&mnt->child))
+    {
+        rt_list_remove(&mnt->sibling);
+        if (mnt->parent)
+        {
+            /* parent unref parent */
+            rt_atomic_sub(&(mnt->parent->ref_count), 1);
+        }
+
+        ret = RT_EOK;
+    }
+    else
+    {
+        LOG_W("remove a mnt point:%s with child.", mnt->fullpath);
+    }
+
+    return ret;
+}
+
+/**
+ * this function will return the file system mounted on specified path.
+ *
+ * @param path the specified path string.
+ *
+ * @return the found file system or NULL if no file system mounted on
+ * specified path
+ */
+struct dfs_mnt* dfs_mnt_lookup(const char* fullpath)
+{
+    struct dfs_mnt *mnt = _root_mnt;
+    struct dfs_mnt *iter = RT_NULL;
+
+    if (mnt)
+    {
+        dfs_lock();
+        if (strncmp(mnt->fullpath, fullpath, strlen(fullpath))!= 0)
+        {
+            while (!rt_list_isempty(&mnt->child))
+            {
+                rt_list_for_each_entry(iter, &mnt->child, sibling)
+                {
+                    int mnt_len = rt_strlen(iter->fullpath);
+                    if ((strncmp(iter->fullpath, fullpath, mnt_len) == 0) &&
+                        ((fullpath[mnt_len] == '\0') ||
+                        (fullpath[mnt_len] == '/')))
+                    {
+                        mnt = iter;
+                        break;
+                    }
+                }
+
+                if (mnt != iter) break;
+            }
+        }
+        dfs_unlock();
+
+        if (mnt)
+        {
+            LOG_D("mnt_lookup: %s path @ mount point %p", fullpath, mnt);
+            DLOG(note, "mnt", "found mnt(%s)", mnt->fs_ops->name);
+        }
+    }
+
+    return mnt;
+}
+
+struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt)
+{
+    if (mnt)
+    {
+        rt_atomic_add(&(mnt->ref_count), 1);
+        DLOG(note, "mnt", "mnt(%s),ref_count=%d", mnt->fs_ops->name, rt_atomic_load(&(mnt->ref_count)));
+    }
+
+    return mnt;
+}
+
+int dfs_mnt_unref(struct dfs_mnt* mnt)
+{
+    rt_err_t ret = RT_EOK;
+
+    if (mnt)
+    {
+        ret = dfs_lock();
+        if (ret == RT_EOK)
+        {
+            rt_atomic_sub(&(mnt->ref_count), 1);
+
+            if (rt_atomic_load(&(mnt->ref_count)) < 0)
+            {
+                LOG_W("bug on mnt(%s) release ref_count(%d).", mnt->fullpath, mnt->ref_count);
+            }
+            DLOG(note, "mnt", "mnt(%s),ref_count=%d", mnt->fs_ops->name, rt_atomic_load(&(mnt->ref_count)));
+
+            dfs_unlock();
+        }
+    }
+
+    return 0;
+}
+
+int dfs_mnt_destroy(struct dfs_mnt* mnt)
+{
+    rt_err_t ret = RT_EOK;
+
+    if (mnt)
+    {
+        ret = dfs_lock();
+        if (ret == RT_EOK)
+        {
+            if (rt_atomic_load(&(mnt->ref_count)) != 1)
+            {
+                LOG_W("bug on mnt(%s) ref_count(%d).", mnt->fullpath, mnt->ref_count);
+            }
+
+            /* remote it from mnt list */
+            if (mnt->flags & MNT_IS_ADDLIST)
+            {
+                dfs_mnt_remove(mnt);
+            }
+
+            /* free full path */
+            rt_free(mnt->fullpath);
+            mnt->fullpath = RT_NULL;
+
+            dfs_unlock();
+
+            /* destroy self and the ref_count should be 0 */
+            DLOG(msg, "mnt", "mnt", DLOG_MSG, "free mnt(%s)", mnt->fs_ops->name);
+            rt_free(mnt);
+        }
+    }
+
+    return 0;
+}
+
+static struct dfs_mnt* _dfs_mnt_foreach(struct dfs_mnt *mnt, struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter)
+{
+    struct dfs_mnt *iter, *ret = NULL;
+
+    if (mnt)
+    {
+        ret = func(mnt, parameter);
+        if (ret == RT_NULL)
+        {
+            if (!rt_list_isempty(&mnt->child))
+            {
+                /* for each in mount point list */
+                rt_list_for_each_entry(iter, &mnt->child, sibling)
+                {
+                    ret = _dfs_mnt_foreach(iter, func, parameter);
+                    if (ret != RT_NULL)
+                    {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        ret = RT_NULL;
+    }
+
+    return ret;
+}
+
+static struct dfs_mnt* _mnt_cmp_devid(struct dfs_mnt *mnt, void *device)
+{
+    struct dfs_mnt *ret = RT_NULL;
+    struct rt_device *dev = (struct rt_device*)device;
+
+    if (dev && mnt)
+    {
+        if (mnt->dev_id == dev)
+        {
+            ret = mnt;
+        }
+    }
+
+    return ret;
+}
+
+/**
+ * this function will return the mounted path for specified device.
+ *
+ * @param device the device object which is mounted.
+ *
+ * @return the mounted path or NULL if none device mounted.
+ */
+const char *dfs_mnt_get_mounted_path(struct rt_device *device)
+{
+    const char* path = RT_NULL;
+
+    if (_root_mnt)
+    {
+        struct dfs_mnt* mnt;
+
+        dfs_lock();
+        mnt = _dfs_mnt_foreach(_root_mnt, _mnt_cmp_devid, device);
+        dfs_unlock();
+
+        if (mnt) path = mnt->fullpath;
+    }
+
+    return path;
+}
+
+static struct dfs_mnt* _mnt_dump(struct dfs_mnt *mnt, void *parameter)
+{
+    if (mnt)
+    {
+        if (mnt->dev_id)
+        {
+            rt_kprintf("%-10s  %-6s  %-10s   %d\n",
+                       mnt->fs_ops->name, mnt->dev_id->parent.name, mnt->fullpath, rt_atomic_load(&(mnt->ref_count)));
+        }
+        else
+        {
+            rt_kprintf("%-10s  (NULL)  %-10s   %d\n",
+                       mnt->fs_ops->name, mnt->fullpath, rt_atomic_load(&(mnt->ref_count)));
+        }
+    }
+
+    return RT_NULL;
+}
+
+static struct dfs_mnt* _mnt_cmp_path(struct dfs_mnt* mnt, void *parameter)
+{
+    const char* fullpath = (const char*)parameter;
+    struct dfs_mnt *ret = RT_NULL;
+
+    if (strncmp(mnt->fullpath, fullpath, rt_strlen(fullpath)) == 0)
+    {
+        ret = mnt;
+    }
+
+    return ret;
+}
+
+rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char* fullpath)
+{
+    int ret = RT_FALSE;
+
+    if (mnt && fullpath)
+    {
+        struct dfs_mnt *m = RT_NULL;
+
+        dfs_lock();
+        m = _dfs_mnt_foreach(mnt, _mnt_cmp_path, (void*)fullpath);
+        dfs_unlock();
+
+        if (m)
+        {
+            ret = RT_TRUE;
+        }
+    }
+
+    return ret;
+}
+
+int dfs_mnt_list(struct dfs_mnt *mnt)
+{
+    if (!mnt) mnt = _root_mnt;
+
+    /* lock file system */
+    dfs_lock();
+    _dfs_mnt_foreach(mnt, _mnt_dump, RT_NULL);
+    /* unlock file system */
+    dfs_unlock();
+
+    return 0;
+}

+ 379 - 179
components/dfs/dfs_v2/src/dfs_posix.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -7,12 +7,15 @@
  * Date           Author       Notes
  * 2009-05-27     Yi.qiu       The first version
  * 2018-02-07     Bernard      Change the 3rd parameter of open/fcntl/ioctl to '...'
- * 2022-01-19     Meco Man     add creat()
+ * 2021-08-26     linzhenxing  add setcwd and modify getcwd\chdir
  */
 
-#include <dfs_file.h>
-#include <dfs_private.h>
-#include <sys/errno.h>
+#include <dfs.h>
+#include <unistd.h>
+
+#include <dfs_dentry.h>
+#include <dfs_mnt.h>
+#include "dfs_private.h"
 
 #ifdef RT_USING_SMART
 #include <lwp.h>
@@ -35,26 +38,39 @@
 int open(const char *file, int flags, ...)
 {
     int fd, result;
-    struct dfs_file *d;
+    struct dfs_file *df = RT_NULL;
+    mode_t mode = 0;
 
-    /* allocate a fd */
-    fd = fd_new();
-    if (fd < 0)
+    if (file == NULL)
     {
-        rt_set_errno(-ENOMEM);
-
+        rt_set_errno(-EBADF);
         return -1;
     }
-    d = fd_get(fd);
 
-    result = dfs_file_open(d, file, flags);
+    if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE)
+    {
+        va_list ap;
+        va_start(ap, flags);
+        mode = va_arg(ap, mode_t);
+        va_end(ap);
+    }
+
+    fd = fd_new();
+    if (fd >= 0)
+    {
+        df = fd_get(fd);
+    }
+    else
+    {
+        rt_set_errno(-RT_ERROR);
+        return RT_NULL;
+    }
+
+    result = dfs_file_open(df, file, flags, mode);
     if (result < 0)
     {
-        /* release the ref-count of fd */
         fd_release(fd);
-
         rt_set_errno(result);
-
         return -1;
     }
 
@@ -135,18 +151,17 @@ RTM_EXPORT(creat);
 int close(int fd)
 {
     int result;
-    struct dfs_file *d;
+    struct dfs_file *file;
 
-    d = fd_get(fd);
-    if (d == NULL)
+    file = fd_get(fd);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
         return -1;
     }
 
-    result = dfs_file_close(d);
-
+    result = dfs_file_close(file);
     if (result < 0)
     {
         rt_set_errno(result);
@@ -171,25 +186,30 @@ RTM_EXPORT(close);
  * @return the actual read data buffer length. If the returned value is 0, it
  * may be reach the end of file, please check errno.
  */
-#ifdef _READ_WRITE_RETURN_TYPE
-_READ_WRITE_RETURN_TYPE read(int fd, void *buf, size_t len) /* some gcc tool chains will use different data structure */
+#if defined(RT_USING_NEWLIB) && defined(_EXFUN)
+_READ_WRITE_RETURN_TYPE _EXFUN(read, (int fd, void *buf, size_t len))
 #else
 ssize_t read(int fd, void *buf, size_t len)
 #endif
 {
-    int result;
-    struct dfs_file *d;
+    ssize_t result;
+    struct dfs_file *file;
 
-    /* get the fd */
-    d = fd_get(fd);
-    if (d == NULL)
+    if (buf == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
+    file = fd_get(fd);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
         return -1;
     }
 
-    result = dfs_file_read(d, buf, len);
+    result = dfs_file_read(file, buf, len);
     if (result < 0)
     {
         rt_set_errno(result);
@@ -211,25 +231,30 @@ RTM_EXPORT(read);
  *
  * @return the actual written data buffer length.
  */
-#ifdef _READ_WRITE_RETURN_TYPE
-_READ_WRITE_RETURN_TYPE write(int fd, const void *buf, size_t len) /* some gcc tool chains will use different data structure */
+#if defined(RT_USING_NEWLIB) && defined(_EXFUN)
+_READ_WRITE_RETURN_TYPE _EXFUN(write, (int fd, const void *buf, size_t len))
 #else
 ssize_t write(int fd, const void *buf, size_t len)
 #endif
 {
-    int result;
-    struct dfs_file *d;
+    ssize_t result;
+    struct dfs_file *file;
 
-    /* get the fd */
-    d = fd_get(fd);
-    if (d == NULL)
+    if (buf == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
+    file = fd_get(fd);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
         return -1;
     }
 
-    result = dfs_file_write(d, buf, len);
+    result = dfs_file_write(file, buf, len);
     if (result < 0)
     {
         rt_set_errno(result);
@@ -253,43 +278,18 @@ RTM_EXPORT(write);
  */
 off_t lseek(int fd, off_t offset, int whence)
 {
-    int result;
-    struct dfs_file *d;
+    off_t result;
+    struct dfs_file *file;
 
-    d = fd_get(fd);
-    if (d == NULL)
+    file = fd_get(fd);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
         return -1;
     }
 
-    switch (whence)
-    {
-    case SEEK_SET:
-        break;
-
-    case SEEK_CUR:
-        offset += d->pos;
-        break;
-
-    case SEEK_END:
-        offset += d->vnode->size;
-        break;
-
-    default:
-        rt_set_errno(-EINVAL);
-
-        return -1;
-    }
-
-    if (offset < 0)
-    {
-        rt_set_errno(-EINVAL);
-
-        return -1;
-    }
-    result = dfs_file_lseek(d, offset);
+    result = dfs_file_lseek(file, offset, whence);
     if (result < 0)
     {
         rt_set_errno(result);
@@ -297,11 +297,10 @@ off_t lseek(int fd, off_t offset, int whence)
         return -1;
     }
 
-    return offset;
+    return result;
 }
 RTM_EXPORT(lseek);
 
-#ifndef _WIN32
 /**
  * this function is a POSIX compliant version, which will rename old file name
  * to new file name.
@@ -317,6 +316,12 @@ int rename(const char *old_file, const char *new_file)
 {
     int result;
 
+    if (old_file == NULL || new_file == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
     result = dfs_file_rename(old_file, new_file);
     if (result < 0)
     {
@@ -328,7 +333,6 @@ int rename(const char *old_file, const char *new_file)
     return 0;
 }
 RTM_EXPORT(rename);
-#endif
 
 /**
  * this function is a POSIX compliant version, which will unlink (remove) a
@@ -341,6 +345,21 @@ RTM_EXPORT(rename);
 int unlink(const char *pathname)
 {
     int result;
+    struct stat stat;
+
+    if (pathname == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
+    result = dfs_file_lstat(pathname, &stat);
+    if (result == 0 && S_ISDIR(stat.st_mode))
+    {
+        rt_set_errno(-RT_ERROR);
+
+        return -1;
+    }
 
     result = dfs_file_unlink(pathname);
     if (result < 0)
@@ -354,6 +373,7 @@ int unlink(const char *pathname)
 }
 RTM_EXPORT(unlink);
 
+#ifndef _WIN32 /* we can not implement these functions */
 /**
  * this function is a POSIX compliant version, which will get file information.
  *
@@ -366,12 +386,16 @@ int stat(const char *file, struct stat *buf)
 {
     int result;
 
+    if (file == NULL || buf == NULL)
+    {
+        rt_set_errno(EBADF);
+        return -1;
+    }
+
     result = dfs_file_stat(file, buf);
     if (result < 0)
     {
-        rt_set_errno(result);
-
-        return -1;
+        rt_set_errno(-result);
     }
 
     return result;
@@ -388,20 +412,30 @@ RTM_EXPORT(stat);
  */
 int fstat(int fildes, struct stat *buf)
 {
-    struct dfs_file *d;
+    int ret = 0;
+    struct dfs_file *file;
+
+    if (buf == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
 
     /* get the fd */
-    d = fd_get(fildes);
-    if (d == NULL)
+    file = fd_get(fildes);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
         return -1;
     }
 
-    return stat(d->vnode->fullpath, buf);
+    ret = file->dentry->mnt->fs_ops->stat(file->dentry, buf);
+
+    return ret;
 }
 RTM_EXPORT(fstat);
+#endif
 
 /**
  * this function is a POSIX compliant version, which shall request that all data
@@ -416,17 +450,17 @@ RTM_EXPORT(fstat);
 int fsync(int fildes)
 {
     int ret;
-    struct dfs_file *d;
+    struct dfs_file *file;
 
-    /* get the fd */
-    d = fd_get(fildes);
-    if (d == NULL)
+    file = fd_get(fildes);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
+
         return -1;
     }
 
-    ret = dfs_file_flush(d);
+    ret = dfs_file_fsync(file);
 
     return ret;
 }
@@ -447,11 +481,10 @@ RTM_EXPORT(fsync);
 int fcntl(int fildes, int cmd, ...)
 {
     int ret = -1;
-    struct dfs_file *d;
+    struct dfs_file *file;
 
-    /* get the fd */
-    d = fd_get(fildes);
-    if (d)
+    file = fd_get(fildes);
+    if (file)
     {
         void *arg;
         va_list ap;
@@ -460,9 +493,16 @@ int fcntl(int fildes, int cmd, ...)
         arg = va_arg(ap, void *);
         va_end(ap);
 
-        ret = dfs_file_ioctl(d, cmd, arg);
+        ret = dfs_file_ioctl(file, cmd, arg);
+        if (ret < 0)
+        {
+            ret = dfs_file_fcntl(fildes, cmd, (unsigned long)arg);
+        }
+    }
+    else
+    {
+        ret = -EBADF;
     }
-    else ret = -EBADF;
 
     if (ret < 0)
     {
@@ -513,10 +553,10 @@ RTM_EXPORT(ioctl);
 int ftruncate(int fd, off_t length)
 {
     int result;
-    struct dfs_file *d;
+    struct dfs_file *file;
 
-    d = fd_get(fd);
-    if (d == NULL)
+    file = fd_get(fd);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
@@ -529,7 +569,8 @@ int ftruncate(int fd, off_t length)
 
         return -1;
     }
-    result = dfs_file_ftruncate(d, length);
+
+    result = dfs_file_ftruncate(file, length);
     if (result < 0)
     {
         rt_set_errno(result);
@@ -554,6 +595,12 @@ int statfs(const char *path, struct statfs *buf)
 {
     int result;
 
+    if (path == NULL || buf == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
     result = dfs_statfs(path, buf);
     if (result < 0)
     {
@@ -577,18 +624,27 @@ RTM_EXPORT(statfs);
  */
 int fstatfs(int fildes, struct statfs *buf)
 {
-    struct dfs_file *d;
+    int ret = 0;
+    struct dfs_file *file;
+
+    if (buf == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
 
     /* get the fd */
-    d = fd_get(fildes);
-    if (d == NULL)
+    file = fd_get(fildes);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
         return -1;
     }
 
-    return statfs(d->vnode->fullpath, buf);
+    ret = file->dentry->mnt->fs_ops->statfs(file->dentry->mnt, buf);
+
+    return ret;
 }
 RTM_EXPORT(fstatfs);
 
@@ -602,37 +658,47 @@ RTM_EXPORT(fstatfs);
  */
 int mkdir(const char *path, mode_t mode)
 {
-    int fd;
-    struct dfs_file *d;
     int result;
+    struct stat stat;
+    struct dfs_file file;
 
-    fd = fd_new();
-    if (fd == -1)
+    if (path == NULL)
     {
-        rt_set_errno(-ENOMEM);
-
+        rt_set_errno(-EBADF);
         return -1;
     }
 
-    d = fd_get(fd);
+    if (path && dfs_file_lstat(path, &stat) == 0)
+    {
+        rt_set_errno(-RT_ERROR);
+        return -1;
+    }
 
-    result = dfs_file_open(d, path, O_DIRECTORY | O_CREAT);
+    dfs_file_init(&file);
 
-    if (result < 0)
+    result = dfs_file_open(&file, path, O_DIRECTORY | O_CREAT, mode);
+    if (result >= 0)
+    {
+        dfs_file_close(&file);
+        result = 0;
+    }
+    else
     {
-        fd_release(fd);
         rt_set_errno(result);
-
-        return -1;
+        result = -1;
     }
 
-    dfs_file_close(d);
-    fd_release(fd);
+    dfs_file_deinit(&file);
 
-    return 0;
+    return result;
 }
 RTM_EXPORT(mkdir);
 
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(mkdir, create a directory);
+#endif
+
 /**
  * this function is a POSIX compliant version, which will remove a directory.
  *
@@ -643,6 +709,49 @@ RTM_EXPORT(mkdir);
 int rmdir(const char *pathname)
 {
     int result;
+    DIR *dir = RT_NULL;
+    struct stat stat;
+
+    if (!pathname)
+    {
+        rt_set_errno(-RT_ERROR);
+        return -1;
+    }
+
+    dir = opendir(pathname);
+    if (dir)
+    {
+        struct dirent *dirent;
+
+        while (1)
+        {
+            dirent = readdir(dir);
+            if (dirent == RT_NULL)
+                break;
+            if (rt_strcmp(".", dirent->d_name) != 0 &&
+                rt_strcmp("..", dirent->d_name) != 0)
+            {
+                break;
+            }
+        }
+
+        closedir(dir);
+
+        if (dirent)
+        {
+            rt_set_errno(-RT_ERROR);
+            return -1;
+        }
+    }
+
+    if (dfs_file_lstat(pathname, &stat) == 0)
+    {
+        if (S_ISLNK(stat.st_mode))
+        {
+            rt_set_errno(-RT_ERROR);
+            return -1;
+        }
+    }
 
     result = dfs_file_unlink(pathname);
     if (result < 0)
@@ -665,30 +774,35 @@ RTM_EXPORT(rmdir);
  */
 DIR *opendir(const char *name)
 {
-    struct dfs_file *d;
+    DIR *t = RT_NULL;
     int fd, result;
-    DIR *t;
+    struct dfs_file *file = RT_NULL;
 
-    t = NULL;
+    if (!name || dfs_file_isdir(name) != 0)
+    {
+        rt_set_errno(-RT_ERROR);
+        return RT_NULL;
+    }
 
-    /* allocate a fd */
     fd = fd_new();
-    if (fd == -1)
+    if (fd >= 0)
     {
-        rt_set_errno(-ENOMEM);
-
-        return NULL;
+        file = fd_get(fd);
+    }
+    else
+    {
+        rt_set_errno(-RT_ERROR);
+        return RT_NULL;
     }
-    d = fd_get(fd);
 
-    result = dfs_file_open(d, name, O_RDONLY | O_DIRECTORY);
+    result = dfs_file_open(file, name, O_RDONLY | O_DIRECTORY, 0);
     if (result >= 0)
     {
         /* open successfully */
         t = (DIR *) rt_malloc(sizeof(DIR));
         if (t == NULL)
         {
-            dfs_file_close(d);
+            dfs_file_close(file);
             fd_release(fd);
         }
         else
@@ -701,7 +815,6 @@ DIR *opendir(const char *name)
         return t;
     }
 
-    /* open failed */
     fd_release(fd);
     rt_set_errno(result);
 
@@ -721,40 +834,49 @@ RTM_EXPORT(opendir);
 struct dirent *readdir(DIR *d)
 {
     int result;
-    struct dfs_file *fd;
+    struct dirent *dirent = NULL;
 
-    fd = fd_get(d->fd);
-    if (fd == NULL)
+    if (d == NULL)
     {
         rt_set_errno(-EBADF);
         return NULL;
     }
 
-    if (d->num)
+    do
     {
-        struct dirent *dirent_ptr;
-        dirent_ptr = (struct dirent *)&d->buf[d->cur];
-        d->cur += dirent_ptr->d_reclen;
-    }
+        if (d->num)
+        {
+            struct dirent *dirent_ptr;
+            dirent_ptr = (struct dirent *)&d->buf[d->cur];
+            d->cur += dirent_ptr->d_reclen;
+        }
 
-    if (!d->num || d->cur >= d->num)
-    {
-        /* get a new entry */
-        result = dfs_file_getdents(fd,
-                                   (struct dirent *)d->buf,
-                                   sizeof(d->buf) - 1);
-        if (result <= 0)
+        if (!d->num || d->cur >= d->num)
         {
-            rt_set_errno(result);
+            /* get a new entry */
+            result = dfs_file_getdents(fd_get(d->fd),
+                                       (struct dirent *)d->buf,
+                                       sizeof(d->buf) - 1);
+            if (result <= 0)
+            {
+                rt_set_errno(result);
 
-            return NULL;
+                return NULL;
+            }
+
+            d->num = result;
+            d->cur = 0; /* current entry index */
         }
 
-        d->num = result;
-        d->cur = 0; /* current entry index */
-    }
+        dirent = (struct dirent *)(d->buf + d->cur);
+        if (rt_strcmp(".", dirent->d_name) != 0 &&
+            rt_strcmp("..", dirent->d_name) != 0)
+        {
+            break;
+        }
+    } while (dirent);
 
-    return (struct dirent *)(d->buf + d->cur);
+    return dirent;
 }
 RTM_EXPORT(readdir);
 
@@ -768,18 +890,24 @@ RTM_EXPORT(readdir);
  */
 long telldir(DIR *d)
 {
-    struct dfs_file *fd;
+    struct dfs_file *file;
     long result;
 
-    fd = fd_get(d->fd);
-    if (fd == NULL)
+    if (d == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
+    file = fd_get(d->fd);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
         return 0;
     }
 
-    result = fd->pos - d->num + d->cur;
+    result = file->fpos - d->num + d->cur;
 
     return result;
 }
@@ -794,19 +922,39 @@ RTM_EXPORT(telldir);
  */
 void seekdir(DIR *d, long offset)
 {
-    struct dfs_file *fd;
+    struct dfs_file *file;
+
+    if (d == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return;
+    }
 
-    fd = fd_get(d->fd);
-    if (fd == NULL)
+    file = fd_get(d->fd);
+    if (file == NULL)
     {
         rt_set_errno(-EBADF);
 
-        return ;
+        return;
     }
 
-    /* seek to the offset position of directory */
-    if (dfs_file_lseek(fd, offset) >= 0)
-        d->num = d->cur = 0;
+    if (d && d->fd > 0)
+    {
+        if (file->fpos > offset)
+        {
+            /* seek to the offset position of directory */
+            if (dfs_file_lseek(fd_get(d->fd), 0, SEEK_SET) >= 0)
+                d->num = d->cur = 0;
+        }
+
+        while(file->fpos < offset)
+        {
+            if (!readdir(d))
+            {
+                break;
+            }
+        }
+    }
 }
 RTM_EXPORT(seekdir);
 
@@ -818,19 +966,12 @@ RTM_EXPORT(seekdir);
  */
 void rewinddir(DIR *d)
 {
-    struct dfs_file *fd;
-
-    fd = fd_get(d->fd);
-    if (fd == NULL)
+    if (d && d->fd > 0)
     {
-        rt_set_errno(-EBADF);
-
-        return ;
+        /* seek to the beginning of directory */
+        if (dfs_file_lseek(fd_get(d->fd), 0, SEEK_SET) >= 0)
+            d->num = d->cur = 0;
     }
-
-    /* seek to the beginning of directory */
-    if (dfs_file_lseek(fd, 0) >= 0)
-        d->num = d->cur = 0;
 }
 RTM_EXPORT(rewinddir);
 
@@ -845,21 +986,22 @@ RTM_EXPORT(rewinddir);
 int closedir(DIR *d)
 {
     int result;
-    struct dfs_file *fd;
+    struct dfs_file *file;
 
-    fd = fd_get(d->fd);
-    if (fd == NULL)
+    if (d == NULL)
     {
         rt_set_errno(-EBADF);
-
         return -1;
     }
 
-    result = dfs_file_close(fd);
-    fd_release(d->fd);
-
-    rt_free(d);
+    file = fd_get(d->fd);
+    if (file == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
 
+    result = dfs_file_close(file);
     if (result < 0)
     {
         rt_set_errno(result);
@@ -867,7 +1009,12 @@ int closedir(DIR *d)
         return -1;
     }
     else
-        return 0;
+    {
+        fd_release(d->fd);
+        rt_free(d);
+    }
+
+    return 0;
 }
 RTM_EXPORT(closedir);
 
@@ -893,7 +1040,8 @@ int chdir(const char *path)
 #endif
         dfs_unlock();
 
-        return 0;
+        rt_set_errno(-ENOTDIR);
+        return -1;
     }
 
     if (strlen(path) > DFS_PATH_MAX)
@@ -955,12 +1103,52 @@ FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory);
  */
 int access(const char *path, int amode)
 {
+    int fd, ret = -1, flags = 0;
     struct stat sb;
-    if (stat(path, &sb) < 0)
-        return -1; /* already sets errno */
+
+    if (path == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return -1;
+    }
+
+    if (amode == F_OK)
+    {
+        if (stat(path, &sb) < 0)
+            return -1; /* already sets errno */
+        else
+            return 0;
+    }
 
     /* ignore R_OK,W_OK,X_OK condition */
-    return 0;
+    if (dfs_file_isdir(path) == 0)
+    {
+        flags |= O_DIRECTORY;
+    }
+
+    if (amode & R_OK)
+    {
+        flags |= O_RDONLY;
+    }
+
+    if (amode & W_OK)
+    {
+        flags |= O_WRONLY;
+    }
+
+    if (amode & X_OK)
+    {
+        flags |= O_EXEC;
+    }
+
+    fd = open(path, flags, 0);
+    if (fd >= 0)
+    {
+        ret = 0;
+        close(fd);
+    }
+
+    return ret;
 }
 /**
  * this function is a POSIX compliant version, which will set current
@@ -970,6 +1158,12 @@ int access(const char *path, int amode)
  */
 void setcwd(char *buf)
 {
+    if (buf == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return;
+    }
+
 #ifdef DFS_USING_WORKDIR
     dfs_lock();
 #ifdef RT_USING_SMART
@@ -997,6 +1191,12 @@ RTM_EXPORT(setcwd);
  */
 char *getcwd(char *buf, size_t size)
 {
+    if (buf == NULL)
+    {
+        rt_set_errno(-EBADF);
+        return NULL;
+    }
+
 #ifdef DFS_USING_WORKDIR
     char *dir_buf = RT_NULL;
 

+ 19 - 0
components/dfs/dfs_v2/src/dfs_private.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef DFS_PRIVATE_H__
+#define DFS_PRIVATE_H__
+
+#include <dfs.h>
+
+#define NO_WORKING_DIR  "system does not support working directory\n"
+
+extern char working_directory[];
+
+#endif

+ 134 - 0
components/dfs/dfs_v2/src/dfs_vnode.c

@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-05-05     Bernard      Implement vnode in dfs v2.0
+ */
+
+#include <dfs_file.h>
+#include <dfs_mnt.h>
+
+#define DBG_TAG    "DFS.vnode"
+#define DBG_LVL    DBG_WARNING
+#include <rtdbg.h>
+
+int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops)
+{
+    if (vnode)
+    {
+        rt_memset(vnode, 0, sizeof(struct dfs_vnode));
+
+        vnode->type = type;
+        rt_atomic_store(&(vnode->ref_count), 1);
+        vnode->mnt = RT_NULL;
+        vnode->fops = fops;
+    }
+
+    return 0;
+}
+
+struct dfs_vnode *dfs_vnode_create(void)
+{
+    struct dfs_vnode *vnode = rt_calloc(1, sizeof(struct dfs_vnode));
+    if (!vnode)
+    {
+        LOG_E("create a vnode failed.");
+        return RT_NULL;
+    }
+
+    rt_atomic_store(&(vnode->ref_count), 1);
+
+    LOG_I("create a vnode: %p", vnode);
+
+    return vnode;
+}
+
+int dfs_vnode_destroy(struct dfs_vnode* vnode)
+{
+    rt_err_t ret = RT_EOK;
+
+    if (vnode)
+    {
+        ret = dfs_file_lock();
+        if (ret == RT_EOK)
+        {
+            if (rt_atomic_load(&(vnode->ref_count)) == 1)
+            {
+                LOG_I("free a vnode: %p", vnode);
+
+                if (vnode->mnt)
+                {
+                    DLOG(msg, "vnode", vnode->mnt->fs_ops->name, DLOG_MSG, "fs_ops->free_vnode");
+                    vnode->mnt->fs_ops->free_vnode(vnode);
+                }
+                else
+                {
+                    DLOG(msg, "vnode", "vnode", DLOG_MSG, "destroy vnode(mnt=NULL)");
+                }
+
+                dfs_file_unlock();
+
+                rt_free(vnode);
+            }
+            else
+            {
+                dfs_file_unlock();
+            }
+        }
+    }
+
+    return 0;
+}
+
+struct dfs_vnode *dfs_vnode_ref(struct dfs_vnode *vnode)
+{
+    if (vnode)
+    {
+        rt_atomic_add(&(vnode->ref_count), 1);
+
+        DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
+    }
+
+    return vnode;
+}
+
+void dfs_vnode_unref(struct dfs_vnode *vnode)
+{
+    rt_err_t ret = RT_EOK;
+
+    if (vnode)
+    {
+        ret = dfs_file_lock();
+        if (ret == RT_EOK)
+        {
+            rt_atomic_sub(&(vnode->ref_count), 1);
+            DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
+
+            if (rt_atomic_load(&(vnode->ref_count)) == 0)
+            {
+                LOG_I("free a vnode: %p", vnode);
+                DLOG(msg, "vnode", "vnode", DLOG_MSG, "free vnode, ref_count=0");
+
+                if (vnode->mnt)
+                {
+                    DLOG(msg, "vnode", vnode->mnt->fs_ops->name, DLOG_MSG, "fs_ops->free_vnode");
+                    vnode->mnt->fs_ops->free_vnode(vnode);
+                }
+
+                dfs_file_unlock();
+
+                rt_free(vnode);
+            }
+            else
+            {
+                dfs_file_unlock();
+                DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
+            }
+        }
+    }
+
+    return;
+}

+ 14 - 9
components/drivers/ipc/pipe.c

@@ -200,7 +200,11 @@ static int pipe_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
  *           When the return value is 0, it means O_NONBLOCK is enabled and there is no thread that has the pipe open for writing.
  *           When the return value is -EAGAIN, it means there are no data to be read.
  */
+#ifdef RT_USING_DFS_V2
+static int pipe_fops_read(struct dfs_file *fd, void *buf, size_t count, off_t *pos)
+#else
 static int pipe_fops_read(struct dfs_file *fd, void *buf, size_t count)
+#endif
 {
     int len = 0;
     rt_pipe_t *pipe;
@@ -254,7 +258,11 @@ out:
  *           When the return value is -EAGAIN, it means O_NONBLOCK is enabled and there are no space to be written.
  *           When the return value is -EPIPE, it means there is no thread that has the pipe open for reading.
  */
+#ifdef RT_USING_DFS_V2
+static int pipe_fops_write(struct dfs_file *fd, const void *buf, size_t count, off_t *pos)
+#else
 static int pipe_fops_write(struct dfs_file *fd, const void *buf, size_t count)
+#endif
 {
     int len;
     rt_pipe_t *pipe;
@@ -369,15 +377,12 @@ static int pipe_fops_poll(struct dfs_file *fd, rt_pollreq_t *req)
 
 static const struct dfs_file_ops pipe_fops =
 {
-    pipe_fops_open,
-    pipe_fops_close,
-    pipe_fops_ioctl,
-    pipe_fops_read,
-    pipe_fops_write,
-    RT_NULL,
-    RT_NULL,
-    RT_NULL,
-    pipe_fops_poll,
+    .open  = pipe_fops_open,
+    .close = pipe_fops_close,
+    .ioctl = pipe_fops_ioctl,
+    .read  = pipe_fops_read,
+    .write = pipe_fops_write,
+    .poll  = pipe_fops_poll,
 };
 #endif /* defined(RT_USING_POSIX_DEVIO) && defined(RT_USING_POSIX_PIPE) */
 

+ 14 - 9
components/drivers/serial/serial.c

@@ -135,7 +135,11 @@ static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
     return rt_device_control(device, cmd, args);
 }
 
+#ifdef RT_USING_DFS_V2
+static int serial_fops_read(struct dfs_file *fd, void *buf, size_t count, off_t *pos)
+#else
 static int serial_fops_read(struct dfs_file *fd, void *buf, size_t count)
+#endif
 {
     int size = 0;
     rt_device_t device;
@@ -169,7 +173,11 @@ static int serial_fops_read(struct dfs_file *fd, void *buf, size_t count)
     return size;
 }
 
+#ifdef RT_USING_DFS_V2
+static int serial_fops_write(struct dfs_file *fd, const void *buf, size_t count, off_t *pos)
+#else
 static int serial_fops_write(struct dfs_file *fd, const void *buf, size_t count)
+#endif
 {
     rt_device_t device;
 
@@ -211,15 +219,12 @@ static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req)
 
 static const struct dfs_file_ops _serial_fops =
 {
-    serial_fops_open,
-    serial_fops_close,
-    serial_fops_ioctl,
-    serial_fops_read,
-    serial_fops_write,
-    RT_NULL, /* flush */
-    RT_NULL, /* lseek */
-    RT_NULL, /* getdents */
-    serial_fops_poll,
+    .open   = serial_fops_open,
+    .close  = serial_fops_close,
+    .ioctl  = serial_fops_ioctl,
+    .read   = serial_fops_read,
+    .write  = serial_fops_write,
+    .poll   = serial_fops_poll,
 };
 #endif /* RT_USING_POSIX_STDIO */
 

+ 15 - 10
components/drivers/tty/tty.c

@@ -338,7 +338,11 @@ static int tty_ioctl(struct dfs_file *fd, int cmd, void *args)
     return ret;
 }
 
+#ifdef RT_USING_DFS_V2
+static int tty_read(struct dfs_file *fd, void *buf, size_t count, off_t *pos)
+#else
 static int tty_read(struct dfs_file *fd, void *buf, size_t count)
+#endif
 {
     int ret = 0;
     struct tty_struct *tty = RT_NULL;
@@ -355,7 +359,11 @@ static int tty_read(struct dfs_file *fd, void *buf, size_t count)
     return ret;
 }
 
-static int tty_write(struct dfs_file *fd, const void *buf, size_t count)
+#ifdef RT_USING_DFS_V2
+static int tty_write(struct dfs_file *fd, const void *buf, size_t count, off_t *pos)
+#else
+static int tty_write(struct dfs_file *fd, const void *buf, size_t count )
+#endif
 {
     int ret = 0;
     struct tty_struct *tty = RT_NULL;
@@ -391,15 +399,12 @@ static int tty_poll(struct dfs_file *fd, struct rt_pollreq *req)
 
 static const struct dfs_file_ops tty_fops =
 {
-    tty_open,
-    tty_close,
-    tty_ioctl,
-    tty_read,
-    tty_write,
-    RT_NULL, /* flush */
-    RT_NULL, /* lseek */
-    RT_NULL, /* getdents */
-    tty_poll,
+    .open   = tty_open,
+    .close  = tty_close,
+    .ioctl  = tty_ioctl,
+    .read   = tty_read,
+    .write  = tty_write,
+    .poll   = tty_poll,
 };
 
 const struct dfs_file_ops *tty_get_fops(void)

+ 14 - 2
components/finsh/msh.c

@@ -677,9 +677,21 @@ void msh_auto_complete_path(char *path)
             if (multi == 1)
             {
                 struct stat buffer = {0};
-                if ((stat(path, &buffer) == 0) && (S_ISDIR(buffer.st_mode)))
+                if ((stat(path, &buffer) == 0))
                 {
-                    strcat(path, "/");
+                    if (S_ISDIR(buffer.st_mode))
+                    {
+                        strcat(path, "/");
+                    }
+                    else if (S_ISLNK(buffer.st_mode))
+                    {
+                        DIR *dir = opendir(path);
+                        if (dir)
+                        {
+                            closedir(dir);
+                            strcat(path, "/");
+                        }
+                    }
                 }
             }
         }

+ 359 - 7
components/finsh/msh_file.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -18,6 +18,9 @@
 #include <dfs_file.h>
 #include <unistd.h>
 #include <fcntl.h>
+#ifdef RT_USING_DFS_V2
+#include <dfs_mnt.h>
+#endif
 
 static int msh_readline(int fd, char *line_buf, int size)
 {
@@ -170,6 +173,46 @@ static int cmd_ls(int argc, char **argv)
 }
 MSH_CMD_EXPORT_ALIAS(cmd_ls, ls, List information about the FILEs.);
 
+#ifdef RT_USING_DFS_V2
+static int cmd_ln(int argc, char **argv)
+{
+    if (argc < 3)
+    {
+        rt_kprintf("Usage: ln target link_name\n");
+        rt_kprintf("Make symbolic link between files.\n");
+    }
+    else
+    {
+        for(int i = 0; i + 3 <= argc; i ++)
+        {
+            dfs_file_symlink(argv[1], argv[2 + i]);
+        }
+    }
+
+    return 0;
+}
+MSH_CMD_EXPORT_ALIAS(cmd_ln, ln, Make symbolic link between files);
+
+static int cmd_link(int argc, char **argv)
+{
+    if (argc < 3)
+    {
+        rt_kprintf("Usage: link target link_name\n");
+        rt_kprintf("Make link between files.\n");
+    }
+    else
+    {
+        for(int i = 0; i + 3 <= argc; i ++)
+        {
+            dfs_file_link(argv[1], argv[2 + i]);
+        }
+    }
+
+    return 0;
+}
+MSH_CMD_EXPORT_ALIAS(cmd_link, link, Make link between files);
+#endif
+
 static int cmd_cp(int argc, char **argv)
 {
     void copy(const char *src, const char *dst);
@@ -301,7 +344,7 @@ static void directory_delete_for_msh(const char *pathname, char f, char v)
                 rt_strcmp("..", dirent->d_name) != 0)
         {
             rt_sprintf(full_path, "%s/%s", pathname, dirent->d_name);
-            if (dirent->d_type == DT_REG)
+            if (dirent->d_type != DT_DIR)
             {
                 if (unlink(full_path) != 0)
                 {
@@ -313,7 +356,7 @@ static void directory_delete_for_msh(const char *pathname, char f, char v)
                     rt_kprintf("removed '%s'\n", full_path);
                 }
             }
-            else if (dirent->d_type == DT_DIR)
+            else
             {
                 directory_delete_for_msh(full_path, f, v);
             }
@@ -321,7 +364,7 @@ static void directory_delete_for_msh(const char *pathname, char f, char v)
     }
     closedir(dir);
     rt_free(full_path);
-    if (unlink(pathname) != 0)
+    if (rmdir(pathname) != 0)
     {
         if (f == 0)
             rt_kprintf("cannot remove '%s'\n", pathname);
@@ -373,7 +416,11 @@ static int cmd_rm(int argc, char **argv)
     for (index = 1; index < argc; index ++)
     {
         struct stat s;
+#ifdef RT_USING_DFS_V2
+        if (dfs_file_lstat(argv[index], &s) == 0)
+#else
         if (stat(argv[index], &s) == 0)
+#endif
         {
             if (s.st_mode & S_IFDIR)
             {
@@ -479,8 +526,6 @@ static int cmd_mkfs(int argc, char **argv)
 }
 MSH_CMD_EXPORT_ALIAS(cmd_mkfs, mkfs, format disk with file system);
 
-extern struct dfs_filesystem filesystem_table[];
-
 /*
  * If no argument is specified, display the mount history;
  * If there are 3 arguments, mount the filesystem.
@@ -493,6 +538,14 @@ static int cmd_mount(int argc, char **argv)
 {
     if (argc == 1)
     {
+#ifdef RT_USING_DFS_V2
+        /* display the mount history */
+        rt_kprintf("filesystem  device  mountpoint  refcount\n");
+        rt_kprintf("----------  ------  ----------  --------\n");
+
+        dfs_mnt_list(RT_NULL);
+#else
+        extern struct dfs_filesystem filesystem_table[];
         struct dfs_filesystem *iter;
 
         /* display the mount history */
@@ -507,6 +560,7 @@ static int cmd_mount(int argc, char **argv)
                            iter->ops->name, iter->dev_id->parent.name, iter->path);
             }
         }
+#endif
         return 0;
     }
     else if (argc == 4)
@@ -586,9 +640,11 @@ static int cmd_umount(int argc, char **argv)
 }
 MSH_CMD_EXPORT_ALIAS(cmd_umount, umount, Unmount the mountpoint);
 
-extern int df(const char *path);
 static int cmd_df(int argc, char **argv)
 {
+#ifndef RT_USING_DFS_V2
+    extern int df(const char *path);
+
     if (argc != 2)
     {
         df("/");
@@ -604,6 +660,7 @@ static int cmd_df(int argc, char **argv)
             df(argv[1]);
         }
     }
+#endif
 
     return 0;
 }
@@ -742,4 +799,299 @@ static int cmd_tail(int argc, char **argv)
 }
 MSH_CMD_EXPORT_ALIAS(cmd_tail, tail, print the last N - lines data of the given file);
 
+#ifdef RT_USING_DFS_V2
+
+static void directory_setattr(const char *pathname, struct dfs_attr *attr, char f, char v)
+{
+    DIR *dir = NULL;
+    struct dirent *dirent = NULL;
+    char *full_path;
+
+    if (pathname == RT_NULL)
+        return;
+
+    full_path = (char *)rt_malloc(DFS_PATH_MAX);
+    if (full_path == RT_NULL)
+        return;
+
+    dir = opendir(pathname);
+    if (dir == RT_NULL)
+    {
+        if (f == 0)
+        {
+            rt_kprintf("cannot open '%s'\n", pathname);
+        }
+        rt_free(full_path);
+        return;
+    }
+
+    while (1)
+    {
+        dirent = readdir(dir);
+        if (dirent == RT_NULL)
+            break;
+        if (rt_strcmp(".", dirent->d_name) != 0 &&
+            rt_strcmp("..", dirent->d_name) != 0)
+        {
+            rt_sprintf(full_path, "%s/%s", pathname, dirent->d_name);
+            if (dirent->d_type == DT_REG)
+            {
+                if (dfs_file_setattr(full_path, attr) != 0)
+                {
+                    if (f == 0)
+                    {
+                        rt_kprintf("'%s' setattr failed, no such file or directory\n", full_path);
+                    }
+                }
+                else if (v)
+                {
+                    rt_kprintf("'%s' setattr 0x%X\n", full_path, attr->st_mode);
+                }
+            }
+            else if (dirent->d_type == DT_DIR)
+            {
+                directory_setattr(full_path, attr, f, v);
+            }
+        }
+    }
+    closedir(dir);
+    rt_free(full_path);
+    if (dfs_file_setattr(pathname, attr) != 0)
+    {
+        if (f == 0)
+        {
+            rt_kprintf("'%s' setattr failed, no such file or directory\n", pathname);
+        }
+    }
+    else if (v)
+    {
+        rt_kprintf("'%s' setattr 0x%X\n", pathname, attr->st_mode);
+    }
+}
+
+static int cmd_chmod(int argc, char **argv)
+{
+    if (argc < 3)
+    {
+        rt_kprintf("Usage: chmod [OPTION]... MODE[,MODE]... FILE...\n");
+        rt_kprintf("  chmod [-f|v|r] [u|g|o|a][+/-/=][r|w|x] file...\n");
+        rt_kprintf("  -f  suppress most error messages\n");
+        rt_kprintf("  -v  output a diagnostic for every file processed\n");
+        rt_kprintf("  -r  change files and directories recursively\n");
+        rt_kprintf("Change the mode of each FILE to MODE.\n");
+    }
+    else
+    {
+        int argv_c = 1;
+        char f = 0, r = 0, v = 0;
+
+        if (argv[argv_c][0] == '-')
+        {
+            for (int i = 1; argv[argv_c][i]; i++)
+            {
+                switch (argv[argv_c][i])
+                {
+                case 'f':
+                    f = 1;
+                    break;
+                case 'r':
+                    r = 1;
+                    break;
+                case 'v':
+                    v = 1;
+                    break;
+                default:
+                    rt_kprintf("Error: Bad option: %c\n", argv[argv_c][i]);
+                    return 0;
+                }
+            }
+            argv_c++;
+        }
+
+        if (argc - argv_c > 1)
+        {
+            int U = 1, G = 2, O = 4, ALL = 7;
+            int off[5] = {0, 6, 3, 0, 0};
+            int ADD = 1, SUB = 2, SET = 4;
+            int R = 4, W = 2, X = 1;
+            int user[3] = {0}, change[3] = {0}, mode[3] = {0};
+            struct dfs_attr attr;
+            char *cmd = argv[argv_c];
+            int index = 0, num = 0;
+
+            while (cmd[index] != '\0')
+            {
+                switch (cmd[index])
+                {
+                case 'u':
+                    user[num] |= U;
+                    break;
+                case 'g':
+                    user[num] |= G;
+                    break;
+                case 'o':
+                    user[num] |= O;
+                    break;
+                case 'a':
+                    user[num] |= ALL;
+                    break;
+                case ',':
+                    if (num < 2)
+                        num++;
+                    break;
+                }
+                index++;
+            }
+
+            index = 0;
+            num = 0;
+
+            while (cmd[index] != '\0')
+            {
+                switch (cmd[index])
+                {
+                case '+':
+                    change[num] = ADD;
+                    break;
+                case '-':
+                    change[num] = SUB;
+                    break;
+                case '=':
+                    change[num] = SET;
+                    break;
+                case ',':
+                    if (num < 2)
+                        num++;
+                    break;
+                }
+                index++;
+            }
+
+            index = 0;
+            num = 0;
+
+            while (cmd[index] != '\0')
+            {
+                switch (cmd[index])
+                {
+                case 'r':
+                    mode[num] |= R;
+                    break;
+                case 'w':
+                    mode[num] |= W;
+                    break;
+                case 'x':
+                    mode[num] |= X;
+                    break;
+                case ',':
+                    if (num < 2)
+                        num++;
+                    break;
+                }
+                index++;
+            }
+
+            attr.st_mode = 0;
+
+            for (int i = 0; i <= num; i++)
+            {
+                if (change[i] == ADD)
+                {
+                    if (user[i] & U)
+                    {
+                        attr.st_mode |= mode[i] << off[user[i] & U];
+                    }
+
+                    if (user[i] & G)
+                    {
+                        attr.st_mode |= mode[i] << off[user[i] & G];
+                    }
+
+                    if (user[i] & O)
+                    {
+                        attr.st_mode |= mode[i] << off[user[i] & O];
+                    }
+                }
+                else if (change[i] == SUB)
+                {
+                    if (user[i] & U)
+                    {
+                        attr.st_mode &= ~(mode[i] << off[user[i] & U]);
+                    }
+
+                    if (user[i] & G)
+                    {
+                        attr.st_mode &= ~(mode[i] << off[user[i] & G]);
+                    }
+
+                    if (user[i] & O)
+                    {
+                        attr.st_mode &= ~(mode[i] << off[user[i] & O]);
+                    }
+                }
+                else if (change[i] == SET)
+                {
+                    if (user[i] & U)
+                    {
+                        attr.st_mode &= ~(7 << off[user[i] & U]);
+                        attr.st_mode |= mode[i] << off[user[i] & U];
+                    }
+
+                    if (user[i] & G)
+                    {
+                        attr.st_mode &= ~(7 << off[user[i] & G]);
+                        attr.st_mode |= mode[i] << off[user[i] & G];
+                    }
+
+                    if (user[i] & O)
+                    {
+                        attr.st_mode &= ~(7 << off[user[i] & O]);
+                        attr.st_mode |= mode[i] << off[user[i] & O];
+                    }
+                }
+            }
+
+            argv_c++;
+
+            for (int i = argv_c; i < argc; i++)
+            {
+                if (r)
+                {
+                    struct stat s;
+                    if (stat(argv[i], &s) == 0)
+                    {
+                        if (s.st_mode & S_IFDIR)
+                        {
+                            directory_setattr(argv[i], &attr, f, v);
+                        }
+                        else if (f == 0)
+                        {
+                            rt_kprintf("'%s' is not a directory\n", argv[i]);
+                        }
+                    }
+                }
+                else
+                {
+                    if (dfs_file_setattr(argv[i], &attr) != 0)
+                    {
+                        if (f == 0)
+                        {
+                            rt_kprintf("'%s' setattr failed, no such file or directory\n", argv[i]);
+                        }
+                    }
+                    else if (v)
+                    {
+                        rt_kprintf("'%s' setattr 0x%X\n", argv[i], attr.st_mode);
+                    }
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+MSH_CMD_EXPORT_ALIAS(cmd_chmod, chmod, Change the file attr.);
+
+#endif
+
 #endif /* defined(RT_USING_FINSH) && defined(DFS_USING_POSIX) */

+ 7 - 3
components/libc/compilers/common/include/dirent.h

@@ -26,10 +26,14 @@ extern "C" {
 #define FT_SOCKET       1   /* socket file  */
 #define FT_DIRECTORY    2   /* directory    */
 #define FT_USER         3   /* user defined */
+#define FT_DEVICE       4   /* device */
+#define FT_SYMLINK      5   /* symbol link */
 
 #define DT_UNKNOWN      0x00
-#define DT_REG          0x01
-#define DT_DIR          0x02
+#define DT_FIFO         0x01
+#define DT_SYMLINK      0x03
+#define DT_DIR          0x04
+#define DT_REG          0x08
 
 #ifndef HAVE_DIR_STRUCTURE
 #define HAVE_DIR_STRUCTURE
@@ -61,7 +65,7 @@ DIR           *opendir(const char *);
 struct dirent *readdir(DIR *);
 int            readdir_r(DIR *, struct dirent *, struct dirent **);
 void           rewinddir(DIR *);
-void           seekdir(DIR *, long int);
+void           seekdir(DIR *, long);
 long           telldir(DIR *);
 
 #ifdef __cplusplus

+ 23 - 1
components/libc/compilers/common/include/unistd.h

@@ -1,10 +1,32 @@
 /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
+ * 2023/06/08     Bernard      Add macro definition for `#pragma once`
  */
 
+#ifndef UNISTD_H__
+#define UNISTD_H__
+
 #include "sys/unistd.h"
+
+#ifndef F_OK
+#define	F_OK	0
+#endif
+
+#ifndef R_OK
+#define	R_OK	4
+#endif
+
+#ifndef W_OK
+#define	W_OK	2
+#endif
+
+#ifndef X_OK
+#define	X_OK	1
+#endif
+
+#endif /* UNISTD_H__ */

+ 14 - 2
components/libc/compilers/newlib/fcntl.h

@@ -13,12 +13,24 @@
 
 #include <sys/_default_fcntl.h>
 
-#ifndef O_DIRECTORY
-#define O_DIRECTORY 0x200000
+#ifndef O_EXEC
+#define O_EXEC      0x400000
+#endif
+
+#ifndef O_TMPFILE
+#define O_TMPFILE   0x800000
 #endif
 
 #ifndef O_BINARY
 #define O_BINARY 0x10000
 #endif
 
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW 0x100000
+#endif
+
+#ifndef O_DIRECTORY
+#define O_DIRECTORY 0x200000
+#endif
+
 #endif

+ 3 - 3
components/libc/posix/io/stdio/libc.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2023, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -31,7 +31,7 @@ int libc_system_init(void)
     if (dev_console)
     {
         int fd = libc_stdio_set_console(dev_console->parent.name, O_RDWR);
-        if (fd < 0) 
+        if (fd < 0)
         {
             return -1;
         }
@@ -43,7 +43,7 @@ int libc_system_init(void)
 #endif /* RT_USING_POSIX_STDIO */
     return 0;
 }
-INIT_COMPONENT_EXPORT(libc_system_init);
+INIT_APP_EXPORT(libc_system_init);
 
 #if defined(RT_USING_POSIX_STDIO) && defined(RT_USING_NEWLIBC)
 

+ 10 - 22
components/lwp/lwp_ipc.c

@@ -381,6 +381,7 @@ static int _ipc_msg_fd_new(void *file)
 {
     int fd;
     struct dfs_file *d;
+    struct dfs_vnode *vnode = (struct dfs_vnode *)file;
 
     fd = fd_new();
     if (fd < 0)
@@ -395,7 +396,11 @@ static int _ipc_msg_fd_new(void *file)
         return -1;
     }
 
-    d->vnode = (struct dfs_vnode *)file;
+#ifdef RT_USING_DFS_V2
+    d->fops = vnode->fops;
+#endif
+
+    d->vnode = vnode;
     d->flags = O_RDWR; /* set flags as read and write */
 
     return fd;
@@ -946,15 +951,8 @@ static int channel_fops_close(struct dfs_file *file)
 
 static const struct dfs_file_ops channel_fops =
 {
-    NULL,    /* open     */
-    channel_fops_close,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,    /* lseek    */
-    NULL,    /* getdents */
-    channel_fops_poll,
+    .close = channel_fops_close,    /* close */
+    .poll = channel_fops_poll,      /* poll */
 };
 
 int lwp_channel_open(int fdt_type, const char *name, int flags)
@@ -980,18 +978,8 @@ int lwp_channel_open(int fdt_type, const char *name, int flags)
     ch = rt_raw_channel_open(name, flags);
     if (ch)
     {
-        rt_memset(d->vnode, 0, sizeof(struct dfs_vnode));
-        rt_list_init(&d->vnode->list);
-        d->vnode->type = FT_USER;
-        d->vnode->path = NULL;
-        d->vnode->fullpath = NULL;
-
-        d->vnode->fops = &channel_fops;
-
-        d->flags = O_RDWR; /* set flags as read and write */
-        d->vnode->size = 0;
-        d->pos = 0;
-        d->vnode->ref_count = 1;
+        /* initialize vnode */
+        dfs_vnode_init(d->vnode, FT_USER, &channel_fops);
 
         /* set socket to the data of dfs_file */
         d->vnode->data = (void *)ch;

+ 70 - 4
components/lwp/lwp_syscall.c

@@ -40,6 +40,9 @@
 #include <poll.h>
 #include <sys/select.h>
 #include <dfs_file.h>
+#ifdef RT_USING_DFS_V2
+#include <dfs_dentry.h>
+#endif
 #include <unistd.h>
 #include <stdio.h> /* rename() */
 #include <sys/stat.h>
@@ -482,6 +485,7 @@ sysret_t sys_open(const char *name, int flag, ...)
     int ret = -1;
     rt_size_t len = 0;
     char *kname = RT_NULL;
+    mode_t mode = 0;
 
     if (!lwp_user_accessable((void *)name, 1))
     {
@@ -500,8 +504,16 @@ sysret_t sys_open(const char *name, int flag, ...)
         return -ENOMEM;
     }
 
+    if ((flag & O_CREAT) || (flag & O_TMPFILE) == O_TMPFILE)
+    {
+        va_list ap;
+        va_start(ap, flag);
+        mode = va_arg(ap, mode_t);
+        va_end(ap);
+    }
+
     lwp_get_from_user(kname, (void *)name, len + 1);
-    ret = open(kname, flag, 0);
+    ret = open(kname, flag, mode);
     if (ret < 0)
     {
         ret = GET_ERRNO();
@@ -511,11 +523,23 @@ sysret_t sys_open(const char *name, int flag, ...)
 
     return ret;
 #else
+    int ret;
+    mode_t mode = 0;
+
     if (!lwp_user_accessable((void *)name, 1))
     {
         return -EFAULT;
     }
-    int ret = open(name, flag, 0);
+
+    if ((flag & O_CREAT) || (flag & O_TMPFILE) == O_TMPFILE)
+    {
+        va_list ap;
+        va_start(ap, flag);
+        mode = va_arg(ap, mode_t);
+        va_end(ap);
+    }
+
+    ret = open(name, flag, mode);
     return (ret < 0 ? GET_ERRNO() : ret);
 #endif
 }
@@ -3803,10 +3827,10 @@ sysret_t sys_rmdir(const char *path)
     {
         return -EFAULT;
     }
-    err = unlink(path);
+    err = rmdir(path);
     return (err < 0 ? GET_ERRNO() : err);
 #else
-    int ret = unlink(path);
+    int ret = rmdir(path);
     return (ret < 0 ? GET_ERRNO() : ret);
 #endif
 }
@@ -4294,7 +4318,28 @@ ssize_t sys_readlink(char* path, char *buf, size_t bufsz)
         }
         else
         {
+#ifdef RT_USING_DFS_V2
+            char *link_fn = (char *)rt_malloc(DFS_PATH_MAX);
+            if (link_fn)
+            {
+                err = dfs_file_readlink(copy_path, link_fn, DFS_PATH_MAX);
+                if (err > 0)
+                {
+                    rtn = lwp_put_to_user(buf, link_fn, bufsz > err ? err : bufsz - 1);
+                }
+                else
+                {
+                    rtn = -EIO;
+                }
+                rt_free(link_fn);
+            }
+            else
+            {
+                rtn = -ENOMEM;
+            }
+#else
             rtn = lwp_put_to_user(buf, copy_path, copy_len);
+#endif
         }
         rt_free(copy_path);
         return rtn;
@@ -4315,6 +4360,26 @@ ssize_t sys_readlink(char* path, char *buf, size_t bufsz)
         return -EBADF;
     }
 
+#ifdef RT_USING_DFS_V2
+    {
+        char *fullpath = dfs_dentry_full_path(d->dentry);
+        if (fullpath)
+        {
+            copy_len = strlen(fullpath);
+            if (copy_len > bufsz)
+            {
+                copy_len = bufsz;
+            }
+
+            bufsz = lwp_put_to_user(buf, fullpath, copy_len);
+            rt_free(fullpath);
+        }
+        else
+        {
+            bufsz = 0;
+        }
+    }
+#else
     copy_len = strlen(d->vnode->fullpath);
     if (copy_len > bufsz)
     {
@@ -4322,6 +4387,7 @@ ssize_t sys_readlink(char* path, char *buf, size_t bufsz)
     }
 
     bufsz = lwp_put_to_user(buf, d->vnode->fullpath, copy_len);
+#endif
 
     return bufsz;
 }

+ 16 - 9
components/net/sal/dfs_net/dfs_net.c

@@ -46,7 +46,11 @@ static int dfs_net_ioctl(struct dfs_file* file, int cmd, void* args)
     return ret;
 }
 
+#ifdef RT_USING_DFS_V2
+static int dfs_net_read(struct dfs_file* file, void *buf, size_t count, off_t *pos)
+#else
 static int dfs_net_read(struct dfs_file* file, void *buf, size_t count)
+#endif
 {
     int ret;
     int socket = (int)(size_t)file->vnode->data;
@@ -57,10 +61,15 @@ static int dfs_net_read(struct dfs_file* file, void *buf, size_t count)
         ret = rt_get_errno();
         return (ret > 0) ? (-ret) : ret;
     }
+
     return ret;
 }
 
+#ifdef RT_USING_DFS_V2
+static int dfs_net_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
+#else
 static int dfs_net_write(struct dfs_file *file, const void *buf, size_t count)
+#endif
 {
     int ret;
     int socket = (int)(size_t)file->vnode->data;
@@ -71,8 +80,10 @@ static int dfs_net_write(struct dfs_file *file, const void *buf, size_t count)
         ret = rt_get_errno();
         return (ret > 0) ? (-ret) : ret;
     }
+
     return ret;
 }
+
 static int dfs_net_close(struct dfs_file* file)
 {
     int socket;
@@ -95,15 +106,11 @@ static int dfs_net_poll(struct dfs_file *file, struct rt_pollreq *req)
 
 const struct dfs_file_ops _net_fops =
 {
-    NULL,    /* open     */
-    dfs_net_close,
-    dfs_net_ioctl,
-    dfs_net_read,
-    dfs_net_write,
-    NULL,
-    NULL,    /* lseek    */
-    NULL,    /* getdents */
-    dfs_net_poll,
+    .close = dfs_net_close,
+    .ioctl = dfs_net_ioctl,
+    .read  = dfs_net_read,
+    .write = dfs_net_write,
+    .poll  = dfs_net_poll,
 };
 
 const struct dfs_file_ops *dfs_net_get_fops(void)

+ 10 - 22
components/net/sal/socket/net_sockets.c

@@ -40,6 +40,9 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
         d = fd_get(fd);
         if(d)
         {
+#ifdef RT_USING_DFS_V2
+            d->fops = dfs_net_get_fops();
+#endif
             /* this is a socket fd */
             d->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode));
             if (!d->vnode)
@@ -50,16 +53,7 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
                 return -1;
             }
             rt_memset(d->vnode, 0, sizeof(struct dfs_vnode));
-            rt_list_init(&d->vnode->list);
-
-            d->vnode->type = FT_SOCKET;
-            d->vnode->path = NULL;
-            d->vnode->fullpath = NULL;
-            d->vnode->ref_count = 1;
-            d->vnode->fops = dfs_net_get_fops();
-            d->flags = O_RDWR; /* set flags as read and write */
-            d->vnode->size = 0;
-            d->pos = 0;
+            dfs_vnode_init(d->vnode, FT_SOCKET, dfs_net_get_fops());
 
             /* set socket to the data of dfs_file */
             d->vnode->data = (void *)(size_t)new_socket;
@@ -238,6 +232,11 @@ int socket(int domain, int type, int protocol)
         return -1;
     }
     d = fd_get(fd);
+
+#ifdef RT_USING_DFS_V2
+    d->fops = dfs_net_get_fops();
+#endif
+
     d->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode));
     if (!d->vnode)
     {
@@ -258,18 +257,7 @@ int socket(int domain, int type, int protocol)
     socket = sal_socket(domain, type, protocol);
     if (socket >= 0)
     {
-        rt_memset(d->vnode, 0, sizeof(struct dfs_vnode));
-        rt_list_init(&d->vnode->list);
-        /* this is a socket fd */
-        d->vnode->type = FT_SOCKET;
-        d->vnode->path = NULL;
-        d->vnode->fullpath = NULL;
-        d->vnode->ref_count = 1;
-        d->vnode->fops = dfs_net_get_fops();
-
-        d->flags = O_RDWR; /* set flags as read and write */
-        d->vnode->size = 0;
-        d->pos = 0;
+        dfs_vnode_init(d->vnode, FT_SOCKET, dfs_net_get_fops());
 
         /* set socket to the data of dfs_file */
         d->vnode->data = (void *)(size_t)socket;

部分文件因为文件数量过多而无法显示