⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dosfsfat.c

📁 FAT文件系统原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        }    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 + -