#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
-
-#ifdef HAVE_STRING_H
#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
#ifndef AFS_LINUX20_ENV
#include <net/if.h>
#include <afs/cellconfig.h>
#include <afs/keys.h>
-#include <afs/auth.h>
#include <signal.h>
#include <afs/partition.h>
#include "viced_prototypes.h"
#include "viced.h"
#include "host.h"
+#include "callback.h"
#include <afs/unified_afs.h>
#include <afs/audit.h>
#include <afs/afsutil.h>
/*
* Externals used by the xstat code.
*/
-extern int VolumeCacheSize, VolumeGets, VolumeReplacements;
+extern VolPkgStats VStats;
extern int CEs, CEBlocks;
extern int HTs, HTBlocks;
int retry_flag = 1;
int code = 0;
char hoststr[16], hoststr2[16];
+ struct ubik_client *uclient;
+
+ *ahostp = NULL;
+
if (!tconn) {
ViceLog(0, ("CallPreamble: unexpected null tconn!\n"));
return -1;
H_LOCK;
retry:
tclient = h_FindClient_r(*tconn);
+ if (!tclient) {
+ ViceLog(0, ("CallPreamble: Couldn't get CPS. Too many lockers\n"));
+ H_UNLOCK;
+ return VBUSY;
+ }
thost = tclient->host;
if (tclient->prfail == 1) { /* couldn't get the CPS */
if (!retry_flag) {
/* Take down the old connection and re-read the key file */
ViceLog(0,
("CallPreamble: Couldn't get CPS. Reconnect to ptserver\n"));
+#ifdef AFS_PTHREAD_ENV
+ uclient = (struct ubik_client *)pthread_getspecific(viced_uclient_key);
+
+ /* Is it still necessary to drop this? We hit the net, we should... */
H_UNLOCK;
- code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
+ if (uclient)
+ hpr_End(uclient);
+ code = hpr_Initialize(&uclient);
+
+ assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0);
H_LOCK;
+#else
+ code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0);
+#endif
if (code) {
h_ReleaseClient_r(tclient);
h_Release_r(thost);
H_LOCK;
tclient = h_FindClient_r(aconn);
+ if (!tclient)
+ goto busyout;
thost = tclient->host;
if (thost->hostFlags & HERRORTRANS)
translate = 1;
held = h_Held_r(thost);
if (held)
h_Release_r(thost);
- if (ahost != thost) {
+ if (ahost && ahost != thost) {
char hoststr[16], hoststr2[16];
ViceLog(0, ("CallPostamble: ahost %s:%d (%x) != thost %s:%d (%x)\n",
- afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port),
+ afs_inet_ntoa_r(ahost->host, hoststr), ntohs(ahost->port),
ahost,
afs_inet_ntoa_r(thost->host, hoststr2), ntohs(thost->port),
thost));
h_Release_r(ahost);
+ } else if (!ahost) {
+ char hoststr[16];
+ ViceLog(0, ("CallPostamble: null ahost for thost %s:%d (%x)\n",
+ afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port),
+ thost));
}
+ busyout:
H_UNLOCK;
return (translate ? sys_error_to_et(ret) : ret);
} /*CallPostamble */
CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
{
int fileCode = 0;
- int errorCode = -1;
+ afs_int32 local_errorCode, errorCode = -1;
static struct timeval restartedat = { 0, 0 };
if (fid->Volume == 0 || fid->Vnode == 0) /* not: || fid->Unique == 0) */
while (1) {
errorCode = 0;
- *volptr = VGetVolume(&errorCode, (afs_int32) fid->Volume);
+ *volptr = VGetVolume(&local_errorCode, &errorCode, (afs_int32) fid->Volume);
if (!errorCode) {
assert(*volptr);
break;
}
}
}
- /* allow read operations on busy volume */
- else if (errorCode == VBUSY && lock == READ_LOCK) {
+ /* allow read operations on busy volume.
+ * must check local_errorCode because demand attach fs
+ * can have local_errorCode == VSALVAGING, errorCode == VBUSY */
+ else if (local_errorCode == VBUSY && lock == READ_LOCK) {
errorCode = 0;
break;
} else if (errorCode)
#endif /* AFS_PTHREAD_ENV */
}
- if (client->host->hcps.prlist_len && !client->host->hcps.prlist_val) {
- ViceLog(0,
- ("CheckRights: len=%u, for host=0x%x\n",
- client->host->hcps.prlist_len, client->host->host));
+ if (!client->host->hcps.prlist_len || !client->host->hcps.prlist_val) {
+ char hoststr[16];
+ ViceLog(5,
+ ("CheckRights: len=%u, for host=%s:%d\n",
+ client->host->hcps.prlist_len,
+ afs_inet_ntoa_r(client->host->host, hoststr),
+ ntohs(client->host->port)));
} else
acl_CheckRights(ACL, &client->host->hcps, &hrights);
H_UNLOCK;
}
ino = VN_GET_INO(targetptr);
- assert(VALID_INO(ino));
+ if (!VALID_INO(ino)) {
+ free(buff);
+ VTakeOffline(volptr);
+ ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
+ return EIO;
+ }
targFdP = IH_OPEN(targetptr->handle);
if (targFdP == NULL) {
rc = errno;
("CopyOnWrite failed: volume %u in partition %s (tried reading %u, read %u, wrote %u, errno %u) volume needs salvage\n",
V_id(volptr), volptr->partition->name, length, rdlen,
wrlen, errno));
-#ifdef FAST_RESTART /* if running in no-salvage, don't core the server */
+#if defined(AFS_DEMAND_ATTACH_FS)
+ ViceLog(0, ("CopyOnWrite failed: requesting salvage\n"));
+#else
ViceLog(0, ("CopyOnWrite failed: taking volume offline\n"));
-#else /* Avoid further corruption and try to get a core. */
- assert(0);
#endif
/* Decrement this inode so salvager doesn't find it. */
FDH_REALLYCLOSE(newFdP);
*/
if ((*targetptr)->disk.uniquifier != fileFid->Unique) {
VTakeOffline(volptr);
+ ViceLog(0,
+ ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
errorCode = VSALVAGE;
return errorCode;
}
errno));
if (errno != ENOENT)
{
+ VTakeOffline(volptr);
ViceLog(0,
("Volume %u now offline, must be salvaged.\n",
volptr->hashid));
- VTakeOffline(volptr);
return (EIO);
}
DT1++;
("Error %d deleting %s\n", code,
(((*targetptr)->disk.type ==
Directory) ? "directory" : "file")));
+ VTakeOffline(volptr);
ViceLog(0,
("Volume %u now offline, must be salvaged.\n",
volptr->hashid));
- VTakeOffline(volptr);
if (!errorCode)
errorCode = code;
}
* SAFS_ReleaseLock)
*/
static afs_int32
-HandleLocking(Vnode * targetptr, afs_int32 rights, ViceLockType LockingType)
+HandleLocking(Vnode * targetptr, struct client *client, afs_int32 rights, ViceLockType LockingType)
{
int Time; /* Used for time */
int writeVnode = targetptr->changed_oldTime; /* save original status */
- /* Does the caller has Lock priviledges; root extends locks, however */
- if (LockingType != LockExtend && !(rights & PRSFS_LOCK))
- return (EACCES);
targetptr->changed_oldTime = 1; /* locking doesn't affect any time stamp */
Time = FT_ApproxTime();
switch (LockingType) {
0;
Time += AFS_LOCKWAIT;
if (LockingType == LockRead) {
+ if ( !(rights & PRSFS_LOCK) &&
+ !(rights & PRSFS_WRITE) &&
+ !(OWNSp(client, targetptr) && (rights & PRSFS_INSERT)) )
+ return(EACCES);
+ return(EACCES);
+
if (targetptr->disk.lock.lockCount >= 0) {
++(targetptr->disk.lock.lockCount);
targetptr->disk.lock.lockTime = Time;
} else
return (EAGAIN);
} else if (LockingType == LockWrite) {
+ if ( !(rights & PRSFS_WRITE) &&
+ !(OWNSp(client, targetptr) && (rights & PRSFS_INSERT)) )
+ return(EACCES);
+
if (targetptr->disk.lock.lockCount == 0) {
targetptr->disk.lock.lockCount = -1;
targetptr->disk.lock.lockTime = Time;
afs_uint32 Length, afs_uint32 FileLength,
struct AFSFetchStatus * OutStatus, struct AFSVolSync * Sync)
{
+ if (FileLength > 0x7fffffff || Pos > 0x7fffffff ||
+ (0x7fffffff - Pos) < Length)
+ return EFBIG;
+
return common_StoreData64(acall, Fid, InStatus, Pos, Length, FileLength,
OutStatus, Sync);
} /*SRXAFS_StoreData */
VPutVnode(&errorCode, testvptr);
if ((top == 1) && (testnode != 0)) {
VTakeOffline(volptr);
+ ViceLog(0,
+ ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
errorCode = EIO;
goto Bad_Rename;
}
/* Write the contents of the symbolic link name into the target inode */
fdP = IH_OPEN(targetptr->handle);
- assert(fdP != NULL);
+ if (fdP == NULL) {
+ (void)PutVolumePackage(parentwhentargetnotdir, targetptr, parentptr,
+ volptr, &client);
+ VTakeOffline(volptr);
+ ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
+ return EIO;
+ }
len = strlen((char *) LinkContents);
- code = (len == FDH_WRITE(fdP, (char *) LinkContents, len)) ? 0 : VDISKFULL;
- if (code) ViceLog(0, ("SAFSS_Symlink FDH_WRITE failed for len=%d, Fid=%u.%d.%d\n", len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
+ code = (len == FDH_WRITE(fdP, (char *) LinkContents, len)) ? 0 : VDISKFULL;
+ if (code)
+ ViceLog(0, ("SAFSS_Symlink FDH_WRITE failed for len=%d, Fid=%u.%d.%d\n", len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
FDH_CLOSE(fdP);
/*
* Set up and return modified status for the parent dir and new symlink
SetVolumeSync(Sync, volptr);
/* Handle the particular type of set locking, type */
- errorCode = HandleLocking(targetptr, rights, type);
+ errorCode = HandleLocking(targetptr, client, rights, type);
Bad_SetLock:
/* Write the all modified vnodes (parent, new files) and volume back */
SetVolumeSync(Sync, volptr);
/* Handle the actual lock extension */
- errorCode = HandleLocking(targetptr, rights, LockExtend);
+ errorCode = HandleLocking(targetptr, client, rights, LockExtend);
Bad_ExtendLock:
/* Put back file's vnode and volume */
SetVolumeSync(Sync, volptr);
/* Handle the actual lock release */
- if ((errorCode = HandleLocking(targetptr, rights, LockRelease)))
+ if ((errorCode = HandleLocking(targetptr, client, rights, LockRelease)))
goto Bad_ReleaseLock;
/* if no more locks left, a callback would be triggered here */
{ /*SRXAFS_XStatsVersion */
struct client *t_client = NULL; /* tmp ptr to client data */
- struct rx_connection *tcon;
+ struct rx_connection *tcon = rx_ConnectionOf(a_call);
#if FS_STATS_DETAILED
struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
struct timeval opStartTime, opStopTime; /* Start/stop times for RPC op */
static void
FillPerfValues(struct afs_PerfStats *a_perfP)
{ /*FillPerfValues */
-
+ afs_uint32 hi, lo;
int dir_Buffers; /*# buffers in use by dir package */
int dir_Calls; /*# read calls in dir package */
int dir_IOs; /*# I/O ops in dir package */
a_perfP->vcache_S_Gets = VnodeClassInfo[vSmall].gets;
a_perfP->vcache_S_Reads = VnodeClassInfo[vSmall].reads;
a_perfP->vcache_S_Writes = VnodeClassInfo[vSmall].writes;
- a_perfP->vcache_H_Entries = VolumeCacheSize;
- a_perfP->vcache_H_Gets = VolumeGets;
- a_perfP->vcache_H_Replacements = VolumeReplacements;
+ a_perfP->vcache_H_Entries = VStats.hdr_cache_size;
+ SplitInt64(VStats.hdr_gets, hi, lo);
+ a_perfP->vcache_H_Gets = lo;
+ SplitInt64(VStats.hdr_loads, hi, lo);
+ a_perfP->vcache_H_Replacements = lo;
/*
* Directory section.
#endif
break;
+ case AFS_XSTATSCOLL_CBSTATS:
+ afs_perfstats.numPerfCalls++;
+
+ dataBytes = sizeof(struct cbcounters);
+ dataBuffP = (afs_int32 *) malloc(dataBytes);
+ {
+ extern struct cbcounters cbstuff;
+ dataBuffP[0]=cbstuff.DeleteFiles;
+ dataBuffP[1]=cbstuff.DeleteCallBacks;
+ dataBuffP[2]=cbstuff.BreakCallBacks;
+ dataBuffP[3]=cbstuff.AddCallBacks;
+ dataBuffP[4]=cbstuff.GotSomeSpaces;
+ dataBuffP[5]=cbstuff.DeleteAllCallBacks;
+ dataBuffP[6]=cbstuff.nFEs;
+ dataBuffP[7]=cbstuff.nCBs;
+ dataBuffP[8]=cbstuff.nblks;
+ dataBuffP[9]=cbstuff.CBsTimedOut;
+ dataBuffP[10]=cbstuff.nbreakers;
+ dataBuffP[11]=cbstuff.GSS1;
+ dataBuffP[12]=cbstuff.GSS2;
+ dataBuffP[13]=cbstuff.GSS3;
+ dataBuffP[14]=cbstuff.GSS4;
+ dataBuffP[15]=cbstuff.GSS5;
+ }
+
+ a_dataP->AFS_CollData_len = dataBytes >> 2;
+ a_dataP->AFS_CollData_val = dataBuffP;
+ break;
+
+
default:
/*
* Illegal collection number.
(tcon->peer ? tcon->peer->host : 0)));
errorCode = GetClient(tcon, &client);
if (!errorCode) {
+ H_LOCK;
DeleteAllCallBacks_r(client->host, 1);
+ H_UNLOCK;
PutClient(&client);
}
} else {
struct host *thost;
afs_int32 *dataBuffP;
afs_int32 dataBytes;
-#if FS_STATS_DETAILED
- struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
- struct timeval opStartTime, opStopTime; /* Start/stop times for RPC op */
- struct timeval elapsedTime; /* Transfer time */
- /*
- * Set our stats pointer, remember when the RPC operation started, and
- * tally the operation.
- */
- opP = &(afs_FullPerfStats.det.rpcOpTimes[FS_STATS_RPCIDX_GETCAPABILITIES]);
FS_LOCK;
- (opP->numOps)++;
+ AFSCallStats.GetCapabilities++, AFSCallStats.TotalCalls++;
+ afs_FullPerfStats.overall.fs_nGetCaps++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
-#endif /* FS_STATS_DETAILED */
+ ViceLog(2, ("SAFS_GetCapabilties\n"));
if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
goto Bad_GetCaps;
- FS_LOCK;
- AFSCallStats.GetCapabilities++, AFSCallStats.TotalCalls++;
- FS_UNLOCK;
dataBytes = 1 * sizeof(afs_int32);
dataBuffP = (afs_int32 *) malloc(dataBytes);
- dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS;
+ dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS | VICED_CAPABILITY_WRITELOCKACL;
#if defined(AFS_64BIT_ENV) && defined(AFS_LARGEFILE_ENV)
dataBuffP[0] |= VICED_CAPABILITY_64BITFILES;
#endif
+ if (saneacls)
+ dataBuffP[0] |= VICED_CAPABILITY_SANEACLS;
capabilities->Capabilities_len = dataBytes / sizeof(afs_int32);
capabilities->Capabilities_val = dataBuffP;
- ViceLog(2, ("SAFS_GetCapabilties\n"));
-
Bad_GetCaps:
code = CallPostamble(tcon, code, thost);
-#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
- fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
- if (code == 0) {
- FS_LOCK;
- (opP->numSuccesses)++;
- fs_stats_AddTo((opP->sumTime), elapsedTime);
- fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
- if (fs_stats_TimeLessThan(elapsedTime, (opP->minTime))) {
- fs_stats_TimeAssign((opP->minTime), elapsedTime);
- }
- if (fs_stats_TimeGreaterThan(elapsedTime, (opP->maxTime))) {
- fs_stats_TimeAssign((opP->maxTime), elapsedTime);
- }
- FS_UNLOCK;
- }
-#endif /* FS_STATS_DETAILED */
+
return 0;
}
fdP = IH_OPEN(ihP);
if (fdP == NULL) {
VTakeOffline(volptr);
+ ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
return EIO;
}
optSize = sendBufSize;
if (tlen < 0) {
FDH_CLOSE(fdP);
VTakeOffline(volptr);
+ ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
return EIO;
}
if (Pos > tlen) {
FDH_CLOSE(fdP);
FreeSendBuffer((struct afs_buffer *)tbuffer);
VTakeOffline(volptr);
+ ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
return EIO;
}
errorCode = rx_Write(Call, tbuffer, wlen);
errorCode = rx_WritevAlloc(Call, tiov, &tnio, RX_MAXIOVECS, wlen);
if (errorCode <= 0) {
FDH_CLOSE(fdP);
- VTakeOffline(volptr);
return EIO;
}
wlen = errorCode;
if (errorCode != wlen) {
FDH_CLOSE(fdP);
VTakeOffline(volptr);
+ ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
return EIO;
}
errorCode = rx_Writev(Call, tiov, tnio, wlen);
if (GetLinkCountAndSize(volptr, fdP, &linkCount, &DataLength) < 0) {
FDH_CLOSE(fdP);
VTakeOffline(volptr);
+ ViceLog(0, ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
return EIO;
}
}
tinode = VN_GET_INO(targetptr);
}
- assert(VALID_INO(tinode));
+ if (!VALID_INO(tinode)) {
+ VTakeOffline(volptr);
+ ViceLog(0,("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
+ return EIO;
+ }
/* compute new file length */
NewLength = DataLength;
sys2et[ENAMETOOLONG] = UAENAMETOOLONG;
sys2et[ENOLCK] = UAENOLCK;
sys2et[ENOSYS] = UAENOSYS;
+#if (ENOTEMPTY != EEXIST)
sys2et[ENOTEMPTY] = UAENOTEMPTY;
+#endif
sys2et[ELOOP] = UAELOOP;
+#if (EWOULDBLOCK != EAGAIN)
sys2et[EWOULDBLOCK] = UAEWOULDBLOCK;
+#endif
sys2et[ENOMSG] = UAENOMSG;
sys2et[EIDRM] = UAEIDRM;
sys2et[ECHRNG] = UAECHRNG;
sys2et[EDQUOT] = UAEDQUOT;
sys2et[ENOMEDIUM] = UAENOMEDIUM;
sys2et[EMEDIUMTYPE] = UAEMEDIUMTYPE;
+
+ sys2et[EIO] = UAEIO;
}
/* NOTE: 2006-03-01
{
Error errorCode = 0;
struct rx_connection *tcon;
+ struct host *tcallhost;
#ifdef __EXPERIMENTAL_CALLBACK_CONN_MOVING
struct host *thost;
struct client *tclient;
- struct client *tcallhost;
static struct rx_securityClass *sc = 0;
int i,j;
struct rx_connection *conn;
#else
H_LOCK;
tclient = h_FindClient_r(tcon);
+ if (!tclient) {
+ errorCode = VBUSY;
+ goto Bad_CallBackRxConnAddr;
+ }
thost = tclient->host;
/* nothing more can be done */
if ( !thost->interface )
goto Bad_CallBackRxConnAddr;
- assert(thost->interface->numberOfInterfaces > 0 );
-
/* the only address is the primary interface */
/* can't change when there's only 1 address, anyway */
- if ( thost->interface->numberOfInterfaces == 1 )
+ if ( thost->interface->numberOfInterfaces <= 1 )
goto Bad_CallBackRxConnAddr;
/* initialise a security object only once */