#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
#include <stdio.h>
#include <stdlib.h>
#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"
struct afs_FSStats afs_fsstats;
-void ResetDebug(), SetDebug(), Terminate();
-
int LogLevel = 0;
int supported = 1;
int Console = 0;
afs_int32 PctSpare;
extern afs_int32 implicitAdminRights;
extern afs_int32 readonlyServer;
+extern int CopyOnWrite_calls, CopyOnWrite_off0, CopyOnWrite_size0;
+extern afs_fsize_t CopyOnWrite_maxsize;
/*
* Externals used by the xstat code.
int retry_flag = 1;
int code = 0;
char hoststr[16], hoststr2[16];
+#ifdef AFS_PTHREAD_ENV
+ struct ubik_client *uclient;
+#endif
+ *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);
+ uclient = NULL;
+ }
+ code = hpr_Initialize(&uclient);
+
+ if (!code)
+ 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);
struct host *thost;
struct client *tclient;
int translate = 0;
- int held;
H_LOCK;
tclient = h_FindClient_r(aconn);
+ if (!tclient)
+ goto busyout;
thost = tclient->host;
if (thost->hostFlags & HERRORTRANS)
translate = 1;
h_ReleaseClient_r(tclient);
- held = h_Held_r(thost);
- if (held)
- h_Release_r(thost);
- if (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),
- ahost,
- afs_inet_ntoa_r(thost->host, hoststr2), ntohs(thost->port),
- thost));
- h_Release_r(ahost);
+
+ if (ahost) {
+ if (ahost != thost) {
+ /* host/client recycle */
+ char hoststr[16], hoststr2[16];
+ ViceLog(0, ("CallPostamble: ahost %s:%d (%p) != thost "
+ "%s:%d (%p)\n",
+ afs_inet_ntoa_r(ahost->host, hoststr),
+ ntohs(ahost->port),
+ ahost,
+ afs_inet_ntoa_r(thost->host, hoststr2),
+ ntohs(thost->port),
+ thost));
+ }
+ /* return the reference taken in CallPreamble */
+ h_Release_r(ahost);
+ } else {
+ char hoststr[16];
+ ViceLog(0, ("CallPostamble: null ahost for thost %s:%d (%p)\n",
+ afs_inet_ntoa_r(thost->host, hoststr),
+ ntohs(thost->port),
+ thost));
}
+
+ /* return the reference taken in local h_FindClient_r--h_ReleaseClient_r
+ * does not decrement refcount on client->host */
+ h_Release_r(thost);
+
+ busyout:
H_UNLOCK;
return (translate ? sys_error_to_et(ret) : ret);
} /*CallPostamble */
static afs_int32
CheckVnode(AFSFid * fid, Volume ** volptr, Vnode ** vptr, int lock)
{
- int fileCode = 0;
- afs_int32 local_errorCode, errorCode = -1;
+ Error fileCode = 0;
+ Error local_errorCode, errorCode = -1;
static struct timeval restartedat = { 0, 0 };
if (fid->Volume == 0 || fid->Vnode == 0) /* not: || fid->Unique == 0) */
extern int VInit;
while (1) {
+ int restarting =
+#ifdef AFS_DEMAND_ATTACH_FS
+ VSALVAGE
+#else
+ VRESTARTING
+#endif
+ ;
+
errorCode = 0;
*volptr = VGetVolume(&local_errorCode, &errorCode, (afs_int32) fid->Volume);
if (!errorCode) {
if (restartedat.tv_sec == 0) {
/* I'm not really worried about when we restarted, I'm */
/* just worried about when the first VBUSY was returned. */
- TM_GetTimeOfDay(&restartedat, 0);
+ FT_GetTimeOfDay(&restartedat, 0);
if (busyonrst) {
FS_LOCK;
afs_perfstats.fs_nBusies++;
FS_UNLOCK;
}
- return (busyonrst ? VBUSY : VRESTARTING);
+ return (busyonrst ? VBUSY : restarting);
} else {
struct timeval now;
- TM_GetTimeOfDay(&now, 0);
+ FT_GetTimeOfDay(&now, 0);
if ((now.tv_sec - restartedat.tv_sec) < (11 * 60)) {
if (busyonrst) {
FS_LOCK;
afs_perfstats.fs_nBusies++;
FS_UNLOCK;
}
- return (busyonrst ? VBUSY : VRESTARTING);
+ return (busyonrst ? VBUSY : restarting);
} else {
- return (VRESTARTING);
+ return (restarting);
}
}
}
* must check local_errorCode because demand attach fs
* can have local_errorCode == VSALVAGING, errorCode == VBUSY */
else if (local_errorCode == VBUSY && lock == READ_LOCK) {
+#ifdef AFS_DEMAND_ATTACH_FS
+ /* DAFS case is complicated by the fact that local_errorCode can
+ * be VBUSY in cases where the volume is truly offline */
+ if (!*volptr) {
+ /* volume is in VOL_STATE_UNATTACHED */
+ return (errorCode);
+ }
+#endif /* AFS_DEMAND_ATTACH_FS */
errorCode = 0;
break;
} else if (errorCode)
assert(Fid != 0);
while (1) {
VnodeId parentvnode;
- int errorCode = 0;
+ Error errorCode = 0;
parentvnode = (*targetptr)->disk.parent;
VPutVnode(&errorCode, *targetptr);
#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;
{
struct acl_accessList *aCL; /* Internal access List */
int aCLSize; /* size of the access list */
- int errorCode = 0; /* return code to caller */
+ Error errorCode = 0; /* return code to caller */
if ((errorCode = CheckVnode(Fid, volptr, targetptr, locktype)))
return (errorCode);
PutVolumePackage(Vnode * parentwhentargetnotdir, Vnode * targetptr,
Vnode * parentptr, Volume * volptr, struct client **client)
{
- int fileCode = 0; /* Error code returned by the volume package */
+ Error fileCode = 0; /* Error code returned by the volume package */
if (parentwhentargetnotdir) {
VPutVnode(&fileCode, parentwhentargetnotdir);
afs_int32 rights, int CallingRoutine,
AFSStoreStatus * InStatus)
{
- int errorCode = 0;
+ Error errorCode = 0;
#define OWNSp(client, target) ((client)->ViceId == (target)->disk.owner)
#define CHOWN(i,t) (((i)->Mask & AFS_SETOWNER) &&((i)->Owner != (t)->disk.owner))
#define CHGRP(i,t) (((i)->Mask & AFS_SETGROUP) &&((i)->Group != (t)->disk.group))
{
char *eACL; /* External access list placeholder */
- if (acl_Externalize
- ((targetptr->disk.type ==
+ if (acl_Externalize_pr
+ (hpr_IdToName, (targetptr->disk.type ==
vDirectory ? VVnodeACL(targetptr) :
VVnodeACL(parentwhentargetnotdir)), &eACL) != 0) {
return EIO;
{
struct acl_accessList *newACL; /* PlaceHolder for new access list */
- if (acl_Internalize(AccessList->AFSOpaque_val, &newACL) != 0)
+ if (acl_Internalize_pr(hpr_NameToId, AccessList->AFSOpaque_val, &newACL)
+ != 0)
return (EINVAL);
if ((newACL->size + 4) > VAclSize(targetptr))
return (E2BIG);
* disk.inodeNumber and cloned)
*/
#define COPYBUFFSIZE 8192
+#define MAXFSIZE (~(afs_fsize_t) 0)
static int
-CopyOnWrite(Vnode * targetptr, Volume * volptr)
+CopyOnWrite(Vnode * targetptr, Volume * volptr, afs_foff_t off, afs_fsize_t len)
{
Inode ino, nearInode;
- int rdlen;
- int wrlen;
+ ssize_t rdlen;
+ ssize_t wrlen;
register afs_fsize_t size;
- register int length;
+ size_t length;
char *buff;
int rc; /* return code */
IHandle_t *newH; /* Use until finished copying, then cp to vnode. */
DFlush(); /* just in case? */
VN_GET_LEN(size, targetptr);
+ if (size > off)
+ size -= off;
+ else
+ size = 0;
+ if (size > len)
+ size = len;
+
buff = (char *)malloc(COPYBUFFSIZE);
if (buff == NULL) {
return EIO;
}
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;
newFdP = IH_OPEN(newH);
assert(newFdP != NULL);
+ FDH_SEEK(targFdP, off, SEEK_SET);
+ FDH_SEEK(newFdP, off, SEEK_SET);
while (size > 0) {
if (size > COPYBUFFSIZE) { /* more than a buffer */
length = COPYBUFFSIZE;
size -= COPYBUFFSIZE;
} else {
- length = (int)size;
+ length = size;
size = 0;
}
rdlen = FDH_READ(targFdP, buff, length);
* error code indicates that the disk is full, we roll-back to
* the initial state.
*/
- if ((rdlen != length) || (wrlen != length))
+ if ((rdlen != length) || (wrlen != length)) {
if ((wrlen < 0) && (errno == ENOSPC)) { /* disk full */
ViceLog(0,
("CopyOnWrite failed: Partition %s containing volume %u is full\n",
free(buff);
return ENOSPC;
} else {
+ /* length, rdlen, and wrlen may or may not be 64-bits wide;
+ * since we never do any I/O anywhere near 2^32 bytes at a
+ * time, just case to an unsigned int for printing */
+
ViceLog(0,
("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 */
- ViceLog(0, ("CopyOnWrite failed: taking volume offline\n"));
-#elif defined(AFS_DEMAND_ATTACH_FS)
+ V_id(volptr), volptr->partition->name, (unsigned)length, (unsigned)rdlen,
+ (unsigned)wrlen, errno));
+#if defined(AFS_DEMAND_ATTACH_FS)
ViceLog(0, ("CopyOnWrite failed: requesting salvage\n"));
-#else /* Avoid further corruption and try to get a core. */
- assert(0);
+#else
+ ViceLog(0, ("CopyOnWrite failed: taking volume offline\n"));
#endif
/* Decrement this inode so salvager doesn't find it. */
FDH_REALLYCLOSE(newFdP);
VTakeOffline(volptr);
return EIO;
}
+ }
#ifndef AFS_PTHREAD_ENV
IOMGR_Poll();
#endif /* !AFS_PTHREAD_ENV */
return 0; /* success */
} /*CopyOnWrite */
+static int
+CopyOnWrite2(FdHandle_t *targFdP, FdHandle_t *newFdP, afs_foff_t off, afs_fsize_t size) {
+ char *buff = (char *)malloc(COPYBUFFSIZE);
+ size_t length;
+ ssize_t rdlen;
+ ssize_t wrlen;
+ int rc;
+
+ FDH_SEEK(targFdP, off, SEEK_SET);
+ FDH_SEEK(newFdP, off, SEEK_SET);
+
+ if (size > FDH_SIZE(targFdP) - off) size = FDH_SIZE(targFdP) - off;
+ while (size > 0) {
+ if (size > COPYBUFFSIZE) { /* more than a buffer */
+ length = COPYBUFFSIZE;
+ size -= COPYBUFFSIZE;
+ } else {
+ length = size;
+ size = 0;
+ }
+ rdlen = FDH_READ(targFdP, buff, length);
+ if (rdlen == length)
+ wrlen = FDH_WRITE(newFdP, buff, length);
+ else
+ wrlen = 0;
+
+ if ((rdlen != length) || (wrlen != length)) {
+ /* no error recovery, at the worst we'll have a "hole" in the file */
+ rc = 1;
+ break;
+ }
+ }
+ free(buff);
+ return rc;
+}
+
/*
* Common code to handle with removing the Name (file when it's called from
DirHandle * dir, AFSFid * fileFid, char *Name, int ChkForDir)
{
DirHandle childdir; /* Handle for dir package I/O */
- int errorCode = 0;
+ Error errorCode = 0;
int code;
/* watch for invalid names */
return (EINVAL);
if (parentptr->disk.cloned) {
ViceLog(25, ("DeleteTarget : CopyOnWrite called\n"));
- if ((errorCode = CopyOnWrite(parentptr, volptr))) {
+ if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE))) {
ViceLog(20,
("DeleteTarget %s: CopyOnWrite failed %d\n", Name,
errorCode));
*/
if ((*targetptr)->disk.uniquifier != fileFid->Unique) {
VTakeOffline(volptr);
+ ViceLog(0,
+ ("Volume %u now offline, must be salvaged.\n",
+ volptr->hashid));
errorCode = VSALVAGE;
return errorCode;
}
SetDirHandle(&childdir, *targetptr);
if (IsEmpty(&childdir) != 0)
return (EEXIST);
- DZap(&childdir);
+ DZap((afs_int32 *) &childdir);
+ FidZap(&childdir);
(*targetptr)->delete = 1;
} else if ((--(*targetptr)->disk.linkCount) == 0)
(*targetptr)->delete = 1;
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;
}
{
afs_fsize_t newlength; /* Holds new directory length */
afs_fsize_t parentLength;
- int errorCode;
+ Error errorCode;
#if FS_STATS_DETAILED
Date currDate; /*Current date */
int writeIdx; /*Write index to bump */
AdjustDiskUsage(Volume * volptr, afs_sfsize_t length,
afs_sfsize_t checkLength)
{
- int rc;
- int nc;
+ Error rc;
+ Error nc;
VAdjustDiskUsage(&rc, volptr, length, checkLength);
if (rc) {
Vnode ** targetptr, char *Name, struct AFSFid *OutFid,
int FileType, afs_sfsize_t BlocksPreallocatedForVnode)
{
- int errorCode = 0; /* Error code returned back */
- int temp;
+ Error errorCode = 0; /* Error code returned back */
+ Error temp;
Inode inode = 0;
Inode nearInode; /* hint for inode allocation in solaris */
AdjustDiskUsage(volptr, BlocksPreallocatedForVnode,
BlocksPreallocatedForVnode))) {
ViceLog(25,
- ("Insufficient space to allocate %lld blocks\n",
+ ("Insufficient space to allocate %" AFS_INT64_FMT " blocks\n",
(afs_intmax_t) BlocksPreallocatedForVnode));
return (errorCode);
}
if (parentptr->disk.cloned) {
ViceLog(25, ("Alloc_NewVnode : CopyOnWrite called\n"));
- if ((errorCode = CopyOnWrite(parentptr, volptr))) { /* disk full */
+ if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE))) { /* disk full */
ViceLog(25, ("Alloc_NewVnode : CopyOnWrite failed\n"));
/* delete the vnode previously allocated */
(*targetptr)->delete = 1;
* 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);
+
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;
status->MinQuota = V_minquota(volptr);
status->MaxQuota = V_maxquota(volptr);
status->BlocksInUse = V_diskused(volptr);
- status->PartBlocksAvail = volptr->partition->free;
- status->PartMaxBlocks = volptr->partition->totalUsable;
+ status->PartBlocksAvail = RoundInt64ToInt32(volptr->partition->free);
+ status->PartMaxBlocks = RoundInt64ToInt32(volptr->partition->totalUsable);
/* now allocate and copy these things; they're freed by the RXGEN stub */
temp = strlen(V_name(volptr)) + 1;
}
afs_int32
-SRXAFS_ResidencyCmd(struct rx_call * acall, struct AFSFid * Fid,
- struct ResidencyCmdInputs * Inputs,
- struct ResidencyCmdOutputs * Outputs)
+SRXAFS_FsCmd(struct rx_call * acall, struct AFSFid * Fid,
+ struct FsCmdInputs * Inputs,
+ struct FsCmdOutputs * Outputs)
{
- return EINVAL;
+ afs_int32 code = 0;
+
+ switch (Inputs->command) {
+ default:
+ code = EINVAL;
+ }
+ ViceLog(1,("FsCmd: cmd = %d, code=%d\n",
+ Inputs->command, Outputs->code));
+ return code;
}
#ifdef AFS_NT40_ENV
Vnode *targetptr = 0; /* pointer to vnode to fetch */
Vnode *parentwhentargetnotdir = 0; /* parent vnode if vptr is a file */
Vnode tparentwhentargetnotdir; /* parent vnode for GetStatus */
- int errorCode = 0; /* return code to caller */
- int fileCode = 0; /* return code from vol package */
+ Error errorCode = 0; /* return code to caller */
+ Error fileCode = 0; /* return code from vol package */
Volume *volptr = 0; /* pointer to the volume */
struct client *client = 0; /* pointer to the client data */
struct rx_connection *tcon; /* the connection we're part of */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
ViceLog(1,
/*
* Remember when the data transfer started.
*/
- TM_GetTimeOfDay(&xferStartTime, 0);
+ FT_GetTimeOfDay(&xferStartTime, 0);
#endif /* FS_STATS_DETAILED */
/* actually do the data transfer */
* integrate the transfer size and elapsed time into the stats. If the
* operation failed, we jump to the appropriate point.
*/
- TM_GetTimeOfDay(&xferStopTime, 0);
+ FT_GetTimeOfDay(&xferStopTime, 0);
FS_LOCK;
(xferP->numXfers)++;
if (!errorCode) {
errorCode = CallPostamble(tcon, errorCode, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
afs_sfsize_t tPos, tLen;
#ifdef AFS_64BIT_ENV
-#ifndef AFS_LARGEFILE_ENV
- if (Pos + Len > 0x7fffffff)
- return EFBIG;
-#endif /* !AFS_LARGEFILE_ENV */
tPos = (afs_sfsize_t) Pos;
tLen = (afs_sfsize_t) Len;
#else /* AFS_64BIT_ENV */
{
Vnode *targetptr = 0; /* pointer to vnode to fetch */
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
- int errorCode = 0; /* return error code to caller */
+ Error errorCode = 0; /* return error code to caller */
Volume *volptr = 0; /* pointer to the volume */
struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
ViceLog(1,
errorCode = CallPostamble(tcon, errorCode, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{
Vnode *targetptr = 0; /* pointer to vnode to fetch */
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
- int errorCode = 0; /* return code to caller */
+ Error errorCode = 0; /* return code to caller */
Volume *volptr = 0; /* pointer to the volume */
struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
afs_int32 nfiles;
Vnode *targetptr = 0; /* pointer to vnode to fetch */
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
- int errorCode = 0; /* return code to caller */
+ Error errorCode = 0; /* return code to caller */
Volume *volptr = 0; /* pointer to the volume */
struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
ViceLog(1, ("SAFS_BulkStatus\n"));
&rights, &anyrights)))
goto Bad_BulkStatus;
/* set volume synchronization information, but only once per call */
- if (i == nfiles)
+ if (i == 0)
SetVolumeSync(Sync, volptr);
/* Are we allowed to fetch Fid's status? */
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
afs_int32 nfiles;
Vnode *targetptr = 0; /* pointer to vnode to fetch */
Vnode *parentwhentargetnotdir = 0; /* parent vnode if targetptr is a file */
- int errorCode = 0; /* return code to caller */
+ Error errorCode = 0; /* return code to caller */
Volume *volptr = 0; /* pointer to the volume */
struct client *client = 0; /* pointer to the client data */
afs_int32 rights, anyrights; /* rights for this and any user */
struct host *thost;
struct client *t_client = NULL; /* tmp ptr to client data */
AFSFetchStatus *tstatus;
+ int VolSync_set = 0;
#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 */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
ViceLog(1, ("SAFS_InlineBulkStatus\n"));
}
CallBacks->AFSCBs_len = nfiles;
+ /* Zero out return values to avoid leaking information on partial succes */
+ memset(OutStats->AFSBulkStats_val, 0, nfiles * sizeof(struct AFSFetchStatus));
+ memset(CallBacks->AFSCBs_val, 0, nfiles * sizeof(struct AFSCallBack));
+ memset(Sync, 0, sizeof(*Sync));
+
if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost))) {
goto Bad_InlineBulkStatus;
}
}
/* set volume synchronization information, but only once per call */
- if (i == nfiles)
+ if (!VolSync_set) {
SetVolumeSync(Sync, volptr);
+ VolSync_set = 1;
+ }
/* Are we allowed to fetch Fid's status? */
if (targetptr->disk.type != vDirectory) {
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *targetptr = 0; /* pointer to input fid */
Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
Vnode tparentwhentargetnotdir; /* parent vnode for GetStatus */
- int errorCode = 0; /* return code for caller */
- int fileCode = 0; /* return code from vol package */
+ Error errorCode = 0; /* return code for caller */
+ Error fileCode = 0; /* return code from vol package */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
ViceLog(1,
("StoreData: Fid = %u.%u.%u\n", Fid->Volume, Fid->Vnode,
Fid->Unique));
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
FS_LOCK;
/*
* Remember when the data transfer started.
*/
- TM_GetTimeOfDay(&xferStartTime, 0);
+ FT_GetTimeOfDay(&xferStartTime, 0);
#endif /* FS_STATS_DETAILED */
/* Do the actual storing of the data */
* integrate the transfer size and elapsed time into the stats. If the
* operation failed, we jump to the appropriate point.
*/
- TM_GetTimeOfDay(&xferStopTime, 0);
+ FT_GetTimeOfDay(&xferStopTime, 0);
FS_LOCK;
(xferP->numXfers)++;
if (!errorCode) {
errorCode = CallPostamble(tcon, errorCode, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
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 */
afs_fsize_t tFileLength;
#ifdef AFS_64BIT_ENV
-#ifndef AFS_LARGEFILE_ENV
- if (FileLength > 0x7fffffff)
- return EFBIG;
-#endif /* !AFS_LARGEFILE_ENV */
tPos = (afs_fsize_t) Pos;
tLength = (afs_fsize_t) Length;
tFileLength = (afs_fsize_t) FileLength;
{
Vnode *targetptr = 0; /* pointer to input fid */
Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
- int errorCode = 0; /* return code for caller */
+ Error errorCode = 0; /* return code for caller */
struct AFSStoreStatus InStatus; /* Input status for fid */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
goto Bad_StoreACL;
errorCode = CallPostamble(tcon, errorCode, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{
Vnode *targetptr = 0; /* pointer to input fid */
Vnode *parentwhentargetnotdir = 0; /* parent of Fid to get ACL */
- int errorCode = 0; /* return code for caller */
+ Error errorCode = 0; /* return code for caller */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *targetptr = 0; /* file to be deleted */
Volume *volptr = 0; /* pointer to the volume header */
AFSFid fileFid; /* area for Fid from the directory */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *targetptr = 0; /* vnode of the new file */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
Volume *volptr = 0; /* pointer to the volume header */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
memset(OutFid, 0, sizeof(struct AFSFid));
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *newfileptr = 0; /* vnode of the file to delete */
Vnode *testvptr = 0; /* used in directory tree walk */
Vnode *parent = 0; /* parent for use in SetAccessList */
- int errorCode = 0; /* error code */
- int fileCode = 0; /* used when writing Vnodes */
+ Error errorCode = 0; /* error code */
+ Error fileCode = 0; /* used when writing Vnodes */
VnodeId testnode; /* used in directory tree walk */
AFSFid fileFid; /* Fid of file to move */
AFSFid newFileFid; /* Fid of new file */
afs_int32 newanyrights; /* rights for any user */
int doDelete; /* deleted the rename target (ref count now 0) */
int code;
+ int updatefile = 0; /* are we changing the renamed file? (we do this
+ * if we need to update .. on a renamed dir) */
struct client *t_client; /* tmp ptr to client data */
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
struct rx_connection *tcon = rx_ConnectionOf(acall);
*/
if (oldvptr->disk.cloned) {
ViceLog(25, ("Rename : calling CopyOnWrite on old dir\n"));
- if ((errorCode = CopyOnWrite(oldvptr, volptr)))
+ if ((errorCode = CopyOnWrite(oldvptr, volptr, 0, MAXFSIZE)))
goto Bad_Rename;
}
SetDirHandle(&olddir, oldvptr);
if (newvptr->disk.cloned) {
ViceLog(25, ("Rename : calling CopyOnWrite on new dir\n"));
- if ((errorCode = CopyOnWrite(newvptr, volptr)))
+ if ((errorCode = CopyOnWrite(newvptr, volptr, 0, MAXFSIZE)))
goto Bad_Rename;
}
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;
}
assert(errorCode == 0);
}
}
+
+ if (fileptr->disk.type == vDirectory) {
+ SetDirHandle(&filedir, fileptr);
+ if (oldvptr != newvptr) {
+ /* we always need to update .. if we've moving fileptr to a
+ * different directory */
+ updatefile = 1;
+ } else {
+ struct AFSFid unused;
+
+ code = Lookup(&filedir, "..", &unused);
+ if (code == ENOENT) {
+ /* only update .. if it doesn't already exist */
+ updatefile = 1;
+ }
+ }
+ }
+
/* Do the CopyonWrite first before modifying anything else. Copying is
- * required because we may have to change entries for ..
+ * required when we have to change entries for ..
*/
- if ((fileptr->disk.type == vDirectory) && (fileptr->disk.cloned)) {
+ if (updatefile && (fileptr->disk.cloned)) {
ViceLog(25, ("Rename : calling CopyOnWrite on target dir\n"));
- if ((errorCode = CopyOnWrite(fileptr, volptr)))
+ if ((errorCode = CopyOnWrite(fileptr, volptr, 0, MAXFSIZE)))
goto Bad_Rename;
}
if (oldvptr == newvptr)
oldvptr->disk.dataVersion--; /* Since it was bumped by 2! */
- fileptr->disk.parent = newvptr->vnodeNumber;
- fileptr->changed_newTime = 1; /* status change of moved file */
+ if (fileptr->disk.parent != newvptr->vnodeNumber) {
+ fileptr->disk.parent = newvptr->vnodeNumber;
+ fileptr->changed_newTime = 1;
+ }
- /* if we are dealing with a rename of a directory */
- if (fileptr->disk.type == vDirectory) {
+ /* if we are dealing with a rename of a directory, and we need to
+ * update the .. entry of that directory */
+ if (updatefile) {
assert(!fileptr->disk.cloned);
- SetDirHandle(&filedir, fileptr);
+
+ fileptr->changed_newTime = 1; /* status change of moved file */
+
/* fix .. to point to the correct place */
Delete(&filedir, ".."); /* No assert--some directories may be bad */
assert(Create(&filedir, "..", NewDirFid) == 0);
fileptr->disk.dataVersion++;
+
/* if the parent directories are different the link counts have to be */
/* changed due to .. in the renamed directory */
if (oldvptr != newvptr) {
BreakCallBack(client->host, NewDirFid, 0);
if (oldvptr != newvptr) {
BreakCallBack(client->host, OldDirFid, 0);
- if (fileptr->disk.type == vDirectory) /* if a dir moved, .. changed */
- BreakCallBack(client->host, &fileFid, 0);
+ }
+ if (updatefile) {
+ /* if a dir moved, .. changed */
+ BreakCallBack(client->host, &fileFid, 0);
}
if (newfileptr) {
/* Note: it is not necessary to break the callback */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *parentptr = 0; /* vnode of input Directory */
Vnode *targetptr = 0; /* vnode of the new link */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
- int errorCode = 0; /* error code */
- int len, code = 0;
+ Error errorCode = 0; /* error code */
+ afs_sfsize_t len;
+ int code = 0;
DirHandle dir; /* Handle for dir package I/O */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
/* 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", (int)len, OutFid->Volume, OutFid->Vnode, OutFid->Unique));
FDH_CLOSE(fdP);
/*
* Set up and return modified status for the parent dir and new symlink
afs_int32
-SRXAFS_Symlink(acall, DirFid, Name, LinkContents, InStatus, OutFid,
- OutFidStatus, OutDirStatus, Sync)
- struct AFSVolSync *Sync;
- struct rx_call *acall; /* Rx call */
- struct AFSFid *DirFid; /* Parent dir's fid */
- char *Name; /* File name to create */
- char *LinkContents; /* Contents of the new created file */
- struct AFSStoreStatus *InStatus; /* Input status for the new symbolic link */
- struct AFSFid *OutFid; /* Fid for newly created symbolic link */
- struct AFSFetchStatus *OutFidStatus; /* Output status for new symbolic link */
- struct AFSFetchStatus *OutDirStatus; /* Output status for parent dir */
-
+SRXAFS_Symlink(struct rx_call *acall, /* Rx call */
+ struct AFSFid *DirFid, /* Parent dir's fid */
+ char *Name, /* File name to create */
+ char *LinkContents, /* Contents of the new created file */
+ struct AFSStoreStatus *InStatus, /* Input status for the new symbolic link */
+ struct AFSFid *OutFid, /* Fid for newly created symbolic link */
+ struct AFSFetchStatus *OutFidStatus, /* Output status for new symbolic link */
+ struct AFSFetchStatus *OutDirStatus, /* Output status for parent dir */
+ struct AFSVolSync *Sync)
{
afs_int32 code;
struct rx_connection *tcon;
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *targetptr = 0; /* vnode of the new file */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
Volume *volptr = 0; /* pointer to the volume header */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
}
if (parentptr->disk.cloned) {
ViceLog(25, ("Link : calling CopyOnWrite on target dir\n"));
- if ((errorCode = CopyOnWrite(parentptr, volptr)))
+ if ((errorCode = CopyOnWrite(parentptr, volptr, 0, MAXFSIZE)))
goto Bad_Link; /* disk full error */
}
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *targetptr = 0; /* vnode of the new file */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
Volume *volptr = 0; /* pointer to the volume header */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
struct acl_accessList *newACL; /* Access list */
int newACLSize; /* Size of access list */
DirHandle dir; /* Handle for dir package I/O */
/* Actually create the New directory in the directory package */
SetDirHandle(&dir, targetptr);
- assert(!(MakeDir(&dir, OutFid, DirFid)));
+ assert(!(MakeDir(&dir, (afs_int32 *)OutFid, (afs_int32 *)DirFid)));
DFlush();
VN_SET_LEN(targetptr, (afs_fsize_t) Length(&dir));
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
goto Bad_MakeDir;
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
Vnode *targetptr = 0; /* file to be deleted */
AFSFid fileFid; /* area for Fid from the directory */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
DirHandle dir; /* Handle for dir package I/O */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{
Vnode *targetptr = 0; /* vnode of input file */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
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 */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{
Vnode *targetptr = 0; /* vnode of input file */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
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 */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{
Vnode *targetptr = 0; /* vnode of input file */
Vnode *parentwhentargetnotdir = 0; /* parent for use in SetAccessList */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client structure */
afs_int32 rights, anyrights; /* rights for this and any user */
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 */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
struct timeval time;
/* this works on all system types */
- TM_GetTimeOfDay(&time, 0);
+ FT_GetTimeOfDay(&time, 0);
stats->CurrentTime = time.tv_sec;
} /*SetSystemStats */
void
SetVolumeStats(struct AFSStatistics *stats)
{
- struct DiskPartition *part;
+ struct DiskPartition64 *part;
int i = 0;
for (part = DiskPartitionList; part && i < AFS_MSTATDISKS;
part = part->next) {
- stats->Disks[i].TotalBlocks = part->totalUsable;
- stats->Disks[i].BlocksAvailable = part->free;
+ stats->Disks[i].TotalBlocks = RoundInt64ToInt32(part->totalUsable);
+ stats->Disks[i].BlocksAvailable = RoundInt64ToInt32(part->free);
memset(stats->Disks[i].Name, 0, AFS_DISKNAMESIZE);
strncpy(stats->Disks[i].Name, part->name, AFS_DISKNAMESIZE);
i++;
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
+ if (code == 0) {
+ FS_LOCK;
+ (opP->numSuccesses)++;
+ fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
+ 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 */
+
+ osi_auditU(acall, GetStatisticsEvent, code,
+ AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+ return code;
+} /*SRXAFS_GetStatistics */
+
+
+afs_int32
+SRXAFS_GetStatistics64(struct rx_call *acall, afs_int32 statsVersion, ViceStatistics64 *Statistics)
+{
+ extern afs_int32 StartTime, CurrentConnections;
+ int seconds;
+ afs_int32 code;
+ struct rx_connection *tcon = rx_ConnectionOf(acall);
+ struct host *thost;
+ struct client *t_client = NULL; /* tmp ptr to client data */
+ struct timeval time;
+#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_GETSTATISTICS]);
+ FS_LOCK;
+ (opP->numOps)++;
+ FS_UNLOCK;
+ FT_GetTimeOfDay(&opStartTime, 0);
+#endif /* FS_STATS_DETAILED */
+
+ if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+ goto Bad_GetStatistics64;
+
+ ViceLog(1, ("SAFS_GetStatistics64 Received\n"));
+ Statistics->ViceStatistics64_val =
+ malloc(statsVersion*sizeof(afs_int64));
+ Statistics->ViceStatistics64_len = statsVersion;
+ FS_LOCK;
+ AFSCallStats.GetStatistics++, AFSCallStats.TotalCalls++;
+ Statistics->ViceStatistics64_val[STATS64_STARTTIME] = StartTime;
+ Statistics->ViceStatistics64_val[STATS64_CURRENTCONNECTIONS] =
+ CurrentConnections;
+ Statistics->ViceStatistics64_val[STATS64_TOTALVICECALLS] =
+ AFSCallStats.TotalCalls;
+ Statistics->ViceStatistics64_val[STATS64_TOTALFETCHES] =
+ AFSCallStats.FetchData + AFSCallStats.FetchACL +
+ AFSCallStats.FetchStatus;
+ Statistics->ViceStatistics64_val[STATS64_FETCHDATAS] =
+ AFSCallStats.FetchData;
+ Statistics->ViceStatistics64_val[STATS64_FETCHEDBYTES] =
+ AFSCallStats.TotalFetchedBytes;
+ seconds = AFSCallStats.AccumFetchTime / 1000;
+ if (seconds <= 0)
+ seconds = 1;
+ Statistics->ViceStatistics64_val[STATS64_FETCHDATARATE] =
+ AFSCallStats.TotalFetchedBytes / seconds;
+ Statistics->ViceStatistics64_val[STATS64_TOTALSTORES] =
+ AFSCallStats.StoreData + AFSCallStats.StoreACL +
+ AFSCallStats.StoreStatus;
+ Statistics->ViceStatistics64_val[STATS64_STOREDATAS] =
+ AFSCallStats.StoreData;
+ Statistics->ViceStatistics64_val[STATS64_STOREDBYTES] =
+ AFSCallStats.TotalStoredBytes;
+ seconds = AFSCallStats.AccumStoreTime / 1000;
+ if (seconds <= 0)
+ seconds = 1;
+ Statistics->ViceStatistics64_val[STATS64_STOREDATARATE] =
+ AFSCallStats.TotalStoredBytes / seconds;
+#ifdef AFS_NT40_ENV
+ Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] = -1;
+#else
+ Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] =
+ (afs_int32) ((long)sbrk(0) >> 10);
+#endif
+ FS_UNLOCK;
+ h_GetWorkStats((int *)&(Statistics->ViceStatistics64_val[STATS64_WORKSTATIONS]),
+ (int *)&(Statistics->ViceStatistics64_val[STATS64_ACTIVEWORKSTATIONS]),
+ (int *)0,
+ (afs_int32) (FT_ApproxTime()) - (15 * 60));
+
+
+
+ /* this works on all system types */
+ FT_GetTimeOfDay(&time, 0);
+ Statistics->ViceStatistics64_val[STATS64_CURRENTTIME] = time.tv_sec;
+
+ Bad_GetStatistics64:
+ code = CallPostamble(tcon, code, thost);
+
+ t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
+
+#if FS_STATS_DETAILED
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{ /*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 */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
*a_versionP = AFS_XSTAT_VERSION;
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
fs_stats_AddTo((opP->sumTime), elapsedTime);
fs_stats_SquareAddTo((opP->sqrTime), elapsedTime);
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
/*
} /*Switch on collection number */
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if (FidArray)
(tcon->peer ? tcon->peer->host : 0)));
errorCode = GetClient(tcon, &client);
if (!errorCode) {
+ H_LOCK;
DeleteAllCallBacks_r(client->host, 1);
+ H_UNLOCK;
PutClient(&client);
}
} else {
errorCode = CallPostamble(tcon, errorCode, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
afs_int32 code;
struct rx_connection *tcon;
struct host *thost;
- afs_int32 *dataBuffP;
+ afs_uint32 *dataBuffP;
afs_int32 dataBytes;
FS_LOCK;
goto Bad_GetCaps;
dataBytes = 1 * sizeof(afs_int32);
- dataBuffP = (afs_int32 *) malloc(dataBytes);
- dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS;
-#if defined(AFS_64BIT_ENV) && defined(AFS_LARGEFILE_ENV)
+ dataBuffP = (afs_uint32 *) malloc(dataBytes);
+ dataBuffP[0] = VICED_CAPABILITY_ERRORTRANS | VICED_CAPABILITY_WRITELOCKACL;
+#if defined(AFS_64BIT_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;
int i;
afs_int32 nids, naddrs;
afs_int32 *vd, *addr;
- int errorCode = 0; /* return code to caller */
+ Error errorCode = 0; /* return code to caller */
struct client *client = 0;
- struct rx_connection *tcon = rx_ConnectionOf(acall);
ViceLog(1, ("SRXAFS_FlushCPS\n"));
FS_LOCK;
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
goto Bad_GetVolumeInfo;
code = CallPostamble(tcon, code, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{
Vnode *targetptr = 0; /* vnode of the new file */
Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client entry */
afs_int32 rights, anyrights; /* rights for this and any user */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid));
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
{
Vnode *targetptr = 0; /* vnode of the new file */
Vnode *parentwhentargetnotdir = 0; /* vnode of parent */
- int errorCode = 0; /* error code */
+ Error errorCode = 0; /* error code */
Volume *volptr = 0; /* pointer to the volume header */
struct client *client = 0; /* pointer to client entry */
afs_int32 rights, anyrights; /* rights for this and any user */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid));
t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
char *temp;
struct rx_connection *tcon;
struct host *thost;
+ Error errorCode = 0;
#endif
- int errorCode = 0;
#if FS_STATS_DETAILED
struct fs_stats_opTimingData *opP; /* Ptr to this op's timing struct */
struct timeval opStartTime; /* Start time for RPC op */
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
return FSERR_EOPNOTSUPP;
errorCode = CallPostamble(tcon, errorCode, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (errorCode == 0) {
FS_LOCK;
(opP->numSuccesses)++;
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
code = CallPostamble(tcon, code, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
if (code == 0) {
FS_LOCK;
(opP->numSuccesses)++;
FS_LOCK;
(opP->numOps)++;
FS_UNLOCK;
- TM_GetTimeOfDay(&opStartTime, 0);
+ FT_GetTimeOfDay(&opStartTime, 0);
#endif /* FS_STATS_DETAILED */
if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
FS_LOCK;
AFSCallStats.GetTime++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
- TM_GetTimeOfDay(&tpl, 0);
+ FT_GetTimeOfDay(&tpl, 0);
*Seconds = tpl.tv_sec;
*USeconds = tpl.tv_usec;
code = CallPostamble(tcon, code, thost);
#if FS_STATS_DETAILED
- TM_GetTimeOfDay(&opStopTime, 0);
+ FT_GetTimeOfDay(&opStopTime, 0);
fs_stats_GetDiff(elapsedTime, opStartTime, opStopTime);
if (code == 0) {
FS_LOCK;
)
{
struct timeval StartTime, StopTime; /* used to calculate file transfer rates */
- int errorCode = 0; /* Returned error code to caller */
IHandle_t *ihP;
FdHandle_t *fdP;
#ifdef AFS_NT40_ENV
rx_Write(Call, (char *)&zero, sizeof(afs_int32)); /* send 0-length */
return (0);
}
- TM_GetTimeOfDay(&StartTime, 0);
+ FT_GetTimeOfDay(&StartTime, 0);
ihP = targetptr->handle;
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) {
Len = 0;
}
- if (Pos + Len > tlen)
- Len = tlen - Pos; /* get length we should send */
+ if (Pos + Len > tlen) /* get length we should send */
+ Len = ((tlen - Pos) < 0) ? 0 : tlen - Pos;
+
(void)FDH_SEEK(fdP, Pos, 0);
{
afs_int32 high, low;
tbuffer = AllocSendBuffer();
#endif /* AFS_NT40_ENV */
while (Len > 0) {
- int wlen;
+ size_t wlen;
+ ssize_t nBytes;
if (Len > optSize)
wlen = optSize;
else
- wlen = (int)Len;
+ wlen = Len;
#ifdef AFS_NT40_ENV
- errorCode = FDH_READ(fdP, tbuffer, wlen);
- if (errorCode != wlen) {
+ nBytes = FDH_READ(fdP, tbuffer, wlen);
+ if (nBytes != wlen) {
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);
+ nBytes = rx_Write(Call, tbuffer, wlen);
#else /* AFS_NT40_ENV */
- errorCode = rx_WritevAlloc(Call, tiov, &tnio, RX_MAXIOVECS, wlen);
- if (errorCode <= 0) {
+ nBytes = rx_WritevAlloc(Call, tiov, &tnio, RX_MAXIOVECS, wlen);
+ if (nBytes <= 0) {
FDH_CLOSE(fdP);
- VTakeOffline(volptr);
return EIO;
}
- wlen = errorCode;
- errorCode = FDH_READV(fdP, tiov, tnio);
- if (errorCode != wlen) {
+ wlen = nBytes;
+ nBytes = FDH_READV(fdP, tiov, tnio);
+ if (nBytes != 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);
+ nBytes = rx_Writev(Call, tiov, tnio, wlen);
#endif /* AFS_NT40_ENV */
#if FS_STATS_DETAILED
/*
* Bump the number of bytes actually sent by the number from this
* latest iteration
*/
- (*a_bytesFetchedP) += errorCode;
+ (*a_bytesFetchedP) += nBytes;
#endif /* FS_STATS_DETAILED */
- if (errorCode != wlen) {
+ if (nBytes != wlen) {
FDH_CLOSE(fdP);
#ifdef AFS_NT40_ENV
FreeSendBuffer((struct afs_buffer *)tbuffer);
FreeSendBuffer((struct afs_buffer *)tbuffer);
#endif /* AFS_NT40_ENV */
FDH_CLOSE(fdP);
- TM_GetTimeOfDay(&StopTime, 0);
+ FT_GetTimeOfDay(&StopTime, 0);
/* Adjust all Fetch Data related stats */
FS_LOCK;
{
afs_sfsize_t bytesTransfered; /* number of bytes actually transfered */
struct timeval StartTime, StopTime; /* Used to measure how long the store takes */
- int errorCode = 0; /* Returned error code to caller */
+ Error errorCode = 0; /* Returned error code to caller */
#ifdef AFS_NT40_ENV
register char *tbuffer; /* data copying buffer */
#else /* AFS_NT40_ENV */
afs_sfsize_t tlen; /* temp for xfr length */
Inode tinode; /* inode for I/O */
afs_int32 optSize; /* optimal transfer size */
- afs_sfsize_t DataLength; /* size of inode */
+ afs_sfsize_t DataLength = 0; /* size of inode */
afs_sfsize_t TruncatedLength; /* size after ftruncate */
afs_fsize_t NewLength; /* size after this store completes */
afs_sfsize_t adjustSize; /* bytes to call VAdjust... with */
- int linkCount; /* link count on inode */
- FdHandle_t *fdP;
+ int linkCount = 0; /* link count on inode */
+ afs_fsize_t CoW_off, CoW_len;
+ ssize_t nBytes;
+ FdHandle_t *fdP, *origfdP = NULL;
struct in_addr logHostAddr; /* host ip holder for inet_ntoa */
#if FS_STATS_DETAILED
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;
}
* mechanisms (i.e. copy on write overhead.) Also the right size
* of the disk will be recorded...
*/
- FDH_CLOSE(fdP);
+ origfdP = fdP;
VN_GET_LEN(size, targetptr);
volptr->partition->flags &= ~PART_DONTUPDATE;
VSetPartitionDiskUsage(volptr->partition);
volptr->partition->flags |= PART_DONTUPDATE;
if ((errorCode = VDiskUsage(volptr, nBlocks(size)))) {
volptr->partition->flags &= ~PART_DONTUPDATE;
+ FDH_CLOSE(origfdP);
return (errorCode);
}
- ViceLog(25, ("StoreData : calling CopyOnWrite on target dir\n"));
- if ((errorCode = CopyOnWrite(targetptr, volptr))) {
+ CoW_len = (FileLength >= (Length + Pos)) ? FileLength - Length : Pos;
+ CopyOnWrite_calls++;
+ if (CoW_len == 0) CopyOnWrite_size0++;
+ if (Pos == 0) CopyOnWrite_off0++;
+ if (CoW_len > CopyOnWrite_maxsize) CopyOnWrite_maxsize = CoW_len;
+
+ ViceLog(1, ("StoreData : calling CopyOnWrite on vnode %u.%u (%s) "
+ "off 0x0 size 0x%llx\n",
+ afs_printable_VolumeId_u(V_id(volptr)),
+ afs_printable_VnodeId_u(targetptr->vnodeNumber),
+ V_name(volptr), Pos));
+ if ((errorCode = CopyOnWrite(targetptr, volptr, 0, Pos))) {
ViceLog(25, ("StoreData : CopyOnWrite failed\n"));
volptr->partition->flags &= ~PART_DONTUPDATE;
+ FDH_CLOSE(origfdP);
return (errorCode);
}
volptr->partition->flags &= ~PART_DONTUPDATE;
if (fdP == NULL) {
ViceLog(25,
("StoreData : Reopen after CopyOnWrite failed\n"));
+ FDH_CLOSE(origfdP);
return ENOENT;
}
}
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;
AdjustDiskUsage(volptr, adjustSize,
adjustSize - SpareComp(volptr)))) {
FDH_CLOSE(fdP);
+ if (origfdP) FDH_CLOSE(origfdP);
return (errorCode);
}
/* this bit means that the locks are set and protections are OK */
rx_SetLocalStatus(Call, 1);
- TM_GetTimeOfDay(&StartTime, 0);
+ FT_GetTimeOfDay(&StartTime, 0);
optSize = sendBufSize;
ViceLog(25,
/* Set the file's length; we've already done an lseek to the right
* spot above.
*/
- errorCode = FDH_WRITE(fdP, &tlen, 1);
- if (errorCode != 1)
+ nBytes = FDH_WRITE(fdP, &tlen, 1);
+ if (nBytes != 1) {
+ errorCode = -1;
goto done;
+ }
errorCode = FDH_TRUNC(fdP, Pos);
} else {
/* have some data to copy */
#else /* AFS_NT40_ENV */
errorCode = rx_Readv(Call, tiov, &tnio, RX_MAXIOVECS, rlen);
#endif /* AFS_NT40_ENV */
-#if FS_STATS_DETAILED
- (*a_bytesStoredP) += errorCode;
-#endif /* FS_STATS_DETAILED */
if (errorCode <= 0) {
errorCode = -32;
break;
}
+#if FS_STATS_DETAILED
+ (*a_bytesStoredP) += errorCode;
+#endif /* FS_STATS_DETAILED */
rlen = errorCode;
#ifdef AFS_NT40_ENV
- errorCode = FDH_WRITE(fdP, tbuffer, rlen);
+ nBytes = FDH_WRITE(fdP, tbuffer, rlen);
#else /* AFS_NT40_ENV */
- errorCode = FDH_WRITEV(fdP, tiov, tnio);
+ nBytes = FDH_WRITEV(fdP, tiov, tnio);
#endif /* AFS_NT40_ENV */
- if (errorCode != rlen) {
+ if (nBytes != rlen) {
errorCode = VDISKFULL;
break;
}
* need to update the target vnode.
*/
targetptr->changed_newTime = 1;
+ if (origfdP && (bytesTransfered < Length)) /* Need to "finish" CopyOnWrite still */
+ CopyOnWrite2(origfdP, fdP, Pos + bytesTransfered, NewLength - Pos - bytesTransfered);
+ if (origfdP) FDH_CLOSE(origfdP);
FDH_CLOSE(fdP);
/* set disk usage to be correct */
VAdjustDiskUsage(&errorCode, volptr,
nBlocks(NewLength)), 0);
return errorCode;
}
+ if (origfdP) { /* finish CopyOnWrite */
+ if ( (CoW_off = Pos + Length) < NewLength) {
+ errorCode = CopyOnWrite2(origfdP, fdP, CoW_off, CoW_len = NewLength - CoW_off);
+ ViceLog(1, ("StoreData : CopyOnWrite2 on vnode %u.%u (%s) "
+ "off 0x%llx size 0x%llx returns %d\n",
+ afs_printable_VolumeId_u(V_id(volptr)),
+ afs_printable_VnodeId_u(targetptr->vnodeNumber),
+ V_name(volptr), CoW_off, CoW_len, errorCode));
+ }
+ FDH_CLOSE(origfdP);
+ }
FDH_CLOSE(fdP);
- TM_GetTimeOfDay(&StopTime, 0);
+ FT_GetTimeOfDay(&StopTime, 0);
VN_SET_LEN(targetptr, NewLength);
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
struct rx_connection *conn;
#endif
- if (errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &tcallhost))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &tcallhost)))
goto Bad_CallBackRxConnAddr1;
#ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING
#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 */
return 0;
if (in < 0 || in > 511)
return in;
- if (in >= VICE_SPECIAL_ERRORS && in <= VIO || in == VRESTRICTED)
+ if ((in >= VICE_SPECIAL_ERRORS && in <= VIO) || in == VRESTRICTED)
return in;
if (sys2et[in] != 0)
return sys2et[in];