スポンサーリンク

VOP_LOCK(9) FreeBSD カーネル開発者マニュアル VOP_LOCK(9)

名称

VOP_LOCK, VOP_UNLOCK, VOP_ISLOCKED, vn_lock − vnode アクセスの直列化

書式

#include <sys/param.h>
#include <sys/lock.h>
#include <sys/vnode.h>

int

VOP_LOCK(struct vnode *vp, int flags, struct thread *td);

int

VOP_UNLOCK(struct vnode *vp, int flags, struct thread *td);

int

VOP_ISLOCKED(struct vnode *vp, struct thread *td);

int

vn_lock(struct vnode *vp, int flags, struct thread *td);

解説

これらの呼び出しは、ファイルシステムへのアクセスを直列化するために使用さ れます。例えば、同一ファイルに対する 2 つの書き込みが同時に発生することを 避けるために使用します。

引数は以下の通りです。

       vp

ロックまたはロック解除される vnode。

flags
以下のロック要求タイプのひとつ。

LK_SHARED 共有ロック

LK_EXCLUSIVE 排他的ロック

LK_UPGRADE 共有から排他的へのアップグレード

LK_EXCLUPGRADE 最初の共有から排他的へのアップグレード

LK_DOWNGRADE 排他的から共有へのダウングレード

LK_RELEASE 全てのロックタイプの解除

LK_DRAIN ロック状態終了までの待機

ロックタイプは、以下のロックフラグと OR されているかもしれません。

LK_NOWAIT ロックを待つために sleep しない
LK_SLEEPFAIL sleep して、失敗を返す
LK_CANRECURSE 再帰的排他的ロックを認める
LK_REENABLE ロック消失後再有効化されるべき
LK_NOPAUSE 空回りしない

ロックタイプは、以下の制御フラグと OR されているかもしれません。

LK_INTERLOCK 呼び出し側が既に簡易ロックを保持している時に 指定 (VOP_LOCK はロックを取得した後で簡易 ロックを解除します)
LK_RETRY ロックされるまでリトライ
LK_NOOBJ オブジェクトを作成しない

       td

ロックを使用するためのスレッドコンテキスト。

カーネルコードは vnode をロックするために VOP_LOCK() を直接呼び出さずに、 vn_lock() を使用するべきです。

戻り値

成功時には 0 が返され、そうでない場合にはエラーが返されます。

疑似コード

struct vopnode {
    int von_flag;
    /*
     * 他のファイルシステム固有データ
     */
    ...;
};

#define VON_LOCKED

1

#define VON_WANTED

2

#define VTOVON(vp)

((struct vopnode *) (vp)->v_data)

int
vop_lock(struct vnode *vp)
{
struct vopnode* vop;

start:
while (vp->v_flag & VXLOCK) {

vp->v_flag |= VXWANT;

tsleep((caddr_t)vp, PINOD, "voplk1", 0);

}
if (vp->v_tag == VT_NON)

return ENOENT;

vop = VTOVON(vp);
if (vop->von_flag & VON_LOCKED) {

vop->von_flag |= VON_WANTED;

tsleep((caddr_t) vop, PINOD, "voplk2", 0);

goto start;

}

vop->von_flag |= VON_LOCKED;

return 0;
}

int
vop_unlock(struct vnode *vp)
{
struct vopnode *vop = VTOVON(vp);

if ((vop->von_flag & VON_LOCKED) == 0) {

panic("vop_unlock not locked");

}
vop->von_flag &= ~VON_LOCKED;
if (vop->von_flag & VON_WANTED) {

vop->von_flag &= ~VON_WANTED;

wakeup((caddr_t) vop);

}

return 0;
}

int
vop_islocked(struct vnode *vp)
{
struct vopnode *vop = VTOVON(vp);

if (vop->von_flag & VON_LOCKED)

return 1;

else

return 0;

}

関連項目

vnode(9)

作者

このマニュアルページは Doug Rabson が書きました。

FreeBSD 10.0 July 24, 1996 FreeBSD 10.0

スポンサーリンク