~ssalley/ubuntu/maverick/likewise-open/likewise-open.fix627272

« back to all changes in this revision

Viewing changes to lwio/server/pvfs/fcb.c

  • Committer: Bazaar Package Importer
  • Author(s): Gerald Carter, Michael Casadevall, Gerald Carter
  • Date: 2010-03-13 07:42:44 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100313074244-j1gy0zo19cc32xhl
Tags: 5.4.0.42111-1
[ Michael Casadevall ]
* LP: #517300
  - added debian/patches/disable_parallel_builds.diff to allow successful builds
    on non-x86 architectures caused by improperly parsing /proc/cpuinfo to
    determine the number of CPUs and set make -jX.
  - added debian/patches/correct_lwio_configure_detection.diff to correct configure
    tests for properly checking proc filesystems on non-x86 linux platforms
  - added ${misc:Depends} to Depends lines to satisfy lintian
  - Added debian/README.source to satisfy lintian 
  - Bumped standards version to 3.8.3

[ Gerald Carter ]
* New upstream release. (LP: #538616)
* likewise-open.install: Include uninstalled binaries and ncalrpc
    servers required for domainjoin-cli {join,leave}
* patches/version-in-share.diff:
  - Corrected location of VERSION file in lsassd

Show diffs side-by-side

added added

removed removed

Lines of Context:
126
126
    {
127
127
        if (pFcb->pParentFcb)
128
128
        {
129
 
            PvfsReleaseFCB(pFcb->pParentFcb);
 
129
            PvfsReleaseFCB(&pFcb->pParentFcb);
130
130
        }
131
131
 
132
132
        RtlCStringFree(&pFcb->pszFilename);
136
136
        pthread_mutex_destroy(&pFcb->mutexNotify);
137
137
        pthread_rwlock_destroy(&pFcb->rwCcbLock);
138
138
        pthread_rwlock_destroy(&pFcb->rwBrlLock);
 
139
        pthread_rwlock_destroy(&pFcb->rwFileName);
 
140
        pthread_rwlock_destroy(&pFcb->rwParent);
139
141
 
140
142
        PvfsListDestroy(&pFcb->pPendingLockQueue);
141
143
        PvfsListDestroy(&pFcb->pOplockPendingOpsQueue);
147
149
 
148
150
 
149
151
        PVFS_FREE(&pFcb);
 
152
 
 
153
#ifdef _PVFS_DEVELOPER_DEBUG
 
154
        InterlockedDecrement(&gPvfsFcbCount);
 
155
#endif
 
156
 
150
157
    }
151
158
 
152
159
    return;
165
172
    /* This should never be called.  The CCB count has to be 0 when
166
173
       we call PvfsFreeFCB() and hence destroy the FCB->pCcbList */
167
174
 
168
 
    PVFS_ASSERT(FALSE);
 
175
    return;
169
176
}
170
177
 
171
178
 
192
199
    pthread_mutex_init(&pFcb->mutexNotify, NULL);
193
200
    pthread_rwlock_init(&pFcb->rwCcbLock, NULL);
194
201
    pthread_rwlock_init(&pFcb->rwBrlLock, NULL);
 
202
    pthread_rwlock_init(&pFcb->rwFileName, NULL);
 
203
    pthread_rwlock_init(&pFcb->rwParent, NULL);
195
204
 
196
205
    pFcb->RefCount = 1;
197
206
 
251
260
    /* Miscellaneous */
252
261
 
253
262
    pFcb->bDeleteOnClose = FALSE;
 
263
    pFcb->bRemoved = FALSE;
254
264
    pFcb->pParentFcb = NULL;
255
265
 
256
266
    *ppFcb = pFcb;
257
 
    pFcb = NULL;
 
267
 
 
268
#ifdef _PVFS_DEVELOPER_DEBUG
 
269
        InterlockedIncrement(&gPvfsFcbCount);
 
270
#endif
258
271
 
259
272
    ntError = STATUS_SUCCESS;
260
273
 
