From fd478cae4787d7b462a2a85c4e9fb967c2039933 Mon Sep 17 00:00:00 2001 From: wangchen Date: Wed, 12 Apr 2023 17:23:34 +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 | 2 ++ components/fs/vfs/vfs_fs.c | 53 +++++++++++++++++++++++++++++++++++ components/fs/vfs/vfs_mount.c | 24 ++++++++++------ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/components/fs/vfs/vfs_files.h b/components/fs/vfs/vfs_files.h index 180aedbf..759af178 100644 --- a/components/fs/vfs/vfs_files.h +++ b/components/fs/vfs/vfs_files.h @@ -87,6 +87,7 @@ struct Dir { struct dirent dDent; off_t dOffset; void *dData; + struct Dir *next; }; int FileToFd(const struct File *file); @@ -94,6 +95,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..0a84f1a2 100644 --- a/components/fs/vfs/vfs_fs.c +++ b/components/fs/vfs/vfs_fs.c @@ -93,6 +93,57 @@ int PollQueryFd(int fd, struct PollTable *table) UINT32 g_fsMutex; static UINT32 g_dirNum = 0; +static struct Dir *g_dirs = NULL; + +static void AddToDirList(struct Dir *d) +{ + d->next = g_dirs; + g_dirs = d; +} + +static void DelFromDirList(struct Dir *d) +{ + struct Dir *node = g_dirs; + + if (d == g_dirs) { + g_dirs = d->next; + return; + } + + while (node->next != d) { + node = node->next; + } + + node->next = d->next; +} + +void CloseDirInMp(struct MountPoint *mp) +{ + struct Dir *node = g_dirs; + struct Dir *tmp = node; + + while (node != NULL) { + if (node->dMp != mp) { + tmp = node; + node = node->next; + continue; + } + + tmp->next = node->next; + if ((node->dMp->mFs != NULL) && (node->dMp->mFs->fsFops != NULL) && + (node->dMp->mFs->fsFops->closedir != NULL)) { + (void)node->dMp->mFs->fsFops->closedir(node); + } + + LOSCFG_FS_FREE_HOOK(node); + mp->mRefs--; + g_dirNum--; + node = tmp->next; + } + + g_dirs = NULL; +} + int LOS_FsLock(void) { if (!OsCheckKernelRunning()) { @@ -932,6 +983,7 @@ DIR *opendir(const char *path) if (ret == 0) { mp->mRefs++; g_dirNum++; + AddToDirList(dir); } else { LOSCFG_FS_FREE_HOOK(dir); dir = NULL; @@ -998,6 +1050,7 @@ int closedir(DIR *dir) if (ret == 0) { mp->mRefs--; g_dirNum--; + DelFromDirList(d); } else { VFS_ERRNO_SET(EBADF); } diff --git a/components/fs/vfs/vfs_mount.c b/components/fs/vfs/vfs_mount.c index d6821b1a..2be0880a 100644 --- a/components/fs/vfs/vfs_mount.c +++ b/components/fs/vfs/vfs_mount.c @@ -346,18 +346,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 +373,20 @@ 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) { - CloseFdsInMp(mp); + if (mp->mRefs != 0) { + if ((UINT32)flag & MNT_FORCE) { + CloseFdsInMp(mp); + CloseDirInMp(mp); + LOS_ASSERT(mp->mRefs == 0); + } else { + goto errout; + } } ret = mp->mFs->fsMops->umount2(mp, flag);