更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
vnode.c 文件参考

浏览源代码.

函数

int VnodesInit (void)
 
static struct VnodeGetFromFreeList (void)
 获取空闲节点链表,分配的节点从空闲链表里出 更多...
 
struct VnodeVnodeReclaimLru (void)
 节点批量回收, LRU是Least Recently Used的缩写,即最近最少使用, 更多...
 
int VnodeAlloc (struct VnodeOps *vop, struct Vnode **newVnode)
 申请分配一个 vnode 节点,vop为操作节点的驱动程序 更多...
 
int VnodeFree (struct Vnode *vnode)
 是否 vnode 节点 更多...
 
int VnodeFreeAll (const struct Mount *mount)
 释放mount下所有的索引节点 更多...
 
BOOL VnodeInUseIter (const struct Mount *mount)
 mount是否正在被某个索引节点使用 更多...
 
int VnodeHold ()
 拿锁,封装互斥量 更多...
 
int VnodeDrop ()
 归还锁 更多...
 
static char * NextName (char *pos, uint8_t *len)
 
static int PreProcess (const char *originPath, struct Vnode **startVnode, char **path)
 处理前的准备 更多...
 
static struct VnodeConvertVnodeIfMounted (struct Vnode *vnode)
 
static void RefreshLRU (struct Vnode *vnode)
 刷新虚拟节点 更多...
 
static int ProcessVirtualVnode (struct Vnode *parent, uint32_t flags, struct Vnode **vnode)
 
static int Step (char **currentDir, struct Vnode **currentVnode, uint32_t flags)
 一级一级向下找 更多...
 
int VnodeLookupAt (const char *path, struct Vnode **result, uint32_t flags, struct Vnode *orgVnode)
 通过路径 查找索引节点.路径和节点是 N:1的关系, 硬链接 更多...
 
int VnodeLookup (const char *path, struct Vnode **vnode, uint32_t flags)
 通过路径查询vnode节点 更多...
 
int VnodeLookupFullpath (const char *fullpath, struct Vnode **vnode, uint32_t flags)
 根节点内部改变 更多...
 
static void ChangeRootInternal (struct Vnode *rootOld, char *dirname)
 
void ChangeRoot (struct Vnode *rootNew)
 改变根节点 更多...
 
static int VnodeReaddir (struct Vnode *vp, struct fs_dirent_s *dir)
 
int VnodeOpendir (struct Vnode *vnode, struct fs_dirent_s *dir)
 
int VnodeClosedir (struct Vnode *vnode, struct fs_dirent_s *dir)
 
int VnodeCreate (struct Vnode *parent, const char *name, int mode, struct Vnode **vnode)
 创建节点 更多...
 
int VnodeDevInit ()
 设备初始化,设备结点:/dev目录下,对应一个设备,如/dev/mmcblk0 更多...
 
int VnodeGetattr (struct Vnode *vnode, struct stat *buf)
 buf 接走 vnode 属性 更多...
 
struct VnodeVnodeGetRoot ()
 
static int VnodeChattr (struct Vnode *vnode, struct IATTR *attr)
 
int VnodeDevLookup (struct Vnode *parentVnode, const char *path, int len, struct Vnode **vnode)
 
void VnodeMemoryDump (void)
 
LIST_HEADGetVnodeFreeList ()
 
LIST_HEADGetVnodeVirtualList ()
 
LIST_HEADGetVnodeActiveList ()
 
int VnodeClearCache ()
 

变量

LIST_HEAD g_vnodeFreeList
 @ver 更多...
 
LIST_HEAD g_vnodeVirtualList
 
LIST_HEAD g_vnodeActiveList
 
static int g_freeVnodeSize = 0
 
static int g_totalVnodeSize = 0
 
static LosMux g_vnodeMux
 操作链表互斥量
更多...
 
static struct Vnodeg_rootVnode = NULL
 根节点 更多...
 
static struct VnodeOps g_devfsOps
 设备文件节点操作 更多...
 

函数说明

◆ ChangeRoot()

void ChangeRoot ( struct Vnode rootNew)

改变根节点

在文件 vnode.c536 行定义.

537{
538 struct Vnode *rootOld = g_rootVnode;
539 g_rootVnode = rootNew;
540 ChangeRootInternal(rootOld, "proc");
541 ChangeRootInternal(rootOld, "dev");
542}
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
static void ChangeRootInternal(struct Vnode *rootOld, char *dirname)
Definition: vnode.c:501
static struct Vnode * g_rootVnode
根节点
Definition: vnode.c:48
函数调用图:

◆ ChangeRootInternal()

static void ChangeRootInternal ( struct Vnode rootOld,
char *  dirname 
)
static

在文件 vnode.c501 行定义.

