public VirtualNode CreateFileNode(string name) { if (!IsDirectory) { throw new Exception("Must be a directory to create children!"); } // read current list of children LoadChildren(); // Find the first two FREE_SECTORs on the disk int[] freeSectors = drive.GetNextFreeSectors(2); // allocate a new FILE_NODE and DATA_SECTOR on the disk //FILE_NODE FILE_NODE fileSector = new FILE_NODE(drive.Disk.BytesPerSector, freeSectors[1], name, 0); drive.Disk.WriteSector(freeSectors[0], fileSector.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], fileSector, this); // Add it to its parent children.Add(name, newNode); CommitChildren(); return(newNode); }
public void Unmount(string mountPoint) { // look up the drive and remove it's mountPoint if (!drives.ContainsKey(mountPoint)) { throw new Exception("Cannot unmount drive that has not been mounted!"); } // Remove from the drive list VirtualDrive vd = drives[mountPoint]; drives.Remove(mountPoint); // Check if this drive was the first mounted drive... if (mountPoint == FSConstants.ROOT_DIR_NAME) { // If mounted first drive, blank out the root node rootNode = null; } else { // else it;s a2nd, 3rd, etc... // TODO: extra credit } }
public void Move(VirtualNode destination) { // remove this node from it's current parent and attach it to the new one // update the directory information for both parents on disk // Don't try and move the root! if (parent == null) { throw new Exception("Can't Move the root!"); } // Validate destination if (destination == null || !destination.IsDirectory) { throw new Exception("Invalid destination for Move!"); } // Remove node from current parent parent.LoadChildren(); parent.children.Remove(Name); parent.CommitChildren(); // Set parent to new parent parent = destination; // Add node to new parent parent.LoadChildren(); parent.children.Add(Name, this); parent.CommitChildren(); }
public VirtualNode CreateFileNode(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 file? which sector? //find 2 free sectors int[] sectors = drive.GetNextFreeSectors(2); int newFileNodeSectorAt = sectors[0]; int newFileDataSectorAt = sectors[1]; //creat new on disk FILE_NODE newFileNodeSector = new FILE_NODE(drive.Disk.BytesPerSector, newFileDataSectorAt, name, 0); drive.Disk.WriteSector(newFileNodeSectorAt, newFileNodeSector.RawBytes); //creat a data sector for dir DATA_SECTOR newFileDataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, null); drive.Disk.WriteSector(newFileDataSectorAt, newFileDataSector.RawBytes); //creat virtual node VirtualNode newFile = new VirtualNode(drive, newFileNodeSectorAt, newFileNodeSector, this); //add dir to parent children.Add(name, newFile); CommitChildren(); return(newFile); }
public void Delete() { node.Delete(); node = null; // TODO: Deal with null nodes in the rest f the logial file systems objects // e.g. Move() }
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 FSEntry Find(string path) { // good: /foo/bar, /foo/bar/ // bad: foo, foo/bar, //foo/bar, /foo//bar, /foo/../foo/bar VirtualNode current = virtualFileSystem.RootNode; string[] elements = path.Split(PATH_SEPARATOR); foreach (string element in elements.Skip(1)) { VirtualNode child = current.GetChild(element); if (child != null) { current = child; } else { return(null); } } FSEntry result = null; if (current.IsDirectory) { result = new SimpleDirectory(current); } else { result = new SimpleFile(current); } return(result); }
public FSEntry Find(string path) { // good: /foo/bar, /foo/bar/ // bad: foo, foo/bar, //foo/bar, /foo//bar, /foo/../foo/bar // Make sure path starts correctly if (path.Length <= 0 || path[0] != PATH_SEPARATOR) { //Console.WriteLine("invalid path"); return(null); } if (path.Length == 1) { return(new SimpleDirectory(virtualFileSystem.RootNode)); } try { string[] elements = path.Split(PATH_SEPARATOR); VirtualNode currentNode = virtualFileSystem.RootNode; for (int i = 1; i < elements.Length; i++) { if (currentNode.IsFile) { //Console.WriteLine("File, not directory"); return(null); } else { if (elements[i].Length != 0) { // Check if valid child currentNode = currentNode.GetChild(elements[i]); if (currentNode == null) { //Console.WriteLine("can't find child..."); return(null); } } else { // Allow trailing path separator if (i < elements.Length - 1) { //Console.WriteLine("empty path element!"); return(null); } } } } return(currentNode.IsDirectory ? (FSEntry) new SimpleDirectory(currentNode) : new SimpleFile(currentNode)); } catch (Exception ex) { Console.WriteLine("Caught exception in simplefs.find(): " + ex.Message); } return(null); }
private List <VirtualBlock> blocks; // cache of file blocks public VirtualNode(VirtualDrive drive, int nodeSector, NODE sector, VirtualNode parent) { this.drive = drive; this.nodeSector = nodeSector; this.sector = sector; this.parent = parent; this.children = null; // initially empty cache this.blocks = null; // initially empty cache }
public void Unmount(string mountPoint) { // remove drive mountPoint and root node drives.Remove(mountPoint); //rework for when multiples drives are mounted *look up by mount point rootNode = null; }
public FSEntry Find(string path) { // Follow the path down and return a ne directory or file // wrapping the node // Path must be an absolute path, including the root / // Simplifying assumption... not allowing ".." or "." in our paths // good: /foo/bar, /foo/bar/ // bad: foo, foo/bar, //foo/bar, /foo//bar, /foo/../foo/bar if (String.IsNullOrEmpty(path) || path[0] != '/') { throw new Exception("Hey! Invalid path!"); } // If path ends in a trailing slash, then... bool mustBeDirectory = false; if (path.EndsWith(PATH_SEPARATOR.ToString())) { // Remove the trailing slash and remember that we expect a directory path = path.Substring(0, path.Length - 1); mustBeDirectory = true; } // Walk through path and find the result string[] elements = path.Split(PATH_SEPARATOR); VirtualNode current = virtualFileSystem.RootNode; foreach (string element in elements.Skip(1)) // Skips the first blank { // We need to dig deeper, but we do not have a directory, so return null if (!current.IsDirectory) { return(null); } try { // Get the named child from the directory VirtualNode child = current.GetChild(element); current = child; } catch (Exception) { // If we can't find the child, return null return(null); } } if (mustBeDirectory && !current.IsDirectory) { return(null); } return(current.IsDirectory ? new SimpleDirectory(current) as FSEntry : new SimpleFile(current)); }
public void Move(VirtualNode destination) { // remove this node from it's current parent and attach it to it's new parent // update the directory information for both parents on disk VirtualNode currentParent = parent; parent.LoadChildren(); parent.children.Remove(Name); destination.LoadChildren(); destination.children.Add(Name, this); parent = destination; currentParent.CommitChildren(); destination.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 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); }
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); } } }
public void Unmount(string mountPoint) { // look up the drive and remove it's mountPoint if (!drives.ContainsKey(mountPoint)) { throw new Exception("No drive mounted at mount point: " + mountPoint); } // Unset root node if needed VirtualDrive drive = drives.Where(x => x.Key == mountPoint).FirstOrDefault().Value; if (rootNode.Drive == drive) { rootNode = null; } drives.Remove(mountPoint); }
public void Mount(DiskDriver disk, string mountPoint) { // for the first mounted drive, expect mountPoint to be named FSConstants.PATH_SEPARATOR as the root if (drives.Count == 0 && mountPoint != FSConstants.PATH_SEPARATOR.ToString()) { throw new Exception("Expected first mounted dist to be at root directory!"); } // read drive info from disk, load root node and connect to mountPoint DRIVE_INFO driveInfo = DRIVE_INFO.CreateFromBytes(disk.ReadSector(DRIVE_INFO_SECTOR)); VirtualDrive drive = new VirtualDrive(disk, DRIVE_INFO_SECTOR, driveInfo); DIR_NODE rootSector = DIR_NODE.CreateFromBytes(disk.ReadSector(ROOT_DIR_SECTOR)); rootNode = new VirtualNode(drive, ROOT_DIR_SECTOR, rootSector, null); drives.Add(mountPoint, drive); }
public void Move(VirtualNode destination) { // remove this node from it's current parent and attach it to it's new parent // update the directory information for both parents on disk if (!destination.IsDirectory) { throw new Exception("Destination must be a directory!"); } destination.LoadChildren(); destination.children.Add(Name, this); destination.CommitChildren(); parent.LoadChildren(); parent.children.Remove(Name); parent.CommitChildren(); parent = destination; }
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 //read drive info for disk to determin what sector contains its root node DRIVE_INFO diSector = DRIVE_INFO.CreateFromBytes(disk.ReadSector(DRIVE_INFO_SECTOR)); int rootNodeAt = diSector.RootNodeAt; VirtualDrive drive = new VirtualDrive(disk, DRIVE_INFO_SECTOR, diSector); DIR_NODE rootNodeSector = DIR_NODE.CreateFromBytes(disk.ReadSector(rootNodeAt)); if (rootNode == null) { rootNode = new VirtualNode(drive, rootNodeAt, rootNodeSector, null); } drives.Add(mountPoint, drive); }
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"); } }
public void Close() { // Detatch the stream from the underlying file VirtualNode node = null; }
public VirtualFS() { this.drives = new Dictionary <string, VirtualDrive>(); this.rootNode = null; }
protected SimpleEntry(VirtualNode node) { this.node = node; }
public SimpleDirectory(VirtualNode node) : base(node) { }
public void Close() { //remove access to file node, prevent future read/write calls on this stream node = null; }
public SimpleStream(VirtualNode node) { this.node = node; }
public SimpleFile(VirtualNode node) : base(node) { }