From: Jeffrey Altman Date: Tue, 22 Nov 2005 00:30:01 +0000 (+0000) Subject: STABLE14-windows-afsd-service-20051121 X-Git-Tag: openafs-stable-1_4_1-rc2~22 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=d009e36f84ba9ef523e61ba620b6d2c785e1a67a;p=packages%2Fo%2Fopenafs.git STABLE14-windows-afsd-service-20051121 add logic to process VNOVNODE in cm_Analyze. Force re-evaluation of symlink strings and flush the stat cache entry. force the use of new rx_connections when the server is marked down. prevent server objects from being freed if user preferences are set. --- diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index c7cc7eebe..6251c7ef4 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -401,6 +401,25 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, } if ( timeLeft > 2 ) retry = 1; + } else if ( errorCode == VNOVNODE ) { + if ( fidp ) { + cm_scache_t * scp; + osi_Log4(afsd_logp, "cm_Analyze passed VNOVNODE cell %u vol %u vn %u uniq %u.", + fidp->cell, fidp->volume, fidp->vnode, fidp->unique); +#ifdef VNOVNODE_FLUSH_VOLUME + cm_FlushVolume(userp, reqp, fidp->cell, fidp->volume); +#else /* VNOVNODE_FLUSH_FILE */ + if (!cm_GetSCache(fidp, &scp, userp, reqp)) { + cm_FlushFile(scp, userp, reqp); +#ifdef VNOVNODE_FLUSH_PARENT + cm_FlushParent(scp, userp, reqp); +#endif /* VNOVNODE_FLUSH_PARENT */ + cm_ReleaseSCache(scp); + } +#endif /* VNODE_FLUSH_xxxx */ + } else { + osi_Log0(afsd_logp, "cm_Analyze passed VNOVNODE unknown fid."); + } } /* RX codes */ @@ -430,6 +449,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, lock_ObtainMutex(&serverp->mx); serverp->flags |= CM_SERVERFLAG_DOWN; lock_ReleaseMutex(&serverp->mx); + cm_ForceNewConnections(serverp); if ( timeLeft > 2 ) retry = 1; } @@ -696,7 +716,8 @@ long cm_ConnByServer(cm_server_t *serverp, cm_user_t *userp, cm_conn_t **connpp) tcp->refCount = 1; lock_ReleaseMutex(&tcp->mx); } else { - if ((tcp->ucgen < ucellp->gen) || + if ((tcp->flags & CM_CONN_FLAG_FORCE_NEW) || + (tcp->ucgen < ucellp->gen) || (tcp->cryptlevel != (cryptall ? (ucellp->flags & CM_UCELLFLAG_RXKAD ? rxkad_crypt : rxkad_clear) : rxkad_clear))) { if (tcp->ucgen < ucellp->gen) @@ -704,6 +725,7 @@ long cm_ConnByServer(cm_server_t *serverp, cm_user_t *userp, cm_conn_t **connpp) else osi_Log0(afsd_logp, "cm_ConnByServer replace connection due to crypt change"); lock_ObtainMutex(&tcp->mx); + tcp->flags &= ~CM_CONN_FLAG_FORCE_NEW; rx_DestroyConnection(tcp->callp); cm_NewRXConnection(tcp, ucellp, serverp); lock_ReleaseMutex(&tcp->mx); @@ -749,3 +771,15 @@ cm_GetRxConn(cm_conn_t *connp) return rxconn; } +void cm_ForceNewConnections(cm_server_t *serverp) +{ + cm_conn_t *tcp; + + lock_ObtainWrite(&cm_connLock); + for (tcp = serverp->connsp; tcp; tcp=tcp->nextp) { + lock_ObtainMutex(&tcp->mx); + tcp->flags |= CM_CONN_FLAG_FORCE_NEW; + lock_ReleaseMutex(&tcp->mx); + } + lock_ReleaseWrite(&cm_connLock); +} diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index e993edaab..29ce89bd3 100644 --- a/src/WINNT/afsd/cm_conn.h +++ b/src/WINNT/afsd/cm_conn.h @@ -29,6 +29,8 @@ typedef struct cm_conn { int cryptlevel; /* encrytion status */ } cm_conn_t; +#define CM_CONN_FLAG_FORCE_NEW 1 + /* structure used for tracking RPC progress */ typedef struct cm_req { DWORD startTime; /* Quit before RDR times us out */ @@ -115,4 +117,6 @@ extern void cm_GCConnections(cm_server_t *serverp); extern struct rx_connection * cm_GetRxConn(cm_conn_t *connp); +extern void cm_ForceNewConnections(cm_server_t *serverp); + #endif /* __CM_CONN_H_ENV__ */ diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index ae7b9f2d3..7e92a10ea 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -1368,7 +1368,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, if (code == 0) code = EndRXAFS_FetchData(callp, &afsStatus, &callback, &volSync); else - osi_Log0(afsd_logp, "CALL EndRXAFS_FetchData skipped due to error"); + osi_Log1(afsd_logp, "CALL EndRXAFS_FetchData skipped due to error %d", code); code = rx_EndCall(callp, code); if (code == RXKADUNKNOWNKEY) osi_Log0(afsd_logp, "CALL EndCall returns RXKADUNKNOWNKEY"); diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 6190774ee..8e41311a1 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -75,6 +75,10 @@ long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) cm_dnlcPurgedp(scp); cm_dnlcPurgevp(scp); cm_FreeAllACLEnts(scp); + + /* Force mount points and symlinks to be re-evaluated */ + scp->mountPointStringp[0] = '\0'; + lock_ReleaseMutex(&scp->mx); lock_ReleaseWrite(&scp->bufCreateLock); @@ -82,6 +86,63 @@ long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) return code; } +long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) +{ + long code = 0; + int i; + cm_fid_t parent_fid; + + lock_ObtainWrite(&cm_scacheLock); + cm_HoldSCacheNoLock(scp); + parent_fid = scp->fid; + parent_fid.vnode = scp->parentVnode; + parent_fid.unique = scp->parentUnique; + cm_ReleaseSCacheNoLock(scp); + + for (i=0; inextp) { + if (cm_FidCmp(&scp->fid, &parent_fid)) { + cm_HoldSCacheNoLock(scp); + lock_ReleaseWrite(&cm_scacheLock); + + /* now flush the file */ + code = cm_FlushFile(scp, userp, reqp); + lock_ObtainWrite(&cm_scacheLock); + cm_ReleaseSCacheNoLock(scp); + } + } + } + lock_ReleaseWrite(&cm_scacheLock); + + return code; +} + + +long cm_FlushVolume(cm_user_t *userp, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume) +{ + long code = 0; + cm_scache_t *scp; + int i; + + lock_ObtainWrite(&cm_scacheLock); + for (i=0; inextp) { + if (scp->fid.volume == volume && scp->fid.cell == cell) { + cm_HoldSCacheNoLock(scp); + lock_ReleaseWrite(&cm_scacheLock); + + /* now flush the file */ + code = cm_FlushFile(scp, userp, reqp); + lock_ObtainWrite(&cm_scacheLock); + cm_ReleaseSCacheNoLock(scp); + } + } + } + lock_ReleaseWrite(&cm_scacheLock); + + return code; +} + /* * cm_ResetACLCache -- invalidate ACL info for a user that has just * obtained or lost tokens @@ -533,6 +594,8 @@ long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp) return code; } + + long cm_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp) { long code; @@ -564,7 +627,7 @@ long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp) long code; cm_scache_t *scp; unsigned long volume; - int i; + unsigned long cell; cm_req_t req; cm_InitReq(&req); @@ -573,23 +636,10 @@ long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp) if (code) return code; volume = scp->fid.volume; + cell = scp->fid.cell; cm_ReleaseSCache(scp); - lock_ObtainWrite(&cm_scacheLock); - for (i=0; inextp) { - if (scp->fid.volume == volume) { - cm_HoldSCacheNoLock(scp); - lock_ReleaseWrite(&cm_scacheLock); - - /* now flush the file */ - code = cm_FlushFile(scp, userp, &req); - lock_ObtainWrite(&cm_scacheLock); - cm_ReleaseSCacheNoLock(scp); - } - } - } - lock_ReleaseWrite(&cm_scacheLock); + code = cm_FlushVolume(userp, &req, cell, volume); return code; } @@ -1453,13 +1503,16 @@ long cm_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp) /* set preferences for an existing vlserver */ cm_ChangeRankCellVLServer(tsp); } - cm_PutServer(tsp); /* decrease refcount */ } else /* add a new server without a cell */ { tsp = cm_NewServer(&tmp, type, NULL); /* refcount = 1 */ tsp->ipRank = rank; } + lock_ObtainMutex(&tsp->mx); + tsp->flags |= CM_SERVERFLAG_PREF_SET; + lock_ReleaseMutex(&tsp->mx); + cm_PutServer(tsp); /* decrease refcount */ } return 0; } diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index bbc4f15ae..a0d3c0173 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -118,6 +118,10 @@ extern long cm_IoctlCreateMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp); extern long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp); +extern long cm_FlushVolume(cm_user_t *, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume); + +extern long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp); + extern long cm_IoctlTraceControl(smb_ioctl_t *ioctlp, cm_user_t *userp); extern long cm_IoctlSetToken(smb_ioctl_t *ioctlp, cm_user_t *userp); diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index d8b1faa1f..309b57717 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -107,6 +107,8 @@ void cm_CheckServers(long flags, cm_cell_t *cellp) else { /* mark server as down */ tsp->flags |= CM_SERVERFLAG_DOWN; + if (code != VRESTARTING) + cm_ForceNewConnections(tsp); } lock_ReleaseMutex(&tsp->mx); } @@ -438,21 +440,24 @@ void cm_FreeServer(cm_server_t* serverp) */ cm_GCConnections(serverp); /* connsp */ - lock_FinalizeMutex(&serverp->mx); - if ( cm_allServersp == serverp ) - cm_allServersp = serverp->allNextp; - else { - cm_server_t *tsp; - - for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) { - if ( tsp->allNextp == serverp ) { - tsp->allNextp = serverp->allNextp; - break; - } + if (!(serverp->flags & CM_SERVERFLAG_PREF_SET)) { + lock_FinalizeMutex(&serverp->mx); + if ( cm_allServersp == serverp ) + cm_allServersp = serverp->allNextp; + else { + cm_server_t *tsp; + + for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) { + if ( tsp->allNextp == serverp ) { + tsp->allNextp = serverp->allNextp; + break; + } + } } + free(serverp); } } - } +} void cm_FreeServerList(cm_serverRef_t** list) { diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index 5643512e0..265eb1a1a 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -24,12 +24,12 @@ typedef struct cm_server { struct cm_server *allNextp; /* locked by cm_serverLock */ struct sockaddr_in addr; /* by mx */ int type; /* by mx */ - struct cm_conn *connsp; /* locked by cm_connLock */ + struct cm_conn *connsp; /* locked by cm_connLock */ long flags; /* by mx */ - struct cm_cell *cellp; /* cell containing this server */ - unsigned long refCount; /* locked by cm_serverLock */ + struct cm_cell *cellp; /* cell containing this server */ + unsigned long refCount; /* locked by cm_serverLock */ osi_mutex_t mx; - unsigned short ipRank; /* server priority */ + unsigned short ipRank; /* server priority */ } cm_server_t; enum repstate {not_busy, busy, offline}; @@ -47,6 +47,7 @@ typedef struct cm_serverRef { /* flags */ #define CM_SERVERFLAG_DOWN 1 /* server is down */ +#define CM_SERVERFLAG_PREF_SET 2 /* server preference set by user */ /* flags for procedures */ #define CM_FLAG_CHECKUPSERVERS 1 /* check working servers */