502{
503 int ret;
504 struct Mount *mnt = NULL;
505 char *name = NULL;
506 struct Vnode *node = NULL;
507 struct Vnode *nodeInFs = NULL;
508 struct PathCache *item = NULL;
509 struct PathCache *nextItem = NULL;
510 //遍历参数节点孩子节点
511 LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &rootOld->childPathCaches, struct PathCache, childEntry) {
512 name = item->name;
513 node = item->childVnode;
514
515 if (strcmp(name, dirname)) {
516 continue;
517 }
518 PathCacheFree(item);
519
520 ret = VnodeLookup(dirname, &nodeInFs, 0);
521 if (ret) {
522 PRINTK("%s-%d %s NOT exist in rootfs\n", __FUNCTION__, __LINE__, dirname);
523 break;
524 }
525
526 mnt = node->newMount;
527 mnt->vnodeBeCovered = nodeInFs;
528
529 nodeInFs->newMount = mnt;
530 nodeInFs->flag |= VNODE_FLAG_MOUNT_ORIGIN;
531
532 break;
533 }
534}
int PathCacheFree(struct PathCache *cache)
Definition: path_cache.c:147
举例: mount /dev/mmcblk0p0 /bin1/vs/sd vfat 将/dev/mmcblk0p0 挂载到/bin1/vs/sd目录
Definition: mount.h:68
struct Vnode * vnodeBeCovered
Definition: mount.h:71
struct Vnode * childVnode
Definition: path_cache.h:40
LIST_ENTRY childEntry
Definition: path_cache.h:42
char name[0]
Definition: path_cache.h:48
struct Mount * newMount
Definition: vnode.h:181
uint32_t flag
Definition: vnode.h:177
LIST_HEAD childPathCaches
Definition: vnode.h:172
int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags)
通过路径查询vnode节点
Definition: vnode.c:491
函数调用图:
这是这个函数的调用关系图:

◆ ConvertVnodeIfMounted()

static struct Vnode * ConvertVnodeIfMounted ( struct Vnode vnode)
static

在文件 vnode.c332 行定义.

333{
334 if ((vnode == NULL) || !(vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) {
335 return vnode;
336 }
337 return vnode->newMount->vnodeCovered;
338}
struct Vnode * vnodeCovered
Definition: mount.h:72
这是这个函数的调用关系图:

◆ GetFromFreeList()

static struct Vnode * GetFromFreeList ( void  )
static

获取空闲节点链表,分配的节点从空闲链表里出

在文件 vnode.c114 行定义.

115{
116 if (g_freeVnodeSize <= 0) {
117 return NULL;
118 }
119 struct Vnode *vnode = NULL;
120
122 PRINT_ERR("get vnode from free list failed, list empty but g_freeVnodeSize = %d!\n", g_freeVnodeSize);
123 g_freeVnodeSize = 0;
124 return NULL;
125 }
126
127 vnode = ENTRY_TO_VNODE(LOS_DL_LIST_FIRST(&g_vnodeFreeList));
128 LOS_ListDelete(&vnode->actFreeEntry);//从空闲链表上摘出去.
130 return vnode;
131}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
LIST_ENTRY actFreeEntry
Definition: vnode.h:179
static int g_freeVnodeSize
Definition: vnode.c:44
LIST_HEAD g_vnodeFreeList
@ver
Definition: vnode.c:41
函数调用图:
这是这个函数的调用关系图:

◆ GetVnodeActiveList()

LIST_HEAD * GetVnodeActiveList ( void  )

在文件 vnode.c736 行定义.

737{
738 return &g_vnodeActiveList;
739}
LIST_HEAD g_vnodeActiveList
Definition: vnode.c:43
这是这个函数的调用关系图:

◆ GetVnodeFreeList()

LIST_HEAD * GetVnodeFreeList ( void  )

在文件 vnode.c726 行定义.

727{
728 return &g_vnodeFreeList;
729}
这是这个函数的调用关系图:

◆ GetVnodeVirtualList()

LIST_HEAD * GetVnodeVirtualList ( void  )

在文件 vnode.c731 行定义.

732{
733 return &g_vnodeVirtualList;
734}
LIST_HEAD g_vnodeVirtualList
Definition: vnode.c:42
这是这个函数的调用关系图:

◆ NextName()

static char * NextName ( char *  pos,
uint8_t *  len 
)
static

在文件 vnode.c301 行定义.

302{
303 char *name = NULL;
304 while (*pos != 0 && *pos == '/') {
305 pos++;
306 }
307 if (*pos == '\0') {
308 return NULL;
309 }
310 name = (char *)pos;
311 while (*pos != '\0' && *pos != '/') {
312 pos++;
313 }
314 *len = pos - name;
315 return name;
316}
这是这个函数的调用关系图:

◆ PreProcess()

static int PreProcess ( const char *  originPath,
struct Vnode **  startVnode,
char **  path 
)
static

处理前的准备

在文件 vnode.c318 行定义.

319{
320 int ret;
321 char *absolutePath = NULL;
322 //通过相对路径找到绝对路径
323 ret = vfs_normalize_path(NULL, originPath, &absolutePath);
324 if (ret == LOS_OK) {//成功
325 *startVnode = g_rootVnode;//根节点为开始节点
326 *path = absolutePath;//返回绝对路径
327 }
328
329 return ret;
330}
int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
Definition: fullpath.c:245
函数调用图:
这是这个函数的调用关系图:

