148 lines
3.4 KiB
C
148 lines
3.4 KiB
C
|
/*
|
||
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2023-05-05 Bernard Implement vnode in dfs v2.0
|
||
|
*/
|
||
|
|
||
|
#include <dfs_file.h>
|
||
|
#include <dfs_mnt.h>
|
||
|
#ifdef RT_USING_PAGECACHE
|
||
|
#include "dfs_pcache.h"
|
||
|
#endif
|
||
|
|
||
|
#define DBG_TAG "DFS.vnode"
|
||
|
#define DBG_LVL DBG_WARNING
|
||
|
#include <rtdbg.h>
|
||
|
|
||
|
int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops)
|
||
|
{
|
||
|
if (vnode)
|
||
|
{
|
||
|
rt_memset(vnode, 0, sizeof(struct dfs_vnode));
|
||
|
|
||
|
vnode->type = type;
|
||
|
rt_atomic_store(&(vnode->ref_count), 1);
|
||
|
vnode->mnt = RT_NULL;
|
||
|
vnode->fops = fops;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
struct dfs_vnode *dfs_vnode_create(void)
|
||
|
{
|
||
|
struct dfs_vnode *vnode = rt_calloc(1, sizeof(struct dfs_vnode));
|
||
|
if (!vnode)
|
||
|
{
|
||
|
LOG_E("create a vnode failed.");
|
||
|
return RT_NULL;
|
||
|
}
|
||
|
|
||
|
rt_atomic_store(&(vnode->ref_count), 1);
|
||
|
|
||
|
LOG_I("create a vnode: %p", vnode);
|
||
|
|
||
|
return vnode;
|
||
|
}
|
||
|
|
||
|
int dfs_vnode_destroy(struct dfs_vnode* vnode)
|
||
|
{
|
||
|
rt_err_t ret = RT_EOK;
|
||
|
|
||
|
if (vnode)
|
||
|
{
|
||
|
ret = dfs_file_lock();
|
||
|
if (ret == RT_EOK)
|
||
|
{
|
||
|
if (rt_atomic_load(&(vnode->ref_count)) == 1)
|
||
|
{
|
||
|
LOG_I("free a vnode: %p", vnode);
|
||
|
#ifdef RT_USING_PAGECACHE
|
||
|
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();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
struct dfs_vnode *dfs_vnode_ref(struct dfs_vnode *vnode)
|
||
|
{
|
||
|
if (vnode)
|
||
|
{
|
||
|
rt_atomic_add(&(vnode->ref_count), 1);
|
||
|
|
||
|
DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
|
||
|
}
|
||
|
|
||
|
return vnode;
|
||
|
}
|
||
|
|
||
|
void dfs_vnode_unref(struct dfs_vnode *vnode)
|
||
|
{
|
||
|
rt_err_t ret = RT_EOK;
|
||
|
|
||
|
if (vnode)
|
||
|
{
|
||
|
ret = dfs_file_lock();
|
||
|
if (ret == RT_EOK)
|
||
|
{
|
||
|
rt_atomic_sub(&(vnode->ref_count), 1);
|
||
|
DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
|
||
|
#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();
|
||
|
|
||
|
rt_free(vnode);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dfs_file_unlock();
|
||
|
DLOG(note, "vnode", "vnode ref_count=%d", rt_atomic_load(&(vnode->ref_count)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|