NAMEI(9)

名称
namei, NDINIT, NDFREE - パス名の変換および検索操作

書式
<sys/param.h> <sys/proc.h> <sys/namei.h> int namei(struct nameidata *ndp) void NDINIT(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg, const char *namep, struct thread *td) void NDFREE(struct nameidata *ndp, const uint flags)

解説
namei の仕組みはクライアントによるパス名の変換および検索の操作を可能にします。 namei 関数は対象の vnode のための参照カウントをインクリメントします。 その参照カウントは、 LOCKLEAF フラグが指定されたかどうかに依存して、 vrele(9) または vput(9) のどちらかを使用して、その vnode の使用後にデクリメントされなければなりません。

NDINIT() 関数は namei の要素を初期化するために使用されます。 これは以下の引数を取ります。

ndp 初期化されるべき struct nameidata 構造体です。

op  namei() が実行する操作です。 LOOKUP, CREATE, DELETE および RENAME の操作が有効です。 後者 3 つはこれらの効果のためのセットアップだけです。 namei() の呼び出しだけでは VOP_RENAME() が呼び出されたような結果にはなりません。

flags
    操作フラグです。 これらの内の幾つかは、同時に有効化されることが可能です。

segflg
    UIO セグメントのインジケータです。 これはオブジェクトの名前がユーザ空間 (UIO_USERSPACE) にあるのかカーネルアドレス空間 (UIO_SYSSPACE) にあるのかを示します。

namep
    構成要素のパス名バッファへのポインタです (検索されるファイル名またはディレクトリ名)。

td  namei の操作およびロックのために使用されるスレッドコンテキストです。

NAMEI 操作フラグ
namei() は操作がどのような影響を及ぼすかという、以下の “操作フラグ” のセットを取ります。

LOCKLEAF
    戻るときに vnode をロックします。 これはその vnode の完全なロックで、ロックを解放するためには VOP_UNLOCK(9) を使用するべきです。 (または vrele(9) が後に続く VOP_UNLOCK(9) の呼び出しを一緒に行うことと等価である vput(9) を使用するべきです。)

LOCKPARENT
    このフラグは ni_vdp と ni_vp が一致しない場合には、 namei() 関数に親 (ディレクトリ) の vnode である ni_dvp がロックされた状態で返されるようにします。 この場合、これ自体では ni_dvp はロックされません (が、 LOCKLEAF のためロックされるかもしれません)。 ロックが実施された場合には、 vput(9) または VOP_UNLOCK(9) と vrele(9) を使用してロックが解放されるべきです。

WANTPARENT
    このフラグは namei() 関数が親 (ディレクトリ) の vnode をロックされていない状態で、 返すようにします。 その親の vnode は vrele(9) を使用して個別に解放されなければなりません。

NOCACHE
    名前キャッシュのエントリが既に存在していない場合には、 namei() が名前キャッシュにこのエントリを作成することを回避します。 通常、そこにエントリが未だない場合には、 namei() は名前キャッシュにエントリを追加します。

FOLLOW
    このフラグがあると、 namei() は与えられたパス名の最後の部分がシンボリックリンクであれば、 シンボリックリンクを辿ります (すなわち、リンクそれ自体の vnode の代わりに、 リンクが指しているところの vnode が返されます)。

NOOBJ
    たとえ VM サポートのための要求された基準を満たしているとしても、 返される vnode のために vfs_object_create() を呼び出しません。

NOFOLLOW
    シンボリックリンクを辿りません (擬似フラグ)。 このフラグは実際のコードによって期待されません。 コードは FOLLOW の有無をみます。 NOFOLLOW は、シンボリックリンクが辿られないことを、 ソースコードの読者に対して意図的に示すために使用されます。

SAVENAME
    呼出し側がそのパス名のバッファにアクセスするかもしれない時のために、 namei() の実行の最後で、パス名のバッファを解放しません。 代わりに後で NDFREE() でその名前バッファを解放します。 詳細は下記を参照してください。

SAVESTART
    親ディレクトリへの追加の参照を維持します。 パス名のバッファを解放しません。 詳細は下記を参照してください。

割当てられた要素
nameidata 構造体は以下のフィールドで構成されます。

ni_startdir
    通常の場合、これは現在のディレクトリまたはルートディレクトリのどちらかです。 渡された名前が ‘/’ で始まっておらず、絶対パスのシンボリックリンクを 通り抜けていない場合には現在のディレクトリで、そうでない場合にはルートです。

    この場合、 lookup() によってのみ使用され、 namei() への呼出しの後で利用可能だとみなされるべきではありません。 SAVESTART が設定されている場合には、追加の vref(9) を伴なった ni_dvp と同様に設定されます。 ni_startdir の解放から NDFREE() をブロックするために、 NDF_NO_STARTDIR_RELE を設定することが可能です。

ni_dvp
    検索が実行されているオブジェクトのディレクトリへの vnode ポインタです。 LOCKPARENT または WANTPARENT が設定されている場合に、成功して戻った時に利用可能です。 LOCKPARENT が設定されている場合にはロックされます。 NDF_NO_DVP_RELE, NDF_NO_DVP_PUT または NDF_NO_DVP_UNLOCK によって、(明らかな効果を伴って) NDFREE() 内の ni_dvp の解放を抑制することが可能です。

ni_vp
    オブジェクトが返されるための vnode ポインタで、そうでなければ NULL です。 この vnode の v_usecount フィールドがインクリメントされます。 LOCKLEAF が設定されている場合には、ロックもされます。

    NDF_NO_VP_RELE, NDF_NO_VP_PUT または NDF_NO_VP_UNLOCK によって、(明らかな効果を伴って) NDFREE() 内の ni_vp の解放を抑制することが可能です。

ni_cnd.cn_pnbuf
    namei 操作によって使用される、 ファイルまたはディレクトリの位置が入っているパス名のバッファです。 これは uma(9) ゾーン割り当てインタフェースによって管理されます。 SAVESTART または SAVENAME フラグが設定されている場合には、そのパス名のバッファは namei() 関数の呼び出し後も利用可能です。

    パス名のバッファ ni_cnd.cn_pnbuf によって使用されているリソースのみを解放するために、 NDF_ONLY_PNBUF フラグを NDFREE() 関数に渡すことが可能です。 パス名のバッファをそのままで保持するために、 ND_NO_FREE_PNBUF フラグを NDFREE() 関数に渡すことが可能です。

関連ファイル

src/sys/kern/vfs_lookup.c

関連項目
uio(9), uma(9), VFS(9), vnode(9), vput(9), vref(9)

作者
-nosplit このマニュアルページは Eivind Eklund <eivind@FreeBSD.org> が書き、その後で Hiten M. Pandya <hmp@FreeBSD.org> が大幅に修正しました。

バグ
LOCKPARENT フラグは常に親の vnode がロックされる結果になるとは限りません。 LOCKPARENT が使用される時には、複雑化する結果となります。 LOCKPARENT および LOCKLEAF の両方が使用される場合のこの問題の解決のために、 再帰的ロックに頼ることが必要になります。