Пример #1
0
        /// <summary>
        /// Initializes paging
        /// </summary>
        public static void Init()
        {
            // Flags
            PageFlags kernelFlags   = PageFlags.Present | PageFlags.Writable;
            PageFlags usercodeFlags = PageFlags.Present | PageFlags.UserMode;
            PageFlags userFlags     = PageFlags.Present | PageFlags.Writable | PageFlags.UserMode;

            // Bit array to store which frames are free
            bitmap = new BitArray(4096 * 1024 / 4);

            // Create a new page directory for the kernel
            // Note: At this point, virtual address == physical address due to identity mapping
            KernelDirectory = CreateNewDirectoryPhysically(userFlags);
            SetPageDirectory(KernelDirectory, KernelDirectory);

            // Identity map
            int end = (int)PhysicalMemoryManager.FirstFree();

            for (int address = 0; address < end; address += 0x1000)
            {
                MapPage(KernelDirectory, address, address, kernelFlags);
                bitmap.SetBit(address / 0x1000);
            }

            // Usercode is a section that is code in the kernel available to usermode
            int usercode = (int)getUsercodeAddress();

            MapPage(KernelDirectory, usercode, usercode, usercodeFlags);

            // Enable paging
            Enable();
        }
Пример #2
0
        /// <summary>
        /// Creates a new page directory using only physical memory (used in Init)
        /// </summary>
        /// <param name="flags">The flags</param>
        /// <returns>The page directory</returns>
        public static PageDirectory *CreateNewDirectoryPhysically(PageFlags flags)
        {
            // Allocate a new block of physical memory to store our physical page in
            PageDirectory *directory = (PageDirectory *)Heap.AlignedAlloc(0x1000, sizeof(PageDirectory));

            directory->PhysicalDirectory = directory;
            if (directory == null)
            {
                Panic.DoPanic("directory == null");
            }

            // Allocate the tables
            for (int i = 0; i < 1024; i++)
            {
                PageTable *table = (PageTable *)PhysicalMemoryManager.Alloc();
                if (table == null)
                {
                    Panic.DoPanic("table == null");
                }

                Memory.Memclear(table, sizeof(PageTable));

                // Note: At this point, virtual address == physical address due to identity mapping
                directory->PhysicalTables[i] = (int)table | (int)flags;
                directory->VirtualTables[i]  = (int)table;
            }

            return(directory);
        }
Пример #3
0
        internal static Page NewPage(Transaction tx, PageFlags flags, int num)
        {
            var page = tx.AllocatePage(num);

            page.Flags = flags;

            return(page);
        }
Пример #4
0
        internal Page NewPage(PageFlags flags, int num)
        {
            var page = _tx.AllocatePage(num, flags);

            State.RecordNewPage(page, num);

            return(page);
        }
Пример #5
0
        public PageHeader(File file, long position)
        {
            file.Seek(position);

            // An Ogg page header is at least 27 bytes, so we'll go ahead and read that
            // much and then get the rest when we're ready for it.

            ByteVector data = file.ReadBlock(27);

            if (data.Count < 27 || !data.StartsWith("OggS"))
            {
                throw new CorruptFileException("Error reading page header");
            }

            _version = data [4];
            _flags   = (PageFlags)data [5];
            _absolute_granular_position = data.Mid(6, 8).ToULong(false);
            _stream_serial_number       = data.Mid(14, 4).ToUInt(false);
            _page_sequence_number       = data.Mid(18, 4).ToUInt(false);

            // Byte number 27 is the number of page segments, which is the only variable
            // length portion of the page header.  After reading the number of page
            // segments we'll then read in the coresponding data for this count.
            int        page_segment_count = data [26];
            ByteVector page_segments      = file.ReadBlock(page_segment_count);

            // Another sanity check.
            if (page_segment_count < 1 || page_segments.Count != page_segment_count)
            {
                throw new CorruptFileException("Incorrect number of page segments");
            }

            // The base size of an Ogg page 27 bytes plus the number of lacing values.
            _size         = (uint)(27 + page_segment_count);
            _packet_sizes = new List <int> ();

            int packet_size = 0;

            _data_size = 0;

            for (int i = 0; i < page_segment_count; i++)
            {
                _data_size  += page_segments [i];
                packet_size += page_segments [i];

                if (page_segments [i] < 255)
                {
                    _packet_sizes.Add(packet_size);
                    packet_size = 0;
                }
            }

            if (packet_size > 0)
            {
                _packet_sizes.Add(packet_size);
            }
        }
