69#define ENTRY_TO_VNODE(ptr) LOS_DL_LIST_ENTRY(ptr, struct Vnode, actFreeEntry)
70#define VNODE_LRU_COUNT 10
71#define DEV_VNODE_MODE 0755
94 if (retval != LOS_OK) {
95 PRINT_ERR(
"Create mutex for vnode fail, status: %d", retval);
103 if (retval != LOS_OK) {
104 PRINT_ERR(
"VnodeInit failed error %d\n", retval);
119 struct Vnode *vnode = NULL;
122 PRINT_ERR(
"get vnode from free list failed, list empty but g_freeVnodeSize = %d!\n",
g_freeVnodeSize);
135 struct Vnode *item = NULL;
136 struct Vnode *nextItem = NULL;
137 int releaseCount = 0;
141 (item->
flag & VNODE_FLAG_MOUNT_ORIGIN) ||
142 (item->
flag & VNODE_FLAG_MOUNT_NEW)) {
149 if (releaseCount >= VNODE_LRU_COUNT) {
154 if (releaseCount == 0) {
155 PRINT_ERR(
"VnodeAlloc failed, vnode size hit max but can't reclaim anymore!\n");
161 PRINT_ERR(
"VnodeAlloc failed, reclaim and get from free list failed!\n");
168 struct Vnode* vnode = NULL;
242 (
void)memset_s(vnode,
sizeof(
struct Vnode), 0,
sizeof(
struct Vnode));
253 struct Vnode *vnode = NULL;
254 struct Vnode *nextVnode = NULL;
258 if ((vnode->
originMount == mount) && !(vnode->
flag & VNODE_FLAG_MOUNT_NEW)) {
271 struct Vnode *vnode = NULL;
275 if ((vnode->
useCount > 0) || (vnode->
flag & VNODE_FLAG_MOUNT_ORIGIN)) {
287 PRINT_ERR(
"VnodeHold lock failed !\n");
296 PRINT_ERR(
"VnodeDrop unlock failed !\n");
304 while (*pos != 0 && *pos ==
'/') {
311 while (*pos !=
'\0' && *pos !=
'/') {
321 char *absolutePath = NULL;
326 *path = absolutePath;
334 if ((vnode == NULL) || !(vnode->
flag & VNODE_FLAG_MOUNT_ORIGIN)) {
353 if (flags & V_CREATE) {
358 (*vnode)->parent =
parent;
363static int Step(
char **currentDir,
struct Vnode **currentVnode, uint32_t flags)
367 struct Vnode *nextVnode = NULL;
368 char *nextDir = NULL;
373 nextDir =
NextName(*currentDir, &len);
374 if (nextDir == NULL) {
384 (*currentVnode)->useCount++;
385 if (flags & V_DUMMY) {
388 if ((*currentVnode)->vop != NULL && (*currentVnode)->vop->Lookup != NULL) {
389 ret = (*currentVnode)->vop->Lookup(*currentVnode, nextDir, len, &nextVnode);
394 (*currentVnode)->useCount--;
404 *currentDir = nextDir + len;
406 *currentVnode = nextVnode;
416 char *vnodePath = NULL;
417 struct Vnode *startVnode = NULL;
418 char *normalizedPath = NULL;
420 if (orgVnode != NULL) {
421 startVnode = orgVnode;
422 normalizedPath = strdup(path);
423 if (normalizedPath == NULL) {
424 PRINT_ERR(
"[VFS]lookup failed, strdup err\n");
429 ret =
PreProcess(path, &startVnode, &normalizedPath);
431 PRINT_ERR(
"[VFS]lookup failed, invalid path err = %d\n", ret);
436 if (normalizedPath[1] ==
'\0' && normalizedPath[0] ==
'/') {
438 free(normalizedPath);
442 char *currentDir = normalizedPath;
443 struct Vnode *currentVnode = startVnode;
445 while (*currentDir !=
'\0') {
446 ret =
Step(¤tDir, ¤tVnode, flags);
447 if (currentDir == NULL || *currentDir ==
'\0') {
449 *result = currentVnode;
450 if (currentVnode->
filePath == NULL) {
451 currentVnode->
filePath = normalizedPath;
453 free(normalizedPath);
465 if (currentVnode->
filePath == NULL) {
466 vnodePathLen = currentDir - normalizedPath;
467 vnodePath =
malloc(vnodePathLen + 1);
468 if (vnodePath == NULL) {
472 ret = strncpy_s(vnodePath, vnodePathLen + 1, normalizedPath, vnodePathLen);
479 currentVnode->
filePath[vnodePathLen] = 0;
484 if (normalizedPath) {
485 free(normalizedPath);
504 struct Mount *mnt = NULL;
506 struct Vnode *node = NULL;
507 struct Vnode *nodeInFs = NULL;
515 if (strcmp(
name, dirname)) {
522 PRINTK(
"%s-%d %s NOT exist in rootfs\n", __FUNCTION__, __LINE__, dirname);
530 nodeInFs->
flag |= VNODE_FLAG_MOUNT_ORIGIN;
550 unsigned int dstNameSize;
560 if (i < dir->fd_position) {
565 idx = i - dir->fd_position;
567 dstNameSize =
sizeof(dir->fd_dir[idx].d_name);
568 result = strncpy_s(dir->fd_dir[idx].d_name, dstNameSize, item->
name, item->
nameLen);
570 return -ENAMETOOLONG;
572 dir->fd_dir[idx].d_off = i;
573 dir->fd_dir[idx].d_reclen = (uint16_t)
sizeof(
struct dirent);
576 if (++cnt >= dir->read_cnt) {
581 dir->fd_position = i;
603 struct Vnode *newVnode = NULL;
613 newVnode->
data = NULL;
629 struct Vnode *devNode = NULL;
630 struct Mount *devMount = NULL;
632 int retval =
VnodeLookup(
"/dev", &devNode, V_CREATE | V_DUMMY);
633 if (retval != LOS_OK) {
634 PRINT_ERR(
"VnodeDevInit failed error %d\n", retval);
637 devNode->
mode = DEV_VNODE_MODE | S_IFDIR;
641 if (devMount == NULL) {
642 PRINT_ERR(
"VnodeDevInit failed mount point alloc failed.\n");
652 (
void)memset_s(buf,
sizeof(
struct stat), 0,
sizeof(
struct stat));
653 buf->st_mode = vnode->
mode;
654 buf->st_uid = vnode->
uid;
655 buf->st_gid = vnode->
gid;
668 if (vnode == NULL || attr == NULL) {
674 vnode->
mode &= S_IFMT;
675 vnode->
mode = tmpMode | vnode->
mode;
708 struct Vnode *item = NULL;
709 struct Vnode *nextItem = NULL;
714 (item->
flag & VNODE_FLAG_MOUNT_ORIGIN) ||
715 (item->
flag & VNODE_FLAG_MOUNT_NEW)) {
722 PRINTK(
"Vnode number = %d\n", vnodeCount);
723 PRINTK(
"Vnode memory size = %d(B)\n", vnodeCount *
sizeof(
struct Vnode));
743 struct Vnode *item = NULL;
744 struct Vnode *nextItem = NULL;
750 (item->
flag & VNODE_FLAG_MOUNT_ORIGIN) ||
751 (item->
flag & VNODE_FLAG_MOUNT_NEW)) {
int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a new node to a doubly linked list.
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
初始化互斥锁
LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
释放锁
LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
拿互斥锁,
VOID LOS_SpinInit(SPIN_LOCK_S *lock)
void * zalloc(size_t size)
void * malloc(size_t size)
动态分配内存块大小
void free(void *ptr)
释放ptr所指向的内存空间
struct Mount * MountAlloc(struct Vnode *vnode, struct MountOps *mop)
void VnodePathCacheFree(struct Vnode *vnode)
和长辈,晚辈告别,从此不再是父亲和孩子.
int PathCacheFree(struct PathCache *cache)
int PathCacheLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vnode)
struct PathCache * PathCacheAlloc(struct Vnode *parent, struct Vnode *vnode, const char *name, uint8_t len)
unsigned attr_chg_uid
用户ID
unsigned attr_chg_mode
确定了文件的类型,以及它的所有者、它的group、其它用户访问此文件的权限 (S_IWUSR | ...)
unsigned int attr_chg_valid
节点改变有效性 (CHG_MODE | CHG_UID | ... )
举例: mount /dev/mmcblk0p0 /bin1/vs/sd vfat 将/dev/mmcblk0p0 挂载到/bin1/vs/sd目录
struct Vnode * vnodeCovered
struct Vnode * vnodeBeCovered
struct Vnode * childVnode
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
struct page_mapping mapping
LIST_HEAD childPathCaches
struct file_operations_vfs * fop
struct Mount * originMount
LIST_HEAD parentPathCaches
int(* Lookup)(struct Vnode *parent, const char *name, int len, struct Vnode **vnode)
查询节点
int(* Reclaim)(struct Vnode *vnode)
回 收节点
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 ARG_NUM_0 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_6 ARG_NUM_3 ARG_NUM_5 ARG_NUM_7 ARG_NUM_1 ARG_NUM_4 ARG_NUM_5 ARG_NUM_4 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_7 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_7 ARG_NUM_3 ARG_NUM_2 char ARG_NUM_2 ARG_NUM_1 ARG_NUM_0 ARG_NUM_0 ARG_NUM_3 void ARG_NUM_1 ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_5 ARG_NUM_3 ARG_NUM_3 ARG_NUM_4 ARG_NUM_1 ARG_NUM_1 ARG_NUM_3 ARG_NUM_2 mode_t
int VfsVnodePermissionCheck(const struct Vnode *node, int accMode)
static int g_freeVnodeSize
static int ProcessVirtualVnode(struct Vnode *parent, uint32_t flags, struct Vnode **vnode)
LIST_HEAD * GetVnodeFreeList()
LIST_HEAD * GetVnodeVirtualList()
BOOL VnodeInUseIter(const struct Mount *mount)
mount是否正在被某个索引节点使用
static int g_totalVnodeSize
int VnodeCreate(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode)
创建节点
static struct VnodeOps g_devfsOps
设备文件节点操作
int VnodeLookupFullpath(const char *fullpath, struct Vnode **vnode, uint32_t flags)
根节点内部改变
int VnodeFree(struct Vnode *vnode)
是否 vnode 节点
int VnodeDevLookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **vnode)
static struct Vnode * ConvertVnodeIfMounted(struct Vnode *vnode)
int VnodeFreeAll(const struct Mount *mount)
释放mount下所有的索引节点
static int PreProcess(const char *originPath, struct Vnode **startVnode, char **path)
处理前的准备
int VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struct Vnode *orgVnode)
通过路径 查找索引节点.路径和节点是 N:1的关系, 硬链接
LIST_HEAD * GetVnodeActiveList()
static char * NextName(char *pos, uint8_t *len)
LIST_HEAD g_vnodeFreeList
@ver
LIST_HEAD g_vnodeVirtualList
LIST_HEAD g_vnodeActiveList
static void RefreshLRU(struct Vnode *vnode)
刷新虚拟节点
static int VnodeReaddir(struct Vnode *vp, struct fs_dirent_s *dir)
int VnodeDevInit()
设备初始化,设备结点:/dev目录下,对应一个设备,如/dev/mmcblk0
static int VnodeChattr(struct Vnode *vnode, struct IATTR *attr)
void ChangeRoot(struct Vnode *rootNew)
改变根节点
static void ChangeRootInternal(struct Vnode *rootOld, char *dirname)
int VnodeClosedir(struct Vnode *vnode, struct fs_dirent_s *dir)
static struct Vnode * g_rootVnode
根节点
int VnodeAlloc(struct VnodeOps *vop, struct Vnode **newVnode)
申请分配一个 vnode 节点,vop为操作节点的驱动程序
int VnodeOpendir(struct Vnode *vnode, struct fs_dirent_s *dir)
static LosMux g_vnodeMux
操作链表互斥量
int VnodeGetattr(struct Vnode *vnode, struct stat *buf)
buf 接走 vnode 属性
static struct Vnode * GetFromFreeList(void)
获取空闲节点链表,分配的节点从空闲链表里出
struct Vnode * VnodeReclaimLru(void)
节点批量回收, LRU是Least Recently Used的缩写,即最近最少使用,
void VnodeMemoryDump(void)
int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags)
通过路径查询vnode节点
static int Step(char **currentDir, struct Vnode **currentVnode, uint32_t flags)
一级一级向下找
struct Vnode * VnodeGetRoot()