ramfs


Rev.1を表示中。最新版はこちら

ramfsはfs/ramfs配下にそのソースがある。中を見るとコーディングの少なさに驚かされる。まるでファイルシステムモジュールのサンプルスケルトンのようで、これでRAMディスクが構築来るのかと。

実はramfsというのは、Linuxの要素コンポーネントであるVFSとページキャッシュで成せる技と言える。ユーザが見るファイル構造はVFSのそれを見ている。そしてVFSのストレージはページ゙キャッシュとも言える。ext2/ex3のような物理デバイス下のファイルシステムも、VFSから見ると、ある意味RAMディスクと言えなくはない。そしてその物理デバイスは、そのバックアップと言う風にみると、ramfsの実装が見えてくる。

ファイル処理では、そのinodeオペレーションのコールバック関数がコールされる。inodeを操作するものと、ブロックを操作するものを、ファイルとディレクトリにfile_operations、 inode_operationsとしてそれぞれ定義している。そして実際の物理デバイスとのやり取りとしてはaddress_space_operationsで定義する。

VFSからファイルの読み込みでは、ページキャッシュに目的のデータが無いときのみ、address_space_operationsで設定されるreadpageがコールされる。

下記はディレクトリのinode_operationsで、
static const struct inode_operations ramfs_dir_inode_operations = {
       .create         = ramfs_create,
       .lookup         = simple_lookup,
       .link           = simple_link,
       .unlink         = simple_unlink,
       .symlink        = ramfs_symlink,
       .mkdir          = ramfs_mkdir,
       .rmdir          = simple_rmdir,
       .mknod          = ramfs_mknod,
       .rename         = simple_rename,
};
ramfs_mkdirはどのようになっているかというと、
static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
{
       int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0);
 :
}

static int
ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
{
       struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev);
 :
 :
}

struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
{
       struct inode * inode = new_inode(sb);

       if (inode) {
               inode->i_mode = mode;
               inode->i_uid = current->fsuid;
               inode->i_gid = current->fsgid;
               inode->i_blocks = 0;
               inode->i_mapping->a_ops = &ramfs_aops;
               inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
               mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
               switch (mode & S_IFMT) {
               default:
                       init_special_inode(inode, mode, dev);
                       break;
               case S_IFREG:
                       inode->i_op = &ramfs_file_inode_operations;
                       inode->i_fop = &ramfs_file_operations;
                       break;
               case S_IFDIR:
                       inode->i_op = &ramfs_dir_inode_operations;
                       inode->i_fop = &simple_dir_operations;

                       /* directory inodes start off with i_nlink == 2 (for "." entry) */
                       inc_nlink(inode);
                       break;
               case S_IFLNK:
                       inode->i_op = &page_symlink_inode_operations;
                       break;
               }
       }
       return inode;
}
new_inode関数は、スーパブロックオペレーションのalloc_inodeコールバック関数が定義されているなら、それを、そうでないならkmem_cache_alloc関数としてinodeを取得する。ramfsではalloc_inodeは定義されていない。ext2/ex3なら、ここで、がりがりとinodeを取得の処理となるわけだ。要は実デバイスにかかる処理は行っていないと言う事だ。これは他のコールバック関数についても当てはまる。(たぶん)

それでは、実デバイスとやり取りするaddress_space_operations はどのようになっているのだろうか?
const struct address_space_operations ramfs_aops = {
       .readpage       = simple_readpage,
       .write_begin    = simple_write_begin,
       .write_end      = simple_write_end,
       .set_page_dirty = __set_page_dirty_no_writeback,
};
simple_readpage関数はページキャッシュがないということで、ページキャッシュをアロケートして、そのページを引数としてコールされる。simple_readpage関数はpageを0クリアする処理のようで、readでこの関数をコールすれば、結果は0ということだ。実はこの処理で悩んでしまった。これではいくらreadしてもnullしか返ってこないのではと。でもよくよく考えると、ramディスクであり、この関数が呼ばれるということは、すでにwriteでこのファイ内容を作成済みということだ。従ってこのページはすぜにページキャッシュ上にあるわけで、たぶんファイルフォール等のケースで呼ばれる事を想定しての処理ではないかと・・・。
int simple_readpage(struct file *file, struct page *page)
{
       clear_highpage(page);
       flush_dcache_page(page);
       SetPageUptodate(page);
       unlock_page(page);
       return 0;
}
write時の場合、simple_write_begin、simple_commit_write、simple_commit_write関数とコールされ、ページキャッシュを獲得し、書き込みデータがページサイズに満たない末端部を0クリアし、inodeにそのサイズを設定し、ページにPG_uptodateおよび汚れているのマークを付けているだけのようである。

上で見てきたようにramfsは完全にページキャッシュに依存した実装になっており、従ってかかる機能はページキャッシュのそれに依存するとも言える。ページキャッシュはメモリーの許す限り獲得される(たぶん)。したがってramfsのサイズは不定で、物理メモリの許す限り増えていくと言う訳だ。


最終更新 2010/06/02 18:21:57 - north
(2010/06/02 18:21:57 作成)


検索

アクセス数
3575654
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。