protected OffsetTableHardDisk(HardDisk hdd)
 {
     if (hdd == null)
     {
         throw new ArgumentNullException(nameof(hdd));
     }
     mHdd         = hdd;
     mReadBlock   = readBlock;
     mGetBlockKey = getBlockKey;
 }
Exemple #2
0
        public LeafVdevInfo(HardDisk hdd)
        {
            this.HDD = hdd;

            var rentedBytes = Program.RentBytes(VDEV_PHYS_SIZE);

            try
            {
                if (!hdd.ReadLabelBytes(rentedBytes, VDEV_SKIP_SIZE))
                {
                    throw new Exception("Invalid checksum on lable config data!");
                }
                Config = new NvList(rentedBytes);
            }
            finally
            {
                Program.ReturnBytes(rentedBytes);
                rentedBytes = default(ArraySegment <byte>);
            }

            //figure out how big the uber blocks are
            var vdevTree = Config.Get <NvList>("vdev_tree");
            var ubShift  = (int)vdevTree.Get <ulong>("ashift");

            ubShift = Math.Max(ubShift, UBERBLOCK_SHIFT);
            ubShift = Math.Min(ubShift, MAX_UBERBLOCK_SHIFT);
            var ubSize  = 1 << ubShift;
            var ubCount = VDEV_UBERBLOCK_RING >> ubShift;

            List <uberblock_t> blocks = new List <uberblock_t>();
            var ubBytes = Program.RentBytes(ubSize);

            try
            {
                for (long i = 0; i < ubCount; i++)
                {
                    var offset = VDEV_SKIP_SIZE + VDEV_PHYS_SIZE + ubSize * i;
                    if (!hdd.ReadLabelBytes(ubBytes, offset))
                    {
                        continue;
                    }
                    uberblock_t b = Program.ToStruct <uberblock_t>(ubBytes.Array, ubBytes.Offset);
                    if (b.Magic == uberblock_t.UbMagic)
                    {
                        blocks.Add(b);
                    }
                }
            }
            finally
            {
                Program.ReturnBytes(ubBytes);
                ubBytes = default(ArraySegment <byte>);
            }
            this.Uberblock = blocks.OrderByDescending(u => u.Txg).ThenByDescending(u => u.TimeStamp).First();

            const int VDevLableSizeStart = 4 << 20;
            const int VDevLableSizeEnd   = 512 << 10;

            hdd      = OffsetHardDisk.Create(hdd, VDevLableSizeStart, hdd.Length - VDevLableSizeStart - VDevLableSizeEnd);
            this.HDD = hdd;
        }