美文网首页
day7 文件系统剩余部分

day7 文件系统剩余部分

作者: 柯基是只dog | 来源:发表于2018-12-11 15:19 被阅读0次

1. exec.c

exec大概流程是,调用中断陷入内核态后,在内核态内中断处理程序从eax寄存器里发现是调用exec,接着从其他几个寄存器中读出argc,argv,envc等参数,这里有个地方要注意,因为内核态和用户态的段空间是不一样的。linux用fs寄存器存储了用户态的数据段选择符,这样就可以在内核态访问一些用户空间的数据了,还有argv和env都是字符串数组,c语音里字符串是已null结尾的,包括从用户空间读和最后写入新的用户栈内,都大量用到了这个技巧来判断是否是一个字符串的结尾。

还有一个重要的事情,close_on_exec,进程对象有个这个字段,是一个位图,标记了哪些fd是应该在exec后关闭的包括fork后exec这样的情况。很多时候我们不希望子进程占用我们的fd,比如socket,会导致端口一直被占用

do_execve方法主要干了下面这些事

  1. 参数校验,如果不是从用户栈陷入的调用则报错
  2. 用nemei方法取执行的文件节点信息,检查文件是否是可执行文件
  3. 校验进程用户和执行文件的权限
  4. 读节点的第一块数据
  5. 如果是#!开头的代表对应的处理脚本文件执行,则解析文本重新构造filename和参数等信息后回到第2步
  6. 第一块数据现在是执行文件头了,校验一些参数(魔术类型,代码长度,数据长度等)
  7. 拷贝参数和环境变量到页面
  8. 释放原来的内存空间
  9. 重新设置idt描述符的基址和长度
  10. 把内核栈原来的eip(就是ret的返回点改成执行文件的entry),当从内核态iret后就彻底完成跳转到新程序入口处运行了

2. stat.c

就是处理平时查询文件状态的调用,逻辑都很简单,需要注意的还是当从内核查处的信息是在内核段里的,需要从内核复制到用户空间内。

3. open.c

该文件定义了我们平时使用的cd,chmod,chown等系统调用,最重要的方法应该是sys_open了,前面我们已经知道每个打开个文件都会被加载到一个inode节点,node节点存在inode_table中,是全局的但大小有限制代表着linux系统中同时最多可以被打开的文件数。

而在用户的进程当中,同样也有一个数组叫做file_table存放当前进程当前打开的文件表,每个表项里有一个f_inode指针指向真正的inode节点。这样做的好处是可以让多个进程共享底层同一个文件,而且每个进程都能对访问的文件设置不同的访问权限。比如我们知道的管道pipe,就是多个进程共享一个文件节点,然后写进程只用写权限,读进程只用读权限来实现的。

open主要完成以下事情

  1. 遍历当前进程的fd数组,找一个空闲的fd
  2. 复位进程关闭时的句柄位图
  3. 从file_table中寻找一个未使用的,找到后把fd指向该项
  4. 调用open_namei打开文件节点
  5. 初始化一些f的属性,最后返回fd

4. fcntl.c

该文件主要是处理复制文件fd的系统调用,dup,dup2,dup2只是强调复制的fd号(只是如果新fd存在,新关闭它),sys_fcntl主要处理所有的文件控制,根据cmd不同,设置文件的属性,包括dup操作,取文件的执行时关闭标志,设置执行时关闭标志,取文件模式,设置文件的访问模式(堵塞模式也在这儿操作)

// 参数fd 是文件句柄,cmd 是操作命令(参见include/fcntl.h,23-30 行)。
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{   
    struct file * filp;

// 如果文件句柄值大于一个进程最多打开文件数NR_OPEN,或者该句柄的文件结构指针为空,则出错,
// 返回出错码并退出。
    if (fd >= NR_OPEN || !(filp = current->filp[fd]))
        return -EBADF;
// 根据不同命令cmd 进行分别处理。
    switch (cmd) {
        case F_DUPFD:   // 复制文件句柄。
            return dupfd(fd,arg);
        case F_GETFD:   // 取文件句柄的执行时关闭标志。
            return (current->close_on_exec>>fd)&1;
        case F_SETFD:   // 设置句柄执行时关闭标志。arg 位0 置位是设置,否则关闭。
            if (arg&1)
                current->close_on_exec |= (1<<fd);
            else
                current->close_on_exec &= ~(1<<fd);
            return 0;
        case F_GETFL:   // 取文件状态标志和访问模式。
            return filp->f_flags;
        case F_SETFL:   // 设置文件状态和访问模式(根据arg 设置添加、非阻塞标志)。
            filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
            filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
            return 0;
        case F_GETLK:   case F_SETLK:   case F_SETLKW:  // 未实现。
            return -1;
        default:
            return -1;
    }
}

4. ioctl.c

该版本的ioctl中只有对tty设备的控制,该函数是对不同设备的控制,后期的linux中该方法很强大了,可以对任何支持的驱动程序做特殊控制

相关文章

  • day7 文件系统剩余部分

    1. exec.c exec大概流程是,调用中断陷入内核态后,在内核态内中断处理程序从eax寄存器里发现是调用ex...

  • 剩余的部分

    剩余的部分 文 谨安 这条街,有些年头了 却,静 沥青新的裂,仿佛是你额上添的褶 黑在缩,黄在伸 某个真相,将被...

  • 《原则》剩余部分

    1、35岁之前必须要养成的好习惯。 习惯本质上是一种惯性,一种继续把你一直做的事情继续做下去的强烈倾向。 2、人生...

  • Linux 内核的缓存简介

    缓存机制介绍 Linux 系统中,为了提高文件系统的读写性能1,内核会利用一部分内存(相当大的剩余内存)分配缓存区...

  • linux查看硬盘 、内存大小命令

    Df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息, 显示格式为:文件系统 容...

  • Linux下查看磁盘剩余空间和文件夹大小

    df命令是[linux](javascript:;)系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间...

  • hadoop MapReduce 实现wordcount并降序

    头文件: 剩余代码部分

  • 服务器磁盘管理(分区和挂载)

    文件系统简介 以ext4文件系统为例,设计的时候分为4个部分 超级块: 最开头部分,记录整个文件系统/分区中的文件...

  • 连载20:可选头字段解释(下)

    前两篇介绍了关于可选头的部分字段,本篇接着介绍可选头的剩余部分字段。 可选头剩余的字段介绍 可选头剩余的字段还有两...

  • 8.spark core之读写数据

      spark支持多种数据源,从总体来分分为两大部分:文件系统和数据库。 文件系统   文件系统主要有本地文件系统...

网友评论

      本文标题:day7 文件系统剩余部分

      本文链接:https://www.haomeiwen.com/subject/pogshqtx.html