Linux Kernel(2.6)の実装に関するメモ書き

Virtual File System


Rev.11を表示中。最新版はこちら

1. 概要

sys_open,sys_readなどのシステムコールのエントリルーチンと実際のファイルシステムの間に入るレイヤ。struct fileのf_opに登録されている処理を呼び出すことで実際のファイルシステムへ処理を渡す。

2. 処理概要

2.1 open処理

open()システムコールのエントリルーチンはsys_open()。sys_open()はdo_sys_open()を呼び出す。do_sys_open()はget_unused_fd()により未使用のファイルディスクリプタを取得し、ファイル管理用のfile構造体をdo_filp_open()で生成する。do_filp_open()はopen_namei()を呼び出す。open_namei()は実質open処理のほとんどを行なう。

do_sys_open()の処理概要
long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
{
    char *tmp = getname(filename);
    int fd = PTR_ERR(tmp);

    if (!IS_ERR(tmp)) {
        /* 未使用のファイルディスクリプタを取得 */
        fd = get_unused_fd();
        if (fd >= 0) {
            /* file構造体を取得する */
            struct file *f = do_filp_open(dfd, tmp, flags, mode);
            if (IS_ERR(f)) {
                put_unused_fd(fd);
                fd = PTR_ERR(f);
            } else {
                fsnotify_open(f->f_dentry);
                fd_install(fd, f);
            }
        }
        putname(tmp);
    }
    return fd;
}


open_namei()の処理概要
int open_namei(int dfd, const char *pathname, int flag,
                int mode, struct nameidata *nd)
{
    :

    if (!(flag & O_CREAT)) {
        /*
         * struct nameidata(nd)を作成する。
         * fileも作成されnd->intent.open.fileにポインタが保存される。
         */
        error = path_lookup_open(dfd, pathname, lookup_flags(flag),
                                 nd, flag);
        if (error)
            return error;
        goto ok;
    }
    error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
    if (error)
        return error;
    :
}

2.2 Read処理

read()システムコールのエントリルーチンはsys_read()。sys_read()は渡されたfd(ファイルディスクリプタ)に対応するstruct fileを取得して、VFSのRead処理(vfs_read())を呼び出す。

vfs_read()はパーミッションのチェックなどを行った後、file->f_opに登録されているファイルシステムのReadルーチンを呼び出してファイルシステムに処理をさせる。

sys_read()処理の概要

sys_read(unsigned int fd, char __user * buf, size_t count)
{
    /* ファイルディスクリプタに対応するstruct fileを取得 */
    file = fget_light(fd, &fput_needed);
    if (file) {
        loff_t pos = file_pos_read(file);
        /* Virtual File SystemのRead処理へ */
        ret = vfs_read(file, buf, count, &pos);
        file_pos_write(file, pos);
        fput_light(file, fput_needed);
    }

    return ret;
}

vfs_read()の処理概要

vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
    ret = rw_verify_area(READ, file, pos, count);
    if (ret >= 0) {
        count = ret;
        ret = security_file_permission (file, MAY_READ);
        if (!ret) {
            /* fileが存在するファイルシステムのRead処理の呼び出し */
            if (file->f_op->read)
                ret = file->f_op->read(file, buf, count, pos);
            else
                ret = do_sync_read(file, buf, count, pos);
            if (ret > 0) {
                fsnotify_access(file->f_dentry);
                current->rchar += ret;
            }
            current->syscr++;
        }
    }
    return ret;
}


3. 関連データ

3.1 struct file

open済みのファイルを管理する構造体。ファイルopen時にdo_filp_open()により確保される。

新しいstruct fileを取得するにはget_empty_filp()を使用する。get_empty_filp()はスラブアロケータからstruct fileを取得(キャッシュ名:filp)して初期化する。

表1 struct fileの主なフィールド

フィールド
説明
f_op
ファイルシステムのstruct file_operationsへのポインタ。read,write,ioctlなどのハンドラへのポインタ群を持つ
f_pos
ファイルのRead/Write位置。
f_mode
ファイルのアクセスモード
f_uid
ファイルのUser ID
f_gid
ファイルのGroup ID



最終更新 2006/10/05 02:24:39 - kztomita
(2006/09/26 20:39:20 作成)


リンク
最近更新したページ
検索