| @@ -441,6 +441,12 @@ cunique(Chan *c) · 440 unmodified lines |
| 441 | c = nc; | 441 | c = nc; |
| 442 | } | 442 | } |
| 443 | | 443 | |
| | 444 | if(c->umh != nil){ //BUG |
| | 445 | print("cunique umh != nil from %#p\n", getcallerpc(&c)); |
| | 446 | putmhead(c->umh); |
| | 447 | c->umh = nil; |
| | 448 | } |
| | 449 | |
| 444 | return c; | 450 | return c; |
| 445 | } | 451 | } |
| 446 | | 452 | |
| @@ -512,128 +518,124 @@ newmhead(Chan *from) · 65 unmodified lines |
| 512 | void | 518 | void |
| 513 | putmhead(Mhead *m) | 519 | putmhead(Mhead *m) |
| 514 | { | 520 | { |
| 515 | if(m != nil && decref(&m->ref) == 0){ | 521 | if(m == nil) |
| 516 | assert(m->mount == nil); | 522 | return; |
| 517 | cclose(m->from); | 523 | if(decref(&m->ref)) |
| 518 | free(m); | 524 | return; |
| 519 | } | 525 | assert(m->mount == nil); |
| | 526 | cclose(m->from); |
| | 527 | free(m); |
| 520 | } | 528 | } |
| 521 | | 529 | |
| 522 | int | 530 | int |
| 523 | cmount(Chan **newp, Chan *old, int flag, char *spec) | 531 | cmount(Chan *new, Chan *old, int flag, char *spec) |
| 524 | { | 532 | { |
| 525 | int order, flg; | 533 | int order; |
| 526 | Chan *new; | | |
| 527 | Mhead *m, **l, *mh; | 534 | Mhead *m, **l, *mh; |
| 528 | Mount *nm, *f, *um, **h; | 535 | Mount *nm, *f, *um; |
| 529 | Pgrp *pg; | 536 | Pgrp *pg; |
| 530 | | 537 | |
| 531 | if(QTDIR & (old->qid.type^(*newp)->qid.type)) | | |
| 532 | error(Emount); | | |
| 533 | | | |
| 534 | if(old->umh != nil) | 538 | if(old->umh != nil) |
| 535 | print("cmount: unexpected umh, caller %#p\n", getcallerpc(&newp)); | 539 | print("cmount: unexpected umh, caller %#p\n", getcallerpc(&new)); |
| | 540 | |
| | 541 | if(QTDIR & (old->qid.type^new->qid.type)) |
| | 542 | error(Emount); |
| 536 | | 543 | |
| 537 | order = flag&MORDER; | 544 | order = flag&MORDER; |
| 538 | | 545 | |
| 539 | if((old->qid.type&QTDIR) == 0 && order != MREPL) | 546 | if((old->qid.type&QTDIR) == 0 && order != MREPL) |
| 540 | error(Emount); | 547 | error(Emount); |
| 541 | | 548 | |
| 542 | new = *newp; | 549 | nm = newmount(new, flag, spec); |
| 543 | mh = new->umh; | 550 | mh = new->umh; |
| | 551 | if(mh != nil) { |
| | 552 | rlock(&mh->lock); |
| | 553 | if(waserror()) { |
| | 554 | runlock(&mh->lock); |
| | 555 | mountfree(nm); |
| | 556 | nexterror(); |
| | 557 | } |
| | 558 | um = mh->mount; |
| | 559 | if(um != nil){ |
| | 560 | /* |
| | 561 | * Not allowed to bind when the old directory is itself a union. |
| | 562 | * (Maybe it should be allowed, but I don't see what the semantics |
| | 563 | * would be.) |
| | 564 | * |
| | 565 | * We need to check mh->mount->next to tell unions apart from |
| | 566 | * simple mount points, so that things like |
| | 567 | * mount -c fd /root |
| | 568 | * bind -c /root / |
| | 569 | * work. |
| | 570 | * |
| | 571 | * The check of mount->mflag allows things like |
| | 572 | * mount fd /root |
| | 573 | * bind -c /root / |
| | 574 | * |
| | 575 | * This is far more complicated than it should be, but I don't |
| | 576 | * see an easier way at the moment. |
| | 577 | */ |
| | 578 | if((flag&MCREATE) != 0 && (um->next != nil || (um->mflag&MCREATE) == 0)) |
| | 579 | error(Emount); |
| 544 | | 580 | |
| 545 | /* | 581 | /* |
| 546 | * Not allowed to bind when the old directory is itself a union. | 582 | * copy a union when binding it onto a directory |
| 547 | * (Maybe it should be allowed, but I don't see what the semantics | 583 | */ |
| 548 | * would be.) | 584 | f = nm; |
| 549 | * | 585 | for(um = um->next; um != nil; um = um->next){ |
| 550 | * We need to check mh->mount->next to tell unions apart from | 586 | f->next = newmount(um->to, order==MREPL? MAFTER: order, um->spec); |
| 551 | * simple mount points, so that things like | 587 | f = f->next; |
| 552 | * mount -c fd /root | 588 | } |
| 553 | * bind -c /root / | 589 | } |
| 554 | * work. | 590 | runlock(&mh->lock); |
| 555 | * | 591 | poperror(); |
| 556 | * The check of mount->mflag allows things like | 592 | } |
| 557 | * mount fd /root | | |
| 558 | * bind -c /root / | | |
| 559 | * | | |
| 560 | * This is far more complicated than it should be, but I don't | | |
| 561 | * see an easier way at the moment. | | |
| 562 | */ | | |
| 563 | if((flag&MCREATE) != 0 && mh != nil && mh->mount != nil | | |
| 564 | && (mh->mount->next != nil || (mh->mount->mflag&MCREATE) == 0)) | | |
| 565 | error(Emount); | | |
| 566 | | 593 | |
| 567 | pg = up->pgrp; | 594 | pg = up->pgrp; |
| 568 | wlock(&pg->ns); | 595 | wlock(&pg->ns); |
| 569 | | | |
| 570 | l = &MOUNTH(pg, old->qid); | 596 | l = &MOUNTH(pg, old->qid); |
| 571 | for(m = *l; m != nil; m = m->hash){ | 597 | for(m = *l; m != nil; m = m->hash){ |
| 572 | if(eqchan(m->from, old, 1)) | 598 | if(eqchan(m->from, old, 1)) |
| 573 | break; | 599 | break; |
| 574 | l = &m->hash; | 600 | l = &m->hash; |
| 575 | } | 601 | } |
| 576 | | | |
| 577 | if(m == nil){ | 602 | if(m == nil){ |
| 578 | /* | 603 | /* |
| 579 | * nothing mounted here yet. create a mount | 604 | * nothing mounted here yet. create a mount |
| 580 | * head and add to the hash table. | 605 | * head and add to the hash table. |
| 581 | */ | 606 | */ |
| 582 | m = newmhead(old); | 607 | m = newmhead(old); |
| 583 | *l = m; | | |
| 584 | | | |
| 585 | /* | 608 | /* |
| 586 | * if this is a union mount, add the old | 609 | * if this is a union mount, add the old |
| 587 | * node to the mount chain. | 610 | * node to the mount chain. |
| 588 | */ | 611 | */ |
| 589 | if(order != MREPL) | 612 | if(order != MREPL) |
| 590 | m->mount = newmount(old, 0, nil); | 613 | m->mount = newmount(old, 0, nil); |
| | 614 | *l = m; |
| 591 | } | 615 | } |
| 592 | wlock(&m->lock); | 616 | wlock(&m->lock); |
| 593 | if(waserror()){ | 617 | um = m->mount; |
| 594 | wunlock(&m->lock); | 618 | if(um != nil && order == MAFTER){ |
| 595 | nexterror(); | 619 | for(f = um; f->next != nil; f = f->next) |
| 596 | } | | |
| 597 | wunlock(&pg->ns); | | |
| 598 | | | |
| 599 | nm = newmount(new, flag, spec); | | |
| 600 | if(mh != nil && mh->mount != nil){ | | |
| 601 | /* | | |
| 602 | * copy a union when binding it onto a directory | | |
| 603 | */ | | |
| 604 | flg = order; | | |
| 605 | if(order == MREPL) | | |
| 606 | flg = MAFTER; | | |
| 607 | h = &nm->next; | | |
| 608 | um = mh->mount; | | |
| 609 | for(um = um->next; um != nil; um = um->next){ | | |
| 610 | f = newmount(um->to, flg, um->spec); | | |
| 611 | *h = f; | | |
| 612 | h = &f->next; | | |
| 613 | } | | |
| 614 | } | | |
| 615 | | | |
| 616 | if(m->mount != nil && order == MREPL){ | | |
| 617 | mountfree(m->mount); | | |
| 618 | m->mount = nil; | | |
| 619 | } | | |
| 620 | | | |
| 621 | if(flag & MCREATE) | | |
| 622 | nm->mflag |= MCREATE; | | |
| 623 | | | |
| 624 | if(m->mount != nil && order == MAFTER){ | | |
| 625 | for(f = m->mount; f->next != nil; f = f->next) | | |
| 626 | ; | 620 | ; |
| 627 | f->next = nm; | 621 | f->next = nm; |
| 628 | }else{ | 622 | um = nil; |
| 629 | for(f = nm; f->next != nil; f = f->next) | 623 | } else { |
| 630 | ; | 624 | if(order != MREPL){ |
| 631 | f->next = m->mount; | 625 | for(f = nm; f->next != nil; f = f->next) |
| | 626 | ; |
| | 627 | f->next = um; |
| | 628 | um = nil; |
| | 629 | } |
| 632 | m->mount = nm; | 630 | m->mount = nm; |
| 633 | } | 631 | } |
| | 632 | order = nm->mountid; |
| 634 | wunlock(&m->lock); | 633 | wunlock(&m->lock); |
| 635 | poperror(); | 634 | wunlock(&pg->ns); |
| 636 | return nm->mountid; | 635 | |
| | 636 | mountfree(um); |
| | 637 | |
| | 638 | return order; |
| 637 | } | 639 | } |
| 638 | | 640 | |
| 639 | void | 641 | void |
| @@ -736,13 +738,13 @@ findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid) · 96 unmodified lines |
| 736 | rlock(&pg->ns); | 738 | rlock(&pg->ns); |
| 737 | for(m = MOUNTH(pg, qid); m != nil; m = m->hash){ | 739 | for(m = MOUNTH(pg, qid); m != nil; m = m->hash){ |
| 738 | if(eqchantdqid(m->from, type, dev, qid, 1)){ | 740 | if(eqchantdqid(m->from, type, dev, qid, 1)){ |
| 739 | rlock(&m->lock); | | |
| 740 | runlock(&pg->ns); | | |
| 741 | if(mp != nil) | 741 | if(mp != nil) |
| 742 | incref(&m->ref); | 742 | incref(&m->ref); |
| | 743 | rlock(&m->lock); |
| 743 | to = m->mount->to; | 744 | to = m->mount->to; |
| 744 | incref(&to->ref); | 745 | incref(&to->ref); |
| 745 | runlock(&m->lock); | 746 | runlock(&m->lock); |
| | 747 | runlock(&pg->ns); |
| 746 | if(mp != nil){ | 748 | if(mp != nil){ |
| 747 | putmhead(*mp); | 749 | putmhead(*mp); |
| 748 | *mp = m; | 750 | *mp = m; |
| @@ -957,7 +959,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) · 208 unmodified lines |
| 957 | n = wq->nqid; | 959 | n = wq->nqid; |
| 958 | nc = wq->clone; | 960 | nc = wq->clone; |
| 959 | }else{ /* stopped early, at a mount point */ | 961 | }else{ /* stopped early, at a mount point */ |
| 960 | didmount = 1; | 962 | assert(didmount); |
| 961 | if(wq->clone != nil){ | 963 | if(wq->clone != nil){ |
| 962 | cclose(wq->clone); | 964 | cclose(wq->clone); |
| 963 | wq->clone = nil; | 965 | wq->clone = nil; |
| @@ -979,11 +981,6 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) · 15 unmodified lines |
| 979 | } | 981 | } |
| 980 | putmhead(mh); | 982 | putmhead(mh); |
| 981 | c = cunique(c); | 983 | c = cunique(c); |
| 982 | if(c->umh != nil){ //BUG | | |
| 983 | print("walk umh\n"); | | |
| 984 | putmhead(c->umh); | | |
| 985 | c->umh = nil; | | |
| 986 | } | | |
| 987 | | 984 | |
| 988 | pathclose(c->path); | 985 | pathclose(c->path); |
| 989 | c->path = path; | 986 | c->path = path; |
| @@ -1293,8 +1290,13 @@ namec(char *aname, int amode, int omode, ulong perm) · 303 unmodified lines |
| 1293 | m = nil; | 1290 | m = nil; |
| 1294 | if(!nomount) | 1291 | if(!nomount) |
| 1295 | domount(&c, &m, nil); | 1292 | domount(&c, &m, nil); |
| 1296 | putmhead(c->umh); | 1293 | if(waserror()){ |
| | 1294 | putmhead(m); |
| | 1295 | nexterror(); |
| | 1296 | } |
| | 1297 | c = cunique(c); |
| 1297 | c->umh = m; | 1298 | c->umh = m; |
| | 1299 | poperror(); |
| 1298 | break; | 1300 | break; |
| 1299 | | 1301 | |
| 1300 | case Aaccess: | 1302 | case Aaccess: |
| @@ -1311,9 +1313,13 @@ namec(char *aname, int amode, int omode, ulong perm) · 10 unmodified lines |
| 1311 | m = nil; | 1313 | m = nil; |
| 1312 | if(!nomount) | 1314 | if(!nomount) |
| 1313 | domount(&c, &m, &path); | 1315 | domount(&c, &m, &path); |
| 1314 | | 1316 | if(waserror()){ |
| | 1317 | putmhead(m); |
| | 1318 | nexterror(); |
| | 1319 | } |
| 1315 | /* our own copy to open or remove */ | 1320 | /* our own copy to open or remove */ |
| 1316 | c = cunique(c); | 1321 | c = cunique(c); |
| | 1322 | poperror(); |
| 1317 | | 1323 | |
| 1318 | /* now it's our copy anyway, we can put the name back */ | 1324 | /* now it's our copy anyway, we can put the name back */ |
| 1319 | pathclose(c->path); | 1325 | pathclose(c->path); |
| @@ -1331,16 +1337,17 @@ namec(char *aname, int amode, int omode, ulong perm) · 11 unmodified lines |
| 1331 | | 1337 | |
| 1332 | case Aopen: | 1338 | case Aopen: |
| 1333 | case Acreate: | 1339 | case Acreate: |
| 1334 | if(c->umh != nil){ | | |
| 1335 | print("cunique umh Open\n"); | | |
| 1336 | putmhead(c->umh); | | |
| 1337 | c->umh = nil; | | |
| 1338 | } | | |
| 1339 | /* only save the mount head if it's a multiple element union */ | 1340 | /* only save the mount head if it's a multiple element union */ |
| 1340 | if(m != nil && m->mount != nil && m->mount->next != nil) | 1341 | if(m != nil) { |
| 1341 | c->umh = m; | 1342 | rlock(&m->lock); |
| 1342 | else | 1343 | if(m->mount != nil && m->mount->next != nil) { |
| 1343 | putmhead(m); | 1344 | c->umh = m; |
| | 1345 | runlock(&m->lock); |
| | 1346 | } else { |
| | 1347 | runlock(&m->lock); |
| | 1348 | putmhead(m); |
| | 1349 | } |
| | 1350 | } |
| 1344 | | 1351 | |
| 1345 | /* save registers else error() in open has wrong value of c saved */ | 1352 | /* save registers else error() in open has wrong value of c saved */ |
| 1346 | saveregisters(); | 1353 | saveregisters(); |