rem: err = ENOMEM;
add: err = FS_ENOMEM;
context: rootfs_rename(void *_ns, void *_olddir, const char *oldname, void *_newdir,                    const char *newname){    nspace      *ns;    vnode       *olddir, *newdir;    int         err;    vnode       *vn, *nvn, *pvn, *avn;    char        *p;    ns = (nspace *) _ns;    olddir = (vnode *) _olddir;    newdir = (vnode *) _newdir;    LOCK(ns->lock);    if (!MY_S_ISDIR(olddir->mode) || !MY_S_ISDIR(newdir->mode)) {        err = ENOTDIR;        goto error1;    }        /*    find (olddir, oldname)    */    if (!strcmp(oldname, ".") || !strcmp(oldname, "..")) {        err = EPERM;        goto error1;    }    vn = olddir->head;    while (vn) {        if (!strcmp(vn->name, oldname))            break;        vn = vn->next;    }    if (!vn) {        err = ENOENT;        goto error1;    }    /*    look for (newdir, newname)    */    if (!strcmp(newname, ".") || !strcmp(newname, "..")) {        err = EPERM;        goto error1;    }    nvn = newdir->head;    while (nvn) {        if (!strcmp(nvn->name, newname))            break;        nvn = nvn->next;    }    /*    don't do anything if old and new are the same    */    if (vn == nvn)        goto exit;    /*    make sure new is not a subdirectory of old    */    avn = newdir;    while (avn != ns->root) {        avn = avn->parent;        if (avn == olddir) {            err = EINVAL;            goto error1;        }    }    if (strlen(newname) > strlen(vn->name)) {        p = (char *) realloc(vn->name, strlen(newname)+1);        if (!p) {            err = ENOMEM;            goto error1;        }    } else        p = vn->name;    /*    if (newdir, newname) exists, remove it from the name space    */    if (nvn) {    /*    make sure it is not the root and it is not empty    */        if (nvn == nvn->ns->root) {            err = EBUSY;            goto error1;        }        if (MY_S_ISDIR(nvn->mode) && nvn->head) {            err = ENOTEMPTY;            goto error1;        }        err = get_vnode(ns->nsid, nvn->vnid, (void *)&nvn);        if (err)            goto error1;        err = remove_vnode(ns->nsid, nvn->vnid);        if (err)            goto error1;        if (nvn->prev)            nvn->prev->next = nvn->next;        else            nvn->parent->head = nvn->next;        if (nvn->next)            nvn->next->prev = nvn->prev;        nvn->prev = nvn->next = NULL;        put_vnode(ns->nsid, nvn->vnid);    }    if (vn->prev)        vn->prev->next = vn->next;    else        vn->parent->head = vn->next;    if (vn->next)        vn->next->prev = vn->prev;    pvn = NULL;    nvn = newdir->head;    while (nvn && (strcmp(newname, 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        newdir->head = vn;    vn->parent = newdir;    newdir->mtime = olddir->mtime = time(NULL);    strcpy(p, newname);    vn->name = p;exit:    UNLOCK(ns->lock);    return 0;error1:    UNLOCK(ns->lock);    return err;}