summaryrefslogtreecommitdiff
path: root/components/dfs/src
diff options
context:
space:
mode:
authorguo <[email protected]>2022-12-03 12:07:44 +0800
committerGitHub <[email protected]>2022-12-03 12:07:44 +0800
commitecf2d8215961ca7c539132b62a72df6072cc3e14 (patch)
tree59005f0f74f2593c0435059264f624c862a89f55 /components/dfs/src
parentaaf5462c6d4ae9466a0a8cd2a4bb00cfe1fef2f2 (diff)
sync branch rt-smart. (#6641)
* Synchronize the code of the rt mart branch to the master branch. * TTY device * Add lwP code from rt-smart * Add vnode in DFS, but DFS will be re-write for rt-smart * There are three libcpu for rt-smart: * arm/cortex-a, arm/aarch64 * riscv64 Co-authored-by: Rbb666 <[email protected]> Co-authored-by: zhkag <[email protected]>
Diffstat (limited to 'components/dfs/src')
-rw-r--r--components/dfs/src/dfs.c605
-rw-r--r--components/dfs/src/dfs_file.c412
-rw-r--r--components/dfs/src/dfs_fs.c17
-rw-r--r--components/dfs/src/dfs_posix.c131
4 files changed, 917 insertions, 248 deletions
diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c
index f1d7571c0c..f3f9c2354b 100644
--- a/components/dfs/src/dfs.c
+++ b/components/dfs/src/dfs.c
@@ -28,12 +28,14 @@ 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
@@ -54,6 +56,9 @@ int dfs_init(void)
return 0;
}
+ /* init vnode hash table */
+ dfs_fnode_mgr_init();
+
/* clear filesystem operations table */
rt_memset((void *)filesystem_operation_table, 0, sizeof(filesystem_operation_table));
/* clear filesystem table */
@@ -63,6 +68,7 @@ int dfs_init(void)
/* 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 */
@@ -70,6 +76,13 @@ int dfs_init(void)
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);
@@ -79,6 +92,13 @@ int dfs_init(void)
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;
@@ -107,6 +127,21 @@ void dfs_lock(void)
}
}
+void dfs_fd_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);
+ }
+}
+
/**
* this function will lock device file system.
*
@@ -118,51 +153,95 @@ void dfs_unlock(void)
}
#ifdef DFS_USING_POSIX
-static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
+
+void dfs_fd_unlock(void)
{
- int idx;
+ rt_mutex_release(&fdlock);
+}
- /* find an empty fd entry */
- for (idx = startfd; idx < (int)fdt->maxfd; idx++)
+static int fd_slot_expand(struct dfs_fdtable *fdt, int fd)
+{
+ int nr;
+ int index;
+ struct dfs_fd **fds = NULL;
+
+ if (fd < fdt->maxfd)
{
- if (fdt->fds[idx] == RT_NULL)
- break;
- if (fdt->fds[idx]->ref_count == 0)
- break;
+ return fd;
+ }
+ if (fd >= DFS_FD_MAX)
+ {
+ return -1;
}
- /* allocate a larger FD container */
- if (idx == (int)fdt->maxfd && fdt->maxfd < DFS_FD_MAX)
+ nr = ((fd + 4) & ~3);
+ if (nr > DFS_FD_MAX)
{
- int cnt, index;
- struct dfs_fd **fds;
+ nr = DFS_FD_MAX;
+ }
+ fds = (struct dfs_fd **)rt_realloc(fdt->fds, nr * sizeof(struct dfs_fd *));
+ if (!fds)
+ {
+ return -1;
+ }
- /* increase the number of FD with 4 step length */
- cnt = fdt->maxfd + 4;
- cnt = cnt > DFS_FD_MAX ? DFS_FD_MAX : cnt;
+ /* clean the new allocated fds */
+ for (index = fdt->maxfd; index < nr; index++)
+ {
+ fds[index] = NULL;
+ }
+ fdt->fds = fds;
+ fdt->maxfd = nr;
- fds = (struct dfs_fd **)rt_realloc(fdt->fds, cnt * sizeof(struct dfs_fd *));
- if (fds == NULL) goto __exit; /* return fdt->maxfd */
+ return fd;
+}
+
+static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd)
+{
+ int idx;
- /* clean the new allocated fds */
- for (index = (int)fdt->maxfd; index < cnt; index ++)
+ /* find an empty fd slot */
+ for (idx = startfd; idx < (int)fdt->maxfd; idx++)
+ {
+ if (fdt->fds[idx] == RT_NULL)
{
- fds[index] = NULL;
+ return idx;
}
+ }
- fdt->fds = fds;
- fdt->maxfd = cnt;
+ idx = fdt->maxfd;
+ if (idx < startfd)
+ {
+ idx = startfd;
}
+ if (fd_slot_expand(fdt, idx) < 0)
+ {
+ return -1;
+ }
+ return idx;
+}
+static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
+{
+ int idx;
+ struct dfs_fd *fd = NULL;
+
+ idx = fd_slot_alloc(fdt, startfd);
/* allocate 'struct dfs_fd' */
- if (idx < (int)fdt->maxfd && fdt->fds[idx] == RT_NULL)
+ if (idx < 0)
{
- fdt->fds[idx] = (struct dfs_fd *)rt_calloc(1, sizeof(struct dfs_fd));
- if (fdt->fds[idx] == RT_NULL)
- idx = fdt->maxfd;
+ return -1;
}
+ fd = (struct dfs_fd *)rt_calloc(1, sizeof(struct dfs_fd));
+ if (!fd)
+ {
+ return -1;
+ }
+ fd->ref_count = 1;
+ fd->magic = DFS_FD_MAGIC;
+ fd->vnode = NULL;
+ fdt->fds[idx] = fd;
-__exit:
return idx;
}
@@ -172,34 +251,32 @@ __exit:
*
* @return -1 on failed or the allocated file descriptor.
*/
-int fd_new(void)
+int fdt_fd_new(struct dfs_fdtable *fdt)
{
- struct dfs_fd *d;
int idx;
- struct dfs_fdtable *fdt;
- fdt = dfs_fdtable_get();
/* lock filesystem */
- dfs_lock();
+ dfs_fd_lock();
/* find an empty fd entry */
- idx = fd_alloc(fdt, 0);
+ idx = fd_alloc(fdt, DFS_STDIO_OFFSET);
/* can't find an empty fd entry */
- if (idx == (int)fdt->maxfd)
+ if (idx < 0)
{
- idx = -(1 + DFS_FD_OFFSET);
LOG_E("DFS fd new is failed! Could not found an empty fd entry.");
- goto __result;
}
- d = fdt->fds[idx];
- d->ref_count = 1;
- d->magic = DFS_FD_MAGIC;
+ dfs_fd_unlock();
+ return idx;
+}
-__result:
- dfs_unlock();
- return idx + DFS_FD_OFFSET;
+int fd_new(void)
+{
+ struct dfs_fdtable *fdt = NULL;
+
+ fdt = dfs_fdtable_get();
+ return fdt_fd_new(fdt);
}
/**
@@ -211,69 +288,119 @@ __result:
* @return NULL on on this file descriptor or the file descriptor structure
* pointer.
*/
-struct dfs_fd *fd_get(int fd)
+
+struct dfs_fd *fdt_fd_get(struct dfs_fdtable* fdt, int fd)
{
struct dfs_fd *d;
- struct dfs_fdtable *fdt;
-#ifdef RT_USING_POSIX_STDIO
- if ((0 <= fd) && (fd <= 2))
- fd = libc_stdio_get_console();
-#endif /* RT_USING_POSIX_STDIO */
-
- fdt = dfs_fdtable_get();
- fd = fd - DFS_FD_OFFSET;
if (fd < 0 || fd >= (int)fdt->maxfd)
+ {
return NULL;
+ }
- dfs_lock();
+ dfs_fd_lock();
d = fdt->fds[fd];
/* check dfs_fd valid or not */
if ((d == NULL) || (d->magic != DFS_FD_MAGIC))
{
- dfs_unlock();
+ dfs_fd_unlock();
return NULL;
}
- /* increase the reference count */
- d->ref_count ++;
- dfs_unlock();
+ dfs_fd_unlock();
return d;
}
+struct dfs_fd *fd_get(int fd)
+{
+ struct dfs_fdtable *fdt;
+
+ fdt = dfs_fdtable_get();
+ return fdt_fd_get(fdt, fd);
+}
+
/**
* @ingroup Fd
*
* This function will put the file descriptor.
*/
-void fd_put(struct dfs_fd *fd)
+void fdt_fd_release(struct dfs_fdtable* fdt, int fd)
{
- RT_ASSERT(fd != NULL);
+ struct dfs_fd *fd_slot = NULL;
- dfs_lock();
+ RT_ASSERT(fdt != NULL);
- fd->ref_count --;
+ dfs_fd_lock();
- /* clear this fd entry */
- if (fd->ref_count == 0)
+ if ((fd < 0) || (fd >= fdt->maxfd))
{
- int index;
- struct dfs_fdtable *fdt;
+ dfs_fd_unlock();
+ return;
+ }
+
+ fd_slot = fdt->fds[fd];
+ if (fd_slot == NULL)
+ {
+ dfs_fd_unlock();
+ return;
+ }
+ fdt->fds[fd] = NULL;
- fdt = dfs_fdtable_get();
- for (index = 0; index < (int)fdt->maxfd; index ++)
+ /* 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_fnode *vnode = fd_slot->vnode;
+ if (vnode)
{
- if (fdt->fds[index] == fd)
- {
- rt_free(fd);
- fdt->fds[index] = 0;
- break;
- }
+ vnode->ref_count--;
}
+ rt_free(fd_slot);
}
- dfs_unlock();
+ dfs_fd_unlock();
+}
+
+void fd_release(int fd)
+{
+ struct dfs_fdtable *fdt;
+
+ fdt = dfs_fdtable_get();
+ fdt_fd_release(fdt, fd);
+}
+
+int sys_dup(int oldfd)
+{
+ int newfd = -1;
+ struct dfs_fdtable *fdt = NULL;
+
+ dfs_fd_lock();
+ /* check old fd */
+ fdt = dfs_fdtable_get();
+ if ((oldfd < 0) || (oldfd >= fdt->maxfd))
+ {
+ goto exit;
+ }
+ if (!fdt->fds[oldfd])
+ {
+ goto exit;
+ }
+ /* get a new fd */
+ newfd = fd_slot_alloc(fdt, DFS_STDIO_OFFSET);
+ if (newfd >= 0)
+ {
+ fdt->fds[newfd] = fdt->fds[oldfd];
+ /* inc ref_count */
+ fdt->fds[newfd]->ref_count++;
+ }
+exit:
+ dfs_fd_unlock();
+ return newfd;
}
#endif /* DFS_USING_POSIX */
@@ -320,9 +447,9 @@ int fd_is_open(const char *pathname)
for (index = 0; index < fdt->maxfd; index++)
{
fd = fdt->fds[index];
- if (fd == NULL || fd->fops == NULL || fd->path == NULL) continue;
+ if (fd == NULL || fd->vnode->fops == NULL || fd->vnode->path == NULL) continue;
- if (fd->fs == fs && strcmp(fd->path, mountpath) == 0)
+ if (fd->vnode->fs == fs && strcmp(fd->vnode->path, mountpath) == 0)
{
/* found file in file descriptor table */
rt_free(fullpath);
@@ -339,6 +466,139 @@ int fd_is_open(const char *pathname)
return -1;
}
+int sys_dup2(int oldfd, int newfd)
+{
+ struct dfs_fdtable *fdt = NULL;
+ int ret = 0;
+ int retfd = -1;
+
+ dfs_fd_lock();
+ /* check old fd */
+ fdt = dfs_fdtable_get();
+ if ((oldfd < 0) || (oldfd >= fdt->maxfd))
+ {
+ goto exit;
+ }
+ if (!fdt->fds[oldfd])
+ {
+ goto exit;
+ }
+ if (newfd < 0)
+ {
+ goto exit;
+ }
+ if (newfd >= fdt->maxfd)
+ {
+ newfd = fd_slot_expand(fdt, newfd);
+ if (newfd < 0)
+ {
+ goto exit;
+ }
+ }
+ if (fdt->fds[newfd] == fdt->fds[oldfd])
+ {
+ /* ok, return newfd */
+ retfd = newfd;
+ goto exit;
+ }
+
+ if (fdt->fds[newfd])
+ {
+ ret = dfs_file_close(fdt->fds[newfd]);
+ if (ret < 0)
+ {
+ goto exit;
+ }
+ fd_release(newfd);
+ }
+
+ fdt->fds[newfd] = fdt->fds[oldfd];
+ /* inc ref_count */
+ fdt->fds[newfd]->ref_count++;
+ retfd = newfd;
+exit:
+ dfs_fd_unlock();
+ return retfd;
+}
+
+static int fd_get_fd_index_form_fdt(struct dfs_fdtable *fdt, struct dfs_fd *file)
+{
+ int fd = -1;
+
+ if (file == RT_NULL)
+ {
+ return -1;
+ }
+
+ dfs_fd_lock();
+
+ for(int index = 0; index < (int)fdt->maxfd; index++)
+ {
+ if(fdt->fds[index] == file)
+ {
+ fd = index;
+ break;
+ }
+ }
+
+ dfs_fd_unlock();
+
+ return fd;
+}
+
+int fd_get_fd_index(struct dfs_fd *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_fd *file)
+{
+ int retfd = -1;
+
+ if (!file)
+ {
+ return retfd;
+ }
+ if (!fdt)
+ {
+ return retfd;
+ }
+
+ dfs_fd_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_fd_unlock();
+ return retfd;
+}
+
+void fd_init(struct dfs_fd *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.
*
@@ -383,7 +643,13 @@ char *dfs_normalize_path(const char *directory, const char *filename)
#ifdef DFS_USING_WORKDIR
if (directory == NULL) /* shall use working directory */
+ {
+#ifdef RT_USING_LWP
+ directory = lwp_getcwd();
+#else
directory = &working_directory[0];
+#endif
+ }
#else
if ((directory == NULL) && (filename[0] != '/'))
{
@@ -422,14 +688,14 @@ 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 */
src += 2;
while ((*src == '/') && (*src != '\0'))
- src ++;
+ src++;
continue;
}
else if (src[1] == '.')
@@ -446,7 +712,7 @@ char *dfs_normalize_path(const char *directory, const char *filename)
src += 3;
while ((*src == '/') && (*src != '\0'))
- src ++;
+ src++;
goto up_one;
}
}
@@ -454,15 +720,15 @@ char *dfs_normalize_path(const char *directory, const char *filename)
/* copy up the next '/' and erase all '/' */
while ((c = *src++) != '\0' && c != '/')
- *dst ++ = c;
+ *dst++ = c;
if (c == '/')
{
- *dst ++ = '/';
+ *dst++ = '/';
while (c == '/')
c = *src++;
- src --;
+ src--;
}
else if (!c)
break;
@@ -470,20 +736,25 @@ char *dfs_normalize_path(const char *directory, const char *filename)
continue;
up_one:
- dst --;
- if (dst < dst0)
+ /* keep the topmost root directory */
+ if (dst - dst0 != 1 || dst[-1] != '/')
{
- rt_free(fullpath);
- return NULL;
+ dst--;
+
+ if (dst < dst0)
+ {
+ rt_free(fullpath);
+ return NULL;
+ }
}
while (dst0 < dst && dst[-1] != '/')
- dst --;
+ dst--;
}
*dst = '\0';
/* remove '/' in the end of path if exist */
- dst --;
+ dst--;
if ((dst != fullpath) && (*dst == '/'))
*dst = '\0';
@@ -519,6 +790,27 @@ struct dfs_fdtable *dfs_fdtable_get(void)
return fdt;
}
+#ifdef RT_USING_LWP
+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
int list_fd(void)
{
@@ -532,28 +824,97 @@ int list_fd(void)
rt_kprintf("fd type ref magic path\n");
rt_kprintf("-- ------ --- ----- ------\n");
- for (index = 0; index < (int)fd_table->maxfd; index ++)
+ for (index = 0; index < (int)fd_table->maxfd; index++)
{
struct dfs_fd *fd = fd_table->fds[index];
- if (fd && fd->fops)
+ if (fd && fd->vnode->fops)
{
- rt_kprintf("%2d ", index + DFS_FD_OFFSET);
- if (fd->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir");
- else if (fd->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
- else if (fd->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket");
- else if (fd->type == FT_USER) rt_kprintf("%-7.7s ", "user");
- else if (fd->type == FT_DEVICE) rt_kprintf("%-7.7s ", "device");
+ 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("%3d ", fd->ref_count);
+ rt_kprintf("%3d ", fd->vnode->ref_count);
rt_kprintf("%04x ", fd->magic);
- if (fd->fs && fd->fs->path && rt_strlen(fd->fs->path) > 1)
+ if (fd->vnode->path)
{
- rt_kprintf("%s", fd->fs->path);
+ rt_kprintf("%s\n", fd->vnode->path);
}
- if (fd->path)
+ else
{
- rt_kprintf("%s\n", fd->path);
+ rt_kprintf("\n");
+ }
+ }
+ }
+ dfs_unlock();
+
+ return 0;
+}
+
+#ifdef RT_USING_LWP
+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_fd *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);
}
else
{
@@ -561,10 +922,50 @@ int list_fd(void)
}
}
}
- dfs_unlock();
+ rt_exit_critical();
+
+ return 0;
+}
+
+int lsof(int argc, char *argv[])
+{
+ rt_kprintf("PID fd type fd-ref magic vnode vnode/data addr path \n");
+
+ if (argc == 1)
+ {
+ 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 rt_lwp *lwp = (struct rt_lwp *)pids[index].data;
+
+ if (lwp)
+ {
+ list = &lwp->t_grp;
+ for (node = list->next; node != list; node = node->next)
+ {
+ lsofp(lwp_to_pid(lwp));
+ }
+ }
+ }
+ }
+ else if (argc == 3)
+ {
+ if (argv[1][0] == '-' && argv[1][1] == 'p')
+ {
+ int pid = atoi(argv[2]);
+ lsofp(pid);
+ }
+ }
return 0;
}
-#endif /* RT_USING_FINSH */
+MSH_CMD_EXPORT(lsof, list open files);
+#endif /* RT_USING_LWP */
+#endif
/*@}*/
+
diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c
index a798bd3c59..1f6f0d1e29 100644
--- a/components/dfs/src/dfs_file.c
+++ b/components/dfs/src/dfs_file.c
@@ -14,6 +14,78 @@
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_private.h>
+#include <unistd.h>
+
+#define DFS_FNODE_HASH_NR 128
+
+struct dfs_fnode_mgr
+{
+ struct rt_mutex lock;
+ rt_list_t head[DFS_FNODE_HASH_NR];
+};
+
+static struct dfs_fnode_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_fnode_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++)
+ {
+ rt_list_init(&dfs_fm.head[i]);
+ }
+}
+
+/* BKDR Hash Function */
+static unsigned int bkdr_hash(const char *str)
+{
+ unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
+ unsigned int hash = 0;
+
+ while (*str)
+ {
+ hash = hash * seed + (*str++);
+ }
+
+ return (hash % DFS_FNODE_HASH_NR);
+}
+
+static struct dfs_fnode *dfs_fnode_find(const char *path, rt_list_t **hash_head)
+{
+ struct dfs_fnode *vnode = NULL;
+ int hash = bkdr_hash(path);
+ rt_list_t *hh;
+
+ hh = dfs_fm.head[hash].next;
+
+ if (hash_head)
+ {
+ *hash_head = &dfs_fm.head[hash];
+ }
+
+ while (hh != &dfs_fm.head[hash])
+ {
+ vnode = rt_container_of(hh, struct dfs_fnode, list);
+ if (rt_strcmp(path, vnode->fullpath) == 0)
+ {
+ /* found */
+ return vnode;
+ }
+ hh = hh->next;
+ }
+ return NULL;
+}
/**
* @addtogroup FileApi
@@ -22,6 +94,34 @@
/*@{*/
/**
+ * 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)
+{
+ char *fullpath = NULL;
+ struct dfs_fnode *vnode = NULL;
+ int ret = 0;
+
+ fullpath = dfs_normalize_path(NULL, pathname);
+
+ dfs_fm_lock();
+ vnode = dfs_fnode_find(fullpath, NULL);
+ if (vnode)
+ {
+ ret = 1;
+ }
+ dfs_fm_unlock();
+
+ rt_free(fullpath);
+ return ret;
+}
+
+
+/**
* this function will open a file which specified by path with specified flags.
*
* @param fd the file descriptor pointer to return the corresponding result.
@@ -35,6 +135,8 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
struct dfs_filesystem *fs;
char *fullpath;
int result;
+ struct dfs_fnode *vnode = NULL;
+ rt_list_t *hash_head;
/* parameter check */
if (fd == NULL)
@@ -49,56 +151,101 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
LOG_D("open file:%s", fullpath);
- /* find filesystem */
- fs = dfs_filesystem_lookup(fullpath);
- if (fs == NULL)
+ dfs_fm_lock();
+ /* vnode find */
+ vnode = dfs_fnode_find(fullpath, &hash_head);
+ if (vnode)
{
+ vnode->ref_count++;
+ fd->pos = 0;
+ fd->vnode = vnode;
+ dfs_fm_unlock();
rt_free(fullpath); /* release path */
-
- return -ENOENT;
}
+ else
+ {
+ /* find filesystem */
+ fs = dfs_filesystem_lookup(fullpath);
+ if (fs == NULL)
+ {
+ dfs_fm_unlock();
+ rt_free(fullpath); /* release path */
+ return -ENOENT;
+ }
+
+ vnode = rt_calloc(1, sizeof(struct dfs_fnode));
+ if (!vnode)
+ {
+ dfs_fm_unlock();
+ rt_free(fullpath); /* release path */
+ return -ENOMEM;
+ }
+ vnode->ref_count = 1;
- LOG_D("open in filesystem:%s", fs->ops->name);
- fd->fs = fs; /* set file system */
- fd->fops = fs->ops->fops; /* set file ops */
+ 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 */
- fd->type = FT_REGULAR;
- fd->flags = flags;
- fd->size = 0;
- fd->pos = 0;
- fd->data = fs;
+ /* 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)
- fd->path = rt_strdup("/");
+ 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);
+ }
else
- fd->path = rt_strdup(dfs_subdir(fs->path, fullpath));
- rt_free(fullpath);
- LOG_D("Actual file path: %s", fd->path);
- }
- else
- {
- fd->path = fullpath;
- }
+ {
+ vnode->path = fullpath;
+ }
+ vnode->fullpath = fullpath;
- /* specific file system open routine */
- if (fd->fops->open == NULL)
- {
- /* clear fd */
- rt_free(fd->path);
- fd->path = NULL;
+ /* 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;
+ return -ENOSYS;
+ }
+
+ fd->pos = 0;
+ fd->vnode = vnode;
+
+ /* insert vnode to hash */
+ rt_list_insert_after(hash_head, &vnode->list);
}
- if ((result = fd->fops->open(fd)) < 0)
+ fd->flags = flags;
+
+ if ((result = vnode->fops->open(fd)) < 0)
{
- /* clear fd */
- rt_free(fd->path);
- fd->path = NULL;
+ 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;
@@ -107,9 +254,10 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
fd->flags |= DFS_F_OPEN;
if (flags & O_DIRECTORY)
{
- fd->type = FT_DIRECTORY;
+ fd->vnode->type = FT_DIRECTORY;
fd->flags |= DFS_F_DIRECTORY;
}
+ dfs_fm_unlock();
LOG_D("open successful");
return 0;
@@ -124,20 +272,52 @@ int dfs_file_open(struct dfs_fd *fd, const char *path, int flags)
*/
int dfs_file_close(struct dfs_fd *fd)
{
+ struct dfs_fnode *vnode = NULL;
int result = 0;
if (fd == NULL)
+ {
return -ENXIO;
+ }
- if (fd->fops->close != NULL)
- result = fd->fops->close(fd);
+ if (fd->ref_count == 1)
+ {
+ dfs_fm_lock();
+ vnode = fd->vnode;
- /* close fd error, return */
- if (result < 0)
- return result;
+ if (vnode->ref_count <= 0)
+ {
+ dfs_fm_unlock();
+ return -ENXIO;
+ }
- rt_free(fd->path);
- fd->path = NULL;
+ 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)
+ {
+ rt_free(vnode->fullpath);
+ }
+ rt_free(vnode->path);
+ rt_free(vnode);
+ }
+ dfs_fm_unlock();
+ }
return result;
}
@@ -154,10 +334,12 @@ int dfs_file_close(struct dfs_fd *fd)
int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
{
if (fd == NULL)
+ {
return -EINVAL;
+ }
/* regular file system fd */
- if (fd->type == FT_REGULAR)
+ if (fd->vnode->type == FT_REGULAR || fd->vnode->type == FT_DEVICE)
{
switch (cmd)
{
@@ -176,8 +358,10 @@ int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args)
}
}
- if (fd->fops->ioctl != NULL)
- return fd->fops->ioctl(fd, cmd, args);
+ if (fd->vnode->fops->ioctl != NULL)
+ {
+ return fd->vnode->fops->ioctl(fd, cmd, args);
+ }
return -ENOSYS;
}
@@ -197,13 +381,19 @@ int dfs_file_read(struct dfs_fd *fd, void *buf, size_t len)
int result = 0;
if (fd == NULL)
+ {
return -EINVAL;
+ }
- if (fd->fops->read == NULL)
+ if (fd->vnode->fops->read == NULL)
+ {
return -ENOSYS;
+ }
- if ((result = fd->fops->read(fd, buf, len)) < 0)
+ if ((result = fd->vnode->fops->read(fd, buf, len)) < 0)
+ {
fd->flags |= DFS_F_EOF;
+ }
return result;
}
@@ -220,11 +410,20 @@ int dfs_file_read(struct dfs_fd *fd, void *buf, size_t len)
int dfs_file_getdents(struct dfs_fd *fd, struct dirent *dirp, size_t nbytes)
{
/* parameter check */
- if (fd == NULL || fd->type != FT_DIRECTORY)
+ if (fd == NULL)
+ {
+ return -EINVAL;
+ }
+
+ if (fd->vnode->type != FT_DIRECTORY)
+ {
return -EINVAL;
+ }
- if (fd->fops->getdents != NULL)
- return fd->fops->getdents(fd, dirp, nbytes);
+ if (fd->vnode->fops->getdents != NULL)
+ {
+ return fd->vnode->fops->getdents(fd, dirp, nbytes);
+ }
return -ENOSYS;
}
@@ -249,17 +448,17 @@ int dfs_file_unlink(const char *path)
return -EINVAL;
}
- /* get filesystem */
- if ((fs = dfs_filesystem_lookup(fullpath)) == NULL)
+ /* Check whether file is already open */
+ if (dfs_file_is_open(fullpath))
{
- result = -ENOENT;
+ result = -EBUSY;
goto __exit;
}
- /* Check whether file is already open */
- if (fd_is_open(fullpath) == 0)
+ /* get filesystem */
+ if ((fs = dfs_filesystem_lookup(fullpath)) == NULL)
{
- result = -EBUSY;
+ result = -ENOENT;
goto __exit;
}
@@ -294,12 +493,16 @@ __exit:
int dfs_file_write(struct dfs_fd *fd, const void *buf, size_t len)
{
if (fd == NULL)
+ {
return -EINVAL;
+ }
- if (fd->fops->write == NULL)
+ if (fd->vnode->fops->write == NULL)
+ {
return -ENOSYS;
+ }
- return fd->fops->write(fd, buf, len);
+ return fd->vnode->fops->write(fd, buf, len);
}
/**
@@ -314,10 +517,10 @@ int dfs_file_flush(struct dfs_fd *fd)
if (fd == NULL)
return -EINVAL;
- if (fd->fops->flush == NULL)
+ if (fd->vnode->fops->flush == NULL)
return -ENOSYS;
- return fd->fops->flush(fd);
+ return fd->vnode->fops->flush(fd);
}
/**
@@ -335,10 +538,10 @@ int dfs_file_lseek(struct dfs_fd *fd, off_t offset)
if (fd == NULL)
return -EINVAL;
- if (fd->fops->lseek == NULL)
+ if (fd->vnode->fops->lseek == NULL)
return -ENOSYS;
- result = fd->fops->lseek(fd, offset);
+ result = fd->vnode->fops->lseek(fd, offset);
/* update current position */
if (result >= 0)
@@ -425,11 +628,10 @@ int dfs_file_stat(const char *path, struct stat *buf)
*/
int dfs_file_rename(const char *oldpath, const char *newpath)
{
- int result;
- struct dfs_filesystem *oldfs, *newfs;
- char *oldfullpath, *newfullpath;
+ int result = RT_EOK;
+ struct dfs_filesystem *oldfs = NULL, *newfs = NULL;
+ char *oldfullpath = NULL, *newfullpath = NULL;
- result = RT_EOK;
newfullpath = NULL;
oldfullpath = NULL;
@@ -440,6 +642,12 @@ int dfs_file_rename(const char *oldpath, const char *newpath)
goto __exit;
}
+ if (dfs_file_is_open((const char *)oldfullpath))
+ {
+ result = -EBUSY;
+ goto __exit;
+ }
+
newfullpath = dfs_normalize_path(NULL, newpath);
if (newfullpath == NULL)
{
@@ -473,8 +681,14 @@ int dfs_file_rename(const char *oldpath, const char *newpath)
}
__exit:
- rt_free(oldfullpath);
- rt_free(newfullpath);
+ if (oldfullpath)
+ {
+ rt_free(oldfullpath);
+ }
+ if (newfullpath)
+ {
+ rt_free(newfullpath);
+ }
/* not at same file system, return EXDEV */
return result;
@@ -494,28 +708,52 @@ int dfs_file_ftruncate(struct dfs_fd *fd, off_t length)
int result;
/* fd is null or not a regular file system fd, or length is invalid */
- if (fd == NULL || fd->type != FT_REGULAR || length < 0)
+ if (fd == NULL || fd->vnode->type != FT_REGULAR || length < 0)
return -EINVAL;
- if (fd->fops->ioctl == NULL)
+ if (fd->vnode->fops->ioctl == NULL)
return -ENOSYS;
- result = fd->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length);
+ result = fd->vnode->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length);
/* update current size */
if (result == 0)
- fd->size = length;
+ fd->vnode->size = length;
return result;
}
+int dfs_file_mmap2(struct dfs_fd *fd, struct dfs_mmap2_args *mmap2)
+{
+ int ret = 0;
+
+ if (fd && mmap2)
+ {
+ if (fd->vnode->type != FT_DEVICE || !fd->vnode->fops->ioctl)
+ {
+ rt_set_errno(EINVAL);
+ }
+ else if (fd->vnode->type == FT_DEVICE && fd->vnode->fops->ioctl)
+ {
+ ret = fd->vnode->fops->ioctl(fd, RT_FIOMMAP2, mmap2);
+ if (ret != 0)
+ {
+ ret = ret > 0? ret : -ret;
+ rt_set_errno(ret);
+ }
+ }
+ }
+
+ return ret;
+}
+
#ifdef RT_USING_FINSH
#include <finsh.h>
-static struct dfs_fd fd;
-static struct dirent dirent;
void ls(const char *pathname)
{
+ struct dfs_fd fd;
+ struct dirent dirent;
struct stat stat;
int length;
char *fullpath, *path;
@@ -537,6 +775,7 @@ void ls(const char *pathname)
path = (char *)pathname;
}
+ fd_init(&fd);
/* list directory */
if (dfs_file_open(&fd, path, O_DIRECTORY) == 0)
{
@@ -595,9 +834,11 @@ FINSH_FUNCTION_EXPORT(rm, remove files or directories);
void cat(const char *filename)
{
- uint32_t length;
+ struct dfs_fd fd;
+ int length = 0;
char buffer[81];
+ fd_init(&fd);
if (dfs_file_open(&fd, filename, O_RDONLY) < 0)
{
rt_kprintf("Open %s failed\n", filename);
@@ -607,15 +848,15 @@ void cat(const char *filename)
do
{
- rt_memset(buffer, 0, sizeof(buffer));
- length = dfs_file_read(&fd, buffer, sizeof(buffer) - 1);
+ rt_memset(buffer, 0x0, sizeof(buffer));
+ length = dfs_file_read(&fd, (void *)buffer, sizeof(buffer) - 1);
if (length > 0)
{
- rt_kprintf("%s", buffer);
+ buffer[length] = '\0';
+ rt_device_t out_device = rt_console_get_device();
+ rt_device_write(out_device, 0, (void *)buffer, sizeof(buffer));
}
- }
- while (length > 0);
- rt_kprintf("\n");
+ } while (length > 0);
dfs_file_close(&fd);
}
@@ -625,6 +866,7 @@ FINSH_FUNCTION_EXPORT(cat, print file);
#define BUF_SZ 4096
static void copyfile(const char *src, const char *dst)
{
+ struct dfs_fd fd;
struct dfs_fd src_fd;
rt_uint8_t *block_ptr;
rt_int32_t read_bytes;
@@ -637,6 +879,7 @@ static void copyfile(const char *src, const char *dst)
return;
}
+ fd_init(&src_fd);
if (dfs_file_open(&src_fd, src, O_RDONLY) < 0)
{
rt_free(block_ptr);
@@ -644,6 +887,7 @@ static void copyfile(const char *src, const char *dst)
return;
}
+ fd_init(&fd);
if (dfs_file_open(&fd, dst, O_WRONLY | O_CREAT) < 0)
{
rt_free(block_ptr);
diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c
index 2abad9dfeb..7724afc7bc 100644
--- a/components/dfs/src/dfs_fs.c
+++ b/components/dfs/src/dfs_fs.c
@@ -241,7 +241,7 @@ int dfs_mount(const char *device_name,
for (ops = &filesystem_operation_table[0];
ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++)
- if ((*ops != NULL) && (strcmp((*ops)->name, filesystemtype) == 0))
+ if ((*ops != NULL) && (strncmp((*ops)->name, filesystemtype, strlen((*ops)->name)) == 0))
break;
dfs_unlock();
@@ -273,6 +273,7 @@ int dfs_mount(const char *device_name,
{
struct dfs_fd fd;
+ fd_init(&fd);
if (dfs_file_open(&fd, fullpath, O_RDONLY | O_DIRECTORY) < 0)
{
rt_free(fullpath);
@@ -312,6 +313,9 @@ int dfs_mount(const char *device_name,
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();
@@ -447,7 +451,8 @@ int dfs_mkfs(const char *fs_name, const char *device_name)
for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index ++)
{
if (filesystem_operation_table[index] != NULL &&
- strcmp(filesystem_operation_table[index]->name, fs_name) == 0)
+ strncmp(filesystem_operation_table[index]->name, fs_name,
+ strlen(filesystem_operation_table[index]->name)) == 0)
break;
}
dfs_unlock();
@@ -463,7 +468,7 @@ int dfs_mkfs(const char *fs_name, const char *device_name)
return -1;
}
- return ops->mkfs(dev_id);
+ return ops->mkfs(dev_id, fs_name);
}
LOG_E("File system (%s) was not found.", fs_name);
@@ -490,6 +495,7 @@ int dfs_statfs(const char *path, struct statfs *buffer)
return fs->ops->statfs(fs, buffer);
}
+ rt_set_errno(-ENOSYS);
return -1;
}
@@ -625,7 +631,10 @@ int df(const char *path)
result = dfs_statfs(path ? path : NULL, &buffer);
if (result != 0)
{
- rt_kprintf("dfs_statfs failed.\n");
+ 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;
}
diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c
index ed0647121d..e3efa5bed6 100644
--- a/components/dfs/src/dfs_posix.c
+++ b/components/dfs/src/dfs_posix.c
@@ -14,6 +14,16 @@
#include <dfs_private.h>
#include <sys/errno.h>
+#ifdef RT_USING_LWP
+#include <lwp.h>
+#endif
+
+/**
+ * @addtogroup FsPosixApi
+ */
+
+/*@{*/
+
/**
* this function is a POSIX compliant version, which will open a file and
* return a file descriptor according specified flags.
@@ -42,17 +52,13 @@ int open(const char *file, int flags, ...)
if (result < 0)
{
/* release the ref-count of fd */
- fd_put(d);
- fd_put(d);
+ fd_release(fd);
rt_set_errno(result);
return -1;
}
- /* release the ref-count of fd */
- fd_put(d);
-
return fd;
}
RTM_EXPORT(open);
@@ -94,7 +100,6 @@ int close(int fd)
}
result = dfs_file_close(d);
- fd_put(d);
if (result < 0)
{
@@ -103,7 +108,7 @@ int close(int fd)
return -1;
}
- fd_put(d);
+ fd_release(fd);
return 0;
}
@@ -141,15 +146,11 @@ ssize_t read(int fd, void *buf, size_t len)
result = dfs_file_read(d, buf, len);
if (result < 0)
{
- fd_put(d);
rt_set_errno(result);
return -1;
}
- /* release the ref-count of fd */
- fd_put(d);
-
return result;
}
RTM_EXPORT(read);
@@ -185,15 +186,11 @@ ssize_t write(int fd, const void *buf, size_t len)
result = dfs_file_write(d, buf, len);
if (result < 0)
{
- fd_put(d);
rt_set_errno(result);
return -1;
}
- /* release the ref-count of fd */
- fd_put(d);
-
return result;
}
RTM_EXPORT(write);
@@ -231,11 +228,10 @@ off_t lseek(int fd, off_t offset, int whence)
break;
case SEEK_END:
- offset += d->size;
+ offset += d->vnode->size;
break;
default:
- fd_put(d);
rt_set_errno(-EINVAL);
return -1;
@@ -243,24 +239,17 @@ off_t lseek(int fd, off_t offset, int whence)
if (offset < 0)
{
- fd_put(d);
rt_set_errno(-EINVAL);
return -1;
}
- if(offset != d->pos)
+ result = dfs_file_lseek(d, offset);
+ if (result < 0)
{
- result = dfs_file_lseek(d, offset);
- if (result < 0)
- {
- fd_put(d);
- rt_set_errno(result);
+ rt_set_errno(result);
- return -1;
- }
+ return -1;
}
- /* release the ref-count of fd */
- fd_put(d);
return offset;
}
@@ -369,17 +358,15 @@ int fstat(int fildes, struct stat *buf)
buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
S_IWUSR | S_IWGRP | S_IWOTH;
- if (d->type == FT_DIRECTORY)
+ if (d->vnode->type == FT_DIRECTORY)
{
buf->st_mode &= ~S_IFREG;
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
}
- buf->st_size = d->size;
+ buf->st_size = d->vnode->size;
buf->st_mtime = 0;
- fd_put(d);
-
return RT_EOK;
}
RTM_EXPORT(fstat);
@@ -409,7 +396,6 @@ int fsync(int fildes)
ret = dfs_file_flush(d);
- fd_put(d);
return ret;
}
RTM_EXPORT(fsync);
@@ -443,7 +429,6 @@ int fcntl(int fildes, int cmd, ...)
va_end(ap);
ret = dfs_file_ioctl(d, cmd, arg);
- fd_put(d);
}
else ret = -EBADF;
@@ -508,7 +493,6 @@ int ftruncate(int fd, off_t length)
if (length < 0)
{
- fd_put(d);
rt_set_errno(-EINVAL);
return -1;
@@ -516,15 +500,11 @@ int ftruncate(int fd, off_t length)
result = dfs_file_ftruncate(d, length);
if (result < 0)
{
- fd_put(d);
rt_set_errno(result);
return -1;
}
- /* release the ref-count of fd */
- fd_put(d);
-
return 0;
}
RTM_EXPORT(ftruncate);
@@ -582,16 +562,14 @@ int mkdir(const char *path, mode_t mode)
if (result < 0)
{
- fd_put(d);
- fd_put(d);
+ fd_release(fd);
rt_set_errno(result);
return -1;
}
dfs_file_close(d);
- fd_put(d);
- fd_put(d);
+ fd_release(fd);
return 0;
}
@@ -653,7 +631,7 @@ DIR *opendir(const char *name)
if (t == NULL)
{
dfs_file_close(d);
- fd_put(d);
+ fd_release(fd);
}
else
{
@@ -661,14 +639,12 @@ DIR *opendir(const char *name)
t->fd = fd;
}
- fd_put(d);
return t;
}
/* open failed */
- fd_put(d);
- fd_put(d);
+ fd_release(fd);
rt_set_errno(result);
return NULL;
@@ -711,7 +687,6 @@ struct dirent *readdir(DIR *d)
sizeof(d->buf) - 1);
if (result <= 0)
{
- fd_put(fd);
rt_set_errno(result);
return NULL;
@@ -721,8 +696,6 @@ struct dirent *readdir(DIR *d)
d->cur = 0; /* current entry index */
}
- fd_put(fd);
-
return (struct dirent *)(d->buf + d->cur);
}
RTM_EXPORT(readdir);
@@ -749,7 +722,6 @@ long telldir(DIR *d)
}
result = fd->pos - d->num + d->cur;
- fd_put(fd);
return result;
}
@@ -777,7 +749,6 @@ void seekdir(DIR *d, long offset)
/* seek to the offset position of directory */
if (dfs_file_lseek(fd, offset) >= 0)
d->num = d->cur = 0;
- fd_put(fd);
}
RTM_EXPORT(seekdir);
@@ -802,7 +773,6 @@ void rewinddir(DIR *d)
/* seek to the beginning of directory */
if (dfs_file_lseek(fd, 0) >= 0)
d->num = d->cur = 0;
- fd_put(fd);
}
RTM_EXPORT(rewinddir);
@@ -828,9 +798,8 @@ int closedir(DIR *d)
}
result = dfs_file_close(fd);
- fd_put(fd);
+ fd_release(d->fd);
- fd_put(fd);
rt_free(d);
if (result < 0)
@@ -861,7 +830,9 @@ int chdir(const char *path)
if (path == NULL)
{
dfs_lock();
+#ifdef DFS_USING_WORKDIR
rt_kprintf("%s\n", working_directory);
+#endif
dfs_unlock();
return 0;
@@ -895,9 +866,12 @@ int chdir(const char *path)
/* close directory stream */
closedir(d);
-
+#ifdef RT_USING_LWP
/* copy full path to working directory */
- strncpy(working_directory, fullpath, DFS_PATH_MAX);
+ lwp_setcwd(fullpath);
+#else
+ rt_strncpy(working_directory, fullpath, DFS_PATH_MAX);
+#endif
/* release normalize directory path name */
rt_free(fullpath);
@@ -930,6 +904,31 @@ int access(const char *path, int amode)
/* ignore R_OK,W_OK,X_OK condition */
return 0;
}
+/**
+ * this function is a POSIX compliant version, which will set current
+ * working directory.
+ *
+ * @param buf the current directory.
+ *
+ * @return null.
+ */
+void setcwd(char *buf)
+{
+#ifdef DFS_USING_WORKDIR
+ dfs_lock();
+#ifdef RT_USING_LWP
+ lwp_setcwd(buf);
+#else
+ rt_strncpy(working_directory, buf, DFS_PATH_MAX);
+#endif
+ dfs_unlock();
+#else
+ rt_kprintf(NO_WORKING_DIR);
+#endif
+
+ return ;
+}
+RTM_EXPORT(setcwd);
/**
* this function is a POSIX compliant version, which will return current
@@ -943,8 +942,22 @@ int access(const char *path, int amode)
char *getcwd(char *buf, size_t size)
{
#ifdef DFS_USING_WORKDIR
+ char *dir_buf = RT_NULL;
+
dfs_lock();
- strncpy(buf, working_directory, size);
+
+#ifdef RT_USING_LWP
+ dir_buf = lwp_getcwd();
+#else
+ dir_buf = &working_directory[0];
+#endif
+
+ /* copy to buf parameter */
+ if (buf)
+ {
+ rt_strncpy(buf, dir_buf, size);
+ }
+
dfs_unlock();
#else
rt_kprintf(NO_WORKING_DIR);
@@ -953,3 +966,5 @@ char *getcwd(char *buf, size_t size)
return buf;
}
RTM_EXPORT(getcwd);
+
+/* @} */