rem: err = ENOMEM;
add: err = FS_ENOMEM;
context: do_create(nspace *ns, vnode *dir, const char *name, mode_t mode, vnode **vnp){    int         err;    int         c;    vnode       *vn, *pvn, *nvn;    char        *buf;    vnode_id    vnid;    if (!MY_S_ISDIR(dir->mode)) {        err = ENOTDIR;        goto error1;    }        /*    make sure we are not trying to create something in a directory    that has been removed.    */    if (dir->removed) {        err = ENOENT;        goto error1;    }    /*    filter the name:    can't be '.', or '..'    */    if (!strcmp(name, ".") || !strcmp(name, "..")) {        err = EEXIST;        goto error1;    }            /*    lookup the name in the directory            */    vn = dir->head;    while (vn) {        c = strcmp(name, vn->name);        if (c < 0)            vn = NULL;        if (c <= 0)            break;        vn = vn->next;    }        /*    if it was found, report an error.    */    if (vn) {        err = EEXIST;        goto error1;    }    /*    allocate a vnode and fill it    */    vn = NULL;    buf = NULL;    vn = (vnode *) malloc(sizeof(vnode));    buf = (char *) malloc(strlen(name)+1);    if (!vn || !buf) {        err = ENOMEM;        goto error2;    }    strcpy(buf, name);    vnid = ++ns->nxvnid;    vn->vnid = vnid;    vn->parent = dir;    vn->ns = ns;    vn->removed = FALSE;    vn->name = buf;    vn->mode = mode;    vn->uid = 0;    vn->gid = 0;    dir->mtime = vn->mtime = time(NULL);    pvn = NULL;    nvn = dir->head;    while (nvn && (strcmp(name, nvn->name) > 0)) {        pvn = nvn;        nvn = nvn->next;    }    vn->next = nvn;    if (nvn)        nvn->prev = vn;    vn->prev = pvn;    if (pvn)        pvn->next = vn;    else        dir->head = vn;    vn->head = NULL;    vn->symlink = NULL;    atomic_add(&ns->vnnum, 1);    InsertSL(ns->skiplist, vn);    *vnp = vn;    return 0;error2:    if (vn)        free(vn);    if (buf)        free(buf);error1:    return err;}