protected OffsetTableHardDisk(HardDisk hdd) { if (hdd == null) { throw new ArgumentNullException(nameof(hdd)); } mHdd = hdd; mReadBlock = readBlock; mGetBlockKey = getBlockKey; }
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; }