154568cb3Sopenharmony_ci/* 254568cb3Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved. 354568cb3Sopenharmony_ci * 454568cb3Sopenharmony_ci * UniProton is licensed under Mulan PSL v2. 554568cb3Sopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 654568cb3Sopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 754568cb3Sopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 854568cb3Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 954568cb3Sopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 1054568cb3Sopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 1154568cb3Sopenharmony_ci * See the Mulan PSL v2 for more details. 1254568cb3Sopenharmony_ci * Create: 2022-09-21 1354568cb3Sopenharmony_ci * Description: 文件系统vfs层 1454568cb3Sopenharmony_ci */ 1554568cb3Sopenharmony_ci 1654568cb3Sopenharmony_ci#include "stdlib.h" 1754568cb3Sopenharmony_ci#include "string.h" 1854568cb3Sopenharmony_ci#include "securec.h" 1954568cb3Sopenharmony_ci#include "vfs_mount.h" 2054568cb3Sopenharmony_ci#include "vfs_files.h" 2154568cb3Sopenharmony_ci#include "vfs_maps.h" 2254568cb3Sopenharmony_ci#include "vfs_config.h" 2354568cb3Sopenharmony_ci#include "vfs_operations.h" 2454568cb3Sopenharmony_ci#include "prt_fs.h" 2554568cb3Sopenharmony_ci 2654568cb3Sopenharmony_cistatic struct TagMountPoint *g_mountPoints; 2754568cb3Sopenharmony_ci 2854568cb3Sopenharmony_cistatic void OsMpDeleteFromList(struct TagMountPoint *mp) 2954568cb3Sopenharmony_ci{ 3054568cb3Sopenharmony_ci struct TagMountPoint *prev = NULL; 3154568cb3Sopenharmony_ci 3254568cb3Sopenharmony_ci if (g_mountPoints == mp) { 3354568cb3Sopenharmony_ci g_mountPoints = mp->mNext; 3454568cb3Sopenharmony_ci return; 3554568cb3Sopenharmony_ci } 3654568cb3Sopenharmony_ci 3754568cb3Sopenharmony_ci for (prev = g_mountPoints; prev != NULL; prev = prev->mNext) { 3854568cb3Sopenharmony_ci if (prev->mNext != mp) { 3954568cb3Sopenharmony_ci continue; 4054568cb3Sopenharmony_ci } 4154568cb3Sopenharmony_ci 4254568cb3Sopenharmony_ci prev->mNext = mp->mNext; 4354568cb3Sopenharmony_ci break; 4454568cb3Sopenharmony_ci } 4554568cb3Sopenharmony_ci} 4654568cb3Sopenharmony_ci 4754568cb3Sopenharmony_cistatic S32 OsVfsFindMpByPath(const char *mPath, const char *iPath) 4854568cb3Sopenharmony_ci{ 4954568cb3Sopenharmony_ci const char *t = NULL; 5054568cb3Sopenharmony_ci S32 matches = 0; 5154568cb3Sopenharmony_ci do { 5254568cb3Sopenharmony_ci while ((*mPath == '/') && (*(mPath + 1) != '/')) { 5354568cb3Sopenharmony_ci mPath++; 5454568cb3Sopenharmony_ci } 5554568cb3Sopenharmony_ci while ((*iPath == '/') && (*(iPath + 1) != '/')) { 5654568cb3Sopenharmony_ci iPath++; 5754568cb3Sopenharmony_ci } 5854568cb3Sopenharmony_ci 5954568cb3Sopenharmony_ci t = strchr(mPath, '/'); 6054568cb3Sopenharmony_ci if (t == NULL) { 6154568cb3Sopenharmony_ci t = strchr(mPath, '\0'); 6254568cb3Sopenharmony_ci } 6354568cb3Sopenharmony_ci if ((t == mPath) || (t == NULL)) { 6454568cb3Sopenharmony_ci break; 6554568cb3Sopenharmony_ci } 6654568cb3Sopenharmony_ci if (strncmp(mPath, iPath, (size_t)(t - mPath)) != 0) { 6754568cb3Sopenharmony_ci return 0; 6854568cb3Sopenharmony_ci } 6954568cb3Sopenharmony_ci 7054568cb3Sopenharmony_ci iPath += (t - mPath); 7154568cb3Sopenharmony_ci if ((*iPath != '\0') && (*iPath != '/')) { 7254568cb3Sopenharmony_ci return 0; 7354568cb3Sopenharmony_ci } 7454568cb3Sopenharmony_ci 7554568cb3Sopenharmony_ci matches += (t - mPath); 7654568cb3Sopenharmony_ci mPath += (t - mPath); 7754568cb3Sopenharmony_ci } while (*mPath != '\0'); 7854568cb3Sopenharmony_ci 7954568cb3Sopenharmony_ci return matches; 8054568cb3Sopenharmony_ci} 8154568cb3Sopenharmony_ci 8254568cb3Sopenharmony_cistruct TagMountPoint *OsVfsFindMp(const char *path, const char **pathInMp) 8354568cb3Sopenharmony_ci{ 8454568cb3Sopenharmony_ci struct TagMountPoint *mp = g_mountPoints; 8554568cb3Sopenharmony_ci struct TagMountPoint *bestMp = NULL; 8654568cb3Sopenharmony_ci const char *iPath = NULL; 8754568cb3Sopenharmony_ci S32 bestMatches = 0; 8854568cb3Sopenharmony_ci S32 matches; 8954568cb3Sopenharmony_ci 9054568cb3Sopenharmony_ci if (path == NULL) { 9154568cb3Sopenharmony_ci return NULL; 9254568cb3Sopenharmony_ci } 9354568cb3Sopenharmony_ci 9454568cb3Sopenharmony_ci if (pathInMp != NULL) { 9554568cb3Sopenharmony_ci *pathInMp = NULL; 9654568cb3Sopenharmony_ci } 9754568cb3Sopenharmony_ci 9854568cb3Sopenharmony_ci while ((mp != NULL) && (mp->mPath != NULL)) { 9954568cb3Sopenharmony_ci matches = OsVfsFindMpByPath(mp->mPath, path); 10054568cb3Sopenharmony_ci if (matches > bestMatches) { 10154568cb3Sopenharmony_ci bestMatches = matches; 10254568cb3Sopenharmony_ci bestMp = mp; 10354568cb3Sopenharmony_ci 10454568cb3Sopenharmony_ci iPath = path + matches; 10554568cb3Sopenharmony_ci while ((*iPath == '/') && (*(iPath + 1) != '/')) { 10654568cb3Sopenharmony_ci iPath++; 10754568cb3Sopenharmony_ci } 10854568cb3Sopenharmony_ci 10954568cb3Sopenharmony_ci if (pathInMp != NULL) { 11054568cb3Sopenharmony_ci *pathInMp = path; 11154568cb3Sopenharmony_ci } 11254568cb3Sopenharmony_ci } 11354568cb3Sopenharmony_ci mp = mp->mNext; 11454568cb3Sopenharmony_ci } 11554568cb3Sopenharmony_ci return bestMp; 11654568cb3Sopenharmony_ci} 11754568cb3Sopenharmony_ci 11854568cb3Sopenharmony_ciS32 OsVfsFindMountPoint(const char *fsType) 11954568cb3Sopenharmony_ci{ 12054568cb3Sopenharmony_ci struct TagMountPoint *iter = NULL; 12154568cb3Sopenharmony_ci for (iter = g_mountPoints; iter != NULL; iter = iter->mNext) { 12254568cb3Sopenharmony_ci if ((iter->mFs != NULL) && (iter->mFs->fsType != NULL) && 12354568cb3Sopenharmony_ci strcmp(iter->mFs->fsType, fsType) == 0) { 12454568cb3Sopenharmony_ci return FS_OK; 12554568cb3Sopenharmony_ci } 12654568cb3Sopenharmony_ci } 12754568cb3Sopenharmony_ci return FS_NOK; 12854568cb3Sopenharmony_ci} 12954568cb3Sopenharmony_ci 13054568cb3Sopenharmony_cistatic void OsVfsFreeMp(struct TagMountPoint *mp) 13154568cb3Sopenharmony_ci{ 13254568cb3Sopenharmony_ci if (mp == NULL) { 13354568cb3Sopenharmony_ci return; 13454568cb3Sopenharmony_ci } 13554568cb3Sopenharmony_ci if (mp->mPath != NULL) { 13654568cb3Sopenharmony_ci free((void *)mp->mPath); 13754568cb3Sopenharmony_ci } 13854568cb3Sopenharmony_ci if (mp->mDev != NULL) { 13954568cb3Sopenharmony_ci free((void *)mp->mDev); 14054568cb3Sopenharmony_ci } 14154568cb3Sopenharmony_ci free(mp); 14254568cb3Sopenharmony_ci} 14354568cb3Sopenharmony_ci 14454568cb3Sopenharmony_ciS32 OsVfsMount(const char *source, const char *target, 14554568cb3Sopenharmony_ci const char *filesystemtype, uintptr_t mountflags, 14654568cb3Sopenharmony_ci const void *data) 14754568cb3Sopenharmony_ci{ 14854568cb3Sopenharmony_ci S32 ret; 14954568cb3Sopenharmony_ci struct TagMountPoint *mp = NULL; 15054568cb3Sopenharmony_ci struct TagFsMap *mFs = NULL; 15154568cb3Sopenharmony_ci const char *pathInMp = NULL; 15254568cb3Sopenharmony_ci 15354568cb3Sopenharmony_ci if ((target == NULL) || (target[0] != '/')) { 15454568cb3Sopenharmony_ci return FS_NOK; 15554568cb3Sopenharmony_ci } 15654568cb3Sopenharmony_ci (void)OsVfsLock(); 15754568cb3Sopenharmony_ci /* 确认是否已经被挂载 */ 15854568cb3Sopenharmony_ci mp = OsVfsFindMp(target, &pathInMp); 15954568cb3Sopenharmony_ci if (mp != NULL && pathInMp != NULL) { 16054568cb3Sopenharmony_ci OsVfsUnlock(); 16154568cb3Sopenharmony_ci return FS_NOK; 16254568cb3Sopenharmony_ci } 16354568cb3Sopenharmony_ci 16454568cb3Sopenharmony_ci mFs = OsVfsGetFsMap(filesystemtype); 16554568cb3Sopenharmony_ci if ((mFs == NULL) || (mFs->fsMops == NULL) || (mFs->fsMops->mount == NULL)) { 16654568cb3Sopenharmony_ci OsVfsUnlock(); 16754568cb3Sopenharmony_ci return FS_NOK; 16854568cb3Sopenharmony_ci } 16954568cb3Sopenharmony_ci 17054568cb3Sopenharmony_ci mp = (struct TagMountPoint *)malloc(sizeof(struct TagMountPoint)); 17154568cb3Sopenharmony_ci if (mp == NULL) { 17254568cb3Sopenharmony_ci OsVfsUnlock(); 17354568cb3Sopenharmony_ci return FS_NOK; 17454568cb3Sopenharmony_ci } 17554568cb3Sopenharmony_ci if (memset_s(mp, sizeof(struct TagMountPoint), 0, sizeof(struct TagMountPoint)) != EOK) { 17654568cb3Sopenharmony_ci free(mp); 17754568cb3Sopenharmony_ci OsVfsUnlock(); 17854568cb3Sopenharmony_ci return FS_NOK; 17954568cb3Sopenharmony_ci } 18054568cb3Sopenharmony_ci 18154568cb3Sopenharmony_ci mp->mFs = mFs; 18254568cb3Sopenharmony_ci mp->mDev = NULL; 18354568cb3Sopenharmony_ci if (source != NULL) { 18454568cb3Sopenharmony_ci mp->mDev = strdup(source); 18554568cb3Sopenharmony_ci if (mp->mDev == NULL) { 18654568cb3Sopenharmony_ci OsVfsFreeMp(mp); 18754568cb3Sopenharmony_ci OsVfsUnlock(); 18854568cb3Sopenharmony_ci return FS_NOK; 18954568cb3Sopenharmony_ci } 19054568cb3Sopenharmony_ci } 19154568cb3Sopenharmony_ci mp->mPath = strdup(target); 19254568cb3Sopenharmony_ci if (mp->mPath == NULL) { 19354568cb3Sopenharmony_ci OsVfsFreeMp(mp); 19454568cb3Sopenharmony_ci OsVfsUnlock(); 19554568cb3Sopenharmony_ci return FS_NOK; 19654568cb3Sopenharmony_ci } 19754568cb3Sopenharmony_ci 19854568cb3Sopenharmony_ci ret = mp->mFs->fsMops->mount(mp, mountflags, data); 19954568cb3Sopenharmony_ci if (ret != 0) { 20054568cb3Sopenharmony_ci OsVfsFreeMp(mp); 20154568cb3Sopenharmony_ci OsVfsUnlock(); 20254568cb3Sopenharmony_ci return FS_NOK; 20354568cb3Sopenharmony_ci } 20454568cb3Sopenharmony_ci mp->mRefs = 0; 20554568cb3Sopenharmony_ci mp->mWriteEnable = (mountflags & MS_RDONLY) ? FALSE : TRUE; 20654568cb3Sopenharmony_ci mp->mFs->fsRefs++; 20754568cb3Sopenharmony_ci mp->mNext = g_mountPoints; 20854568cb3Sopenharmony_ci g_mountPoints = mp; 20954568cb3Sopenharmony_ci OsVfsUnlock(); 21054568cb3Sopenharmony_ci return FS_OK; 21154568cb3Sopenharmony_ci} 21254568cb3Sopenharmony_ci 21354568cb3Sopenharmony_ciS32 OsVfsUmount(const char *target) 21454568cb3Sopenharmony_ci{ 21554568cb3Sopenharmony_ci struct TagMountPoint *mp = NULL; 21654568cb3Sopenharmony_ci const char *pathInMp = NULL; 21754568cb3Sopenharmony_ci S32 ret = FS_NOK; 21854568cb3Sopenharmony_ci 21954568cb3Sopenharmony_ci if (target == NULL) { 22054568cb3Sopenharmony_ci return ret; 22154568cb3Sopenharmony_ci } 22254568cb3Sopenharmony_ci 22354568cb3Sopenharmony_ci (void)OsVfsLock(); 22454568cb3Sopenharmony_ci mp = OsVfsFindMp(target, &pathInMp); 22554568cb3Sopenharmony_ci if ((mp == NULL) || (mp->mRefs != 0) || 22654568cb3Sopenharmony_ci (mp->mFs == NULL) || (mp->mFs->fsMops == NULL) || 22754568cb3Sopenharmony_ci (mp->mFs->fsMops->umount == NULL)) { 22854568cb3Sopenharmony_ci OsVfsUnlock(); 22954568cb3Sopenharmony_ci return ret; 23054568cb3Sopenharmony_ci } 23154568cb3Sopenharmony_ci 23254568cb3Sopenharmony_ci ret = mp->mFs->fsMops->umount(mp); 23354568cb3Sopenharmony_ci if (ret != 0) { 23454568cb3Sopenharmony_ci OsVfsUnlock(); 23554568cb3Sopenharmony_ci return ret; 23654568cb3Sopenharmony_ci } 23754568cb3Sopenharmony_ci 23854568cb3Sopenharmony_ci OsMpDeleteFromList(mp); 23954568cb3Sopenharmony_ci mp->mFs->fsRefs--; 24054568cb3Sopenharmony_ci free((void *)mp->mPath); 24154568cb3Sopenharmony_ci free((void *)mp->mDev); 24254568cb3Sopenharmony_ci free(mp); 24354568cb3Sopenharmony_ci 24454568cb3Sopenharmony_ci OsVfsUnlock(); 24554568cb3Sopenharmony_ci return FS_OK; 24654568cb3Sopenharmony_ci} 24754568cb3Sopenharmony_ci 24854568cb3Sopenharmony_cistatic void OsCloseFdsInMp(struct TagMountPoint *mp) 24954568cb3Sopenharmony_ci{ 25054568cb3Sopenharmony_ci for (S32 fd = 0; fd < NR_OPEN_DEFAULT; fd++) { 25154568cb3Sopenharmony_ci struct TagFile *f = OsFdToFile(fd); 25254568cb3Sopenharmony_ci if (f == NULL) { 25354568cb3Sopenharmony_ci continue; 25454568cb3Sopenharmony_ci } 25554568cb3Sopenharmony_ci if ((f->fMp == mp) && 25654568cb3Sopenharmony_ci (f->fFops != NULL) && 25754568cb3Sopenharmony_ci (f->fFops->close != NULL)) { 25854568cb3Sopenharmony_ci (void)f->fFops->close(f); 25954568cb3Sopenharmony_ci } 26054568cb3Sopenharmony_ci } 26154568cb3Sopenharmony_ci} 26254568cb3Sopenharmony_ciS32 OsVfsUmount2(const char *target, S32 flag) 26354568cb3Sopenharmony_ci{ 26454568cb3Sopenharmony_ci struct TagMountPoint *mp = NULL; 26554568cb3Sopenharmony_ci const char *pathInMp = NULL; 26654568cb3Sopenharmony_ci S32 ret = FS_NOK; 26754568cb3Sopenharmony_ci 26854568cb3Sopenharmony_ci if (target == NULL) { 26954568cb3Sopenharmony_ci return ret; 27054568cb3Sopenharmony_ci } 27154568cb3Sopenharmony_ci 27254568cb3Sopenharmony_ci (void)OsVfsLock(); 27354568cb3Sopenharmony_ci mp = OsVfsFindMp(target, &pathInMp); 27454568cb3Sopenharmony_ci if ((mp == NULL) || (mp->mRefs != 0) || 27554568cb3Sopenharmony_ci (mp->mFs == NULL) || (mp->mFs->fsMops == NULL) || 27654568cb3Sopenharmony_ci (mp->mFs->fsMops->umount2 == NULL)) { 27754568cb3Sopenharmony_ci OsVfsUnlock(); 27854568cb3Sopenharmony_ci return ret; 27954568cb3Sopenharmony_ci } 28054568cb3Sopenharmony_ci 28154568cb3Sopenharmony_ci /* 关闭当前挂载节点下的所有文件 */ 28254568cb3Sopenharmony_ci if ((U32)flag & MNT_FORCE) { 28354568cb3Sopenharmony_ci OsCloseFdsInMp(mp); 28454568cb3Sopenharmony_ci } 28554568cb3Sopenharmony_ci 28654568cb3Sopenharmony_ci ret = mp->mFs->fsMops->umount2(mp, flag); 28754568cb3Sopenharmony_ci if (ret != 0) { 28854568cb3Sopenharmony_ci OsVfsUnlock(); 28954568cb3Sopenharmony_ci return FS_NOK; 29054568cb3Sopenharmony_ci } 29154568cb3Sopenharmony_ci 29254568cb3Sopenharmony_ci OsMpDeleteFromList(mp); 29354568cb3Sopenharmony_ci mp->mFs->fsRefs--; 29454568cb3Sopenharmony_ci free((void *)mp->mPath); 29554568cb3Sopenharmony_ci free((void *)mp->mDev); 29654568cb3Sopenharmony_ci free(mp); 29754568cb3Sopenharmony_ci 29854568cb3Sopenharmony_ci OsVfsUnlock(); 29954568cb3Sopenharmony_ci return FS_OK; 30054568cb3Sopenharmony_ci} 30154568cb3Sopenharmony_ci 302