diff --git a/components/fs/vfs/vfs_files.h b/components/fs/vfs/vfs_files.h index 180aedbf37b59bfe1ddfd4c5060bd72faa3c6c35..416b5f289d5558d3c7d1c543e5a2fae7347f18f7 100644 --- a/components/fs/vfs/vfs_files.h +++ b/components/fs/vfs/vfs_files.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -35,6 +35,7 @@ #include "sys/stat.h" #include "unistd.h" #include "los_compiler.h" +#include "los_list.h" #ifdef __cplusplus #if __cplusplus @@ -87,6 +88,7 @@ struct Dir { struct dirent dDent; off_t dOffset; void *dData; + LOS_DL_LIST dirNode; }; int FileToFd(const struct File *file); @@ -94,6 +96,7 @@ struct File *FdToFile(int fd); struct File *VfsFileGet(void); struct File *VfsFileGetSpec(int fd); void VfsFilePut(struct File *file); +void CloseDirInMp(struct MountPoint *mp); #ifdef __cplusplus #if __cplusplus diff --git a/components/fs/vfs/vfs_fs.c b/components/fs/vfs/vfs_fs.c index 2fa1fdfe8836e98b5fdd5db3b876e3edce8697cf..44dc0a22ac5361bed57ad67585c8cf840fec312f 100644 --- a/components/fs/vfs/vfs_fs.c +++ b/components/fs/vfs/vfs_fs.c @@ -93,6 +93,26 @@ int PollQueryFd(int fd, struct PollTable *table) UINT32 g_fsMutex; static UINT32 g_dirNum = 0; +void CloseDirInMp(struct MountPoint *mp) +{ + struct Dir *node = NULL; + + while (mp->dirList.pstNext != &mp->dirList) { + node = LOS_DL_LIST_ENTRY(mp->dirList.pstNext, struct Dir, dirNode); + + // the node will not be empty and the node is found in mp, mp will not be empty + if ((node->dMp->mFs != NULL) && (node->dMp->mFs->fsFops != NULL) && + (node->dMp->mFs->fsFops->closedir != NULL)) { + (void)node->dMp->mFs->fsFops->closedir(node); + } + + LOS_ListDelete(mp->dirList.pstNext); + LOSCFG_FS_FREE_HOOK(node); + mp->mRefs--; + g_dirNum--; + } +} + int LOS_FsLock(void) { if (!OsCheckKernelRunning()) { @@ -932,6 +952,7 @@ DIR *opendir(const char *path) if (ret == 0) { mp->mRefs++; g_dirNum++; + LOS_ListAdd(&mp->dirList, &dir->dirNode); } else { LOSCFG_FS_FREE_HOOK(dir); dir = NULL; @@ -998,6 +1019,7 @@ int closedir(DIR *dir) if (ret == 0) { mp->mRefs--; g_dirNum--; + LOS_ListDelete(&d->dirNode); } else { VFS_ERRNO_SET(EBADF); } diff --git a/components/fs/vfs/vfs_mount.c b/components/fs/vfs/vfs_mount.c index d6821b1a69d4475dc60cd2fdfe177ea59cd3e899..01d4cad2a5d166579e323c1a684e4c69036ff2d9 100644 --- a/components/fs/vfs/vfs_mount.c +++ b/components/fs/vfs/vfs_mount.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -295,6 +295,8 @@ int mount(const char *source, const char *target, goto errout; } + LOS_ListInit(&mp->dirList); + mp->mNext = g_mountPoints; g_mountPoints = mp; LOS_FsUnlock(); @@ -346,18 +348,19 @@ errout: return (int)LOS_NOK; } -static void CloseFdsInMp(const struct MountPoint *mp) +static void CloseFdsInMp(struct MountPoint *mp) { for (int fd = 0; fd < NR_OPEN_DEFAULT; fd++) { struct File *f = FdToFile(fd); - if (f == NULL) { + if ((f == NULL) || (f->fMp != mp)) { continue; } - if ((f->fMp == mp) && - (f->fFops != NULL) && + if ((f->fFops != NULL) && (f->fFops->close != NULL)) { (void)f->fFops->close(f); } + mp->mRefs--; + VfsFilePut(f); } } @@ -372,15 +375,19 @@ int umount2(const char *target, int flag) } mp = VfsMpFind(target, NULL); - if ((mp == NULL) || (mp->mRefs != 0) || - (mp->mFs == NULL) || (mp->mFs->fsMops == NULL) || + if ((mp == NULL) || (mp->mFs == NULL) || + (mp->mFs->fsMops == NULL) || (mp->mFs->fsMops->umount2 == NULL)) { goto errout; } - /* Close all files under the mount point */ - if ((UINT32)flag & MNT_FORCE) { + if (mp->mRefs != 0) { + if (((UINT32)flag & MNT_FORCE) == 0) { + goto errout; + } + CloseFdsInMp(mp); + CloseDirInMp(mp); } ret = mp->mFs->fsMops->umount2(mp, flag); diff --git a/components/fs/vfs/vfs_mount.h b/components/fs/vfs/vfs_mount.h index 5507141d9742b200dd2dd260d5c03ff243b3f779..3ad607ce8511c3b9bf636c7e7964011eef02bab6 100644 --- a/components/fs/vfs/vfs_mount.h +++ b/components/fs/vfs/vfs_mount.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -33,6 +33,7 @@ #include "sys/statfs.h" #include "los_compiler.h" +#include "los_list.h" #ifdef __cplusplus #if __cplusplus @@ -59,6 +60,7 @@ struct MountPoint { UINT32 mRefs; /* reference to mount point */ void *mData; /* specific file system handle */ BOOL mWriteEnable; /* writable flag */ + LOS_DL_LIST dirList; }; extern struct MountPoint *g_mountPoints;