Notes

Do not read codes but patch binary.

xv6 code reading(3.vfs編)

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
になるだけ。