操作系统课程设计报告文件系统_第1页
操作系统课程设计报告文件系统_第2页
操作系统课程设计报告文件系统_第3页
操作系统课程设计报告文件系统_第4页
操作系统课程设计报告文件系统_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、东莞理工学院操作系统课程设计报告设计时间: 2011-1-5至2011-1-7 专业年级:08计科4班 姓名: 一.设计目的:通过操作系统内其中一个子系统的设计和实现,掌握linux文件系统的基本原理、结构和实现方法,掌握linux文件系统中文件的建立、打开、读/写、执行、属性等系统调用的使用,学会设计简单的文件系统并实现一组操作,以及学习文件系统的系统调用命令,提高对文件系统实现功能的理解和掌握。同时,掌握操作系统设计的方法与技巧,增强系统软件设计的实际工作能力。二.设计内容:为linux 设计一个简单的二级文件系统。本文件系统采用类似dos系统的文件管理方式,每次调用该文件系统时,首先申请

2、一定的内存空间,然后对该内存空间进行分配。将申请到的空间划分为目录区,文件区;采用位示图进行空间管理,盘块的分配使用显示链接(fat表)的方式。每次调用该文件系统时自动为其分配空间,并将上次操作的结果从硬盘上调入内存;当结束调用时则将操作的结果重新存入硬盘,以便下次调用。(每次使用都会自动搜索文件系统,以此确定是否是第一次使用;若是则格式化生成文件系统,否则读取已存在的文件系统。)三设计过程1、 实现功能该系统具备下列功能:login 用户登录 logout 注销mkdir/md 创建目录 rmdir/rd 删除目录cd/cd . 修改目录creat 创建文件open 打开文件dir 显示当前

3、目录和文件write 读文件 delete 删除文件close 关闭文件2、 添加功能(1) 制作了一个“操作命令符”列表框,说明接下来如何操作,这样有利于更好地阅读、操作和运行程序,使不懂得程序代码的人也可以运行该程序,更好地理解该程序实现的功能。(2) 在命令解释层函数cmdexp()里加了一些选择和操作功能,增加程序实现的功能,如原来程序只有显示当前目录和文件、创建目录和修改目录的功能,把它拓展到系统所要求的全部功能,并在原有的程序的基础上进行相应的修改,使程序更加完善。3、 设计思路(1) 要将文件存储在磁盘上,必须为之分配相应的存储空间,并对文件存储空间进行管理,为了简化对文件的访问

4、和共享,还应设置相应的用户文件描述表及文件表。 文件卷的组织unix中,把每个磁盘(带)看作是一个文件卷,每个文件卷上可存放一个具有独立目录结构的文件系统。一个文件卷包含许多物理块,并按块号排列如下图:0# 1# 2# 3# k# k+1# n# 其中,0#块用于系统引导或空闲,1#为超级块(superblock),存放文件卷的资源管理信息,如整个文件卷的盘块数、磁盘索引结点的盘块数、空闲盘块号栈及指针等。2#k#存放磁盘索引结点。每个索引结点64b,第k+1#n#存放文件数据。 空闲盘块的组织 unix采用成组链接法组织空闲盘块。它将若干个空闲盘块划归一个组,将每组中所有盘块号存放在其前一组

5、的第一个空闲盘块中,而第一组中所有空闲盘块号放入超级块的空闲盘块号栈中。 例: 超级块表 10910610310095211208205202 310307304301空闲盘块的分配与回收内核要从文件系统中分配一盘块时,先检查超级块空闲盘块号栈是否已上锁。是则调用sleep睡眠,否则将超级块中空闲盘块栈栈顶盘块号分配出去。回收时,若空闲盘块号栈未满,直接将回收盘块编号记入空闲盘块号栈中。若回收时栈已满,须先将栈中的所有空闲盘块号复制到新回收的盘块中,再将新回收盘块的编号作为新栈的栈底块号进栈。(2) unix中,为了加速对文件目录的查找,将文件名和文件说明分开,由文件说明形成一个称为索引结点的

