public VirtualNode CreateDirectoryNode(string name)
        {
            LoadChildren(); //insure child cached is full
            if (children.ContainsKey(name))
            {
                throw new Exception("Another child with that name already exists");
            }

            //where do we store new dir? which sector?
            //find 2 free sectors

            int[] sectors = drive.GetNextFreeSectors(2);
            int   newDirectoryNodeSectorAt = sectors[0];
            int   newDirDataSectorAt       = sectors[1];

            //creat new dir on disk
            DIR_NODE newDirNodeSector = new DIR_NODE(drive.Disk.BytesPerSector, newDirDataSectorAt, name, 0);

            drive.Disk.WriteSector(newDirectoryNodeSectorAt, newDirNodeSector.RawBytes);

            //creat a data sector for dir
            DATA_SECTOR newDirDataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, null);

            drive.Disk.WriteSector(newDirDataSectorAt, newDirDataSector.RawBytes);

            //creat virtual node
            VirtualNode newDirectory = new VirtualNode(drive, newDirectoryNodeSectorAt, newDirNodeSector, this);

            //add dir to parent
            children.Add(name, newDirectory);
            CommitChildren();

            return(newDirectory);
        }
示例#2
0
        public static void ExtendBlocks(VirtualDrive drive, List <VirtualBlock> blocks, int initialFileLength, int finalFileLength)
        {
            // if current number of blocks is too small, then append more blocks as needed
            // allocate free sectors for each new block
            int finalBlockCount  = BlocksNeeded(drive, finalFileLength);
            int additionalBlocks = finalBlockCount - blocks.Count;

            if (additionalBlocks > 0)
            {
                int[] freeSectorAddresses = drive.GetNextFreeSectors(additionalBlocks);

                VirtualBlock prevBlock = blocks.Last();
                foreach (int i in freeSectorAddresses)
                {
                    // connect sectors
                    prevBlock.sector.NextSectorAt = i;
                    prevBlock.dirty = true;

                    // create new block
                    DATA_SECTOR  dataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, new byte[] { 0 });
                    VirtualBlock newBlock   = new VirtualBlock(drive, i, dataSector, true);

                    // add to the end of block list
                    blocks.Add(newBlock);

                    // prepare next block
                    prevBlock = newBlock;
                }
            }
        }
示例#3
0
        public VirtualNode CreateDirectoryNode(string name)
        {
            // Only create children if we're a directory
            if (!IsDirectory)
            {
                throw new Exception("Must be a directory to create children!");
            }

            // read current list of children
            LoadChildren();

            // allocate a new DIR_NODE and DATA_SECTOR on the disk

            // Find the first two FREE_SECTORs on the disk
            int[] freeSectors = drive.GetNextFreeSectors(2);

            //DIR_NODE
            DIR_NODE dirSector = new DIR_NODE(drive.Disk.BytesPerSector, freeSectors[1], name, 0);

            drive.Disk.WriteSector(freeSectors[0], dirSector.RawBytes);

            //DATA_SECTOR
            DATA_SECTOR dataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, new byte[] { 0 });

            drive.Disk.WriteSector(freeSectors[1], dataSector.RawBytes);

            // Create a new virtual node
            VirtualNode newNode = new VirtualNode(drive, freeSectors[0], dirSector, this);

            // Add it to its parent
            children.Add(name, newNode);

            CommitChildren();

            // Return new node
            return(newNode);
        }
