博文

如何挂载一个文件系统

图片
挂载一个文件系统中最重要的数据结构有以下3个: 1.          file_system_type 要挂载的文件系统类型。 2.          super_block其中有怎样获取该文件系统相关数据的方法。 3.          vfsmount 这个数据结构起到被挂载文件系统和挂载点文件系统的枢纽所用 这几个数据结构的关系,请着重看下图的红色椭圆形区域:     对照上图,我们可以得出结论,如果要挂载一个文件系统需要做的工作: 1.查找相应的文件系统类型,such as ext2 ext3 or ntfs or yaffs2 or rootfs etc. 2.查找相应的挂载点,方法:一路摸索,顺藤摸瓜。找到其dentry和inode. 3.生成一个vfsmount,这个数据结构是挂载点目录以及正在挂载的这个文件系统的根目录(依据的数据结构是:mnt_mountpoing和mnt_root)的枢纽(非常重要),并将这个vfsmount放在到hashtable中。这个hashtable的hash值运算依据的是挂载点目录以及挂载点inode.除了挂载到hashtable中外,还要链到父挂载点的子链表中。 放在hashtable的原因是,将来在lookup其内的目录或者文件时,需要根据挂载点的目录和挂载点的inode取hash值快速得到vfsmount。 4.主要的工作完成后,还需要把正在挂载的这个文件系统的根目录的inode和dentry取出来放在内存中,其中dentry的值还要赋给vfsmount的mnt_root. 当然这个第4步骤和第3步骤可能会有混合,主要是为了给vfsmount->mnt_root赋值,所以,需要取该文件系统的根目录。   按照以上的分析,我们对照review一下内核的源码的流程(为了方便,将与分析无关的语句去掉了): 2393 SYSCALL_DEFINE5(mount, char __user *...

page cache\swap cache\buffer cache

page cache是与文件映射对应的,而swap cache是与匿名页对应的。如果一个内存页面不是文件映射,则在换入换出的时候加入到swap cache,如果是文件映射,则不需要交换缓冲。 这两个相同的就是都是address_space,都有相对应的文件操作。一个被访问文件的物理页面都驻留在page cache或swap cache中,一个页面的所有信息由struct page来描述。 struct page中有一个域为指针mapping ,它指向一个struct address_space类型结构。 page cache或swap cache中的所有页面就是根据address_space结构以及一个偏移量来区分的。 一般情况下用户进程调用mmap()时,只是在进程空间内新增了一块相应大小的缓冲区,并设置了相应的访问标识,但并没有建立进程空间到物理页面的映射。因此,第一次访问该空间时,会引发一个缺页异常。 对于共享内存映射情况,缺页异常处理程序首先在swap cache中寻找目标页(符合address_space以及偏移量的物理页),如果找到,则直接返回地址;如果没有找到,则判断该页是否在交换区 (swap area),如果在,则执行一个换入操作;如果上述两种情况都不满足,处理程序将分配新的物理页面,并把它插入到page cache中。进程最终将更新进程页表。 注:对于映射普通文件情况(非共享映射),缺页异常处理程序首先会在page cache中根据address_space以及数据偏移量寻找相应的页面。如果没有找到,则说明文件数据还没有读入内存,处理程序会从磁盘读入相应的页面,并返回相应地址,同时,进程页表也会更新。 说到page cache我们很容易就与buffer cache混淆,在这里我需要说的是page cache是VFS的一部分,buffer cache是块设备驱动的一部分,或者说page cache是面向用户IO的cache,buffer cache是面向块设备IO的cache,page cache按照文件的逻辑页进行缓冲,buffer cache按照文件的物理块进行缓冲。page cache与buffer cache并不相互独立而是相互融合的,同一文件的cache页即可存在于page cache中,又可存在于buffer cache中,它们在物理内...

通过简单的例子,学习systemtap

看例子先!  怎样遍历数组: 1.  # 2.  # Print the system call count by process name in descending order. 3.  # 4. 5.  global syscalls 6. 7.  probe begin { 8.     print ("Collecting data... Type Ctrl-C to exit and display results\n") 9.  } 10. 11. probe syscall.* { 12.    syscalls[execname()]++ 13. } 14. 15. probe end { 16.    printf ("%-10s %-s\n", "#SysCalls", "Process Name") 17.    foreach (proc in syscalls-) 18.       printf("%-10d %-s\n", syscalls[proc], proc) 19. }   这中间,比较难理解的是第17行,那么它的解释如下: The variable proc is an index variable that iterates over the range of values possible for the array index of syscalls. Also note the en dash (-) after syscalls that denotes that the iteration runs in reverse order. This character ensures that the number of system calls made print in descending order. To print in ascending order, change the...

外网主机ssh和vnc访问内网主机

之前,孤陋寡闻,以为外网访问内网纯属扯淡!早上开shlug的邮件列表,看到这个thread。实验了一下,夷~,竟然可以。太棒了! 外网通过ssh访问内网的方法: $ ssh -f -N -R 7070: 127.0.0.1:22  外网主机用户名@外网主机ip $ ssh 内网主机用户名@ 127.0.0.1  -p 7070 原理:将外网7070的端口映射到内网主机的22端口 外网通过VNC访问内网的方法: 同ssh访问的方法一样,我们还可以使用VNC服务: 在内网主机上安装好VNC,然后,开启一个session(默认的端口是从5900开始的) 在内网主机操作: $vnc4server :1 $vnc4passwd //设定VNC连接密码 $ssh -f -N -R 1234: 127.0.0.1:5901  外网主机用户名@外网主机ip 好,已经将5901绑定到外网主机的1234端口了。 然后,操作外网主机: 在外网主机菜单Applications->Internet->Remote Desktop Viewer 选择VNC协议,填入 127.0.0.1:1234 然后, 会要求输入密码,就是内网主机通过vnc4passwd设定的密码了。 OK啦~

__copy_user_zeroing

2.6内核和2.4相比,又加入了一个异常修复地址 #define __copy_user_zeroing(to,from,size)               \ do {                                   \    int __d0, __d1, __d2;                       \    __asm__ __volatile__(                       \        "   cmp $7,%0\n"                   \        "   jbe  1f \n"                   \        "   movl %1,%0\n"        ...

看例子,学Systemtap

看例子先! 例子 : 怎样遍历数组: 1. # 2. # Print the system call count by process name in descending order. 3. # 4. 5. global syscalls 6. 7. probe begin { 8. print ("Collecting data... Type Ctrl-C to exit and display results\n") 9. } 10. 11. probe syscall.* { 12. syscalls[execname()]++ 13. } 14. 15. probe end { 16. printf ("%-10s %-s\n", "#SysCalls", "Process Name") 17. foreach (proc in syscalls-) 18. printf("%-10d %-s\n", syscalls[proc], proc) 19. } 这中间,比较难理解的是第17行,那么它的解释如下: The variable  proc  is an index variable that iterates over the range of values possible for the array index of  syscalls . Also note the en dash (-) after  syscalls  that denotes that the iteration runs in reverse order. This character ensures that the number of system calls made print in descending order. To print in ascending order, change the script to syscalls+ . ------------------------------ ------------------------------ -----...

Linux系统调用宏展开笔记

不知道从哪个版本的内核开始,系统调用变成宏了。在2.6.38的内核里面追踪了一下,以SYSCALL_DEFINE1为例:   SYSCALL_DEFINE1(name,...)展开sys_name,后面的数字,若为1则是一个参数,若为2则为2个参数   具体的宏,展开跟踪流程如下: #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)                                         |                                            v                            #define SYSCALL_DEFINEx(x, sname, ...)              \                                   __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)                         ...