10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci *
40d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
50d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
60d163575Sopenharmony_ci *
70d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
80d163575Sopenharmony_ci *    conditions and the following disclaimer.
90d163575Sopenharmony_ci *
100d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
110d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
120d163575Sopenharmony_ci *    provided with the distribution.
130d163575Sopenharmony_ci *
140d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
150d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
160d163575Sopenharmony_ci *    permission.
170d163575Sopenharmony_ci *
180d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
190d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
200d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
210d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
220d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
230d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
240d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
250d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
260d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
270d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
280d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
290d163575Sopenharmony_ci */
300d163575Sopenharmony_ci
310d163575Sopenharmony_ci#include "los_mux.h"
320d163575Sopenharmony_ci#include "fs/dirent_fs.h"
330d163575Sopenharmony_ci#include "path_cache.h"
340d163575Sopenharmony_ci#include "vnode.h"
350d163575Sopenharmony_ci#include "los_process.h"
360d163575Sopenharmony_ci#include "los_process_pri.h"
370d163575Sopenharmony_ci
380d163575Sopenharmony_ciLIST_HEAD g_vnodeFreeList;              /* free vnodes list */
390d163575Sopenharmony_ciLIST_HEAD g_vnodeVirtualList;           /* dev vnodes list */
400d163575Sopenharmony_ciLIST_HEAD g_vnodeActiveList;              /* inuse vnodes list */
410d163575Sopenharmony_cistatic int g_freeVnodeSize = 0;         /* system free vnodes size */
420d163575Sopenharmony_cistatic int g_totalVnodeSize = 0;        /* total vnode size */
430d163575Sopenharmony_ci
440d163575Sopenharmony_cistatic LosMux g_vnodeMux;
450d163575Sopenharmony_cistatic struct Vnode *g_rootVnode = NULL;
460d163575Sopenharmony_cistatic struct VnodeOps g_devfsOps;
470d163575Sopenharmony_ci
480d163575Sopenharmony_ci#define ENTRY_TO_VNODE(ptr)  LOS_DL_LIST_ENTRY(ptr, struct Vnode, actFreeEntry)
490d163575Sopenharmony_ci#define VNODE_LRU_COUNT      10
500d163575Sopenharmony_ci#define DEV_VNODE_MODE       0755
510d163575Sopenharmony_ci
520d163575Sopenharmony_ciint VnodesInit(void)
530d163575Sopenharmony_ci{
540d163575Sopenharmony_ci    int retval = LOS_MuxInit(&g_vnodeMux, NULL);
550d163575Sopenharmony_ci    if (retval != LOS_OK) {
560d163575Sopenharmony_ci        PRINT_ERR("Create mutex for vnode fail, status: %d", retval);
570d163575Sopenharmony_ci        return retval;
580d163575Sopenharmony_ci    }
590d163575Sopenharmony_ci
600d163575Sopenharmony_ci    LOS_ListInit(&g_vnodeFreeList);
610d163575Sopenharmony_ci    LOS_ListInit(&g_vnodeVirtualList);
620d163575Sopenharmony_ci    LOS_ListInit(&g_vnodeActiveList);
630d163575Sopenharmony_ci    retval = VnodeAlloc(NULL, &g_rootVnode);
640d163575Sopenharmony_ci    if (retval != LOS_OK) {
650d163575Sopenharmony_ci        PRINT_ERR("VnodeInit failed error %d\n", retval);
660d163575Sopenharmony_ci        return retval;
670d163575Sopenharmony_ci    }
680d163575Sopenharmony_ci    g_rootVnode->mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
690d163575Sopenharmony_ci    g_rootVnode->type = VNODE_TYPE_DIR;
700d163575Sopenharmony_ci    g_rootVnode->filePath = "/";
710d163575Sopenharmony_ci
720d163575Sopenharmony_ci#ifdef LOSCFG_CHROOT
730d163575Sopenharmony_ci    LosProcessCB *processCB = OsGetKernelInitProcess();
740d163575Sopenharmony_ci    if (processCB->files != NULL) {
750d163575Sopenharmony_ci        g_rootVnode->useCount++;
760d163575Sopenharmony_ci        processCB->files->rootVnode = g_rootVnode;
770d163575Sopenharmony_ci    }
780d163575Sopenharmony_ci#endif
790d163575Sopenharmony_ci    return LOS_OK;
800d163575Sopenharmony_ci}
810d163575Sopenharmony_ci
820d163575Sopenharmony_cistatic struct Vnode *GetFromFreeList(void)
830d163575Sopenharmony_ci{
840d163575Sopenharmony_ci    if (g_freeVnodeSize <= 0) {
850d163575Sopenharmony_ci        return NULL;
860d163575Sopenharmony_ci    }
870d163575Sopenharmony_ci    struct Vnode *vnode = NULL;
880d163575Sopenharmony_ci
890d163575Sopenharmony_ci    if (LOS_ListEmpty(&g_vnodeFreeList)) {
900d163575Sopenharmony_ci        PRINT_ERR("get vnode from free list failed, list empty but g_freeVnodeSize = %d!\n", g_freeVnodeSize);
910d163575Sopenharmony_ci        g_freeVnodeSize = 0;
920d163575Sopenharmony_ci        return NULL;
930d163575Sopenharmony_ci    }
940d163575Sopenharmony_ci
950d163575Sopenharmony_ci    vnode = ENTRY_TO_VNODE(LOS_DL_LIST_FIRST(&g_vnodeFreeList));
960d163575Sopenharmony_ci    LOS_ListDelete(&vnode->actFreeEntry);
970d163575Sopenharmony_ci    g_freeVnodeSize--;
980d163575Sopenharmony_ci    return vnode;
990d163575Sopenharmony_ci}
1000d163575Sopenharmony_ci
1010d163575Sopenharmony_cistruct Vnode *VnodeReclaimLru(void)
1020d163575Sopenharmony_ci{
1030d163575Sopenharmony_ci    struct Vnode *item = NULL;
1040d163575Sopenharmony_ci    struct Vnode *nextItem = NULL;
1050d163575Sopenharmony_ci    int releaseCount = 0;
1060d163575Sopenharmony_ci
1070d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
1080d163575Sopenharmony_ci        if ((item->useCount > 0) ||
1090d163575Sopenharmony_ci            (item->flag & VNODE_FLAG_MOUNT_ORIGIN) ||
1100d163575Sopenharmony_ci            (item->flag & VNODE_FLAG_MOUNT_NEW)) {
1110d163575Sopenharmony_ci            continue;
1120d163575Sopenharmony_ci        }
1130d163575Sopenharmony_ci
1140d163575Sopenharmony_ci        if (VnodeFree(item) == LOS_OK) {
1150d163575Sopenharmony_ci            releaseCount++;
1160d163575Sopenharmony_ci        }
1170d163575Sopenharmony_ci        if (releaseCount >= VNODE_LRU_COUNT) {
1180d163575Sopenharmony_ci            break;
1190d163575Sopenharmony_ci        }
1200d163575Sopenharmony_ci    }
1210d163575Sopenharmony_ci
1220d163575Sopenharmony_ci    if (releaseCount == 0) {
1230d163575Sopenharmony_ci        PRINT_ERR("VnodeAlloc failed, vnode size hit max but can't reclaim anymore!\n");
1240d163575Sopenharmony_ci        return NULL;
1250d163575Sopenharmony_ci    }
1260d163575Sopenharmony_ci
1270d163575Sopenharmony_ci    item = GetFromFreeList();
1280d163575Sopenharmony_ci    if (item == NULL) {
1290d163575Sopenharmony_ci        PRINT_ERR("VnodeAlloc failed, reclaim and get from free list failed!\n");
1300d163575Sopenharmony_ci    }
1310d163575Sopenharmony_ci    return item;
1320d163575Sopenharmony_ci}
1330d163575Sopenharmony_ci
1340d163575Sopenharmony_ciint VnodeAlloc(struct VnodeOps *vop, struct Vnode **newVnode)
1350d163575Sopenharmony_ci{
1360d163575Sopenharmony_ci    struct Vnode* vnode = NULL;
1370d163575Sopenharmony_ci
1380d163575Sopenharmony_ci    VnodeHold();
1390d163575Sopenharmony_ci    vnode = GetFromFreeList();
1400d163575Sopenharmony_ci    if ((vnode == NULL) && g_totalVnodeSize < LOSCFG_MAX_VNODE_SIZE) {
1410d163575Sopenharmony_ci        vnode = (struct Vnode *)zalloc(sizeof(struct Vnode));
1420d163575Sopenharmony_ci        g_totalVnodeSize++;
1430d163575Sopenharmony_ci    }
1440d163575Sopenharmony_ci
1450d163575Sopenharmony_ci    if (vnode == NULL) {
1460d163575Sopenharmony_ci        vnode = VnodeReclaimLru();
1470d163575Sopenharmony_ci    }
1480d163575Sopenharmony_ci
1490d163575Sopenharmony_ci    if (vnode == NULL) {
1500d163575Sopenharmony_ci        *newVnode = NULL;
1510d163575Sopenharmony_ci        VnodeDrop();
1520d163575Sopenharmony_ci        return -ENOMEM;
1530d163575Sopenharmony_ci    }
1540d163575Sopenharmony_ci
1550d163575Sopenharmony_ci    vnode->type = VNODE_TYPE_UNKNOWN;
1560d163575Sopenharmony_ci    LOS_ListInit((&(vnode->parentPathCaches)));
1570d163575Sopenharmony_ci    LOS_ListInit((&(vnode->childPathCaches)));
1580d163575Sopenharmony_ci    LOS_ListInit((&(vnode->hashEntry)));
1590d163575Sopenharmony_ci    LOS_ListInit((&(vnode->actFreeEntry)));
1600d163575Sopenharmony_ci
1610d163575Sopenharmony_ci    if (vop == NULL) {
1620d163575Sopenharmony_ci        LOS_ListAdd(&g_vnodeVirtualList, &(vnode->actFreeEntry));
1630d163575Sopenharmony_ci        vnode->vop = &g_devfsOps;
1640d163575Sopenharmony_ci    } else {
1650d163575Sopenharmony_ci        LOS_ListTailInsert(&g_vnodeActiveList, &(vnode->actFreeEntry));
1660d163575Sopenharmony_ci        vnode->vop = vop;
1670d163575Sopenharmony_ci    }
1680d163575Sopenharmony_ci    LOS_ListInit(&vnode->mapping.page_list);
1690d163575Sopenharmony_ci    LOS_SpinInit(&vnode->mapping.list_lock);
1700d163575Sopenharmony_ci    (VOID)LOS_MuxInit(&vnode->mapping.mux_lock, NULL);
1710d163575Sopenharmony_ci    vnode->mapping.host = vnode;
1720d163575Sopenharmony_ci
1730d163575Sopenharmony_ci    VnodeDrop();
1740d163575Sopenharmony_ci
1750d163575Sopenharmony_ci    *newVnode = vnode;
1760d163575Sopenharmony_ci
1770d163575Sopenharmony_ci    return LOS_OK;
1780d163575Sopenharmony_ci}
1790d163575Sopenharmony_ci
1800d163575Sopenharmony_ciint VnodeFree(struct Vnode *vnode)
1810d163575Sopenharmony_ci{
1820d163575Sopenharmony_ci    if (vnode == NULL) {
1830d163575Sopenharmony_ci        return LOS_OK;
1840d163575Sopenharmony_ci    }
1850d163575Sopenharmony_ci
1860d163575Sopenharmony_ci    VnodeHold();
1870d163575Sopenharmony_ci    if (vnode->useCount > 0) {
1880d163575Sopenharmony_ci        VnodeDrop();
1890d163575Sopenharmony_ci        return -EBUSY;
1900d163575Sopenharmony_ci    }
1910d163575Sopenharmony_ci
1920d163575Sopenharmony_ci    VnodePathCacheFree(vnode);
1930d163575Sopenharmony_ci    LOS_ListDelete(&(vnode->hashEntry));
1940d163575Sopenharmony_ci    LOS_ListDelete(&vnode->actFreeEntry);
1950d163575Sopenharmony_ci
1960d163575Sopenharmony_ci    if (vnode->vop->Reclaim) {
1970d163575Sopenharmony_ci        vnode->vop->Reclaim(vnode);
1980d163575Sopenharmony_ci    }
1990d163575Sopenharmony_ci
2000d163575Sopenharmony_ci    if (vnode->filePath) {
2010d163575Sopenharmony_ci        free(vnode->filePath);
2020d163575Sopenharmony_ci    }
2030d163575Sopenharmony_ci    if (vnode->vop == &g_devfsOps) {
2040d163575Sopenharmony_ci        /* for dev vnode, just free it */
2050d163575Sopenharmony_ci        free(vnode->data);
2060d163575Sopenharmony_ci        free(vnode);
2070d163575Sopenharmony_ci        g_totalVnodeSize--;
2080d163575Sopenharmony_ci    } else {
2090d163575Sopenharmony_ci        /* for normal vnode, reclaim it to g_VnodeFreeList */
2100d163575Sopenharmony_ci        (void)memset_s(vnode, sizeof(struct Vnode), 0, sizeof(struct Vnode));
2110d163575Sopenharmony_ci        LOS_ListAdd(&g_vnodeFreeList, &vnode->actFreeEntry);
2120d163575Sopenharmony_ci        g_freeVnodeSize++;
2130d163575Sopenharmony_ci    }
2140d163575Sopenharmony_ci    VnodeDrop();
2150d163575Sopenharmony_ci
2160d163575Sopenharmony_ci    return LOS_OK;
2170d163575Sopenharmony_ci}
2180d163575Sopenharmony_ci
2190d163575Sopenharmony_ciint VnodeFreeAll(const struct Mount *mount)
2200d163575Sopenharmony_ci{
2210d163575Sopenharmony_ci    struct Vnode *vnode = NULL;
2220d163575Sopenharmony_ci    struct Vnode *nextVnode = NULL;
2230d163575Sopenharmony_ci    int ret;
2240d163575Sopenharmony_ci
2250d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(vnode, nextVnode, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
2260d163575Sopenharmony_ci        if ((vnode->originMount == mount) && !(vnode->flag & VNODE_FLAG_MOUNT_NEW)) {
2270d163575Sopenharmony_ci            ret = VnodeFree(vnode);
2280d163575Sopenharmony_ci            if (ret != LOS_OK) {
2290d163575Sopenharmony_ci                return ret;
2300d163575Sopenharmony_ci            }
2310d163575Sopenharmony_ci        }
2320d163575Sopenharmony_ci    }
2330d163575Sopenharmony_ci
2340d163575Sopenharmony_ci    return LOS_OK;
2350d163575Sopenharmony_ci}
2360d163575Sopenharmony_ci
2370d163575Sopenharmony_ciBOOL VnodeInUseIter(const struct Mount *mount)
2380d163575Sopenharmony_ci{
2390d163575Sopenharmony_ci    struct Vnode *vnode = NULL;
2400d163575Sopenharmony_ci
2410d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY(vnode, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
2420d163575Sopenharmony_ci        if (vnode->originMount == mount) {
2430d163575Sopenharmony_ci            if ((vnode->useCount > 0) || (vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) {
2440d163575Sopenharmony_ci                return TRUE;
2450d163575Sopenharmony_ci            }
2460d163575Sopenharmony_ci        }
2470d163575Sopenharmony_ci    }
2480d163575Sopenharmony_ci    return FALSE;
2490d163575Sopenharmony_ci}
2500d163575Sopenharmony_ci
2510d163575Sopenharmony_ciint VnodeHold(void)
2520d163575Sopenharmony_ci{
2530d163575Sopenharmony_ci    int ret = LOS_MuxLock(&g_vnodeMux, LOS_WAIT_FOREVER);
2540d163575Sopenharmony_ci    if (ret != LOS_OK) {
2550d163575Sopenharmony_ci        PRINT_ERR("VnodeHold lock failed !\n");
2560d163575Sopenharmony_ci    }
2570d163575Sopenharmony_ci    return ret;
2580d163575Sopenharmony_ci}
2590d163575Sopenharmony_ci
2600d163575Sopenharmony_ciint VnodeDrop(void)
2610d163575Sopenharmony_ci{
2620d163575Sopenharmony_ci    int ret = LOS_MuxUnlock(&g_vnodeMux);
2630d163575Sopenharmony_ci    if (ret != LOS_OK) {
2640d163575Sopenharmony_ci        PRINT_ERR("VnodeDrop unlock failed !\n");
2650d163575Sopenharmony_ci    }
2660d163575Sopenharmony_ci    return ret;
2670d163575Sopenharmony_ci}
2680d163575Sopenharmony_ci
2690d163575Sopenharmony_cistatic char *NextName(char *pos, uint8_t *len)
2700d163575Sopenharmony_ci{
2710d163575Sopenharmony_ci    char *name = NULL;
2720d163575Sopenharmony_ci    while (*pos != 0 && *pos == '/') {
2730d163575Sopenharmony_ci        pos++;
2740d163575Sopenharmony_ci    }
2750d163575Sopenharmony_ci    if (*pos == '\0') {
2760d163575Sopenharmony_ci        return NULL;
2770d163575Sopenharmony_ci    }
2780d163575Sopenharmony_ci    name = (char *)pos;
2790d163575Sopenharmony_ci    while (*pos != '\0' && *pos != '/') {
2800d163575Sopenharmony_ci        pos++;
2810d163575Sopenharmony_ci    }
2820d163575Sopenharmony_ci    *len = pos - name;
2830d163575Sopenharmony_ci    return name;
2840d163575Sopenharmony_ci}
2850d163575Sopenharmony_ci
2860d163575Sopenharmony_cistatic int PreProcess(const char *originPath, struct Vnode **startVnode, char **path)
2870d163575Sopenharmony_ci{
2880d163575Sopenharmony_ci    int ret;
2890d163575Sopenharmony_ci    char *absolutePath = NULL;
2900d163575Sopenharmony_ci
2910d163575Sopenharmony_ci    ret = vfs_normalize_path(NULL, originPath, &absolutePath);
2920d163575Sopenharmony_ci    if (ret == LOS_OK) {
2930d163575Sopenharmony_ci        *startVnode = GetCurrRootVnode();
2940d163575Sopenharmony_ci        *path = absolutePath;
2950d163575Sopenharmony_ci    }
2960d163575Sopenharmony_ci
2970d163575Sopenharmony_ci    return ret;
2980d163575Sopenharmony_ci}
2990d163575Sopenharmony_ci
3000d163575Sopenharmony_cistatic struct Vnode *ConvertVnodeIfMounted(struct Vnode *vnode)
3010d163575Sopenharmony_ci{
3020d163575Sopenharmony_ci    if ((vnode == NULL) || !(vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) {
3030d163575Sopenharmony_ci        return vnode;
3040d163575Sopenharmony_ci    }
3050d163575Sopenharmony_ci#ifdef LOSCFG_MNT_CONTAINER
3060d163575Sopenharmony_ci    LIST_HEAD *mntList = GetMountList();
3070d163575Sopenharmony_ci    struct Mount *mnt = NULL;
3080d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY(mnt, mntList, struct Mount, mountList) {
3090d163575Sopenharmony_ci        if ((mnt != NULL) && (mnt->vnodeBeCovered == vnode)) {
3100d163575Sopenharmony_ci            return mnt->vnodeCovered;
3110d163575Sopenharmony_ci        }
3120d163575Sopenharmony_ci    }
3130d163575Sopenharmony_ci    if (strcmp(vnode->filePath, "/dev") == 0) {
3140d163575Sopenharmony_ci        return vnode->newMount->vnodeCovered;
3150d163575Sopenharmony_ci    }
3160d163575Sopenharmony_ci    return vnode;
3170d163575Sopenharmony_ci#else
3180d163575Sopenharmony_ci    return vnode->newMount->vnodeCovered;
3190d163575Sopenharmony_ci#endif
3200d163575Sopenharmony_ci}
3210d163575Sopenharmony_ci
3220d163575Sopenharmony_cistatic void RefreshLRU(struct Vnode *vnode)
3230d163575Sopenharmony_ci{
3240d163575Sopenharmony_ci    if (vnode == NULL || (vnode->type != VNODE_TYPE_REG && vnode->type != VNODE_TYPE_DIR) ||
3250d163575Sopenharmony_ci        vnode->vop == &g_devfsOps || vnode->vop == NULL) {
3260d163575Sopenharmony_ci        return;
3270d163575Sopenharmony_ci    }
3280d163575Sopenharmony_ci    LOS_ListDelete(&(vnode->actFreeEntry));
3290d163575Sopenharmony_ci    LOS_ListTailInsert(&g_vnodeActiveList, &(vnode->actFreeEntry));
3300d163575Sopenharmony_ci}
3310d163575Sopenharmony_ci
3320d163575Sopenharmony_cistatic int ProcessVirtualVnode(struct Vnode *parent, uint32_t flags, struct Vnode **vnode)
3330d163575Sopenharmony_ci{
3340d163575Sopenharmony_ci    int ret = -ENOENT;
3350d163575Sopenharmony_ci    if (flags & V_CREATE) {
3360d163575Sopenharmony_ci        // only create /dev/ vnode
3370d163575Sopenharmony_ci        ret = VnodeAlloc(NULL, vnode);
3380d163575Sopenharmony_ci    }
3390d163575Sopenharmony_ci    if (ret == LOS_OK) {
3400d163575Sopenharmony_ci        (*vnode)->parent = parent;
3410d163575Sopenharmony_ci    }
3420d163575Sopenharmony_ci    return ret;
3430d163575Sopenharmony_ci}
3440d163575Sopenharmony_ci
3450d163575Sopenharmony_cistatic int Step(char **currentDir, struct Vnode **currentVnode, uint32_t flags)
3460d163575Sopenharmony_ci{
3470d163575Sopenharmony_ci    int ret;
3480d163575Sopenharmony_ci    uint8_t len = 0;
3490d163575Sopenharmony_ci    struct Vnode *nextVnode = NULL;
3500d163575Sopenharmony_ci    char *nextDir = NULL;
3510d163575Sopenharmony_ci
3520d163575Sopenharmony_ci    if ((*currentVnode)->type != VNODE_TYPE_DIR) {
3530d163575Sopenharmony_ci        return -ENOTDIR;
3540d163575Sopenharmony_ci    }
3550d163575Sopenharmony_ci    nextDir = NextName(*currentDir, &len);
3560d163575Sopenharmony_ci    if (nextDir == NULL) {
3570d163575Sopenharmony_ci        // there is '/' at the end of the *currentDir.
3580d163575Sopenharmony_ci        *currentDir = NULL;
3590d163575Sopenharmony_ci        return LOS_OK;
3600d163575Sopenharmony_ci    }
3610d163575Sopenharmony_ci
3620d163575Sopenharmony_ci    ret = PathCacheLookup(*currentVnode, nextDir, len, &nextVnode);
3630d163575Sopenharmony_ci    if (ret == LOS_OK) {
3640d163575Sopenharmony_ci        goto STEP_FINISH;
3650d163575Sopenharmony_ci    }
3660d163575Sopenharmony_ci
3670d163575Sopenharmony_ci    (*currentVnode)->useCount++;
3680d163575Sopenharmony_ci    if (flags & V_DUMMY) {
3690d163575Sopenharmony_ci        ret = ProcessVirtualVnode(*currentVnode, flags, &nextVnode);
3700d163575Sopenharmony_ci    } else {
3710d163575Sopenharmony_ci        if ((*currentVnode)->vop != NULL && (*currentVnode)->vop->Lookup != NULL) {
3720d163575Sopenharmony_ci            ret = (*currentVnode)->vop->Lookup(*currentVnode, nextDir, len, &nextVnode);
3730d163575Sopenharmony_ci        } else {
3740d163575Sopenharmony_ci            ret = -ENOSYS;
3750d163575Sopenharmony_ci        }
3760d163575Sopenharmony_ci    }
3770d163575Sopenharmony_ci    (*currentVnode)->useCount--;
3780d163575Sopenharmony_ci
3790d163575Sopenharmony_ci    if (ret == LOS_OK) {
3800d163575Sopenharmony_ci        (void)PathCacheAlloc((*currentVnode), nextVnode, nextDir, len);
3810d163575Sopenharmony_ci    }
3820d163575Sopenharmony_ci
3830d163575Sopenharmony_ciSTEP_FINISH:
3840d163575Sopenharmony_ci    nextVnode = ConvertVnodeIfMounted(nextVnode);
3850d163575Sopenharmony_ci    RefreshLRU(nextVnode);
3860d163575Sopenharmony_ci
3870d163575Sopenharmony_ci    *currentDir = nextDir + len;
3880d163575Sopenharmony_ci    if (ret == LOS_OK) {
3890d163575Sopenharmony_ci        *currentVnode = nextVnode;
3900d163575Sopenharmony_ci    }
3910d163575Sopenharmony_ci
3920d163575Sopenharmony_ci    return ret;
3930d163575Sopenharmony_ci}
3940d163575Sopenharmony_ci
3950d163575Sopenharmony_ciint VnodeLookupAt(const char *path, struct Vnode **result, uint32_t flags, struct Vnode *orgVnode)
3960d163575Sopenharmony_ci{
3970d163575Sopenharmony_ci    int ret;
3980d163575Sopenharmony_ci    int vnodePathLen;
3990d163575Sopenharmony_ci    char *vnodePath = NULL;
4000d163575Sopenharmony_ci    struct Vnode *startVnode = NULL;
4010d163575Sopenharmony_ci    char *normalizedPath = NULL;
4020d163575Sopenharmony_ci
4030d163575Sopenharmony_ci    if (orgVnode != NULL) {
4040d163575Sopenharmony_ci        startVnode = orgVnode;
4050d163575Sopenharmony_ci        normalizedPath = strdup(path);
4060d163575Sopenharmony_ci        if (normalizedPath == NULL) {
4070d163575Sopenharmony_ci            PRINT_ERR("[VFS]lookup failed, strdup err\n");
4080d163575Sopenharmony_ci            ret = -EINVAL;
4090d163575Sopenharmony_ci            goto OUT_FREE_PATH;
4100d163575Sopenharmony_ci        }
4110d163575Sopenharmony_ci    } else {
4120d163575Sopenharmony_ci        ret = PreProcess(path, &startVnode, &normalizedPath);
4130d163575Sopenharmony_ci        if (ret != LOS_OK) {
4140d163575Sopenharmony_ci            PRINT_ERR("[VFS]lookup failed, invalid path err = %d\n", ret);
4150d163575Sopenharmony_ci            goto OUT_FREE_PATH;
4160d163575Sopenharmony_ci        }
4170d163575Sopenharmony_ci    }
4180d163575Sopenharmony_ci
4190d163575Sopenharmony_ci    if (normalizedPath[1] == '\0' && normalizedPath[0] == '/') {
4200d163575Sopenharmony_ci        *result = GetCurrRootVnode();
4210d163575Sopenharmony_ci        free(normalizedPath);
4220d163575Sopenharmony_ci        return LOS_OK;
4230d163575Sopenharmony_ci    }
4240d163575Sopenharmony_ci
4250d163575Sopenharmony_ci    char *currentDir = normalizedPath;
4260d163575Sopenharmony_ci    struct Vnode *currentVnode = startVnode;
4270d163575Sopenharmony_ci
4280d163575Sopenharmony_ci    while (*currentDir != '\0') {
4290d163575Sopenharmony_ci        ret = Step(&currentDir, &currentVnode, flags);
4300d163575Sopenharmony_ci        if (currentDir == NULL || *currentDir == '\0') {
4310d163575Sopenharmony_ci            // return target or parent vnode as result
4320d163575Sopenharmony_ci            *result = currentVnode;
4330d163575Sopenharmony_ci            if (currentVnode->filePath == NULL) {
4340d163575Sopenharmony_ci                currentVnode->filePath = normalizedPath;
4350d163575Sopenharmony_ci            } else {
4360d163575Sopenharmony_ci                free(normalizedPath);
4370d163575Sopenharmony_ci            }
4380d163575Sopenharmony_ci            return ret;
4390d163575Sopenharmony_ci        } else if (VfsVnodePermissionCheck(currentVnode, EXEC_OP)) {
4400d163575Sopenharmony_ci            ret = -EACCES;
4410d163575Sopenharmony_ci            goto OUT_FREE_PATH;
4420d163575Sopenharmony_ci        }
4430d163575Sopenharmony_ci
4440d163575Sopenharmony_ci        if (ret != LOS_OK) {
4450d163575Sopenharmony_ci            // no such file, lookup failed
4460d163575Sopenharmony_ci            goto OUT_FREE_PATH;
4470d163575Sopenharmony_ci        }
4480d163575Sopenharmony_ci        if (currentVnode->filePath == NULL) {
4490d163575Sopenharmony_ci            vnodePathLen = currentDir - normalizedPath;
4500d163575Sopenharmony_ci            vnodePath = malloc(vnodePathLen + 1);
4510d163575Sopenharmony_ci            if (vnodePath == NULL) {
4520d163575Sopenharmony_ci                ret = -ENOMEM;
4530d163575Sopenharmony_ci                goto OUT_FREE_PATH;
4540d163575Sopenharmony_ci            }
4550d163575Sopenharmony_ci            ret = strncpy_s(vnodePath, vnodePathLen + 1, normalizedPath, vnodePathLen);
4560d163575Sopenharmony_ci            if (ret != EOK) {
4570d163575Sopenharmony_ci                ret = -ENAMETOOLONG;
4580d163575Sopenharmony_ci                free(vnodePath);
4590d163575Sopenharmony_ci                goto OUT_FREE_PATH;
4600d163575Sopenharmony_ci            }
4610d163575Sopenharmony_ci            currentVnode->filePath = vnodePath;
4620d163575Sopenharmony_ci            currentVnode->filePath[vnodePathLen] = 0;
4630d163575Sopenharmony_ci        }
4640d163575Sopenharmony_ci    }
4650d163575Sopenharmony_ci
4660d163575Sopenharmony_ciOUT_FREE_PATH:
4670d163575Sopenharmony_ci    if (normalizedPath) {
4680d163575Sopenharmony_ci        free(normalizedPath);
4690d163575Sopenharmony_ci    }
4700d163575Sopenharmony_ci    return ret;
4710d163575Sopenharmony_ci}
4720d163575Sopenharmony_ci
4730d163575Sopenharmony_ciint VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags)
4740d163575Sopenharmony_ci{
4750d163575Sopenharmony_ci    return VnodeLookupAt(path, vnode, flags, NULL);
4760d163575Sopenharmony_ci}
4770d163575Sopenharmony_ci
4780d163575Sopenharmony_ciint VnodeLookupFullpath(const char *fullpath, struct Vnode **vnode, uint32_t flags)
4790d163575Sopenharmony_ci{
4800d163575Sopenharmony_ci    return VnodeLookupAt(fullpath, vnode, flags, GetCurrRootVnode());
4810d163575Sopenharmony_ci}
4820d163575Sopenharmony_ci
4830d163575Sopenharmony_cistatic void ChangeRootInternal(struct Vnode *rootOld, char *dirname)
4840d163575Sopenharmony_ci{
4850d163575Sopenharmony_ci    int ret;
4860d163575Sopenharmony_ci    struct Mount *mnt = NULL;
4870d163575Sopenharmony_ci    char *name = NULL;
4880d163575Sopenharmony_ci    struct Vnode *node = NULL;
4890d163575Sopenharmony_ci    struct Vnode *nodeInFs = NULL;
4900d163575Sopenharmony_ci    struct PathCache *item = NULL;
4910d163575Sopenharmony_ci    struct PathCache *nextItem = NULL;
4920d163575Sopenharmony_ci
4930d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &rootOld->childPathCaches, struct PathCache, childEntry) {
4940d163575Sopenharmony_ci        name = item->name;
4950d163575Sopenharmony_ci        node = item->childVnode;
4960d163575Sopenharmony_ci
4970d163575Sopenharmony_ci        if (strcmp(name, dirname)) {
4980d163575Sopenharmony_ci            continue;
4990d163575Sopenharmony_ci        }
5000d163575Sopenharmony_ci        PathCacheFree(item);
5010d163575Sopenharmony_ci
5020d163575Sopenharmony_ci        ret = VnodeLookup(dirname, &nodeInFs, 0);
5030d163575Sopenharmony_ci        if (ret) {
5040d163575Sopenharmony_ci            PRINTK("%s-%d %s NOT exist in rootfs\n", __FUNCTION__, __LINE__, dirname);
5050d163575Sopenharmony_ci            break;
5060d163575Sopenharmony_ci        }
5070d163575Sopenharmony_ci
5080d163575Sopenharmony_ci        mnt = node->newMount;
5090d163575Sopenharmony_ci        mnt->vnodeBeCovered = nodeInFs;
5100d163575Sopenharmony_ci
5110d163575Sopenharmony_ci        nodeInFs->newMount = mnt;
5120d163575Sopenharmony_ci        nodeInFs->flag |= VNODE_FLAG_MOUNT_ORIGIN;
5130d163575Sopenharmony_ci
5140d163575Sopenharmony_ci        break;
5150d163575Sopenharmony_ci    }
5160d163575Sopenharmony_ci}
5170d163575Sopenharmony_ci
5180d163575Sopenharmony_civoid ChangeRoot(struct Vnode *rootNew)
5190d163575Sopenharmony_ci{
5200d163575Sopenharmony_ci    struct Vnode *rootOld = g_rootVnode;
5210d163575Sopenharmony_ci    g_rootVnode = rootNew;
5220d163575Sopenharmony_ci#ifdef LOSCFG_CHROOT
5230d163575Sopenharmony_ci    LosProcessCB *curr = OsCurrProcessGet();
5240d163575Sopenharmony_ci    if ((curr->files != NULL) &&
5250d163575Sopenharmony_ci        (curr->files->rootVnode != NULL) &&
5260d163575Sopenharmony_ci        (curr->files->rootVnode->useCount > 0)) {
5270d163575Sopenharmony_ci        curr->files->rootVnode->useCount--;
5280d163575Sopenharmony_ci    }
5290d163575Sopenharmony_ci    rootNew->useCount++;
5300d163575Sopenharmony_ci    curr->files->rootVnode = rootNew;
5310d163575Sopenharmony_ci#endif
5320d163575Sopenharmony_ci
5330d163575Sopenharmony_ci    ChangeRootInternal(rootOld, "proc");
5340d163575Sopenharmony_ci    ChangeRootInternal(rootOld, "dev");
5350d163575Sopenharmony_ci}
5360d163575Sopenharmony_ci
5370d163575Sopenharmony_cistatic int VnodeReaddir(struct Vnode *vp, struct fs_dirent_s *dir)
5380d163575Sopenharmony_ci{
5390d163575Sopenharmony_ci    int result;
5400d163575Sopenharmony_ci    int cnt = 0;
5410d163575Sopenharmony_ci    off_t i = 0;
5420d163575Sopenharmony_ci    off_t idx;
5430d163575Sopenharmony_ci    unsigned int dstNameSize;
5440d163575Sopenharmony_ci
5450d163575Sopenharmony_ci    struct PathCache *item = NULL;
5460d163575Sopenharmony_ci    struct PathCache *nextItem = NULL;
5470d163575Sopenharmony_ci
5480d163575Sopenharmony_ci    if (dir == NULL) {
5490d163575Sopenharmony_ci        return -EINVAL;
5500d163575Sopenharmony_ci    }
5510d163575Sopenharmony_ci
5520d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vp->childPathCaches, struct PathCache, childEntry) {
5530d163575Sopenharmony_ci        if (i < dir->fd_position) {
5540d163575Sopenharmony_ci            i++;
5550d163575Sopenharmony_ci            continue;
5560d163575Sopenharmony_ci        }
5570d163575Sopenharmony_ci
5580d163575Sopenharmony_ci        idx = i - dir->fd_position;
5590d163575Sopenharmony_ci
5600d163575Sopenharmony_ci        dstNameSize = sizeof(dir->fd_dir[idx].d_name);
5610d163575Sopenharmony_ci        result = strncpy_s(dir->fd_dir[idx].d_name, dstNameSize, item->name, item->nameLen);
5620d163575Sopenharmony_ci        if (result != EOK) {
5630d163575Sopenharmony_ci            return -ENAMETOOLONG;
5640d163575Sopenharmony_ci        }
5650d163575Sopenharmony_ci        dir->fd_dir[idx].d_off = i;
5660d163575Sopenharmony_ci        dir->fd_dir[idx].d_reclen = (uint16_t)sizeof(struct dirent);
5670d163575Sopenharmony_ci
5680d163575Sopenharmony_ci        i++;
5690d163575Sopenharmony_ci        if (++cnt >= dir->read_cnt) {
5700d163575Sopenharmony_ci            break;
5710d163575Sopenharmony_ci        }
5720d163575Sopenharmony_ci    }
5730d163575Sopenharmony_ci
5740d163575Sopenharmony_ci    dir->fd_position = i;
5750d163575Sopenharmony_ci
5760d163575Sopenharmony_ci    return cnt;
5770d163575Sopenharmony_ci}
5780d163575Sopenharmony_ci
5790d163575Sopenharmony_ciint VnodeOpendir(struct Vnode *vnode, struct fs_dirent_s *dir)
5800d163575Sopenharmony_ci{
5810d163575Sopenharmony_ci    (void)vnode;
5820d163575Sopenharmony_ci    (void)dir;
5830d163575Sopenharmony_ci    return LOS_OK;
5840d163575Sopenharmony_ci}
5850d163575Sopenharmony_ci
5860d163575Sopenharmony_ciint VnodeClosedir(struct Vnode *vnode, struct fs_dirent_s *dir)
5870d163575Sopenharmony_ci{
5880d163575Sopenharmony_ci    (void)vnode;
5890d163575Sopenharmony_ci    (void)dir;
5900d163575Sopenharmony_ci    return LOS_OK;
5910d163575Sopenharmony_ci}
5920d163575Sopenharmony_ci
5930d163575Sopenharmony_ciint VnodeCreate(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode)
5940d163575Sopenharmony_ci{
5950d163575Sopenharmony_ci    int ret;
5960d163575Sopenharmony_ci    struct Vnode *newVnode = NULL;
5970d163575Sopenharmony_ci
5980d163575Sopenharmony_ci    ret = VnodeAlloc(NULL, &newVnode);
5990d163575Sopenharmony_ci    if (ret != 0) {
6000d163575Sopenharmony_ci        return -ENOMEM;
6010d163575Sopenharmony_ci    }
6020d163575Sopenharmony_ci
6030d163575Sopenharmony_ci    newVnode->type = VNODE_TYPE_CHR;
6040d163575Sopenharmony_ci    newVnode->vop = parent->vop;
6050d163575Sopenharmony_ci    newVnode->fop = parent->fop;
6060d163575Sopenharmony_ci    newVnode->data = NULL;
6070d163575Sopenharmony_ci    newVnode->parent = parent;
6080d163575Sopenharmony_ci    newVnode->originMount = parent->originMount;
6090d163575Sopenharmony_ci    newVnode->uid = parent->uid;
6100d163575Sopenharmony_ci    newVnode->gid = parent->gid;
6110d163575Sopenharmony_ci    newVnode->mode = mode;
6120d163575Sopenharmony_ci    /* The 'name' here is not full path, but for device we don't depend on this path, it's just a name for DFx.
6130d163575Sopenharmony_ci       When we have devfs, we can get a fullpath. */
6140d163575Sopenharmony_ci    newVnode->filePath = strdup(name);
6150d163575Sopenharmony_ci
6160d163575Sopenharmony_ci    *vnode = newVnode;
6170d163575Sopenharmony_ci    return 0;
6180d163575Sopenharmony_ci}
6190d163575Sopenharmony_ci
6200d163575Sopenharmony_ciint VnodeDevInit(void)
6210d163575Sopenharmony_ci{
6220d163575Sopenharmony_ci    struct Vnode *devNode = NULL;
6230d163575Sopenharmony_ci    struct Mount *devMount = NULL;
6240d163575Sopenharmony_ci
6250d163575Sopenharmony_ci    int retval = VnodeLookup("/dev", &devNode, V_CREATE | V_DUMMY);
6260d163575Sopenharmony_ci    if (retval != LOS_OK) {
6270d163575Sopenharmony_ci        PRINT_ERR("VnodeDevInit failed error %d\n", retval);
6280d163575Sopenharmony_ci        return retval;
6290d163575Sopenharmony_ci    }
6300d163575Sopenharmony_ci    devNode->mode = DEV_VNODE_MODE | S_IFDIR;
6310d163575Sopenharmony_ci    devNode->type = VNODE_TYPE_DIR;
6320d163575Sopenharmony_ci
6330d163575Sopenharmony_ci    devMount = MountAlloc(devNode, NULL);
6340d163575Sopenharmony_ci    if (devMount == NULL) {
6350d163575Sopenharmony_ci        PRINT_ERR("VnodeDevInit failed mount point alloc failed.\n");
6360d163575Sopenharmony_ci        return -ENOMEM;
6370d163575Sopenharmony_ci    }
6380d163575Sopenharmony_ci    devMount->vnodeCovered = devNode;
6390d163575Sopenharmony_ci    devMount->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN;
6400d163575Sopenharmony_ci    return LOS_OK;
6410d163575Sopenharmony_ci}
6420d163575Sopenharmony_ci
6430d163575Sopenharmony_ciint VnodeGetattr(struct Vnode *vnode, struct stat *buf)
6440d163575Sopenharmony_ci{
6450d163575Sopenharmony_ci    (void)memset_s(buf, sizeof(struct stat), 0, sizeof(struct stat));
6460d163575Sopenharmony_ci    buf->st_mode = vnode->mode;
6470d163575Sopenharmony_ci    buf->st_uid = vnode->uid;
6480d163575Sopenharmony_ci    buf->st_gid = vnode->gid;
6490d163575Sopenharmony_ci
6500d163575Sopenharmony_ci    return LOS_OK;
6510d163575Sopenharmony_ci}
6520d163575Sopenharmony_ci
6530d163575Sopenharmony_cistruct Vnode *VnodeGetRoot(void)
6540d163575Sopenharmony_ci{
6550d163575Sopenharmony_ci    return g_rootVnode;
6560d163575Sopenharmony_ci}
6570d163575Sopenharmony_ci
6580d163575Sopenharmony_cistatic int VnodeChattr(struct Vnode *vnode, struct IATTR *attr)
6590d163575Sopenharmony_ci{
6600d163575Sopenharmony_ci    mode_t tmpMode;
6610d163575Sopenharmony_ci    if (vnode == NULL || attr == NULL) {
6620d163575Sopenharmony_ci        return -EINVAL;
6630d163575Sopenharmony_ci    }
6640d163575Sopenharmony_ci    if (attr->attr_chg_valid & CHG_MODE) {
6650d163575Sopenharmony_ci        tmpMode = attr->attr_chg_mode;
6660d163575Sopenharmony_ci        tmpMode &= ~S_IFMT;
6670d163575Sopenharmony_ci        vnode->mode &= S_IFMT;
6680d163575Sopenharmony_ci        vnode->mode = tmpMode | vnode->mode;
6690d163575Sopenharmony_ci    }
6700d163575Sopenharmony_ci    if (attr->attr_chg_valid & CHG_UID) {
6710d163575Sopenharmony_ci        vnode->uid = attr->attr_chg_uid;
6720d163575Sopenharmony_ci    }
6730d163575Sopenharmony_ci    if (attr->attr_chg_valid & CHG_GID) {
6740d163575Sopenharmony_ci        vnode->gid = attr->attr_chg_gid;
6750d163575Sopenharmony_ci    }
6760d163575Sopenharmony_ci    return LOS_OK;
6770d163575Sopenharmony_ci}
6780d163575Sopenharmony_ci
6790d163575Sopenharmony_ciint VnodeDevLookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **vnode)
6800d163575Sopenharmony_ci{
6810d163575Sopenharmony_ci    (void)parentVnode;
6820d163575Sopenharmony_ci    (void)path;
6830d163575Sopenharmony_ci    (void)len;
6840d163575Sopenharmony_ci    (void)vnode;
6850d163575Sopenharmony_ci    /* dev node must in pathCache. */
6860d163575Sopenharmony_ci    return -ENOENT;
6870d163575Sopenharmony_ci}
6880d163575Sopenharmony_ci
6890d163575Sopenharmony_cistatic struct VnodeOps g_devfsOps = {
6900d163575Sopenharmony_ci    .Lookup = VnodeDevLookup,
6910d163575Sopenharmony_ci    .Getattr = VnodeGetattr,
6920d163575Sopenharmony_ci    .Readdir = VnodeReaddir,
6930d163575Sopenharmony_ci    .Opendir = VnodeOpendir,
6940d163575Sopenharmony_ci    .Closedir = VnodeClosedir,
6950d163575Sopenharmony_ci    .Create = VnodeCreate,
6960d163575Sopenharmony_ci    .Chattr = VnodeChattr,
6970d163575Sopenharmony_ci};
6980d163575Sopenharmony_ci
6990d163575Sopenharmony_civoid VnodeMemoryDump(void)
7000d163575Sopenharmony_ci{
7010d163575Sopenharmony_ci    struct Vnode *item = NULL;
7020d163575Sopenharmony_ci    struct Vnode *nextItem = NULL;
7030d163575Sopenharmony_ci    int vnodeCount = 0;
7040d163575Sopenharmony_ci
7050d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
7060d163575Sopenharmony_ci        if ((item->useCount > 0) ||
7070d163575Sopenharmony_ci            (item->flag & VNODE_FLAG_MOUNT_ORIGIN) ||
7080d163575Sopenharmony_ci            (item->flag & VNODE_FLAG_MOUNT_NEW)) {
7090d163575Sopenharmony_ci            continue;
7100d163575Sopenharmony_ci        }
7110d163575Sopenharmony_ci
7120d163575Sopenharmony_ci        vnodeCount++;
7130d163575Sopenharmony_ci    }
7140d163575Sopenharmony_ci
7150d163575Sopenharmony_ci    PRINTK("Vnode number = %d\n", vnodeCount);
7160d163575Sopenharmony_ci    PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode));
7170d163575Sopenharmony_ci}
7180d163575Sopenharmony_ci
7190d163575Sopenharmony_ci#ifdef LOSCFG_PROC_PROCESS_DIR
7200d163575Sopenharmony_cistruct Vnode *VnodeFind(int fd)
7210d163575Sopenharmony_ci{
7220d163575Sopenharmony_ci    INT32 sysFd;
7230d163575Sopenharmony_ci
7240d163575Sopenharmony_ci    if (fd < 0) {
7250d163575Sopenharmony_ci        PRINT_ERR("Error. fd is invalid as %d\n", fd);
7260d163575Sopenharmony_ci        return NULL;
7270d163575Sopenharmony_ci    }
7280d163575Sopenharmony_ci
7290d163575Sopenharmony_ci    /* Process fd convert to system global fd */
7300d163575Sopenharmony_ci    sysFd = GetAssociatedSystemFd(fd);
7310d163575Sopenharmony_ci    if (sysFd < 0) {
7320d163575Sopenharmony_ci        PRINT_ERR("Error. sysFd is invalid as %d\n", sysFd);
7330d163575Sopenharmony_ci        return NULL;
7340d163575Sopenharmony_ci    }
7350d163575Sopenharmony_ci
7360d163575Sopenharmony_ci    return files_get_openfile((int)sysFd);
7370d163575Sopenharmony_ci}
7380d163575Sopenharmony_ci#endif
7390d163575Sopenharmony_ci
7400d163575Sopenharmony_ciLIST_HEAD* GetVnodeFreeList()
7410d163575Sopenharmony_ci{
7420d163575Sopenharmony_ci    return &g_vnodeFreeList;
7430d163575Sopenharmony_ci}
7440d163575Sopenharmony_ci
7450d163575Sopenharmony_ciLIST_HEAD* GetVnodeVirtualList()
7460d163575Sopenharmony_ci{
7470d163575Sopenharmony_ci    return &g_vnodeVirtualList;
7480d163575Sopenharmony_ci}
7490d163575Sopenharmony_ci
7500d163575Sopenharmony_ciLIST_HEAD* GetVnodeActiveList()
7510d163575Sopenharmony_ci{
7520d163575Sopenharmony_ci    return &g_vnodeActiveList;
7530d163575Sopenharmony_ci}
7540d163575Sopenharmony_ci
7550d163575Sopenharmony_ciint VnodeClearCache(void)
7560d163575Sopenharmony_ci{
7570d163575Sopenharmony_ci    struct Vnode *item = NULL;
7580d163575Sopenharmony_ci    struct Vnode *nextItem = NULL;
7590d163575Sopenharmony_ci    int count = 0;
7600d163575Sopenharmony_ci
7610d163575Sopenharmony_ci    VnodeHold();
7620d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeActiveList, struct Vnode, actFreeEntry) {
7630d163575Sopenharmony_ci        if ((item->useCount > 0) ||
7640d163575Sopenharmony_ci            (item->flag & VNODE_FLAG_MOUNT_ORIGIN) ||
7650d163575Sopenharmony_ci            (item->flag & VNODE_FLAG_MOUNT_NEW)) {
7660d163575Sopenharmony_ci            continue;
7670d163575Sopenharmony_ci        }
7680d163575Sopenharmony_ci
7690d163575Sopenharmony_ci        if (VnodeFree(item) == LOS_OK) {
7700d163575Sopenharmony_ci            count++;
7710d163575Sopenharmony_ci        }
7720d163575Sopenharmony_ci    }
7730d163575Sopenharmony_ci    VnodeDrop();
7740d163575Sopenharmony_ci
7750d163575Sopenharmony_ci    return count;
7760d163575Sopenharmony_ci}
7770d163575Sopenharmony_ci
7780d163575Sopenharmony_cistruct Vnode *GetCurrRootVnode(void)
7790d163575Sopenharmony_ci{
7800d163575Sopenharmony_ci#ifdef LOSCFG_CHROOT
7810d163575Sopenharmony_ci    LosProcessCB *curr = OsCurrProcessGet();
7820d163575Sopenharmony_ci    return curr->files->rootVnode;
7830d163575Sopenharmony_ci#else
7840d163575Sopenharmony_ci    return g_rootVnode;
7850d163575Sopenharmony_ci#endif
7860d163575Sopenharmony_ci}
787