261
274
cleanup:
262
 
    PvfsFreeFCB(pFcb);
263
 
 
264
275
    return ntError;
265
276
 
266
277
error:
 
278
    if (pFcb)
 
279
    {
 
280
        PvfsFreeFCB(pFcb);
 
281
    }
 
282
 
267
283
    goto cleanup;
268
284
}
269
285
 
330
346
                           LastAccessTime);
331
347
    BAIL_ON_NT_STATUS(ntError);
332
348
 
 
349
    pFcb->LastWriteTime = 0;
 
350
 
333
351
cleanup:
334
352
    return ntError;
335
353
 
345
363
{
346
364
    NTSTATUS ntError = STATUS_SUCCESS;
347
365
 
348
 
    ntError = PvfsValidatePath(pFcb->pszFilename, &pFcb->FileId);
349
 
    BAIL_ON_NT_STATUS(ntError);
350
 
 
351
 
    ntError = PvfsSysRemove(pFcb->pszFilename);
 
366
    /* Always reset the delete-on-close state to be safe */
 
367
 
 
368
    pFcb->bDeleteOnClose = FALSE;
 
369
 
 
370
    /* Verify we are deleting the file we think we are */
 
371
 
 
372
    ntError = PvfsValidatePath(pFcb, &pFcb->FileId);
 
373
    if (ntError == STATUS_SUCCESS)
 
374
    {
 
375
        ntError = PvfsSysRemove(pFcb->pszFilename);
 
376
 
 
377
        /* Reset dev/inode state */
 
378
 
 
379
        pFcb->FileId.Device = 0;
 
380
        pFcb->FileId.Inode  = 0;
 
381
 
 
382
    }
352
383
    BAIL_ON_NT_STATUS(ntError);
353
384
 
354
385
cleanup:
361
392
 
362
393
VOID
363
394
PvfsReleaseFCB(
364
 
    PPVFS_FCB pFcb
 
395
    PPVFS_FCB *ppFcb
365
396
    )
366
397
{
367
398
    NTSTATUS ntError = STATUS_SUCCESS;
368
 
    BOOLEAN bLocked = FALSE;
 
399
    BOOLEAN bTableLocked = FALSE;
369
400
    BOOLEAN bFcbLocked = FALSE;
 
401
    BOOLEAN bFcbControlLocked = FALSE;
370
402
    PVFS_STAT Stat = {0};
 
403
    PPVFS_FCB pFcb = NULL;
 
404
    BOOLEAN bDeleteLocked = FALSE;
371
405
 
372
406
    /* Do housekeeping such as setting the last write time or
373
407
       honoring DeletOnClose when the CCB handle count reaches
374
 
       0.  Not necessaril.y when the RefCount reaches 0.  We
 
408
       0.  Not necessarily when the RefCount reaches 0.  We
375
409
       may have a non-handle open in the FCB table for a
376
410
       path component (see PvfsFindParentFCB()). */
377
411
 
 
412
    if (ppFcb == NULL || *ppFcb == NULL)
 
413
    {
 
414
        goto cleanup;
 
415
    }
 
416
 
 
417
    pFcb = *ppFcb;
 
418
 
378
419
    LWIO_LOCK_RWMUTEX_SHARED(bFcbLocked, &pFcb->rwCcbLock);
379
420
 
380
 
    if (PvfsListLength(pFcb->pCcbList) == 0)
 
421
    if (!PVFS_IS_DEVICE_HANDLE(pFcb) && (PvfsListLength(pFcb->pCcbList) == 0))
381
422
    {
382
423
        ntError = PvfsSysStat(pFcb->pszFilename, &Stat);
383
424
        if (ntError == STATUS_SUCCESS)
386
427
            {
387
428
 
388
429
                ntError = PvfsSetLastWriteTime(pFcb);
389
 
                pFcb->LastWriteTime = 0;
390
430
 
391
431
                if (ntError == STATUS_SUCCESS)
392
432
                {
398
438
                }
399
439
            }
400
440
 
 
441
            LWIO_LOCK_MUTEX(bDeleteLocked, &pFcb->ControlBlock);
401
442
            if (pFcb->bDeleteOnClose)
402
443
            {
403
444
                ntError = PvfsExecuteDeleteOnClose(pFcb);
404
 
                pFcb->bDeleteOnClose = FALSE;
 
445
 
 
446
                /* Remove the FCB and allow the refcount to handle the free().
 
447
                   This prevents a failed delete-on-close from preventing
 
448
                   any future opens. */
 
449
 
 
450
                LWIO_LOCK_RWMUTEX_EXCLUSIVE(bTableLocked, &gFcbTable.rwLock);
 
451
 
 
452
                if (!pFcb->bRemoved)
 
453
                {
 
454
                    PvfsRemoveFCB(pFcb);
 
455
                    pFcb->bRemoved = TRUE;
 
456
                }
 
457
 
 
458
                LWIO_UNLOCK_RWMUTEX(bTableLocked, &gFcbTable.rwLock);
 
459
                LWIO_UNLOCK_MUTEX(bDeleteLocked, &pFcb->ControlBlock);
405
460
 
406
461
                if (ntError == STATUS_SUCCESS)
407
462
                {
 
463
                    /* Clear the cache entry but ignore any errors */
 
464
 
 
465
                    PvfsPathCacheRemove(pFcb->pszFilename);
 
466
 
408
467
                    PvfsNotifyScheduleFullReport(
409
468
                        pFcb,
410
469
                        S_ISDIR(Stat.s_mode) ?
414
473
                        pFcb->pszFilename);
415
474
                }
416
475
            }
 
476
            LWIO_UNLOCK_MUTEX(bDeleteLocked, &pFcb->ControlBlock);
417
477
        }
418
478
    }
419
479
 
425
485
       Otherwise another open request could search and locate the
426
486
       FCB in the tree and return free()'d memory. */
427
487
 
428
 
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bLocked, &gFcbTable.rwLock);
 
