vfs_mount と vfs_cmount2006年08月01日 13時34分22秒

mount_XXX 実行時のカーネル内の操作は二段階らしい。

なお、前回のものも含めて、私自身で FreeBSD 6.1 のソースを読んで理解したことを書いている。もし、私のソースコードの読み方が間違っていたら、これらの記述も間違っていることになる。もし、間違いがあったら、是非指摘して欲しい。BSD 関連のデザインの本を一冊持っていたが、今はどこにあるのやら。

さて、mount_XXX が呼び出されると、カーネル内で XXX ファイルシステムに対応する vfs_mount が呼ばれ、その後に vfs_cmount が呼ばれる。mount はマウントの下層領域を確保し、各種 mount の為の動作をする。その後に呼ばれる、cmount がオプションをカーネルにコピーした後にマウントの作業を完了させる。

第一段階の vfs_mount はまずデバイスを確保し、オプションの解析を行なうらしい。ufs や ntfs 等の場合は、パーティションやスライスがデバイスに当たる。smbfs はネットワークを介したファイルシステムなので、FreeBSD 上では smbiod というカーネルプロセスが作られて、smbfs の上層はこの smbiod を介して、サーバと通信をする。見てはいないが、nfs なども似たような機構を持っていると予想される。nfs の場合は、システムの起動時に nfsd を起動しておくことが多いが。

smbfs や ntfs の vfs_mount は以下のように宣言されている。


static int
smbfs_mount(struct mount *mp, struct thread *td)


static int
ntfs_mount (
        struct mount *mp,
        struct thread *td )

同じ、mount *mp 構造体を取る。これらは、各自の構造体に戻されて、処理される。文字コードの変換や、その他のオプションも各種 vfs_mount に処理されている。

それに引き替え、vfs_cmount はオプションをカーネル内に保存するためだけのようだ。


static int
smbfs_cmount(struct mntarg *ma, void * data, int flags, struct thread *td)
{
        struct smbfs_args args;
        int error;

        error = copyin(data, (caddr_t)&args, sizeof(struct smbfs_args));
        if (error)
                return error;


static int
ntfs_cmount (
        struct mntarg *ma,
        void *data,
        int flags,
        struct thread *td )
{
        int error;
        struct ntfs_args args;

        error = copyin(data, (caddr_t)&args, sizeof args);
        if (error)
                return (error);
        ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN);
        ma = mount_arg(ma, "export", &args.export, sizeof args.export);
        ma = mount_argf(ma, "uid", "%d", args.uid);
        ma = mount_argf(ma, "gid", "%d", args.gid);
        ma = mount_argf(ma, "mode", "%d", args.mode);
        ma = mount_argb(ma, args.flag & NTFS_MFLAG_CASEINS, "nocaseins");
        ma = mount_argb(ma, args.flag & NTFS_MFLAG_ALLNAMES, "noallnames");
        if (args.flag & NTFS_MFLAG_KICONV) {
                ma = mount_argsu(ma, "cs_ntfs", args.cs_ntfs, 64);
                ma = mount_argsu(ma, "cs_local", args.cs_local, 64);
        }

        error = kernel_mount(ma, flags);

        return (error)
}

smbfs と ntfs のどちらも、最初に copyin でユーザ空間から、mount_XXX へのオプションを持ってきている。smbfs より短い ntfs の方のコードを全部取ったが、他の種類のファイルシステムでもやっていることは、同じような処理だった。

前回