xv6 のsystemcallは次の21種類(因みに、linux2.6で190近くある).
// process start extern int sys_exec(void); // operation towards a file(s) extern int sys_chdir(void); extern int sys_close(void); extern int sys_dup(void); extern int sys_fstat(void); extern int sys_link(void); extern int sys_mkdir(void); extern int sys_mknod(void); extern int sys_open(void); extern int sys_pipe(void); extern int sys_read(void); extern int sys_unlink(void); extern int sys_write(void); // operation towards a process(es) extern int sys_exit(void); extern int sys_fork(void); extern int sys_getpid(void); extern int sys_kill(void); extern int sys_sbrk(void); extern int sys_sleep(void); extern int sys_wait(void); extern int sys_uptime(void);
この中で関数の実態に関しては、前回触れたexecを除き、file処理系関連のsyscallの12コはsysfile.cに、process処理関連の8コはsysproc.cに書かれている。
file処理系の12コだが、一言file処理といっても様々あり、以下のように分類しよう。
対象となる構造体 | 処理 | 該当するsystemcall |
---|---|---|
file | create | open |
file | read | |
file | mutate | pipe,dup |
file | remove | close |
inode | create | mkdir, mknod, open(create mode) |
inode | read | fstat,read |
inode | mutate | write,link,chdir |
inode | remove | unlink |
この中でfile構造体がkernel内でdisk上にあるデータを直接管理せず(さらにfile構造体自体はsuperblockのentryに含まれておらず)、processとinodeを繋ぐ血流の役割を果たしていることに注意。
また、inodeをmutateさせると書かれているchdirは、shに直接attachされたinodeというものがcurdirを示す為に存在し、そいつをmutateしているので、他とは少し毛色が異なる。
openは上の表に2度出現しているが、createmodeの時はinode/file構造体を作り、否では、file構造体のみ作る。
struct file { enum { FD_NONE, FD_PIPE, FD_INODE } type; int ref; // reference count char readable; char writable; struct pipe *pipe; struct inode *ip; uint off; }; // in-memory copy of an inode struct inode { uint dev; // Device number uint inum; // Inode number int ref; // Reference count struct sleeplock lock; // protects everything below here int valid; // inode has been read from disk? short type; // copy of disk inode short major; short minor; short nlink; uint size; uint addrs[NDIRECT+1]; };
上の構造体を見てfileとinodeを比較してみよう。
file | inode | |
---|---|---|
役割 | 1. inodeとprocessを繋ぐ / 2. permissionの管理?(※1) | fileと(disk)deviceを繋ぐ |
type | none/pipe/inode | dev/dir/cache |
lock有無 | x | o |
管理元object | ftable | icache |
管理元objectのlock有無 | o | o |
link(※2)の有無 | x | o |
ref count up | filealloc/filedup | ialloc/iget/idup |
ref count up(caller) | open/dup(<-init,exec) | open/fork |
ref count down | fileclose | iput |
ref count down(caller) | pipe/close/exit | close/exit/mklink(※3) |
※1. permissionの管理はinodeのlayerでやるべきではないのか。この方法だとdiskにpermission情報が残らない?
※2 linkとは,hardlinkの生成によってupし、rmされることで消去される。mkfs時にdefaultで1となる。
(これはfileからどれだけ参照されているかを表すrefとは異なる/refが0でもlinkがあればinodeは消えない)
※3. mklinkでlink先へのlinkをupしているが代わりにrefがdownするのは???
以下comment
file,inodeともreference countの仕組みを持っているが、
fileはprocessからattachされた時にreference値がup(dup),inodeは fileから参照され、reference値がupする。
通常のobjectに対するref-countのconceptとは異なり、構造体がdeallocateされる訳では無く、管理objectで再割り当て可能object
になるだけ。