◆ ProcessVirtualVnode()

static int ProcessVirtualVnode ( struct Vnode parent,
uint32_t  flags,
struct Vnode **  vnode 
)
static

在文件 vnode.c350 行定义.

351{
352 int ret = -ENOENT;
353 if (flags & V_CREATE) {
354 // only create /dev/ vnode
355 ret = VnodeAlloc(NULL, vnode);
356 }
357 if (ret == LOS_OK) {
358 (*vnode)->parent = parent;
359 }
360 return ret;
361}
int VnodeAlloc(struct VnodeOps *vop, struct Vnode **newVnode)
申请分配一个 vnode 节点,vop为操作节点的驱动程序
Definition: vnode.c:166
函数调用图:
这是这个函数的调用关系图:

◆ RefreshLRU()

static void RefreshLRU ( struct Vnode vnode)
static

刷新虚拟节点

在文件 vnode.c340 行定义.

341{
342 if (vnode == NULL || (vnode->type != VNODE_TYPE_REG && vnode->type != VNODE_TYPE_DIR) ||
343 vnode->vop == &g_devfsOps || vnode->vop == NULL) {
344 return;
345 }
346 LOS_ListDelete(&(vnode->actFreeEntry));
348}
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.
Definition: los_list.h:244
enum VnodeType type
Definition: vnode.h:165
struct VnodeOps * vop
Definition: vnode.h:174
@ VNODE_TYPE_DIR
Definition: vnode.h:137
@ VNODE_TYPE_REG
Definition: vnode.h:136
static struct VnodeOps g_devfsOps
设备文件节点操作
Definition: vnode.c:49
函数调用图:
这是这个函数的调用关系图:

◆ Step()

static int Step ( char **  currentDir,
struct Vnode **  currentVnode,
uint32_t  flags 
)
static

一级一级向下找

在文件 vnode.c363 行定义.

364{
365 int ret;
366 uint8_t len = 0;
367 struct Vnode *nextVnode = NULL;
368 char *nextDir = NULL;
369
370 if ((*currentVnode)->type != VNODE_TYPE_DIR) {//必须是目录节点
371 return -ENOTDIR;
372 }
373 nextDir = NextName(*currentDir, &len);//
374 if (nextDir == NULL) {
375 *currentDir = NULL;
376 return LOS_OK;
377 }
378
379 ret = PathCacheLookup(*currentVnode, nextDir, len, &nextVnode);
380 if (ret == LOS_OK) {
381 goto STEP_FINISH;
382 }
383
384 (*currentVnode)->useCount++;
385 if (flags & V_DUMMY) {
386 ret = ProcessVirtualVnode(*currentVnode, flags, &nextVnode);
387 } else {
388 if ((*currentVnode)->vop != NULL && (*currentVnode)->vop->Lookup != NULL) {
389 ret = (*currentVnode)->vop->Lookup(*currentVnode, nextDir, len, &nextVnode);
390 } else {
391 ret = -ENOSYS;
392 }
393 }
394 (*currentVnode)->useCount--;
395
396 if (ret == LOS_OK) {
397 (void)PathCacheAlloc((*currentVnode), nextVnode, nextDir, len);
398 }
399
400STEP_FINISH:
401 nextVnode = ConvertVnodeIfMounted(nextVnode);
402 RefreshLRU(nextVnode);
403
404 *currentDir = nextDir + len;
405 if (ret == LOS_OK) {
406 *currentVnode = nextVnode;
407 }
408
409 return ret;
410}
int PathCacheLookup(struct Vnode *parent, const char *name, int len, struct Vnode **vnode)
Definition: path_cache.c:162
struct PathCache * PathCacheAlloc(struct Vnode *parent, struct Vnode *vnode, const char *name, uint8_t len)
Definition: path_cache.c:112
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
static int ProcessVirtualVnode(struct Vnode *parent, uint32_t flags, struct Vnode **vnode)
Definition: vnode.c:350
static struct Vnode * ConvertVnodeIfMounted(struct Vnode *vnode)
Definition: vnode.c:332
static char * NextName(char *pos, uint8_t *len)
Definition: vnode.c:301
static void RefreshLRU(struct Vnode *vnode)
刷新虚拟节点
Definition: vnode.c:340
函数调用图:
这是这个函数的调用关系图:

◆ VnodeAlloc()

int VnodeAlloc ( struct VnodeOps vop,
struct Vnode **  newVnode 
)

申请分配一个 vnode 节点,vop为操作节点的驱动程序

在文件 vnode.c166 行定义.

