読者です 読者をやめる 読者になる 読者になる

久々にramfsを読んでみる

linux
  55struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
  56{
  57        struct inode * inode = new_inode(sb);
  58

new_inode()はスーパーブロック構造体を渡して、新しいinodeの領域を確保してくれる。

  59        if (inode) {
  60                inode->i_mode = mode;
  61                inode->i_uid = current_fsuid();
  62                inode->i_gid = current_fsgid();

fsuidとfsgidはファイルシステムへのアクセス権限のチェックに使用して、通常はeuid、egidと同じらしい。
この2個はlinuxの独自実装みたい。

  63                inode->i_mapping->a_ops = &ramfs_aops;

ramfs_aopsはこんな感じで定義。

 161static const struct super_operations ramfs_ops = {
 162        .statfs         = simple_statfs,
 163        .drop_inode     = generic_delete_inode,
 164        .show_options   = generic_show_options,
 165};

設定する関数は極一部で、ramfsとしては特に独自の実装はない。

  64                inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;

ramfs_backing_dev_infoも構造体。

  48static struct backing_dev_info ramfs_backing_dev_info = {
  49        .ra_pages       = 0,    /* No readahead */
  50        .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK |
  51                          BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
  52                          BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
  53};

この構造体はlinux/include/linux/backing-dev.hで定義していて、
構造体に説明は付いていないけどファイルの先頭にコメントが付いてて、それによると
「low-level device information and state which is propagated up through to high-level code.」

そして、設定が続いていく。

  65                mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
  66                mapping_set_unevictable(inode->i_mapping);
  67                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;

switch文で使ってる、S_XXXはlinux/include/linux/stat.hで定義されている。
定義している内容はstat(2)で使うS_XXXと同じ値。

modeによって、設定する内容が変わって、switch文ではmodeとS_IFMTとアンドを取る。
caseで使うフラグは以下のとおり
・S_IFREGは通常ファイル
・S_IFDIRはディレクトリ
・S_IFLNKはシンボリックリンク
上の3意外ならdefaultに入る。

  68                switch (mode & S_IFMT) {
  69                default:
  70                        init_special_inode(inode, mode, dev);
  71                        break;
  72                case S_IFREG:
  73                        inode->i_op = &ramfs_file_inode_operations;
  74                        inode->i_fop = &ramfs_file_operations;
  75                        break;
  76                case S_IFDIR:
  77                        inode->i_op = &ramfs_dir_inode_operations;
  78                        inode->i_fop = &simple_dir_operations;
  79
  80                        /* directory inodes start off with i_nlink == 2 (for "." entry) */
  81                        inc_nlink(inode);
  82                        break;
  83                case S_IFLNK:
  84                        inode->i_op = &page_symlink_inode_operations;
  85                        break;
  86                }
  87        }
  88        return inode;
  89}

ramfs_mknod()、ramfs_symlink()、ramfs_fill_super()がこの関数を呼んでinodeを取得している。
これで、ramfs_fill_super()は読んだのでつぎは、別の関数を見よう。