文件系统注册及mount过程分析
2012-01-04 19:51
399 查看
http://www.vrlinux.com/naheyuanma/20100813/73134.html
小弟是个菜鸟,如果写得有错误的地方,请不吝赐教
kernel version: 2.6.35
从ext4文件的init开始分析一下,暂时先不去看cache的使用
看一下注册的过程
注册的ext4的文件系统的类型结构,这个在do_kernel_mount的时候会通过这个的name来查找fstype
然后通过传递的flag来判断挂载操作, 这些flag可以在man 2 mount中看到说明,这个与mount命令有区别,mount命令要在应用程序里面做很多
先看do_kernel_mount
进入到vfs_kern_mount里面看一下,里面肯定会调到get_sb,
get_sb_bdev里面会用到ext4_fill_super,因为要注册一下里面的细节,比如创建节点,文件,目录,链接,读文件,读目录,写文件,写目录,删除文件,很多很多。
后面涉及到了对块设备操作的很多工作,文件系统最关键的就是管理文件,并且是块设备上的,这个块设备就是在get_sb_bdev里面得到的
就这样,对磁盘文件操作就了解了
通过这个fill_super来进行读读块设备
然后回到do_new_mount,将挂载点添加到列表里就可以了,这个列表在/proc中可以展现出来
T-Bagwell 说
:em06::em06::em06:
其实我就是把过程写一下,希望大伙能指点一下
Godbach 说
T-Bag兄顺便说一下内核版本
cambyzju 说
不是说了2.6.35么
T-Bagwell 说
差点误认子弟,刚刚交流了一下,一般情况下是修改sb的
比如mount的时候修改时间撮一类的属性
下面是在irc里面mason说的
<mason> usually when we mount, we update those counters and timestamps and write the new result back to disk
nkmxl 说
好文章 EXT4听话很稳定啊。
小弟是个菜鸟,如果写得有错误的地方,请不吝赐教
kernel version: 2.6.35
从ext4文件的init开始分析一下,暂时先不去看cache的使用
register_as_ext2(); register_as_ext3(); err = register_filesystem(&ext4_fs_type);可以看出来注册了ext2,ext3,ext4
看一下注册的过程
56 /** 57 * register_filesystem - register a new filesystem 58 * @fs: the file system structure 59 * 60 * Adds the file system passed to the list of file systems the kernel 61 * is aware of for mount and other syscalls. Returns 0 on success, 62 * or a negative errno code on an error. 63 * 64 * The &struct file_system_type that is passed is linked into the kernel 65 * structures and must not be freed until the file system has been 66 * unregistered. 67 */ 68 69 int register_filesystem(struct file_system_type * fs) 70 { 71 int res = 0; 72 struct file_system_type ** p; 73 74 BUG_ON(strchr(fs->name, '.')); 75 if (fs->next) 76 return -EBUSY; 77 INIT_LIST_HEAD(&fs->fs_supers); 78 write_lock(&file_systems_lock); 79 p = find_filesystem(fs->name, strlen(fs->name)); 80 if (*p) 81 res = -EBUSY; 82 else 83 *p = fs; 84 write_unlock(&file_systems_lock); 85 return res; 86 } 87 88 EXPORT_SYMBOL(register_filesystem);在这里面调用了find_filesystem,先找一下看看是不是有同样的文件系统类型被使用了,这个就像银行卡号一样,不能重复,否则会出现自己存的钱被另一个人取走的可能,如果存在了文件系统就返回错误,如果没有存在就添加到支持的文件系统的列表里面,开始支持注册的文件系统,比如ext4
注册的ext4的文件系统的类型结构,这个在do_kernel_mount的时候会通过这个的name来查找fstype
static struct file_system_type ext4_fs_type = { .owner = THIS_MODULE, .name = "ext4", .get_sb = ext4_get_sb, .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, };这里的ext4_get_sb是在do_kern_mount的时候调用到的,走一下流程
2122 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, 2123 char __user *, type, unsigned long, flags, void __user *, data) 2124 { 2125 int ret; 2126 char *kernel_type; 2127 char *kernel_dir; 2128 char *kernel_dev; 2129 unsigned long data_page; 2130 2131 ret = copy_mount_string(type, &kernel_type); 2132 if (ret < 0) 2133 goto out_type; 2134 2135 kernel_dir = getname(dir_name); 2136 if (IS_ERR(kernel_dir)) { 2137 ret = PTR_ERR(kernel_dir); 2138 goto out_dir; 2139 } 2140 2141 ret = copy_mount_string(dev_name, &kernel_dev); 2142 if (ret < 0) 2143 goto out_dev; 2144 2145 ret = copy_mount_options(data, &data_page); 2146 if (ret < 0) 2147 goto out_data; 2148 2149 ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags, 2150 (void *) data_page); 2151 2152 free_page(data_page); 2153 out_data: 2154 kfree(kernel_dev); 2155 out_dev: 2156 putname(kernel_dir); 2157 out_dir: 2158 kfree(kernel_type); 2159 out_type: 2160 return ret; 2161 }系统调用的mount,会走到这里,然后进入do_mount接口里面进行mount操作
1942 long do_mount(char *dev_name, char *dir_name, char *type_page, 1943 unsigned long flags, void *data_page) 1944 { 1945 struct path path; 1946 int retval = 0; 1947 int mnt_flags = 0; 1948 1949 /* Discard magic */ 1950 if ((flags & MS_MGC_MSK) == MS_MGC_VAL) 1951 flags &= ~MS_MGC_MSK; 1952 1953 /* Basic sanity checks */ 1954 1955 if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) 1956 return -EINVAL; 1957 1958 if (data_page) 1959 ((char *)data_page)[PAGE_SIZE - 1] = 0; 1960 1961 /* ... and get the mountpoint */ 1962 retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); 1963 if (retval) 1964 return retval; 1965 1966 retval = security_sb_mount(dev_name, &path, 1967 type_page, flags, data_page); 1968 if (retval) 1969 goto dput_out; 1970 1971 /* Default to relatime unless overriden */ 1972 if (!(flags & MS_NOATIME)) 1973 mnt_flags |= MNT_RELATIME; 1974 1975 /* Separate the per-mountpoint flags */ 1976 if (flags & MS_NOSUID) 1977 mnt_flags |= MNT_NOSUID; 1978 if (flags & MS_NODEV) 1979 mnt_flags |= MNT_NODEV; 1980 if (flags & MS_NOEXEC) 1981 mnt_flags |= MNT_NOEXEC; 1982 if (flags & MS_NOATIME) 1983 mnt_flags |= MNT_NOATIME; 1984 if (flags & MS_NODIRATIME) 1985 mnt_flags |= MNT_NODIRATIME; 1986 if (flags & MS_STRICTATIME) 1987 mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME); 1988 if (flags & MS_RDONLY) 1989 mnt_flags |= MNT_READONLY; 1990 1991 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | 1992 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | 1993 MS_STRICTATIME); 1994 1995 if (flags & MS_REMOUNT) 1996 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, 1997 data_page); 1998 else if (flags & MS_BIND) 1999 retval = do_loopback(&path, dev_name, flags & MS_REC); 2000 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) 2001 retval = do_change_type(&path, flags); 2002 else if (flags & MS_MOVE) 2003 retval = do_move_mount(&path, dev_name); 2004 else 2005 retval = do_new_mount(&path, type_page, flags, mnt_flags, 2006 dev_name, data_page); 2007 dput_out: 2008 path_put(&path); 2009 return retval; 2010 }通过kern_path来获得挂载点&path
然后通过传递的flag来判断挂载操作, 这些flag可以在man 2 mount中看到说明,这个与mount命令有区别,mount命令要在应用程序里面做很多
[root@T-bagwell ~]# strace mount -t ext4 /dev/sdc1 /mnt execve("/bin/mount", ["mount", "-t", "ext4", "/dev/sdc1", "/mnt"], [/* 26 vars */]) = 0 brk(0) = 0xb894c000 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb777a000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=59157, ...}) = 0 mmap2(NULL, 59157, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb776b000 close(3) = 0 open("/lib/libblkid.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20d\33\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=85520, ...}) = 0 mmap2(NULL, 86652, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7755000 mmap2(0xb7769000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13) = 0xb7769000 close(3) = 0 open("/lib/libuuid.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`N\337\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=16112, ...}) = 0 mmap2(NULL, 17072, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7750000 mmap2(0xb7754000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3) = 0xb7754000 close(3) = 0 open("/lib/libselinux.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`\201\262\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=118316, ...}) = 0 mmap2(NULL, 121848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7732000 mmap2(0xb774e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b) = 0xb774e000 close(3) = 0 open("/lib/libsepol.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\337\271\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=242288, ...}) = 0 mmap2(NULL, 244992, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb76f6000 mmap2(0xb7731000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3a) = 0xb7731000 close(3) = 0 open("/lib/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20M\225\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=2402248, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76f5000 mmap2(NULL, 1526120, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7580000 mprotect(0xb76ee000, 4096, PROT_NONE) = 0 mmap2(0xb76ef000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16e) = 0xb76ef000 mmap2(0xb76f2000, 10600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76f2000 close(3) = 0 open("/lib/libdl.so.2", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`Z\253\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=28364, ...}) = 0 mmap2(NULL, 16500, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb757b000 mmap2(0xb757e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2) = 0xb757e000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb757a000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb757a750, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb757e000, 4096, PROT_READ) = 0 mprotect(0xb76ef000, 8192, PROT_READ) = 0 mprotect(0xb774e000, 4096, PROT_READ) = 0 mprotect(0xb779a000, 4096, PROT_READ) = 0 munmap(0xb776b000, 59157) = 0 statfs64("/selinux", 84, {f_type="EXT2_SUPER_MAGIC", f_bsize=4096, f_blocks=3466984, f_bfree=1622516, f_bavail=1446401, f_files=881280, f_ffree=686391, f_fsid={1492870975, 1857190837}, f_namelen=255, f_frsize=4096}) = 0 brk(0) = 0xb894c000 brk(0xb896d000) = 0xb896d000 open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3 fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7779000 read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tb"..., 1024) = 283 read(3, "", 1024) = 0 close(3) = 0 munmap(0xb7779000, 4096) = 0 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=98765760, ...}) = 0 mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb737a000 close(3) = 0 umask(022) = 022 open("/dev/null", O_RDWR|O_LARGEFILE) = 3 close(3) = 0 getuid32() = 0 geteuid32() = 0 readlink("/dev", 0xbf909b5b, 4096) = -1 EINVAL (Invalid argument) readlink("/dev/sdc1", 0xbf909b5b, 4096) = -1 EINVAL (Invalid argument) stat64("/sbin/mount.ext4", 0xbf90a8f8) = -1 ENOENT (No such file or directory) rt_sigprocmask(SIG_BLOCK, ~[TRAP SEGV RTMIN RT_1], NULL, 8) = 0 stat64("/sbin/mount.ext4", 0xbf90a8b8) = -1 ENOENT (No such file or directory) *********************************关键是这里**************************************** mount("/dev/sdc1", "/mnt", "ext4", MS_MGC_VAL, NULL) = 0 readlink("/dev", 0xbf90995b, 4096) = -1 EINVAL (Invalid argument) readlink("/dev/sdc1", 0xbf90995b, 4096) = -1 EINVAL (Invalid argument) readlink("/mnt", 0xbf90995b, 4096) = -1 EINVAL (Invalid argument) lstat64("/etc/mtab", {st_mode=S_IFREG|0644, st_size=279, ...}) = 0 open("/etc/mtab", O_RDWR|O_CREAT|O_LARGEFILE, 0644) = 3 close(3) = 0 rt_sigaction(SIGHUP, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGINT, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGQUIT, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGILL, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGTRAP, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGABRT, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGBUS, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGFPE, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGKILL, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = -1 EINVAL (Invalid argument) rt_sigaction(SIGUSR1, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGSEGV, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGUSR2, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGPIPE, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGALRM, {0xb77a2eb0, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGTERM, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGSTKFLT, {0xb77a3a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 getpid() = 1406 open("/etc/mtab~1406", O_WRONLY|O_CREAT|O_LARGEFILE, 0600) = 3 close(3) = 0 gettimeofday({1281688440, 625200}, NULL) = 0 link("/etc/mtab~1406", "/etc/mtab~") = 0 open("/etc/mtab~", O_WRONLY|O_LARGEFILE) = 3 fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}, 0xbf90a92c) = 0 unlink("/etc/mtab~1406") = 0 umask(077) = 022 open("/etc/mtab", O_RDWR|O_CREAT|O_APPEND|O_LARGEFILE, 0666) = 4 umask(022) = 077 fstat64(4, {st_mode=S_IFREG|0644, st_size=279, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7779000 fstat64(4, {st_mode=S_IFREG|0644, st_size=279, ...}) = 0 _llseek(4, 0, [0], SEEK_SET) = 0 read(4, "/dev/sda1 / ext4 rw 0 0\nproc /pr"..., 279) = 279 write(4, "/dev/sdc1 /mnt ext4 rw 0 0\n", 27) = 27 close(4) = 0 munmap(0xb7779000, 4096) = 0 close(3) = 0 unlink("/etc/mtab~") = 0 rt_sigprocmask(SIG_UNBLOCK, ~[TRAP SEGV RTMIN RT_1], NULL, 8) = 0 exit_group(0) = ?
[root@T-bagwell ~]# strace mount -t ext4 -o remount /dev/sdc1 /mnt execve("/bin/mount", ["mount", "-t", "ext4", "-o", "remount", "/dev/sdc1", "/mnt"], [/* 26 vars */]) = 0 brk(0) = 0xb7dee000 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7730000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=59157, ...}) = 0 mmap2(NULL, 59157, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7721000 close(3) = 0 open("/lib/libblkid.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20d\33\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=85520, ...}) = 0 mmap2(NULL, 86652, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb770b000 mmap2(0xb771f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13) = 0xb771f000 close(3) = 0 open("/lib/libuuid.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`N\337\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=16112, ...}) = 0 mmap2(NULL, 17072, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7706000 mmap2(0xb770a000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3) = 0xb770a000 close(3) = 0 open("/lib/libselinux.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`\201\262\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=118316, ...}) = 0 mmap2(NULL, 121848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb76e8000 mmap2(0xb7704000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b) = 0xb7704000 close(3) = 0 open("/lib/libsepol.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\337\271\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=242288, ...}) = 0 mmap2(NULL, 244992, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb76ac000 mmap2(0xb76e7000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3a) = 0xb76e7000 close(3) = 0 open("/lib/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20M\225\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=2402248, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76ab000 mmap2(NULL, 1526120, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7536000 mprotect(0xb76a4000, 4096, PROT_NONE) = 0 mmap2(0xb76a5000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16e) = 0xb76a5000 mmap2(0xb76a8000, 10600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76a8000 close(3) = 0 open("/lib/libdl.so.2", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`Z\253\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=28364, ...}) = 0 mmap2(NULL, 16500, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7531000 mmap2(0xb7534000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2) = 0xb7534000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7530000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb7530750, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb7534000, 4096, PROT_READ) = 0 mprotect(0xb76a5000, 8192, PROT_READ) = 0 mprotect(0xb7704000, 4096, PROT_READ) = 0 mprotect(0xb7750000, 4096, PROT_READ) = 0 munmap(0xb7721000, 59157) = 0 statfs64("/selinux", 84, {f_type="EXT2_SUPER_MAGIC", f_bsize=4096, f_blocks=3466984, f_bfree=1622515, f_bavail=1446400, f_files=881280, f_ffree=686391, f_fsid={1492870975, 1857190837}, f_namelen=255, f_frsize=4096}) = 0 brk(0) = 0xb7dee000 brk(0xb7e0f000) = 0xb7e0f000 open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 3 fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb772f000 read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tb"..., 1024) = 283 read(3, "", 1024) = 0 close(3) = 0 munmap(0xb772f000, 4096) = 0 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=98765760, ...}) = 0 mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7330000 close(3) = 0 umask(022) = 022 open("/dev/null", O_RDWR|O_LARGEFILE) = 3 close(3) = 0 getuid32() = 0 geteuid32() = 0 readlink("/dev", 0xbf9fc3ab, 4096) = -1 EINVAL (Invalid argument) readlink("/dev/sdc1", 0xbf9fc3ab, 4096) = -1 EINVAL (Invalid argument) stat64("/sbin/mount.ext4", 0xbf9fd148) = -1 ENOENT (No such file or directory) rt_sigprocmask(SIG_BLOCK, ~[TRAP SEGV RTMIN RT_1], NULL, 8) = 0 stat64("/sbin/mount.ext4", 0xbf9fd108) = -1 ENOENT (No such file or directory) *********************************关键是这里**********因为是-o remount,所以这里多了一个MS_REMOUNT****************************** mount("/dev/sdc1", "/mnt", 0xb7def0d8, MS_MGC_VAL|MS_REMOUNT, NULL) = 0 readlink("/dev", 0xbf9fc1ab, 4096) = -1 EINVAL (Invalid argument) readlink("/dev/sdc1", 0xbf9fc1ab, 4096) = -1 EINVAL (Invalid argument) readlink("/mnt", 0xbf9fc1ab, 4096) = -1 EINVAL (Invalid argument) lstat64("/etc/mtab", {st_mode=S_IFREG|0644, st_size=306, ...}) = 0 open("/etc/mtab", O_RDWR|O_CREAT|O_LARGEFILE, 0644) = 3 close(3) = 0 open("/etc/mtab", O_RDWR|O_CREAT|O_LARGEFILE, 0644) = 3 close(3) = 0 rt_sigaction(SIGHUP, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGINT, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGQUIT, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGILL, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGTRAP, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGABRT, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGBUS, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGFPE, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGKILL, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = -1 EINVAL (Invalid argument) rt_sigaction(SIGUSR1, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGSEGV, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGUSR2, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGPIPE, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGALRM, {0xb7758eb0, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGTERM, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 rt_sigaction(SIGSTKFLT, {0xb7759a90, ~[RTMIN RT_1], 0}, NULL, 8) = 0 getpid() = 1415 open("/etc/mtab~1415", O_WRONLY|O_CREAT|O_LARGEFILE, 0600) = 3 close(3) = 0 gettimeofday({1281688501, 78710}, NULL) = 0 link("/etc/mtab~1415", "/etc/mtab~") = 0 open("/etc/mtab~", O_WRONLY|O_LARGEFILE) = 3 fcntl64(3, F_SETLK64, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}, 0xbf9fd08c) = 0 unlink("/etc/mtab~1415") = 0 umask(077) = 022 open("/etc/mtab", O_RDONLY|O_LARGEFILE) = 4 umask(022) = 077 fstat64(4, {st_mode=S_IFREG|0644, st_size=306, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb772f000 read(4, "/dev/sda1 / ext4 rw 0 0\nproc /pr"..., 4096) = 306 read(4, "", 4096) = 0 close(4) = 0 munmap(0xb772f000, 4096) = 0 umask(077) = 022 open("/etc/mtab.tmp", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4 umask(022) = 077 fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb772f000 fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 _llseek(4, 0, [0], SEEK_SET) = 0 write(4, "/dev/sda1 / ext4 rw 0 0\n", 24) = 24 fstat64(4, {st_mode=S_IFREG|0600, st_size=24, ...}) = 0 _llseek(4, 24, [24], SEEK_SET) = 0 write(4, "proc /proc proc rw 0 0\n", 23) = 23 fstat64(4, {st_mode=S_IFREG|0600, st_size=47, ...}) = 0 _llseek(4, 47, [47], SEEK_SET) = 0 write(4, "sysfs /sys sysfs rw 0 0\n", 24) = 24 fstat64(4, {st_mode=S_IFREG|0600, st_size=71, ...}) = 0 _llseek(4, 71, [71], SEEK_SET) = 0 write(4, "devpts /dev/pts devpts rw,gid=5,"..., 45) = 45 fstat64(4, {st_mode=S_IFREG|0600, st_size=116, ...}) = 0 _llseek(4, 116, [116], SEEK_SET) = 0 write(4, "tmpfs /dev/shm tmpfs rw 0 0\n", 28) = 28 fstat64(4, {st_mode=S_IFREG|0600, st_size=144, ...}) = 0 _llseek(4, 144, [144], SEEK_SET) = 0 write(4, "none /proc/sys/fs/binfmt_misc bi"..., 49) = 49 fstat64(4, {st_mode=S_IFREG|0600, st_size=193, ...}) = 0 _llseek(4, 193, [193], SEEK_SET) = 0 write(4, "sunrpc /var/lib/nfs/rpc_pipefs r"..., 49) = 49 fstat64(4, {st_mode=S_IFREG|0600, st_size=242, ...}) = 0 _llseek(4, 242, [242], SEEK_SET) = 0 write(4, "/dev/sdb1 /media/android ext4 rw"..., 37) = 37 fstat64(4, {st_mode=S_IFREG|0600, st_size=279, ...}) = 0 _llseek(4, 279, [279], SEEK_SET) = 0 fchmod(4, 0644) = 0 stat64("/etc/mtab", {st_mode=S_IFREG|0644, st_size=306, ...}) = 0 fchown32(4, 0, 0) = 0 write(4, "/dev/sdc1 /mnt ext4 rw 0 0\n", 27) = 27 close(4) = 0 munmap(0xb772f000, 4096) = 0 rename("/etc/mtab.tmp", "/etc/mtab") = 0 close(3) = 0 unlink("/etc/mtab~") = 0 rt_sigprocmask(SIG_UNBLOCK, ~[TRAP SEGV RTMIN RT_1], NULL, 8) = 0 exit_group(0)只说挂载就可以了,remount先忽略,do_new_mount
1669 /* 1670 * create a new mount for userspace and request it to be added into the 1671 * namespace's tree 1672 */ 1673 static int do_new_mount(struct path *path, char *type, int flags, 1674 int mnt_flags, char *name, void *data) 1675 { 1676 struct vfsmount *mnt; 1677 1678 if (!type) 1679 return -EINVAL; 1680 1681 /* we need capabilities... */ 1682 if (!capable(CAP_SYS_ADMIN)) 1683 return -EPERM; 1684 1685 lock_kernel(); 1686 mnt = do_kern_mount(type, flags, name, data); 1687 unlock_kernel(); 1688 if (IS_ERR(mnt)) 1689 return PTR_ERR(mnt); 1690 1691 return do_add_mount(mnt, path, mnt_flags, NULL); 1692 }里面有两个和mount有关的操作一个是do_kern_mount,一个是 do_add_mount,一个是做mount挂载,一个是将mount挂载的fs添加到mount的列表里
先看do_kernel_mount
1079 struct vfsmount * 1080 do_kern_mount(const char *fstype, int flags, const char *name, void *data) 1081 { 1082 struct file_system_type *type = get_fs_type(fstype); 1083 struct vfsmount *mnt; 1084 if (!type) 1085 return ERR_PTR(-ENODEV); 1086 mnt = vfs_kern_mount(type, flags, name, data); 1087 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) && 1088 !mnt->mnt_sb->s_subtype) 1089 mnt = fs_set_subtype(mnt, fstype); 1090 put_filesystem(type); 1091 return mnt; 1092 } 1093 EXPORT_SYMBOL_GPL(do_kern_mount);这里就用到了最开始说的注册的文件系统,通过get_fs_type来查找是否支持fstype类型的文件系统,例如ext4支持的话就把前面注册的结构返回到这里,以后使用的type都是ext4_fs_type,例如vfs_kern_mount里面传递进去的type,就是ext4_fs_type了,
进入到vfs_kern_mount里面看一下,里面肯定会调到get_sb,
899 struct vfsmount * 900 vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) 901 { 902 struct vfsmount *mnt; 903 char *secdata = NULL; 904 int error; 905 906 if (!type) 907 return ERR_PTR(-ENODEV); 908 909 error = -ENOMEM; 910 mnt = alloc_vfsmnt(name); 911 if (!mnt) 912 goto out; 913 914 if (flags & MS_KERNMOUNT) 915 mnt->mnt_flags = MNT_INTERNAL; 916 917 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { 918 secdata = alloc_secdata(); 919 if (!secdata) 920 goto out_mnt; 921 922 error = security_sb_copy_data(data, secdata); 923 if (error) 924 goto out_free_secdata; 925 } 926*************************在这呢,这里的get_sb就是fs/ext4/super.c里面的ext4_get_sb*********************************** 927 error = type->get_sb(type, flags, name, data, mnt); 928 if (error < 0) 929 goto out_free_secdata; 930 BUG_ON(!mnt->mnt_sb); 931 WARN_ON(!mnt->mnt_sb->s_bdi); 932 mnt->mnt_sb->s_flags |= MS_BORN; 933 934 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); 935 if (error) 936 goto out_sb; 937 938 /* 939 * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE 940 * but s_maxbytes was an unsigned long long for many releases. Throw 941 * this warning for a little while to try and catch filesystems that 942 * violate this rule. This warning should be either removed or 943 * converted to a BUG() in 2.6.34. 944 */ 945 WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " 946 "negative value (%lld)\n", type->name, mnt->mnt_sb->s_maxbytes); 947 948 mnt->mnt_mountpoint = mnt->mnt_root; 949 mnt->mnt_parent = mnt; 950 up_write(&mnt->mnt_sb->s_umount); 951 free_secdata(secdata); 952 return mnt; 953 out_sb: 954 dput(mnt->mnt_root); 955 deactivate_locked_super(mnt->mnt_sb); 956 out_free_secdata: 957 free_secdata(secdata); 958 out_mnt: 959 free_vfsmnt(mnt); 960 out: 961 return ERR_PTR(error); 962 } 963 964 EXPORT_SYMBOL_GPL(vfs_kern_mount);接下来就要进入到ext4系统里面看一下get_sb做了什么
4232 static int ext4_get_sb(struct file_system_type *fs_type, int flags, 4233 const char *dev_name, void *data, struct vfsmount *mnt) 4234 { 4235 return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); 4236 }这里面一共调用了两个接口get_sb_bdev和ext4_fill_super,一个文件系统的细节部分都在ext4_fill_super里面去做
get_sb_bdev里面会用到ext4_fill_super,因为要注册一下里面的细节,比如创建节点,文件,目录,链接,读文件,读目录,写文件,写目录,删除文件,很多很多。
后面涉及到了对块设备操作的很多工作,文件系统最关键的就是管理文件,并且是块设备上的,这个块设备就是在get_sb_bdev里面得到的
747 int get_sb_bdev(struct file_system_type *fs_type, 748 int flags, const char *dev_name, void *data, 749 int (*fill_super)(struct super_block *, void *, int), 750 struct vfsmount *mnt) 751 { 752 struct block_device *bdev; 753 struct super_block *s; 754 fmode_t mode = FMODE_READ; 755 int error = 0; 756 757 if (!(flags & MS_RDONLY)) 758 mode |= FMODE_WRITE; 759 760 bdev = open_bdev_exclusive(dev_name, mode, fs_type); 761 if (IS_ERR(bdev)) 762 return PTR_ERR(bdev); …… 799 800 s->s_flags = flags; 801 s->s_mode = mode; 802 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); 803 sb_set_blocksize(s, block_size(bdev)); 804 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 805 if (error) { 806 deactivate_locked_super(s); 807 goto error; 808 } 809 810 s->s_flags |= MS_ACTIVE; 811 bdev->bd_super = s; 812 } 813 814 simple_set_mnt(mnt, s); 815 return 0; ……通过这个open_bdev_exclusive拿到设备文件后进入到了error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
就这样,对磁盘文件操作就了解了
通过这个fill_super来进行读读块设备
2545 static int ext4_fill_super(struct super_block *sb, void *data, int silent) 2546 __releases(kernel_lock) 2547 __acquires(kernel_lock) 2548 { 2549 char *orig_data = kstrdup(data, GFP_KERNEL); 2550 struct buffer_head *bh; 2551 struct ext4_super_block *es = NULL; 2552 struct ext4_sb_info *sbi; 2553 ext4_fsblk_t block; 2554 ext4_fsblk_t sb_block = get_sb_block(&data); 2555 ext4_fsblk_t logical_sb_block; 2556 unsigned long offset = 0; …… 2580 } 2581 sb->s_fs_info = sbi; 2582 sbi->s_mount_opt = 0; 2583 sbi->s_resuid = EXT4_DEF_RESUID; 2584 sbi->s_resgid = EXT4_DEF_RESGID; 2585 sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS; 2586 sbi->s_sb_block = sb_block; 2587 if (sb->s_bdev->bd_part) 2588 sbi->s_sectors_written_start = 2589 part_stat_read(sb->s_bdev->bd_part, sectors[1]); 2590 2591 unlock_kernel(); 2592 2593 /* Cleanup superblock name */ 2594 for (cp = sb->s_id; (cp = strchr(cp, '/'));) 2595 *cp = '!'; 2596 2597 ret = -EINVAL; 2598 blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); 2599 if (!blocksize) { 2600 ext4_msg(sb, KERN_ERR, "unable to set blocksize"); 2601 goto out_fail; 2602 } 2603 2604 /* 2605 * The ext4 superblock will not be buffer aligned for other than 1kB 2606 * block sizes. We need to calculate the offset from buffer start. 2607 */ 2608 if (blocksize != EXT4_MIN_BLOCK_SIZE) { 2609 logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; 2610 offset = do_div(logical_sb_block, blocksize); 2611 } else { 2612 logical_sb_block = sb_block; 2613 } 2614 2615 if (!(bh = sb_bread(sb, logical_sb_block))) { 2616 ext4_msg(sb, KERN_ERR, "unable to read superblock"); 2617 goto out_fail; 2618 } …… 2649 if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) 2650 set_opt(sbi->s_mount_opt, JOURNAL_DATA); 2651 else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) 2652 set_opt(sbi->s_mount_opt, ORDERED_DATA); 2653 else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) 2654 set_opt(sbi->s_mount_opt, WRITEBACK_DATA); 2655 2656 if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) 2657 set_opt(sbi->s_mount_opt, ERRORS_PANIC); 2658 else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_CONTINUE) 2659 set_opt(sbi->s_mount_opt, ERRORS_CONT); 2660 else 2661 set_opt(sbi->s_mount_opt, ERRORS_RO); 2662 if (def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY) 2663 set_opt(sbi->s_mount_opt, BLOCK_VALIDITY); 2664 if (def_mount_opts & EXT4_DEFM_DISCARD) 2665 set_opt(sbi->s_mount_opt, DISCARD); …… 2931 * set up enough so that it can read an inode 2932 */ 2933 if (!test_opt(sb, NOLOAD) && 2934 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) 2935 sb->s_op = &ext4_sops; 2936 else 2937 sb->s_op = &ext4_nojournal_sops; 2938 sb->s_export_op = &ext4_export_ops; 2939 sb->s_xattr = ext4_xattr_handlers; 2940 #ifdef CONFIG_QUOTA 2941 sb->s_qcop = &ext4_qctl_operations; 2942 sb->dq_op = &ext4_quota_operations; 2943 #endif …… 3052 root = ext4_iget(sb, EXT4_ROOT_INO); 3053 if (IS_ERR(root)) { 3054 ext4_msg(sb, KERN_ERR, "get root inode failed"); 3055 ret = PTR_ERR(root); 3056 goto failed_mount4; 3057 } 3058 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { 3059 iput(root); 3060 ext4_msg(sb, KERN_ERR, "corrupt root inode, run e2fsck"); 3061 goto failed_mount4; 3062 } 3063 sb->s_root = d_alloc_root(root); 3064 if (!sb->s_root) { 3065 ext4_msg(sb, KERN_ERR, "get root dentry failed"); 3066 iput(root); 3067 ret = -ENOMEM; 3068 goto failed_mount4; 3069 } 3070 3071 ext4_setup_super(sb, es, sb->s_flags & MS_RDONLY); 3072这些介绍了从读超级快,获得磁盘的块的属性,然后进行了sops注册,然后进入ext4_iget进行了文件操作,目录操作,链接操作等函数的注册,比如读文件
然后回到do_new_mount,将挂载点添加到列表里就可以了,这个列表在/proc中可以展现出来
[root@T-bagwell ~]# cat /proc/mounts rootfs / rootfs rw 0 0 /dev/root / ext4 rw,relatime,barrier=1,data=ordered 0 0 /dev /dev tmpfs rw,relatime,mode=755 0 0 /proc /proc proc rw,relatime 0 0 /sys /sys sysfs rw,relatime 0 0 /proc/bus/usb /proc/bus/usb usbfs rw,relatime 0 0 devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0 none /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0 sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0 /dev/sdb1 /media/android ext4 rw,relatime,barrier=1,data=ordered 0 0 [root@T-bagwell ~]#到这里文件系统的注册和磁盘的挂载完成
T-Bagwell 说
:em06::em06::em06:
其实我就是把过程写一下,希望大伙能指点一下
Godbach 说
T-Bag兄顺便说一下内核版本
cambyzju 说
不是说了2.6.35么
T-Bagwell 说
差点误认子弟,刚刚交流了一下,一般情况下是修改sb的
比如mount的时候修改时间撮一类的属性
下面是在irc里面mason说的
<mason> usually when we mount, we update those counters and timestamps and write the new result back to disk
nkmxl 说
好文章 EXT4听话很稳定啊。
相关文章推荐
- Dalvik虚拟机JNI方法的注册过程分析
- 【转】网卡驱动注册到PCI总线这一过程的分析
- 我在unpack 中写的一些技术文章集合,这些是对一些软件的注册过程进行分析的(比较简单)
- mount 挂载原理及过程分析
- dubbo作为消费者注册过程分析
- Android服务注册完整过程源码分析
- 广播注册过程分析
- Dalvik虚拟机JNI方法的注册过程分析
- Android Binder机制(2) ContextManager注册过程分析
- curl源码分析(二)协议注册与使用过程
- platform_device和platform_driver的注册过程,及probe函数何时调用的分析
- 深入理解SpringCloud之Eureka注册过程分析
- 今天我以fb设备的注册过程来分析platform设备的添加流程
- Android Dalvik虚拟机JNI方法的注册过程分析
- Android应用程序注册广播接收器(registerReceiver)的过程分析
- Android4.4 Framework分析——广播的注册(BroadcastReceiver)和发送(sendbroadcast)过程分析
- Android4.4 Camera callback注册和回调过程分析
- Netty 源码分析(三):服务器端的初始化和注册过程
- Dalvik虚拟机JNI方法的注册过程分析
- PCI设备的注册过程分析1