iget (3)
ええと微妙な理解ながら疑似コードに変換してみる。
iget(struct super_block *sb, unsigned long ino) iget_locked(sb, ino) の戻りを inode にセット inode が NULL でなく、inode オブジェクトの i_state が I_NEW なら sb->s_op->read_inode(inode); unlock_new_inode(inode); inode を戻す
tarfs で言えばスデに投入しているエントリによれば、tarfs_read_inode が sb->sop->read_inode 属性にセットされているはず。ここを掘るのは別途。
iget_locked
コメントによれば
マウント済みのファイルシステムから inode 取得
基本的には inode cache からオブジェクトを探して (ifind_fast 手続き) ソコにあればソレを戻す。無かった場合はオブジェクトを (get_new_inode_fast 手続きで) 作る模様。コメントには unlock_new_inode 手続きで unlock するまでに云々とある。
これは上記 iget 手続きの条件分岐の中の処理だな。
- iget_locked は基本的には NULL は戻さない
- i_state が I_NEW なら get_new_inode_fast で作成されたばかり
- read_inode でオブジェクトに必要なナニを設定
- 設定済んだら unlock_new_inode でリセット
というカンジ??
iget_locked(struct super_block *sb, unsigned long ino) struct hlist_head *head の定義と下準備 struct inode *inode の定義 ifind_fast(sb, head, ino) の戻りを inode に設定 inode が NULL でないのであれば inode を返却 get_new_inode_fast(sb, head, ino) の戻りを返却
hash は微妙なので略 (を
ifind_fast
なんか昨日のヤキ直しっぽい気がしますがスルー。
こいつは単純に inode cache 探して無ければそのまま戻るはず (上記の記述が正しければ、ですが)。逆に見つかった時のナニがソレ。
- __iget 手続き呼び出し
- spinlock 解除
- wait_oninode 手続き呼び出し
- inode オブジェクトのポインタ戻す
という形になってます。コメント見ると参照カウントを増分して云々とある。
次
find_inode_fast 手続きなんですが色々見てると hlist_entry マクロで container_of が出てきた。
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
ちなみに hlist_for_each マクロも同じ include/linux/list.h にて定義されてます。で、container_of マクロは include/linux/kernel.h にて定義されてて以下。
/** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
このマクロはあの本に出ていたのを今朝便所にて再度チェキしとります。このマクロが
inode = hlist_entry(node, struct inode, i_hash);
な命令をどう扱うように変換するのか、を確認してみるのは面白いナニではないかと。
と言いつつ
今日は遅いのでもう寝ます。