1 #include "u.h" 2 #include "lib.h" 3 #include "dat.h" 4 #include "fns.h" 5 #include "error.h" 6 7 static Ref pgrpid; 8 static Ref mountid; 9 10 #ifdef NOTDEF 11 void 12 pgrpnote(ulong noteid, char *a, long n, int flag) 13 { 14 Proc *p, *ep; 15 char buf[ERRMAX]; 16 17 if(n >= ERRMAX-1) 18 error(Etoobig); 19 20 memmove(buf, a, n); 21 buf[n] = 0; 22 p = proctab(0); 23 ep = p+conf.nproc; 24 for(; p < ep; p++) { 25 if(p->state == Dead) 26 continue; 27 if(up != p && p->noteid == noteid && p->kp == 0) { 28 qlock(&p->debug); 29 if(p->pid == 0 || p->noteid != noteid){ 30 qunlock(&p->debug); 31 continue; 32 } 33 if(!waserror()) { 34 postnote(p, 0, buf, flag); 35 poperror(); 36 } 37 qunlock(&p->debug); 38 } 39 } 40 } 41 #endif 42 43 Pgrp* 44 newpgrp(void) 45 { 46 Pgrp *p; 47 48 p = smalloc(sizeof(Pgrp)); 49 p->ref.ref = 1; 50 p->pgrpid = incref(&pgrpid); 51 return p; 52 } 53 54 Rgrp* 55 newrgrp(void) 56 { 57 Rgrp *r; 58 59 r = smalloc(sizeof(Rgrp)); 60 r->ref.ref = 1; 61 return r; 62 } 63 64 void 65 closergrp(Rgrp *r) 66 { 67 if(decref(&r->ref) == 0) 68 free(r); 69 } 70 71 void 72 closepgrp(Pgrp *p) 73 { 74 Mhead **h, **e, *f, *next; 75 76 if(decref(&p->ref) != 0) 77 return; 78 79 qlock(&p->debug); 80 wlock(&p->ns); 81 p->pgrpid = -1; 82 83 e = &p->mnthash[MNTHASH]; 84 for(h = p->mnthash; h < e; h++) { 85 for(f = *h; f; f = next) { 86 wlock(&f->lock); 87 cclose(f->from); 88 mountfree(f->mount); 89 f->mount = nil; 90 next = f->hash; 91 wunlock(&f->lock); 92 putmhead(f); 93 } 94 } 95 wunlock(&p->ns); 96 qunlock(&p->debug); 97 free(p); 98 } 99 100 void 101 pgrpinsert(Mount **order, Mount *m) 102 { 103 Mount *f; 104 105 m->order = 0; 106 if(*order == 0) { 107 *order = m; 108 return; 109 } 110 for(f = *order; f; f = f->order) { 111 if(m->mountid < f->mountid) { 112 m->order = f; 113 *order = m; 114 return; 115 } 116 order = &f->order; 117 } 118 *order = m; 119 } 120 121 /* 122 * pgrpcpy MUST preserve the mountid allocation order of the parent group 123 */ 124 void 125 pgrpcpy(Pgrp *to, Pgrp *from) 126 { 127 int i; 128 Mount *n, *m, **link, *order; 129 Mhead *f, **tom, **l, *mh; 130 131 wlock(&from->ns); 132 order = 0; 133 tom = to->mnthash; 134 for(i = 0; i < MNTHASH; i++) { 135 l = tom++; 136 for(f = from->mnthash[i]; f; f = f->hash) { 137 rlock(&f->lock); 138 mh = newmhead(f->from); 139 *l = mh; 140 l = &mh->hash; 141 link = &mh->mount; 142 for(m = f->mount; m; m = m->next) { 143 n = newmount(mh, m->to, m->mflag, m->spec); 144 m->copy = n; 145 pgrpinsert(&order, m); 146 *link = n; 147 link = &n->next; 148 } 149 runlock(&f->lock); 150 } 151 } 152 /* 153 * Allocate mount ids in the same sequence as the parent group 154 */ 155 lock(&mountid.lk); 156 for(m = order; m; m = m->order) 157 m->copy->mountid = mountid.ref++; 158 unlock(&mountid.lk); 159 wunlock(&from->ns); 160 } 161 162 Fgrp* 163 dupfgrp(Fgrp *f) 164 { 165 Fgrp *new; 166 Chan *c; 167 int i; 168 169 new = smalloc(sizeof(Fgrp)); 170 if(f == nil){ 171 new->fd = smalloc(DELTAFD*sizeof(Chan*)); 172 new->nfd = DELTAFD; 173 new->ref.ref = 1; 174 return new; 175 } 176 177 lock(&f->ref.lk); 178 /* Make new fd list shorter if possible, preserving quantization */ 179 new->nfd = f->maxfd+1; 180 i = new->nfd%DELTAFD; 181 if(i != 0) 182 new->nfd += DELTAFD - i; 183 new->fd = malloc(new->nfd*sizeof(Chan*)); 184 if(new->fd == 0){ 185 unlock(&f->ref.lk); 186 error("no memory for fgrp"); 187 } 188 new->ref.ref = 1; 189 190 new->maxfd = f->maxfd; 191 for(i = 0; i <= f->maxfd; i++) { 192 if((c = f->fd[i])){ 193 incref(&c->ref); 194 new->fd[i] = c; 195 } 196 } 197 unlock(&f->ref.lk); 198 199 return new; 200 } 201 202 void 203 closefgrp(Fgrp *f) 204 { 205 int i; 206 Chan *c; 207 208 if(f == 0) 209 return; 210 211 if(decref(&f->ref) != 0) 212 return; 213 214 for(i = 0; i <= f->maxfd; i++) 215 if((c = f->fd[i])) 216 cclose(c); 217 218 free(f->fd); 219 free(f); 220 } 221 222 Mount* 223 newmount(Mhead *mh, Chan *to, int flag, char *spec) 224 { 225 Mount *m; 226 227 m = smalloc(sizeof(Mount)); 228 m->to = to; 229 m->head = mh; 230 incref(&to->ref); 231 m->mountid = incref(&mountid); 232 m->mflag = flag; 233 if(spec != 0) 234 kstrdup(&m->spec, spec); 235 236 return m; 237 } 238 239 void 240 mountfree(Mount *m) 241 { 242 Mount *f; 243 244 while(m) { 245 f = m->next; 246 cclose(m->to); 247 m->mountid = 0; 248 free(m->spec); 249 free(m); 250 m = f; 251 } 252 } 253 254 #ifdef NOTDEF 255 void 256 resrcwait(char *reason) 257 { 258 char *p; 259 260 if(up == 0) 261 panic("resrcwait"); 262 263 p = up->psstate; 264 if(reason) { 265 up->psstate = reason; 266 print("%s\n", reason); 267 } 268 269 tsleep(&up->sleep, return0, 0, 300); 270 up->psstate = p; 271 } 272 #endif 273