6、数据结构,而相应的文件目录项则只由文件符号名和指向索引结点的指针构成。对目录的管理应包括的功能有:对索引结点的管理:每个文件都有一唯一的磁盘索引结点(di_node)。文件被打开后,还有一个内存索引结点(i_node)。创建一新文件时,就为之建立一个磁盘索引结点,以将文件的有关信息记入其中,并将用户提供的文件名和磁盘索引结点号一并组成一个新目录项,记入其父目录文件中。文件被撤消时,系统要回收该文件的磁盘索引结点,从其父目录中删除该目录项。随着文件的打开与关闭,系统还要为之分配和回收内存索引结点。磁盘索引结点中,包含有关文件的下述一系列信息:文件模式di_mode、文件所有者用户标识符di_ui

7、d、同组用户标识符di_gid、文件长度di_size、文件的联接计数di_nlink、文件的物理地址di_addr、文件的访问时间di_atime、文件的修改时间di_mtime和文件的建立时间di_citime。 内存索引结点:文件被打开后,系统为它在内存索引结点表区中建一内存索引结点,以方便用户和系统对文件的访问。磁盘索引结点的分配与回收分配过程ialloc:当内核创建一新文件时,要为之分配一空闲磁盘i结点。如分配成功,便再分配一内存i结点。其过程如下:检查超级块上锁否。由于超级块是临界资源,诸进程必须互斥地访问它,故在进入ialloc后,要先检查它是否已上锁,若是则睡眠等待;检查i结点

8、栈空否。若i结点栈中已无空闲结点编号,则应从盘中再调入一批i结点号进栈。若盘中已无空闲i结点,则出错处理,返回;从空闲i结点编号栈中分配一i结点,并对它初始化、填写有关文件的属性;分配内存i结点;将磁盘i结点总数-1,置超级块修改标志,返回。 回收过程ifree:当删除文件时,应回收其所占用的盘块及相应的磁盘i结点。具体有:检查超级块上锁否。若是,直接返回,即不把本次回收的i结点号记入空闲i结点编号栈中;检查i结点编号栈满否。若已满,无法再装入新回收的i结点号,立即返回,若未满,便将回收的i结点编号进栈,并使当前空闲结点数+1;置超级块修改标志,返回。 内存索引结点的分配与回收 分配过程ige

9、t:虽然iget用在打开文件时为之分配i结点,但由于允许文件被共享,因此,如果一文件已被其他用户打开并有了内存i结点,则此时只需将i结点中的引用计数+1。如果文件尚未被任何用户(进程)打开,则由iget过程为该文件分配一内存i结点,并调用bread过程将其磁盘i结点的内容拷贝到内存i结点中并进行初始化。 回收过程iput:进程要关闭某文件时,须调用iput过程,先对该文件内存i结点中的引用计数-1。若结果为0,便回收该内存i结点,再对该文件的磁盘i结点中的连接计数减1,若其结果也为0,便删除此文件,并回收分配给该文件的盘块和磁盘i结点。(3)主要文件操作的处理过程打开文件open:检索目录,内

10、核调用namei从根目录或从当前目录,沿目录树查找指定的索引结点。若未找到或该文件不允许存取,则出错处理返回null,否则转入下一步;分配内存索引结点,如果该文件已被其它用户打开,只需对上一步中所找到的i结点引用计数+1,否则应为被打开文件分配一内存i结点,并调用磁盘读过程将磁盘i结点的内容拷贝到内存i结点中,并设置i.count=1;分配文件表项,为已打开的文件分配一文件表项,使表项中的f.inode 指向内存索引结点;分配用户文件描述表项。 创建文件creat:核心调用namei,从根目录或当前目录开始,逐级向下查找指定的索引结点。此时有以下二种情况:重写文件,namei找到了指定i结点,

11、调用free释放原有文件的磁盘块。此时内核忽略用户指定的许可权方式和所有者,而保持原有文件的存取权限方式和文件主。最后打开。新建,namei未找到。调用ialloc,为新创建的文件分配一磁盘索引结点,并将新文件名及所分配到的i结点编号,写入其父目录中,建立一新目录项。利用与open相同的方式,把新文件打开。 关闭文件close:根据用户文件描述符fd,从相应的用户文件描述符表项中,获得指向文件表项的指针fp,再对该文件表项中的f.count-1。4、 算法和流程图(1)部分主要的算法:主函数:#include #include filsys.hstruct hinode hinodenhino

