tfid.volume = fidp->Volume;
tfid.vnode = fidp->Vnode;
tfid.unique = fidp->Unique;
+ CM_FID_GEN_HASH(&tfid);
hash = CM_SCACHE_HASH(&tfid);
osi_Log3(afsd_logp, "RevokeCallback vol %u vn %u uniq %u",
osi_Log4(afsd_logp, "RevokeCallback Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
- if (RDR_Initialized)
- RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
- scp->fid.hash, scp->fileType, AFS_INVALIDATE_CALLBACK);
-
lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw);
+ if (RDR_Initialized)
+ RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
+ scp->fid.hash, scp->fileType, AFS_INVALIDATE_CALLBACK);
+
cm_CallbackNotifyChange(scp);
lock_ObtainWrite(&cm_scacheLock);
cm_PutVolume(volp);
if (volp->cbExpiresRO) {
volp->cbExpiresRO = 0;
+ volp->cbIssuedRO = 0;
if (volp->cbServerpRO) {
cm_PutServer(volp->cbServerpRO);
volp->cbServerpRO = NULL;
extern osi_rwlock_t buf_globalLock;
extern osi_rwlock_t cm_cellLock;
extern osi_rwlock_t cm_connLock;
-extern osi_rwlock_t cm_daemonLock;
extern osi_rwlock_t cm_dnlcLock;
extern osi_rwlock_t cm_scacheLock;
extern osi_rwlock_t cm_serverLock;
{"cm_connLock", (char*)&cm_connLock, LOCKTYPE_RW},
{"cm_userLock", (char*)&cm_userLock, LOCKTYPE_RW},
{"cm_volumeLock", (char*)&cm_volumeLock, LOCKTYPE_RW},
- {"cm_daemonLock", (char*)&cm_daemonLock, LOCKTYPE_RW},
{"cm_dnlcLock", (char*)&cm_dnlcLock, LOCKTYPE_RW},
{"cm_utilsLock", (char*)&cm_utilsLock, LOCKTYPE_RW},
{"smb_globalLock", (char*)&smb_globalLock, LOCKTYPE_RW},
cm_cell_t* cellp = NULL;
afs_uint32 hash;
int discarded;
+ cm_fid_t discardFid;
+ afs_uint32 discardType;
struct rx_connection *connp;
struct rx_peer *peerp;
unsigned long host = 0;
if (cm_ServerEqual(scp->cbServerp, tsp)) {
osi_Log4(afsd_logp, "InitCallbackState3 Discarding SCache scp 0x%p vol %u vn %u uniq %u",
scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
+ discardFid = scp->fid;
+ discardType = scp->fileType;
cm_DiscardSCache(scp);
discarded = 1;
}
if (discarded) {
cm_CallbackNotifyChange(scp);
if (RDR_Initialized)
- RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
- scp->fid.hash, scp->fileType, AFS_INVALIDATE_EXPIRED);
+ RDR_InvalidateObject(discardFid.cell, discardFid.volume, discardFid.vnode, discardFid.unique,
+ discardFid.hash, discardType, AFS_INVALIDATE_EXPIRED);
}
lock_ObtainWrite(&cm_scacheLock);
cm_ReleaseSCacheNoLock(scp);
afs_int32 sn;
cm_cell_t * cellp;
cm_serverRef_t * serverRefp;
+ size_t len;
cellp = cm_FindCellByID(a_cellnum, CM_FLAG_NOPROBE);
if (!cellp) {
- *a_name = strdup("");
+ *a_name = (char *)xdr_alloc(sizeof(char));
+ if (*a_name)
+ *a_name = '\0';
return 0;
}
lock_ObtainRead(&cm_serverLock);
- *a_name = strdup(cellp->name);
+ len = strlen(cellp->name)+1;
+ *a_name = (char *)xdr_alloc(len);
+ if (*a_name)
+ memcpy(*a_name, cellp->name, len);
for ( sn = 0, serverRefp = cellp->vlServersp;
sn < AFSMAXCELLHOSTS && serverRefp;
struct rx_peer *peerp;
unsigned long host = 0;
unsigned short port = 0;
+ size_t len;
if (cm_shutdown)
return 1;
ntohl(host), ntohs(port));
if (cm_data.rootCellp) {
- t_name = strdup(cm_data.rootCellp->name);
+ len = strlen(cm_data.rootCellp->name) + 1;
+ t_name = (char *)xdr_alloc(len);
+ if (t_name)
+ memcpy(t_name, cm_data.rootCellp->name, len);
} else {
t_name = (char *)xdr_alloc(1);
t_name[0] = '\0';
*
* Called with scp write locked, so we can discard the callbacks easily with
* this locking hierarchy.
+ *
+ * Performs cleanup of the stack allocated cm_callbackRequest_t object.
+ *
+ * Returns 0 on success and non-zero if the callback lost a race.
*/
-void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
- AFSCallBack *cbp, AFSVolSync *volSyncp, long flags)
+int
+cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
+ AFSCallBack *cbp, AFSVolSync *volSyncp, long flags)
{
cm_racingRevokes_t *revp; /* where we are */
cm_racingRevokes_t *nrevp; /* where we'll be next */
- int freeFlag;
+ int freeRacingRevokes;
+ int freeServer;
cm_server_t * serverp = NULL;
- int discardScp = 0, discardVolCB = 0;
+ int lostRace = 0;
lock_ObtainWrite(&cm_callbackLock);
if (flags & CM_CALLBACK_MAINTAINCOUNT) {
osi_assertx(cm_activeCallbackGrantingCalls > 0,
"CM_CALLBACK_MAINTAINCOUNT && cm_activeCallbackGrantingCalls == 0");
+ freeServer = 0;
}
else {
osi_assertx(cm_activeCallbackGrantingCalls-- > 0,
"!CM_CALLBACK_MAINTAINCOUNT && cm_activeCallbackGrantingCalls == 0");
+ freeServer = 1;
}
if (cm_activeCallbackGrantingCalls == 0)
- freeFlag = 1;
+ freeRacingRevokes = 1;
else
- freeFlag = 0;
+ freeRacingRevokes = 0;
- /* record the callback; we'll clear it below if we really lose it */
- if (cbrp) {
- if (scp) {
- if (!cm_ServerEqual(scp->cbServerp, cbrp->serverp)) {
- serverp = scp->cbServerp;
- if (!freeFlag)
- cm_GetServer(cbrp->serverp);
- scp->cbServerp = cbrp->serverp;
- } else {
- if (freeFlag)
- serverp = cbrp->serverp;
- }
- scp->cbExpires = cbrp->startTime + cbp->ExpirationTime;
- } else {
- if (freeFlag)
- serverp = cbrp->serverp;
- }
- if (freeFlag)
- cbrp->serverp = NULL;
- }
-
- /* a callback was actually revoked during our granting call, so
+ /*
+ * a callback was revoked during our granting call, so
* run down the list of revoked fids, looking for ours.
* If activeCallbackGrantingCalls is zero, free the elements, too.
*
scp,
cbrp->callbackCount, revp->callbackCount,
cm_callbackCount);
- discardScp = 1;
+ lostRace = 1;
if ((scp->flags & CM_SCACHEFLAG_PURERO) &&
(revp->flags & CM_RACINGFLAG_ALL))
cm_callbackDiscardROVolumeByFID(&scp->fid);
}
- if (freeFlag)
+ if (freeRacingRevokes)
free(revp);
}
/* if we freed the list, zap the pointer to it */
- if (freeFlag)
+ if (freeRacingRevokes)
cm_racingRevokesp = NULL;
-
lock_ReleaseWrite(&cm_callbackLock);
- if ( discardScp ) {
- cm_DiscardSCache(scp);
- lock_ReleaseWrite(&scp->rw);
- cm_CallbackNotifyChange(scp);
- if (RDR_Initialized)
- RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
- scp->fid.hash, scp->fileType, AFS_INVALIDATE_CALLBACK);
- lock_ObtainWrite(&scp->rw);
- } else {
- if (scp && scp->flags & CM_SCACHEFLAG_PURERO) {
+ /* record the callback if we didn't lose it */
+ if (!lostRace && scp) {
+ if (cbrp) {
+ if (!cm_ServerEqual(scp->cbServerp, cbrp->serverp)) {
+ serverp = scp->cbServerp;
+ scp->cbServerp = cbrp->serverp;
+ if (freeServer) {
+ cbrp->serverp = NULL;
+ } else {
+ cm_GetServer(scp->cbServerp);
+ }
+ } else if (freeServer) {
+ serverp = cbrp->serverp;
+ cbrp->serverp = NULL;
+ }
+ scp->cbExpires = cbrp->startTime + cbp->ExpirationTime;
+ scp->cbIssued = time(NULL);
+ }
+
+ if (scp->flags & CM_SCACHEFLAG_PURERO) {
cm_volume_t * volp = cm_GetVolumeByFID(&scp->fid);
if (volp) {
if (volSyncp) {
lock_ObtainWrite(&cm_scacheLock);
volp->cbExpiresRO = scp->cbExpires;
+ volp->cbIssuedRO = scp->cbIssued;
volp->creationDateRO = volSyncp->spare1;
if (volp->cbServerpRO != scp->cbServerp) {
if (volp->cbServerpRO)
}
}
}
+ else
+ {
+ /*
+ * No need to discard the cm_scache object or notify the
+ * afs redirector or smb client about a change if we did lose
+ * the race. That was done when the callback was processed in
+ * cm_RevokeCallback().
+ */
+ if (cbrp && freeServer) {
+ serverp = cbrp->serverp;
+ cbrp->serverp = NULL;
+ }
+ }
if ( serverp ) {
lock_ObtainWrite(&cm_serverLock);
cm_FreeServer(serverp);
lock_ReleaseWrite(&cm_serverLock);
}
+
+ return lostRace;
}
/* if flags is 1, we want to force the code to make one call, anyway.
&afsStatus, &callback, &volSync);
rx_PutConnection(rxconnp);
- } while (cm_Analyze(connp, userp, reqp, &sfid, &volSync, NULL,
+ } while (cm_Analyze(connp, userp, reqp, &sfid, 0, &volSync, NULL,
&cbr, code));
code = cm_MapRPCError(code, reqp);
if (code)
lock_ObtainWrite(&scp->rw);
if (code == 0) {
- cm_EndCallbackGrantingCall(scp, &cbr, &callback, &volSync, 0);
- cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, reqp, 0);
+ int lostRace = cm_EndCallbackGrantingCall(scp, &cbr, &callback, &volSync, 0);
+ if (!lostRace)
+ cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, reqp, 0);
} else {
cm_EndCallbackGrantingCall(NULL, &cbr, NULL, NULL, 0);
InterlockedDecrement(&scp->activeRPCs);
{
lock_ObtainWrite(&scp->rw);
scp->cbExpires = volp->cbExpiresRO;
+ scp->cbIssued = volp->cbIssuedRO;
if (volp->cbServerpRO != scp->cbServerp) {
if (scp->cbServerp)
cm_PutServer(scp->cbServerp);
if (RDR_Initialized)
RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
- scp->fid.hash, scp->fileType, AFS_INVALIDATE_EXPIRED);
+ scp->fid.hash, scp->fileType, AFS_INVALIDATE_EXPIRED);
cm_CallbackNotifyChange(scp);
if ((tsp->type == CM_SERVER_FILE) && !(tsp->flags & CM_SERVERFLAG_DOWN))
{
- code = cm_ConnByServer(tsp, cm_rootUserp, &connp);
+ code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &connp);
if (code == 0) {
rxconnp = cm_GetRxConn(connp);
rx_SetConnDeadTime(rxconnp, 10);
lock_ReleaseRead(&cm_serverLock);
serversp[nconns] = tsp;
- code = cm_ConnByServer(tsp, cm_rootUserp, &conns[nconns]);
+ code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &conns[nconns]);
if (code) {
lock_ObtainRead(&cm_serverLock);
cm_PutServerNoLock(tsp);