设计院总工程师正科:文件系统的学习

来源:百度文库 编辑:九乡新闻网 时间:2024/05/02 11:31:36
一、 文件系统 的建立过程

start_kernel()函数调用fs/dcach.c 中vfs_caches_init()

void __init vfs_caches_init(unsigned long mempages)
{
    unsigned long reserve;

    /* Base hash sizes on available memory, with a reserve equal to
           150% of current kernel size */

    reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1); //内存页数减去 空闲页数的1.5倍
    mempages -= reserve;

    names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,//分配一个缓存区,和kmalloc 调用的函数相同
            SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);

    dcache_init();//创建dentry结构对象的cache
    inode_init();//创建inode对象的cache  同dcache_init()调用过程相同
    files_init(mempages);//初始化struct file_stat_struct files_stat
    mnt_init();//初始化挂接点 全局变量链表
    bdev_cache_init();//注册设备块文件系统
    chrdev_init();//注册字符文件系统
}


void __init files_init(unsigned long mempages)
{
    int n;

    filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,
            SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);

    /*
     * One file with associated inode and dcache is very roughly 1K.
     * Per default don't use more than 10% of our memory for files.
     */

    n = (mempages * (PAGE_SIZE / 1024)) / 10;
    files_stat.max_files = n;
    if (files_stat.max_files < NR_FILE)
        files_stat.max_files = NR_FILE;
    files_defer_init();
    percpu_counter_init(&nr_files, 0);//smp

}
********************************
void __init mnt_init(void)
{
    unsigned u;
    int err;

    init_rwsem(&namespace_sem);

    mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
            0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);

    mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);

    if (!mount_hashtable)
        panic("Failed to allocate mount hash table\n");

    printk("Mount-cache hash table entries: %lu\n", HASH_SIZE);

    for (u = 0; u < HASH_SIZE; u++)
        INIT_LIST_HEAD(&mount_hashtable[u]);

    err = sysfs_init();//sysfs初始化
    if (err)
        printk(KERN_WARNING "%s: sysfs_init error: %d\n",
            __func__, err);
    fs_kobj = kobject_create_and_add("fs", NULL);
    if (!fs_kobj)
        printk(KERN_WARNING "%s: kobj create error\n", __func__);
    init_rootfs(); //初始化跟文件系统
    init_mount_tree();//挂接根文件系统 ,给每个任务设置namespace,设置当前进程的根目录和当前目录
}

static void __init init_mount_tree(void)
{
    struct vfsmount *mnt;
    struct mnt_namespace *ns;
    struct path root;

    mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
    if (IS_ERR(mnt))
        panic("Can't create rootfs");
    ns = create_mnt_ns(mnt);
    if (IS_ERR(ns))
        panic("Can't allocate initial namespace");

    init_task.nsproxy->mnt_ns = ns;
    get_mnt_ns(ns);

    root.mnt = ns->root;
    root.dentry = ns->root->mnt_root;

    set_fs_pwd(current->fs, &root);
    set_fs_root(current->fs, &root);
}