Пример #6
0
        /// <summary>
        /// Maps a page in a directory
        /// </summary>
        /// <param name="directory">The page directory</param>
        /// <param name="phys">The physical address</param>
        /// <param name="virt">The virtual address</param>
        /// <param name="flags">The flags</param>
        public static void MapPage(PageDirectory *directory, int phys, int virt, PageFlags flags)
        {
            // Get indices
            int pageIndex  = virt / 0x1000;
            int tableIndex = pageIndex / 1024;

            // Set page using its virtual address
            PageTable *table = (PageTable *)directory->VirtualTables[tableIndex];

            table->Pages[pageIndex & (1024 - 1)] = ToFrameAddress(phys) | (int)flags;
        }
Пример #7
0
        internal Page NewPage(PageFlags flags, int num)
        {
            Page page;

            using (IsFreeSpaceTree ? _tx.Environment.FreeSpaceHandling.Disable() : null)
            {
                page = _tx.AllocatePage(num, flags);
            }

            State.RecordNewPage(page, num);

            return(page);
        }
Пример #8
0
 public PageHeader (uint streamSerialNumber, uint pageNumber, PageFlags flags)
 {
    _version = 0;
    _flags = flags;
    _absolute_granular_position = 0;
    _stream_serial_number = streamSerialNumber;
    _page_sequence_number = pageNumber;
    _size = 0;
    _data_size = 0;
    _packet_sizes = new List<int> ();
    
    if (pageNumber == 0 && (flags & PageFlags.FirstPacketContinued) == 0)
       _flags |= PageFlags.FirstPageOfStream;
 }
Пример #9
0
        public PageHeader(File file, long position)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }
            if (position < 0 || position > file.Length - 27)
            {
                throw new ArgumentOutOfRangeException("position");
            }
            file.Seek(position);
            ByteVector data = file.ReadBlock(27);

            if (data.Count < 27 || !data.StartsWith("OggS"))
            {
                throw new CorruptFileException("Error reading page header");
            }
            version    = data[4];
            this.flags = (PageFlags)data[5];
            absolute_granular_position = data.Mid(6, 8).ToULong(false);
            stream_serial_number       = data.Mid(14, 4).ToUInt(false);
            page_sequence_number       = data.Mid(18, 4).ToUInt(false);
            int        page_segment_count = data[26];
            ByteVector page_segments      = file.ReadBlock(page_segment_count);

            if (page_segment_count < 1 || page_segments.Count != page_segment_count)
            {
                throw new CorruptFileException("Incorrect number of page segments");
            }
            size         = (uint)(27 + page_segment_count);
            packet_sizes = new List <int>();
            int packet_size = 0;

            data_size = 0;
            for (int i = 0; i < page_segment_count; i++)
            {
                data_size   += page_segments[i];
                packet_size += page_segments[i];
                if (page_segments[i] < 255)
                {
                    packet_sizes.Add(packet_size);
                    packet_size = 0;
                }
            }
            if (packet_size > 0)
            {
                packet_sizes.Add(packet_size);
            }
        }
Пример #10
0
      public PageHeader (File file, long position)
      {
         file.Seek (position);

         // An Ogg page header is at least 27 bytes, so we'll go ahead and read that
         // much and then get the rest when we're ready for it.

         ByteVector data = file.ReadBlock (27);
         if (data.Count < 27 || !data.StartsWith ("OggS"))
            throw new CorruptFileException ("Error reading page header");
         
         _version = data [4];
         _flags = (PageFlags) data [5];
         _absolute_granular_position = data.Mid( 6, 8).ToULong (false);
         _stream_serial_number       = data.Mid(14, 4).ToUInt (false);
         _page_sequence_number       = data.Mid(18, 4).ToUInt (false);

         // Byte number 27 is the number of page segments, which is the only variable
         // length portion of the page header.  After reading the number of page
         // segments we'll then read in the coresponding data for this count.
         int page_segment_count = data [26];
         ByteVector page_segments = file.ReadBlock (page_segment_count);
         
         // Another sanity check.
         if(page_segment_count < 1 || page_segments.Count != page_segment_count)
            throw new CorruptFileException ("Incorrect number of page segments");

         // The base size of an Ogg page 27 bytes plus the number of lacing values.
         _size = (uint)(27 + page_segment_count);
         _packet_sizes = new List<int> ();
         
         int packet_size = 0;
         _data_size = 0;
         
         for (int i = 0; i < page_segment_count; i++)
         {
            _data_size += page_segments [i];
            packet_size += page_segments [i];

            if (page_segments [i] < 255)
            {
               _packet_sizes.Add (packet_size);
               packet_size = 0;
            }
         }
         
         if (packet_size > 0)
            _packet_sizes.Add (packet_size);
      }
