Exemplo n.º 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;
}
Exemplo n.º 2
0
VOID
SrvTreeRundown(
    PLWIO_SRV_TREE pTree
    )
{
    BOOLEAN bInLock = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    LwRtlRBTreeTraverse(
                pTree->pAsyncStateCollection,
                LWRTL_TREE_TRAVERSAL_TYPE_IN_ORDER,
                SrvTreeRundownAsyncStatesRbTreeVisit,
                NULL);

	if (pTree->pAsyncStateCollection)
	{
	LwRtlRBTreeRemoveAll(pTree->pAsyncStateCollection);
	}

    LwRtlRBTreeTraverse(
            pTree->pFileCollection,
            LWRTL_TREE_TRAVERSAL_TYPE_IN_ORDER,
            SrvTreeRundownFileRbTreeVisit,
            NULL);

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);
}
Exemplo n.º 3
0
NTSTATUS
PvfsRemoveFileObject(
    IN PPVFS_FCB pFcb
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PPVFS_CB_TABLE_ENTRY fcbBucket = NULL;
    BOOLEAN fcbBucketLocked = FALSE;

    if (pFcb->BaseControlBlock.pBucket == NULL)
    {
        status = STATUS_SUCCESS;
        goto cleanup;
    }

    status = PvfsRemoveStreamObjects(pFcb);
    LWIO_ASSERT(STATUS_SUCCESS == status);

    fcbBucket = pFcb->BaseControlBlock.pBucket;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(fcbBucketLocked, &fcbBucket->rwLock);

    status = PvfsCbTableRemove_inlock(
                 (PPVFS_CONTROL_BLOCK)pFcb,
                 pFcb->pszFilename);
    LWIO_ASSERT(status == STATUS_SUCCESS);

    LWIO_UNLOCK_RWMUTEX(fcbBucketLocked, &fcbBucket->rwLock);

cleanup:

    LWIO_UNLOCK_RWMUTEX(fcbBucketLocked, &fcbBucket->rwLock);

    return status;
}
Exemplo n.º 4
0
NTSTATUS
SrvTreeRemoveFile(
    PLWIO_SRV_TREE pTree,
    USHORT        fid
    )
{
    NTSTATUS ntStatus = 0;
    BOOLEAN bInLock = FALSE;
    PLWIO_SRV_FILE pFile = NULL;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    pFile = pTree->lruFile[ fid % SRV_LRU_CAPACITY ];
    if (pFile && (pFile->fid == fid))
    {
        pTree->lruFile[ fid % SRV_LRU_CAPACITY ] = NULL;
    }

    ntStatus = LwRtlRBTreeRemove(
                    pTree->pFileCollection,
                    &fid);
    BAIL_ON_NT_STATUS(ntStatus);

    pTree->ulNumOpenFiles--;

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    return ntStatus;

error:

    goto cleanup;
}
Exemplo n.º 5
0
NTSTATUS
SrvSession2SetPrincipalName(
    PLWIO_SRV_SESSION_2 pSession,
    PCSTR               pszClientPrincipal
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN  bInLock  = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

    if (!pszClientPrincipal)
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    SRV_SAFE_FREE_MEMORY(pSession->pwszClientPrincipalName);

    ntStatus = SMBMbsToWc16s(
                    pszClientPrincipal,
                    &pSession->pwszClientPrincipalName);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);

    return ntStatus;

