예제 #1
0
        /// <summary>
        /// Inserts the entry into list.
        /// Tries to resurrect deleted entry if possible.
        /// Adds new entry if not possible. Updates data in storage.
        /// Tries to do optimization on every 100 items added.
        /// </summary>
        private void InsertEntryIntoList([NotNull] string name, bool directory, [NotNull] Address nodeAddress)
        {
            uint currentBlockIndex = 0;
            uint currentBlockSpace = Constants.BlockSizeBytes;
            foreach (var currentEntry in _list)
            {
                if (currentEntry.IsDeleted && currentEntry.Name.Length >= name.Length)
                {
                    currentEntry.Resurrect(name, directory, nodeAddress);
                    currentEntry.Save(DiskAccess);
                    return;
                }
                if (currentEntry.EntrySizeBytes > currentBlockSpace)
                {
                    currentBlockIndex++;
                    currentBlockSpace = Constants.BlockSizeBytes;
                }

                currentBlockSpace -= currentEntry.EntrySizeBytes;
            }

            var newEntry = new DirectoryEntry { Name = name, IsDirectory = directory, NodeAddress = nodeAddress };
            if (currentBlockSpace < newEntry.EntrySizeBytes)
            {
                currentBlockIndex++;
                currentBlockSpace = Constants.BlockSizeBytes;
            }

            if (currentBlockIndex >= Storage.NumBlocksAllocated)
            {
                // should never need to allocate more than 1 block
                Storage.AddBlocks(1);
            }

            var offset = Constants.BlockSizeBytes - currentBlockSpace;
            var addr = Storage.GetBlockStartAddress(currentBlockIndex);
            newEntry.EntrySelfAddress = new Address(addr.Value + offset);
            newEntry.Save(DiskAccess);
            var lastItem = _list.LastOrDefault();
            if (lastItem != null)
            {
                lastItem.Next = newEntry.EntrySelfAddress;
                lastItem.Save(DiskAccess);
            }

            _list.Add(newEntry);
            UpdateSize((ulong)_list.Count); // size holds total number of entries, including deleted ones.

            if (_list.Count % 100 == 0)
            {
                // do space optimization on every 100 files,
                // to prevent attack like adding files with increasing name length.
                Save();
            }
        }
예제 #2
0
        /// <summary>
        /// Overload of base load, used to load directory entries from storage.
        /// </summary>
        /// <exception cref="Exception">Directory entry list corrupted.</exception>
        public override void Load()
        {
            base.Load();

            // now load directory list, after loading base node info.
            _list.Clear();
            var address = Storage.GetBlockStartAddress(0);
            var dataOffset = address.Value;
            for (int i = 0; i < NumberOfEntries; ++i)
            {
                var entry = new DirectoryEntry();
                entry.Load(dataOffset, DiskAccess);
                _list.Add(entry);
                dataOffset = entry.Next == null ? 0 : entry.Next.Value;
            }

            if (NumberOfEntries > 0 && dataOffset != 0)
            {
                throw new Exception("Directory entry list corrupted.");
            }
        }