diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index 730d982b16f1d8c59b4a1c4400ebb87cbac4aeff..d15a4af7435e307dcb63723f918fccfe49bcb3a6 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -787,6 +787,13 @@ struct files_struct *alloc_files(void) (VOID)LOS_MemFree(m_aucSysMem0, files); return NULL; } +#ifdef LOSCFG_CHROOT + if (VnodeGetRoot() != NULL) + { + VnodeGetRoot()->useCount++; + } + files->rootVnode = VnodeGetRoot(); +#endif return files; } @@ -824,6 +831,13 @@ struct files_struct *dup_fd(struct files_struct *old_files) } copy_fd_table(new_fdt, old_fdt); files->fdt = new_fdt; +#ifdef LOSCFG_CHROOT + if (old_files->rootVnode != NULL) + { + old_files->rootVnode->useCount++; + } + files->rootVnode = old_files->rootVnode; +#endif return files; } @@ -900,6 +914,13 @@ struct files_struct *create_files_snapshot(const struct files_struct *old_files) } copy_fds((const struct fd_table_s *)new_fdt, (const struct fd_table_s *)old_fdt); files->fdt = new_fdt; +#ifdef LOSCFG_CHROOT + if (old_files->rootVnode != NULL) + { + old_files->rootVnode->useCount++; + } + files->rootVnode = old_files->rootVnode; +#endif return files; diff --git a/fs/mount/fs_mount.c b/fs/mount/fs_mount.c index 1b9e3a593f39e33b01de189da4fcdd70cadf0433..9bb96cb05a9933fada922050b33207477a6816c0 100644 --- a/fs/mount/fs_mount.c +++ b/fs/mount/fs_mount.c @@ -49,7 +49,9 @@ #ifdef LOSCFG_FS_ZPFS #include "zpfs.h" #endif - +#ifdef LOSCFG_MNT_CONTAINER +#include "los_mnt_container_pri.h" +#endif /* At least one filesystem must be defined, or this file will not compile. * It may be desire-able to make filesystems dynamically registered at @@ -206,11 +208,48 @@ int mount(const char *source, const char *target, } if (mountpt_vnode->flag & VNODE_FLAG_MOUNT_NEW) { +#ifdef LOSCFG_MNT_CONTAINER + struct Mount *tMnt = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(tMnt, GetMountList(), struct Mount, mountList) + { + if (tMnt->vnodeCovered == mountpt_vnode) + { + PRINT_ERR("can't mount to %s, already mounted.\n", target); + errcode = -EINVAL; + goto errout_with_lock; + } + } +#else PRINT_ERR("can't mount to %s, already mounted.\n", target); errcode = -EINVAL; goto errout_with_lock; +#endif } +#ifdef LOSCFG_MNT_CONTAINER + struct Mount *cacheMnt = NULL; + if (source != NULL) + { + LOS_DL_LIST_FOR_EACH_ENTRY(cacheMnt, GetMountCache(), struct Mount, mountList) + { + if (strcmp(cacheMnt->devName, source) == 0) + { + struct Mount *newMnt = (struct Mount *)zalloc(sizeof(struct Mount)); + if (newMnt == NULL) + { + PRINT_ERR("New mount alloc failed no memory!\n"); + errcode = -EINVAL; + goto errout; + } + *newMnt = *cacheMnt; + LOS_ListTailInsert(GetMountList(), &(newMnt->mountList)); + cacheMnt->vnodeCovered->mntCount++; + VnodeDrop(); + return OK; + } + } + } +#endif /* Bind the block driver to an instance of the file system. The file * system returns a reference to some opaque, fs-dependent structure * that encapsulates this binding. @@ -306,6 +345,21 @@ int mount(const char *source, const char *target, mount_list = GetMountList(); LOS_ListAdd(mount_list, &mnt->mountList); +#ifdef LOSCFG_MNT_CONTAINER + if (source != NULL) + { + struct Mount *newMnt = (struct Mount *)zalloc(sizeof(struct Mount)); + if (newMnt == NULL) + { + PRINT_ERR("New mount alloc failed no memory!\n"); + errcode = -EINVAL; + goto errout; + } + *newMnt = *mnt; + LOS_ListTailInsert(GetMountCache(), &(newMnt->mountList)); + } +#endif + if (!strcmp("/", target)) { ChangeRoot(mnt->vnodeCovered); diff --git a/fs/mount/fs_umount.c b/fs/mount/fs_umount.c index 261a62c2601067731c9e30fc70021f55907a92de..ec50d203daa0d43c1b5dc5e52d0133ba9992e4ed 100644 --- a/fs/mount/fs_umount.c +++ b/fs/mount/fs_umount.c @@ -47,6 +47,9 @@ #include "string.h" #include "disk.h" #include "fs/mount.h" +#ifdef LOSCFG_MNT_CONTAINER +#include "los_mnt_container_pri.h" +#endif /**************************************************************************** * Public Functions @@ -114,6 +117,35 @@ int umount(const char *target) goto errout; } +#ifdef LOSCFG_MNT_CONTAINER + /* Verify that the vnode is a mountpoint */ + struct Mount *tMnt = NULL; + bool found = false; + LOS_DL_LIST_FOR_EACH_ENTRY(tMnt, GetMountList(), struct Mount, mountList) + { + if (tMnt->vnodeCovered == mountpt_vnode) + { + found = true; + break; + } + } + + if (!found) + { + ret = -EINVAL; + goto errout; + } + + if (tMnt->vnodeCovered->mntCount > 0) + { + tMnt->vnodeCovered->mntCount--; + LOS_ListDelete(&tMnt->mountList); + free(tMnt); + VnodeDrop(); + return OK; + } +#endif + /* Get mount point covered vnode and mount structure */ mnt = mountpt_vnode->originMount; if (!mnt) @@ -158,9 +190,21 @@ int umount(const char *target) { goto errout; } - +#ifdef LOSCFG_MNT_CONTAINER + struct Mount *tCacheMnt = NULL; + LOS_DL_LIST_FOR_EACH_ENTRY(tCacheMnt, GetMountCache(), struct Mount, mountList) + { + if (tCacheMnt->vnodeCovered == mountpt_vnode) + { + LOS_ListDelete(&tCacheMnt->mountList); + free(tCacheMnt); + break; + } + } +#endif VnodeFree(mountpt_vnode); LOS_ListDelete(&mnt->mountList); + free(mnt); /* Did the unbind method return a contained block driver */ @@ -170,7 +214,24 @@ int umount(const char *target) } covered_vnode->newMount = NULL; +#ifdef LOSCFG_MNT_CONTAINER + tCacheMnt = NULL; + found = false; + LOS_DL_LIST_FOR_EACH_ENTRY(tCacheMnt, GetMountCache(), struct Mount, mountList) + { + if (tCacheMnt->vnodeBeCovered == covered_vnode) + { + found = true; + break; + } + } + if (!found) + { + covered_vnode->flag &= ~(VNODE_FLAG_MOUNT_ORIGIN); + } +#else covered_vnode->flag &= ~(VNODE_FLAG_MOUNT_ORIGIN); +#endif VnodeDrop(); return OK;