public void RenameNode(BobFsNode node, string name) { DeleteNode(node); LinkNode(name, node); node.NumLinks--; node.Commit(); }
// TODO: We should update the inode bitmap if necessary public void DeleteNode(BobFsNode node) { if (!IsDirectory) { throw new InvalidOperationException("Current node is not a directory."); } int runner = 0; DirEntry entry = new DirEntry(); while (runner < Size) { entry.ReadFrom(this, runner); if (entry.Inum == node.Inum) { int read; while ((read = ReadAll(runner + (8 + entry.Name.Length), _tmpBuffer, 0, BobFs.BlockSize)) != 0) { WriteAll(runner, _tmpBuffer, 0, read); runner += read; } Size -= (uint)(8 + entry.Name.Length); return; } runner += 8 + entry.Name.Length; // Point to next direntry's inum } throw new Exception("Node not found."); }
public void Format() { // Setup superblock Array.Clear(_tmpBuffer, 0, BlockSize); Encoding.ASCII.GetBytes(HeaderMagic).CopyTo(_tmpBuffer, 0); BitConverter.GetBytes((int)0).CopyTo(_tmpBuffer, HeaderMagic.Length); Source.WriteAll(0, _tmpBuffer, 0, BlockSize); _superBlock = Superblock.ReadFrom(_tmpBuffer); // Setup block bitmap byte[] tmpBuffer = new byte[BlockSize]; Source.WriteAll(BlockSize * 1, tmpBuffer, 0, BlockSize); // Clear inode bitmap BitArray inodeBitmap = new BitArray(tmpBuffer); inodeBitmap[0] = true; inodeBitmap.CopyTo(tmpBuffer, 0); Source.WriteAll(BlockSize * 2, tmpBuffer, 0, BlockSize); // Create root directory BobFsNode root = new BobFsNode(this, 0); root.Type = ENodeType.Directory; root.NumLinks = 1; root.Size = 0; root.Commit(); }
public int WriteTo(BobFsNode node, int offset) { byte[] buf = new byte[Name.Length + 8]; BitConverter.GetBytes(Inum).CopyTo(buf, 0); BitConverter.GetBytes((uint)Name.Length).CopyTo(buf, 4); Encoding.ASCII.GetBytes(Name).CopyTo(buf, 8); return(node.WriteAll(offset, buf, 0, buf.Length)); }
public void ReadFrom(BobFsNode node, int offset) { byte[] headBuf = new byte[8]; node.ReadAll(offset, headBuf, 0, 8); Inum = BitConverter.ToUInt32(headBuf, 0); uint nameLength = BitConverter.ToUInt32(headBuf, 4); byte[] nameBuf = new byte[nameLength]; node.ReadAll(offset + 8, nameBuf, 0, (int)nameLength); Name = Encoding.ASCII.GetString(nameBuf, 0, (int)nameLength); }
private BobFsNode NewNode(string name, ENodeType type) { if (!IsDirectory) { throw new InvalidOperationException("Current node is not a directory."); } // Get free inum // TODO: Can be optimized // TODO: Implement caching int freeInum = -1; _bobFs.Source.ReadAll(BobFs.BlockSize * 2, _tmpBuffer, 0, BobFs.BlockSize); BitArray inodeBitmap = new BitArray(_tmpBuffer); for (int index = 0; index < BobFs.BlockSize * 8 && freeInum == -1; index++) { if (!inodeBitmap[index]) { freeInum = index; } } if (freeInum == -1) { throw new Exception("No free Inode."); } inodeBitmap[freeInum] = true; inodeBitmap.CopyTo(_tmpBuffer, 0); _bobFs.Source.WriteAll(BobFs.BlockSize * 2, _tmpBuffer, 0, BobFs.BlockSize); // Add to directory DirEntry newDirEntry = new DirEntry(); newDirEntry.Inum = (uint)freeInum; newDirEntry.Name = name; int bytesWritten = newDirEntry.WriteTo(this, (int)Size); if (bytesWritten < 0) { throw new Exception("Current directory is full."); } // Create inode at inum BobFsNode newInode = new BobFsNode(_bobFs, (uint)freeInum); newInode.Type = type; newInode.NumLinks = 1; newInode.Size = 0; newInode.Commit(); return(newInode); }
public void LinkNode(string name, BobFsNode file) { if (!IsDirectory) { throw new InvalidOperationException("Current node is not a directory."); } // Add to directory DirEntry newDirEntry = new DirEntry(); newDirEntry.Inum = file.Inum; newDirEntry.Name = name; int bytesWritten = newDirEntry.WriteTo(this, (int)Size); if (bytesWritten < 0) { throw new Exception("Current directory is full."); } // Update nlinks in node file.Node.NumLinks++; file.Commit(); }