コード例 #1
0
ファイル: Zio.cs プロジェクト: AustinWise/ZfsSharp
        private void ReadGangBlkPtr(blkptr_t blkptr, ArraySegment <byte> dest, ref int offset)
        {
            int size = blkptr.LogicalSizeBytes;

            Read(blkptr, dest.SubSegment(offset, size));
            offset += size;
        }
コード例 #2
0
ファイル: Zio.cs プロジェクト: AustinWise/ZfsSharp
        public void Read(blkptr_t blkptr, Span <byte> dest)
        {
            if (blkptr.birth == 0)
            {
                throw new NotSupportedException("Invalid block pointer: 0 birth txg.");
            }
            if (blkptr.IsHole)
            {
                throw new Exception("Block pointer is a hole.");
            }
            if (blkptr.IsLittleEndian != BitConverter.IsLittleEndian)
            {
                throw new NotImplementedException("Byte swapping not implemented.");
            }
            if (blkptr.LogicalSizeBytes != dest.Length)
            {
                throw new ArgumentOutOfRangeException("dest", "Dest does not match logical size of block pointer.");
            }

            if (blkptr.IsEmbedded)
            {
                ReadEmbedded(blkptr, dest);
                return;
            }

            //if (blkptr.fill == 0)
            //    throw new NotSupportedException("There is no data in this block pointer.");

            //TODO: try other DVAs
            Read(blkptr, blkptr.dva1, dest);
        }
コード例 #3
0
ファイル: Zio.cs プロジェクト: AustinWise/ZfsSharp
        private static zio_cksum_t CalculateGangChecksumVerifier(ref blkptr_t blkptr)
        {
            var ret = new zio_cksum_t();

            ret.word1 = (ulong)blkptr.dva1.VDev;
            ret.word2 = (ulong)(blkptr.dva1.Offset << SPA_MINBLOCKSHIFT);
            ret.word3 = (ulong)blkptr.PhysBirth;
            ret.word4 = 0;
            return(ret);
        }
コード例 #4
0
ファイル: Zio.cs プロジェクト: AustinWise/ZfsSharp
        unsafe void ReadEmbedded(blkptr_t blkptr, Span <byte> dest)
        {
            if (blkptr.EmbedType != EmbeddedType.Data)
            {
                throw new Exception("Unsupported embedded type: " + blkptr.EmbedType);
            }

            int physicalSize = blkptr.PhysicalSizeBytes;

            if (physicalSize > blkptr_t.EM_DATA_SIZE)
            {
                throw new Exception("PSize is too big!");
            }
            var physicalBytes = Program.RentBytes(physicalSize);

            const int NUMBER_OF_EMBEDDED_CHUNKS = 3;

            Debug.Assert(blkptr_t.EmbeddedSizes.Length == NUMBER_OF_EMBEDDED_CHUNKS);
            byte **embeddedDataPoints = stackalloc byte *[NUMBER_OF_EMBEDDED_CHUNKS];

            embeddedDataPoints[0] = blkptr.EmbeddedData1;
            embeddedDataPoints[1] = blkptr.EmbeddedData2;
            embeddedDataPoints[2] = blkptr.EmbeddedData3;

            fixed(byte *pStartPtr = physicalBytes.Array)
            {
                var pBytes       = pStartPtr + physicalBytes.Offset;
                int remaingBytes = physicalSize;

                for (int i = 0; remaingBytes > 0 && i < NUMBER_OF_EMBEDDED_CHUNKS; i++)
                {
                    int size = Math.Min(remaingBytes, blkptr_t.EmbeddedSizes[i]);
                    Debug.Assert(size > 0);
                    Unsafe.CopyBlock(pBytes, embeddedDataPoints[i], (uint)size);
                    pBytes       += size;
                    remaingBytes -= size;
                }
            }

            mCompression[blkptr.Compress].Decompress(physicalBytes, dest);
            Program.ReturnBytes(physicalBytes);
        }
コード例 #5
0
ファイル: Zio.cs プロジェクト: AustinWise/ZfsSharp
        /// <summary>
        /// Just reads the bytes off the disk, reading gang blocks as needed.
        /// </summary>
        /// <param name="blkptr"></param>
        /// <param name="dva"></param>
        /// <returns>A buffer allocated from <see cref="Program.RentBytes"/>.</returns>
        private ArraySegment <byte> ReadPhyical(blkptr_t blkptr, dva_t dva)
        {
            Vdev dev         = mVdevs[dva.VDev];
            int  hddReadSize = dva.IsGang ? zio_gbh_phys_t.SPA_GANGBLOCKSIZE : blkptr.PhysicalSizeBytes;

            var hddBytes = Program.RentBytes(hddReadSize);

            dev.ReadBytes(hddBytes, dva.Offset << SPA_MINBLOCKSHIFT);

            if (!dva.IsGang)
            {
                return(hddBytes);
            }

            var gangHeader = Program.ToStruct <zio_gbh_phys_t>(hddBytes);

            bool isChecksumValid = IsEmbeddedChecksumValid(hddBytes, CalculateGangChecksumVerifier(ref blkptr));

            Program.ReturnBytes(hddBytes);
            hddBytes = default(ArraySegment <byte>);

            if (!isChecksumValid)
                throw new Exception("Could not find a correct copy of the requested data."); }
コード例 #6
0
ファイル: DNode.cs プロジェクト: AustinWise/ZfsSharp
 private void readBlock(Span <byte> dest, blkptr_t blkptr, int startNdx)
 {
     if (blkptr.IsHole)
         return; }
コード例 #7
0
ファイル: Zio.cs プロジェクト: AustinWise/ZfsSharp
 public void Read(blkptr_t blkptr, ArraySegment <byte> dest)
 {
     Read(blkptr, (Span <byte>)dest);
 }