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