internal DatasetDirectory(ObjectSet mos, long objectid, string name, Zio zio) { this.mMos = mos; this.mZio = zio; this.Name = name; this.Type = DataSetType.MetaData; var rootDslObj = mos.ReadEntry(objectid); if (rootDslObj.Type != dmu_object_type_t.DSL_DIR) throw new NotSupportedException("Expected DSL_DIR dnode."); if (rootDslObj.BonusType != dmu_object_type_t.DSL_DIR) throw new NotSupportedException("Expected DSL_DIR bonus."); mDslDir = rootDslObj.GetBonus<dsl_dir_phys_t>(); var rootDslProps = Zap.Parse(mos, mDslDir.props_zapobj); Dictionary<string, long> clones; if (mDslDir.clones != 0) { clones = Zap.GetDirectoryEntries(mos, mDslDir.clones); } if (mDslDir.head_dataset_obj == 0) return; //probably meta data, like $MOS or $FREE var rootDataSetObj = mos.ReadEntry(mDslDir.head_dataset_obj); if (!IsDataSet(rootDataSetObj)) throw new Exception("Not a dataset!"); if (rootDataSetObj.BonusType != dmu_object_type_t.DSL_DATASET) throw new Exception("Missing dataset bonus!"); var headDs = rootDataSetObj.GetBonus<dsl_dataset_phys_t>(); if (headDs.bp.IsHole && mDslDir.origin_obj == 0) return; //this is $ORIGIN if (headDs.snapnames_zapobj != 0) { mSnapShots = Zap.GetDirectoryEntries(mMos, headDs.snapnames_zapobj); } if (headDs.bp.Type != dmu_object_type_t.OBJSET) throw new Exception("Expected OBJSET."); var headDsObjset = zio.Get<objset_phys_t>(headDs.bp); switch (headDsObjset.Type) { case dmu_objset_type_t.DMU_OST_ZFS: this.Type = DataSetType.ZFS; break; case dmu_objset_type_t.DMU_OST_ZVOL: this.Type = DataSetType.ZVOL; break; default: throw new Exception("Unknow dataset type: " + headDsObjset.Type.ToString()); } }
public MetaSlabs(ObjectSet mos, long metaSlabArray, int metaSlabShift, int aShift) { mMos = mos; mSlabSize = 1L << metaSlabShift; var slabDnode = mos.ReadEntry(metaSlabArray); var someBytes = Program.RentBytes(checked((int)slabDnode.AvailableDataSize)); slabDnode.Read(someBytes, 0); int numberOfSlabs = someBytes.Count / 8; mRangeMap = new RangeMap[numberOfSlabs]; long[] ids = new long[numberOfSlabs]; Buffer.BlockCopy(someBytes.Array, someBytes.Offset, ids, 0, someBytes.Count); Program.ReturnBytes(someBytes); someBytes = default(ArraySegment<byte>); for (int i = 0; i < numberOfSlabs; i++) { var id = ids[i]; RangeMap map; if (id == 0) { map = new RangeMap(); } else { map = LoadEntrysForMetaSlab(id, aShift); } mRangeMap[i] = map; } }