[文件系统]文件系统学习笔记(九)---rootfs

一:根文件系统(rootfs)

1,rootfs文件系统的注册
在linux kernel初始化阶段会调用int __init init_rootfs(void)向内核注册rootfs文件系统,
init_rootfs()的核心的函数为register_filesystem();这个函数将结构file_system_type?注册在内核一 个单链表中,

[cpp] view plaincopy

  1. 307 int __init init_rootfs(void)
  2. 308 {
  3. 309         int err;
  4. 311         err = bdi_init(&ramfs_backing_dev_info);
  5. 312         if (err)
  6. 313                 return err;
  7. 315         err = register_filesystem(&rootfs_fs_type);
  8. 316         if (err)
  9. 317                 bdi_destroy(&ramfs_backing_dev_info);
  10. 319         return err;
  11. 320 }
  12. 288 static struct file_system_type rootfs_fs_type = {
  13. 289         .name           = "rootfs",
  14. 290         .mount         = rootfs_mount,
  15. 291         .kill_sb        = kill_litter_super,
  16. 292 };

2,rootfs_mount()函数解析
static struct dentry *rootfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
rootfs_mount()函数首先会调用mount_nodev()函数,mount_nodev()函数原型如下:mount_nodev(fs_type, flags, data, ramfs_fill_super);

[cpp] view plaincopy

  1. 1060 struct dentry *mount_nodev(struct file_system_type *fs_type,
  2. 1061         int flags, void *data,
  3. 1062         int (*fill_super)(struct super_block *, void *, int))
  4. 1063 {
  5. 1064         int error;
  6. 1065         struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
  7. 1067         if (IS_ERR(s))
  8. 1068                 return ERR_CAST(s);
  9. 1069
  10. 1070         s->s_flags = flags;
  11. 1072         error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
  12. 1073         if (error) {
  13. 1074                 deactivate_locked_super(s);
  14. 1075                 return ERR_PTR(error);
  15. 1076         }
  16. 1077         s->s_flags |= MS_ACTIVE;
  17. 1078         return dget(s->s_root);
  18. 1079 }

上述函数sget()函数的作用主要是分配一个超级快(super_block)的实例,并.通过s_list加入链表super_blocks,然后通过s_instances加入链表typer->fs_supers。

fill_super()函数调用到ramfs_fill_super()函数,ramfs_fill_super()函数的定义如下:

[cpp] view plaincopy

    1. 209 int ramfs_fill_super(struct super_block *sb, void *data, int silent)
    2. 210 {
    3. 211         struct ramfs_fs_info *fsi;
    4. 212         struct inode *inode;
    5. 213         int err;
    6. 215         save_mount_options(sb, data);
    7. 217         fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
    8. 218         sb->s_fs_info = fsi;
    9. 219         if (!fsi)
    10. 220                 return -ENOMEM;
    11. 222         err = ramfs_parse_options(data, &fsi->mount_opts);
    12. 223         if (err)
    13. 224                 return err;
    14. 226         sb->s_maxbytes          = MAX_LFS_FILESIZE;  //文件的最大值
    15. 227         sb->s_blocksize         = PAGE_CACHE_SIZE;  //以字节为单位的块的大小
    16. 228         sb->s_blocksize_bits    = PAGE_CACHE_SHIFT;  //以位为单位的块的大小
    17. 229         sb->s_magic             = RAMFS_MAGIC;
    18. 230         sb->s_op                = &ramfs_ops;  //超级块的方法 ,在处理inode的时候会有用
    19. 231         sb->s_time_gran         = 1;
    20. 233         inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);  //建立根目录索引节点
    21. 234         sb->s_root = d_make_root(inode);  //建立根目录目录对象; 超级块的s_root指向刚建立的根目录对象
    22. 235         if (!sb->s_root)
    23. 236                 return -ENOMEM;
    24. 238         return 0;
    25. 239 }
    26. 54 struct inode *ramfs_get_inode(struct super_block *sb,
    27. 55                                 const struct inode *dir, umode_t mode, dev_t dev)
    28. 56 {
    29. 57         struct inode * inode = new_inode(sb); //在索引节点高速缓存里创建一个inode,
    30. 59         if (inode) {
    31. 60                 inode->i_ino = get_next_ino();  //获取一个inode number
    32. 61                 inode_init_owner(inode, dir, mode); //设置inode,初始化uid gid mode等
    33. 62                 inode->i_mapping->a_ops = &ramfs_aops;
    34. 63                 inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
    35. 64                 mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
    36. 65                 mapping_set_unevictable(inode->i_mapping);
    37. 66                 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
    38. 67                 switch (mode & S_IFMT) {
    39. 68                 default:               //特殊文件;如:字符~块设备文件,FIFO,SOCKET文件
    40. 69                         init_special_inode(inode, mode, dev);
    41. 70                         break;
    42. 71                 case S_IFREG:         //普通文件
    43. 72                         inode->i_op = &ramfs_file_inode_operations;
    44. 73                         inode->i_fop = &ramfs_file_operations;
    45. 74                         break;
    46. 75                 case S_IFDIR:         //目录文件
    47. 76                         inode->i_op = &ramfs_dir_inode_operations;
    48. 77                         inode->i_fop = &simple_dir_operations;
    49. 79                         /* directory inodes start off with i_nlink == 2 (for "." entry) */
    50. 80                         inc_nlink(inode);
    51. 81                         break;
    52. 82                 case S_IFLNK:         //链接文件
    53. 83                         inode->i_op = &page_symlink_inode_operations;
    54. 84                         break;
    55. 85                 }
    56. 86         }
    57. 87         return inode;              //返回创建的inode与对应的目录项对象关联
    58. 88 }