Пример #11
0
 public PageHeader(uint streamSerialNumber, uint pageNumber, PageFlags flags)
 {
     version    = 0;
     this.flags = flags;
     absolute_granular_position = 0;
     stream_serial_number       = streamSerialNumber;
     page_sequence_number       = pageNumber;
     size         = 0;
     data_size    = 0;
     packet_sizes = new List <int>();
     if (pageNumber == 0 && (flags & PageFlags.FirstPacketContinued) == 0)
     {
         this.flags |= PageFlags.FirstPageOfStream;
     }
 }
Пример #12
0
 public PageHeader(PageHeader original, uint offset, PageFlags flags)
 {
     this.version = original.version;
     this.flags = flags;
     this.absolute_granular_position = original.absolute_granular_position;
     this.stream_serial_number = original.stream_serial_number;
     this.page_sequence_number = original.page_sequence_number + offset;
     this.size = original.size;
     this.data_size = original.data_size;
     this.packet_sizes = new List<int>();
     if ((this.page_sequence_number == 0) && (((byte) (flags & PageFlags.FirstPacketContinued)) == 0))
     {
         this.flags = (PageFlags) ((byte) (this.flags | PageFlags.FirstPageOfStream));
     }
 }
Пример #13
0
 public PageHeader(uint streamSerialNumber, uint pageNumber, PageFlags flags)
 {
     this.version = 0;
     this.flags = flags;
     this.absolute_granular_position = 0L;
     this.stream_serial_number = streamSerialNumber;
     this.page_sequence_number = pageNumber;
     this.size = 0;
     this.data_size = 0;
     this.packet_sizes = new List<int>();
     if ((pageNumber == 0) && (((byte) (flags & PageFlags.FirstPacketContinued)) == 0))
     {
         this.flags = (PageFlags) ((byte) (this.flags | PageFlags.FirstPageOfStream));
     }
 }
Пример #14
0
 public PageHeader(PageHeader original, uint offset, PageFlags flags)
 {
     version    = original.version;
     this.flags = flags;
     absolute_granular_position = original.absolute_granular_position;
     stream_serial_number       = original.stream_serial_number;
     page_sequence_number       = original.page_sequence_number + offset;
     size         = original.size;
     data_size    = original.data_size;
     packet_sizes = new List <int>();
     if (page_sequence_number == 0 && (flags & PageFlags.FirstPacketContinued) == 0)
     {
         this.flags |= PageFlags.FirstPageOfStream;
     }
 }
Пример #15
0
        public static unsafe ulong CalculatePageChecksum(byte *ptr, long pageNumber, PageFlags flags, int overflowSize)
        {
            var dataLength = Constants.Storage.PageSize - (PageHeader.ChecksumOffset + sizeof(ulong));

            if ((flags & PageFlags.Overflow) == PageFlags.Overflow)
            {
                dataLength = overflowSize - (PageHeader.ChecksumOffset + sizeof(ulong));
            }

            var ctx = Hashing.Streamed.XXHash64.BeginProcess((ulong)pageNumber);

            Hashing.Streamed.XXHash64.Process(ctx, ptr, PageHeader.ChecksumOffset);
            Hashing.Streamed.XXHash64.Process(ctx, ptr + PageHeader.ChecksumOffset + sizeof(ulong), dataLength);

            return(Hashing.Streamed.XXHash64.EndProcess(ctx));
        }