167{
168 struct Vnode* vnode = NULL;
169
170 VnodeHold();
171 vnode = GetFromFreeList();
172 if ((vnode == NULL) && g_totalVnodeSize < LOSCFG_MAX_VNODE_SIZE) {
173 vnode = (struct Vnode*)zalloc(sizeof(struct Vnode));
175 }
176
177 if (vnode == NULL) {//没有分配到节点
178 vnode = VnodeReclaimLru();//执行回收算法,释放节点
179 }
180
181 if (vnode == NULL) {//回收也没有可用节点
182 *newVnode = NULL;
183 VnodeDrop();
184 return -ENOMEM;//分配失败,返回
185 }
186
187 vnode->type = VNODE_TYPE_UNKNOWN; //节点默认类型,未知
188 LOS_ListInit((&(vnode->parentPathCaches)));//后续可能要当爸爸,做好准备
189 LOS_ListInit((&(vnode->childPathCaches)));//后续可能要当儿子,做好准备
190 LOS_ListInit((&(vnode->hashEntry))); //用它挂到全局哈希表上
191 LOS_ListInit((&(vnode->actFreeEntry))); //用它挂到全局正使用节点链表上
192
193 if (vop == NULL) {//
194 LOS_ListAdd(&g_vnodeVirtualList, &(vnode->actFreeEntry));//挂到虚拟设备
195 vnode->vop = &g_devfsOps;
196 } else {//如果已有指定的文件系统(FAT),直接绑定
198 vnode->vop = vop;
199 }
202 (VOID)LOS_MuxInit(&vnode->mapping.mux_lock, NULL);
203 vnode->mapping.host = vnode;
204
205 VnodeDrop();
206
207 *newVnode = vnode;
208
209 return LOS_OK;
210}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
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.
Definition: los_list.h:217
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
初始化互斥锁
Definition: los_mux.c:262
VOID LOS_SpinInit(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:37
void * zalloc(size_t size)
Definition: malloc.c:91
struct page_mapping mapping
Definition: vnode.h:183
LIST_ENTRY hashEntry
Definition: vnode.h:178
LIST_HEAD parentPathCaches
Definition: vnode.h:171
SPIN_LOCK_S list_lock
LOS_DL_LIST page_list
struct file * host
@ VNODE_TYPE_UNKNOWN
Definition: vnode.h:135
static int g_totalVnodeSize
Definition: vnode.c:45
int VnodeDrop()
归还锁
Definition: vnode.c:292
int VnodeHold()
拿锁,封装互斥量
Definition: vnode.c:283
static struct Vnode * GetFromFreeList(void)
获取空闲节点链表,分配的节点从空闲链表里出
Definition: vnode.c:114
struct Vnode * VnodeReclaimLru(void)
节点批量回收, LRU是Least Recently Used的缩写,即最近最少使用,
Definition: vnode.c:133
函数调用图:
这是这个函数的调用关系图:

◆ VnodeChattr()

static int VnodeChattr ( struct Vnode vnode,
struct IATTR attr 
)
static

在文件 vnode.c665 行定义.

666{
667 mode_t tmpMode;
668 if (vnode == NULL || attr == NULL) {
669 return -EINVAL;
670 }
671 if (attr->attr_chg_valid & CHG_MODE) {
672 tmpMode = attr->attr_chg_mode;
673 tmpMode &= ~S_IFMT;
674 vnode->mode &= S_IFMT;
675 vnode->mode = tmpMode | vnode->mode;
676 }
677 if (attr->attr_chg_valid & CHG_UID) {
678 vnode->uid = attr->attr_chg_uid;
679 }
680 if (attr->attr_chg_valid & CHG_GID) {
681 vnode->gid = attr->attr_chg_gid;
682 }
683 return LOS_OK;
684}
unsigned attr_chg_uid
用户ID
Definition: vnode.h:86
unsigned attr_chg_mode
确定了文件的类型,以及它的所有者、它的group、其它用户访问此文件的权限 (S_IWUSR | ...)
Definition: vnode.h:85
unsigned attr_chg_gid
组ID
Definition: vnode.h:87
unsigned int attr_chg_valid
节点改变有效性 (CHG_MODE | CHG_UID | ... )
Definition: vnode.h:83
uint gid
Definition: vnode.h:169
mode_t mode
Definition: vnode.h:170
uint uid
Definition: vnode.h:168
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

◆ VnodeClearCache()

int VnodeClearCache ( void  )

在文件 vnode.c741 行定义.

742{
743 struct Vnode *item = NULL;
744 struct Vnode *nextItem = NULL;
745 int count = 0;
746
747 VnodeHold();
748 LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
749 if ((item->useCount > 0) ||
750 (item->flag & VNODE_FLAG_MOUNT_ORIGIN) ||
751 (item->flag & VNODE_FLAG_MOUNT_NEW)) {
752 continue;
753 }
754
755 if (VnodeFree(item) == LOS_OK) {
756 count++;
757 }
758 }
759 VnodeDrop();
760
761 return count;
762}
int useCount
Definition: vnode.h:166
int VnodeFree(struct Vnode *vnode)
是否 vnode 节点
Definition: vnode.c:212
函数调用图:
这是这个函数的调用关系图:

◆ VnodeClosedir()

int VnodeClosedir ( struct Vnode vnode,
struct fs_dirent_s *  dir 
)

在文件 vnode.c593 行定义.

594{
595 (void)vnode;
596 (void)dir;
597 return LOS_OK;
598}

◆ VnodeCreate()

