}
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);
+ if (!cm_GetSCache(fidp, &scp, userp, reqp)) {
+ cm_FlushParent(scp, userp, reqp);
+ cm_FlushFile(scp, userp, reqp);
+ cm_ReleaseSCache(scp);
+ }
+ } else {
+ osi_Log0(afsd_logp, "cm_Analyze passed VNOVNODE unknown fid.");
+ }
}
/* RX codes */
lock_ObtainMutex(&serverp->mx);
serverp->flags |= CM_SERVERFLAG_DOWN;
lock_ReleaseMutex(&serverp->mx);
+ cm_ForceNewConnections(serverp);
if ( timeLeft > 2 )
retry = 1;
}
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)
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);
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);
+}
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 */
extern struct rx_connection * cm_GetRxConn(cm_conn_t *connp);
+extern void cm_ForceNewConnections(cm_server_t *serverp);
+
#endif /* __CM_CONN_H_ENV__ */
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");
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);
- afsi_log("cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
+ osi_Log2(afsd_logp,"cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
+ 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; i<cm_data.hashTableSize; i++) {
+ for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+ 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; i<cm_data.hashTableSize; i++) {
+ for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+ 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;
}
return code;
}
+
+
long cm_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
{
long code;
long code;
cm_scache_t *scp;
unsigned long volume;
- int i;
+ unsigned long cell;
cm_req_t req;
cm_InitReq(&req);
if (code) return code;
volume = scp->fid.volume;
+ cell = scp->fid.cell;
cm_ReleaseSCache(scp);
- lock_ObtainWrite(&cm_scacheLock);
- for (i=0; i<cm_data.hashTableSize; i++) {
- for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
- 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;
}
/* 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;
}
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);
else {
/* mark server as down */
tsp->flags |= CM_SERVERFLAG_DOWN;
+ if (code != VRESTARTING)
+ cm_ForceNewConnections(tsp);
}
lock_ReleaseMutex(&tsp->mx);
}
*/
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)
{
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};
/* 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 */