-/*
- * Copyright (C) 1998, 1989 Transarc Corporation - All rights reserved
- *
- * (C) COPYRIGHT IBM CORPORATION 1987, 1988
- * LICENSED MATERIALS - PROPERTY OF IBM
- *
- *
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License. For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
*/
+
#include <afs/param.h>
#include <afs/afs_args.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#endif /* !DJGPP */
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include "afsd.h"
+/*extern void afsi_log(char *pattern, ...);*/
+
/* read/write lock for all global storage in this module */
osi_rwlock_t cm_callbackLock;
+#ifdef AFS_FREELANCE_CLIENT
+extern osi_mutex_t cm_Freelance_Lock;
+#endif
+
/* count of # of callback breaking messages received by this CM so far. We use
* this count in determining whether there have been any callback breaks that
* apply to a call that returned a new callback. If the counter doesn't
cm_racingRevokes_t *rp;
lock_ObtainWrite(&cm_callbackLock);
+
+ osi_Log3(afsd_logp, "RecordRacingRevoke Volume %d Flags %lX activeCalls %d",
+ fidp->volume, cancelFlags, cm_activeCallbackGrantingCalls);
+
if (cm_activeCallbackGrantingCalls > 0) {
rp = malloc(sizeof(*rp));
memset(rp, 0, sizeof(*rp));
*/
void cm_CallbackNotifyChange(cm_scache_t *scp)
{
+ osi_Log2(afsd_logp, "CallbackNotifyChange FileType %d Flags %lX",
+ scp->fileType, scp->flags);
+
if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
if (scp->flags & CM_SCACHEFLAG_ANYWATCH)
smb_NotifyChange(0,
smb_NotifyChange(0,
FILE_NOTIFY_GENERIC_FILE_FILTER,
dscp, NULL, NULL, TRUE);
+ if (dscp) cm_ReleaseSCache(dscp);
}
}
tfid.unique = fidp->Unique;
hash = CM_SCACHE_HASH(&tfid);
- osi_Log3(afsd_logp, "Revoke callback vol %d vn %d un %d",
+ osi_Log3(afsd_logp, "RevokeCallback vol %d vn %d un %d",
fidp->Volume, fidp->Vnode, fidp->Unique);
/* do this first, so that if we're executing a callback granting call
scp->fid.unique == tfid.unique) {
scp->refCount++;
lock_ReleaseWrite(&cm_scacheLock);
- osi_Log1(afsd_logp, "Revoke scp %x", scp);
+ osi_Log1(afsd_logp, "Discarding SCache scp %x", scp);
lock_ObtainMutex(&scp->mx);
cm_DiscardSCache(scp);
lock_ReleaseMutex(&scp->mx);
cm_scache_t *scp;
cm_fid_t tfid;
+ osi_Log1(afsd_logp, "RevokeVolumeCallback %d", fidp->Volume);
+
/* do this first, so that if we're executing a callback granting call
* at this moment, we kill it before it can be merged in. Otherwise,
* it could complete while we're doing the scan below, and get missed
tfid.volume = fidp->Volume;
cm_RecordRacingRevoke(&tfid, CM_RACINGFLAG_CANCELVOL);
- osi_Log1(afsd_logp, "Revoke Volume %d", fidp->Volume);
lock_ObtainWrite(&cm_scacheLock);
for(hash = 0; hash < cm_hashTableSize; hash++) {
scp->refCount++;
lock_ReleaseWrite(&cm_scacheLock);
lock_ObtainMutex(&scp->mx);
+ osi_Log1(afsd_logp, "Discarding SCache scp %x", scp);
cm_DiscardSCache(scp);
lock_ReleaseMutex(&scp->mx);
cm_CallbackNotifyChange(scp);
int i;
AFSFid *tfidp;
+ osi_Log0(afsd_logp, "SRXAFSCB_CallBack");
+
for(i=0; i < (long) fidsArrayp->AFSCBFids_len; i++) {
tfidp = &fidsArrayp->AFSCBFids_val[i];
- if (tfidp->Volume == 0) continue; /* means don't do anything */
+ if (tfidp->Volume == 0)
+ continue; /* means don't do anything */
else if (tfidp->Vnode == 0)
cm_RevokeVolumeCallback(callp, tfidp);
- else cm_RevokeCallback(callp, tfidp);
+ else
+ cm_RevokeCallback(callp, tfidp);
}
return 0;
int hash;
int discarded;
+ osi_Log0(afsd_logp, "SRXAFSCB_InitCallBackState");
+
if ((rx_ConnectionOf(callp)) && (rx_PeerOf(rx_ConnectionOf(callp)))) {
taddr.sin_family = AF_INET;
taddr.sin_addr.s_addr = rx_HostOf(rx_PeerOf(rx_ConnectionOf(callp)));
if (scp->cbServerp != NULL) {
/* we have a callback, now decide if we should clear it */
if (scp->cbServerp == tsp || tsp == NULL) {
+ osi_Log1(afsd_logp, "Discarding SCache scp %x", scp);
cm_DiscardSCache(scp);
discarded = 1;
}
/* just returns if we're up */
SRXAFSCB_Probe(struct rx_call *callp)
{
+ osi_Log0(afsd_logp, "SRXAFSCB_Probe - not implemented");
return 0;
}
/* debug interface: not implemented */
+SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
+{
+ /* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_GetCE64 - not implemented");
+ return RXGEN_OPCODE;
+}
+
+/* debug interface: not implemented */
SRXAFSCB_GetLock(struct rx_call *callp, long index, AFSDBLock *lockp)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_GetLock - not implemented");
return RXGEN_OPCODE;
}
SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_GetCE - not implemented");
return RXGEN_OPCODE;
}
SRXAFSCB_XStatsVersion(struct rx_call *callp, long *vp)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_XStatsVersion - not implemented");
*vp = -1;
return RXGEN_OPCODE;
}
AFSCB_CollData *datap)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_GetXStats - not implemented");
return RXGEN_OPCODE;
}
SRXAFSCB_InitCallBackState2(struct rx_call *callp, struct interfaceAddr* addr)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_InitCallBackState2 - not implemented");
return RXGEN_OPCODE;
}
SRXAFSCB_WhoAreYou(struct rx_call *callp, struct interfaceAddr* addr)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_WhoAreYou - not implemented");
return RXGEN_OPCODE;
}
SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_InitCallBackState3 - not implemented");
return RXGEN_OPCODE;
}
SRXAFSCB_ProbeUuid(struct rx_call *callp, afsUUID* clientUuid)
{
/* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_ProbeUuid - not implemented");
return RXGEN_OPCODE;
}
afs_int32 *a_srvr_addr,
afs_int32 *a_srvr_rank)
{
+ osi_Log0(afsd_logp, "SRXAFSCB_GetServerPrefs - not implemented");
+
*a_srvr_addr = 0xffffffff;
*a_srvr_rank = 0xffffffff;
return 0;
struct rx_call *a_call,
afs_int32 a_index,
char **a_name,
- afs_int32 *a_hosts)
+ serverList *a_hosts)
{
char *t_name;
+ osi_Log0(afsd_logp, "SRXAFSCB_GetCellServDB - not implemented");
+
t_name = (char *)malloc(AFSNAMEMAX);
t_name[0] = '\0';
*a_name = t_name;
- bzero(a_hosts, AFSMAXCELLHOSTS * sizeof(afs_int32));
+ a_hosts->serverList_len = 0;
return 0;
}
{
char *t_name;
- t_name = (char *)malloc(AFSNAMEMAX);
+ osi_Log0(afsd_logp, "SRXAFSCB_GetLocalCell");
+
if (cm_rootCellp) {
+ t_name = (char *)malloc(strlen(cm_rootCellp->namep)+1);
strcpy(t_name, cm_rootCellp->namep);
} else {
+ t_name = (char *)malloc(1);
t_name[0] = '\0';
}
*a_name = t_name;
size_t allocsize;
extern cm_initparams_v1 cm_initParams;
+ osi_Log0(afsd_logp, "SRXAFSCB_GetCacheConfig - version 1 only");
+
/*
* Currently only support version 1
*/
*/
int cm_HaveCallback(cm_scache_t *scp)
{
- if (scp->cbServerp != NULL)
- return 1;
- else return 0;
+#ifdef AFS_FREELANCE_CLIENT
+ // yj: we handle callbacks specially for callbacks on the root directory
+ // Since it's local, we almost always say that we have callback on it
+ // The only time we send back a 0 is if we're need to initialize or
+ // reinitialize the fake directory
+
+ // There are 2 state variables cm_fakeGettingCallback and cm_fakeDirCallback
+ // cm_fakeGettingCallback is 1 if we're in the process of initialization and
+ // hence should return false. it's 0 otherwise
+ // cm_fakeDirCallback is 0 if we haven't loaded the fake directory, it's 1
+ // if the fake directory is loaded and this is the first time cm_HaveCallback
+ // is called since then. We return false in this case to allow cm_GetCallback
+ // to be called because cm_GetCallback has some initialization work to do.
+ // If cm_fakeDirCallback is 2, then it means that the fake directory is in
+ // good shape and we simply return true, provided no change is detected.
+ int fdc, fgc;
+
+ if (cm_freelanceEnabled &&
+ scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) { // if it's something on /afs
+ if (!(scp->fid.vnode==0x1 && scp->fid.unique==0x1)) // if it's not root.afs
+ return 1;
+ else {
+ lock_ObtainMutex(&cm_Freelance_Lock);
+ fdc = cm_fakeDirCallback;
+ fgc = cm_fakeGettingCallback;
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ if (fdc==1) { // first call since init
+ return 0;
+ } else if (fdc==2 && !fgc) { // we're in good shape
+ if (cm_getLocalMountPointChange()) { // check for changes
+ cm_clearLocalMountPointChange(); // clear the changefile
+ cm_reInitLocalMountPoints(); // start reinit
+ return 0;
+ }
+ return 1; // no change
+ }
+ return 0;
+ }
+ }
+#endif
+
+ if (scp->cbServerp != NULL)
+ return 1;
+ else return 0;
}
/* need to detect a broken callback that races with our obtaining a callback.
*/
if (scp && cbrp->callbackCount != cm_callbackCount
&& revp->callbackCount > cbrp->callbackCount
- && (
- (scp->fid.volume == revp->fid.volume &&
+ && (( scp->fid.volume == revp->fid.volume &&
scp->fid.vnode == revp->fid.vnode &&
scp->fid.unique == revp->fid.unique)
||
struct cm_req *reqp, long flags)
{
long code;
- cm_conn_t *connp;
- AFSFetchStatus afsStatus;
- AFSVolSync volSync;
- AFSCallBack callback;
- AFSFid tfid;
- cm_callbackRequest_t cbr;
- int mustCall;
- long sflags;
+ cm_conn_t *connp;
+ AFSFetchStatus afsStatus;
+ AFSVolSync volSync;
+ AFSCallBack callback;
+ AFSFid tfid;
+ cm_callbackRequest_t cbr;
+ int mustCall;
+ long sflags;
+ cm_fid_t sfid;
+
+ osi_Log2(afsd_logp, "GetCallback scp %x flags %lX", scp, flags);
+
+#ifdef AFS_FREELANCE_CLIENT
+ // The case where a callback is needed on /afs is handled
+ // specially. We need to fetch the status by calling
+ // cm_MergeStatus and mark that cm_fakeDirCallback is 2
+ if (cm_freelanceEnabled) {
+ if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
+ scp->fid.unique==0x1 &&
+ scp->fid.vnode==0x1) {
+ // Start by indicating that we're in the process
+ // of fetching the callback
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+ cm_fakeGettingCallback = 1;
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ // Fetch the status info
+ cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0);
+
+ // Indicate that the callback is not done
+ lock_ObtainMutex(&cm_Freelance_Lock);
+ cm_fakeDirCallback = 2;
+ // Indicate that we're no longer fetching the callback
+ cm_fakeGettingCallback = 0;
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ return 0;
+ }
+ if (scp->fid.cell==AFS_FAKE_ROOT_CELL_ID && scp->fid.volume==AFS_FAKE_ROOT_VOL_ID) {
+ osi_Log0(afsd_logp,"cm_getcallback should NEVER EVER get here... ");
+ }
+ }
+#endif /* AFS_FREELANCE_CLIENT */
+
mustCall = (flags & 1);
cm_AFSFidFromFid(&tfid, &scp->fid);
while (1) {
if (!mustCall && cm_HaveCallback(scp)) return 0;
- /* turn off mustCall, since it has now forced us past the check above */
- mustCall = 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 */
+ /* otherwise, we have to make an RPC to get the status */
sflags = CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK;
- cm_SyncOp(scp, NULL, NULL, NULL, 0, sflags);
- cm_StartCallbackGrantingCall(scp, &cbr);
+ cm_SyncOp(scp, NULL, NULL, NULL, 0, sflags);
+ cm_StartCallbackGrantingCall(scp, &cbr);
+ sfid = scp->fid;
lock_ReleaseMutex(&scp->mx);
/* now make the RPC */
osi_Log1(afsd_logp, "CALL FetchStatus vp %x", (long) scp);
- do {
- code = cm_Conn(&scp->fid, userp, reqp, &connp);
- if (code) continue;
+ do {
+ code = cm_Conn(&sfid, userp, reqp, &connp);
+ if (code) continue;
- code = RXAFS_FetchStatus(connp->callp, &tfid,
- &afsStatus, &callback, &volSync);
+ code = RXAFS_FetchStatus(connp->callp, &tfid,
+ &afsStatus, &callback, &volSync);
- } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync,
- &cbr, code));
- code = cm_MapRPCError(code, reqp);
+ } while (cm_Analyze(connp, userp, reqp, &sfid, &volSync, NULL,
+ &cbr, code));
+ code = cm_MapRPCError(code, reqp);
osi_Log0(afsd_logp, "CALL FetchStatus DONE");
lock_ObtainMutex(&scp->mx);
- cm_SyncOpDone(scp, NULL, sflags);
+ cm_SyncOpDone(scp, NULL, sflags);
if (code == 0) {
- cm_EndCallbackGrantingCall(scp, &cbr, &callback, 0);
- cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0);
- }
- else
- cm_EndCallbackGrantingCall(NULL, NULL, NULL, 0);
-
- /* now check to see if we got an error */
- if (code) return code;
- }
+ cm_EndCallbackGrantingCall(scp, &cbr, &callback, 0);
+ cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0);
+ }
+ else
+ cm_EndCallbackGrantingCall(NULL, NULL, NULL, 0);
+
+ /* now check to see if we got an error */
+ if (code) return code;
+ }
}
/* called periodically by cm_daemon to shut down use of expired callbacks */
cm_scache_t *scp;
long now;
+ osi_Log0(afsd_logp, "CheckCBExpiration");
+
now = osi_Time();
lock_ObtainWrite(&cm_scacheLock);
for(i=0; i<cm_hashTableSize; i++) {
lock_ReleaseWrite(&cm_scacheLock);
lock_ObtainMutex(&scp->mx);
if (scp->cbServerp && now > scp->cbExpires) {
+ osi_Log1(afsd_logp, "Discarding SCache scp %x", scp);
cm_DiscardSCache(scp);
}
lock_ReleaseMutex(&scp->mx);
}
lock_ReleaseWrite(&cm_scacheLock);
}
+
+/* debug interface: not implemented */
+int SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
+ char **a_name, serverList *a_hosts)
+{
+ /* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_GetCellByNum - not implemented");
+ return RXGEN_OPCODE;
+}
+
+/* debug interface: not implemented */
+int SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call, afs_int32 a_cellnum,
+ char **a_name, serverList *a_hosts)
+{
+ /* XXXX */
+ osi_Log0(afsd_logp, "SRXAFSCB_TellMeAboutYourself - not implemented");
+ return RXGEN_OPCODE;
+}