Linux-0.11 文件系统open.c详解

news/2024/10/21 10:00:07/

Linux-0.11 文件系统open.c详解

模块简介

对于一个文件系统,需要提供一些封装好的系统调用提供给应用层调用。例如打开一个文件,对于应用层而言,其并不关心底层的inode和buffer_cache的操作。 open.c便是提供这样的一个功能。

同样是文件系统high-level的API的有:

  • open.c
  • exec.c
  • stat.c
  • fcntl.c
  • ioctl.c

函数详解

sys_ustat

int sys_ustat(int dev, struct ustat * ubuf)

该函数的作用是获取文件系统信息。不过Linux-0.11版本尚未实现。

在代码实现中,仅仅是返回了一个错误码ENOSYS。

    return -ENOSYS;

sys_utime

int sys_utime(char * filename, struct utimbuf * times)

该函数的作用是设置文件的修改和访问时间。入参中,filename代表文件名, times是一个访问和修改时间结构的指针。

首先调用namei函数(fs/namei.c)获取文件的i节点, 因为一个文件与时间相关的信息存储在inode节点中。 接着从入参中提取出访问时间和修改时间。

	struct m_inode * inode;long actime,modtime;if (!(inode=namei(filename)))//获取文件的i节点return -ENOENT;if (times) {//如果times指针不为空,则从times中获取。actime = get_fs_long((unsigned long *) &times->actime);modtime = get_fs_long((unsigned long *) &times->modtime);} else//如果times指针为空,则直接从系统时间获取actime = modtime = CURRENT_TIME;

接着将i节点的访问时间和修改时间进行修改, 并设置该i节点有脏数据。

	inode->i_atime = actime;      //设置访问时间inode->i_mtime = modtime;     //设置修改时间inode->i_dirt = 1;            //设置i节点有脏数据iput(inode);                  //放回i节点return 0;

sys_access

int sys_access(const char * filename,int mode)

该函数的作用是检查文件的访问权限。

	struct m_inode * inode;int res, i_mode;mode &= 0007;if (!(inode=namei(filename)))return -EACCES;i_mode = res = inode->i_mode & 0777;iput(inode);if (current->uid == inode->i_uid)res >>= 6;else if (current->gid == inode->i_gid)res >>= 6;   //这里似乎是一个bug, 应该是>>3, namei中的permission函数没有这个问题if ((res & 0007 & mode) == mode)return 0;/** XXX we are doing this test last because we really should be* swapping the effective with the real user id (temporarily),* and then calling suser() routine.  If we do call the* suser() routine, it needs to be called last. */if ((!current->uid) &&(!(mode & 1) || (i_mode & 0111)))return 0;return -EACCES;

sys_chdir

int sys_chdir(const char * filename)

该函数的作用是改变当前进程的工作目录

