示例#1
0
VOID
PvfsReleaseFCB(
    PPVFS_FCB *ppFcb
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    BOOLEAN bucketLocked = FALSE;
    BOOLEAN fcbLocked = FALSE;
    PPVFS_FCB pFcb = NULL;
    PPVFS_CB_TABLE_ENTRY pBucket = NULL;
    LONG refCount = 0;

    LWIO_ASSERT((ppFcb != NULL) && (*ppFcb != NULL));

    pFcb = *ppFcb;

    // It is important to lock the ScbTable here so that there is no window
    // between the refcount check and the remove. Otherwise another open request
    // could search and locate the SCB in the tree and return free()'d memory.
    // However, if the SCB has no bucket pointer, it has already been removed
    // from the ScbTable so locking is unnecessary. */

    LWIO_LOCK_MUTEX(fcbLocked, &pFcb->BaseControlBlock.Mutex);

    pBucket = pFcb->BaseControlBlock.pBucket;

    if (pBucket)
    {
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(bucketLocked, &pBucket->rwLock);
    }

    refCount = InterlockedDecrement(&pFcb->BaseControlBlock.RefCount);
    LWIO_ASSERT(refCount >= 0);

    if (refCount == 0)
    {
        LWIO_ASSERT(PvfsListIsEmpty(pFcb->pScbList));

        if (pBucket)
        {
            ntError = PvfsCbTableRemove_inlock(
                          (PPVFS_CONTROL_BLOCK)pFcb,
                          pFcb->pszFilename);
            LWIO_ASSERT(ntError == STATUS_SUCCESS);

            LWIO_UNLOCK_RWMUTEX(bucketLocked, &pBucket->rwLock);
        }

        LWIO_UNLOCK_MUTEX(fcbLocked, &pFcb->BaseControlBlock.Mutex);

        PvfsFreeFCB(pFcb);
    }

    LWIO_UNLOCK_RWMUTEX(bucketLocked, &pBucket->rwLock);
    LWIO_UNLOCK_MUTEX(fcbLocked, &pFcb->BaseControlBlock.Mutex);

    *ppFcb = NULL;

    return;
}
示例#2
0
NTSTATUS
PvfsListRemoveItem(
    PPVFS_LIST pList,
    PLW_LIST_LINKS pItem
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;

    BAIL_ON_INVALID_PTR(pList, ntError);
    BAIL_ON_INVALID_PTR(pItem, ntError);

    if (PvfsListIsEmpty(pList))
    {
        ntError = STATUS_NOT_FOUND;
        BAIL_ON_NT_STATUS(ntError);
    }

    LwListRemove(pItem);
    pList->CurrentSize--;

    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    goto cleanup;
}
示例#3
0
VOID
PvfsListDestroy(
    PPVFS_LIST *ppList
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_LIST pList = NULL;
    PLW_LIST_LINKS pData = NULL;

    if (ppList && *ppList)
    {
        pList = *ppList;

        while (!PvfsListIsEmpty(pList))
        {
            pData = NULL;

            ntError = PvfsListRemoveHead(pList, &pData);

            /* Avoid an infinite loop in the case of
               an error.  This means we may leak memory. */
            BAIL_ON_NT_STATUS(ntError);

            if (pList->pfnFreeData)
            {
                pList->pfnFreeData((PVOID*)&pData);
            }
            else
            {
                PVFS_FREE(&pData);
            }
        }

        RTL_FREE(ppList);
    }

cleanup:
    return;

error:
    goto cleanup;
}