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(¤tDir, ¤tVnode, 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