Example #1
0
        /// <summary>
        /// 获取空闲块
        /// </summary>
        /// <returns></returns>
        public int GetFreeBlock()
        {
            int reValue;

            byte[] readIn = new byte[4];

            reValue = _initSuper._s_free[--_initSuper._s_nfree];

            //出错处理,已经分配完空闲盘块
            if (_initSuper._s_nfree <= 0 && reValue == 0)
            {
                throw (new Exception("空闲数据块已分配完"));
            }

            //如果本批次直接管理的空闲块用完,则导入下一组
            if (_initSuper._s_nfree <= 0)
            {
                _diskFile.OpenFile();
                _diskFile.SeekFilePosition(512 * reValue, System.IO.SeekOrigin.Begin);
                _diskFile.ReadFile(ref readIn, 0, 4);
                _initSuper._s_nfree = (int)Helper.Bytes2Struct(readIn, typeof(int));

                for (int i = 0; i < 100; ++i)
                {
                    _diskFile.ReadFile(ref readIn, 0, 4);
                    _initSuper._s_free[i] = (int)Helper.Bytes2Struct(readIn, typeof(int));
                }
                _diskFile.CloseFile();
            }
            //最好在这里将新申请到的块全部清零

            CleanBlock(reValue);
            _initSuper.UpdateSuperBlockToDisk();
            return(reValue);
        }