error:

    goto cleanup;
}
Exemplo n.º 6
0
NTSTATUS
SrvSession2CreateTree(
    PLWIO_SRV_SESSION_2 pSession,
    PSRV_SHARE_INFO     pShareInfo,
    PLWIO_SRV_TREE_2*   ppTree
    )
{
    NTSTATUS ntStatus = 0;
    PLWIO_SRV_TREE_2 pTree = NULL;
    BOOLEAN bInLock = FALSE;
    ULONG   ulTid = 0;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

    ntStatus = SrvSession2UpdateLastActivityTime_inlock(pSession);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvSession2AcquireTreeId_inlock(
                    pSession,
                    &ulTid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvTree2Create(
                    ulTid,
                    pShareInfo,
                    &pTree);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = LwRtlRBTreeAdd(
                    pSession->pTreeCollection,
                    &pTree->ulTid,
                    pTree);
    BAIL_ON_NT_STATUS(ntStatus);

    pTree->ullUid                 = pSession->ullUid;
    pTree->ulConnectionResourceId = pSession->ulConnectionResourceId;

    *ppTree = SrvTree2Acquire(pTree);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);

    return ntStatus;

error:

    *ppTree = NULL;

    if (pTree)
    {
        SrvTree2Release(pTree);
    }

    goto cleanup;
}
Exemplo n.º 7
0
VOID
SrvTree2ClearInParent(
    PLWIO_SRV_TREE_2 pTree
    )
{
    BOOLEAN bInLock = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);
    LWIO_ASSERT(IsSetFlag(pTree->objectFlags, SRV_OBJECT_FLAG_IN_PARENT));
    ClearFlag(pTree->objectFlags, SRV_OBJECT_FLAG_IN_PARENT);
    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);
}
Exemplo n.º 8
0
VOID
PvfsSetLastWriteTimeFCB(
    PPVFS_FCB pFcb,
    LONG64 LastWriteTime
    )
{
    BOOLEAN bLocked = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bLocked, &pFcb->BaseControlBlock.RwLock);
    pFcb->LastWriteTime = LastWriteTime;
    LWIO_UNLOCK_RWMUTEX(bLocked, &pFcb->BaseControlBlock.RwLock);
}
Exemplo n.º 9
0
BOOLEAN
SrvTree2IsInParent(
    PLWIO_SRV_TREE_2 pTree
    )
{
    BOOLEAN bIsInParent = FALSE;
    BOOLEAN bInLock = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);
    bIsInParent = SrvTree2IsInParent_inlock(pTree);
    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    return bIsInParent;
}
Exemplo n.º 10
0
NTSTATUS
SrvElementsResetStats(
    VOID
    )
{
    BOOLEAN  bInLock  = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gSrvElements.statsLock);

    memset(&gSrvElements.stats, 0, sizeof(gSrvElements.stats));

    LWIO_UNLOCK_RWMUTEX(bInLock, &gSrvElements.statsLock);

    return STATUS_SUCCESS;
}
Exemplo n.º 11
0
LONG64
PvfsClearLastWriteTimeFCB(
    PPVFS_FCB pFcb
    )
{
    BOOLEAN bLocked = FALSE;
    LONG64 LastWriteTime = 0;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bLocked, &pFcb->BaseControlBlock.RwLock);
    LastWriteTime = pFcb->LastWriteTime;
    pFcb->LastWriteTime = 0;
    LWIO_UNLOCK_RWMUTEX(bLocked, &pFcb->BaseControlBlock.RwLock);

    return LastWriteTime;
}
Exemplo n.º 12
0
NTSTATUS
SrvTreeAddAsyncState(
    PLWIO_SRV_TREE    pTree,
    PLWIO_ASYNC_STATE pAsyncState
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN  bInLock  = FALSE;
    PLWIO_ASYNC_STATE pAsyncState1 = NULL;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    ntStatus = LwRtlRBTreeFind(
                    pTree->pAsyncStateCollection,
                    &pAsyncState->ullAsyncId,
                    (PVOID*)&pAsyncState1);
    switch (ntStatus)
    {
        case STATUS_NOT_FOUND:

            ntStatus = LwRtlRBTreeAdd(
                            pTree->pAsyncStateCollection,
                            &pAsyncState->ullAsyncId,
                            pAsyncState);
            BAIL_ON_NT_STATUS(ntStatus);

            SrvAsyncStateAcquire(pAsyncState);

            break;

        case STATUS_SUCCESS:

            ntStatus = STATUS_DUPLICATE_OBJECTID;

            break;

        default:

            ;
    }
    BAIL_ON_NT_STATUS(ntStatus);

error:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    return ntStatus;
}
Exemplo n.º 13
0
VOID
SrvSession2SetUserFlags(
    PLWIO_SRV_SESSION_2 pSession,
    ULONG Flags
    )
{
    BOOLEAN  bInLock  = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

    SetFlag(pSession->ulUserFlags, Flags);

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);

    return;
}
Exemplo n.º 14
0
VOID
SrvTree2Rundown(
    PLWIO_SRV_TREE_2 pTree
    )
{
    BOOLEAN bInLock = FALSE;
    BOOLEAN bDoRundown = FALSE;
    BOOLEAN bIsInParent = FALSE;
    PLWIO_SRV_FILE_2 pRundownFileList = NULL;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    if (!SrvTree2IsRundown_inlock(pTree))
    {
        SrvTree2SetRundown_inlock(pTree);

        bDoRundown = TRUE;
        bIsInParent = SrvTree2IsInParent_inlock(pTree);

        SrvEnumFile2Collection(
                pTree->pFileCollection,
                SrvTree2GatherRundownFileListCallback,
                &pRundownFileList);
    }

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    if (bIsInParent)
    {
        SrvSession2RemoveTree(pTree->pSession, pTree);
    }

    if (bDoRundown)
    {
        if (pTree->resource.ulResourceId)
        {
            PSRV_RESOURCE pResource = NULL;

            SrvElementsUnregisterResource(pTree->resource.ulResourceId,
                                          &pResource);
            pTree->resource.ulResourceId = 0;
        }

        // Cannot rundown with lock held as they self-remove
        SrvTree2RundownFileList(pRundownFileList);
    }
}
Exemplo n.º 15
0
NTSTATUS
SrvElementsUnregisterResource(
    ULONG          ulResourceId, /* IN             */
    PSRV_RESOURCE* ppResource    /*    OUT OPTIONAL*/
    )
{
    NTSTATUS      ntStatus  = STATUS_SUCCESS;
    BOOLEAN       bInLock   = FALSE;
    PSRV_RESOURCE pResource = NULL;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gSrvElements.resources.mutex);

    if (ppResource)
    {
        ntStatus = LwRtlRBTreeFind(
                        gSrvElements.resources.pResources,
                        &ulResourceId,
                        (PVOID*)&pResource);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = LwRtlRBTreeRemove(
                    gSrvElements.resources.pResources,
                    &ulResourceId);
    BAIL_ON_NT_STATUS(ntStatus);

    if (ppResource)
    {
        *ppResource = pResource;
    }

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &gSrvElements.resources.mutex);

    return ntStatus;

