generic_file_write()
1. 概要
ファイルシステム上のファイルにWriteするための汎用ルーチンgeneric_file_write()の解説。
generic_file_write()はファイルへの書き込みの際にVirtual File Systemのレイヤから呼び出される(図1)(*1)。generic_file_write()はVirtual File Systemから渡された書き込みデータを指定ファイルのページキャッシュに書き込み、Dirty状態にしておく。ページキャッシュへの書き込みのみでディスクへの書き込みはここでは行われない(*2)。ページキャッシュがDirty状態になっているので、ディスクには遅延して書き込まれる。
図1 generic_file_write()での書き込み処理
(*1) 各ファイルシステムのstruct file_operationsのwriteにgeneric_file_write()が登録されており、Virtual File Systemからfile->f_op->write()のようにして呼び出される。本関数を使用しないファイルシステムもある。
(*2) O_SYNCが指定されていた場合などは除く。
2. generic_file_write()の動作
generic_file_write()のプロトタイプは以下のとおり。
ssize_t generic_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
fileは書き込み対象ファイル。buf,countは書き込みデータのバッファとバッファサイズ。pposはファイル内の書き込み位置を示す。
generic_file_write()は図1に示すように関数を呼び出し、ページキャッシュへの書き込みはgeneric_file_buffered_write()で行われる。
generic_file_buffered_write()は主に以下の手順でデータの書き込みを行う。
(2) ページキャッシュへのデータの書き込み
(3) commit_write処理 (書き込み後処理 - FS固有)
2.1 prepare_write処理
a_ops->prepare_write()を呼び出して、ファイルシステム固有のprepare_write処理を行う(a_opsは struct address_space_operations *で各ファイルシステム毎に提供される)。
prepare_write処理では、書き込みの準備作業を行う。
Ext2など多くのファイルシステムでは、prepare_write処理において、block_prepare_write()を呼び出して、書き込み対象のページキャッシュに対してBufferの割り当て、ディスクブロックの割り当てを行う。
Ext3などファイルシステムによってはジャーナリングの開始など追加の処理も行う。
2.2 ページキャッシュへのデータの書き込み
filemap_copy_from_user()でユーザ空間上の書き込みバッファのデータを対応ファイルのページキャッシュにコピーする。
2.3 commit_write処理
a_ops->commit_write()を呼び出して、ファイルシステム固有のcommit_write処理を行う。
commit_write処理では、書き込みの終了処理を行う。
基本的な処理は汎用ルーチンgeneric_commit_write()で行われる。generic_commit_write()は書き込んだ領域のPage,BufferをDirty状態にして後からデータがディスクに書き込まれるようにする。
ファイルシステムによってはここで、ジャーナリングの停止処理も行う。