亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

利用yaffs_GetTnode怎么映射文件地址

發布時間:2021-07-21 09:20:08 來源:億速云 閱讀:156 作者:Leah 欄目:互聯網科技

今天就跟大家聊聊有關利用yaffs_GetTnode怎么映射文件地址,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

yaffs文件系統在更新文件數據的時候,會分配一塊新的chunk,也就是說,同樣的文件偏移地址,在該地址上的數據更新前和更新后,其對應的flash上的存儲地址是不一樣的。那么,如何根據文件內偏移地址確定flash存儲地址呢?最容易想到的辦法,就是在內存中維護一張映射表。由于 flash基本存儲單位是chunk,因此,只要將以chunk描述的文件偏移量作為表索引,將flash chunk序號作為表內容,就可以解決該問題了。但是這個方法有幾個問題,首先就是在做seek操作的時候,要從表項0開始按序搜索,對于大文件會消耗很多時間;其次是在建立映射表的時候,無法預計文件大小的變化,于是就可能在后來的操作中頻繁釋放分配內存以改變表長,造成內存碎片。yaffs的解決方法是將這張大的映射表拆分成若干個等長的小表,并將這些小表組織成樹的結構,方便管理。我們先看小表的定義:

struct yaffs_tnode {

struct yaffs_tnode *internal[YAFFS_NTNODES_INTERNAL];

};

YAFFS_NTNODES_INTERNAL定義為(YAFFS_NTNODES_LEVEL0 / 2),而YAFFS_NTNODES_LEVEL0定義為16,所以這實際上是一個長度為8的指針數組。不管是葉子節點還是非葉節點,都是這個結構。當節點為非葉節點時,數組中的每個元素都指向下一層子節點;當節點為葉子節點時,該數組拆分為16個16位長的短整數(也有例外,后面會說到),該短整數就是文件內容 在flash上的存儲位置(即chunk序號)。至于如何通過文件內偏移找到對應的flash存儲位置,源代碼所附文檔(Development/yaffs/Documentation/yaffs-notes2.html)已經有說明,俺就不在此處饒舌了。下面看具體函數。

為了行文方便,后文中將yaffs_Tnode這個指針數組稱為“一組”Tnode,而將數組中的每個元素稱為“一個”Tnode。樹中的每個節點,都是“一組”Tnode。

先看映射樹的節點的分配。

struct yaffs_tnode *yaffs_get_tnode(struct yaffs_dev *dev)

{

struct yaffs_tnode *tn = yaffs_alloc_raw_tnode(dev);

if (tn) {

memset(tn, 0, dev->tnode_size);

dev->n_tnodes++;

}

dev->checkpoint_blocks_required = 0;/* force recalculation */

return tn;

}

調用yaffs_GetTnodeRaw分配節點,然后將得到的節點初始化為零。

static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device * dev)

 {

yaffs_Tnode *tn = NULL;

/* If there are none left make more */

if (!dev->freeTnodes) {

yaffs_CreateTnodes(dev, YAFFS_ALLOCATION_NTNODES);

 }

當前所有空閑節點組成一個鏈表,dev->freeTnodes是這個鏈表的表頭。我們假定已經沒有空閑節點可用,需通過yaffs_CreateTnodes創建一批新的節點。

static int yaffs_CreateTnodes(yaffs_Device * dev, int nTnodes)

 {

 ......

tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;

newTnodes = YMALLOC(nTnodes * tnodeSize);

mem = (__u8 *)newTnodes;

}

(其實在最新版本的yaffs中已經加入了slab緩沖區,這樣提高了效率)上面說過,葉節點中一個Tnode的位寬默認為16位,也就是可以表示65536個chunk。對于時下的大容量flash,chunk的大小為2K,因 此在默認情況下yaffs2所能尋址的最大flash空間就是128M。為了能將yaffs2用于大容量flash上,代碼作者試圖通過兩種手段解決這個問題。第一種手段就是這里的dev->tnodeWidth,通過增加單個Tnode的位寬,就可以增加其所能表示的最大chunk Id;另一種手段是我們后面將看到的chunk group,通過將若干個chunk合成一組用同一個id來表示,也可以增加系統所能尋址的chunk范圍。

俺為了簡單,分析的時候不考慮這兩種情況,因此tnodeWidth取默認值16,也不考慮將多個chunk合成一組的情況,只在遇到跟這兩種情況有關的代碼時作簡單說明。

在32位的系統中,指針的寬度為32位,而chunk id的寬度為16位,因此相同大小的Tnode組,可以用來表示N個非葉Tnode(作為指針使用),也可以用來表示N * 2個葉子Tnode(作為chunk id使用)。代碼中分別用YAFFS_NTNODES_INTERNAL和YAFFS_NTNODES_LEVEL0來表示。前者取值為8,后者取值為16。從這里我們也可以看出若將yaffs2用于64位系統需要作哪些修改。 針對上一段敘述的問題,俺以為在內存不緊張的情況下,不如將葉節點Tnode和非葉節點Tnode都設為一個指針的長度。分配得到所需的內存后,就將這些空閑空間組成Tnode鏈表:

for(i = 0; i < nTnodes -1; i++) {

curr = (yaffs_Tnode *) &mem[i * tnodeSize];

next = (yaffs_Tnode *) &mem[(i+1) * tnodeSize];

curr->internal[0] = next;

}

每組Tnode的第一個元素作為指針指向下一組Tnode。完成鏈表構造后,還要遞增統計量,并將新得到的Tnodes掛入一個全局管理鏈表yaffs_TnodeList:

dev->nFreeTnodes += nTnodes;

dev->nTnodesCreated += nTnodes;

tnl = YMALLOC(sizeof(yaffs_TnodeList));

if (!tnl) {

T(YAFFS_TRACE_ERROR, (TSTR ("yaffs: Could not add tnodes to management list" TENDSTR)));

} else {

tnl->tnodes = newTnodes;

tnl->next = dev->allocatedTnodeList;

dev->allocatedTnodeList = tnl;

 }

回到yaffs_GetTnodeRaw,創建了若干組新的Tnode以后,從中切下所需的Tnode,并修改空閑鏈表表頭指針:

if (dev->freeTnodes) {

tn = dev->freeTnodes;

dev->freeTnodes = dev->freeTnodes->internal[0];

dev->nFreeTnodes--;

 }

看完上述內容,你們對利用yaffs_GetTnode怎么映射文件地址有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

连江县| 崇文区| 东乌珠穆沁旗| 永川市| 安图县| 鄂托克前旗| 信宜市| 孟津县| 郎溪县| 巴林右旗| 白山市| 永和县| 怀仁县| 娱乐| 茂名市| 隆化县| 平顶山市| 阿鲁科尔沁旗| 达孜县| 稷山县| 柳江县| 凉山| 华安县| 茌平县| 武冈市| 丘北县| 宣威市| 林芝县| 瑞丽市| 夏河县| 加查县| 弥勒县| 新蔡县| 黄梅县| 宣恩县| 呼玛县| 石景山区| 工布江达县| 喀什市| 余庆县| 古田县|