/* external function definitions */ int chanproc(void) { struct node work; /* queue marker */ struct node done; /* queue marker */ struct node *hp = &chans; struct node *wp = &work; struct node *dp = &done; struct node *np; struct chan *p; int pri=0; /* initialize local queue markers */ wp->f = wp->b = wp; dp->f = dp->b = dp; /* search for a priority with something to do */ for (np = hp->f; np != hp; np = np->f) { p = CHANAT(np); if (fdsisset(p->afds, p->fd)) { pri = p->pri; break; } } if (np == hp) return 0; /* nothing found to do */ /* place head of work list */ nodeinsert(wp, np); /* search forward for first with different priority */ while (((np = np->f) != hp) && (CHANAT(np)->pri == pri)); /* split the work list out of the chan list */ nodeinsert(wp, np); /* place the done marker into the list */ nodeinsert(dp, wp); /* process work list */ while ((np = wp->f) != dp) { nodetoad(wp); /* leap wp over np */ p = CHANAT(np); if (fdsisset(p->afds, p->fd)) { fdsclr(p->afds, p->fd); (*(p->func)) (p->ccbp); } } /* take out the work list head */ noderemove(wp); /* find insertion point for done things */ for (np = hp->f; np != hp; np = np->f) { if (pri >= CHANAT(np)->pri) break; } /* splice in the done list at the place found in the chan list */ nodeinsert(dp, np); /* take out the done list head */ noderemove(dp); return 1; }
/* * 9P supports renames only for files within a directory * from what I could tell. So just support in-directory renames * for now. */ int puffs9p_node_rename(struct puffs_usermount *pu, void *opc, void *src, const struct puffs_cn *pcn_src, void *targ_dir, void *targ, const struct puffs_cn *pcn_targ) { AUTOVAR(pu); struct puffs_node *pn_src = src; struct p9pnode *p9n_src = pn_src->pn_data; if (opc != targ_dir) { rv = EOPNOTSUPP; goto out; } /* 9P doesn't allow to overwrite in rename */ if (targ) { struct puffs_node *pn_targ = targ; rv = noderemove(pu, pn_targ->pn_data); if (rv) goto out; } p9pbuf_put_1(pb, P9PROTO_T_WSTAT); p9pbuf_put_2(pb, tag); p9pbuf_put_4(pb, p9n_src->fid_base); proto_make_stat(pb, NULL, pcn_targ->pcn_name, pn_src->pn_va.va_type); GETRESPONSE(pb); if (p9pbuf_get_type(pb) != P9PROTO_R_WSTAT) rv = EPROTO; out: RETURN(rv); }
/* external function definitions */ void mtmuprm(struct mtm * p) { if (p != (struct mtm *) (0)) { noderemove(p->unp); p->up = (void *) (0); } return; }
int puffs9p_node_rmdir(struct puffs_usermount *pu, void *opc, void *targ, const struct puffs_cn *pcn) { struct puffs_node *pn = targ; if (pn->pn_va.va_type != VDIR) return ENOTDIR; return noderemove(pu, pn); }
/* external function definitions */ void slpqwakeup(struct slpq * p, void (*sched) ()) { /* if the slpq is null we fake it cause it doesn't matter */ if (p != (struct slpq *) (0)) { struct node *np; if ((p->wakes <= 0) && ((np = p->wq->f) != p->wq)) { noderemove(np); slpqsched(SLPQENTAT(np), sched); } else if (p->wakes < p->maxwakes) ++(p->wakes); } return; }
/* external function definitions */ void slpqgiveup(struct slpqent * ep) { if (ep != (struct slpqent *) (0)) { struct slpq *p = ep->sp; int sched = ep->sched; noderemove(ep->np); nodefree(ep->np); bfree((char *) ep); if (sched) slpqwakeup(p, (void (*) ()) (0)); } return; }
/* external function definitions */ void chansetpri(struct chan * p, int pri) { if (p != (struct chan *) (0)) { struct node *np = p->np; struct node *hp = &chans; struct node *tnp; noderemove(np); p->pri = pri; for (tnp = hp->f; tnp != hp; tnp = tnp->f) { if (pri >= CHANAT(tnp)->pri) break; } nodeinsert(np, tnp); } return; }