示例#4
0
        private VirtualNode CreateNode(string name, SECTOR.SectorType type)
        {
            // Create a new file, both on disk and in memory
            // type may be DIR_NODE or FILE_NODE

            if (type != SECTOR.SectorType.DIR_NODE && type != SECTOR.SectorType.FILE_NODE)
            {
                throw new Exception("Illegal type, CreateNode only take DIR_NODE and FILE_NODE types!");
            }

            // Get 2 free sectors
            // First Sector: NODE, containing metadata
            // Second Sector: DATA_SECTOR, containing the new node's data
            int[] freeSectors = drive.GetNextFreeSectors(2);
            if (freeSectors == null || freeSectors.Length != 2)
            {
                throw new Exception("Can't find 2 free sectors for a new " +
                                    (type == SECTOR.SectorType.DIR_NODE ? "directory" : "file") + "!");
            }
            int newNodeAt       = freeSectors[0];
            int newDataSectorAt = freeSectors[1];

            // Create the node sector on disk, initially empty
            int  bps     = drive.Disk.BytesPerSector;
            NODE newNode = (type == SECTOR.SectorType.DIR_NODE
                ? new DIR_NODE(bps, newDataSectorAt, name, 0) as NODE
                : new FILE_NODE(bps, newDataSectorAt, name, 0) as NODE);

            //Create the DATA_SECTOR sector on disk for the new directory
            // initially empty data sector for this new directory
            DATA_SECTOR dataSector = new DATA_SECTOR(bps, 0, null);

            // Write sectors to disk
            drive.Disk.WriteSector(newNodeAt, newNode.RawBytes);
            drive.Disk.WriteSector(newDataSectorAt, dataSector.RawBytes);

            // Create a new VirtualNode instance
            VirtualNode newVirtualNode = new VirtualNode(drive, newNodeAt, newNode, this);

            // Add this to the in-memory cache of this directory's children
            LoadChildren();
            children.Add(name, newVirtualNode);
            CommitChildren();

            // Return the new VirtualNode instace
            return(newVirtualNode);
        }
示例#5
0
        public static void ExtendBlocks(VirtualDrive drive, List <VirtualBlock> blocks, int initialFileLength, int finalFileLength)
        {
            // If the file length has grown...
            if (finalFileLength > initialFileLength)
            {
                // ...and if we need ore blocks...
                int finalBlockCount = BlocksNeeded(drive, finalFileLength);
                if (finalBlockCount > blocks.Count)
                {
                    // how many new blocks to do what we need to do?
                    int neededNewBlocks = finalBlockCount - blocks.Count;

                    // Get needed number of free sectors
                    int[] freeSectors = drive.GetNextFreeSectors(neededNewBlocks);

                    // Allocate and connect them up
                    VirtualBlock previousBlock = blocks.Last();
                    for (int i = 0; i < neededNewBlocks; i++)
                    {
                        // write out the previousBlock to connect it to this new block
                        previousBlock.sector.NextSectorAt = freeSectors[i];
                        previousBlock.dirty = true;


                        // instantiate new DATA_SECTOR
                        DATA_SECTOR newDataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, null);

                        // instantiate new VirtualBlock
                        VirtualBlock newBlock = new VirtualBlock(drive, freeSectors[i], newDataSector, true);

                        // Add new VirtualBlocks to the list of blocks
                        blocks.Add(newBlock);

                        // Update prev block
                        previousBlock = newBlock;
                    }
                }
            }
        }
        public static void ExtendBlocks(VirtualDrive drive, List <VirtualBlock> blocks, int initialFileLength, int finalFileLength)
        {
            //given initial list of blocks in memory add more block if necessary to grow file from initial to final length

            //determine # of blocks eeded for the file
            int currentBlockCount = blocks.Count;
            int finalBlockCount   = BlocksNeeded(drive, finalFileLength);

            if (finalBlockCount <= currentBlockCount)
            {
                return;
            }

            //get sector addresses for new blocks
            int additionalBlocks = finalBlockCount - currentBlockCount;

            int[] additionalBlockAddresses = drive.GetNextFreeSectors(additionalBlocks);

            //update the last current block to point to the first new block
            blocks[currentBlockCount - 1].sector.NextSectorAt = additionalBlockAddresses[0];
            blocks[currentBlockCount - 1].dirty = true;

            //Allocate each block as a sector
            for (int i = 0; i < additionalBlocks; i++)
            {
                //wcreate new data sectorin memory
                DATA_SECTOR dataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, null);

                //set this sector's link to the data sector, if there is a next sector
                if (i < additionalBlocks - 1)
                {
                    dataSector.NextSectorAt = additionalBlockAddresses[i + 1];
                }

                //add new virtualblock to list which is drity so it will be writen to disk when commited
                blocks.Add(new VirtualBlock(drive, additionalBlockAddresses[i], dataSector, true));
            }
        }