--- /sys/src/9k/port/sysseg.c +++ /sys/src/9k/port/sysseg.c @@ -72,13 +72,15 @@ ibrk(uintptr addr, int seg) return s->top; qlock(&s->lk); + if(waserror()){ + qunlock(&s->lk); + nexterror(); + } /* We may start with the bss overlapping the data */ if(addr < s->base) { - if(seg != BSEG || up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base) { - qunlock(&s->lk); + if(seg != BSEG || up->seg[DSEG] == 0 || addr < up->seg[DSEG]->base) error(Enovmem); - } addr = s->base; } @@ -91,12 +93,11 @@ ibrk(uintptr addr, int seg) * to-be-freed address space may have been passed to the kernel * already by another proc and is past the validaddr stage. */ - if(s->ref > 1){ - qunlock(&s->lk); + if(s->ref > 1) error(Einuse); - } mfreeseg(s, newtop, s->top); s->top = newtop; + poperror(); s->size = newsize; qunlock(&s->lk); mmuflush(); @@ -107,17 +108,13 @@ ibrk(uintptr addr, int seg) ns = up->seg[i]; if(ns == 0 || ns == s) continue; - if(newtop >= ns->base && newtop < ns->top) { - qunlock(&s->lk); + if(newtop >= ns->base && newtop < ns->top) error(Esoverlap); - } } mapsize = HOWMANY(newsize, PTEPERTAB); - if(mapsize > SEGMAPSIZE) { - qunlock(&s->lk); + if(mapsize > SEGMAPSIZE) error(Enovmem); - } if(mapsize > s->mapsize){ map = smalloc(mapsize*sizeof(Pte*)); memmove(map, s->map, s->mapsize*sizeof(Pte*)); @@ -129,6 +126,8 @@ ibrk(uintptr addr, int seg) s->top = newtop; s->size = newsize; + + poperror(); qunlock(&s->lk); return newtop;