示例#1
0
        /// <summary>
        /// Reads the file descriptor sector for a given file and verified that all sectors in the file segment list (and the file descriptor sector itself)
        /// are marked as free in the passed cluster allocation map.  It then marks the clusters as marked.
        /// </summary>
        /// <param name="map">Cluster allocation map.</param>
        /// <param name="filedesc">Logical sector number of the file descriptor sector for the file.</param>
        /// <param name="clustersize">Cluster size for this filesystem.</param>
        /// <exception cref="FilesystemConsistencyException">Thrown if any cluster used for this file is already allocated.</exception>
        private void VerifyAndUpdateAllocationMap(OS9AllocationMap map, int filedesc, int clustersize)
        {
            var fileinfo = OS9FileInfo.Parse(ReadSector(filedesc), null);

            /* Verify that all sectors used by this file are marked as free in the cluster allocation map. */
            if (map.IsAllocated(filedesc / clustersize))
            {
                throw new FilesystemConsistencyException(String.Format("Sector {0} is in use by multiple files", filedesc));
            }
            foreach (var segment in fileinfo.Segments)
            {
                int sector = segment.Lsn;
                for (int i = 0; i < segment.Size; i++)
                {
                    if (map.IsAllocated(sector / clustersize))
                    {
                        throw new FilesystemConsistencyException(String.Format("Sector {0} is in use by multiple files", sector));
                    }
                    sector++;
                }
            }

            /* Mark all sectors as allocated. */
            map.SetAllocated(filedesc / clustersize, true);
            foreach (var segment in fileinfo.Segments)
            {
                int sector = segment.Lsn;
                for (int i = 0; i < segment.Size; i++)
                {
                    map.SetAllocated(sector / clustersize, true);
                    sector++;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Checks the filesystem consistency.
        /// </summary>
        /// <exception cref="FilesystemConsistencyException">Thrown if the filesystem is not consistent in a manner that makes write operations unsafe.</exception>
        public void Check()
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            ReadDiskHeader();

            var allocmap = new OS9AllocationMap(DiskInfo.AllocationMapSize);            // mirror the allocation map

            allocmap.SetAllocated(IdentificationSector / DiskInfo.ClusterSize, true);
            allocmap.SetAllocated(AllocationMapSector / DiskInfo.ClusterSize, true);

            var dirs = new Queue <int>();                        // LSN of all directories found while traversing the file structure

            dirs.Enqueue(DiskInfo.RootDirectory);
            VerifyAndUpdateAllocationMap(allocmap, DiskInfo.RootDirectory, DiskInfo.ClusterSize);

            /* Traverse the directory hierarchy and update the cluster allocation map for all files encountered. */
            while (dirs.Count > 0)
            {
                int lsn   = dirs.Dequeue();
                var files = ReadDirectory(lsn);
                foreach (var file in files)
                {
                    if (file.IsValid && !String.Equals(file.Filename, ".") && !String.Equals(file.Filename, ".."))
                    {
                        VerifyAndUpdateAllocationMap(allocmap, file.Sector, DiskInfo.ClusterSize);
                        var fileinfo = OS9FileInfo.Parse(ReadSector(file.Sector), file.Filename);
                        if (fileinfo.IsDirectory)
                        {
                            dirs.Enqueue(file.Sector);
                        }
                    }
                }
            }

            /* Finally, verify that all clusters used by files found are actually marked as allocated in the disk cluster allocation map. */
            for (int i = 0; i < AllocationMap.AllocationMapSize; i++)
            {
                if (allocmap.IsAllocated(i) && !AllocationMap.IsAllocated(i))
                {
                    throw new FilesystemConsistencyException(String.Format("Cluster {0} is in use by a file but not marked as allocated", i));
                }
            }
        }
示例#3
0
        /// <summary>
        /// Reads a directory starting at a given disk sector.
        /// </summary>
        /// <param name="sector">First sector of the directory file.</param>
        /// <returns>A list of (filename, sector) tuples for the entries in the directory.</returns>
        internal List <OS9DirectoryEntry> ReadDirectory(int sector)
        {
            var header = OS9FileInfo.Parse(ReadSector(sector), null);

            if (!header.IsDirectory)
            {
                throw new InvalidFileException();
            }

            var dir        = new List <OS9DirectoryEntry>();
            var raw        = ReadFile(header);
            int direntries = raw.Length / OS9DirectoryEntry.RawEntrySize;

            for (int i = 0; i < direntries; i++)
            {
                dir.Add(new OS9DirectoryEntry(raw, i));
            }

            return(dir);
        }
示例#4
0
        /// <summary>
        /// Returns meta-information for a named file.
        /// </summary>
        /// <param name="filename">Name of file</param>
        /// <returns>File meta-information object.</returns>
        public IFileInfo GetFileInfo(string filename)
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
            if (filename == null)
            {
                throw new ArgumentNullException();
            }

            int sector = FindPath(filename);

            if (sector == -1)
            {
                throw new FileNotFoundException(filename);
            }

            var raw = ReadSector(sector);

            return(OS9FileInfo.Parse(raw, filename));
        }