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