1. 程式人生 > >筆記 Linux檔案系統的初始化

筆記 Linux檔案系統的初始化

uboot結束時呼叫start_kernel(/3.1.10/init/main.c)函式啟動linux

start_kernel做記憶體初始化,作業系統資料結構初始化,排程系統初始化,各種資源初始化之後會呼叫vfs_caches_init初始化檔案系統(/3.1.10/fs/dcache.c)

vfs_cache_init:

vfs_cache_init呼叫inode_init(/3.1.10/fs/inode.c)初始化inode資料結構,就是申請一大片記憶體,雜湊表;

vfs_cache_init呼叫files_init(/3.1.10/fs/file_table.c)初始化檔案控制代碼資料結構;

vfs_cache_init呼叫mnt_init(/3.1.10/fs/namespace.c)掛載根檔案系統"/";

vfs_cache_init呼叫bdev_cache_init(/3.1.10/fs/block_dev.c)初始化塊裝置檔案系統;

vfs_cache_init呼叫chrdev_init(/3.1.10/fs/char_dev.c)初始化字元裝置檔案系統。

mnt_init:

mnt_init呼叫sysfs_init(/3.1.10/fs/mount.c)註冊"sysfs"型別的檔案系統

    sysfs_init呼叫sysfs_inode_init(/3.1.10/fs/inode.c)

        sysfs_inode_init呼叫bdi_init(&sysfs_backing_dev_info)初始化backing_dev(???)

    sysfs_init呼叫register_filesystem(&sysfs_fs_type)(/3.1.10/fs/filesystem.c)註冊型別為"sysfs"的檔案系統

        register_filesystem將sysfs_fs_type新增到file_systems的全域性連結串列中

    sysfs_init再呼叫kern_mount(/3.1.10/fs/namespace.c)將sysfs_fs_type繫結

        kern_mount_data呼叫vfs_kern_mount

            vfs_kern_mount呼叫alloc_vfsmnt分配一個mount的資料結構

                alloc_vfsmnt呼叫mnt_alloc_id分配一個mount id

                alloc_vfsmnt初始化mount資料結構中的各種連結串列,包括mnt_hash,mnt_child,mnt_mounts等等

            vfs_kern_mount呼叫mount_fs(/3.1.10/fs/super.c)繫結檔案系統,得到一個dentry

                mount_fs呼叫file_system_type的mount回撥函式執行繫結

                    這裡進入sysfs_fs_type的回撥也就是sysfs_mount函式

                    sysfs_mount分配私有資料

                    sysfs_mount呼叫sget來獲取一個superblock

                        sget呼叫alloc_super分配superblock

                            alloc_super分配superblock結構

                            alloc_super初始化superblock的各種連結串列和互斥量

                        sget設定sb的私有資料

                        sget將sb的s_id設定為檔案系統的名字

                        sget將sb新增到全域性連結串列super_blocks中

                        sget將此sb新增到檔案系統的自身的fs_supers連結串列中

                    sysfs_mount呼叫sysfs_fill_super設定sb的資料

                        sysfs_fill_super設定sb的操作為sysfs_ops

                        sysfs_fill_super呼叫sysfs_get_inode(&sysfs_root)分配一個inode(sysfs_root是預定義的sysfs_dirent型別全域性變數,name為“”,ino為1)

                            sysfs_get_inode呼叫iget_locked

                                iget_locked呼叫find_inode_fast在sb的已分配的inode雜湊表中查詢指定ino的inode

                                如果找到,會呼叫wait_on_inode鎖住該inode並返回

                                這裡顯然找不到, 

                                    所以呼叫alloc_inode分配inode

                                        alloc_inode分配inode節點

                                        alloc_inode呼叫inode_init_always初始化inode

                                            inode_init_always初始化inode,記錄所屬sb,初始inode的uid,gid,各種標誌,預設操作等

                                    iget_locked新增本次查詢到inode的雜湊連結串列

                                    iget_locked新增sb到inode的sb連結串列

                                    iget_locked設定I_NEW標誌並返回鎖定狀態下的inode

                            sysfs_getinode檢測到返回的inode設定了I_NEW標誌,呼叫sysfs_init_inode

                                sysfs_init_inode記錄inode所對應的sysfs_dirent為inode的私有資料

                                sysfs_init_inode設定inode的inode操作為sysfs_inode_operations(包含許可權檢查,設定屬性,讀取屬性等操作)

                                sysfs_init_inode檢查到型別為DIR,重新設定inode的inode操作為sysfs_dir_inode_operations(包含查詢,許可權檢查,設定屬性,讀取屬性等操作)

                                sysfs_init_inode設定inode的檔案操作為sysfs_dir_operations(包含讀,讀目錄,釋放,檔案seek等操作)

                                sysfs_init_inode呼叫unlock_new_inode解鎖inode,去掉I_NEW標誌並返回

                        sysfs_fill_super呼叫d_alloc_root為inode分配一個根目錄的dentry

                            d_alloc_root呼叫__d_alloc,引數中name為“/”,sb為inode的sb

                                __d_alloc分配dentry結構

                                __d_alloc儲存dentry的名稱

                                __d_alloc初始化dentry的各變數和列表,置操作函式為空

                                __d_alloc根據sb的操作函式設定dentry的Hash,比較,刪除等標誌

                           d_alloc_root呼叫d_instantiate填充dentry的inode資訊

                                d_instantiate呼叫__d_instantiate將inode指標設定到dentry的d_inode中

                        sysfs_fill_super設定新建的dentry的d_fsdata為sysfs_root(包含根目錄的目錄標誌,模式(許可權屬性),ino為1)

                        sysfs_fill_super設定新建的dentry為sb的根dentry(s_root)

                   sysfs_mount呼叫dget來鎖定所獲得的superblock的dentry並返回此dentry

            vfs_kern_mount將返回的dentry儲存到mount結構的mnt_root中作為該檔案系統的根節點,

            vfs_kern_mount記錄mount點的sb為dentry的superblock,記錄mount的mount_point為dentry,返回所建立的mount結構

        kern_mount_data呼叫mnt_make_longterm記錄mount為長期不釋放的

        kern_mount_data返回

    sysfs_init返回