Пример #16
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="PageHeader" /> with a given serial number, page
        ///    number, and flags.
        /// </summary>
        /// <param name="streamSerialNumber">
        ///    A <see cref="uint" /> value containing the serial number
        ///    for the stream containing the page described by the new
        ///    instance.
        /// </param>
        /// <param name="pageNumber">
        ///    A <see cref="uint" /> value containing the index of the
        ///    page described by the new instance in the stream.
        /// </param>
        /// <param name="flags">
        ///    A <see cref="PageFlags" /> object containing the flags
        ///    that apply to the page described by the new instance.
        /// </param>
        public PageHeader(uint streamSerialNumber, uint pageNumber, PageFlags flags)
        {
            version = 0;
            Flags   = flags;
            absolute_granular_position = 0;
            StreamSerialNumber         = streamSerialNumber;
            PageSequenceNumber         = pageNumber;
            Size         = 0;
            DataSize     = 0;
            packet_sizes = new List <int> ();

            if (pageNumber == 0 && (flags & PageFlags.FirstPacketContinued) == 0)
            {
                Flags |= PageFlags.FirstPageOfStream;
            }
        }
Пример #17
0
        public PageHeader(PageHeader original, uint offset, PageFlags flags)
        {
            _version = original._version;
            _flags   = flags;
            _absolute_granular_position = original._absolute_granular_position;
            _stream_serial_number       = original._stream_serial_number;
            _page_sequence_number       = original._page_sequence_number + offset;
            _size         = original._size;
            _data_size    = original._data_size;
            _packet_sizes = new List <int> ();

            if (_page_sequence_number == 0 && (flags & PageFlags.FirstPacketContinued) == 0)
            {
                _flags |= PageFlags.FirstPageOfStream;
            }
        }
Пример #18
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="PageHeader" /> by copying the values from another
        ///    instance, offsetting the page number and applying new
        ///    flags.
        /// </summary>
        /// <param name="original">
        ///    A <see cref="PageHeader"/> object to copy the values
        ///    from.
        /// </param>
        /// <param name="offset">
        ///    A <see cref="uint"/> value specifying how much to offset
        ///    the page sequence number in the new instance.
        /// </param>
        /// <param name="flags">
        ///    A <see cref="PageFlags"/> value specifying the flags to
        ///    use in the new instance.
        /// </param>
        public PageHeader(PageHeader original, uint offset, PageFlags flags)
        {
            version = original.version;
            Flags   = flags;
            absolute_granular_position = original.absolute_granular_position;
            StreamSerialNumber         = original.StreamSerialNumber;
            PageSequenceNumber         = original.PageSequenceNumber + offset;
            Size         = original.Size;
            DataSize     = original.DataSize;
            packet_sizes = new List <int> ();

            if (PageSequenceNumber == 0 && (flags & PageFlags.FirstPacketContinued) == 0)
            {
                Flags |= PageFlags.FirstPageOfStream;
            }
        }
Пример #19
0
 public PageHeader(TagLib.Ogg.File file, long position)
 {
     if (file == null)
     {
         throw new ArgumentNullException("file");
     }
     if ((position < 0L) || (position > (file.Length - 0x1bL)))
     {
         throw new ArgumentOutOfRangeException("position");
     }
     file.Seek(position);
     ByteVector vector = file.ReadBlock(0x1b);
     if ((vector.Count < 0x1b) || !vector.StartsWith("OggS"))
     {
         throw new CorruptFileException("Error reading page header");
     }
     this.version = vector[4];
     this.flags = (PageFlags) vector[5];
     this.absolute_granular_position = vector.Mid(6, 8).ToULong(false);
     this.stream_serial_number = vector.Mid(14, 4).ToUInt(false);
     this.page_sequence_number = vector.Mid(0x12, 4).ToUInt(false);
     int length = vector[0x1a];
     ByteVector vector2 = file.ReadBlock(length);
     if ((length < 1) || (vector2.Count != length))
     {
         throw new CorruptFileException("Incorrect number of page segments");
     }
     this.size = (uint) (0x1b + length);
     this.packet_sizes = new List<int>();
     int item = 0;
     this.data_size = 0;
     for (int i = 0; i < length; i++)
     {
         this.data_size += vector2[i];
         item += vector2[i];
         if (vector2[i] < 0xff)
         {
             this.packet_sizes.Add(item);
             item = 0;
         }
     }
     if (item > 0)
     {
         this.packet_sizes.Add(item);
     }
 }