int VnodeCreate ( struct Vnode parent,
const char *  name,
int  mode,
struct Vnode **  vnode 
)

创建节点

在文件 vnode.c600 行定义.

601{
602 int ret;
603 struct Vnode *newVnode = NULL;
604
605 ret = VnodeAlloc(NULL, &newVnode);//分配一个节点
606 if (ret != 0) {
607 return -ENOMEM;
608 }
609 //继承老爹的基因.
610 newVnode->type = VNODE_TYPE_CHR;//默认是字符设备
611 newVnode->vop = parent->vop;//继承父节点 vop 驱动程序(也叫接口实现)
612 newVnode->fop = parent->fop;//继承父节点 fop 驱动程序(也叫接口实现)
613 newVnode->data = NULL; //默认值
614 newVnode->parent = parent; //指定父节点
615 newVnode->originMount = parent->originMount; //继承父节点挂载信息
616 newVnode->uid = parent->uid; //用户ID
617 newVnode->gid = parent->gid; //用户组ID
618 newVnode->mode = mode;
619 /* The 'name' here is not full path, but for device we don't depend on this path, it's just a name for DFx.
620 When we have devfs, we can get a fullpath. */
621 newVnode->filePath = strdup(name);
622
623 *vnode = newVnode;
624 return 0;
625}
void * data
Definition: vnode.h:176
char * filePath
Definition: vnode.h:182
struct file_operations_vfs * fop
Definition: vnode.h:175
struct Mount * originMount
Definition: vnode.h:180
struct Vnode * parent
Definition: vnode.h:173
@ VNODE_TYPE_CHR
Definition: vnode.h:139
函数调用图:

◆ VnodeDevInit()

int VnodeDevInit ( void  )

设备初始化,设备结点:/dev目录下,对应一个设备,如/dev/mmcblk0

在文件 vnode.c627 行定义.

628{
629 struct Vnode *devNode = NULL;
630 struct Mount *devMount = NULL;
631
632 int retval = VnodeLookup("/dev", &devNode, V_CREATE | V_DUMMY);
633 if (retval != LOS_OK) {
634 PRINT_ERR("VnodeDevInit failed error %d\n", retval);
635 return retval;
636 }
637 devNode->mode = DEV_VNODE_MODE | S_IFDIR; // 40755(chmod 755)
638 devNode->type = VNODE_TYPE_DIR; //设备根节点目录
639
640 devMount = MountAlloc(devNode, NULL);//分配一个mount节点
641 if (devMount == NULL) {
642 PRINT_ERR("VnodeDevInit failed mount point alloc failed.\n");
643 return -ENOMEM;
644 }
645 devMount->vnodeCovered = devNode;
646 devMount->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN;
647 return LOS_OK;
648}
struct Mount * MountAlloc(struct Vnode *vnode, struct MountOps *mop)
Definition: mount.c:48
函数调用图:
这是这个函数的调用关系图:

◆ VnodeDevLookup()

int VnodeDevLookup ( struct Vnode parentVnode,
const char *  path,
int  len,
struct Vnode **  vnode 
)

在文件 vnode.c686 行定义.

687{
688 (void)parentVnode;
689 (void)path;
690 (void)len;
691 (void)vnode;
692 /* dev node must in pathCache. */
693 return -ENOENT;
694}

◆ VnodeDrop()

int VnodeDrop ( void  )

归还锁

在文件 vnode.c292 行定义.

293{
294 int ret = LOS_MuxUnlock(&g_vnodeMux);
295 if (ret != LOS_OK) {
296 PRINT_ERR("VnodeDrop unlock failed !\n");
297 }
298 return ret;
299}
LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
释放锁
Definition: los_mux.c:559
static LosMux g_vnodeMux
操作链表互斥量
Definition: vnode.c:47
函数调用图:
这是这个函数的调用关系图:

◆ VnodeFree()

int VnodeFree ( struct Vnode vnode)

是否 vnode 节点

在文件 vnode.c212 行定义.

213{
214 if (vnode == NULL) {
215 return LOS_OK;
216 }
217
218 VnodeHold();//拿互斥锁
219 if (vnode->useCount > 0) {//还有引用数,或者叫链接数.这里的链接数指的是还有硬链接没删除的情况
220 VnodeDrop();
221 return -EBUSY;//返回设备或资源忙着呢.
222 }
223
224 VnodePathCacheFree(vnode);//节点和父亲,孩子告别
225 LOS_ListDelete(&(vnode->hashEntry));//将自己从当前哈希链表上摘出来,此时vnode通过hashEntry挂在 g_vnodeHashEntrys
226 LOS_ListDelete(&vnode->actFreeEntry);//将自己从当前链表摘出来,此时vnode通过actFreeEntry挂在 g_vnodeCurrList
227
228 if (vnode->vop->Reclaim) {//资源的回收操作
229 vnode->vop->Reclaim(vnode);//先回收资源
230 }
231
232 if (vnode->filePath) {
233 free(vnode->filePath);
234 }
235 if (vnode->vop == &g_devfsOps) {//对设备文件的回收
236 /* for dev vnode, just free it */
237 free(vnode->data);//
238 free(vnode);
240 } else {
241 /* for normal vnode, reclaim it to g_VnodeFreeList */
242 (void)memset_s(vnode, sizeof(struct Vnode), 0, sizeof(struct Vnode));
243 LOS_ListAdd(&g_vnodeFreeList, &vnode->actFreeEntry);//actFreeEntry换个地方挂,从活动链接换到空闲链表上.
244 g_freeVnodeSize++;//空闲链表节点数量增加
245 }
246 VnodeDrop();//释放互斥锁
247
248 return LOS_OK;
249}
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
void VnodePathCacheFree(struct Vnode *vnode)
和长辈,晚辈告别,从此不再是父亲和孩子.
Definition: path_cache.c:199
int(* Reclaim)(struct Vnode *vnode)
回 收节点
Definition: vnode.h:197
函数调用图:
这是这个函数的调用关系图:

