/** * eblob_l2hash_remove_nolock() - remove l2hash entry specified by @key * * Returns: * 0: @key removed * -ENOENT: @key not found * Other: Error */ static int eblob_l2hash_remove_nolock(struct eblob_l2hash *l2h, struct eblob_key *key) { struct eblob_l2hash_collision *collision; struct eblob_l2hash_entry *e; int err; assert(l2h != NULL); assert(key != NULL); assert(pthread_mutex_trylock(&l2h->root_lock) == EBUSY); /* Find entry in tree */ if ((e = __eblob_l2hash_lookup(l2h, key)) == NULL) return -ENOENT; /* * If there are no collisions check that key belongs to rctl and * remove entry from tree */ if (e->collision == 0) { switch(err = eblob_l2hash_compare_index(key, &e->rctl)) { case 0: rb_erase(&e->node, &l2h->root); free(e); return 0; case 1: return -ENOENT; default: return err; } } /* If collision is set and entry is not present in collision tree */ collision = __eblob_l2hash_resolve_collision(&l2h->collisions, key); if (collision == NULL) return -ENOENT; /* Otherwise - remove entry from collision tree */ rb_erase(&collision->node, &l2h->collisions); free(collision); return 0; }
/** * eblob_l2hash_resolve_collision() - resolves possible collision in l2hash by * going to disk or walking collision tree. * * Returns: * 0: @key resolved into @rctl * -ENOENT: @key not found * Other: Error */ static int eblob_l2hash_resolve_collision(struct rb_root *root, struct eblob_l2hash_entry *e, const struct eblob_key *key, struct eblob_ram_control *rctl) { struct eblob_l2hash_collision *collision; int err; assert(root != NULL); assert(e != NULL); assert(key != NULL); assert(rctl != NULL); /* * No collision detected so just check that key really belongs * to cached ram control. */ if (e->collision == 0) { switch((err = eblob_l2hash_compare_index(key, &e->rctl))) { case 0: *rctl = e->rctl; return 0; case 1: return -ENOENT; default: return err; } /* NOT REACHED */ } /* * If there is collision then we should look in collision tree. */ if ((collision = __eblob_l2hash_resolve_collision(root, key)) == NULL) return -ENOENT; *rctl = collision->rctl; return 0; }