488
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bTableLocked, &gFcbTable.rwLock);
429
489
 
430
490
    if (InterlockedDecrement(&pFcb->RefCount) == 0)
431
491
    {
432
 
        PvfsRemoveFCB(pFcb);
433
 
 
434
 
        LWIO_UNLOCK_RWMUTEX(bLocked, &gFcbTable.rwLock);
 
492
 
 
493
        /* Clear the path cache */
 
494
 
 
495
        PvfsPathCacheRemove(pFcb->pszFilename);
 
496
 
 
497
        LWIO_LOCK_MUTEX(bFcbControlLocked, &pFcb->ControlBlock);
 
498
        if (!pFcb->bRemoved)
 
499
        {
 
500
            PvfsRemoveFCB(pFcb);
 
501
            pFcb->bRemoved = TRUE;
 
502
        }
 
503
        LWIO_UNLOCK_MUTEX(bFcbControlLocked, &pFcb->ControlBlock);
 
504
 
 
505
        LWIO_UNLOCK_RWMUTEX(bTableLocked, &gFcbTable.rwLock);
435
506
 
436
507
        PvfsFreeFCB(pFcb);
437
508
    }
438
509
 
439
 
    LWIO_UNLOCK_RWMUTEX(bLocked, &gFcbTable.rwLock);
440
 
 
 
510
    LWIO_UNLOCK_RWMUTEX(bTableLocked, &gFcbTable.rwLock);
 
511
 
 
512
    *ppFcb = (PPVFS_FCB)NULL;
 
513
 
 
514
cleanup:
441
515
    return;
442
516
}
443
517
 
448
522
static NTSTATUS
449
523
_PvfsFindFCB(
450
524
    PPVFS_FCB *ppFcb,
451
 
    PSTR pszFilename
 
525
    PCSTR pszFilename
452
526
    )
453
527
{
454
528
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
462
536
    }
463
537
    BAIL_ON_NT_STATUS(ntError);
464
538
 
465
 
    PvfsReferenceFCB(pFcb);
466
 
 
467
 
    *ppFcb = pFcb;
 