◆ VnodeFreeAll()

int VnodeFreeAll ( const struct Mount mount)

释放mount下所有的索引节点

在文件 vnode.c251 行定义.

252{
253 struct Vnode *vnode = NULL;
254 struct Vnode *nextVnode = NULL;
255 int ret;
256
257 LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(vnode, nextVnode, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
258 if ((vnode->originMount == mount) && !(vnode->flag & VNODE_FLAG_MOUNT_NEW)) {//找到装载点,且这个装载点没有被新使用
259 ret = VnodeFree(vnode);//释放节点,@note_thinking 是不是树杈被释放后,树叶也默认被释放了?
260 if (ret != LOS_OK) {
261 return ret;
262 }
263 }
264 }
265
266 return LOS_OK;
267}
函数调用图:

◆ VnodeGetattr()

int VnodeGetattr ( struct Vnode vnode,
struct stat *  buf 
)

buf 接走 vnode 属性

在文件 vnode.c650 行定义.

651{
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;
656
657 return LOS_OK;
658}

◆ VnodeGetRoot()

struct Vnode * VnodeGetRoot ( void  )

在文件 vnode.c660 行定义.

661{
662 return g_rootVnode;
663}

◆ VnodeHold()

int VnodeHold ( void  )

拿锁,封装互斥量

在文件 vnode.c283 行定义.

284{
285 int ret = LOS_MuxLock(&g_vnodeMux, LOS_WAIT_FOREVER);
286 if (ret != LOS_OK) {
287 PRINT_ERR("VnodeHold lock failed !\n");
288 }
289 return ret;
290}
LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
拿互斥锁,
Definition: los_mux.c:437
函数调用图:
这是这个函数的调用关系图:

◆ VnodeInUseIter()

BOOL VnodeInUseIter ( const struct Mount mount)

mount是否正在被某个索引节点使用

在文件 vnode.c269 行定义.

270{
271 struct Vnode *vnode = NULL;
272
273 LOS_DL_LIST_FOR_EACH_ENTRY(vnode, &g_vnodeActiveList, struct Vnode, actFreeEntry) {//遍历活动链表
274 if (vnode->originMount == mount) {//找到一致挂载点
275 if ((vnode->useCount > 0) || (vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) {//还在被使用
276 return TRUE;
277 }
278 }
279 }
280 return FALSE;
281}

◆ VnodeLookup()

int VnodeLookup ( const char *  path,
struct Vnode **  vnode,
uint32_t  flags 
)

通过路径查询vnode节点

在文件 vnode.c491 行定义.

492{
493 return VnodeLookupAt(path, vnode, flags, NULL);
494}
int VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struct Vnode *orgVnode)
通过路径 查找索引节点.路径和节点是 N:1的关系, 硬链接
Definition: vnode.c:412
函数调用图:
这是这个函数的调用关系图:

◆ VnodeLookupAt()

int VnodeLookupAt ( const char *  path,
struct Vnode **  result,
uint32_t  flags,
struct Vnode orgVnode 
)

通过路径 查找索引节点.路径和节点是 N:1的关系, 硬链接

在文件 vnode.c412 行定义.

