AllocateBlock() public method

分配一个新数据块并清空内容
public AllocateBlock ( Byte fill ) : Block
fill Byte
return Block
示例#1
0
文件: INode.cs 项目: bwbwbwbw/vfs
        /// <summary>
        /// 查找指定偏移所在的块,若块不存在则创建
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public Block PrepareBlockAtPosition(UInt32 position)
        {
            UInt32 blockSize     = vfs.GetSuperBlock().data.blockSize;
            UInt32 IndexPerBlock = blockSize / sizeof(UInt32);

            // 直接索引
            if (position < BoundLv0)
            {
                UInt32 totalBlocks = 0;
                UInt32 lv0_index   = position / blockSize;

                totalBlocks += lv0_index + 1;
                UInt32 preserve = GetBlocksToPreserve(totalBlocks);
                //Console.WriteLine("preserve block: {0} (+{1})", totalBlocks, preserve);

                if (preserve > 0)
                {
                    vfs.PreserveBlock(preserve);
                    data.blockPreserved += preserve;
                    //Console.WriteLine("data.blockPreserved = {0}", data.blockPreserved);
                    Save();
                }

                Block lv0_block = new Block(vfs, data.dataBlockId[lv0_index]);
                if (lv0_block.index == UInt32.MaxValue)
                {
                    lv0_block = vfs.AllocateBlock();
                    data.dataBlockId[lv0_index] = lv0_block.index;
                    Save();
                }

                return(lv0_block);
            }
            else if (position < BoundLv1)
            {
                // 一级间接索引
                position -= BoundLv0;

                UInt32 totalBlocks = 0;
                UInt32 lv0_index   = 12;
                UInt32 lv1_index   = position / blockSize;

                totalBlocks += lv0_index + 1;
                totalBlocks += lv1_index + 1;
                UInt32 preserve = GetBlocksToPreserve(totalBlocks);
                //Console.WriteLine("preserve block: {0} (+{1})", totalBlocks, preserve);

                if (preserve > 0)
                {
                    vfs.PreserveBlock(preserve);
                    data.blockPreserved += preserve;
                    //Console.WriteLine("data.blockPreserved = {0}", data.blockPreserved);
                    Save();
                }

                Block lv0_block = new Block(vfs, data.dataBlockId[lv0_index]);
                if (lv0_block.index == UInt32.MaxValue)
                {
                    lv0_block = vfs.AllocateBlock(0xFF);
                    data.dataBlockId[lv0_index] = lv0_block.index;
                    Save();
                }

                Block lv1_block = new Block(vfs, lv0_block.Read <UInt32>(lv1_index * sizeof(UInt32)));
                if (lv1_block.index == UInt32.MaxValue)
                {
                    lv1_block = vfs.AllocateBlock();
                    lv0_block.Write(lv1_index * sizeof(UInt32), lv1_block.index);
                }

                return(lv1_block);
            }
            else
            {
                // 二级间接索引
                position -= BoundLv1;

                UInt32 totalBlocks = 0;
                UInt32 lv0_index   = 13;
                UInt32 lv1_index   = (position / blockSize) / IndexPerBlock;
                UInt32 lv2_index   = (position / blockSize) % IndexPerBlock;

                //Console.WriteLine("position = {0}, lv0_index = {1}, lv1_index = {2}, lv2_index = {3}", position, lv0_index, lv1_index, lv2_index);

                totalBlocks += lv0_index + 1;
                totalBlocks += IndexPerBlock + 1;
                totalBlocks += (IndexPerBlock + 1) * lv1_index;
                totalBlocks += lv2_index + 1;
                UInt32 preserve = GetBlocksToPreserve(totalBlocks);
                //Console.WriteLine("preserve block: {0} (+{1})", totalBlocks, preserve);

                if (preserve > 0)
                {
                    vfs.PreserveBlock(preserve);
                    data.blockPreserved += preserve;
                    //Console.WriteLine("data.blockPreserved = {0}", data.blockPreserved);
                    Save();
                }

                Block lv0_block = new Block(vfs, data.dataBlockId[lv0_index]);
                if (lv0_block.index == UInt32.MaxValue)
                {
                    lv0_block = vfs.AllocateBlock(0xFF);
                    data.dataBlockId[lv0_index] = lv0_block.index;
                    Save();
                }

                Block lv1_block = new Block(vfs, lv0_block.Read <UInt32>(lv1_index * sizeof(UInt32)));
                if (lv1_block.index == UInt32.MaxValue)
                {
                    lv1_block = vfs.AllocateBlock(0xFF);
                    lv0_block.Write(lv1_index * sizeof(UInt32), lv1_block.index);
                }

                Block lv2_block = new Block(vfs, lv1_block.Read <UInt32>(lv2_index * sizeof(UInt32)));
                if (lv2_block.index == UInt32.MaxValue)
                {
                    lv2_block = vfs.AllocateBlock(0xFF);
                    lv1_block.Write(lv2_index * sizeof(UInt32), lv2_block.index);
                }

                return(lv2_block);
            }
        }