现在的位置: 首页 > 综合 > 正文

文件系统注册及mount过程分析

2014年10月10日 ⁄ 综合 ⁄ 共 30125字 ⁄ 字号 评论关闭

http://www.vrlinux.com/naheyuanma/20100813/73134.html

小弟是个菜鸟,如果写得有错误的地方,请不吝赐教

kernel version: 2.6.35
从ext4文件的init开始分析一下,暂时先不去看cache的使用[code]  register_as_ext2();
    register_as_ext3();
    err = register_filesystem(&ext4_fs_type);[/code]可以看出来注册了ext2,ext3,ext4
看一下注册的过程[code]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);
[/code]在这里面调用了find_filesystem,先找一下看看是不是有同样的文件系统类型被使用了,这个就像银行卡号一样,不能重复,否则会出现自己存的钱被另一个人取走的可能,如果存在了文件系统就返回错误,如果没有存在就添加到支持的文件系统的列表里面,开始支持注册的文件系统,比如ext4
注册的ext4的文件系统的类型结构,这个在do_kernel_mount的时候会通过这个的name来查找fstype[code]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,
};[/code]这里的ext4_get_sb是在do_kern_mount的时候调用到的,走一下流程[code]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 }
[/code]系统调用的mount,会走到这里,然后进入do_mount接口里面进行mount操作[code]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 }[/code]通过kern_path来获得挂载点&path
然后通过传递的flag来判断挂载操作, 这些flag可以在man 2 mount中看到说明,这个与mount命令有区别,mount命令要在应用程序里面做很多[code][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)                           = ?
[/code][code]

[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)      [/code]只说挂载就可以了,remount先忽略,do_new_mount[code]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 }
[/code]里面有两个和mount有关的操作一个是do_kern_mount,一个是 do_add_mount,一个是做mount挂载,一个是将mount挂载的fs添加到mount的列表里

先看do_kernel_mount[code]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);
[/code]这里就用到了最开始说的注册的文件系统,通过get_fs_type来查找是否支持fstype类型的文件系统,例如ext4支持的话就把前面注册的结构返回到这里,以后使用的type都是ext4_fs_type,例如vfs_kern_mount里面传递进去的type,就是ext4_fs_type了,
进入到vfs_kern_mount里面看一下,里面肯定会调到get_sb,[code]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);[/code]接下来就要进入到ext4系统里面看一下get_sb做了什么[code]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 }[/code]这里面一共调用了两个接口get_sb_bdev和ext4_fill_super,一个文件系统的细节部分都在ext4_fill_super里面去做
get_sb_bdev里面会用到ext4_fill_super,因为要注册一下里面的细节,比如创建节点,文件,目录,链接,读文件,读目录,写文件,写目录,删除文件,很多很多。
后面涉及到了对块设备操作的很多工作,文件系统最关键的就是管理文件,并且是块设备上的,这个块设备就是在get_sb_bdev里面得到的[code] 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;
……[/code]通过这个open_bdev_exclusive拿到设备文件后进入到了error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
就这样,对磁盘文件操作就了解了
通过这个fill_super来进行读读块设备[code]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[/code]这些介绍了从读超级快,获得磁盘的块的属性,然后进行了sops注册,然后进入ext4_iget进行了文件操作,目录操作,链接操作等函数的注册,比如读文件

然后回到do_new_mount,将挂载点添加到列表里就可以了,这个列表在/proc中可以展现出来[code][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 ~]#[/code]到这里文件系统的注册和磁盘的挂载完成

 

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听话很稳定啊。

抱歉!评论已关闭.