12、;/* 查找内存i节点的hash表 */struct filsys filsys;/* 超级块数据结构 */struct inode * cur_path_inode; /* 文件系统(内存i节点)数据结构 */struct user userusernum; /* 用户打开表数据结构 */struct file sys_ofilesysopenfile; /* 系统打开表数据结构 */struct direct cur_directnofile;/* 目录数据结构路径 */unsigned short cur_dir_id;/* 当前目录指针 */char cur_path_namedirs

13、iz;file *fd; /* 本系统的所有文件指针 */void main()char reg_or_log; / 注册/登录变量名char buf50,buf250,buf350;int i;cur_dir_id = 0;printf( nttwelcome to this system!n );printf( initializing.n );fd = fopen( filesystem.dat, r+b );if( fd != null )/* 文件已经存在,不用格式化 */printf( installing.n );init();/* 读取磁盘数据 */else/* 文件已经存在,

14、要进行格式化 */if( format() = 0 )/* 格式化 */return;/* 格式化不成功 */printf( installing.n );init();/* 读取磁盘数据 */again:printf( ndo you want to register or login? (r/l) );while( 1 )reg_or_log = getch();/* 注册新用户 */if( reg_or_log = r ) | ( reg_or_log = r )printf( %cn, reg_or_log );reg();goto again;/* 登陆已有用户 */else if(

15、 reg_or_log = l ) | ( reg_or_log = l )printf( %cn, reg_or_log );if( login() = 0) /* 登陆不成功 */goto again;break;strcpy( cur_directcur_dir_id.d_name, / );cur_directcur_dir_id.d_ino = rootdir;strcpy( cur_path_name, / );printf(n t操作命令符n); for (i=0; i=35; i+) printf( *); printf(n * );printf( 1-dir/l/ls 显示当

16、前目录和文件 ); printf(2-cd .退回到上一级目录 ); printf(*n);printf(n * ); printf( 3-cd 文件名 显示文件名目录 );printf(4-mkdir/md 文件名 创建目录 );printf(*n);printf(n * );printf( 5-rmdir/rd 文件名 删除目录 );printf(6-mkfile/mf 文件名 创建文件 );printf(*n);printf(n * );printf( 7-open 文件名 打开文件 );printf(8-write 文件名 写文件 );printf(*n);printf(n * );p

17、rintf( 9-read 文件名 读文件 );printf( 10-close 文件名 关闭文件 );printf(*n);printf(n * );printf( 11-delete 文件名 删除文件 ); printf( 12-logout 注销 ); printf(*n); for (i=0; i=35; i+) printf( *);printf(n);while(1)if( cmdexp() = 1 )break;halt();命令解释层函数:#include #include #include filsys.hchar input_buf20;/* 命令行输入缓冲区 */stat

18、ic char str20;int over;/* 命令行结束标记 */int fd1;int i,j;/* 命令解释层函数 */int cmdexp()over = 0;printf(%slocalhost%s$ , useruser_id.u_name, cur_path_name);getcmd();/* 显示当前目录 */if( strcmp( input_buf, dir ) = 0 ) | ( strcmp( input_buf, l ) = 0 ) | ( strcmp( input_buf, ls ) = 0 )_dir();clearbuf();return 0;/* 改变当

19、前目录 */if( strcmp( input_buf, cd ) = 0 )getcmd(); /* 取得命令 */chdir ( input_buf ); /改变当前目录用函数clearbuf();return 0;/* 创建目录(建立子目录) */if( strcmp( input_buf, mkdir ) = 0 ) |( strcmp( input_buf, md ) = 0 )if( over )printf( 请在mkdir后输入要创建的目录名n );clearbuf();return 0;getcmd();if( input_buf0 = 0 )printf( 请在mkdir后

20、输入要创建的目录名n );clearbuf();return 0;mkdir( input_buf );while(!over)getcmd();if( input_buf0 != 0 )mkdir( input_buf );clearbuf();return 0;if( strcmp( input_buf, rmdir ) = 0 ) | ( strcmp( input_buf, rd ) = 0 )if( over )printf( 请在rmdir后输入要删除的目录名 );clearbuf();return 0;getcmd();if( input_buf0 = 0 )printf( 请在

21、rmdir后输入要删除的目录名n );clearbuf();return 0;rmdir( input_buf );while( !over )getcmd();if( input_buf0 != 0 )rmdir( input_buf );clearbuf();return 0;if( strcmp( input_buf, mkfile ) = 0 | ( strcmp( input_buf, mf ) = 0 )if( over )printf( 请在mkfile后输入要创建的文件名n );clearbuf();return 0;getcmd();if( input_buf0 = 0 )p

22、rintf( 请在mkfile后输入要创建的文件名n );clearbuf();return 0;creat( input_buf,01777);while(!over)getcmd();if( input_buf0 != 0 )creat( input_buf,01777);clearbuf();return 0;if( strcmp( input_buf, open ) = 0 )if( over )printf( 请在open后输入要打开的文件名n );clearbuf();return 0;getcmd();if( input_buf0 = 0 )printf( 请在open后输入要打

23、开的文件名n );clearbuf();return 0;open( input_buf,0004);while(!over)getcmd();if( input_buf0 != 0 )open( input_buf,0004);clearbuf();return 0;if( strcmp( input_buf, write ) = 0 )if( over )printf( 请在write后输入要执行“写”操作的文件名n );clearbuf();return 0;getcmd();if( input_buf0 = 0 )printf( 请在write后输入要执行“写”操作的文件名n );cl

24、earbuf();return 0; fd1=creat( input_buf,01777);i=write(fd1,str,512);printf(请输入你要写的内容:);for(j=0;ji;i+)scanf(%c,&stri);if( stri = n )break;while(!over)getcmd();if( input_buf0 != 0 )fd1=creat( input_buf,01777);i=write(fd1,str,512);printf(请输入你要写的内容:);for(j=0;ji;i+)scanf(%c,&stri);if( stri = n )break;cle

25、arbuf();return 0;if( strcmp( input_buf, close ) = 0 )if( over )printf( 请在close后输入要关闭的文件名n );clearbuf();return 0;getcmd();if( input_buf0 = 0 )printf( 请在close后输入要关闭的文件名n );clearbuf();return 0; fd1=creat( input_buf,01777);close(fd1);while(!over)getcmd();if( input_buf0 != 0 )fd1=creat( input_buf,01777);

26、close(fd1);clearbuf();return 0;if( strcmp( input_buf, delete ) = 0 )if(over)printf( 请在delete后输入要删除的文件名n );clearbuf();return 0;getcmd();if( input_buf0 = 0 )printf( 请在delete后输入要删除的文件名n );clearbuf();return 0;_delete(input_buf);while(!over)getcmd();if( input_buf0 != 0 )_delete(input_buf);clearbuf();retu

27、rn 0;if( strcmp( input_buf, logout ) = 0 )clearbuf();return 1;/* 找不到该命令 */if( input_buf0 != 0 )printf( bash: %s command not foundn, input_buf );clearbuf();return 0;/* 取得命令 */getcmd()int i= 0;while( !over )input_bufi = getchar();if( input_bufi = )if( i = 0 )/* 命令行的开始是空格,应舍去 */i-;elseinput_bufi=0;brea

28、k;elseif( input_bufi = n )over = 1;input_bufi=0;break;i+;/* 清空缓冲区 */clearbuf()while( !over )if( getchar() =n )break;文件系统格式化函数:#include #include filsys.hint format() /文件系统格式化函数struct filsys aaa;struct inode * inode;struct user tempuserusernum;struct dinode dinode_buf;struct direct dir_bufblocksiz / d

29、irectsiz;unsigned int block_bufblocksiz / sizeof( int );char * buf;int i, j, k;fd = fopen( filesystem.dat, w+b );/* 建立文件 */buf = (char * )malloc( 1024*1024 );/* 申请1m空间 */if( buf = null )/* 申请不成功,返回 */printf( nthe system file cant be created!n );return 0;/* 申请成功,把其空间写入filesystem.dat,使filesystem.dat为1

30、m */fseek( fd, 0, seek_set );fwrite( buf, 1, 1024*1024, fd );free ( buf );dinode_buf.di_mode = diempty;/* 设置磁盘i节点缓冲区,diempty表示空闲 */fseek( fd, dinodestart, seek_set );for( i = 0; i i_mode = diempty;/* 第0块不用 */iput( inode );inode = iget( 1 );/* 第1盘块放用户名表 */inode-i_number = 1;inode-i_mode = direg; /普通文

31、件inode-i_size = sizeof( struct user ) * usernum;inode-i_addr0 = 1;/* 用户imacih是超级用户 */strcpy( tempuser0.u_name, imacih );strcpy( tempuser0.password, dgh123456 );tempuser0.u_default_mode = supermode;tempuser0.u_gid = 1;tempuser0.u_uid = 1;for( i = 1; i i_addr0, seek_set );fwrite( tempuser, 1, inode-i_

32、size, fd );iput( inode );inode = iget( 2 );/* 第2盘块用于存储根目录 */inode-i_number = 1;inode-i_mode = defaultmode | didir;inode-i_size = 2 * directsiz;inode-i_addr0 = 2;strcpy( dir_buf0.d_name, / );dir_buf0.d_ino = 2;strcpy( dir_buf1.d_name, / );dir_buf1.d_ino = 2;strcpy( dir_buf2.d_name, etc );dir_buf2.d_i

33、no = 3;fseek( fd, datastart + blocksiz * inode-i_addr0, seek_set );fwrite( dir_buf, 1, inode-i_size, fd );iput( inode );inode = iget( 2 );/* 2 etc dir id */inode-i_number = 1;inode-i_mode = defaultmode | didir;inode-i_size = 2 * directsiz;inode-i_addr0 = 2;/* 第3盘块用于根目录下的子目录 */strcpy( dir_buf0.d_name

34、, . );dir_buf0.d_ino = 1;strcpy( dir_buf1.d_name, . );dir_buf1.d_ino = 2;fseek( fd, datastart + blocksiz * inode-i_addr0, seek_set );fwrite( dir_buf, 1, 2 * directsiz, fd );iput( inode );/* 2. 初始化超级块 */filsys.s_ninode = dinodeblk * blocksiz / dinodesiz - 3;/* 空闲磁盘i节点数 */filsys.s_nfree = fileblk - 3;

35、/* 空闲文件块数 */* 初始化空闲磁盘i节点堆栈 */for( i = 0; i nicinod; i+ )filsys.s_inodei = 3 + i;/* 从第3个磁盘i块,前面3个已用 */filsys.s_pinode = 0;/* 当前空闲块指针 */filsys.s_rinode = nicinod + 3;/ 下一准备装入空闲盘块号栈的盘块号/* 把第1组空闲盘块放进空闲盘块堆栈 */for( i = 0; i nicfree; i+ )filsys.s_freei = 3 + nicfree - 1 - i;filsys.s_pfree = nicfree - 1;for

36、( i = 3 + nicfree * 2 - 1; i fileblk; i += nicfree )for( j = 0; j nicfree; j+ )/* 往缓冲区写与成组链接法组织空闲盘块有关的信息:下一组盘块空闲块号与块数 */block_bufj = i - j;block_bufnicfree = nicfree;/* 该项记录本组的空闲盘块数 */* 把缓冲区内容写到每组空闲盘块的最后一块中 */bwrite( i - nicfree, block_buf );/* 最后一组空闲盘块可能不足nicfree块,故需单独处理 */i = i - nicfree;for( j =

37、0; j fileblk - i + 1; j+ )block_bufj = fileblk - j;block_bufnicfree = fileblk - i + 1;/* 最末组的空闲盘块数 */bwrite( i, block_buf );/* 把超级块写入 block 1# */fseek( fd, blocksiz, seek_set );fwrite( &filsys, 1, sizeof( struct filsys ), fd );aaa=filsys;return 1;空闲盘块分配、回收函数:#include #include filsys.hstatic unsigned

38、 int block_bufblocksiz;/* 空闲盘块分配函数 */unsigned int balloc()unsigned int free_block, free_block_num;int i;if( filsys.s_nfree = 0 )/* 磁盘已满,无空闲盘块 */printf( disk has no spacen );return -1;free_block = filsys.s_freefilsys.s_pfree;if( filsys.s_pfree = 0 )/* 已经是栈底 */* 读取栈底盘块号所对应的盘块数据 */bread( filsys.s_freef

39、ilsys.s_pfree, block_buf );free_block_num = block_bufnicfree;/* 该空闲盘块组的盘块数 */* 把盘块组放到空闲盘块号栈上 */for( i = 0; i free_block_num; i+ )filsys.s_freei = block_bufi;filsys.s_pfree = free_block_num - 1;/* 指针指向栈顶 */elsefilsys.s_pfree-;/* 栈指针下移一位 */filsys.s_nfree-;/* 空闲盘块少1 */filsys.s_fmod = supdate;/* 置超级块修改标

40、志 */return free_block;/* 空闲盘块回收函数 */bfree( unsigned int block_num )int i;filsys.s_pfree+;if( filsys.s_pfree = nicfree )/* 空闲盘块堆栈已满 */block_bufnicfree = nicfree;/* 空闲盘块堆栈的盘块数nicfree记入缓冲区 */for( i = 0; i nicfree; i+ )block_bufi = filsys.s_freei; /* 把空闲盘块数据写入缓冲区 */filsys.s_pfree = 0;/* 栈指针指向栈底 */bwrite

41、( block_num, block_buf );/* 缓冲区内容写入新回收的盘块 */filsys.s_freefilsys.s_pfree = block_num;/* 回收盘块 */filsys.s_nfree+;/* 空闲盘块多1 */filsys.s_fmod = supdate;/* 置超级块修改标志 */节点分配和释放函数:#include #include filsys.hstatic struct dinode block_bufblocksiz / dinodesiz;struct inode * ialloc()struct filsys aaa;struct inode

42、 * temp_inode;unsigned int cur_di,temp;int i;if( filsys.s_ninode = 0 )/* 没有空闲磁盘i节点 */printf( no leisure dinode!n );return null;if( filsys.s_pinode = nicinod )/* 空闲磁盘i节点栈空 */cur_di = filsys.s_rinode;if( filsys.s_ninode = nicinod )/* 空闲磁盘i节点数可装满空闲i节点栈 */filsys.s_pinode = 0;/* 把下一组磁盘i节点读进空闲磁盘i节点栈 */whi

43、le( filsys.s_pinode nicinod )fseek (fd, dinodestart + cur_di * dinodesiz, seek_set);fread (block_buf, 1, blocksiz, fd);for( i = 0; ( i blocksiz / dinodesiz ) & ( filsys.s_pinode nicinod ); )if( block_bufi.di_mode = diempty )/* 该磁盘i节点空闲 */filsys.s_inodefilsys.s_pinode = cur_di;/* 把该i节点装入空闲栈 */filsys.

44、s_pinode+;/* 栈指针下移一位 */i+;cur_di+;filsys.s_pinode = 0;else/* 剩下的空闲磁盘i节点不能装满栈区 */* 计算出空闲栈指针装入i节点的第一个位置 */filsys.s_pinode = nicinod - filsys.s_ninode;while( filsys.s_pinode nicinod )fseek (fd, dinodestart + cur_di * dinodesiz, seek_set);fread (block_buf, 1, blocksiz, fd);for( i = 0; ( i blocksiz / din

45、odesiz ) & ( filsys.s_pinode i_number = 1;/temp_inode-i_uid = useruser_id.u_uid;/temp_inode-i_gid = useruser_id.u_gid;/temp_inode-i_size = 0;/temp_inode-i_addr0 = 0;/iput( temp_inode );/* 分配内存i节点 */temp_inode = iget( filsys.s_inodefilsys.s_pinode );/* 从磁盘i节点读取数据到内存i节点 */fseek( fd, dinodestart + filsys.s_inodefilsys.s_pinode * dinodesiz, seek_set );fwrite( &tem

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论