error:

    if (ppResource)
    {
        *ppResource = NULL;
    }

    goto cleanup;
}
Exemplo n.º 16
0
static
NTSTATUS
SrvSession2UpdateLastActivityTime(
   PLWIO_SRV_SESSION_2 pSession
   )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN  bInLock  = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

    ntStatus = SrvSession2UpdateLastActivityTime_inlock(pSession);

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);

    return ntStatus;
}
Exemplo n.º 17
0
NTSTATUS
SrvElementsResetStats(
    VOID
    )
{
    BOOLEAN  bInLock  = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gSrvElements.statsLock);

    gSrvElements.stats.llMaxNumConnections = gSrvElements.stats.llNumConnections;
    gSrvElements.stats.llMaxNumSessions    = gSrvElements.stats.llNumSessions;
    gSrvElements.stats.llMaxNumTreeConnects = gSrvElements.stats.llNumTreeConnects;
    gSrvElements.stats.llMaxNumOpenFiles   = gSrvElements.stats.llNumOpenFiles;

    LWIO_UNLOCK_RWMUTEX(bInLock, &gSrvElements.statsLock);

    return STATUS_SUCCESS;
}
Exemplo n.º 18
0
NTSTATUS
SrvElementsRegisterResource(
    PSRV_RESOURCE pResource,    /* IN OUT          */
    PULONG        pulResourceId /* IN OUT OPTIONAL */
    )
{
    NTSTATUS ntStatus     = 0;
    BOOLEAN  bInLock      = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gSrvElements.resources.mutex);

    ntStatus = SrvElementsResourceAcquireId_inlock(
                    &gSrvElements.resources,
                    &pResource->ulResourceId);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = LwRtlRBTreeAdd(
                    gSrvElements.resources.pResources,
                    &pResource->ulResourceId,
                    pResource);
    BAIL_ON_NT_STATUS(ntStatus);

    if (pulResourceId)
    {
        *pulResourceId = pResource->ulResourceId;
    }

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &gSrvElements.resources.mutex);

    return ntStatus;

