From: Jeffrey Altman Date: Wed, 30 Mar 2005 21:50:15 +0000 (+0000) Subject: STABLE14-windows-stress-test-fixes-20050330 X-Git-Tag: openafs-devel-1_3_81~30 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=3ed69d2cbd56f727936adeebc5e094f7f913d6af;p=packages%2Fo%2Fopenafs.git STABLE14-windows-stress-test-fixes-20050330 Ran more stress tests against 1.3.80b on a dual processor machine and found a number of additional errors which could be fixed. cm_callback.c: correct the refCount handling of server lists when processing registering callbacks on the scache entry cm_conn.c: cm_Analyze was not handling the CM_ERROR_NOSUCHVOLUME case. In this case force a retry and Force Update the Volume info cm_dcache.c; do not hold mx locks around calls to rx_NewCall(). That is why we have reference counting on the rx_connection objects. cm_ioctl.c: replace references to afsdcell.ini with CellServDB cm_utils.c: formatting cm_vnodeops.c: improve the logging and add a missing call to cm_EndCallbackGrantingCall() cm_volume.c: allows cm_volume_t objects to be reused if their ref count is 0 and we have hit the maximum number allowed. smb.c: improve the logging and the handling of dead_vcp references. If all of the SMB sessions and NCBs are in use, return BUSY to the CIFS client. smb3.c: convert constants to preprocessor symbols (cherry picked from commit b9bf7ee01acc7f2646fbc6e09c1ca8d41cc59d55) --- diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 1108c16e3..19606a058 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -1517,13 +1517,20 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, if (scp) { if (scp->cbServerp != cbrp->serverp) { serverp = scp->cbServerp; + if (!freeFlag) + cm_GetServer(cbrp->serverp); + scp->cbServerp = cbrp->serverp; + } else { + if (freeFlag) + serverp = cbrp->serverp; } - scp->cbServerp = cbrp->serverp; scp->cbExpires = cbrp->startTime + cbp->ExpirationTime; } else { - serverp = cbrp->serverp; + if (freeFlag) + serverp = cbrp->serverp; } - cbrp->serverp = NULL; + if (freeFlag) + cbrp->serverp = NULL; } /* a callback was actually revoked during our granting call, so diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 11611ef4d..2a4080df8 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -99,16 +99,16 @@ void cm_InitReq(cm_req_t *reqp) static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp, struct cm_req *reqp, cm_serverRef_t ***serversppp) { - long code; + long code; cm_volume_t *volp = NULL; cm_cell_t *cellp = NULL; if (!fidp) { - *serversppp = NULL; - return 0; - } + *serversppp = NULL; + return 0; + } - cellp = cm_FindCellByID(fidp->cell); + cellp = cm_FindCellByID(fidp->cell); if (!cellp) return CM_ERROR_NOSUCHCELL; code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp); @@ -117,7 +117,7 @@ static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp, *serversppp = cm_GetVolServers(volp, fidp->volume); cm_PutVolume(volp); - return 0; + return 0; } /* @@ -204,7 +204,24 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, } } - /* if all servers are offline, mark them non-busy and start over */ + /* if there is nosuchvolume, then we have a situation in which a + * previously known volume no longer has a set of servers + * associated with it. Either the volume has moved or + * the volume has been deleted. Try to find a new server list + * until the timeout period expires. + */ + else if (errorCode == CM_ERROR_NOSUCHVOLUME) { + if (timeLeft > 7) { + osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_NOSUCHVOLUME."); + thrd_Sleep(5000); + + retry = 1; + + if (fidp != NULL) /* Not a VLDB call */ + cm_ForceUpdateVolume(fidp, userp, reqp); + } + } + else if (errorCode == CM_ERROR_ALLOFFLINE) { if (timeLeft > 7) { osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLOFFLINE."); diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index f0153eeef..de221e462 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -55,7 +55,7 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, osi_hyper_t thyper; AFSVolSync volSync; AFSFid tfid; - struct rx_call *callp; + struct rx_call *oldCallp, *callp; osi_queueData_t *qdp; cm_buf_t *bufp; long wbytes; @@ -129,11 +129,11 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, if (code) continue; - lock_ObtainMutex(&connp->mx); - callp = rx_NewCall(connp->callp); - lock_ReleaseMutex(&connp->mx); + oldCallp = cm_GetRxConn(connp); + callp = rx_NewCall(oldCallp); + rx_PutConnection(oldCallp); - osi_Log3(afsd_logp, "CALL StoreData vp %x, off 0x%x, size 0x%x", + osi_Log3(afsd_logp, "CALL StoreData scp 0x%x, off 0x%x, size 0x%x", (long) scp, biod.offset.LowPart, nbytes); code = StartRXAFS_StoreData(callp, &tfid, &inStatus, @@ -175,11 +175,15 @@ long cm_BufWrite(void *vfidp, osi_hyper_t *offsetp, long length, long flags, osi_Log1(afsd_logp, "EndRXAFS_StoreData failed (%lX)",code); } code = rx_EndCall(callp, code); - osi_Log0(afsd_logp, "CALL StoreData DONE"); } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); + if (code) + osi_Log1(afsd_logp, "CALL StoreData FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL StoreData SUCCESS"); + /* now, clean up our state */ lock_ObtainMutex(&scp->mx); @@ -234,7 +238,7 @@ long cm_StoreMini(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) long code; long truncPos; cm_conn_t *connp; - struct rx_call *callp; + struct rx_call *oldCallp, *callp; /* Serialize StoreData RPC's; for rationale see cm_scache.c */ (void) cm_SyncOp(scp, NULL, userp, reqp, 0, @@ -262,9 +266,9 @@ long cm_StoreMini(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) if (code) continue; - lock_ObtainMutex(&connp->mx); - callp = rx_NewCall(connp->callp); - lock_ReleaseMutex(&connp->mx); + oldCallp = cm_GetRxConn(connp); + callp = rx_NewCall(oldCallp); + rx_PutConnection(oldCallp); code = StartRXAFS_StoreData(callp, &tfid, &inStatus, 0, 0, truncPos); @@ -1116,7 +1120,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, cm_buf_t *tbufp; /* buf we're filling */ osi_queueData_t *qdp; /* q element we're scanning */ AFSFid tfid; - struct rx_call *callp; + struct rx_call *oldCallp, *callp; cm_bulkIO_t biod; /* bulk IO descriptor */ cm_conn_t *connp; int getroot; @@ -1247,10 +1251,10 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, code = cm_Conn(&scp->fid, up, reqp, &connp); if (code) continue; - - lock_ObtainMutex(&connp->mx); - callp = rx_NewCall(connp->callp); - lock_ReleaseMutex(&connp->mx); + + oldCallp = cm_GetRxConn(connp); + callp = rx_NewCall(oldCallp); + rx_PutConnection(oldCallp); osi_Log3(afsd_logp, "CALL FetchData vp %x, off 0x%x, size 0x%x", (long) scp, biod.offset.LowPart, biod.length); diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index fbbe014f3..47a7094bb 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -1114,7 +1114,7 @@ extern long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *namep); long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp) { - /* NT cache manager will read cell information from afsdcell.ini each time + /* NT cache manager will read cell information from CellServDB each time * cell is accessed. So, this call is necessary only if list of server for a cell * changes (or IP addresses of cell servers changes). * All that needs to be done is to refresh server information for all cells that diff --git a/src/WINNT/afsd/cm_utils.c b/src/WINNT/afsd/cm_utils.c index 525791701..3acf3679a 100644 --- a/src/WINNT/afsd/cm_utils.c +++ b/src/WINNT/afsd/cm_utils.c @@ -80,36 +80,37 @@ long cm_MapRPCError(long error, cm_req_t *reqp) long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp) { - if (error == 0) return 0; - - /* If we had to stop retrying, report our saved error code. */ - if (reqp && error == CM_ERROR_TIMEDOUT) { - if (reqp->accessError) - return reqp->accessError; - if (reqp->volumeError) - return reqp->volumeError; - if (reqp->rpcError) - return reqp->rpcError; - return error; - } + if (error == 0) + return 0; - if (error < 0) - error = CM_ERROR_TIMEDOUT; - else if (error == 30) - error = CM_ERROR_READONLY; - else if (error == 20) - error = CM_ERROR_NOTDIR; - else if (error == 13) - error = CM_ERROR_NOACCESS; - else if (error == 2) - error = CM_ERROR_NOSUCHFILE; - else if (error == 17 /* AIX */ - || error == 66 /* SunOS 4, Digital UNIX */ - || error == 93 /* Solaris 2, IRIX */ - || error == 247) /* HP/UX */ - error = CM_ERROR_NOTEMPTY; + /* If we had to stop retrying, report our saved error code. */ + if (reqp && error == CM_ERROR_TIMEDOUT) { + if (reqp->accessError) + return reqp->accessError; + if (reqp->volumeError) + return reqp->volumeError; + if (reqp->rpcError) + return reqp->rpcError; return error; -} + } + + if (error < 0) + error = CM_ERROR_TIMEDOUT; + else if (error == 30) + error = CM_ERROR_READONLY; + else if (error == 20) + error = CM_ERROR_NOTDIR; + else if (error == 13) + error = CM_ERROR_NOACCESS; + else if (error == 2) + error = CM_ERROR_NOSUCHFILE; + else if (error == 17 /* AIX */ + || error == 66 /* SunOS 4, Digital UNIX */ + || error == 93 /* Solaris 2, IRIX */ + || error == 247) /* HP/UX */ + error = CM_ERROR_NOTEMPTY; + return error; +} long cm_MapVLRPCError(long error, cm_req_t *reqp) { diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 7361cb51f..58eaa5730 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1196,6 +1196,8 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp) afsFid.Volume = dscp->fid.volume; afsFid.Vnode = dscp->fid.vnode; afsFid.Unique = dscp->fid.unique; + + osi_Log1(afsd_logp, "CALL RemoveFile scp 0x%x", (long) dscp); do { code = cm_Conn(&dscp->fid, userp, reqp, &connp); if (code) @@ -1209,6 +1211,11 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp) } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); + if (code) + osi_Log1(afsd_logp, "CALL RemoveFile FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL RemoveFile SUCCESS"); + lock_ObtainMutex(&dscp->mx); cm_dnlcRemove(dscp, namep); cm_SyncOpDone(dscp, NULL, sflags); @@ -1610,7 +1617,7 @@ long cm_EvaluateSymLink(cm_scache_t *dscp, cm_scache_t *linkScp, cm_space_t *spacep; cm_scache_t *newRootScp; - osi_Log1(afsd_logp, "Evaluating symlink vp %x", linkScp); + osi_Log1(afsd_logp, "Evaluating symlink scp 0x%x", linkScp); code = cm_AssembleLink(linkScp, "", &newRootScp, &spacep, userp, reqp); if (code) @@ -1775,7 +1782,8 @@ void cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, lock_ObtainMutex(&dscp->mx); /* if we failed, bail out early */ - if (code && code != CM_ERROR_STOPNOW) return; + if (code && code != CM_ERROR_STOPNOW) + return; /* otherwise, we may have one or more bulk stat's worth of stuff in bb; * make the calls to create the entries. Handle AFSCBMAX files at a @@ -1784,7 +1792,8 @@ void cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, filex = 0; while (filex < bb.counter) { filesThisCall = bb.counter - filex; - if (filesThisCall > AFSCBMAX) filesThisCall = AFSCBMAX; + if (filesThisCall > AFSCBMAX) + filesThisCall = AFSCBMAX; fidStruct.AFSCBFids_len = filesThisCall; fidStruct.AFSCBFids_val = &bb.fids[filex]; @@ -1808,16 +1817,21 @@ void cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, cm_user_t *userp, &volSync, NULL, &cbReq, code)); code = cm_MapRPCError(code, reqp); - osi_Log0(afsd_logp, "CALL BulkStatus DONE"); + if (code) + osi_Log1(afsd_logp, "CALL BulkStatus FAILURE code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL BulkStatus SUCCESS"); /* may as well quit on an error, since we're not going to do * much better on the next immediate call, either. */ - if (code) + if (code) { + cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); break; + } /* otherwise, we should do the merges */ - for(i = 0; ifid.cell; tfid.volume = bb.fids[j].Volume; @@ -2019,7 +2033,7 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, return code; /* now make the RPC */ - osi_Log1(afsd_logp, "CALL StoreStatus vp %x", (long) scp); + osi_Log1(afsd_logp, "CALL StoreStatus scp 0x%x", (long) scp); tfid.Volume = scp->fid.volume; tfid.Vnode = scp->fid.vnode; tfid.Unique = scp->fid.unique; @@ -2037,7 +2051,10 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); - osi_Log1(afsd_logp, "CALL StoreStatus DONE, code %d", code); + if (code) + osi_Log1(afsd_logp, "CALL StoreStatus FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL StoreStatus SUCCESS"); lock_ObtainMutex(&scp->mx); cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STORESTATUS); @@ -2096,6 +2113,7 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, cm_StatusFromAttr(&inStatus, NULL, attrp); /* try the RPC now */ + osi_Log1(afsd_logp, "CALL CreateFile scp 0x%x", (long) dscp); do { code = cm_Conn(&dscp->fid, userp, reqp, &connp); if (code) @@ -2116,6 +2134,11 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, &dscp->fid, &volSync, NULL, &cbReq, code)); code = cm_MapRPCError(code, reqp); + if (code) + osi_Log1(afsd_logp, "CALL CreateFile FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL CreateFile SUCCESS"); + lock_ObtainMutex(&dscp->mx); cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); if (code == 0) { @@ -2218,6 +2241,7 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, cm_StatusFromAttr(&inStatus, NULL, attrp); /* try the RPC now */ + osi_Log1(afsd_logp, "CALL MakeDir scp 0x%x", (long) dscp); do { code = cm_Conn(&dscp->fid, userp, reqp, &connp); if (code) @@ -2238,6 +2262,11 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, &dscp->fid, &volSync, NULL, &cbReq, code)); code = cm_MapRPCError(code, reqp); + if (code) + osi_Log1(afsd_logp, "CALL MakeDir FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL MakeDir SUCCESS"); + lock_ObtainMutex(&dscp->mx); cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); if (code == 0) { @@ -2302,6 +2331,8 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, if (code) return code; + /* try the RPC now */ + osi_Log1(afsd_logp, "CALL Link scp 0x%x", (long) dscp); do { code = cm_Conn(&dscp->fid, userp, reqp, &connp); if (code) continue; @@ -2318,13 +2349,18 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, code = RXAFS_Link(callp, &dirAFSFid, namep, &existingAFSFid, &newLinkStatus, &updatedDirStatus, &volSync); rx_PutConnection(callp); - osi_Log1(smb_logp," RXAFS_Link returns %d", code); + osi_Log1(smb_logp," RXAFS_Link returns 0x%x", code); } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); + if (code) + osi_Log1(afsd_logp, "CALL Link FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL Link SUCCESS"); + lock_ObtainMutex(&dscp->mx); cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); if (code == 0) { @@ -2364,6 +2400,7 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, cm_StatusFromAttr(&inStatus, NULL, attrp); /* try the RPC now */ + osi_Log1(afsd_logp, "CALL Symlink scp 0x%x", (long) dscp); do { code = cm_Conn(&dscp->fid, userp, reqp, &connp); if (code) @@ -2383,6 +2420,11 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); + if (code) + osi_Log1(afsd_logp, "CALL Symlink FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL Symlink SUCCESS"); + lock_ObtainMutex(&dscp->mx); cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); if (code == 0) { @@ -2440,6 +2482,7 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, cm_user_t *userp, didEnd = 0; /* try the RPC now */ + osi_Log1(afsd_logp, "CALL RemoveDir scp 0x%x", (long) dscp); do { code = cm_Conn(&dscp->fid, userp, reqp, &connp); if (code) @@ -2457,11 +2500,16 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, cm_user_t *userp, } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCErrorRmdir(code, reqp); - + + if (code) + osi_Log1(afsd_logp, "CALL RemoveDir FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL RemoveDir SUCCESS"); + lock_ObtainMutex(&dscp->mx); - cm_dnlcRemove(dscp, namep); cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); if (code == 0) { + cm_dnlcRemove(dscp, namep); cm_MergeStatus(dscp, &updatedDirStatus, &volSync, userp, 0); } lock_ReleaseMutex(&dscp->mx); @@ -2581,6 +2629,8 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp, didEnd = 0; /* try the RPC now */ + osi_Log2(afsd_logp, "CALL Rename old scp 0x%x new scp 0x%x", + (long) oldDscp, (long) newDscp); do { code = cm_Conn(&oldDscp->fid, userp, reqp, &connp); if (code) @@ -2604,6 +2654,11 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); + if (code) + osi_Log1(afsd_logp, "CALL Rename FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL Rename SUCCESS"); + /* update the individual stat cache entries for the directories */ lock_ObtainMutex(&oldDscp->mx); cm_SyncOpDone(oldDscp, NULL, CM_SCACHESYNC_STOREDATA); @@ -2766,6 +2821,7 @@ long cm_Unlock(cm_scache_t *scp, unsigned char LockType, tfid.Vnode = scp->fid.vnode; tfid.Unique = scp->fid.unique; lock_ReleaseMutex(&scp->mx); + osi_Log1(afsd_logp, "CALL ReleaseLock scp 0x%x", (long) scp); do { code = cm_Conn(&scp->fid, userp, reqp, &connp); if (code) @@ -2778,6 +2834,12 @@ long cm_Unlock(cm_scache_t *scp, unsigned char LockType, } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, reqp); + + if (code) + osi_Log1(afsd_logp, "CALL ReleaseLock FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL ReleaseLock SUCCESS"); + lock_ObtainMutex(&scp->mx); } @@ -2811,6 +2873,7 @@ void cm_CheckLocks() tfid.Vnode = fileLock->fid.vnode; tfid.Unique = fileLock->fid.unique; lock_ReleaseWrite(&cm_scacheLock); + osi_Log1(afsd_logp, "CALL ExtendLock lock 0x%x", (long) fileLock); do { code = cm_Conn(&fileLock->fid, fileLock->userp, &req, &connp); @@ -2826,6 +2889,11 @@ void cm_CheckLocks() &fileLock->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, &req); + if (code) + osi_Log1(afsd_logp, "CALL ExtendLock FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL ExtendLock SUCCESS"); + lock_ObtainWrite(&cm_scacheLock); } q = nq; @@ -2884,6 +2952,7 @@ long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead) tfid.Volume = oldFileLock->fid.volume; tfid.Vnode = oldFileLock->fid.vnode; tfid.Unique = oldFileLock->fid.unique; + osi_Log1(afsd_logp, "CALL SetLock lock 0x%x", (long) oldFileLock); do { code = cm_Conn(&oldFileLock->fid, oldFileLock->userp, &req, &connp); @@ -2899,6 +2968,11 @@ long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead) &oldFileLock->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCError(code, &req); + + if (code) + osi_Log1(afsd_logp, "CALL SetLock FAILURE, code 0x%x", code); + else + osi_Log0(afsd_logp, "CALL SetLock SUCCESS"); } handleCode: diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index 15dc09a78..86de5c823 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -423,20 +423,35 @@ long cm_GetVolumeByName(struct cm_cell *cellp, char *volumeNamep, /* otherwise, get from VLDB */ if (!volp) { - if ( cm_data.currentVolumes >= cm_data.maxVolumes ) + if ( cm_data.currentVolumes >= cm_data.maxVolumes ) { + for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { + if ( volp->refCount == 0 ) { + /* There is one we can re-use */ + break; + } + } osi_panic("Exceeded Max Volumes", __FILE__, __LINE__); + } - volp = &cm_data.volumeBaseAddress[cm_data.currentVolumes++]; - memset(volp, 0, sizeof(cm_volume_t)); - volp->magic = CM_VOLUME_MAGIC; + if (volp) { + volp->rwID = volp->roID = volp->bkID = 0; + volp->dotdotFid.cell = 0; + volp->dotdotFid.volume = 0; + volp->dotdotFid.unique = 0; + volp->dotdotFid.vnode = 0; + } else { + volp = &cm_data.volumeBaseAddress[cm_data.currentVolumes++]; + memset(volp, 0, sizeof(cm_volume_t)); + volp->magic = CM_VOLUME_MAGIC; + volp->nextp = cm_data.allVolumesp; + cm_data.allVolumesp = volp; + lock_InitializeMutex(&volp->mx, "cm_volume_t mutex"); + } volp->cellp = cellp; - volp->nextp = cm_data.allVolumesp; - cm_data.allVolumesp = volp; strncpy(volp->namep, volumeNamep, VL_MAXNAMELEN); volp->namep[VL_MAXNAMELEN-1] = '\0'; - lock_InitializeMutex(&volp->mx, "cm_volume_t mutex"); volp->refCount = 1; /* starts off held */ - volp->flags |= CM_VOLUMEFLAG_RESET; + volp->flags = CM_VOLUMEFLAG_RESET; } else { volp->refCount++; @@ -509,16 +524,16 @@ void cm_ForceUpdateVolume(cm_fid_t *fidp, cm_user_t *userp, cm_req_t *reqp) /* find the appropriate servers from a volume */ cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, unsigned long volume) { - cm_serverRef_t **serverspp; + cm_serverRef_t **serverspp; cm_serverRef_t *current;; lock_ObtainWrite(&cm_serverLock); - if (volume == volp->rwID) + if (volume == volp->rwID) serverspp = &volp->rwServersp; - else if (volume == volp->roID) + else if (volume == volp->roID) serverspp = &volp->roServersp; - else if (volume == volp->bkID) + else if (volume == volp->bkID) serverspp = &volp->bkServersp; else osi_panic("bad volume ID in cm_GetVolServers", __FILE__, __LINE__); @@ -533,9 +548,9 @@ cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, unsigned long volume) void cm_PutVolume(cm_volume_t *volp) { - lock_ObtainWrite(&cm_volumeLock); - osi_assert(volp->refCount-- > 0); - lock_ReleaseWrite(&cm_volumeLock); + lock_ObtainWrite(&cm_volumeLock); + osi_assert(volp->refCount-- > 0); + lock_ReleaseWrite(&cm_volumeLock); } /* return the read-only volume, if there is one, or the read-write volume if diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index bddb0df22..ebb3b088c 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -6519,11 +6519,11 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp); else { - osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn); - osi_Log4(smb_logp,"Dispatch %s vcp[%x] lana[%d] lsn[%d]",myCrt_Dispatch(inp->inCom),vcp,vcp->lana,vcp->lsn); + osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp 0x%x lana %d lsn %d",(int)vcp,vcp->lana,vcp->lsn); + osi_Log4(smb_logp,"Dispatch %s vcp 0x%x lana %d lsn %d",myCrt_Dispatch(inp->inCom),vcp,vcp->lana,vcp->lsn); code = (*(dp->procp)) (vcp, inp, outp); - osi_LogEvent("AFS Dispatch return",NULL,"Code[%d]",(code==0)?0:code-CM_ERROR_BASE); - osi_Log1(smb_logp,"Dispatch return code[%d]",(code==0)?0:code-CM_ERROR_BASE); + osi_LogEvent("AFS Dispatch return",NULL,"Code 0x%x",(code==0)?0:code-CM_ERROR_BASE); + osi_Log4(smb_logp,"Dispatch return code 0x%x vcp 0x%x lana %d lsn %d",(code==0)?0:code-CM_ERROR_BASE,vcp,vcp->lana,vcp->lsn); #ifdef LOG_PACKET if ( code == CM_ERROR_BADSMB || code == CM_ERROR_BADOP ) @@ -6973,7 +6973,7 @@ void smb_Server(VOID *parmp) if (idx_NCB < 0 || idx_NCB > (sizeof(NCBs) / sizeof(NCBs[0]))) { /* this is fatal - log as much as possible */ - osi_Log1(smb_logp, "Fatal: idx_NCB [ %d ] out of range.\n", idx_NCB); + osi_Log1(smb_logp, "Fatal: idx_NCB %d out of range.\n", idx_NCB); osi_assert(0); } @@ -7002,13 +7002,13 @@ void smb_Server(VOID *parmp) osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal buffer address", ncbp->ncb_lsn, idx_session); break; case 0x08: - osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lsn %d session number out of range", ncbp->ncb_lsn, idx_session); + osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session number out of range", ncbp->ncb_lsn, idx_session); break; case 0x09: osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no resource available", ncbp->ncb_lsn, idx_session); break; case 0x0a: - osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lsn %d session closed", ncbp->ncb_lsn, idx_session); + osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session closed", ncbp->ncb_lsn, idx_session); break; case 0x0b: osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command cancelled", ncbp->ncb_lsn, idx_session); @@ -7023,10 +7023,10 @@ void smb_Server(VOID *parmp) osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no deletions, name has active lsn %d sessions", ncbp->ncb_lsn, idx_session); break; case 0x11: - osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: local lsn %d session table full", ncbp->ncb_lsn, idx_session); + osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: local session table full", ncbp->ncb_lsn, idx_session); break; case 0x12: - osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: remote lsn %d session table full", ncbp->ncb_lsn, idx_session); + osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: remote session table full", ncbp->ncb_lsn, idx_session); break; case 0x13: osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal name number", ncbp->ncb_lsn, idx_session); @@ -7044,7 +7044,7 @@ void smb_Server(VOID *parmp) osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name deleted", ncbp->ncb_lsn, idx_session); break; case 0x18: - osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lsn %d session ended abnormally", ncbp->ncb_lsn, idx_session); + osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session ended abnormally", ncbp->ncb_lsn, idx_session); break; case 0x19: osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name conflict detected", ncbp->ncb_lsn, idx_session); @@ -7108,9 +7108,8 @@ void smb_Server(VOID *parmp) break; case NRC_PENDING: - /* Can this happen? Or is it just my - * UNIX paranoia? - */ + /* Can this happen? Or is it just my UNIX paranoia? */ + osi_Log2(smb_logp, "NCBRECV pending lsn %d session %d", ncbp->ncb_lsn, idx_session); continue; case NRC_SCLOSED: @@ -7128,15 +7127,17 @@ void smb_Server(VOID *parmp) * also cleanup after dead vcp */ if (vcp) { - if (dead_vcp) - osi_Log1(smb_logp, - "dead_vcp already set, %x", - dead_vcp); + if (dead_vcp == vcp) + osi_Log1(smb_logp, "dead_vcp already set, 0x%x", dead_vcp); else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { - osi_Log2(smb_logp, - "setting dead_vcp %x, user struct %x", + osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x", vcp, vcp->usersp); smb_HoldVC(vcp); + if (dead_vcp) { + smb_ReleaseVC(dead_vcp); + osi_Log1(smb_logp, + "Previous dead_vcp %x", dead_vcp); + } dead_vcp = vcp; vcp->flags |= SMB_VCFLAG_ALREADYDEAD; } @@ -7271,7 +7272,7 @@ void smb_Server(VOID *parmp) "bufp=0x%x\n", bufp->dos_pkt / 16, bufp);*/ fflush(stderr); - dosmemget(bufp->dos_pkt, ncbp->ncb_length, bufp->data); + dosmemget(bufp->dos_pkt, ncbp-d>ncb_length, bufp->data); #endif /* DJGPP */ smbp = (smb_t *)bufp->data; outbufp->flags = 0; @@ -7552,7 +7553,6 @@ void smb_Listener(void *parmp) vcp = smb_FindVC(ncbp->ncb_lsn, SMB_FLAG_CREATE, ncbp->ncb_lana_num); vcp->flags |= flags; strcpy(vcp->rname, rname); - smb_ReleaseVC(vcp); /* Allocate slot in session arrays */ /* Re-use dead session if possible, otherwise add one more */ @@ -7565,43 +7565,82 @@ void smb_Listener(void *parmp) } } - /* assert that we do not exceed the maximum number of sessions or NCBs. - * we should probably want to wait for a session to be freed in case - * we run out. - */ + if (i >= Sessionmax - 1 || numNCBs >= NCBmax - 1) { + unsigned long code = CM_ERROR_ALLBUSY; + smb_packet_t * outp = GetPacket(); + unsigned char *outWctp; + smb_t *smbp; + + outp->ncbp = ncbp; - osi_assert(i < Sessionmax - 1); - osi_assert(numNCBs < NCBmax - 1); /* if we pass this test we can allocate one more */ + if (vcp->flags & SMB_VCFLAG_STATUS32) { + unsigned long NTStatus; + smb_MapNTError(code, &NTStatus); + outWctp = outp->wctp; + smbp = (smb_t *) &outp->data; + *outWctp++ = 0; + *outWctp++ = 0; + *outWctp++ = 0; + smbp->rcls = (unsigned char) (NTStatus & 0xff); + smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); + smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); + smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); + smbp->flg2 |= SMB_FLAGS2_32BIT_STATUS; + } else { + unsigned short errCode; + unsigned char errClass; + smb_MapCoreError(code, vcp, &errCode, &errClass); + outWctp = outp->wctp; + smbp = (smb_t *) &outp->data; + *outWctp++ = 0; + *outWctp++ = 0; + *outWctp++ = 0; + smbp->errLow = (unsigned char) (errCode & 0xff); + smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); + smbp->rcls = errClass; + } + smb_SendPacket(vcp, outp); + smb_FreePacket(outp); + } else { + /* assert that we do not exceed the maximum number of sessions or NCBs. + * we should probably want to wait for a session to be freed in case + * we run out. + */ + osi_assert(i < Sessionmax - 1); + osi_assert(numNCBs < NCBmax - 1); /* if we pass this test we can allocate one more */ - LSNs[i] = ncbp->ncb_lsn; - lanas[i] = ncbp->ncb_lana_num; + LSNs[i] = ncbp->ncb_lsn; + lanas[i] = ncbp->ncb_lana_num; - if (i == numSessions) { - /* Add new NCB for new session */ - char eventName[MAX_PATH]; - - osi_Log1(smb_logp, "smb_Listener creating new session %d", i); - - InitNCBslot(numNCBs); - numNCBs++; - thrd_SetEvent(NCBavails[0]); - thrd_SetEvent(NCBevents[0]); - for (j = 0; j < smb_NumServerThreads; j++) - thrd_SetEvent(NCBreturns[j][0]); - /* Also add new session event */ - sprintf(eventName, "SessionEvents[%d]", i); - SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); - if ( GetLastError() == ERROR_ALREADY_EXISTS ) - osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); - numSessions++; - osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions); - thrd_SetEvent(SessionEvents[0]); - } else { - thrd_SetEvent(SessionEvents[i]); + if (i == numSessions) { + /* Add new NCB for new session */ + char eventName[MAX_PATH]; + + osi_Log1(smb_logp, "smb_Listener creating new session %d", i); + + InitNCBslot(numNCBs); + numNCBs++; + thrd_SetEvent(NCBavails[0]); + thrd_SetEvent(NCBevents[0]); + for (j = 0; j < smb_NumServerThreads; j++) + thrd_SetEvent(NCBreturns[j][0]); + /* Also add new session event */ + sprintf(eventName, "SessionEvents[%d]", i); + SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName); + if ( GetLastError() == ERROR_ALREADY_EXISTS ) + osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName)); + numSessions++; + osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions); + thrd_SetEvent(SessionEvents[0]); + } else { + thrd_SetEvent(SessionEvents[i]); + } } + + smb_ReleaseVC(vcp); + /* unlock */ lock_ReleaseMutex(&smb_ListenerLock); - } /* dispatch while loop */ } @@ -8076,13 +8115,15 @@ void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt, ); if (nts != STATUS_SUCCESS && ntsEx != STATUS_SUCCESS) { + char message[256]; + sprintf(message,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x", + nts, ntsEx); + OutputDebugString(message); osi_Log2(smb_logp,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x", nts, ntsEx); - OutputDebugString("MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x", - nts, ntsEx); } else { - osi_Log0(smb_logp,"MsV1_0SetProcessOption success"); OutputDebugString("MsV1_0SetProcessOption success"); + osi_Log0(smb_logp,"MsV1_0SetProcessOption success"); } /* END - code from Larry */ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 4d436d152..356d76cd7 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -5115,6 +5115,23 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #define FILE_OVERWRITE 4 // (open & truncate, but do not create) #define FILE_OVERWRITE_IF 5 // (open & truncate, or create) +/* Flags field */ +#define REQUEST_OPLOCK 2 +#define REQUEST_BATCH_OPLOCK 4 +#define OPEN_DIRECTORY 8 +#define EXTENDED_RESPONSE_REQUIRED 0x10 + +/* CreateOptions field. */ +#define FILE_DIRECTORY_FILE 0x0001 +#define FILE_WRITE_THROUGH 0x0002 +#define FILE_SEQUENTIAL_ONLY 0x0004 +#define FILE_NON_DIRECTORY_FILE 0x0040 +#define FILE_NO_EA_KNOWLEDGE 0x0200 +#define FILE_EIGHT_DOT_THREE_ONLY 0x0400 +#define FILE_RANDOM_ACCESS 0x0800 +#define FILE_DELETE_ON_CLOSE 0x1000 +#define FILE_OPEN_BY_FILE_ID 0x2000 + long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { char *pathp, *realPathp; @@ -5132,6 +5149,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) unsigned int requestOpLock; unsigned int requestBatchOpLock; unsigned int mustBeDir; + unsigned int extendedRespRequired; unsigned int treeCreate; int realDirFlag; unsigned int desiredAccess; @@ -5166,9 +5184,10 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) nameLength = smb_GetSMBOffsetParm(inp, 2, 1); flags = smb_GetSMBOffsetParm(inp, 3, 1) | (smb_GetSMBOffsetParm(inp, 4, 1) << 16); - requestOpLock = flags & 0x02; - requestBatchOpLock = flags & 0x04; - mustBeDir = flags & 0x08; + requestOpLock = flags & REQUEST_OPLOCK; + requestBatchOpLock = flags & REQUEST_BATCH_OPLOCK; + mustBeDir = flags & OPEN_DIRECTORY; + extendedRespRequired = flags & EXTENDED_RESPONSE_REQUIRED; /* * Why all of a sudden 32-bit FID? @@ -5189,9 +5208,9 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* mustBeDir is never set; createOptions directory bit seems to be * more important */ - if (createOptions & 1) + if (createOptions & FILE_DIRECTORY_FILE) realDirFlag = 1; - else if (createOptions & 0x40) + else if (createOptions & FILE_NON_DIRECTORY_FILE) realDirFlag = 0; else realDirFlag = -1; @@ -5418,7 +5437,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } } while (dscp == NULL && code == 0); } else - code = 0; + code = 0; /* we might have scp and we might have dscp */ @@ -5847,10 +5866,10 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out lparmp = (ULONG *) parmp; flags = lparmp[0]; - requestOpLock = flags & 0x02; - requestBatchOpLock = flags & 0x04; - mustBeDir = flags & 0x08; - extendedRespRequired = flags & 0x10; + requestOpLock = flags & REQUEST_OPLOCK; + requestBatchOpLock = flags & REQUEST_BATCH_OPLOCK; + mustBeDir = flags & OPEN_DIRECTORY; + extendedRespRequired = flags & EXTENDED_RESPONSE_REQUIRED; /* * Why all of a sudden 32-bit FID? @@ -5883,9 +5902,9 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out /* mustBeDir is never set; createOptions directory bit seems to be * more important */ - if (createOptions & 1) + if (createOptions & FILE_DIRECTORY_FILE) realDirFlag = 1; - else if (createOptions & 0x40) + else if (createOptions & FILE_NON_DIRECTORY_FILE) realDirFlag = 0; else realDirFlag = -1;