您的位置:首页 > 其它

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

2012-01-04 19:51 399 查看
http://www.vrlinux.com/naheyuanma/20100813/73134.html

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

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听话很稳定啊。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: