mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-20 09:12:09 +08:00
sync smart & dfs (#8672)
Signed-off-by: xqyjlj <xqyjlj@126.com> Signed-off-by: Shell <smokewood@qq.com> Co-authored-by: xqyjlj <xqyjlj@126.com>
This commit is contained in:
@@ -45,6 +45,7 @@ endif
|
||||
|
||||
config RT_USING_DFS_V2
|
||||
bool "DFS v2.0"
|
||||
select RT_USING_DEVICE_OPS
|
||||
endchoice
|
||||
|
||||
if RT_USING_DFS_V1
|
||||
@@ -170,6 +171,13 @@ endif
|
||||
depends on RT_USING_DFS_ROMFS
|
||||
default n
|
||||
|
||||
if RT_USING_SMART
|
||||
config RT_USING_DFS_PTYFS
|
||||
bool "Using Pseudo-Teletype Filesystem (UNIX98 PTY)"
|
||||
depends on RT_USING_DFS_DEVFS
|
||||
default y
|
||||
endif
|
||||
|
||||
config RT_USING_DFS_CROMFS
|
||||
bool "Enable ReadOnly compressed file system on flash"
|
||||
default n
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,9 @@
|
||||
#ifndef __DEVICE_FS_H__
|
||||
#define __DEVICE_FS_H__
|
||||
|
||||
int dfs_devfs_init(void);
|
||||
const struct dfs_file_ops *dfs_devfs_fops(void);
|
||||
mode_t dfs_devfs_device_to_mode(struct rt_device *device);
|
||||
void dfs_devfs_device_add(rt_device_t device);
|
||||
int dfs_devfs_update(void);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -145,7 +145,7 @@ static struct dfs_vnode *dfs_mqueue_create_vnode(struct dfs_dentry *dentry, int
|
||||
}
|
||||
mq_file->msg_size = 8192;
|
||||
mq_file->max_msgs = 10;
|
||||
strncpy(mq_file->name, dentry->pathname + 1, RT_NAME_MAX);
|
||||
strncpy(mq_file->name, dentry->pathname + 1, RT_NAME_MAX - 1);
|
||||
dfs_mqueue_insert_after(&(mq_file->list));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# The Pseudo Terminal Filesystem
|
||||
|
||||
The device register on ptyfs is also registered in device frameworks with `rt_device_register()`.
|
||||
|
||||
It's possible to mount a new ptyfs instance on another path. Each instance is isolated to each other. And they don't share the id system. But generally speaking, you have to mount the ptyfs on `/dev` root, since all the file nodes in ptyfs are devices.
|
||||
@@ -0,0 +1,11 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_PTYFS'], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-12-02 Shell init ver.
|
||||
*/
|
||||
#ifndef __FS_PTYFS_H__
|
||||
#define __FS_PTYFS_H__
|
||||
#include <rtthread.h>
|
||||
|
||||
typedef rt_base_t ptsno_t;
|
||||
|
||||
ptsno_t ptyfs_register_pts(rt_device_t ptmx, rt_device_t pts);
|
||||
|
||||
rt_err_t ptyfs_unregister_pts(rt_device_t ptmx, ptsno_t ptsno);
|
||||
|
||||
const char *ptyfs_get_rootpath(rt_device_t ptmx);
|
||||
|
||||
#endif /* __FS_PTYFS_H__ */
|
||||
@@ -29,6 +29,9 @@ 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, "proc", RT_NULL, 0},
|
||||
{ROMFS_DIRENT_DIR, "etc", RT_NULL, 0},
|
||||
{ROMFS_DIRENT_DIR, "bin", 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)},
|
||||
};
|
||||
|
||||
@@ -202,6 +202,7 @@ int dfs_tmpfs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||
|
||||
superblock = d_file->sb;
|
||||
RT_ASSERT(superblock != NULL);
|
||||
RT_UNUSED(superblock);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
@@ -317,26 +318,21 @@ static ssize_t dfs_tmpfs_read(struct dfs_file *file, void *buf, size_t count, of
|
||||
return length;
|
||||
}
|
||||
|
||||
static ssize_t dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
|
||||
static ssize_t _dfs_tmpfs_write(struct tmpfs_file *d_file, const void *buf, size_t count, off_t *pos)
|
||||
{
|
||||
struct tmpfs_file *d_file;
|
||||
struct tmpfs_sb *superblock;
|
||||
|
||||
d_file = (struct tmpfs_file *)file->vnode->data;
|
||||
RT_ASSERT(d_file != NULL);
|
||||
|
||||
superblock = d_file->sb;
|
||||
RT_ASSERT(superblock != NULL);
|
||||
|
||||
rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER);
|
||||
|
||||
if (count + *pos > file->vnode->size)
|
||||
if (count + *pos > d_file->size)
|
||||
{
|
||||
rt_uint8_t *ptr;
|
||||
ptr = rt_realloc(d_file->data, *pos + count);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
rt_mutex_release(&file->vnode->lock);
|
||||
rt_set_errno(-ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
@@ -347,7 +343,6 @@ static ssize_t dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t co
|
||||
/* update d_file and file size */
|
||||
d_file->data = ptr;
|
||||
d_file->size = *pos + count;
|
||||
file->vnode->size = d_file->size;
|
||||
LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size);
|
||||
}
|
||||
|
||||
@@ -356,6 +351,21 @@ static ssize_t dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t co
|
||||
|
||||
/* update file current position */
|
||||
*pos += count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
|
||||
{
|
||||
struct tmpfs_file *d_file;
|
||||
|
||||
d_file = (struct tmpfs_file *)file->vnode->data;
|
||||
RT_ASSERT(d_file != NULL);
|
||||
|
||||
rt_mutex_take(&file->vnode->lock, RT_WAITING_FOREVER);
|
||||
|
||||
count = _dfs_tmpfs_write(d_file, buf, count, pos);
|
||||
|
||||
rt_mutex_release(&file->vnode->lock);
|
||||
|
||||
return count;
|
||||
@@ -504,6 +514,7 @@ static int dfs_tmpfs_getdents(struct dfs_file *file,
|
||||
|
||||
superblock = d_file->sb;
|
||||
RT_ASSERT(superblock != RT_NULL);
|
||||
RT_UNUSED(superblock);
|
||||
|
||||
/* make integer count */
|
||||
count = (count / sizeof(struct dirent));
|
||||
@@ -797,6 +808,8 @@ static ssize_t dfs_tmp_page_read(struct dfs_file *file, struct dfs_page *page)
|
||||
|
||||
ssize_t dfs_tmp_page_write(struct dfs_page *page)
|
||||
{
|
||||
off_t pos;
|
||||
size_t count = 0;
|
||||
struct tmpfs_file *d_file;
|
||||
|
||||
if (page->aspace->vnode->type == FT_DIRECTORY)
|
||||
@@ -806,13 +819,16 @@ ssize_t dfs_tmp_page_write(struct dfs_page *page)
|
||||
|
||||
d_file = (struct tmpfs_file *)(page->aspace->vnode->data);
|
||||
RT_ASSERT(d_file != RT_NULL);
|
||||
|
||||
rt_mutex_take(&page->aspace->vnode->lock, RT_WAITING_FOREVER);
|
||||
if (page->len > 0)
|
||||
memcpy(d_file->data + page->fpos, page->page, page->len);
|
||||
|
||||
{
|
||||
pos = page->fpos;
|
||||
count = _dfs_tmpfs_write(d_file, page->page, page->len, &pos);
|
||||
}
|
||||
rt_mutex_release(&page->aspace->vnode->lock);
|
||||
|
||||
return F_OK;
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include <rtatomic.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#ifndef ATTR_MODE_SET
|
||||
#define ATTR_MODE_SET (1 << 6)
|
||||
#endif
|
||||
|
||||
#ifndef ATTR_ATIME_SET
|
||||
#define ATTR_ATIME_SET (1 << 7)
|
||||
#endif
|
||||
@@ -33,6 +37,14 @@
|
||||
#define ATTR_MTIME_SET (1 << 8)
|
||||
#endif
|
||||
|
||||
#ifndef ATTR_UID_SET
|
||||
#define ATTR_UID_SET (1 << 9)
|
||||
#endif
|
||||
|
||||
#ifndef ATTR_GID_SET
|
||||
#define ATTR_GID_SET (1 << 10)
|
||||
#endif
|
||||
|
||||
#ifndef AT_SYMLINK_NOFOLLOW
|
||||
#define AT_SYMLINK_NOFOLLOW 0x100
|
||||
#endif
|
||||
|
||||
@@ -175,20 +175,25 @@ 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);
|
||||
char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode);
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2);
|
||||
|
||||
int dfs_file_mmap(struct dfs_file *file, struct dfs_mmap2_args *mmap2);
|
||||
#endif
|
||||
|
||||
char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode);
|
||||
|
||||
/* 0x5254 is just a magic number to make these relatively unique ("RT") */
|
||||
#define RT_FIOFTRUNCATE 0x52540000U
|
||||
#define RT_FIOGETADDR 0x52540001U
|
||||
#define RT_FIOMMAP2 0x52540002U
|
||||
|
||||
/* dfs_file_realpath mode */
|
||||
#define DFS_REALPATH_EXCEPT_LAST 0
|
||||
#define DFS_REALPATH_EXCEPT_NONE 1
|
||||
#define DFS_REALPATH_ONLY_LAST 3
|
||||
|
||||
char *dfs_file_realpath(struct dfs_mnt **mnt, const char *fullpath, int mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,9 @@ struct dfs_partition
|
||||
struct dfs_attr
|
||||
{
|
||||
unsigned int ia_valid;
|
||||
mode_t st_mode;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
mode_t st_mode;
|
||||
struct timespec ia_atime;
|
||||
struct timespec ia_mtime;
|
||||
};
|
||||
|
||||
@@ -23,6 +23,8 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct rt_varea;
|
||||
struct rt_aspace;
|
||||
struct dfs_vnode;
|
||||
struct dfs_dentry;
|
||||
struct dfs_aspace;
|
||||
@@ -30,7 +32,8 @@ struct dfs_aspace;
|
||||
struct dfs_mmap
|
||||
{
|
||||
rt_list_t mmap_node;
|
||||
struct rt_varea *varea;
|
||||
struct rt_aspace *aspace;
|
||||
void *vaddr;
|
||||
};
|
||||
|
||||
struct dfs_page
|
||||
|
||||
@@ -557,6 +557,111 @@ exit:
|
||||
return newfd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The fd in the current process dup to designate fd table.
|
||||
*
|
||||
* @param oldfd is the fd in current process.
|
||||
*
|
||||
* @param fdtab is the fd table to dup, if empty, use global (_fdtab).
|
||||
*
|
||||
* @return -1 on failed or the allocated file descriptor.
|
||||
*/
|
||||
int dfs_dup_to(int oldfd, struct dfs_fdtable *fdtab)
|
||||
{
|
||||
int newfd = -1;
|
||||
struct dfs_fdtable *fdt = NULL;
|
||||
|
||||
if (dfs_file_lock() != RT_EOK)
|
||||
{
|
||||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
if (fdtab == NULL)
|
||||
{
|
||||
fdtab = &_fdtab;
|
||||
}
|
||||
|
||||
/* check old fd */
|
||||
fdt = dfs_fdtable_get();
|
||||
if ((oldfd < 0) || (oldfd >= fdt->maxfd))
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
if (!fdt->fds[oldfd])
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
/* get a new fd*/
|
||||
newfd = _fdt_slot_alloc(fdtab, DFS_STDIO_OFFSET);
|
||||
if (newfd >= 0)
|
||||
{
|
||||
fdtab->fds[newfd] = fdt->fds[oldfd];
|
||||
|
||||
/* inc ref_count */
|
||||
rt_atomic_add(&(fdtab->fds[newfd]->ref_count), 1);
|
||||
}
|
||||
exit:
|
||||
dfs_file_unlock();
|
||||
|
||||
return newfd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The fd in the designate fd table dup to current process.
|
||||
*
|
||||
* @param oldfd is the fd in the designate fd table.
|
||||
*
|
||||
* @param fdtab is the fd table for oldfd, if empty, use global (_fdtab).
|
||||
*
|
||||
* @return -1 on failed or the allocated file descriptor.
|
||||
*/
|
||||
int dfs_dup_from(int oldfd, struct dfs_fdtable *fdtab)
|
||||
{
|
||||
int newfd = -1;
|
||||
struct dfs_file *file;
|
||||
|
||||
if (dfs_file_lock() != RT_EOK)
|
||||
{
|
||||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
if (fdtab == NULL)
|
||||
{
|
||||
fdtab = &_fdtab;
|
||||
}
|
||||
|
||||
/* check old fd */
|
||||
if ((oldfd < 0) || (oldfd >= fdtab->maxfd))
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
if (!fdtab->fds[oldfd])
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
/* get a new fd*/
|
||||
newfd = fd_new();
|
||||
file = fd_get(newfd);
|
||||
if (newfd >= 0 && file)
|
||||
{
|
||||
file->mode = fdtab->fds[oldfd]->mode;
|
||||
file->flags = fdtab->fds[oldfd]->flags;
|
||||
file->fops = fdtab->fds[oldfd]->fops;
|
||||
file->dentry = dfs_dentry_ref(fdtab->fds[oldfd]->dentry);
|
||||
file->vnode = fdtab->fds[oldfd]->vnode;
|
||||
file->mmap_context = RT_NULL;
|
||||
file->data = fdtab->fds[oldfd]->data;
|
||||
}
|
||||
|
||||
dfs_file_close(fdtab->fds[oldfd]);
|
||||
|
||||
exit:
|
||||
fdt_fd_release(fdtab, oldfd);
|
||||
dfs_file_unlock();
|
||||
|
||||
return newfd;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
sysret_t sys_dup(int oldfd)
|
||||
#else
|
||||
@@ -856,7 +961,11 @@ int dfs_fd_dump(int argc, char** argv)
|
||||
{
|
||||
int index;
|
||||
|
||||
dfs_file_lock();
|
||||
if (dfs_file_lock() != RT_EOK)
|
||||
{
|
||||
return -RT_ENOSYS;
|
||||
}
|
||||
|
||||
for (index = 0; index < _fdtab.maxfd; index++)
|
||||
{
|
||||
struct dfs_file *file = _fdtab.fds[index];
|
||||
|
||||
@@ -29,22 +29,86 @@
|
||||
|
||||
#define MAX_RW_COUNT 0xfffc0000
|
||||
|
||||
rt_inline int _find_path_node(const char *path)
|
||||
rt_inline int _first_path_len(const char *path)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (path[i] != '\0')
|
||||
if (path[i] == '/')
|
||||
{
|
||||
if ('/' == path[i++])
|
||||
i++;
|
||||
while (path[i] != '\0' && path[i] != '/')
|
||||
{
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* return path-note length */
|
||||
return i;
|
||||
}
|
||||
|
||||
static int _get_parent_path(const char *fullpath, char *path)
|
||||
{
|
||||
int len = 0;
|
||||
char *str = 0;
|
||||
|
||||
str = strrchr(fullpath, '/');
|
||||
if (str)
|
||||
{
|
||||
len = str - fullpath;
|
||||
if (len > 0)
|
||||
{
|
||||
rt_memcpy(path, fullpath, len);
|
||||
path[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int _try_readlink(const char *path, struct dfs_mnt *mnt, char *link)
|
||||
{
|
||||
int ret = -1;
|
||||
struct dfs_dentry *dentry = dfs_dentry_lookup(mnt, path, 0);
|
||||
|
||||
if (dentry && dentry->vnode->type == FT_SYMLINK)
|
||||
{
|
||||
if (mnt->fs_ops->readlink)
|
||||
{
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->readlink(dentry, link, DFS_PATH_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
dfs_dentry_unref(dentry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _insert_link_path(const char *link_fn, int link_len, char *tmp_path, int *index)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (link_fn[0] != '/')
|
||||
{
|
||||
if (link_len + 1 <= *index)
|
||||
{
|
||||
*index -= link_len;
|
||||
rt_memcpy(tmp_path + *index, link_fn, link_len);
|
||||
*index -= 1;
|
||||
tmp_path[*index] = '/';
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else if (link_len <= *index)
|
||||
{
|
||||
*index -= link_len;
|
||||
rt_memcpy(tmp_path + *index, link_fn, link_len);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* rw_verify_area doesn't like huge counts. We limit
|
||||
* them to something that fits in "int" so that others
|
||||
@@ -149,166 +213,97 @@ static void dfs_file_unref(struct dfs_file *file)
|
||||
}
|
||||
}
|
||||
|
||||
struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
|
||||
{
|
||||
int ret = 0;
|
||||
struct dfs_dentry *tmp = dfs_dentry_ref(dentry);
|
||||
|
||||
if (dentry && dentry->vnode && dentry->vnode->type == FT_SYMLINK)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
buf = (char *)rt_malloc(DFS_PATH_MAX);
|
||||
if (buf)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (dfs_is_mounted(tmp->mnt) == 0)
|
||||
{
|
||||
ret = tmp->mnt->fs_ops->readlink(tmp, buf, DFS_PATH_MAX);
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
struct dfs_mnt *mnt = NULL;
|
||||
|
||||
if (buf[0] != '/')
|
||||
{
|
||||
char *dir = dfs_dentry_pathname(tmp);
|
||||
|
||||
/* 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(tmp);
|
||||
tmp = de;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (tmp && tmp->vnode->type == FT_SYMLINK);
|
||||
}
|
||||
|
||||
rt_free(buf);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function is creat a nolink path.
|
||||
*
|
||||
* @param mnt
|
||||
* @param fullpath
|
||||
* @param mode 0 middle path nolink; 1 all path nolink.
|
||||
* @param mode
|
||||
*
|
||||
* @return new path.
|
||||
*/
|
||||
char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
|
||||
char *dfs_file_realpath(struct dfs_mnt **mnt, const char *fullpath, int mode)
|
||||
{
|
||||
int index = 0;
|
||||
char *path = RT_NULL;
|
||||
char *link_fn;
|
||||
struct dfs_dentry *dentry = RT_NULL;
|
||||
|
||||
path = (char *)rt_malloc((DFS_PATH_MAX * 2) + 2); // path + \0 + link_fn + \0
|
||||
if (!path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
link_fn = path + DFS_PATH_MAX + 1;
|
||||
int path_len = 0, index = 0;
|
||||
char *path = RT_NULL, *link_fn, *tmp_path;
|
||||
struct dfs_mnt *tmp_mnt;
|
||||
|
||||
if (*mnt && fullpath)
|
||||
{
|
||||
int i = 0;
|
||||
char *fp = fullpath;
|
||||
int len, link_len;
|
||||
|
||||
while ((i = _find_path_node(fp)) > 0)
|
||||
path = (char *)rt_malloc((DFS_PATH_MAX * 3) + 3); // path + \0 + link_fn + \0 + tmp_path + \0
|
||||
if (!path)
|
||||
{
|
||||
if (i + index > DFS_PATH_MAX)
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
link_fn = path + DFS_PATH_MAX + 1;
|
||||
tmp_path = link_fn + (DFS_PATH_MAX + 1);
|
||||
|
||||
len = rt_strlen(fullpath);
|
||||
if (len > DFS_PATH_MAX)
|
||||
{
|
||||
goto _ERR_RET;
|
||||
}
|
||||
|
||||
index = (DFS_PATH_MAX - len);
|
||||
rt_strcpy(tmp_path + index, fullpath);
|
||||
|
||||
if (mode == DFS_REALPATH_ONLY_LAST)
|
||||
{
|
||||
path_len = _get_parent_path(fullpath, path);
|
||||
index += path_len;
|
||||
}
|
||||
|
||||
while ((len = _first_path_len(tmp_path + index)) > 0)
|
||||
{
|
||||
if (len + path_len > DFS_PATH_MAX)
|
||||
{
|
||||
goto _ERR_RET;
|
||||
}
|
||||
|
||||
rt_memcpy(path + index, fp, i);
|
||||
path[index + i] = '\0';
|
||||
rt_memcpy(path + path_len, tmp_path + index, len);
|
||||
path[path_len + len] = '\0';
|
||||
index += len;
|
||||
|
||||
tmp_mnt = dfs_mnt_lookup(path);
|
||||
if (tmp_mnt == RT_NULL)
|
||||
{
|
||||
goto _ERR_RET;
|
||||
}
|
||||
|
||||
*mnt = tmp_mnt;
|
||||
|
||||
/* the last should by mode process. */
|
||||
if ((fp[i] == '\0') && (!mode))
|
||||
if ((tmp_path[index] == '\0') && (mode == DFS_REALPATH_EXCEPT_LAST))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fp += i;
|
||||
|
||||
dentry = dfs_dentry_lookup(*mnt, path, 0);
|
||||
if (dentry && dentry->vnode->type == FT_SYMLINK)
|
||||
link_len = _try_readlink(path, *mnt, link_fn);
|
||||
if (link_len > 0)
|
||||
{
|
||||
int ret = -1;
|
||||
int ret = _insert_link_path(link_fn, link_len, tmp_path, &index);
|
||||
|
||||
if ((*mnt)->fs_ops->readlink)
|
||||
if (ret == 1)
|
||||
{
|
||||
if (dfs_is_mounted((*mnt)) == 0)
|
||||
{
|
||||
ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
|
||||
}
|
||||
/* link_fn[0] == '/' */
|
||||
path_len = 0;
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
int len = rt_strlen(link_fn);
|
||||
|
||||
if (link_fn[0] != '/')
|
||||
{
|
||||
path[index] = '/';
|
||||
}
|
||||
else
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (len + index + 1 >= DFS_PATH_MAX)
|
||||
{
|
||||
goto _ERR_RET;
|
||||
}
|
||||
|
||||
rt_memcpy(path + index, link_fn, len);
|
||||
index += len;
|
||||
path[index] = '\0';
|
||||
*mnt = dfs_mnt_lookup(path);
|
||||
}
|
||||
else
|
||||
else if (ret < 0)
|
||||
{
|
||||
goto _ERR_RET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
index += i;
|
||||
path_len += len;
|
||||
}
|
||||
dfs_dentry_unref(dentry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return path;
|
||||
|
||||
_ERR_RET:
|
||||
rt_free(path);
|
||||
path = RT_NULL;
|
||||
@@ -349,7 +344,7 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
@@ -370,9 +365,12 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||
else
|
||||
{
|
||||
struct dfs_dentry *target_dentry = RT_NULL;
|
||||
|
||||
/* follow symbol link */
|
||||
target_dentry = dfs_file_follow_link(dentry);
|
||||
char *path = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_ONLY_LAST);
|
||||
if (path)
|
||||
{
|
||||
target_dentry = dfs_dentry_lookup(mnt, path, oflags);
|
||||
rt_free(path);
|
||||
}
|
||||
dfs_dentry_unref(dentry);
|
||||
dentry = target_dentry;
|
||||
}
|
||||
@@ -507,7 +505,7 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_E("open %s failed in file system: %s", path, dentry->mnt->fs_ops->name);
|
||||
LOG_I("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);
|
||||
}
|
||||
@@ -791,7 +789,7 @@ int dfs_file_stat(const char *path, struct stat *buf)
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 1);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_NONE);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
@@ -845,7 +843,7 @@ int dfs_file_lstat(const char *path, struct stat *buf)
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
@@ -924,7 +922,7 @@ int dfs_file_setattr(const char *path, struct dfs_attr *attr)
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
@@ -1097,7 +1095,7 @@ int dfs_file_unlink(const char *path)
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
@@ -1199,7 +1197,7 @@ int dfs_file_link(const char *oldname, const char *newname)
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *tmp = dfs_nolink_path(&mnt, old_fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, old_fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(old_fullpath);
|
||||
@@ -1210,7 +1208,7 @@ int dfs_file_link(const char *oldname, const char *newname)
|
||||
new_fullpath = dfs_normalize_path(NULL, newname);
|
||||
if (new_fullpath)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, new_fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, new_fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(new_fullpath);
|
||||
@@ -1310,7 +1308,7 @@ int dfs_file_symlink(const char *target, const char *linkpath)
|
||||
mnt = dfs_mnt_lookup(parent);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, parent, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, parent, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(parent);
|
||||
@@ -1318,7 +1316,7 @@ int dfs_file_symlink(const char *target, const char *linkpath)
|
||||
}
|
||||
|
||||
DLOG(msg, "dfs_file", "dentry", DLOG_MSG, "dfs_dentry_lookup(mnt, %s)", fullpath);
|
||||
dentry = dfs_dentry_lookup(mnt, parent, 0);
|
||||
dentry = dfs_dentry_lookup(mnt, parent, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (dentry)
|
||||
{
|
||||
if (dentry->mnt->fs_ops->symlink)
|
||||
@@ -1326,17 +1324,6 @@ int dfs_file_symlink(const char *target, const char *linkpath)
|
||||
char *path = dfs_normalize_path(parent, target);
|
||||
if (path)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, path, 0);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(path);
|
||||
path = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = path;
|
||||
}
|
||||
|
||||
ret = rt_strncmp(parent, path, strlen(parent));
|
||||
if (ret == 0)
|
||||
{
|
||||
@@ -1346,6 +1333,10 @@ int dfs_file_symlink(const char *target, const char *linkpath)
|
||||
tmp ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = path;
|
||||
}
|
||||
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
@@ -1401,7 +1392,7 @@ int dfs_file_readlink(const char *path, char *buf, int bufsize)
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
@@ -1466,7 +1457,7 @@ int dfs_file_rename(const char *old_file, const char *new_file)
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *tmp = dfs_nolink_path(&mnt, old_fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, old_fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(old_fullpath);
|
||||
@@ -1477,7 +1468,7 @@ int dfs_file_rename(const char *old_file, const char *new_file)
|
||||
new_fullpath = dfs_normalize_path(NULL, new_file);
|
||||
if (new_fullpath)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, new_fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, new_fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(new_fullpath);
|
||||
@@ -1652,7 +1643,7 @@ int dfs_file_isdir(const char *path)
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 1);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_NONE);
|
||||
if (tmp)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
@@ -1853,7 +1844,7 @@ void ls(const char *pathname)
|
||||
mnt = dfs_mnt_lookup(fullpath);
|
||||
if (mnt)
|
||||
{
|
||||
char *tmp = dfs_nolink_path(&mnt, fullpath, 0);
|
||||
char *tmp = dfs_file_realpath(&mnt, fullpath, DFS_REALPATH_EXCEPT_LAST);
|
||||
if (tmp)
|
||||
{
|
||||
char *index;
|
||||
|
||||
@@ -269,7 +269,6 @@ static void dfs_pcache_thread(void *parameter)
|
||||
{
|
||||
page->len = page->size;
|
||||
}
|
||||
//rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, page->page, page->size);
|
||||
if (aspace->ops->write)
|
||||
{
|
||||
aspace->ops->write(page);
|
||||
@@ -676,9 +675,14 @@ static int dfs_page_unmap(struct dfs_page *page)
|
||||
|
||||
if (map)
|
||||
{
|
||||
void *vaddr = dfs_aspace_vaddr(map->varea, page->fpos);
|
||||
//rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, vaddr, ARCH_PAGE_SIZE);
|
||||
rt_varea_unmap_page(map->varea, vaddr);
|
||||
rt_varea_t varea;
|
||||
void *vaddr;
|
||||
|
||||
varea = rt_aspace_query(map->aspace, map->vaddr);
|
||||
RT_ASSERT(varea);
|
||||
vaddr = dfs_aspace_vaddr(varea, page->fpos);
|
||||
|
||||
rt_varea_unmap_page(varea, vaddr);
|
||||
|
||||
rt_free(map);
|
||||
}
|
||||
@@ -741,7 +745,6 @@ static void dfs_page_release(struct dfs_page *page)
|
||||
{
|
||||
page->len = page->size;
|
||||
}
|
||||
//rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, page->page, page->size);
|
||||
if (aspace->ops->write)
|
||||
{
|
||||
aspace->ops->write(page);
|
||||
@@ -995,7 +998,6 @@ static struct dfs_page *dfs_aspace_load_page(struct dfs_file *file, off_t pos)
|
||||
page->size = ARCH_PAGE_SIZE;
|
||||
page->fpos = pos / ARCH_PAGE_SIZE * ARCH_PAGE_SIZE;
|
||||
aspace->ops->read(file, page);
|
||||
//rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, page->page, page->size);
|
||||
page->ref_count ++;
|
||||
|
||||
dfs_page_insert(page);
|
||||
@@ -1105,7 +1107,6 @@ int dfs_aspace_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
|
||||
len = count > len ? len : count;
|
||||
if (len)
|
||||
{
|
||||
//rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, page->page, page->size);
|
||||
rt_memcpy(ptr, page->page + *pos - page->fpos, len);
|
||||
ptr += len;
|
||||
*pos += len;
|
||||
@@ -1158,7 +1159,6 @@ int dfs_aspace_write(struct dfs_file *file, const void *buf, size_t count, off_t
|
||||
len = page->fpos + ARCH_PAGE_SIZE - *pos;
|
||||
len = count > len ? len : count;
|
||||
rt_memcpy(page->page + *pos - page->fpos, ptr, len);
|
||||
//rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, page->page, page->size);
|
||||
ptr += len;
|
||||
*pos += len;
|
||||
count -= len;
|
||||
@@ -1225,7 +1225,7 @@ int dfs_aspace_flush(struct dfs_aspace *aspace)
|
||||
{
|
||||
page->len = page->size;
|
||||
}
|
||||
//rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, page->page, page->size);
|
||||
|
||||
if (aspace->ops->write)
|
||||
{
|
||||
aspace->ops->write(page);
|
||||
@@ -1277,6 +1277,7 @@ void *dfs_aspace_mmap(struct dfs_file *file, struct rt_varea *varea, void *vaddr
|
||||
void *ret = RT_NULL;
|
||||
struct dfs_page *page;
|
||||
struct dfs_aspace *aspace = file->vnode->aspace;
|
||||
rt_aspace_t target_aspace = varea->aspace;
|
||||
|
||||
page = dfs_page_lookup(file, dfs_aspace_fpos(varea, vaddr));
|
||||
if (page)
|
||||
@@ -1284,7 +1285,8 @@ void *dfs_aspace_mmap(struct dfs_file *file, struct rt_varea *varea, void *vaddr
|
||||
struct dfs_mmap *map = (struct dfs_mmap *)rt_calloc(1, sizeof(struct dfs_mmap));
|
||||
if (map)
|
||||
{
|
||||
void *pg_paddr = rt_kmem_v2p(page->page);
|
||||
void *pg_vaddr = page->page;
|
||||
void *pg_paddr = rt_kmem_v2p(pg_vaddr);
|
||||
int err = rt_varea_map_range(varea, vaddr, pg_paddr, page->size);
|
||||
if (err == RT_EOK)
|
||||
{
|
||||
@@ -1301,10 +1303,12 @@ void *dfs_aspace_mmap(struct dfs_file *file, struct rt_varea *varea, void *vaddr
|
||||
* fetching of the next instruction can see the coherent data with the data cache,
|
||||
* TLB, MMU, main memory, and all the other observers in the computer system.
|
||||
*/
|
||||
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, vaddr, ARCH_PAGE_SIZE);
|
||||
rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, vaddr, ARCH_PAGE_SIZE);
|
||||
|
||||
ret = page->page;
|
||||
map->varea = varea;
|
||||
ret = pg_vaddr;
|
||||
map->aspace = target_aspace;
|
||||
map->vaddr = vaddr;
|
||||
dfs_aspace_lock(aspace);
|
||||
rt_list_insert_after(&page->mmap_head, &map->mmap_node);
|
||||
dfs_page_release(page);
|
||||
@@ -1329,6 +1333,8 @@ int dfs_aspace_unmap(struct dfs_file *file, struct rt_varea *varea)
|
||||
{
|
||||
struct dfs_vnode *vnode = file->vnode;
|
||||
struct dfs_aspace *aspace = vnode->aspace;
|
||||
void *unmap_start = varea->start;
|
||||
void *unmap_end = (char *)unmap_start + varea->size;
|
||||
|
||||
if (aspace)
|
||||
{
|
||||
@@ -1347,20 +1353,32 @@ int dfs_aspace_unmap(struct dfs_file *file, struct rt_varea *varea)
|
||||
{
|
||||
rt_list_t *node, *tmp;
|
||||
struct dfs_mmap *map;
|
||||
rt_varea_t map_varea = RT_NULL;
|
||||
|
||||
node = page->mmap_head.next;
|
||||
|
||||
while (node != &page->mmap_head)
|
||||
{
|
||||
rt_aspace_t map_aspace;
|
||||
map = rt_list_entry(node, struct dfs_mmap, mmap_node);
|
||||
tmp = node;
|
||||
node = node->next;
|
||||
|
||||
if (map && varea == map->varea)
|
||||
if (map && varea->aspace == map->aspace
|
||||
&& map->vaddr >= unmap_start && map->vaddr < unmap_end)
|
||||
{
|
||||
void *vaddr = dfs_aspace_vaddr(map->varea, page->fpos);
|
||||
void *vaddr = map->vaddr;
|
||||
map_aspace = map->aspace;
|
||||
|
||||
rt_varea_unmap_page(map->varea, vaddr);
|
||||
if (!map_varea || map_varea->aspace != map_aspace ||
|
||||
vaddr < map_varea->start ||
|
||||
vaddr >= map_varea->start + map_varea->size)
|
||||
{
|
||||
/* lock the tree so we don't access uncompleted data */
|
||||
map_varea = rt_aspace_query(map_aspace, vaddr);
|
||||
}
|
||||
|
||||
rt_varea_unmap_page(map_varea, vaddr);
|
||||
|
||||
if (varea->attr == MMU_MAP_U_RWCB && page->fpos < page->aspace->vnode->size)
|
||||
{
|
||||
@@ -1405,7 +1423,7 @@ int dfs_aspace_page_unmap(struct dfs_file *file, struct rt_varea *varea, void *v
|
||||
tmp = node;
|
||||
node = node->next;
|
||||
|
||||
if (map && varea == map->varea)
|
||||
if (map && varea->aspace == map->aspace && vaddr == map->vaddr)
|
||||
{
|
||||
if (varea->attr == MMU_MAP_U_RWCB)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user