LASSERT(cache->free_entry);
LASSERT(atomic_read(&entry->ue_refcount) == 0);
- CDEBUG(D_OTHER, "destroy %s entry %p for key "LPU64"\n",
+ CDEBUG(D_SEC, "destroy %s entry %p for key "LPU64"\n",
cache->uc_name, entry, entry->ue_key);
list_del(&entry->ue_hash);
static int check_unlink_entry(struct upcall_cache_entry *entry)
{
+ /* upcall will be issued upon new entries immediately
+ * after they are created
+ */
+ LASSERT(!UC_CACHE_IS_NEW(entry));
+
if (UC_CACHE_IS_VALID(entry) &&
time_before(get_seconds(), entry->ue_expire))
return 0;
- if (UC_CACHE_IS_ACQUIRING(entry) &&
- time_after(get_seconds(), entry->ue_acquire_expire)) {
- UC_CACHE_SET_EXPIRED(entry);
- wake_up_all(&entry->ue_waitq);
+ if (UC_CACHE_IS_ACQUIRING(entry)) {
+ if (time_before(get_seconds(), entry->ue_acquire_expire))
+ return 0;
+ else {
+ UC_CACHE_SET_EXPIRED(entry);
+ wake_up_all(&entry->ue_waitq);
+ }
} else if (!UC_CACHE_IS_INVALID(entry)) {
UC_CACHE_SET_EXPIRED(entry);
}
set_current_state(TASK_INTERRUPTIBLE);
write_unlock(&cache->uc_hashlock);
- schedule_timeout(cache->uc_acquire_expire);
+ schedule_timeout(cache->uc_acquire_expire * HZ);
write_lock(&cache->uc_hashlock);
remove_wait_queue(&entry->ue_waitq, &wait);
entry->ue_expire);
put_entry(entry);
write_unlock(&cache->uc_hashlock);
+ CERROR("Interrupted? Or check whether %s is in place\n",
+ cache->uc_upcall);
RETURN(NULL);
}
/* fall through */
}
/* Now we know it's good */
- LASSERT(UC_CACHE_IS_VALID(entry));
write_unlock(&cache->uc_hashlock);
RETURN(entry);
}
EXPORT_SYMBOL(upcall_cache_put_entry);
-int upcall_cache_downcall(struct upcall_cache *cache, __u64 key,
- int err, void *args)
+int upcall_cache_downcall(struct upcall_cache *cache, __u64 key, void *args)
{
struct list_head *head;
struct upcall_cache_entry *entry;
RETURN(-EINVAL);
}
- if (err < 0) {
- UC_CACHE_SET_INVALID(entry);
- GOTO(out, rc = err);
+ if (!UC_CACHE_IS_ACQUIRING(entry)) {
+ if (UC_CACHE_IS_VALID(entry)) {
+ /* This should not happen, just give a warning
+ * at this moment.
+ */
+ CWARN("entry %p(key "LPU64", ac %ld, ex %ld): "
+ "already valid???\n", entry, entry->ue_key,
+ entry->ue_acquire_expire, entry->ue_expire);
+ GOTO(out, rc = 0);
+ }
+
+ CWARN("stale entry %p: cur %lu, key "LPU64", ref %d, "
+ "fl %u, ac %ld, ex %ld\n",
+ entry, get_seconds(), entry->ue_key,
+ atomic_read(&entry->ue_refcount), entry->ue_flags,
+ entry->ue_acquire_expire, entry->ue_expire);
+ GOTO(out, rc = -EINVAL);
}
if (!UC_CACHE_IS_ACQUIRING(entry) ||
rc = cache->parse_downcall(cache, entry, args);
write_lock(&cache->uc_hashlock);
atomic_dec(&entry->ue_refcount);
- if (rc) {
+
+ if (rc < 0) {
UC_CACHE_SET_INVALID(entry);
list_del_init(&entry->ue_hash);
GOTO(out, rc);
+ } else if (rc == 0) {
+ entry->ue_expire = get_seconds() + cache->uc_entry_expire;
+ } else {
+ entry->ue_expire = get_seconds() + cache->uc_err_entry_expire;
}
- entry->ue_expire = get_seconds() + cache->uc_entry_expire;
+
UC_CACHE_SET_VALID(entry);
- CDEBUG(D_OTHER, "create ucache entry %p(key "LPU64")\n",
+ CDEBUG(D_SEC, "create ucache entry %p(key "LPU64")\n",
entry, entry->ue_key);
out:
wake_up_all(&entry->ue_waitq);