ファイルディスクリプタ(その2)
Rev.2を表示中。最新版はこちら。
ファイルディスクリプタは、openシステムコールでファイル名に対するinodeを検索し、空のfile構造体配列インデックスとしてそこに設定するというものでした。従ってファイルディスクリプタを引数でread,writeを呼び出せば、目的のfile構造体が得られ、そのinodeのfile_operation,inode_operationのコールバックで、read,write等の処理が可能となるわけです。そこでふと疑問がわいてきました。openはinodeを取得するものです。それなのにinodeが分からないと呼び出すことができないfile_operatinのopenコールバックってなに? ということです。でも、ちょっと考えると、たぶんopenでファイルディスクリプタを取得できたのちに呼び出される初期設定みたいなものかなと・・・。でもせっかくだから向学もかねて、はてなのnaoyaさんよろしく深追いってやつに挑戦してみました。
openはdo_sys_openからのdo_filp_openがその実態になります。そこではファイル名によりCREATEの場合path_lookup_creatがそうでない場合、path_lookup_openが呼び出され、nameidataを取得します。それを引数にしてnameidata_to_filpからの__dentry_openでfile構造体を設定し、その時file_opreationのopenコールバック関数が定義されていたら呼び出すようになっていました。
do_sys_open do_filp_open path_lookup_open(dfd, pathname, LOOKUP_PARENT, path_lookup_create(dfd, pathname, LOOKUP_PARENT, nameidata_to_filp __dentry_open { f->f_mapping = inode->i_mapping; f->f_path.dentry = dentry; f->f_path.mnt = mnt; f->f_pos = 0; f->f_op = fops_get(inode->i_fop); f->f_mapping = inode->i_mapping; f->f_path.dentry = dentry; f->f_path.mnt = mnt; f->f_pos = 0; f->f_op = fops_get(inode->i_fop); file_move(f, &inode->i_sb->s_files); error = security_dentry_open(f); if (error) goto cleanup_all; if (!open && f->f_op) open = f->f_op->open; if (open) { error = open(inode, f); <- ここでfile_operationのopenの呼び出し if (error) goto cleanup_all; } }