/// <summary>
 /// "All disks holding extents for a given volume must have the same sector size"
 /// </summary>
 public static int?GetBytesPerSector(List <DynamicColumn> columns)
 {
     foreach (DynamicColumn column in columns)
     {
         int?bytesPerSector = DynamicColumn.GetBytesPerSector(column.Extents);
         if (bytesPerSector.HasValue)
         {
             return(bytesPerSector.Value);
         }
     }
     return(null);
 }
Ejemplo n.º 2
0
        public override void WriteSectors(long sectorIndex, byte[] data)
        {
            int sectorCount = data.Length / this.BytesPerSector;
            List <ArrayPosition> writePositions = TranslateSectors(sectorIndex, sectorCount);

            int bytesWritten = 0;

            foreach (ArrayPosition writePosition in writePositions)
            {
                byte[] stripeBytes = new byte[writePosition.SectorCount * this.BytesPerSector];
                Array.Copy(data, bytesWritten, stripeBytes, 0, stripeBytes.Length);
                DynamicColumn column = m_columns[writePosition.DiskIndex];
                column.WriteSectors(writePosition.SectorIndex, stripeBytes);
                bytesWritten += stripeBytes.Length;
            }
        }
Ejemplo n.º 3
0
        public override byte[] ReadSectors(long sectorIndex, int sectorCount)
        {
            List <ArrayPosition> readPositions = TranslateSectors(sectorIndex, sectorCount);

            byte[] result    = new byte[sectorCount * BytesPerSector];
            int    bytesRead = 0;

            foreach (ArrayPosition readPosition in readPositions)
            {
                DynamicColumn column      = m_columns[readPosition.DiskIndex];
                byte[]        stripeBytes = column.ReadSectors(readPosition.SectorIndex, (int)readPosition.SectorCount);
                Array.Copy(stripeBytes, 0, result, bytesRead, stripeBytes.Length);
                bytesRead += stripeBytes.Length;
            }

            return(result);
        }
Ejemplo n.º 4
0
        public override byte[] ReadSectors(long sectorIndex, int sectorCount)
        {
            CheckBoundaries(sectorIndex, sectorCount);
            List <ArrayPosition> readPositions = TranslateSectors(sectorIndex, sectorCount);

            byte[] result    = new byte[sectorCount * BytesPerSector];
            int    bytesRead = 0;

            foreach (ArrayPosition readPosition in readPositions)
            {
                DynamicColumn column = m_columns[readPosition.DiskIndex];
                byte[]        stripeBytes;

                if (column.IsOperational)
                {
                    stripeBytes = column.ReadSectors(readPosition.SectorIndex, readPosition.SectorCount);
                }
                else
                {
                    stripeBytes = new byte[readPosition.SectorCount * BytesPerDynamicDiskSector];
                    for (int index = 0; index < m_columns.Count; index++)
                    {
                        if (index != readPosition.DiskIndex)
                        {
                            byte[] currentBytes = m_columns[index].ReadSectors(readPosition.SectorIndex, readPosition.SectorCount);
                            stripeBytes = XOR(stripeBytes, currentBytes);
                        }
                    }
                }

                Array.Copy(stripeBytes, 0, result, bytesRead, stripeBytes.Length);
                bytesRead += stripeBytes.Length;
            }

            return(result);
        }
Ejemplo n.º 5
0
        // We support degraded arrays
        public override void WriteSectors(long sectorIndex, byte[] data)
        {
            CheckBoundaries(sectorIndex, data.Length / this.BytesPerSector);

            int numberOfColumns = m_columns.Count;

            int sectorCount = data.Length / this.BytesPerSector;
            List <ArrayPosition> writePositions = TranslateSectors(sectorIndex, sectorCount);

            int bytesWritten = 0;

            foreach (ArrayPosition writePosition in writePositions)
            {
                DynamicColumn column = m_columns[writePosition.DiskIndex];

                byte[] stripeBytes = new byte[writePosition.SectorCount * this.BytesPerSector];
                Array.Copy(data, bytesWritten, stripeBytes, 0, stripeBytes.Length);

                // first we obtain the necessary data from the other columns
                long          stripeIndexInColumn = writePosition.SectorIndex / m_sectorsPerStripe;
                int           parityColumnIndex   = (numberOfColumns - 1) - (int)(stripeIndexInColumn % numberOfColumns);
                List <byte[]> segment             = new List <byte[]>();
                for (int index = 0; index < numberOfColumns; index++)
                {
                    if (m_columns[index].IsOperational)
                    {
                        byte[] bytes = m_columns[index].ReadSectors(writePosition.SectorIndex, writePosition.SectorCount);
                        segment.Add(bytes);
                    }
                    else
                    {
                        segment.Add(null);
                    }
                }

                int missingColumnIndex = segment.IndexOf(null);
                if (missingColumnIndex >= 0)
                {
                    if (missingColumnIndex != parityColumnIndex && missingColumnIndex != writePosition.DiskIndex)
                    {
                        // let's calculate the missing data stripe
                        byte[] missingBytes = segment[parityColumnIndex];
                        for (int index = 0; index < numberOfColumns; index++)
                        {
                            if (index != missingColumnIndex && index != parityColumnIndex)
                            {
                                missingBytes = XOR(missingBytes, segment[index]);
                            }
                        }
                        segment[missingColumnIndex] = missingBytes;
                    }
                }

                if (column.IsOperational)
                {
                    column.WriteSectors(writePosition.SectorIndex, stripeBytes);
                }

                if (missingColumnIndex != parityColumnIndex)
                {
                    // lets calculate the new parity disk
                    segment[writePosition.DiskIndex] = stripeBytes;

                    byte[] parityBytes = new byte[writePosition.SectorCount * this.BytesPerSector];
                    for (int index = 0; index < numberOfColumns; index++)
                    {
                        if (index != parityColumnIndex)
                        {
                            parityBytes = XOR(parityBytes, segment[index]);
                        }
                    }
                    m_columns[parityColumnIndex].WriteSectors(writePosition.SectorIndex, parityBytes);
                }

                bytesWritten += stripeBytes.Length;
            }
        }
Ejemplo n.º 6
0
 public SpannedVolume(DynamicColumn column, Guid volumeGuid, Guid diskGroupGuid) : base(volumeGuid, diskGroupGuid)
 {
     m_column = column;
 }