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