chan.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. int chandebug=0; /* toggled by sysr1 */
  8. QLock chanprint; /* probably asking for trouble (deadlocks) -rsc */
  9. int domount(Chan**, Mhead**);
  10. void
  11. dumpmount(void) /* DEBUGGING */
  12. {
  13. Pgrp *pg;
  14. Mount *t;
  15. Mhead **h, **he, *f;
  16. if(up == nil){
  17. print("no process for dumpmount\n");
  18. return;
  19. }
  20. pg = up->pgrp;
  21. if(pg == nil){
  22. print("no pgrp for dumpmount\n");
  23. return;
  24. }
  25. rlock(&pg->ns);
  26. if(waserror()) {
  27. runlock(&pg->ns);
  28. nexterror();
  29. }
  30. he = &pg->mnthash[MNTHASH];
  31. for(h = pg->mnthash; h < he; h++) {
  32. for(f = *h; f; f = f->hash) {
  33. print("head: %p: %s 0x%llux.%lud %C %lud -> \n", f,
  34. f->from->name->s, f->from->qid.path,
  35. f->from->qid.vers, devtab[f->from->type]->dc,
  36. f->from->dev);
  37. for(t = f->mount; t; t = t->next)
  38. print("\t%p: %s (umh %p) (path %.8llux dev %C %lud)\n", t, t->to->name->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev);
  39. }
  40. }
  41. poperror();
  42. runlock(&pg->ns);
  43. }
  44. char*
  45. channame(Chan *c) /* DEBUGGING */
  46. {
  47. if(c == nil)
  48. return "<nil chan>";
  49. if(c->name == nil)
  50. return "<nil name>";
  51. if(c->name->s == nil)
  52. return "<nil name.s>";
  53. return c->name->s;
  54. }
  55. enum
  56. {
  57. CNAMESLOP = 20
  58. };
  59. struct
  60. {
  61. Lock;
  62. int fid;
  63. Chan *free;
  64. Chan *list;
  65. }chanalloc;
  66. typedef struct Elemlist Elemlist;
  67. struct Elemlist
  68. {
  69. char *name; /* copy of name, so '/' can be overwritten */
  70. int nelems;
  71. char **elems;
  72. int *off;
  73. int mustbedir;
  74. };
  75. #define SEP(c) ((c) == 0 || (c) == '/')
  76. void cleancname(Cname*);
  77. int
  78. isdotdot(char *p)
  79. {
  80. return p[0]=='.' && p[1]=='.' && p[2]=='\0';
  81. }
  82. long
  83. incref(Ref *r)
  84. {
  85. long x;
  86. lock(r);
  87. x = ++r->ref;
  88. unlock(r);
  89. return x;
  90. }
  91. long
  92. decref(Ref *r)
  93. {
  94. long x;
  95. lock(r);
  96. x = --r->ref;
  97. unlock(r);
  98. if(x < 0)
  99. panic("deccnt pc=0x%lux", getcallerpc(&r));
  100. return x;
  101. }
  102. /*
  103. * Rather than strncpy, which zeros the rest of the buffer, kstrcpy
  104. * truncates if necessary, always zero terminates, does not zero fill,
  105. * and puts ... at the end of the string if it's too long. Usually used to
  106. * save a string in up->genbuf;
  107. */
  108. void
  109. kstrcpy(char *s, char *t, int ns)
  110. {
  111. int nt;
  112. nt = strlen(t);
  113. if(nt+1 <= ns){
  114. memmove(s, t, nt+1);
  115. return;
  116. }
  117. /* too long */
  118. if(ns < 4){
  119. /* but very short! */
  120. strncpy(s, t, ns);
  121. return;
  122. }
  123. /* truncate with ... at character boundary (very rare case) */
  124. memmove(s, t, ns-4);
  125. ns -= 4;
  126. s[ns] = '\0';
  127. /* look for first byte of UTF-8 sequence by skipping continuation bytes */
  128. while(ns>0 && (s[--ns]&0xC0)==0x80)
  129. ;
  130. strcpy(s+ns, "...");
  131. }
  132. int
  133. emptystr(char *s)
  134. {
  135. if(s == nil)
  136. return 1;
  137. if(s[0] == '\0')
  138. return 1;
  139. return 0;
  140. }
  141. /*
  142. * Atomically replace *p with copy of s
  143. */
  144. void
  145. kstrdup(char **p, char *s)
  146. {
  147. int n;
  148. char *t, *prev;
  149. static Lock l;
  150. n = strlen(s)+1;
  151. /* if it's a user, we can wait for memory; if not, something's very wrong */
  152. if(up){
  153. t = smalloc(n);
  154. setmalloctag(t, getcallerpc(&p));
  155. }else{
  156. t = malloc(n);
  157. if(t == nil)
  158. panic("kstrdup: no memory");
  159. }
  160. memmove(t, s, n);
  161. prev = *p;
  162. *p = t;
  163. free(prev);
  164. }
  165. void
  166. chandevreset(void)
  167. {
  168. int i;
  169. for(i=0; devtab[i] != nil; i++)
  170. devtab[i]->reset();
  171. }
  172. void
  173. chandevinit(void)
  174. {
  175. int i;
  176. for(i=0; devtab[i] != nil; i++)
  177. devtab[i]->init();
  178. }
  179. void
  180. chandevshutdown(void)
  181. {
  182. int i;
  183. /* shutdown in reverse order */
  184. for(i=0; devtab[i] != nil; i++)
  185. ;
  186. for(i--; i >= 0; i--)
  187. devtab[i]->shutdown();
  188. }
  189. Chan*
  190. newchan(void)
  191. {
  192. Chan *c;
  193. lock(&chanalloc);
  194. c = chanalloc.free;
  195. if(c != 0)
  196. chanalloc.free = c->next;
  197. unlock(&chanalloc);
  198. if(c == nil) {
  199. c = smalloc(sizeof(Chan));
  200. lock(&chanalloc);
  201. c->fid = ++chanalloc.fid;
  202. c->link = chanalloc.list;
  203. chanalloc.list = c;
  204. unlock(&chanalloc);
  205. }
  206. /* if you get an error before associating with a dev,
  207. close calls rootclose, a nop */
  208. c->type = 0;
  209. c->flag = 0;
  210. c->ref = 1;
  211. c->dev = 0;
  212. c->offset = 0;
  213. c->devoffset = 0;
  214. c->iounit = 0;
  215. c->umh = 0;
  216. c->uri = 0;
  217. c->dri = 0;
  218. c->aux = 0;
  219. c->mchan = 0;
  220. c->mcp = 0;
  221. c->mux = 0;
  222. memset(&c->mqid, 0, sizeof(c->mqid));
  223. c->name = 0;
  224. c->ismtpt = 0;
  225. return c;
  226. }
  227. static Ref ncname;
  228. Cname*
  229. newcname(char *s)
  230. {
  231. Cname *n;
  232. int i;
  233. n = smalloc(sizeof(Cname));
  234. i = strlen(s);
  235. n->len = i;
  236. n->alen = i+CNAMESLOP;
  237. n->s = smalloc(n->alen);
  238. memmove(n->s, s, i+1);
  239. n->ref = 1;
  240. incref(&ncname);
  241. return n;
  242. }
  243. void
  244. cnameclose(Cname *n)
  245. {
  246. if(n == nil)
  247. return;
  248. if(decref(n))
  249. return;
  250. decref(&ncname);
  251. free(n->s);
  252. free(n);
  253. }
  254. Cname*
  255. addelem(Cname *n, char *s)
  256. {
  257. int i, a;
  258. char *t;
  259. Cname *new;
  260. if(s[0]=='.' && s[1]=='\0')
  261. return n;
  262. if(n->ref > 1){
  263. /* copy on write */
  264. new = newcname(n->s);
  265. cnameclose(n);
  266. n = new;
  267. }
  268. i = strlen(s);
  269. if(n->len+1+i+1 > n->alen){
  270. a = n->len+1+i+1 + CNAMESLOP;
  271. t = smalloc(a);
  272. memmove(t, n->s, n->len+1);
  273. free(n->s);
  274. n->s = t;
  275. n->alen = a;
  276. }
  277. if(n->len>0 && n->s[n->len-1]!='/' && s[0]!='/') /* don't insert extra slash if one is present */
  278. n->s[n->len++] = '/';
  279. memmove(n->s+n->len, s, i+1);
  280. n->len += i;
  281. if(isdotdot(s))
  282. cleancname(n);
  283. return n;
  284. }
  285. void
  286. chanfree(Chan *c)
  287. {
  288. c->flag = CFREE;
  289. if(c->dirrock != nil){
  290. free(c->dirrock);
  291. c->dirrock = 0;
  292. c->nrock = 0;
  293. c->mrock = 0;
  294. }
  295. if(c->umh != nil){
  296. putmhead(c->umh);
  297. c->umh = nil;
  298. }
  299. if(c->umc != nil){
  300. cclose(c->umc);
  301. c->umc = nil;
  302. }
  303. if(c->mux != nil){
  304. muxclose(c->mux);
  305. c->mux = nil;
  306. }
  307. if(c->mchan != nil){
  308. cclose(c->mchan);
  309. c->mchan = nil;
  310. }
  311. cnameclose(c->name);
  312. lock(&chanalloc);
  313. c->next = chanalloc.free;
  314. chanalloc.free = c;
  315. unlock(&chanalloc);
  316. }
  317. void
  318. cclose(Chan *c)
  319. {
  320. if(c->flag&CFREE)
  321. panic("cclose %lux", getcallerpc(&c));
  322. if(decref(c))
  323. return;
  324. if(!waserror()){
  325. devtab[c->type]->close(c);
  326. poperror();
  327. }
  328. chanfree(c);
  329. }
  330. /*
  331. * Make sure we have the only copy of c. (Copy on write.)
  332. */
  333. Chan*
  334. cunique(Chan *c)
  335. {
  336. Chan *nc;
  337. if(c->ref != 1) {
  338. nc = cclone(c);
  339. cclose(c);
  340. c = nc;
  341. }
  342. return c;
  343. }
  344. int
  345. eqqid(Qid a, Qid b)
  346. {
  347. return a.path==b.path && a.vers==b.vers;
  348. }
  349. int
  350. eqchan(Chan *a, Chan *b, int pathonly)
  351. {
  352. if(a->qid.path != b->qid.path)
  353. return 0;
  354. if(!pathonly && a->qid.vers!=b->qid.vers)
  355. return 0;
  356. if(a->type != b->type)
  357. return 0;
  358. if(a->dev != b->dev)
  359. return 0;
  360. return 1;
  361. }
  362. int
  363. eqchantdqid(Chan *a, int type, int dev, Qid qid, int pathonly)
  364. {
  365. if(a->qid.path != qid.path)
  366. return 0;
  367. if(!pathonly && a->qid.vers!=qid.vers)
  368. return 0;
  369. if(a->type != type)
  370. return 0;
  371. if(a->dev != dev)
  372. return 0;
  373. return 1;
  374. }
  375. Mhead*
  376. newmhead(Chan *from)
  377. {
  378. Mhead *mh;
  379. mh = smalloc(sizeof(Mhead));
  380. mh->ref = 1;
  381. mh->from = from;
  382. incref(from);
  383. /*
  384. n = from->name->len;
  385. if(n >= sizeof(mh->fromname))
  386. n = sizeof(mh->fromname)-1;
  387. memmove(mh->fromname, from->name->s, n);
  388. mh->fromname[n] = 0;
  389. */
  390. return mh;
  391. }
  392. int
  393. cmount(Chan **newp, Chan *old, int flag, char *spec)
  394. {
  395. Pgrp *pg;
  396. int order, flg;
  397. Mhead *m, **l, *mh;
  398. Mount *nm, *f, *um, **h;
  399. Chan *new;
  400. if(QTDIR & (old->qid.type^(*newp)->qid.type))
  401. error(Emount);
  402. if(old->umh)print("cmount old extra umh\n");
  403. order = flag&MORDER;
  404. if((old->qid.type&QTDIR)==0 && order != MREPL)
  405. error(Emount);
  406. new = *newp;
  407. mh = new->umh;
  408. /*
  409. * Not allowed to bind when the old directory
  410. * is itself a union. (Maybe it should be allowed, but I don't see
  411. * what the semantics would be.)
  412. *
  413. * We need to check mh->mount->next to tell unions apart from
  414. * simple mount points, so that things like
  415. * mount -c fd /root
  416. * bind -c /root /
  417. * work. The check of mount->mflag catches things like
  418. * mount fd /root
  419. * bind -c /root /
  420. *
  421. * This is far more complicated than it should be, but I don't
  422. * see an easier way at the moment. -rsc
  423. */
  424. if((flag&MCREATE) && mh && mh->mount
  425. && (mh->mount->next || !(mh->mount->mflag&MCREATE)))
  426. error(Emount);
  427. pg = up->pgrp;
  428. wlock(&pg->ns);
  429. l = &MOUNTH(pg, old->qid);
  430. for(m = *l; m; m = m->hash) {
  431. if(eqchan(m->from, old, 1))
  432. break;
  433. l = &m->hash;
  434. }
  435. if(m == nil) {
  436. /*
  437. * nothing mounted here yet. create a mount
  438. * head and add to the hash table.
  439. */
  440. m = newmhead(old);
  441. *l = m;
  442. /*
  443. * if this is a union mount, add the old
  444. * node to the mount chain.
  445. */
  446. if(order != MREPL)
  447. m->mount = newmount(m, old, 0, 0);
  448. }
  449. wlock(&m->lock);
  450. if(waserror()){
  451. wunlock(&m->lock);
  452. nexterror();
  453. }
  454. wunlock(&pg->ns);
  455. nm = newmount(m, new, flag, spec);
  456. if(mh != nil && mh->mount != nil) {
  457. /*
  458. * copy a union when binding it onto a directory
  459. */
  460. flg = order;
  461. if(order == MREPL)
  462. flg = MAFTER;
  463. h = &nm->next;
  464. um = mh->mount;
  465. for(um = um->next; um; um = um->next) {
  466. f = newmount(m, um->to, flg, um->spec);
  467. *h = f;
  468. h = &f->next;
  469. }
  470. }
  471. if(m->mount && order == MREPL) {
  472. mountfree(m->mount);
  473. m->mount = 0;
  474. }
  475. if(flag & MCREATE)
  476. nm->mflag |= MCREATE;
  477. if(m->mount && order == MAFTER) {
  478. for(f = m->mount; f->next; f = f->next)
  479. ;
  480. f->next = nm;
  481. }
  482. else {
  483. for(f = nm; f->next; f = f->next)
  484. ;
  485. f->next = m->mount;
  486. m->mount = nm;
  487. }
  488. wunlock(&m->lock);
  489. poperror();
  490. return nm->mountid;
  491. }
  492. void
  493. cunmount(Chan *mnt, Chan *mounted)
  494. {
  495. Pgrp *pg;
  496. Mhead *m, **l;
  497. Mount *f, **p;
  498. if(mnt->umh) /* should not happen */
  499. print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
  500. /*
  501. * It _can_ happen that mounted->umh is non-nil,
  502. * because mounted is the result of namec(Aopen)
  503. * (see sysfile.c:/^sysunmount).
  504. * If we open a union directory, it will have a umh.
  505. * Although surprising, this is okay, since the
  506. * cclose will take care of freeing the umh.
  507. */
  508. pg = up->pgrp;
  509. wlock(&pg->ns);
  510. l = &MOUNTH(pg, mnt->qid);
  511. for(m = *l; m; m = m->hash) {
  512. if(eqchan(m->from, mnt, 1))
  513. break;
  514. l = &m->hash;
  515. }
  516. if(m == 0) {
  517. wunlock(&pg->ns);
  518. error(Eunmount);
  519. }
  520. wlock(&m->lock);
  521. if(mounted == 0) {
  522. *l = m->hash;
  523. wunlock(&pg->ns);
  524. mountfree(m->mount);
  525. m->mount = nil;
  526. cclose(m->from);
  527. wunlock(&m->lock);
  528. putmhead(m);
  529. return;
  530. }
  531. p = &m->mount;
  532. for(f = *p; f; f = f->next) {
  533. /* BUG: Needs to be 2 pass */
  534. if(eqchan(f->to, mounted, 1) ||
  535. (f->to->mchan && eqchan(f->to->mchan, mounted, 1))) {
  536. *p = f->next;
  537. f->next = 0;
  538. mountfree(f);
  539. if(m->mount == nil) {
  540. *l = m->hash;
  541. cclose(m->from);
  542. wunlock(&m->lock);
  543. wunlock(&pg->ns);
  544. putmhead(m);
  545. return;
  546. }
  547. wunlock(&m->lock);
  548. wunlock(&pg->ns);
  549. return;
  550. }
  551. p = &f->next;
  552. }
  553. wunlock(&m->lock);
  554. wunlock(&pg->ns);
  555. error(Eunion);
  556. }
  557. Chan*
  558. cclone(Chan *c)
  559. {
  560. Chan *nc;
  561. Walkqid *wq;
  562. wq = devtab[c->type]->walk(c, nil, nil, 0);
  563. if(wq == nil)
  564. error("clone failed");
  565. nc = wq->clone;
  566. free(wq);
  567. nc->name = c->name;
  568. if(c->name)
  569. incref(c->name);
  570. return nc;
  571. }
  572. int
  573. findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
  574. {
  575. Pgrp *pg;
  576. Mhead *m;
  577. pg = up->pgrp;
  578. rlock(&pg->ns);
  579. for(m = MOUNTH(pg, qid); m; m = m->hash){
  580. rlock(&m->lock);
  581. if(m->from == nil){
  582. print("m %p m->from 0\n", m);
  583. runlock(&m->lock);
  584. continue;
  585. }
  586. if(eqchantdqid(m->from, type, dev, qid, 1)){
  587. runlock(&pg->ns);
  588. if(mp != nil){
  589. incref(m);
  590. if(*mp != nil)
  591. putmhead(*mp);
  592. *mp = m;
  593. }
  594. if(*cp != nil)
  595. cclose(*cp);
  596. incref(m->mount->to);
  597. *cp = m->mount->to;
  598. runlock(&m->lock);
  599. return 1;
  600. }
  601. runlock(&m->lock);
  602. }
  603. runlock(&pg->ns);
  604. return 0;
  605. }
  606. int
  607. domount(Chan **cp, Mhead **mp)
  608. {
  609. return findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid);
  610. }
  611. Chan*
  612. undomount(Chan *c, Cname *name)
  613. {
  614. Chan *nc;
  615. Pgrp *pg;
  616. Mount *t;
  617. Mhead **h, **he, *f;
  618. pg = up->pgrp;
  619. rlock(&pg->ns);
  620. if(waserror()) {
  621. runlock(&pg->ns);
  622. nexterror();
  623. }
  624. he = &pg->mnthash[MNTHASH];
  625. for(h = pg->mnthash; h < he; h++) {
  626. for(f = *h; f; f = f->hash) {
  627. if(strcmp(f->from->name->s, name->s) != 0)
  628. continue;
  629. for(t = f->mount; t; t = t->next) {
  630. if(eqchan(c, t->to, 1)) {
  631. /*
  632. * We want to come out on the left hand side of the mount
  633. * point using the element of the union that we entered on.
  634. * To do this, find the element that has a from name of
  635. * c->name->s.
  636. */
  637. if(strcmp(t->head->from->name->s, name->s) != 0)
  638. continue;
  639. nc = t->head->from;
  640. incref(nc);
  641. cclose(c);
  642. c = nc;
  643. break;
  644. }
  645. }
  646. }
  647. }
  648. poperror();
  649. runlock(&pg->ns);
  650. return c;
  651. }
  652. /*
  653. * Either walks all the way or not at all. No partial results in *cp.
  654. * *nerror is the number of names to display in an error message.
  655. */
  656. static char Edoesnotexist[] = "does not exist";
  657. int
  658. walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
  659. {
  660. int dev, dotdot, i, n, nhave, ntry, type;
  661. Chan *c, *nc;
  662. Cname *cname;
  663. Mount *f;
  664. Mhead *mh, *nmh;
  665. Walkqid *wq;
  666. c = *cp;
  667. incref(c);
  668. cname = c->name;
  669. incref(cname);
  670. mh = nil;
  671. /*
  672. * While we haven't gotten all the way down the path:
  673. * 1. step through a mount point, if any
  674. * 2. send a walk request for initial dotdot or initial prefix without dotdot
  675. * 3. move to the first mountpoint along the way.
  676. * 4. repeat.
  677. *
  678. * An invariant is that each time through the loop, c is on the undomount
  679. * side of the mount point, and c's name is cname.
  680. */
  681. for(nhave=0; nhave<nnames; nhave+=n){
  682. if((c->qid.type&QTDIR)==0){
  683. if(nerror)
  684. *nerror = nhave;
  685. cnameclose(cname);
  686. cclose(c);
  687. strcpy(up->errstr, Enotdir);
  688. if(mh != nil)
  689. putmhead(mh);
  690. return -1;
  691. }
  692. ntry = nnames - nhave;
  693. if(ntry > MAXWELEM)
  694. ntry = MAXWELEM;
  695. dotdot = 0;
  696. for(i=0; i<ntry; i++){
  697. if(isdotdot(names[nhave+i])){
  698. if(i==0) {
  699. dotdot = 1;
  700. ntry = 1;
  701. } else
  702. ntry = i;
  703. break;
  704. }
  705. }
  706. if(!dotdot && !nomount)
  707. domount(&c, &mh);
  708. type = c->type;
  709. dev = c->dev;
  710. if((wq = devtab[type]->walk(c, nil, names+nhave, ntry)) == nil){
  711. /* try a union mount, if any */
  712. if(mh && !nomount){
  713. /*
  714. * mh->mount->to == c, so start at mh->mount->next
  715. */
  716. rlock(&mh->lock);
  717. for(f = mh->mount->next; f; f = f->next)
  718. if((wq = devtab[f->to->type]->walk(f->to, nil, names+nhave, ntry)) != nil)
  719. break;
  720. runlock(&mh->lock);
  721. if(f != nil){
  722. type = f->to->type;
  723. dev = f->to->dev;
  724. }
  725. }
  726. if(wq == nil){
  727. cclose(c);
  728. cnameclose(cname);
  729. if(nerror)
  730. *nerror = nhave+1;
  731. if(mh != nil)
  732. putmhead(mh);
  733. return -1;
  734. }
  735. }
  736. nmh = nil;
  737. if(dotdot){
  738. assert(wq->nqid == 1);
  739. assert(wq->clone != nil);
  740. cname = addelem(cname, "..");
  741. nc = undomount(wq->clone, cname);
  742. n = 1;
  743. }else{
  744. nc = nil;
  745. if(!nomount)
  746. for(i=0; i<wq->nqid && i<ntry-1; i++)
  747. if(findmount(&nc, &nmh, type, dev, wq->qid[i]))
  748. break;
  749. if(nc == nil){ /* no mount points along path */
  750. if(wq->clone == nil){
  751. cclose(c);
  752. cnameclose(cname);
  753. if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
  754. if(nerror)
  755. *nerror = nhave+wq->nqid+1;
  756. strcpy(up->errstr, Edoesnotexist);
  757. }else{
  758. if(nerror)
  759. *nerror = nhave+wq->nqid;
  760. strcpy(up->errstr, Enotdir);
  761. }
  762. free(wq);
  763. if(mh != nil)
  764. putmhead(mh);
  765. return -1;
  766. }
  767. n = wq->nqid;
  768. nc = wq->clone;
  769. }else{ /* stopped early, at a mount point */
  770. if(wq->clone != nil){
  771. cclose(wq->clone);
  772. wq->clone = nil;
  773. }
  774. n = i+1;
  775. }
  776. for(i=0; i<n; i++)
  777. cname = addelem(cname, names[nhave+i]);
  778. }
  779. cclose(c);
  780. c = nc;
  781. putmhead(mh);
  782. mh = nmh;
  783. free(wq);
  784. }
  785. putmhead(mh);
  786. c = cunique(c);
  787. if(c->umh != nil){ //BUG
  788. print("walk umh\n");
  789. putmhead(c->umh);
  790. c->umh = nil;
  791. }
  792. cnameclose(c->name);
  793. c->name = cname;
  794. cclose(*cp);
  795. *cp = c;
  796. if(nerror)
  797. *nerror = 0;
  798. return 0;
  799. }
  800. /*
  801. * c is a mounted non-creatable directory. find a creatable one.
  802. */
  803. Chan*
  804. createdir(Chan *c, Mhead *m)
  805. {
  806. Chan *nc;
  807. Mount *f;
  808. rlock(&m->lock);
  809. if(waserror()) {
  810. runlock(&m->lock);
  811. nexterror();
  812. }
  813. for(f = m->mount; f; f = f->next) {
  814. if(f->mflag&MCREATE) {
  815. nc = cclone(f->to);
  816. runlock(&m->lock);
  817. poperror();
  818. cclose(c);
  819. return nc;
  820. }
  821. }
  822. error(Enocreate);
  823. return 0;
  824. }
  825. void
  826. saveregisters(void)
  827. {
  828. }
  829. /*
  830. * In place, rewrite name to compress multiple /, eliminate ., and process ..
  831. */
  832. void
  833. cleancname(Cname *n)
  834. {
  835. char *p;
  836. if(n->s[0] == '#'){
  837. p = strchr(n->s, '/');
  838. if(p == nil)
  839. return;
  840. cleanname(p);
  841. /*
  842. * The correct name is #i rather than #i/,
  843. * but the correct name of #/ is #/.
  844. */
  845. if(strcmp(p, "/")==0 && n->s[1] != '/')
  846. *p = '\0';
  847. }else
  848. cleanname(n->s);
  849. n->len = strlen(n->s);
  850. }
  851. static void
  852. growparse(Elemlist *e)
  853. {
  854. char **new;
  855. int *inew;
  856. enum { Delta = 8 };
  857. if(e->nelems % Delta == 0){
  858. new = smalloc((e->nelems+Delta) * sizeof(char*));
  859. memmove(new, e->elems, e->nelems*sizeof(char*));
  860. free(e->elems);
  861. e->elems = new;
  862. inew = smalloc((e->nelems+Delta+1) * sizeof(int));
  863. memmove(inew, e->off, e->nelems*sizeof(int));
  864. free(e->off);
  865. e->off = inew;
  866. }
  867. }
  868. /*
  869. * The name is known to be valid.
  870. * Copy the name so slashes can be overwritten.
  871. * An empty string will set nelem=0.
  872. * A path ending in / or /. or /.//./ etc. will have
  873. * e.mustbedir = 1, so that we correctly
  874. * reject, e.g., "/adm/users/." when /adm/users is a file
  875. * rather than a directory.
  876. */
  877. static void
  878. parsename(char *name, Elemlist *e)
  879. {
  880. char *slash;
  881. kstrdup(&e->name, name);
  882. name = e->name;
  883. e->nelems = 0;
  884. e->elems = nil;
  885. e->off = smalloc(sizeof(int));
  886. e->off[0] = skipslash(name) - name;
  887. for(;;){
  888. name = skipslash(name);
  889. if(*name=='\0'){
  890. e->mustbedir = 1;
  891. break;
  892. }
  893. growparse(e);
  894. e->elems[e->nelems++] = name;
  895. slash = utfrune(name, '/');
  896. if(slash == nil){
  897. e->off[e->nelems] = name+strlen(name) - e->name;
  898. e->mustbedir = 0;
  899. break;
  900. }
  901. e->off[e->nelems] = slash - e->name;
  902. *slash++ = '\0';
  903. name = slash;
  904. }
  905. }
  906. void*
  907. memrchr(void *va, int c, long n)
  908. {
  909. uchar *a, *e;
  910. a = va;
  911. for(e=a+n-1; e>a; e--)
  912. if(*e == c)
  913. return e;
  914. return nil;
  915. }
  916. void
  917. nameerror(char *name, char *error)
  918. {
  919. int len;
  920. char tmperr[ERRMAX], *p;
  921. strcpy(tmperr, error); /* error might be in genbuf or tmperr */
  922. len = strlen(name);
  923. if(len < ERRMAX/3 || (p=strrchr(name, '/'))==nil || p==name)
  924. snprint(up->genbuf, sizeof up->genbuf, "%s", name);
  925. else
  926. snprint(up->genbuf, sizeof up->genbuf, "...%s", p);
  927. snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, tmperr);
  928. nexterror();
  929. }
  930. /*
  931. * Turn a name into a channel.
  932. * &name[0] is known to be a valid address. It may be a kernel address.
  933. *
  934. * Opening with amode Aopen, Acreate, Aremove, or Aaccess guarantees
  935. * that the result will be the only reference to that particular fid.
  936. * This is necessary since we might pass the result to
  937. * devtab[]->remove().
  938. *
  939. * Opening Atodir or Amount does not guarantee this.
  940. *
  941. * Under certain circumstances, opening Aaccess will cause
  942. * an unnecessary clone in order to get a cunique Chan so it
  943. * can attach the correct name. Sysstat and sys_stat need the
  944. * correct name so they can rewrite the stat info.
  945. */
  946. Chan*
  947. namec(char *aname, int amode, int omode, ulong perm)
  948. {
  949. int n, t, nomount, npath;
  950. Chan *c, *cnew;
  951. Cname *cname;
  952. Elemlist e;
  953. Rune r;
  954. Mhead *m;
  955. char *createerr, tmperrbuf[ERRMAX];
  956. char *name;
  957. name = aname;
  958. if(name[0] == '\0')
  959. error("empty file name");
  960. name = validnamedup(name, 1);
  961. if(waserror()){
  962. free(name);
  963. nexterror();
  964. }
  965. /*
  966. * Find the starting off point (the current slash, the root of
  967. * a device tree, or the current dot) as well as the name to
  968. * evaluate starting there.
  969. */
  970. nomount = 0;
  971. switch(name[0]){
  972. case '/':
  973. c = up->slash;
  974. incref(c);
  975. break;
  976. case '#':
  977. nomount = 1;
  978. up->genbuf[0] = '\0';
  979. n = 0;
  980. while(*name!='\0' && (*name != '/' || n < 2)){
  981. if(n >= sizeof(up->genbuf)-1)
  982. error(Efilename);
  983. up->genbuf[n++] = *name++;
  984. }
  985. up->genbuf[n] = '\0';
  986. /*
  987. * noattach is sandboxing.
  988. *
  989. * the OK exceptions are:
  990. * | it only gives access to pipes you create
  991. * d this process's file descriptors
  992. * e this process's environment
  993. * the iffy exceptions are:
  994. * c time and pid, but also cons and consctl
  995. * p control of your own processes (and unfortunately
  996. * any others left unprotected)
  997. */
  998. n = chartorune(&r, up->genbuf+1)+1;
  999. /* actually / is caught by parsing earlier */
  1000. if(utfrune("M", r))
  1001. error(Enoattach);
  1002. if(up->pgrp->noattach && utfrune("|decp", r)==nil)
  1003. error(Enoattach);
  1004. t = devno(r, 1);
  1005. if(t == -1)
  1006. error(Ebadsharp);
  1007. c = devtab[t]->attach(up->genbuf+n);
  1008. break;
  1009. default:
  1010. c = up->dot;
  1011. incref(c);
  1012. break;
  1013. }
  1014. e.name = nil;
  1015. e.elems = nil;
  1016. e.off = nil;
  1017. e.nelems = 0;
  1018. if(waserror()){
  1019. cclose(c);
  1020. free(e.name);
  1021. free(e.elems);
  1022. free(e.off);
  1023. //dumpmount();
  1024. nexterror();
  1025. }
  1026. /*
  1027. * Build a list of elements in the path.
  1028. */
  1029. parsename(name, &e);
  1030. /*
  1031. * On create, ....
  1032. */
  1033. if(amode == Acreate){
  1034. /* perm must have DMDIR if last element is / or /. */
  1035. if(e.mustbedir && !(perm&DMDIR)){
  1036. npath = e.nelems;
  1037. nameerror(aname, "create without DMDIR");
  1038. }
  1039. /* don't try to walk the last path element just yet. */
  1040. if(e.nelems == 0)
  1041. error(Eexist);
  1042. e.nelems--;
  1043. }
  1044. if(walk(&c, e.elems, e.nelems, nomount, &npath) < 0){
  1045. if(npath < 0 || npath > e.nelems){
  1046. print("namec %s walk error npath=%d\n", aname, npath);
  1047. nexterror();
  1048. }
  1049. nameerror(aname, up->errstr);
  1050. }
  1051. if(e.mustbedir && !(c->qid.type&QTDIR)){
  1052. npath = e.nelems;
  1053. nameerror(aname, "not a directory");
  1054. }
  1055. if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR)){
  1056. npath = e.nelems;
  1057. error("cannot exec directory");
  1058. }
  1059. switch(amode){
  1060. case Abind:
  1061. m = nil;
  1062. if(!nomount)
  1063. domount(&c, &m);
  1064. if(c->umh != nil)
  1065. putmhead(c->umh);
  1066. c->umh = m;
  1067. break;
  1068. case Aaccess:
  1069. case Aremove:
  1070. case Aopen:
  1071. Open:
  1072. /* save the name; domount might change c */
  1073. cname = c->name;
  1074. incref(cname);
  1075. m = nil;
  1076. if(!nomount)
  1077. domount(&c, &m);
  1078. /* our own copy to open or remove */
  1079. c = cunique(c);
  1080. /* now it's our copy anyway, we can put the name back */
  1081. cnameclose(c->name);
  1082. c->name = cname;
  1083. /* record whether c is on a mount point */
  1084. c->ismtpt = m!=nil;
  1085. switch(amode){
  1086. case Aaccess:
  1087. case Aremove:
  1088. putmhead(m);
  1089. break;
  1090. case Aopen:
  1091. case Acreate:
  1092. if(c->umh != nil){
  1093. print("cunique umh Open\n");
  1094. putmhead(c->umh);
  1095. c->umh = nil;
  1096. }
  1097. /* only save the mount head if it's a multiple element union */
  1098. if(m && m->mount && m->mount->next)
  1099. c->umh = m;
  1100. else
  1101. putmhead(m);
  1102. /* save registers else error() in open has wrong value of c saved */
  1103. saveregisters();
  1104. if(omode == OEXEC)
  1105. c->flag &= ~CCACHE;
  1106. c = devtab[c->type]->open(c, omode&~OCEXEC);
  1107. if(omode & OCEXEC)
  1108. c->flag |= CCEXEC;
  1109. if(omode & ORCLOSE)
  1110. c->flag |= CRCLOSE;
  1111. break;
  1112. }
  1113. break;
  1114. case Atodir:
  1115. /*
  1116. * Directories (e.g. for cd) are left before the mount point,
  1117. * so one may mount on / or . and see the effect.
  1118. */
  1119. if(!(c->qid.type & QTDIR))
  1120. error(Enotdir);
  1121. break;
  1122. case Amount:
  1123. /*
  1124. * When mounting on an already mounted upon directory,
  1125. * one wants subsequent mounts to be attached to the
  1126. * original directory, not the replacement. Don't domount.
  1127. */
  1128. break;
  1129. case Acreate:
  1130. /*
  1131. * We've already walked all but the last element.
  1132. * If the last exists, try to open it OTRUNC.
  1133. * If omode&OEXCL is set, just give up.
  1134. */
  1135. e.nelems++;
  1136. if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0){
  1137. if(omode&OEXCL)
  1138. error(Eexist);
  1139. omode |= OTRUNC;
  1140. goto Open;
  1141. }
  1142. /*
  1143. * The semantics of the create(2) system call are that if the
  1144. * file exists and can be written, it is to be opened with truncation.
  1145. * On the other hand, the create(5) message fails if the file exists.
  1146. * If we get two create(2) calls happening simultaneously,
  1147. * they might both get here and send create(5) messages, but only
  1148. * one of the messages will succeed. To provide the expected create(2)
  1149. * semantics, the call with the failed message needs to try the above
  1150. * walk again, opening for truncation. This correctly solves the
  1151. * create/create race, in the sense that any observable outcome can
  1152. * be explained as one happening before the other.
  1153. * The create/create race is quite common. For example, it happens
  1154. * when two rc subshells simultaneously update the same
  1155. * environment variable.
  1156. *
  1157. * The implementation still admits a create/create/remove race:
  1158. * (A) walk to file, fails
  1159. * (B) walk to file, fails
  1160. * (A) create file, succeeds, returns
  1161. * (B) create file, fails
  1162. * (A) remove file, succeeds, returns
  1163. * (B) walk to file, return failure.
  1164. *
  1165. * This is hardly as common as the create/create race, and is really
  1166. * not too much worse than what might happen if (B) got a hold of a
  1167. * file descriptor and then the file was removed -- either way (B) can't do
  1168. * anything with the result of the create call. So we don't care about this race.
  1169. *
  1170. * Applications that care about more fine-grained decision of the races
  1171. * can use the OEXCL flag to get at the underlying create(5) semantics;
  1172. * by default we provide the common case.
  1173. *
  1174. * We need to stay behind the mount point in case we
  1175. * need to do the first walk again (should the create fail).
  1176. *
  1177. * We also need to cross the mount point and find the directory
  1178. * in the union in which we should be creating.
  1179. *
  1180. * The channel staying behind is c, the one moving forward is cnew.
  1181. */
  1182. m = nil;
  1183. cnew = nil; /* is this assignment necessary? */
  1184. if(!waserror()){ /* try create */
  1185. if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
  1186. cnew = createdir(cnew, m);
  1187. else{
  1188. cnew = c;
  1189. incref(cnew);
  1190. }
  1191. /*
  1192. * We need our own copy of the Chan because we're
  1193. * about to send a create, which will move it. Once we have
  1194. * our own copy, we can fix the name, which might be wrong
  1195. * if findmount gave us a new Chan.
  1196. */
  1197. cnew = cunique(cnew);
  1198. cnameclose(cnew->name);
  1199. cnew->name = c->name;
  1200. incref(cnew->name);
  1201. devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
  1202. poperror();
  1203. if(omode & OCEXEC)
  1204. cnew->flag |= CCEXEC;
  1205. if(omode & ORCLOSE)
  1206. cnew->flag |= CRCLOSE;
  1207. if(m)
  1208. putmhead(m);
  1209. cclose(c);
  1210. c = cnew;
  1211. c->name = addelem(c->name, e.elems[e.nelems-1]);
  1212. break;
  1213. }else{ /* create failed */
  1214. cclose(cnew);
  1215. if(m)
  1216. putmhead(m);
  1217. if(omode & OEXCL)
  1218. nexterror();
  1219. /* save error */
  1220. createerr = up->errstr;
  1221. up->errstr = tmperrbuf;
  1222. /* note: we depend that walk does not error */
  1223. if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){
  1224. up->errstr = createerr;
  1225. error(createerr); /* report true error */
  1226. }
  1227. up->errstr = createerr;
  1228. omode |= OTRUNC;
  1229. goto Open;
  1230. }
  1231. panic("namec: not reached");
  1232. default:
  1233. panic("unknown namec access %d\n", amode);
  1234. }
  1235. /* place final element in genbuf for e.g. exec */
  1236. if(e.nelems > 0)
  1237. kstrcpy(up->genbuf, e.elems[e.nelems-1], sizeof up->genbuf);
  1238. else
  1239. kstrcpy(up->genbuf, ".", sizeof up->genbuf);
  1240. free(e.name);
  1241. free(e.elems);
  1242. free(e.off);
  1243. poperror(); /* e c */
  1244. free(name);
  1245. poperror(); /* name */
  1246. return c;
  1247. }
  1248. /*
  1249. * name is valid. skip leading / and ./ as much as possible
  1250. */
  1251. char*
  1252. skipslash(char *name)
  1253. {
  1254. while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
  1255. name++;
  1256. return name;
  1257. }
  1258. char isfrog[256]={
  1259. /*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1260. /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1261. /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1262. /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1263. ['/'] 1,
  1264. [0x7f] 1,
  1265. };
  1266. /*
  1267. * Check that the name
  1268. * a) is in valid memory.
  1269. * b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
  1270. * c) contains no frogs.
  1271. * The first byte is known to be addressible by the requester, so the
  1272. * routine works for kernel and user memory both.
  1273. * The parameter slashok flags whether a slash character is an error
  1274. * or a valid character.
  1275. *
  1276. * The parameter dup flags whether the string should be copied
  1277. * out of user space before being scanned the second time.
  1278. * (Otherwise a malicious thread could remove the NUL, causing us
  1279. * to access unchecked addresses.)
  1280. */
  1281. static char*
  1282. validname0(char *aname, int slashok, int dup, ulong pc)
  1283. {
  1284. char *p, *ename, *name, *s;
  1285. uint t;
  1286. int c, n;
  1287. Rune r;
  1288. name = aname;
  1289. if(((ulong)name & KZERO) != KZERO) {
  1290. if(!dup)
  1291. print("warning: validname called from %lux with user pointer", pc);
  1292. p = name;
  1293. t = BY2PG-((ulong)p&(BY2PG-1));
  1294. while((ename=vmemchr(p, 0, t)) == nil) {
  1295. p += t;
  1296. t = BY2PG;
  1297. }
  1298. }else
  1299. ename = memchr(name, 0, (1<<16));
  1300. if(ename==nil || ename-name>=(1<<16))
  1301. error("name too long");
  1302. s = nil;
  1303. if(dup){
  1304. n = ename-name;
  1305. s = smalloc(n+1);
  1306. memmove(s, name, n);
  1307. s[n] = 0;
  1308. aname = s;
  1309. name = s;
  1310. }
  1311. while(*name){
  1312. /* all characters above '~' are ok */
  1313. c = *(uchar*)name;
  1314. if(c >= Runeself)
  1315. name += chartorune(&r, name);
  1316. else{
  1317. if(isfrog[c])
  1318. if(!slashok || c!='/'){
  1319. snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
  1320. free(s);
  1321. error(up->genbuf);
  1322. }
  1323. name++;
  1324. }
  1325. }
  1326. return s;
  1327. }
  1328. void
  1329. validname(char *aname, int slashok)
  1330. {
  1331. validname0(aname, slashok, 0, getcallerpc(&aname));
  1332. }
  1333. char*
  1334. validnamedup(char *aname, int slashok)
  1335. {
  1336. return validname0(aname, slashok, 1, 0);
  1337. }
  1338. void
  1339. isdir(Chan *c)
  1340. {
  1341. if(c->qid.type & QTDIR)
  1342. return;
  1343. error(Enotdir);
  1344. }
  1345. /*
  1346. * This is necessary because there are many
  1347. * pointers to the top of a given mount list:
  1348. *
  1349. * - the mhead in the namespace hash table
  1350. * - the mhead in chans returned from findmount:
  1351. * used in namec and then by unionread.
  1352. * - the mhead in chans returned from createdir:
  1353. * used in the open/create race protect, which is gone.
  1354. *
  1355. * The RWlock in the Mhead protects the mount list it contains.
  1356. * The mount list is deleted when we cunmount.
  1357. * The RWlock ensures that nothing is using the mount list at that time.
  1358. *
  1359. * It is okay to replace c->mh with whatever you want as
  1360. * long as you are sure you have a unique reference to it.
  1361. *
  1362. * This comment might belong somewhere else.
  1363. */
  1364. void
  1365. putmhead(Mhead *m)
  1366. {
  1367. if(m && decref(m) == 0){
  1368. m->mount = (Mount*)0xCafeBeef;
  1369. free(m);
  1370. }
  1371. }