Index: openafs/src/NTMakefile diff -c openafs/src/NTMakefile:1.27.2.1 openafs/src/NTMakefile:1.27.2.2 *** openafs/src/NTMakefile:1.27.2.1 Tue Jul 4 02:28:22 2006 --- openafs/src/NTMakefile Thu Oct 12 17:19:35 2006 *************** *** 570,576 **** $(NTMAKE) $(CD) ..\..\.. ! extra: aklog ! IF EXIST($(SRC)\WINNT\extra) && EXIST($(SRC)\WINNT\extra\NTMakefile) echo ***** $@ $(DOCD) $(SRC)\WINNT\$@ --- 570,583 ---- $(NTMAKE) $(CD) ..\..\.. ! netidmgr_plugin: aklog ! echo ***** $@ ! $(DOCD) $(SRC)\WINNT\$@ ! $(CD) $(SRC)\WINNT\$@ ! $(NTMAKE) ! $(CD) ..\..\.. ! ! extra: netidmgr_plugin ! IF EXIST($(SRC)\WINNT\extra) && EXIST($(SRC)\WINNT\extra\NTMakefile) echo ***** $@ $(DOCD) $(SRC)\WINNT\$@ Index: openafs/src/WINNT/afsd/afsd_init.c diff -c openafs/src/WINNT/afsd/afsd_init.c:1.79.2.5 openafs/src/WINNT/afsd/afsd_init.c:1.79.2.7 *** openafs/src/WINNT/afsd/afsd_init.c:1.79.2.5 Wed Aug 30 16:12:03 2006 --- openafs/src/WINNT/afsd/afsd_init.c Sun Oct 8 21:52:20 2006 *************** *** 1238,1243 **** --- 1238,1250 ---- return 0; } + int afsd_ShutdownCM(void) + { + cm_ReleaseSCache(cm_data.rootSCachep); + + return 0; + } + int afsd_InitDaemons(char **reasonP) { long code; Index: openafs/src/WINNT/afsd/afsd_init.h diff -c openafs/src/WINNT/afsd/afsd_init.h:1.6 openafs/src/WINNT/afsd/afsd_init.h:1.6.6.1 *** openafs/src/WINNT/afsd/afsd_init.h:1.6 Mon May 9 23:34:03 2005 --- openafs/src/WINNT/afsd/afsd_init.h Sun Oct 8 16:31:36 2006 *************** *** 19,24 **** --- 19,25 ---- int afsd_InitSMB(char **reasonP); #endif /* !DJGPP */ int afsd_InitDaemons(char **reasonP); + int afsd_ShutdownCM(void); void afsd_ForceTrace(BOOL flush); void afsd_SetUnhandledExceptionFilter(); Index: openafs/src/WINNT/afsd/afsd_service.c diff -c openafs/src/WINNT/afsd/afsd_service.c:1.52.4.4 openafs/src/WINNT/afsd/afsd_service.c:1.52.4.6 *** openafs/src/WINNT/afsd/afsd_service.c:1.52.4.4 Mon Aug 7 17:19:05 2006 --- openafs/src/WINNT/afsd/afsd_service.c Sun Oct 8 16:31:36 2006 *************** *** 360,366 **** { afsi_log("SERVICE_CONTROL_CUSTOM_DUMP"); GenerateMiniDump(NULL); ! dwRet = NO_ERROR; } break; } /* end switch(ctrlCode) */ --- 360,366 ---- { afsi_log("SERVICE_CONTROL_CUSTOM_DUMP"); GenerateMiniDump(NULL); ! dwRet = NO_ERROR; } break; } /* end switch(ctrlCode) */ *************** *** 1069,1078 **** --- 1069,1081 ---- #endif #ifdef _DEBUG + afsd_DbgBreakAllocInit(); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ | _CRTDBG_CHECK_CRT_DF /* | _CRTDBG_DELAY_FREE_MEM_DF */ ); #endif + afsd_SetUnhandledExceptionFilter(); + osi_InitPanic(afsd_notifier); osi_InitTraceOption(); *************** *** 1398,1404 **** cm_DaemonShutdown(); afsi_log("Daemon shutdown complete"); ! buf_Shutdown(); afsi_log("Buffer shutdown complete"); --- 1401,1409 ---- cm_DaemonShutdown(); afsi_log("Daemon shutdown complete"); ! ! afsd_ShutdownCM(); ! buf_Shutdown(); afsi_log("Buffer shutdown complete"); *************** *** 1406,1412 **** afsi_log("rx finalization complete"); #ifndef AFSIFS ! smb_Shutdown(); afsi_log("smb shutdown complete"); #endif --- 1411,1417 ---- afsi_log("rx finalization complete"); #ifndef AFSIFS ! smb_Shutdown(); afsi_log("smb shutdown complete"); #endif Index: openafs/src/WINNT/afsd/cm_access.c diff -c openafs/src/WINNT/afsd/cm_access.c:1.7.2.3 openafs/src/WINNT/afsd/cm_access.c:1.7.2.7 *** openafs/src/WINNT/afsd/cm_access.c:1.7.2.3 Wed Jun 28 01:34:50 2006 --- openafs/src/WINNT/afsd/cm_access.c Fri Oct 6 01:15:22 2006 *************** *** 118,143 **** { long code; cm_fid_t tfid; ! cm_scache_t *aclScp; int got_cb = 0; /* pretty easy: just force a pass through the fetch status code */ ! osi_Log2(afsd_logp, "GetAccess scp %x user %x", scp, userp); /* first, start by finding out whether we have a directory or something * else, so we can find what object's ACL we need. */ ! if (!cm_HaveCallback(scp)) { code = cm_SyncOp(scp, NULL, userp, reqp, 0, ! CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! if (code) ! return code; ! ! got_cb = 1; ! } ! ! if (scp->fileType != CM_SCACHETYPE_DIRECTORY) { /* not a dir, use parent dir's acl */ tfid.cell = scp->fid.cell; tfid.volume = scp->fid.volume; --- 118,139 ---- { long code; cm_fid_t tfid; ! cm_scache_t *aclScp = NULL; int got_cb = 0; /* pretty easy: just force a pass through the fetch status code */ ! osi_Log2(afsd_logp, "GetAccess scp 0x%p user 0x%p", scp, userp); /* first, start by finding out whether we have a directory or something * else, so we can find what object's ACL we need. */ ! if (scp->fileType == CM_SCACHETYPE_DIRECTORY ) { code = cm_SyncOp(scp, NULL, userp, reqp, 0, ! CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB); ! if (!code) ! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! } else { /* not a dir, use parent dir's acl */ tfid.cell = scp->fid.cell; tfid.volume = scp->fid.volume; *************** *** 147,165 **** code = cm_GetSCache(&tfid, &aclScp, userp, reqp); if (code) { lock_ObtainMutex(&scp->mx); ! return code; } osi_Log2(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp); ! lock_ObtainMutex(&aclScp->mx); ! ! code = cm_GetCallback(aclScp, userp, reqp, 1); ! lock_ReleaseMutex(&aclScp->mx); cm_ReleaseSCache(aclScp); lock_ObtainMutex(&scp->mx); - } else if (!got_cb) { - code = cm_GetCallback(scp, userp, reqp, 1); } return code; } --- 143,163 ---- code = cm_GetSCache(&tfid, &aclScp, userp, reqp); if (code) { lock_ObtainMutex(&scp->mx); ! goto _done; } osi_Log2(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp); ! lock_ObtainMutex(&aclScp->mx); ! code = cm_SyncOp(aclScp, NULL, userp, reqp, 0, ! CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB); ! if (!code) ! cm_SyncOpDone(aclScp, NULL, ! CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! lock_ReleaseMutex(&aclScp->mx); cm_ReleaseSCache(aclScp); lock_ObtainMutex(&scp->mx); } + _done: return code; } Index: openafs/src/WINNT/afsd/cm_buf.c diff -c openafs/src/WINNT/afsd/cm_buf.c:1.31.2.2 openafs/src/WINNT/afsd/cm_buf.c:1.31.2.7 *** openafs/src/WINNT/afsd/cm_buf.c:1.31.2.2 Thu Aug 3 23:46:39 2006 --- openafs/src/WINNT/afsd/cm_buf.c Tue Oct 10 11:57:44 2006 *************** *** 108,114 **** --- 108,119 ---- { /* ensure that we're in the LRU queue if our ref count is 0 */ osi_assert(bp->magic == CM_BUF_MAGIC); + #ifdef DEBUG + if (bp->refCount == 0) + osi_panic("buf refcount 0",__FILE__,__LINE__);; + #else osi_assert(bp->refCount > 0); + #endif if (--bp->refCount == 0) { if (!(bp->flags & CM_BUF_INLRU)) { osi_QAdd((osi_queue_t **) &cm_data.buf_freeListp, &bp->q); *************** *** 134,160 **** { cm_buf_t *bp; /* buffer we're hacking on; held */ long i; /* counter */ ! long nAtOnce; /* how many to do at once */ cm_req_t req; lock_ObtainWrite(&buf_globalLock); bp = cm_data.buf_allp; buf_HoldLocked(bp); lock_ReleaseWrite(&buf_globalLock); ! nAtOnce = (long)sqrt((double)cm_data.buf_nbuffers); while (buf_ShutdownFlag == 0) { #ifndef DJGPP ! i = SleepEx(5000, 1); ! if (i != 0) continue; #else ! thrd_Sleep(5000); #endif /* DJGPP */ ! if (buf_ShutdownFlag == 1) return; /* now go through our percentage of the buffers */ ! for (i=0; imagic == CM_SCACHE_MAGIC); osi_assert(bp->magic == CM_BUF_MAGIC); *************** *** 478,486 **** if ( bp->flags & CM_BUF_WAITING ) { bp->waitCount++; bp->waitRequests++; ! osi_Log1(afsd_logp, "buf_WaitIO CM_BUF_WAITING already set for 0x%p", bp); } else { ! osi_Log1(afsd_logp, "buf_WaitIO CM_BUF_WAITING set for 0x%p", bp); bp->flags |= CM_BUF_WAITING; bp->waitCount = bp->waitRequests = 1; } --- 492,500 ---- if ( bp->flags & CM_BUF_WAITING ) { bp->waitCount++; bp->waitRequests++; ! osi_Log1(buf_logp, "buf_WaitIO CM_BUF_WAITING already set for 0x%p", bp); } else { ! osi_Log1(buf_logp, "buf_WaitIO CM_BUF_WAITING set for 0x%p", bp); bp->flags |= CM_BUF_WAITING; bp->waitCount = bp->waitRequests = 1; } *************** *** 489,509 **** smb_UpdateServerPriority(); lock_ObtainMutex(&bp->mx); ! osi_Log1(afsd_logp, "buf_WaitIO conflict wait done for 0x%p", bp); bp->waitCount--; if (bp->waitCount == 0) { ! osi_Log1(afsd_logp, "buf_WaitIO CM_BUF_WAITING reset for 0x%p", bp); bp->flags &= ~CM_BUF_WAITING; bp->waitRequests = 0; } if ( !scp ) { ! scp = cm_FindSCache(&bp->fid); } if ( scp ) { lock_ObtainMutex(&scp->mx); if (scp->flags & CM_SCACHEFLAG_WAITING) { ! osi_Log1(afsd_logp, "buf_WaitIO waking scp 0x%p", scp); osi_Wakeup((LONG_PTR)&scp->flags); } lock_ReleaseMutex(&scp->mx); --- 503,524 ---- smb_UpdateServerPriority(); lock_ObtainMutex(&bp->mx); ! osi_Log1(buf_logp, "buf_WaitIO conflict wait done for 0x%p", bp); bp->waitCount--; if (bp->waitCount == 0) { ! osi_Log1(buf_logp, "buf_WaitIO CM_BUF_WAITING reset for 0x%p", bp); bp->flags &= ~CM_BUF_WAITING; bp->waitRequests = 0; } if ( !scp ) { ! if (scp = cm_FindSCache(&bp->fid)) ! release = 1; } if ( scp ) { lock_ObtainMutex(&scp->mx); if (scp->flags & CM_SCACHEFLAG_WAITING) { ! osi_Log1(buf_logp, "buf_WaitIO waking scp 0x%p", scp); osi_Wakeup((LONG_PTR)&scp->flags); } lock_ReleaseMutex(&scp->mx); *************** *** 514,523 **** * the I/O to complete. Do so. */ if (bp->flags & CM_BUF_WAITING) { ! osi_Log1(afsd_logp, "buf_WaitIO Waking bp 0x%p", bp); osi_Wakeup((LONG_PTR) bp); } ! osi_Log1(afsd_logp, "WaitIO finished wait for bp 0x%p", bp); } /* find a buffer, if any, for a particular file ID and offset. Assumes --- 529,541 ---- * the I/O to complete. Do so. */ if (bp->flags & CM_BUF_WAITING) { ! osi_Log1(buf_logp, "buf_WaitIO Waking bp 0x%p", bp); osi_Wakeup((LONG_PTR) bp); } ! osi_Log1(buf_logp, "WaitIO finished wait for bp 0x%p", bp); ! ! if (scp && release) ! cm_ReleaseSCache(scp); } /* find a buffer, if any, for a particular file ID and offset. Assumes *************** *** 562,586 **** * Makes sure that there's only one person writing this block * at any given time, and also ensures that the log is forced sufficiently far, * if this buffer contains logged data. */ ! void buf_CleanAsyncLocked(cm_buf_t *bp, cm_req_t *reqp) { long code = 0; osi_assert(bp->magic == CM_BUF_MAGIC); while ((bp->flags & CM_BUF_DIRTY) == CM_BUF_DIRTY) { lock_ReleaseMutex(&bp->mx); ! osi_Log1(afsd_logp, "buf_CleanAsyncLocked starts I/O on 0x%p", bp); ! code = (*cm_buf_opsp->Writep)(&bp->fid, &bp->offset, ! cm_data.buf_blockSize, 0, bp->userp, ! reqp); ! osi_Log2(afsd_logp, "buf_CleanAsyncLocked I/O on 0x%p, done=%d", bp, code); ! ! lock_ObtainMutex(&bp->mx); ! if (code) ! break; #ifdef DISKCACHE95 /* Disk cache support */ --- 580,627 ---- * Makes sure that there's only one person writing this block * at any given time, and also ensures that the log is forced sufficiently far, * if this buffer contains logged data. + * + * Returns one if the buffer was dirty. */ ! long buf_CleanAsyncLocked(cm_buf_t *bp, cm_req_t *reqp) { long code = 0; + long isdirty = 0; + cm_scache_t * scp = NULL; osi_assert(bp->magic == CM_BUF_MAGIC); while ((bp->flags & CM_BUF_DIRTY) == CM_BUF_DIRTY) { + isdirty = 1; lock_ReleaseMutex(&bp->mx); ! scp = cm_FindSCache(&bp->fid); ! if (scp) { ! osi_Log2(buf_logp, "buf_CleanAsyncLocked starts I/O on scp 0x%p buf 0x%p", scp, bp); ! code = (*cm_buf_opsp->Writep)(scp, &bp->offset, ! cm_data.buf_blockSize, 0, bp->userp, ! reqp); ! osi_Log3(buf_logp, "buf_CleanAsyncLocked I/O on scp 0x%p buf 0x%p, done=%d", scp, bp, code); ! ! cm_ReleaseSCache(scp); ! scp = NULL; ! } else { ! osi_Log1(buf_logp, "buf_CleanAsyncLocked unable to start I/O - scp not found buf 0x%p", bp); ! code = CM_ERROR_NOSUCHFILE; ! } ! ! lock_ObtainMutex(&bp->mx); ! /* if the Write routine returns No Such File, clear the dirty flag ! * because we aren't going to be able to write this data to the file ! * server. ! */ ! if (code == CM_ERROR_NOSUCHFILE){ ! bp->flags &= ~CM_BUF_DIRTY; ! bp->flags |= CM_BUF_ERROR; ! bp->error = CM_ERROR_NOSUCHFILE; ! bp->dataVersion = -1; /* bad */ ! bp->dirtyCounter++; ! } #ifdef DISKCACHE95 /* Disk cache support */ *************** *** 599,604 **** --- 640,646 ---- osi_Log1(buf_logp, "buf_WaitIO Waking bp 0x%p", bp); osi_Wakeup((LONG_PTR) bp); } + return isdirty; } /* Called with a zero-ref count buffer and with the buf_globalLock write locked. *************** *** 799,804 **** --- 841,849 ---- if (scp) { bp->flags |= CM_BUF_INHASH; bp->fid = scp->fid; + #ifdef DEBUG + bp->scp = scp; + #endif bp->offset = *offsetp; i = BUF_HASH(&scp->fid, offsetp); bp->hashp = cm_data.buf_hashTablepp[i]; *************** *** 930,945 **** if (bp) { /* lock it and break out */ lock_ObtainMutex(&bp->mx); - break; #ifdef DISKCACHE95 /* touch disk chunk to update LRU info */ diskcache_Touch(bp->dcp); #endif /* DISKCACHE95 */ } /* otherwise, we have to create a page */ code = buf_GetNewLocked(scp, &pageOffset, &bp); /* check if the buffer was created in a race condition branch. * If so, go around so we can hold a reference to it. --- 975,991 ---- if (bp) { /* lock it and break out */ lock_ObtainMutex(&bp->mx); #ifdef DISKCACHE95 /* touch disk chunk to update LRU info */ diskcache_Touch(bp->dcp); #endif /* DISKCACHE95 */ + break; } /* otherwise, we have to create a page */ code = buf_GetNewLocked(scp, &pageOffset, &bp); + /* bp->mx is now held */ /* check if the buffer was created in a race condition branch. * If so, go around so we can hold a reference to it. *************** *** 1078,1090 **** } /* clean a buffer synchronously */ ! void buf_CleanAsync(cm_buf_t *bp, cm_req_t *reqp) { osi_assert(bp->magic == CM_BUF_MAGIC); lock_ObtainMutex(&bp->mx); ! buf_CleanAsyncLocked(bp, reqp); lock_ReleaseMutex(&bp->mx); } /* wait for a buffer's cleaning to finish */ --- 1124,1139 ---- } /* clean a buffer synchronously */ ! long buf_CleanAsync(cm_buf_t *bp, cm_req_t *reqp) { + long code; osi_assert(bp->magic == CM_BUF_MAGIC); lock_ObtainMutex(&bp->mx); ! code = buf_CleanAsyncLocked(bp, reqp); lock_ReleaseMutex(&bp->mx); + + return code; } /* wait for a buffer's cleaning to finish */ *************** *** 1153,1160 **** /* now no locks are held; clean buffer and go on */ cm_InitReq(&req); ! buf_CleanAsync(bp, &req); ! buf_CleanWait(NULL, bp); /* relock and release buffer */ lock_ObtainWrite(&buf_globalLock); --- 1202,1209 ---- /* now no locks are held; clean buffer and go on */ cm_InitReq(&req); ! buf_CleanAsync(bp, &req); ! buf_CleanWait(NULL, bp); /* relock and release buffer */ lock_ObtainWrite(&buf_globalLock); *************** *** 1313,1318 **** --- 1362,1371 ---- } } + cm_SyncOpDone( scp, bufp, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_SETSIZE | CM_SCACHESYNC_BUFLOCKED); + lock_ReleaseMutex(&scp->mx); lock_ReleaseMutex(&bufp->mx); *************** *** 1434,1441 **** bp->userp = userp; lock_ReleaseMutex(&bp->mx); } ! buf_CleanAsync(bp, reqp); ! buf_CleanWait(scp, bp); lock_ObtainMutex(&bp->mx); if (bp->flags & CM_BUF_ERROR) { if (code == 0 || code == -1) --- 1487,1494 ---- bp->userp = userp; lock_ReleaseMutex(&bp->mx); } ! code = buf_CleanAsync(bp, reqp); ! buf_CleanWait(scp, bp); lock_ObtainMutex(&bp->mx); if (bp->flags & CM_BUF_ERROR) { if (code == 0 || code == -1) *************** *** 1472,1502 **** lock_ObtainRead(&buf_globalLock); for (bp = cm_data.buf_freeListEndp; bp; bp=(cm_buf_t *) osi_QPrev(&bp->q)) { if (bp->magic != CM_BUF_MAGIC) ! DebugBreak(); countb++; bpb = bp; } for (bp = cm_data.buf_freeListp; bp; bp=(cm_buf_t *) osi_QNext(&bp->q)) { if (bp->magic != CM_BUF_MAGIC) ! DebugBreak(); countf++; bpf = bp; } for (bp = cm_data.buf_allp; bp; bp=bp->allp) { if (bp->magic != CM_BUF_MAGIC) ! DebugBreak(); counta++; bpa = bp; } lock_ReleaseRead(&buf_globalLock); if (countb != countf) ! DebugBreak(); if (counta != cm_data.buf_nbuffers) ! DebugBreak(); } #endif /* TESTING */ --- 1525,1555 ---- lock_ObtainRead(&buf_globalLock); for (bp = cm_data.buf_freeListEndp; bp; bp=(cm_buf_t *) osi_QPrev(&bp->q)) { if (bp->magic != CM_BUF_MAGIC) ! osi_panic("buf magic error",__FILE__,__LINE__); countb++; bpb = bp; } for (bp = cm_data.buf_freeListp; bp; bp=(cm_buf_t *) osi_QNext(&bp->q)) { if (bp->magic != CM_BUF_MAGIC) ! osi_panic("buf magic error",__FILE__,__LINE__); countf++; bpf = bp; } for (bp = cm_data.buf_allp; bp; bp=bp->allp) { if (bp->magic != CM_BUF_MAGIC) ! osi_panic("buf magic error",__FILE__,__LINE__); counta++; bpa = bp; } lock_ReleaseRead(&buf_globalLock); if (countb != countf) ! osi_panic("buf magic error",__FILE__,__LINE__); if (counta != cm_data.buf_nbuffers) ! osi_panic("buf magic error",__FILE__,__LINE__); } #endif /* TESTING */ *************** *** 1561,1563 **** --- 1614,1657 ---- FlushFileBuffers(handle); CloseHandle(handle); } + + long buf_DirtyBuffersExist(cm_fid_t *fidp) + { + cm_buf_t *bp; + afs_uint32 bcount = 0; + + for (bp = cm_data.buf_allp; bp; bp=bp->allp, bcount++) { + if (!cm_FidCmp(fidp, &bp->fid) && (bp->flags & CM_BUF_DIRTY)) + return 1; + } + return 0; + } + + #if 0 + long buf_CleanDirtyBuffers(cm_scache_t *scp) + { + cm_buf_t *bp; + afs_uint32 bcount = 0; + cm_fid_t * fidp = &scp->fid; + + for (bp = cm_data.buf_allp; bp; bp=bp->allp, bcount++) { + if (!cm_FidCmp(fidp, &bp->fid) && (bp->flags & CM_BUF_DIRTY)) { + buf_Hold(bp); + lock_ObtainMutex(&bp->mx); + bp->cmFlags &= ~CM_BUF_CMSTORING; + bp->flags &= ~CM_BUF_DIRTY; + bp->flags |= CM_BUF_ERROR; + bp->error = VNOVNODE; + bp->dataVersion = -1; /* bad */ + bp->dirtyCounter++; + if (bp->flags & CM_BUF_WAITING) { + osi_Log2(buf_logp, "BUF CleanDirtyBuffers Waking [scp 0x%x] bp 0x%x", scp, bp); + osi_Wakeup((long) &bp); + } + lock_ReleaseMutex(&bp->mx); + buf_Release(bp); + } + } + return 0; + } + #endif Index: openafs/src/WINNT/afsd/cm_buf.h diff -c openafs/src/WINNT/afsd/cm_buf.h:1.12.4.1 openafs/src/WINNT/afsd/cm_buf.h:1.12.4.2 *** openafs/src/WINNT/afsd/cm_buf.h:1.12.4.1 Thu Aug 3 23:46:39 2006 --- openafs/src/WINNT/afsd/cm_buf.h Mon Oct 2 23:23:21 2006 *************** *** 80,85 **** --- 80,89 ---- #endif /* notdef */ osi_hyper_t offset; /* offset */ cm_fid_t fid; /* file ID */ + #ifdef DEBUG + cm_scache_t *scp; /* for debugging, the scache object belonging to */ + /* the fid at the time of fid assignment. */ + #endif long flags; /* flags we're using */ long size; /* size in bytes of this buffer */ char *datap; /* data in this buffer */ *************** *** 113,119 **** long counter; /* counter of changes to identity */ } cm_softRef_t; ! #define CM_BUF_READING 1 /* now reading buffer to the disk */ #define CM_BUF_WRITING 2 /* now writing buffer to the disk */ #define CM_BUF_INHASH 4 /* in the hash table */ #define CM_BUF_DIRTY 8 /* buffer is dirty */ --- 117,123 ---- long counter; /* counter of changes to identity */ } cm_softRef_t; ! #define CM_BUF_READING 1 /* now reading buffer from the disk */ #define CM_BUF_WRITING 2 /* now writing buffer to the disk */ #define CM_BUF_INHASH 4 /* in the hash table */ #define CM_BUF_DIRTY 8 /* buffer is dirty */ *************** *** 164,172 **** extern long buf_GetNew(struct cm_scache *, osi_hyper_t *, cm_buf_t **); ! extern void buf_CleanAsyncLocked(cm_buf_t *, cm_req_t *); ! extern void buf_CleanAsync(cm_buf_t *, cm_req_t *); extern void buf_CleanWait(cm_scache_t *, cm_buf_t *); --- 168,176 ---- extern long buf_GetNew(struct cm_scache *, osi_hyper_t *, cm_buf_t **); ! extern long buf_CleanAsyncLocked(cm_buf_t *, cm_req_t *); ! extern long buf_CleanAsync(cm_buf_t *, cm_req_t *); extern void buf_CleanWait(cm_scache_t *, cm_buf_t *); *************** *** 201,206 **** --- 205,214 ---- extern void buf_ForceTrace(BOOL flush); + extern long buf_DirtyBuffersExist(cm_fid_t * fidp); + + extern long buf_CleanDirtyBuffers(cm_scache_t *scp); + /* error codes */ #define CM_BUF_EXISTS 1 /* buffer exists, and shouldn't */ #endif /* _BUF_H__ENV_ */ Index: openafs/src/WINNT/afsd/cm_callback.c diff -c openafs/src/WINNT/afsd/cm_callback.c:1.41.4.6 openafs/src/WINNT/afsd/cm_callback.c:1.41.4.9 *** openafs/src/WINNT/afsd/cm_callback.c:1.41.4.6 Fri Aug 25 13:08:23 2006 --- openafs/src/WINNT/afsd/cm_callback.c Thu Oct 5 16:30:38 2006 *************** *** 1618,1624 **** long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, struct cm_req *reqp, long flags) { ! long code; cm_conn_t *connp = NULL; AFSFetchStatus afsStatus; AFSVolSync volSync; --- 1618,1624 ---- long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp, struct cm_req *reqp, long flags) { ! long code = 0; cm_conn_t *connp = NULL; AFSFetchStatus afsStatus; AFSVolSync volSync; *************** *** 1626,1634 **** AFSFid tfid; cm_callbackRequest_t cbr; int mustCall; - long sflags; cm_fid_t sfid; struct rx_connection * callp = NULL; osi_Log4(afsd_logp, "GetCallback scp 0x%p cell %d vol %d flags %lX", scp, scp->fid.cell, scp->fid.volume, flags); --- 1626,1634 ---- AFSFid tfid; cm_callbackRequest_t cbr; int mustCall; cm_fid_t sfid; struct rx_connection * callp = NULL; + int syncop_done = 0; osi_Log4(afsd_logp, "GetCallback scp 0x%p cell %d vol %d flags %lX", scp, scp->fid.cell, scp->fid.volume, flags); *************** *** 1675,1692 **** mustCall = (flags & 1); cm_AFSFidFromFid(&tfid, &scp->fid); while (1) { ! if (!mustCall && cm_HaveCallback(scp)) { ! osi_Log3(afsd_logp, "GetCallback Complete scp 0x%p cell %d vol %d", ! scp, scp->fid.cell, scp->fid.volume); ! return 0; ! } /* turn off mustCall, since it has now forced us past the check above */ mustCall = 0; /* otherwise, we have to make an RPC to get the status */ ! sflags = CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK; ! cm_SyncOp(scp, NULL, userp, reqp, 0, sflags); cm_StartCallbackGrantingCall(scp, &cbr); sfid = scp->fid; lock_ReleaseMutex(&scp->mx); --- 1675,1694 ---- mustCall = (flags & 1); cm_AFSFidFromFid(&tfid, &scp->fid); while (1) { ! if (!mustCall && cm_HaveCallback(scp)) ! break; /* turn off mustCall, since it has now forced us past the check above */ mustCall = 0; /* otherwise, we have to make an RPC to get the status */ ! if (!syncop_done) { ! code = cm_SyncOp(scp, NULL, userp, reqp, 0, ! CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK); ! if (code) ! break; ! syncop_done = 1; ! } cm_StartCallbackGrantingCall(scp, &cbr); sfid = scp->fid; lock_ReleaseMutex(&scp->mx); *************** *** 1721,1736 **** } else { cm_EndCallbackGrantingCall(NULL, &cbr, NULL, 0); } - cm_SyncOpDone(scp, NULL, sflags); ! /* now check to see if we got an error */ ! if (code) { ! osi_Log2(afsd_logp, "GetCallback Failed code 0x%x scp 0x%p -->",code, scp); ! osi_Log4(afsd_logp, " cell %u vol %u vn %u uniq %u", ! scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique); ! return code; ! } } } /* called periodically by cm_daemon to shut down use of expired callbacks */ --- 1723,1747 ---- } else { cm_EndCallbackGrantingCall(NULL, &cbr, NULL, 0); } ! /* if we got an error, return to caller */ ! if (code) ! break; } + + if (syncop_done) + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK); + + if (code) { + osi_Log2(afsd_logp, "GetCallback Failed code 0x%x scp 0x%p -->",code, scp); + osi_Log4(afsd_logp, " cell %u vol %u vn %u uniq %u", + scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique); + } else { + osi_Log3(afsd_logp, "GetCallback Complete scp 0x%p cell %d vol %d", + scp, scp->fid.cell, scp->fid.volume); + } + + return code; } /* called periodically by cm_daemon to shut down use of expired callbacks */ Index: openafs/src/WINNT/afsd/cm_conn.c diff -c openafs/src/WINNT/afsd/cm_conn.c:1.49.2.5 openafs/src/WINNT/afsd/cm_conn.c:1.49.2.8 *** openafs/src/WINNT/afsd/cm_conn.c:1.49.2.5 Tue Aug 8 12:39:17 2006 --- openafs/src/WINNT/afsd/cm_conn.c Fri Oct 6 01:15:22 2006 *************** *** 77,99 **** code = RegQueryValueEx(parmKey, "ConnDeadTimeout", NULL, NULL, (BYTE *) &dwValue, &dummyLen); if (code == ERROR_SUCCESS) ! ConnDeadtimeout = dwValue; dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "HardDeadTimeout", NULL, NULL, (BYTE *) &dwValue, &dummyLen); if (code == ERROR_SUCCESS) ! HardDeadtimeout = dwValue; afsi_log("HardDeadTimeout is %d", HardDeadtimeout); RegCloseKey(parmKey); } afsi_log("lanmanworkstation : SessTimeout %d", RDRtimeout); if (ConnDeadtimeout == 0) ! ConnDeadtimeout = RDRtimeout / 2; afsi_log("ConnDeadTimeout is %d", ConnDeadtimeout); if (HardDeadtimeout == 0) ! HardDeadtimeout = RDRtimeout; afsi_log("HardDeadTimeout is %d", HardDeadtimeout); osi_EndOnce(&once); --- 77,99 ---- code = RegQueryValueEx(parmKey, "ConnDeadTimeout", NULL, NULL, (BYTE *) &dwValue, &dummyLen); if (code == ERROR_SUCCESS) ! ConnDeadtimeout = (unsigned short)dwValue; dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "HardDeadTimeout", NULL, NULL, (BYTE *) &dwValue, &dummyLen); if (code == ERROR_SUCCESS) ! HardDeadtimeout = (unsigned short)dwValue; afsi_log("HardDeadTimeout is %d", HardDeadtimeout); RegCloseKey(parmKey); } afsi_log("lanmanworkstation : SessTimeout %d", RDRtimeout); if (ConnDeadtimeout == 0) ! ConnDeadtimeout = (unsigned short) (RDRtimeout / 2); afsi_log("ConnDeadTimeout is %d", ConnDeadtimeout); if (HardDeadtimeout == 0) ! HardDeadtimeout = (unsigned short) RDRtimeout; afsi_log("HardDeadTimeout is %d", HardDeadtimeout); osi_EndOnce(&once); *************** *** 438,449 **** if (scp->fileType != CM_SCACHETYPE_DIRECTORY) pscp = cm_FindSCacheParent(scp); lock_ObtainWrite(&cm_scacheLock); ! cm_RecycleSCache(scp, CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS); lock_ReleaseWrite(&cm_scacheLock); if (pscp) { ! if (pscp->cbExpires > 0 && pscp->cbServerp != NULL) { lock_ObtainMutex(&pscp->mx); cm_DiscardSCache(pscp); lock_ReleaseMutex(&pscp->mx); --- 438,454 ---- if (scp->fileType != CM_SCACHETYPE_DIRECTORY) pscp = cm_FindSCacheParent(scp); + + lock_ObtainMutex(&scp->mx); lock_ObtainWrite(&cm_scacheLock); ! cm_RemoveSCacheFromHashTable(scp); lock_ReleaseWrite(&cm_scacheLock); + scp->flags |= CM_SCACHEFLAG_DELETED; + lock_ReleaseMutex(&scp->mx); + cm_ReleaseSCache(scp); if (pscp) { ! if (cm_HaveCallback(pscp)) { lock_ObtainMutex(&pscp->mx); cm_DiscardSCache(pscp); lock_ReleaseMutex(&pscp->mx); Index: openafs/src/WINNT/afsd/cm_daemon.c diff -c openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.4 openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.7 *** openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.4 Wed Aug 30 16:16:15 2006 --- openafs/src/WINNT/afsd/cm_daemon.c Fri Oct 6 12:32:43 2006 *************** *** 89,97 **** osi_assert(cm_bkgQueueCount-- > 0); lock_ReleaseWrite(&cm_daemonLock); (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp); ! ! cm_ReleaseUser(rp->userp); cm_ReleaseSCache(rp->scp); free(rp); --- 89,102 ---- osi_assert(cm_bkgQueueCount-- > 0); lock_ReleaseWrite(&cm_daemonLock); + #ifdef DEBUG_REFCOUNT + osi_Log2(afsd_logp,"cm_BkgDaemon (before) scp 0x%x ref %d",rp->scp, rp->scp->refCount); + #endif (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp); ! #ifdef DEBUG_REFCOUNT ! osi_Log2(afsd_logp,"cm_BkgDaemon (after) scp 0x%x ref %d",rp->scp, rp->scp->refCount); ! #endif ! cm_ReleaseUser(rp->userp); cm_ReleaseSCache(rp->scp); free(rp); *************** *** 100,106 **** lock_ReleaseWrite(&cm_daemonLock); } ! void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, long p1, long p2, long p3, long p4, cm_user_t *userp) { cm_bkgRequest_t *rp; --- 105,111 ---- lock_ReleaseWrite(&cm_daemonLock); } ! void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, cm_user_t *userp) { cm_bkgRequest_t *rp; Index: openafs/src/WINNT/afsd/cm_daemon.h diff -c openafs/src/WINNT/afsd/cm_daemon.h:1.4 openafs/src/WINNT/afsd/cm_daemon.h:1.4.4.1 *** openafs/src/WINNT/afsd/cm_daemon.h:1.4 Sat Oct 29 16:13:43 2005 --- openafs/src/WINNT/afsd/cm_daemon.h Mon Oct 2 23:23:21 2006 *************** *** 24,44 **** void cm_InitDaemon(int nDaemons); ! typedef void (cm_bkgProc_t)(cm_scache_t *scp, long p1, long p2, long p3, ! long p4, struct cm_user *up); typedef struct cm_bkgRequest { osi_queue_t q; cm_bkgProc_t *procp; cm_scache_t *scp; ! long p1; ! long p2; ! long p3; ! long p4; struct cm_user *userp; } cm_bkgRequest_t; ! extern void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, long p1, ! long p2, long p3, long p4, cm_user_t *userp); #endif /* __CM_DAEMON_H_ENV_ */ --- 24,44 ---- void cm_InitDaemon(int nDaemons); ! typedef void (cm_bkgProc_t)(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, ! afs_uint32 p4, struct cm_user *up); typedef struct cm_bkgRequest { osi_queue_t q; cm_bkgProc_t *procp; cm_scache_t *scp; ! afs_uint32 p1; ! afs_uint32 p2; ! afs_uint32 p3; ! afs_uint32 p4; struct cm_user *userp; } cm_bkgRequest_t; ! extern void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, ! afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, cm_user_t *userp); #endif /* __CM_DAEMON_H_ENV_ */ Index: openafs/src/WINNT/afsd/cm_dcache.c diff -c openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.2 openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.8 *** openafs/src/WINNT/afsd/cm_dcache.c:1.30.2.2 Wed Aug 9 19:49:41 2006 --- openafs/src/WINNT/afsd/cm_dcache.c Fri Oct 6 12:32:43 2006 *************** *** 46,52 **** /* functions called back from the buffer package when reading or writing data, * or when holding or releasing a vnode pointer. */ ! long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, cm_user_t *userp, cm_req_t *reqp) { /* store the data back from this buffer; the buffer is locked and held, --- 46,52 ---- /* functions called back from the buffer package when reading or writing data, * or when holding or releasing a vnode pointer. */ ! long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags, cm_user_t *userp, cm_req_t *reqp) { /* store the data back from this buffer; the buffer is locked and held, *************** *** 56,63 **** * bufp->scp. */ long code; ! cm_fid_t *fidp = vfidp; ! cm_scache_t *scp; long nbytes; long temp; AFSFetchStatus outStatus; --- 56,62 ---- * bufp->scp. */ long code; ! cm_scache_t *scp = vscp; long nbytes; long temp; AFSFetchStatus outStatus; *************** *** 77,100 **** int require_64bit_ops = 0; osi_assert(userp != NULL); /* now, the buffer may or may not be filled with good data (buf_GetNew * drops lots of locks, and may indeed return a properly initialized * buffer, although more likely it will just return a new, empty, buffer. */ - scp = cm_FindSCache(fidp); - if (scp == NULL) - return CM_ERROR_NOSUCHFILE; /* shouldn't happen */ - - cm_AFSFidFromFid(&tfid, fidp); lock_ObtainMutex(&scp->mx); code = cm_SetupStoreBIOD(scp, offsetp, length, &biod, userp, reqp); if (code) { osi_Log1(afsd_logp, "cm_SetupStoreBIOD code %x", code); lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); return code; } --- 76,100 ---- int require_64bit_ops = 0; osi_assert(userp != NULL); + osi_assert(scp != NULL); /* now, the buffer may or may not be filled with good data (buf_GetNew * drops lots of locks, and may indeed return a properly initialized * buffer, although more likely it will just return a new, empty, buffer. */ lock_ObtainMutex(&scp->mx); + cm_AFSFidFromFid(&tfid, &scp->fid); + + if (scp->flags & CM_SCACHEFLAG_DELETED) { + lock_ReleaseMutex(&scp->mx); + return CM_ERROR_NOSUCHFILE; + } code = cm_SetupStoreBIOD(scp, offsetp, length, &biod, userp, reqp); if (code) { osi_Log1(afsd_logp, "cm_SetupStoreBIOD code %x", code); lock_ReleaseMutex(&scp->mx); return code; } *************** *** 102,108 **** osi_Log0(afsd_logp, "cm_SetupStoreBIOD length 0"); lock_ReleaseMutex(&scp->mx); cm_ReleaseBIOD(&biod, 1); /* should be a NOOP */ - cm_ReleaseSCache(scp); return 0; } --- 102,107 ---- *************** *** 295,301 **** } lock_ReleaseMutex(&scp->mx); cm_ReleaseBIOD(&biod, 1); - cm_ReleaseSCache(scp); return code; } --- 294,299 ---- *************** *** 427,439 **** /* stabilize scache entry, and return with it locked so * it stays stable. */ ! long cm_BufStabilize(void *parmp, cm_user_t *userp, cm_req_t *reqp) { ! cm_scache_t *scp; long code; - scp = parmp; - lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE); --- 425,435 ---- /* stabilize scache entry, and return with it locked so * it stays stable. */ ! long cm_BufStabilize(void *vscp, cm_user_t *userp, cm_req_t *reqp) { ! cm_scache_t *scp = vscp; long code; lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE); *************** *** 446,457 **** } /* undoes the work that cm_BufStabilize does: releases lock so things can change again */ ! long cm_BufUnstabilize(void *parmp, cm_user_t *userp) { ! cm_scache_t *scp; ! ! scp = parmp; lock_ReleaseMutex(&scp->mx); /* always succeeds */ --- 442,453 ---- } /* undoes the work that cm_BufStabilize does: releases lock so things can change again */ ! long cm_BufUnstabilize(void *vscp, cm_user_t *userp) { ! cm_scache_t *scp = vscp; + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSIZE); + lock_ReleaseMutex(&scp->mx); /* always succeeds */ *************** *** 561,566 **** --- 557,563 ---- && bp->dataVersion != scp->dataVersion) stop = 1; buf_Release(bp); + bp = NULL; } else stop = 1; *************** *** 594,616 **** return code; } ! void cm_BkgStore(cm_scache_t *scp, long p1, long p2, long p3, long p4, cm_user_t *userp) { osi_hyper_t toffset; long length; cm_req_t req; ! cm_InitReq(&req); ! req.flags |= CM_REQ_NORETRY; ! toffset.LowPart = p1; ! toffset.HighPart = p2; ! length = p3; ! osi_Log4(afsd_logp, "Starting BKG store scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3); ! cm_BufWrite(&scp->fid, &toffset, length, /* flags */ 0, userp, &req); lock_ObtainMutex(&scp->mx); cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_ASYNCSTORE); --- 591,620 ---- return code; } ! void cm_BkgStore(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, cm_user_t *userp) { osi_hyper_t toffset; long length; cm_req_t req; + long code; ! if (scp->flags & CM_SCACHEFLAG_DELETED) { ! osi_Log4(afsd_logp, "Skipping BKG store - Deleted scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3); ! } else { ! cm_InitReq(&req); ! #ifdef NO_BKG_RETRIES ! req.flags |= CM_REQ_NORETRY; ! #endif ! toffset.LowPart = p1; ! toffset.HighPart = p2; ! length = p3; ! osi_Log4(afsd_logp, "Starting BKG store scp 0x%p, offset 0x%x:%08x, length 0x%x", scp, p2, p1, p3); ! code = cm_BufWrite(scp, &toffset, length, /* flags */ 0, userp, &req); ! } lock_ObtainMutex(&scp->mx); cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_ASYNCSTORE); *************** *** 636,642 **** } /* do the prefetch */ ! void cm_BkgPrefetch(cm_scache_t *scp, long p1, long p2, long p3, long p4, cm_user_t *userp) { long length; --- 640,646 ---- } /* do the prefetch */ ! void cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, cm_user_t *userp) { long length; *************** *** 742,748 **** long flags; /* flags to cm_SyncOp */ /* clear things out */ ! biop->scp = scp; /* don't hold */ biop->offset = *inOffsetp; biop->length = 0; biop->bufListp = NULL; --- 746,752 ---- long flags; /* flags to cm_SyncOp */ /* clear things out */ ! biop->scp = scp; /* do not hold; held by caller */ biop->offset = *inOffsetp; biop->length = 0; biop->bufListp = NULL; *************** *** 755,761 **** lock_ObtainMutex(&scp->mx); bufp = NULL; ! for (temp = 0; temp < inSize; temp += cm_data.buf_blockSize, bufp = NULL) { thyper.HighPart = 0; thyper.LowPart = temp; tbase = LargeIntegerAdd(*inOffsetp, thyper); --- 759,765 ---- lock_ObtainMutex(&scp->mx); bufp = NULL; ! for (temp = 0; temp < inSize; temp += cm_data.buf_blockSize) { thyper.HighPart = 0; thyper.LowPart = temp; tbase = LargeIntegerAdd(*inOffsetp, thyper); *************** *** 767,776 **** lock_ObtainMutex(&bufp->mx); lock_ObtainMutex(&scp->mx); ! flags = CM_SCACHESYNC_NEEDCALLBACK ! | CM_SCACHESYNC_GETSTATUS ! | CM_SCACHESYNC_STOREDATA ! | CM_SCACHESYNC_BUFLOCKED; code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags); if (code) { lock_ReleaseMutex(&bufp->mx); --- 771,777 ---- lock_ObtainMutex(&bufp->mx); lock_ObtainMutex(&scp->mx); ! flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_BUFLOCKED; code = cm_SyncOp(scp, bufp, userp, reqp, 0, flags); if (code) { lock_ReleaseMutex(&bufp->mx); *************** *** 791,796 **** --- 792,798 ---- cm_SyncOpDone(scp, bufp, flags); lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + bufp = NULL; } } *************** *** 816,821 **** --- 818,824 ---- biop->length = cm_data.buf_blockSize; firstModOffset = bufp->offset; biop->offset = firstModOffset; + bufp = NULL; /* this buffer and reference added to the queue */ /* compute the window surrounding *inOffsetp of size cm_chunkSize */ scanStart = *inOffsetp; *************** *** 824,831 **** thyper.HighPart = 0; scanEnd = LargeIntegerAdd(scanStart, thyper); ! flags = CM_SCACHESYNC_NEEDCALLBACK ! | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_BUFLOCKED | CM_SCACHESYNC_NOWAIT; --- 827,833 ---- thyper.HighPart = 0; scanEnd = LargeIntegerAdd(scanStart, thyper); ! flags = CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_BUFLOCKED | CM_SCACHESYNC_NOWAIT; *************** *** 846,851 **** --- 848,854 ---- lock_ObtainMutex(&scp->mx); if (code == 0) { buf_Release(bufp); + bufp = NULL; break; } *************** *** 853,858 **** --- 856,862 ---- if (code) { lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + bufp = NULL; break; } *************** *** 861,866 **** --- 865,871 ---- cm_SyncOpDone(scp, bufp, flags); lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + bufp = NULL; break; } *************** *** 877,882 **** --- 882,888 ---- osi_QAddT((osi_queue_t **) &biop->bufListp, (osi_queue_t **) &biop->bufListEndp, &qdp->q); + bufp = NULL; /* added to the queue */ /* update biod info describing the transfer */ biop->offset = LargeIntegerSubtract(biop->offset, thyper); *************** *** 902,907 **** --- 908,914 ---- lock_ObtainMutex(&scp->mx); if (code == 0) { buf_Release(bufp); + bufp = NULL; break; } *************** *** 909,914 **** --- 916,922 ---- if (code) { lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + bufp = NULL; break; } *************** *** 917,922 **** --- 925,931 ---- cm_SyncOpDone(scp, bufp, flags); lock_ReleaseMutex(&bufp->mx); buf_Release(bufp); + bufp = NULL; break; } *************** *** 933,938 **** --- 942,948 ---- osi_QAddH((osi_queue_t **) &biop->bufListp, (osi_queue_t **) &biop->bufListEndp, &qdp->q); + bufp = NULL; /* update biod info describing the transfer */ biop->length += cm_data.buf_blockSize; *************** *** 967,973 **** osi_queueData_t *heldBufListEndp; /* first one */ int reserving; ! biop->scp = scp; biop->offset = *offsetp; /* null out the list of buffers */ biop->bufListp = biop->bufListEndp = NULL; --- 977,983 ---- osi_queueData_t *heldBufListEndp; /* first one */ int reserving; ! biop->scp = scp; /* do not hold; held by caller */ biop->offset = *offsetp; /* null out the list of buffers */ biop->bufListp = biop->bufListEndp = NULL; *************** *** 1100,1107 **** break; } ! flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_FETCHDATA ! | CM_SCACHESYNC_BUFLOCKED; if (!isFirst) flags |= CM_SCACHESYNC_NOWAIT; --- 1110,1116 ---- break; } ! flags = CM_SCACHESYNC_FETCHDATA | CM_SCACHESYNC_BUFLOCKED; if (!isFirst) flags |= CM_SCACHESYNC_NOWAIT; *************** *** 1181,1187 **** */ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore) { ! cm_scache_t *scp; cm_buf_t *bufp; osi_queueData_t *qdp; osi_queueData_t *nqdp; --- 1190,1196 ---- */ void cm_ReleaseBIOD(cm_bulkIO_t *biop, int isStore) { ! cm_scache_t *scp; /* do not release; not held in biop */ cm_buf_t *bufp; osi_queueData_t *qdp; osi_queueData_t *nqdp; *************** *** 1191,1231 **** if (biop->reserved) buf_UnreserveBuffers(cm_chunkSize / cm_data.buf_blockSize); - flags = CM_SCACHESYNC_NEEDCALLBACK; if (isStore) ! flags |= CM_SCACHESYNC_STOREDATA; else ! flags |= CM_SCACHESYNC_FETCHDATA; scp = biop->scp; ! for(qdp = biop->bufListp; qdp; qdp = nqdp) { ! /* lookup next guy first, since we're going to free this one */ ! nqdp = (osi_queueData_t *) osi_QNext(&qdp->q); ! /* extract buffer and free queue data */ ! bufp = osi_GetQData(qdp); ! osi_QRemoveHT((osi_queue_t **) &biop->bufListp, ! (osi_queue_t **) &biop->bufListEndp, ! &qdp->q); ! osi_QDFree(qdp); ! ! /* now, mark I/O as done, unlock the buffer and release it */ ! lock_ObtainMutex(&bufp->mx); ! lock_ObtainMutex(&scp->mx); ! cm_SyncOpDone(scp, bufp, flags); ! /* turn off writing and wakeup users */ ! if (isStore) { ! if (bufp->flags & CM_BUF_WAITING) { ! osi_Log2(afsd_logp, "cm_ReleaseBIOD Waking [scp 0x%p] bp 0x%p", scp, bufp); ! osi_Wakeup((LONG_PTR) bufp); ! } ! bufp->flags &= ~(CM_BUF_WRITING | CM_BUF_DIRTY); ! } ! ! lock_ReleaseMutex(&scp->mx); ! lock_ReleaseMutex(&bufp->mx); ! buf_Release(bufp); } /* clean things out */ --- 1200,1246 ---- if (biop->reserved) buf_UnreserveBuffers(cm_chunkSize / cm_data.buf_blockSize); if (isStore) ! flags = CM_SCACHESYNC_STOREDATA; else ! flags = CM_SCACHESYNC_FETCHDATA; scp = biop->scp; ! if (biop->bufListp) { ! for(qdp = biop->bufListp; qdp; qdp = nqdp) { ! /* lookup next guy first, since we're going to free this one */ ! nqdp = (osi_queueData_t *) osi_QNext(&qdp->q); ! /* extract buffer and free queue data */ ! bufp = osi_GetQData(qdp); ! osi_QRemoveHT((osi_queue_t **) &biop->bufListp, ! (osi_queue_t **) &biop->bufListEndp, ! &qdp->q); ! osi_QDFree(qdp); ! ! /* now, mark I/O as done, unlock the buffer and release it */ ! lock_ObtainMutex(&bufp->mx); ! lock_ObtainMutex(&scp->mx); ! cm_SyncOpDone(scp, bufp, flags); ! /* turn off writing and wakeup users */ ! if (isStore) { ! if (bufp->flags & CM_BUF_WAITING) { ! osi_Log2(afsd_logp, "cm_ReleaseBIOD Waking [scp 0x%p] bp 0x%p", scp, bufp); ! osi_Wakeup((LONG_PTR) bufp); ! } ! bufp->flags &= ~(CM_BUF_WRITING | CM_BUF_DIRTY); ! } ! ! lock_ReleaseMutex(&scp->mx); ! lock_ReleaseMutex(&bufp->mx); ! buf_Release(bufp); ! bufp = NULL; ! } ! } else { ! lock_ObtainMutex(&scp->mx); ! cm_SyncOpDone(scp, NULL, flags); ! lock_ReleaseMutex(&scp->mx); } /* clean things out */ *************** *** 1411,1417 **** nbytes_hi = ntohl(nbytes_hi); } else { nbytes_hi = 0; ! code = callp->error; rx_EndCall(callp, code); callp = NULL; } --- 1426,1432 ---- nbytes_hi = ntohl(nbytes_hi); } else { nbytes_hi = 0; ! code = callp->error; rx_EndCall(callp, code); callp = NULL; } Index: openafs/src/WINNT/afsd/cm_dcache.h diff -c openafs/src/WINNT/afsd/cm_dcache.h:1.4 openafs/src/WINNT/afsd/cm_dcache.h:1.4.4.1 *** openafs/src/WINNT/afsd/cm_dcache.h:1.4 Fri Nov 18 18:45:02 2005 --- openafs/src/WINNT/afsd/cm_dcache.h Mon Oct 2 23:23:21 2006 *************** *** 42,51 **** extern long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, cm_bulkIO_t *biop, cm_user_t *userp, cm_req_t *reqp); ! extern void cm_BkgPrefetch(cm_scache_t *scp, long p1, long p2, long p3, long p4, struct cm_user *userp); ! extern void cm_BkgStore(cm_scache_t *scp, long p1, long p2, long p3, long p4, struct cm_user *userp); extern void cm_ConsiderPrefetch(cm_scache_t *scp, osi_hyper_t *offsetp, --- 42,51 ---- extern long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, cm_bulkIO_t *biop, cm_user_t *userp, cm_req_t *reqp); ! extern void cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, struct cm_user *userp); ! extern void cm_BkgStore(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, struct cm_user *userp); extern void cm_ConsiderPrefetch(cm_scache_t *scp, osi_hyper_t *offsetp, Index: openafs/src/WINNT/afsd/cm_dnlc.c diff -c openafs/src/WINNT/afsd/cm_dnlc.c:1.10.4.1 openafs/src/WINNT/afsd/cm_dnlc.c:1.10.4.3 *** openafs/src/WINNT/afsd/cm_dnlc.c:1.10.4.1 Wed Sep 6 13:21:19 2006 --- openafs/src/WINNT/afsd/cm_dnlc.c Sat Oct 7 18:33:29 2006 *************** *** 187,200 **** int safety, match; if (!cm_useDnlc) ! return 0; if ( cm_debugDnlc ) osi_Log2(afsd_logp, "cm_dnlcLookup dir %x name %s", adp, osi_LogSaveString(afsd_logp,aname)); dnlcHash( ts, key ); /* leaves ts pointing at the NULL */ if (ts - aname >= CM_AFSNCNAMESIZE) ! return 0; skey = key & (NHSIZE -1); --- 187,200 ---- int safety, match; if (!cm_useDnlc) ! return NULL; if ( cm_debugDnlc ) osi_Log2(afsd_logp, "cm_dnlcLookup dir %x name %s", adp, osi_LogSaveString(afsd_logp,aname)); dnlcHash( ts, key ); /* leaves ts pointing at the NULL */ if (ts - aname >= CM_AFSNCNAMESIZE) ! return NULL; skey = key & (NHSIZE -1); *************** *** 203,209 **** ts = 0; tnc_begin = cm_data.nameHash[skey]; ! for ( tvc = (cm_scache_t *) 0, tnc = tnc_begin, safety=0; tnc; tnc = tnc->next, safety++ ) { if (tnc->dirp == adp) --- 203,209 ---- ts = 0; tnc_begin = cm_data.nameHash[skey]; ! for ( tvc = (cm_scache_t *) NULL, tnc = tnc_begin, safety=0; tnc; tnc = tnc->next, safety++ ) { if (tnc->dirp == adp) *************** *** 264,270 **** if ( cm_debugDnlc ) osi_Log0(afsd_logp, "DNLC cycle"); cm_dnlcPurge(); ! return(0); } } --- 264,270 ---- if ( cm_debugDnlc ) osi_Log0(afsd_logp, "DNLC cycle"); cm_dnlcPurge(); ! return(NULL); } } Index: openafs/src/WINNT/afsd/cm_ioctl.c diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.4 openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.8 *** openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.4 Thu Jul 20 17:46:19 2006 --- openafs/src/WINNT/afsd/cm_ioctl.c Mon Oct 16 20:21:36 2006 *************** *** 217,223 **** { long code; #ifndef AFSIFS ! cm_scache_t *substRootp; #endif char * relativePath = ioctlp->inDatap; --- 217,223 ---- { long code; #ifndef AFSIFS ! cm_scache_t *substRootp = NULL; #endif char * relativePath = ioctlp->inDatap; *************** *** 241,248 **** CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, "", reqp, scpp); ! if (code) ! return code; #else /* AFSIFS */ if (relativePath[0] == relativePath[1] && relativePath[1] == '\\' && --- 241,250 ---- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, "", reqp, scpp); ! if (code) { ! osi_Log1(afsd_logp,"cm_ParseIoctlPath code 0x%x", code); ! return code; ! } #else /* AFSIFS */ if (relativePath[0] == relativePath[1] && relativePath[1] == '\\' && *************** *** 275,287 **** CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, sharePath, reqp, &substRootp); free(sharePath); ! if (code) return code; code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); ! if (code) return code; } else { /* otherwise, treat the name as a cellname mounted off the afs root. * This requires that we reconstruct the shareName string with --- 277,294 ---- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, sharePath, reqp, &substRootp); free(sharePath); ! if (code) { ! osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code); return code; + } code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); ! cm_ReleaseSCache(substRootp); ! if (code) { ! osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code); return code; + } } else { /* otherwise, treat the name as a cellname mounted off the afs root. * This requires that we reconstruct the shareName string with *************** *** 303,327 **** code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, shareName, reqp, &substRootp); ! if (code) return code; code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); ! if (code) return code; } } else { code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, ioctlp->tidPathp, reqp, &substRootp); ! if (code) return code; code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); ! if (code) return code; } #endif /* AFSIFS */ --- 310,344 ---- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, shareName, reqp, &substRootp); ! if (code) { ! osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code); return code; + } code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); ! if (code) { ! cm_ReleaseSCache(substRootp); ! osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code); return code; + } } } else { code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, ioctlp->tidPathp, reqp, &substRootp); ! if (code) { ! osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code); return code; + } code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); ! if (code) { ! cm_ReleaseSCache(substRootp); ! osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code); return code; + } } #endif /* AFSIFS */ *************** *** 332,338 **** --- 349,359 ---- /* This is usually nothing, but for StatMountPoint it is the file name. */ TranslateExtendedChars(ioctlp->inDatap); + if (substRootp) + cm_ReleaseSCache(substRootp); + /* and return success */ + osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code); return 0; } *************** *** 393,399 **** long code; char tbuffer[1024]; char *tp, *jp; ! cm_scache_t *substRootp; StringCbCopyA(tbuffer, sizeof(tbuffer), ioctlp->inDatap); tp = strrchr(tbuffer, '\\'); --- 414,420 ---- long code; char tbuffer[1024]; char *tp, *jp; ! cm_scache_t *substRootp = NULL; StringCbCopyA(tbuffer, sizeof(tbuffer), ioctlp->inDatap); tp = strrchr(tbuffer, '\\'); *************** *** 448,453 **** --- 469,475 ---- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); + cm_ReleaseSCache(substRootp); if (code) return code; } else { /* otherwise, treat the name as a cellname mounted off the afs root. *************** *** 473,478 **** --- 495,501 ---- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); + cm_ReleaseSCache(substRootp); if (code) return code; } } else { *************** *** 483,488 **** --- 506,512 ---- code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, NULL, reqp, scpp); + cm_ReleaseSCache(substRootp); if (code) return code; } *************** *** 1005,1011 **** /* if something went wrong, bail out now */ if (code) { ! goto done; } lock_ObtainMutex(&scp->mx); --- 1029,1035 ---- /* if something went wrong, bail out now */ if (code) { ! goto done2; } lock_ObtainMutex(&scp->mx); *************** *** 1014,1020 **** if (code) { lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); ! goto done; } /* now check that this is a real mount point */ --- 1038,1044 ---- if (code) { lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); ! goto done2; } /* now check that this is a real mount point */ *************** *** 1022,1028 **** lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); code = CM_ERROR_INVAL; ! goto done; } /* time to make the RPC, so drop the lock */ --- 1046,1052 ---- lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); code = CM_ERROR_INVAL; ! goto done1; } /* time to make the RPC, so drop the lock */ *************** *** 1036,1042 **** FILE_NOTIFY_CHANGE_DIR_NAME, dscp, cp, NULL, TRUE); ! done: cm_ReleaseSCache(dscp); return code; } --- 1060,1071 ---- FILE_NOTIFY_CHANGE_DIR_NAME, dscp, cp, NULL, TRUE); ! done1: ! lock_ObtainMutex(&scp->mx); ! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! lock_ReleaseMutex(&scp->mx); ! ! done2: cm_ReleaseSCache(dscp); return code; } *************** *** 1660,1665 **** --- 1689,1695 ---- osi_Log0(afsd_logp,"IoctlCreateMountPoint within Freelance root dir"); code = cm_FreelanceAddMount(leaf, fullCell, volume, *ioctlp->inDatap == '%', NULL); + cm_ReleaseSCache(dscp); return code; } #endif *************** *** 1718,1723 **** --- 1748,1754 ---- } osi_Log0(afsd_logp,"IoctlCreateSymlink within Freelance root dir"); code = cm_FreelanceAddSymlink(leaf, cp, NULL); + cm_ReleaseSCache(dscp); return code; } #endif *************** *** 1851,1856 **** --- 1882,1888 ---- * the freelance code to do the add. */ osi_Log0(afsd_logp,"IoctlDeletelink from Freelance root dir"); code = cm_FreelanceRemoveSymlink(cp); + cm_ReleaseSCache(dscp); return code; } #endif *************** *** 1858,1889 **** code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); /* if something went wrong, bail out now */ ! if (code) { ! goto done; ! } lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! if (code) { ! lock_ReleaseMutex(&scp->mx); ! cm_ReleaseSCache(scp); ! goto done; ! } /* now check that this is a real symlink */ if (scp->fileType != CM_SCACHETYPE_SYMLINK && scp->fileType != CM_SCACHETYPE_DFSLINK && scp->fileType != CM_SCACHETYPE_INVALID) { - lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); code = CM_ERROR_INVAL; ! goto done; } /* time to make the RPC, so drop the lock */ lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); /* easier to do it this way */ code = cm_Unlink(dscp, cp, userp, &req); --- 1890,1914 ---- code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp); /* if something went wrong, bail out now */ ! if (code) ! goto done3; lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! if (code) ! goto done2; /* now check that this is a real symlink */ if (scp->fileType != CM_SCACHETYPE_SYMLINK && scp->fileType != CM_SCACHETYPE_DFSLINK && scp->fileType != CM_SCACHETYPE_INVALID) { code = CM_ERROR_INVAL; ! goto done1; } /* time to make the RPC, so drop the lock */ lock_ReleaseMutex(&scp->mx); /* easier to do it this way */ code = cm_Unlink(dscp, cp, userp, &req); *************** *** 1893,1899 **** | FILE_NOTIFY_CHANGE_DIR_NAME, dscp, cp, NULL, TRUE); ! done: cm_ReleaseSCache(dscp); return code; } --- 1918,1932 ---- | FILE_NOTIFY_CHANGE_DIR_NAME, dscp, cp, NULL, TRUE); ! lock_ObtainMutex(&scp->mx); ! done1: ! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! ! done2: ! lock_ReleaseMutex(&scp->mx); ! cm_ReleaseSCache(scp); ! ! done3: cm_ReleaseSCache(dscp); return code; } Index: openafs/src/WINNT/afsd/cm_scache.c diff -c openafs/src/WINNT/afsd/cm_scache.c:1.35.2.13 openafs/src/WINNT/afsd/cm_scache.c:1.35.2.22 *** openafs/src/WINNT/afsd/cm_scache.c:1.35.2.13 Thu Jul 27 22:10:15 2006 --- openafs/src/WINNT/afsd/cm_scache.c Mon Oct 16 20:32:57 2006 *************** *** 52,79 **** cm_data.scacheLRULastp = scp; } ! /* called with cm_scacheLock write-locked; recycles an existing scp. */ ! long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) { cm_scache_t **lscpp; cm_scache_t *tscp; int i; ! if (scp->flags & CM_SCACHEFLAG_INHASH) { /* hash it out first */ i = CM_SCACHE_HASH(&scp->fid); for (lscpp = &cm_data.hashTablep[i], tscp = cm_data.hashTablep[i]; ! tscp; ! lscpp = &tscp->nextp, tscp = tscp->nextp) { if (tscp == scp) { *lscpp = scp->nextp; scp->flags &= ~CM_SCACHEFLAG_INHASH; break; } } - osi_assertx(tscp, "afsd: scache hash screwup"); } if (flags & CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS) { osi_queueData_t *qdp; cm_buf_t *bufp; --- 52,100 ---- cm_data.scacheLRULastp = scp; } ! /* call with scache write-locked and mutex held */ ! void cm_RemoveSCacheFromHashTable(cm_scache_t *scp) { cm_scache_t **lscpp; cm_scache_t *tscp; int i; ! if (scp->flags & CM_SCACHEFLAG_INHASH) { /* hash it out first */ i = CM_SCACHE_HASH(&scp->fid); for (lscpp = &cm_data.hashTablep[i], tscp = cm_data.hashTablep[i]; ! tscp; ! lscpp = &tscp->nextp, tscp = tscp->nextp) { if (tscp == scp) { *lscpp = scp->nextp; scp->flags &= ~CM_SCACHEFLAG_INHASH; break; } } } + } + /* called with cm_scacheLock write-locked; recycles an existing scp. + * + * this function ignores all of the locking hierarchy. + */ + long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) + { + if (scp->refCount != 0) { + return -1; + } + + if (scp->flags & CM_SCACHEFLAG_SMB_FID) { + osi_Log1(afsd_logp,"cm_RecycleSCache CM_SCACHEFLAG_SMB_FID detected scp 0x%p", scp); + #ifdef DEBUG + osi_panic("cm_RecycleSCache CM_SCACHEFLAG_SMB_FID detected",__FILE__,__LINE__); + #endif + return -1; + } + + cm_RemoveSCacheFromHashTable(scp); + + #if 0 if (flags & CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS) { osi_queueData_t *qdp; cm_buf_t *bufp; *************** *** 86,91 **** --- 107,114 ---- lock_ObtainMutex(&bufp->mx); bufp->cmFlags &= ~CM_BUF_CMSTORING; bufp->flags &= ~CM_BUF_DIRTY; + bufp->flags |= CM_BUF_ERROR; + bufp->error = VNOVNODE; bufp->dataVersion = -1; /* bad */ bufp->dirtyCounter++; if (bufp->flags & CM_BUF_WAITING) { *************** *** 104,109 **** --- 127,134 ---- lock_ObtainMutex(&bufp->mx); bufp->cmFlags &= ~CM_BUF_CMFETCHING; bufp->flags &= ~CM_BUF_DIRTY; + bufp->flags |= CM_BUF_ERROR; + bufp->error = VNOVNODE; bufp->dataVersion = -1; /* bad */ bufp->dirtyCounter++; if (bufp->flags & CM_BUF_WAITING) { *************** *** 114,132 **** buf_Release(bufp); } } } else { /* look for things that shouldn't still be set */ osi_assert(scp->bufWritesp == NULL); osi_assert(scp->bufReadsp == NULL); } /* invalidate so next merge works fine; * also initialize some flags */ scp->flags &= ~(CM_SCACHEFLAG_STATD | CM_SCACHEFLAG_RO | CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_OVERQUOTA ! | CM_SCACHEFLAG_OUTOFSPACE); scp->serverModTime = 0; scp->dataVersion = 0; scp->bulkStatProgress = hzero; --- 139,161 ---- buf_Release(bufp); } } + buf_CleanDirtyBuffers(scp); } else { /* look for things that shouldn't still be set */ osi_assert(scp->bufWritesp == NULL); osi_assert(scp->bufReadsp == NULL); } + #endif /* invalidate so next merge works fine; * also initialize some flags */ scp->flags &= ~(CM_SCACHEFLAG_STATD + | CM_SCACHEFLAG_DELETED | CM_SCACHEFLAG_RO | CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_OVERQUOTA ! | CM_SCACHEFLAG_OUTOFSPACE ! | CM_SCACHEFLAG_EACCESS); scp->serverModTime = 0; scp->dataVersion = 0; scp->bulkStatProgress = hzero; *************** *** 174,180 **** * while we hold the global refcount lock. */ cm_FreeAllACLEnts(scp); - return 0; } --- 203,208 ---- *************** *** 185,218 **** cm_scache_t *cm_GetNewSCache(void) { cm_scache_t *scp; ! start: ! if (cm_data.currentSCaches >= cm_data.maxSCaches) { ! for (scp = cm_data.scacheLRULastp; ! scp; ! scp = (cm_scache_t *) osi_QPrev(&scp->q)) { ! if (scp->refCount == 0) ! break; ! } ! ! if (scp) { ! osi_assert(scp >= cm_data.scacheBaseAddress && scp < (cm_scache_t *)cm_data.hashTablep); ! if (!cm_RecycleSCache(scp, 0)) { ! /* we found an entry, so return it */ /* now remove from the LRU queue and put it back at the ! * head of the LRU queue. ! */ cm_AdjustLRU(scp); /* and we're done */ return scp; - } else { - /* We don't like this entry, choose another one. */ - goto start; } ! } } /* if we get here, we should allocate a new scache entry. We either are below --- 213,289 ---- cm_scache_t *cm_GetNewSCache(void) { cm_scache_t *scp; + int retry = 0; ! #if 0 ! /* first pass - look for deleted objects */ ! for ( scp = cm_data.scacheLRULastp; ! scp; ! scp = (cm_scache_t *) osi_QPrev(&scp->q)) ! { ! osi_assert(scp >= cm_data.scacheBaseAddress && scp < (cm_scache_t *)cm_data.hashTablep); ! if (scp->refCount == 0) { ! if (scp->flags & CM_SCACHEFLAG_DELETED) { ! osi_Log1(afsd_logp, "GetNewSCache attempting to recycle deleted scp 0x%x", scp); ! if (!cm_RecycleSCache(scp, CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS)) { ! ! /* we found an entry, so return it */ ! /* now remove from the LRU queue and put it back at the ! * head of the LRU queue. ! */ ! cm_AdjustLRU(scp); ! ! /* and we're done */ ! return scp; ! } ! osi_Log1(afsd_logp, "GetNewSCache recycled failed scp 0x%x", scp); ! } else if (!(scp->flags & CM_SCACHEFLAG_INHASH)) { /* we found an entry, so return it */ /* now remove from the LRU queue and put it back at the ! * head of the LRU queue. ! */ cm_AdjustLRU(scp); /* and we're done */ return scp; } ! } ! } ! osi_Log0(afsd_logp, "GetNewSCache no deleted or recycled entries available for reuse"); ! #endif ! ! if (cm_data.currentSCaches >= cm_data.maxSCaches) { ! /* There were no deleted scache objects that we could use. Try to find ! * one that simply hasn't been used in a while. ! */ ! for ( scp = cm_data.scacheLRULastp; ! scp; ! scp = (cm_scache_t *) osi_QPrev(&scp->q)) ! { ! /* It is possible for the refCount to be zero and for there still ! * to be outstanding dirty buffers. If there are dirty buffers, ! * we must not recycle the scp. */ ! if (scp->refCount == 0 && scp->bufReadsp == NULL && scp->bufWritesp == NULL) { ! if (!buf_DirtyBuffersExist(&scp->fid)) { ! if (!cm_RecycleSCache(scp, 0)) { ! /* we found an entry, so return it */ ! /* now remove from the LRU queue and put it back at the ! * head of the LRU queue. ! */ ! cm_AdjustLRU(scp); ! ! /* and we're done */ ! return scp; ! } ! } else { ! osi_Log1(afsd_logp,"GetNewSCache dirty buffers exist scp 0x%x", scp); ! } ! } ! } ! osi_Log1(afsd_logp, "GetNewSCache all scache entries in use (retry = %d)", retry); ! ! return NULL; } /* if we get here, we should allocate a new scache entry. We either are below *************** *** 445,452 **** cm_scache_t *scp; hash = CM_SCACHE_HASH(fidp); ! ! osi_assert(fidp->cell != 0); lock_ObtainWrite(&cm_scacheLock); for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { --- 516,525 ---- cm_scache_t *scp; hash = CM_SCACHE_HASH(fidp); ! ! if (fidp->cell == 0) { ! return NULL; ! } lock_ObtainWrite(&cm_scacheLock); for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { *************** *** 461,468 **** --- 534,546 ---- return NULL; } + #ifdef DEBUG_REFCOUNT + long cm_GetSCacheDbg(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, + cm_req_t *reqp, char * file, long line) + #else long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, cm_req_t *reqp) + #endif { long hash; cm_scache_t *scp; *************** *** 482,488 **** fidp->volume==cm_data.rootFid.volume && fidp->vnode==0x0 && fidp->unique==0x0) { ! osi_Log0(afsd_logp,"cm_getSCache called with root cell/volume and vnode=0 and unique=0"); } // yj: check if we have the scp, if so, we don't need --- 560,566 ---- fidp->volume==cm_data.rootFid.volume && fidp->vnode==0x0 && fidp->unique==0x0) { ! osi_Log0(afsd_logp,"cm_GetSCache called with root cell/volume and vnode=0 and unique=0"); } // yj: check if we have the scp, if so, we don't need *************** *** 490,495 **** --- 568,577 ---- lock_ObtainWrite(&cm_scacheLock); for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_GetSCache (1) outScpp 0x%p ref %d", file, line, scp, scp->refCount); + osi_Log1(afsd_logp,"cm_GetSCache (1) outScpp 0x%p", scp); + #endif cm_HoldSCacheNoLock(scp); *outScpp = scp; cm_AdjustLRU(scp); *************** *** 514,520 **** fidp->volume==AFS_FAKE_ROOT_VOL_ID && fidp->vnode==0x1 && fidp->unique==0x1); if (cm_freelanceEnabled && isRoot) { ! osi_Log0(afsd_logp,"cm_getSCache Freelance and isRoot"); /* freelance: if we are trying to get the root scp for the first * time, we will just put in a place holder entry. */ --- 596,602 ---- fidp->volume==AFS_FAKE_ROOT_VOL_ID && fidp->vnode==0x1 && fidp->unique==0x1); if (cm_freelanceEnabled && isRoot) { ! osi_Log0(afsd_logp,"cm_GetSCache Freelance and isRoot"); /* freelance: if we are trying to get the root scp for the first * time, we will just put in a place holder entry. */ *************** *** 522,528 **** } if (cm_freelanceEnabled && special) { ! osi_Log0(afsd_logp,"cm_getSCache Freelance and special"); if (fidp->vnode > 1 && fidp->vnode <= cm_noLocalMountPoints + 2) { lock_ObtainMutex(&cm_Freelance_Lock); mp =(cm_localMountPoints+fidp->vnode-2)->mountPointStringp; --- 604,610 ---- } if (cm_freelanceEnabled && special) { ! osi_Log0(afsd_logp,"cm_GetSCache Freelance and special"); if (fidp->vnode > 1 && fidp->vnode <= cm_noLocalMountPoints + 2) { lock_ObtainMutex(&cm_Freelance_Lock); mp =(cm_localMountPoints+fidp->vnode-2)->mountPointStringp; *************** *** 531,538 **** mp = ""; } scp = cm_GetNewSCache(); ! lock_ObtainMutex(&scp->mx); scp->fid = *fidp; scp->volp = cm_data.rootSCachep->volp; scp->dotdotFid.cell=AFS_FAKE_ROOT_CELL_ID; --- 613,634 ---- mp = ""; } scp = cm_GetNewSCache(); ! if (scp == NULL) { ! osi_Log0(afsd_logp,"cm_GetSCache unable to obtain *new* scache entry"); ! lock_ReleaseWrite(&cm_scacheLock); ! return CM_ERROR_WOULDBLOCK; ! } ! ! #if not_too_dangerous ! /* dropping the cm_scacheLock allows more than one thread ! * to obtain the same cm_scache_t from the LRU list. Since ! * the refCount is known to be zero at this point we have to ! * assume that no one else is using the one this is returned. ! */ ! lock_ReleaseWrite(&cm_scacheLock); lock_ObtainMutex(&scp->mx); + lock_ObtainWrite(&cm_scacheLock); + #endif scp->fid = *fidp; scp->volp = cm_data.rootSCachep->volp; scp->dotdotFid.cell=AFS_FAKE_ROOT_CELL_ID; *************** *** 544,549 **** --- 640,646 ---- cm_data.hashTablep[hash]=scp; scp->flags |= CM_SCACHEFLAG_INHASH; scp->refCount = 1; + osi_Log1(afsd_logp,"cm_GetSCache (freelance) sets refCount to 1 scp 0x%x", scp); if (fidp->vnode > 1 && fidp->vnode <= cm_noLocalMountPoints + 2) scp->fileType = (cm_localMountPoints+fidp->vnode-2)->fileType; else *************** *** 565,573 **** scp->group=0; scp->dataVersion=cm_data.fakeDirVersion; scp->lockDataVersion=-1; /* no lock yet */ lock_ReleaseMutex(&scp->mx); ! *outScpp = scp; lock_ReleaseWrite(&cm_scacheLock); return 0; } // end of yj code --- 662,676 ---- scp->group=0; scp->dataVersion=cm_data.fakeDirVersion; scp->lockDataVersion=-1; /* no lock yet */ + #if not_too_dangerous lock_ReleaseMutex(&scp->mx); ! #endif ! *outScpp = scp; lock_ReleaseWrite(&cm_scacheLock); + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_GetSCache (2) outScpp 0x%p ref %d", file, line, scp, scp->refCount); + osi_Log1(afsd_logp,"cm_GetSCache (2) outScpp 0x%p", scp); + #endif return 0; } // end of yj code *************** *** 591,596 **** --- 694,703 ---- */ for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) { if (cm_FidCmp(fidp, &scp->fid) == 0) { + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_GetSCache (3) outScpp 0x%p ref %d", file, line, scp, scp->refCount); + osi_Log1(afsd_logp,"cm_GetSCache (3) outScpp 0x%p", scp); + #endif cm_HoldSCacheNoLock(scp); osi_assert(scp->volp == volp); cm_AdjustLRU(scp); *************** *** 604,611 **** --- 711,735 ---- /* now, if we don't have the fid, recycle something */ scp = cm_GetNewSCache(); + if (scp == NULL) { + osi_Log0(afsd_logp,"cm_GetNewSCache unable to obtain *new* scache entry"); + lock_ReleaseWrite(&cm_scacheLock); + return CM_ERROR_WOULDBLOCK; + } + osi_Log2(afsd_logp,"cm_GetNewSCache returns scp 0x%x flags 0x%x", scp, scp->flags); + osi_assert(!(scp->flags & CM_SCACHEFLAG_INHASH)); + + #if not_too_dangerous + /* dropping the cm_scacheLock allows more than one thread + * to obtain the same cm_scache_t from the LRU list. Since + * the refCount is known to be zero at this point we have to + * assume that no one else is using the one this is returned. + */ + lock_ReleaseWrite(&cm_scacheLock); lock_ObtainMutex(&scp->mx); + lock_ObtainWrite(&cm_scacheLock); + #endif scp->fid = *fidp; scp->volp = volp; /* a held reference */ *************** *** 627,633 **** --- 751,760 ---- cm_data.hashTablep[hash] = scp; scp->flags |= CM_SCACHEFLAG_INHASH; scp->refCount = 1; + osi_Log1(afsd_logp,"cm_GetSCache sets refCount to 1 scp 0x%x", scp); + #if not_too_dangerous lock_ReleaseMutex(&scp->mx); + #endif /* XXX - The following fields in the cm_scache are * uninitialized: *************** *** 639,644 **** --- 766,775 ---- /* now we have a held scache entry; just return it */ *outScpp = scp; + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_GetSCache (4) outScpp 0x%p ref %d", file, line, scp, scp->refCount); + osi_Log1(afsd_logp,"cm_GetSCache (4) outScpp 0x%p", scp); + #endif return 0; } *************** *** 651,672 **** cm_fid_t parent_fid; cm_scache_t * pscp = NULL; ! lock_ObtainWrite(&cm_scacheLock); parent_fid = scp->fid; parent_fid.vnode = scp->parentVnode; parent_fid.unique = scp->parentUnique; if (cm_FidCmp(&scp->fid, &parent_fid)) { ! for (i=0; inextp) { ! if (!cm_FidCmp(&pscp->fid, &parent_fid)) { ! cm_HoldSCacheNoLock(pscp); ! break; ! } } } } ! lock_ReleaseWrite(&cm_scacheLock); return pscp; } --- 782,803 ---- cm_fid_t parent_fid; cm_scache_t * pscp = NULL; ! lock_ObtainRead(&cm_scacheLock); parent_fid = scp->fid; parent_fid.vnode = scp->parentVnode; parent_fid.unique = scp->parentUnique; if (cm_FidCmp(&scp->fid, &parent_fid)) { ! i = CM_SCACHE_HASH(&parent_fid); ! for (pscp = cm_data.hashTablep[i]; pscp; pscp = pscp->nextp) { ! if (!cm_FidCmp(&pscp->fid, &parent_fid)) { ! cm_HoldSCacheNoLock(pscp); ! break; } } } ! ! lock_ReleaseRead(&cm_scacheLock); return pscp; } *************** *** 734,755 **** cm_buf_t *tbufp; afs_uint32 outRights; int bufLocked; /* lookup this first */ bufLocked = flags & CM_SCACHESYNC_BUFLOCKED; ! /* some minor assertions */ ! if (flags & (CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_FETCHDATA ! | CM_SCACHESYNC_READ | CM_SCACHESYNC_WRITE ! | CM_SCACHESYNC_SETSIZE)) { ! if (bufp) { ! osi_assert(bufp->refCount > 0); ! /* ! osi_assert(cm_FidCmp(&bufp->fid, &scp->fid) == 0); ! */ ! } ! } ! else osi_assert(bufp == NULL); /* Do the access check. Now we don't really do the access check * atomically, since the caller doesn't expect the parent dir to be --- 865,880 ---- cm_buf_t *tbufp; afs_uint32 outRights; int bufLocked; + afs_uint32 sleep_scp_flags = 0; + afs_uint32 sleep_buf_cmflags = 0; + afs_uint32 sleep_scp_bufs = 0; /* lookup this first */ bufLocked = flags & CM_SCACHESYNC_BUFLOCKED; ! if (bufp) ! osi_assert(bufp->refCount > 0); ! /* Do the access check. Now we don't really do the access check * atomically, since the caller doesn't expect the parent dir to be *************** *** 900,906 **** // yj: modified this so that callback only checked if we're // not checking something on /afs /* fix the conditional to match the one in cm_HaveCallback */ ! if ( (flags & CM_SCACHESYNC_NEEDCALLBACK) #ifdef AFS_FREELANCE_CLIENT && (!cm_freelanceEnabled || !(scp->fid.vnode==0x1 && scp->fid.unique==0x1) || --- 1025,1031 ---- // yj: modified this so that callback only checked if we're // not checking something on /afs /* fix the conditional to match the one in cm_HaveCallback */ ! if ((flags & CM_SCACHESYNC_NEEDCALLBACK) #ifdef AFS_FREELANCE_CLIENT && (!cm_freelanceEnabled || !(scp->fid.vnode==0x1 && scp->fid.unique==0x1) || *************** *** 909,920 **** cm_fakeDirCallback < 2) #endif /* AFS_FREELANCE_CLIENT */ ) { ! if (!cm_HaveCallback(scp)) { osi_Log1(afsd_logp, "CM SyncOp getting callback on scp 0x%p", scp); if (bufLocked) lock_ReleaseMutex(&bufp->mx); ! code = cm_GetCallback(scp, userp, reqp, 0); if (bufLocked) { lock_ReleaseMutex(&scp->mx); lock_ObtainMutex(&bufp->mx); --- 1034,1045 ---- cm_fakeDirCallback < 2) #endif /* AFS_FREELANCE_CLIENT */ ) { ! if ((flags & CM_SCACHESYNC_FORCECB) || !cm_HaveCallback(scp)) { osi_Log1(afsd_logp, "CM SyncOp getting callback on scp 0x%p", scp); if (bufLocked) lock_ReleaseMutex(&bufp->mx); ! code = cm_GetCallback(scp, userp, reqp, (flags & CM_SCACHESYNC_FORCECB)?1:0); if (bufLocked) { lock_ReleaseMutex(&scp->mx); lock_ObtainMutex(&bufp->mx); *************** *** 922,927 **** --- 1047,1053 ---- } if (code) return code; + flags &= ~CM_SCACHESYNC_FORCECB; /* only force once */ continue; } } *************** *** 962,967 **** --- 1088,1097 ---- if (flags & CM_SCACHESYNC_NOWAIT) return CM_ERROR_WOULDBLOCK; + sleep_scp_flags = scp->flags; /* so we know why we slept */ + sleep_buf_cmflags = bufp ? bufp->cmFlags : 0; + sleep_scp_bufs = (scp->bufReadsp ? 1 : 0) | (scp->bufWritesp ? 2 : 0); + /* wait here, then try again */ osi_Log1(afsd_logp, "CM SyncOp sleeping scp 0x%p", scp); if ( scp->flags & CM_SCACHEFLAG_WAITING ) { *************** *** 1059,1064 **** --- 1189,1196 ---- osi_queueData_t *qdp; cm_buf_t *tbufp; + lock_AssertMutex(&scp->mx); + /* now, update the recorded state for RPC-type calls */ if (flags & CM_SCACHESYNC_FETCHSTATUS) scp->flags &= ~CM_SCACHEFLAG_FETCHING; *************** *** 1088,1099 **** osi_QDFree(qdp); } if (bufp) { bufp->cmFlags &= ~(CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED); if (bufp->flags & CM_BUF_WAITING) { osi_Log2(afsd_logp, "CM SyncOpDone Waking [scp 0x%p] bufp 0x%p", scp, bufp); osi_Wakeup((LONG_PTR) &bufp); } ! buf_Release(bufp); } } --- 1220,1235 ---- osi_QDFree(qdp); } if (bufp) { + int release = 0; + if (bufp->cmFlags & CM_BUF_CMFETCHING) + release = 1; bufp->cmFlags &= ~(CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED); if (bufp->flags & CM_BUF_WAITING) { osi_Log2(afsd_logp, "CM SyncOpDone Waking [scp 0x%p] bufp 0x%p", scp, bufp); osi_Wakeup((LONG_PTR) &bufp); } ! if (release) ! buf_Release(bufp); } } *************** *** 1110,1121 **** osi_QDFree(qdp); } if (bufp) { bufp->cmFlags &= ~CM_BUF_CMSTORING; if (bufp->flags & CM_BUF_WAITING) { osi_Log2(afsd_logp, "CM SyncOpDone Waking [scp 0x%p] bufp 0x%p", scp, bufp); osi_Wakeup((LONG_PTR) &bufp); } ! buf_Release(bufp); } } --- 1246,1261 ---- osi_QDFree(qdp); } if (bufp) { + int release = 0; + if (bufp->cmFlags & CM_BUF_CMSTORING) + release = 1; bufp->cmFlags &= ~CM_BUF_CMSTORING; if (bufp->flags & CM_BUF_WAITING) { osi_Log2(afsd_logp, "CM SyncOpDone Waking [scp 0x%p] bufp 0x%p", scp, bufp); osi_Wakeup((LONG_PTR) &bufp); } ! if (release) ! buf_Release(bufp); } } *************** *** 1305,1338 **** afsFidp->Unique = fidp->unique; } void cm_HoldSCacheNoLock(cm_scache_t *scp) { osi_assert(scp != 0); - osi_assert(scp->refCount >= 0); scp->refCount++; } void cm_HoldSCache(cm_scache_t *scp) { osi_assert(scp != 0); lock_ObtainWrite(&cm_scacheLock); - osi_assert(scp->refCount >= 0); scp->refCount++; lock_ReleaseWrite(&cm_scacheLock); } void cm_ReleaseSCacheNoLock(cm_scache_t *scp) { ! osi_assert(scp != 0); osi_assert(scp->refCount-- >= 0); } void cm_ReleaseSCache(cm_scache_t *scp) { ! osi_assert(scp != 0); lock_ObtainWrite(&cm_scacheLock); osi_assert(scp->refCount != 0); scp->refCount--; lock_ReleaseWrite(&cm_scacheLock); } --- 1445,1512 ---- afsFidp->Unique = fidp->unique; } + #ifdef DEBUG_REFCOUNT + void cm_HoldSCacheNoLockDbg(cm_scache_t *scp, char * file, long line) + #else void cm_HoldSCacheNoLock(cm_scache_t *scp) + #endif { osi_assert(scp != 0); scp->refCount++; + #ifdef DEBUG_REFCOUNT + osi_Log2(afsd_logp,"cm_HoldSCacheNoLock scp 0x%p ref %d",scp, scp->refCount); + afsi_log("%s:%d cm_HoldSCacheNoLock scp 0x%p, ref %d", file, line, scp, scp->refCount); + #endif } + #ifdef DEBUG_REFCOUNT + void cm_HoldSCacheDbg(cm_scache_t *scp, char * file, long line) + #else void cm_HoldSCache(cm_scache_t *scp) + #endif { osi_assert(scp != 0); lock_ObtainWrite(&cm_scacheLock); scp->refCount++; + #ifdef DEBUG_REFCOUNT + osi_Log2(afsd_logp,"cm_HoldSCache scp 0x%p ref %d",scp, scp->refCount); + afsi_log("%s:%d cm_HoldSCache scp 0x%p ref %d", file, line, scp, scp->refCount); + #endif lock_ReleaseWrite(&cm_scacheLock); } + #ifdef DEBUG_REFCOUNT + void cm_ReleaseSCacheNoLockDbg(cm_scache_t *scp, char * file, long line) + #else void cm_ReleaseSCacheNoLock(cm_scache_t *scp) + #endif { ! osi_assert(scp != NULL); ! if (scp->refCount == 0) ! osi_Log1(afsd_logp,"cm_ReleaseSCacheNoLock about to panic scp 0x%x",scp); osi_assert(scp->refCount-- >= 0); + #ifdef DEBUG_REFCOUNT + osi_Log2(afsd_logp,"cm_ReleaseSCacheNoLock scp 0x%p ref %d",scp,scp->refCount); + afsi_log("%s:%d cm_ReleaseSCacheNoLock scp 0x%p ref %d", file, line, scp, scp->refCount); + #endif } + #ifdef DEBUG_REFCOUNT + void cm_ReleaseSCacheDbg(cm_scache_t *scp, char * file, long line) + #else void cm_ReleaseSCache(cm_scache_t *scp) + #endif { ! osi_assert(scp != NULL); lock_ObtainWrite(&cm_scacheLock); + if (scp->refCount == 0) + osi_Log1(afsd_logp,"cm_ReleaseSCache about to panic scp 0x%x",scp); osi_assert(scp->refCount != 0); scp->refCount--; + #ifdef DEBUG_REFCOUNT + osi_Log2(afsd_logp,"cm_ReleaseSCache scp 0x%p ref %d",scp,scp->refCount); + afsi_log("%s:%d cm_ReleaseSCache scp 0x%p ref %d", file, line, scp, scp->refCount); + #endif lock_ReleaseWrite(&cm_scacheLock); } Index: openafs/src/WINNT/afsd/cm_scache.h diff -c openafs/src/WINNT/afsd/cm_scache.h:1.21.2.3 openafs/src/WINNT/afsd/cm_scache.h:1.21.2.8 *** openafs/src/WINNT/afsd/cm_scache.h:1.21.2.3 Wed Jun 28 11:01:21 2006 --- openafs/src/WINNT/afsd/cm_scache.h Mon Oct 16 20:32:57 2006 *************** *** 246,251 **** --- 246,252 ---- (CM_SCACHEFLAG_WATCHED | CM_SCACHEFLAG_WATCHEDSUBTREE) #define CM_SCACHEFLAG_EACCESS 0x200000 /* Bulk Stat returned EACCES */ + #define CM_SCACHEFLAG_SMB_FID 0x400000 /* sync flags for calls to the server. The CM_SCACHEFLAG_FETCHING, * CM_SCACHEFLAG_STORING and CM_SCACHEFLAG_SIZESTORING flags correspond to the *************** *** 280,285 **** --- 281,288 ---- #define CM_SCACHESYNC_BUFLOCKED 0x80000 /* the buffer is locked */ #define CM_SCACHESYNC_NOWAIT 0x100000/* don't wait for the state, * just fail */ + #define CM_SCACHESYNC_FORCECB 0x200000/* when calling cm_GetCallback() + * set the force flag */ /* flags for cm_RecycleSCache */ #define CM_SCACHE_RECYCLEFLAG_DESTROY_BUFFERS 0x1 *************** *** 305,314 **** extern void cm_InitSCache(int, long); extern long cm_GetSCache(cm_fid_t *, cm_scache_t **, struct cm_user *, struct cm_req *); ! ! extern void cm_PutSCache(cm_scache_t *); extern cm_scache_t *cm_GetNewSCache(void); --- 308,322 ---- extern void cm_InitSCache(int, long); + #ifdef DEBUG_REFCOUNT + extern long cm_GetSCacheDbg(cm_fid_t *, cm_scache_t **, struct cm_user *, + struct cm_req *, char *, long); + + #define cm_GetSCache(a,b,c,d) cm_GetSCacheDbg(a,b,c,d,__FILE__,__LINE__) + #else extern long cm_GetSCache(cm_fid_t *, cm_scache_t **, struct cm_user *, struct cm_req *); ! #endif extern cm_scache_t *cm_GetNewSCache(void); *************** *** 324,329 **** --- 332,351 ---- extern void cm_AFSFidFromFid(struct AFSFid *, cm_fid_t *); + #ifdef DEBUG_REFCOUNT + extern void cm_HoldSCacheNoLockDbg(cm_scache_t *, char *, long); + + extern void cm_HoldSCacheDbg(cm_scache_t *, char *, long); + + extern void cm_ReleaseSCacheNoLockDbg(cm_scache_t *, char *, long); + + extern void cm_ReleaseSCacheDbg(cm_scache_t *, char *, long); + + #define cm_HoldSCacheNoLock(scp) cm_HoldSCacheNoLockDbg(scp, __FILE__, __LINE__) + #define cm_HoldSCache(scp) cm_HoldSCacheDbg(scp, __FILE__, __LINE__) + #define cm_ReleaseSCacheNoLock(scp) cm_ReleaseSCacheNoLockDbg(scp, __FILE__, __LINE__) + #define cm_ReleaseSCache(scp) cm_ReleaseSCacheDbg(scp, __FILE__, __LINE__) + #else extern void cm_HoldSCacheNoLock(cm_scache_t *); extern void cm_HoldSCache(cm_scache_t *); *************** *** 331,337 **** extern void cm_ReleaseSCacheNoLock(cm_scache_t *); extern void cm_ReleaseSCache(cm_scache_t *); ! extern cm_scache_t *cm_FindSCache(cm_fid_t *fidp); extern cm_scache_t *cm_FindSCacheParent(cm_scache_t *); --- 353,359 ---- extern void cm_ReleaseSCacheNoLock(cm_scache_t *); extern void cm_ReleaseSCache(cm_scache_t *); ! #endif extern cm_scache_t *cm_FindSCache(cm_fid_t *fidp); extern cm_scache_t *cm_FindSCacheParent(cm_scache_t *); *************** *** 354,357 **** --- 376,380 ---- extern long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags); + extern void cm_RemoveSCacheFromHashTable(cm_scache_t *scp); #endif /* __CM_SCACHE_H_ENV__ */ Index: openafs/src/WINNT/afsd/cm_utils.c diff -c openafs/src/WINNT/afsd/cm_utils.c:1.11.4.2 openafs/src/WINNT/afsd/cm_utils.c:1.11.4.3 *** openafs/src/WINNT/afsd/cm_utils.c:1.11.4.2 Sat Jun 24 16:41:54 2006 --- openafs/src/WINNT/afsd/cm_utils.c Thu Oct 5 16:30:39 2006 *************** *** 261,273 **** || error == 122 /* EDQUOT on Linux */ || error == 1133) /* EDQUOT on Irix */ error = CM_ERROR_QUOTA; ! else if (error == VNOVNODE) { ! #ifdef COMMENT error = CM_ERROR_BADFD; ! #else ! error = CM_ERROR_RETRY; ! #endif ! } else if (error == 21) return CM_ERROR_ISDIR; return error; } --- 261,269 ---- || error == 122 /* EDQUOT on Linux */ || error == 1133) /* EDQUOT on Irix */ error = CM_ERROR_QUOTA; ! else if (error == VNOVNODE) error = CM_ERROR_BADFD; ! else if (error == 21) return CM_ERROR_ISDIR; return error; } Index: openafs/src/WINNT/afsd/cm_vnodeops.c diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.11 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.17 *** openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.11 Wed Sep 6 13:21:19 2006 --- openafs/src/WINNT/afsd/cm_vnodeops.c Mon Oct 16 20:32:57 2006 *************** *** 452,459 **** /* First check permissions */ lock_ObtainMutex(&dscp->mx); code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_DELETE, ! CM_SCACHESYNC_GETSTATUS ! | CM_SCACHESYNC_NEEDCALLBACK); lock_ReleaseMutex(&dscp->mx); if (code) return code; --- 452,459 ---- /* First check permissions */ lock_ObtainMutex(&dscp->mx); code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_DELETE, ! CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); ! cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); lock_ReleaseMutex(&dscp->mx); if (code) return code; *************** *** 489,494 **** --- 489,495 ---- lock_ReleaseMutex(&scp->mx); lock_ObtainMutex(&bufferp->mx); lock_ObtainMutex(&scp->mx); + cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ | CM_SCACHESYNC_BUFLOCKED); if (code) break; } *************** *** 695,700 **** --- 696,702 ---- lock_ReleaseMutex(&scp->mx); break; } + cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ | CM_SCACHESYNC_BUFLOCKED); if (cm_HaveBuffer(scp, bufferp, 1)) { lock_ReleaseMutex(&scp->mx); *************** *** 913,918 **** --- 915,922 ---- if (code) { goto done; } + cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); + if (cm_HaveBuffer(scp, bufp, 0)) break; *************** *** 1187,1192 **** --- 1191,1197 ---- cm_ReleaseSCache(tscp); return code; } + cm_SyncOpDone(tscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); /* tscp is now locked */ if (!(flags & CM_FLAG_NOMOUNTCHASE) *************** *** 1253,1266 **** --- 1258,1281 ---- return 1; } + #ifdef DEBUG_REFCOUNT + long cm_LookupDbg(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, + cm_req_t *reqp, cm_scache_t **outpScpp, char * file, long line) + #else long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp) + #endif { long code; char tname[256]; int sysNameIndex = 0; cm_scache_t *scp = NULL; + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_Lookup dscp 0x%p ref %d", file, line, dscp, dscp->refCount, file, line); + osi_Log2(afsd_logp, "cm_Lookup dscp 0x%p ref %d", dscp, dscp->refCount); + #endif + if ( stricmp(namep,SMB_IOCTL_FILENAME_NOSLASH) == 0 ) { if (flags & CM_FLAG_CHECKPATH) return CM_ERROR_NOSUCHPATH; *************** *** 1272,1277 **** --- 1287,1297 ---- code = cm_ExpandSysName(namep, tname, sizeof(tname), sysNameIndex); if (code > 0) { code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp); + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_LookupInternal (1) code 0x%x dscp 0x%p ref %d scp 0x%p ref %d", file, line, code, dscp, dscp->refCount, scp, scp ? scp->refCount : 0); + osi_Log3(afsd_logp, "cm_LookupInternal (1) code 0x%x dscp 0x%p scp 0x%p", code, dscp, scp); + #endif + if (code == 0) { *outpScpp = scp; return 0; *************** *** 1281,1287 **** scp = NULL; } } else { ! return cm_LookupInternal(dscp, namep, flags, userp, reqp, outpScpp); } } --- 1301,1313 ---- scp = NULL; } } else { ! code = cm_LookupInternal(dscp, namep, flags, userp, reqp, &scp); ! #ifdef DEBUG_REFCOUNT ! afsi_log("%s:%d cm_LookupInternal (2) code 0x%x dscp 0x%p ref %d scp 0x%p ref %d", file, line, code, dscp, dscp->refCount, scp, scp ? scp->refCount : 0); ! osi_Log3(afsd_logp, "cm_LookupInternal (2) code 0x%x dscp 0x%p scp 0x%p", code, dscp, scp); ! #endif ! *outpScpp = scp; ! return code; } } *************** *** 1385,1390 **** --- 1411,1418 ---- buf_Release(bufp); return code; } + cm_SyncOpDone(linkScp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); + if (cm_HaveBuffer(linkScp, bufp, 0)) break; *************** *** 1510,1518 **** lock_ReleaseMutex(&linkScp->mx); return code; } ! long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp) { long code; char *tp; /* ptr moving through input buffer */ --- 1538,1551 ---- lock_ReleaseMutex(&linkScp->mx); return code; } ! #ifdef DEBUG_REFCOUNT ! long cm_NameIDbg(cm_scache_t *rootSCachep, char *pathp, long flags, ! cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp, ! char * file, long line) ! #else long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp) + #endif { long code; char *tp; /* ptr moving through input buffer */ *************** *** 1533,1538 **** --- 1566,1578 ---- int extraFlag; /* avoid chasing mt pts for dir cmd */ int phase = 1; /* 1 = tidPathp, 2 = pathp */ + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_NameI rootscp 0x%p ref %d", file, line, rootSCachep, rootSCachep->refCount); + osi_Log4(afsd_logp,"cm_NameI rootscp 0x%p path %s tidpath %s flags 0x%x", + rootSCachep, pathp ? pathp : "", tidPathp ? tidPathp : "", + flags); + #endif + tp = tidPathp; if (tp == NULL) { tp = pathp; *************** *** 1548,1553 **** --- 1588,1594 ---- symlinkCount = 0; dirScp = NULL; + while (1) { tc = *tp++; *************** *** 1601,1610 **** cm_ReleaseSCache(dirScp); if (psp) cm_FreeSpace(psp); ! if (code == CM_ERROR_NOSUCHFILE && tscp->fileType == CM_SCACHETYPE_SYMLINK) return CM_ERROR_NOSUCHPATH; ! else return code; } haveComponent = 0; /* component done */ if (dirScp) --- 1642,1654 ---- cm_ReleaseSCache(dirScp); if (psp) cm_FreeSpace(psp); ! if (code == CM_ERROR_NOSUCHFILE && tscp->fileType == CM_SCACHETYPE_SYMLINK) { ! osi_Log0(afsd_logp,"cm_NameI code CM_ERROR_NOSUCHPATH"); return CM_ERROR_NOSUCHPATH; ! } else { ! osi_Log1(afsd_logp,"cm_NameI code 0x%x", code); return code; + } } haveComponent = 0; /* component done */ if (dirScp) *************** *** 1638,1643 **** --- 1682,1689 ---- } break; } + cm_SyncOpDone(tscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (tscp->fileType == CM_SCACHETYPE_SYMLINK) { /* this is a symlink; assemble a new buffer */ lock_ReleaseMutex(&tscp->mx); *************** *** 1650,1655 **** --- 1696,1702 ---- } if (psp) cm_FreeSpace(psp); + osi_Log0(afsd_logp,"cm_NameI code CM_ERROR_TOO_MANY_SYMLINKS"); return CM_ERROR_TOO_MANY_SYMLINKS; } if (tc == 0) *************** *** 1733,1738 **** --- 1780,1790 ---- *outScpp = tscp; else if (tscp) cm_ReleaseSCache(tscp); + + #ifdef DEBUG_REFCOUNT + afsi_log("%s:%d cm_NameI code 0x%x outScpp 0x%p ref %d", file, line, code, *outScpp, (*outScpp)->refCount); + #endif + osi_Log2(afsd_logp,"cm_NameI code 0x%x outScpp 0x%p", code, *outScpp); return code; } *************** *** 2107,2113 **** CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) goto done; ! if (scp->fileType != CM_SCACHETYPE_FILE) { code = CM_ERROR_ISDIR; goto done; --- 2159,2166 ---- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) goto done; ! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! if (scp->fileType != CM_SCACHETYPE_FILE) { code = CM_ERROR_ISDIR; goto done; *************** *** 2166,2171 **** --- 2219,2228 ---- /* done successfully */ code = 0; + cm_SyncOpDone(scp, NULL, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE); + done: lock_ReleaseMutex(&scp->mx); lock_ReleaseWrite(&scp->bufCreateLock); *************** *** 2178,2184 **** cm_req_t *reqp) { long code; - int flags; AFSFetchStatus afsOutStatus; AFSVolSync volSync; cm_conn_t *connp; --- 2235,2240 ---- *************** *** 2190,2200 **** if (attrp->mask & CM_ATTRMASK_LENGTH) return cm_SetLength(scp, &attrp->length, userp, reqp); - flags = CM_SCACHESYNC_STORESTATUS; - lock_ObtainMutex(&scp->mx); /* otherwise, we have to make an RPC to get the status */ code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS); /* make the attr structure */ cm_StatusFromAttr(&afsInStatus, scp, attrp); --- 2246,2258 ---- if (attrp->mask & CM_ATTRMASK_LENGTH) return cm_SetLength(scp, &attrp->length, userp, reqp); lock_ObtainMutex(&scp->mx); /* otherwise, we have to make an RPC to get the status */ code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS); + if (code) { + lock_ReleaseMutex(&scp->mx); + return code; + } /* make the attr structure */ cm_StatusFromAttr(&afsInStatus, scp, attrp); *************** *** 2202,2211 **** tfid.Volume = scp->fid.volume; tfid.Vnode = scp->fid.vnode; tfid.Unique = scp->fid.unique; ! ! lock_ReleaseMutex(&scp->mx); ! if (code) ! return code; /* now make the RPC */ osi_Log1(afsd_logp, "CALL StoreStatus scp 0x%p", scp); --- 2260,2266 ---- tfid.Volume = scp->fid.volume; tfid.Vnode = scp->fid.vnode; tfid.Unique = scp->fid.unique; ! lock_ReleaseMutex(&scp->mx); /* now make the RPC */ osi_Log1(afsd_logp, "CALL StoreStatus scp 0x%p", scp); *************** *** 2774,2780 **** lock_ReleaseMutex(&newDscp->mx); if (code) { /* cleanup first one */ ! lock_ObtainMutex(&newDscp->mx); cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA); lock_ReleaseMutex(&oldDscp->mx); --- 2829,2835 ---- lock_ReleaseMutex(&newDscp->mx); if (code) { /* cleanup first one */ ! lock_ObtainMutex(&oldDscp->mx); cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA); lock_ReleaseMutex(&oldDscp->mx); *************** *** 3513,3518 **** --- 3568,3575 ---- osi_Log0(afsd_logp, "cm_LockCheckPerms user is creator but has no INSERT bits for scp"); } + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + osi_Log1(afsd_logp, "cm_LockCheckPerms returning code %d", code); return code; Index: openafs/src/WINNT/afsd/cm_vnodeops.h diff -c openafs/src/WINNT/afsd/cm_vnodeops.h:1.14.4.1 openafs/src/WINNT/afsd/cm_vnodeops.h:1.14.4.2 *** openafs/src/WINNT/afsd/cm_vnodeops.h:1.14.4.1 Tue Jun 27 23:24:05 2006 --- openafs/src/WINNT/afsd/cm_vnodeops.h Mon Oct 16 20:32:57 2006 *************** *** 65,76 **** extern long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp); extern long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp); - extern long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp); extern long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, cm_req_t *reqp, --- 65,87 ---- extern long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp); + #ifdef DEBUG_REFCOUNT + extern long cm_NameIDbg(cm_scache_t *rootSCachep, char *pathp, long flags, + cm_user_t *userp, char *tidPathp, cm_req_t *reqp, + cm_scache_t **outScpp, char *, long); + + extern long cm_LookupDbg(cm_scache_t *dscp, char *namep, long flags, + cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp, char *, long); + + #define cm_Lookup(a,b,c,d,e,f) cm_LookupDbg(a,b,c,d,e,f,__FILE__,__LINE__) + #define cm_NameI(a,b,c,d,e,f,g) cm_NameIDbg(a,b,c,d,e,f,g,__FILE__,__LINE__) + #else extern long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp); extern long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp); + #endif extern long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, cm_req_t *reqp, Index: openafs/src/WINNT/afsd/rawops.c diff -c openafs/src/WINNT/afsd/rawops.c:1.2 openafs/src/WINNT/afsd/rawops.c:1.2.4.1 *** openafs/src/WINNT/afsd/rawops.c:1.2 Fri Jun 17 12:08:01 2005 --- openafs/src/WINNT/afsd/rawops.c Mon Oct 2 23:23:21 2006 *************** *** 41,46 **** --- 41,48 ---- if (code) goto done; + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + /* now we have the entry locked, look up the length */ fileLength = scp->length; *************** *** 98,103 **** --- 100,107 ---- if (code) goto done; + cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); + if (cm_HaveBuffer(scp, bufferp, 0)) break; /* otherwise, load the buffer and try again */ *************** *** 177,182 **** --- 181,188 ---- if (code) goto done; + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_GETSTATUS); + #if 0 /* make sure we have a writable FD */ if (!(fidp->flags & SMB_FID_OPENWRITE)) { *************** *** 260,266 **** | CM_SCACHESYNC_BUFLOCKED); if (code) goto done; ! /* If we're overwriting the entire buffer, or * if we're writing at or past EOF, mark the * buffer as current so we don't call --- 266,277 ---- | CM_SCACHESYNC_BUFLOCKED); if (code) goto done; ! ! cm_SyncOpDone(scp, bufferp, ! CM_SCACHESYNC_NEEDCALLBACK ! | CM_SCACHESYNC_WRITE ! | CM_SCACHESYNC_BUFLOCKED); ! /* If we're overwriting the entire buffer, or * if we're writing at or past EOF, mark the * buffer as current so we don't call *************** *** 363,370 **** lock_ReleaseMutex(&scp->mx); cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, writeBackOffset.HighPart, cm_chunkSize, 0, userp); ! } return code; } --- 374,382 ---- lock_ReleaseMutex(&scp->mx); cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, writeBackOffset.HighPart, cm_chunkSize, 0, userp); ! } + /* cm_SyncOpDone is called when cm_BkgStore completes */ return code; } Index: openafs/src/WINNT/afsd/smb.c diff -c openafs/src/WINNT/afsd/smb.c:1.118.2.17 openafs/src/WINNT/afsd/smb.c:1.118.2.23 *** openafs/src/WINNT/afsd/smb.c:1.118.2.17 Thu Aug 3 19:30:28 2006 --- openafs/src/WINNT/afsd/smb.c Sat Oct 7 18:33:29 2006 *************** *** 216,222 **** void smb_SetRequestStartTime() { ! time_t * tp = malloc(sizeof(time_t)); if (tp) { *tp = osi_Time(); --- 216,224 ---- void smb_SetRequestStartTime() { ! time_t * tp = TlsGetValue(smb_TlsRequestSlot); ! if (!tp) ! tp = malloc(sizeof(time_t)); if (tp) { *tp = osi_Time(); *************** *** 892,897 **** --- 894,900 ---- { smb_vc_t *vcp; + lock_ObtainWrite(&smb_globalLock); /* for numVCs */ lock_ObtainWrite(&smb_rctLock); for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp) { if (vcp->magic != SMB_VC_MAGIC) *************** *** 907,915 **** if (!vcp && (flags & SMB_FLAG_CREATE)) { vcp = malloc(sizeof(*vcp)); memset(vcp, 0, sizeof(*vcp)); - lock_ObtainWrite(&smb_globalLock); vcp->vcID = ++numVCs; - lock_ReleaseWrite(&smb_globalLock); vcp->magic = SMB_VC_MAGIC; vcp->refCount = 2; /* smb_allVCsp and caller */ vcp->tidCounter = 1; --- 910,916 ---- *************** *** 952,964 **** memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH); if (numVCs >= CM_SESSION_RESERVED) { - lock_ObtainWrite(&smb_globalLock); numVCs = 0; - lock_ReleaseWrite(&smb_globalLock); osi_Log0(smb_logp, "WARNING: numVCs wrapping around"); } } lock_ReleaseWrite(&smb_rctLock); return vcp; } --- 953,964 ---- memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH); if (numVCs >= CM_SESSION_RESERVED) { numVCs = 0; osi_Log0(smb_logp, "WARNING: numVCs wrapping around"); } } lock_ReleaseWrite(&smb_rctLock); + lock_ReleaseWrite(&smb_globalLock); return vcp; } *************** *** 1147,1153 **** --- 1147,1162 ---- smb_tid_t *tidp; lock_ObtainWrite(&smb_rctLock); + retry: for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) { + if (tidp->refCount == 0 && tidp->delete) { + tidp->refCount++; + lock_ReleaseWrite(&smb_rctLock); + smb_ReleaseTID(tidp); + lock_ObtainWrite(&smb_rctLock); + goto retry; + } + if (tid == tidp->tid) { tidp->refCount++; break; *************** *** 1452,1457 **** --- 1461,1473 ---- retry: for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) { + if (fidp->refCount == 0 && fidp->delete) { + fidp->refCount++; + lock_ReleaseWrite(&smb_rctLock); + smb_ReleaseFID(fidp); + lock_ObtainWrite(&smb_rctLock); + goto retry; + } if (fid == fidp->fid) { if (newFid) { fid++; *************** *** 1545,1551 **** --- 1561,1573 ---- vcp = fidp->vcp; fidp->vcp = NULL; scp = fidp->scp; /* release after lock is released */ + if (scp) { + lock_ObtainMutex(&scp->mx); + scp->flags &= ~CM_SCACHEFLAG_SMB_FID; + lock_ReleaseMutex(&scp->mx); + osi_Log2(afsd_logp,"smb_ReleaseFID fidp 0x%p scp 0x%p", fidp, scp); fidp->scp = NULL; + } userp = fidp->userp; fidp->userp = NULL; *************** *** 2007,2012 **** --- 2029,2035 ---- lock_ReleaseMutex(&dsp->mx); lock_FinalizeMutex(&dsp->mx); scp = dsp->scp; + osi_Log2(afsd_logp,"smb_ReleaseDirSearch dsp 0x%p scp 0x%p", dsp, scp); free(dsp); } else { lock_ReleaseMutex(&dsp->mx); *************** *** 3602,3607 **** --- 3625,3631 ---- wlRequest); scp = wlRequest->scp; + osi_Log2(afsd_logp,"smb_WaitingLocksDaemon wlRequest 0x%p scp 0x%p", wlRequest, scp); cm_InitReq(&req); *************** *** 3963,3968 **** --- 3987,3994 ---- continue; } + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + attr = smb_Attributes(scp); /* check hidden attribute (the flag is only ON when dot file hiding is on ) */ if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE) *************** *** 4136,4141 **** --- 4162,4168 ---- lock_ObtainMutex(&dsp->mx); if (dsp->scp) { scp = dsp->scp; + osi_Log2(afsd_logp,"smb_ReceiveCoreSearchDir (1) dsp 0x%p scp 0x%p", dsp, scp); cm_HoldSCache(scp); code = 0; } else { *************** *** 4167,4172 **** --- 4194,4200 ---- #endif /* DFS_SUPPORT */ dsp->scp = scp; + osi_Log2(afsd_logp,"smb_ReceiveCoreSearchDir (2) dsp 0x%p scp 0x%p", dsp, scp); /* we need one hold for the entry we just stored into, * and one for our own processing. When we're done with this * function, we'll drop the one for our own processing. *************** *** 4211,4216 **** --- 4239,4246 ---- return code; } + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + dirLength = scp->length; bufferp = NULL; bufferOffset.LowPart = bufferOffset.HighPart = 0; *************** *** 4317,4322 **** --- 4347,4354 ---- break; } + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); + if (cm_HaveBuffer(scp, bufferp, 0)) { osi_Log2(smb_logp, "SMB search dir !HaveBuffer scp %x bufferp %x", scp, bufferp); break; *************** *** 4492,4498 **** /* release the mutex */ lock_ReleaseMutex(&scp->mx); ! if (bufferp) buf_Release(bufferp); /* apply and free last set of patches; if not doing a star match, this * will be empty, but better safe (and freeing everything) than sorry. --- 4524,4533 ---- /* release the mutex */ lock_ReleaseMutex(&scp->mx); ! if (bufferp) { ! buf_Release(bufferp); ! bufferp = NULL; ! } /* apply and free last set of patches; if not doing a star match, this * will be empty, but better safe (and freeing everything) than sorry. *************** *** 4597,4607 **** lock_ObtainMutex(&newScp->mx); code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); ! if (code && code != CM_ERROR_NOACCESS) { ! lock_ReleaseMutex(&newScp->mx); ! cm_ReleaseSCache(newScp); ! cm_ReleaseUser(userp); ! return code; } attrs = smb_Attributes(newScp); --- 4632,4646 ---- lock_ObtainMutex(&newScp->mx); code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); ! if (code) { ! if (code != CM_ERROR_NOACCESS) { ! lock_ReleaseMutex(&newScp->mx); ! cm_ReleaseSCache(newScp); ! cm_ReleaseUser(userp); ! return code; ! } ! } else { ! cm_SyncOpDone(newScp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); } attrs = smb_Attributes(newScp); *************** *** 4690,4695 **** --- 4729,4736 ---- return code; } + cm_SyncOpDone(newScp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + /* Check for RO volume */ if (newScp->flags & CM_SCACHEFLAG_RO) { lock_ReleaseMutex(&newScp->mx); *************** *** 4809,4817 **** code = CM_ERROR_NOSUCHFILE; else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { cm_buf_t *bp = buf_Find(dscp, &hzero); ! if (bp) buf_Release(bp); ! else code = CM_ERROR_NOSUCHFILE; } cm_ReleaseSCache(dscp); --- 4850,4859 ---- code = CM_ERROR_NOSUCHFILE; else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { cm_buf_t *bp = buf_Find(dscp, &hzero); ! if (bp) { buf_Release(bp); ! bp = NULL; ! } else code = CM_ERROR_NOSUCHFILE; } cm_ReleaseSCache(dscp); *************** *** 4852,4857 **** --- 4894,4901 ---- return code; } + cm_SyncOpDone(newScp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + #ifdef undef /* use smb_Attributes instead. Also the fact that a file is * in a readonly volume doesn't mean it shojuld be marked as RO *************** *** 5016,5021 **** --- 5060,5070 ---- /* save a pointer to the vnode */ fidp->scp = scp; + osi_Log2(afsd_logp,"smb_ReceiveCoreOpen fidp 0x%p scp 0x%p", fidp, scp); + lock_ObtainMutex(&scp->mx); + scp->flags |= CM_SCACHEFLAG_SMB_FID; + lock_ReleaseMutex(&scp->mx); + /* and the user */ cm_HoldUser(userp); fidp->userp = userp; *************** *** 5093,5099 **** code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, ! FILE_NOTIFY_CHANGE_FILE_NAME, dscp, dep->name, NULL, TRUE); if (code == 0) { rockp->any = 1; --- 5142,5148 ---- code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, ! FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, dep->name, NULL, TRUE); if (code == 0) { rockp->any = 1; *************** *** 5651,5657 **** code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, ! FILE_NOTIFY_CHANGE_DIR_NAME, dscp, dep->name, NULL, TRUE); if (code == 0) rockp->any = 1; --- 5700,5706 ---- code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, ! FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION, dscp, dep->name, NULL, TRUE); if (code == 0) rockp->any = 1; *************** *** 5846,5857 **** afs_uint32 dosTime) { long code = 0; cm_req_t req; ! cm_scache_t *dscp = fidp->NTopen_dscp; ! char *pathp = fidp->NTopen_pathp; ! cm_scache_t * scp; ! osi_Log3(smb_logp, "smb_CloseFID Closing fidp 0x%x (fid=%d vcp=0x%x)", ! fidp, fidp->fid, vcp); if (!userp) { lock_ObtainMutex(&fidp->mx); --- 5895,5908 ---- afs_uint32 dosTime) { long code = 0; cm_req_t req; ! cm_scache_t *dscp = NULL; ! char *pathp = NULL; ! cm_scache_t * scp = NULL; ! int deleted = 0; ! int nullcreator = 0; ! osi_Log4(smb_logp, "smb_CloseFID Closing fidp 0x%x (fid=%d scp=0x%x vcp=0x%x)", ! fidp, fidp->fid, scp, vcp); if (!userp) { lock_ObtainMutex(&fidp->mx); *************** *** 5878,5883 **** --- 5929,5948 ---- lock_ReleaseWrite(&smb_rctLock); lock_ObtainMutex(&fidp->mx); + if (fidp->NTopen_dscp) { + dscp = fidp->NTopen_dscp; + cm_HoldSCache(dscp); + } + + if (fidp->NTopen_pathp) { + pathp = strdup(fidp->NTopen_pathp); + } + + if (fidp->scp) { + scp = fidp->scp; + cm_HoldSCache(scp); + } + /* Don't jump the gun on an async raw write */ while (fidp->raw_writers) { lock_ReleaseMutex(&fidp->mx); *************** *** 5885,5894 **** lock_ObtainMutex(&fidp->mx); } - scp = fidp->scp; - if (scp) - cm_HoldSCache(scp); - /* watch for ioctl closes, and read-only opens */ if (scp != NULL && (fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE)) --- 5950,5955 ---- *************** *** 5932,5938 **** cm_UnlockByKey(scp, key, CM_UNLOCK_BY_FID, userp, &req); ! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK); post_syncopdone: --- 5993,5999 ---- cm_UnlockByKey(scp, key, CM_UNLOCK_BY_FID, userp, &req); ! cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK); post_syncopdone: *************** *** 5947,5962 **** smb_FullName(dscp, scp, pathp, &fullPathp, userp, &req); if (scp->fileType == CM_SCACHETYPE_DIRECTORY) { code = cm_RemoveDir(dscp, fullPathp, userp, &req); ! if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) ! smb_NotifyChange(FILE_ACTION_REMOVED, ! FILE_NOTIFY_CHANGE_DIR_NAME, ! dscp, fullPathp, NULL, TRUE); } else { code = cm_Unlink(dscp, fullPathp, userp, &req); ! if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) ! smb_NotifyChange(FILE_ACTION_REMOVED, ! FILE_NOTIFY_CHANGE_FILE_NAME, ! dscp, fullPathp, NULL, TRUE); } free(fullPathp); lock_ObtainMutex(&fidp->mx); --- 6008,6029 ---- smb_FullName(dscp, scp, pathp, &fullPathp, userp, &req); if (scp->fileType == CM_SCACHETYPE_DIRECTORY) { code = cm_RemoveDir(dscp, fullPathp, userp, &req); ! if (code == 0) { ! deleted = 1; ! if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) ! smb_NotifyChange(FILE_ACTION_REMOVED, ! FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION, ! dscp, fullPathp, NULL, TRUE); ! } } else { code = cm_Unlink(dscp, fullPathp, userp, &req); ! if (code == 0) { ! deleted = 1; ! if (dscp->flags & CM_SCACHEFLAG_ANYWATCH) ! smb_NotifyChange(FILE_A