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

📄 cat.c

📁 ST5518机顶盒系统文件系统源代码!绝对超值!
💻 C
📖 第 1 页 / 共 3 页
字号:
        }    }        /* Return the actual space found */        if (NumClusters > Cache_p->Blocks[M_CatBlockId].M_CatData[M_CatIdx])    {        NumClusters = Cache_p->Blocks[M_CatBlockId].M_CatData[M_CatIdx];    }        /* Check to see if we found any space */        if (Cache_p->Blocks[M_CatBlockId].M_CatData[M_CatIdx] > 0)    {        /* We have found some space */        /* Return the information about the space */                stavfs_LocalCatCache_t *LocalCat_p = NULL;                /* Get the first free cluster address */                ClusterBlockId  = M_CatBlockId * M_CAT_ENTRIES_PER_BLOCK + M_CatIdx;                if (ST_NO_ERROR != stavfs_GetLocalCat(Device_p, ClusterBlockId, &LocalCat_p))        {            /* No space found */            NumClusters = 0;        }        else        {            U32 i;                        /* Find the first free Cluster in the Cluster Block */                        for (i = 0; (i < MAX_CLUSTERS_PER_BLOCK); i++)            {                if (INT_I64_AreEqual(LocalCat_p->Data.Cat[i].PrevLBA, InvalidLBA) ||                    INT_I64_AreEqual(LocalCat_p->Data.Cat[i].NextLBA, InvalidLBA))                {                    /* Found the first free Cluster */                    break;                }            }                        if (i >= MAX_CLUSTERS_PER_BLOCK)            {                /* No free cluster found */                NumClusters = 0;            }            else            {                stavfs_GetClusterLBA(Device_p, ClusterBlockId, i, FreeLBA_p);            }                        stavfs_ReleaseLocalCat(LocalCat_p);        }    }        return (NumClusters);}/******************************************************************************Function Name : stavfs_AllocFreeClusters  Description : Allocate clusters in a Cluster for the required number of clusters.                The LBA of the previous Cluster is given. This is needed to link                back when allocating the clusters. The PrevLBA value is moved to be the                LBA for the last allocated Cluster.                FreeLBA is the address of the first free cluster to be allocated.   Parameters :******************************************************************************/U32 stavfs_AllocFreeClusters(stavfs_Device_t *Device_p, U32 NumClusters, U8 InUnits, U64 *PrevLBA_p, U64 *FreeLBA_p){    stavfs_MCatCache_t *Cache_p = NULL;        U32 ClusterBlockId = 0;    U32 ClusterIdx     = 0;        U32 AllocatedClusters  = 0;            stavfs_LocalCatCache_t *LocalCat_p = NULL;        assert (Device_p       != NULL);    assert (Device_p->MCat != NULL);    assert (FreeLBA_p      != NULL);        Cache_p = (stavfs_MCatCache_t*)Device_p->MCat;        while (AllocatedClusters < NumClusters)    {        /* Find the Local CAT entry for the Free LBA */         stavfs_GetClusterIdx(Device_p, &ClusterBlockId, &ClusterIdx, FreeLBA_p);         if (ST_NO_ERROR != stavfs_GetLocalCat(Device_p, ClusterBlockId, &LocalCat_p))        {            /* No space found */            NumClusters = AllocatedClusters;        }        else if (INT_I64_AreNotEqual(LocalCat_p->Data.Cat[ClusterIdx].PrevLBA, InvalidLBA) &&            INT_I64_AreNotEqual(LocalCat_p->Data.Cat[ClusterIdx].NextLBA, InvalidLBA))        {            /* Our target cluster is no longer free */            NumClusters = AllocatedClusters;        }        else        {            int LastClusterIdx     = -1;            U64 ThisLBA            = *FreeLBA_p;            int AllocatedThisBlock = 0;             /* Set the forward pointer from PrevLBA */            /* For the first time round             */            /* We sort this out at the end of the   */            /* for subsequent iterations            */             if ((AllocatedClusters == 0) &&                INT_I64_AreNotEqual(*PrevLBA_p, NullLBA))            {                U32 PrevClusterBlockId = 0;                U32 PrevClusterIdx     = 0;                 stavfs_GetClusterIdx(Device_p, &PrevClusterBlockId, &PrevClusterIdx, PrevLBA_p);                 if (ClusterBlockId == PrevClusterBlockId)                {                    /* The previous LBA is in this block */                    LocalCat_p->Data.Cat[PrevClusterIdx].NextLBA = *FreeLBA_p;                }                else                {                    stavfs_SetClusterNext(Device_p, PrevLBA_p, FreeLBA_p);                }            }                        /* Allocate the Clusters */             do            {                if (INT_I64_AreEqual(LocalCat_p->Data.Cat[ClusterIdx].PrevLBA, InvalidLBA) ||                    INT_I64_AreEqual(LocalCat_p->Data.Cat[ClusterIdx].NextLBA, InvalidLBA))                {                    /* Allocate the specified Cluster */                    LocalCat_p->Data.Cat[ClusterIdx].PrevLBA = *PrevLBA_p;                    if (LastClusterIdx >= 0)                    {                        LocalCat_p->Data.Cat[LastClusterIdx].NextLBA = ThisLBA;                    }                     AllocatedThisBlock++;                    AllocatedClusters++;                    LastClusterIdx = ClusterIdx;                    *PrevLBA_p     = ThisLBA;                }                                INT_I64_AddLit(ThisLBA, Device_p->ClusterSize, ThisLBA);                ClusterIdx++;            }            while ((AllocatedClusters < NumClusters) &&                   (ClusterIdx        < CLUSTERS_PER_BLOCK(Device_p)));             /* Update the Local CAT */             LocalCat_p->Data.FreeClusters -= AllocatedThisBlock;                        /* Update the Master CAT */                        stavfs_UpdateMasterCAT(Device_p, ClusterBlockId, LocalCat_p);                        /* Set the Final Next Pointer */             if (LastClusterIdx < 0)            {                /* We did not allocate anything in this block */                                if (AllocatedClusters > 0)                {                    /* We have allocated somthing in a previous block */                    /* Rewind that block */                                    stavfs_SetClusterNext(Device_p, PrevLBA_p, &NullLBA);                }            }            else if (AllocatedClusters < NumClusters)            {                /* N.B. The Master CAT must be uptodate at this point */                                if (0 < stavfs_GetFreeClusters(Device_p, InUnits, PrevLBA_p, FreeLBA_p))                {                    /* Found some more space */                    LocalCat_p->Data.Cat[LastClusterIdx].NextLBA = *FreeLBA_p;                }                else                {                    /* No more space */                    LocalCat_p->Data.Cat[LastClusterIdx].NextLBA = NullLBA;                    NumClusters = AllocatedClusters;                }            }            else            {                LocalCat_p->Data.Cat[LastClusterIdx].NextLBA = NullLBA;            }                        /* Flush the Local CAT back to disk */             if (ST_NO_ERROR != stavfs_SetLocalCat(LocalCat_p, Device_p))            {                /* The allocation failed */                /* Rewind */                                AllocatedClusters -= AllocatedThisBlock;                NumClusters        = AllocatedClusters;                                LocalCat_p->Data.FreeClusters += AllocatedThisBlock;                                stavfs_UpdateMasterCAT(Device_p, ClusterBlockId, LocalCat_p);                                stavfs_InvalidLocalCat(LocalCat_p);                                stavfs_SetClusterNext(Device_p, PrevLBA_p, &NullLBA);            }        }         stavfs_ReleaseLocalCat(LocalCat_p);    }        return (NumClusters);}/******************************************************************************Function Name : stavfs_FreeClusterChain  Description : Free a chain of clusters in a Cluster Block ending with the                specified Cluster. The chain is scanned backwards from the last                Cluster.   Parameters : LBA_p  is set to the new end of chain (NullLBA if sucessful),                the return value counts the clusters freed******************************************************************************/U32 stavfs_FreeClusterChain(stavfs_Device_t *Device_p, U64 *LBA_p){    ST_ErrorCode_t      Error   = ST_NO_ERROR;    stavfs_MCatCache_t *Cache_p = NULL;        U32 ClusterBlockId = 0;    U32 ClusterIdx     = 0;    U32 NumClusters    = 0;            stavfs_LocalCatCache_t *LocalCat_p = NULL;        assert (Device_p       != NULL);    assert (Device_p->MCat != NULL);    assert (LBA_p          != NULL);        Cache_p = (stavfs_MCatCache_t*)Device_p->MCat;        if (INT_I64_AreNotEqual(*LBA_p, NullLBA) &&        INT_I64_AreNotEqual(*LBA_p, InvalidLBA))    {        /* Check that we are at the end of the chain */         Error = stavfs_WalkTheChain(Device_p, FALSE, LBA_p, NULL);    }        while (INT_I64_AreNotEqual(*LBA_p, NullLBA)    &&           INT_I64_AreNotEqual(*LBA_p, InvalidLBA) &&           (Error == ST_NO_ERROR))    {            /* Find the Local CAT entry for the Free LBA */                stavfs_GetClusterIdx(Device_p, &ClusterBlockId, &ClusterIdx, LBA_p);        if (ST_NO_ERROR == (Error = stavfs_GetLocalCat(Device_p, ClusterBlockId, &LocalCat_p)))        {            /* Check that it is not already free */             if (INT_I64_AreNotEqual(LocalCat_p->Data.Cat[ClusterIdx].PrevLBA, InvalidLBA))            {                U64 LBAOffset;                U64 BaseLBA       = *LBA_p;                U32 BlockClusters = 0;                 stavfs_GetClusterLBA(Device_p, ClusterBlockId, 0, &BaseLBA);                 /* Free the Clusters */                 do                {                    /* Free the specified Cluster */                     /* Get the previous Cluster */                                        *LBA_p = LocalCat_p->Data.Cat[ClusterIdx].PrevLBA;                                        /* Get the Index to the previous Cluster */                                        INT_I64_Sub   (*LBA_p,    BaseLBA,               LBAOffset);                    INT_I64_DivLit(LBAOffset, Device_p->ClusterSize, LBAOffset);                                        /* Free up this cluster */                     LocalCat_p->Data.Cat[ClusterIdx].PrevLBA = InvalidLBA;                    LocalCat_p->Data.Cat[ClusterIdx].NextLBA = InvalidLBA;                                        /* Move to the previous cluster */                     NumClusters++;                    BlockClusters++;                    ClusterIdx = LBAOffset.LSW;                }                while (ClusterIdx < CLUSTERS_PER_BLOCK(Device_p));  /* Valid Index - are we still in this cluster block */                 /* Update the Local CAT */                 LocalCat_p->Data.FreeClusters += BlockClusters;                 if (ST_NO_ERROR != (Error = stavfs_SetLocalCat(LocalCat_p, Device_p)))                {                    /* The allocation failed */                    stavfs_InvalidLocalCat(LocalCat_p);                    NumClusters = 0;                }                else                {                    /* Update the Master CAT entry for the Cluster Block. If we crash                      before this is flushed, fsck will rebuild because the file is                      marked 'being deleted' */                                          U32 M_CatIdx;                     M_CatIdx       = ClusterBlockId % M_CAT_ENTRIES_PER_BLOCK;                    ClusterBlockId = ClusterBlockId / M_CAT_ENTRIES_PER_BLOCK;                     Cache_p->Blocks[ClusterBlockId].Unused2 = 1;  /* Flag Modified */                    Cache_p->Blocks[ClusterBlockId].M_CatData[M_CatIdx] =                            LocalCat_p->Data.FreeClusters;                }            }             /* We are now finished with the Cluster Block */                        stavfs_ReleaseLocalCat(LocalCat_p);        }    } /* Continue with the next Cluster Block */        if  (INT_I64_AreNotEqual(*LBA_p, NullLBA) && INT_I64_AreNotEqual(*LBA_p, InvalidLBA))    {        /* Terminate the chain */                stavfs_SetClusterNext(Device_p, LBA_p, &NullLBA);    }        return (NumClusters);} /******************************************************************************Function Name : stavfs_SetClusterNext  Description : Set the NextLBA for the Cluster.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_SetClusterNext(stavfs_Device_t *Device_p, U64 const *LBA_p, U64 const *NextLBA_p){    ST_ErrorCode_t Error = ST_NO_ERROR;        U32 ClusterBlockId = 0;    U32 ClusterIdx     = 0;            stavfs_LocalCatCache_t *LocalCat_p = NULL;        assert (Device_p != NULL);    assert (LBA_p    != NULL);        /* Find the Local CAT entry for the Free LBA */        stavfs_GetClusterIdx(Device_p, &ClusterBlockId, &ClusterIdx, LBA_p);        if (ST_NO_ERROR != (Error = stavfs_GetLocalCat(Device_p, ClusterBlockId, &LocalCat_p)))    {        /* Failed to get the local CAT */    }    else    {        LocalCat_p->Data.Cat[ClusterIdx].NextLBA = *NextLBA_p;         Error = stavfs_SetLocalCat(LocalCat_p, Device_p);                    stavfs_ReleaseLocalCat(LocalCat_p);    }        return (Error);}/******************************************************************************Function Name : stavfs_GetLocalCat  Description : Cache the local CAT for the Cluster Block.                We increment a reference count to say the cache entry is in use.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_GetLocalCat(stavfs_Device_t *Device_p, U32 ClusterBlockId, stavfs_LocalCatCache_t **ReturnCat_p){    ST_ErrorCode_t Error = ST_NO_ERROR;        stavfs_MCatCache_t     *Cache_p      = NULL;    stavfs_LocalCatCache_t *LocalCat_p   = NULL;    stavfs_LocalCatCache_t *InvalidCat_p = NULL;    stavfs_LocalCatCache_t *OldCat_p     = NULL;        U16 OldestCat = 0;    int idx;        assert(Device_p       != NULL);    assert(Device_p->MCat != NULL);    assert(ReturnCat_p    != NULL);        /* Tick */        Cache_p = (stavfs_MCatCache_t*)Device_p->MCat;    Cache_p->LCatTime++;

⌨️ 快捷键说明

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