Esempio n. 1
0
        private Dir LoadDir(uint dinode, Dir parent, string name)
        {
            // 100M blocks is enough for a 6TB file.
            const int MAX_BLOCKS = 100_000_000;
            var       ret        = new Dir()
            {
                name = name, parent = parent
            };
            var ino      = dinodes[dinode];
            var postLoad = new List <Func <Dir> >();
            var blocks   = (int)ino.Blocks;

            if (blocks < 1 || ino.StartBlock < 1 || ino.StartBlock > MAX_BLOCKS || blocks > MAX_BLOCKS)
            {
                throw new Exception($"inode {dinode} is corrupt. ");
            }
            foreach (var x in Enumerable.Range(ino.StartBlock, blocks))
            {
                var position = hdr.BlockSize * x;
                reader.Read(position, sectorBuf, 0, sectorBuf.Length);
                sectorStream.Position = 0;
                while (position < hdr.BlockSize * (x + 1))
                {
                    var dirent = PfsDirent.ReadFromStream(sectorStream);
                    if (dirent.EntSize == 0)
                    {
                        break;
                    }
                    switch (dirent.Type)
                    {
                    case DirentType.File:
                        ret.children.Add(LoadFile(dirent.InodeNumber, ret, dirent.Name));
                        break;

                    case DirentType.Directory:
                        postLoad.Add(() => LoadDir(dirent.InodeNumber, ret, dirent.Name));
                        break;

                    case DirentType.Dot:
                        break;

                    case DirentType.DotDot:
                        break;

                    default:
                        break;
                    }
                    position += dirent.EntSize;
                }
            }
            foreach (var p in postLoad)
            {
                ret.children.Add(p());
            }
            return(ret);
        }
        private Dir LoadDir(uint dinode, Node parent, string name)
        {
            var ret = new Dir()
            {
                name = name, parent = parent
            };
            var ino      = dinodes[dinode];
            var postLoad = new List <Func <Dir> >();

            foreach (var x in Enumerable.Range(ino.StartBlock, (int)ino.Blocks))
            {
                var position = hdr.BlockSize * x;
                reader.Read(position, sectorBuf, 0, sectorBuf.Length);
                sectorStream.Position = 0;
                while (position < hdr.BlockSize * (x + 1))
                {
                    var dirent = PfsDirent.ReadFromStream(sectorStream);
                    if (dirent.EntSize == 0)
                    {
                        break;
                    }
                    switch (dirent.Type)
                    {
                    case DirentType.File:
                        ret.children.Add(LoadFile(dirent.InodeNumber, ret, dirent.Name));
                        break;

                    case DirentType.Directory:
                        postLoad.Add(() => LoadDir(dirent.InodeNumber, ret, dirent.Name));
                        break;

                    case DirentType.Dot:
                        break;

                    case DirentType.DotDot:
                        break;

                    default:
                        break;
                    }
                    position += dirent.EntSize;
                }
            }
            foreach (var p in postLoad)
            {
                ret.children.Add(p());
            }
            return(ret);
        }