539
    *ppFcb = PvfsReferenceFCB(pFcb);
468
540
    ntError = STATUS_SUCCESS;
469
541
 
470
542
cleanup:
547
619
    ntError = _PvfsFindFCB(&pFcb, pszFilename);
548
620
    if (ntError == STATUS_SUCCESS) {
549
621
 
550
 
        ntError = PvfsEnforceShareMode(pFcb,
551
 
                                       SharedAccess,
552
 
                                       DesiredAccess);
553
 
        BAIL_ON_NT_STATUS(ntError);
554
 
 
555
 
        *ppFcb = pFcb;
556
 
 
 
622
        ntError = PvfsEnforceShareMode(
 
623
                      pFcb,
 
624
                      SharedAccess,
 
625
                      DesiredAccess);
 
626
 
 
627
        /* If we have success, then we are good.  If we have a sharing
 
628
           violation, give the caller a chance to break the oplock and
 
629
           we'll try again when the create is resumed. */
 
630
 
 
631
        if (ntError == STATUS_SUCCESS ||
 
632
            ntError == STATUS_SHARING_VIOLATION)
 
633
        {
 
634
            *ppFcb = PvfsReferenceFCB(pFcb);
 
635
        }
557
636
        goto cleanup;
558
637
    }
559
638
 
575
654
 
576
655
    /* Return a reference to the FCB */
577
656
 
578
 
    *ppFcb = pFcb;
 
657
    *ppFcb = PvfsReferenceFCB(pFcb);
579
658
    ntError = STATUS_SUCCESS;
580
659
 
581
660
cleanup:
582
661
    LWIO_UNLOCK_RWMUTEX(bFcbTableLocked, &gFcbTable.rwLock);
583
662
 
584
 
    return ntError;
585
 
 
586
 
error:
587
663
    if (pFcb) {
588
 
        PvfsReleaseFCB(pFcb);
 
664
        PvfsReleaseFCB(&pFcb);
589
665
    }
 
666
 
 
667
    return ntError;
 
668
 
 
669
error:
590
670
    goto cleanup;
591
671
}
592
672
 
637
717
    }
638
718
 
639
719
    *ppParentFcb = pFcb;
640
 
    pFcb = NULL;
641
720
 
642
721
    ntError = STATUS_SUCCESS;
643
722
 
644
723
cleanup:
645
 
    if (pFcb)
646
 
    {
647
 
        PvfsReleaseFCB(pFcb);
648
 
    }
649
 
 
650
724
    LwRtlCStringFree(&pszDirname);
651
725
 
652
726
    return ntError;
653
727
 
654
728
error:
 
729
    if (pFcb)
 
730
    {
 
731
        PvfsReleaseFCB(&pFcb);
 
732
    }
 
733
 
655
734
    goto cleanup;
656
735
}
657
736
 
673
752
    ntError = PvfsListAddTail(pFcb->pCcbList, &pCcb->FcbList);
674
753
    BAIL_ON_NT_STATUS(ntError);
675
754
 
676
 
    pCcb->pFcb = pFcb;
 
755
    pCcb->pFcb = PvfsReferenceFCB(pFcb);
677
756
 
678
757
    ntError = STATUS_SUCCESS;
679
758
 
729
808
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
730
809
    PPVFS_PENDING_OPLOCK_BREAK_TEST pTestCtx = NULL;
731
810
 
 
811
    BAIL_ON_INVALID_PTR(pFcb, ntError);
 
812
    BAIL_ON_INVALID_PTR(pfnCompletion, ntError);
 
813
 
732
814
    ntError = PvfsCreateOplockBreakTestContext(
733
815
                  &pTestCtx,
734
816
                  pFcb,
782
864
                  sizeof(PVFS_OPLOCK_PENDING_OPERATION));
783
865
    BAIL_ON_NT_STATUS(ntError);
784
866
 
785
 
    pPendingOp->pIrpContext = pIrpContext;
 
867
    pPendingOp->pIrpContext = PvfsReferenceIrpContext(pIrpContext);
