From 38f7079f43d66fd41614aa11bc6afcabdf44ca03 Mon Sep 17 00:00:00 2001 From: wangchen Date: Tue, 25 Apr 2023 16:20:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20umount2=E5=87=BD=E6=95=B0=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=BC=BA=E5=88=B6=E5=85=B3=E9=97=AD=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 方案描述: 1, 增加DIR链表管理 2,umount2时遍历关闭mp下的fd和dir fix #I6V3HQ Signed-off-by: wangchen --- components/fs/vfs/vfs_files.h | 5 ++++- components/fs/vfs/vfs_fs.c | 22 ++++++++++++++++++++++ components/fs/vfs/vfs_mount.c | 25 ++++++++++++++++--------- components/fs/vfs/vfs_mount.h | 4 +++- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/components/fs/vfs/vfs_files.h b/components/fs/vfs/vfs_files.h index 180aedbf..416b5f28 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 2fa1fdfe..44dc0a22 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 d6821b1a..01d4cad2 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 5507141d..3ad607ce 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;