} /*SetAccessList */
+/* Must not be called with H_LOCK held */
+static void
+client_CheckRights(struct client *client, struct acl_accessList *ACL,
+ afs_int32 *rights)
+{
+ *rights = 0;
+ ObtainReadLock(&client->lock);
+ if (client->CPS.prlist_len > 0 && !client->deleted &&
+ client->host && !(client->host->hostFlags & HOSTDELETED))
+ acl_CheckRights(ACL, &client->CPS, rights);
+ ReleaseReadLock(&client->lock);
+}
+
+/* Must not be called with H_LOCK held */
+static afs_int32
+client_HasAsMember(struct client *client, afs_int32 id)
+{
+ afs_int32 code = 0;
+
+ ObtainReadLock(&client->lock);
+ if (client->CPS.prlist_len > 0 && !client->deleted &&
+ client->host && !(client->host->hostFlags & HOSTDELETED))
+ ReleaseReadLock(&client->lock);
+ return code;
+}
+
/*
* Compare the directory's ACL with the user's access rights in the client
* connection and return the user's and everybody else's access permissions
#endif
if (acl_CheckRights(ACL, &SystemAnyUserCPS, anyrights) != 0) {
-
ViceLog(0, ("CheckRights failed\n"));
*anyrights = 0;
}
*rights = 0;
- ObtainWriteLock(&client->lock);
- acl_CheckRights(ACL, &client->CPS, rights);
- ReleaseWriteLock(&client->lock);
+ client_CheckRights(client, ACL, rights);
/* wait if somebody else is already doing the getCPS call */
H_LOCK;
acl_CheckRights(ACL, &client->host->hcps, &hrights);
H_UNLOCK;
/* Allow system:admin the rights given with the -implicit option */
- if (acl_IsAMember(SystemId, &client->CPS))
+ if (client_HasAsMember(client, SystemId))
*rights |= implicitAdminRights;
+
*rights |= hrights;
*anyrights |= hrights;
static afs_int32
VanillaUser(struct client *client)
{
- if (acl_IsAMember(SystemId, &client->CPS))
+ if (client_HasAsMember(client, SystemId))
return (0); /* not a system administrator, then you're "vanilla" */
return (1);
return (errorCode);
if (chkforDir == MustBeDIR)
assert((*parent) == 0);
- if ((errorCode = GetClient(tcon, client)) != 0)
- return (errorCode);
- if (!(*client))
- return (EINVAL);
- assert(GetRights(*client, aCL, rights, anyrights) == 0);
+ if (!(*client)) {
+ if ((errorCode = GetClient(tcon, client)) != 0)
+ return (errorCode);
+ if (!(*client))
+ return (EINVAL);
+ }
+ GetRights(*client, aCL, rights, anyrights);
/* ok, if this is not a dir, set the PRSFS_ADMINISTER bit iff we're the owner */
if ((*targetptr)->disk.type != vDirectory) {
/* anyuser can't be owner, so only have to worry about rights, not anyrights */
*/
static void
PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
- Vnode * parentptr, Volume * volptr)
+ Vnode * parentptr, Volume * volptr, struct client **client)
{
int fileCode = 0; /* Error code returned by the volume package */
if (volptr) {
VPutVolume(volptr);
}
+ if (*client) {
+ PutClient(client);
+ }
} /*PutVolumePackage */
static int
* We don't have to check for host's cps since only regular
* viceid are volume owners.
*/
- return (acl_IsAMember(owner, &client->CPS));
+ return (client_HasAsMember(client, owner));
}
} /*VolumeOwner */
&& targetptr->disk.type == vFile)
#ifdef USE_GROUP_PERMS
if (!OWNSp(client, targetptr)
- && !acl_IsAMember(targetptr->disk.owner, &client->CPS)) {
+ && !client_HasAsMember(client, targetptr->disk.owner)) {
errorCode =
(((GROUPREAD | GROUPEXEC) & targetptr->disk.modeBits)
? 0 : EACCES);
if ((targetptr->disk.type == vFile)
&& VanillaUser(client)) {
if (!OWNSp(client, targetptr)
- && !acl_IsAMember(targetptr->disk.owner,
- &client->CPS)) {
+ && !client_HasAsMember(client, targetptr->disk.owner)) {
errorCode =
((GROUPWRITE & targetptr->disk.modeBits)
? 0 : EACCES);
int errorCode = 0; /* return code to caller */
int fileCode = 0; /* return code from vol package */
Volume *volptr = 0; /* pointer to the volume */
- struct client *client; /* pointer to the client data */
+ struct client *client = 0; /* pointer to the client data */
struct rx_connection *tcon; /* the connection we're part of */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client = NULL; /* tmp ptr to client data */
Bad_FetchData:
/* Update and store volume/vnode and parent vnodes back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
ViceLog(2, ("SRXAFS_FetchData returns %d\n", errorCode));
errorCode = CallPostamble(tcon, errorCode);
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
int errorCode = 0; /* return error code to caller */
Volume *volptr = 0; /* pointer to the volume */
- struct client *client; /* pointer to the client data */
+ struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
struct rx_connection *tcon = rx_ConnectionOf(acall);
struct client *t_client = NULL; /* tmp ptr to client data */
Bad_FetchACL:
/* Update and store volume/vnode and parent vnodes back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
ViceLog(2,
("SAFS_FetchACL returns %d (ACL=%s)\n", errorCode,
AccessList->AFSOpaque_val));
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
int errorCode = 0; /* return code to caller */
Volume *volptr = 0; /* pointer to the volume */
- struct client *client; /* pointer to the client data */
+ struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client = NULL; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_FetchStatus:
/* Update and store volume/vnode and parent vnodes back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
ViceLog(2, ("SAFS_FetchStatus returns %d\n", errorCode));
return errorCode;
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
int errorCode = 0; /* return code to caller */
Volume *volptr = 0; /* pointer to the volume */
- struct client *client; /* pointer to the client data */
+ struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
register struct AFSFid *tfid; /* file id we're dealing with now */
struct rx_connection *tcon = rx_ConnectionOf(acall);
/* put back the file ID and volume */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
parentwhentargetnotdir = (Vnode *) 0;
targetptr = (Vnode *) 0;
volptr = (Volume *) 0;
+ client = (struct client *)0;
}
Bad_BulkStatus:
/* Update and store volume/vnode and parent vnodes back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
errorCode = CallPostamble(tcon, errorCode);
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
int errorCode = 0; /* return code to caller */
Volume *volptr = 0; /* pointer to the volume */
- struct client *client; /* pointer to the client data */
+ struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
register struct AFSFid *tfid; /* file id we're dealing with now */
struct rx_connection *tcon;
&rights, &anyrights))) {
tstatus = &OutStats->AFSBulkStats_val[i];
tstatus->errorCode = errorCode;
- PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr);
+ PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
+ volptr, &client);
parentwhentargetnotdir = (Vnode *) 0;
targetptr = (Vnode *) 0;
volptr = (Volume *) 0;
+ client = (struct client *)0;
continue;
}
tstatus = &OutStats->AFSBulkStats_val[i];
tstatus->errorCode = errorCode;
(void)PutVolumePackage(parentwhentargetnotdir, targetptr,
- (Vnode *) 0, volptr);
+ (Vnode *) 0, volptr, &client);
parentwhentargetnotdir = (Vnode *) 0;
targetptr = (Vnode *) 0;
volptr = (Volume *) 0;
+ client = (struct client *)0;
continue;
}
}
/* put back the file ID and volume */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
parentwhentargetnotdir = (Vnode *) 0;
targetptr = (Vnode *) 0;
volptr = (Volume *) 0;
+ client = (struct client *)0;
}
Bad_InlineBulkStatus:
/* Update and store volume/vnode and parent vnodes back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
errorCode = CallPostamble(tcon, errorCode);
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
int errorCode = 0; /* return code for caller */
int fileCode = 0; /* return code from vol package */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client = NULL; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_StoreData:
/* Update and store volume/vnode and parent vnodes back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
ViceLog(2, ("SAFS_StoreData returns %d\n", errorCode));
errorCode = CallPostamble(tcon, errorCode);
int errorCode = 0; /* return code for caller */
struct AFSStoreStatus InStatus; /* Input status for fid */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct rx_connection *tcon;
struct client *t_client = NULL; /* tmp ptr to client data */
Bad_StoreACL:
/* Update and store volume/vnode and parent vnodes back */
- PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr);
+ PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
+ volptr, &client);
ViceLog(2, ("SAFS_StoreACL returns %d\n", errorCode));
errorCode = CallPostamble(tcon, errorCode);
Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
int errorCode = 0; /* return code for caller */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client = NULL; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_StoreStatus:
/* Update and store volume/vnode and parent vnodes back */
- PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr);
+ PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
+ volptr, &client);
ViceLog(2, ("SAFS_StoreStatus returns %d\n", errorCode));
return errorCode;
AFSFid fileFid; /* area for Fid from the directory */
int errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_RemoveFile:
/* Update and store volume/vnode and parent vnodes back */
- PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr, volptr);
+ PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+ volptr, &client);
FidZap(&dir);
ViceLog(2, ("SAFS_RemoveFile returns %d\n", errorCode));
return errorCode;
Volume *volptr = 0; /* pointer to the volume header */
int errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_CreateFile:
/* Update and store volume/vnode and parent vnodes back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
- volptr);
+ volptr, &client);
FidZap(&dir);
ViceLog(2, ("SAFS_CreateFile returns %d\n", errorCode));
return errorCode;
DirHandle filedir; /* Handle for dir package I/O */
DirHandle newfiledir; /* Handle for dir package I/O */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
afs_int32 newrights; /* rights for this user */
afs_int32 newanyrights; /* rights for any user */
VPutVnode(&fileCode, newfileptr);
assert(fileCode == 0);
}
- (void)PutVolumePackage(fileptr,
- (newvptr
- && newvptr != oldvptr ? newvptr : 0), oldvptr,
- volptr);
+ (void)PutVolumePackage(fileptr, (newvptr && newvptr != oldvptr ?
+ newvptr : 0), oldvptr, volptr, &client);
FidZap(&olddir);
FidZap(&newdir);
FidZap(&filedir);
int len, code = 0;
DirHandle dir; /* Handle for dir package I/O */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_SymLink:
/* Write the all modified vnodes (parent, new files) and volume back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
- volptr);
+ volptr, &client);
FidZap(&dir);
ViceLog(2, ("SAFS_Symlink returns %d\n", errorCode));
return ( errorCode ? errorCode : code );
Volume *volptr = 0; /* pointer to the volume header */
int errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_Link:
/* Write the all modified vnodes (parent, new files) and volume back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
- volptr);
+ volptr, &client);
FidZap(&dir);
ViceLog(2, ("SAFS_Link returns %d\n", errorCode));
return errorCode;
int newACLSize; /* Size of access list */
DirHandle dir; /* Handle for dir package I/O */
DirHandle parentdir; /* Handle for dir package I/O */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_MakeDir:
/* Write the all modified vnodes (parent, new files) and volume back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
- volptr);
+ volptr, &client);
FidZap(&dir);
FidZap(&parentdir);
ViceLog(2, ("SAFS_MakeDir returns %d\n", errorCode));
int errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
Vnode debugvnode1, debugvnode2;
struct client *t_client; /* tmp ptr to client data */
Bad_RemoveDir:
/* Write the all modified vnodes (parent, new files) and volume back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
- volptr);
+ volptr, &client);
FidZap(&dir);
ViceLog(2, ("SAFS_RemoveDir returns %d\n", errorCode));
return errorCode;
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
int errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_SetLock:
/* Write the all modified vnodes (parent, new files) and volume back */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
if ((errorCode == VREADONLY) && (type == LockRead))
errorCode = 0; /* allow read locks on RO volumes without saving state */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
int errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_ExtendLock:
/* Put back file's vnode and volume */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
if ((errorCode == VREADONLY)) /* presumably, we already granted this lock */
errorCode = 0; /* under our generous policy re RO vols */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
int errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client structure */
+ struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
Bad_ReleaseLock:
/* Put back file's vnode and volume */
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
if ((errorCode == VREADONLY)) /* presumably, we already granted this lock */
errorCode = 0; /* under our generous policy re RO vols */
{
afs_int32 errorCode = 0;
register int i;
- struct client *client;
+ struct client *client = 0;
struct rx_connection *tcon;
#if FS_STATS_DETAILED
struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
("SAFS_GiveUpAllCallBacks: host=%x\n",
(tcon->peer ? tcon->peer->host : 0)));
errorCode = GetClient(tcon, &client);
- if (!errorCode)
+ if (!errorCode) {
DeleteAllCallBacks_r(client->host, 1);
+ PutClient(&client);
+ }
} else {
if (FidArray->AFSCBFids_len < CallBackArray->AFSCBs_len) {
ViceLog(0,
register struct AFSFid *fid = &(FidArray->AFSCBFids_val[i]);
DeleteCallBack(client->host, fid);
}
+ PutClient(&client);
}
}
afs_int32 nids, naddrs;
afs_int32 *vd, *addr;
int errorCode = 0; /* return code to caller */
- struct client *client;
+ struct client *client = 0;
struct rx_connection *tcon = rx_ConnectionOf(acall);
ViceLog(1, ("SRXAFS_FlushCPS\n"));
Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
int errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client entry */
+ struct client *client = 0; /* pointer to client entry */
afs_int32 rights, anyrights; /* rights for this and any user */
AFSFid dummyFid;
struct rx_connection *tcon;
Bad_GetVolumeStatus:
(void)PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
- volptr);
+ volptr, &client);
ViceLog(2, ("SAFS_GetVolumeStatus returns %d\n", errorCode));
/* next is to guarantee out strings exist for stub */
if (*Name == 0) {
Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
int errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
- struct client *client; /* pointer to client entry */
+ struct client *client = 0; /* pointer to client entry */
afs_int32 rights, anyrights; /* rights for this and any user */
AFSFid dummyFid;
struct rx_connection *tcon = rx_ConnectionOf(acall);
RXUpdate_VolumeStatus(volptr, StoreVolStatus, Name, OfflineMsg, Motd);
Bad_SetVolumeStatus:
- PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0, volptr);
+ PutVolumePackage(parentwhentargetnotdir, targetptr, (Vnode *) 0,
+ volptr, &client);
ViceLog(2, ("SAFS_SetVolumeStatus returns %d\n", errorCode));
errorCode = CallPostamble(tcon, errorCode);
return 0;
if (in < 0 || in > 511)
return in;
+ if (in >= VICE_SPECIAL_ERRORS && in <= VIO || in == VRESTRICTED)
+ return in;
if (sys2et[in] != 0)
return sys2et[in];
return in;
};
static void h_TossStuff_r(register struct host *host);
+static int hashDelete_r(afs_uint32 addr, afs_uint16 port, struct host *host);
/*
* Make sure the subnet macros have been defined.
if (client->refCount) {
char hoststr[16];
ViceLog(0,
- ("Warning: Host %s:%d client %x refcount %d while deleting.\n",
+ ("Warning: Host %s:%d client %x refcount %d while deleting, failing.\n",
afs_inet_ntoa_r(host->host, hoststr),
ntohs(host->port), client, client->refCount));
+ /* This is the same thing we do if the host is locked */
+ return;
}
+ /* We can't protect this without dropping the H_LOCK */
+ client->CPS.prlist_len = 0;
if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) {
free(client->CPS.prlist_val);
client->CPS.prlist_val = NULL;
}
- client->CPS.prlist_len = 0;
if (client->tcon) {
rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
}
afsUUID uuid = oldHost->interface->uuid;
cb_conn = oldHost->callback_rxcon;
rx_GetConnection(cb_conn);
+ rx_SetConnDeadTime(cb_conn, 2);
+ rx_SetConnHardDeadTime(cb_conn, AFS_HARDDEADTIME);
H_UNLOCK;
code = RXAFSCB_ProbeUuid(cb_conn, &uuid);
+ H_LOCK;
+ rx_SetConnDeadTime(cb_conn, 50);
+ rx_SetConnHardDeadTime(cb_conn, AFS_HARDDEADTIME);
rx_PutConnection(cb_conn);
cb_conn=NULL;
- H_LOCK;
if (code && MultiProbeAlternateAddress_r(oldHost)) {
probefail = 1;
}
* the list of interfaces for the existing host and
* delete the host structure we just allocated. */
if (oldHost->host != haddr || oldHost->port != hport) {
- ViceLog(25,
- ("CB: new addr %s:%d for old host %s:%d\n",
- afs_inet_ntoa_r(host->host, hoststr),
- ntohs(host->port),
- afs_inet_ntoa_r(oldHost->host, hoststr2),
- ntohs(oldHost->port)));
+ ViceLog(25,
+ ("CB: new addr %s:%d for old host %s:%d\n",
+ afs_inet_ntoa_r(haddr, hoststr),
+ ntohs(hport),
+ afs_inet_ntoa_r(oldHost->host, hoststr2),
+ ntohs(oldHost->port)));
if (oldHost->host == haddr) {
/* We have just been contacted by a client behind a NAT */
removeInterfaceAddr_r(oldHost, oldHost->host, oldHost->port);
removeInterfaceAddr_r(oldHost, haddr, interface->interface[i].port);
}
}
- addInterfaceAddr_r(oldHost, haddr, hport);
+ addInterfaceAddr_r(oldHost, haddr, hport);
oldHost->host = haddr;
oldHost->port = hport;
}
char uname[PR_MAXNAMELEN];
char tcell[MAXKTCREALMLEN];
int fail = 0;
+ int created = 0;
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
- if (client && !client->deleted) {
+ if (client) {
client->refCount++;
h_Hold_r(client->host);
- if (client->prfail != 2) { /* Could add shared lock on client here */
+ if (!client->deleted && client->prfail != 2) {
+ /* Could add shared lock on client here */
/* note that we don't have to lock entry in this path to
* ensure CPS is initialized, since we don't call rx_SetSpecific
* until initialization is done, and we only get here if
H_UNLOCK;
ObtainWriteLock(&client->lock); /* released at end */
H_LOCK;
- } else if (client) {
- client->refCount++;
}
authClass = rx_SecurityClassOf((struct rx_connection *)tcon);
expTime = 0x7fffffff;
}
- if (!client) {
+ if (!client) { /* loop */
host = h_GetHost_r(tcon); /* Returns it h_Held */
retryfirstclient:
goto retryfirstclient;
}
}
+ created = 1;
client = GetCE();
ObtainWriteLock(&client->lock);
client->refCount = 1;
client->host = host;
- client->next = host->FirstClient;
- host->FirstClient = client;
#if FS_STATS_DETAILED
client->InSameNetwork = host->InSameNetwork;
#endif /* FS_STATS_DETAILED */
client->CPS.prlist_val = 0;
client->CPS.prlist_len = 0;
h_Unlock_r(host);
- CurrentConnections++; /* increment number of connections */
}
}
client->prfail = fail;
oldClient = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
if (oldClient && oldClient->tcon == tcon) {
char hoststr[16];
- oldClient->tcon = (struct rx_connection *)0;
- ViceLog(0, ("FindClient: client %x(%x) already had conn %x (host %s:%d), stolen by client %x(%x)\n",
- oldClient, oldClient->sid, tcon,
- afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
- ntohs(rxr_PortOf(tcon)),
- client, client->sid));
- /* rx_SetSpecific will be done immediately below */
+ if (!oldClient->deleted) {
+ /* if we didn't create it, it's not ours to put back */
+ if (created) {
+ ViceLog(0, ("FindClient: stillborn client %x(%x); conn %x (host %s:%d) had client %x(%x)\n",
+ client, client->sid, tcon,
+ afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
+ ntohs(rxr_PortOf(tcon)),
+ oldClient, oldClient->sid));
+ if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) {
+ free(client->CPS.prlist_val);
+ client->CPS.prlist_val = NULL;
+ }
+ client->CPS.prlist_len = 0;
+ if (client->tcon) {
+ rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
+ }
+ }
+ /* We should perhaps check for 0 here */
+ client->refCount--;
+ ReleaseWriteLock(&client->lock);
+ if (created) {
+ FreeCE(client);
+ created = 0;
+ }
+ ObtainWriteLock(&oldClient->lock);
+ oldClient->refCount++;
+ client = oldClient;
+ } else {
+ oldClient->tcon = (struct rx_connection *)0;
+ ViceLog(0, ("FindClient: deleted client %x(%x) already had conn %x (host %s:%d), stolen by client %x(%x)\n",
+ oldClient, oldClient->sid, tcon,
+ afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
+ ntohs(rxr_PortOf(tcon)),
+ client, client->sid));
+ /* rx_SetSpecific will be done immediately below */
+ }
+ }
+ /* Avoid chaining in more than once. */
+ if (created) {
+ h_Lock_r(host);
+ client->next = host->FirstClient;
+ host->FirstClient = client;
+ h_Unlock_r(host);
+ CurrentConnections++; /* increment number of connections */
}
client->tcon = tcon;
rx_SetSpecific(tcon, rxcon_client_key, client);
register struct client *client;
H_LOCK;
- *cp = client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
+ *cp = NULL;
+ client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
if (client == NULL || client->tcon == NULL) {
ViceLog(0,
("GetClient: no client in conn %x (host %x:%d), VBUSYING\n",
return VICETOKENDEAD;
}
+ client->refCount++;
+ *cp = client;
H_UNLOCK;
return 0;
-
} /*GetClient */
+int
+PutClient(struct client **cp)
+{
+ if (*cp == NULL)
+ return -1;
+
+ H_LOCK;
+ h_ReleaseClient_r(*cp);
+ *cp = NULL;
+ H_UNLOCK;
+ return 0;
+} /*PutClient */
+
/* Client user name for short term use. Note that this is NOT inexpensive */
char *
/* deleted a HashChain structure for this address and host */
/* returns 1 on success */
-int
+static int
hashDelete_r(afs_uint32 addr, afs_uint16 port, struct host *host)
{
int flag;