net: Change transport_header_end -> tranport_offset
[akaros.git] / kern / src / ns / pgrp.c
index 8c21dcc..df747d5 100644 (file)
@@ -1,4 +1,31 @@
-// INFERNO
+/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+ * Portions Copyright © 1997-1999 Vita Nuova Limited
+ * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
+ *                                (www.vitanuova.com)
+ * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+ *
+ * Modified for the Akaros operating system:
+ * Copyright (c) 2013-2014 The Regents of the University of California
+ * Copyright (c) 2013-2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
 #include <vfs.h>
 #include <kfs.h>
 #include <slab.h>
 #include <cpio.h>
 #include <pmap.h>
 #include <smp.h>
-#include <ip.h>
+#include <net/ip.h>
 
-static struct kref pgrpid;
-static struct kref mountid;
+/* TODO: (ID) need a unique ID service.  These will loop around... */
+static int pgrpid;
+static int mountid;
+#define NEXT_ID(x) (__sync_add_and_fetch(&(x), 1))
 
-void
-closepgrp(struct pgrp *p)
+void closepgrp(struct pgrp *p)
 {
        struct mhead **h, **e, *f, *next;
-       
+
        wlock(&p->ns);
        p->pgrpid = -1;
 
        e = &p->mnthash[MNTHASH];
-       for(h = p->mnthash; h < e; h++) {
-               for(f = *h; f; f = next) {
+       for (h = p->mnthash; h < e; h++) {
+               for (f = *h; f; f = next) {
                        wlock(&f->lock);
                        cclose(f->from);
                        mountfree(f->mount);
@@ -42,38 +70,37 @@ closepgrp(struct pgrp *p)
        kfree(p);
 }
 
-static void
-freepgrp(struct kref *k)
+static void freepgrp(struct kref *k)
 {
        struct pgrp *p = container_of(k, struct pgrp, ref);
        closepgrp(p);
 }
 
-struct pgrp*
-newpgrp(void)
+struct pgrp *newpgrp(void)
 {
        struct pgrp *p;
 
-       p = kzmalloc(sizeof(struct pgrp), 0);
+       p = kzmalloc(sizeof(struct pgrp), MEM_WAIT);
        kref_init(&p->ref, freepgrp, 1);
-       kref_get(&pgrpid, 1);
-       p->pgrpid = kref_refcnt(&pgrpid);
+       p->pgrpid = NEXT_ID(pgrpid);
        p->progmode = 0644;
+       qlock_init(&p->debug);
+       rwinit(&p->ns);
+       qlock_init(&p->nsh);
        return p;
 }
 
-void
-pgrpinsert(struct mount **order, struct mount *m)
+void pgrpinsert(struct mount **order, struct mount *m)
 {
        struct mount *f;
 
        m->order = 0;
-       if(*order == 0) {
+       if (*order == 0) {
                *order = m;
                return;
        }
-       for(f = *order; f; f = f->order) {
-               if(m->mountid < f->mountid) {
+       for (f = *order; f; f = f->order) {
+               if (m->mountid < f->mountid) {
                        m->order = f;
                        *order = m;
                        return;
@@ -86,8 +113,7 @@ pgrpinsert(struct mount **order, struct mount *m)
 /*
  * pgrpcpy MUST preserve the mountid allocation order of the parent group
  */
-void
-pgrpcpy(struct pgrp *to, struct pgrp *from)
+void pgrpcpy(struct pgrp *to, struct pgrp *from)
 {
        ERRSTACK(2);
        int i;
@@ -95,30 +121,27 @@ pgrpcpy(struct pgrp *to, struct pgrp *from)
        struct mhead *f, **tom, **l, *mh;
 
        wlock(&from->ns);
-       if(waserror()){
+       if (waserror()) {
                wunlock(&from->ns);
                nexterror();
        }
        order = 0;
        tom = to->mnthash;
-       for(i = 0; i < MNTHASH; i++) {
+       for (i = 0; i < MNTHASH; i++) {
                l = tom++;
-               for(f = from->mnthash[i]; f; f = f->hash) {
+               for (f = from->mnthash[i]; f; f = f->hash) {
                        rlock(&f->lock);
-                       if(waserror()){
+                       if (waserror()) {
                                runlock(&f->lock);
                                nexterror();
                        }
-                       mh = kzmalloc(sizeof(struct mhead), 0);
-                       if(mh == NULL)
-                               error(Enomem);
-                       mh->from = f->from;
-                       kref_init(&mh->ref, fake_release, 1);
-                       kref_get(&mh->from->ref, 1);
+                       mh = newmhead(f->from);
+                       if (!mh)
+                               error(ENOMEM, ERROR_FIXME);
                        *l = mh;
                        l = &mh->hash;
                        link = &mh->mount;
-                       for(m = f->mount; m; m = m->next) {
+                       for (m = f->mount; m; m = m->next) {
                                n = newmount(mh, m->to, m->mflag, m->spec);
                                m->copy = n;
                                pgrpinsert(&order, m);
@@ -133,9 +156,8 @@ pgrpcpy(struct pgrp *to, struct pgrp *from)
         * Allocate mount ids in the same sequence as the parent group
         */
        /* should probably protect with a spinlock and be done with it */
-       for(m = order; m; m = m->order){
-               kref_get(&mountid, 1);
-               m->copy->mountid = kref_refcnt(&mountid);
+       for (m = order; m; m = m->order) {
+               m->copy->mountid = NEXT_ID(mountid);
        }
 
        to->progmode = from->progmode;
@@ -147,109 +169,27 @@ pgrpcpy(struct pgrp *to, struct pgrp *from)
        wunlock(&from->ns);
 }
 
-void
-closefgrp(struct fgrp *f)
-{
-       int i;
-       struct chan *c;
-
-       if(f == NULL || kref_put(&f->ref) != 0)
-               return;
-
-       for(i = 0; i <= f->maxfd; i++)
-               if((c = f->fd[i]))
-                       cclose(c);
-
-       kfree(f->fd);
-       kfree(f);
-}
-
-static void
-freefgrp(struct kref *k)
-{
-       struct fgrp *f = container_of(k, struct fgrp, ref);
-       closefgrp(f);
-}
-
-struct fgrp*
-newfgrp(struct fgrp *old)
-{
-       struct fgrp *new;
-       int n;
-
-       new = kzmalloc(sizeof(struct fgrp), 0);
-       kref_init(&new->ref, freefgrp, 1);
-       n = DELTAFD;
-       if(old != NULL){
-               spin_lock(&old->lock);
-               if(old->maxfd >= n)
-                       n = (old->maxfd+1 + DELTAFD-1)/DELTAFD * DELTAFD;
-               new->maxfd = old->maxfd;
-               spin_unlock(&old->lock);
-       }
-       new->nfd = n;
-       new->fd = kzmalloc(n * sizeof(struct chan *), 0);
-       return new;
-}
-
-struct fgrp*
-dupfgrp(struct fgrp *f)
-{
-       int i;
-       struct chan *c;
-       struct fgrp *new;
-       int n;
-
-       new = kzmalloc(sizeof(struct fgrp), 0);
-       kref_init(&new->ref, freefgrp, 1);
-       spin_lock(&f->lock);
-       n = DELTAFD;
-       if(f->maxfd >= n)
-               n = (f->maxfd+1 + DELTAFD-1)/DELTAFD * DELTAFD;
-       new->nfd = n;
-       new->fd = kzmalloc(n * sizeof(struct chan *), 0);
-       if(new->fd == NULL){
-               spin_unlock(&f->lock);
-               kfree(new);
-               error(Enomem);
-       }
-       new->maxfd = f->maxfd;
-       new->minfd = f->minfd;
-       for(i = 0; i <= f->maxfd; i++) {
-               if((c = f->fd[i])){
-                       kref_get(&c->ref, 1);
-                       new->fd[i] = c;
-               }
-       }
-       spin_unlock(&f->lock);
-
-       return new;
-}
-
-struct mount*
-newmount(struct mhead *mh, struct chan *to, int flag, char *spec)
+struct mount *newmount(struct mhead *mh, struct chan *to, int flag, char *spec)
 {
        struct mount *m;
 
        m = kzmalloc(sizeof(struct mount), 0);
        m->to = to;
        m->head = mh;
-       kref_get(&to->ref, 1);
-       kref_get(&mountid, 1);
-       m->mountid = kref_refcnt(&mountid);
+       chan_incref(to);
+       m->mountid = NEXT_ID(mountid);
        m->mflag = flag;
-       if(spec != 0)
+       if (spec != 0)
                kstrdup(&m->spec, spec);
 
        return m;
 }
 
-void
-mountfree(struct mount *m)
+void mountfree(struct mount *m)
 {
        struct mount *f;
 
-       while(m) {
+       while (m) {
                f = m->next;
                cclose(m->to);
                m->mountid = 0;
@@ -260,44 +200,53 @@ mountfree(struct mount *m)
 }
 
 #if 0
-almost certainly not needed.
-void
-resrcwait(char *reason)
+almost certainly not needed.void resrcwait(char *reason)
 {
        char *p;
 
-       if(current == 0)
+       if (current == 0)
                panic("resrcwait");
 
        p = up->psstate;
-       if(reason) {
+       if (reason) {
                up->psstate = reason;
                printd("%s\n", reason);
        }
 
-       udelay_sched(300 * 1000);
+       kthread_usleep(300 * 1000);
        up->psstate = p;
 }
 #endif
 
-void
-closesigs(struct skeyset *s)
+/* TODO: We don't have any alloc / initializer methods for skeyset or signerkey
+ * yet.  When we do, use these releases for their kref_init. */
+static void __sigs_release(struct kref *kref)
 {
+       struct skeyset *s = container_of(kref, struct skeyset, ref);
        int i;
-
-       if(s == NULL || kref_put(&s->ref) != 0)
-               return;
-       for(i=0; i<s->nkey; i++)
+       for (i = 0; i < s->nkey; i++)
                freeskey(s->keys[i]);
        kfree(s);
 }
 
-void
-freeskey(struct signerkey *key)
+void closesigs(struct skeyset *s)
 {
-       if(key == NULL || kref_put(&key->ref) != 0)
+       if (!s)
                return;
+       kref_put(&s->ref);
+}
+
+static void __key_release(struct kref *kref)
+{
+       struct signerkey *key = container_of(kref, struct signerkey, ref);
        kfree(key->owner);
-       (*key->pkfree)(key->pk);
+       (*key->pkfree) (key->pk);
        kfree(key);
 }
+
+void freeskey(struct signerkey *key)
+{
+       if (!key)
+               return;
+       kref_put(&key->ref);
+}