Пример #20
0
        public override void Map(uint pAddr, uint vAddr, PageFlags flags, UpdateUsedPagesFlags UpdateUsedPages = UpdateUsedPagesFlags.Both)
        {
            PTEFlags pteFlags = PTEFlags.None;

            if ((flags & PageFlags.Present) != 0)
            {
                pteFlags |= PTEFlags.Present;
            }
            if ((flags & PageFlags.KernelOnly) == 0)
            {
                pteFlags |= PTEFlags.UserAllowed;
            }
            if ((flags & PageFlags.Writeable) != 0)
            {
                pteFlags |= PTEFlags.Writeable;
            }
            Map(pAddr, vAddr, pteFlags, UpdateUsedPages);
        }
Пример #21
0
        /// <summary>
        /// Allocates a virtual address range
        /// </summary>
        /// <param name="size">The size</param>
        /// <returns>The pointer to the block</returns>
        public static void *AllocateVirtual(int size)
        {
            // Page align size
            uint sizeAligned = AlignUp((uint)size);

            // Allocate
            int       free  = bitmap.FindFirstFreeRange((int)(sizeAligned / 0x1000), true);
            int       start = free * 0x1000;
            int       end   = (int)(start + sizeAligned);
            PageFlags flags = PageFlags.Present | PageFlags.Writable | PageFlags.UserMode;

            for (int address = start; address < end; address += 0x1000)
            {
                int phys = (int)PhysicalMemoryManager.Alloc();
                MapPage(KernelDirectory, phys, address, flags);
                MapPage(CurrentDirectory, phys, address, flags);
            }

            // Clear the data before returning it for safety
            Memory.Memclear((void *)start, size);

            return((void *)start);
        }
Пример #22
0
 /// <summary>
 /// Maps the specified virtual address to the specified physical address.
 /// </summary>
 /// <param name="pAddr">The physical address to map to.</param>
 /// <param name="vAddr">The virtual address to map.</param>
 /// <param name="flags">The flags to apply to the allocated pages.</param>
 /// <param name="UpdateUsedPages">Which, if any, of the physical and virtual used pages lists to update.</param>
 public abstract void Map(uint pAddr, uint vAddr, PageFlags flags, UpdateUsedPagesFlags UpdateUsedPages = UpdateUsedPagesFlags.Both);
Пример #23
0
		public PageHeader (PageHeader original, uint offset, PageFlags flags)
		{
			_version = original._version;
			_flags = flags;
			_absolute_granular_position = original._absolute_granular_position;
			_stream_serial_number = original._stream_serial_number;
			_page_sequence_number = original._page_sequence_number + offset;
			_size = original._size;
			_data_size = original._data_size;
			_packet_sizes = new List<int> ();
			
			if (_page_sequence_number == 0 && (flags & PageFlags.FirstPacketContinued) == 0)
				_flags |= PageFlags.FirstPageOfStream;
		}
Пример #24
0
		internal Page AllocatePage(int numberOfPages, PageFlags flags, long? pageNumber = null)
		{
            if (_disposed)
                throw new ObjectDisposedException("Transaction");

			if (pageNumber == null)
			{
				pageNumber = _freeSpaceHandling.TryAllocateFromFreeSpace(this, numberOfPages);
				if (pageNumber == null) // allocate from end of file
				{
					pageNumber = State.NextPageNumber;
					State.NextPageNumber += numberOfPages;
				}
			}

			if (_env.Options.MaxStorageSize.HasValue) // check against quota
			{
				var maxAvailablePageNumber = _env.Options.MaxStorageSize / AbstractPager.PageSize;

				if(pageNumber.Value > maxAvailablePageNumber)
					throw new QuotaException(
						string.Format(
							"The maximum storage size quota ({0} bytes) has been reached. " +
							"Currently configured storage quota is allowing to allocate the following maximum page number {1}, while the requested page number is {2}. " +
							"To increase the quota, use the MaxStorageSize property on the storage environment options.",
							_env.Options.MaxStorageSize, maxAvailablePageNumber, pageNumber.Value));
			}


			Debug.Assert(pageNumber < State.NextPageNumber);

			var pageFromScratchBuffer = _env.ScratchBufferPool.Allocate(this, numberOfPages);
			_transactionPages.Add(pageFromScratchBuffer);

			var page = _env.ScratchBufferPool.ReadPage(pageFromScratchBuffer.ScratchFileNumber, pageFromScratchBuffer.PositionInScratchBuffer);
			page.PageNumber = pageNumber.Value;

			_allocatedPagesInTransaction++;
			if (numberOfPages > 1)
			{
				_overflowPagesInTransaction += (numberOfPages - 1);
			}

			_scratchPagesTable[pageNumber.Value] = pageFromScratchBuffer;

			page.Lower = (ushort)Constants.PageHeaderSize;
			page.Flags = flags;

			if ((flags & PageFlags.KeysPrefixed) == PageFlags.KeysPrefixed)
			{
				page.Upper = (ushort) (AbstractPager.PageSize - Constants.PrefixInfoSectionSize);
				page.ClearPrefixInfo();
			}
			else
				page.Upper = AbstractPager.PageSize;

			page.Dirty = true;

			_dirtyPages.Add(page.PageNumber);

			if (numberOfPages > 1)
				_dirtyOverflowPages.Add(page.PageNumber + 1, numberOfPages - 1);

			return page;
		}
