ramfs

来源:互联网 发布:access数据库特点 编辑:程序博客网 时间:2024/06/08 09:27
01./* 02. * Resizable simple ram filesystem for Linux. 03. * 04. * Copyright (C) 2000 Linus Torvalds. 05. *               2000 Transmeta Corp. 06. * 07. * Usage limits added by David Gibson, Linuxcare Australia. 08. * This file is released under the GPL. 09. */  10.  11./* 12. * NOTE! This filesystem is probably most useful 13. * not as a real filesystem, but as an example of 14. * how virtual filesystems can be written. 15. * 16. * It doesn't get much simpler than this. Consider 17. * that this file implements the full semantics of 18. * a POSIX-compliant read-write filesystem. 19. * 20. * Note in particular how the filesystem does not 21. * need to implement any data structures of its own 22. * to keep track of the virtual data: using the VFS 23. * caches is sufficient. 24. */  25.  26.#include <linux/module.h>  27.#include <linux/fs.h>  28.#include <linux/pagemap.h>  29.#include <linux/highmem.h>  30.#include <linux/time.h>  31.#include <linux/init.h>  32.#include <linux/string.h>  33.#include <linux/backing-dev.h>  34.#include <linux/ramfs.h>  35.#include <linux/sched.h>  36.#include <linux/parser.h>  37.#include <linux/magic.h>  38.#include <asm/uaccess.h>  39.#include "internal.h"  40.  41.#define RAMFS_DEFAULT_MODE  0755  42.  43.static const struct super_operations ramfs_ops;    /* 针对ramfs的操作回调函数 */  44.static const struct inode_operations ramfs_dir_inode_operations; /* 针对目录inode的操作回调函数 */   45.  46. /* 描述底层块设备 */  47.static struct backing_dev_info ramfs_backing_dev_info = {  48.    .name       = "ramfs",  49.    .ra_pages   = 0,    /* No readahead 由于ramfs直接放在缓存中,所以不需要预读 */   50.       /* 描述底层块设备具备的功能, 51.           BDI_CAP_NO_ACCT_AND_WRITEBACK含义为不回写脏页、不统计脏页、不自动统计回写的脏页  52.           BDI_CAP_MAP_DIRECT 表示块设备支持mmap操作的MAP_PRIVATE 53.           BDI_CAP_MAP_COPY表示块设备支持mmap操作的MAP_PRIVATE 54.           BDI_CAP_READ_MAP表示块设备支持mmap操作的PROT_READ 55.           BDI_CAP_WRITE_MAP表示块设备支持mmap操作的PROT_WRITE 56.           BDI_CAP_EXEC_MAP表示块设备支持mmap操作的PROT_EXEC 57.           */  58.    .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK |  59.              BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |  60.              BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,  61.};  62.  63. /* 创建一个inode */  64.struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)  65.{  66.        /* 从内存中分配一个inode空间 */  67.    struct inode * inode = new_inode(sb);  68.  69.    if (inode) {  70.         /* 填充inode结构 */  71.        inode->i_mode = mode;                  /* 文件类型 */  72.        inode->i_uid = current_fsuid();       /* 获得当前进程的UID */  73.        inode->i_gid = current_fsgid();       /* 获得当前进程的GID */  74.        inode->i_mapping->a_ops = &ramfs_aops;     /* 注册内存操作回调 */  75.        inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;  /* 保存底层块设备信息 */  76.        mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);   /* 为inode分配内存地址空间 */  77.        mapping_set_unevictable(inode->i_mapping);  78.        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;  79.        switch (mode & S_IFMT) {  80.        default:  81.            /* 处理特殊的inode,包括socket、fifo、块设备、字符设备*/  82.            init_special_inode(inode, mode, dev);  83.            break;  84.        case S_IFREG:  85.            /* 普通文件,注册回调函数 */  86.            inode->i_op = &ramfs_file_inode_operations;  87.            inode->i_fop = &ramfs_file_operations;  88.            break;  89.        case S_IFDIR:  90.            /* 目录,注册回调函数 */  91.            inode->i_op = &ramfs_dir_inode_operations;  92.            inode->i_fop = &simple_dir_operations;  93.  94.            /* directory inodes start off with i_nlink == 2 (for "." entry) */  95.            /* 增加文件引用计数即inode->i_nlink,目录的引用计数为2,因为包括了"."  96.                        当inode->i_nlink为0时,说明这个inode闲置 97.            */  98.            inc_nlink(inode);  99.            break;  100.        case S_IFLNK:  101.            inode->i_op = &page_symlink_inode_operations;  102.            break;  103.        }  104.    }  105.    return inode;  106.}  107.  108./* 109. * File creation. Allocate an inode, and we're done.. 110. */  111./* SMP-safe */  112./* 在指定的目录下创建节点 */  113.static int  114.ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)  115.{  116.       /* 获得一个inode */  117.    struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev);  118.    int error = -ENOSPC;  119.  120.    if (inode) {  121.        if (dir->i_mode & S_ISGID) {  /* 如果mode带有GID,需要将GID付给inode */  122.            inode->i_gid = dir->i_gid;  123.            if (S_ISDIR(mode))  124.                inode->i_mode |= S_ISGID;  125.        }  126.        d_instantiate(dentry, inode);  /* 用于向dentry结构中填写inode信息 */  127.        dget(dentry);   /* Extra count - pin the dentry in core 对dentry->d_count加一*/  128.        error = 0;  129.        dir->i_mtime = dir->i_ctime = CURRENT_TIME;  /* 修改目录的访问时间、inode修改时间 */  130.    }  131.    return error;  132.}  133.  134./* 创建目录 */  135.static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)  136.{  137.    int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0);  138.    if (!retval)  139.        inc_nlink(dir);  /* 将目录inode->i_nlink加一 */  140.    return retval;  141.}  142.  143./* 创建文件 */  144.static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)  145.{  146.    return ramfs_mknod(dir, dentry, mode | S_IFREG, 0);  147.}  148.  149.  150./* 建立软连接 */  151.static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)  152.{  153.    struct inode *inode;  154.    int error = -ENOSPC;  155.  156.       /* 获得一个inode */  157.    inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);  158.    if (inode) {  159.        int l = strlen(symname)+1;  160.        error = page_symlink(inode, symname, l);  /* 将软连接写入pagecache ,并将页置为脏*/  161.        if (!error) {  162.            if (dir->i_mode & S_ISGID)  163.                inode->i_gid = dir->i_gid;  164.            d_instantiate(dentry, inode);   /* 用于向dentry结构中填写inode信息 */  165.            dget(dentry);    /* dentry->d_count加1 */  166.            dir->i_mtime = dir->i_ctime = CURRENT_TIME;  /* 置操作时间 */  167.        } else  168.            iput(inode);  169.    }  170.    return error;  171.}  172.  173.  174./* 为inode操作注册回调函数 */  175.static const struct inode_operations ramfs_dir_inode_operations = {  176.    .create     = ramfs_create,  177.    .lookup     = simple_lookup,  178.    .link       = simple_link,  179.    .unlink     = simple_unlink,  180.    .symlink    = ramfs_symlink,  181.    .mkdir      = ramfs_mkdir,  182.    .rmdir      = simple_rmdir,  183.    .mknod      = ramfs_mknod,  184.    .rename     = simple_rename,  185.};  186.  187.  188./* 为超级块操作注册回调 */  189.static const struct super_operations ramfs_ops = {  190.    .statfs     = simple_statfs,  191.    .drop_inode = generic_delete_inode,  192.    .show_options   = generic_show_options,  193.};  194.  195.struct ramfs_mount_opts {  196.    umode_t mode;  197.};  198.  199.enum {  200.    Opt_mode,  201.    Opt_err  202.};  203.  204.static const match_table_t tokens = {  205.    {Opt_mode, "mode=%o"},  206.    {Opt_err, NULL}  207.};  208.  209.struct ramfs_fs_info {  210.    struct ramfs_mount_opts mount_opts;  211.};  212.  213.static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)  214.{  215.    substring_t args[MAX_OPT_ARGS];  216.    int option;  217.    int token;  218.    char *p;  219.  220.    opts->mode = RAMFS_DEFAULT_MODE;  221.  222.    while ((p = strsep(&data, ",")) != NULL) {  223.        if (!*p)  224.            continue;  225.  226.        token = match_token(p, tokens, args);  227.        switch (token) {  228.        case Opt_mode:  229.            if (match_octal(&args[0], &option))  230.                return -EINVAL;  231.            opts->mode = option & S_IALLUGO;  232.            break;  233.        /* 234.         * We might like to report bad mount options here; 235.         * but traditionally ramfs has ignored all mount options, 236.         * and as it is used as a !CONFIG_SHMEM simple substitute 237.         * for tmpfs, better continue to ignore other mount options. 238.         */  239.        }  240.    }  241.  242.    return 0;  243.}  244.  245./* 填充超级块 */  246.static int ramfs_fill_super(struct super_block * sb, void * data, int silent)  247.{  248.    struct ramfs_fs_info *fsi;  249.    struct inode *inode = NULL;  250.    struct dentry *root;  251.    int err;  252.  253.    save_mount_options(sb, data);  254.  255.    fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);  256.    sb->s_fs_info = fsi;  257.    if (!fsi) {  258.        err = -ENOMEM;  259.        goto fail;  260.    }  261.  262.    err = ramfs_parse_options(data, &fsi->mount_opts);  263.    if (err)  264.        goto fail;  265.  266.       /* 填充超级块结构体 */  267.    sb->s_maxbytes       = MAX_LFS_FILESIZE;  268.    sb->s_blocksize      = PAGE_CACHE_SIZE;  269.    sb->s_blocksize_bits = PAGE_CACHE_SHIFT;  270.    sb->s_magic      = RAMFS_MAGIC;  271.    sb->s_op     = &ramfs_ops;  /* 注册超级块操作回调 */  272.    sb->s_time_gran      = 1;  273.  274.       /* 为文件系统root分配inode */  275.    inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0);  276.    if (!inode) {  277.        err = -ENOMEM;  278.        goto fail;  279.    }  280.  281.      /* 为root分配缓存 */  282.    root = d_alloc_root(inode);  283.    sb->s_root = root;  284.    if (!root) {  285.        err = -ENOMEM;  286.        goto fail;  287.    }  288.  289.    return 0;  290.fail:  /* 异常处理 */  291.    kfree(fsi);  292.    sb->s_fs_info = NULL;  293.    iput(inode);  294.    return err;  295.}  296.  297./* 装载ramfs的超级块 */  298.int ramfs_get_sb(struct file_system_type *fs_type,  299.    int flags, const char *dev_name, void *data, struct vfsmount *mnt)  300.{  301.       /*在内存中分配一个超级块结构 (struct super_block) sb,并初始化其部分成员变量,将成员 s_instances 插入到 rootfs 文件系统类型结构中的 fs_supers 指向的双向链表中。*/  302.    return get_sb_nodev(fs_type, flags, data, ramfs_fill_super, mnt);  303.}  304.  305./* 装载rootfs的超级块 */  306.static int rootfs_get_sb(struct file_system_type *fs_type,  307.    int flags, const char *dev_name, void *data, struct vfsmount *mnt)  308.{  309.    return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super,  310.                mnt);  311.}  312.  313./* 卸载超级块 */  314.static void ramfs_kill_sb(struct super_block *sb)  315.{  316.    kfree(sb->s_fs_info);  317.    kill_litter_super(sb);  318.}  319.  320.static struct file_system_type ramfs_fs_type = {  321.    .name       = "ramfs",  322.    .get_sb     = ramfs_get_sb,  323.    .kill_sb    = ramfs_kill_sb,  324.};  325.static struct file_system_type rootfs_fs_type = {  326.    .name       = "rootfs",  327.    .get_sb     = rootfs_get_sb,  328.    .kill_sb    = kill_litter_super,  329.};  330.  331.  332./* 初始化模块,注册文件系统 */  333.static int __init init_ramfs_fs(void)  334.{  335.    return register_filesystem(&ramfs_fs_type);  336.}  337.  338./* 退出模块,注销文件系统 */  339.static void __exit exit_ramfs_fs(void)  340.{  341.    unregister_filesystem(&ramfs_fs_type);  342.}  343.  344.module_init(init_ramfs_fs)  345.module_exit(exit_ramfs_fs)  346.  347.  348./* 初始化rootfs文件系统,在引导开机的过程中调用 */  349.int __init init_rootfs(void)  350.{  351.    int err;  352.  353.      /* 初始化对应的块设备 */  354.    err = bdi_init(&ramfs_backing_dev_info);  355.    if (err)  356.        return err;  357.  358.       /* 注册rootfs文件系统 */  359.    err = register_filesystem(&rootfs_fs_type);  360.    if (err)  361.        bdi_destroy(&ramfs_backing_dev_info);  362.  363.    return err;  364.}  365.  366.MODULE_LICENSE("GPL");  


 

原创粉丝点击