fix: VnodeInUseIter and VnodeFreeAll used to be recursive

Function VnodeInUseIter and VnodeFreeAll used to be recursive.
Now we traverse the current in-use vnode list to find the vnode in
1 filesystem

Close #I3NN3U
This commit is contained in:
Far 2021-04-28 14:35:29 +08:00
parent 806ce4eb26
commit 5f6656cb36
3 changed files with 29 additions and 79 deletions

View File

@ -111,15 +111,14 @@ int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags);
int VnodeHold(void); int VnodeHold(void);
int VnodeDrop(void); int VnodeDrop(void);
void VnodeRefDec(struct Vnode *vnode); void VnodeRefDec(struct Vnode *vnode);
int VnodeFreeIter(struct Vnode *vnode); int VnodeFreeAll(const struct Mount *mnt);
int VnodeFreeAll(struct Mount *mnt);
int VnodeHashInit(void); int VnodeHashInit(void);
uint32_t VfsHashIndex(struct Vnode *vnode); uint32_t VfsHashIndex(struct Vnode *vnode);
int VfsHashGet(const struct Mount *mount, uint32_t hash, struct Vnode **vnode, VfsHashCmp *fun, void *arg); int VfsHashGet(const struct Mount *mount, uint32_t hash, struct Vnode **vnode, VfsHashCmp *fun, void *arg);
void VfsHashRemove(struct Vnode *vnode); void VfsHashRemove(struct Vnode *vnode);
int VfsHashInsert(struct Vnode *vnode, uint32_t hash); int VfsHashInsert(struct Vnode *vnode, uint32_t hash);
void ChangeRoot(struct Vnode *newRoot); void ChangeRoot(struct Vnode *newRoot);
BOOL VnodeInUseIter(struct Vnode *vnode); BOOL VnodeInUseIter(const struct Mount *mount);
struct Vnode *VnodeGetRoot(void); struct Vnode *VnodeGetRoot(void);
void VnodeMemoryDump(void); void VnodeMemoryDump(void);

View File

