always make an upcall

if the thread placing an upcall was woken up from the sleep, but have not been picked up by the daemon thread from the upcall queue, we would just cancel the upcall. thus nfsd would never see it. however, it was causing leaks in the open state. we would allocate open state but matching close would never make it to the daemon.

instead, always place an upcall to the daemon, but mark it that nobody is waiting for it if the requesting thread gets interrupted and goes away.
This commit is contained in:
Olga Kornievskaia 2010-10-20 17:04:26 -04:00
parent aa49d80acc
commit 1b88791f6f

View file

@ -1254,18 +1254,11 @@ process_upcall:
entry = (nfs41_updowncall_entry *)CONTAINING_RECORD(pEntry, entry = (nfs41_updowncall_entry *)CONTAINING_RECORD(pEntry,
nfs41_updowncall_entry, next); nfs41_updowncall_entry, next);
ExAcquireFastMutex(&entry->lock); ExAcquireFastMutex(&entry->lock);
if (entry->state == NFS41_WAITING_FOR_UPCALL) {
nfs41_AddEntry(downcallLock, downcall, entry); nfs41_AddEntry(downcallLock, downcall, entry);
status = handle_upcall(RxContext, entry, &len); status = handle_upcall(RxContext, entry, &len);
if (status == STATUS_SUCCESS) if (status == STATUS_SUCCESS &&
entry->state == NFS41_WAITING_FOR_UPCALL)
entry->state = NFS41_WAITING_FOR_DOWNCALL; entry->state = NFS41_WAITING_FOR_DOWNCALL;
} else if (entry->state == NFS41_NOT_WAITING) {
DbgP("[upcall] Canceling %s upcall entry %p xid %d\n",
opcode2string(entry->opcode), entry, entry->xid);
ExReleaseFastMutex(&entry->lock);
RxFreePool(entry);
goto process_upcall;
}
ExReleaseFastMutex(&entry->lock); ExReleaseFastMutex(&entry->lock);
if (status == STATUS_INSUFFICIENT_RESOURCES) { if (status == STATUS_INSUFFICIENT_RESOURCES) {
DbgP("upcall buffer is too small\n"); DbgP("upcall buffer is too small\n");