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関数が出てきたけど,これは後回し.