private void LoadBlocks() { // read data secvtors from disk and create virtual blocks in memory //check if cahce is up to date if (blocks != null) { return; } //instantiate an empty cache blocks = new List <VirtualBlock>(); //loop through data sectors for this file int nextDataSectorAt = DataSectorAt; while (nextDataSectorAt != 0) { //read sector DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(nextDataSectorAt)); //create virtual block to cache VirtualBlock block = new VirtualBlock(drive, nextDataSectorAt, dataSector); //add block to cache blocks.Add(block); //get the address of the next daa scetor nextDataSectorAt = dataSector.NextSectorAt; } }
private void CommitChildren() { if (children != null) { // Write changes to the in-memory cache to disk // so that what is in the cache and on the disk is the same // Speciffically, write the list of children back to disk dor this directory // in the directory's data sector! // Create a list of children node sectors, in bytes byte[] rawList = new byte[drive.BytesPerDataSector]; int i = 0; foreach (VirtualNode child in children.Values) { int sectorAt = child.nodeSector; BitConverter.GetBytes(sectorAt).CopyTo(rawList, i); i += 4; // 4 byte integers are being copied to the array } // write the bytes to the directory's DATA_SECTOR // by replacing it's data bytes with the new list int dataSectorAt = sector.FirstDataAt; DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(dataSectorAt)); dataSector.DataBytes = rawList; drive.Disk.WriteSector(dataSectorAt, dataSector.RawBytes); // Update the number of children in the dir's node on disk (sector as DIR_NODE).EntryCount = children.Count; drive.Disk.WriteSector(nodeSector, sector.RawBytes); } }
private void CommitChildren() { //write list of this dir's children back to disk //check if cache has data if no data return if (children == null) { return; } //allocate list of children sector addresses byte[] childAddresses = GetChildAddresses(); //write the sector addesses list to directory's data sector DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(DataSectorAt)); dataSector.DataBytes = childAddresses; drive.Disk.WriteSector(DataSectorAt, dataSector.RawBytes); byte[] dataBytes = new byte[dataSector.DataBytes.Length]; childAddresses.CopyTo(dataBytes, 0); dataSector.DataBytes = dataBytes; drive.Disk.WriteSector(DataSectorAt, dataSector.RawBytes); //update number of children entries for this dir (sector as DIR_NODE).EntryCount = ChildCount; drive.Disk.WriteSector(nodeSector, sector.RawBytes); }
private void LoadChildren() { //test if we already have everything in cache? if (children != null) { return; } //create empty cache children = new Dictionary <string, VirtualNode>(); //read this dir's data sector DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(DataSectorAt)); //create virtual nodes for each child and add to children dictionary byte[] data = dataSector.DataBytes; for (int i = 0; i < ChildCount; i++) { int childAt = BitConverter.ToInt32(data, i * 4); NODE childNodeSector = NODE.CreateFromBytes(drive.Disk.ReadSector(childAt)); VirtualNode childNode = new VirtualNode(drive, childAt, childNodeSector, this); children.Add(childNode.Name, childNode); } }
public void Delete() { if (IsDirectory) { //nuke children LoadChildren(); foreach (VirtualNode child in children.Values.ToArray()) { child.Delete(); } CommitChildren(); } // make sectors free! //overwirte node sector FREE_SECTOR freeSector = new FREE_SECTOR(drive.Disk.BytesPerSector); drive.Disk.WriteSector(nodeSector, freeSector.RawBytes); //overwrite data sectors int lba = DataSectorAt; while (lba != 0) { DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(lba)); drive.Disk.WriteSector(lba, freeSector.RawBytes); lba = dataSector.NextSectorAt; } // remove this node from it's parent node parent.LoadChildren(); parent.children.Remove(Name); parent.CommitChildren(); }
public void Delete() { /* make sectors free! * - wipe data for this node from the disk * - wipe this node from parent directory from the disk * - remove this node from it's parent node */ // Don't try to nuke the root! if (parent == null) { throw new Exception("Can't delete the root!"); } // Recurse into directory contents and delete children if (IsDirectory) { LoadChildren(); // Loop throught a copy of the children cahce and delete each foreach (VirtualNode child in children.Values.ToArray()) { child.Delete(); } // NOTE: do not need to call CommitChildren(); } // Replace data sector(s) with free sector(s) FREE_SECTOR free = new FREE_SECTOR(drive.Disk.BytesPerSector); int dataSectorAt = sector.FirstDataAt; while (dataSectorAt != 0) { // Read the data sector om and save nextSectorAt DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(dataSectorAt)); int nextDataSectorAt = dataSector.NextSectorAt; // Replace it drive.Disk.WriteSector(dataSectorAt, free.RawBytes); // Next one dataSectorAt = nextDataSectorAt; } // Replace node sector with free sector drive.Disk.WriteSector(nodeSector, free.RawBytes); // Remove ourself from our parent and commit paren'ts list of children parent.LoadChildren(); parent.children.Remove(Name); parent.CommitChildren(); }
private void LoadChildren() { // Ensure that the children cache is correctly put in memory (i.e. reflects what's on the disk) // Assume if the cache exsists, it is correct at the moment // So, we need to call CommitChildren() if (children == null) { // Create the cache itself children = new Dictionary <string, VirtualNode>(); // Read the list of children for this directory from disk // Instantiate a VirtualNode for each [child?] and add them to the children cache. // Read the data sector for this directory DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(sector.FirstDataAt)); // Extract the list of children from the sata sector byte[] rawList = dataSector.DataBytes; // Foreach child in the list... for (int i = 0; i < ChildCount; i++) { // Getthe child's sector address int childSectorAt = BitConverter.ToInt32(rawList, i * 4); // Read its sector from disk // Check if it's a file or directory byte[] childNodeBytes = drive.Disk.ReadSector(childSectorAt); NODE childSector; if (SECTOR.GetTypeFromBytes(childNodeBytes) == SECTOR.SectorType.DIR_NODE) { childSector = DIR_NODE.CreateFromBytes(drive.Disk.ReadSector(childSectorAt)); } else if (SECTOR.GetTypeFromBytes(childNodeBytes) == SECTOR.SectorType.FILE_NODE) { childSector = FILE_NODE.CreateFromBytes(drive.Disk.ReadSector(childSectorAt)); } else { throw new Exception("Unexpected sector type whe reading directory's children!"); } // Construct a VirtualNode VirtualNode childNode = new VirtualNode(drive, childSectorAt, childSector, this); // Add the VirtualNode to the children cache children.Add(childNode.Name, childNode); } } }
private void LoadChildren() { if (children == null) { children = new Dictionary <string, VirtualNode>(); DATA_SECTOR data = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(sector.FirstDataAt)); for (int i = 0; i < ChildCount; i++) { int childAddress = BitConverter.ToInt32(data.DataBytes, i * 4); NODE childSector = NODE.CreateFromBytes(drive.Disk.ReadSector(childAddress)); VirtualNode vn = new VirtualNode(drive, childAddress, childSector, this); children.Add(childSector.Name, vn); } } }
private void LoadBlocks() { if (blocks == null) { blocks = new List <VirtualBlock>(); // find data sectors int dataSectorAddr = sector.FirstDataAt; while (dataSectorAddr != 0) { DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(dataSectorAddr)); VirtualBlock block = new VirtualBlock(drive, dataSectorAddr, dataSector); blocks.Add(block); // Go on to next data sector dataSectorAddr = dataSector.NextSectorAt; } } }
public void Mount(DiskDriver disk, string mountPoint) { // read drive info from disk, load root node and connect to mountPoint // for the first mounted drive, expect mountPoint to be named "/", FSConstants.ROOT_DIR_NAME, as the root try { // Step 1: Read infor from the disk to understand it's directory structure // Read DRIVE_INFO from FRIVE_INFO_SECTOR DRIVE_INFO di = DRIVE_INFO.CreateFromBytes(disk.ReadSector(DRIVE_INFO_SECTOR)); DIR_NODE dn = DIR_NODE.CreateFromBytes(disk.ReadSector(di.RootNodeAt)); DATA_SECTOR ds = DATA_SECTOR.CreateFromBytes(disk.ReadSector(dn.FirstDataAt)); // Step 2: Join th new disk into the virtual file system structure, at the mount point. // Create a VistualDrive for the disk VirtualDrive vd = new VirtualDrive(disk, DRIVE_INFO_SECTOR, di); if (rootNode == null) { // Create a VirtualNode to represent the root dictionaru, at the mount point. // Set the VFS's root node, if this is the first disk to be mounted. rootNode = new VirtualNode(vd, di.RootNodeAt, dn, null); } else { // TODO: Extra Credit: Handle 2nd dick mounted to exsisting VFS // Create a virtual node for this new disk's root // "join" the new node to the exsisting node structure at the mount point } // Add a new VirtualDrive to drives dictionary, using te mountPoint as the key drives.Add(mountPoint, vd); } catch (Exception ex) { throw new Exception("Failed to mount disk"); } }
private void LoadBlocks() { // Read each block if not alread in cache if (blocks == null) { // The cache is currently empty, so create and fill it! blocks = new List <VirtualBlock>(); // Read the data sectors off the disk for this file and... int dataSectorAt = sector.FirstDataAt; while (dataSectorAt != 0) { // ...create VirtualBlocks for them and add to the cache DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(dataSectorAt)); VirtualBlock vb = new VirtualBlock(drive, dataSectorAt, dataSector); blocks.Add(vb); // Go on to the next data sector dataSectorAt = dataSector.NextSectorAt; } } }