error:

    if (pulResourceId)
    {
        *pulResourceId = 0;
    }

    pResource->ulResourceId = 0;

    goto cleanup;
}
Exemplo n.º 19
0
VOID
SrvSession2Rundown(
    PLWIO_SRV_SESSION_2 pSession
    )
{
    BOOLEAN bInLock = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

    SrvSession2UpdateLastActivityTime_inlock(pSession);

    LwRtlRBTreeTraverse(
            pSession->pTreeCollection,
            LWRTL_TREE_TRAVERSAL_TYPE_IN_ORDER,
            SrvSession2RundownTreeRbTreeVisit,
            NULL);

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);
}
Exemplo n.º 20
0
NTSTATUS
SrvTreeRemoveAsyncState(
    PLWIO_SRV_TREE pTree,
    ULONG64        ullAsyncId
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN  bInLock  = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    ntStatus = LwRtlRBTreeRemove(
                    pTree->pAsyncStateCollection,
                    &ullAsyncId);

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    return ntStatus;
}
Exemplo n.º 21
0
NTSTATUS
SrvTree2RemoveFile(
    PLWIO_SRV_TREE_2 pTree,
    PLWIO_SRV_FILE_2 pFile
    )
{
    NTSTATUS ntStatus = 0;
    BOOLEAN bInLock = FALSE;
    PLWIO_SRV_FILE_2 pCachedFile = NULL;
    PSMB2_FID pFid = &pFile->fid;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    if (SrvFile2IsInParent(pFile))
    {
        pCachedFile = pTree->lruFile[ pFid->ullVolatileId % SRV_LRU_CAPACITY ];
        if (pCachedFile &&
            (pCachedFile->fid.ullPersistentId == pFid->ullPersistentId) &&
            (pCachedFile->fid.ullVolatileId == pFid->ullVolatileId))
        {
            pTree->lruFile[ pFid->ullVolatileId % SRV_LRU_CAPACITY ] = NULL;
        }

        // removal automatically releases reference
        ntStatus = LwRtlRBTreeRemove(pTree->pFileCollection, pFid);
        BAIL_ON_NT_STATUS(ntStatus);

        SrvFile2ClearInParent(pFile);

        pTree->ulNumOpenFiles--;
    }

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    return ntStatus;

error:

    goto cleanup;
}
Exemplo n.º 22
0
NTSTATUS
SrvElementsConfigRefresh(
    VOID
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    SRV_ELEMENTS_CONFIG config = { 0 };
    PSRV_ELEMENTS_CONFIG pConfig = &config;
    LWIO_CONFIG_TABLE configTable[] = SRV_ELEMENTS_CONFIG_TABLE_INITIALIZER;
    ULONG   ulNumConfig = sizeof(configTable) / sizeof(LWIO_CONFIG_TABLE);
    BOOLEAN bInLock = FALSE;

    SrvElementsConfigGetDefaults(pConfig);

    ntStatus = LwIoProcessConfig(
                    "Services\\lwio\\Parameters\\Drivers\\srv\\smb2",
                    "Policy\\Services\\lwio\\Parameters\\Drivers\\srv\\smb2",
                    configTable,
                    ulNumConfig,
                    TRUE);
    BAIL_ON_NT_STATUS(ntStatus);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gSrvElements.configLock);

    SrvElementsConfigFree(&gSrvElements.config);
    memcpy(&gSrvElements.config, pConfig, sizeof(SRV_ELEMENTS_CONFIG));

    LWIO_UNLOCK_RWMUTEX(bInLock, &gSrvElements.configLock);

cleanup:

    return ntStatus;

error:

    SrvElementsConfigFree(pConfig);

    goto cleanup;
}
Exemplo n.º 23
0
NTSTATUS
SrvSession2RemoveTree(
    PLWIO_SRV_SESSION_2 pSession,
    ULONG               ulTid
    )
{
    NTSTATUS ntStatus = 0;
    BOOLEAN bInLock = FALSE;
    PLWIO_SRV_TREE_2 pTree = NULL;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

    ntStatus = SrvSession2UpdateLastActivityTime_inlock(pSession);
    BAIL_ON_NT_STATUS(ntStatus);

    pTree = pSession->lruTree[ ulTid % SRV_LRU_CAPACITY ];
    if (pTree && (pTree->ulTid == ulTid))
    {
        pSession->lruTree[ ulTid % SRV_LRU_CAPACITY ] = NULL;
    }

    ntStatus = LwRtlRBTreeRemove(
                    pSession->pTreeCollection,
                    &ulTid);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);

    return ntStatus;

