Skip to content

Latest commit

 

History

History
3040 lines (2739 loc) · 88.6 KB

a10c_128.md

File metadata and controls

3040 lines (2739 loc) · 88.6 KB
ARM10C : 128 주차
일시 : 2015.12.19 (128 주차 스터디 진행)
모임명 : KernelStudy_ARM
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 3명

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

128 주차 진도

  • 127 주차 진도를 복습하였습니다.

  • vfs_caches_init()

  • start_kernel 1 ~/linux-stable/init/main.c
  • vfs_caches_init 925 ~/linux-stable/init/main.c
  • mnt_init 3542 mnt_init();
  • sysfs_init 3139 ~/linux-stable/fs/namespace.c
  • kern_mount 594 ~/linux-stable/fs/sysfs/mount.c
  • kern_mount_data 1953 ~/linux-stable/include/linux/fs.h
  • vfs_kern_mount 3165 ~/linux-stable/fs/namespace.c
  • mount_fs 1111 ~/linux-stable/fs/namespace.c
  • sysfs_mount 1640 ~/linux-stable/fs/super.c
  • sysfs_fill_super 468 ~/linux-stable/fs/sysfs/mount.c
  • d_make_root 189 ~/linux-stable/fs/sysfs/mount.c
  • __d_alloc 1838 res = __d_alloc(root_inode->i_sb, &name);
  • 127주차 함수 호출 구조
  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
        • kmem_cache_create()
        • sysfs_inode_init()
        • register_filesystem()
        • kern_mount()
          • kern_mount_data()
            • vfs_kern_mount()
              • alloc_vfsmnt()
              • mount_fs()
              • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
        • free_sysfs_super_info()
          • IS_ERR()
          • sysfs_fill_super()
            • mutex_lock()
            • sysfs_get_inode()
            • mutex_unlock()
            • d_make_root()
              • __d_alloc()

main.c::start_kernel()

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

...

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

dcache.c::vfs_caches_init()

  • call: start_kernel()
  • vfs_caches_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();

	// dcache_init에서 한일:
	//
	// struct dentry를 위한 kmem_cache 생성
	// dentry_cache: kmem_cache#5

	inode_init();

	// inode_init에서 한일:
	//
	// struct inode를 위한 kmem_cache 생성
	// inode_cachep: kmem_cache#4

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

	// files_init에서 한일:
	//
	// filp_cachep: kmem_cache#3
	// files_stat.max_files: (총 free된 page 수 - XXX) * 4 / 10
	// sysctl_nr_open_max: 0x3FFFFFE0
	//
	// (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(&(&(&nr_files)->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&nr_files)->list)->next: &(&nr_files)->list
	// (&(&nr_files)->list)->prev: &(&nr_files)->list
	// (&nr_files)->count: 0
	// (&nr_files)->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
	// list head 인 &percpu_counters에 &(&nr_files)->list를 연결함

	mnt_init();

namespace.c::mnt_init()

  • start_kernel()->vfs_caches_init()
  • vfs_caches_init()
  • mnt_init() : mnt_cahce를 할당받는다.
// 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만큼 할당받은 메모리 주소

// 2015/10/24 종료
// 2015/10/31 시작

	// 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 수행

	err = sysfs_init();

mount.c::sysfs_init()

  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
