diff --git a/components/dfs/dfs_v2/include/dfs.h b/components/dfs/dfs_v2/include/dfs.h index 8b8c80188f8..a99443bf476 100644 --- a/components/dfs/dfs_v2/include/dfs.h +++ b/components/dfs/dfs_v2/include/dfs.h @@ -128,11 +128,11 @@ int dfs_fdtable_drop_fd(struct dfs_fdtable *fdtab, int fd); /* FD APIs */ int fdt_fd_new(struct dfs_fdtable *fdt); struct dfs_file *fdt_get_file(struct dfs_fdtable* fdt, int fd); -void fdt_fd_release(struct dfs_fdtable* fdt, int fd); +rt_err_t fdt_fd_release(struct dfs_fdtable* fdt, int fd); int fd_new(void); -int fdt_fd_associate_file(struct dfs_fdtable *fdt, int fd, struct dfs_file *file); +int fdt_fd_associate_file(struct dfs_fdtable *fdt, int fd, struct dfs_file *file, rt_bool_t replace); struct dfs_file *fd_get(int fd); -void fd_release(int fd); +rt_err_t fd_release(int fd); void fd_init(struct dfs_file *fd); diff --git a/components/dfs/dfs_v2/include/dfs_file.h b/components/dfs/dfs_v2/include/dfs_file.h index 48958028ab0..6096b2caa33 100644 --- a/components/dfs/dfs_v2/include/dfs_file.h +++ b/components/dfs/dfs_v2/include/dfs_file.h @@ -14,6 +14,7 @@ #include #include +#include #ifdef __cplusplus extern "C" @@ -88,7 +89,8 @@ struct dfs_file uint16_t mode; uint32_t flags; - rt_atomic_t ref_count; + struct rt_ref ref_count; /* when to release the file struct */ + rt_atomic_t open_count; /* when to do real close of the file */ off_t fpos; struct rt_mutex pos_lock; @@ -146,6 +148,11 @@ struct dfs_mmap2_args void dfs_file_init(struct dfs_file *file); void dfs_file_deinit(struct dfs_file *file); +struct dfs_file *dfs_file_create(void); + +struct dfs_file *dfs_file_get(struct dfs_file *file); +struct dfs_file *dfs_file_put(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); diff --git a/components/dfs/dfs_v2/include/dfs_pcache.h b/components/dfs/dfs_v2/include/dfs_pcache.h index 01abfe31504..db1bb6db743 100644 --- a/components/dfs/dfs_v2/include/dfs_pcache.h +++ b/components/dfs/dfs_v2/include/dfs_pcache.h @@ -77,7 +77,6 @@ struct dfs_aspace rt_bool_t is_active; struct rt_mutex lock; - rt_atomic_t ref_count; struct dfs_vnode *vnode; const struct dfs_aspace_ops *ops; diff --git a/components/dfs/dfs_v2/src/dfs.c b/components/dfs/dfs_v2/src/dfs.c index 939e4dd66ef..a8b81f12e69 100644 --- a/components/dfs/dfs_v2/src/dfs.c +++ b/components/dfs/dfs_v2/src/dfs.c @@ -215,22 +215,16 @@ int fdt_fd_new(struct dfs_fdtable *fdt) } else if (!fdt->fds[idx]) { - struct dfs_file *file; - - file = (struct dfs_file *)rt_calloc(1, sizeof(struct dfs_file)); + struct dfs_file *file = dfs_file_create(); if (file) { - file->magic = DFS_FD_MAGIC; - file->ref_count = 1; - rt_mutex_init(&file->pos_lock, "fpos", RT_IPC_FLAG_PRIO); - fdt->fds[idx] = file; - + fdt_fd_associate_file(fdt, idx, file, RT_FALSE); + dfs_file_put(file); LOG_D("allocate a new fd @ %d", idx); } else { - fdt->fds[idx] = RT_NULL; idx = -1; } } @@ -245,32 +239,28 @@ int fdt_fd_new(struct dfs_fdtable *fdt) return idx; } -void fdt_fd_release(struct dfs_fdtable *fdt, int fd) +rt_err_t fdt_fd_release(struct dfs_fdtable *fdt, int fd) { + rt_err_t ret = -EBADF; + if (fd < fdt->maxfd) { - struct dfs_file *file; - - file = fdt_get_file(fdt, fd); + struct dfs_file *file = fdt_get_file(fdt, fd); - if (file && file->ref_count == 1) + if (file) { - rt_mutex_detach(&file->pos_lock); + ret = dfs_file_close(file); - if (file->mmap_context) + if (ret == 0) { - rt_free(file->mmap_context); + fdt->fds[fd] = RT_NULL; + dfs_file_put(file); /* put fdtable's ref to file */ + dfs_file_put(file); /* put this function's ref to file */ } - - rt_free(file); } - else - { - rt_atomic_sub(&(file->ref_count), 1); - } - - fdt->fds[fd] = RT_NULL; } + + return ret; } /** @@ -300,10 +290,12 @@ struct dfs_file *fdt_get_file(struct dfs_fdtable *fdt, int fd) return NULL; } + dfs_file_get(f); + return f; } -int fdt_fd_associate_file(struct dfs_fdtable *fdt, int fd, struct dfs_file *file) +int fdt_fd_associate_file(struct dfs_fdtable *fdt, int fd, struct dfs_file *file, rt_bool_t replace) { int retfd = -1; @@ -329,11 +321,19 @@ int fdt_fd_associate_file(struct dfs_fdtable *fdt, int fd, struct dfs_file *file if (fdt->fds[fd]) { - goto exit; + if (replace == RT_FALSE) + { + goto exit; + } + else + { + dfs_file_close(fdt->fds[fd]); + dfs_file_put(fdt->fds[fd]); + } } - /* inc ref_count */ - rt_atomic_add(&(file->ref_count), 1); + dfs_file_get(file); + rt_atomic_add(&(file->open_count), 1); fdt->fds[fd] = file; retfd = fd; @@ -356,12 +356,12 @@ int fd_new(void) * * This function will put the file descriptor. */ -void fd_release(int fd) +rt_err_t fd_release(int fd) { struct dfs_fdtable *fdt; fdt = dfs_fdtable_get(); - fdt_fd_release(fdt, fd); + return fdt_fd_release(fdt, fd); } struct dfs_file *fd_get(int fd) @@ -470,7 +470,7 @@ int dfs_fdtable_dup(struct dfs_fdtable *fdt_dst, struct dfs_fdtable *fdt_src, in fdt_dst->fds[newfd]->flags = fdt_src->fds[fd_src]->flags; fdt_dst->fds[newfd]->fops = fdt_src->fds[fd_src]->fops; fdt_dst->fds[newfd]->dentry = dfs_dentry_ref(fdt_src->fds[fd_src]->dentry); - fdt_dst->fds[newfd]->vnode = fdt_src->fds[fd_src]->vnode; + fdt_dst->fds[newfd]->vnode = dfs_vnode_ref(fdt_src->fds[fd_src]->vnode); fdt_dst->fds[newfd]->mmap_context = RT_NULL; fdt_dst->fds[newfd]->data = fdt_src->fds[fd_src]->data; @@ -512,11 +512,7 @@ int dfs_fdtable_drop_fd(struct dfs_fdtable *fdt, int fd) return -RT_ENOSYS; } - err = dfs_file_close(fdt->fds[fd]); - if (!err) - { - fdt_fd_release(fdt, fd); - } + err = fdt_fd_release(fdt, fd); dfs_file_unlock(); @@ -547,10 +543,7 @@ int dfs_dup(int oldfd, int startfd) newfd = _fdt_slot_alloc(fdt, startfd); if (newfd >= 0) { - fdt->fds[newfd] = fdt->fds[oldfd]; - - /* inc ref_count */ - rt_atomic_add(&(fdt->fds[newfd]->ref_count), 1); + newfd = fdt_fd_associate_file(fdt, newfd, fdt->fds[oldfd], RT_FALSE); } exit: dfs_file_unlock(); @@ -595,10 +588,7 @@ int dfs_dup_to(int oldfd, struct dfs_fdtable *fdtab) 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); + newfd = fdt_fd_associate_file(fdtab, newfd, fdt->fds[oldfd], RT_FALSE); } exit: dfs_file_unlock(); @@ -648,13 +638,11 @@ int dfs_dup_from(int oldfd, struct dfs_fdtable *fdtab) 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->vnode = dfs_vnode_ref(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(); @@ -680,7 +668,6 @@ int sys_dup(int oldfd) rt_err_t sys_dup2(int oldfd, int newfd) { struct dfs_fdtable *fdt = NULL; - int ret = 0; int retfd = -1; if (dfs_file_lock() != RT_EOK) @@ -717,20 +704,8 @@ rt_err_t sys_dup2(int oldfd, int newfd) goto exit; } - if (fdt->fds[newfd]) - { - ret = dfs_file_close(fdt->fds[newfd]); - if (ret < 0) - { - goto exit; - } - fd_release(newfd); - } + retfd = fdt_fd_associate_file(fdt, newfd, fdt->fds[oldfd], RT_TRUE); - fdt->fds[newfd] = fdt->fds[oldfd]; - /* inc ref_count */ - rt_atomic_add(&(fdt->fds[newfd]->ref_count), 1); - retfd = newfd; exit: dfs_file_unlock(); return retfd; @@ -938,7 +913,7 @@ int list_fd(void) 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 ", file->ref_count); + rt_kprintf("%3d ", file->open_count); rt_kprintf("%04x ", file->magic); if (file->dentry) @@ -974,14 +949,14 @@ int dfs_fd_dump(int argc, char** argv) char* fullpath = dfs_dentry_full_path(file->dentry); if (fullpath) { - printf("[%d] - %s, ref_count %zd\n", index, - fullpath, (size_t)rt_atomic_load(&(file->ref_count))); + printf("[%d] - %s, open_count %zd\n", index, + fullpath, (size_t)rt_atomic_load(&(file->open_count))); rt_free(fullpath); } else { - printf("[%d] - %s, ref_count %zd\n", index, - file->dentry->pathname, (size_t)rt_atomic_load(&(file->ref_count))); + printf("[%d] - %s, open_count %zd\n", index, + file->dentry->pathname, (size_t)rt_atomic_load(&(file->open_count))); } } } diff --git a/components/dfs/dfs_v2/src/dfs_dentry.c b/components/dfs/dfs_v2/src/dfs_dentry.c index 8623ec051f2..a04fb191b73 100644 --- a/components/dfs/dfs_v2/src/dfs_dentry.c +++ b/components/dfs/dfs_v2/src/dfs_dentry.c @@ -87,20 +87,13 @@ struct dfs_dentry *dfs_dentry_create_rela(struct dfs_mnt *mnt, char *rela_path) struct dfs_dentry * dfs_dentry_ref(struct dfs_dentry *dentry) { - if (dentry) + RT_ASSERT(dentry); + + rt_atomic_add(&(dentry->ref_count), 1); + if (dentry->vnode) { - 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(); - } + rt_atomic_add(&(dentry->vnode->ref_count), 1); // TODO: dont add vnode's ref } - return dentry; } @@ -108,53 +101,43 @@ struct dfs_dentry *dfs_dentry_unref(struct dfs_dentry *dentry) { rt_err_t ret = RT_EOK; - if (dentry) + RT_ASSERT(dentry && (dentry->flags & DENTRY_IS_ALLOCED)); + + ret = dfs_file_lock(); + if (ret == RT_EOK) { - ret = dfs_file_lock(); - if (ret == RT_EOK) + if (rt_atomic_dec_and_test(&(dentry->ref_count))) { - if (dentry->flags & DENTRY_IS_ALLOCED) + DLOG(msg, "dentry", "dentry", DLOG_MSG, "free dentry, ref_count=0"); + if (dentry->flags & DENTRY_IS_ADDHASH) { - rt_atomic_sub(&(dentry->ref_count), 1); + rt_list_remove(&dentry->hashlist); } - if (rt_atomic_load(&(dentry->ref_count)) == 0) + /* release vnode */ + if (dentry->vnode) { - 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); - dentry = RT_NULL; + dfs_vnode_unref(dentry->vnode); } - else + + /* release mnt */ + DLOG(msg, "dentry", "mnt", DLOG_MSG, "dfs_mnt_unref(dentry->mnt)"); + if (dentry->mnt) { - 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))); + dfs_mnt_unref(dentry->mnt); } + + dfs_file_unlock(); + + LOG_I("free a dentry: %p", dentry); + rt_free(dentry->pathname); + rt_free(dentry); + dentry = RT_NULL; + } + else + { + dfs_file_unlock(); + DLOG(note, "dentry", "dentry ref_count=%d", rt_atomic_load(&(dentry->ref_count))); } } diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c index 53e110ef595..46b8b08c9c1 100644 --- a/components/dfs/dfs_v2/src/dfs_file.c +++ b/components/dfs/dfs_v2/src/dfs_file.c @@ -86,7 +86,11 @@ static int _try_readlink(const char *path, struct dfs_mnt *mnt, char *link) } } } - dfs_dentry_unref(dentry); + + if (dentry) + { + dfs_dentry_unref(dentry); + } return ret; } @@ -161,84 +165,134 @@ ssize_t rw_verify_area(struct dfs_file *file, off_t *ppos, size_t count) off_t dfs_file_get_fpos(struct dfs_file *file) { - if (file) + RT_ASSERT(file); + + if (file->vnode->type == FT_REGULAR) { - if (file->vnode->type == FT_REGULAR) - { - rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER); - } - return file->fpos; + rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER); } - - return 0; + return file->fpos; } void dfs_file_set_fpos(struct dfs_file *file, off_t fpos) { - if (file) + RT_ASSERT(file); + + if (file->vnode->type != FT_REGULAR) { - if (file->vnode->type != FT_REGULAR) - { - rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER); - } - file->fpos = fpos; - rt_mutex_release(&file->pos_lock); + rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER); } + file->fpos = fpos; + rt_mutex_release(&file->pos_lock); } void dfs_file_init(struct dfs_file *file) { - if (file) + RT_ASSERT(file); + + 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->open_count), 1); + rt_ref_init(&file->ref_count); +} + +void dfs_file_deinit(struct dfs_file *file) +{ + RT_ASSERT(file); + + if (file->fops && file->fops->close) { - 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); + if (file->fops->close(file) != RT_EOK) + { + LOG_E("file %p close error", file); + } + } + + rt_mutex_detach(&file->pos_lock); + + if (file->dentry) + { + dfs_dentry_unref(file->dentry); + } + + if (file->vnode) + { + //dfs_vnode_unref(file->vnode); + } + + if (file->mmap_context) + { + rt_free(file->mmap_context); } } -void dfs_file_deinit(struct dfs_file *file) +struct dfs_file *dfs_file_create(void) { - if (file) + struct dfs_file *file = rt_calloc(1, sizeof(struct dfs_file)); + + if (!file) { - rt_mutex_detach(&file->pos_lock); + return RT_NULL; } + + 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->open_count), 0); + rt_ref_init(&file->ref_count); + + return file; } -static void dfs_file_unref(struct dfs_file *file) +static void _dfs_file_release(struct rt_ref *ref) { - rt_err_t ret = RT_EOK; + struct dfs_file *file = rt_container_of(ref, struct dfs_file, ref_count); - ret = dfs_file_lock(); - if (ret == RT_EOK) + RT_ASSERT(rt_atomic_load(&file->open_count) == 0); + + if (file->fops && file->fops->close) { - if (rt_atomic_load(&(file->ref_count)) == 1) + if (file->fops->close(file) != RT_EOK) { - /* 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) - { - rt_atomic_sub(&(file->vnode->ref_count), 1); - } - else if (file->vnode->ref_count == 1) - { - rt_free(file->vnode); - file->vnode = RT_NULL; - } - } - - LOG_I("release a file: %p", file); + LOG_E("file %p close error", file); } + } - dfs_file_unlock(); + rt_mutex_detach(&file->pos_lock); + + if (file->dentry) + { + dfs_dentry_unref(file->dentry); + } + + if (file->vnode) + { + //dfs_vnode_unref(file->vnode); } + + if (file->mmap_context) + { + rt_free(file->mmap_context); + } + + rt_free(file); +} + +struct dfs_file *dfs_file_get(struct dfs_file *file) +{ + RT_ASSERT(file); + + rt_ref_get(&file->ref_count); + return file; +} + +struct dfs_file *dfs_file_put(struct dfs_file *file) +{ + RT_ASSERT(file); + + rt_ref_put(&file->ref_count, _dfs_file_release); + return RT_NULL; } /* @@ -413,12 +467,14 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo struct dfs_dentry *dentry = RT_NULL; int fflags = dfs_fflags(oflags); + RT_ASSERT(file); + if (mode == 0) { mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); /* 0666 */ } - if (file && path) + if (path) { fullpath = dfs_normalize_path(NULL, path); if (fullpath) @@ -592,7 +648,6 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo { 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); } else { @@ -606,7 +661,6 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo else { DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "no permission or fops->open"); - dfs_file_unref(file); ret = -EPERM; } } @@ -624,7 +678,7 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo 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"); + DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_put(file), trunc on RDOnly or directory"); ret = -RT_ERROR; } else @@ -650,14 +704,13 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo } } - if (ret < 0) - { - dfs_file_unref(file); - } - file->flags &= ~O_TRUNC; } } + else /* path */ + { + ret = -EFAULT; + } _ERR_RET: if (fullpath != NULL) @@ -671,41 +724,30 @@ int dfs_file_close(struct dfs_file *file) { int ret = -RT_ERROR; - if (file) + if (dfs_file_lock() == RT_EOK) { - if (dfs_file_lock() == RT_EOK) - { - rt_atomic_t ref_count = rt_atomic_load(&(file->ref_count)); + ret = 0; - if (ref_count == 1 && file->fops && file->fops->close) - { - DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)"); + if (rt_atomic_dec_and_test(&file->open_count) && file->fops && file->fops->close) + { + DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)"); #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace) - { - dfs_aspace_flush(file->vnode->aspace); - } + if (file->vnode && file->vnode->aspace) + { + ret = dfs_aspace_flush(file->vnode->aspace); + } #endif - 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); - } + if (ret == 0) /* close file sucessfully */ + { + DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_put(file)"); } else { - DLOG(msg, "dfs_file", "dfs_file", DLOG_MSG, "dfs_file_unref(file)"); - dfs_file_unref(file); - ret = 0; + LOG_W("close file:%s failed on low level file system", file->dentry->pathname); } - dfs_file_unlock(); } + + dfs_file_unlock(); } return ret; @@ -715,44 +757,43 @@ ssize_t dfs_file_pread(struct dfs_file *file, void *buf, size_t len, off_t offse { ssize_t ret = -EBADF; - if (file) + RT_ASSERT(file); + + /* check whether read */ + if (!(dfs_fflags(file->flags) & DFS_F_FREAD)) { - /* 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) + ret = -EPERM; + } + else if (!file->fops || !file->fops->read) + { + ret = -ENOSYS; + } + else if (file->vnode && file->vnode->type != FT_DIRECTORY) + { + off_t pos = offset; + + ret = rw_verify_area(file, &pos, len); + if (ret > 0) { - off_t pos = offset; + len = ret; - ret = rw_verify_area(file, &pos, len); - if (ret > 0) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - len = ret; - - if (dfs_is_mounted(file->vnode->mnt) == 0) - { #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace && !(file->flags & O_DIRECT)) - { - ret = dfs_aspace_read(file, buf, len, &pos); - } - else -#endif - { - ret = file->fops->read(file, buf, len, &pos); - } + if (file->vnode->aspace && !(file->flags & O_DIRECT)) + { + ret = dfs_aspace_read(file, buf, len, &pos); } else +#endif { - ret = -EINVAL; + ret = file->fops->read(file, buf, len, &pos); } } + else + { + ret = -EINVAL; + } } } @@ -763,48 +804,47 @@ ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len) { ssize_t ret = -EBADF; - if (file) + RT_ASSERT(file); + + /* check whether read */ + if (!(dfs_fflags(file->flags) & DFS_F_FREAD)) { - /* 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) + ret = -EPERM; + } + else if (!file->fops || !file->fops->read) + { + ret = -ENOSYS; + } + else if (file->vnode && file->vnode->type != FT_DIRECTORY) + { + /* fpos lock */ + off_t pos = dfs_file_get_fpos(file); + + ret = rw_verify_area(file, &pos, len); + if (ret > 0) { - /* fpos lock */ - off_t pos = dfs_file_get_fpos(file); + len = ret; - ret = rw_verify_area(file, &pos, len); - if (ret > 0) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - len = ret; - - if (dfs_is_mounted(file->vnode->mnt) == 0) - { #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace && !(file->flags & O_DIRECT)) - { - ret = dfs_aspace_read(file, buf, len, &pos); - } - else -#endif - { - ret = file->fops->read(file, buf, len, &pos); - } + if (file->vnode->aspace && !(file->flags & O_DIRECT)) + { + ret = dfs_aspace_read(file, buf, len, &pos); } else +#endif { - ret = -EINVAL; + ret = file->fops->read(file, buf, len, &pos); } } - /* fpos unlock */ - dfs_file_set_fpos(file, pos); + else + { + ret = -EINVAL; + } } + /* fpos unlock */ + dfs_file_set_fpos(file, pos); } return ret; @@ -814,52 +854,51 @@ ssize_t dfs_file_pwrite(struct dfs_file *file, const void *buf, size_t len, off_ { ssize_t ret = -EBADF; - if (file) + RT_ASSERT(file); + + if (!(dfs_fflags(file->flags) & DFS_F_FWRITE)) { - 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) + 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 = offset; + + ret = rw_verify_area(file, &pos, len); + if (ret > 0) { - off_t pos = offset; + len = ret; + DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, + "dfs_file_write(fd, buf, %d)", len); - ret = rw_verify_area(file, &pos, len); - if (ret > 0) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - len = ret; - DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, - "dfs_file_write(fd, buf, %d)", len); - - if (dfs_is_mounted(file->vnode->mnt) == 0) - { #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace && !(file->flags & O_DIRECT)) - { - ret = dfs_aspace_write(file, buf, len, &pos); - } - else -#endif - { - ret = file->fops->write(file, buf, len, &pos); - } - - if (file->flags & O_SYNC) - { - file->fops->flush(file); - } + if (file->vnode->aspace && !(file->flags & O_DIRECT)) + { + ret = dfs_aspace_write(file, buf, len, &pos); } else +#endif + { + ret = file->fops->write(file, buf, len, &pos); + } + + if (file->flags & O_SYNC) { - ret = -EINVAL; + file->fops->flush(file); } } + else + { + ret = -EINVAL; + } } } @@ -870,68 +909,67 @@ ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len) { ssize_t ret = -EBADF; - if (file) + RT_ASSERT(file); + + if (!(dfs_fflags(file->flags) & DFS_F_FWRITE)) + { + LOG_W("bad write flags."); + ret = -EBADF; + } + else if (!file->fops || !file->fops->write) { - if (!(dfs_fflags(file->flags) & DFS_F_FWRITE)) + LOG_W("no fops write."); + ret = -ENOSYS; + } + else if (file->vnode && file->vnode->type != FT_DIRECTORY) + { + off_t pos; + + if (!(file->flags & O_APPEND)) { - LOG_W("bad write flags."); - ret = -EBADF; + /* fpos lock */ + pos = dfs_file_get_fpos(file); } - else if (!file->fops || !file->fops->write) + else { - LOG_W("no fops write."); - ret = -ENOSYS; + pos = file->vnode->size; } - else if (file->vnode && file->vnode->type != FT_DIRECTORY) - { - off_t pos; - if (!(file->flags & O_APPEND)) - { - /* fpos lock */ - pos = dfs_file_get_fpos(file); - } - else - { - pos = file->vnode->size; - } + 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 = rw_verify_area(file, &pos, len); - if (ret > 0) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - len = ret; - DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, - "dfs_file_write(fd, buf, %d)", len); - - if (dfs_is_mounted(file->vnode->mnt) == 0) - { #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace && !(file->flags & O_DIRECT)) - { - ret = dfs_aspace_write(file, buf, len, &pos); - } - else -#endif - { - ret = file->fops->write(file, buf, len, &pos); - } - - if (file->flags & O_SYNC) - { - file->fops->flush(file); - } + if (file->vnode->aspace && !(file->flags & O_DIRECT)) + { + ret = dfs_aspace_write(file, buf, len, &pos); } else +#endif { - ret = -EINVAL; + ret = file->fops->write(file, buf, len, &pos); + } + + if (file->flags & O_SYNC) + { + file->fops->flush(file); } } - if (!(file->flags & O_APPEND)) + else { - /* fpos unlock */ - dfs_file_set_fpos(file, pos); + ret = -EINVAL; } } + if (!(file->flags & O_APPEND)) + { + /* fpos unlock */ + dfs_file_set_fpos(file, pos); + } } return ret; @@ -957,7 +995,9 @@ off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece) { off_t retval = -EINVAL; - if (file && file->fops->lseek) + RT_ASSERT(file); + + if (file->fops->lseek) { if (dfs_is_mounted(file->vnode->mnt) == 0) { @@ -1090,20 +1130,15 @@ int dfs_file_fstat(struct dfs_file *file, struct stat *buf) { size_t ret = -EBADF; - if (file) + RT_ASSERT(file); + + if (file->fops && file->fops->ioctl) { - if (file->fops && file->fops->ioctl) - { - // ret = file->fops->fstat(file, buf); - } - else - { - ret = -ENOSYS; - } + // ret = file->fops->fstat(file, buf); } else { - ret = -EBADF; + ret = -ENOSYS; } return ret; @@ -1161,29 +1196,24 @@ int dfs_file_setattr(const char *path, struct dfs_attr *attr) int dfs_file_ioctl(struct dfs_file *file, int cmd, void *args) { - size_t ret = 0; + size_t ret = -EBADF; - if (file) + RT_ASSERT(file); + + if (file->fops && file->fops->ioctl) { - if (file->fops && file->fops->ioctl) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - if (dfs_is_mounted(file->vnode->mnt) == 0) - { - ret = file->fops->ioctl(file, cmd, args); - } - else - { - ret = -EINVAL; - } + ret = file->fops->ioctl(file, cmd, args); } else { - ret = -ENOSYS; + ret = -EINVAL; } } else { - ret = -EBADF; + ret = -ENOSYS; } return ret; @@ -1251,6 +1281,8 @@ int dfs_file_fcntl(int fd, int cmd, unsigned long arg) ret = -EBADF; } + dfs_file_put(file); + return ret; } @@ -1258,24 +1290,23 @@ int dfs_file_fsync(struct dfs_file *file) { int ret = -EBADF; - if (file) + RT_ASSERT(file); + + if (file->fops->flush) { - if (file->fops->flush) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - if (dfs_is_mounted(file->vnode->mnt) == 0) - { #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace) - { - dfs_aspace_flush(file->vnode->aspace); - } -#endif - ret = file->fops->flush(file); - } - else + if (file->vnode->aspace) { - ret = -EINVAL; + dfs_aspace_flush(file->vnode->aspace); } +#endif + ret = file->fops->flush(file); + } + else + { + ret = -EINVAL; } } @@ -1722,35 +1753,30 @@ int dfs_file_rename(const char *old_file, const char *new_file) int dfs_file_ftruncate(struct dfs_file *file, off_t length) { - int ret = 0; + int ret = -EBADF; - if (file) + RT_ASSERT(file); + + if (file->fops->truncate) { - if (file->fops->truncate) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - if (dfs_is_mounted(file->vnode->mnt) == 0) - { #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace) - { - dfs_aspace_clean(file->vnode->aspace); - } -#endif - ret = file->fops->truncate(file, length); - } - else + if (file->vnode->aspace) { - ret = -EINVAL; + dfs_aspace_clean(file->vnode->aspace); } +#endif + ret = file->fops->truncate(file, length); } else { - ret = -ENOSYS; + ret = -EINVAL; } } else { - ret = -EBADF; + ret = -ENOSYS; } return ret; @@ -1758,35 +1784,30 @@ int dfs_file_ftruncate(struct dfs_file *file, off_t length) int dfs_file_flush(struct dfs_file *file) { - int ret = 0; + int ret = -EBADF; - if (file) + RT_ASSERT(file); + + if (file->fops->flush) { - if (file->fops->flush) + if (dfs_is_mounted(file->vnode->mnt) == 0) { - if (dfs_is_mounted(file->vnode->mnt) == 0) - { #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace) - { - dfs_aspace_flush(file->vnode->aspace); - } -#endif - ret = file->fops->flush(file); - } - else + if (file->vnode->aspace) { - ret = -EINVAL; + dfs_aspace_flush(file->vnode->aspace); } +#endif + ret = file->fops->flush(file); } else { - ret = -ENOSYS; + ret = -EINVAL; } } else { - ret = -EBADF; + ret = -ENOSYS; } return ret; @@ -1796,29 +1817,24 @@ int dfs_file_getdents(struct dfs_file *file, struct dirent *dirp, size_t nbytes) { int ret = -RT_ERROR; - if (file) + RT_ASSERT(file); + + if (file->vnode && S_ISDIR(file->vnode->mode)) { - if (file->vnode && S_ISDIR(file->vnode->mode)) + if (file->fops && file->fops->getdents) { - if (file->fops && file->fops->getdents) - { - DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->getdents()"); + DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->getdents()"); - if (dfs_is_mounted(file->vnode->mnt) == 0) - { - ret = file->fops->getdents(file, dirp, nbytes); - } - else - { - ret = -EINVAL; - } + if (dfs_is_mounted(file->vnode->mnt) == 0) + { + ret = file->fops->getdents(file, dirp, nbytes); + } + else + { + ret = -EINVAL; } } } - else - { - ret = -EBADF; - } return ret; } @@ -1892,8 +1908,8 @@ int dfs_file_isdir(const char *path) int dfs_file_access(const char *path, mode_t mode) { - int ret; struct dfs_file file; + int ret; dfs_file_init(&file); @@ -1917,7 +1933,9 @@ int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2) { int ret = RT_EOK; - if (file && mmap2) + RT_ASSERT(file); + + if (mmap2) { if (file->vnode->type == FT_REGULAR) { diff --git a/components/dfs/dfs_v2/src/dfs_file_mmap.c b/components/dfs/dfs_v2/src/dfs_file_mmap.c index b976a85a270..3bf0cd8e386 100644 --- a/components/dfs/dfs_v2/src/dfs_file_mmap.c +++ b/components/dfs/dfs_v2/src/dfs_file_mmap.c @@ -106,6 +106,9 @@ static void on_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *ms } page = dfs_aspace_mmap(file, varea, msg->fault_vaddr); + + dfs_file_put(file); + if (page) { msg->response.status = MM_FAULT_STATUS_OK_MAPPED; @@ -128,7 +131,7 @@ static void on_varea_open(struct rt_varea *varea) { struct dfs_file *file = dfs_mem_obj_get_file(varea->mem_obj); varea->data = RT_NULL; - rt_atomic_add(&(file->ref_count), 1); + dfs_file_put(file); } /* do post close bushiness like def a ref */ @@ -148,16 +151,7 @@ static void on_varea_close(struct rt_varea *varea) } dfs_aspace_unmap(file, varea); - dfs_file_lock(); - if (rt_atomic_load(&(file->ref_count)) == 1) - { - dfs_file_close(file); - } - else - { - rt_atomic_sub(&(file->ref_count), 1); - } - dfs_file_unlock(); + dfs_file_put(file); } else { @@ -169,7 +163,14 @@ static const char *get_name(rt_varea_t varea) { struct dfs_file *file = dfs_mem_obj_get_file(varea->mem_obj); - return (file && file->dentry) ? file->dentry->pathname : "file-mapper"; + const char *ret = (file && file->dentry) ? file->dentry->pathname : "file-mapper"; + + if (file) + { + dfs_file_put(file); + } + + return ret; } void page_read(struct rt_varea *varea, struct rt_aspace_io_msg *msg) @@ -184,6 +185,9 @@ void page_read(struct rt_varea *varea, struct rt_aspace_io_msg *msg) varea->start, varea->size, varea->offset, varea->attr, varea->flag); ret = dfs_aspace_mmap_read(file, varea, msg); + + dfs_file_put(file); + if (ret >= 0) { msg->response.status = MM_FAULT_STATUS_OK; @@ -211,6 +215,9 @@ void page_write(struct rt_varea *varea, struct rt_aspace_io_msg *msg) varea->start, varea->size, varea->offset, varea->attr, varea->flag); ret = dfs_aspace_mmap_write(file, varea, msg); + + dfs_file_put(file); + if (ret > 0) { msg->response.status = MM_FAULT_STATUS_OK; @@ -242,6 +249,8 @@ static rt_err_t unmap_pages(rt_varea_t varea, void *rm_start, void *rm_end) rm_start += ARCH_PAGE_SIZE; } + dfs_file_put(file); + return RT_EOK; } else @@ -304,6 +313,8 @@ rt_err_t on_varea_split(struct rt_varea *existed, void *unmap_start, rt_size_t u LOG_I("file: %s%s", file->dentry->mnt->fullpath, file->dentry->pathname); } + dfs_file_put(file); + rc = unmap_pages(existed, unmap_start, (char *)unmap_start + unmap_len); if (!rc) { @@ -338,6 +349,9 @@ rt_err_t on_varea_merge(struct rt_varea *merge_to, struct rt_varea *merge_from) } dfs_aspace_unmap(file, merge_from); + + dfs_file_put(file); + on_varea_close(merge_from); return RT_EOK; @@ -364,6 +378,8 @@ void *on_varea_mremap(struct rt_varea *varea, rt_size_t new_size, int flags, voi int ret; rt_mem_obj_t mem_obj = dfs_get_mem_obj(file); + dfs_file_put(file); + vaddr = new_address ? new_address : varea->start; new_size = (new_size + ARCH_PAGE_SIZE - 1); new_size &= ~ARCH_PAGE_MASK; @@ -378,6 +394,10 @@ void *on_varea_mremap(struct rt_varea *varea, rt_size_t new_size, int flags, voi LOG_I("old: %p size: %p new: %p size: %p", varea->start, varea->size, vaddr, new_size); } } + else if (file) + { + dfs_file_put(file); + } return vaddr; } @@ -416,7 +436,7 @@ static rt_mem_obj_t dfs_get_mem_obj(struct dfs_file *file) dfs_mobj = rt_malloc(sizeof(*dfs_mobj)); if (dfs_mobj) { - dfs_mobj->file = file; + dfs_mobj->file = dfs_file_get(file); mobj = &dfs_mobj->mem_obj; memcpy(mobj, &_mem_obj, sizeof(*mobj)); file->mmap_context = mobj; @@ -430,6 +450,11 @@ static void *dfs_mem_obj_get_file(rt_mem_obj_t mem_obj) { struct dfs_mem_obj *dfs_mobj; dfs_mobj = rt_container_of(mem_obj, struct dfs_mem_obj, mem_obj); + + if (dfs_mobj->file) + { + dfs_file_get(dfs_mobj->file); + } return dfs_mobj->file; } diff --git a/components/dfs/dfs_v2/src/dfs_mnt.c b/components/dfs/dfs_v2/src/dfs_mnt.c index 4ad73c6dee9..aa0f74072cd 100644 --- a/components/dfs/dfs_v2/src/dfs_mnt.c +++ b/components/dfs/dfs_v2/src/dfs_mnt.c @@ -233,11 +233,10 @@ struct dfs_mnt *dfs_mnt_lookup(const char *fullpath) 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))); - } + RT_ASSERT(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; } @@ -248,9 +247,7 @@ int dfs_mnt_unref(struct dfs_mnt* mnt) if (mnt) { - rt_atomic_sub(&(mnt->ref_count), 1); - - if (rt_atomic_load(&(mnt->ref_count)) == 0) + if (rt_atomic_dec_and_test(&(mnt->ref_count))) { dfs_lock(); diff --git a/components/dfs/dfs_v2/src/dfs_pcache.c b/components/dfs/dfs_v2/src/dfs_pcache.c index 6868170b9cb..024996e0169 100644 --- a/components/dfs/dfs_v2/src/dfs_pcache.c +++ b/components/dfs/dfs_v2/src/dfs_pcache.c @@ -67,7 +67,7 @@ static struct dfs_page *dfs_page_lookup(struct dfs_file *file, off_t pos); static void dfs_page_ref(struct dfs_page *page); static int dfs_page_inactive(struct dfs_page *page); static int dfs_page_remove(struct dfs_page *page); -static void dfs_page_release(struct dfs_page *page); +static void dfs_page_unref(struct dfs_page *page); static int dfs_page_dirty(struct dfs_page *page); static int dfs_aspace_release(struct dfs_aspace *aspace); @@ -86,40 +86,39 @@ static int dfs_aspace_gc(struct dfs_aspace *aspace, int count) { int cnt = count; - if (aspace) + RT_ASSERT(aspace); + + dfs_aspace_lock(aspace); + + if (aspace->pages_count > 0) { - dfs_aspace_lock(aspace); + struct dfs_page *page = RT_NULL; + rt_list_t *node = aspace->list_inactive.next; - if (aspace->pages_count > 0) + while (cnt && node != &aspace->list_active) { - struct dfs_page *page = RT_NULL; - rt_list_t *node = aspace->list_inactive.next; - - while (cnt && node != &aspace->list_active) + page = rt_list_entry(node, struct dfs_page, space_node); + node = node->next; + if (dfs_page_remove(page) == 0) { - page = rt_list_entry(node, struct dfs_page, space_node); - node = node->next; - if (dfs_page_remove(page) == 0) - { - cnt --; - } + cnt --; } + } - node = aspace->list_active.next; - while (cnt && node != &aspace->list_inactive) + node = aspace->list_active.next; + while (cnt && node != &aspace->list_inactive) + { + page = rt_list_entry(node, struct dfs_page, space_node); + node = node->next; + if (dfs_page_remove(page) == 0) { - page = rt_list_entry(node, struct dfs_page, space_node); - node = node->next; - if (dfs_page_remove(page) == 0) - { - cnt --; - } + cnt --; } } - - dfs_aspace_unlock(aspace); } + dfs_aspace_unlock(aspace); + return count - cnt; } @@ -284,7 +283,7 @@ static void dfs_pcache_thread(void *parameter) } } } - dfs_page_release(page); + dfs_page_unref(page); dfs_aspace_unlock(aspace); } else @@ -381,12 +380,10 @@ static struct dfs_aspace *dfs_aspace_hash_lookup(struct dfs_dentry *dentry, cons dfs_pcache_lock(); rt_list_for_each_entry(aspace, &__pcache.head[dfs_aspace_hash(dentry->mnt, dentry->pathname)], hash_node) { - if (aspace->mnt == dentry->mnt && aspace->ops == ops && !strcmp(aspace->pathname, dentry->pathname)) { - rt_atomic_add(&aspace->ref_count, 1); dfs_pcache_unlock(); return aspace; } @@ -403,7 +400,6 @@ static void dfs_aspace_insert(struct dfs_aspace *aspace) val = dfs_aspace_hash(aspace->mnt, aspace->pathname); dfs_pcache_lock(); - rt_atomic_add(&aspace->ref_count, 1); rt_list_insert_after(&__pcache.head[val], &aspace->hash_node); rt_list_insert_before(&__pcache.list_inactive, &aspace->cache_node); dfs_pcache_unlock(); @@ -463,7 +459,6 @@ static struct dfs_aspace *_dfs_aspace_create(struct dfs_dentry *dentry, aspace->avl_page = 0; rt_mutex_init(&aspace->lock, rt_thread_self()->parent.name, RT_IPC_FLAG_PRIO); - rt_atomic_store(&aspace->ref_count, 1); aspace->pages_count = 0; aspace->vnode = vnode; @@ -510,92 +505,88 @@ struct dfs_aspace *dfs_aspace_create(struct dfs_dentry *dentry, int dfs_aspace_destroy(struct dfs_aspace *aspace) { - int ret = -EINVAL; + int ret = 0; - if (aspace) + RT_ASSERT(aspace); + + dfs_pcache_lock(); + dfs_aspace_lock(aspace); + dfs_aspace_flush(aspace); + dfs_aspace_gc(aspace, aspace->pages_count); + RT_ASSERT(aspace->pages_count == 0); + if (dfs_aspace_release(aspace) != 0) { - dfs_pcache_lock(); - dfs_aspace_lock(aspace); - rt_atomic_sub(&aspace->ref_count, 1); - RT_ASSERT(rt_atomic_load(&aspace->ref_count) > 0); - dfs_aspace_inactive(aspace); - aspace->vnode = RT_NULL; - if (dfs_aspace_release(aspace) != 0) - { - dfs_aspace_unlock(aspace); - } - dfs_pcache_unlock(); + dfs_aspace_unlock(aspace); } + dfs_pcache_unlock(); return ret; } static int dfs_aspace_release(struct dfs_aspace *aspace) { - int ret = -1; + int ret = 0; - if (aspace) - { - dfs_pcache_lock(); - dfs_aspace_lock(aspace); + RT_ASSERT(aspace); - if (rt_atomic_load(&aspace->ref_count) == 1 && aspace->pages_count == 0) + dfs_pcache_lock(); + dfs_aspace_lock(aspace); + + if (aspace->pages_count == 0) + { + dfs_aspace_remove(aspace); + if (aspace->fullpath) { - dfs_aspace_remove(aspace); - if (aspace->fullpath) - { - rt_free(aspace->fullpath); - } - if (aspace->pathname) - { - rt_free(aspace->pathname); - } - rt_mutex_detach(&aspace->lock); - rt_free(aspace); - ret = 0; + rt_free(aspace->fullpath); } - else + if (aspace->pathname) { - dfs_aspace_unlock(aspace); + rt_free(aspace->pathname); } - dfs_pcache_unlock(); + rt_mutex_detach(&aspace->lock); + rt_free(aspace); } + else + { + dfs_aspace_unlock(aspace); + } + dfs_pcache_unlock(); return ret; } static int _dfs_aspace_dump(struct dfs_aspace *aspace, int is_dirty) { - if (aspace) - { - rt_list_t *next; - struct dfs_page *page; + RT_ASSERT(aspace); - dfs_aspace_lock(aspace); - if (aspace->pages_count > 0) + rt_list_t *next; + struct dfs_page *page; + + dfs_aspace_lock(aspace); + if (aspace->pages_count > 0) + { + rt_list_for_each(next, &aspace->list_inactive) { - rt_list_for_each(next, &aspace->list_inactive) + if (next != &aspace->list_active) { - if (next != &aspace->list_active) + page = rt_list_entry(next, struct dfs_page, space_node); + if (is_dirty && page->is_dirty) { - page = rt_list_entry(next, struct dfs_page, space_node); - if (is_dirty && page->is_dirty) - { - rt_kprintf(" pages >> fpos: %d index :%d is_dirty: %d\n", page->fpos, page->fpos / ARCH_PAGE_SIZE, page->is_dirty); - } - else if (is_dirty == 0) - { - rt_kprintf(" pages >> fpos: %d index :%d is_dirty: %d\n", page->fpos, page->fpos / ARCH_PAGE_SIZE, page->is_dirty); - } + rt_kprintf(" pages >> fpos: %d index :%d is_dirty: %d\n", page->fpos, page->fpos / ARCH_PAGE_SIZE, page->is_dirty); + } + else if (is_dirty == 0) + { + rt_kprintf(" pages >> fpos: %d index :%d is_dirty: %d\n", page->fpos, page->fpos / ARCH_PAGE_SIZE, page->is_dirty); } } } - else - { - rt_kprintf(" pages >> empty\n"); - } - dfs_aspace_unlock(aspace); } + else + { + rt_kprintf(" pages >> empty\n"); + } + dfs_aspace_unlock(aspace); + return 0; } @@ -724,15 +715,13 @@ static void dfs_page_ref(struct dfs_page *page) rt_atomic_add(&(page->ref_count), 1); } -static void dfs_page_release(struct dfs_page *page) +static void dfs_page_unref(struct dfs_page *page) { struct dfs_aspace *aspace = page->aspace; dfs_aspace_lock(aspace); - rt_atomic_sub(&(page->ref_count), 1); - - if (rt_atomic_load(&(page->ref_count)) == 0) + if (rt_atomic_dec_and_test(&(page->ref_count))) { dfs_page_unmap(page); @@ -873,7 +862,7 @@ static int dfs_page_remove(struct dfs_page *page) rt_atomic_sub(&(__pcache.pages_count), 1); - dfs_page_release(page); + dfs_page_unref(page); ret = 0; } @@ -1032,7 +1021,7 @@ static struct dfs_page *dfs_page_lookup(struct dfs_file *file, off_t pos) } else { - dfs_page_release(page); + dfs_page_unref(page); } } else @@ -1044,7 +1033,7 @@ static struct dfs_page *dfs_page_lookup(struct dfs_file *file, off_t pos) page = dfs_page_search(aspace, fpos); if (page) { - dfs_page_release(page); + dfs_page_unref(page); } count --; @@ -1116,11 +1105,11 @@ int dfs_aspace_read(struct dfs_file *file, void *buf, size_t count, off_t *pos) } else { - dfs_page_release(page); + dfs_page_unref(page); dfs_aspace_unlock(aspace); break; } - dfs_page_release(page); + dfs_page_unref(page); dfs_aspace_unlock(aspace); } else @@ -1189,7 +1178,7 @@ int dfs_aspace_write(struct dfs_file *file, const void *buf, size_t count, off_t dfs_page_dirty(page); } - dfs_page_release(page); + dfs_page_unref(page); dfs_aspace_unlock(aspace); } else @@ -1204,72 +1193,71 @@ int dfs_aspace_write(struct dfs_file *file, const void *buf, size_t count, off_t int dfs_aspace_flush(struct dfs_aspace *aspace) { - if (aspace) - { - rt_list_t *next; - struct dfs_page *page; + RT_ASSERT(aspace); - dfs_aspace_lock(aspace); + rt_list_t *next; + struct dfs_page *page; + + dfs_aspace_lock(aspace); - if (aspace->pages_count > 0 && aspace->vnode) + if (aspace->pages_count > 0 && aspace->vnode) + { + rt_list_for_each(next, &aspace->list_dirty) { - rt_list_for_each(next, &aspace->list_dirty) + page = rt_list_entry(next, struct dfs_page, dirty_node); + if (page->is_dirty == 1 && aspace->vnode) { - page = rt_list_entry(next, struct dfs_page, dirty_node); - if (page->is_dirty == 1 && aspace->vnode) + if (aspace->vnode->size < page->fpos + page->size) { - if (aspace->vnode->size < page->fpos + page->size) - { - page->len = aspace->vnode->size - page->fpos; - } - else - { - page->len = page->size; - } - - if (aspace->ops->write) - { - aspace->ops->write(page); - } + page->len = aspace->vnode->size - page->fpos; + } + else + { + page->len = page->size; + } - page->is_dirty = 0; + if (aspace->ops->write) + { + aspace->ops->write(page); } - RT_ASSERT(page->is_dirty == 0); + + page->is_dirty = 0; } + RT_ASSERT(page->is_dirty == 0); } - - dfs_aspace_unlock(aspace); } + + dfs_aspace_unlock(aspace); + return 0; } int dfs_aspace_clean(struct dfs_aspace *aspace) { - if (aspace) + RT_ASSERT(aspace); + + dfs_aspace_lock(aspace); + + if (aspace->pages_count > 0) { - dfs_aspace_lock(aspace); + rt_list_t *next = aspace->list_active.next; + struct dfs_page *page; - if (aspace->pages_count > 0) + while (next && next != &aspace->list_active) { - rt_list_t *next = aspace->list_active.next; - struct dfs_page *page; - - while (next && next != &aspace->list_active) + if (next == &aspace->list_inactive) { - if (next == &aspace->list_inactive) - { - next = next->next; - continue; - } - page = rt_list_entry(next, struct dfs_page, space_node); next = next->next; - dfs_page_remove(page); + continue; } + page = rt_list_entry(next, struct dfs_page, space_node); + next = next->next; + dfs_page_remove(page); } - - dfs_aspace_unlock(aspace); } + dfs_aspace_unlock(aspace); + return 0; } @@ -1312,18 +1300,18 @@ void *dfs_aspace_mmap(struct dfs_file *file, struct rt_varea *varea, void *vaddr map->vaddr = vaddr; dfs_aspace_lock(aspace); rt_list_insert_after(&page->mmap_head, &map->mmap_node); - dfs_page_release(page); + dfs_page_unref(page); dfs_aspace_unlock(aspace); } else { - dfs_page_release(page); + dfs_page_unref(page); rt_free(map); } } else { - dfs_page_release(page); + dfs_page_unref(page); } } @@ -1437,7 +1425,7 @@ int dfs_aspace_page_unmap(struct dfs_file *file, struct rt_varea *varea, void *v } } - dfs_page_release(page); + dfs_page_unref(page); } dfs_aspace_unlock(aspace); @@ -1459,7 +1447,7 @@ int dfs_aspace_page_dirty(struct dfs_file *file, struct rt_varea *varea, void *v if (page) { dfs_page_dirty(page); - dfs_page_release(page); + dfs_page_unref(page); } dfs_aspace_unlock(aspace); diff --git a/components/dfs/dfs_v2/src/dfs_posix.c b/components/dfs/dfs_v2/src/dfs_posix.c index ef6e8e78e51..f6e4ba9e17e 100644 --- a/components/dfs/dfs_v2/src/dfs_posix.c +++ b/components/dfs/dfs_v2/src/dfs_posix.c @@ -67,6 +67,9 @@ int open(const char *file, int flags, ...) } result = dfs_file_open(df, file, flags, mode); + + dfs_file_put(df); + if (result < 0) { fd_release(fd); @@ -100,15 +103,23 @@ int openat(int dirfd, const char *path, int flag, ...) if (dirfd != AT_FDCWD) { d = fd_get(dirfd); - if (!d || !d->vnode) + if (!d) { rt_set_errno(-EBADF); return -1; } + if (!d->vnode) + { + dfs_file_put(d); + rt_set_errno(-EBADF); + return -1; + } + fullpath = dfs_dentry_full_path(d->dentry); if (!fullpath) { + dfs_file_put(d); rt_set_errno(-ENOMEM); return -1; } @@ -122,6 +133,8 @@ int openat(int dirfd, const char *path, int flag, ...) rt_free(fullpath); } + dfs_file_put(d); + return fd; } @@ -157,14 +170,24 @@ int utimensat(int __fd, const char *__path, const struct timespec __times[2], in if (__fd != AT_FDCWD) { d = fd_get(__fd); - if (!d || !d->vnode) + if (!d) + { + rt_set_errno(-EBADF); + return -1; + } + + if (!d->vnode) { - return -EBADF; + dfs_file_put(d); + rt_set_errno(-EBADF); + return -1; } fullpath = dfs_dentry_full_path(d->dentry); + dfs_file_put(d); + if (!fullpath) - { + { rt_set_errno(-ENOMEM); return -1; } @@ -258,17 +281,9 @@ RTM_EXPORT(creat); int close(int fd) { int result; - struct dfs_file *file; - file = fd_get(fd); - if (file == NULL) - { - rt_set_errno(-EBADF); + result = fd_release(fd); - return -1; - } - - result = dfs_file_close(file); if (result < 0) { rt_set_errno(result); @@ -276,8 +291,6 @@ int close(int fd) return -1; } - fd_release(fd); - return 0; } RTM_EXPORT(close); @@ -317,6 +330,9 @@ ssize_t read(int fd, void *buf, size_t len) } result = dfs_file_read(file, buf, len); + + dfs_file_put(file); + if (result < 0) { rt_set_errno(result); @@ -362,6 +378,9 @@ ssize_t write(int fd, const void *buf, size_t len) } result = dfs_file_write(file, buf, len); + + dfs_file_put(file); + if (result < 0) { rt_set_errno(result); @@ -397,6 +416,9 @@ off_t lseek(int fd, off_t offset, int whence) } result = dfs_file_lseek(file, offset, whence); + + dfs_file_put(file); + if (result < 0) { rt_set_errno(result); @@ -542,6 +564,8 @@ int fstat(int fildes, struct stat *buf) ret = file->dentry->mnt->fs_ops->stat(file->dentry, buf); } + dfs_file_put(file); + return ret; } RTM_EXPORT(fstat); @@ -572,6 +596,8 @@ int fsync(int fildes) ret = dfs_file_fsync(file); + dfs_file_put(file); + return ret; } RTM_EXPORT(fsync); @@ -604,6 +630,9 @@ int fcntl(int fildes, int cmd, ...) va_end(ap); ret = dfs_file_ioctl(file, cmd, arg); + + dfs_file_put(file); + if (ret < 0) { ret = dfs_file_fcntl(fildes, cmd, (unsigned long)arg); @@ -675,12 +704,16 @@ int ftruncate(int fd, off_t length) if (length < 0) { + dfs_file_put(file); rt_set_errno(-EINVAL); return -1; } result = dfs_file_ftruncate(file, length); + + dfs_file_put(file); + if (result < 0) { rt_set_errno(result); @@ -745,6 +778,7 @@ int fstatfs(int fildes, struct statfs *buf) /* get the fd */ file = fd_get(fildes); + if (file == NULL) { rt_set_errno(-EBADF); @@ -757,6 +791,8 @@ int fstatfs(int fildes, struct statfs *buf) ret = file->dentry->mnt->fs_ops->statfs(file->dentry->mnt, buf); } + dfs_file_put(file); + return ret; } RTM_EXPORT(fstatfs); @@ -908,14 +944,20 @@ DIR *opendir(const char *name) return RT_NULL; } + if (file == RT_NULL) + { + 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(file); fd_release(fd); } else @@ -925,10 +967,13 @@ DIR *opendir(const char *name) t->fd = fd; } + dfs_file_put(file); return t; } + dfs_file_put(file); fd_release(fd); + rt_set_errno(result); return NULL; @@ -967,13 +1012,21 @@ struct dirent *readdir(DIR *d) if (!d->num || d->cur >= d->num) { /* get a new entry */ - result = dfs_file_getdents(fd_get(d->fd), + struct dfs_file *file = fd_get(d->fd); + if (file == RT_NULL) + { + rt_set_errno(-EBADF); + return NULL; + } + result = dfs_file_getdents(file, (struct dirent *)d->buf, sizeof(d->buf) - 1); + + dfs_file_put(file); + if (result <= 0) { rt_set_errno(result); - return NULL; } @@ -1016,12 +1069,12 @@ long telldir(DIR *d) if (file == NULL) { rt_set_errno(-EBADF); - return 0; } result = file->fpos - d->num + d->cur; + dfs_file_put(file); return result; } RTM_EXPORT(telldir); @@ -1047,7 +1100,6 @@ void seekdir(DIR *d, long offset) if (file == NULL) { rt_set_errno(-EBADF); - return; } @@ -1056,7 +1108,7 @@ void seekdir(DIR *d, long offset) if (file->fpos > offset) { /* seek to the offset position of directory */ - if (dfs_file_lseek(fd_get(d->fd), 0, SEEK_SET) >= 0) + if (dfs_file_lseek(file, 0, SEEK_SET) >= 0) d->num = d->cur = 0; } @@ -1068,6 +1120,8 @@ void seekdir(DIR *d, long offset) } } } + + dfs_file_put(file); } RTM_EXPORT(seekdir); @@ -1081,9 +1135,19 @@ void rewinddir(DIR *d) { if (d && d->fd > 0) { + struct dfs_file *file = fd_get(d->fd); + + if (file == NULL) + { + rt_set_errno(-EBADF); + return; + } + /* seek to the beginning of directory */ - if (dfs_file_lseek(fd_get(d->fd), 0, SEEK_SET) >= 0) + if (dfs_file_lseek(file, 0, SEEK_SET) >= 0) d->num = d->cur = 0; + + dfs_file_put(file); } } RTM_EXPORT(rewinddir); @@ -1099,7 +1163,6 @@ RTM_EXPORT(rewinddir); int closedir(DIR *d) { int result; - struct dfs_file *file; if (d == NULL) { @@ -1107,14 +1170,8 @@ int closedir(DIR *d) return -1; } - file = fd_get(d->fd); - if (file == NULL) - { - rt_set_errno(-EBADF); - return -1; - } + result = fd_release(d->fd); - result = dfs_file_close(file); if (result < 0) { rt_set_errno(result); @@ -1123,7 +1180,6 @@ int closedir(DIR *d) } else { - fd_release(d->fd); rt_free(d); } @@ -1367,6 +1423,9 @@ ssize_t pread(int fd, void *buf, size_t len, off_t offset) result = dfs_file_pread(file, buf, len, offset); /* fpos unlock */ dfs_file_set_fpos(file, fpos); + + dfs_file_put(file); + if (result < 0) { rt_set_errno(result); @@ -1413,6 +1472,9 @@ ssize_t pwrite(int fd, const void *buf, size_t len, off_t offset) result = dfs_file_pwrite(file, buf, len, offset); /* fpos unlock */ dfs_file_set_fpos(file, fpos); + + dfs_file_put(file); + if (result < 0) { rt_set_errno(result); diff --git a/components/dfs/dfs_v2/src/dfs_vnode.c b/components/dfs/dfs_v2/src/dfs_vnode.c index 21778e683c3..b6df6a39f54 100644 --- a/components/dfs/dfs_v2/src/dfs_vnode.c +++ b/components/dfs/dfs_v2/src/dfs_vnode.c @@ -20,15 +20,14 @@ 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)); + RT_ASSERT(vnode); - vnode->type = type; - rt_atomic_store(&(vnode->ref_count), 1); - vnode->mnt = RT_NULL; - vnode->fops = fops; - } + 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; } @@ -53,39 +52,32 @@ int dfs_vnode_destroy(struct dfs_vnode* vnode) { rt_err_t ret = RT_EOK; - if (vnode) + RT_ASSERT(vnode); + RT_ASSERT(rt_atomic_dec_and_test(&vnode->ref_count)); + + ret = dfs_file_lock(); + if (ret == RT_EOK) { - ret = dfs_file_lock(); - if (ret == RT_EOK) - { - if (rt_atomic_load(&(vnode->ref_count)) == 1) - { - LOG_I("free a vnode: %p", vnode); + LOG_I("free a vnode: %p", vnode); #ifdef RT_USING_PAGECACHE - if (vnode->aspace) - { - dfs_aspace_destroy(vnode->aspace); - } + if (vnode->aspace) + { + dfs_aspace_destroy(vnode->aspace); + } #endif - 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(); - } + 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); } return 0; @@ -93,12 +85,11 @@ int dfs_vnode_destroy(struct dfs_vnode* vnode) struct dfs_vnode *dfs_vnode_ref(struct dfs_vnode *vnode) { - if (vnode) - { - rt_atomic_add(&(vnode->ref_count), 1); + RT_ASSERT(vnode); - DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count))); - } + rt_atomic_add(&(vnode->ref_count), 1); + + DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count))); return vnode; } @@ -107,39 +98,34 @@ void dfs_vnode_unref(struct dfs_vnode *vnode) { rt_err_t ret = RT_EOK; - if (vnode) + RT_ASSERT(vnode); + + DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count))); + + if (rt_atomic_dec_and_test(&vnode->ref_count)) { 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))); #ifdef RT_USING_PAGECACHE if (vnode->aspace) { dfs_aspace_destroy(vnode->aspace); } #endif - 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(); + LOG_I("free a vnode: %p", vnode); + DLOG(msg, "vnode", "vnode", DLOG_MSG, "free vnode, ref_count=0"); - rt_free(vnode); - } - else + if (vnode->mnt) { - dfs_file_unlock(); - DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count))); + 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); } } diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 7677b8deea5..78bdf52dc0e 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -369,6 +369,10 @@ static int epoll_epf_init(int fd) { ret = -ENOMEM; } + +#ifdef RT_USING_DFS_V2 + dfs_file_put(df); +#endif } return ret; @@ -656,6 +660,10 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) break; } +#ifdef RT_USING_DFS_V2 + dfs_file_put(epdf); +#endif + if (ret < 0) { rt_set_errno(-ret); @@ -750,6 +758,11 @@ static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req) { req->_key = fl->revents | POLLERR | POLLHUP; mask = df->vnode->fops->poll(df, req); + +#ifdef RT_USING_DFS_V2 + dfs_file_put(df); +#endif + if (mask < 0) return mask; } @@ -931,13 +944,27 @@ static int epoll_do_wait(int epfd, struct epoll_event *events, int maxevents, in if ((maxevents > 0) && (epfd >= 0)) { df = fd_get(epfd); + if (df && df->vnode) { ep = (struct rt_eventpoll *)df->vnode->data; + if (ep) { ret = epoll_do(ep, events, maxevents, timeout); } +#ifdef RT_USING_DFS_V2 + dfs_file_put(df); +#endif + } + else if (!df) + { + ret = -EBADF; + } + else if (!df->vnode) + { + dfs_file_put(df); + ret = -EBADF; } } diff --git a/components/libc/posix/io/eventfd/eventfd.c b/components/libc/posix/io/eventfd/eventfd.c index b42a9b01a0c..07a7ab62705 100644 --- a/components/libc/posix/io/eventfd/eventfd.c +++ b/components/libc/posix/io/eventfd/eventfd.c @@ -317,6 +317,11 @@ static int do_eventfd(unsigned int count, int flags) file = fd_get(fd); status = rt_eventfd_create(file, count, flags); + +#ifdef RT_USING_DFS_V2 + dfs_file_put(file); +#endif + if (status < 0) { fd_release(fd); diff --git a/components/libc/posix/io/poll/poll.c b/components/libc/posix/io/poll/poll.c index 7ab4a9bec13..01e37727844 100644 --- a/components/libc/posix/io/poll/poll.c +++ b/components/libc/posix/io/poll/poll.c @@ -224,6 +224,9 @@ static int do_pollfd(struct pollfd *pollfd, rt_pollreq_t *req) mask = f->vnode->fops->poll(f, req); +#ifdef RT_USING_DFS_V2 + dfs_file_put(f); +#endif /* dealwith the device return error -1*/ if (mask < 0) { diff --git a/components/libc/posix/io/signalfd/signalfd.c b/components/libc/posix/io/signalfd/signalfd.c index b4a08fa9467..33c3d2f56f2 100644 --- a/components/libc/posix/io/signalfd/signalfd.c +++ b/components/libc/posix/io/signalfd/signalfd.c @@ -345,6 +345,9 @@ static int signalfd_do(int fd, const sigset_t *mask, int flags) fd_release(fd); ret = -1; } + #ifdef RT_USING_DFS_V2 + dfs_file_put(df); + #endif } else { @@ -361,6 +364,9 @@ static int signalfd_do(int fd, const sigset_t *mask, int flags) sigemptyset(&sfd->sigmask); memcpy(&sfd->sigmask, mask, sizeof(sigset_t)); ret = fd; + #ifdef RT_USING_DFS_V2 + dfs_file_put(df); + #endif } else { diff --git a/components/libc/posix/io/timerfd/timerfd.c b/components/libc/posix/io/timerfd/timerfd.c index 19f86e48cc9..31fabfb9ccb 100644 --- a/components/libc/posix/io/timerfd/timerfd.c +++ b/components/libc/posix/io/timerfd/timerfd.c @@ -262,6 +262,9 @@ static int timerfd_do_create(int clockid, int flags) rt_set_errno(ENOMEM); ret = -1; } +#ifdef RT_USING_DFS_V2 + dfs_file_put(df); +#endif } else { @@ -383,6 +386,10 @@ static int timerfd_do_settime(int fd, int flags, const struct itimerspec *new, s tfd = df->vnode->data; +#ifdef RT_USING_DFS_V2 + dfs_file_put(df); +#endif + rt_atomic_store(&(tfd->ticks), 0); rt_atomic_store(&(tfd->timeout_num), 0); @@ -510,6 +517,10 @@ static int timerfd_do_gettime(int fd, struct itimerspec *cur) tfd = df->vnode->data; +#ifdef RT_USING_DFS_V2 + dfs_file_put(df); +#endif + get_current_time(tfd, &cur_time); rt_mutex_take(&tfd->lock, RT_WAITING_FOREVER); diff --git a/components/lwp/lwp.c b/components/lwp/lwp.c index e8092226cae..8864cb3433d 100644 --- a/components/lwp/lwp.c +++ b/components/lwp/lwp.c @@ -291,13 +291,17 @@ static void lwp_execve_setup_stdio(struct rt_lwp *lwp) /* init 4 fds */ lwp_fdt->fds = rt_calloc(4, sizeof(void *)); + rt_memset(lwp_fdt->fds, 0, 4 * sizeof(void *)); + if (lwp_fdt->fds) { cons_file = fd_get(cons_fd); lwp_fdt->maxfd = 4; - fdt_fd_associate_file(lwp_fdt, 0, cons_file); - fdt_fd_associate_file(lwp_fdt, 1, cons_file); - fdt_fd_associate_file(lwp_fdt, 2, cons_file); + + fdt_fd_associate_file(lwp_fdt, 0, cons_file, RT_FALSE); + fdt_fd_associate_file(lwp_fdt, 1, cons_file, RT_FALSE); + fdt_fd_associate_file(lwp_fdt, 2, cons_file, RT_FALSE); + dfs_file_put(cons_file); } close(cons_fd); diff --git a/components/lwp/lwp_ipc.c b/components/lwp/lwp_ipc.c index f75597376d2..143bebe56bf 100644 --- a/components/lwp/lwp_ipc.c +++ b/components/lwp/lwp_ipc.c @@ -412,7 +412,11 @@ static void *_ipc_msg_get_file(int fd) return RT_NULL; if (!d->vnode) + { + dfs_file_put(d); return RT_NULL; + } + return (void *)d; } @@ -433,6 +437,8 @@ static int _ipc_msg_fd_new(void *file) df = (struct dfs_file *)file; + dfs_file_get(df); + fd = fd_new(); if (fd < 0) { @@ -465,6 +471,9 @@ static int _ipc_msg_fd_new(void *file) d->vnode->ref_count++; #endif + dfs_file_put(d); + dfs_file_put(df); + return fd; } @@ -1002,6 +1011,8 @@ static void _chfd_free(int fd, int fdt_type) { return; } + + dfs_file_put(d); lwp_fd_release(fdt_type, fd); } @@ -1091,6 +1102,7 @@ int lwp_channel_open(int fdt_type, const char *name, int flags) d->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode)); if (!d->vnode) { + dfs_file_put(d); _chfd_free(fd, fdt_type); fd = -1; goto quit; @@ -1113,6 +1125,7 @@ int lwp_channel_open(int fdt_type, const char *name, int flags) _chfd_free(fd, fdt_type); fd = -1; } + dfs_file_put(d); quit: return fd; } @@ -1127,6 +1140,7 @@ static rt_channel_t fd_2_channel(int fdt_type, int fd) rt_channel_t ch; ch = (rt_channel_t)d->vnode->data; + dfs_file_put(d); if (ch) { return ch; @@ -1150,9 +1164,11 @@ rt_err_t lwp_channel_close(int fdt_type, int fd) vnode = d->vnode; if (!vnode) { + dfs_file_put(d); return -RT_EIO; } + dfs_file_put(d); ch = fd_2_channel(fdt_type, fd); if (!ch) { diff --git a/components/lwp/lwp_pid.c b/components/lwp/lwp_pid.c index af32818162a..2438f2f63a1 100644 --- a/components/lwp/lwp_pid.c +++ b/components/lwp/lwp_pid.c @@ -220,7 +220,6 @@ static void __exit_files(struct rt_lwp *lwp) d = lwp->fdt.fds[fd]; if (d) { - dfs_file_close(d); fdt_fd_release(&lwp->fdt, fd); } fd--; diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 21a34bd28ee..44370b090c6 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -1999,6 +1999,8 @@ static int lwp_copy_files(struct rt_lwp *dst, struct rt_lwp *src) dst_fdt = &dst->fdt; /* init fds */ dst_fdt->fds = rt_calloc(src_fdt->maxfd, sizeof(void *)); + rt_memset(dst_fdt->fds, 0, src_fdt->maxfd * sizeof(void *)); + if (dst_fdt->fds) { struct dfs_file *d_s; @@ -2013,8 +2015,8 @@ static int lwp_copy_files(struct rt_lwp *dst, struct rt_lwp *src) d_s = fdt_get_file(src_fdt, i); if (d_s) { - dst_fdt->fds[i] = d_s; - d_s->ref_count++; + fdt_fd_associate_file(dst_fdt, i, d_s, RT_FALSE); + dfs_file_put(d_s); } } dfs_file_unlock(); @@ -4417,11 +4419,20 @@ sysret_t sys_fchdir(int fd) char *kpath; d = fd_get(fd); - if (!d || !d->vnode) + if (!d) + { + return -EBADF; + } + + if (!d->vnode) { + dfs_file_put(d); return -EBADF; } + kpath = dfs_dentry_full_path(d->dentry); + dfs_file_put(d); + if (!kpath) { return -EACCES; @@ -4546,7 +4557,16 @@ sysret_t sys_getdents(int fd, struct libc_dirent *dirp, size_t nbytes) return -ENOMEM; } file = fd_get(fd); + + if (!file) + { + return -EBADF; + } + ret = dfs_file_getdents(file, rtt_dirp, rtt_nbytes); + + dfs_file_put(file); + if (ret > 0) { size_t i = 0; diff --git a/components/lwp/lwp_user_mm.c b/components/lwp/lwp_user_mm.c index 18f10e176fe..48b808922ff 100644 --- a/components/lwp/lwp_user_mm.c +++ b/components/lwp/lwp_user_mm.c @@ -560,6 +560,8 @@ void *lwp_mmap2(struct rt_lwp *lwp, void *addr, size_t length, int prot, mmap2.lwp = lwp; rc = dfs_file_mmap2(d, &mmap2); + dfs_file_put(d); + if (rc == RT_EOK) { ret = mmap2.ret; diff --git a/components/net/sal/dfs_net/dfs_net.c b/components/net/sal/dfs_net/dfs_net.c index cae03c40a1c..46b3ff9ca48 100644 --- a/components/net/sal/dfs_net/dfs_net.c +++ b/components/net/sal/dfs_net/dfs_net.c @@ -29,6 +29,10 @@ int dfs_net_getsocket(int fd) if (file->vnode->type != FT_SOCKET) socket = -1; else socket = (int)(size_t)file->vnode->data; +#ifdef RT_USING_DFS_V2 + dfs_file_put(file); +#endif + return socket; } @@ -89,7 +93,7 @@ static int dfs_net_close(struct dfs_file* file) int socket; int ret = 0; - if (file->vnode->ref_count == 1) + if (file->vnode && file->vnode->ref_count == 1) { socket = (int)(size_t)file->vnode->data; ret = sal_closesocket(socket); diff --git a/components/net/sal/socket/net_sockets.c b/components/net/sal/socket/net_sockets.c index 63de88e870d..2e51e56596c 100644 --- a/components/net/sal/socket/net_sockets.c +++ b/components/net/sal/socket/net_sockets.c @@ -59,6 +59,9 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen) /* set socket to the data of dfs_file */ d->vnode->data = (void *)(size_t)new_socket; +#ifdef RT_USING_DFS_V2 + dfs_file_put(d); +#endif return fd; } @@ -99,6 +102,10 @@ int shutdown(int s, int how) return -1; } +#ifdef RT_USING_DFS_V2 + dfs_file_put(d); +#endif + if (sal_shutdown(socket, how) == 0) { error = 0; @@ -231,27 +238,38 @@ int socket(int domain, int type, int protocol) d->fops = dfs_net_get_fops(); #endif - d->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode)); - if (!d->vnode) - { - /* release fd */ - fd_release(fd); - rt_set_errno(-ENOMEM); - return -1; - } - /* create socket and then put it to the dfs_file */ socket = sal_socket(domain, type, protocol); + if (socket >= 0) { + d->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode)); + + if (!d->vnode) + { +#ifdef RT_USING_DFS_V2 + dfs_file_put(d); +#endif + /* release fd */ + fd_release(fd); + rt_set_errno(-ENOMEM); + return -1; + } + dfs_vnode_init(d->vnode, FT_SOCKET, dfs_net_get_fops()); d->flags = O_RDWR; /* set flags as read and write */ /* set socket to the data of dfs_file */ d->vnode->data = (void *)(size_t)socket; +#ifdef RT_USING_DFS_V2 + dfs_file_put(d); +#endif } else { +#ifdef RT_USING_DFS_V2 + dfs_file_put(d); +#endif /* release fd */ fd_release(fd); rt_set_errno(-ENOMEM); @@ -284,10 +302,17 @@ int closesocket(int s) if (!d->vnode) { +#ifdef RT_USING_DFS_V2 + dfs_file_put(d); +#endif rt_set_errno(-EBADF); return -1; } +#ifdef RT_USING_DFS_V2 + dfs_file_put(d); +#endif + if (sal_closesocket(socket) == 0) { error = 0;