786
868
    pPendingOp->pfnCompletion = pfnCompletion;
787
869
    pPendingOp->pfnFreeContext = pfnFreeContext;
788
870
    pPendingOp->pCompletionContext = pCompletionContext;
793
875
                  pFcb->pOplockPendingOpsQueue,
794
876
                  (PVOID)pPendingOp);
795
877
    BAIL_ON_NT_STATUS(ntError);
 
878
 
796
879
    pIrpContext->QueueType = PVFS_QUEUE_TYPE_PENDING_OPLOCK_BREAK;
797
880
 
798
881
    pIrpContext->pFcb = PvfsReferenceFCB(pFcb);
799
882
 
800
 
    /* An item could be requeued here */
801
 
 
802
 
    if (!pIrpContext->bIsPended)
803
 
    {
804
 
        PvfsIrpMarkPending(
805
 
            pIrpContext,
806
 
            PvfsQueueCancelIrp,
807
 
            pIrpContext);
808
 
    }
 
883
    PvfsIrpMarkPending(
 
884
        pIrpContext,
 
885
        PvfsQueueCancelIrp,
 
886
        pIrpContext);
 
887
 
 
888
    /* Set the request in a cancellable state */
 
889
 
 
890
    PvfsIrpContextClearFlag(pIrpContext, PVFS_IRP_CTX_FLAG_ACTIVE);
809
891
 
810
892
cleanup:
811
893
    LWIO_UNLOCK_MUTEX(bLocked, &pFcb->mutexOplock);
813
895
    return ntError;
814
896
 
815
897
error:
 
898
    if (pPendingOp)
 
899
    {
 
900
        PvfsFreePendingOp(&pPendingOp);
 
901
    }
 
902
 
816
903
    goto cleanup;
817
904
}
818
905
 
891
978
                      PVFS_OPLOCK_RECORD,
892
979
                      OplockList);
893
980
 
894
 
        if (pOplock->pIrpContext->bIsCancelled)
 
981
        if (PvfsIrpContextCheckFlag(
 
982
                pOplock->pIrpContext,
 
983
                PVFS_IRP_CTX_FLAG_CANCELLED))
895
984
        {
896
985
            pOplock = NULL;
897
986
            continue;
943
1032
 
944
1033
    pOplock->OplockType = OplockType;
945
1034
    pOplock->pCcb = PvfsReferenceCCB(pCcb);
946
 
    pOplock->pIrpContext = pIrpContext;
 
1035
    pOplock->pIrpContext = PvfsReferenceIrpContext(pIrpContext);
947
1036
 
948
1037
    ntError = PvfsListAddTail(pFcb->pOplockList, &pOplock->OplockList);
949
1038
    BAIL_ON_NT_STATUS(ntError);
952
1041
    return ntError;
953
1042
 
954
1043
error:
 
1044
    if (pOplock)
 
1045
    {
 
1046
        PvfsFreeOplockRecord(&pOplock);
 
1047
    }
 
1048
 
955
1049
    goto cleanup;
956
1050
}
957
1051
 
965
1059
    PPVFS_OPLOCK_RECORD *ppOplockRec
966
1060
    )