// ARM10C 20151031
int __init sysfs_init(void)
{
	// ENOMEM: 12
	int err = -ENOMEM;
	// err: -12

	// sizeof(struct sysfs_dirent): 64 bytes
	// kmem_cache_create("sysfs_dir_cache", 64, 0, 0, NULL): kmem_cache#1
	sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
					      sizeof(struct sysfs_dirent),
					      0, 0, NULL);
	// sysfs_dir_cachep: kmem_cache#1

	// sysfs_dir_cachep: kmem_cache#1
	if (!sysfs_dir_cachep)
		goto out;

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

	// err: 0
	if (err)
		goto out_err;

	// register_filesystem(&sysfs_fs_type): 0
	err = register_filesystem(&sysfs_fs_type);
	// err: 0

	// register_filesystem에서 한일:
	// file_systems: &sysfs_fs_type

	// err: 0
	if (!err) {
		sysfs_mnt = kern_mount(&sysfs_fs_type);

namespace.c::kern_mount_data()

  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
        • kmem_cache_create()
        • sysfs_inode_init()
        • register_filesystem()
        • kern_mount()

namespace.c::kern_mount_data()

  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
        • kmem_cache_create()
        • sysfs_inode_init()
        • register_filesystem()
        • kern_mount(): kern_mount_data()
// ARM10C 20151031
// &sysfs_fs_type
#define kern_mount(type) kern_mount_data(type, NULL)

namespace.c::kern_mount_data()

  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
        • kmem_cache_create()
        • sysfs_inode_init()
        • register_filesystem()
        • kern_mount(): kern_mount_data()
// ARM10C 20151031
// &sysfs_fs_type, NULL
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{
	struct vfsmount *mnt;

	// type: &sysfs_fs_type, MS_KERNMOUNT: 0x400000, type->name: (&sysfs_fs_type)->name: "sysfs", data: NULL
	mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);

namespace.c::vfs_kern_mount()

  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
        • kmem_cache_create()
        • sysfs_inode_init()
        • register_filesystem()
        • kern_mount(): kern_mount_data()
// ARM10C 20151031
// &sysfs_fs_type, NULL
struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{
	struct vfsmount *mnt;

	// type: &sysfs_fs_type, MS_KERNMOUNT: 0x400000, type->name: (&sysfs_fs_type)->name: "sysfs", data: NULL
	mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);

namespace.c::vfs_kern_mount()

  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
        • kmem_cache_create()
        • sysfs_inode_init()
        • register_filesystem()
        • kern_mount(): kern_mount_data()
          • vfs_kern_mount()
// ARM10C 20151031
// type: &sysfs_fs_type, MS_KERNMOUNT: 0x400000, type->name: (&sysfs_fs_type)->name: "sysfs", data: 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: &sysfs_fs_type
	if (!type)
		return ERR_PTR(-ENODEV);

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

	// mnt: kmem_cache#2-oX (struct mount)
	if (!mnt)
		return ERR_PTR(-ENOMEM);

// 2015/11/07 종료
// 2015/11/14 시작

	// flags: 0x400000, 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: &sysfs_fs_type, flags: 0x400000, name: "sysfs", data: NULL
	root = mount_fs(type, flags, name, data);

super.c::mount_fs()

  • start_kernel()
  • vfs_caches_init()
    • mnt_init()
      • sysfs_init()
        • kmem_cache_create()
        • sysfs_inode_init()
        • register_filesystem()
        • kern_mount(): kern_mount_data()
          • vfs_kern_mount()
            • alloc_vfsmnt()
            • mount_fs()
// ARM10C 20151114
// type: &sysfs_fs_type, flags: 0x400000, name: "sysfs", 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: (&sysfs_fs_type)->fs_flags: 8, FS_BINARY_MOUNTDATA: 2
	if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {

mount.c::sysfs_mount()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
// ARM10C 20151114
// type: &sysfs_fs_type, flags: 0x400000, name: "sysfs", data: NULL
static struct dentry *sysfs_mount(struct file_system_type *fs_type,
	int flags, const char *dev_name, void *data)
{
	struct sysfs_super_info *info;
	enum kobj_ns_type type;
	struct super_block *sb;
	int error;

	// flags: 0x400000, MS_KERNMOUNT: 0x400000
	if (!(flags & MS_KERNMOUNT)) {
		if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
			return ERR_PTR(-EPERM);

		for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
			if (!kobj_ns_current_may_mount(type))
				return ERR_PTR(-EPERM);
		}
	}

	// sizeof(struct sysfs_super_info): 8 bytes, GFP_KERNEL: 0xD0
	// kzalloc(8, GFP_KERNEL: 0xD0): kmem_cache#30-oX
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	// info: kmem_cache#30-oX (struct sysfs_super_info)

	// info: kmem_cache#30-oX (struct sysfs_super_info)
	if (!info)
		return ERR_PTR(-ENOMEM);

	// KOBJ_NS_TYPE_NONE: 0, KOBJ_NS_TYPES: 2
	for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
		// type: 0, info->ns[0]: (kmem_cache#30-oX (struct sysfs_super_info))->ns[0],
		// kobj_ns_grab_current(0): NULL
		info->ns[type] = kobj_ns_grab_current(type);
		// info->ns[0]: (kmem_cache#30-oX (struct sysfs_super_info))->ns[0]: NULL

	// fs_type: &sysfs_fs_type, flags: 0x400000, info: kmem_cache#30-oX (struct sysfs_super_info)
	// sget(&sysfs_fs_type, sysfs_test_super, sysfs_set_super, 0x400000, kmem_cache#30-oX (struct sysfs_super_info)): kmem_cache#25-oX (struct super_block)
	sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info);
	// sb: kmem_cache#25-oX (struct super_block)

	// sb: kmem_cache#25-oX (struct super_block)
	// IS_ERR(kmem_cache#25-oX (struct super_block)): 0,
	// sb->s_fs_info: (kmem_cache#25-oX (struct super_block))->s_fs_info: kmem_cache#30-oX (struct sysfs_super_info),
	// info: kmem_cache#30-oX (struct sysfs_super_info)
	if (IS_ERR(sb) || sb->s_fs_info != info)
		free_sysfs_super_info(info);

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

	// sb->s_root: (kmem_cache#25-oX (struct super_block))->s_root: NULL
	if (!sb->s_root) {
		// sb: kmem_cache#25-oX (struct super_block), data: NULL, flags: 0x400000, MS_SILENT: 0x8000
		error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);

mount.c::sysfs_fill_super()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
// ARM10C 20151121
// sb: kmem_cache#25-oX (struct super_block), data: NULL, 0
static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct inode *inode;
	struct dentry *root;

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

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

	// sb->s_magic: (kmem_cache#25-oX (struct super_block))->s_magic, SYSFS_MAGIC: 0x62656572
	sb->s_magic = SYSFS_MAGIC;
	// sb->s_magic: (kmem_cache#25-oX (struct super_block))->s_magic: 0x62656572

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

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

	/* get root inode, initialize and unlock it */
	mutex_lock(&sysfs_mutex);

	// mutex_lock에서 한일:
	// &sysfs_mutex을 사용하여 mutex lock을 수행함

	// sb: kmem_cache#25-oX (struct super_block),
	// sysfs_get_inode(kmem_cache#25-oX (struct super_block), &sysfs_root): kmem_cache#4-oX
	inode = sysfs_get_inode(sb, &sysfs_root);
	// inode: kmem_cache#4-oX

sysfs_get_inode에서 한일:

//
// inode용 kmem_cache인 inode_cachep: kmem_cache#4 를 사용하여 inode를 위한 메모리 kmem_cache#4-oX 할당 받음
//
// (kmem_cache#4-oX)->i_sb: kmem_cache#25-oX (struct super_block)
// (kmem_cache#4-oX)->i_blkbits: 12
// (kmem_cache#4-oX)->i_flags: 0
// (kmem_cache#4-oX)->i_count: 1
// (kmem_cache#4-oX)->i_op: &empty_iops
// (kmem_cache#4-oX)->__i_nlink: 1
// (kmem_cache#4-oX)->i_opflags: 0
// (kmem_cache#4-oX)->i_uid: 0
// (kmem_cache#4-oX)->i_gid: 0
// (kmem_cache#4-oX)->i_count: 0
// (kmem_cache#4-oX)->i_size: 0
// (kmem_cache#4-oX)->i_blocks: 0
// (kmem_cache#4-oX)->i_bytes: 0
// (kmem_cache#4-oX)->i_generation: 0
// (kmem_cache#4-oX)->i_pipe: NULL
// (kmem_cache#4-oX)->i_bdev: NULL
// (kmem_cache#4-oX)->i_cdev: NULL
// (kmem_cache#4-oX)->i_rdev: 0
// (kmem_cache#4-oX)->dirtied_when: 0
//
// &(kmem_cache#4-oX)->i_lock을 이용한 spin lock 초기화 수행
//
// ((&(kmem_cache#4-oX)->i_lock)->rlock)->raw_lock: { { 0 } }
// ((&(kmem_cache#4-oX)->i_lock)->rlock)->magic: 0xdead4ead
// ((&(kmem_cache#4-oX)->i_lock)->rlock)->owner: 0xffffffff
// ((&(kmem_cache#4-oX)->i_lock)->rlock)->owner_cpu: 0xffffffff
//
// (&(kmem_cache#4-oX)->i_mutex)->count: 1
// (&(&(&(kmem_cache#4-oX)->i_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
// (&(&(&(kmem_cache#4-oX)->i_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
// (&(&(&(kmem_cache#4-oX)->i_mutex)->wait_lock)->rlock)->owner: 0xffffffff
// (&(&(&(kmem_cache#4-oX)->i_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
// (&(&(kmem_cache#4-oX)->i_mutex)->wait_list)->next: &(&(kmem_cache#4-oX)->i_mutex)->wait_list
// (&(&(kmem_cache#4-oX)->i_mutex)->wait_list)->prev: &(&(kmem_cache#4-oX)->i_mutex)->wait_list
// (&(kmem_cache#4-oX)->i_mutex)->onwer: NULL
// (&(kmem_cache#4-oX)->i_mutex)->magic: &(kmem_cache#4-oX)->i_mutex
//
// (kmem_cache#4-oX)->i_dio_count: 0
//
// (&(kmem_cache#4-oX)->i_data)->a_ops: &empty_aops
// (&(kmem_cache#4-oX)->i_data)->host: kmem_cache#4-oX
// (&(kmem_cache#4-oX)->i_data)->flags: 0
// (&(kmem_cache#4-oX)->i_data)->flags: 0x200DA
// (&(kmem_cache#4-oX)->i_data)->private_data: NULL
// (&(kmem_cache#4-oX)->i_data)->backing_dev_info: &default_backing_dev_info
// (&(kmem_cache#4-oX)->i_data)->writeback_index: 0
//
// (kmem_cache#4-oX)->i_private: NULL
// (kmem_cache#4-oX)->i_mapping: &(kmem_cache#4-oX)->i_data
// (&(kmem_cache#4-oX)->i_dentry)->first: NULL
// (kmem_cache#4-oX)->i_acl: (void *)(0xFFFFFFFF),
// (kmem_cache#4-oX)->i_default_acl: (void *)(0xFFFFFFFF)
// (kmem_cache#4-oX)->i_fsnotify_mask: 0
//
// [pcp0] nr_inodes: 1
//
// (kmem_cache#4-oX)->i_ino: 1
// (kmem_cache#4-oX)->i_state: 0x8
//
// (&(kmem_cache#4-oX)->i_hash)->next: NULL
// (256KB의 메모리 공간 + 계산된 hash index 값)->first: &(kmem_cache#4-oX)->i_hash
// (&(kmem_cache#4-oX)->i_hash)->pprev: &(&(kmem_cache#4-oX)->i_hash)
//
// head list인 &(kmem_cache#4-oX)->i_sb->s_inodes에 &(kmem_cache#4-oX)->i_sb_list를 추가함
//
// (&sysfs_root)->s_count: 2
//
// (kmem_cache#4-oX)->i_private: 2
// (kmem_cache#4-oX)->i_mapping->a_ops: &sysfs_aops
// (kmem_cache#4-oX)->i_mapping->backing_dev_info: &sysfs_backing_dev_info
// (kmem_cache#4-oX)->i_op: &sysfs_inode_operations
// (kmem_cache#4-oX)->i_mode: 40447
// (kmem_cache#4-oX)->i_atime: 현재시간값,
// (kmem_cache#4-oX)->i_mtime: 현재시간값,
// (kmem_cache#4-oX)->i_ctime: 현재시간값
// (kmem_cache#4-oX)->i_mode: 40447
// (kmem_cache#4-oX)->__i_nlink: 2
// (kmem_cache#4-oX)->i_op: &sysfs_dir_inode_operations
// (kmem_cache#4-oX)->i_fop: &sysfs_dir_operations
// (kmem_cache#4-oX)->i_state: 0x0
// memory barrier 수행 (공유자원을 다른 cpu core가 사용할 수 있게 해줌)

dcache.c::d_make_root()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
// ARM10C 20151212
// inode: kmem_cache#4-oX
struct dentry *d_make_root(struct inode *root_inode)
{
	struct dentry *res = NULL;
	// res: NULL

	// root_inode: kmem_cache#4-oX
	if (root_inode) {
		// QSTR_INIT("/", 1): { { { .len = 1 } }, .name = "/" }
		static const struct qstr name = QSTR_INIT("/", 1);

		// QSTR_INIT에서 한일:
		// name.name: "/"
		// name.len: 1

		// root_inode->i_sb: (kmem_cache#4-oX)->i_sb: kmem_cache#25-oX (struct super_block)
		res = __d_alloc(root_inode->i_sb, &name);

dcache.c::__d_alloc()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
// ARM10C 20151212
// root_inode->i_sb: (kmem_cache#4-oX)->i_sb: kmem_cache#25-oX (struct super_block), &name
struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
{
	struct dentry *dentry;
	char *dname;

	// dentry_cache: kmem_cache#5, GFP_KERNEL: 0xD0
	// kmem_cache_alloc(kmem_cache#5, GFP_KERNEL: 0xD0): kmem_cache#5-oX
	dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
	// dentry: kmem_cache#5-oX

	// dentry: kmem_cache#5-oX
	if (!dentry)
		return NULL;

	/*
	 * We guarantee that the inline name is always NUL-terminated.
	 * This way the memcpy() done by the name switching in rename
	 * will still always have a NUL at the end, even if we might
	 * be overwriting an internal NUL character
	 */
	// DNAME_INLINE_LEN: 36, dentry->d_iname: (kmem_cache#5-oX)->d_iname[35]
	dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
	// dentry->d_iname: (kmem_cache#5-oX)->d_iname[35]: 0

	// name->len: (&name)->len: 1, DNAME_INLINE_LEN: 36
	if (name->len > DNAME_INLINE_LEN-1) {
		dname = kmalloc(name->len + 1, GFP_KERNEL);
		if (!dname) {
			kmem_cache_free(dentry_cache, dentry); 
			return NULL;
		}
	} else  {
		// dentry->d_iname: (kmem_cache#5-oX)->d_iname
		dname = dentry->d_iname;
		// dname: (kmem_cache#5-oX)->d_iname
	}	

	// dentry->d_name.len: (kmem_cache#5-oX)->d_name.len, name->len: (&name)->len: 1
	dentry->d_name.len = name->len;
	// dentry->d_name.len: (kmem_cache#5-oX)->d_name.len: 1

	// dentry->d_name.hash: (kmem_cache#5-oX)->d_name.hash, name->hash: (&name)->hash: 0
	dentry->d_name.hash = name->hash;
	// dentry->d_name.hash: (kmem_cache#5-oX)->d_name.hash: (&name)->hash: 0

	// dname: (kmem_cache#5-oX)->d_iname, name->name: (&name)->name: "/", name->len: (&name)->len: 1
	memcpy(dname, name->name, name->len);

	// memcpy에서 한일:
	// dname: (kmem_cache#5-oX)->d_iname: "/"

	// name->len: (&name)->len: 1, dname[1]: (kmem_cache#5-oX)->d_iname[1]
	dname[name->len] = 0;
	// dname[1]: (kmem_cache#5-oX)->d_iname[1]: 0

// 2015/12/12 종료
// 2015/12/19 시작

	/* Make sure we always see the terminating NUL character */
	smp_wmb();
	// smp_wmb에서 한일:
	// 공유자원을 다른 cpu core가 사용할수 있게 함

	// dentry->d_name.name: (kmem_cache#5-oX)->d_name.name, dname: "/"
	dentry->d_name.name = dname;
	// dentry->d_name.name: (kmem_cache#5-oX)->d_name.name: "/"

	// dentry->d_lockref.count: (kmem_cache#5-oX)->d_lockref.count
	dentry->d_lockref.count = 1;
	// dentry->d_lockref.count: (kmem_cache#5-oX)->d_lockref.count: 1

	// dentry->d_flags: (kmem_cache#5-oX)->d_flags
	dentry->d_flags = 0;
	// dentry->d_flags: (kmem_cache#5-oX)->d_flags: 0

	// &dentry->d_lock: &(kmem_cache#5-oX)->d_lock
	spin_lock_init(&dentry->d_lock);

	// spin_lock_init에서 한일:
	// (&(kmem_cache#5-oX)->d_lock)->raw_lock: { { 0 } }
	// (&(kmem_cache#5-oX)->d_lock)->magic: 0xdead4ead
	// (&(kmem_cache#5-oX)->d_lock)->owner: 0xffffffff
	// (&(kmem_cache#5-oX)->d_lock)->owner_cpu: 0xffffffff

	// TODO:
	// seqcount lock 을 어떨때 사용하는지, 사용하는 부분 분석 및 확인 필요함

	// &dentry->d_seq: &(kmem_cache#5-oX)->d_seq
	seqcount_init(&dentry->d_seq);

	// seqcount_init에서 한일:
	// (&(kmem_cache#5-oX)->d_seq)->sequence: 0

	// dentry->d_inode: (kmem_cache#5-oX)->d_inode
	dentry->d_inode = NULL;
	// dentry->d_inode: (kmem_cache#5-oX)->d_inode: NULL

	// dentry->d_parent: (kmem_cache#5-oX)->d_parent, dentry: kmem_cache#5-oX
	dentry->d_parent = dentry;
	// dentry->d_parent: (kmem_cache#5-oX)->d_parent: kmem_cache#5-oX

	// dentry->d_sb: (kmem_cache#5-oX)->d_sb, sb: kmem_cache#25-oX (struct super_block)
	dentry->d_sb = sb;
	// dentry->d_sb: (kmem_cache#5-oX)->d_sb: kmem_cache#25-oX (struct super_block)

	// dentry->d_op: (kmem_cache#5-oX)->d_op
	dentry->d_op = NULL;
	// dentry->d_op: (kmem_cache#5-oX)->d_op: NULL

	// dentry->d_fsdata: (kmem_cache#5-oX)->d_fsdata
	dentry->d_fsdata = NULL;
	// dentry->d_fsdata: (kmem_cache#5-oX)->d_fsdata: NULL

	// &dentry->d_hash: &(kmem_cache#5-oX)->d_hash
	INIT_HLIST_BL_NODE(&dentry->d_hash);

	// INIT_HLIST_BL_NODE에서 한일:
	// (&(kmem_cache#5-oX)->d_hash)->next: NULL
	// (&(kmem_cache#5-oX)->d_hash)->pprev: NULL

	// &dentry->d_lru: &(kmem_cache#5-oX)->d_lru
	INIT_LIST_HEAD(&dentry->d_lru);

	// INIT_LIST_HEAD에서 한일:
	// (&(kmem_cache#5-oX)->d_lru)->next: &(kmem_cache#5-oX)->d_lru
	// (&(kmem_cache#5-oX)->d_lru)->prev: &(kmem_cache#5-oX)->d_lru

	// &dentry->d_subdirs: &(kmem_cache#5-oX)->d_subdirs
	INIT_LIST_HEAD(&dentry->d_subdirs);

	// INIT_LIST_HEAD에서 한일:
	// (&(kmem_cache#5-oX)->d_subdirs)->next: &(kmem_cache#5-oX)->d_subdirs
	// (&(kmem_cache#5-oX)->d_subdirs)->prev: &(kmem_cache#5-oX)->d_subdirs

	// &dentry->d_alias: &(kmem_cache#5-oX)->d_alias
	INIT_HLIST_NODE(&dentry->d_alias);

	// INIT_HLIST_NODE에서 한일:
	// (&(kmem_cache#5-oX)->d_alias)->next: NULL
	// (&(kmem_cache#5-oX)->d_alias)->pprev: NULL

	// &dentry->d_u.d_child: &(kmem_cache#5-oX)->d_u.d_child
	INIT_LIST_HEAD(&dentry->d_u.d_child);

	// INIT_LIST_HEAD에서 한일:
	// (&(kmem_cache#5-oX)->d_u.d_child)->next: &(kmem_cache#5-oX)->d_u.d_child
	// (&(kmem_cache#5-oX)->d_u.d_child)->prev: &(kmem_cache#5-oX)->d_u.d_child

	// dentry: kmem_cache#5-oX, dentry->d_sb: (kmem_cache#5-oX)->d_sb: kmem_cache#25-oX (struct super_block)
	// dentry->d_sb->s_d_op: (kmem_cache#5-oX)->d_sb->s_d_op: NULL
	d_set_d_op(dentry, dentry->d_sb->s_d_op);

list_bl.h::INIT_HLIST_BL_NODE()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
  • INIT_HLIST_BL_NODE(&dentry->d_hash);
// ARM10C 20151219
// &dentry->d_hash: &(kmem_cache#5-oX)->d_hash
static inline void INIT_HLIST_BL_NODE(struct hlist_bl_node *h)
{
	// h->next: (&(kmem_cache#5-oX)->d_hash)->next
	h->next = NULL;
	// h->next: (&(kmem_cache#5-oX)->d_hash)->next: NULL

	// h->pprev: (&(kmem_cache#5-oX)->d_hash)->pprev
	h->pprev = NULL;
	// h->pprev: (&(kmem_cache#5-oX)->d_hash)->pprev: NULL
}
  • INIT_LIST_HEAD(&dentry->d_lru);
// ARM10C 20151219
// &dentry->d_lru: &(kmem_cache#5-oX)->d_lru
static inline void INIT_LIST_HEAD(struct list_head *list)
{
	list->next = list;
	list->prev = list;
}
  • INIT_LIST_HEAD(&dentry->d_subdirs);
// ARM10C 20151219
// &dentry->d_subdirs: &(kmem_cache#5-oX)->d_subdirs
static inline void INIT_LIST_HEAD(struct list_head *list)
{
	list->next = list;
	list->prev = list;
}
  • INIT_HLIST_NODE(&dentry->d_alias);
// ARM10C 20151219
// &dentry->d_alias: &(kmem_cache#5-oX)->d_alias
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{

	// h->next: (&init_css_set.hlist)->next
	h->next = NULL;
	// h->next: (&init_css_set.hlist)->next: NULL

	// h->pprev: (&init_css_set.hlist)->pprev
	h->pprev = NULL;
	// h->pprev: (&init_css_set.hlist)->pprev: NULL
}
  • INIT_LIST_HEAD(&dentry->d_u.d_child);
// &dentry->d_u.d_child: &(kmem_cache#5-oX)->d_u.d_child
static inline void INIT_LIST_HEAD(struct list_head *list)
{
	list->next = list;
	list->prev = list;
}

list_bl.h::INIT_HLIST_BL_NODE()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
// ARM10C 20151219
// dentry: kmem_cache#5-oX, dentry->d_sb->s_d_op: (kmem_cache#5-oX)->d_sb->s_d_op: NULL
void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
{
	// dentry->d_op: (kmem_cache#5-oX)->d_op: NULL
	WARN_ON_ONCE(dentry->d_op);

	// dentry->d_flags: (kmem_cache#5-oX)->d_flags: 0
	// DCACHE_OP_HASH: 0x00000001, DCACHE_OP_COMPARE: 0x00000002, DCACHE_OP_REVALIDATE: 0x00000004
	// DCACHE_OP_WEAK_REVALIDATE: 0x00000800, DCACHE_OP_DELETE: 0x00000008
	WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH	|
				DCACHE_OP_COMPARE	|
				DCACHE_OP_REVALIDATE	|
				DCACHE_OP_WEAK_REVALIDATE	|
				DCACHE_OP_DELETE ));

	// dentry->d_op: (kmem_cache#5-oX)->d_op: NULL, op: (kmem_cache#5-oX)->d_sb->s_d_op: NULL
	dentry->d_op = op;
	// dentry->d_op: (kmem_cache#5-oX)->d_op: NULL

	// dentry->d_op: (kmem_cache#5-oX)->d_op: NULL
	if (!op)
		return;
		// return 수행

	if (op->d_hash)
		dentry->d_flags |= DCACHE_OP_HASH;
	if (op->d_compare)
		dentry->d_flags |= DCACHE_OP_COMPARE;
	if (op->d_revalidate)
		dentry->d_flags |= DCACHE_OP_REVALIDATE;
	if (op->d_weak_revalidate)
		dentry->d_flags |= DCACHE_OP_WEAK_REVALIDATE;
	if (op->d_delete)
		dentry->d_flags |= DCACHE_OP_DELETE;
	if (op->d_prune)
		dentry->d_flags |= DCACHE_OP_PRUNE;

}
EXPORT_SYMBOL(d_set_d_op);

list_bl.h::this_cpu_dec()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
# define this_cpu_inc(pcp)		this_cpu_add((pcp), 1)

dcache.c::d_make_root()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
// ARM10C 20151219
// res: kmem_cache#5-oX, root_inode: kmem_cache#4-oX
void d_instantiate(struct dentry *entry, struct inode * inode)
{
	// &entry->d_alias: &(kmem_cache#5-oX)->d_alias, hlist_unhashed(&(kmem_cache#5-oX)->d_alias): 1
	BUG_ON(!hlist_unhashed(&entry->d_alias));

	// inode: kmem_cache#4-oX
	if (inode)
		// &inode->i_lock: &(kmem_cache#4-oX)->i_lock
		spin_lock(&inode->i_lock);

		// spin_lock에서 한일:
		// &(kmem_cache#4-oX)->i_lock을 이용하여 spin lock을 수행

	// entry: kmem_cache#5-oX, inode: kmem_cache#4-oX
	__d_instantiate(entry, inode);
  • hlist_unhashed(&entry->d_alias)
static inline int hlist_unhashed(const struct hlist_node *h)
{
	return !h->pprev;
}

dcache.c::__d_instantiate()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
// ARM10C 20151219
// entry: kmem_cache#5-oX, inode: kmem_cache#4-oX
static void __d_instantiate(struct dentry *dentry, struct inode *inode)
{
	// inode: kmem_cache#4-oX, i d_flags_for_inode(kmem_cache#4-oX): 0x00100000
	unsigned add_flags = d_flags_for_inode(inode);
	// add_flags: 0x00100000

	spin_lock(&dentry->d_lock);

	dentry->d_flags &= ~DCACHE_ENTRY_TYPE;
	dentry->d_flags |= add_flags;
	if (inode)
		hlist_add_head(&dentry->d_alias, &inode->i_dentry);
	dentry->d_inode = inode;
	dentry_rcuwalk_barrier(dentry);
	spin_unlock(&dentry->d_lock);
	fsnotify_d_instantiate(dentry, inode);
}

dcache.c::d_flag_for_inode()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
// ARM10C 20151219
// inode: kmem_cache#4-oX
static unsigned d_flags_for_inode(struct inode *inode)
{
	// DCACHE_FILE_TYPE: 0x00400000
	unsigned add_flags = DCACHE_FILE_TYPE;
	// add_flags: 0x00400000

	// inode: kmem_cache#4-oX
	if (!inode)
		return DCACHE_MISS_TYPE;

	// inode->i_mode: (kmem_cache#4-oX)->i_mode: 40447, S_ISDIR(40447): 1
	if (S_ISDIR(inode->i_mode)) {
		// DCACHE_DIRECTORY_TYPE: 0x00100000
		add_flags = DCACHE_DIRECTORY_TYPE;
		// add_flags: 0x00100000

		// inode->i_opflags: (kmem_cache#4-oX)->i_opflags: 0, IOP_LOOKUP: 0x0002
		if (unlikely(!(inode->i_opflags & IOP_LOOKUP))) {
			// inode->i_op: (kmem_cache#4-oX)->i_op: &sysfs_dir_inode_operations
			// inode->i_op->lookup: (kmem_cache#4-oX)->i_op->lookup: sysfs_lookup
			if (unlikely(!inode->i_op->lookup))
				add_flags = DCACHE_AUTODIR_TYPE;
			else
				// inode->i_opflags: (kmem_cache#4-oX)->i_opflags: 0, IOP_LOOKUP: 0x0002
				inode->i_opflags |= IOP_LOOKUP;
				// inode->i_opflags: (kmem_cache#4-oX)->i_opflags: 0x0002
		}
	} else if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) {
		if (unlikely(inode->i_op->follow_link))
			add_flags = DCACHE_SYMLINK_TYPE;
		else
			inode->i_opflags |= IOP_NOFOLLOW;
	}

	// inode: kmem_cache#4-oX, IS_AUTOMOUNT(kmem_cache#4-oX): 0
	if (unlikely(IS_AUTOMOUNT(inode)))
		add_flags |= DCACHE_NEED_AUTOMOUNT;

	// add_flags: 0x00100000
	return add_flags;
	// return 0x00100000
}

dcache.c::security_d_instantiate()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
// ARM10C 20151219
// entry: kmem_cache#5-oX, inode: kmem_cache#4-oX
static void __d_instantiate(struct dentry *dentry, struct inode *inode)
{
	// inode: kmem_cache#4-oX, i d_flags_for_inode(kmem_cache#4-oX): 0x00100000
	unsigned add_flags = d_flags_for_inode(inode);
	// add_flags: 0x00100000

	spin_lock(&dentry->d_lock);
	dentry->d_flags &= ~DCACHE_ENTRY_TYPE;
	dentry->d_flags |= add_flags;
	if (inode)
		hlist_add_head(&dentry->d_alias, &inode->i_dentry);
	dentry->d_inode = inode;
	dentry_rcuwalk_barrier(dentry);
	spin_unlock(&dentry->d_lock);
	fsnotify_d_instantiate(dentry, inode);
}

dcache.c::dentry_rcuwalk_barrier()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
static inline void dentry_rcuwalk_barrier(struct dentry *dentry)
{
	assert_spin_locked(&dentry->d_lock);
	/* Go through a barrier */
	write_seqcount_barrier(&dentry->d_seq);
}

spinlock.h::assert_spin_locked()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
static inline void write_seqcount_barrier(seqcount_t *s)
{
	smp_wmb();
	s->sequence+=2;
}

dcache.c::__d_instantiate()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
// ARM10C 20151219
// entry: kmem_cache#5-oX, inode: kmem_cache#4-oX
static void __d_instantiate(struct dentry *dentry, struct inode *inode)
{
	// inode: kmem_cache#4-oX, i d_flags_for_inode(kmem_cache#4-oX): 0x00100000
	unsigned add_flags = d_flags_for_inode(inode);
	// add_flags: 0x00100000

	spin_lock(&dentry->d_lock);
	dentry->d_flags &= ~DCACHE_ENTRY_TYPE;
	dentry->d_flags |= add_flags;
	if (inode)
		hlist_add_head(&dentry->d_alias, &inode->i_dentry);
	dentry->d_inode = inode;
	dentry_rcuwalk_barrier(dentry);
	spin_unlock(&dentry->d_lock);
	fsnotify_d_instantiate(dentry, inode);
}
static inline void fsnotify_d_instantiate(struct dentry *dentry,
					  struct inode *inode)
{
	__fsnotify_d_instantiate(dentry, inode);
}

fsnotify_backend.h::__fsnotify_d_instantiate()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode)
{
	if (!inode)
		return;

	spin_lock(&dentry->d_lock);
	__fsnotify_update_dcache_flags(dentry);
	spin_unlock(&dentry->d_lock);
}

## fsnotify_backend.h::__fsnotify_update_dcache_flags()

* start_kernel()->vfs_caches_init()
 - mnt_init()
  - sysfs_init()
    - kmem_cache_create()
    - sysfs_inode_init()
    - register_filesystem()
    - kern_mount()
	  - kern_mount_data()
        - vfs_kern_mount()
		  - alloc_vfsmnt()
		  - mount_fs()
            - mount(): sysfs_mount()
			  - sget()
		        - spin_lock()
				- hlist_for_eash_entry()
				- spin_unlock()
				- alloc_super()
				- set()
				- strlcpy()
				- list_add_tail()
				- hlist_add_head()
				- spin_unlock(&sb_lock)
				- get_filesystem(type)
				- register_shrinker()
      - free_sysfs_super_info()
	  - IS_ERR()
	  - sysfs_fill_super()
	    - mutex_lock()
		- sysfs_get_inode()
		- mutex_unlock()
		- d_make_root()
		  - __d_alloc()
		    - kmem_cache_alloc()
			- swp_wmb()
			- spin_lock_init()
			- seqcount_init()
			- INIT_HLIST_BL_NODE()
			- INIT_LIST_HEAD()
			- INIT_LIST_HEAD()
			- INIT_HLIST_NODE()
			- INIT_LIST_HEAD()
			- d_set_d_op()
			- this_cpu_inc()
		  - d_instantiate()
		    - __d_instantiate()
			  - d_flags_for_inode()
			  - spin_lock()
			  - dentry_rcuwalk_barrier()
			    - assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
				- write_seqcount_barrier()
			  - spin_unlock()
			  - fsnotify_d_instantiate()
			    - spin_lock()
				- __fsnotify_update_dcache_flags()

```fsnotify_backend.h
static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
{
	struct dentry *parent;

	assert_spin_locked(&dentry->d_lock);

	/*
	 * Serialisation of setting PARENT_WATCHED on the dentries is provided
	 * by d_lock. If inotify_inode_watched changes after we have taken
	 * d_lock, the following __fsnotify_update_child_dentry_flags call will
	 * find our entry, so it will spin until we complete here, and update
	 * us with the new state.
	 */
	parent = dentry->d_parent;
	if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))
		dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
	else
		dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
}

fsnotify_backend.h::__fsnotify_update_dcache_flags()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
                • spin_lock()
                • __fsnotify_update_dcache_flags()
                  • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                  • fsnotify_inode_watched_children()
static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
{
	struct dentry *parent;

	assert_spin_locked(&dentry->d_lock);

	/*
	 * Serialisation of setting PARENT_WATCHED on the dentries is provided
	 * by d_lock. If inotify_inode_watched changes after we have taken
	 * d_lock, the following __fsnotify_update_child_dentry_flags call will
	 * find our entry, so it will spin until we complete here, and update
	 * us with the new state.
	 */
	parent = dentry->d_parent;
	if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))

fsnotify_backend.h::fsnotify_inode_watches_children()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
                • spin_lock()
                • __fsnotify_update_dcache_flags()
                  • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                  • fsnotify_inode_watched_children()
static inline int fsnotify_inode_watches_children(struct inode *inode)
{
	/* FS_EVENT_ON_CHILD is set if the inode may care */
	if (!(inode->i_fsnotify_mask & FS_EVENT_ON_CHILD))
		return 0;
	/* this inode might care about child events, does it care about the
	 * specific set of events that can happen on a child? */
	return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD;
}

fsnotify_backend.h::__fsnotify_update_dcache_flags()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
                • spin_lock()
                • __fsnotify_update_dcache_flags()
                  • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                  • fsnotify_inode_watched_children()
static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
{
	struct dentry *parent;

	assert_spin_locked(&dentry->d_lock);

	/*
	 * Serialisation of setting PARENT_WATCHED on the dentries is provided
	 * by d_lock. If inotify_inode_watched changes after we have taken
	 * d_lock, the following __fsnotify_update_child_dentry_flags call will
	 * find our entry, so it will spin until we complete here, and update
	 * us with the new state.
	 */
	parent = dentry->d_parent;
	if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))
		dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
	else
		dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
}

fsnotify_backend.h::__fsnotify_d_instantiate()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
                • spin_lock()
                • __fsnotify_update_dcache_flags()
                  • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                  • fsnotify_inode_watched_children()
                • spin_unlock()
static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode)
{
	if (!inode)
		return;

	spin_lock(&dentry->d_lock);
	__fsnotify_update_dcache_flags(dentry);
	spin_unlock(&dentry->d_lock);
}

dcache.c::d_instantiate()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
                • spin_lock()
                • __fsnotify_update_dcache_flags()
                  • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                  • fsnotify_inode_watched_children()
                • spin_unlock()
            • spin_unlock()
            • security_d_instantiate()
// ARM10C 20151219
// res: kmem_cache#5-oX, root_inode: kmem_cache#4-oX
void d_instantiate(struct dentry *entry, struct inode * inode)
{
	// &entry->d_alias: &(kmem_cache#5-oX)->d_alias, hlist_unhashed(&(kmem_cache#5-oX)->d_alias): 1
	BUG_ON(!hlist_unhashed(&entry->d_alias));

	// inode: kmem_cache#4-oX
	if (inode)
		// &inode->i_lock: &(kmem_cache#4-oX)->i_lock
		spin_lock(&inode->i_lock);

		// spin_lock에서 한일:
		// &(kmem_cache#4-oX)->i_lock을 이용하여 spin lock을 수행

	// entry: kmem_cache#5-oX, inode: kmem_cache#4-oX
	__d_instantiate(entry, inode);
	if (inode)
		spin_unlock(&inode->i_lock);
	security_d_instantiate(entry, inode);
}
EXPORT_SYMBOL(d_instantiate);

dcache.c::d_make_root()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
                • spin_lock()
                • __fsnotify_update_dcache_flags()
                  • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                  • fsnotify_inode_watched_children()
                • spin_unlock()
            • spin_unlock()
            • security_d_instantiate()
// ARM10C 20151212
// inode: kmem_cache#4-oX
struct dentry *d_make_root(struct inode *root_inode)
{
	struct dentry *res = NULL;
	// res: NULL

	// root_inode: kmem_cache#4-oX
	if (root_inode) {
		// QSTR_INIT("/", 1): { { { .len = 1 } }, .name = "/" }
		static const struct qstr name = QSTR_INIT("/", 1);

		// QSTR_INIT에서 한일:
		// name.name: "/"
		// name.len: 1

		// root_inode->i_sb: (kmem_cache#4-oX)->i_sb: kmem_cache#25-oX (struct super_block)
		// __d_alloc(kmem_cache#25-oX (struct super_block), &name): kmem_cache#5-oX
		res = __d_alloc(root_inode->i_sb, &name);
		// res: kmem_cache#5-oX

		// res: kmem_cache#5-oX
		if (res)
			// res: kmem_cache#5-oX, root_inode: kmem_cache#4-oX
			d_instantiate(res, root_inode);
		else
			iput(root_inode);
	}
	return res;
}
EXPORT_SYMBOL(d_make_root);
  • d_make_root가 끝나서 res값을 반환함.

mount.c::sysfs_fill_super()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount()
      • kern_mount_data()
        • vfs_kern_mount()
          • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
      • free_sysfs_super_info()
      • IS_ERR()
      • sysfs_fill_super()
        • mutex_lock()
        • sysfs_get_inode()
        • mutex_unlock()
        • d_make_root()
          • __d_alloc()
            • kmem_cache_alloc()
            • swp_wmb()
            • spin_lock_init()
            • seqcount_init()
            • INIT_HLIST_BL_NODE()
            • INIT_LIST_HEAD()
            • INIT_LIST_HEAD()
            • INIT_HLIST_NODE()
            • INIT_LIST_HEAD()
            • d_set_d_op()
            • this_cpu_inc()
          • d_instantiate()
            • __d_instantiate()
              • d_flags_for_inode()
              • spin_lock()
              • dentry_rcuwalk_barrier()
                • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                • write_seqcount_barrier()
              • spin_unlock()
              • fsnotify_d_instantiate()
                • spin_lock()
                • __fsnotify_update_dcache_flags()
                  • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                  • fsnotify_inode_watched_children()
                • spin_unlock()
            • spin_unlock()
            • security_d_instantiate()
// ARM10C 20151121
// sb: kmem_cache#25-oX (struct super_block), data: NULL, 0
static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct inode *inode;
	struct dentry *root;

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

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

	// sb->s_magic: (kmem_cache#25-oX (struct super_block))->s_magic, SYSFS_MAGIC: 0x62656572
	sb->s_magic = SYSFS_MAGIC;
	// sb->s_magic: (kmem_cache#25-oX (struct super_block))->s_magic: 0x62656572

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

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

	/* get root inode, initialize and unlock it */
	mutex_lock(&sysfs_mutex);

	// mutex_lock에서 한일:
	// &sysfs_mutex을 사용하여 mutex lock을 수행함

	// sb: kmem_cache#25-oX (struct super_block),
	// sysfs_get_inode(kmem_cache#25-oX (struct super_block), &sysfs_root): kmem_cache#4-oX
	inode = sysfs_get_inode(sb, &sysfs_root);
	// inode: kmem_cache#4-oX

	mutex_unlock(&sysfs_mutex);

	// mutex_unlock에서 한일:
	// &sysfs_mutex을 사용하여 mutex unlock을 수행함

	// inode: kmem_cache#4-oX
	if (!inode) {
		pr_debug("sysfs: could not get root inode\n");
		return -ENOMEM;
	}

	/* instantiate and link root dentry */
	// inode: kmem_cache#4-oX
	root = d_make_root(inode);
	if (!root) {
		pr_debug("%s: could not get root dentry!\n", __func__);
		return -ENOMEM;
	}
	root->d_fsdata = &sysfs_root;
	sb->s_root = root;
	sb->s_d_op = &sysfs_dentry_ops;
	return 0;
}

mount.c::sysfs_mount()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount() : kern_mount_data()
      • vfs_kern_mount()
        • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
              • free_sysfs_super_info()
              • IS_ERR()
              • sysfs_fill_super()
                • mutex_lock()
                • sysfs_get_inode()
                • mutex_unlock()
                • d_make_root()
                  • __d_alloc()
                    • kmem_cache_alloc()
                    • swp_wmb()
                    • spin_lock_init()
                    • seqcount_init()
                    • INIT_HLIST_BL_NODE()
                    • INIT_LIST_HEAD()
                    • INIT_LIST_HEAD()
                    • INIT_HLIST_NODE()
                    • INIT_LIST_HEAD()
                    • d_set_d_op()
                    • this_cpu_inc()
                    • d_instantiate()
                    • __d_instantiate()
                    • d_flags_for_inode()
                    • spin_lock()
                    • dentry_rcuwalk_barrier()
                    • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                    • write_seqcount_barrier()
                    • spin_unlock()
                    • fsnotify_d_instantiate()
                    • spin_lock()
                    • __fsnotify_update_dcache_flags()
                    • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                    • fsnotify_inode_watched_children()
                    • spin_unlock()
                    • spin_unlock()
                    • security_d_instantiate()
// ARM10C 20151114
// type: &sysfs_fs_type, flags: 0x400000, name: "sysfs", data: NULL
static struct dentry *sysfs_mount(struct file_system_type *fs_type,
	int flags, const char *dev_name, void *data)
{
	struct sysfs_super_info *info;
	enum kobj_ns_type type;
	struct super_block *sb;
	int error;

	// flags: 0x400000, MS_KERNMOUNT: 0x400000
	if (!(flags & MS_KERNMOUNT)) {
		if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
			return ERR_PTR(-EPERM);

		for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
			if (!kobj_ns_current_may_mount(type))
				return ERR_PTR(-EPERM);
		}
	}

	// sizeof(struct sysfs_super_info): 8 bytes, GFP_KERNEL: 0xD0
	// kzalloc(8, GFP_KERNEL: 0xD0): kmem_cache#30-oX
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	// info: kmem_cache#30-oX (struct sysfs_super_info)

	// info: kmem_cache#30-oX (struct sysfs_super_info)
	if (!info)
		return ERR_PTR(-ENOMEM);

	// KOBJ_NS_TYPE_NONE: 0, KOBJ_NS_TYPES: 2
	for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
		// type: 0, info->ns[0]: (kmem_cache#30-oX (struct sysfs_super_info))->ns[0],
		// kobj_ns_grab_current(0): NULL
		info->ns[type] = kobj_ns_grab_current(type);
		// info->ns[0]: (kmem_cache#30-oX (struct sysfs_super_info))->ns[0]: NULL

	// fs_type: &sysfs_fs_type, flags: 0x400000, info: kmem_cache#30-oX (struct sysfs_super_info)
	// sget(&sysfs_fs_type, sysfs_test_super, sysfs_set_super, 0x400000, kmem_cache#30-oX (struct sysfs_super_info)): kmem_cache#25-oX (struct super_block)
	sb = sget(fs_type, sysfs_test_super, sysfs_set_super, flags, info);
	// sb: kmem_cache#25-oX (struct super_block)

	// sget에서 한일:
	// struct super_block 만큼의 메모리를 할당 받음 kmem_cache#25-oX (struct super_block)
	//
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(&(&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->lock)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list
	// (&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->count: 0
	// (&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->counters: kmem_cache#26-o0 에서 할당된 4 bytes 메모리 주소
	// list head 인 &percpu_counters에 &(&(kmem_cache#25-oX (struct super_block))->s_writers.counter[0...2])->list를 연결함
	//
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait)->lock을 사용한 spinlock 초기화
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait)->task_list를 사용한 list 초기화
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait_unfrozen)->lock을 사용한 spinlock 초기화
	// &(&(kmem_cache#25-oX (struct super_block))->s_writers.wait_unfrozen)->task_list를 사용한 list 초기화
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->next: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->pprev: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_anon)->first: NULL
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_inodes)->next: &(kmem_cache#25-oX (struct super_block))->s_inodes
	// (&(kmem_cache#25-oX (struct super_block))->s_inodes)->prev: &(kmem_cache#25-oX (struct super_block))->s_inodes
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node: kmem_cache#30-oX
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->active_nodes)->bits[0]: 0
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->raw_lock: { { 0 } }
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->magic: 0xdead4ead
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->owner: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].lock)->owner_cpu: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list)->next: (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list
	// ((&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list)->prev: (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].list
	// (&(kmem_cache#25-oX (struct super_block))->s_dentry_lru)->node[0].nr_items: 0
	// (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node: kmem_cache#30-oX
	// (&(&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->active_nodes)->bits[0]: 0
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->raw_lock: { { 0 } }
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->magic: 0xdead4ead
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->owner: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].lock)->owner_cpu: 0xffffffff
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list)->next: (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list
	// ((&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list)->prev: (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].list
	// (&(kmem_cache#25-oX (struct super_block))->s_inode_lru)->node[0].nr_items: 0
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_mounts)->next: &(kmem_cache#25-oX (struct super_block))->s_mounts
	// (&(kmem_cache#25-oX (struct super_block))->s_mounts)->prev: &(kmem_cache#25-oX (struct super_block))->s_mounts
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_umount)->activity: 0
	// &(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_lock을 사용한 spinlock 초기화
	// (&(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_umount)->wait_list
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_umount)->activity: -1
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->count: 1
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->wait_list
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->onwer: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex)->magic: &(kmem_cache#25-oX (struct super_block))->s_vfs_rename_mutex
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->count: 1
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->wait_list
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->onwer: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex)->magic: &(kmem_cache#25-oX (struct super_block))->s_dquot.dqio_mutex
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->count: 1
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->raw_lock: { { 0 } }
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->magic: 0xdead4ead
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->owner: 0xffffffff
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_lock)->rlock)->owner_cpu: 0xffffffff
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->wait_list
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->onwer: NULL
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex)->magic: &(kmem_cache#25-oX (struct super_block))->s_dquot.dqonoff_mutex
	// (&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->activity: 0
	// &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_lock을 사용한 spinlock 초기화
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list)->next: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list
	// (&(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list)->prev: &(&(kmem_cache#25-oX (struct super_block))->s_dquot.dqptr_sem)->wait_list
	//
	// (kmem_cache#25-oX (struct super_block))->s_flags: 0x400000
	// (kmem_cache#25-oX (struct super_block))->s_bdi: &default_backing_dev_info
	// (kmem_cache#25-oX (struct super_block))->s_count: 1
	// ((kmem_cache#25-oX (struct super_block))->s_active)->counter: 1
	// (kmem_cache#25-oX (struct super_block))->s_maxbytes: 0x7fffffff
	// (kmem_cache#25-oX (struct super_block))->s_op: &default_op
	// (kmem_cache#25-oX (struct super_block))->s_time_gran: 1000000000
	// (kmem_cache#25-oX (struct super_block))->cleancache_poolid: -1
	// (kmem_cache#25-oX (struct super_block))->s_shrink.seeks: 2
	// (kmem_cache#25-oX (struct super_block))->s_shrink.scan_objects: super_cache_scan
	// (kmem_cache#25-oX (struct super_block))->s_shrink.count_objects: super_cache_count
	// (kmem_cache#25-oX (struct super_block))->s_shrink.batch: 1024
	// (kmem_cache#25-oX (struct super_block))->s_shrink.flags: 1
	//
	// idr_layer_cache를 사용하여 struct idr_layer 의 메모리 kmem_cache#21-o0...7를 8 개를 할당 받음
	// (kmem_cache#21-o0...7)->ary[0]: NULL
	// (&(&unnamed_dev_ida)->idr)->id_free: kmem_cache#21-o7
	// (&(&unnamed_dev_ida)->idr)->id_free_cnt: 7
	//
	// struct ida_bitmap 의 메모리 kmem_cache#27-oX 할당 받음
	// (&unnamed_dev_ida)->free_bitmap: kmem_cache#27-oX
	//
	// (&(&unnamed_dev_ida)->idr)->id_free: NULL
	// (&(&unnamed_dev_ida)->idr)->id_free_cnt: 6
	// (&(&unnamed_dev_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer)
	// (&(&unnamed_dev_ida)->idr)->layers: 1
	// (&unnamed_dev_ida)->free_bitmap: NULL
	//
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL
	// (kmem_cache#21-o7 (struct idr_layer))->layer: 0
	// (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap)
	// (kmem_cache#21-o7 (struct idr_layer))->count: 1
	//
	// (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행
	//
	// unnamed_dev_start: 1
	//
	// (kmem_cache#25-oX (struct super_block))->s_dev: 0
	// (kmem_cache#25-oX (struct super_block))->s_bdi: &noop_backing_dev_info
	// (kmem_cache#25-oX (struct super_block))->s_fs_info: kmem_cache#30-oX (struct sysfs_super_info)
	//
	// (kmem_cache#25-oX (struct super_block))->s_type: &sysfs_fs_type
	// (kmem_cache#25-oX (struct super_block))->s_id: "sysfs"
	//
	// list head인 &super_blocks 에 (kmem_cache#25-oX (struct super_block))->s_list을 tail에 추가
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->next: NULL
	// (&(&sysfs_fs_type)->fs_supers)->first: &(kmem_cache#25-oX (struct super_block))->s_instances
	// (&(kmem_cache#25-oX (struct super_block))->s_instances)->pprev: &(&(&sysfs_fs_type)->fs_supers)->first
	//
	// (&(kmem_cache#25-oX (struct super_block))->s_shrink)->flags: 0
	// (&(kmem_cache#25-oX (struct super_block))->s_shrink)->nr_deferred: kmem_cache#30-oX
	// head list인 &shrinker_list에 &(&(kmem_cache#25-oX (struct super_block))->s_shrink)->list를 tail로 추가함

	// sb: kmem_cache#25-oX (struct super_block)
	// IS_ERR(kmem_cache#25-oX (struct super_block)): 0,
	// sb->s_fs_info: (kmem_cache#25-oX (struct super_block))->s_fs_info: kmem_cache#30-oX (struct sysfs_super_info),
	// info: kmem_cache#30-oX (struct sysfs_super_info)
	if (IS_ERR(sb) || sb->s_fs_info != info)
		free_sysfs_super_info(info);

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

	// sb->s_root: (kmem_cache#25-oX (struct super_block))->s_root: NULL
	if (!sb->s_root) {
		// sb: kmem_cache#25-oX (struct super_block), data: NULL, flags: 0x400000, MS_SILENT: 0x8000
		error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
		if (error) {
			deactivate_locked_super(sb);
			return ERR_PTR(error);
		}
		sb->s_flags |= MS_ACTIVE;
	}

	return dget(sb->s_root);
}

dcache.h::dget()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount() : kern_mount_data()
      • vfs_kern_mount()
        • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
              • free_sysfs_super_info()
              • IS_ERR()
              • sysfs_fill_super()
                • mutex_lock()
                • sysfs_get_inode()
                • mutex_unlock()
                • d_make_root()
                  • __d_alloc()
                    • kmem_cache_alloc()
                    • swp_wmb()
                    • spin_lock_init()
                    • seqcount_init()
                    • INIT_HLIST_BL_NODE()
                    • INIT_LIST_HEAD()
                    • INIT_LIST_HEAD()
                    • INIT_HLIST_NODE()
                    • INIT_LIST_HEAD()
                    • d_set_d_op()
                    • this_cpu_inc()
                    • d_instantiate()
                    • __d_instantiate()
                    • d_flags_for_inode()
                    • spin_lock()
                    • dentry_rcuwalk_barrier()
                    • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                    • write_seqcount_barrier()
                    • spin_unlock()
                    • fsnotify_d_instantiate()
                    • spin_lock()
                    • __fsnotify_update_dcache_flags()
                    • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                    • fsnotify_inode_watched_children()
                    • spin_unlock()
                    • spin_unlock()
                    • security_d_instantiate()
            • dget()
static inline struct dentry *dget(struct dentry *dentry)
{
	if (dentry)
		lockref_get(&dentry->d_lockref);
	return dentry;
}

lockref.c::lockref_get()

  • start_kernel()->vfs_caches_init()
  • mnt_init()
  • sysfs_init()
    • kmem_cache_create()
    • sysfs_inode_init()
    • register_filesystem()
    • kern_mount() : kern_mount_data()
      • vfs_kern_mount()
        • alloc_vfsmnt()
          • mount_fs()
            • mount(): sysfs_mount()
              • sget()
                • spin_lock()
                • hlist_for_eash_entry()
                • spin_unlock()
                • alloc_super()
                • set()
                • strlcpy()
                • list_add_tail()
                • hlist_add_head()
                • spin_unlock(&sb_lock)
                • get_filesystem(type)
                • register_shrinker()
              • free_sysfs_super_info()
              • IS_ERR()
              • sysfs_fill_super()
                • mutex_lock()
                • sysfs_get_inode()
                • mutex_unlock()
                • d_make_root()
                  • __d_alloc()
                    • kmem_cache_alloc()
                    • swp_wmb()
                    • spin_lock_init()
                    • seqcount_init()
                    • INIT_HLIST_BL_NODE()
                    • INIT_LIST_HEAD()
                    • INIT_LIST_HEAD()
                    • INIT_HLIST_NODE()
                    • INIT_LIST_HEAD()
                    • d_set_d_op()
                    • this_cpu_inc()
                    • d_instantiate()
                    • __d_instantiate()
                    • d_flags_for_inode()
                    • spin_lock()
                    • dentry_rcuwalk_barrier()
                    • assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                    • write_seqcount_barrier()
                    • spin_unlock()
                    • fsnotify_d_instantiate()
                    • spin_lock()
                    • __fsnotify_update_dcache_flags()
                    • assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
                    • fsnotify_inode_watched_children()
                    • spin_unlock()
                    • spin_unlock()
                    • security_d_instantiate()
            • dget()
              • lockref_get()
/**
 * lockref_get - Increments reference count unconditionally
 * @lockref: pointer to lockref structure
 *
 * This operation is only valid if you already hold a reference
 * to the object, so you know the count cannot be zero.
 */
void lockref_get(struct lockref *lockref)
{
	CMPXCHG_LOOP(
		new.count++;
	,
		return;
	);

	spin_lock(&lockref->lock);
	lockref->count++;
	spin_unlock(&lockref->lock);
}
EXPORT_SYMBOL(lockref_get);
  • 여기에서 USE_CMPXCHG_LOCKREF에서 0이므로 else로 빠져서 do { } while (0)
#if USE_CMPXCHG_LOCKREF

#define CMPXCHG_LOOP(CODE, SUCCESS) do {					\
	struct lockref old;							\
	BUILD_BUG_ON(sizeof(old) != 8);						\
	old.lock_count = ACCESS_ONCE(lockref->lock_count);			\
	while (likely(arch_spin_value_unlocked(old.lock.rlock.raw_lock))) {  	\
		struct lockref new = old, prev = old;				\
		CODE								\
		old.lock_count = cmpxchg64_relaxed(&lockref->lock_count,	\
						   old.lock_count,		\
						   new.lock_count);		\
		if (likely(old.lock_count == prev.lock_count)) {		\
			SUCCESS;						\
		}								\
		arch_mutex_cpu_relax();						\
	}									\
} while (0)

#else

#define CMPXCHG_LOOP(CODE, SUCCESS) do { } while (0)

#endif

void lockref_get(struct lockref *lockref) { // #define CMPXCHG_LOOP(CODE, SUCCESS) do { } while (0) CMPXCHG_LOOP( new.count++; , return; );

spin_lock(&lockref->lock);
lockref->count++;
spin_unlock(&lockref->lock);

} EXPORT_SYMBOL(lockref_get);


* start_kernel()->vfs_caches_init()
 - mnt_init()
  - sysfs_init()
    - kmem_cache_create()
    - sysfs_inode_init()
    - register_filesystem()
    - kern_mount() : kern_mount_data()
      - vfs_kern_mount()
	    - alloc_vfsmnt()
		  - mount_fs()
            - mount(): sysfs_mount()
			  - sget()
		        - spin_lock()
				- hlist_for_eash_entry()
				- spin_unlock()
				- alloc_super()
				- set()
				- strlcpy()
				- list_add_tail()
				- hlist_add_head()
				- spin_unlock(&sb_lock)
				- get_filesystem(type)
				- register_shrinker()
              - free_sysfs_super_info()
			  - IS_ERR()
			  - sysfs_fill_super()
			    - mutex_lock()
				- sysfs_get_inode()
				- mutex_unlock()
				- d_make_root()
				  - __d_alloc()
				    - kmem_cache_alloc()
					  - swp_wmb()
					  - spin_lock_init()
					  - seqcount_init()
					  - INIT_HLIST_BL_NODE()
					  - INIT_LIST_HEAD()
					  - INIT_LIST_HEAD()
					  - INIT_HLIST_NODE()
					  - INIT_LIST_HEAD()
					  - d_set_d_op()
					  - this_cpu_inc()
					- d_instantiate()
					- __d_instantiate()
					  - d_flags_for_inode()
					    - spin_lock()
						- dentry_rcuwalk_barrier()
						  - assert_spin_locked : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
						  - write_seqcount_barrier()
						- spin_unlock()
						- fsnotify_d_instantiate()
						  - spin_lock()
						    - __fsnotify_update_dcache_flags()
							- assert_spin_locked() : assert_raw_spin_locked() : BUG_ON(!raw_spin_is_locked(x))
							- fsnotify_inode_watched_children()
						  - spin_unlock()
						- spin_unlock()
						- security_d_instantiate()
			- dget()
			  - lockref_get()
			    - spin_lock()
				- lockref->count++;
				- spin_unlock()
          - 
		  
```super.c
// ARM10C 20151114
// type: &sysfs_fs_type, flags: 0x400000, name: "sysfs", 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: (&sysfs_fs_type)->fs_flags: 8, 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):
	root = type->mount(type, flags, name, data);

log

  • 1st log
99cb0c4..4e5ea36f master     -> origin/master
Updating 99cb0c4..4e5ea36f
Fast-forward
arch/arm/include/asm/barrier.h |   1 +
fs/dcache.c                    | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/sysfs/dir.c                 |   1 +
fs/sysfs/mount.c               |   1 -
include/asm-generic/bug.h      |   2 ++
include/linux/dcache.h         |  14 +++++++++++
include/linux/fs.h             |   8 +++++++
include/linux/list.h           |  10 ++++++++
include/linux/list_bl.h        |  12 ++++++++++
include/linux/lockdep.h        |   2 ++
include/linux/percpu-defs.h    |   4 ++++
include/linux/percpu.h         |  31 ++++++++++++++++++++++++
include/linux/seqlock.h        |  10 +++++++-
include/linux/spinlock.h       |   4 ++++
include/uapi/linux/stat.h      |   7 ++++++
15 files changed, 288 insertions(+), 2 deletions(-)
  • 2nd log
dbf60ca..c68141d  master     -> origin/master
Updating dbf60ca..c68141d
Fast-forward
Reference/Breakdown/002_linux-kernel_20130504.md |  25 +-
arch/arm/include/asm/spinlock.h                  |   2 +
fs/dcache.c                                      |  85 +++++-
fs/namespace.c                                   | 318 ++++++++++++++++++++++
fs/super.c                                       | 328 ++++++++++++++++++++++-
fs/sysfs/dir.c                                   |   1 +
fs/sysfs/mount.c                                 | 232 +++++++++++++++-
include/linux/dcache.h                           |  15 ++
include/linux/err.h                              |   3 +
include/linux/fsnotify.h                         |   6 +
include/linux/fsnotify_backend.h                 |  36 ++-
include/linux/list.h                             |   2 +
include/linux/lockref.h                          |   1 +
include/linux/security.h                         |   8 +-
include/linux/seqlock.h                          |   8 +
include/linux/spinlock.h                         |  13 +
include/linux/spinlock_api_smp.h                 |   2 +
include/uapi/linux/fs.h                          |   4 +
kernel/locking/rwsem.c                           |   2 +
lib/lockref.c                                    |  18 +-
mm/backing-dev.c                                 |   1 +
21 files changed, 1102 insertions(+), 8 deletions(-)