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

📄 fatfilt.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif
        return flFormatNotSupported;

    /* 
     * Is it a bogus BPB (leftover from previous disk partitioning) ? 
     * Check that there is no overlap with next partition (if one exists).
     */

#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
    sectors = UNAL2(bpb->totalSectorsInVolumeDOS3);

    if (sectors == (SectorNo)0)
        sectors = (SectorNo) LE4(bpb->totalSectorsInVolume);
#else
    sectors = FL_GET_UNAL2(bpb, FL_BPB_TOTAL_SECTORS_IN_VOL_DOS3_OFFSET);

    if (sectors == (SectorNo)0)
        sectors = (SectorNo) FL_GET_LE4(bpb, FL_BPB_TOTAL_SECTORS_IN_VOL_OFFSET);
#endif

    if ((partNo+1 < pd->parts) && (pd->part[partNo+1] != NULL)) {

        if( sectors > (pd->part[partNo+1])->startSecNo - pv->startSecNo )
            return flNonFATformat;
    }

    /* number of sectors in partition as reported by BPB */

    pv->sectors = sectors;

    /* get number of reserved sectors from BPB, and check it's sanity */

#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
    reservedSectors = (SectorNo) LE2(bpb->reservedSectors);
#else
    reservedSectors = (SectorNo) FL_GET_LE2(bpb, FL_BPB_RESERVED_SECTORS_OFFSET);
#endif

    switch( (int)reservedSectors ) {

        case 32:      /* always the case with FAT 32 */

#ifndef FL_INCLUDE_FAT32

            DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT32 detected.\r\n");
            return flFormatNotSupported;
#endif

        case 1:       /* must always be the case for FAT 12 and FAT16 */
        default:

            break;
    }

    /* get location and size of the first FAT copy */

    pv->firstFATsecNo = pv->startSecNo + reservedSectors;

#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
    sectorsPerFAT = (SectorNo) LE2(bpb->sectorsPerFAT);
#else
    sectorsPerFAT = (SectorNo) FL_GET_LE2(bpb, FL_BPB_SECTORS_PER_FAT_OFFSET);
#endif

#ifndef FL_INCLUDE_FAT32

    if (sectorsPerFAT == 0) {        /* always the case with FAT32 */

        DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT32 detected.\r\n");
        return flFormatNotSupported;
    }

#endif

    pv->lastFATsecNo = pv->firstFATsecNo + sectorsPerFAT - (SectorNo)1;

    /* get location and size of root directory */

#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
    rootDirSecNo = pv->firstFATsecNo + (sectorsPerFAT * bpb->noOfFATS);

    rootDirEntries = (SectorNo) UNAL2(bpb->rootDirectoryEntries);
#else
    rootDirSecNo = pv->firstFATsecNo + (sectorsPerFAT * (FL_REF_1(bpb, FL_BPB_NO_OF_FATS_OFFSET)));

    rootDirEntries = (SectorNo) FL_GET_UNAL2(bpb, FL_BPB_ROOT_DIR_ENTRIES_OFFSET);
#endif

    switch (rootDirEntries) {

#ifndef FL_INCLUDE_FAT32

        case 0:            /* always the case with FAT32 */

            DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT32 detected.\r\n");
            return flFormatNotSupported;
#endif
    
        default:

            if( ((rootDirEntries * DIRECTORY_ENTRY_SIZE) % FL_SECTOR_SIZE) != 0 )
                return flNonFATformat;
            break;
    }

    rootDirSectors = (SectorNo)(((rootDirEntries * DIRECTORY_ENTRY_SIZE) - 1) / FL_SECTOR_SIZE) +
                             (SectorNo)1;

    /* get location of data area */

    pv->firstDataSecNo = rootDirSecNo + rootDirSectors;

    /* get size of FAT cluster in sectors, and check it's sanity */

#ifndef FL_NO_PACKED_STRUCTS_SUPPORTED
    pv->clusterSize = bpb->sectorsPerCluster;
#else
    pv->clusterSize = FL_REF_1(bpb, FL_BPB_SECTORS_PER_CLUSTER_OFFSET);
#endif

    switch( (int)pv->clusterSize ) {

        case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128:  
            break;

        default:
            return flNonFATformat;
    }

    if ((pv->clusterSize << FL_SECTOR_SIZE_BITS) > (32768 /*(32 * 1024)*/))
        return flFormatNotSupported;

    /* sanity check */

    if( (pv->lastFATsecNo   < pv->firstFATsecNo)  ||
        (pv->firstDataSecNo <= pv->lastFATsecNo)  ||  
        (pv->sectors        < pv->firstDataSecNo) )
        return flNonFATformat;


    /* decide which type of FAT is it */

    maxCluster         = (unsigned)1 + (unsigned) 
        ((pv->sectors - (pv->firstDataSecNo - pv->startSecNo)) / pv->clusterSize);

    if (maxCluster < 4085) {

        pv->flags |= VOLUME_12BIT_FAT;    /* 12-bit FAT */

#ifndef FS_FAT_12BIT

        DBG_PRINT_ERR(FLZONE_FS,"ERROR - FS_FAT_12BIT must be defined.\r\n");
        return flFormatNotSupported;

#else

        DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT12 detected.\r\n");

#endif /* FS_FAT_12BIT */
    }
    else {

        DBG_PRINT_FLOW(FLZONE_FS,"Debug: (partEnableFF) FAT16 detected.\r\n");
    }

    /* turn on FAT filter on this partition */

    pv->ffEnabled = TRUE;

    return flOK;
}




/* --------------------------------------------------------------------------- *
 *                                                                             *
 *                   p a r t F r e e D e l C l u s t e r s                     *
 *                                                                             * 
 *  Compare the new contents of the specified FAT sector against the old       * 
 *  one on the disk. If any freed clusters are found, issue 'sector delete'    * 
 *  calls for all sectors that are occupied by these freed clusters.           * 
 *                                                                             * 
 *  Parameters:                                                                * 
 *      pv              : disk partition (filesystem volume)                   * 
 *      secNo           : abs. sector # of the FAT sector                      * 
 *      newFAT          : new contents of this FAT sector                      * 
 *                                                                             * 
 *  Returns:                                                                   * 
 *      flOK on success, otherwise error code                                  * 
 *                                                                             * 
 *  NOTE:  This routine uses disk's scratch buffer.                            * 
 *                                                                             * 
 * --------------------------------------------------------------------------- */