Example #2
0
        /// <summary>
        /// 创建文件时的目录搜索
        /// 本函数共4个出口
        /// 出口1:目录搜索完毕,且满足三个条件:1.之前各级目录名都能找到,2.但没有符合的最后一级文件,3.且传入的flag为CREATFILE
        /// 出口2:目录搜索完毕,但不完全满足上述三个条件
        /// 出口3:文件(或目录)在系统中已存在,且传入flag为DELETEFILE
        /// 出口4:文件(或目录)在系统中已存在,但传入flag不为DELETEFILE
        /// </summary>
        /// <param name="path">创建文件的目录</param>
        /// <param name="DirInodeNo">父目录的inode号</param>
        /// <returns>目录项的位置</returns>
        public int NameI(string path, ref int dirInodeNo, ref InodeStr dirInode, ref int fileInodeNo, ref InodeStr fileInode, ref char[] fileName, int flag)
        {
            //用于记录在路径字符串中扫描到了哪里
            int curPos = 0;

            //用于记录inode号
            dirInodeNo = 0;
            //首先读入根目录inode
            _inode.GetInodeFromDisk(dirInode, dirInodeNo);

            //跳过开始的一个(或者多个)'/'字符
            for (; curPos < path.Length; ++curPos)
            {
                if (path[curPos] != '/')
                {
                    break;
                }
            }

            //主循环
            while (true)
            {
                //获取两个'/'当中的内容,存入dirPath中
                char[] tmp = new char[28];
                for (int i = 0; curPos < path.Length; ++curPos, ++i)
                {
                    if (path[curPos] == '/')
                    {
                        break;
                    }
                    tmp[i] = path[curPos];
                }
                tmp.CopyTo(fileName, 0);

                //跳过下一个(或者多个)'/'字符,为下一次循环(下一级目录,如果有的话)做准备
                for (; curPos < path.Length; ++curPos)
                {
                    if (path[curPos] != '/')
                    {
                        break;
                    }
                }
                //用于存储扫描当前目录文件的偏移量
                int offset = 0;
                //用于记录第一个空闲目录项的偏移量
                int firstFreeOffset = 0;
                //记录是否又空闲目录项
                int freeFlag = 0;
                //目录项项数
                int dirSize = dirInode._i_size / 32;
                //用于读取一个磁盘块
                byte[] buffer = new byte[512];

                //(次循环)在当前目录文件中搜索
                while (true)
                {
                    //出口1:对当前目录搜索完毕(用于查找是否有同名文件存在)
                    if (dirSize == 0)
                    {
                        //若当前目录索搜索完毕(没有找到相应项),且只是路径名的最后一段没有找到(要创建的文件名),则创建文件
                        if (flag == File.CREATFILE && curPos == path.Length)
                        {
                            //新分配一个inode控制块,返回该inode号
                            try
                            {
                                fileInodeNo = _inode.FetchFreeInode();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                            //根据inode号获取对应的inode(搜索到了哪一层就获取哪一层目录的inode)
                            _inode.GetInodeFromDisk(fileInode, fileInodeNo);
                            //若之前扫描途中有空闲项,则返回其偏移,否则就返回当前inode的大小(即要对当前inode进行扩充)
                            if (freeFlag == 0)
                            {
                                return(dirInode._i_size);
                            }
                            else
                            {
                                return(firstFreeOffset);
                            }
                        }
                        //出口2:若当前目录搜索完毕(没有找到相应项),且中间路径没有找到,则出错
                        else
                        {
                            Error.ErrorType = Error.SEARCHDIR;
                            return(-1);
                        }
                    }

                    //搜索完一块,需要读入新块
                    if (offset % 512 == 0)
                    {
                        _diskFile.OpenFile();
                        _diskFile.SeekFilePosition(this.BMap(dirInode, offset / 512) * 512, System.IO.SeekOrigin.Begin);
                        _diskFile.ReadFile(ref buffer, 0, 512);
                        _diskFile.CloseFile();
                    }

                    bool match = true;
                    for (int j = 0; j < 28; ++j)
                    {
                        if (Convert.ToByte(fileName[j]) != buffer[offset % 512 + j + 4])
                        {
                            match = false;
                            break;
                        }
                    }

                    //表示不匹配
                    if (!match)
                    {
                        dirSize--;
                        //如果之前的目录项为空,则将其用first_free_offset标记
                        //+4是因为每个目录项的前四个字节是inode号
                        if (buffer[offset % 512 + 4] == '\0' && firstFreeOffset == 0)
                        {
                            firstFreeOffset = offset;
                            freeFlag        = 1;
                        }
                        offset += 32;
                        continue;
                    }
                    //在当前目录中找到了和dirPath匹配的目录项
                    else
                    {
                        break;
                    }
                }

                byte[] ino = new byte[4];
                for (int k = 0; k < 4; ++k)
                {
                    ino[k] = buffer[offset % 512 + k];
                }

                /* 出口3:
                 * 删除操作
                 * pathPoint == path.Length表示:目录项已经搜索完毕*/
                if (flag == File.DELETEFILE && curPos == path.Length)
                {
                    //需删除文件的inode号
                    fileInodeNo = (int)Helper.Bytes2Struct(ino, typeof(int));
                    return(offset);
                }

                /* 出口4:
                 * 同一目录下的文件名相同,且不是要做删除操作,则出错
                 * pathPoint == path.Length表示:目录项已经搜索完毕*/
                if (flag != File.DELETEFILE && curPos == path.Length)
                {
                    Error.ErrorType = Error.SAMEFILENAME;
                    return(-1);
                }

                //如果还有下级目录,则更新dirInodeNo与dirInode,为当前目录
                dirInodeNo = (int)Helper.Bytes2Struct(ino, typeof(int));
                _inode.GetInodeFromDisk(dirInode, dirInodeNo);
            }
        }
Example #3
0
        /// <summary>
        /// 从磁盘读出当前超级块的内容(暂无引用)
        /// </summary>
        public void ReadSuperBlock()
        {
            byte[] read;
            //定位到超级块起始位置
            _diskFile.OpenFile();
            _diskFile.SeekFilePosition(MachinePara.BootAndKernelSize * 512, System.IO.SeekOrigin.Begin);

            //inode区占据的磁盘块数
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_isize = (int)Helper.Bytes2Struct(read, typeof(int));

            //总的磁盘块数,为扇区数的一半
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_fsize = (int)Helper.Bytes2Struct(read, typeof(int));

            //得到直接管理块数
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_nfree = (int)Helper.Bytes2Struct(read, typeof(int));

            //得到空闲列表
            for (int i = 0; i < 100; ++i)
            {
                read = new byte[4];
                _diskFile.ReadFile(ref read, 0, 4);
                _s_free[i] = (int)Helper.Bytes2Struct(read, typeof(int));
            }

            //得到直接管理的inode数量
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_ninode = (int)Helper.Bytes2Struct(read, typeof(int));

            //得到空闲inode列表
            for (int i = 0; i < 100; ++i)
            {
                read = new byte[4];
                _diskFile.ReadFile(ref read, 0, 4);
                _s_inode[i] = (int)Helper.Bytes2Struct(read, typeof(int));
            }

            //封锁标志
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_flock = (int)Helper.Bytes2Struct(read, typeof(int));

            //inode封锁标志
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_ilock = (int)Helper.Bytes2Struct(read, typeof(int));

            //已修改标志
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_fmod = (int)Helper.Bytes2Struct(read, typeof(int));

            //只读标志
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_ronly = (int)Helper.Bytes2Struct(read, typeof(int));

            //最后修改时间
            read = new byte[4];
            _diskFile.ReadFile(ref read, 0, 4);
            _s_time = (int)Helper.Bytes2Struct(read, typeof(int));

            _diskFile.CloseFile();
        }