bindmount関数からcmount関数

bind,mount,_mountとも引数が違うだけで,同じbindmount関数が呼ばれている.

port/sysfile.c
 1075: long
 1076: sysbind(ulong *arg)
 1077: {
 1078:         return bindmount(0, -1, -1, (char*)arg[0], (char*)arg[1], arg[2], nil);
 1079: }
 1080: 
 1081: long
 1082: sysmount(ulong *arg)
 1083: {
 1084:         return bindmount(1, arg[0], arg[1], nil, (char*)arg[2], arg[3], (char*)arg[4]);
 1085: }
 1086: 
 1087: long
 1088: sys_mount(ulong *arg)
 1089: {
 1090:         return bindmount(1, arg[0], -1, nil, (char*)arg[1], arg[2], (char*)arg[3]);
 1091: }

bindmount関数を見ていこう.第三引数のafdはmount時の認証に使われるが,ここでは無視する.重要な変数はチャネルc0とc1で,前者は新たに追加されるチャネル,c1は既存のチャネルを示している.mountのときはmnt(3)のデバイス番号をインデックスにdevtab[]からチャネルc0を取得する.一方,bindのときはnamec(arg0, Abind,...)経由でチャネルc0を取得する.そして,チャネルc1はnamec(arg1, Amount,...)経由で取得する.最終的にc0とc1というチャネルを引数にcmount関数を呼び出す.

  988: long
  989: bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec)
  990: {
  991:         int ret;
  992:         Chan *c0, *c1, *ac, *bc;

 1005:         if(ismount){

 1036:                 ret = devno('M', 0);
 1037:                 c0 = devtab[ret]->attach((char*)&bogus);

 1045:         }else{

 1048:                 c0 = namec(arg0, Abind, 0, 0);
 1049:         }

 1057:         c1 = namec(arg1, Amount, 0, 0);

 1063:         ret = cmount(&c0, c1, flag, bogus.spec);

 1073: }

ここでもnamec関数が出てきたけど,これは後回し.