967
1061
{
968
 
    PPVFS_CCB pCcb = NULL;
969
 
    PPVFS_IRP_CONTEXT pIrpContext = NULL;
 
1062
    PPVFS_OPLOCK_RECORD pOplock = NULL;
970
1063
 
971
1064
    if (ppOplockRec && *ppOplockRec)
972
1065
    {
973
 
        pCcb = (*ppOplockRec)->pCcb;
974
 
        pIrpContext = (*ppOplockRec)->pIrpContext;
 
1066
        pOplock = *ppOplockRec;
975
1067
 
976
 
        if (pIrpContext)
 
1068
        if (pOplock->pIrpContext)
977
1069
        {
978
 
            pIrpContext->pIrp->IoStatusBlock.Status = STATUS_FILE_CLOSED;
979
 
 
980
 
            PvfsAsyncIrpComplete(pIrpContext);
981
 
            PvfsFreeIrpContext(&pIrpContext);
 
1070
            PvfsReleaseIrpContext(&pOplock->pIrpContext);
982
1071
        }
983
1072
 
984
 
 
985
 
        if (pCcb)
 
1073
        if (pOplock->pCcb)
986
1074
        {
987
 
            PvfsReleaseCCB(pCcb);
 
1075
            PvfsReleaseCCB(pOplock->pCcb);
988
1076
        }
989
1077
 
990
1078
        PVFS_FREE(ppOplockRec);
1085
1173
 
1086
1174
    if (pFcb)
1087
1175
    {
1088
 
        PvfsReleaseFCB(pFcb);
 
1176
        PvfsReleaseFCB(&pFcb);
1089
1177
    }
1090
1178
 
1091
1179
    return ntError;
1109
1197
    PPVFS_OPLOCK_PENDING_OPERATION pOperation = NULL;
1110
1198
    PLW_LIST_LINKS pOpLink = NULL;
1111
1199
    PLW_LIST_LINKS pNextLink = NULL;
 
1200
    BOOLEAN bFound = FALSE;
1112
1201
 
1113
1202
    pOpLink = PvfsListTraverse(pQueue, NULL);
1114
1203
 
1127
1216
            continue;
1128
1217
        }
1129
1218
 
 
1219
        bFound = TRUE;
 
1220
 
1130
1221
        PvfsListRemoveItem(pQueue, pOpLink);
1131
1222
        pOpLink = NULL;
1132
1223
 
1133
1224
        pOperation->pIrpContext->pIrp->IoStatusBlock.Status = STATUS_CANCELLED;
1134
1225
 
1135
1226
        PvfsAsyncIrpComplete(pOperation->pIrpContext);
1136
 
        PvfsFreeIrpContext(&pOperation->pIrpContext);
1137
1227
 
1138
1228
        PvfsFreePendingOp(&pOperation);
1139
1229
 
1141
1231
        ntError = STATUS_SUCCESS;
1142
1232
    }
1143
1233
 
 
1234
    if (!bFound)
 
1235
    {
 
1236
        pIrpContext->pIrp->IoStatusBlock.Status = STATUS_CANCELLED;
 
1237
 
 
1238
        PvfsAsyncIrpComplete(pIrpContext);
 
1239
    }
 
1240
 
 
1241
    if (pIrpContext)
 
1242
    {
 
1243
        PvfsReleaseIrpContext(&pIrpContext);
 
1244
    }
 
1245
 
1144
1246
    return ntError;
1145
1247
}
1146
1248
 
1159
1261
}
1160
1262
 
1161
1263
 
 
1264
/*****************************************************************************
 
1265
 ****************************************************************************/
 
1266
 
 
1267
NTSTATUS
 
1268
PvfsRenameFCB(
 
1269
    PPVFS_FCB pFcb,
 
1270
    PPVFS_CCB pCcb,
 
1271
    PCSTR pszNewFilename
 
1272
    )
 
1273
{
 
1274
    NTSTATUS ntError = STATUS_SUCCESS;
 
1275
    BOOLEAN bTableLocked = FALSE;
 
1276
    BOOLEAN bFcbLocked = FALSE;
 
1277
    BOOLEAN bCcbLocked = FALSE;
 
1278
    BOOLEAN bParentLinkLocked = FALSE;
 
1279
    PPVFS_FCB pNewParentFcb = NULL;
 
1280
    PPVFS_FCB pOldParentFcb = NULL;
 
1281
    PPVFS_FCB pExistingTargetFcb = NULL;
 
1282
    BOOLEAN bExistingFcbLocked = FALSE;
 
1283
 
 
1284
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bTableLocked, &gFcbTable.rwLock);
 
1285
 
 
1286
        ntError = PvfsValidatePath(pCcb->pFcb, &pCcb->FileId);
 
1287
        BAIL_ON_NT_STATUS(ntError);
 
