📄 dosfsfat.c
字号:
/* Free a chain of clusters */ while ((curClust >= DOS_MIN_CLUST) && (curClust < pFatDesc->nFatEnts)) { /* get next cluster in chain */ nextClust = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, curClust); /* free current cluster (mark cluster in FAT as available) */ if (ENTRY_WRITE (pFd, pFatDesc->dosFatDesc.activeCopyNum, curClust, pFatDesc->dos_fat_avail) != OK) return ERROR; /* Update free clusters counter */ pFatDesc->fatEntFreeCnt++; curClust = nextClust; /* do next cluster */ } if (curClust <= pFatDesc->dos_fat_bad) /* If not end of file */ return ERROR; return OK; } /* fat16Truncate *//********************************************************************************* fat16Seek - seek cluster within file chain** Returns a particular cluster relative to the cluster chain beginning* which is noted in the file descriptor structure.* It is used to seek in to a file.** RETURNS: requested position is returned in the file descriptor structure*/LOCAL STATUS fat16Seek ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t sector, /* sector to seek from */ FAST uint32_t sectOff /* sector offset within file */ ) { 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 nextClust; /* next cluster number */ FAST uint32_t count; /* count of clusters */ FAST uint32_t cluster; /* cluster to seek from */ FAST uint32_t clustOff; /* */ if (sector == FH_FILE_START) { pFd->fatHdl.nextClust = 0; pFd->fatHdl.lastClust = 0; pFd->fatHdl.cbioCookie = 0; pFd->curSec = 0; pFd->nSec = 0; cluster = pFd->pFileHdl->startClust; if (cluster == 0) return OK; if (cluster < DOS_MIN_CLUST) return ERROR; } else { if (sector < pVolDesc->dataStartSec) return ERROR; /* cluster to seek from */ cluster = SEC_TO_CLUST (pVolDesc, sector); /* offset from start of cluster */ sectOff += (sector - pVolDesc->dataStartSec) % pVolDesc->secPerClust; } if (cluster >= pFatDesc->nFatEnts) return ERROR; clustOff = sectOff / pVolDesc->secPerClust; sectOff %= pVolDesc->secPerClust; /* Skip contiguous area */ if ( (cluster < pFd->pFileHdl->contigEndPlus1) && (cluster >= pFd->pFileHdl->startClust) ) { count = min (clustOff, pFd->pFileHdl->contigEndPlus1 - cluster - 1); cluster += count; clustOff -= count; } for (count = 0; count < clustOff; count++) { nextClust = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, cluster); /* follow chain */ /* If end of cluster chain, bad cluster number or disk access error */ if ((nextClust < DOS_MIN_CLUST) || (nextClust >= pFatDesc->nFatEnts)) return ERROR; cluster = nextClust; /* do next cluster */ } pFd->fatHdl.nextClust = cluster; if (fat16ContigGet (pFd, pFatDesc->fatGroupSize) != OK) return ERROR; pFd->curSec += sectOff; pFd->nSec -= sectOff; return OK; } /* fat16Seek *//********************************************************************************* fat16NFree - count number of free bytes on disk*** RETURNS: amount of free space is returned in file descriptor handle*/LOCAL fsize_t fat16NFree ( FAST DOS_FILE_DESC_ID pFd /* pointer to file descriptor */ ) { 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 clustNum; /* cluster number */ FAST uint32_t fatEntry; /* */ FAST uint32_t freeCount; /* */ freeCount = pFatDesc->fatEntFreeCnt; if(freeCount == 0xffffffff) { freeCount = 0; /* Read file allocation table (FAT) to find unused clusters */ for (clustNum=DOS_MIN_CLUST; clustNum < pFatDesc->nFatEnts; clustNum++) { fatEntry = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, clustNum); if ((fatEntry == FAT_CBIO_ERR)&& (pFd->fatHdl.errCode == FAT_CBIO_ERR)) return ERROR; if (fatEntry == pFatDesc->dos_fat_avail) freeCount++; } pFatDesc->fatEntFreeCnt = freeCount; } return ( (((fsize_t)freeCount) * pVolDesc->secPerClust) << pVolDesc->secSizeShift ); } /* fat16NFree *//********************************************************************************* fat16ContigChk - check file chain for contiguity** RETURNS: ERROR if an illegal cluster number is encountered*/LOCAL STATUS fat16ContigChk ( FAST DOS_FILE_DESC_ID pFd /* pointer to file descriptor */ ) { FAST DOS_FILE_HDL_ID pFileHdl = pFd->pFileHdl; /* pointer to file handle */ FAST MS_FAT_DESC_ID pFatDesc = (void *) pFd->pVolDesc->pFatDesc; /* pointer to FAT handler descriptor */ FAST uint32_t nextClust; /* next cluster number */ FAST uint32_t cluster; /* cluster number */ cluster = pFileHdl->startClust; if (cluster == 0) return OK; if ((cluster < DOS_MIN_CLUST) || (cluster >= pFatDesc->nFatEnts)) { errnoSet (S_dosFsLib_ILLEGAL_CLUSTER_NUMBER); return ERROR; } FOREVER { nextClust = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, cluster); /* follow chain */ if (nextClust != ++cluster) break; /* end of contiguous area */ } if (pFd->fatHdl.errCode == FAT_CBIO_ERR) return ERROR; pFileHdl->contigEndPlus1 = cluster; if (nextClust > pFatDesc->dos_fat_bad) /* end of file chain */ return OK; if ((nextClust < DOS_MIN_CLUST) || (nextClust >= pFatDesc->nFatEnts)) { errnoSet (S_dosFsLib_ILLEGAL_CLUSTER_NUMBER); } return ERROR; } /* fat16ContigChk *//********************************************************************************* fat16MaxContigClustersGet - return size of largest contiguous space on disk* * RETURNS: max contiguous space in clusters*/ LOCAL size_t fat16MaxContigClustersGet ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t * pMaxStart /* were to return start clust */ ) { FAST MS_FAT_DESC_ID pFatDesc = (void *) pFd->pVolDesc->pFatDesc; /* pointer to FAT handler descriptor */ FAST uint32_t fatEntry; /* */ FAST uint32_t curClust; /* */ FAST uint32_t firstContig; /* 1st clust. of contig area */ FAST uint32_t contigCount; /* count of fit clusters */ FAST uint32_t maxStart; /* */ FAST uint32_t maxCount; /* */ firstContig = DOS_MIN_CLUST; contigCount = 0; maxStart = 0; maxCount = 0; for (curClust = DOS_MIN_CLUST; curClust < pFatDesc->nFatEnts; curClust++) { fatEntry = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, curClust); if ((fatEntry == FAT_CBIO_ERR)&&(pFd->fatHdl.errCode == FAT_CBIO_ERR)) return 0; if (fatEntry == pFatDesc->dos_fat_avail) { /* free space */ contigCount++; /* one more found */ } else { /* Check for maximum */ if (contigCount > maxCount) { maxStart = firstContig; maxCount = contigCount; } firstContig = curClust + 1; /* next one will be new start */ contigCount = 0; } } /* for */ if (contigCount > maxCount) { maxStart = firstContig; maxCount = contigCount; } *pMaxStart = maxStart; return (maxCount); } /* fat16MaxContigClustersGet *//********************************************************************************* fat16ContigAlloc - allocate <numSect> contiguous chain** This function employs the Best Fit algorithm to locate a* contiguous fragment of space for the requested size** RETURNS: ERROR if requested space is not available*/LOCAL STATUS fat16ContigAlloc ( FAST DOS_FILE_DESC_ID pFd, /* pointer to file descriptor */ FAST uint32_t number /* number of sectors needed */ ) { 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 handler descriptor */ FAST uint32_t fatEntry; /* */ FAST uint32_t curClust; /* */ FAST uint32_t firstContig; /* 1st clust. of contig area */ FAST uint32_t contigCount; /* count of fit clusters */ FAST uint32_t bestCount; /* */ uint32_t bestStart; /* */ if (number == (uint32_t)CONTIG_MAX) { semTake (pFatDesc->allocSem, WAIT_FOREVER); number = fat16MaxContigClustersGet (pFd, &bestStart); if (number == 0) { errnoSet (S_dosFsLib_DISK_FULL); goto contig_alloc_error; } goto contig_alloc; } /* Convert number of sectors needed to number of clusters */ number = (number + pVolDesc->secPerClust - 1) / pVolDesc->secPerClust; firstContig = DOS_MIN_CLUST; contigCount = 0; bestStart = 0; bestCount = pFatDesc->nFatEnts; semTake (pFatDesc->allocSem, WAIT_FOREVER); for (curClust = DOS_MIN_CLUST; /* firstContig <= (pFatDesc->nFatEnts - number); ??? for 1st fit ??? */ curClust < (pFatDesc->nFatEnts - number); curClust++) { fatEntry = ENTRY_READ (pFd, pFatDesc->dosFatDesc.activeCopyNum, curClust); if ((fatEntry == FAT_CBIO_ERR)&&(pFd->fatHdl.errCode == FAT_CBIO_ERR)) goto contig_alloc_error;#if FALSE /* best fit */ if (fatEntry == pFatDesc->dos_fat_avail) { /* free space */ contigCount++; /* one more found */ } else { /* Check for best fit */ if ((contigCount >= number) && (contigCount < bestCount)) { /* most close from above */ bestStart = firstContig; bestCount = contigCount; if (contigCount == number) break; /* fit exactly */ } firstContig = curClust + 1; /* next one will be new start */ contigCount = 0; }#else /* 1st fit */ if (fatEntry == pFatDesc->dos_fat_avail) { /* free space */ if (++contigCount == number) /* one more found */ { bestStart = firstContig; /* ??? temporary solution */ bestCount = contigCount; /* ??? temporary solution */ goto contig_alloc; /* quit if enough found */ } } else /* allocated space */ { firstContig = curClust + 1; /* next one will be new start */ contigCount = 0; }#endif /* FALSE */ } /* for */ if (bestStart == 0) { if (contigCount < number) { errnoSet (S_dosFsLib_NO_CONTIG_SPACE); goto contig_alloc_error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -