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

📄 cat.c

📁 ST5518机顶盒系统文件系统源代码!绝对超值!
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* Check to see if we have it already */        LocalCat_p = *ReturnCat_p;        if ((LocalCat_p == NULL)                                 ||        (LocalCat_p->InvalidData)                            ||        (LocalCat_p->ClusterBlockId != ClusterBlockId)       ||        (LocalCat_p <  Cache_p->LCatCache)                   ||        (LocalCat_p >= Cache_p->LCatCache + LCAT_CACHE_SIZE))    {        /* We don't already have it */        LocalCat_p = NULL;    }        /* Locate in the Cache */        for (idx = 0; (idx < LCAT_CACHE_SIZE) && (LocalCat_p == NULL); idx++)    {        if ((ClusterBlockId == Cache_p->LCatCache[idx].ClusterBlockId) &&            !Cache_p->LCatCache[idx].InvalidData)        {            LocalCat_p = Cache_p->LCatCache +idx;        }        else if (InvalidCat_p != NULL)        {            /* We already know which entry to use */        }        else if (Cache_p->LCatCache[idx].RefCount > 0)        {            /* This entry is in use */        }        else if (Cache_p->LCatCache[idx].InvalidData)        {            InvalidCat_p = Cache_p->LCatCache +idx;        }        else        {            U16 Age = Cache_p->LCatTime - Cache_p->LCatCache[idx].TimeStamp;                        if (Age > OldestCat)            {                OldestCat = Age;                OldCat_p  = Cache_p->LCatCache +idx;            }        }    }        /* Did we find an entry */        if (LocalCat_p == NULL)    {        /* Allocate from Cache */                if (InvalidCat_p != NULL)        {            LocalCat_p = InvalidCat_p;        }        else if (OldCat_p != NULL)        {            LocalCat_p = OldCat_p;        }        else        {            /* This is bad */            /* The Cache is full */            Error = STAVFS_ERROR_CACHE_FULL;            STTBX_Print(("LCat Cache is FULL\n"));        }                if (LocalCat_p != NULL)        {            /* Set up the entry */            LocalCat_p->ClusterBlockId = ClusterBlockId;            LocalCat_p->RefCount       = 0;            LocalCat_p->InvalidData    = 1;            stavfs_GetLCatLBA(Device_p, ClusterBlockId, &(LocalCat_p->LBA));        }    }        /* Update the Cache State */        if (LocalCat_p != NULL)    {        LocalCat_p->RefCount++;        LocalCat_p->TimeStamp = Cache_p->LCatTime;            /* Ensure the data in Cache is correct */                if (LocalCat_p->InvalidData)        {            if (ST_NO_ERROR != (Error = stavfs_BOWCATRead(Device_p, &(LocalCat_p->LBA), (U8*)&(LocalCat_p->Data))))            {                /* This is a bad CAT - return nothing */                                 LocalCat_p->RefCount--;                LocalCat_p->InvalidData = 1;                LocalCat_p = NULL;            }            else            {                LocalCat_p->InvalidData = 0;            }        }    }        *ReturnCat_p = LocalCat_p;        return (Error);}/******************************************************************************Function Name : stavfs_SetLocalCat  Description : Write the Local CAT to disk.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_SetLocalCat(stavfs_LocalCatCache_t *LocalCat_p, stavfs_Device_t *Device_p){    ST_ErrorCode_t Error = ST_NO_ERROR;        assert(Device_p   != NULL);    assert(LocalCat_p != NULL);        Error = stavfs_BOWCATWrite(Device_p, &(LocalCat_p->LBA), (U8*)&(LocalCat_p->Data));        return (Error);}/******************************************************************************Function Name : stavfs_InvalidLocalCat  Description : The data in this Local CAT has been invalidated. Reload from disk                when next requesting this Local CAT.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_InvalidLocalCat(stavfs_LocalCatCache_t *LocalCat_p){    LocalCat_p->InvalidData = 1;    return (ST_NO_ERROR);}/******************************************************************************Function Name : stavfs_ReleaseLocalCat  Description : Decrement the reference count so we know when it is free.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_ReleaseLocalCat(stavfs_LocalCatCache_t *LocalCat_p){    if (LocalCat_p == NULL)    {        /* NULL pointer - just ignore it */        return (ST_NO_ERROR);    }    else if (LocalCat_p->RefCount > 0)    {        LocalCat_p->RefCount--;        return (ST_NO_ERROR);    }    else    {        /* This is a coding error and should never happen */        STTBX_Print(("Local CAT Cache %X has negative reference count\n", LocalCat_p->ClusterBlockId));        assert (LocalCat_p->RefCount != 0);        return (!ST_NO_ERROR);    }}/******************************************************************************Function Name : stavfs_WalkTheChain  Description : Walk down the file cluster chain to the end do any fixes to the                chain.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_WalkTheChain(stavfs_Device_t *Device_p, BOOL CheckMCat, U64 *LBA_p, U32 *Count_p){    ST_ErrorCode_t      Error   = ST_NO_ERROR;    stavfs_MCatCache_t *Cache_p = NULL;        U32 ThisClusterBlockId = 0;    U32 ThisClusterIdx     = 0;    U32 LastClusterBlockId = 0;    U32 LastClusterIdx     = 0;        U64 LastLBA = *LBA_p;    U64 ThisLBA = *LBA_p;            stavfs_LocalCatCache_t *LastLocalCat_p = NULL;    stavfs_LocalCatCache_t *ThisLocalCat_p = NULL;        assert (Device_p       != NULL);    assert (Device_p->MCat != NULL);    assert (LBA_p          != NULL);        Cache_p = (stavfs_MCatCache_t*)Device_p->MCat;        /* Sanity check */        if (INT_I64_AreEqual(*LBA_p, InvalidLBA))    {        /* There is no chain !! */        Error = ST_ERROR_BAD_PARAMETER;    }        while ((Error == ST_NO_ERROR)                &&           INT_I64_AreNotEqual(ThisLBA, NullLBA))    {        /* Find the Local CAT entry for this LBA */            stavfs_GetClusterIdx(Device_p, &ThisClusterBlockId, &ThisClusterIdx, &ThisLBA);        if (ST_NO_ERROR == (Error = stavfs_GetLocalCat(Device_p, ThisClusterBlockId, &ThisLocalCat_p)))        {            /* We could check the Master CAT here */                        if (CheckMCat &&                ((LastLocalCat_p     == NULL) ||                 (LastClusterBlockId != ThisClusterBlockId)))            {                /* New Local CAT - Update the Master CAT */                                stavfs_RebuildLocalCAT(Device_p, ThisLocalCat_p, FALSE);                                stavfs_UpdateMasterCAT(Device_p, ThisClusterBlockId, ThisLocalCat_p);            }                        /* Do we link back correctly */                        if ((LastLocalCat_p != NULL) &&                INT_I64_AreNotEqual(LastLBA, ThisLocalCat_p->Data.Cat[ThisClusterIdx].PrevLBA))            {                /* Clean the Bad link */                STTBX_Print(("Fix a bad forward link\n"));                                LastLocalCat_p->Data.Cat[LastClusterIdx].NextLBA = NullLBA;                ThisLBA = NullLBA;                                /* Flush the fix to disk */                                stavfs_SetLocalCat(LastLocalCat_p, Device_p);                                /* Clean up */                                stavfs_ReleaseLocalCat(ThisLocalCat_p);            }            else if (INT_I64_AreEqual(ThisLocalCat_p->Data.Cat[ThisClusterIdx].NextLBA, InvalidLBA) ||                     INT_I64_AreEqual(ThisLocalCat_p->Data.Cat[ThisClusterIdx].PrevLBA, InvalidLBA))            {                /* Unallocated Cluster (First Cluster)    */                /* Correct the first cluster in the chain */                STTBX_Print(("Correct the first cluster in the chain\n"));                                ThisLBA = NullLBA;                LastLBA = NullLBA;            }            else            {                stavfs_ReleaseLocalCat(LastLocalCat_p);                LastClusterBlockId = ThisClusterBlockId;                                LastClusterIdx = ThisClusterIdx;                LastLBA        = ThisLBA;                ThisLBA        = ThisLocalCat_p->Data.Cat[ThisClusterIdx].NextLBA;                LastLocalCat_p = ThisLocalCat_p;                ThisLocalCat_p = NULL;                                /* Count the clusters */                                if (Count_p != NULL) (*Count_p)++;            }        }    }        /* Clean up */        /* Release the local cat */    stavfs_ReleaseLocalCat(LastLocalCat_p);        /* Return the last LBA in the chain */        *LBA_p  = LastLBA;        return (Error);}/******************************************************************************Function Name : stavfs_UpdateMasterCAT  Description : Update the Master CAT from the local CAT.   Parameters :******************************************************************************/void stavfs_UpdateMasterCAT(stavfs_Device_t *Device_p, U32 ClusterBlockId, stavfs_LocalCatCache_t *LocalCat_p){    /* Update the Master CAT entry for the Cluster Block */    U32 M_CatIdx;    U32 M_BlockIdx;    stavfs_MCatCache_t *Cache_p = NULL;        assert (Device_p       != NULL);    assert (Device_p->MCat != NULL);    assert (LocalCat_p     != NULL);    M_CatIdx   = ClusterBlockId % M_CAT_ENTRIES_PER_BLOCK;    M_BlockIdx = ClusterBlockId / M_CAT_ENTRIES_PER_BLOCK;        Cache_p = (stavfs_MCatCache_t*)Device_p->MCat;    if (Cache_p->Blocks[M_BlockIdx].M_CatData[M_CatIdx] != LocalCat_p->Data.FreeClusters)    {        Cache_p->Blocks[M_BlockIdx].Unused2 = 1;  /* Flag Modified */        Cache_p->Blocks[M_BlockIdx].M_CatData[M_CatIdx] = LocalCat_p->Data.FreeClusters;    }}/******************************************************************************Function Name : stavfs_RebuildLocalCAT  Description : Rebuild the Local CAT from the local CAT.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_RebuildLocalCAT(stavfs_Device_t *Device_p, stavfs_LocalCatCache_t *LocalCat_p, BOOL Force){    ST_ErrorCode_t Error = ST_NO_ERROR;        BOOL Modified = FALSE;    U32  Count;    int  j;    #ifndef STAVFS_NO_BACKUP_ON_WRITE    if (Force)#endif    {        /* Check the entries */            Count = 0;        for (j = 0; (j < CLUSTERS_PER_BLOCK(Device_p)); j++)        {            if (INT_I64_AreEqual(LocalCat_p->Data.Cat[j].PrevLBA, InvalidLBA) ||                INT_I64_AreEqual(LocalCat_p->Data.Cat[j].NextLBA, InvalidLBA))            {                /* This entry is free */                 Count++;                 if (INT_I64_AreNotEqual(LocalCat_p->Data.Cat[j].PrevLBA, InvalidLBA))                {                    STTBX_Print(("Bad free PrevLBA Cluster %d:%d\n", LocalCat_p->ClusterBlockId, j));                    LocalCat_p->Data.Cat[j].PrevLBA = InvalidLBA;                    Modified = TRUE;                }                else if (INT_I64_AreNotEqual(LocalCat_p->Data.Cat[j].NextLBA, InvalidLBA))                {                    STTBX_Print(("Bad free NextLBA Cluster %d:%d\n", LocalCat_p->ClusterBlockId, j));                    LocalCat_p->Data.Cat[j].NextLBA = InvalidLBA;                    Modified = TRUE;                }            }        }         /* Check the free cluster count */         if (Count != LocalCat_p->Data.FreeClusters)        {            STTBX_Print(("LCAT %d: Bad free clusters count\n", LocalCat_p->ClusterBlockId));            LocalCat_p->Data.FreeClusters = Count;            Modified = TRUE;        }         /* If we have modified the CAT then rewrite it */         if (Modified)        {            Error = stavfs_SetLocalCat(LocalCat_p, Device_p);        }    }        return (Error);}/******************************************************************************Function Name : stavfs_ClearUnusedMasterCAT  Description : Clear those Master CAT entries for which there are no Cluster                Blocks.   Parameters :******************************************************************************/void stavfs_ClearUnusedMasterCAT(stavfs_Device_t *Device_p, stavfs_LocalCatCache_t *LocalCat_p){    U32 M_CatIdx;    U32 M_BlockIdx;    stavfs_MCatCache_t *Cache_p = NULL;        assert (Device_p->MCat != NULL);        M_CatIdx   =  Device_p->NumClusterBlock % M_CAT_ENTRIES_PER_BLOCK;    M_BlockIdx =  Device_p->NumClusterBlock / M_CAT_ENTRIES_PER_BLOCK;        Cache_p = (stavfs_MCatCache_t*)Device_p->MCat;        for (; (M_CatIdx < M_CAT_ENTRIES_PER_BLOCK); ++M_CatIdx)    {        if (Cache_p->Blocks[M_BlockIdx].M_CatData[M_CatIdx] != 0)        {            /* There is no Cluster block so no free clusters */                        Cache_p->Blocks[M_BlockIdx].M_CatData[M_CatIdx] = 0;            Cache_p->Blocks[M_BlockIdx].Unused2 = 1;  /* Flag Modified */        }    }}

⌨️ 快捷键说明

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