Пример #25
0
        bool ReadPageHeader(out int streamSerial, out PageFlags flags, out long granulePosition, out int seqNo, out long dataOffset, out int[] packetSizes, out bool lastPacketContinues)
        {
            streamSerial = -1;
            flags = PageFlags.None;
            granulePosition = -1L;
            seqNo = -1;
            dataOffset = -1L;
            packetSizes = null;
            lastPacketContinues = false;

            // header
            var hdrBuf = new byte[27];
            if (_stream.Read(hdrBuf, 0, hdrBuf.Length) != hdrBuf.Length) return false;

            // capture signature
            if (hdrBuf[0] != 0x4f || hdrBuf[1] != 0x67 || hdrBuf[2] != 0x67 || hdrBuf[3] != 0x53) return false;

            // check the stream version
            if (hdrBuf[4] != 0) return false;

            // bit flags
            flags = (PageFlags)hdrBuf[5];

            // granulePosition
            granulePosition = BitConverter.ToInt64(hdrBuf, 6);

            // stream serial
            streamSerial = BitConverter.ToInt32(hdrBuf, 14);

            // sequence number
            seqNo = BitConverter.ToInt32(hdrBuf, 18);

            // save off the CRC
            var crc = BitConverter.ToUInt32(hdrBuf, 22);

            // start calculating the CRC value for this page
            var testCRC = 0U;
            for (int i = 0; i < 22; i++)
            {
                UpdateCRC(hdrBuf[i], ref testCRC);
            }
            UpdateCRC(0, ref testCRC);
            UpdateCRC(0, ref testCRC);
            UpdateCRC(0, ref testCRC);
            UpdateCRC(0, ref testCRC);
            UpdateCRC(hdrBuf[26], ref testCRC);

            // figure out the length of the page
            var segCnt = (int)hdrBuf[26];
            packetSizes = new int[segCnt];
            int size = 0, idx = 0;
            for (int i = 0; i < segCnt; i++)
            {
                var temp = _stream.ReadByte();
                UpdateCRC(temp, ref testCRC);

                packetSizes[idx] += temp;
                if (temp < 255)
                {
                    ++idx;
                    lastPacketContinues = false;
                }
                else
                {
                    lastPacketContinues = true;
                }

                size += temp;
            }
            if (lastPacketContinues) ++idx;
            if (idx < packetSizes.Length)
            {
                var temp = new int[idx];
                for (int i = 0; i < idx; i++)
                {
                    temp[i] = packetSizes[i];
                }
                packetSizes = temp;
            }

            dataOffset = _stream.Position;

            // now we have to go through every byte in the page
            while (--size >= 0)
            {
                UpdateCRC(_stream.ReadByte(), ref testCRC);
            }

            _nextPageOffset = _stream.Position;

            _containerBits += 8 * (27 + segCnt);
            if (testCRC == crc)
            {
                ++_pageCount;
                return true;
            }
            _containerBits -= 8 * (27 + segCnt);    // we're going to look for the bits separately...
            return false;
        }
