/// <summary> /// Initializes a new instance of the <see cref="VirtualFileSystem"/> class. /// Create new file system. /// </summary> internal VirtualFileSystem([NotNull] IDirectDiskAccess diskAccess, ulong newVolumeSize) { Validate.ArgumentNotNull(diskAccess, "diskAccess"); _diskAccess = diskAccess; _record = MasterRecord.CreateNewVolume(diskAccess, newVolumeSize); _record.Save(); }
/// <summary> /// Initializes a new instance of the <see cref="VirtualFileSystem"/> class. /// Load existing file system. /// </summary> internal VirtualFileSystem([NotNull] IDirectDiskAccess diskAccess) { Validate.ArgumentNotNull(diskAccess, "diskAccess"); _diskAccess = diskAccess; _record = new MasterRecord(diskAccess); _record.Load(); }
private readonly MasterRecord _record; // todo: decouple as INodeStorage #endregion Fields #region Constructors /// <summary> /// Initializes a new instance of the <see cref="DirectoryNode"/> class. /// </summary> /// <param name="record">The master record.</param> /// <param name="address">The directory node address.</param> /// <param name="diskAccess">The disk access interface.</param> private DirectoryNode([NotNull] MasterRecord record, [NotNull] Address address, [NotNull] IDirectDiskAccess diskAccess) : base(record, diskAccess, address, record.GlobalBlocksStartAddress) { Validate.ArgumentNotNull(record, "record"); Validate.ArgumentNotNull(address, "address"); Validate.ArgumentNotNull(diskAccess, "diskAccess"); _record = record; }
public static MasterRecord CreateNewVolume([NotNull] IDirectDiskAccess access, ulong size) { Validate.ArgumentNotNull(access, "access"); if (size % Constants.BlockSizeBytes != 0) { throw new ArgumentOutOfRangeException("Volume size should be on block size boundary."); } if (size <= BlockGroup.ReservedBlocks * Constants.BlockSizeBytes) { throw new ArgumentOutOfRangeException(string.Format("Min volume size is {0}", Constants.BlockSizeBytes * (BlockGroup.ReservedBlocks + 1))); } var totalBlocks = (uint)(size / Constants.BlockSizeBytes); uint numberOfFullGroups = totalBlocks / Constants.BlocksPerGroup; uint remainingBlocks = totalBlocks % Constants.BlocksPerGroup; if (remainingBlocks > BlockGroup.ReservedBlocks) { numberOfFullGroups++; } var rec = new MasterRecord(access); rec._groupsReserved = new BlockGroup[numberOfFullGroups]; var offset = new Address(32 + (BlockGroupDescriptor.RawSizeBytes * numberOfFullGroups)); offset = offset.AlignOnBlockBoundary; uint totalFreeBlocks = 0; for (uint i = 0; i < numberOfFullGroups; ++i) { bool last = (i == numberOfFullGroups - 1 && remainingBlocks > 0); var groupSize = last ? remainingBlocks : Constants.BlocksPerGroup; var newGroup = new BlockGroup(offset, groupSize); offset = offset.AddBlocks(groupSize); totalFreeBlocks += newGroup.Descriptor.NumFreeBlocksInGroup; rec._groupsReserved[i] = newGroup; } rec._freeSpaceBlocks = totalFreeBlocks; rec.VolumeSize = offset.Value; rec.RootNode = rec.CreateDirectoryNode("\\", null); return rec; }