コード例 #1
0
        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;
            }
        }
コード例 #2
0
        unsafe RangeMap LoadEntrysForMetaSlab(long dnEntry, int sm_shift)
        {
            RangeMap ret = new RangeMap();

            var dn = mMos.ReadEntry(dnEntry);

            if (dn.Type != dmu_object_type_t.SPACE_MAP || dn.BonusType != dmu_object_type_t.SPACE_MAP_HEADER)
            {
                throw new Exception("Not a space map.");
            }

            var head = dn.GetBonus <space_map_obj>();

            if (head.smo_object != dnEntry)
            {
                throw new Exception();
            }

            if (head.smo_objsize > int.MaxValue)
            {
                throw new Exception("Holy cow, this space map is greater than 2GB, what is wrong with your VDev!?!?");
            }

            var someBytes = Program.RentBytes((int)head.smo_objsize);

            dn.Read(someBytes, 0);
            for (int i = 0; i < someBytes.Count; i += 8)
            {
                var ent = Program.ToStruct <spaceMapEntry>(someBytes.SubSegment(i, sizeof(spaceMapEntry)));
                if (ent.IsDebug)
                {
                    continue;
                }

                ulong offset = (ent.Offset << sm_shift);
                ulong range  = ent.Run << sm_shift;
                //Console.WriteLine("\t    [{4,6}]    {0}  range: {1:x10}-{2:x10}  size: {3:x6}", ent.Type, offset, offset + range, range, i / 8);
                if (ent.Type == SpaceMapEntryType.A)
                {
                    ret.AddRange(offset, range);
                }
                else if (ent.Type == SpaceMapEntryType.F)
                {
                    ret.RemoveRange(offset, range);
                }
            }
            Program.ReturnBytes(someBytes);

            return(ret);
        }