mnt_init呼叫init_rootfs(/3.1.10/fs/ramfs/inode.c)註冊"rootfs"檔案系統

    init_rootfs呼叫bdi_init(&ramfs_backing_dev_info)新增一個backing_dev(ramfs_backing_dev_info中描述了ramfs檔案系統的能力(如WRITEBACK等))

    inti_rootfs呼叫register_filesystem(&rootfs_fs_type)註冊名稱為"rootfs"的檔案系統

mnt_init呼叫init_mount_tree(/3.1.10/fs/namespace.c)繫結“rootfs”檔案系統並設定當前工作目錄為rootfs的根目錄

    init_mount_tree呼叫do_kern_mount繫結"rootfs"檔案系統

        do_kern_mount先呼叫get_fs_type得到先前註冊的rootfs檔案系統

        do_kern_mount呼叫vfs_kern_mount繫結檔案系統

            vfs_kern_mount呼叫alloc_vfsmnt分配mount資料

            vfs_kern_mount呼叫mount_fs繫結

                與前相同,mount_fs呼叫mount回撥函式,這裡進入rootfs_mount函式

                    rootfs_mount呼叫mount_nodev進行繫結

                        mount_nodev呼叫sget建立新的superbloack

                        mount_nodev呼叫fill_super填充新的sb,這裡fill_super是回撥函式,進入ramfs_fill_super

                            ramfs_fill_super呼叫ramfs_get_inode建立新的inode

                                ramfs_get_inode呼叫new_inode分配一個新的inode

                                ramfs_get_inode呼叫get_next_ino設定一個新的ino

                                由於有DIR標誌,ramfs_get_inode設定inode的inode操作為ramfs_dir_inode_operations

                                由於有DIR標誌,ramfs_get_inode設定inode的目錄操作為simple_dir_operations

                            ramfs_fill_super呼叫d_alloc_root在inode上建立一個dentry(這裡目錄名為"/")

                            ramfs_fill_super設定superblock的根目錄為新建立的dentry

                    rootfs_mount返回

            vfs_kern_mount將返回的dentry儲存到mount結構的mnt_root中作為該檔案系統的根節點,

            vfs_kern_mount記錄mount點的sb為dentry的superblock,記錄mount的mount_point為dentry,返回所建立的mount結構

        do_kern_mount呼叫put_filesystem解鎖所繫結的檔案系統並返回mount點

    init_mount_tree呼叫create_mnt_ns在繫結點上建立一個namespace

    init_mount_tree建立一個路徑root,root的繫結點設定為剛建立的mount點,root的dentry設定為剛建立的mount點的根dentry

    init_mount_tree呼叫set_fs_pwd設定當前目錄為路徑root(即rootfs的根目錄)(資訊記錄在當前task的fs資料中)

    init_mount_tree呼叫set_fs_root設定當前根目錄為路徑root(即rootfs的根目錄)(資訊記錄在當前task的fs資料中)