EN JA
NAMEI(9)
NAMEI(9) FreeBSD Kernel Developer's Manual NAMEI(9)

名称

namei, NDINIT, NDFREE, NDHASGIANTパス名の変換と検索操作

書式

#include < sys/param.h>
#include < sys/fcntl.h>
#include < 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);

int
NDHASGIANT( struct nameidata *ndp);

解説

namei 機能によって、クライアントは、パス名の変換と検索の操作を実行することができます。 namei 関数は、対象の vnode のための参照カウントをインクリメントします。その参照カウントは、 LOCKLEAF フラグが指定されたかどうかに依存して、 vrele(9) または vput(9) のどちらかを使用して、その vnode の使用後にデクリメントされなければなりません。 Giant ロックが要求されるなら、 namei は、呼び出し側が、それが MPSAFE であることを示すなら、それを取得します。その場合、呼び出し側は、 NDHASGIANT() の結果をふまえて Giant を後で解放しなければなりません。

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

ndp
初期化されるべき struct nameidata 構造体です。
op
namei() が実行する操作です。 LOOKUP, CREATE, DELETERENAME の操作が有効です。後者 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_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 が返されます)。
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_vp
オブジェクトが返されるための vnode ポインタで、そうでなければ NULL です。この vnode の v_usecount フィールドがインクリメントされます。 LOCKLEAF が設定されている場合には、ロックもされます。

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

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

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

戻り値

成功するなら、 namei() は、0 を返し、そうでなければ、エラーを返します。

関連ファイル

src/sys/kern/vfs_lookup.c

エラー

namei() が返すエラーは、次の通りです:
[ ENOTDIR]
ディレクトリが予想されるとき、指定されたパス名の構成要素が、ディレクトリではありません。
[ ENAMETOOLONG]
パス名の構成要素が、255 文字を超えたか、または全体のパス名が、 1023 文字を超えています。
[ ENOENT]
指定されたパス名の構成要素が存在していないか、パス名が空の文字列です。
[ EACCES]
そのファイルアクセスパーミッションによって禁断の方法でファイルにアクセスすることを試みます。
[ ELOOP]
パス名の変換であまりに多くのシンボリックリンクに遭遇しました。
[ EISDIR]
指定されたモードの書き込みで、ディレクトリをオープンすることを試みます。
[ EINVAL]
DELETE または RENAME 操作のために指定されたパス名の最後の構成要素が、‘ .’です。
[ EROFS]
読み込み専用ファイルシステムでファイルまたはディレクトリを変更することを試みます。

作者

このマニュアルページは、 Eivind Eklund <eivind@FreeBSD.org>によって書かれ、その後で Hiten M. Pandya <hmp@FreeBSD.org>によって大幅に修正されました。

バグ

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

呼び出し側が条件付きで Giant をアンロックするのが必要であることで、非 MPSAFE ファイルシステムは、存在しています。

March 1, 2012 FreeBSD