rem: return EBADF;
add: return FS_EBADF;
context: flush_blocks(int dev, fs_off_t bnum, int nblocks){    int        cur, i;    cache_ent *ce;    cache_ent *ents[NUM_FLUSH_BLOCKS];    if (nblocks == 0)   /* might as well check for this */        return 0;    LOCK(bc.lock);        cur = 0;    for(; nblocks > 0; nblocks--, bnum++) {        ce = block_lookup(dev, bnum);        if (ce == NULL)            continue;                    if (bnum != ce->block_num || dev != ce->dev) {            UNLOCK(bc.lock);            panic("error2: looked up dev %d block %ld but found %d %ld\n",                  dev, bnum, ce->dev, ce->block_num);            return EBADF;        }        if ((ce->flags & CE_DIRTY) == 0 && ce->clone == NULL)            continue;        ce->flags |= CE_BUSY;        ents[cur++] = ce;        if (cur >= NUM_FLUSH_BLOCKS) {            UNLOCK(bc.lock);            qsort(ents, cur, sizeof(cache_ent **), cache_ent_cmp);            flush_ents(ents, cur);            LOCK(bc.lock);            for(i=0; i < cur; i++) {                ents[i]->flags &= ~CE_BUSY;            }            cur = 0;        }    }    UNLOCK(bc.lock);    if (cur == 0)     /* nothing more to do */        return 0;    /* flush out the last few buggers */    qsort(ents, cur, sizeof(cache_ent **), cache_ent_cmp);    flush_ents(ents, cur);    for(i=0; i < cur; i++) {        ents[i]->flags &= ~CE_BUSY;    }    return 0;}