Skip to content

Latest commit

 

History

History
1156 lines (957 loc) · 30.4 KB

a10c_144.md

File metadata and controls

1156 lines (957 loc) · 30.4 KB
KernelStudy : 144 주차
일시 : 2016.05.21 (144주차 스터디 진행)
모임명 : KernelStudy_ARM
장소 : 토즈 서현점
장소지원 : 공개 소프트웨어 개발자 커뮤니티 지원 프로그램
참여인원 : 2명

============

144주차 진도

  • ᇂ144차 시작 위치
  • start_kernel 1 ~/init/main.c
  • vfs_caches_init 925 ~/init/main.c
  • mnt_init 3809 ~/fs/dcache.c
  • init_mount_tree 5266 ~/fs/namespace.c
  • create_mnt_ns 5194 ns = create_mnt_ns(mnt);
  • real_mount 4536 struct mount *mnt = real_mount(m);

144주차 함수 호출 구조

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): shmem_mount() 호출
  • call: shmem_mount()
  • mount_nodev()
  • call: mount_nodev()
  • sget()
  • IS_ERR()
  • fill_super(): shmem_fill_super()

main.c::start_kernel()

  • call: start_kernel()->vfs_caches_init()
asmlinkage void __init start_kernel(void)
{
	char * command_line;
	extern const struct kernel_param __start___param[], __stop___param[];
	// ATAG,DTB 정보로 사용

...

    proc_caches_init();
	// sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
	// 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행

	buffer_init();
	// buffer_head 를 사용하기 위한 kmem_cache 할당자 및 max_buffer_heads 값 초기화 수행

	key_init(); // null funtion
	security_init(); // null funtion
	dbg_late_init(); // null funtion

	// totalram_pages: 총 free된 page 수
	vfs_caches_init(totalram_pages);

dcache.c::vfs_caches_init()

  • call: start_kernel()
  • vfs_caches_init()
    • kmem_cache_create(): names_cache
    • dcache_init()
    • inode_init()
    • files_init()
    • mnt_init()
// ARM10C 20151003
// totalram_pages: 총 free된 page 수
void __init vfs_caches_init(unsigned long mempages)
{
	unsigned long reserve;

	/* Base hash sizes on available memory, with a reserve equal to
           150% of current kernel size */

	// NOTE:
	// mempages 값과 nr_free_pages() 의 값을 정확히 알 수 없음
	// 계산된 reserve의 값을 XXX 로 함

	// mempages: 총 free된 page 수, nr_free_pages(): 현재의 free pages 수
	reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
	// reserve: XXX

	// mempages: 총 free된 page 수, reserve: XXX
	mempages -= reserve;
	// mempages: 총 free된 page 수 - XXX

	// PATH_MAX: 4096
	// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
	names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
			SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
	// names_cachep: kmem_cache#6

	dcache_init();

	inode_init();

	// mempages: 총 free된 page 수 - XXX
	files_init(mempages);

	mnt_init();

namespace.c::mnt_init()

  • call: start_kernel()

    • vfs_caches_init()
  • call: vfs_caches_init()

    • kmem_cache_create(): names_cache
    • dcache_init()
    • inode_init()
    • files_init()
    • mnt_init()
// ARM10C 20151024
void __init mnt_init(void)
{
	unsigned u;
	int err;
	// sizeof(struct mount): 152 bytes, SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
	// kmem_cache_create("mnt_cache", 152, 0, 0x42000, NULL): kmem_cache#2
	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
	// mnt_cache: kmem_cache#2

	// sizeof(struct hlist_head): 4 bytes, mhash_entries: 0
	// alloc_large_system_hash("Mount-cache", 4, 0, 19, 0, &m_hash_shift, &m_hash_mask, 0, 0): 16kB만큼 할당받은 메모리 주소
	mount_hashtable = alloc_large_system_hash("Mount-cache",
				sizeof(struct hlist_head),
				mhash_entries, 19,
				0,
				&m_hash_shift, &m_hash_mask, 0, 0);
	// mount_hashtable: 16kB만큼 할당받은 메모리 주소

	// sizeof(struct hlist_head): 4 bytes, mphash_entries: 0
	// alloc_large_system_hash("Mountpoint-cache", 4, 0, 19, 0, &m_hash_shift, &m_hash_mask, 0, 0): 16kB만큼 할당받은 메모리 주소
	mountpoint_hashtable = alloc_large_system_hash("Mountpoint-cache",
				sizeof(struct hlist_head),
				mphash_entries, 19,
				0,
				&mp_hash_shift, &mp_hash_mask, 0, 0);
	// mountpoint_hashtable: 16kB만큼 할당받은 메모리 주소

	// mount_hashtable: 16kB만큼 할당받은 메모리 주소, mountpoint_hashtable: 16kB만큼 할당받은 메모리 주소
	if (!mount_hashtable || !mountpoint_hashtable)
		panic("Failed to allocate mount hash table\n");

	// m_hash_mask: 0xFFF
	for (u = 0; u <= m_hash_mask; u++)
		// u: 0
		INIT_HLIST_HEAD(&mount_hashtable[u]);

		// INIT_HLIST_HEAD 에서 한일:
		// ((&mount_hashtable[0])->first = NULL)

		// u: 1...4095 까지 loop 수행

	// mp_hash_mask: 0xFFF
	for (u = 0; u <= mp_hash_mask; u++)
		// u: 0
		INIT_HLIST_HEAD(&mountpoint_hashtable[u]);

		// INIT_HLIST_HEAD 에서 한일:
		// ((&mountpoint_hashtable[0])->first = NULL)

		// u: 1...4095 까지 loop 수행

	// sysfs_init(): 0
	err = sysfs_init();
	// err: 0

	// err: 0
	if (err)
		printk(KERN_WARNING "%s: sysfs_init error: %d\n",
			__func__, err);

	// kobject_create_and_add("fs", NULL): kmem_cache#30-oX (struct kobject)
	fs_kobj = kobject_create_and_add("fs", NULL);
	// fs_kobj: kmem_cache#30-oX (struct kobject)

	// fs_kobj: kmem_cache#30-oX (struct kobject)
	if (!fs_kobj)
		printk(KERN_WARNING "%s: kobj create error\n", __func__);

	init_rootfs();

    init_mount_tree();

namespace.c::init_mount_tree()

  • call: start_kernel()
  • vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()
    • kmem_cache_create()
    • alloc_large_system_hash() : mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
// ARM10C 20160326
static void __init init_mount_tree(void)
{
	struct vfsmount *mnt;
	struct mnt_namespace *ns;
	struct path root;
	struct file_system_type *type;

	// get_fs_type("rootfs"): &rootfs_fs_type
	type = get_fs_type("rootfs");
	// type: &rootfs_fs_type

	// get_fs_type 에서 한일:
	// "rootfs" 으로 등록된 &rootfs_fs_type 을 찾음

	// type: &rootfs_fs_type
	if (!type)
		panic("Can't find rootfs type");

	// type: &rootfs_fs_type
	mnt = vfs_kern_mount(type, 0, "rootfs", NULL);

super.c::mount_fs()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()
    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
// ARM10C 20160409
// type: &rootfs_fs_type, 0, "rootfs", NULL
struct vfsmount *
vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
{
	struct mount *mnt;
	struct dentry *root;

	// type: &rootfs_fs_type
	if (!type)
		return ERR_PTR(-ENODEV);

	// name: "rootfs", alloc_vfsmnt("rootfs"): kmem_cache#2-oX (struct mount)
	mnt = alloc_vfsmnt(name);
	// mnt: kmem_cache#2-oX (struct mount)

	// flags: 0, MS_KERNMOUNT: 0x400000
	if (flags & MS_KERNMOUNT)
		// mnt->mnt.mnt_flags: (kmem_cache#2-oX (struct mount))->mnt.mnt_flags, MNT_INTERNAL: 0x4000
		mnt->mnt.mnt_flags = MNT_INTERNAL;
		// mnt->mnt.mnt_flags: (kmem_cache#2-oX (struct mount))->mnt.mnt_flags: 0x4000

	// type: &rootfs_fs_type, flags: 0, name: "rootfs", data: NULL
	// mount_fs(&rootfs_fs_type, 0, "rootfs", NULL): kmem_cache#5-oX (struct dentry)
	root = mount_fs(type, flags, name, data);

super.c::mount_fs()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type
// ARM10C 20160416
// type: &rootfs_fs_type, flags: 0, name: "rootfs", data: NULL
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
	struct dentry *root;
	struct super_block *sb;
	char *secdata = NULL;
	// secdata: NULL

	// ENOMEM: 12
	int error = -ENOMEM;
	// error: -12

	// data: NULL, type->fs_flags: (&rootfs_fs_type)->fs_flags: 0, FS_BINARY_MOUNTDATA: 2
	if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
		secdata = alloc_secdata();
		if (!secdata)
			goto out;

		error = security_sb_copy_data(data, secdata);
		if (error)
			goto out_free_secdata;
	}

	// type->mount: (&rootfs_fs_type)->mount: rootfs_mount
	// type: &rootfs_fs_type, flags: 0, name: "rootfs", data: NULL
	// rootfs_mount(&rootfs_fs_type, 0, "rootfs", NULL):
	root = type->mount(type, flags, name, data);

do_mounts.c::rootfs_mount()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출

rootfs_fs_type 구조체에 .mount는 rootfs_mount 로 정의했다. 따라서 rootfs_mount() 함수를 호출한다.

// ARM10C 20160402
static struct file_system_type rootfs_fs_type = {
	.name		= "rootfs",
	.mount		= rootfs_mount,
	.kill_sb	= kill_litter_super,
};

do_mounts.c::rootfs_mount()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출
// ARM10C 20160416
// type: &rootfs_fs_type, flags: 0, name: "rootfs", data: NULL
static struct dentry *rootfs_mount(struct file_system_type *fs_type,
	int flags, const char *dev_name, void *data)
{
	static unsigned long once;
	void *fill = ramfs_fill_super;
	// fill: ramfs_fill_super

	// once: 0, test_and_set_bit(0, &once): 0
	if (test_and_set_bit(0, &once))
		return ERR_PTR(-ENODEV);

	// test_and_set_bit 에서 한일:
	// once: 1

	// CONFIG_TMPFS=y, IS_ENABLED(CONFIG_TMPFS): 1, is_tmpfs: 1
	if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
		// fill: ramfs_fill_super
		fill = shmem_fill_super;
		// fill: shmem_fill_super

	// fs_type: &rootfs_fs_type, flags: 0, data: NULL, fill: shmem_fill_super
	return mount_nodev(fs_type, flags, data, fill);
}

mount_nodev()를 실행후 mount_fs()로 돌아간다.

super.c::mount_nodev()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출
  • call: rootfs_mount()
  • test_and_set_bit()
  • IS_ENABLED()
  • mount_nodev(): rootfs_fs_type
// ARM10C 20160416
// fs_type: &rootfs_fs_type, flags: 0, data: NULL, fill: shmem_fill_super
struct dentry *mount_nodev(struct file_system_type *fs_type,
	int flags, void *data,
	int (*fill_super)(struct super_block *, void *, int))
{
	int error;

	// fs_type: &rootfs_fs_type, flags: 0
	// sget(&rootfs_fs_type, NULL, set_anon_super, 0, NULL): kmem_cache#25-oX (struct super_block)
	struct super_block *s = sget(fs_type, NULL, set_anon_super, flags, NULL);
	// s: kmem_cache#25-oX (struct super_block)

	// s: kmem_cache#25-oX (struct super_block), IS_ERR(kmem_cache#25-oX (struct super_block)): 0
	if (IS_ERR(s))
		return ERR_CAST(s);

	// s: kmem_cache#25-oX (struct super_block), data: NULL, flags: 0, MS_SILENT: 0x8000
	error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);

inode.c::fill_super()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출
  • call: rootfs_mount()
  • test_and_set_bit()
  • IS_ENABLED()
  • mount_nodev(): rootfs_fs_type
  • call: mount_nodev(): rootfs_fs_type
  • sget()
  • fill_super()
// ARM10C 20160319
// s: kmem_cache#25-oX (struct super_block), data: NULL, 0
static int fill_super(struct super_block *sb, void *data, int silent)
{
	static struct tree_descr files[] = {{""}};
	// files[0].name: "", files[0].ops: NULL, files[0].mode: 0

	// sb: kmem_cache#25-oX (struct super_block), SECURITYFS_MAGIC: 0x73636673
	// simple_fill_super(kmem_cache#25-oX (struct super_block), 0x73636673, files): 0
	return simple_fill_super(sb, SECURITYFS_MAGIC, files);
}

simple_fill_super()를 호출하고 그 결과를 mount_nodev()로 반환한다.

libfs.c::simple_fill_super()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출
  • call: rootfs_mount()
  • test_and_set_bit()
  • IS_ENABLED()
  • mount_nodev(): rootfs_fs_type
  • call: mount_nodev(): rootfs_fs_type
  • sget()
  • fill_super()
  • call: fill_super()
  • simple_fill_super()
// ARM10C 20160319
// sb: kmem_cache#25-oX (struct super_block), SECURITYFS_MAGIC: 0x73636673, files
int simple_fill_super(struct super_block *s, unsigned long magic,
		      struct tree_descr *files)
{
	struct inode *inode;
	struct dentry *root;
	struct dentry *dentry;
	int i;

	// s->s_blocksize: (kmem_cache#25-oX (struct super_block))->s_blocksize, PAGE_CACHE_SIZE: 0x1000
	s->s_blocksize = PAGE_CACHE_SIZE;
	// s->s_blocksize: (kmem_cache#25-oX (struct super_block))->s_blocksize: 0x1000

	// s->s_blocksize_bits: (kmem_cache#25-oX (struct super_block))->s_blocksize_bits, PAGE_CACHE_SHIFT: 12
	s->s_blocksize_bits = PAGE_CACHE_SHIFT;
	// s->s_blocksize_bits: (kmem_cache#25-oX (struct super_block))->s_blocksize_bits: 12

	// s->s_magic: (kmem_cache#25-oX (struct super_block))->s_magic, magic: 0x73636673
	s->s_magic = magic;
	// s->s_magic: (kmem_cache#25-oX (struct super_block))->s_magic: 0x73636673

	// s->s_op: (kmem_cache#25-oX (struct super_block))->s_op
	s->s_op = &simple_super_operations;
	// s->s_op: (kmem_cache#25-oX (struct super_block))->s_op: &simple_super_operations

	// s->s_time_gran: (kmem_cache#25-oX (struct super_block))->s_time_gran
	s->s_time_gran = 1;
	// s->s_time_gran: (kmem_cache#25-oX (struct super_block))->s_time_gran: 1

	// s: kmem_cache#25-oX (struct super_block),
	// new_inode(kmem_cache#25-oX (struct super_block)): kmem_cache#4-oX (struct inode)
	inode = new_inode(s);
	// inode: kmem_cache#4-oX (struct inode)
static int shmem_initxattrs(struct inode *inode,
			    const struct xattr *xattr_array,
			    void *fs_info)
{
	struct shmem_inode_info *info = SHMEM_I(inode);
	const struct xattr *xattr;
	struct simple_xattr *new_xattr;
	size_t len;

	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
		new_xattr = simple_xattr_alloc(xattr->value, xattr->value_len);
		if (!new_xattr)
			return -ENOMEM;

		len = strlen(xattr->name) + 1;
		new_xattr->name = kmalloc(XATTR_SECURITY_PREFIX_LEN + len,
					  GFP_KERNEL);
		if (!new_xattr->name) {
			kfree(new_xattr);
			return -ENOMEM;
		}

		memcpy(new_xattr->name, XATTR_SECURITY_PREFIX,
		       XATTR_SECURITY_PREFIX_LEN);
		memcpy(new_xattr->name + XATTR_SECURITY_PREFIX_LEN,
		       xattr->name, len);

		simple_xattr_list_add(&info->xattrs, new_xattr);

dcahce.c::dget()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출
  • call: rootfs_mount()
  • test_and_set_bit()
  • IS_ENABLED()
  • mount_nodev(): rootfs_fs_type
  • call: mount_nodev(): rootfs_fs_type
  • sget()
  • fill_super()
  • shmem_fill_super()
  • dget()
// ARM10C 20160319
// s->s_root: (kmem_cache#25-oX (struct super_block))->s_root: kmem_cache#5-oX (struct dentry)
static inline struct dentry *dget(struct dentry *dentry)
{
	// dentry: kmem_cache#5-oX (struct dentry)
	if (dentry)
		// &dentry->d_lockref: &(kmem_cache#5-oX (struct dentry))->d_lockref
		lockref_get(&dentry->d_lockref);

		// lockref_get에서 한일:
		// (&(kmem_cache#5-oX (struct dentry))->d_lockref)->count: 1

	// dentry: kmem_cache#5-oX (struct dentry)
	return dentry;
	// return kmem_cache#5-oX (struct dentry)
}

super.c::mount_nodev()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출

super.c::mount.c

// ARM10C 20160416
// type: &rootfs_fs_type, flags: 0, name: "rootfs", data: NULL
struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{
	struct dentry *root;
	struct super_block *sb;
	char *secdata = NULL;
	// secdata: NULL
	// secdata: NULL
	// secdata: NULL

	// ENOMEM: 12
	// ENOMEM: 12
	// ENOMEM: 12
	int error = -ENOMEM;
	// error: -12
	// error: -12
	// error: -12

	// data: NULL, type->fs_flags: (&sysfs_fs_type)->fs_flags: 8, FS_BINARY_MOUNTDATA: 2
	// data: NULL, type->fs_flags: (&shmem_fs_type)->fs_flags: 8, FS_BINARY_MOUNTDATA: 2
	// data: NULL, type->fs_flags: (&rootfs_fs_type)->fs_flags: 0, FS_BINARY_MOUNTDATA: 2
	if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
		secdata = alloc_secdata();
		if (!secdata)
			goto out;

		error = security_sb_copy_data(data, secdata);
		if (error)
			goto out_free_secdata;
	}

	// type->mount: (&sysfs_fs_type)->mount: sysfs_mount
	// type: &sysfs_fs_type, flags: 0x400000, name: "sysfs", data: NULL
	// sysfs_mount(&sysfs_fs_type, 0x400000, "sysfs", NULL): kmem_cache#5-oX (struct dentry)
	// type->mount: (&shmem_fs_type)->mount: shmem_mount
	// type: &shmem_fs_type, flags: 0x400000, name: "tmpfs", data: NULL
	// shmem_mount(&shmem_fs_type, 0x400000, "tmpfs", NULL): kmem_cache#5-oX (struct dentry)
	//
	// type->mount: (&rootfs_fs_type)->mount: rootfs_mount
	// type: &rootfs_fs_type, flags: 0, name: "rootfs", data: NULL
	// rootfs_mount(&rootfs_fs_type, 0, "rootfs", NULL):
	root = type->mount(type, flags, name, data);
	// root: kmem_cache#5-oX (struct dentry)
	// root: kmem_cache#5-oX (struct dentry)

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • call: vfs_kern_mount(): rootfs_fs_type
  • alloc_vfsmnt()
  • mount_fs(): rootfs_fs_type -> rootfs_mount() 호출

namespace.c::init_mount_tree()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
// ARM10C 20160326
static void __init init_mount_tree(void)
{
	struct vfsmount *mnt;
	struct mnt_namespace *ns;
	struct path root;
	struct file_system_type *type;

	// get_fs_type("rootfs"): &rootfs_fs_type
	type = get_fs_type("rootfs");
	// type: &rootfs_fs_type

	// get_fs_type 에서 한일:
	// "rootfs" 으로 등록된 &rootfs_fs_type 을 찾음

	// type: &rootfs_fs_type
	if (!type)
		panic("Can't find rootfs type");

	// type: &rootfs_fs_type
	mnt = vfs_kern_mount(type, 0, "rootfs", NULL);

namespace.c::init_mount_tree()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • put_filesystem()
  • call: put_filesystem()
void put_filesystem(struct file_system_type *fs)
{
	module_put(fs->owner);
}
static inline void module_put(struct module *module)
{
}

namespace.c::init_mount_tree()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • put_filesystem()
  • IS_ERR()
  • create_mnt_ns()
static struct mnt_namespace *create_mnt_ns(struct vfsmount *m)
{
	struct mnt_namespace *new_ns = alloc_mnt_ns(&init_user_ns);
	if (!IS_ERR(new_ns)) {
		struct mount *mnt = real_mount(m);
		mnt->mnt_ns = new_ns;
		new_ns->root = mnt;
		list_add(&mnt->mnt_list, &new_ns->list);
	} else {
		mntput(m);
	}
	return new_ns;
}
  • call: alloc_mnt_ns()

namespace.c::alloc_mnt_ns()

  • calll: start_kernel()-> vfs_caches_init()
  • kmem_cache_create(): names_cache
  • dcache_init()
  • inode_init()
  • files_init()
  • mnt_init()
  • call: mnt_init()

    • kmem_cache_create(): mnt_cache
    • alloc_large_system_hash() : Mount-cache
    • alloc_large_system_hash() : Mountpoint-cache
    • INIT_HLIST_HEAD() : &mount_hashtable[u]
    • INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
    • sysfs_init()
    • kobject_create_and_add() : fs
    • init_rootfs()
    • init_mount_tree()
  • call: init_mount_tree()

  • get_fs_type(): rootfs 3994 ~/fs/namespace.c
  • vfs_kern_mount(): rootfs_fs_type
  • put_filesystem()
  • IS_ERR()
  • create_mnt_ns()
static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
{
	struct mnt_namespace *new_ns;
	int ret;

	new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
  • kmalloc(): mnt_namespace
    • stuct mnt_namespace
    • size: 60 bytes
// ARM10C 20160326
struct mnt_namespace {
	atomic_t		count;
	unsigned int		proc_inum;
	struct mount *	root;
	struct list_head	list;
	struct user_namespace	*user_ns;
	u64			seq;	/* Sequence number to prevent loops */
	wait_queue_head_t poll;
	int event;
};
static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
{
	struct mnt_namespace *new_ns;
	int ret;

	new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
	if (!new_ns)
		return ERR_PTR(-ENOMEM);
	ret = proc_alloc_inum(&new_ns->proc_inum);
	if (ret) {
		kfree(new_ns);
		return ERR_PTR(ret);
	}
	new_ns->seq = atomic64_add_return(1, &mnt_ns_seq);
	atomic_set(&new_ns->count, 1);
	new_ns->root = NULL;
	INIT_LIST_HEAD(&new_ns->list);
	init_waitqueue_head(&new_ns->poll);
	new_ns->event = 0;
	new_ns->user_ns = get_user_ns(user_ns);
	return new_ns;
}

libfs.c::mount_pseudo()

// ARM10C 20151212
// #define QSTR_INIT("/", 1):
// { { { .len = 1 } }, .name = "/" }
#define QSTR_INIT(n,l) { { { .len = l } }, .name = n }
struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
	const struct super_operations *ops,
	const struct dentry_operations *dops, unsigned long magic)
{
	struct super_block *s;
	struct dentry *dentry;
	struct inode *root;
	struct qstr d_name = QSTR_INIT(name, strlen(name));

	s = sget(fs_type, NULL, set_anon_super, MS_NOUSER, NULL);

log

  • ᆼᇂᆫ1st log
2c4afa3..51b1191  master     -> origin/master
Updating 2c4afa3..51b1191
Fast-forward
arch/arm/include/asm/atomic.h |    4 +
fs/dcache.c                   | 1827 ++++++++++++++++++++++++++++++++++++++++
fs/fs_struct.c                |   82 ++
fs/mount.h                    |    9 +
fs/namei.c                    |   13 +
fs/namespace.c                |  592 ++++++++++++-
include/asm-generic/current.h |    1 +
include/linux/dcache.h        |    2 +
include/linux/err.h           |    2 +
include/linux/fs_struct.h     |    1 +
include/linux/list.h          |    2 +
include/linux/path.h          |    1 +
include/linux/percpu.h        |   29 +
include/linux/seqlock.h       |    8 +
include/linux/spinlock.h      |    8 +
init/init_task.c              |    1 +
kernel/nsproxy.c              |    5 +-
17 files changed, 2584 insertions(+), 3 deletions(-)
51b1191..2518303  master     -> origin/master
Updating 51b1191..2518303
Fast-forward
README.md                   |   16 +
arch/arm/include/asm/page.h |    2 +
drivers/base/map.c          |   33 +
fs/block_dev.c              |  675 ++++-
fs/char_dev.c               |   38 +
fs/dcache.c                 |  367 +++
fs/filesystems.c            |   21 +
fs/inode.c                  |    2 +
fs/libfs.c                  |  335 +++
fs/namespace.c              | 6644 ++++++++++++++++++++++++-------------------
fs/super.c                  |  624 +++-
include/linux/dcache.h      |    7 +
include/linux/fs.h          |   13 +-
include/linux/gfp.h         |    1 +
include/linux/list.h        |    2 +
include/linux/mount.h       |    1 +
include/linux/mutex.h       |   19 +
include/linux/slab.h        |    8 +
include/linux/slub_def.h    |    1 +
include/linux/time.h        |    1 +
include/linux/types.h       |    3 +
include/uapi/linux/fs.h     |    2 +
include/uapi/linux/magic.h  |    2 +
include/uapi/linux/stat.h   |    3 +
lib/idr.c                   |    6 +
mm/slab_common.c            |    7 +
26 files changed, 5926 insertions(+), 2907 deletions(-)