ramfs

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");  


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值