Пример #26
0
        internal Page AllocatePage(int numberOfPages, PageFlags flags, long?pageNumber = null)
        {
            if (pageNumber == null)
            {
                pageNumber = _freeSpaceHandling.TryAllocateFromFreeSpace(this, numberOfPages);
                if (pageNumber == null)                 // allocate from end of file
                {
                    pageNumber            = State.NextPageNumber;
                    State.NextPageNumber += numberOfPages;
                }
            }

            if (_env.Options.MaxStorageSize.HasValue)             // check against quota
            {
                var maxAvailablePageNumber = _env.Options.MaxStorageSize / AbstractPager.PageSize;

                if (pageNumber.Value > maxAvailablePageNumber)
                {
                    throw new QuotaException(
                              string.Format(
                                  "The maximum storage size quota ({0} bytes) has been reached. " +
                                  "Currently configured storage quota is allowing to allocate the following maximum page number {1}, while the requested page number is {2}. " +
                                  "To increase the quota, use the MaxStorageSize property on the storage environment options.",
                                  _env.Options.MaxStorageSize, maxAvailablePageNumber, pageNumber.Value));
                }
            }


            Debug.Assert(pageNumber < State.NextPageNumber);

            var pageFromScratchBuffer = _env.ScratchBufferPool.Allocate(this, numberOfPages);

            _transactionPages.Add(pageFromScratchBuffer);

            var page = _env.ScratchBufferPool.ReadPage(pageFromScratchBuffer.ScratchFileNumber, pageFromScratchBuffer.PositionInScratchBuffer);

            page.PageNumber = pageNumber.Value;

            _allocatedPagesInTransaction++;
            if (numberOfPages > 1)
            {
                _overflowPagesInTransaction += (numberOfPages - 1);
            }

            _scratchPagesTable[pageNumber.Value] = pageFromScratchBuffer;

            page.Lower = (ushort)Constants.PageHeaderSize;
            page.Flags = flags;

            if ((flags & PageFlags.KeysPrefixed) == PageFlags.KeysPrefixed)
            {
                page.Upper = (ushort)(AbstractPager.PageSize - Constants.PrefixInfoSectionSize);
                page.ClearPrefixInfo();
            }
            else
            {
                page.Upper = AbstractPager.PageSize;
            }

            page.Dirty = true;

            _dirtyPages.Add(page.PageNumber);

            if (numberOfPages > 1)
            {
                _dirtyOverflowPages.Add(page.PageNumber + 1, numberOfPages - 1);
            }

            return(page);
        }
Пример #27
0
        /// <summary>
        /// Maps a physical address (range) to a free virtual address (range)
        /// </summary>
        /// <param name="directory">The page directory</param>
        /// <param name="phys">The physical address</param>
        /// <param name="size">The size of the range</param>
        /// <param name="flags">The flags</param>
        /// <returns>The virtual address</returns>
        public static void *MapToVirtual(PageDirectory *directory, int phys, int size, PageFlags flags)
        {
            int sizeAligned = (int)AlignUp((uint)size) / 0x1000;
            int free        = bitmap.FindFirstFreeRange(sizeAligned, true);
            int virt        = free * 0x1000;

            for (int i = 0; i < sizeAligned; i++)
            {
                int offset = i * 0x1000;
                MapPage(directory, phys + offset, virt + offset, flags);
                PhysicalMemoryManager.Set(phys + offset);
            }
            Paging.setDirectoryInternal(Paging.CurrentDirectoryPhysical);
            return((void *)virt);
        }
Пример #28
0
		internal static Page NewPage(Transaction tx, PageFlags flags, int num)
		{
			var page = tx.AllocatePage(num);
			page.Flags = flags;

			return page;
		}
Пример #29
0
 public override void Map(uint pAddr, uint vAddr, PageFlags flags, UpdateUsedPagesFlags UpdateUsedPages = UpdateUsedPagesFlags.Both)
 {
     PTEFlags pteFlags = PTEFlags.None;
     if ((flags & PageFlags.Present) != 0)
     {
         pteFlags |= PTEFlags.Present;
     }
     if ((flags & PageFlags.KernelOnly) == 0)
     {
         pteFlags |= PTEFlags.UserAllowed;
     }
     if ((flags & PageFlags.Writeable) != 0)
     {
         pteFlags |= PTEFlags.Writeable;
     }
     Map(pAddr, vAddr, pteFlags, UpdateUsedPages);
 }
