| 2957 | /* get the first Mcb record in Vcb->McbList */ |
| 2958 | |
| 2959 | PEXT2_MCB |
| 2960 | Ext2FirstUnusedMcb(PEXT2_VCB Vcb, BOOLEAN Wait, ULONG Number) |
| 2961 | { |
| 2962 | PEXT2_MCB Head = NULL; |
| 2963 | PEXT2_MCB Tail = NULL; |
| 2964 | PEXT2_MCB Mcb = NULL; |
| 2965 | PLIST_ENTRY List = NULL; |
| 2966 | ULONG i = 0; |
| 2967 | LARGE_INTEGER start, now; |
| 2968 | |
| 2969 | if (!ExAcquireResourceExclusiveLite(&Vcb->McbLock, Wait)) { |
| 2970 | return NULL; |
| 2971 | } |
| 2972 | |
| 2973 | KeQuerySystemTime(&start); |
| 2974 | |
| 2975 | while (Number--) { |
| 2976 | |
| 2977 | BOOLEAN Skip = TRUE; |
| 2978 | |
| 2979 | if (IsListEmpty(&Vcb->McbList)) { |
| 2980 | break; |
| 2981 | } |
| 2982 | |
| 2983 | while (i++ < Vcb->NumOfMcb) { |
| 2984 | |
| 2985 | KeQuerySystemTime(&now); |
| 2986 | if (now.QuadPart > start.QuadPart + (LONGLONG)10*1000*1000) { |
| 2987 | break; |
| 2988 | } |
| 2989 | |
| 2990 | List = RemoveHeadList(&Vcb->McbList); |
| 2991 | Mcb = CONTAINING_RECORD(List, EXT2_MCB, Link); |
| 2992 | ASSERT(IsFlagOn(Mcb->Flags, MCB_VCB_LINK)); |
| 2993 | |
| 2994 | if (Mcb->Fcb == NULL && !IsMcbRoot(Mcb) && |
| 2995 | Mcb->Refercount == 0 && |
| 2996 | (Mcb->Child == NULL || IsMcbSymLink(Mcb))) { |
| 2997 | |
| 2998 | Ext2RemoveMcb(Vcb, Mcb); |
| 2999 | ClearLongFlag(Mcb->Flags, MCB_VCB_LINK); |
| 3000 | Ext2DerefXcb(&Vcb->NumOfMcb); |
| 3001 | |
| 3002 | /* attach all Mcb into a chain*/ |
| 3003 | if (Head) { |
| 3004 | ASSERT(Tail != NULL); |
| 3005 | Tail->Next = Mcb; |
| 3006 | Tail = Mcb; |
| 3007 | } else { |
| 3008 | Head = Tail = Mcb; |
| 3009 | } |
| 3010 | Tail->Next = NULL; |
| 3011 | Skip = FALSE; |
| 3012 | |
| 3013 | } else { |
| 3014 | |
| 3015 | InsertTailList(&Vcb->McbList, &Mcb->Link); |
| 3016 | Mcb = NULL; |
no test coverage detected