error:

    goto cleanup;
}
Exemplo n.º 24
0
NTSTATUS
PvfsRenameFCB(
    PPVFS_FCB pFcb,
    PPVFS_CCB pCcb,
    PPVFS_FILE_NAME pNewFilename
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PPVFS_CB_TABLE fcbTable = &gPvfsDriverState.FcbTable;
    PPVFS_FCB pNewParentFcb = NULL;
    PPVFS_FCB pOldParentFcb = NULL;
    PPVFS_FCB pTargetFcb = NULL;
    PPVFS_CB_TABLE_ENTRY pTargetBucket = NULL;
    PPVFS_CB_TABLE_ENTRY pCurrentBucket = NULL;
    BOOLEAN currentFcbControl = FALSE;
    BOOLEAN targetFcbListLocked = FALSE;
    BOOLEAN targetBucketLocked = FALSE;
    BOOLEAN currentBucketLocked = FALSE;
    BOOLEAN fcbRwLocked = FALSE;
    BOOLEAN renameLock = FALSE;
    PPVFS_FILE_NAME currentFileName = NULL;

    /* If the target has an existing SCB, remove it from the Table and let
       the existing ref counters play out (e.g. pending change notifies. */

    BAIL_ON_INVALID_PTR(pNewFilename, ntError);

    ntError = PvfsFindParentFCB(&pNewParentFcb, pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsAllocateFileNameFromScb(&currentFileName, pCcb->pScb);
    BAIL_ON_NT_STATUS(ntError);

    // Obtain all locks for the rename
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(renameLock, &fcbTable->rwLock);
    LWIO_LOCK_MUTEX(currentFcbControl, &pFcb->BaseControlBlock.Mutex);

    pCurrentBucket = pFcb->BaseControlBlock.pBucket;

    ntError = PvfsCbTableGetBucket(
                  &pTargetBucket,
                  fcbTable,
                  pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(currentBucketLocked, &pCurrentBucket->rwLock);
    if (pCurrentBucket != pTargetBucket)
    {
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(targetBucketLocked, &pTargetBucket->rwLock);
    }

    // Do the rename work now
    ntError = PvfsCbTableLookup_inlock(
                  (PPVFS_CONTROL_BLOCK*)OUT_PPVOID(&pTargetFcb),
                  pTargetBucket,
                  pNewFilename->FileName);
    if (ntError == STATUS_SUCCESS)
    {
        if (pTargetFcb != pFcb)
        {
            // Remove an existing FCB for the target file/stream (if one exists)
            // But make sure it is a different FCB

            LWIO_LOCK_RWMUTEX_SHARED(targetFcbListLocked, &pTargetFcb->rwScbLock);

            if (pTargetFcb->OpenHandleCount > 0 )
            {
                // if TargetScb has open handles cannot rename
                // This except in the batch-oplock case
                ntError = STATUS_INVALID_PARAMETER;
                BAIL_ON_NT_STATUS(ntError);
            }

            LWIO_UNLOCK_RWMUTEX(targetFcbListLocked, &pTargetFcb->rwScbLock);

            // TODO - How to get the Control Mutex without violating the
            // lock heirarchy?  Does it matter at all ?

            ntError = PvfsRemoveStreamObjects(pTargetFcb);
            LWIO_ASSERT(STATUS_SUCCESS == ntError);

            ntError = PvfsCbTableRemove_inlock(
                          (PPVFS_CONTROL_BLOCK)pTargetFcb,
                          pTargetFcb->pszFilename);
            LWIO_ASSERT(STATUS_SUCCESS == ntError);
        }
    }

    ntError = PvfsSysRenameByFileName(currentFileName, pNewFilename);
    // Ignore the error here and continue

    ntError = PvfsPathCacheRemove(currentFileName);
    // Ignore the error here and continue

    /* Remove the SCB from the table, update the lookup key, and then re-add.
       Otherwise you will get memory corruption as a freed pointer gets left
       in the Table because if cannot be located using the current (updated)
       filename. Another reason to use the dev/inode pair instead if we could
       solve the "Create New File" issue. */

    // Remove FCB
    ntError = PvfsCbTableRemove_inlock(
                  (PPVFS_CONTROL_BLOCK)pFcb,
                  pFcb->pszFilename);
    LWIO_ASSERT(STATUS_SUCCESS == ntError);

    // Rename FCB & Update parent links
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);
    LwRtlCStringFree(&pFcb->pszFilename);

    ntError = LwRtlCStringDuplicate(&pFcb->pszFilename, pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    if (pNewParentFcb != pFcb->pParentFcb)
    {
        pOldParentFcb = pFcb->pParentFcb;
        pFcb->pParentFcb = pNewParentFcb;
        pNewParentFcb = NULL;
    }
    LWIO_UNLOCK_RWMUTEX(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);

    // Re-Add SCB
    ntError = PvfsCbTableAdd_inlock(
                  pTargetBucket,
                  pFcb->pszFilename,
                  (PPVFS_CONTROL_BLOCK)pFcb);
    BAIL_ON_NT_STATUS(ntError);

error:

    // Release all locks .. Whew!
    LWIO_UNLOCK_RWMUTEX(targetFcbListLocked, &pTargetFcb->rwScbLock);
    LWIO_UNLOCK_RWMUTEX(targetBucketLocked, &pTargetBucket->rwLock);
    LWIO_UNLOCK_RWMUTEX(currentBucketLocked, &pCurrentBucket->rwLock);
    LWIO_UNLOCK_RWMUTEX(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);
    LWIO_UNLOCK_MUTEX(currentFcbControl, &pFcb->BaseControlBlock.Mutex);
    LWIO_UNLOCK_RWMUTEX(renameLock, &fcbTable->rwLock);

    if (pNewParentFcb)
    {
        PvfsReleaseFCB(&pNewParentFcb);
    }
    if (pOldParentFcb)
    {
        PvfsReleaseFCB(&pOldParentFcb);
    }
    if (pTargetFcb)
    {
        PvfsReleaseFCB(&pTargetFcb);
    }
    if (currentFileName)
    {
        PvfsFreeFileName(currentFileName);
    }

    return ntError;
}
Exemplo n.º 25
0
NTSTATUS
PvfsRemoveStreamObjects(
    IN PPVFS_FCB pFcb
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN scbBucketLocked = FALSE;
    BOOLEAN scbLocked = FALSE;
    PLW_LIST_LINKS scbCursorLink = NULL;
    PPVFS_SCB scbCursor = NULL;
    PPVFS_FILE_NAME streamName = NULL;
    PSTR fullStreamName = NULL;
    PPVFS_CB_TABLE_ENTRY scbCursorBucket = NULL;

    for (scbCursorLink = PvfsListTraverse(pFcb->pScbList, NULL);
         scbCursorLink;
         scbCursorLink = PvfsListTraverse(pFcb->pScbList, scbCursorLink))
    {
        scbCursor = LW_STRUCT_FROM_FIELD(
                          scbCursorLink,
                          PVFS_SCB,
                          FcbList);

        LWIO_ASSERT(scbCursor->OpenHandleCount == 0);

        status = PvfsAllocateFileNameFromScb(&streamName, scbCursor);
        BAIL_ON_NT_STATUS(status);

        status = PvfsAllocateCStringFromFileName(&fullStreamName, streamName);
        BAIL_ON_NT_STATUS(status);

        LWIO_LOCK_MUTEX(scbLocked, &scbCursor->BaseControlBlock.Mutex);

        scbCursorBucket = scbCursor->BaseControlBlock.pBucket;
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(scbBucketLocked, &scbCursorBucket->rwLock);

        status = PvfsCbTableRemove_inlock(
                      (PPVFS_CONTROL_BLOCK)scbCursor,
                      fullStreamName);
        LWIO_ASSERT(STATUS_SUCCESS == status);

        LWIO_UNLOCK_RWMUTEX(scbBucketLocked, &scbCursorBucket->rwLock);
        LWIO_UNLOCK_MUTEX(scbLocked, &scbCursor->BaseControlBlock.Mutex);

        if (streamName)
        {
            PvfsFreeFileName(streamName);
            streamName = NULL;
        }
        if (fullStreamName)
        {
            LwRtlCStringFree(&fullStreamName);
        }
    }

error:

    LWIO_UNLOCK_RWMUTEX(scbBucketLocked, &scbCursorBucket->rwLock);
    LWIO_UNLOCK_MUTEX(scbLocked, &scbCursor->BaseControlBlock.Mutex);

    if (streamName)
    {
        PvfsFreeFileName(streamName);
    }
    if (fullStreamName)
    {
        LwRtlCStringFree(&fullStreamName);
    }

    return status;
}
Exemplo n.º 26
0
NTSTATUS
SrvTreeCreateFile(
    PLWIO_SRV_TREE          pTree,
    PWSTR                   pwszFilename,
    PIO_FILE_HANDLE         phFile,
    PIO_FILE_NAME*          ppFilename,
    ACCESS_MASK             desiredAccess,
    LONG64                  allocationSize,
    FILE_ATTRIBUTES         fileAttributes,
    FILE_SHARE_FLAGS        shareAccess,
    FILE_CREATE_DISPOSITION createDisposition,
    FILE_CREATE_OPTIONS     createOptions,
    PLWIO_SRV_FILE*         ppFile
    )
{
    NTSTATUS ntStatus = 0;
    BOOLEAN bInLock = FALSE;
    PLWIO_SRV_FILE pFile = NULL;
    USHORT  fid = 0;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    ntStatus = SrvTreeAcquireFileId_inlock(
                    pTree,
                    &fid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvFileCreate(
                    fid,
                    pwszFilename,
                    phFile,
                    ppFilename,
                    desiredAccess,
                    allocationSize,
                    fileAttributes,
                    shareAccess,
                    createDisposition,
                    createOptions,
                    &pFile);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = LwRtlRBTreeAdd(
                    pTree->pFileCollection,
                    &pFile->fid,
                    pFile);
    BAIL_ON_NT_STATUS(ntStatus);

    pFile->resource.pAttributes->treeId.usTid    = pTree->tid;
    pFile->resource.pAttributes->sessionId.usUid = pTree->uid;
    pFile->resource.pAttributes->ulConnectionResourceId =
                                                pTree->ulConnectionResourceId;

    pTree->ulNumOpenFiles++;

    *ppFile = SrvFileAcquire(pFile);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    return ntStatus;

error:

    *ppFile = NULL;

    if (pFile)
    {
        SrvFileRelease(pFile);
    }

    goto cleanup;
}
Exemplo n.º 27
0
static
NTSTATUS
SrvShareDbCreate(
    VOID
    )
{
    NTSTATUS ntStatus = 0;
    PSRV_SHARE_DB_CONTEXT pDbContext = NULL;
    PSTR pszError = NULL;
    BOOLEAN bExists = FALSE;
    PCSTR pszShareDBPath = LWIO_SRV_SHARE_DB;
    PCSTR pszShareDBDir = LWIO_SRV_DB_DIR;
    BOOLEAN bInLock = FALSE;

    ntStatus = SMBCheckFileExists(pszShareDBPath, &bExists);
    BAIL_ON_NT_STATUS(ntStatus);

    // TODO: Implement an upgrade scenario
    if (bExists)
    {
       goto cleanup;
    }

    ntStatus = SMBCheckDirectoryExists(pszShareDBDir, &bExists);
    BAIL_ON_NT_STATUS(ntStatus);

    if (!bExists)
    {
        mode_t cacheDirMode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;

        /* Allow go+rx to the base folder */
        ntStatus = SMBCreateDirectory(pszShareDBDir, cacheDirMode);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    /* restrict access to u+rwx to the db folder */
    ntStatus = SMBChangeOwnerAndPermissions(pszShareDBDir, 0, 0, S_IRWXU);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvShareDbAcquireContext(&pDbContext);
    BAIL_ON_NT_STATUS(ntStatus);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gShareRepository_lwshare.dbMutex);

    ntStatus = sqlite3_exec(
                       pDbContext->pDbHandle,
                       DB_QUERY_CREATE_SHARES_TABLE,
                       NULL,
                       NULL,
                       &pszError);
    BAIL_ON_LWIO_SRV_SQLITE_ERROR_DB(ntStatus, pDbContext->pDbHandle);

    ntStatus = SMBChangeOwnerAndPermissions(
                    pszShareDBPath,
                    0,
                    0,
                    S_IRWXU);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    if (pDbContext)
    {
        SrvShareDbReleaseContext(pDbContext);
    }

    LWIO_UNLOCK_RWMUTEX(bInLock, &gShareRepository_lwshare.dbMutex);

    return ntStatus;

error:

    if (pszError)
    {
       LWIO_LOG_ERROR("%s", pszError);
       sqlite3_free(pszError);
    }

    goto cleanup;
}
Exemplo n.º 28
0
NTSTATUS
SrvShareDbDelete(
    IN HANDLE hRepository,
    IN PWSTR  pwszShareName
    )
{
    NTSTATUS ntStatus = 0;
    PSRV_SHARE_DB_CONTEXT pDbContext = (PSRV_SHARE_DB_CONTEXT)hRepository;
    PSTR pszShareName = NULL;
    BOOLEAN bInLock = FALSE;

    if (IsNullOrEmptyString(pwszShareName))
    {
        ntStatus = STATUS_INVALID_PARAMETER_3;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = SrvWc16sToMbs(pwszShareName, &pszShareName);
    BAIL_ON_NT_STATUS(ntStatus);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gShareRepository_lwshare.dbMutex);

    if (!pDbContext->pDeleteStmt)
    {
        PCSTR pszQueryTemplate = "DELETE FROM " LWIO_SRV_SHARES_DB_TABLE_NAME \
                   " WHERE UPPER(" LWIO_SRV_SHARES_DB_COL_NAME ") = UPPER(?1)";

        ntStatus = sqlite3_prepare_v2(
                        pDbContext->pDbHandle,
                        pszQueryTemplate,
                        -1,
                        &pDbContext->pDeleteStmt,
                        NULL);
        BAIL_ON_LWIO_SRV_SQLITE_ERROR_DB(ntStatus, pDbContext->pDbHandle);
    }

    ntStatus = sqlite3_bind_text(
                    pDbContext->pDeleteStmt,
                    1,
                    pszShareName,
                    -1,
                    SQLITE_TRANSIENT);
    BAIL_ON_LWIO_SRV_SQLITE_ERROR_STMT(ntStatus, pDbContext->pDeleteStmt);

    if ((ntStatus = sqlite3_step(pDbContext->pDeleteStmt)) == SQLITE_DONE)
    {
        ntStatus = STATUS_SUCCESS;
    }
    BAIL_ON_LWIO_SRV_SQLITE_ERROR_STMT(ntStatus, pDbContext->pDeleteStmt);

cleanup:

    if (pDbContext)
    {
        if (pDbContext->pDeleteStmt)
        {
           sqlite3_reset(pDbContext->pDeleteStmt);
        }
    }

    LWIO_UNLOCK_RWMUTEX(bInLock, &gShareRepository_lwshare.dbMutex);

    SRV_SAFE_FREE_MEMORY(pszShareName);

    return ntStatus;

error:

    goto cleanup;
}
Exemplo n.º 29
0
NTSTATUS
SrvShareDbAdd(
    IN HANDLE hRepository,
    IN PWSTR  pwszShareName,
    IN PWSTR  pwszPath,
    IN PWSTR  pwszComment,
    IN PBYTE  pSecDesc,
    IN ULONG  ulSecDescLen,
    IN PWSTR  pwszService,
    IN ULONG  ulFlags
    )
{
    NTSTATUS ntStatus = 0;
    PSRV_SHARE_DB_CONTEXT pDbContext = NULL;
    PSTR pszShareName = NULL;
    PSTR pszPath = NULL;
    PSTR pszComment = NULL;
    PSTR pszService = NULL;
    BOOLEAN bInLock = FALSE;

    if (pwszShareName)
    {
        ntStatus = SrvWc16sToMbs(pwszShareName, &pszShareName);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    if (pwszPath)
    {
        ntStatus = SrvWc16sToMbs(pwszPath, &pszPath);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    if (pwszComment)
    {
        ntStatus = SrvWc16sToMbs(pwszComment, &pszComment);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    if (pwszService)
    {
        ntStatus = SrvWc16sToMbs(pwszService, &pszService);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gShareRepository_lwshare.dbMutex);

    pDbContext = (PSRV_SHARE_DB_CONTEXT)hRepository;

    ntStatus = SrvShareDbAdd_inlock(
                    pDbContext,
                    pszShareName,
                    pszPath,
                    pszComment,
                    pSecDesc,
                    ulSecDescLen,
                    pszService,
		    ulFlags);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &gShareRepository_lwshare.dbMutex);

    SRV_SAFE_FREE_MEMORY(pszShareName);
    SRV_SAFE_FREE_MEMORY(pszPath);
    SRV_SAFE_FREE_MEMORY(pszComment);
    SRV_SAFE_FREE_MEMORY(pszService);

    return ntStatus;

error:

    goto cleanup;
}
Exemplo n.º 30
0
NTSTATUS
SrvTree2CreateFile(
    PLWIO_SRV_TREE_2        pTree,
    PWSTR                   pwszFilename,
    PIO_FILE_HANDLE         phFile,
    PIO_FILE_NAME*          ppFilename,
    ACCESS_MASK             desiredAccess,
    LONG64                  allocationSize,
    FILE_ATTRIBUTES         fileAttributes,
    FILE_SHARE_FLAGS        shareAccess,
    FILE_CREATE_DISPOSITION createDisposition,
    FILE_CREATE_OPTIONS     createOptions,
    PLWIO_SRV_FILE_2*       ppFile
    )
{
    NTSTATUS ntStatus = 0;
    BOOLEAN bInLock = FALSE;
    PLWIO_SRV_FILE_2 pFile = NULL;
    SMB2_FID  fid = {0};

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex);

    if (SrvTree2IsRundown_inlock(pTree))
    {
        ntStatus = STATUS_INVALID_HANDLE;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = SrvTree2AcquireFileId_inlock(
                    pTree,
                    &fid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvFile2Create(
                    pTree,
                    &fid,
                    pwszFilename,
                    phFile,
                    ppFilename,
                    desiredAccess,
                    allocationSize,
                    fileAttributes,
                    shareAccess,
                    createDisposition,
                    createOptions,
                    &pFile);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvTree2AddFile_inlock(pTree, pFile);
    BAIL_ON_NT_STATUS(ntStatus);

    SrvFile2BlockIdleTimeout(pFile);

    *ppFile = pFile;

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    return ntStatus;

error:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex);

    *ppFile = NULL;

    if (pFile)
    {
        SrvFile2Rundown(pFile);
        SrvFile2Release(pFile);
    }

    goto cleanup;
}