static FLStatus  partFreeDelClusters ( FLffVol      * pv,
                                       SectorNo       secNo,
                                       FLSByte FAR1 * newFAT,
                                       IOreq        * ioreq_delete )
{
    FLffDisk * pd;
    int        socNo, diskNo;
    FLWord     oldFATentry, newFATentry;
    SectorNo   iSec;
    unsigned   firstCluster;
    IOreq      ioreq;
    int        offset;
    int        iPart;

#ifdef FS_FAT_12BIT
    int        halfBytes;
#endif

#ifdef  FL_MALLOC
    FLSByte     * oldFAT;
#else
    FLSByte       oldFAT[FL_SECTOR_SIZE];
#endif

    /* arg. sanity check */

    if (pv == NULL)
        return flBadDriveHandle;
 
    /* break TFFS handle into socket# and disk#, and do sanity check */

    socNo  = H2S(pv->handle);
    diskNo = H2D(pv->handle);
 
    if ((socNo >= ((int) noOfSockets)) || (diskNo >= FL_MAX_TL_PARTITIONS))
        return flBadDriveHandle;

    /* check if 'pv' belongs to this disk */

    pd = ffDisk[socNo][diskNo];

    if (pd == NULL)
        return flBadDriveHandle;

    for (iPart = 0; iPart < pd->parts; iPart++) {

        if (pd->part[iPart] == pv)
            break;
    }

    if (iPart >= pd->parts)
        return flBadDriveHandle;

#ifdef  FL_MALLOC

    /* make sure scratch buffer is available */

    if (pd->buf == NULL)
        return flBufferingError;

    oldFAT = pd->buf;
 
#endif /* FL_MALLOC */

    /* read in the FAT sector from the disk */

    ioreq.irHandle      = pv->handle;
    ioreq.irSectorNo    = secNo;
    ioreq.irSectorCount = 1;
    ioreq.irData        = (void FAR1 *) oldFAT;
    checkStatus( flAbsRead(&ioreq) );

#ifdef FS_FAT_12BIT

    /* size of FAT entry in half-bytes */

    halfBytes = ((pv->flags & VOLUME_12BIT_FAT) ? 3 : 4);

    /* starting cluster */

    if (halfBytes == 3) {

        firstCluster = 
            ((((unsigned)(secNo - pv->firstFATsecNo)) * (2 * FL_SECTOR_SIZE)) + 2) / 3;
    }
    else {

        firstCluster = ((unsigned)(secNo - pv->firstFATsecNo)) * (FL_SECTOR_SIZE / 2);
    }

    /* starting data sector */

    iSec = (((SectorNo)firstCluster - 2) * pv->clusterSize) + pv->firstDataSecNo;

    offset = (firstCluster * ((unsigned) halfBytes)) & ((2 * FL_SECTOR_SIZE) - 1);

    /* 
     *  Find if any clusters were logically deleted, and if so, delete them.
     *
     *  NOTE: We are skipping over 12-bit FAT entries which span more than
     *        one sector.
     */

    for (; offset < ((2 * FL_SECTOR_SIZE) - 2); 
               offset += halfBytes, iSec += pv->clusterSize) {

        oldFATentry = UNAL2( *(Unaligned FAR0 *)(oldFAT + (offset / 2)) );
        newFATentry = UNAL2( *(Unaligned FAR1 *)(newFAT + (offset / 2)) );

        if (offset & 1) {
            oldFATentry >>= 4;
            newFATentry >>= 4;
        }
        else { 
            if (halfBytes == 3) {
                oldFATentry &= 0xfff;
                newFATentry &= 0xfff;
            }
        }

#else /* !FS_FAT_12BIT */

    firstCluster = ((unsigned) (secNo - pv->firstFATsecNo) * (FL_SECTOR_SIZE / 2));
    iSec  = pv->firstDataSecNo + 
            (((SectorNo)(firstCluster - (unsigned)2)) * pv->clusterSize);

    /* Find if any clusters were logically deleted, and if so, delete them */

    for (offset = 0;  offset < FL_SECTOR_SIZE;  offset += 2, iSec += pv->clusterSize) {

        oldFATentry = LE2( *(LEushort FAR0 *)(oldFAT + offset) );
        newFATentry = LE2( *(LEushort FAR1 *)(newFAT + offset) );

#endif /* FS_FAT_12BIT */

        if ((oldFATentry != FAT_FREE) && (newFATentry == FAT_FREE)) {

#ifdef FL_DEL_SECTOR_SETS

            if (del_sect_sets == TRUE) {

                /* Rather then deleting this cluster's sectors immediately, we try to 
                 * accumulate as many consecutive clusters as only possible before 
                 * calling flAbsDelete(). The hope here is that the underlaying
                 * TL will be able to handle deletion of larger sets of
                 * consecutive sectors more efficiently. 
                 */

                if ((SectorNo)(ioreq_delete->irSectorNo + ioreq_delete->irSectorCount) == iSec) {

                    ioreq_delete->irSectorCount += pv->clusterSize;
                }
                else {

                    if (ioreq_delete->irSectorNo != (SectorNo)(-1)) {

#ifdef FL_DEL_SECTOR_STATS
                        {  register int x = -1, S = (int)(ioreq_delete->irSectorCount);
                           while (S != 0) { x++;  S >>= 1; }
                           if ((x >= 0) && (x < (sizeof(del_sect_stats)/sizeof(del_sect_stats[0])))) { del_sect_stats[x]++; }
                        }
#endif
                        flAbsDelete (ioreq_delete);
                    }

                    ioreq_delete->irSectorNo    = iSec;
                    ioreq_delete->irSectorCount = pv->clusterSize;
                }
            }
            else

#endif /* FL_DEL_SECTOR_SETS */

            {   /* delete one FAT cluster at a time */

                ioreq_delete->irHandle      = pv->handle;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -