操作系统实验报告 实验4 文件系统管理实验(答案全)

网友投稿 1131 2022-08-28

操作系统实验报告 实验4 文件系统管理实验(答案全)

操作系统实验报告 实验4 文件系统管理实验(答案全)

这里写目录标题

​​1.实验目的​​​​2实验要求​​​​3.实验步骤​​

​​A. 创建文件模块分析​​​​B. 删除文件 rm 模块分析​​​​C. 读写模块分析​​

1.实验目的

了解与文件管理有关的Linux内核模块的代码结构。

2实验要求

1)创建文件模块分析 2)删除文件 rm 模块分析 3)读写模块分析

3.实验步骤

A. 创建文件模块分析

5780 /*creat system call */ 5781 Creat() 5782 { 5783 resister *ip;//将ip地址放在寄存器中,这样程序运行速度更快5784 extern uchar; //uchar变量是在别处定义的,要在此处应用5785 5786 ip = namei(&uchar,1); //namei可以列出路径中所有成分的信息,包含符号链接。 ip获取了uchar的指针。5787 if(ip == NULL){//如果ip是空的5788 if(u.u_error)//这里列出各种出错条件0 5789 return;//结束该程序 5790 ip = maknode(u.u_arg[1]&07777&(~ISVTX));// 调用maknode()新建一inode;makenode(7455)是个简单的函数,它内部调用ialloc()分配磁盘inode资源,进行简单设置后,调用wdir()将此inode写入磁盘5791 if (ip == NULL)//如果ip是空的 5792 return;//结束程序 5793 open1(ip,FWRITE,2);//调用open1(ip, FWRITE, 2)分配file数组和u_ofile数组资源 5794 }else 5795 open1(ip,FWRITE,1); //调用open1(ip, FWRITE, 1)——删除原有文件,复用其inode5796 } 第 5786:“namei”( 7 5 1 8 )将一路径名变换成一个“inode”指针。“uchar”是一个过程的名字,它从用户程序数据区一个字符一个字符地取得文件路径名。 5787:一个空“inode”指针表示出了一个错,或者并没有具有给定路径名的文件存在。 5788:对于出错的各种条件,请见 UMP 的 CREAT(II)。 5790:“maknode”( 7455)调用“ialloc”创建一内存“ inode”,然后对其赋初值,并使其进入适当的目录。注意,显式地清除了“粘住”位( ISVTX)。

B. 删除文件 rm 模块分析

3510 unlink() 3511 { 3512 resister *ip,*pp;//将ip地址放在寄存器中,这样程序运行速度更快3513 extern uchar; //uchar变量是在别处定义的,要在此处应用3514 3515 pp = namei(&uchar,2); //获取父目录的inode3516 if (pp ==NULL)//如果pp是空的3517 return;//程序结束 3518 prele(pp); //清除ILOCK标记,唤醒因此睡眠的进程3519 ip = iset(pp ->dev,u.u_dent.u_ino); 3520 if (ip == NULL) //如果ip是空的3521 panic (*unlink – iset *); 3522 if ((ip ->i_mode%IFMT) == IFDIR && !suser()) 3523 goto out; //去到35323524 u.u_offset[1] = - DIRSIZ+2; //u_offset执行文件名目录项起始地址3525 u.ubase = &u.u_dent; //用户地址设置为u_dent3526 u.ucount = DIRSIZE +2; //长度为目录项长度3527 u.u_dent.u_ino = 0; //inode指针置0,即此目录项设置为空3528 writei(pp); //更新父目录(该文件名的目录项置为空)3529 ip ->i_nlink--; //文件硬链接计数减一3530 ip->i_flag =! IUPD; //设置IUPD标志 3531 3532 out: 3533 iput(pp); //释放文件inode3534 iput(ip); //释放文件inode3535 }

新文件作为永久文件自动进入文件目录。关闭文件不会自动地造成文件被删除。当内存“ inode”项中的“ i _ nlink”字段值为 0 并且相应文件未被打开时,将删除该文件。在创建文件时,该字段由“ maknode”赋初值为 1。系统调用“ link”( 5941 )可将其值加1,系统调用“unlink”( 3529 )则可将其值减 1。创建临时“工作文件”的程序应当在其终止前执行“ unlink”系统调用将这些文件删除。 注意,“unlink”系统调用本身并没有删除文件。当引用计数( i _ count )被减为 0 时(7350、7362),才删除该文件。 为了减少在程序或系统崩溃时遗留下来的临时文件所带来的问题,程序员应当遵守下列约定: (1) 在打开临时文件后立即对其执行“ unlink”操作。 (2) 应在“tmp”目录下创建临时文件。在文件名中包括进程标识数就可构成一惟一文件名

C. 读写模块分析

5711 Read( ); 5712{ 5713 rdwr(FREAD); 5714 } //在2693中有trap{#3系统调用}。用户进程执行系统调用激活运行在核心态的“trap”。“trap”识别#3系统调用,然后通过“trapl”调用例程“read”,它又调用“rdwr”。5720 Write( )5721 { 5722 rdwr(FWRITE); 5723 } //调用例程“Write”,又调用例程:“rdwr”5731 rdwr(mode) 5732{ 5733 resister *fp,m; //在寄存器中定义,速度更快5734 5735 m = mode; 5736 fp = setf(u.u_arg[R0]); //将用户程序文件标识变换成指向相应文件表项的指针。5737 if (fp ==NILL) //如果fp是空的5738 return; //程序结束5739 if ((fp ->f_flag&m ==0) { //检查所要求的操作(读或写)是否与文件打开时的读/写方式符合。5740 u.u_error = EBADF; 5741 return; 5742 } 5743 u.u_base = u.u_arg[0]; //用各参数在“u”中设置几个标准单元。5744 u.u_count = u.u_arg[1]; 5745 u.u_segflg = 0; 5746 if(fp ->f_flag&FPIPE) { //从此开始对“管道”文件进行特殊处理。5747 if(m == FREAD) 5748 readp(fp);else 5749 writep(fp); 5750 }else{ 5751 u.u_offset[1] = fp ->f_offset[1]; 5752 u.u_offset[0] = fp ->f_offset[0]; 5753 if (m == FREAD) 5754 readi(fp ->f_inode);else 5755 writei(fp ->f_inode); //按读、写要求分别调用“ read i”或“write i”。 5756 dpadd(fp ->f_offset,u.u_arg[1] – u.u_count; //更新文件位移量,使其增加实际传送的字符数,同时也将实际传送的字符数返回5757 } 5758 u.u_ar0[R0] = u.u_arg[1] – u.u_count; //赋值5759 } “read”系统调用的基本工作过程为: ……read ( f , b , n ) ;/*用户程序*/ {发生陷入} 2693 trap{#3 系统调用} 5711 read() ; 5713 rdwr(FREAD); 用户进程执行系统调用激活运行在核心态的“ trap”。“trap”识别#3系统调用,然后通过“trap l”调用例程“read”,它又调用“rdwr”。 “rdwr”包含了很多“read”和“write”操作共用的代码。它调用“ getf”( 6 6 1 9 )将用户进程提供的文件标识变换成“file”数组中一项的地址。 注意,该系统调用的第 1 个参数是以不同于另外 2 个参数的方式传送的。 将“u.u_segflg”设置为0,这表示此操作的目的地址在用户地址空间中。在以一个 inode指针参数调用“ read i”后,将要求传送的字符数减去剩余未传输字符数(在 u.u _ count 中),加至文件位移量中。 6221 readi 6239 lbn = lshift (u.u_offset,-9); //“l s h i f t”( 1 4 1 0 )将“u.u _ o ff s e t”数组中的两个字并接,然后右移 9位,并切除为1 6 位。这规定了要引用的文件逻辑块号;6248 on = u.u_offset[i] & 0777; //调用“b m a p”,将文件逻辑块号变换成其宿主设备上的物理块块号。很快我们还 要对“b m a p”作更多说明,现在我们应注意到“ b m a p”作为一副作用设置了“r a b l o c k” 6241 n = min (512 – on,u.u_count); //在本块内剩余字符数(亦即o n之后的字符数)和要求传送的字符数两者之中选择较小 者,并将其赋予“n”。注意,“m i n”( 6 3 3 9 )将其参数处理为无符号整型。6250 dn = ip->i_dev; //从“i n o d e”取设备标识,并将其赋予“ d n”。6258 bp = bread (dn,bn); //只是读所希望的块。6260 iomove (bp,on,n,B_READ); //调用“i o m o v e”,将信息从缓存传送到用户区。6261 brelse (bp); //将该缓存释放回a v列表。

“read i”将文件位移量分解成两部分:一个逻辑块号“lbn”,以及一个块内索引“on”。将要传输的字符数是下而两个值中的较小者:“u.u _ count”和块内尚余字符数(在这种情况下以后还必须读其他块,此处没有进一步对此说明),还应考虑尚余留在文件中的字符数(对这种情况也未进一步说明)。 “dn”是存储在“ inode”中的设备编号,“bn”是在该设备(磁盘)上的实际块号,这是由“bmap”(6415)用“lbn”计算得到的。 对“ bread ”的调用找到所要求的磁盘块,若需要,则将其从磁盘复制到内存中。“iomove”(6364)将适当数量的字符传送至目的区,然后执行计数操作。 “read”和“ write”执行的操作有很多相似之处,两者共享很多代码。 系统调用“ read”(5711)和“write”( 5720),然后立即调用“rdwr”,它执行下列操作: 5736:将用户程序文件标识变换成指向相应文件表项的指针。 5739:检查所要求的操作(读或写)是否与文件打开时的读/写方式符合。 5743:用各参数在“u”中设置几个标准单元。 5746:从此开始对“管道”文件进行特殊处理。 5755:按读、写要求分别调用“ read i”或“write i”。 5756:更新文件位移量,使其增加实际传送的字符数,同时也将实际传送的字符数返回。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Qt功能优化:Qt人脸识别
下一篇:程序员必知的7种软件架构模式(软件架构模式有哪些)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~