From 99e80f8d3311a5222a028165f9d708870a3bb301 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Sat, 10 Jun 2023 21:35:25 +0800 Subject: [PATCH] [dfs] Add DFS v2.0 (#7606) --- components/dfs/Kconfig | 143 +- components/dfs/dfs_v1/Kconfig | 138 - components/dfs/dfs_v1/include/dfs_file.h | 2 + components/dfs/dfs_v1/src/dfs_file.c | 14 + components/dfs/dfs_v2/Kconfig | 35 - components/dfs/dfs_v2/SConscript | 25 +- .../dfs/dfs_v2/filesystems/devfs/devfs.c | 590 +++-- .../dfs/dfs_v2/filesystems/devfs/devfs.h | 4 +- .../dfs/dfs_v2/filesystems/elmfat/dfs_elm.c | 265 +- components/dfs/dfs_v2/filesystems/elmfat/ff.c | 4 +- .../dfs/dfs_v2/filesystems/nfs/SConscript | 13 - .../dfs/dfs_v2/filesystems/nfs/dfs_nfs.c | 1192 --------- .../dfs/dfs_v2/filesystems/nfs/dfs_nfs.h | 15 - components/dfs/dfs_v2/filesystems/nfs/mount.h | 131 - components/dfs/dfs_v2/filesystems/nfs/mount.x | 68 - .../dfs/dfs_v2/filesystems/nfs/mount_clnt.c | 78 - .../dfs/dfs_v2/filesystems/nfs/mount_xdr.c | 142 -- components/dfs/dfs_v2/filesystems/nfs/nfs.h | 1110 -------- components/dfs/dfs_v2/filesystems/nfs/nfs.x | 774 ------ .../dfs/dfs_v2/filesystems/nfs/nfs_auth.c | 172 -- .../dfs/dfs_v2/filesystems/nfs/nfs_clnt.c | 222 -- .../dfs/dfs_v2/filesystems/nfs/nfs_xdr.c | 1622 ------------ .../dfs/dfs_v2/filesystems/nfs/rpc/auth.h | 112 - .../dfs_v2/filesystems/nfs/rpc/auth_none.c | 135 - .../dfs/dfs_v2/filesystems/nfs/rpc/clnt.h | 330 --- .../dfs_v2/filesystems/nfs/rpc/clnt_generic.c | 95 - .../dfs/dfs_v2/filesystems/nfs/rpc/clnt_udp.c | 406 --- .../dfs/dfs_v2/filesystems/nfs/rpc/pmap.c | 62 - .../dfs/dfs_v2/filesystems/nfs/rpc/pmap.h | 66 - .../dfs/dfs_v2/filesystems/nfs/rpc/rpc.h | 62 - .../dfs/dfs_v2/filesystems/nfs/rpc/rpc_msg.h | 203 -- .../dfs/dfs_v2/filesystems/nfs/rpc/rpc_prot.c | 267 -- .../dfs/dfs_v2/filesystems/nfs/rpc/types.h | 89 - .../dfs/dfs_v2/filesystems/nfs/rpc/xdr.c | 784 ------ .../dfs/dfs_v2/filesystems/nfs/rpc/xdr.h | 369 --- .../dfs/dfs_v2/filesystems/nfs/rpc/xdr_mem.c | 172 -- .../dfs/dfs_v2/filesystems/romfs/dfs_romfs.c | 277 +- .../dfs/dfs_v2/filesystems/romfs/romfs.c | 3 +- .../dfs_v2/filesystems/skeleton/skeleton.c | 1 - .../dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c | 406 +-- components/dfs/dfs_v2/include/dfs.h | 63 +- components/dfs/dfs_v2/include/dfs_dentry.h | 64 + components/dfs/dfs_v2/include/dfs_file.h | 160 +- components/dfs/dfs_v2/include/dfs_fs.h | 127 +- components/dfs/dfs_v2/include/dfs_mnt.h | 65 + components/dfs/dfs_v2/include/dfs_posix.h | 32 + components/dfs/dfs_v2/include/dfs_private.h | 28 - components/dfs/dfs_v2/src/dfs.c | 781 +++--- components/dfs/dfs_v2/src/dfs_dentry.c | 368 +++ components/dfs/dfs_v2/src/dfs_file.c | 2250 ++++++++++++----- components/dfs/dfs_v2/src/dfs_fs.c | 926 +++---- components/dfs/dfs_v2/src/dfs_mnt.c | 386 +++ components/dfs/dfs_v2/src/dfs_posix.c | 570 +++-- components/dfs/dfs_v2/src/dfs_private.h | 19 + components/dfs/dfs_v2/src/dfs_vnode.c | 134 + components/drivers/ipc/pipe.c | 23 +- components/drivers/serial/serial.c | 23 +- components/drivers/tty/tty.c | 25 +- components/finsh/msh.c | 16 +- components/finsh/msh_file.c | 366 ++- .../libc/compilers/common/include/dirent.h | 10 +- .../libc/compilers/common/include/unistd.h | 24 +- components/libc/compilers/newlib/fcntl.h | 16 +- components/libc/posix/io/stdio/libc.c | 6 +- components/lwp/lwp_ipc.c | 32 +- components/lwp/lwp_syscall.c | 74 +- components/net/sal/dfs_net/dfs_net.c | 25 +- components/net/sal/socket/net_sockets.c | 32 +- 68 files changed, 5563 insertions(+), 11680 deletions(-) delete mode 100644 components/dfs/dfs_v1/Kconfig delete mode 100644 components/dfs/dfs_v2/Kconfig delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/SConscript delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/mount.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/mount.x delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/mount_clnt.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/mount_xdr.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/nfs.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/nfs.x delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/nfs_auth.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/nfs_clnt.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/nfs_xdr.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/auth.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/auth_none.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/clnt.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_generic.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_udp.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/rpc.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_msg.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_prot.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/types.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.c delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.h delete mode 100644 components/dfs/dfs_v2/filesystems/nfs/rpc/xdr_mem.c create mode 100644 components/dfs/dfs_v2/include/dfs_dentry.h create mode 100644 components/dfs/dfs_v2/include/dfs_mnt.h create mode 100644 components/dfs/dfs_v2/include/dfs_posix.h delete mode 100644 components/dfs/dfs_v2/include/dfs_private.h create mode 100644 components/dfs/dfs_v2/src/dfs_dentry.c create mode 100644 components/dfs/dfs_v2/src/dfs_mnt.c create mode 100644 components/dfs/dfs_v2/src/dfs_private.h create mode 100644 components/dfs/dfs_v2/src/dfs_vnode.c diff --git a/components/dfs/Kconfig b/components/dfs/Kconfig index c33078b1b1..f7b386c8f5 100644 --- a/components/dfs/Kconfig +++ b/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 diff --git a/components/dfs/dfs_v1/Kconfig b/components/dfs/dfs_v1/Kconfig deleted file mode 100644 index 0d003339f5..0000000000 --- a/components/dfs/dfs_v1/Kconfig +++ /dev/null @@ -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 diff --git a/components/dfs/dfs_v1/include/dfs_file.h b/components/dfs/dfs_v1/include/dfs_file.h index b818614365..971089f21b 100644 --- a/components/dfs/dfs_v1/include/dfs_file.h +++ b/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); diff --git a/components/dfs/dfs_v1/src/dfs_file.c b/components/dfs/dfs_v1/src/dfs_file.c index bc9ac3ccdc..6dbec6e129 100644 --- a/components/dfs/dfs_v1/src/dfs_file.c +++ b/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) { diff --git a/components/dfs/dfs_v2/Kconfig b/components/dfs/dfs_v2/Kconfig deleted file mode 100644 index a673432c1b..0000000000 --- a/components/dfs/dfs_v2/Kconfig +++ /dev/null @@ -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 diff --git a/components/dfs/dfs_v2/SConscript b/components/dfs/dfs_v2/SConscript index c691f91da4..a8f2811a18 100644 --- a/components/dfs/dfs_v2/SConscript +++ b/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_POSIX'): + src += ['src/poll.c', 'src/select.c'] + +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'): - src = ['src/dfs.c', 'src/dfs_file.c', 'src/dfs_fs.c'] - - if GetDepend('DFS_USING_POSIX'): - src += ['src/dfs_posix.c'] - - group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH) - # search in the file system implementation list = os.listdir(cwd) diff --git a/components/dfs/dfs_v2/filesystems/devfs/devfs.c b/components/dfs/dfs_v2/filesystems/devfs/devfs.c index 0779a594d0..0353a20527 100644 --- a/components/dfs/dfs_v2/filesystems/devfs/devfs.c +++ b/components/dfs/dfs_v2/filesystems/devfs/devfs.c @@ -8,38 +8,252 @@ * 2018-02-11 Bernard Ignore O_CREAT flag in open. */ #include -#include +#include #include +#include +#include + #include #include #include +#include +#include #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_device_fs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) +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, +}; + +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_devfs_umount(struct dfs_mnt *mnt) { return RT_EOK; } -int dfs_device_fs_statfs(struct dfs_filesystem *fs, struct statfs *buf) +int dfs_devfs_statfs(struct dfs_mnt *mnt, struct statfs *buf) { - buf->f_bsize = 512; - buf->f_blocks = 2048 * 64; // 64M - buf->f_bfree = buf->f_blocks; - buf->f_bavail = buf->f_bfree; + 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_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')) - { - struct device_dirent *root_dirent; - - root_dirent = (struct device_dirent *)file->vnode->data; - RT_ASSERT(root_dirent != RT_NULL); - - /* release dirent */ - rt_free(root_dirent); - return RT_EOK; - } - - /* 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; -} - -int dfs_device_fs_open(struct dfs_file *file) -{ - rt_err_t result; + rt_err_t result = RT_EOK; rt_device_t device; - RT_ASSERT(file->vnode->ref_count > 0); - if (file->vnode->ref_count > 1) + RT_ASSERT(file != RT_NULL); + + if (!S_ISDIR(file->vnode->mode)) { - file->pos = 0; - return 0; + /* get device handler */ + device = (rt_device_t)file->vnode->data; + RT_ASSERT(device != RT_NULL); + + /* close device handler */ + result = rt_device_close(device); } + + return result; +} + +int dfs_devfs_open(struct dfs_file *file) +{ + rt_err_t result = RT_EOK; + /* open root directory */ - if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0') && - (file->flags & O_DIRECTORY)) + if ((file->dentry->pathname[0] == '/' && file->dentry->pathname[1] == '\0') || + (S_ISDIR(file->vnode->mode))) { - 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(); - - /* 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) - { - 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) - { - /* avoid memory write through */ - if (count == root_dirent->device_count) - { - rt_kprintf("warning: There are newly added devices that are not displayed!"); - break; - } - 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; - + /* re-open the root directory for re-scan devices */ + _devfs_root_dirent_update(file->vnode); return RT_EOK; } -#ifdef RT_USING_DEV_BUS - else if (file->flags & O_CREAT) + else { - 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; - } + rt_device_t device = RT_NULL; + device = (struct rt_device *)file->vnode->data; + if (device) + { #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) + if (device->fops) { - file->vnode->type = FT_DEVICE; - return 0; + /* use device fops */ + file->fops = device->fops; + /* use fops->open */ + if (file->vnode->fops->open) + { + result = file->vnode->fops->open(file); + if (result == RT_EOK || result == -RT_ENOSYS) + { + 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->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')) + int ret = RT_EOK; + const char *path = RT_NULL; + struct dfs_vnode *vnode = RT_NULL; + + if (dentry && dentry->vnode) { - st->st_dev = 0; + path = dentry->pathname; + vnode = dentry->vnode; - 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; - - st->st_size = 0; - st->st_mtime = 0; - - return RT_EOK; - } - else - { - rt_device_t dev_id; - - 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); + diff --git a/components/dfs/dfs_v2/filesystems/devfs/devfs.h b/components/dfs/dfs_v2/filesystems/devfs/devfs.h index 30a9482a35..acaae11f2f 100644 --- a/components/dfs/dfs_v2/filesystems/devfs/devfs.h +++ b/components/dfs/dfs_v2/filesystems/devfs/devfs.h @@ -10,8 +10,6 @@ #ifndef __DEVICE_FS_H__ #define __DEVICE_FS_H__ -#include - -int devfs_init(void); +int dfs_devfs_init(void); #endif diff --git a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c index a2a6258f36..589bf22f62 100644 --- a/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/dfs_v2/filesystems/elmfat/dfs_elm.c @@ -26,8 +26,11 @@ /* ELM FatFs provide a DIR struct */ #define HAVE_DIR_STRUCTURE +#include #include +#include #include +#include #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, - dfs_elm_unlink, - dfs_elm_stat, - dfs_elm_rename, + .unlink = dfs_elm_unlink, + .stat = dfs_elm_stat, + .rename = 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; } diff --git a/components/dfs/dfs_v2/filesystems/elmfat/ff.c b/components/dfs/dfs_v2/filesystems/elmfat/ff.c index 815c3d2b83..286c39481b 100644 --- a/components/dfs/dfs_v2/filesystems/elmfat/ff.c +++ b/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); } diff --git a/components/dfs/dfs_v2/filesystems/nfs/SConscript b/components/dfs/dfs_v2/filesystems/nfs/SConscript deleted file mode 100644 index f830dfc754..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/SConscript +++ /dev/null @@ -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') diff --git a/components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.c b/components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.c deleted file mode 100644 index 9adc5b6c42..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.c +++ /dev/null @@ -1,1192 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include -#include -#include -#include -#include - -#include - -#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); - diff --git a/components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.h b/components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.h deleted file mode 100644 index 460027410d..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/dfs_nfs.h +++ /dev/null @@ -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 diff --git a/components/dfs/dfs_v2/filesystems/nfs/mount.h b/components/dfs/dfs_v2/filesystems/nfs/mount.h deleted file mode 100644 index ff0cec76fb..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/mount.h +++ /dev/null @@ -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 - -#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 */ diff --git a/components/dfs/dfs_v2/filesystems/nfs/mount.x b/components/dfs/dfs_v2/filesystems/nfs/mount.x deleted file mode 100644 index 8e11a55507..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/mount.x +++ /dev/null @@ -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; -typedef string dirpath; -typedef string name; - -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; diff --git a/components/dfs/dfs_v2/filesystems/nfs/mount_clnt.c b/components/dfs/dfs_v2/filesystems/nfs/mount_clnt.c deleted file mode 100644 index 9e05f7ee61..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/mount_clnt.c +++ /dev/null @@ -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 /* 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)); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/mount_xdr.c b/components/dfs/dfs_v2/filesystems/nfs/mount_xdr.c deleted file mode 100644 index e1e797000f..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/mount_xdr.c +++ /dev/null @@ -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); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/nfs.h b/components/dfs/dfs_v2/filesystems/nfs/nfs.h deleted file mode 100644 index 8c417ec7f4..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/nfs.h +++ /dev/null @@ -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 - -#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 */ diff --git a/components/dfs/dfs_v2/filesystems/nfs/nfs.x b/components/dfs/dfs_v2/filesystems/nfs/nfs.x deleted file mode 100644 index c17c52fce4..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/nfs.x +++ /dev/null @@ -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; -}; - -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; diff --git a/components/dfs/dfs_v2/filesystems/nfs/nfs_auth.c b/components/dfs/dfs_v2/filesystems/nfs/nfs_auth.c deleted file mode 100644 index 4b6be8d498..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/nfs_auth.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include -#include -#include - -#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) -{ -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/nfs_clnt.c b/components/dfs/dfs_v2/filesystems/nfs/nfs_clnt.c deleted file mode 100644 index b50cf7ff1d..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/nfs_clnt.c +++ /dev/null @@ -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 /* 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)); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/nfs_xdr.c b/components/dfs/dfs_v2/filesystems/nfs/nfs_xdr.c deleted file mode 100644 index 2662a17df6..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/nfs_xdr.c +++ /dev/null @@ -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); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/auth.h b/components/dfs/dfs_v2/filesystems/nfs/rpc/auth.h deleted file mode 100644 index 0dc947a887..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/auth.h +++ /dev/null @@ -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 - -/* - * 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 diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/auth_none.c b/components/dfs/dfs_v2/filesystems/nfs/rpc/auth_none.c deleted file mode 100644 index 7e22e7d864..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/auth_none.c +++ /dev/null @@ -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 -#include -#include -#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) -{ -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt.h b/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt.h deleted file mode 100644 index 1d27dee359..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt.h +++ /dev/null @@ -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 -#include -#include - -/* - * 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 */ diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_generic.c b/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_generic.c deleted file mode 100644 index bbcd8011ef..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_generic.c +++ /dev/null @@ -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 -#include - -/* - * 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); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_udp.c b/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_udp.c deleted file mode 100644 index 91973631c4..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/clnt_udp.c +++ /dev/null @@ -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 -#include -#include - -/* - * 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); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.c b/components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.c deleted file mode 100644 index afa2583d09..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.c +++ /dev/null @@ -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 - -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, ®s->pm_prog) && - xdr_u_long(xdrs, ®s->pm_vers) && - xdr_u_long(xdrs, ®s->pm_prot)) - return (xdr_u_long(xdrs, ®s->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); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.h b/components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.h deleted file mode 100644 index 3a0305a6b8..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/pmap.h +++ /dev/null @@ -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 - -/* 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 diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc.h b/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc.h deleted file mode 100644 index 12d2477ef6..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc.h +++ /dev/null @@ -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 /* some typedefs */ - -/* external data representation interfaces */ -#include /* generic (de)serializer */ - -#include - -/* Client side (mostly) remote procedure call */ -#include /* generic rpc stuff */ - -/* semi-private protocol headers */ -#include /* protocol for rpc messages */ - -#endif diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_msg.h b/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_msg.h deleted file mode 100644 index 358c3f7903..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_msg.h +++ /dev/null @@ -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 -#include - -/* - * 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 */ diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_prot.c b/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_prot.c deleted file mode 100644 index 61cb6cbc85..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/rpc_prot.c +++ /dev/null @@ -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 - -/* * * * * * * * * * * * * * 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; - } -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/types.h b/components/dfs/dfs_v2/filesystems/nfs/rpc/types.h deleted file mode 100644 index 6afc2279b8..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/types.h +++ /dev/null @@ -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 - */ -#ifndef _RPC_TYPES_H -#define _RPC_TYPES_H 1 - -#include -#include -#include - -#include -#include - -#ifndef RT_USING_MINILIBC -typedef unsigned int u_int; -typedef unsigned char u_char; -typedef unsigned long u_long; -#else -#include -#include -#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 */ diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.c b/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.c deleted file mode 100644 index 7045aef352..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.c +++ /dev/null @@ -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 -#include -#include -#include -#include - -/* - * 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 (tmpx_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)); -} diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.h b/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.h deleted file mode 100644 index d938f0eaa8..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr.h +++ /dev/null @@ -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 - -/* We need FILE. */ -#include - -/* - * 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; - * *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 */ diff --git a/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr_mem.c b/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr_mem.c deleted file mode 100644 index 7bd4737e16..0000000000 --- a/components/dfs/dfs_v2/filesystems/nfs/rpc/xdr_mem.c +++ /dev/null @@ -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 -#include -#include -#include - -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); -} - diff --git a/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c b/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c index 8c80b5690e..4e9502fc10 100644 --- a/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c +++ b/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 #include #include +#include #include +#include #include "dfs_romfs.h" +#include +#include -int dfs_romfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) +#include + +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) +static int dfs_romfs_close(struct dfs_file *file) { - if (offset <= file->vnode->size) - { - file->pos = offset; - return file->pos; - } - - return -EIO; -} - -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 = dentry->vnode->mode; + st->st_size = dentry->vnode->size; + st->st_nlink = dentry->vnode->nlink; + st->st_mtime = 0; + + dfs_file_unlock(); } - st->st_dev = 0; - st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; - - if (dirent->type == ROMFS_DIRENT_DIR) - { - st->st_mode &= ~S_IFREG; - st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - } - - 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 = + +static const struct dfs_filesystem_ops _romfs_ops = { - "rom", - DFS_FS_FLAG_DEFAULT, - &_rom_fops, + .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 +}; - dfs_romfs_mount, - dfs_romfs_unmount, - NULL, - NULL, - - NULL, - dfs_romfs_stat, - NULL, +static struct dfs_filesystem_type _romfs = +{ + .fs_ops = &_romfs_ops, }; int dfs_romfs_init(void) { /* register rom file system */ dfs_register(&_romfs); + return 0; } INIT_COMPONENT_EXPORT(dfs_romfs_init); - diff --git a/components/dfs/dfs_v2/filesystems/romfs/romfs.c b/components/dfs/dfs_v2/filesystems/romfs/romfs.c index 0ca17766c8..91465116b3 100644 --- a/components/dfs/dfs_v2/filesystems/romfs/romfs.c +++ b/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]) }; - diff --git a/components/dfs/dfs_v2/filesystems/skeleton/skeleton.c b/components/dfs/dfs_v2/filesystems/skeleton/skeleton.c index 5c35cd1ffc..af2c871dfc 100644 --- a/components/dfs/dfs_v2/filesystems/skeleton/skeleton.c +++ b/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); - diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c index f8a4a8bc58..512c2ecdf2 100644 --- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c +++ b/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 #include #include +#include #include +#include #ifdef RT_USING_SMART #include @@ -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]; + struct tmpfs_file *d_file; - 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); - - 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 = +static const struct dfs_filesystem_ops _tmpfs_ops = { - "tmp", - DFS_FS_FLAG_DEFAULT, - &_tmp_fops, + .name = "tmp", + .flags = DFS_FS_FLAG_DEFAULT, + .default_fops = &_tmp_fops, - dfs_tmpfs_mount, - dfs_tmpfs_unmount, - NULL, /* mkfs */ - dfs_tmpfs_statfs, + .mount = dfs_tmpfs_mount, + .umount = dfs_tmpfs_unmount, + .statfs = dfs_tmpfs_statfs, - dfs_tmpfs_unlink, - dfs_tmpfs_stat, - dfs_tmpfs_rename, + .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 struct dfs_filesystem_type _tmpfs = +{ + .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); diff --git a/components/dfs/dfs_v2/include/dfs.h b/components/dfs/dfs_v2/include/dfs.h index 450100fc32..1ebd8b608f 100644 --- a/components/dfs/dfs_v2/include/dfs.h +++ b/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 #include #include -#include +#include "../../libc/compilers/common/include/dirent.h" #include #include #include #include +#include +#include #include -#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 diff --git a/components/dfs/dfs_v2/include/dfs_dentry.h b/components/dfs/dfs_v2/include/dfs_dentry.h new file mode 100644 index 0000000000..190e277b0b --- /dev/null +++ b/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__*/ diff --git a/components/dfs/dfs_v2/include/dfs_file.h b/components/dfs/dfs_v2/include/dfs_file.h index b818614365..7dbe366fe9 100644 --- a/components/dfs/dfs_v2/include/dfs_file.h +++ b/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 #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 (*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 (*poll) (struct dfs_file *fd, 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 diff --git a/components/dfs/dfs_v2/include/dfs_fs.h b/components/dfs/dfs_v2/include/dfs_fs.h index adfed8d787..5146d42f7d 100644 --- a/components/dfs/dfs_v2/include/dfs_fs.h +++ b/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 -#include -#include +#include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/* Pre-declaration */ -struct dfs_filesystem; -struct dfs_file; - -/* File system operations */ -struct dfs_filesystem_ops -{ - char *name; - uint32_t flags; /* flags for file system operations */ - - /* operations for file */ - const struct dfs_file_ops *fops; - - /* mount and unmount file system */ - int (*mount) (struct dfs_filesystem *fs, unsigned long rwflag, const void *data); - int (*unmount) (struct dfs_filesystem *fs); - - /* 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 (*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); -}; - -/* Mounted file system */ -struct dfs_filesystem -{ - rt_device_t dev_id; /* Attached device */ - - char *path; /* File system mount point */ - const struct dfs_filesystem_ops *ops; /* Operations for file system type */ - - void *data; /* Specific file system data */ -}; - /* file system partition table */ struct dfs_partition { - uint8_t type; /* file system type */ - off_t offset; /* partition start offset */ - size_t size; /* partition size */ + uint8_t type; /* file system type */ + off_t offset; /* partition start offset */ + size_t size; /* partition size */ rt_sem_t lock; }; -/* mount table */ -struct dfs_mount_tbl +struct dfs_attr { - const char *device_name; - const char *path; - const char *filesystemtype; - unsigned long rwflag; - const void *data; + mode_t st_mode; }; -int dfs_register(const struct dfs_filesystem_ops *ops); -struct dfs_filesystem *dfs_filesystem_lookup(const char *path); +struct dfs_mnt; +struct dfs_dentry; +struct dfs_vnode; + +struct statfs; + +struct dfs_filesystem_ops +{ + const char *name; + uint32_t flags; +#define FS_NEED_DEVICE 0x1 + + const struct dfs_file_ops *default_fops; + + int (*mount)(struct dfs_mnt *mnt, unsigned long rwflag, const void *data); + int (*umount)(struct dfs_mnt *mnt); + + int (*mkfs)(rt_device_t devid, const char *fs_name); + + 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*/ + + int (*rename)(struct dfs_dentry *old_dentry, struct dfs_dentry *new_dentry); + int (*stat)(struct dfs_dentry *dentry, struct stat *buf); + + int (*statfs)(struct dfs_mnt *mnt, struct statfs *buf); + + int (*setattr) (struct dfs_dentry *dentry, struct dfs_attr *attr); + + 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); +}; + +struct dfs_filesystem_type +{ + const struct dfs_filesystem_ops *fs_ops; + struct dfs_filesystem_type *next; +}; + +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 } diff --git a/components/dfs/dfs_v2/include/dfs_mnt.h b/components/dfs/dfs_v2/include/dfs_mnt.h new file mode 100644 index 0000000000..c917520438 --- /dev/null +++ b/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 +#include + +#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 diff --git a/components/dfs/dfs_v2/include/dfs_posix.h b/components/dfs/dfs_v2/include/dfs_posix.h new file mode 100644 index 0000000000..71a6098c89 --- /dev/null +++ b/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 +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/dfs/dfs_v2/include/dfs_private.h b/components/dfs/dfs_v2/include/dfs_private.h deleted file mode 100644 index e602c21730..0000000000 --- a/components/dfs/dfs_v2/include/dfs_private.h +++ /dev/null @@ -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 - -#define DBG_TAG "DFS" -#define DBG_LVL DBG_INFO -#include - -#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 diff --git a/components/dfs/dfs_v2/src/dfs.c b/components/dfs/dfs_v2/src/dfs.c index 5487b1c012..c181930fcc 100644 --- a/components/dfs/dfs_v2/src/dfs.c +++ b/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,106 +12,38 @@ #include #include +#include #include +#include + +#include + #include "dfs_private.h" + +#define DBG_TAG "DFS" +#define DBG_LVL DBG_INFO +#include + #ifdef RT_USING_SMART #include #endif -#ifdef RT_USING_POSIX_STDIO -#include -#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 - * @{ - */ - -/** - * this function will initialize device file system. - */ -int dfs_init(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(); - - 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) - { - rt_kprintf("Dir /dev/shm mount failed!\n"); - } -#endif -#endif - - init_ok = RT_TRUE; - - return 0; -} -INIT_PREV_EXPORT(dfs_init); +/* 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 lock device file system. * * @note please don't invoke it on ISR. */ -void dfs_lock(void) +rt_err_t dfs_lock(void) { rt_err_t result = -RT_EBUSY; @@ -120,25 +52,7 @@ void dfs_lock(void) result = rt_mutex_take(&fslock, RT_WAITING_FOREVER); } - if (result != RT_EOK) - { - RT_ASSERT(0); - } -} - -void dfs_file_lock(void) -{ - rt_err_t result = -RT_EBUSY; - - while (result == -RT_EBUSY) - { - result = rt_mutex_take(&fdlock, RT_WAITING_FOREVER); - } - - if (result != RT_EOK) - { - RT_ASSERT(0); - } + return result; } /** @@ -151,13 +65,54 @@ void dfs_unlock(void) rt_mutex_release(&fslock); } -#ifdef DFS_USING_POSIX +/** + * @addtogroup DFS + */ + +/*@{*/ + +rt_err_t dfs_file_lock(void) +{ + rt_err_t result = -RT_EBUSY; + + while (result == -RT_EBUSY) + { + result = rt_mutex_take(&fdlock, RT_WAITING_FOREVER); + } + + return result; +} void dfs_file_unlock(void) { rt_mutex_release(&fdlock); } +/** + * this function will initialize device file system. + */ +int dfs_init(void) +{ + static rt_bool_t init_ok = RT_FALSE; + if (init_ok) + { + LOG_E("DFS was already initialized.\n"); + return 0; + } + + /* create device filesystem lock */ + rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO); + rt_mutex_init(&fdlock, "fdlock", RT_IPC_FLAG_FIFO); + + /* 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) { int nr; @@ -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,51 +280,6 @@ struct dfs_file *fd_get(int fd) * * This function will put the file descriptor. */ -void fdt_fd_release(struct dfs_fdtable* fdt, int fd) -{ - struct dfs_file *fd_slot = NULL; - - RT_ASSERT(fdt != NULL); - - dfs_file_lock(); - - if ((fd < 0) || (fd >= fdt->maxfd)) - { - dfs_file_unlock(); - return; - } - - fd_slot = fdt->fds[fd]; - if (fd_slot == NULL) - { - dfs_file_unlock(); - return; - } - fdt->fds[fd] = NULL; - - /* check fd */ - RT_ASSERT(fd_slot->magic == DFS_FD_MAGIC); - - fd_slot->ref_count--; - - /* clear this fd entry */ - if (fd_slot->ref_count == 0) - { - struct dfs_vnode *vnode = fd_slot->vnode; - if (vnode) - { - vnode->ref_count--; - if(vnode->ref_count == 0) - { - rt_free(vnode); - fd_slot->vnode = RT_NULL; - } - } - rt_free(fd_slot); - } - dfs_file_unlock(); -} - void fd_release(int fd) { struct dfs_fdtable *fdt; @@ -378,7 +288,135 @@ void fd_release(int fd) fdt_fd_release(fdt, fd); } -rt_err_t sys_dup(int oldfd) +void fdt_fd_release(struct dfs_fdtable *fdt, int fd) +{ + if (fd < fdt->maxfd) + { + 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; + } +} + +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 */ + rt_atomic_add(&(file->ref_count), 1); + fdt->fds[fd] = file; + retfd = fd; + +exit: + dfs_file_unlock(); + return retfd; +} + +/** + * 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; +} + +int dfs_dup(int oldfd, int startfd) { int newfd = -1; struct dfs_fdtable *fdt = NULL; @@ -395,79 +433,32 @@ rt_err_t sys_dup(int oldfd) goto exit; } /* get a new fd */ - newfd = fd_slot_alloc(fdt, DFS_STDIO_OFFSET); + newfd = fd_slot_alloc(fdt, startfd); if (newfd >= 0) { fdt->fds[newfd] = fdt->fds[oldfd]; + /* inc ref_count */ - fdt->fds[newfd]->ref_count++; + rt_atomic_add(&(fdt->fds[newfd]->ref_count), 1); } exit: dfs_file_unlock(); return newfd; } -#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. - */ -int fd_is_open(const char *pathname) +#ifdef RT_USING_SMART +sysret_t sys_dup(int oldfd) +#else +int sys_dup(int oldfd) +#endif { - char *fullpath; - unsigned int index; - struct dfs_filesystem *fs; - struct dfs_file *fd; - struct dfs_fdtable *fdt; + int newfd = dfs_dup(oldfd, DFS_STDIO_OFFSET); - 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); - - return -1; - } - - /* get file path name under mounted file system */ - if (fs->path[0] == '/' && fs->path[1] == '\0') - mountpath = fullpath; - else - mountpath = fullpath + strlen(fs->path); - - dfs_lock(); - - for (index = 0; index < fdt->maxfd; index++) - { - fd = fdt->fds[index]; - if (fd == NULL || fd->vnode->fops == NULL || fd->vnode->path == NULL) continue; - - if (fd->vnode->fs == fs && strcmp(fd->vnode->path, mountpath) == 0) - { - /* found file in file descriptor table */ - rt_free(fullpath); - dfs_unlock(); - - return 0; - } - } - dfs_unlock(); - - rt_free(fullpath); - } - - return -1; +#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 int list_fd(void) { int index; @@ -824,101 +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); - } - else - { - rt_kprintf("\n"); - } - } - } - dfs_unlock(); - - return 0; -} - -#ifdef RT_USING_SMART -static int lsofp(int pid) -{ - 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++) - { - struct dfs_file *fd = fd_table->fds[index]; - - if (fd && fd->vnode->fops) - { - 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 - { - 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); + rt_kprintf("%s%s\n", file->dentry->mnt->fullpath, file->dentry->pathname); } else { @@ -930,45 +726,66 @@ static int lsofp(int pid) return 0; } +MSH_CMD_EXPORT(list_fd, list file descriptor); -int lsof(int argc, char *argv[]) +int dfs_fd_dump(int argc, char** argv) { - rt_kprintf("PID fd type fd-ref magic vnode vnode/data addr path \n"); + int index; - if (argc == 1) + dfs_file_lock(); + for (index = 0; index < _fdtab.maxfd; index++) { - 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++) + struct dfs_file *file = _fdtab.fds[index]; + if (file) { - struct rt_lwp *lwp = (struct rt_lwp *)pids[index].data; - - if (lwp) + char* fullpath = dfs_dentry_full_path(file->dentry); + if (fullpath) { - list = &lwp->t_grp; - for (node = list->next; node != list; node = node->next) - { - lsofp(lwp_to_pid(lwp)); - } + printf("[%d] - %s, ref_count %zd\n", index, + fullpath, (size_t)rt_atomic_load(&(file->ref_count))); + rt_free(fullpath); + } + else + { + printf("[%d] - %s, ref_count %zd\n", index, + file->dentry->pathname, (size_t)rt_atomic_load(&(file->ref_count))); } } } - else if (argc == 3) + dfs_file_unlock(); + + return 0; +} +MSH_CMD_EXPORT_ALIAS(dfs_fd_dump, fd_dump, fd dump); + +#ifdef PKG_USING_DLOG + +int dfs_dlog(int argc, char** argv) +{ + if (argc == 2) { - if (argv[1][0] == '-' && argv[1][1] == 'p') + if (strcmp(argv[1], "on") == 0) { - int pid = atoi(argv[2]); - lsofp(pid); + 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 (strcmp(argv[1], "off") == 0) + { + 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 /**@}*/ diff --git a/components/dfs/dfs_v2/src/dfs_dentry.c b/components/dfs/dfs_v2/src/dfs_dentry.c new file mode 100644 index 0000000000..5d62a6dc76 --- /dev/null +++ b/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 + +#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 + +#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); diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c index fd97976cf1..ca917ba9b7 100644 --- a/components/dfs/dfs_v2/src/dfs_file.c +++ b/components/dfs/dfs_v2/src/dfs_file.c @@ -1,743 +1,1538 @@ /* - * 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. - * 2011-12-08 Bernard Merges rename patch from iamcacy. - * 2015-05-27 Bernard Fix the fd clear issue. - * 2019-01-24 Bernard Remove file repeatedly open check. + * 2023-05-05 Bernard Implement file APIs in dfs v2.0 */ +#include "errno.h" +#include "fcntl.h" + #include -#include -#include -#include -#define DFS_FNODE_HASH_NR 128 +#include "dfs_file.h" +#include "dfs_dentry.h" +#include "dfs_fs.h" +#include "dfs_mnt.h" +#include "dfs_private.h" -struct dfs_vnode_mgr +#define DBG_TAG "DFS.file" +#define DBG_LVL DBG_WARNING +#include + + +#define MAX_RW_COUNT 0xfffc0000 + +/* + * rw_verify_area doesn't like huge counts. We limit + * them to something that fits in "int" so that others + * won't have to do range checks all the time. + */ +ssize_t rw_verify_area(struct dfs_file *file, off_t *ppos, size_t count) { - struct rt_mutex lock; - rt_list_t head[DFS_FNODE_HASH_NR]; -}; + off_t pos; + ssize_t retval = -EINVAL; -static struct dfs_vnode_mgr dfs_fm; - -void dfs_fm_lock(void) -{ - rt_mutex_take(&dfs_fm.lock, RT_WAITING_FOREVER); -} - -void dfs_fm_unlock(void) -{ - rt_mutex_release(&dfs_fm.lock); -} - -void dfs_vnode_mgr_init(void) -{ - int i = 0; - - rt_mutex_init(&dfs_fm.lock, "dfs_mgr", RT_IPC_FLAG_PRIO); - for (i = 0; i < DFS_FNODE_HASH_NR; i++) + if ((size_t)count < 0) + return retval; + pos = *ppos; + if (pos < 0) { - rt_list_init(&dfs_fm.head[i]); + if (count >= -pos) /* both values are in 0..LLONG_MAX */ + return -EOVERFLOW; + } + + return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; +} + +void dfs_file_set_fpos(struct dfs_file *file, off_t fpos) +{ + if (file) + { + rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER); + file->fpos = fpos; + rt_mutex_release(&file->pos_lock); } } -/* BKDR Hash Function */ -static unsigned int bkdr_hash(const char *str) +void dfs_file_init(struct dfs_file *file) { - unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. - unsigned int hash = 0; - - while (*str) + if (file) { - hash = hash * seed + (*str++); + rt_memset(file, 0x00, sizeof(struct dfs_file)); + file->magic = DFS_FD_MAGIC; + rt_mutex_init(&file->pos_lock, "fpos", RT_IPC_FLAG_PRIO); + rt_atomic_store(&(file->ref_count), 1); } - - return (hash % DFS_FNODE_HASH_NR); } -static struct dfs_vnode *dfs_vnode_find(const char *path, rt_list_t **hash_head) +void dfs_file_deinit(struct dfs_file *file) { - struct dfs_vnode *vnode = NULL; - int hash = bkdr_hash(path); - rt_list_t *hh; - - hh = dfs_fm.head[hash].next; - - if (hash_head) + if (file) { - *hash_head = &dfs_fm.head[hash]; + rt_mutex_detach(&file->pos_lock); } +} - while (hh != &dfs_fm.head[hash]) +static void dfs_file_unref(struct dfs_file *file) +{ + rt_err_t ret = RT_EOK; + + ret = dfs_file_lock(); + if (ret == RT_EOK) { - vnode = rt_container_of(hh, struct dfs_vnode, list); - if (rt_strcmp(path, vnode->fullpath) == 0) + if (rt_atomic_load(&(file->ref_count)) == 1) { - /* found */ - return vnode; + /* should release this file */ + if (file->dentry) + { + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry(%s))", file->dentry->pathname); + dfs_dentry_unref(file->dentry); + file->dentry = RT_NULL; + } + else if (file->vnode) + { + if (file->vnode->ref_count > 1) + { + file->vnode->ref_count--; + } + else if (file->vnode->ref_count == 1) + { + rt_free(file->vnode); + file->vnode = RT_NULL; + } + } + + LOG_I("release a file: %p", file); } - hh = hh->next; + + dfs_file_unlock(); } - return NULL; } -/** - * @addtogroup FileApi - * @{ - */ - -/** - * 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. - */ -int dfs_file_is_open(const char *pathname) +struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry) { - char *fullpath = NULL; - struct dfs_vnode *vnode = NULL; int ret = 0; - fullpath = dfs_normalize_path(NULL, pathname); - - dfs_fm_lock(); - vnode = dfs_vnode_find(fullpath, NULL); - if (vnode) + if (dentry && dentry->vnode && dentry->vnode->type == FT_SYMLINK) { - ret = 1; - } - dfs_fm_unlock(); + char *buf = NULL; - rt_free(fullpath); - return ret; + buf = (char *) rt_malloc (DFS_PATH_MAX); + if (buf) + { + do + { + ret = dentry->mnt->fs_ops->readlink(dentry, buf, DFS_PATH_MAX); + if (ret > 0) + { + struct dfs_mnt *mnt = NULL; + + if (buf[0] != '/') + { + char *dir = dfs_dentry_pathname(dentry); + + /* is the relative directory */ + if (dir) + { + char *fullpath = dfs_normalize_path(dir, buf); + if (fullpath) + { + strncpy(buf, fullpath, DFS_PATH_MAX); + + rt_free(fullpath); + } + rt_free(dir); + } + } + + mnt = dfs_mnt_lookup(buf); + if (mnt) + { + struct dfs_dentry *de = dfs_dentry_lookup(mnt, buf, 0); + + /* release the old dentry */ + dfs_dentry_unref(dentry); + dentry = de; + } + } + else + { + break; + } + } while (dentry && dentry->vnode->type == FT_SYMLINK); + } + + rt_free(buf); + } + + return dentry; } +/* + * this function is creat a nolink path. + * + * @param mnt + * @param fullpath + * @param mode 0 middle path nolink; 1 all path nolink. + * + * @return new path. + */ +static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode) +{ + int index = 0; + char *path = RT_NULL; + char link_fn[DFS_PATH_MAX] = {0}; + struct dfs_dentry *dentry = RT_NULL; + + path = (char *)rt_malloc(DFS_PATH_MAX); + if (!path) + { + return path; + } + + if (*mnt && fullpath) + { + int i = 0; + char *fp = fullpath; + + while (*fp != '\0') + { + fp++; + i++; + if (*fp == '/') + { + rt_memcpy(path + index, fp - i, i); + path[index + i] = '\0'; + + dentry = dfs_dentry_lookup(*mnt, path, 0); + if (dentry && dentry->vnode->type == FT_SYMLINK) + { + int ret = -1; + + if ((*mnt)->fs_ops->readlink) + { + ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX); + } + + if (ret > 0) + { + int len = rt_strlen(link_fn); + if (link_fn[0] == '/') + { + rt_memcpy(path, link_fn, len); + index = len; + } + else + { + path[index] = '/'; + index++; + rt_memcpy(path + index, link_fn, len); + index += len; + } + path[index] = '\0'; + *mnt = dfs_mnt_lookup(path); + } + else + { + rt_kprintf("link error: %s\n", path); + } + } + else + { + index += i; + } + dfs_dentry_unref(dentry); + i = 0; + } + } + + if (i) + { + rt_memcpy(path + index, fp - i, i); + path[index + i] = '\0'; + + if (mode) + { + dentry = dfs_dentry_lookup(*mnt, path, 0); + if (dentry && dentry->vnode->type == FT_SYMLINK) + { + int ret = -1; + + if ((*mnt)->fs_ops->readlink) + { + ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX); + } + + if (ret > 0) + { + int len = rt_strlen(link_fn); + if (link_fn[0] == '/') + { + rt_memcpy(path, link_fn, len); + index = len; + } + else + { + path[index] = '/'; + index++; + rt_memcpy(path + index, link_fn, len); + index += len; + } + path[index] = '\0'; + *mnt = dfs_mnt_lookup(path); + } + else + { + rt_kprintf("link error: %s\n", path); + } + } + dfs_dentry_unref(dentry); + } + } + } + else + { + rt_free(path); + path = RT_NULL; + } + + //rt_kprintf("%s: %s => %s\n", __FUNCTION__, fullpath, path); + + return path; +} /** - * this function will open a file which specified by path with specified flags. + * this function will open a file which specified by path with specified oflags. * * @param fd the file descriptor pointer to return the corresponding result. * @param path the specified file path. - * @param flags the flags for open operator. + * @param oflags the oflags for open operator. * * @return 0 on successful, -1 on failed. */ -int dfs_file_open(struct dfs_file *fd, const char *path, int flags) +int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mode) { - struct dfs_filesystem *fs; - char *fullpath; - int result; - struct dfs_vnode *vnode = NULL; - rt_list_t *hash_head; + int ret = -RT_ERROR;; + char *fullpath = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; + int fflags = dfs_fflags(oflags); - /* parameter check */ - if (fd == NULL) - return -EINVAL; - - /* make sure we have an absolute path */ - fullpath = dfs_normalize_path(NULL, path); - if (fullpath == NULL) + if (mode == 0) { - return -ENOMEM; + mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); /* 0666 */ } - LOG_D("open file:%s", fullpath); - - dfs_fm_lock(); - /* vnode find */ - vnode = dfs_vnode_find(fullpath, &hash_head); - if (vnode) + if (file && path) { - vnode->ref_count++; - fd->pos = 0; - fd->vnode = vnode; - dfs_fm_unlock(); - rt_free(fullpath); /* release path */ + fullpath = dfs_normalize_path(NULL, path); + if (fullpath) + { + struct dfs_mnt *mnt = RT_NULL; + + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) + { + char *tmp = dfs_nolink_path(&mnt, fullpath, 0); + if (tmp) + { + rt_free(fullpath); + fullpath = tmp; + } + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, fullpath, oflags); + if (dentry && dentry->vnode->type == FT_SYMLINK) + { + /* it's a symbol link but not follow */ + if (oflags & O_NOFOLLOW) + { + /* no follow symbol link */ + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } + else + { + struct dfs_dentry *target_dentry = RT_NULL; + + /* follow symbol link */ + target_dentry = dfs_file_follow_link(dentry); + if (target_dentry) + { + dentry = target_dentry; + } + } + } + + if (dentry) + { + if (oflags & O_DIRECTORY) + { + if (dentry->vnode->type != FT_DIRECTORY) + { + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } + } + else if (dentry->vnode->type == FT_DIRECTORY) + { + if (fflags & (DFS_F_FWRITE)) + { + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } + else + { + oflags |= O_DIRECTORY; + } + } + } + + if (oflags & O_CREAT) + { + if (dentry) + { + oflags &= ~O_CREAT; + + if (oflags & O_EXCL) + { + oflags &= ~O_EXCL; + /* the dentry already exists */ + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } + } + else + { + /* create file/directory */ + if (mnt->fs_ops->create_vnode) + { + struct dfs_vnode *vnode = RT_NULL; + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_create(%s)", fullpath); + dentry = dfs_dentry_create(mnt, fullpath); + if (dentry) + { + mode &= ~S_IFMT; + DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->create_vnode"); + vnode = mnt->fs_ops->create_vnode(dentry, oflags & O_DIRECTORY ? FT_DIRECTORY:FT_REGULAR, mode); + + if (vnode) + { + /* set vnode */ + dentry->vnode = vnode; /* the refcount of created vnode is 1. no need to reference */ + dfs_dentry_insert(dentry); + } + else + { + DLOG(msg, mnt->fs_ops->name, "dfs_file", DLOG_MSG_RET, "create failed."); + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } + } + } + } + } + + if (dentry) + { + rt_bool_t permission = RT_TRUE; + file->dentry = dentry; + file->vnode = dentry->vnode; + file->fops = dentry->mnt->fs_ops->default_fops; + file->flags = oflags; + + /* check permission */ + if (!(oflags & O_CREAT)) + { + if (fflags & DFS_F_FWRITE) + { + if (!(file->vnode->mode & S_IWUSR)) + { + permission = RT_FALSE; + } + } + + if (fflags & DFS_F_FREAD) + { + if (!(file->vnode->mode & S_IRUSR)) + { + permission = RT_FALSE; + } + } + + if (oflags & O_EXEC) + { + if (!(file->vnode->mode & S_IXUSR)) + { + permission = RT_FALSE; + } + } + } + + if (permission && file->fops->open) + { + DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fops->open(file)"); + ret = file->fops->open(file); + if (ret < 0) + { + LOG_E("open %s failed in file system: %s", path, dentry->mnt->fs_ops->name); + DLOG(msg, mnt->fs_ops->name, "dfs_file", DLOG_MSG_RET, "open failed."); + dfs_file_unref(file); + } + else + { + /* for char/block device */ + if ((S_ISCHR(file->vnode->mode)) || (S_ISBLK(file->vnode->mode))) + { + file->fops = file->vnode->fops; + } + } + } + else + { + DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "no permission or fops->open"); + dfs_file_unref(file); + } + } + else + { + LOG_I("lookup file:%s failed in file system", path); + } + } + + rt_free(fullpath); + } + + if (ret >= 0 && (oflags & O_TRUNC)) + { + /* trunc file */ + if (!(fflags & DFS_F_FWRITE) || file->vnode->type == FT_DIRECTORY) + { + /* truncate on read a only file or a directory */ + DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_unref(file), trunc on RDOnly or directory"); + ret = -RT_ERROR; + } + else + { + if (file->fops->truncate) + { + DLOG(msg, "dfs_file", dentry->mnt->fs_ops->name, DLOG_MSG, "fops->truncate(file, 0)"); + ret = file->fops->truncate(file, 0); + } + } + + if (ret < 0) + { + dfs_file_unref(file); + } + + file->flags &= ~O_TRUNC; + } + } + + return ret; +} + +int dfs_file_close(struct dfs_file *file) +{ + int ret = -RT_ERROR; + + if (file) + { + if (dfs_file_lock() == RT_EOK) + { + rt_atomic_t ref_count = rt_atomic_load(&(file->ref_count)); + + if (ref_count == 1 && file->fops && file->fops->close) + { + DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)"); + ret = file->fops->close(file); + + if (ret == 0) /* close file sucessfully */ + { + DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_unref(file)"); + dfs_file_unref(file); + } + else + { + LOG_W("close file:%s failed on low level file system", file->dentry->pathname); + } + } + else + { + DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_unref(file)"); + dfs_file_unref(file); + ret = 0; + } + dfs_file_unlock(); + } + } + + return ret; +} + +ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len) +{ + ssize_t ret = -EBADF; + + if (file) + { + /* check whether read */ + if (!(dfs_fflags(file->flags) & DFS_F_FREAD)) + { + ret = -EPERM; + } + else if (!file->fops || !file->fops->read) + { + ret = -ENOSYS; + } + else if (file->vnode && file->vnode->type != FT_DIRECTORY) + { + off_t pos; + pos = file->fpos; + + ret = rw_verify_area(file, &pos, len); + if (ret > 0) + { + len = ret; + + ret = file->fops->read(file, buf, len, &pos); + if (ret > 0) + { + dfs_file_set_fpos(file, pos); + } + } + } + } + + return ret; +} + +ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len) +{ + size_t ret = -EBADF; + + if (file) + { + if (!(dfs_fflags(file->flags) & DFS_F_FWRITE)) + { + LOG_W("bad write flags."); + ret = -EBADF; + } + else if (!file->fops || !file->fops->write) + { + LOG_W("no fops write."); + ret = -ENOSYS; + } + else if (file->vnode && file->vnode->type != FT_DIRECTORY) + { + off_t pos; + + pos = file->fpos; + ret = rw_verify_area(file, &pos, len); + if (ret > 0) + { + len = ret; + DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, + "dfs_file_write(fd, buf, %d)", len); + ret = file->fops->write(file, buf, len, &pos); + if (ret > 0) + { + dfs_file_set_fpos(file, pos); + } + } + } + } + + return ret; +} + +int generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence) +{ + off_t foffset; + + if (whence == SEEK_SET) + foffset = offset; + else if (whence == SEEK_CUR) + foffset = file->fpos + offset; + else if (whence == SEEK_END) + foffset = file->vnode->size + offset; + else + return -EINVAL; + + dfs_file_set_fpos(file, foffset); + + return foffset; +} + +off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece) +{ + off_t retval; + + if (!file) + return -EBADF; + + retval = -EINVAL; + if (file->fops->lseek) + { + retval = file->fops->lseek(file, offset, wherece); + if (retval >= 0) + { + dfs_file_set_fpos(file, retval); + } + } + + return retval; +} + +int dfs_file_stat(const char *path, struct stat *buf) +{ + int ret = -ENOENT; + char *fullpath = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; + + fullpath = dfs_normalize_path(NULL, path); + if (fullpath) + { + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) + { + char *tmp = dfs_nolink_path(&mnt, fullpath, 1); + if (tmp) + { + rt_free(fullpath); + fullpath = tmp; + } + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, fullpath, 0); + if (dentry) + { + DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry"); + if (mnt->fs_ops->stat) + { + DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)"); + ret = mnt->fs_ops->stat(dentry, buf); + } + + /* unref dentry */ + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)"); + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } + } + + rt_free(fullpath); + fullpath = RT_NULL; } else { - /* find filesystem */ - fs = dfs_filesystem_lookup(fullpath); - if (fs == NULL) + ret = -ENOMEM; + } + + return ret; +} + +int dfs_file_lstat(const char *path, struct stat *buf) +{ + int ret = -ENOENT; + char *fullpath = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; + + fullpath = dfs_normalize_path(NULL, path); + if (fullpath) + { + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) { - dfs_fm_unlock(); - rt_free(fullpath); /* release path */ - return -ENOENT; + char *tmp = dfs_nolink_path(&mnt, fullpath, 0); + if (tmp) + { + rt_free(fullpath); + fullpath = tmp; + } + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, fullpath, 0); + if (dentry) + { + DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry"); + if (mnt->fs_ops->stat) + { + DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)"); + ret = mnt->fs_ops->stat(dentry, buf); + } + + /* unref dentry */ + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)"); + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } } - vnode = rt_calloc(1, sizeof(struct dfs_vnode)); - if (!vnode) + rt_free(fullpath); + fullpath = RT_NULL; + } + else + { + ret = -ENOMEM; + } + + rt_set_errno(-ret); + + return ret; +} + +int dfs_file_fstat(struct dfs_file *file, struct stat *buf) +{ + size_t ret = -EBADF; + + if (file) + { + if (file->fops && file->fops->ioctl) { - dfs_fm_unlock(); - rt_free(fullpath); /* release path */ - return -ENOMEM; - } - vnode->ref_count = 1; - - LOG_D("open in filesystem:%s", fs->ops->name); - vnode->fs = fs; /* set file system */ - vnode->fops = fs->ops->fops; /* set file ops */ - - /* initialize the fd item */ - vnode->type = FT_REGULAR; - vnode->flags = 0; - - if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH)) - { - if (dfs_subdir(fs->path, fullpath) == NULL) - vnode->path = rt_strdup("/"); - else - vnode->path = rt_strdup(dfs_subdir(fs->path, fullpath)); - LOG_D("Actual file path: %s", vnode->path); + // ret = file->fops->fstat(file, buf); } else { - vnode->path = fullpath; + ret = -ENOSYS; } - vnode->fullpath = fullpath; - - /* specific file system open routine */ - if (vnode->fops->open == NULL) - { - dfs_fm_unlock(); - /* clear fd */ - if (vnode->path != vnode->fullpath) - { - rt_free(vnode->fullpath); - } - rt_free(vnode->path); - rt_free(vnode); - - return -ENOSYS; - } - - fd->pos = 0; - fd->vnode = vnode; - - /* insert vnode to hash */ - rt_list_insert_after(hash_head, &vnode->list); } - - fd->flags = flags; - - if ((result = vnode->fops->open(fd)) < 0) + else { - vnode->ref_count--; - if (vnode->ref_count == 0) - { - /* remove from hash */ - rt_list_remove(&vnode->list); - /* clear fd */ - if (vnode->path != vnode->fullpath) - { - rt_free(vnode->fullpath); - } - rt_free(vnode->path); - fd->vnode = NULL; - rt_free(vnode); - } - - dfs_fm_unlock(); - LOG_D("%s open failed", fullpath); - - return result; + ret = -EBADF; } - fd->flags |= DFS_F_OPEN; - if (flags & O_DIRECTORY) - { - fd->vnode->type = FT_DIRECTORY; - fd->flags |= DFS_F_DIRECTORY; - } - dfs_fm_unlock(); - - LOG_D("open successful"); - return 0; + return ret; } -/** - * this function will close a file descriptor. - * - * @param fd the file descriptor to be closed. - * - * @return 0 on successful, -1 on failed. - */ -int dfs_file_close(struct dfs_file *fd) +int dfs_file_setattr(const char *path, struct dfs_attr *attr) { - struct dfs_vnode *vnode = NULL; - int result = 0; + int ret = -RT_ERROR; + char *fullpath = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; - if (fd == NULL) + fullpath = dfs_normalize_path(NULL, path); + if (fullpath) { - return -ENXIO; - } - - if (fd->ref_count == 1) - { - dfs_fm_lock(); - vnode = fd->vnode; - - if (vnode->ref_count <= 0) + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) { - dfs_fm_unlock(); - return -ENXIO; - } - - if (vnode->fops->close != NULL) - { - result = vnode->fops->close(fd); - } - - /* close fd error, return */ - if (result < 0) - { - dfs_fm_unlock(); - return result; - } - - if (vnode->ref_count == 1) - { - /* remove from hash */ - rt_list_remove(&vnode->list); - fd->vnode = NULL; - - if (vnode->path != vnode->fullpath) + char *tmp = dfs_nolink_path(&mnt, fullpath, 0); + if (tmp) { - rt_free(vnode->fullpath); + rt_free(fullpath); + fullpath = tmp; + } + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, fullpath, 0); + if (dentry) + { + DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry"); + if (mnt->fs_ops->setattr) + { + DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->setattr(dentry, attr)"); + ret = mnt->fs_ops->setattr(dentry, attr); + } + + /* unref dentry */ + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)"); + dfs_dentry_unref(dentry); + dentry = RT_NULL; } - rt_free(vnode->path); - rt_free(vnode); } - dfs_fm_unlock(); + + rt_free(fullpath); + fullpath = RT_NULL; } - return result; + return ret; } -/** - * this function will perform a io control on a file descriptor. - * - * @param fd the file descriptor. - * @param cmd the command to send to file descriptor. - * @param args the argument to send to file descriptor. - * - * @return 0 on successful, -1 on failed. - */ -int dfs_file_ioctl(struct dfs_file *fd, int cmd, void *args) +int dfs_file_ioctl(struct dfs_file *file, int cmd, void *args) { - if (fd == NULL) + size_t ret = 0; + + if (file) { - return -EINVAL; + if (file->fops && file->fops->ioctl) + { + ret = file->fops->ioctl(file, cmd, args); + } + else + { + ret = -ENOSYS; + } + } + else + { + ret = -EBADF; } - /* regular file system fd */ - if (fd->vnode->type == FT_REGULAR || fd->vnode->type == FT_DEVICE) + return ret; +} + +int dfs_file_fcntl(int fd, int cmd, unsigned long arg) +{ + int ret = 0; + struct dfs_file *file; + + file = fd_get(fd); + if (file) { switch (cmd) { + case F_DUPFD: + ret = dfs_dup(fd, arg); + break; + case F_GETFD: + ret = file->mode; + break; + case F_SETFD: + file->mode = arg; + break; case F_GETFL: - return fd->flags; /* return flags */ + ret = file->flags; + break; case F_SETFL: - { - int flags = (int)(rt_base_t)args; - int mask = O_NONBLOCK | O_APPEND; + file->flags = arg; + break; + case F_GETLK: + break; + case F_SETLK: + case F_SETLKW: + break; + default: + ret = -EPERM; + break; + } + } + else + { + ret = -EBADF; + } - flags &= mask; - fd->flags &= ~mask; - fd->flags |= flags; - } - return 0; + return ret; +} + +int dfs_file_fsync(struct dfs_file *file) +{ + int ret = -EBADF; + + if (file) + { + if (file->fops->flush) + { + ret = file->fops->flush(file); } } - if (fd->vnode->fops->ioctl != NULL) - { - return fd->vnode->fops->ioctl(fd, cmd, args); - } - - return -ENOSYS; + return ret; } -/** - * this function will read specified length data from a file descriptor to a - * buffer. - * - * @param fd the file descriptor. - * @param buf the buffer to save the read data. - * @param len the length of data buffer to be read. - * - * @return the actual read data bytes or 0 on end of file or failed. - */ -int dfs_file_read(struct dfs_file *fd, void *buf, size_t len) -{ - int result = 0; - - if (fd == NULL) - { - return -EINVAL; - } - - if (fd->vnode->fops->read == NULL) - { - return -ENOSYS; - } - - if ((result = fd->vnode->fops->read(fd, buf, len)) < 0) - { - fd->flags |= DFS_F_EOF; - } - - return result; -} - -/** - * this function will fetch directory entries from a directory descriptor. - * - * @param fd the directory descriptor. - * @param dirp the dirent buffer to save result. - * @param nbytes the available room in the buffer. - * - * @return the read dirent, others on failed. - */ -int dfs_file_getdents(struct dfs_file *fd, struct dirent *dirp, size_t nbytes) -{ - /* parameter check */ - if (fd == NULL) - { - return -EINVAL; - } - - if (fd->vnode->type != FT_DIRECTORY) - { - return -EINVAL; - } - - if (fd->vnode->fops->getdents != NULL) - { - return fd->vnode->fops->getdents(fd, dirp, nbytes); - } - - return -ENOSYS; -} - -/** - * this function will unlink (remove) a specified path file from file system. - * - * @param path the specified path file to be unlinked. - * - * @return 0 on successful, -1 on failed. - */ int dfs_file_unlink(const char *path) { - int result; - char *fullpath; - struct dfs_filesystem *fs; + int ret = -RT_ERROR; + char *fullpath = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; - /* Make sure we have an absolute path */ fullpath = dfs_normalize_path(NULL, path); - if (fullpath == NULL) + if (fullpath) { - return -EINVAL; - } - - /* Check whether file is already open */ - if (dfs_file_is_open(fullpath)) - { - result = -EBUSY; - goto __exit; - } - - /* get filesystem */ - if ((fs = dfs_filesystem_lookup(fullpath)) == NULL) - { - result = -ENOENT; - goto __exit; - } - - if (fs->ops->unlink != NULL) - { - if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH)) + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) { - if (dfs_subdir(fs->path, fullpath) == NULL) - result = fs->ops->unlink(fs, "/"); + char *tmp = dfs_nolink_path(&mnt, fullpath, 0); + if (tmp) + { + rt_free(fullpath); + fullpath = tmp; + } + + if (strcmp(mnt->fullpath, fullpath) != 0) + { + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, fullpath, 0); + if (dentry) + { + rt_bool_t has_child = RT_FALSE; + + has_child = dfs_mnt_has_child_mnt(mnt, fullpath); + if (has_child == RT_FALSE && rt_atomic_load(&(dentry->ref_count)) == 1) + { + /* no child mnt point, unlink it */ + ret = -RT_ERROR; + + if (mnt->fs_ops->unlink) + { + ret = mnt->fs_ops->unlink(dentry); + } + } + else + { + ret = -EBUSY; + } + + /* release this dentry */ + dfs_dentry_unref(dentry); + } + else + { + /* no this entry */ + ret = -ENOENT; + } + } else - result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath)); + { + /* it's a mount point, failed for busy */ + ret = -EBUSY; + } } else - result = fs->ops->unlink(fs, fullpath); - } - else result = -ENOSYS; + { + ret = -ENOENT; + } -__exit: - rt_free(fullpath); - return result; -} - -/** - * this function will write some specified length data to file system. - * - * @param fd the file descriptor. - * @param buf the data buffer to be written. - * @param len the data buffer length - * - * @return the actual written data length. - */ -int dfs_file_write(struct dfs_file *fd, const void *buf, size_t len) -{ - if (fd == NULL) - { - return -EINVAL; - } - - if (fd->vnode->fops->write == NULL) - { - return -ENOSYS; - } - - return fd->vnode->fops->write(fd, buf, len); -} - -/** - * this function will flush buffer on a file descriptor. - * - * @param fd the file descriptor. - * - * @return 0 on successful, -1 on failed. - */ -int dfs_file_flush(struct dfs_file *fd) -{ - if (fd == NULL) - return -EINVAL; - - if (fd->vnode->fops->flush == NULL) - return -ENOSYS; - - return fd->vnode->fops->flush(fd); -} - -/** - * this function will seek the offset for specified file descriptor. - * - * @param fd the file descriptor. - * @param offset the offset to be sought. - * - * @return the current position after seek. - */ -int dfs_file_lseek(struct dfs_file *fd, off_t offset) -{ - int result; - - if (fd == NULL) - return -EINVAL; - - if (fd->vnode->fops->lseek == NULL) - return -ENOSYS; - - result = fd->vnode->fops->lseek(fd, offset); - - /* update current position */ - if (result >= 0) - fd->pos = result; - - return result; -} - -/** - * this function will get file information. - * - * @param path the file path. - * @param buf the data buffer to save stat description. - * - * @return 0 on successful, -1 on failed. - */ -int dfs_file_stat(const char *path, struct stat *buf) -{ - int result; - char *fullpath; - struct dfs_filesystem *fs; - - fullpath = dfs_normalize_path(NULL, path); - if (fullpath == NULL) - { - return -1; - } - - if ((fs = dfs_filesystem_lookup(fullpath)) == NULL) - { - LOG_E("can't find mounted filesystem on this path:%s", fullpath); + /* release fullpath */ rt_free(fullpath); - - return -ENOENT; - } - - if ((fullpath[0] == '/' && fullpath[1] == '\0') || - (dfs_subdir(fs->path, fullpath) == NULL)) - { - /* it's the root directory */ - buf->st_dev = 0; - - buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; - buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - - buf->st_size = 0; - buf->st_mtime = 0; - - /* release full path */ - rt_free(fullpath); - - return RT_EOK; } else { - if (fs->ops->stat == NULL) + ret = -ENOMEM; + } + + return ret; +} + +int dfs_file_link(const char *oldname, const char *newname) +{ + int ret = -1; + struct stat stat; + struct dfs_mnt *mnt = RT_NULL; + char *old_fullpath, *new_fullpath; + + if (dfs_file_isdir(oldname) == 0) + { + return ret; + } + + if (dfs_file_lstat(newname, &stat) >= 0) + { + return ret; + } + + old_fullpath = dfs_normalize_path(NULL, oldname); + if (old_fullpath) + { + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", old_fullpath); + mnt = dfs_mnt_lookup(old_fullpath); + if (mnt == RT_NULL) { + rt_free(old_fullpath); + return -1; + } + + char *tmp = dfs_nolink_path(&mnt, old_fullpath, 0); + if (tmp) + { + rt_free(old_fullpath); + old_fullpath = tmp; + } + } + + new_fullpath = dfs_normalize_path(NULL, newname); + if (new_fullpath) + { + char *tmp = dfs_nolink_path(&mnt, new_fullpath, 0); + if (tmp) + { + rt_free(new_fullpath); + new_fullpath = tmp; + } + } + + if (old_fullpath && new_fullpath) + { + struct dfs_dentry *old_dentry, *new_dentry; + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", old_fullpath); + old_dentry = dfs_dentry_lookup(mnt, old_fullpath, 0); + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_create(%s)", new_fullpath); + new_dentry = dfs_dentry_create(mnt, new_fullpath); + + if (old_dentry && new_dentry) + { + if (mnt->fs_ops->link) + { + ret = mnt->fs_ops->link(old_dentry, new_dentry); + } + } + + dfs_dentry_unref(old_dentry); + dfs_dentry_unref(new_dentry); + } + + if (old_fullpath) + { + rt_free(old_fullpath); + } + + if (new_fullpath) + { + rt_free(new_fullpath); + } + + return ret; +} + +/* symlink creates a symbolic link named `linkpath` which contains the string `target`. */ +int dfs_file_symlink(const char *target, const char *linkpath) +{ + int ret = -RT_ERROR; + char *fullpath = RT_NULL, *parent = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; + + if (target && linkpath) + { + if (linkpath[0] != '/') + { + fullpath = dfs_normalize_path(NULL, linkpath); + } + else + { + fullpath = (char*)linkpath; + } + + /* linkpath should be not exist */ + if (dfs_file_access(fullpath, O_RDONLY) != 0) + { + char *index; + + /* get parent path */ + index = strrchr(fullpath, '/'); + if (index) + { + int length = index - fullpath; + if (length > 0) + { + parent = (char*) rt_malloc (length + 1); + if (parent) + { + memcpy(parent, fullpath, length); + parent[length] = '\0'; + } + } + else + { + parent = (char*) rt_malloc (1 + 1); + if (parent) + { + parent[0] = '/'; + parent[1] = '\0'; + } + } + } + + if (parent) + { + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(parent); + if (mnt) + { + char *tmp = dfs_nolink_path(&mnt, parent, 0); + if (tmp) + { + rt_free(parent); + parent = tmp; + } + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, parent, 0); + if (dentry) + { + if (dentry->mnt->fs_ops->symlink) + { + char *path = dfs_normalize_path(NULL, target); + if (path) + { + char *tmp = dfs_nolink_path(&mnt, path, 0); + if (tmp) + { + rt_free(path); + path = tmp; + } + else + { + tmp = path; + } + + if (dfs_file_access(path, O_RDONLY) == 0) + { + ret = rt_strncmp(parent, path, strlen(parent)); + if (ret == 0) + { + tmp = path + strlen(parent); + if (*tmp == '/') + { + tmp ++; + } + } + + ret = mnt->fs_ops->symlink(dentry, tmp, index + 1); + } + else + { + ret = -ENOENT; + } + + rt_free(path); + } + } + else + { + ret = -ENOSYS; + } + + dfs_dentry_unref(dentry); + } + else + { + ret = -ENOENT; + } + } + else + { + ret = -ENOENT; + } + + rt_free(parent); + } + } + + if (fullpath != linkpath) rt_free(fullpath); - LOG_E("the filesystem didn't implement this function"); - - return -ENOSYS; - } - - /* get the real file path and get file stat */ - if (fs->ops->flags & DFS_FS_FLAG_FULLPATH) - result = fs->ops->stat(fs, fullpath, buf); - else - result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf); - } - - rt_free(fullpath); - - return result; -} - -/** - * this function will rename an old path name to a new path name. - * - * @param oldpath the old path name. - * @param newpath the new path name. - * - * @return 0 on successful, -1 on failed. - */ -int dfs_file_rename(const char *oldpath, const char *newpath) -{ - int result = RT_EOK; - struct dfs_filesystem *oldfs = NULL, *newfs = NULL; - char *oldfullpath = NULL, *newfullpath = NULL; - - newfullpath = NULL; - oldfullpath = NULL; - - oldfullpath = dfs_normalize_path(NULL, oldpath); - if (oldfullpath == NULL) - { - result = -ENOENT; - goto __exit; - } - - if (dfs_file_is_open((const char *)oldfullpath)) - { - result = -EBUSY; - goto __exit; - } - - newfullpath = dfs_normalize_path(NULL, newpath); - if (newfullpath == NULL) - { - result = -ENOENT; - goto __exit; - } - - oldfs = dfs_filesystem_lookup(oldfullpath); - newfs = dfs_filesystem_lookup(newfullpath); - - if (oldfs == newfs) - { - if (oldfs->ops->rename == NULL) - { - result = -ENOSYS; - } - else - { - if (oldfs->ops->flags & DFS_FS_FLAG_FULLPATH) - result = oldfs->ops->rename(oldfs, oldfullpath, newfullpath); - else - /* use sub directory to rename in file system */ - result = oldfs->ops->rename(oldfs, - dfs_subdir(oldfs->path, oldfullpath), - dfs_subdir(newfs->path, newfullpath)); - } } else { - result = -EXDEV; + ret = -EINVAL; } -__exit: - if (oldfullpath) - { - rt_free(oldfullpath); - } - if (newfullpath) - { - rt_free(newfullpath); - } - - /* not at same file system, return EXDEV */ - return result; + return ret; } -/** - * this function is will cause the regular file referenced by fd - * to be truncated to a size of precisely length bytes. - * - * @param fd the file descriptor. - * @param length the length to be truncated. - * - * @return the status of truncated. - */ -int dfs_file_ftruncate(struct dfs_file *fd, off_t length) +int dfs_file_readlink(const char *path, char *buf, int bufsize) { - int result; + int ret = -RT_ERROR; + char *fullpath = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; - /* fd is null or not a regular file system fd, or length is invalid */ - if (fd == NULL || fd->vnode->type != FT_REGULAR || length < 0) - return -EINVAL; + fullpath = dfs_normalize_path(NULL, path); + if (fullpath) + { + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) + { + char *tmp = dfs_nolink_path(&mnt, fullpath, 0); + if (tmp) + { + rt_free(fullpath); + fullpath = tmp; + } - if (fd->vnode->fops->ioctl == NULL) - return -ENOSYS; + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, fullpath, 0); + if (dentry) + { + if (mnt->fs_ops->readlink) + { + ret = mnt->fs_ops->readlink(dentry, buf, bufsize); + } + else + { + ret = -ENOSYS; + } - result = fd->vnode->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length); + /* release this dentry */ + dfs_dentry_unref(dentry); + } + else + { + /* no this entry */ + ret = -ENOENT; + } + } + else + { + ret = -ENOENT; + } - /* update current size */ - if (result == 0) - fd->vnode->size = length; + /* release fullpath */ + rt_free(fullpath); + } + else + { + ret = -ENOMEM; + } - return result; + return ret; } -int dfs_file_mmap2(struct dfs_file *fd, struct dfs_mmap2_args *mmap2) +int dfs_file_rename(const char *old_file, const char *new_file) +{ + int ret = -1; + struct dfs_mnt *mnt = RT_NULL; + char *old_fullpath, *new_fullpath; + + old_fullpath = dfs_normalize_path(NULL, old_file); + if (old_fullpath) + { + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", old_fullpath); + mnt = dfs_mnt_lookup(old_fullpath); + if (mnt == RT_NULL) + { + rt_free(old_fullpath); + return -1; + } + + char *tmp = dfs_nolink_path(&mnt, old_fullpath, 0); + if (tmp) + { + rt_free(old_fullpath); + old_fullpath = tmp; + } + } + + new_fullpath = dfs_normalize_path(NULL, new_file); + if (new_fullpath) + { + char *tmp = dfs_nolink_path(&mnt, new_fullpath, 0); + if (tmp) + { + rt_free(new_fullpath); + new_fullpath = tmp; + } + } + + if (old_fullpath && new_fullpath) + { + struct dfs_dentry *old_dentry, *new_dentry; + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", old_fullpath); + old_dentry = dfs_dentry_lookup(mnt, old_fullpath, 0); + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_create(%s)", new_fullpath); + new_dentry = dfs_dentry_create(mnt, new_fullpath); + + if (old_dentry && new_dentry) + { + if (mnt->fs_ops->rename) + { + ret = mnt->fs_ops->rename(old_dentry, new_dentry); + } + } + + dfs_dentry_unref(old_dentry); + dfs_dentry_unref(new_dentry); + } + + if (old_fullpath) + { + rt_free(old_fullpath); + } + + if (new_fullpath) + { + rt_free(new_fullpath); + } + + return ret; +} + +int dfs_file_ftruncate(struct dfs_file *file, off_t length) { int ret = 0; - if (fd && mmap2) + if (file) { - if (fd->vnode->type != FT_DEVICE || !fd->vnode->fops->ioctl) + if (file->fops->truncate) + { + ret = file->fops->truncate(file, length); + } + else + { + ret = -ENOSYS; + } + } + else + { + ret = -EBADF; + } + + return ret; +} + +int dfs_file_flush(struct dfs_file *file) +{ + int ret = 0; + + if (file) + { + if (file->fops->flush) + { + ret = file->fops->flush(file); + } + else + { + ret = -ENOSYS; + } + } + else + { + ret = -EBADF; + } + + return ret; +} + +int dfs_file_getdents(struct dfs_file *file, struct dirent *dirp, size_t nbytes) +{ + int ret = -RT_ERROR; + + if (file) + { + if (file->vnode && S_ISDIR(file->vnode->mode)) + { + if (file->fops && file->fops->getdents) + { + DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->getdents()"); + ret = file->fops->getdents(file, dirp, nbytes); + } + } + } + else + { + ret = -EBADF; + } + + return ret; +} + +/** + * this function will check the path is it a directory. + * + * @param path the file path. + * + * @return 0 on is dir, -1 on not dir. + */ +int dfs_file_isdir(const char *path) +{ + int ret = -RT_ERROR; + char *fullpath = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + struct dfs_dentry *dentry = RT_NULL; + + fullpath = dfs_normalize_path(NULL, path); + if (fullpath) + { + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) + { + char *tmp = dfs_nolink_path(&mnt, fullpath, 1); + if (tmp) + { + rt_free(fullpath); + fullpath = tmp; + } + + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dentry = dfs_dentry_lookup(mnt, %s)", fullpath); + dentry = dfs_dentry_lookup(mnt, fullpath, 0); + if (dentry) + { + DLOG(msg, "dentry", "dfs_file", DLOG_MSG_RET, "return dentry"); + if (mnt->fs_ops->stat) + { + struct stat stat = {0}; + DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)"); + ret = mnt->fs_ops->stat(dentry, &stat); + if (ret == RT_EOK && S_ISDIR(stat.st_mode)) + { + ret = RT_EOK; + } + else + { + ret = -RT_ERROR; + } + } + + /* unref dentry */ + DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_unref(dentry)"); + dfs_dentry_unref(dentry); + dentry = RT_NULL; + } + } + + rt_free(fullpath); + fullpath = RT_NULL; + } + + return ret; +} + +int dfs_file_access(const char *path, mode_t mode) +{ + int ret; + struct dfs_file file; + + dfs_file_init(&file); + + if (dfs_file_open(&file, path, O_RDONLY, mode) >= 0) + { + ret = 0; + dfs_file_close(&file); + } + else + { + ret = -1; + } + + dfs_file_deinit(&file); + + return ret; +} + +int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2) +{ + int ret = 0; + + if (file && mmap2) + { + if (file->vnode->type != FT_DEVICE || !file->vnode->fops->ioctl) { rt_set_errno(EINVAL); } - else if (fd->vnode->type == FT_DEVICE && fd->vnode->fops->ioctl) + else if (file->vnode->type == FT_DEVICE && file->vnode->fops->ioctl) { - ret = fd->vnode->fops->ioctl(fd, RT_FIOMMAP2, mmap2); + ret = file->vnode->fops->ioctl(file, RT_FIOMMAP2, mmap2); if (ret != 0) { - ret = ret > 0? ret : -ret; + ret = ret > 0 ? ret : -ret; rt_set_errno(ret); } } @@ -747,17 +1542,22 @@ int dfs_file_mmap2(struct dfs_file *fd, struct dfs_mmap2_args *mmap2) } #ifdef RT_USING_FINSH -#include + +#define _COLOR_RED "\033[31m" +#define _COLOR_GREEN "\033[32m" +#define _COLOR_BLUE "\033[34m" +#define _COLOR_CYAN "\033[36m" +#define _COLOR_WHITE "\033[37m" +#define _COLOR_NORMAL "\033[0m" void ls(const char *pathname) { - struct dfs_file fd; struct dirent dirent; struct stat stat; int length; char *fullpath, *path; + struct dfs_file file; - fullpath = NULL; if (pathname == NULL) { #ifdef DFS_USING_WORKDIR @@ -767,107 +1567,190 @@ void ls(const char *pathname) path = rt_strdup("/"); #endif if (path == NULL) - return ; /* out of memory */ + { + return; /* out of memory */ + } } else { - path = (char *)pathname; + path = dfs_normalize_path(NULL, (char *)pathname); + if (path == NULL) + { + return; /* out of memory */ + } } - fd_init(&fd); + dfs_file_init(&file); + /* list directory */ - if (dfs_file_open(&fd, path, O_DIRECTORY) == 0) + DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_open(%s, O_DIRECTORY, 0)", path); + if (dfs_file_open(&file, path, O_DIRECTORY, 0) >= 0) { - rt_kprintf("Directory %s:\n", path); - do + char *link_fn = (char *) rt_malloc (DFS_PATH_MAX); + if (link_fn) { - rt_memset(&dirent, 0, sizeof(struct dirent)); - length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent)); - if (length > 0) + rt_kprintf("Directory %s:\n", path); + do { - rt_memset(&stat, 0, sizeof(struct stat)); + memset(&dirent, 0, sizeof(struct dirent)); - /* build full path for each file */ - fullpath = dfs_normalize_path(path, dirent.d_name); - if (fullpath == NULL) - break; - - if (dfs_file_stat(fullpath, &stat) == 0) + DLOG(group, "foreach_item"); + DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_getdents(&dirent)"); + length = dfs_file_getdents(&file, &dirent, sizeof(struct dirent)); + if (length > 0) { - rt_kprintf("%-20s", dirent.d_name); - if (S_ISDIR(stat.st_mode)) + DLOG(msg, "dfs_file", "dfs", DLOG_MSG_RET, "dirent.d_name=%s", dirent.d_name); + memset(&stat, 0, sizeof(struct stat)); + + /* build full path for each file */ + fullpath = dfs_normalize_path(path, dirent.d_name); + if (fullpath == NULL) + break; + + DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_lstat(%s, &stat)", fullpath); + if (dfs_file_lstat(fullpath, &stat) == 0) { - rt_kprintf("%-25s\n", ""); + if (S_ISDIR(stat.st_mode)) + { + rt_kprintf(_COLOR_BLUE "%-20s" _COLOR_NORMAL, dirent.d_name); + rt_kprintf("%-25s\n", ""); + } + else if (S_ISLNK(stat.st_mode)) + { + int ret = 0; + + rt_kprintf(_COLOR_CYAN "%-20s" _COLOR_NORMAL, dirent.d_name); + + ret = dfs_file_readlink(fullpath, link_fn, DFS_PATH_MAX); + if (ret > 0) + { + char *link_path = link_fn; + struct dfs_mnt *mnt = RT_NULL; + + mnt = dfs_mnt_lookup(fullpath); + if (mnt) + { + char *tmp = dfs_nolink_path(&mnt, fullpath, 0); + if (tmp) + { + char *index; + + index = strrchr(fullpath, '/'); + if (index) + { + int length = index - fullpath; + char *parent = (char*) rt_malloc (length + 1); + if (parent) + { + rt_memcpy(parent, fullpath, length); + parent[length] = '\0'; + + ret = rt_strncmp(parent, link_fn, length); + if (ret == 0) + { + link_path = link_fn + length; + if (*link_path == '/') + { + link_path ++; + } + } + rt_free(parent); + } + } + rt_free(tmp); + } + } + + rt_kprintf("-> %s\n", link_path); + } + else + { + rt_kprintf(_COLOR_RED "-> link_error\n" _COLOR_NORMAL); + } + } + else + { + rt_kprintf("%-20s", dirent.d_name); + rt_kprintf("%-25lu\n", (unsigned long)stat.st_size); + } } else { - rt_kprintf("%-25lu\n", (unsigned long)stat.st_size); + rt_kprintf("BAD file: %s\n", dirent.d_name); } + + rt_free(fullpath); } else - rt_kprintf("BAD file: %s\n", dirent.d_name); - rt_free(fullpath); - } - } - while (length > 0); + { + DLOG(msg, "dfs_file", "dfs", DLOG_MSG_RET, "return NULL"); + } - dfs_file_close(&fd); + DLOG(group_end); + } while (length > 0); + + rt_free(link_fn); + } + + DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_close()"); + dfs_file_close(&file); } else { rt_kprintf("No such directory\n"); } - if (pathname == NULL) - rt_free(path); -} -FINSH_FUNCTION_EXPORT(ls, list directory contents); -void rm(const char *filename) -{ - if (dfs_file_unlink(filename) < 0) - { - rt_kprintf("Delete %s failed\n", filename); - } + dfs_file_deinit(&file); + + DLOG(msg, "dfs_file", "dfs", DLOG_MSG_RET, "return"); + rt_free(path); } -FINSH_FUNCTION_EXPORT(rm, remove files or directories); void cat(const char *filename) { - struct dfs_file fd; int length = 0; char buffer[81]; + struct dfs_file file; - fd_init(&fd); - if (dfs_file_open(&fd, filename, O_RDONLY) < 0) + if (filename && dfs_file_isdir(filename) == 0) + { + rt_kprintf("cat: %s Is a directory\n", filename); + return; + } + + dfs_file_init(&file); + + DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_open(%s, O_RDONLY, 0)", filename); + if (dfs_file_open(&file, filename, O_RDONLY, 0) < 0) { rt_kprintf("Open %s failed\n", filename); - + dfs_file_deinit(&file); return; } do { rt_memset(buffer, 0x0, sizeof(buffer)); - length = dfs_file_read(&fd, (void *)buffer, sizeof(buffer) - 1); + DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_read(fd, buffer, %d)", sizeof(buffer) - 1); + length = dfs_file_read(&file, (void *)buffer, sizeof(buffer) - 1); if (length > 0) { buffer[length] = '\0'; - rt_device_t out_device = rt_console_get_device(); - rt_device_write(out_device, 0, (void *)buffer, sizeof(buffer)); + rt_kprintf("%s", buffer); } } while (length > 0); rt_kprintf("\n"); - dfs_file_close(&fd); + DLOG(msg, "dfs", "dfs_file", DLOG_MSG, "dfs_file_close()"); + dfs_file_close(&file); + dfs_file_deinit(&file); } -FINSH_FUNCTION_EXPORT(cat, print file); -#ifdef DFS_USING_POSIX #define BUF_SZ 4096 static void copyfile(const char *src, const char *dst) { - struct dfs_file fd; - struct dfs_file src_fd; + int ret; + struct dfs_file src_file, dst_file; rt_uint8_t *block_ptr; rt_int32_t read_bytes; @@ -875,37 +1758,41 @@ static void copyfile(const char *src, const char *dst) if (block_ptr == NULL) { rt_kprintf("out of memory\n"); - return; } - fd_init(&src_fd); - if (dfs_file_open(&src_fd, src, O_RDONLY) < 0) + dfs_file_init(&src_file); + + ret = dfs_file_open(&src_file, src, O_RDONLY, 0); + if (ret < 0) { + dfs_file_deinit(&src_file); rt_free(block_ptr); rt_kprintf("Read %s failed\n", src); - return; } - fd_init(&fd); - if (dfs_file_open(&fd, dst, O_WRONLY | O_CREAT) < 0) + + dfs_file_init(&dst_file); + + ret = dfs_file_open(&dst_file, dst, O_WRONLY | O_CREAT, 0); + if (ret < 0) { + dfs_file_deinit(&dst_file); + dfs_file_close(&src_file); + dfs_file_deinit(&src_file); rt_free(block_ptr); - dfs_file_close(&src_fd); - rt_kprintf("Write %s failed\n", dst); - return; } do { - read_bytes = dfs_file_read(&src_fd, block_ptr, BUF_SZ); + read_bytes = dfs_file_read(&src_file, block_ptr, BUF_SZ); if (read_bytes > 0) { int length; - length = dfs_file_write(&fd, block_ptr, read_bytes); + length = dfs_file_write(&dst_file, block_ptr, read_bytes); if (length != read_bytes) { /* write failed. */ @@ -913,11 +1800,12 @@ static void copyfile(const char *src, const char *dst) break; } } - } - while (read_bytes > 0); + } while (read_bytes > 0); - dfs_file_close(&src_fd); - dfs_file_close(&fd); + dfs_file_close(&dst_file); + dfs_file_deinit(&dst_file); + dfs_file_close(&src_file); + dfs_file_deinit(&src_file); rt_free(block_ptr); } @@ -927,10 +1815,14 @@ static void copydir(const char *src, const char *dst) struct dirent dirent; struct stat stat; int length; - struct dfs_file cpfd; - if (dfs_file_open(&cpfd, src, O_DIRECTORY) < 0) + struct dfs_file file; + + dfs_file_init(&file); + + if (dfs_file_open(&file, src, O_DIRECTORY, 0) < 0) { rt_kprintf("open %s failed\n", src); + dfs_file_deinit(&file); return ; } @@ -938,7 +1830,7 @@ static void copydir(const char *src, const char *dst) { rt_memset(&dirent, 0, sizeof(struct dirent)); - length = dfs_file_getdents(&cpfd, &dirent, sizeof(struct dirent)); + length = dfs_file_getdents(&file, &dirent, sizeof(struct dirent)); if (length > 0) { char *src_entry_full = NULL; @@ -961,7 +1853,7 @@ static void copydir(const char *src, const char *dst) } rt_memset(&stat, 0, sizeof(struct stat)); - if (dfs_file_stat(src_entry_full, &stat) != 0) + if (dfs_file_lstat(src_entry_full, &stat) != 0) { rt_kprintf("open file: %s failed\n", dirent.d_name); continue; @@ -982,7 +1874,8 @@ static void copydir(const char *src, const char *dst) } while (length > 0); - dfs_file_close(&cpfd); + dfs_file_close(&file); + dfs_file_deinit(&file); } static const char *_get_path_lastname(const char *path) @@ -1011,7 +1904,7 @@ void copy(const char *src, const char *dst) uint32_t flag = 0; /* check the staus of src and dst */ - if (dfs_file_stat(src, &stat) < 0) + if (dfs_file_lstat(src, &stat) < 0) { rt_kprintf("copy failed, bad %s\n", src); return; @@ -1087,8 +1980,5 @@ void copy(const char *src, const char *dst) } } FINSH_FUNCTION_EXPORT(copy, copy file or dir) -#endif /* DFS_USING_POSIX */ - -#endif /* RT_USING_FINSH */ -/**@}*/ +#endif diff --git a/components/dfs/dfs_v2/src/dfs_fs.c b/components/dfs/dfs_v2/src/dfs_fs.c index 4240736778..ffedc44fca 100644 --- a/components/dfs/dfs_v2/src/dfs_fs.c +++ b/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,107 +10,408 @@ * 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 #include +#include +#include #include "dfs_private.h" +#define DBG_TAG "DFS.fs" +#define DBG_LVL DBG_INFO +#include + +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) + return type; +} + +int dfs_register(struct dfs_filesystem_type *fs) +{ + int ret = 0; + struct dfs_filesystem_type **type = _find_filesystem(fs->fs_ops->name); + + LOG_D("register %s file system.", fs->fs_ops->name); + + if (*type) { - rt_set_errno(-ENOSPC); - LOG_E("There is no space to register this file system (%s).", ops->name); - ret = -1; + ret = -EBUSY; } - else if (ret == RT_EOK) + else { - *empty = ops; + *type = fs; } - dfs_unlock(); 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_filesystem *dfs_filesystem_lookup(const char *path) +int dfs_unregister(struct dfs_filesystem_type *fs) { - struct dfs_filesystem *iter; - struct dfs_filesystem *fs = NULL; - uint32_t fspath, prefixlen; + int ret = 0; + struct dfs_filesystem_type **type; - prefixlen = 0; - - RT_ASSERT(path); - - /* lock filesystem */ - dfs_lock(); - - /* lookup it in the filesystem table */ - for (iter = &filesystem_table[0]; - iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++) + if (fs) { - if ((iter->path == NULL) || (iter->ops == NULL)) - continue; + LOG_D("unregister %s file system.", fs->fs_ops->name); - fspath = strlen(iter->path); - if ((fspath < prefixlen) - || (strncmp(iter->path, path, fspath) != 0)) - continue; + for (type = &file_systems; *type; type = &(*type)->next) + { + if (strcmp((*type)->fs_ops->name, fs->fs_ops->name) == 0) + { + *type = (*type)->next; + break; + } + } - /* check next path separator */ - if (fspath > 1 && (strlen(path) > fspath) && (path[fspath] != '/')) - continue; - - fs = iter; - prefixlen = fspath; + if (!*type) ret = -EINVAL; } - dfs_unlock(); + return ret; +} - return fs; +/* + * 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, + unsigned long rwflag, + const void *data) +{ + 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 (type) + { + fullpath = dfs_normalize_path(RT_NULL, path); + if (!fullpath) + { + rt_set_errno(EPERM); + ret = -1; + } + } + else + { + rt_set_errno(ENOENT); + ret = -1; + } + + if (fullpath) + { + DLOG(note, "mnt", "mount %s(%s) on path: %s", device_name, filesystemtype, fullpath); + + /* open specific device */ + if (device_name) dev_id = rt_device_find(device_name); + + if (!(type->fs_ops->flags & FS_NEED_DEVICE) || + ((type->fs_ops->flags & FS_NEED_DEVICE) && dev_id)) + { + 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; + } + } + else + { + LOG_E("No device found for this file system."); + rt_set_errno(ENODEV); + ret = -1; + } + rt_free(fullpath); + } + + return ret; +} + +int dfs_umount(const char *specialfile) +{ + int ret = -RT_ERROR; + char *fullpath = RT_NULL; + struct dfs_mnt *mnt = RT_NULL; + + fullpath = dfs_normalize_path(NULL, specialfile); + if (fullpath) + { + DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt = dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) + { + 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); + } + else + { + rt_set_errno(-ENOTDIR); + } + + return ret; +} + +/* for compatibility */ +int dfs_unmount(const char *specialfile) +{ + return dfs_umount(specialfile); +} + +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; + + type = *_find_filesystem(fs_name); + if (!type) + { + rt_kprintf("no file system: %s found!\n", fs_name); + return ret; + } + else + { + if (type->fs_ops->flags & FS_NEED_DEVICE) + { + /* 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 (type->fs_ops->mkfs) + { + ret = type->fs_ops->mkfs(dev_id, type->fs_ops->name); + } + + return ret; +} + +int dfs_statfs(const char *path, struct statfs *buffer) +{ + struct dfs_mnt *mnt; + char *fullpath; + int ret = -RT_ERROR; + + fullpath = dfs_normalize_path(NULL, path); + if (!fullpath) + { + return ret; + } + + DLOG(msg, "dfs_file", "mnt", DLOG_MSG, "dfs_mnt_lookup(%s)", fullpath); + mnt = dfs_mnt_lookup(fullpath); + if (mnt) + { + if (mnt->fs_ops->statfs) + { + ret = mnt->fs_ops->statfs(mnt, buffer); + } + } + + return ret; } /** @@ -123,23 +424,6 @@ struct dfs_filesystem *dfs_filesystem_lookup(const char *path) 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++) - { - /* find the mounted device */ - if (iter->ops == NULL) continue; - else if (iter->dev_id == device) - { - path = iter->path; - break; - } - } - - /* release filesystem_table lock */ - dfs_unlock(); return path; } @@ -154,8 +438,8 @@ const char *dfs_filesystem_get_mounted_path(struct rt_device *device) * @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) + uint8_t *buf, + uint32_t pindex) { #define DPT_ADDRESS 0x1be /* device partition offset in Boot Sector */ #define DPT_ITEM_SIZE 16 /* partition item size */ @@ -183,16 +467,16 @@ int dfs_filesystem_get_partition(struct dfs_partition *part, 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; - rt_kprintf("found part[%d], begin: %d, size: ", + rt_kprintf("found part[%d], begin: %ld, size: ", pindex, part->offset * 512); if ((part->size >> 11) == 0) - rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */ + rt_kprintf("%ld%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"); + rt_kprintf("%d.%ld%s", part_size, (part->size >> 1) & 0x3FF, "MB\n"); else rt_kprintf("%d.%d%s", part_size >> 10, part_size & 0x3FF, "GB\n"); } @@ -200,458 +484,4 @@ int dfs_filesystem_get_partition(struct dfs_partition *part, return RT_EOK; } -/** - * 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. - */ -int dfs_mount(const char *device_name, - const char *path, - const char *filesystemtype, - unsigned long rwflag, - 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(); - - if (ops == &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]) - { - /* can't find filesystem */ - rt_set_errno(-ENODEV); - return -1; - } - - /* check if there is mount implementation */ - if ((*ops == NULL) || ((*ops)->mount == NULL)) - { - rt_set_errno(-ENOSYS); - return -1; - } - - /* make full path for special file */ - fullpath = dfs_normalize_path(NULL, path); - if (fullpath == NULL) /* not an abstract path */ - { - rt_set_errno(-ENOTDIR); - return -1; - } - - /* Check if the path exists or not, raw APIs call, fixme */ - if ((strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0)) - { - struct dfs_file fd; - - fd_init(&fd); - if (dfs_file_open(&fd, fullpath, O_RDONLY | O_DIRECTORY) < 0) - { - rt_free(fullpath); - rt_set_errno(-ENOTDIR); - - return -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) - { - rt_set_errno(-EINVAL); - goto err1; - } - } - - 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; - - /* release filesystem_table lock */ - dfs_unlock(); - - /* open device, but do not check the status of device */ - if (dev_id != NULL) - { - if (rt_device_open(fs->dev_id, - RT_DEVICE_OFLAG_RDWR) != RT_EOK) - { - /* The underlying device has error, clear the entry. */ - dfs_lock(); - rt_memset(fs, 0, sizeof(struct dfs_filesystem)); - - goto err1; - } - } - - /* call mount of this filesystem */ - if ((*ops)->mount(fs, rwflag, data) < 0) - { - /* 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; - } - - return 0; - -err1: - dfs_unlock(); - rt_free(fullpath); - - return -1; -} - -/** - * 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. - */ -int dfs_unmount(const char *specialfile) -{ - char *fullpath; - struct dfs_filesystem *iter; - struct dfs_filesystem *fs = NULL; - - fullpath = dfs_normalize_path(NULL, specialfile); - if (fullpath == NULL) - { - rt_set_errno(-ENOTDIR); - - return -1; - } - - /* lock filesystem */ - dfs_lock(); - - for (iter = &filesystem_table[0]; - iter < &filesystem_table[DFS_FILESYSTEMS_MAX]; iter++) - { - /* check if the PATH is mounted */ - if ((iter->path != NULL) && (strcmp(iter->path, fullpath) == 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(); - rt_free(fullpath); - - return 0; - -err1: - dfs_unlock(); - rt_free(fullpath); - - return -1; -} - -/** - * 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 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; - } - - /* lock file system */ - dfs_lock(); - /* find the file system operations */ - for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index ++) - { - if (filesystem_operation_table[index] != NULL && - strncmp(filesystem_operation_table[index]->name, fs_name, - strlen(filesystem_operation_table[index]->name)) == 0) - break; - } - dfs_unlock(); - - if (index < DFS_FILESYSTEM_TYPES_MAX) - { - /* find file system operation */ - const struct dfs_filesystem_ops *ops = filesystem_operation_table[index]; - if (ops->mkfs == NULL) - { - LOG_E("The file system (%s) mkfs function was not implement", fs_name); - rt_set_errno(-ENOSYS); - return -1; - } - - return ops->mkfs(dev_id, fs_name); - } - - LOG_E("File system (%s) was not found.", fs_name); - - return -1; -} - -/** - * this function will return the information about a mounted file system. - * - * @param path the path which mounted file system. - * @param buffer the buffer to save the returned information. - * - * @return 0 on successful, others on failed. - */ -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) -{ - 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 ++; - } - - rt_kprintf("can't find device:%s to be mounted.\n", dev->parent.name); - return -RT_ERROR; -} - -int dfs_unmount_device(rt_device_t dev) -{ - 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; - -err1: - dfs_unlock(); - - return -1; -} - -#endif - -#ifdef RT_USING_FINSH -#include -void mkfs(const char *fs_name, const char *device_name) -{ - dfs_mkfs(fs_name, device_name); -} -FINSH_FUNCTION_EXPORT(mkfs, make a file system); - -int df(const char *path) -{ - int result; - int minor = 0; - long long cap; - struct statfs buffer; - - int unit_index = 0; - char *unit_str[] = {"KB", "MB", "GB"}; - - result = dfs_statfs(path ? path : NULL, &buffer); - if (result != 0) - { - if (rt_get_errno() == -ENOSYS) - rt_kprintf("The function is not implemented.\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("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; -} -FINSH_FUNCTION_EXPORT(df, get disk free); -#endif - -/**@}*/ +/* @} */ diff --git a/components/dfs/dfs_v2/src/dfs_mnt.c b/components/dfs/dfs_v2/src/dfs_mnt.c new file mode 100644 index 0000000000..759fed5598 --- /dev/null +++ b/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 + +#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 + +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; +} diff --git a/components/dfs/dfs_v2/src/dfs_posix.c b/components/dfs/dfs_v2/src/dfs_posix.c index ca182ee1eb..a9c822c5c8 100644 --- a/components/dfs/dfs_v2/src/dfs_posix.c +++ b/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 -#include -#include +#include +#include + +#include +#include +#include "dfs_private.h" #ifdef RT_USING_SMART #include @@ -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); - - result = dfs_file_open(d, path, O_DIRECTORY | O_CREAT); - - if (result < 0) + if (path && dfs_file_lstat(path, &stat) == 0) + { + rt_set_errno(-RT_ERROR); + return -1; + } + + dfs_file_init(&file); + + 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_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; - - /* allocate a fd */ - fd = fd_new(); - if (fd == -1) + if (!name || dfs_file_isdir(name) != 0) { - rt_set_errno(-ENOMEM); - - return NULL; + rt_set_errno(-RT_ERROR); + return RT_NULL; } - d = fd_get(fd); - result = dfs_file_open(d, name, O_RDONLY | O_DIRECTORY); + fd = fd_new(); + if (fd >= 0) + { + file = fd_get(fd); + } + else + { + rt_set_errno(-RT_ERROR); + return RT_NULL; + } + + 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 || 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) { - rt_set_errno(result); - - return NULL; + struct dirent *dirent_ptr; + dirent_ptr = (struct dirent *)&d->buf[d->cur]; + d->cur += dirent_ptr->d_reclen; } - d->num = result; - d->cur = 0; /* current entry index */ - } + if (!d->num || d->cur >= d->num) + { + /* 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 (struct dirent *)(d->buf + d->cur); + return NULL; + } + + 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 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; - fd = fd_get(d->fd); - if (fd == NULL) + if (d == NULL) + { + rt_set_errno(-EBADF); + return; + } + + 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; diff --git a/components/dfs/dfs_v2/src/dfs_private.h b/components/dfs/dfs_v2/src/dfs_private.h new file mode 100644 index 0000000000..412768e23a --- /dev/null +++ b/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 + +#define NO_WORKING_DIR "system does not support working directory\n" + +extern char working_directory[]; + +#endif diff --git a/components/dfs/dfs_v2/src/dfs_vnode.c b/components/dfs/dfs_v2/src/dfs_vnode.c new file mode 100644 index 0000000000..d3af9b3970 --- /dev/null +++ b/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 +#include + +#define DBG_TAG "DFS.vnode" +#define DBG_LVL DBG_WARNING +#include + +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; +} diff --git a/components/drivers/ipc/pipe.c b/components/drivers/ipc/pipe.c index e02355d096..bfed214678 100644 --- a/components/drivers/ipc/pipe.c +++ b/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) */ diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c index 34d91f9a21..fe5ea0f294 100644 --- a/components/drivers/serial/serial.c +++ b/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 */ diff --git a/components/drivers/tty/tty.c b/components/drivers/tty/tty.c index 29a0f8a601..10683b5f9d 100644 --- a/components/drivers/tty/tty.c +++ b/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) diff --git a/components/finsh/msh.c b/components/finsh/msh.c index a63e34ddfe..186ede00e2 100644 --- a/components/finsh/msh.c +++ b/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, "/"); + } + } } } } diff --git a/components/finsh/msh_file.c b/components/finsh/msh_file.c index 621b8303a5..5c38b579b1 100644 --- a/components/finsh/msh_file.c +++ b/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 #include #include +#ifdef RT_USING_DFS_V2 +#include +#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) */ diff --git a/components/libc/compilers/common/include/dirent.h b/components/libc/compilers/common/include/dirent.h index 55ebcd2d01..857be6388b 100644 --- a/components/libc/compilers/common/include/dirent.h +++ b/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 diff --git a/components/libc/compilers/common/include/unistd.h b/components/libc/compilers/common/include/unistd.h index 6e63bc94d8..6a2173f7e2 100644 --- a/components/libc/compilers/common/include/unistd.h +++ b/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__ */ diff --git a/components/libc/compilers/newlib/fcntl.h b/components/libc/compilers/newlib/fcntl.h index 847ae3d35b..ce8b621125 100644 --- a/components/libc/compilers/newlib/fcntl.h +++ b/components/libc/compilers/newlib/fcntl.h @@ -13,12 +13,24 @@ #include -#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 diff --git a/components/libc/posix/io/stdio/libc.c b/components/libc/posix/io/stdio/libc.c index 4d3ac6dd8a..a5bee3f448 100644 --- a/components/libc/posix/io/stdio/libc.c +++ b/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) diff --git a/components/lwp/lwp_ipc.c b/components/lwp/lwp_ipc.c index 926602cbfd..a4b560e264 100644 --- a/components/lwp/lwp_ipc.c +++ b/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; diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index e33ca0ea9e..bc9af4d1fa 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -40,6 +40,9 @@ #include #include #include +#ifdef RT_USING_DFS_V2 +#include +#endif #include #include /* rename() */ #include @@ -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; } diff --git a/components/net/sal/dfs_net/dfs_net.c b/components/net/sal/dfs_net/dfs_net.c index bb7176f436..8179abdcb5 100644 --- a/components/net/sal/dfs_net/dfs_net.c +++ b/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) diff --git a/components/net/sal/socket/net_sockets.c b/components/net/sal/socket/net_sockets.c index ed8a6c6b1d..0d6852ae32 100644 --- a/components/net/sal/socket/net_sockets.c +++ b/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;