📄 dosfsfat.c
字号:
} if ( (startClust < pFileHdl->contigEndPlus1) && (startClust >= pFileHdl->startClust) ) { /* in contiguous area */ cluster = startClust + numClusts; /* lastClust + 1 */ /* numClusts can be avoided in the function calls and changed * to pFatDesc->fatGroupSize inside the function */ if (cluster >= pFileHdl->contigEndPlus1) { cluster = pFileHdl->contigEndPlus1; /* lastClust + 1 */ nextClust = pFatDesc->dos_fat_eof; } else nextClust = cluster; DBG_MSG (2, "Get from contiguous area.\n", 1,2,3,4,5,6); } else { /* out of contiguous area */ /* Count number of contiguous clusters starting from <startClust> */ maxClust = startClust + numClusts; if (maxClust > pFatDesc->nFatEnts) maxClust = pFatDesc->nFatEnts; cluster = startClust; /* initialize cluster number */ while (cluster < maxClust) { nextClust = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, cluster); /* follow chain */ if (nextClust != ++cluster) break; /* end of contiguous area */ } if (pFatHdl->errCode == FAT_CBIO_ERR) return ERROR; }#ifdef __unused assert ( ((nextClust >= DOS_MIN_CLUST)&& (nextClust < pFatDesc->nFatEnts)) || ((nextClust > pFatDesc->dos_fat_bad) && (nextClust <= pFatDesc->dos_fat_eof)) );#endif /* Store contents of last entry in contiguous section */ pFatHdl->nextClust = nextClust; pFatHdl->lastClust = cluster - 1; pFd->curSec = CLUST_TO_SEC (pVolDesc, startClust); pFd->nSec = (cluster - startClust) * pVolDesc->secPerClust; DBG_MSG (2, "Get %ld clusters starting from cluster %ld\n", cluster - startClust, startClust,3,4,5,6); return OK; } /* fat16ContigGet *//********************************************************************************* fat16MarkAlloc - allocate a contiguous set of clusters*** RETURNS: ERROR if was unable to allocate requested amount of space*/LOCAL STATUS fat16MarkAlloc ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t firstClust, /* initial cluster to search */ FAST uint32_t numClusts /* number of clusters needed */ ) { FAST MS_FAT_DESC_ID pFatDesc = (void *) pFd->pVolDesc->pFatDesc; /* pointer to FAT descriptor */ FAST uint32_t curClust; /* current cluster number */ assert ((firstClust >= DOS_MIN_CLUST) && (firstClust < pFatDesc->nFatEnts)); assert (numClusts <= (pFatDesc->nFatEnts - DOS_MIN_CLUST)); /* Build cluster chain in FAT */ for (curClust = firstClust; curClust < (firstClust + numClusts - 1); curClust++) { /* Each entry = next clust. num. */ if (ENTRY_WRITE (pFd, pFatDesc->dosFatDesc.activeCopyNum, curClust, curClust + 1) != OK) return ERROR; /* disk access error */ /* Update free clusters counter */ pFatDesc->fatEntFreeCnt--; } /* Mark last entry as end of file cluster chain */ if (ENTRY_WRITE (pFd, pFatDesc->dosFatDesc.activeCopyNum, curClust, pFatDesc->dos_fat_eof) != OK) return ERROR; /* disk access error */ pFatDesc->fatEntFreeCnt--; return OK; } /* fat16MarkAlloc *//********************************************************************************* fat16GetNext - get/allocate next cluster for file** This routine searches the File Allocation Table (FAT) for a sequence* of contiguous free clusters, and allocates clusters to extend the* current chain if requested to do so.** RETURNS: resulting chain of sectors in the File Descriptor structure.*/LOCAL STATUS fat16GetNext ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint_t allocPolicy /* allocation policy */ ) { FAST DOS_FILE_HDL_ID pFileHdl = pFd->pFileHdl; /* pointer to file handle */ FAST DOS_FAT_HDL_ID pFatHdl = &pFd->fatHdl; /* pointer to FAT handle */ FAST DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; /* pointer to volume descriptor */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; /* pointer to FAT descriptor */ FAST uint32_t startClust; /* */ FAST uint32_t numClusts; /* */ FAST uint32_t prevClust; /* */ FAST uint32_t firstClust; /* */ FAST uint32_t contigCount; /* count of fit clusters */ FAST uint32_t curClust; /* current cluster number */ FAST uint32_t fatEntry; /* FAT entry */ FAST uint32_t maxClust; /* maximum cluster number */ FAST uint32_t pass; /* */ /* Try to follow file chain */ if (fat16ContigGet (pFd, pFatDesc->fatGroupSize) == OK) return OK; if (pFatHdl->errCode == FAT_CBIO_ERR) return ERROR; /* Can't follow file chain */ if ((allocPolicy & FAT_ALLOC) == 0) /* not alloc */ return ERROR; firstClust = pFatHdl->nextClust; prevClust = pFatHdl->lastClust; startClust = 0; /* Set number of clusters to allocate. */ if (pFatDesc->groupAllocStart == 0) /* no free groups in prev. alloc. */ allocPolicy = FAT_ALLOC_ONE; numClusts = (allocPolicy == (uint_t)FAT_ALLOC_ONE) ? 1 : pFatDesc->fatGroupSize; /* Set initial cluster number to try allocation from. */ if (firstClust > pFatDesc->dos_fat_bad) /* end of file chain */ startClust = prevClust; else if ((firstClust == 0) && (prevClust == 0)) /* it is a new file */ startClust = (allocPolicy == (uint_t)FAT_ALLOC_ONE) ? pFatDesc->clustAllocStart : pFatDesc->groupAllocStart; if (startClust == 0) { errnoSet (S_dosFsLib_ILLEGAL_CLUSTER_NUMBER); return ERROR; } /* Try finding a set of clusters starting at or after the initial one. * Continue searching upwards until end of FAT. */ maxClust = pFatDesc->nFatEnts - 1; curClust = startClust; /* start from initial cluster number */ firstClust = 0; contigCount = 0; semTake (pFatDesc->allocSem, WAIT_FOREVER); for (pass = 0; pass < 2; pass++) { while (curClust <= maxClust) { fatEntry = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, curClust); if ((fatEntry == FAT_CBIO_ERR)&&(pFatHdl->errCode == FAT_CBIO_ERR)) goto group_alloc_error; if (fatEntry == pFatDesc->dos_fat_avail) { /* free space */ if (contigCount == 0) firstClust = curClust;/* this one will be new start */ if (++contigCount == numClusts) /* one more found */ goto group_alloc; /* quit if enough found */ } else /* allocated space */ { contigCount = 0; } curClust++; } /* while */ /* * Try finding a contiguous area starting before the current cluster * Note that the new contiguous area could include the initial cluster */ maxClust = startClust - 1; curClust = DOS_MIN_CLUST; /* start from lowest cluster number */ contigCount = 0; } /* for */ if (firstClust == 0) { errnoSet (S_dosFsLib_DISK_FULL); ERR_MSG (1, "!!! DISK FULL !!!\n", 1,2,3,4,5,6); goto group_alloc_error; /* could not find space */ } pFatDesc->groupAllocStart = 0; numClusts = 1;group_alloc: /* Allocate the found chain */ if (fat16MarkAlloc (pFd, firstClust, numClusts) != OK) goto group_alloc_error; semGive (pFatDesc->allocSem); DBG_MSG (1, "Allocated %ld clusters starting from cluster %ld\n", contigCount, firstClust,3,4,5,6); /* */ if (startClust == prevClust) { /* Add just allocated contiguous section to the file chain */ if (ENTRY_WRITE (pFd, pFatDesc->dosFatDesc.activeCopyNum, prevClust, firstClust) != OK) return ERROR; if (firstClust == pFileHdl->contigEndPlus1) pFileHdl->contigEndPlus1 = firstClust + numClusts; DBG_MSG (1, " ----- Old end %ld -----\n", prevClust,2,3,4,5,6); } else { /* Advance start allocation cluster number */ if (allocPolicy == (uint_t)FAT_ALLOC_ONE) pFatDesc->clustAllocStart = firstClust + 1; else if (pFatDesc->groupAllocStart != 0) pFatDesc->groupAllocStart = firstClust + numClusts; DBG_MSG (1, " ----- Old start %ld -----\n", startClust,2,3,4,5,6); DBG_MSG (1, " ----- New start %ld -----\n", firstClust,2,3,4,5,6); pFileHdl->startClust = firstClust; pFileHdl->contigEndPlus1 = firstClust + numClusts; } pFatHdl->nextClust = pFatDesc->dos_fat_eof; pFatHdl->lastClust = firstClust + numClusts - 1; pFd->curSec = CLUST_TO_SEC (pVolDesc, firstClust); pFd->nSec = numClusts * pVolDesc->secPerClust; return OK;group_alloc_error: semGive (pFatDesc->allocSem); return ERROR; } /* fat16GetNext *//********************************************************************************* fat16Truncate - truncate chain starting from cluster** This routine is used when removing files and directories as well as* when truncating files. It will follow* a chain of cluster entries in the file allocation table (FAT), freeing each* as it goes.** RETURNS: OK or ERROR if invalid cluster encountered in chain*/LOCAL STATUS fat16Truncate ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t sector, /* sector to truncate from */ FAST uint32_t flag /* FH_INCLUDE or FH_EXCLUDE */ ) { FAST DOS_FILE_HDL_ID pFileHdl = pFd->pFileHdl; /* pointer to file handle */ FAST DOS_VOLUME_DESC_ID pVolDesc = pFd->pVolDesc; /* pointer to volume descriptor */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pVolDesc->pFatDesc; /* pointer to FAT descriptor */ FAST uint32_t curClust; /* current cluster */ FAST uint32_t nextClust; /* next cluster in chain */ FAST uint32_t cluster; /* cluster to truncate from */ if (sector == FH_FILE_START) { cluster = pFileHdl->startClust; pFileHdl->contigEndPlus1 = 0; if (cluster < DOS_MIN_CLUST) { errnoSet (S_dosFsLib_INVALID_PARAMETER); /* ??? */ return ERROR; } } else { if (sector < pVolDesc->dataStartSec) { errnoSet (S_dosFsLib_INVALID_PARAMETER); return ERROR; } cluster = SEC_TO_CLUST (pVolDesc, sector); } if (cluster >= pFatDesc->nFatEnts) { errnoSet (S_dosFsLib_INVALID_PARAMETER); /* ??? */ return ERROR; } switch (flag ) { case FH_INCLUDE: if ((sector == FH_FILE_START) || (((sector - pVolDesc->dataStartSec) % pVolDesc->secPerClust) == 0)) { curClust = cluster; break; } case FH_EXCLUDE: /* Read cluster to truncate from, including this one */ curClust = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, cluster); if (curClust > pFatDesc->dos_fat_bad) return OK; /* end of file */ if ((curClust < DOS_MIN_CLUST) || (curClust >= pFatDesc->nFatEnts)) return ERROR; /* */ /* Mark passed cluster as end of file */ if (ENTRY_WRITE (pFd, pFatDesc->dosFatDesc.activeCopyNum, cluster, pFatDesc->dos_fat_eof) != OK) return ERROR; /* disk access error */ break; default: { errnoSet (S_dosFsLib_INVALID_PARAMETER); return ERROR; } } if ( (curClust < pFileHdl->contigEndPlus1) && (curClust >= pFileHdl->startClust) ) pFileHdl->contigEndPlus1 = curClust; if (pFatDesc->groupAllocStart == 0) pFatDesc->groupAllocStart = curClust; /* Adjust single cluster allocation start point to start of the disk */ if (pFatDesc->clustAllocStart > curClust) pFatDesc->clustAllocStart = curClust;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -