Virtual File System
Rev.9を表示中。最新版はこちら。
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処理のほとんどを行なう。
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; }
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)して初期化する。
フィールド |
説明 |
---|---|
f_op |
ファイルを操作するハンドラへのポインタを持つstruct file_operationsへのポインタ |
f_pos |
ファイルのRead/Write位置。 |
f_mode |
ファイルのアクセスモード |
f_uid |
ファイルのUser ID |
f_gid |
ファイルのGroup ID |