static void msgringent_free (msgringent * ktmp) { int i; for(i=0; i<ktmp->body.n; i++) ppage_unpin (kva2pp ((u_long) ktmp->body.r[i].data)); if (ktmp->owner != NULL) ppage_unpin (kva2pp ((u_long) ktmp->owner)); free (ktmp); }
void disk_buf_free (struct buf *bp) { u_int datalen; u_int data, next; /* unpin pages */ if (bp->b_flags & B_SCSICMD) { struct scsicmd *scsicmd = (struct scsicmd *) bp->b_memaddr; data = (u_int) scsicmd->data_addr; datalen = scsicmd->datalen; free (scsicmd->scsi_cmd); free (scsicmd); } else { data = (u_int)bp->b_memaddr; datalen = bp->b_bcount; } while (datalen > 0) { if (bp->b_flags & B_BC_REQ) { ppage_unpin (kva2pp (data)); } else { struct Env *e; int r; e = env_id2env (bp->b_envid, &r); assert (e); /* XXX - what if an env with an outstanding request dies? */ ppage_unpin (&ppages[PGNO (*env_va2ptep (e, data))]); } /* go to start of next page of data */ next = (data & ~PGMASK) + NBPG; if (next - data >= datalen) break; assert (next > data); datalen -= next - data; data = next; } if (bp->b_resptr) { ppage_unpin (kva2pp ((u_int) bp->b_resptr)); } free (bp); }
void wk_free (struct Env *e) { int i; struct Ppage *pp; if (e->env_pred) { free (e->env_pred); e->env_pred = NULL; } if (!e->env_pred_pgs) return; for (i = 0; e->env_pred_pgs[i]; i++) { pp = ppages_get(e->env_pred_pgs[i]); ppage_unpin (pp); } free (e->env_pred_pgs); e->env_pred_pgs = NULL; }
int disk_prepare_bc_request (u_int devno, u_quad_t blkno, void *vaddr, u_int flags, int *resptr, struct buf **headbpp) { struct buf *bp; /* XXX - test for big blkno wraparound */ if ((devno >= si->si_ndisks) || (((blkno * NBPG) / si->si_disks[devno].d_bsize) >= si->si_disks[devno].d_size)) { warn ("disk_prepare_bc_request: invalid devno (%u) or blkno (%qu)", devno, blkno); return (-E_INVAL); } if (headbpp == NULL) { warn ("disk_prepare_bc_request: headbpp == NULL"); return (-E_INVAL); } bp = disk_buf_alloc(); if (!bp) return (-E_NO_MEM); bp->b_next = NULL; bp->b_sgnext = NULL; bp->b_flags = flags; bp->b_dev = devno; bp->b_blkno = (blkno * NBPG) / si->si_disks[devno].d_bsize; bp->b_bcount = NBPG; bp->b_sgtot = 0; bp->b_memaddr = vaddr; bp->b_envid = curenv->env_id; bp->b_resid = 0; bp->b_resptr = NULL; ppage_pin (kva2pp((u_int) vaddr)); if (*headbpp) { struct buf *tmpbp = *headbpp; while (tmpbp->b_flags & B_SCATGATH) { tmpbp = (struct buf *) tmpbp->b_sgnext; if (tmpbp == NULL) { warn ("disk_prepare_bc_request: bad scatter/gather list"); ppage_unpin (kva2pp((u_int) vaddr)); free (bp); return (-E_INVAL); } } /* XXX - test for big blkno wraparound */ if (bp->b_blkno != (tmpbp->b_blkno + (tmpbp->b_bcount / si->si_disks[bp->b_dev].d_bsize))) { warn ("disk_prepare_bc_request: noncontiguous requests " "(prevblk %qu, size %u, curblk %qu) can't be merged", tmpbp->b_blkno, tmpbp->b_bcount, bp->b_blkno); ppage_unpin (kva2pp((u_int) vaddr)); free (bp); return (-E_INVAL); } (*headbpp)->b_sgtot += NBPG; tmpbp->b_flags |= B_SCATGATH; tmpbp->b_sgnext = bp; } else { *headbpp = bp; bp->b_sgtot = NBPG; } if (resptr) { ppage_pin (kva2pp(((u_int) resptr))); } bp->b_resptr = resptr; return (0); }