diff --git a/components/dfs/dfs_v2/include/dfs_pcache.h b/components/dfs/dfs_v2/include/dfs_pcache.h index 01abfe3150..db1bb6db74 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 b08c52acf0..a8b81f12e6 100644 --- a/components/dfs/dfs_v2/src/dfs.c +++ b/components/dfs/dfs_v2/src/dfs.c @@ -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; @@ -638,7 +638,7 @@ 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; } diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c index 69c00ed26e..11bb70fe6b 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; } @@ -256,7 +260,7 @@ static void _dfs_file_release(struct rt_ref *ref) if (file->vnode) { - dfs_vnode_unref(file->vnode); + //dfs_vnode_unref(file->vnode); } if (file->mmap_context) @@ -720,7 +724,7 @@ int dfs_file_close(struct dfs_file *file) { DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)"); #ifdef RT_USING_PAGECACHE - if (file->vnode->aspace) + if (file->vnode && file->vnode->aspace) { ret = dfs_aspace_flush(file->vnode->aspace); } @@ -1269,6 +1273,8 @@ int dfs_file_fcntl(int fd, int cmd, unsigned long arg) ret = -EBADF; } + dfs_file_put(file); + return ret; } diff --git a/components/dfs/dfs_v2/src/dfs_pcache.c b/components/dfs/dfs_v2/src/dfs_pcache.c index 6868170b9c..1f2b2fab75 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 --; - } - } - - 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) - { - cnt --; - } + cnt --; } } - dfs_aspace_unlock(aspace); + 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) + { + cnt --; + } + } } + 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) + RT_ASSERT(aspace); + + dfs_pcache_lock(); + dfs_aspace_lock(aspace); + + if (aspace->pages_count == 0) { - dfs_pcache_lock(); - dfs_aspace_lock(aspace); - - if (rt_atomic_load(&aspace->ref_count) == 1 && 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,7 +715,7 @@ 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; @@ -873,7 +864,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 +1023,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 +1035,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 +1107,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 +1180,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 +1195,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_ASSERT(aspace); + + rt_list_t *next; + struct dfs_page *page; + + dfs_aspace_lock(aspace); + + if (aspace->pages_count > 0 && aspace->vnode) { - rt_list_t *next; - struct dfs_page *page; - - dfs_aspace_lock(aspace); - - 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->is_dirty = 0; + page->len = aspace->vnode->size - page->fpos; + } + else + { + page->len = page->size; } - RT_ASSERT(page->is_dirty == 0); - } - } - dfs_aspace_unlock(aspace); + if (aspace->ops->write) + { + aspace->ops->write(page); + } + + page->is_dirty = 0; + } + RT_ASSERT(page->is_dirty == 0); + } } + + 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 +1302,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 +1427,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 +1449,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_vnode.c b/components/dfs/dfs_v2/src/dfs_vnode.c index b2379384a8..b6df6a39f5 100644 --- a/components/dfs/dfs_v2/src/dfs_vnode.c +++ b/components/dfs/dfs_v2/src/dfs_vnode.c @@ -53,37 +53,31 @@ int dfs_vnode_destroy(struct dfs_vnode* vnode) rt_err_t ret = RT_EOK; RT_ASSERT(vnode); + RT_ASSERT(rt_atomic_dec_and_test(&vnode->ref_count)); 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); + 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 { - dfs_file_unlock(); + DLOG(msg, "vnode", "vnode", DLOG_MSG, "destroy vnode(mnt=NULL)"); } + + dfs_file_unlock(); + + rt_free(vnode); } return 0; @@ -106,19 +100,20 @@ void dfs_vnode_unref(struct dfs_vnode *vnode) RT_ASSERT(vnode); - ret = dfs_file_lock(); - if (ret == RT_EOK) + DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count))); + + if (rt_atomic_dec_and_test(&vnode->ref_count)) { - rt_atomic_sub(&(vnode->ref_count), 1); - DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count))); + ret = dfs_file_lock(); + + if (ret == RT_EOK) + { #ifdef RT_USING_PAGECACHE - if (vnode->aspace) - { - dfs_aspace_destroy(vnode->aspace); - } + 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"); @@ -132,11 +127,6 @@ void dfs_vnode_unref(struct dfs_vnode *vnode) rt_free(vnode); } - else - { - dfs_file_unlock(); - DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count))); - } } return; diff --git a/components/net/sal/dfs_net/dfs_net.c b/components/net/sal/dfs_net/dfs_net.c index 660c30773b..46b3ff9ca4 100644 --- a/components/net/sal/dfs_net/dfs_net.c +++ b/components/net/sal/dfs_net/dfs_net.c @@ -93,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 4286fc08b4..2e51e56596 100644 --- a/components/net/sal/socket/net_sockets.c +++ b/components/net/sal/socket/net_sockets.c @@ -238,22 +238,24 @@ 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) - { -#ifdef RT_USING_DFS_V2 - dfs_file_put(d); -#endif - /* 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 */