413{
414 int ret;
415 int vnodePathLen;
416 char *vnodePath = NULL;
417 struct Vnode *startVnode = NULL;
418 char *normalizedPath = NULL;
419
420 if (orgVnode != NULL) {
421 startVnode = orgVnode;
422 normalizedPath = strdup(path);
423 if (normalizedPath == NULL) {
424 PRINT_ERR("[VFS]lookup failed, strdup err\n");
425 ret = -EINVAL;
426 goto OUT_FREE_PATH;
427 }
428 } else {
429 ret = PreProcess(path, &startVnode, &normalizedPath);
430 if (ret != LOS_OK) {
431 PRINT_ERR("[VFS]lookup failed, invalid path err = %d\n", ret);
432 goto OUT_FREE_PATH;
433 }
434 }
435
436 if (normalizedPath[1] == '\0' && normalizedPath[0] == '/') {
437 *result = g_rootVnode;//啥也不说了,还找啥呀,直接返回根节点
438 free(normalizedPath);
439 return LOS_OK;
440 }
441
442 char *currentDir = normalizedPath;
443 struct Vnode *currentVnode = startVnode;
444
445 while (*currentDir != '\0') {
446 ret = Step(&currentDir, &currentVnode, flags);
447 if (currentDir == NULL || *currentDir == '\0') {
448 // return target or parent vnode as result
449 *result = currentVnode;
450 if (currentVnode->filePath == NULL) {
451 currentVnode->filePath = normalizedPath;
452 } else {
453 free(normalizedPath);
454 }
455 return ret;
456 } else if (VfsVnodePermissionCheck(currentVnode, EXEC_OP)) {
457 ret = -EACCES;
458 goto OUT_FREE_PATH;
459 }
460
461 if (ret != LOS_OK) {
462 // no such file, lookup failed
463 goto OUT_FREE_PATH;
464 }
465 if (currentVnode->filePath == NULL) {
466 vnodePathLen = currentDir - normalizedPath;
467 vnodePath = malloc(vnodePathLen + 1);
468 if (vnodePath == NULL) {
469 ret = -ENOMEM;
470 goto OUT_FREE_PATH;
471 }
472 ret = strncpy_s(vnodePath, vnodePathLen + 1, normalizedPath, vnodePathLen);
473 if (ret != EOK) {
474 ret = -ENAMETOOLONG;
475 free(vnodePath);
476 goto OUT_FREE_PATH;
477 }
478 currentVnode->filePath = vnodePath;
479 currentVnode->filePath[vnodePathLen] = 0;
480 }
481 }
482
483OUT_FREE_PATH:
484 if (normalizedPath) {
485 free(normalizedPath);
486 }
487
488 return ret;
489}
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
int VfsVnodePermissionCheck(const struct Vnode *node, int accMode)
Definition: vfs_other.c:80
static int PreProcess(const char *originPath, struct Vnode **startVnode, char **path)
处理前的准备
Definition: vnode.c:318
static int Step(char **currentDir, struct Vnode **currentVnode, uint32_t flags)
一级一级向下找
Definition: vnode.c:363
函数调用图:
这是这个函数的调用关系图:

◆ VnodeLookupFullpath()

int VnodeLookupFullpath ( const char *  fullpath,
struct Vnode **  vnode,
uint32_t  flags 
)

根节点内部改变

在文件 vnode.c496 行定义.

497{
498 return VnodeLookupAt(fullpath, vnode, flags, g_rootVnode);
499}
函数调用图:

◆ VnodeMemoryDump()

void VnodeMemoryDump ( void  )

在文件 vnode.c706 行定义.

707{
708 struct Vnode *item = NULL;
709 struct Vnode *nextItem = NULL;
710 int vnodeCount = 0;
711 //遍历链表
712 LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
713 if ((item->useCount > 0) ||
714 (item->flag & VNODE_FLAG_MOUNT_ORIGIN) ||
715 (item->flag & VNODE_FLAG_MOUNT_NEW)) {//有效节点
716 continue;
717 }
718
719 vnodeCount++;//统计数量
720 }
721
722 PRINTK("Vnode number = %d\n", vnodeCount);
723 PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode));
724}
这是这个函数的调用关系图:

◆ VnodeOpendir()

int VnodeOpendir ( struct Vnode vnode,
struct fs_dirent_s *  dir 
)

在文件 vnode.c586 行定义.

587{
588 (void)vnode;
589 (void)dir;
590 return LOS_OK;
591}

◆ VnodeReaddir()

static int VnodeReaddir ( struct Vnode vp,
struct fs_dirent_s *  dir 
)
static

在文件 vnode.c544 行定义.

545{
546 int result;
547 int cnt = 0;
548 off_t i = 0;
549 off_t idx;
550 unsigned int dstNameSize;
551
552 struct PathCache *item = NULL;
553 struct PathCache *nextItem = NULL;
554
555 if (dir == NULL) {
556 return -EINVAL;
557 }
558
559 LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vp->childPathCaches, struct PathCache, childEntry) {
560 if (i < dir->fd_position) {
561 i++;
562 continue;
563 }
564
565 idx = i - dir->fd_position;
566
567 dstNameSize = sizeof(dir->fd_dir[idx].d_name);
568 result = strncpy_s(dir->fd_dir[idx].d_name, dstNameSize, item->name, item->nameLen);
569 if (result != EOK) {
570 return -ENAMETOOLONG;
571 }
572 dir->fd_dir[idx].d_off = i;
573 dir->fd_dir[idx].d_reclen = (uint16_t)sizeof(struct dirent);
574
575 i++;
576 if (++cnt >= dir->read_cnt) {
577 break;
578 }
579 }
580
581 dir->fd_position = i;
582
583 return cnt;
584}
uint8_t nameLen
Definition: path_cache.h:44

◆ VnodeReclaimLru()

struct Vnode * VnodeReclaimLru ( void  )

节点批量回收, LRU是Least Recently Used的缩写,即最近最少使用,

在文件 vnode.c133 行定义.