首先通过namei找到路径filename对应的i节点。节点将该i节点设置给PCB中的pwd字段。

	struct m_inode * inode;if (!(inode = namei(filename)))return -ENOENT;if (!S_ISDIR(inode->i_mode)) { //如果给定的filename对应的不是一个目录i节点,则返回错误iput(inode);return -ENOTDIR;}iput(current->pwd);current->pwd = inode;  //将当前进程的工作路径设置为filename对应的i节点return (0);

sys_chroot

int sys_chroot(const char * filename)

该函数的作用是修改进程的根目录。

首先通过namei找到路径filename对应的i节点。节点将该i节点设置给PCB中的root字段。

	struct m_inode * inode;if (!(inode=namei(filename)))return -ENOENT;if (!S_ISDIR(inode->i_mode)) {//如果给定的filename对应的不是一个目录i节点,则返回错误iput(inode);return -ENOTDIR;}iput(current->root);current->root = inode;//将当前进程的根路径设置为filename对应的i节点return (0);

sys_chmod

int sys_chmod(const char * filename,int mode)

该函数的作用是用于修改文件的权限。

	struct m_inode * inode;if (!(inode=namei(filename))) //先查找出filename对应的i节点return -ENOENT;if ((current->euid != inode->i_uid) && !suser()) { //如果当前进程的有效用户不等于i节点用户,并且也不是超级用户,则没有操作该i节点的权限iput(inode);return -EACCES;}inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);//否则重新设置该i节点的文件属性,并设置该i节点含有脏数据inode->i_dirt = 1;iput(inode);return 0;

sys_chown

int sys_chown(const char * filename,int uid,int gid)

该函数的作用是修改文件的拥有用户拥有组

	struct m_inode * inode;if (!(inode=namei(filename)))//获取filename对应的i节点return -ENOENT;if (!suser()) {//如果不是超级用户则不能操作iput(inode);return -EACCES;}inode->i_uid=uid;//设置uidinode->i_gid=gid;//设置gidinode->i_dirt=1;//设置有脏数据iput(inode);return 0;

sys_open

int sys_open(const char * filename,int flag,int mode)

该函数的作用是用于打开一个文件。该函数是打开文件的系统调用。

	struct m_inode * inode;struct file * f;int i,fd;mode &= 0777 & ~current->umask; //mode和进程的屏蔽码相与for(fd=0 ; fd<NR_OPEN ; fd++)   //从进程的fd数组中找到一个空闲项if (!current->filp[fd]) break;if (fd>=NR_OPEN) //如果超过了进程最大可以打开的文件数则返回错误return -EINVAL;current->close_on_exec &= ~(1<<fd);f=0+file_table;for (i=0 ; i<NR_FILE ; i++,f++)if (!f->f_count) break;if (i>=NR_FILE)return -EINVAL;(current->filp[fd]=f)->f_count++;if ((i=open_namei(filename,flag,mode,&inode))<0) {//调用open_namei打开filename对应的i节点current->filp[fd]=NULL;f->f_count=0;return i;}
/* ttys are somewhat special (ttyxx major==4, tty major==5) */if (S_ISCHR(inode->i_mode)) {if (MAJOR(inode->i_zone[0])==4) {//ttyxx  major = 4if (current->leader && current->tty<0) {current->tty = MINOR(inode->i_zone[0]);tty_table[current->tty].pgrp = current->pgrp;}} else if (MAJOR(inode->i_zone[0])==5)//tty major=5if (current->tty<0) {iput(inode);current->filp[fd]=NULL;f->f_count=0;return -EPERM;}}
/* Likewise with block-devices: check for floppy_change */if (S_ISBLK(inode->i_mode))check_disk_change(inode->i_zone[0]);f->f_mode = inode->i_mode;f->f_flags = flag;f->f_count = 1;f->f_inode = inode;f->f_pos = 0;return (fd);

sys_creat

int sys_creat(const char * pathname, int mode)

该函数是创建文件的系统调用。

其内部调用了sys_open函数,传递参数时,设置flag = O_CREAT | O_TRUNC。

	return sys_open(pathname, O_CREAT | O_TRUNC, mode);

sys_close

int sys_close(unsigned int fd)

该函数是关闭文件的系统调用。

	struct file * filp;if (fd >= NR_OPEN)//如果fd大于了程序可以打开的最大的文件数,则返回错误。return -EINVAL;current->close_on_exec &= ~(1<<fd);//将执行时关闭的句柄位图复位为0if (!(filp = current->filp[fd]))//fd对应的进程文件描述符并没有对应的文件结构体,则返回错误。return -EINVAL;current->filp[fd] = NULL;//将fd对应的文件结构体置为NULLif (filp->f_count == 0)panic("Close: file count is 0");if (--filp->f_count)//减少引用计数,如果f_count不为0, 代表还有其他进程在使用该文件结构体,则直接返回return (0);iput(filp->f_inode);//否则代表没有进程在使用该文件结构体,则可以进行放回操作return (0);

Q & A


http://www.ppmy.cn/news/96522.html

相关文章

IOC理解

1. Java反射 Java反射机制存在于运行时&#xff0c;对于任意一个类&#xff0c;都能获取这个类的所有属性和方法&#xff0c;对于任意一个对象&#xff0c;都能通过反射机制去调用它的属性和方法&#xff0c;这种动态获取类信息及动态调用对象方法的功能称为Java反射机制&#…

驱动开发——嵌入式(驱动)软开基础(九)

1 系统调用的作用? (1)为应用程序提供访问硬件资源的统一接口,以至于应用程序不必关心具体的硬件操作细节。 (2)对系统内核进行保护,保证系统的稳定和安全,因为系统调用规定了用户进程进入内核的具体方式以及所能访问的数据范围。 2 BootLoader、Linux内核、根文件系…

Java并发常见面试题

参考:javauide、程序员大斌、面试宝典 1.并发与并行的区别 并发:两个及两个以上的作业在同一 时间段 内执行。并行:两个及两个以上的作业在同一 时刻 执行。2.同步和异步的区别 同步:发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。异步:调用在发…

WPF界面设计

目录 1.设计一个优美的注册界面1.实现效果2.代码展示 2.简易登录按钮设计1.实现效果2.代码展示 3.设计一个优美的注册登录界面&#xff08;连接数据库&#xff09;1.实现效果2.代码展示 4.设计一个简单的在线教育系统界面1.实现效果2.代码展示 5. 设计一个Dashboard1.实现效果2…

医院管理系统详细设计说明书

详细设计说明书 1.引言 1.1编写目的 在完成了针对北京工商大学校医院的前期调查&#xff0c;同时与多位学生进行了全面深入的探讨和分析的基础上&#xff0c;提出了这份概要设计说明书。 此概要设计说明书对北京工商大学校医院管理系统网站做了全面细致的概要设计&#xff0c;…

低代码平台

aims https://aisuda.bce.baidu.com/amis/zh-CN/docs/start/getting-started

AntV X6结合Vue组件渲染节点,并与节点组件进行双向的数据交互

项目使用 Vue2.0 Element-ui 框架&#xff0c;在开发流程功能时自定义节点&#xff0c;为实现稍复杂的样式以及操作交互&#xff0c;使用 markup attrs的方式的话&#xff0c;比较麻烦&#xff0c;且难以结合使用 Element-ui的交互组件&#xff0c;因此换成结合 Vue组件渲染方…

SAP-MM-内向外向交货单

1、内向&外向交货单概念 外向交货&#xff08;outbound delivery&#xff09;是用在客户与企业之间的交货单&#xff0c;而内向交货&#xff08;inbound delivery&#xff09;则是用在供应商与企业之间的交货单&#xff1b;换言之&#xff0c;外向交货多用于SD 模块&#…