//----------------------------------------------------------------------------- //功能: //参数: //返回: 非NULL -- 成功; // NULL -- 输入参数错误 或 文件系统类型不存在; //备注: //----------------------------------------------------------------------------- static struct FileSysType *FindFSType(const char *Type) { struct FileSysTypeInfo *Cur; struct FileSysType *Ret = NULL; char *Name; if(NULL == Type) return (NULL); Lock_MutexPend(g_ptFSTypeMutex, CN_TIMEOUT_FOREVER); if(s_ptFSTypeList) { Cur = s_ptFSTypeList; while(1) { Name = Cur->Type->Name; if(0 == strcmp(Name, Type)) { Ret = Cur->Type; break;// 找到 } else if(NULL == Cur->Next) { break;// 最后一个节点了 } Cur = Cur->Next; } } Lock_MutexPost(g_ptFSTypeMutex); return (Ret); }
static void __TelnetClientRemove(tagTelnetClient *client) { if(Lock_MutexPend(pTelnetClientSync,CN_TIMEOUT_FOREVER)) { if(client == pTelnetClientQ) { pTelnetClientQ = client->nxt; if(NULL != pTelnetClientQ) { pTelnetClientQ->pre = NULL; } } else { client->pre->nxt = client->nxt; if(NULL != client->nxt) { client->nxt->pre = client->pre; } } Lock_MutexPost(pTelnetClientSync); } return; }
//----------------------------------------------------------------------------- //功能: 设置环境变量,系统根 //参数: //返回: 0 -- 成功; -1 -- 目录无法打开; -2 -- 目录无法使用; //备注: //----------------------------------------------------------------------------- s32 SetRoot(const char *Path) { struct FileContext *FileCt; struct VCommon *FileCom; s32 Ret; struct VFile *Dir = __Open(Path, M_READ | M_DIR | M_OPEN);// 打开目录,可以起到防止文件被意外删除的效果 if(NULL == Dir) return -1; FileCt = (struct FileContext *)(Dir->Private); FileCom = FileCt->CHost; Ret = Get(&(FileCom->Obj)); if(!Ret) { Lock_MutexPend(g_ptFSTypeMutex, CN_TIMEOUT_FOREVER); // 进互斥 Put(g_tSysRoot.Obj); g_tSysRoot.Obj = &(FileCom->Obj); g_tSysRoot.VOps = Dir->VOps; Lock_MutexPost(g_ptFSTypeMutex); // 出互斥 } fclose(Dir);// 关闭文件 return (Ret); }
//----------------------------------------------------------------------------- //功能: 设置环境变量,系统当前工作路径 //参数: //返回: 0 -- 成功; -1 -- 目录无法打开; -2 -- 目录无法使用; //备注: //----------------------------------------------------------------------------- s32 SetPWD(const char *Path) { struct FileContext *FileCt; struct VCommon *FileCom; s32 Ret; struct VFile *Dir = __Open(Path, M_READ | M_DIR | M_OPEN);// 打开目录,可以起到防止文件被意外删除的效果 if(NULL == Dir) return (-1); FileCt = Dir->Private; FileCom = FileCt->CHost; Ret = Get(&(FileCom->Obj)); if(!Ret) { Lock_MutexPend(g_ptFSTypeMutex, CN_TIMEOUT_FOREVER); // 进互斥 Put(g_tSysPWD.Obj); g_tSysPWD.Obj = &(FileCom->Obj); g_tSysPWD.VOps = Dir->VOps; g_tSysPWD.Path = __PWDFixRootPath(g_tSysPWD.Obj); g_tSysPWD.FileOps = FileCt->FileOps; Lock_MutexPost(g_ptFSTypeMutex); // 出互斥 } fclose(Dir); __WorkingPath(g_pWokingPath); // 用于shell return (Ret); }
//----------------------------------------------------------------------------- //功能: 注册文件系统类型 //参数: //返回: 0 -- 成功; // -1 -- 输入参数错误; -2 -- 目标文件系统类型已存在;-3 -- 内存不足; //备注: //----------------------------------------------------------------------------- s32 RegisterFSType(struct FileSysType *NewType) { struct FileSysTypeInfo *New; if(NULL == NewType) return (-1); if(FindFSType(NewType->Name)) return (-2); New = malloc(sizeof(struct FileSysTypeInfo)); if(NULL == New) return (-3); New->Type = NewType; Lock_MutexPend(g_ptFSTypeMutex, CN_TIMEOUT_FOREVER); if(s_ptFSTypeList) { New->Next = s_ptFSTypeList->Next; s_ptFSTypeList = New; } else { New->Next = NULL; s_ptFSTypeList = New; } Lock_MutexPost(g_ptFSTypeMutex); return (0); }
//----从MultiplexSets删除对象----------------------------------------------------- //功能: MultiplexAdd的逆函数 //参数: Sets,被操作的MultiplexSets指针 // ObjectHead,被操作的Object队列头指针的指针 //返回: true=成功,false=失败。 //----------------------------------------------------------------------------- bool_t Multiplex_DelObject(struct tagMultiplexSetsCB *Sets, struct tagMultiplexObjectCB **ObjectHead) { struct tagMultiplexObjectCB *Object,*following = NULL; if ((Sets == NULL) || (ObjectHead == NULL)) return false; Lock_MutexPend(&MultiplexMutex, CN_TIMEOUT_FOREVER); Object = *ObjectHead; while (Object != NULL) { //查找被删除的对象控制块 if (Object->MySets != Sets) { following = Object; Object = Object->NextSets; } else break; } if (Object != NULL) { //下面检查被删除的Object是否已经触发, if (__ObjectIsActived(Object->PendingBit, Object->SensingBit & ~0x80000000, Object->SensingBit & 0x80000000)) { if (Sets->Actived != 0) { Sets->Actived--; if (Sets->Actived == 0) Sets->SetsActived = false; } } Sets->ObjectSum--; if (Object->NextObject != Object) { //链表中不止一个结点 Object->NextObject->PreObject = Object->PreObject; Object->PreObject->NextObject = Object->NextObject; if (Object == Sets->ObjectQ) { Sets->ObjectQ = Object->NextObject; } if (Object == Sets->ActiveQ) { Sets->ActiveQ = Object->NextObject; } } else { //链表只有一个结点 if (Object == Sets->ObjectQ) { Sets->ObjectQ = NULL; } if (Object == Sets->ActiveQ) { Sets->ActiveQ = NULL; } } if (following == NULL) { *ObjectHead = NULL; } else { following->NextObject = Object->NextObject; } Mb_Free(g_ptMultiplexObjectPool, Object); } Lock_MutexPost(&MultiplexMutex); return true; }
//----Multiplex执行------------------------------------------------------------ //功能:当MultiplexSets中的对象状态发生变化,由相关模块调用本函数告知Multiplex // 模块。 //参数: ObjectHead,被操作的Object队列头指针 // Status,Object的当前状态 //返回: true=成功,false=失败。 //----------------------------------------------------------------------------- bool_t Multiplex_Set(struct tagMultiplexObjectCB *ObjectHead, u32 Status) { struct tagMultiplexObjectCB *Object; struct tagMultiplexSetsCB *Sets; u32 Sensing, Type; u32 OldPend; if (ObjectHead == NULL) return false; Lock_MutexPend(&MultiplexMutex, CN_TIMEOUT_FOREVER); Object = ObjectHead; while (Object != NULL) { OldPend = Object->PendingBit; Sets = Object->MySets; Sensing = Object->SensingBit & ~0x80000000; Type = Object->SensingBit & 0x80000000; Object->PendingBit = Status & Sensing; //更新PendingBit if (__ObjectIsActived(OldPend, Sensing, Type)) { //调用前,Object已触发 if (!__ObjectIsActived(Object->PendingBit, Sensing, Type)) { //调用Multiplex_Set导致对象变成未触发 //把Object从Sets->ActiveQ队列拿出,放到ObjectQ队列中 __ChangeList(&(Sets->ActiveQ), &(Sets->ObjectQ), Object); if (Sets->Actived != 0) Sets->Actived--; if (Sets->Actived == 0) Sets->SetsActived = false; } } else { //调用前,Object未触发 if (__ObjectIsActived(Object->PendingBit, Sensing, Type)) { //调用Multiplex_Set导致对象被触发 //把Object从Sets->ObjectQ队列拿出,放到ActiveQ队列中 __ChangeList(&(Sets->ObjectQ), &(Sets->ActiveQ), Object); if (Sets->Actived < Sets->ObjectSum) Sets->Actived++; //异步触发模式,须释放信号量 if ((Sets->Actived >= Sets->ActiveLevel) || (Sets->Actived >= Sets->ObjectSum)) { if (false == Sets->SetsActived) { Sets->SetsActived = true; Lock_SempPost(&Sets->Lock); } } } } Object = Object->NextSets; } Lock_MutexPost(&MultiplexMutex); return true; }
//install the device as an stdout device static u32 __telnetWrite(ptu32_t tag,u8 *buf, u32 len,u32 offset, bool_t block,u32 timeout) { tagTelnetClient *client; if(Lock_MutexPend(pTelnetClientSync,CN_TIMEOUT_FOREVER)) { client = pTelnetClientQ; while(NULL != client) { sendexact(client->sock,buf,len); client = client->nxt; } Lock_MutexPost(pTelnetClientSync); } return len; }
static void __TelnetClientAdd(tagTelnetClient *client) { if(Lock_MutexPend(pTelnetClientSync,CN_TIMEOUT_FOREVER)) { if(NULL == pTelnetClientQ) { pTelnetClientQ = client; } else { pTelnetClientQ->pre = client; client->nxt = pTelnetClientQ; pTelnetClientQ= client; } Lock_MutexPost(pTelnetClientSync); } return; }
// ============================================================================= // FUNCTION:this function is used to find an register an transmit layer protocol // PARA IN: // PARA OUT: // RETURN :true success while false failed // INSTRUCT: // ============================================================================= bool_t TPL_RegisterProto(int family, int type, int protocol,tagTlayerProto *proto) { int i = 0; bool_t result = false; tagTlayerProto *tmp = NULL; if((NULL!=pTplProtoTab)&&Lock_MutexPend(pTplProtoSync,CN_TIMEOUT_FOREVER)) { //check any one existed for(i =0; i< gTplProtoNum;i++) { if((pTplProtoTab[i].af_inet == family)&&(pTplProtoTab[i].type == type)&&\ pTplProtoTab[i].protocol == protocol) { tmp = pTplProtoTab[i].proto; break; } } if(NULL == tmp) { //ok, could register it now,find an place and insert for(i =0; i< gTplProtoNum;i++) { if(NULL == pTplProtoTab[i].proto) { pTplProtoTab[i].af_inet = family; pTplProtoTab[i].type = type; pTplProtoTab[i].protocol = protocol; pTplProtoTab[i].proto = proto; result = true; break; } } } Lock_MutexPost(pTplProtoSync); } return result; }
//----------------------------------------------------------------------------- //功能: 注销文件系统类型 //参数: //返回: 0 -- 成功; // -1 -- 输入参数错误; -2 -- 文件系统类型已存在;-3 -- 目标文件系统不存在; //备注: //----------------------------------------------------------------------------- s32 UnRegisterFSType(const char *Type) { struct FileSysTypeInfo *Cur, *Pre; char *Name; if(NULL == Type) return (-1); Lock_MutexPend(g_ptFSTypeMutex, CN_TIMEOUT_FOREVER); if(!s_ptFSTypeList) { Lock_MutexPost(g_ptFSTypeMutex); return (-2); } Cur = Pre = s_ptFSTypeList; while(1) { Name = Cur->Type->Name; if(!strcmp(Name, Type)) { if(Cur == s_ptFSTypeList) s_ptFSTypeList = NULL; else Pre->Next = Cur->Next; } else { if(!Cur->Next) return (-3); Pre = Cur; Cur = Cur->Next; } } Lock_MutexPost(g_ptFSTypeMutex); free(Cur); return (0); }
// ============================================================================= // FUNCTION:this function is used to find an transmit layer proto // PARA IN: // PARA OUT: // RETURN :the proto found or NULL failed // INSTRUCT: // ============================================================================= tagTlayerProto *TPL_GetProto(int family, int type, int protocol) { int i = 0; tagTlayerProto *result = NULL; if((NULL!=pTplProtoTab)&&Lock_MutexPend(pTplProtoSync,CN_TIMEOUT_FOREVER)) { for(i =0; i< gTplProtoNum;i++) { if((pTplProtoTab[i].af_inet == family)&&(pTplProtoTab[i].type == type)&&\ pTplProtoTab[i].protocol == protocol) { result = pTplProtoTab[i].proto; break; } } Lock_MutexPost(pTplProtoSync); } return result; }
// ============================================================================= // 函数功能:TPL_GetProto // 添加一个具体的传输层协议 // 输入参数:family(域,AF_INET等) // type,(类型,SOCK_DGRAM等) // protocal,(协议号) // 输出参数: // 返回值 :family家族的type类型的第protocal个协议,NULL表示没有指定的协议 // 说明 : // ============================================================================= tagTlayerProto *TPL_GetProto(int family, int type, int protocal) { tagTlayerProto *result; tagNetRscNode *typenode; tagTplProtoRscNode *headson; tagTplProtoRscNode *temp; result = NULL; if(true == Lock_MutexPend(pgNetRscNodeSync, CN_TIMEOUT_FOREVER)) { typenode = __TPL_GetTypeNode(family, type, false); if(NULL != typenode) //找到或者创建成功了 { headson = (tagTplProtoRscNode *)Rsc_GetSon(&typenode->node); if(NULL != headson) { //看看是否有重复的,有重复的不必再添加,否则要添加 temp = headson; do{ if(temp->protocal == protocal) { result = &temp->proto; temp = headson; } else { temp = (tagTplProtoRscNode *)Rsc_GetNext(&temp->node); } }while(temp != headson); } } Lock_MutexPost(pgNetRscNodeSync); } return result; }
bool_t pthread_mutex_lock(struct MutexLCB *mutex) { return Lock_MutexPend(mutex, CN_TIMEOUT_FOREVER); }
//----------------------------------------------------------------------------- //功能: 安装一个文件系统. //参数: MountPath -- 挂载点路径; // DevPath -- 文件系统所在设备路径; // Type -- 准备挂载的文件系统类型; // Private -- 传递给安装函数; //返回: 0 -- 成功. // -1 -- 输入参数错误; -2 -- 文件系统类型不存在; // -3 -- 设备无法打开; -4 -- 挂载目录不存在; // -5 -- 文件系统无法安装进设备; // -6 -- 内存不足; //备注: //----------------------------------------------------------------------------- s32 Mount(const char *MountPath, const char *DevPath, const char *Type, void *Private) { struct FileSysType *FSType; struct MountInfo *NewMountInfo; struct VCommon *FileCom; struct FileContext *FileCt; struct DjyDevice *Dev; struct VFile *DevFp = NULL, *DirFp = NULL; s32 Ret = 0; if(!MountPath || !DevPath || !Type) return (-1); FSType = FindFSType(Type); if(!FSType) return (-2);// 目标文件系统类型尚未注册 DevFp = __Open(DevPath, M_READ | M_WRITE | M_OPEN);// 打开设备 if (!DevFp) return (-3); FileCt = (struct FileContext *)(DevFp->Private); Dev = (struct DjyDevice *)(FileCt->Private); if(Get(&Dev->Node))// 设备被用于文件系统了,从此不能该设备删除,除非文件系统卸载 { // 这个错误正常情况是不会出现的 Ret = -3; goto FAIL; } DirFp = __Open(MountPath, M_READ | M_DIR | M_OPEN);// 打开挂载点目录 if(!DirFp) { Ret = -4; goto FAIL; } // 挂载点类型校验 FileCt = (struct FileContext*)(DirFp->Private); FileCom = FileCt->CHost; if(!(FileCom->Obj.Type & OB_DIR ))// DIR已经是O_MOUNT也可以了 { Ret = -4; goto FAIL; } NewMountInfo = malloc(sizeof(struct MountInfo)); if(!NewMountInfo) { Ret = -6; goto FAIL; } NewMountInfo->Type = FSType; NewMountInfo->Dev = &(Dev->Node); Ret = FSType->Install(NewMountInfo, Private);// 挂载文件系统 if(Ret) { Ret = -5; goto FAIL; } // 初始化安装点 NewMountInfo->Mount.OldObj = FileCom->Obj.Child; NewMountInfo->Mount.Context = FileCom->Context; if(NULL == NewMountInfo->Mount.Name)// 用户可以在自己的install函数中指定,例如FAT NewMountInfo->Mount.Name = Dev->Node.Name;// 安装点名(目前研究的几个文件系统,都是已设备名作为文件系统根的区分) if(FSType->Property == MOUNT_FILE)// 当前只支持文件类型的安装 { NewMountInfo->Mount.Private = (void *)FSType->FileOps;// 文件系统的具体操作方式 NewMountInfo->Mount.Property = MOUNT_FILE; NewMountInfo->Mount.VOps = &g_tFOps; if(FileCom->Obj.Type & OB_MOUNT) NewMountInfo->Mount.Property |= MOUNT_ON_MOUNT; else NewMountInfo->Mount.Property |= MOUNT_ON_DIR; Lock_MutexPend(g_ptVFMutex, CN_TIMEOUT_FOREVER); FileCom->Context = &(NewMountInfo->Mount);// File的上下文重新设置为新的Mount FileCom->Obj.Type |= OB_MOUNT; FileCom->Obj.Child = NULL; Lock_MutexPost(g_ptVFMutex); Lock_MutexPend(g_ptFSTypeMutex, CN_TIMEOUT_FOREVER); if(FSType->MountList)// 新的挂载信息链入 { NewMountInfo->Next = FSType->MountList; FSType->MountList = NewMountInfo; } else { FSType->MountList = NewMountInfo;// 链表的第一个 NewMountInfo->Next = NULL; } Lock_MutexPost(g_ptFSTypeMutex); } FAIL: if(DirFp) fclose(DirFp); if(DevFp) fclose(DevFp); return (Ret); }
// ============================================================================= // 函数功能:等待一个信号量 // 输入参数: // 输出参数: // 返回值 : // 会阻塞在此,直到有信号到来 // ============================================================================= void XMutexWait(struct tagMutexLCB *mutex) { Lock_MutexPend(mutex,CN_TIMEOUT_FOREVER); }
// ============================================================================= // 函数功能:TPL_RegisterProto // 添加一个具体的传输层协议 // 输入参数:family(域,AF_INET等) // type,(类型,SOCK_DGRAM等) // protocal,(协议号) // proto,具体的传输层协议 // 输出参数: // 返回值 :注册成功的资源树节点,NULL表示注册不成功(空间不足) // 说明 :如果没有对应的FAMILY和TYPE则会创建对应的FAMILY或者TYPE // ============================================================================= tagTplProtoRscNode* TPL_RegisterProto(int family, int type, int protocal,\ tagTlayerProto *proto) { tagTplProtoRscNode *result = NULL; tagNetRscNode *typenode = NULL; tagTplProtoRscNode *headson = NULL; tagTplProtoRscNode *temp = NULL; if((NULL != proto)&&(NULL != pgNetRscNodeTree)) { if(true == Lock_MutexPend(pgNetRscNodeSync, CN_TIMEOUT_FOREVER)) { typenode = __TPL_GetTypeNode(family, type, true); if(NULL != typenode) //找到或者创建成功了 { headson = (tagTplProtoRscNode *)Rsc_GetSon(&typenode->node); if(NULL == headson) { //现在的type下还没有节点,则完全可以建立新的 result = M_Malloc(sizeof(tagTplProtoRscNode), CN_TIMEOUT_FOREVER); if(NULL != result) { result->protocal = protocal; result->proto = *proto; Rsc_AddSon(&typenode->node, &result->node,\ sizeof(tagTplProtoRscNode),RSC_RSCNODE,NULL); } } else { //看看是否有重复的,有重复的不必再添加,否则要添加 temp = headson; do{ if(temp->protocal == protocal) { result = temp; temp = headson; } else { temp = (tagTplProtoRscNode *)Rsc_GetNext(&temp->node); } }while(temp != headson); if(result != NULL) //已经有存在的 { result = NULL; } else { //没有protocal的节点,建立 result = M_Malloc(sizeof(tagTplProtoRscNode), CN_TIMEOUT_FOREVER); if(NULL != result) { result->protocal = protocal; result->proto = *proto; Rsc_AddSon(&typenode->node, &result->node,\ sizeof(tagTplProtoRscNode),RSC_RSCNODE,NULL); } } } } Lock_MutexPost(pgNetRscNodeSync); } } return result; }
//----添加对象到MultiplexSets-------------------------------------------------- //功能: MultiplexSets中添加一个对象。如果该Object的初始状态是已经触发,则加入到 // ActiveQ队列,否则加入ObjectQ队列。 //参数: Sets,被操作的MultiplexSets指针 // ObjectHead,被操作的Object队列头指针的指针,*ObjectHead=NULL表示该对象尚 // 未加入任何MultiplexSets,因此,*ObjectHead初始化值应该是NULL。Object // 允许加入多个MultiplexSets,每加入一个MultiplexSets,将增加一个 // struct tagMultiplexObjectCB *类型的结点,所有结点的NextSets指针连接 // 成一个单向链表,*ObjectHead指向该链表头。*ObjectHead再也不允许在外部 // 修改,否则结果不可预料。 // ObjectStatus,加入时的状态,31bit的位元组,bit31无效 // ObjectID,被Multiplex的对象的ID。 // SensingBit,对象敏感位标志,31个bit,设为1表示本对象对这个bit标志敏感 // bit31表示敏感类型,CN_SENSINGBIT_AND,或者CN_SENSINGBIT_OR //返回: true=成功,false=失败。 //----------------------------------------------------------------------------- bool_t Multiplex_AddObject(struct tagMultiplexSetsCB *Sets, struct tagMultiplexObjectCB **ObjectHead, u32 ObjectStatus, ptu32_t ObjectID, u32 SensingBit) { struct tagMultiplexObjectCB *temp; struct tagMultiplexObjectCB **TargetQ; bool_t repeat = false; u32 ActivedInc = 0; if (Sets == NULL) return false; ObjectStatus &= ~0x80000000; //下面检查新加入的Object是否已经触发,以决定加入到MultiplexSets的哪个队列中 if (__ObjectIsActived(ObjectStatus, SensingBit & ~0x80000000, SensingBit & 0x80000000)) { TargetQ = &Sets->ActiveQ; ActivedInc = 1; } else TargetQ = &Sets->ObjectQ; Lock_MutexPend(&MultiplexMutex, CN_TIMEOUT_FOREVER); temp = *ObjectHead; //循环检查一个Object是否重复加入同一个MultiplexSets //如果ObjectHead=NULL,检查结果是不重复,后续处理能够正确运行。 while (temp != NULL) { if (temp->MySets != Sets) temp = temp->NextSets; else { repeat = true; break; } } Lock_MutexPost(&MultiplexMutex); if (repeat == false) { temp = Mb_Malloc(g_ptMultiplexObjectPool, CN_TIMEOUT_FOREVER); if (temp != NULL) { Sets->ObjectSum++; temp->SensingBit = SensingBit; temp->PendingBit = ObjectStatus; temp->ObjectID = ObjectID; Lock_MutexPend(&MultiplexMutex, CN_TIMEOUT_FOREVER); temp->MySets = Sets; //设定对象所属MultiplexSets //同一个MultiplexSets包含多个对象,NextObject把这些对象链接起来。 if (*TargetQ == NULL) { *TargetQ = temp; temp->NextObject = temp; temp->PreObject = temp; } else { //新加入MultiplexSets的对象插入队列头部 temp->PreObject = (*TargetQ)->PreObject; temp->NextObject = *TargetQ; (*TargetQ)->PreObject->NextObject = temp; (*TargetQ)->PreObject = temp; (*TargetQ) = temp; } //同一个对象被多个MultiplexSets包含,用NextSets链接。 //NextSets是单向链表,新对象插入链表头部 temp->NextSets = *ObjectHead; *ObjectHead = temp; Lock_MutexPost(&MultiplexMutex); if (ActivedInc == 1) { Sets->Actived += ActivedInc; if ((Sets->Actived >= Sets->ActiveLevel) || (Sets->Actived >= Sets->ObjectSum)) { if (false == Sets->SetsActived) { Sets->SetsActived = true; Lock_SempPost(&Sets->Lock); } } } } else return false; } else { //重复加入,无须做任何处理 } return true; }
//----------------------------------------------------------------------------- //功能: //参数: //返回: -1 -- 安装点不存在; -2 -- 文件系统尚有文件被使用; // -3 -- 严重错误,不在安装信息不在链表; // -4 -- 设备信息错误。 //备注: 当前只支持安装点路径卸载 //----------------------------------------------------------------------------- s32 Unmount(const char *Path) { struct VFile *Fp; struct VCommon *FileCom; struct FileContext *FileCt; struct VMount *Mount; struct FileSysType *FSType; struct MountInfo *Temp; struct MountInfo *MountInfo; s32 Ret = 0; Fp = __Open(Path, M_READ | M_DIR | M_OPEN); if(!Fp) return -1; FileCt = (struct FileContext*)Fp->Private; FileCom = FileCt->CHost; if(!(FileCom->Obj.Type & OB_MOUNT))// 类型校验 { Ret = -1; goto FAIL; } if(FileCom->Obj.Child == NULL) { Mount = (struct VMount*)FileCom->Context; Lock_MutexPend(g_ptVFMutex, CN_TIMEOUT_FOREVER); FileCom->Obj.Child = Mount->OldObj;// 恢复原文件系统下的内容 FileCom->Context = Mount->Context; if(Mount->Property == MOUNT_ON_DIR) FileCom->Obj.Type &= (~OB_MOUNT);// 没有后续MOUNT Lock_MutexPost(g_ptVFMutex); } else { Ret = -2; goto FAIL;// 文件系统下有文件仍在使用中 } MountInfo = Container(Mount, struct MountInfo, Mount); FSType = MountInfo->Type; // 将当前安装点从它所属的文件系统类型的链表上删除 Lock_MutexPend(g_ptFSTypeMutex, CN_TIMEOUT_FOREVER); Temp = FSType->MountList; if(MountInfo == Temp) FSType->MountList = MountInfo->Next;// 第一个 else { while((Temp->Next) && (Temp->Next != MountInfo)) Temp = Temp->Next; if(Temp->Next) Temp->Next = MountInfo->Next; else// 遍历到最后一个都为发现本安装点信息,肯定是系统有问题了,但是先不释放本结构 { Ret = -3; Lock_MutexPost(g_ptFSTypeMutex); goto FAIL; } } Lock_MutexPost(g_ptFSTypeMutex); if(FSType->Uninstall(MountInfo->Private)) return (-4); Put(MountInfo->Dev); free(MountInfo); FAIL: if(Fp) fclose(Fp); return (Ret); }