zoukankan      html  css  js  c++  java
  • APUE 3.10 文件共享

    参考网址:

    http://poincare.matf.bg.ac.rs/~ivana/courses/tos/sistemi_knjige/pomocno/apue/APUE/0201433079/ch03lev1sec10.html

    http://blog.csdn.net/wuheshi/article/details/52872463


    在看到APUE的第3.10的时候, 也就是第一个参考网页,理解的之后,想去看看Linux到底是怎么样实现的。于是就找到了第二个参考的网页:

    在APUE当中,图3-1 描述了这些数据结构

    这个图描述的是,有三个数据结构,是用来实现这个功能的:

    进程表:用于描述进程的属性,在进程表中,有一个文件描述符表。这个表,主要描述fd的标志,和文件的之真。

    内核打开的文件会有一个维持的表:这个表记录了文件状态标志,当前文件偏移量,指向文件v结点的指针

    v-node:包含了文件类型,和对这个文件的操作的各种指针。

    那么,我就很想知道,在Linux下,这些对应的相关结构是什么。就来看看这些概念,到底在Linux下是怎么样的。

    我的操作系统是:

    $ uname -r
    4.10.13-1-ARCH

    按照参考网页2的引导,参考中是2.4版本的,我的是4.10,查看了LXR的网页元马,我做的笔记如下:

    描述 linux 进程的结构是 struct task_struct ,他的定义是在 include/linux/sched.h 文件下:

    相关的结构体定义是

    struct task_struct {
        .
        .
        /* filesystem information */
        struct fs_struct *fs;
        /* open file information */
         struct files_struct *files;
        .
        .
    }

    这里,首先完成的是,找出了在进程中描述打开文件的数据结构是 struct files_struct。

    struct fs_struct 这个结构,是描述文件系统的。我们的目标应该是 struct files_struct 就好了,但是,就当顺带了解多一个,也看下struct fs_struct。

    第一个是fs_struct  定义在 include/linux/fs_struct.h

    这个结构,描述的信息就是一个进程的 root filesystem, current working directory等。根据以下的网页的描述 

    http://www.makelinux.net/books/lkd2/ch12lev1sec10
    Each process on the system has its own list of open files, root filesystem, current working directory, mount points, and so on. Three data structures tie together the VFS layer and the processes on the system: the files_struct, fs_struct, and namespace structure.

    struct fs_struct {
        int users;
        spinlock_t lock;
        seqcount_t seq;
        int umask;
        int in_exec;
        struct path root, pwd;
    };

    明显,跟2.4版本已经有变化了。

    取消了 struct dentry (目录入口),也取消了struct vfsmount ()。我猜测的是,root 和 pwd 和参考2中的意义一样,root 代表着本进程所在的根目录,pwd 指向进程当前所在的目录

    第二个结构体: struct files_struct (include/linux/fdtable.h)

    按照APUE的说法,每个进程用一个 files_struct 结构来记录文件描述符的使用情况, 这个 files_struct结构称为用户打开文件表, 它是进程的私有数据。对比2.4,也梗概了定义的地方

    struct files_struct {
      /*
       * read mostly part
       */
        atomic_t count;
        bool resize_in_progress;
        wait_queue_head_t resize_wait;
    
        struct fdtable __rcu *fdt;
        struct fdtable fdtab;
      /*
       * written part on a separate cache line in SMP
       */
        spinlock_t file_lock ____cacheline_aligned_in_smp;
        unsigned int next_fd;
        unsigned long close_on_exec_init[1];
        unsigned long open_fds_init[1];
        unsigned long full_fds_bits_init[1];
        struct file __rcu * fd_array[NR_OPEN_DEFAULT];
    };

    在这里面看,应该是 struct fdtable 描述的是 fd 的 表格(定义附在下面) ,可以看到 unsigned long close_on_exec_init[1];  unsigned long open_fds_init[1]; unsigned long full_fds_bits_init[1]; 就是3.10中的fd标志。 文件的指针放在 struct file __rcu * fd_array[NR_OPEN_DEFAULT]。 相关的标志还是存在的,但是按这样说, 就会有

    出现struct fdtable 结构体的原因是因为要适应新的RCU算法。(在这里有描述https://www.kernel.org/doc/Documentation/filesystems/files.txt)

    struct fdtable {
        unsigned int max_fds;
        struct file __rcu **fd;      /* current fd array */
        unsigned long *close_on_exec;
        unsigned long *open_fds;
        unsigned long *full_fds_bits;
        struct rcu_head rcu;
    };

    在fdtable里面,有一个结构是struct file的指针。查看一下struct file的结构体,可以看出它是用于来进行描述文件的。

    struct file {
        union {
            struct llist_node    fu_llist;
            struct rcu_head     fu_rcuhead;
        } f_u;
        struct path        f_path;
        struct inode        *f_inode;    /* cached value */
        const struct file_operations    *f_op;
    
        /*
         * Protects f_ep_links, f_flags.
         * Must not be taken from IRQ context.
         */
        spinlock_t        f_lock;
        atomic_long_t        f_count;
        unsigned int         f_flags;
        fmode_t            f_mode;
        struct mutex        f_pos_lock;
        loff_t            f_pos;
        struct fown_struct    f_owner;
        const struct cred    *f_cred;
        struct file_ra_state    f_ra;
    
        u64            f_version;
    #ifdef CONFIG_SECURITY
        void            *f_security;
    #endif
        /* needed for tty driver, and maybe others */
        void            *private_data;
    
    #ifdef CONFIG_EPOLL
        /* Used by fs/eventpoll.c to link all the hooks to this file */
        struct list_head    f_ep_links;
        struct list_head    f_tfile_llink;
    #endif /* #ifdef CONFIG_EPOLL */
        struct address_space    *f_mapping;
    } __attribute__((aligned(4)));    /* lest something weird decides that 2 is OK */

    到这里,我想要找的Linux实现,大概是能够从 struct task_struct, struct files_struct, struct file 中找到了。

    struct inode 也是描述了图中的 i 结点信息。

    vnode的信息,查看了一些资料(http://www.linuxquestions.org/questions/linux-kernel-70/difference-between-inode-and-vnode-657954/),vnode应该是虚拟结点的信息,似乎没有用在这里面。反正我也没从fdtable中看到了。

    就记录到这咯。

  • 相关阅读:
    php中global和$GLOBALS[]的分析之一
    javascript 标签 src 链接动态文件。
    Allegro基本操作——PCB布线
    AMD单桥主板上电时序的详细解释
    AMD单双桥时序简叙
    AMD移动FP5平台时序解释
    orcad元件属性批量修改(通过excel表格)
    加减乘除基本函数
    1.excel如何让一列的数都乘以固定值
    ORCAD元件属性白色区域和黄色区域的理解
  • 原文地址:https://www.cnblogs.com/hwy89289709/p/6843693.html
Copyright © 2011-2022 走看看