Пример #30
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="PageHeader" /> by copying the values from another
        ///    instance, offsetting the page number and applying new
        ///    flags.
        /// </summary>
        /// <param name="original">
        ///    A <see cref="PageHeader"/> object to copy the values
        ///    from.
        /// </param>
        /// <param name="offset">
        ///    A <see cref="uint"/> value specifying how much to offset
        ///    the page sequence number in the new instance.
        /// </param>
        /// <param name="flags">
        ///    A <see cref="PageFlags"/> value specifying the flags to
        ///    use in the new instance.
        /// </param>
        public PageHeader(PageHeader original, uint offset,
		                   PageFlags flags)
        {
            version = original.version;
            this.flags = flags;
            absolute_granular_position =
                original.absolute_granular_position;
            stream_serial_number = original.stream_serial_number;
            page_sequence_number =
                original.page_sequence_number + offset;
            size = original.size;
            data_size = original.data_size;
            packet_sizes = new List<int> ();

            if (page_sequence_number == 0 &&
                (flags & PageFlags.FirstPacketContinued) == 0)
                this.flags |= PageFlags.FirstPageOfStream;
        }
Пример #31
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="PageHeader" /> by reading a raw Ogg page header
        ///    from a specified position in a specified file.
        /// </summary>
        /// <param name="file">
        ///    A <see cref="File" /> object containing the file from
        ///    which the contents of the new instance are to be read.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value specify at what position to
        ///    read.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///    <paramref name="position" /> is less than zero or greater
        ///    than the size of the file.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    The Ogg identifier could not be found at the correct
        ///    location.
        /// </exception>
        public PageHeader(File file, long position)
        {
            if (file == null)
                throw new ArgumentNullException ("file");

            if (position < 0 || position > file.Length - 27)
                throw new ArgumentOutOfRangeException (
                    "position");

            file.Seek (position);

            // An Ogg page header is at least 27 bytes, so we'll go
            // ahead and read that much and then get the rest when
            // we're ready for it.

            ByteVector data = file.ReadBlock (27);
            if (data.Count < 27 || !data.StartsWith ("OggS"))
                System.Console.WriteLine(
                    "Error reading page header");

            version = data [4];
            this.flags = (PageFlags) data [5];
            absolute_granular_position = data.Mid(6, 8).ToULong (
                false);
            stream_serial_number = data.Mid(14, 4).ToUInt (false);
            page_sequence_number = data.Mid(18, 4).ToUInt (false);

            // Byte number 27 is the number of page segments, which
            // is the only variable length portion of the page
            // header. After reading the number of page segments
            // we'll then read in the coresponding data for this
            // count.
            int page_segment_count = data [26];
            ByteVector page_segments =
                file.ReadBlock (page_segment_count);

            // Another sanity check.
            if (page_segment_count < 1 ||
                page_segments.Count != page_segment_count)
                System.Console.WriteLine(
                    "Incorrect number of page segments");

            // The base size of an Ogg page 27 bytes plus the number
            // of lacing values.
            size = (uint)(27 + page_segment_count);
            packet_sizes = new List<int> ();

            int packet_size = 0;
            data_size = 0;

            for (int i = 0; i < page_segment_count; i++) {
                data_size += page_segments [i];
                packet_size += page_segments [i];

                if (page_segments [i] < 255) {
                    packet_sizes.Add (packet_size);
                    packet_size = 0;
                }
            }

            if (packet_size > 0)
                packet_sizes.Add (packet_size);
        }
Пример #32
0
 /// <summary>
 /// Maps the specified virtual address to the specified physical address.
 /// </summary>
 /// <param name="pAddr">The physical address to map to.</param>
 /// <param name="vAddr">The virtual address to map.</param>
 /// <param name="flags">The flags to apply to the allocated pages.</param>
 /// <param name="UpdateUsedPages">Which, if any, of the physical and virtual used pages lists to update.</param>
 public abstract void Map(uint pAddr, uint vAddr, PageFlags flags, UpdateUsedPagesFlags UpdateUsedPages = UpdateUsedPagesFlags.Both);