Image* attachimage(int type, Chan *c, ulong base, ulong len) { Image *i, **l; lock(&imagealloc); /* * Search the image cache for remains of the text from a previous * or currently running incarnation */ for(i = ihash(c->qid.path); i; i = i->hash) { if(c->qid.path == i->qid.path) { lock(i); if(eqqid(c->qid, i->qid) && eqqid(c->mqid, i->mqid) && c->mchan == i->mchan && c->type == i->type) { goto found; } unlock(i); } } /* * imagereclaim dumps pages from the free list which are cached by image * structures. This should free some image structures. */ while(!(i = imagealloc.free)) { unlock(&imagealloc); imagereclaim(); if(!imagealloc.free){ freebroken(); /* can use the memory */ resrcwait("no image after reclaim"); } lock(&imagealloc); } imagealloc.free = i->next; lock(i); incref(c); c->flag &= ~CCACHE; i->c = c; i->type = c->type; i->qid = c->qid; i->mqid = c->mqid; i->mchan = c->mchan; l = &ihash(c->qid.path); i->hash = *l; *l = i; found: unlock(&imagealloc); if(i->s == 0) { i->ref++; if(waserror()) { unlock(i); putimage(i); nexterror(); } i->s = newseg(type, base, len); i->s->image = i; poperror(); } else incref(i->s); return i; }
Image* attachimage(int type, Chan *c, int color, uintptr base, usize len) { Image *i, **l; /* reclaim any free channels from reclaimed segments */ if(imagealloc.nfreechan) imagechanreclaim(); lock(&imagealloc); /* * Search the image cache for remains of the text from a previous * or currently running incarnation */ for(i = ihash(c->qid.path); i; i = i->hash) { if(c->qid.path == i->qid.path) { lock(i); if(eqqid(c->qid, i->qid) && eqqid(c->mqid, i->mqid) && c->mchan == i->mchan && c->dev->dc == i->dc) { //subtype goto found; } unlock(i); } } /* * imagereclaim dumps pages from the free list which are cached by image * structures. This should free some image structures. */ while(!(i = lruimage())) { unlock(&imagealloc); imagereclaim(); sched(); lock(&imagealloc); } lock(i); incref(c); i->c = c; i->dc = c->dev->dc; //subtype i->qid = c->qid; i->mqid = c->mqid; i->mchan = c->mchan; i->color = color; l = &ihash(c->qid.path); i->hash = *l; *l = i; found: imageused(i); unlock(&imagealloc); if(i->s == 0) { /* Disaster after commit in exec */ if(waserror()) { unlock(i); pexit(Enovmem, 1); } i->s = newseg(type, base, len); i->s->image = i; i->s->color = color; i->ref++; poperror(); } else incref(i->s); return i; }
Xfs * getxfs(char *user, char *name) { Xfs *xf, *fxf; Dir *dir; Qid dqid; char *p, *q; int32_t offset; int fd, omode; USED(user); if(name==nil || name[0]==0) name = deffile; if(name == nil){ errno = Enofilsys; return 0; } /* * If the name passed is of the form 'name:offset' then * offset is used to prime xf->offset. This allows accessing * a FAT-based filesystem anywhere within a partition. * Typical use would be to mount a filesystem in the presence * of a boot manager programme at the beginning of the disc. */ offset = 0; if(p = strrchr(name, ':')){ *p++ = 0; offset = strtol(p, &q, 0); chat("name %s, offset %ld\n", p, offset); if(offset < 0 || p == q){ errno = Enofilsys; return 0; } offset *= Sectorsize; } if(readonly) omode = OREAD; else omode = ORDWR; fd = open(name, omode); if(fd < 0 && omode==ORDWR){ omode = OREAD; fd = open(name, omode); } if(fd < 0){ chat("can't open %s: %r\n", name); errno = Eerrstr; return 0; } dir = dirfstat(fd); if(dir == nil){ errno = Eio; close(fd); return 0; } dqid = dir->qid; free(dir); mlock(&xlock); for(fxf=0,xf=xhead; xf; xf=xf->next){ if(xf->ref == 0){ if(fxf == 0) fxf = xf; continue; } if(!eqqid(xf->qid, dqid)) continue; if(strcmp(xf->name, name) != 0 || xf->dev < 0) continue; if(devcheck(xf) < 0) /* look for media change */ continue; if(offset && xf->offset != offset) continue; chat("incref \"%s\", dev=%d...", xf->name, xf->dev); ++xf->ref; unmlock(&xlock); close(fd); return xf; } if(fxf == nil){ fxf = malloc(sizeof(Xfs)); if(fxf == nil){ unmlock(&xlock); close(fd); errno = Enomem; return nil; } fxf->next = xhead; xhead = fxf; } chat("alloc \"%s\", dev=%d...", name, fd); fxf->name = strdup(name); fxf->ref = 1; fxf->qid = dqid; fxf->dev = fd; fxf->fmt = 0; fxf->offset = offset; fxf->ptr = nil; fxf->isfat32 = 0; fxf->omode = omode; unmlock(&xlock); return fxf; }
Image* attachimage(int type, Chan *c, ulong base, ulong len) { Image *i, **l; /* reclaim any free channels from reclaimed segments */ if(imagealloc.nfreechan) imagechanreclaim(); lock(&imagealloc.lk); /* * Search the image cache for remains of the text from a previous * or currently running incarnation */ for(i = ihash(c->qid.path); i; i = i->hash) { if(c->qid.path == i->qid.path) { lock(&i->ref.lk); if(eqqid(c->qid, i->qid) && eqqid(c->mqid, i->mqid) && c->mchan == i->mchan && c->type == i->type) { goto found; } unlock(&i->ref.lk); } } /* * imagereclaim dumps pages from the free list which are cached by image * structures. This should free some image structures. */ while(!(i = imagealloc.free)) { unlock(&imagealloc.lk); imagereclaim(); sched(); lock(&imagealloc.lk); } imagealloc.free = i->next; lock(&i->ref.lk); incref(&c->ref); i->c = c; i->type = c->type; i->qid = c->qid; i->mqid = c->mqid; i->mchan = c->mchan; l = &ihash(c->qid.path); i->hash = *l; *l = i; found: unlock(&imagealloc.lk); if(i->s == 0) { /* Disaster after commit in exec */ if(waserror()) { unlock(&i->ref.lk); pexit(Enovmem, 1); } i->s = newseg(type, base, len); i->s->image = i; i->ref.ref++; poperror(); } else incref(&i->s->ref); return i; }