Ejemplo n.º 1
0
        private void AllocateGrains(int grainTable, int grain, int count)
        {
            // Calculate start pos for new grain
            long grainStartPos = (long)_serverHeader.FreeSector * Sizes.Sector;

            // Copy-on-write semantics, read the bytes from parent and write them out to this extent.
            _parentDiskStream.Position = _diskOffset +
                                         (grain + _header.NumGTEsPerGT * grainTable) * _header.GrainSize *
                                         Sizes.Sector;
            byte[] content = StreamUtilities.ReadExact(_parentDiskStream, (int)(_header.GrainSize * Sizes.Sector * count));
            _fileStream.Position = grainStartPos;
            _fileStream.Write(content, 0, content.Length);

            // Update next-free-sector in disk header
            _serverHeader.FreeSector += (uint)MathUtilities.Ceil(content.Length, Sizes.Sector);
            byte[] headerBytes = _serverHeader.GetBytes();
            _fileStream.Position = 0;
            _fileStream.Write(headerBytes, 0, headerBytes.Length);

            LoadGrainTable(grainTable);
            for (int i = 0; i < count; ++i)
            {
                SetGrainTableEntry(grain + i, (uint)(grainStartPos / Sizes.Sector + _header.GrainSize * i));
            }

            WriteGrainTable();
        }
Ejemplo n.º 2
0
        private static void CreateExtent(Stream extentStream, long size, ExtentType type, long descriptorLength, out long descriptorStart)
        {
            if (type == ExtentType.Flat || type == ExtentType.Vmfs)
            {
                extentStream.SetLength(size);
                descriptorStart = 0;
                return;
            }

            if (type == ExtentType.Sparse)
            {
                CreateSparseExtent(extentStream, size, descriptorLength, out descriptorStart);
                return;
            }
            else if (type == ExtentType.VmfsSparse)
            {
                ServerSparseExtentHeader header = CreateServerSparseExtentHeader(size);

                extentStream.Position = 0;
                extentStream.Write(header.GetBytes(), 0, 4 * Sizes.Sector);

                byte[] blankGlobalDirectory = new byte[header.NumGdEntries * 4];
                extentStream.Write(blankGlobalDirectory, 0, blankGlobalDirectory.Length);

                descriptorStart = 0;
                return;
            }
            else
            {
                throw new NotImplementedException("Extent type not implemented");
            }
        }
Ejemplo n.º 3
0
        internal override List <BuilderExtent> FixExtents(out long totalLength)
        {
            List <BuilderExtent> extents = new List <BuilderExtent>();

            ServerSparseExtentHeader header   = DiskImageFile.CreateServerSparseExtentHeader(_content.Length);
            GlobalDirectoryExtent    gdExtent = new GlobalDirectoryExtent(header);

            long grainTableStart    = (header.GdOffset * Sizes.Sector) + gdExtent.Length;
            long grainTableCoverage = header.NumGTEsPerGT * header.GrainSize * Sizes.Sector;

            foreach (var grainTableRange in StreamExtent.Blocks(_content.Extents, grainTableCoverage))
            {
                for (int i = 0; i < grainTableRange.Count; ++i)
                {
                    long             grainTable = grainTableRange.Offset + i;
                    long             dataStart  = grainTable * grainTableCoverage;
                    GrainTableExtent gtExtent   = new GrainTableExtent(grainTableStart, new SubStream(_content, dataStart, Math.Min(grainTableCoverage, _content.Length - dataStart)), header);
                    extents.Add(gtExtent);
                    gdExtent.SetEntry((int)grainTable, (uint)(grainTableStart / Sizes.Sector));

                    grainTableStart += gtExtent.Length;
                }
            }

            extents.Insert(0, gdExtent);

            header.FreeSector = (uint)(grainTableStart / Sizes.Sector);

            byte[] buffer = header.GetBytes();
            extents.Insert(0, new BuilderBufferExtent(0, buffer));

            totalLength = grainTableStart;

            return(extents);
        }