时间: 2024-10-13 16:06:33

[文件系统]文件系统学习笔记(九)---rootfs的相关文章

APUE 学习笔记(九) 高级I/O

1. 非阻塞I/O 低速系统调用时可能会使进程永远阻塞的一类系统调用,包括以下调用: (1)某些文件类型你(网络socket套接字.终端设备.管道)暂无可使用数据,则读操作可能会使调用者永远阻塞 (2)如果数据不能立即被(1)中文件类型接受,则写操作会使调用者永远阻塞 (3)某些进程间通信函数 非阻塞I/O使我们可以调用open.read.write这样的I/O操作,并使这些操作不会永远阻塞,如果这种操作不能完成,则调用立即出错返回 对于一个给定的文件有两种方法对其指定非阻塞I/O: (1)调用

python学习笔记九——文件与目录

1.python进行文件读写的函数是open或file类 mode:r  只读 r+   读写 w  写入,先删除原文件,再重新写入,如果文件没有则创建 w+  读写,先删除原文件,再重新写入,如果文件没有则创建(可写入和输出) a  写入,在文件末尾追加新的内容,文件不存在则创建 a+  读写,在文件末尾追加新的内容,文件不存在则创建 b  打开二进制文件,可与r,w,a,+结合使用 U  支持所有的换行符号,"\r","\n","\r\n"

angular学习笔记(九)-css类和样式3

再来看一个选择li列表的例子: 点击li中的任意项,被点击的li高亮显示: <!DOCTYPE html> <html ng-app> <head> <title>6.3css类和样式</title> <meta charset="utf-8"> <script src="../angular.js"></script> <script src="scri

angular学习笔记(九)-css类和样式2

在上一个例子中,元素的类名使用拼接的方法,这样,类名中就不得不带有true或false,并且不易维护,所以,angular使用ng-class属性来控制元素的类名: 我们来看一个小例子,点击error按钮,顶部提示错误框,点击warning按钮,顶部提示警告框. 错误框的类名是.err,警告框的类名是.warn: <!DOCTYPE html> <html ng-app> <head> <title>6.2css类和样式</title> <

Linux System Programming 学习笔记(九) 内存管理

1. 进程地址空间 Linux中,进程并不是直接操作物理内存地址,而是每个进程关联一个虚拟地址空间 内存页是memory management unit (MMU) 可以管理的最小地址单元 机器的体系结构决定了内存页大小,32位系统通常是 4KB, 64位系统通常是 8KB 内存页分为 valid or invalid: A valid page is associated with an actual page of data,例如RAM或者磁盘上的文件 An invalid page is

虚拟机VMWare学习笔记九 - 物理机上的文件挂载到虚拟机上

物理机上的文件夹或盘符直接挂载到虚拟机上使用. VM -- Settings Options -- Shared Folders -- 勾选Always enabled , 勾选Map as a network drive in Windows guests 在点击下面的添加来添加共享的文件夹 选择路径 可以看到虚拟机中的共享文件夹已经出现在Windows 中了 虚拟机VMWare学习笔记九 - 物理机上的文件挂载到虚拟机上

初探swift语言的学习笔记九(OC与Swift混编)

swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. 先中简单的入手,先研究在同一个工程目录下混合使用的情况. 为了演示.先准备两个类 第一个是swift语言写的类,文件名为 act.swift import Foundation class Act : NSObject { func hasAct(tag:Int) -> String { swit

《Hibernate学习笔记九》:多对一和一对多的关联关系

<Hibernate学习笔记九>:多对一和一对多的关联关系 前面介绍了一对一的关联关系在Hibernate应该如何来实现,这篇博文就来介绍下多对一和一对多的关联关系. 多对一和一对多的关联关系在我们的生活中也比较常见,例如,在我们学生时代,一个班级可以有多个学生,而一个学生只能属于一个班级,这就是一个多对一(一对多)的例子: 还有在我们的工作中,一个工作小组可以有多个用户,而一个用户只能属于一个小组,这也是一个多对一(一对多)的关系的例子. 1.多对一的单向关联关系 下面就以一个工作小组可以有

Java并发学习笔记(九)-原子类AtomicInteger

AtomicInteger能够保证对一个整型的操作是原子性.像i++这个操作不是原子操作,存在竞态条件,所以需要加锁,但是加锁的性能不高,如果仅仅为了对一个整数加1.我们来看下他的实现. private volatile int value; AtomicInteger本身持有一个整型变量,所有的操作都是基于这个变量的.变量由violate修饰,这个变量是保证可见性的,具体可见另一篇博客 Java并发学习笔记(六)-互斥性和内存可见性. 来看一下对value加1的操作 public final

[傅里叶变换及其应用学习笔记] 九. 继续卷积的讨论

这份是本人的学习笔记,课程为网易公开课上的斯坦福大学公开课:傅里叶变换及其应用. 卷积在滤波中的应用 浑浊度(Turbidity)研究是关于测量水的清澈度的研究.大致方法是把光传感器放置到深水区域,然后测量光线的昏暗程度,测量出来的值将随时间变化. (由于没有真实数据,下面用mathematica比较粗糙地模拟水域的浑浊度数据)         能看到信号主要集中在低频,我们需要把毛刺去除,也就是把高频去除,在频域进行低通滤波(Low Pass Filtering)         滤波后的波形