@ -47,7 +47,6 @@ static struct VnodeOps g_devfsOps;
#define ENTRY_TO_VNODE(ptr) LOS_DL_LIST_ENTRY(ptr, struct Vnode, actFreeEntry) #define ENTRY_TO_VNODE(ptr) LOS_DL_LIST_ENTRY(ptr, struct Vnode, actFreeEntry)
#define VNODE_LRU_COUNT 10 #define VNODE_LRU_COUNT 10
#define DEV_VNODE_MODE 0755 #define DEV_VNODE_MODE 0755
#define MAX_ITER_TIMES 10
int VnodesInit(void) int VnodesInit(void)
{ {
@ -98,8 +97,8 @@ struct Vnode *VnodeReclaimLru(void)
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeCurrList, struct Vnode, actFreeEntry) { LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeCurrList, struct Vnode, actFreeEntry) {
if ((item->useCount > 0) || if ((item->useCount > 0) ||
(item->flag & VNODE_FLAG_MOUNT_NEW) || (item->flag & VNODE_FLAG_MOUNT_ORIGIN) ||
(item->flag & VNODE_FLAG_MOUNT_ORIGIN)) { (item->flag & VNODE_FLAG_MOUNT_NEW)) {
continue; continue;
} }
@ -201,83 +200,35 @@ int VnodeFree(struct Vnode *vnode)
return LOS_OK; return LOS_OK;
} }
int VnodeFreeIter(struct Vnode *vnode) int VnodeFreeAll(const struct Mount *mount)
{ {
struct Vnode *vp = NULL; struct Vnode *vnode = NULL;
struct PathCache *item = NULL; struct Vnode *nextVnode = NULL;
struct PathCache *nextItem = NULL;
int ret; int ret;
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vnode->childPathCaches, struct PathCache, childEntry) { LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(vnode, nextVnode, &g_vnodeCurrList, struct Vnode, actFreeEntry) {
vp = item->childVnode; if ((vnode->originMount == mount) && !(vnode->flag & VNODE_FLAG_MOUNT_NEW)) {
if (vp == NULL) { ret = VnodeFree(vnode);
continue; if (ret != LOS_OK) {
} return ret;
ret = VnodeFreeIter(vp); }
if (ret != LOS_OK) {
return ret;
} }
} }
return VnodeFree(vnode);
return LOS_OK;
} }
int VnodeFreeAll(struct Mount *mnt) BOOL VnodeInUseIter(const struct Mount *mount)
{ {
struct Vnode *vp = NULL; struct Vnode *vnode = NULL;
struct Vnode *mountptVnode = mnt->vnodeCovered;
struct PathCache *item = NULL;
struct PathCache *nextItem = NULL;
int ret;
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &mountptVnode->childPathCaches, struct PathCache, childEntry) { LOS_DL_LIST_FOR_EACH_ENTRY(vnode, &g_vnodeCurrList, struct Vnode, actFreeEntry) {
vp = item->childVnode; if (vnode->originMount == mount) {
if (vp == NULL) { if ((vnode->useCount > 0) || (vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) {
continue; return TRUE;
} }
ret = VnodeFreeIter(vp);
if (ret != LOS_OK) {
return ret;
} }
} }
return 0;
}
static VOID VnodeIterDump(struct Vnode *vnode, int increase)
{
static int count = 0;
LIST_ENTRY *list = &vnode->parentPathCaches;
struct PathCache *pathCache = LOS_DL_LIST_ENTRY(list->pstNext, struct PathCache, parentEntry);
count += increase;
if (count >= MAX_ITER_TIMES) {
PRINTK("########## Vnode In Use Iteration ##########\n");
PRINTK("Iteration times: %d\n", count);
PRINTK("%p -- %s --> %p\n", vnode->parent, pathCache->name, vnode);
PathCacheDump();
}
}
BOOL VnodeInUseIter(struct Vnode *vnode)
{
struct Vnode *vp = NULL;
struct PathCache *item = NULL;
struct PathCache *nextItem = NULL;
VnodeIterDump(vnode, 1);
if (vnode->useCount > 0) {
VnodeIterDump(vnode, -1);
return TRUE;
}
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &vnode->childPathCaches, struct PathCache, childEntry) {
vp = item->childVnode;
if (vp == NULL) {
continue;
}
if (VnodeInUseIter(vp) == TRUE) {
VnodeIterDump(vnode, -1);
return TRUE;
}
}
VnodeIterDump(vnode, -1);
return FALSE; return FALSE;
} }
@ -335,7 +286,7 @@ static int PreProcess(const char *originPath, struct Vnode **startVnode, char **
static struct Vnode *ConvertVnodeIfMounted(struct Vnode *vnode) static struct Vnode *ConvertVnodeIfMounted(struct Vnode *vnode)
{ {
if ((vnode == NULL) || !(vnode->flag & VNODE_FLAG_MOUNT_NEW)) { if ((vnode == NULL) || !(vnode->flag & VNODE_FLAG_MOUNT_ORIGIN)) {
return vnode; return vnode;
} }
return vnode->newMount->vnodeCovered; return vnode->newMount->vnodeCovered;
@ -487,7 +438,7 @@ static void ChangeRootInternal(struct Vnode *rootOld, char *dirname)
mnt->vnodeBeCovered = nodeInFs; mnt->vnodeBeCovered = nodeInFs;
nodeInFs->newMount = mnt; nodeInFs->newMount = mnt;
nodeInFs->flag |= VNODE_FLAG_MOUNT_NEW; nodeInFs->flag |= VNODE_FLAG_MOUNT_ORIGIN;
break; break;
} }
@ -600,7 +551,7 @@ int VnodeDevInit()
return -ENOMEM; return -ENOMEM;
} }
devMount->vnodeCovered = devNode; devMount->vnodeCovered = devNode;
devMount->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_NEW; devMount->vnodeBeCovered->flag |= VNODE_FLAG_MOUNT_ORIGIN;
return LOS_OK; return LOS_OK;
} }
@ -668,8 +619,8 @@ void VnodeMemoryDump(void)
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeCurrList, struct Vnode, actFreeEntry) { LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_vnodeCurrList, struct Vnode, actFreeEntry) {
if ((item->useCount > 0) || if ((item->useCount > 0) ||
(item->flag & VNODE_FLAG_MOUNT_NEW) || (item->flag & VNODE_FLAG_MOUNT_ORIGIN) ||
(item->flag & VNODE_FLAG_MOUNT_ORIGIN)) { (item->flag & VNODE_FLAG_MOUNT_NEW)) {
continue; continue;
} }
@ -678,4 +629,4 @@ void VnodeMemoryDump(void)
PRINTK("Vnode number = %d\n", vnodeCount); PRINTK("Vnode number = %d\n", vnodeCount);
PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode)); PRINTK("Vnode memory size = %d(B)\n", vnodeCount * sizeof(struct Vnode));
} }

View File

@ -134,4 +134,4 @@ int VfsHashInsert(struct Vnode *vnode, uint32_t hash)
LOS_ListHeadInsert(VfsHashBucket(vnode->originMount, hash), &vnode->hashEntry); LOS_ListHeadInsert(VfsHashBucket(vnode->originMount, hash), &vnode->hashEntry);
(void)LOS_MuxUnlock(&g_vnodeHashMux); (void)LOS_MuxUnlock(&g_vnodeHashMux);
return LOS_OK; return LOS_OK;
} }