1288
 
 
1289
        /* If the target has an existing FCB, remove it from the Table
 
1290
           and let the existing ref counters play out (e.g. pending
 
1291
           change notifies. */
 
1292
 
 
1293
        ntError = _PvfsFindFCB(&pExistingTargetFcb, pszNewFilename);
 
1294
        if (ntError == STATUS_SUCCESS)
 
1295
        {
 
1296
            /* Make sure we have a different FCB */
 
1297
 
 
1298
            if (pExistingTargetFcb != pFcb)
 
1299
            {
 
1300
                LWIO_LOCK_MUTEX(bExistingFcbLocked, &pExistingTargetFcb->ControlBlock);
 
1301
                if (!pExistingTargetFcb->bRemoved)
 
1302
                {
 
1303
                    PvfsRemoveFCB(pExistingTargetFcb);
 
1304
                    pExistingTargetFcb->bRemoved = TRUE;
 
1305
                }
 
1306
                LWIO_UNLOCK_MUTEX(bExistingFcbLocked, &pExistingTargetFcb->ControlBlock);
 
1307
            }
 
1308
        }
 
1309
 
 
1310
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(bFcbLocked, &pFcb->rwFileName);
 
1311
 
 
1312
            ntError = PvfsSysRename(pCcb->pFcb->pszFilename, pszNewFilename);
 
1313
            BAIL_ON_NT_STATUS(ntError);
 
1314
 
 
1315
            /* Clear the cache entry but ignore any errors */
 
1316
 
 
1317
            ntError = PvfsPathCacheRemove(pFcb->pszFilename);
 
1318
 
 
1319
            /* Remove the FCB from the table, update the lookup key,
 
1320
               and then re-add.  Otherwise you will get memory corruption
 
1321
               as a freed pointer gets left in the Table because if
 
1322
               cannot be located using the current (updated) filename.
 
1323
               Another reason to use the dev/inode pair instead if
 
1324
               we could solve the "Create New File" issue.  */
 
1325
 
 
1326
            ntError = PvfsRemoveFCB(pFcb);
 
1327
            BAIL_ON_NT_STATUS(ntError);
 
1328
 
 
1329
            PVFS_FREE(&pFcb->pszFilename);
 
1330
            ntError = LwRtlCStringDuplicate(&pFcb->pszFilename, pszNewFilename);
 
1331
            BAIL_ON_NT_STATUS(ntError);
 
1332
 
 
1333
            ntError = PvfsFindParentFCB(&pNewParentFcb, pFcb->pszFilename);
 
1334
            BAIL_ON_NT_STATUS(ntError);
 
1335
 
 
1336
            /* Have to update the parent links as well */
 
1337
 
 
1338
            LWIO_LOCK_RWMUTEX_EXCLUSIVE(bParentLinkLocked, &pFcb->rwParent);
 
1339
            if (pNewParentFcb != pFcb->pParentFcb)
 
1340
            {
 
1341
                pOldParentFcb = pFcb->pParentFcb;
 
1342
                pFcb->pParentFcb = pNewParentFcb;
 
1343
                pNewParentFcb = NULL;
 
1344
            }
 
1345
            LWIO_UNLOCK_RWMUTEX(bParentLinkLocked, &pFcb->rwParent);
 
1346
 
 
1347
            ntError = PvfsAddFCB(pFcb);
 
1348
            BAIL_ON_NT_STATUS(ntError);
 
1349
 
 
1350
        LWIO_UNLOCK_RWMUTEX(bFcbLocked, &pFcb->rwFileName);
 
1351
 
 
1352
    LWIO_UNLOCK_RWMUTEX(bTableLocked, &gFcbTable.rwLock);
 
1353
 
 
1354
    LWIO_LOCK_MUTEX(bCcbLocked, &pCcb->ControlBlock);
 
1355
 
 
1356
        PVFS_FREE(&pCcb->pszFilename);
 
1357
        ntError = LwRtlCStringDuplicate(&pCcb->pszFilename, pszNewFilename);
 
