rem: err = EISDIR;
add: err = FS_EISDIR;
context: do_unlink(nspace *ns, vnode *dir, const char *name, bool isdir){    int         err;    vnode       *vn;    LOCK(ns->lock);    if (!MY_S_ISDIR(dir->mode)) {        err = ENOTDIR;        goto error1;    }        /*    can't delete '..' and '.'    */    if (!strcmp(name, "..") || !strcmp(name, ".")) {        err = EINVAL;        goto error1;    }            /*    lookup the name in the directory            */    vn = dir->head;    while (vn) {        if (!strcmp(vn->name, name))            break;        vn = vn->next;    }        /*    if it was not found, report an error.    */    if (!vn) {        err = ENOENT;        goto error1;    }    /*    ensure it is of the appropriate type.    */    if (isdir && !(vn->mode & MY_S_IFDIR)) {        err = ENOTDIR;        goto error1;    }    if (!isdir && (vn->mode & MY_S_IFDIR)) {        err = EISDIR;        goto error1;    }            /*    make sure it is not the root    */    if (vn == vn->ns->root) {        err = EBUSY;        goto error1;    }    /*    if it is a directory, make sure it is empty    */    if (MY_S_ISDIR(vn->mode) && vn->head) {        err = ENOTEMPTY;        goto error1;    }    err = get_vnode(ns->nsid, vn->vnid, (void *)&vn);    if (err)        goto error1;    err = remove_vnode(ns->nsid, vn->vnid);    if (err)        goto error1;    if (vn->prev)        vn->prev->next = vn->next;    else        vn->parent->head = vn->next;    if (vn->next)        vn->next->prev = vn->prev;    vn->prev = vn->next = NULL;    vn->removed = TRUE;    dir->mtime = time(NULL);    put_vnode(ns->nsid, vn->vnid);    UNLOCK(ns->lock);    return 0;error1:    UNLOCK(ns->lock);    return err;}