134{
135 struct Vnode *item = NULL;
136 struct Vnode *nextItem = NULL;
137 int releaseCount = 0;
138 //遍历链表
139 LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
140 if ((item->useCount > 0) || //还有链接数
141 (item->flag & VNODE_FLAG_MOUNT_ORIGIN) || //原来是个mount节点
142 (item->flag & VNODE_FLAG_MOUNT_NEW)) { //是个新mount节点
143 continue;
144 }
145
146 if (VnodeFree(item) == LOS_OK) {//正式回收,其实就是将自己从链表上摘出去,再挂到空闲链表上.
147 releaseCount++;
148 }
149 if (releaseCount >= VNODE_LRU_COUNT) {//一次最多回收量
150 break;
151 }
152 }
153
154 if (releaseCount == 0) {//回收失败
155 PRINT_ERR("VnodeAlloc failed, vnode size hit max but can't reclaim anymore!\n");
156 return NULL;
157 }
158
159 item = GetFromFreeList();//获取一个空闲节点
160 if (item == NULL) {
161 PRINT_ERR("VnodeAlloc failed, reclaim and get from free list failed!\n");
162 }
163 return item;
164}
函数调用图:
这是这个函数的调用关系图:

◆ VnodesInit()

int VnodesInit ( void  )

#ifndef S_IRUSR #define S_ISUID 04000 #define S_ISGID 02000 #define S_ISVTX 01000 #define S_IRUSR 0400 #define S_IWUSR 0200 #define S_IXUSR 0100 #define S_IRWXU 0700 #define S_IRGRP 0040 #define S_IWGRP 0020 #define S_IXGRP 0010 #define S_IRWXG 0070 #define S_IROTH 0004 #define S_IWOTH 0002 #define S_IXOTH 0001 #define S_IRWXO 0007 #endif

在文件 vnode.c91 行定义.

92{
93 int retval = LOS_MuxInit(&g_vnodeMux, NULL);//初始化操作vnode链表的互斥量
94 if (retval != LOS_OK) {
95 PRINT_ERR("Create mutex for vnode fail, status: %d", retval);
96 return retval;
97 }
98
99 LOS_ListInit(&g_vnodeFreeList); //初始化空闲的节点链表
100 LOS_ListInit(&g_vnodeVirtualList); //初始化虚拟节点链表
101 LOS_ListInit(&g_vnodeActiveList); //初始化活动虚拟节点链表
102 retval = VnodeAlloc(NULL, &g_rootVnode);//分配根节点
103 if (retval != LOS_OK) {
104 PRINT_ERR("VnodeInit failed error %d\n", retval);
105 return retval;
106 }
107 g_rootVnode->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;// 40777 (chmod 777)
108 g_rootVnode->type = VNODE_TYPE_DIR;//节点类型为目录
109 g_rootVnode->filePath = "/";
110
111 return LOS_OK;
112}
函数调用图:
这是这个函数的调用关系图:

变量说明

◆ g_devfsOps

static struct VnodeOps g_devfsOps
static
初始值:
= {
.Lookup = VnodeDevLookup,
.Getattr = VnodeGetattr,
.Readdir = VnodeReaddir,
.Opendir = VnodeOpendir,
.Closedir = VnodeClosedir,
.Create = VnodeCreate,
.Chattr = VnodeChattr,
}
int VnodeCreate(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode)
创建节点
Definition: vnode.c:600
int VnodeDevLookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **vnode)
Definition: vnode.c:686
static int VnodeReaddir(struct Vnode *vp, struct fs_dirent_s *dir)
Definition: vnode.c:544
static int VnodeChattr(struct Vnode *vnode, struct IATTR *attr)
Definition: vnode.c:665
int VnodeClosedir(struct Vnode *vnode, struct fs_dirent_s *dir)
Definition: vnode.c:593
int VnodeOpendir(struct Vnode *vnode, struct fs_dirent_s *dir)
Definition: vnode.c:586
int VnodeGetattr(struct Vnode *vnode, struct stat *buf)
buf 接走 vnode 属性
Definition: vnode.c:650

设备文件节点操作

设备文件系统节点操作

在文件 vnode.c49 行定义.

◆ g_freeVnodeSize

int g_freeVnodeSize = 0
static

在文件 vnode.c44 行定义.

◆ g_rootVnode

struct Vnode* g_rootVnode = NULL
static

根节点

在文件 vnode.c48 行定义.

◆ g_totalVnodeSize

int g_totalVnodeSize = 0
static

在文件 vnode.c45 行定义.

◆ g_vnodeActiveList

LIST_HEAD g_vnodeActiveList

在文件 vnode.c43 行定义.

◆ g_vnodeFreeList

LIST_HEAD g_vnodeFreeList

@ver

在文件 vnode.c41 行定义.

◆ g_vnodeMux

LosMux g_vnodeMux
static

操作链表互斥量

在文件 vnode.c47 行定义.

◆ g_vnodeVirtualList

LIST_HEAD g_vnodeVirtualList

在文件 vnode.c42 行定义.