1358
        BAIL_ON_NT_STATUS(ntError);
 
1359
 
 
1360
    LWIO_UNLOCK_MUTEX(bCcbLocked, &pCcb->ControlBlock);
 
1361
 
 
1362
cleanup:
 
1363
    if (pNewParentFcb)
 
1364
    {
 
1365
        PvfsReleaseFCB(&pNewParentFcb);
 
1366
    }
 
1367
 
 
1368
    if (pOldParentFcb)
 
1369
    {
 
1370
        PvfsReleaseFCB(&pOldParentFcb);
 
1371
    }
 
1372
 
 
1373
    if (pExistingTargetFcb)
 
1374
    {
 
1375
        PvfsReleaseFCB(&pExistingTargetFcb);
 
1376
    }
 
1377
 
 
1378
    return ntError;
 
1379
 
 
1380
error:
 
1381
    LWIO_UNLOCK_RWMUTEX(bParentLinkLocked, &pFcb->rwParent);
 
1382
    LWIO_UNLOCK_MUTEX(bCcbLocked, &pCcb->ControlBlock);
 
1383
    LWIO_UNLOCK_RWMUTEX(bFcbLocked, &pFcb->rwFileName);
 
1384
    LWIO_UNLOCK_RWMUTEX(bTableLocked, &gFcbTable.rwLock);
 
1385
 
 
1386
    goto cleanup;
 
1387
}
 
1388
 
 
1389
 
 
1390
/*****************************************************************************
 
1391
 ****************************************************************************/
 
1392
 
 
1393
BOOLEAN
 
1394
PvfsFcbIsPendingDelete(
 
1395
    PPVFS_FCB pFcb
 
1396
    )
 
1397
{
 
1398
    BOOLEAN bPendingDelete = FALSE;
 
1399
    BOOLEAN bIsLocked = FALSE;
 
1400
 
 
1401
    LWIO_LOCK_MUTEX(bIsLocked, &pFcb->ControlBlock);
 
1402
    bPendingDelete = pFcb->bDeleteOnClose;
 
1403
    LWIO_UNLOCK_MUTEX(bIsLocked, &pFcb->ControlBlock);
 
1404
 
 
1405
    return bPendingDelete;
 
1406
}
 
1407
 
 
1408
/*****************************************************************************
 
1409
 ****************************************************************************/
 
1410
 
 
1411
VOID
 
1412
PvfsFcbSetPendingDelete(
 
1413
    PPVFS_FCB pFcb,
 
1414
    BOOLEAN bPendingDelete
 
1415
    )
 
1416
{
 
1417
    BOOLEAN bIsLocked = FALSE;
 
1418
 
 
1419
    LWIO_LOCK_MUTEX(bIsLocked, &pFcb->ControlBlock);
 
1420
    pFcb->bDeleteOnClose = bPendingDelete;
 
1421
    LWIO_UNLOCK_MUTEX(bIsLocked, &pFcb->ControlBlock);
 
1422
}
 
1423
 
 
1424
/*****************************************************************************
 
1425
 ****************************************************************************/
 
1426
 
 
1427
PPVFS_FCB
 
1428
PvfsGetParentFCB(
 
1429
    PPVFS_FCB pFcb
 
1430
    )
 
1431
{
 
1432
    PPVFS_FCB pParent = NULL;
 
1433
    BOOLEAN bLocked = FALSE;
 
1434
 
 
1435
    if (pFcb)
 
1436
    {
 
1437
        LWIO_LOCK_RWMUTEX_SHARED(bLocked, &pFcb->rwParent);
 
1438
        if (pFcb->pParentFcb)
 
1439
        {
 
1440
            pParent = PvfsReferenceFCB(pFcb->pParentFcb);
 
1441
        }
 
1442
        LWIO_UNLOCK_RWMUTEX(bLocked, &pFcb->rwParent);
 
1443
    }
 
1444
 
 
1445
    return pParent;
 
1446
}
 
1447
 
1162
1448
/*
1163
1449
local variables:
1164
1450
mode: c