iget (2)

メモリiノードの確保という文書によると iget は疑似コード的に表現すると以下らしい

iget(iノード番号)
    if(上記iノードキャッシュ内に目的のiノードが見つかった)
        return 見つかったiノード
    iノード番号に対応するメモリiノードを作成する(get_new_inode関数)
    return 新規に作成したiノード

との事。おそらくこの文書は相当古いものではないか、と判断。
ちょっと 2.6.20 方面をざくざくっと掘っておいてメモだけ残します。

iget

include/linux/fs.h にて以下な定義

static inline struct inode *iget(struct super_block *sb, unsigned long ino)
{
	struct inode *inode = iget_locked(sb, ino);
	
	if (inode && (inode->i_state & I_NEW)) {
		sb->s_op->read_inode(inode);
		unlock_new_inode(inode);
	}

	return inode;
}

引数は struct super_block なオブジェクトと i ノード番号な模様。

iget_locked

定義は fs/inode.c で以下

struct inode *iget_locked(struct super_block *sb, unsigned long ino)
{
	struct hlist_head *head = inode_hashtable + hash(sb, ino);
	struct inode *inode;

	inode = ifind_fast(sb, head, ino);
	if (inode)
		return inode;
	/*
	 * get_new_inode_fast() will do the right thing, re-trying the search
	 * in case it had to block at any point.
	 */
	return get_new_inode_fast(sb, head, ino);
}

EXPORT_SYMBOL(iget_locked);

なんとなくキャッシュから探して云々な処理に見える。ええと hash は fs/inode.c の以下なのかなぁ。

static unsigned long hash(struct super_block *sb, unsigned long hashval)
{
	unsigned long tmp;

	tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) /
			L1_CACHE_BYTES;
	tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS);
	return tmp & I_HASHMASK;
}

あるいは ifind_fast も fs/inode.c にて定義。

static struct inode *ifind_fast(struct super_block *sb,
		struct hlist_head *head, unsigned long ino)
{
	struct inode *inode;

	spin_lock(&inode_lock);
	inode = find_inode_fast(sb, head, ino);
	if (inode) {
		__iget(inode);
		spin_unlock(&inode_lock);
		wait_on_inode(inode);
		return inode;
	}
	spin_unlock(&inode_lock);
	return NULL;
}

もう少しゆっくり検討する時間が欲しいなぁ。なんとなくざくっと意味は分かる気がするんですが、先に引用した疑似コードの意図と何となく合致はしているか。

ちょっと追記

struct inode 型の i_state 属性。include/linux/fs.h にてフラグが定義されている模様。

/* Inode state bits.  Protected by inode_lock. */
#define I_DIRTY_SYNC		1 /* Not dirty enough for O_DATASYNC */
#define I_DIRTY_DATASYNC	2 /* Data-related inode changes pending */
#define I_DIRTY_PAGES		4 /* Data-related inode changes pending */
#define __I_LOCK		3
#define I_LOCK			(1 << __I_LOCK)
#define I_FREEING		16
#define I_CLEAR			32
#define I_NEW			64
#define I_WILL_FREE		128

#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)

struct inodeな LKHJ に記述あり。そろそろ寝ます。