#include <afs/opr.h>
#include <rx/rx_queue.h>
#include <opr/lock.h>
+#include <opr/proc.h>
#include <afs/nfs.h>
#include <afs/afsint.h>
#include <afs/vldbint.h>
#define CREATE_SGUID_ADMIN_ONLY 1
+
+/**
+ * Abort the fileserver on fatal errors returned from vnode operations.
+ */
+#define assert_vnode_success_or_salvaging(code) \
+ opr_Assert((code) == 0 || (code) == VSALVAGE || (code) == VSALVAGING)
+
extern struct afsconf_dir *confDir;
extern afs_int32 dataVersionHigh;
struct afs_FSStats afs_fsstats;
-int LogLevel = 0;
int supported = 1;
int Console = 0;
afs_int32 BlocksSpare = 1024; /* allow 1 MB overruns */
afs_int32 PctSpare;
extern afs_int32 implicitAdminRights;
extern afs_int32 readonlyServer;
+extern afs_int32 adminwriteServer;
extern int CopyOnWrite_calls, CopyOnWrite_off0, CopyOnWrite_size0;
extern afs_fsize_t CopyOnWrite_maxsize;
return 0;
}
+static void
+LogClientError(const char *message, struct rx_connection *tcon, afs_int32 viceid, struct AFSFid *Fid)
+{
+ char hoststr[16];
+ if (Fid) {
+ ViceLog(0, ("%s while handling request from host %s:%d viceid %d "
+ "fid %" AFS_VOLID_FMT ".%lu.%lu, failing request\n",
+ message,
+ afs_inet_ntoa_r(rx_HostOf(rx_PeerOf(tcon)), hoststr),
+ (int)ntohs(rx_PortOf(rx_PeerOf(tcon))),
+ viceid,
+ afs_printable_VolumeId_lu(Fid->Volume),
+ afs_printable_uint32_lu(Fid->Vnode),
+ afs_printable_uint32_lu(Fid->Unique)));
+ } else {
+ ViceLog(0, ("%s while handling request from host %s:%d viceid %d "
+ "fid (none), failing request\n",
+ message,
+ afs_inet_ntoa_r(rx_HostOf(rx_PeerOf(tcon)), hoststr),
+ (int)ntohs(rx_PortOf(rx_PeerOf(tcon))),
+ viceid));
+ }
+}
+
/*
* Note that this function always returns a held host, so
* that CallPostamble can block without the host's disappearing.
* Call returns rx connection in passed in *tconn
+ *
+ * 'Fid' is optional, and is just used for printing log messages.
*/
static int
-CallPreamble(struct rx_call *acall, int activecall,
+CallPreamble(struct rx_call *acall, int activecall, struct AFSFid *Fid,
struct rx_connection **tconn, struct host **ahostp)
{
struct host *thost;
struct client *tclient;
+ afs_int32 viceid = -1;
int retry_flag = 1;
int code = 0;
char hoststr[16], hoststr2[16];
H_LOCK;
retry:
- tclient = h_FindClient_r(*tconn);
+ tclient = h_FindClient_r(*tconn, &viceid);
if (!tclient) {
- ViceLog(0, ("CallPreamble: Couldn't get client.\n"));
H_UNLOCK;
+ LogClientError("CallPreamble: Couldn't get client", *tconn, viceid, Fid);
return VBUSY;
}
- thost = tclient->host;
- if (tclient->prfail == 1) { /* couldn't get the CPS */
+ thost = tclient->z.host;
+ if (tclient->z.prfail == 1) { /* couldn't get the CPS */
if (!retry_flag) {
h_ReleaseClient_r(tclient);
h_Release_r(thost);
- ViceLog(0, ("CallPreamble: Couldn't get CPS. Fail\n"));
H_UNLOCK;
+ LogClientError("CallPreamble: Couldn't get CPS", *tconn, viceid, Fid);
return -1001;
}
retry_flag = 0; /* Retry once */
h_ReleaseClient_r(tclient);
h_Release_r(thost);
H_UNLOCK;
- ViceLog(0, ("CallPreamble: couldn't reconnect to ptserver\n"));
+ LogClientError("CallPreamble: couldn't reconnect to ptserver", *tconn, viceid, Fid);
return -1001;
}
- tclient->prfail = 2; /* Means re-eval client's cps */
+ tclient->z.prfail = 2; /* Means re-eval client's cps */
h_ReleaseClient_r(tclient);
h_Release_r(thost);
goto retry;
}
- tclient->LastCall = thost->LastCall = time(NULL);
+ tclient->z.LastCall = thost->z.LastCall = time(NULL);
if (activecall) /* For all but "GetTime", "GetStats", and "GetCaps" calls */
- thost->ActiveCall = thost->LastCall;
+ thost->z.ActiveCall = thost->z.LastCall;
h_Lock_r(thost);
- if (thost->hostFlags & HOSTDELETED) {
+ if (thost->z.hostFlags & HOSTDELETED) {
ViceLog(3,
("Discarded a packet for deleted host %s:%d\n",
- afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port)));
+ afs_inet_ntoa_r(thost->z.host, hoststr), ntohs(thost->z.port)));
code = VBUSY; /* raced, so retry */
- } else if ((thost->hostFlags & VENUSDOWN)
- || (thost->hostFlags & HFE_LATER)) {
+ } else if ((thost->z.hostFlags & VENUSDOWN)
+ || (thost->z.hostFlags & HFE_LATER)) {
if (BreakDelayedCallBacks_r(thost)) {
ViceLog(0,
("BreakDelayedCallbacks FAILED for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n",
- afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
+ afs_inet_ntoa_r(thost->z.host, hoststr), ntohs(thost->z.port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
ntohs(rxr_PortOf(*tconn))));
if (MultiProbeAlternateAddress_r(thost)) {
ViceLog(0,
("MultiProbe failed to find new address for host %s:%d\n",
- afs_inet_ntoa_r(thost->host, hoststr),
- ntohs(thost->port)));
+ afs_inet_ntoa_r(thost->z.host, hoststr),
+ ntohs(thost->z.port)));
code = -1;
} else {
ViceLog(0,
("MultiProbe found new address for host %s:%d\n",
- afs_inet_ntoa_r(thost->host, hoststr),
- ntohs(thost->port)));
+ afs_inet_ntoa_r(thost->z.host, hoststr),
+ ntohs(thost->z.port)));
if (BreakDelayedCallBacks_r(thost)) {
ViceLog(0,
("BreakDelayedCallbacks FAILED AGAIN for host %s:%d which IS UP. Connection from %s:%d. Possible network or routing failure.\n",
- afs_inet_ntoa_r(thost->host, hoststr), ntohs(thost->port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
+ afs_inet_ntoa_r(thost->z.host, hoststr), ntohs(thost->z.port), afs_inet_ntoa_r(rxr_HostOf(*tconn), hoststr2),
ntohs(rxr_PortOf(*tconn))));
code = -1;
}
int translate = 0;
H_LOCK;
- tclient = h_FindClient_r(aconn);
+ tclient = h_FindClient_r(aconn, NULL);
if (!tclient)
goto busyout;
- thost = tclient->host;
- if (thost->hostFlags & HERRORTRANS)
+ thost = tclient->z.host;
+ if (thost->z.hostFlags & HERRORTRANS)
translate = 1;
h_ReleaseClient_r(tclient);
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),
+ afs_inet_ntoa_r(ahost->z.host, hoststr),
+ ntohs(ahost->z.port),
ahost,
- afs_inet_ntoa_r(thost->host, hoststr2),
- ntohs(thost->port),
+ afs_inet_ntoa_r(thost->z.host, hoststr2),
+ ntohs(thost->z.port),
thost));
}
/* return the reference taken in CallPreamble */
} 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),
+ afs_inet_ntoa_r(thost->z.host, hoststr),
+ ntohs(thost->z.port),
thost));
}
/* return the reference taken in local h_FindClient_r--h_ReleaseClient_r
- * does not decrement refcount on client->host */
+ * does not decrement refcount on client->z.host */
h_Release_r(thost);
busyout:
return (errorCode);
if ((*vptr)->disk.uniquifier != fid->Unique) {
VPutVnode(&fileCode, *vptr);
- opr_Assert(fileCode == 0);
+ assert_vnode_success_or_salvaging(fileCode);
*vptr = 0;
return (VNOVNODE); /* return the right error code, at least */
}
{
*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);
+ if (client->z.CPS.prlist_len > 0 && !client->z.deleted &&
+ client->z.host && !(client->z.host->z.hostFlags & HOSTDELETED))
+ acl_CheckRights(ACL, &client->z.CPS, rights);
ReleaseReadLock(&client->lock);
}
afs_int32 code = 0;
ObtainReadLock(&client->lock);
- if (client->CPS.prlist_len > 0 && !client->deleted &&
- client->host && !(client->host->hostFlags & HOSTDELETED))
- code = acl_IsAMember(id, &client->CPS);
+ if (client->z.CPS.prlist_len > 0 && !client->z.deleted &&
+ client->z.host && !(client->z.host->z.hostFlags & HOSTDELETED))
+ code = acl_IsAMember(id, &client->z.CPS);
ReleaseReadLock(&client->lock);
return code;
}
/* wait if somebody else is already doing the getCPS call */
H_LOCK;
- while (client->host->hostFlags & HCPS_INPROGRESS) {
- client->host->hostFlags |= HCPS_WAITING; /* I am waiting */
- opr_cv_wait(&client->host->cond, &host_glock_mutex);
+ while (client->z.host->z.hostFlags & HCPS_INPROGRESS) {
+ client->z.host->z.hostFlags |= HCPS_WAITING; /* I am waiting */
+ opr_cv_wait(&client->z.host->cond, &host_glock_mutex);
}
- if (!client->host->hcps.prlist_len || !client->host->hcps.prlist_val) {
+ if (!client->z.host->z.hcps.prlist_len || !client->z.host->z.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)));
+ client->z.host->z.hcps.prlist_len,
+ afs_inet_ntoa_r(client->z.host->z.host, hoststr),
+ ntohs(client->z.host->z.port)));
} else
- acl_CheckRights(ACL, &client->host->hcps, &hrights);
+ acl_CheckRights(ACL, &client->z.host->z.hcps, &hrights);
H_UNLOCK;
/* Allow system:admin the rights given with the -implicit option */
if (client_HasAsMember(client, SystemId))
Error errorCode = 0; /* return code to caller */
struct rx_connection *tcon = rx_ConnectionOf(acall);
- rx_KeepAliveOff(acall);
-
if ((errorCode = CheckVnodeWithCall(Fid, volptr, cbv, targetptr, locktype)))
goto gvpdone;
/* 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 */
- if ((*targetptr)->disk.owner == (*client)->ViceId)
+ if ((*targetptr)->disk.owner == (*client)->z.ViceId)
(*rights) |= PRSFS_ADMINISTER;
else
(*rights) &= ~PRSFS_ADMINISTER;
#endif /* ADMIN_IMPLICIT_LOOKUP */
}
gvpdone:
- if (errorCode)
- rx_KeepAliveOn(acall);
return errorCode;
} /*GetVolumePackage */
{
Error fileCode = 0; /* Error code returned by the volume package */
- rx_KeepAliveOff(acall);
if (parentwhentargetnotdir) {
VPutVnode(&fileCode, parentwhentargetnotdir);
- opr_Assert(!fileCode || (fileCode == VSALVAGE));
+ assert_vnode_success_or_salvaging(fileCode);
}
if (targetptr) {
VPutVnode(&fileCode, targetptr);
- opr_Assert(!fileCode || (fileCode == VSALVAGE));
+ assert_vnode_success_or_salvaging(fileCode);
}
if (parentptr) {
VPutVnode(&fileCode, parentptr);
- opr_Assert(!fileCode || (fileCode == VSALVAGE));
+ assert_vnode_success_or_salvaging(fileCode);
}
if (volptr) {
VPutVolumeWithCall(volptr, cbv);
}
- rx_KeepAliveOn(acall);
if (*client) {
PutClient(client);
afs_int32 owner = V_owner(targetptr->volumePtr); /* get volume owner */
if (owner >= 0)
- return (client->ViceId == owner);
+ return (client->z.ViceId == owner);
else {
/*
* We don't have to check for host's cps since only regular
} /*VolumeRootVnode */
+/**
+ * Check if server can perform writes.
+ *
+ * This functions checks if the fileserver is read-only for the client received
+ * as an argument. Read-only fileservers allow write requests for members of
+ * system:administrators when started with both -readonly and -admin-write.
+ *
+ * @param[in] client calling user
+ *
+ * @return 1 if not read-only for this user; 0 otherwise
+ */
+static int
+IsWriteAllowed(struct client *client)
+{
+ if (readonlyServer) {
+ if (adminwriteServer && !VanillaUser(client)) {
+ /* admins can write */
+ return 1;
+ }
+ return 0;
+ }
+ return 1;
+}
+
/*
* Check if target file has the proper access permissions for the Fetch
* (FetchData, FetchACL, FetchStatus) and Store (StoreData, StoreACL,
AFSStoreStatus * InStatus)
{
Error errorCode = 0;
-#define OWNSp(client, target) ((client)->ViceId == (target)->disk.owner)
+#define OWNSp(client, target) ((client)->z.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))
/* must have read access, or be owner and have insert access */
if (!(rights & PRSFS_READ)
&& !((OWNSp(client, targetptr) && (rights & PRSFS_INSERT)
- && (client->ViceId != AnonymousID))))
+ && (client->z.ViceId != AnonymousID))))
return (EACCES);
}
if (CallingRoutine == CHK_FETCHDATA
* reading of files created with no read permission. The owner
* of the file is always allowed to read it.
*/
- if ((client->ViceId != targetptr->disk.owner)
+ if ((client->z.ViceId != targetptr->disk.owner)
&& VanillaUser(client))
errorCode =
(((OWNERREAD | OWNEREXEC) & targetptr->disk.
} else { /* !VanillaUser(client) && !FetchData */
osi_audit(PrivilegeEvent, 0, AUD_ID,
- (client ? client->ViceId : 0), AUD_INT, CallingRoutine,
+ (client ? client->z.ViceId : 0), AUD_INT, CallingRoutine,
AUD_END);
}
} else { /* a store operation */
+ if (!IsWriteAllowed(client)) {
+ return (VREADONLY);
+ }
if ((rights & PRSFS_INSERT) && OWNSp(client, targetptr)
&& (CallingRoutine != CHK_STOREACL)
&& (targetptr->disk.type == vFile)) {
* unless you are a system administrator */
/****** InStatus->Owner && UnixModeBits better be SET!! */
if (CHOWN(InStatus, targetptr) || CHGRP(InStatus, targetptr)) {
- if (readonlyServer)
- return (VREADONLY);
- else if (VanillaUser(client))
+ if (VanillaUser(client))
return (EPERM); /* Was EACCES */
else
osi_audit(PrivilegeEvent, 0, AUD_ID,
- (client ? client->ViceId : 0), AUD_INT,
+ (client ? client->z.ViceId : 0), AUD_INT,
CallingRoutine, AUD_END);
}
} else {
if (CallingRoutine != CHK_STOREDATA && !VanillaUser(client)) {
osi_audit(PrivilegeEvent, 0, AUD_ID,
- (client ? client->ViceId : 0), AUD_INT,
+ (client ? client->z.ViceId : 0), AUD_INT,
CallingRoutine, AUD_END);
} else {
- if (readonlyServer) {
- return (VREADONLY);
- }
if (CallingRoutine == CHK_STOREACL) {
if (!(rights & PRSFS_ADMINISTER)
&& !VolumeOwner(client, targetptr))
/* watch for chowns and chgrps */
if (CHOWN(InStatus, targetptr)
|| CHGRP(InStatus, targetptr)) {
- if (readonlyServer)
- return (VREADONLY);
- else if (VanillaUser(client))
+ if (VanillaUser(client))
return (EPERM); /* Was EACCES */
else
osi_audit(PrivilegeEvent, 0, AUD_ID,
- (client ? client->ViceId : 0), AUD_INT,
+ (client ? client->z.ViceId : 0), AUD_INT,
CallingRoutine, AUD_END);
}
/* must be sysadmin to set suid/sgid bits */
#else
(InStatus->UnixModeBits & (S_ISUID | S_ISGID)) != 0) {
#endif
- if (readonlyServer)
- return (VREADONLY);
if (VanillaUser(client))
return (EACCES);
else
osi_audit(PrivSetID, 0, AUD_ID,
- (client ? client->ViceId : 0), AUD_INT,
+ (client ? client->z.ViceId : 0), AUD_INT,
CallingRoutine, AUD_END);
}
if (CallingRoutine == CHK_STOREDATA) {
- if (readonlyServer)
- return (VREADONLY);
if (!(rights & PRSFS_WRITE))
return (EACCES);
/* Next thing is tricky. We want to prevent people
#endif
if ((targetptr->disk.type != vDirectory)
&& (!(targetptr->disk.modeBits & OWNERWRITE))) {
- if (readonlyServer)
- return (VREADONLY);
if (VanillaUser(client))
return (EACCES);
else
osi_audit(PrivilegeEvent, 0, AUD_ID,
- (client ? client->ViceId : 0),
+ (client ? client->z.ViceId : 0),
AUD_INT, CallingRoutine, AUD_END);
}
} else { /* a status store */
- if (readonlyServer)
- return (VREADONLY);
if (targetptr->disk.type == vDirectory) {
if (!(rights & PRSFS_DELETE)
&& !(rights & PRSFS_INSERT))
FDH_REALLYCLOSE(newFdP);
IH_RELEASE(newH);
FDH_REALLYCLOSE(targFdP);
- rc = IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr));
+ IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr));
free(buff);
VTakeOffline(volptr);
return EIO;
/* check that the file is in the directory */
SetDirHandle(dir, parentptr);
- if (afs_dir_Lookup(dir, Name, fileFid))
- return (ENOENT);
+ errorCode = afs_dir_Lookup(dir, Name, fileFid);
+ if (errorCode && errorCode != ENOENT) {
+ errorCode = EIO;
+ }
+ if (errorCode) {
+ return errorCode;
+ }
fileFid->Volume = V_id(volptr);
/* just-in-case check for something causing deadlock */
VN_SET_LEN(targetptr, length);
/* targetptr->disk.group = 0; save some cycles */
targetptr->disk.modeBits = 0777;
- targetptr->disk.owner = client->ViceId;
+ targetptr->disk.owner = client->z.ViceId;
targetptr->disk.dataVersion = 0; /* consistent with the client */
targetptr->disk.linkCount = (Caller & TVS_MKDIR ? 2 : 1);
/* the inode was created in Alloc_NewVnode() */
* counter is located immediately after its associated ``distance''
* counter.
*/
- if (client->InSameNetwork)
+ if (client->z.InSameNetwork)
writeIdx = VOL_STATS_SAME_NET;
else
writeIdx = VOL_STATS_DIFF_NET;
V_stat_writes(volptr, writeIdx)++;
- if (client->ViceId != AnonymousID) {
+ if (client->z.ViceId != AnonymousID) {
V_stat_writes(volptr, writeIdx + 1)++;
}
VOL_STATS_TIME_CAP_3 ? VOL_STATS_TIME_IDX_3 : currDate <
VOL_STATS_TIME_CAP_4 ? VOL_STATS_TIME_IDX_4 :
VOL_STATS_TIME_IDX_5);
- if (targetptr->disk.author == client->ViceId) {
+ if (targetptr->disk.author == client->z.ViceId) {
V_stat_fileSameAuthor(volptr, timeIdx)++;
} else {
V_stat_fileDiffAuthor(volptr, timeIdx)++;
}
if (!(Caller & TVS_SSTATUS))
- targetptr->disk.author = client->ViceId;
+ targetptr->disk.author = client->z.ViceId;
if (Caller & TVS_SDATA) {
targetptr->disk.dataVersion++;
if (!remote && VanillaUser(client)) {
}
if (InStatus->Mask & AFS_SETMODE) {
int modebits = InStatus->UnixModeBits;
-#define CREATE_SGUID_ADMIN_ONLY 1
#ifdef CREATE_SGUID_ADMIN_ONLY
if (!remote && VanillaUser(client))
modebits = modebits & 0777;
targetptr->disk.modeBits = modebits;
switch (Caller) {
case TVS_SDATA:
- osi_audit(PrivSetID, 0, AUD_ID, client->ViceId, AUD_INT,
+ osi_audit(PrivSetID, 0, AUD_ID, client->z.ViceId, AUD_INT,
CHK_STOREDATA, AUD_END);
break;
case TVS_CFILE:
case TVS_SSTATUS:
- osi_audit(PrivSetID, 0, AUD_ID, client->ViceId, AUD_INT,
+ osi_audit(PrivSetID, 0, AUD_ID, client->z.ViceId, AUD_INT,
CHK_STORESTATUS, AUD_END);
break;
default:
/* Checks if caller has the proper AFS and Unix (WRITE) access permission to the target directory; Prfs_Mode refers to the AFS Mode operation while rights contains the caller's access permissions to the directory. */
static afs_int32
-CheckWriteMode(Vnode * targetptr, afs_int32 rights, int Prfs_Mode)
+CheckWriteMode(Vnode * targetptr, afs_int32 rights, int Prfs_Mode,
+ struct client *client)
{
- if (readonlyServer)
+ if (!IsWriteAllowed(client))
return (VREADONLY);
if (!(rights & Prfs_Mode))
return (EACCES);
FS_LOCK;
AFSCallStats.FetchData++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_FetchData;
/* Get ptr to client data for user Id for logging */
ViceLog(5,
("SRXAFS_FetchData, Fid = %u.%u.%u, Host %s:%d, Id %d\n",
Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
- ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
queue_NodeInit(&tcbv);
tcbv.call = acall;
* Remember that another read operation was performed.
*/
FS_LOCK;
- if (client->InSameNetwork)
+ if (client->z.InSameNetwork)
readIdx = VOL_STATS_SAME_NET;
else
readIdx = VOL_STATS_DIFF_NET;
V_stat_reads(volptr, readIdx)++;
- if (client->ViceId != AnonymousID) {
+ if (client->z.ViceId != AnonymousID) {
V_stat_reads(volptr, readIdx + 1)++;
}
FS_UNLOCK;
if (parentwhentargetnotdir != NULL) {
tparentwhentargetnotdir = *parentwhentargetnotdir;
VPutVnode(&fileCode, parentwhentargetnotdir);
- opr_Assert(!fileCode || (fileCode == VSALVAGE));
+ assert_vnode_success_or_salvaging(fileCode);
parentwhentargetnotdir = NULL;
}
GetStatus(targetptr, OutStatus, rights, anyrights,
&tparentwhentargetnotdir);
- rx_KeepAliveOn(acall); /* I/O done */
-
/* if a r/w volume, promise a callback to the caller */
if (VolumeWriteable(volptr))
- SetCallBackStruct(AddCallBack(client->host, Fid), CallBack);
+ SetCallBackStruct(AddCallBack(client->z.host, Fid), CallBack);
else {
struct AFSFid myFid;
memset(&myFid, 0, sizeof(struct AFSFid));
myFid.Volume = Fid->Volume;
- SetCallBackStruct(AddVolCallBack(client->host, &myFid), CallBack);
+ SetCallBackStruct(AddVolCallBack(client->z.host, &myFid), CallBack);
}
Bad_FetchData:
fsstats_FinishOp(&fsstats, errorCode);
osi_auditU(acall, FetchDataEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_END);
return (errorCode);
} /*SRXAFS_FetchData */
FS_LOCK;
AFSCallStats.FetchACL++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_FetchACL;
/* Get ptr to client data for user Id for logging */
ViceLog(5,
("SAFS_FetchACL, Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,
Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
- ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
AccessList->AFSOpaque_len = 0;
AccessList->AFSOpaque_val = malloc(AFSOPAQUEMAX);
fsstats_FinishOp(&fsstats, errorCode);
osi_auditU(acall, FetchACLEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid,
- AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid,
+ AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
return errorCode;
} /*SRXAFS_FetchACL */
ViceLog(1,
("SAFS_FetchStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n",
Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
- ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.FetchStatus++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
&rights, &anyrights)))
goto Bad_FetchStatus;
- rx_KeepAliveOn(acall);
-
/* set volume synchronization information */
SetVolumeSync(Sync, volptr);
/* If a r/w volume, also set the CallBack state */
if (VolumeWriteable(volptr))
- SetCallBackStruct(AddCallBack(client->host, Fid), CallBack);
+ SetCallBackStruct(AddCallBack(client->z.host, Fid), CallBack);
else {
struct AFSFid myFid;
memset(&myFid, 0, sizeof(struct AFSFid));
myFid.Volume = Fid->Volume;
- SetCallBackStruct(AddVolCallBack(client->host, &myFid), CallBack);
+ SetCallBackStruct(AddVolCallBack(client->z.host, &myFid), CallBack);
}
Bad_FetchStatus:
}
CallBacks->AFSCBs_len = nfiles;
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ tfid = Fids->AFSCBFids_val;
+
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, tfid, &tcon, &thost)))
goto Bad_BulkStatus;
- tfid = Fids->AFSCBFids_val;
for (i = 0; i < nfiles; i++, tfid++) {
/*
* Get volume/vnode for the fetched file; caller's rights to it
&rights, &anyrights)))
goto Bad_BulkStatus;
- rx_KeepAliveOn(acall);
-
/* set volume synchronization information, but only once per call */
if (i == 0)
SetVolumeSync(Sync, volptr);
/* If a r/w volume, also set the CallBack state */
if (VolumeWriteable(volptr))
- SetCallBackStruct(AddBulkCallBack(client->host, tfid),
+ SetCallBackStruct(AddBulkCallBack(client->z.host, tfid),
&CallBacks->AFSCBs_val[i]);
else {
struct AFSFid myFid;
memset(&myFid, 0, sizeof(struct AFSFid));
myFid.Volume = tfid->Volume;
- SetCallBackStruct(AddVolCallBack(client->host, &myFid),
+ SetCallBackStruct(AddVolCallBack(client->z.host, &myFid),
&CallBacks->AFSCBs_val[i]);
}
Audit_and_Return:
ViceLog(2, ("SAFS_BulkStatus returns %d\n", errorCode));
osi_auditU(acall, BulkFetchStatusEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FIDS, Fids, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FIDS, Fids, AUD_END);
return errorCode;
} /*SRXAFS_BulkStatus */
/* Zero out return values to avoid leaking information on partial succes */
memset(Sync, 0, sizeof(*Sync));
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost))) {
+ tfid = Fids->AFSCBFids_val;
+
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, tfid, &tcon, &thost))) {
goto Bad_InlineBulkStatus;
}
- tfid = Fids->AFSCBFids_val;
for (i = 0; i < nfiles; i++, tfid++) {
/*
* Get volume/vnode for the fetched file; caller's rights to it
&rights, &anyrights))) {
tstatus = &OutStats->AFSBulkStats_val[i];
- if (thost->hostFlags & HERRORTRANS) {
+ tstatus->InterfaceVersion = 1;
+ if (thost->z.hostFlags & HERRORTRANS) {
tstatus->errorCode = sys_error_to_et(errorCode);
} else {
tstatus->errorCode = errorCode;
continue;
}
- rx_KeepAliveOn(acall);
-
/* set volume synchronization information, but only once per call */
if (!VolSync_set) {
SetVolumeSync(Sync, volptr);
CHK_FETCHSTATUS, 0))) {
tstatus = &OutStats->AFSBulkStats_val[i];
- if (thost->hostFlags & HERRORTRANS) {
+ tstatus->InterfaceVersion = 1;
+ if (thost->z.hostFlags & HERRORTRANS) {
tstatus->errorCode = sys_error_to_et(errorCode);
} else {
tstatus->errorCode = errorCode;
/* If a r/w volume, also set the CallBack state */
if (VolumeWriteable(volptr))
- SetCallBackStruct(AddBulkCallBack(client->host, tfid),
+ SetCallBackStruct(AddBulkCallBack(client->z.host, tfid),
&CallBacks->AFSCBs_val[i]);
else {
struct AFSFid myFid;
memset(&myFid, 0, sizeof(struct AFSFid));
myFid.Volume = tfid->Volume;
- SetCallBackStruct(AddVolCallBack(client->host, &myFid),
+ SetCallBackStruct(AddVolCallBack(client->z.host, &myFid),
&CallBacks->AFSCBs_val[i]);
}
Audit_and_Return:
ViceLog(2, ("SAFS_InlineBulkStatus returns %d\n", errorCode));
osi_auditU(acall, InlineBulkFetchStatusEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FIDS, Fids, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FIDS, Fids, AUD_END);
return errorCode;
} /*SRXAFS_InlineBulkStatus */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_FETCHSTATUS);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_FetchStatus;
code = SAFSS_FetchStatus(acall, Fid, OutStatus, CallBack, Sync);
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, FetchStatusEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_END);
return code;
} /*SRXAFS_FetchStatus */
FS_LOCK;
AFSCallStats.StoreData++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_StoreData;
/* Get ptr to client data for user Id for logging */
ViceLog(5,
("StoreData: Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,
Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
- ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
/*
* Get associated volume/vnode for the stored file; caller's rights
goto Bad_StoreData;
}
- rx_KeepAliveOn(acall);
-
/* set volume synchronization information */
SetVolumeSync(Sync, volptr);
*/
if (parentwhentargetnotdir != NULL) {
tparentwhentargetnotdir = *parentwhentargetnotdir;
- rx_KeepAliveOff(acall);
VPutVnode(&fileCode, parentwhentargetnotdir);
- rx_KeepAliveOn(acall);
- opr_Assert(!fileCode || (fileCode == VSALVAGE));
+ assert_vnode_success_or_salvaging(fileCode);
parentwhentargetnotdir = NULL;
}
if (errorCode && (!targetptr->changed_newTime))
goto Bad_StoreData;
- rx_KeepAliveOff(acall);
/* Update the status of the target's vnode */
Update_TargetVnodeStatus(targetptr, TVS_SDATA, client, InStatus,
targetptr, volptr, 0, 0);
- rx_KeepAliveOn(acall);
/* Get the updated File's status back to the caller */
GetStatus(targetptr, OutStatus, rights, anyrights,
fsstats_FinishOp(&fsstats, errorCode);
osi_auditU(acall, StoreDataEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_END);
return (errorCode);
} /*common_StoreData64 */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STOREACL);
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_StoreACL;
/* Get ptr to client data for user Id for logging */
ViceLog(1,
("SAFS_StoreACL, Fid = %u.%u.%u, ACL=%s, Host %s:%d, Id %d\n",
Fid->Volume, Fid->Vnode, Fid->Unique, AccessList->AFSOpaque_val,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.StoreACL++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, targetptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
-
- rx_KeepAliveOn(acall);
+ assert_vnode_success_or_salvaging(errorCode);
/* break call backs on the directory */
- BreakCallBack(client->host, Fid, 0);
+ BreakCallBack(client->z.host, Fid, 0);
/* Get the updated dir's status back to the caller */
GetStatus(targetptr, OutStatus, rights, anyrights, 0);
fsstats_FinishOp(&fsstats, errorCode);
osi_auditU(acall, StoreACLEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_ACL, AccessList->AFSOpaque_val, AUD_END);
return errorCode;
} /*SRXAFS_StoreACL */
ViceLog(1,
("SAFS_StoreStatus, Fid = %u.%u.%u, Host %s:%d, Id %d\n",
Fid->Volume, Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
- ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.StoreStatus++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
(parentwhentargetnotdir ? parentwhentargetnotdir
: targetptr), volptr, 0, 0);
- rx_KeepAliveOn(acall);
-
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, targetptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
/* Break call backs on Fid */
- BreakCallBack(client->host, Fid, 0);
+ BreakCallBack(client->z.host, Fid, 0);
/* Return the updated status back to caller */
GetStatus(targetptr, OutStatus, rights, anyrights,
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_STORESTATUS);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_StoreStatus;
code = SAFSS_StoreStatus(acall, Fid, InStatus, OutStatus, Sync);
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, StoreStatusEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_END);
return code;
} /*SRXAFS_StoreStatus */
ViceLog(1,
("SAFS_RemoveFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
DirFid->Volume, DirFid->Vnode, DirFid->Unique,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.RemoveFile++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
SetVolumeSync(Sync, volptr);
/* Does the caller has delete (& write) access to the parent directory? */
- if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE))) {
+ if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE, client))) {
goto Bad_RemoveFile;
}
}
/* Update the vnode status of the parent dir */
- Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+ Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
parentptr->disk.linkCount,
- client->InSameNetwork);
-
- rx_KeepAliveOn(acall);
+ client->z.InSameNetwork);
/* Return the updated parent dir's status back to caller */
GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
DeleteFileCallBacks(&fileFid);
/* convert the parent lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, parentptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
} else {
/* convert the parent lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, parentptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
/* convert the target lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, targetptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
/* tell all the file has changed */
- BreakCallBack(client->host, &fileFid, 1);
+ BreakCallBack(client->z.host, &fileFid, 1);
}
/* break call back on the directory */
- BreakCallBack(client->host, DirFid, 0);
+ BreakCallBack(client->z.host, DirFid, 0);
Bad_RemoveFile:
/* Update and store volume/vnode and parent vnodes back */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEFILE);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
goto Bad_RemoveFile;
code = SAFSS_RemoveFile(acall, DirFid, Name, OutDirStatus, Sync);
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, RemoveFileEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, DirFid, AUD_STR, Name, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, DirFid, AUD_STR, Name, AUD_END);
return code;
} /*SRXAFS_RemoveFile */
ViceLog(1,
("SAFS_CreateFile %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
DirFid->Volume, DirFid->Vnode, DirFid->Unique,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.CreateFile++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
SetVolumeSync(Sync, volptr);
/* Can we write (and insert) onto the parent directory? */
- if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))) {
+ if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))) {
goto Bad_CreateFile;
}
goto Bad_CreateFile;
/* update the status of the parent vnode */
- Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+ Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
parentptr->disk.linkCount,
- client->InSameNetwork);
+ client->z.InSameNetwork);
/* update the status of the new file's vnode */
Update_TargetVnodeStatus(targetptr, TVS_CFILE, client, InStatus,
parentptr, volptr, 0, 0);
- rx_KeepAliveOn(acall);
-
/* set up the return status for the parent dir and the newly created file, and since the newly created file is owned by the creator, give it PRSFS_ADMINISTER to tell the client its the owner of the file */
GetStatus(targetptr, OutFidStatus, rights | PRSFS_ADMINISTER, anyrights, parentptr);
GetStatus(parentptr, OutDirStatus, rights, anyrights, 0);
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, parentptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
/* break call back on parent dir */
- BreakCallBack(client->host, DirFid, 0);
+ BreakCallBack(client->z.host, DirFid, 0);
/* Return a callback promise for the newly created file to the caller */
- SetCallBackStruct(AddCallBack(client->host, OutFid), CallBack);
+ SetCallBackStruct(AddCallBack(client->z.host, OutFid), CallBack);
Bad_CreateFile:
/* Update and store volume/vnode and parent vnodes back */
memset(OutFid, 0, sizeof(struct AFSFid));
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
goto Bad_CreateFile;
code =
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, CreateFileEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, DirFid, AUD_STR, Name, AUD_FID, OutFid, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, DirFid, AUD_STR, Name, AUD_FID, OutFid, AUD_END);
return code;
} /*SRXAFS_CreateFile */
("SAFS_Rename %s to %s, Fid = %u.%u.%u to %u.%u.%u, Host %s:%d, Id %d\n",
OldName, NewName, OldDirFid->Volume, OldDirFid->Vnode,
OldDirFid->Unique, NewDirFid->Volume, NewDirFid->Vnode,
- NewDirFid->Unique, inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ NewDirFid->Unique, inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.Rename++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
/* set volume synchronization information */
SetVolumeSync(Sync, volptr);
- if ((errorCode = CheckWriteMode(oldvptr, rights, PRSFS_DELETE))) {
+ if ((errorCode = CheckWriteMode(oldvptr, rights, PRSFS_DELETE, client))) {
goto Bad_Rename;
}
- if ((errorCode = CheckWriteMode(newvptr, newrights, PRSFS_INSERT))) {
+ if ((errorCode = CheckWriteMode(newvptr, newrights, PRSFS_INSERT,
+ client))) {
goto Bad_Rename;
}
SetDirHandle(&newdir, newvptr);
/* Lookup the file to delete its vnode */
- if (afs_dir_Lookup(&olddir, OldName, &fileFid)) {
- errorCode = ENOENT;
+ errorCode = afs_dir_Lookup(&olddir, OldName, &fileFid);
+ if (errorCode && errorCode != ENOENT) {
+ errorCode = EIO;
+ }
+ if (errorCode) {
goto Bad_Rename;
}
if (fileFid.Vnode == oldvptr->vnodeNumber
}
/* Lookup the new file */
- if (!(afs_dir_Lookup(&newdir, NewName, &newFileFid))) {
- if (readonlyServer) {
+ code = afs_dir_Lookup(&newdir, NewName, &newFileFid);
+ if (code && code != ENOENT) {
+ errorCode = EIO;
+ goto Bad_Rename;
+ }
+ if (!code) {
+ if (!IsWriteAllowed(client)) {
errorCode = VREADONLY;
goto Bad_Rename;
}
}
if (testnode == 1) top = 1;
testvptr = VGetVnode(&errorCode, volptr, testnode, READ_LOCK);
- opr_Assert(errorCode == 0);
+ assert_vnode_success_or_salvaging(errorCode);
testnode = testvptr->disk.parent;
VPutVnode(&errorCode, testvptr);
if ((top == 1) && (testnode != 0)) {
errorCode = EIO;
goto Bad_Rename;
}
- opr_Assert(errorCode == 0);
+ assert_vnode_success_or_salvaging(errorCode);
}
}
struct AFSFid unused;
code = afs_dir_Lookup(&filedir, "..", &unused);
+ if (code && code != ENOENT) {
+ errorCode = EIO;
+ goto Bad_Rename;
+ }
if (code == ENOENT) {
/* only update .. if it doesn't already exist */
updatefile = 1;
NewName, errno));
if ((errno != ENOENT) && (errno != EIO)
&& (errno != ENXIO))
- ViceLog(0, ("Do we need to fsck?"));
+ ViceLog(0, ("Do we need to fsck?\n"));
}
}
VN_SET_INO(newfileptr, (Inode) 0);
opr_Assert(afs_dir_Delete(&olddir, OldName) == 0);
/* if the directory length changes, reflect it in the statistics */
- Update_ParentVnodeStatus(oldvptr, volptr, &olddir, client->ViceId,
- oldvptr->disk.linkCount, client->InSameNetwork);
- Update_ParentVnodeStatus(newvptr, volptr, &newdir, client->ViceId,
- newvptr->disk.linkCount, client->InSameNetwork);
+ Update_ParentVnodeStatus(oldvptr, volptr, &olddir, client->z.ViceId,
+ oldvptr->disk.linkCount, client->z.InSameNetwork);
+ Update_ParentVnodeStatus(newvptr, volptr, &newdir, client->z.ViceId,
+ newvptr->disk.linkCount, client->z.InSameNetwork);
if (oldvptr == newvptr)
oldvptr->disk.dataVersion--; /* Since it was bumped by 2! */
/* convert the write locks to a read locks before breaking callbacks */
VVnodeWriteToRead(&errorCode, newvptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
if (oldvptr != newvptr) {
VVnodeWriteToRead(&errorCode, oldvptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
}
if (newfileptr && !doDelete) {
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, newfileptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
}
- rx_KeepAliveOn(acall);
-
/* break call back on NewDirFid, OldDirFid, NewDirFid and newFileFid */
- BreakCallBack(client->host, NewDirFid, 0);
+ BreakCallBack(client->z.host, NewDirFid, 0);
if (oldvptr != newvptr) {
- BreakCallBack(client->host, OldDirFid, 0);
+ BreakCallBack(client->z.host, OldDirFid, 0);
}
if (updatefile) {
/* if a dir moved, .. changed */
* enough to know that the callback could be broken implicitly,
* but that may not be clear, and some client implementations
* may not know to. */
- BreakCallBack(client->host, &fileFid, 1);
+ BreakCallBack(client->z.host, &fileFid, 1);
}
if (newfileptr) {
/* Note: it is not necessary to break the callback */
DeleteFileCallBacks(&newFileFid); /* no other references */
else
/* other's still exist (with wrong link count) */
- BreakCallBack(client->host, &newFileFid, 1);
+ BreakCallBack(client->z.host, &newFileFid, 1);
}
Bad_Rename:
if (newfileptr) {
- rx_KeepAliveOff(acall);
VPutVnode(&fileCode, newfileptr);
- opr_Assert(fileCode == 0);
+ assert_vnode_success_or_salvaging(fileCode);
}
(void)PutVolumePackage(acall, fileptr, (newvptr && newvptr != oldvptr ?
newvptr : 0), oldvptr, volptr, &client);
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RENAME);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, OldDirFid, &tcon, &thost)))
goto Bad_Rename;
code =
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, RenameFileEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, OldDirFid, AUD_STR, OldName,
- AUD_FID, NewDirFid, AUD_STR, NewName, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, OldDirFid, AUD_STR, OldName,
+ AUD_FID, NewDirFid, AUD_STR, NewName, AUD_END);
return code;
} /*SRXAFS_Rename */
ViceLog(1,
("SAFS_Symlink %s to %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
LinkContents, DirFid->Volume, DirFid->Vnode, DirFid->Unique,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.Symlink++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
SetVolumeSync(Sync, volptr);
/* Does the caller has insert (and write) access to the parent directory? */
- if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT)))
+ if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client)))
goto Bad_SymLink;
/*
* to do this.
*/
if ((InStatus->Mask & AFS_SETMODE) && !(InStatus->UnixModeBits & 0111)) {
- if (readonlyServer) {
+ if (!IsWriteAllowed(client)) {
errorCode = VREADONLY;
goto Bad_SymLink;
}
}
/* update the status of the parent vnode */
- Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+ Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
parentptr->disk.linkCount,
- client->InSameNetwork);
+ client->z.InSameNetwork);
/* update the status of the new symbolic link file vnode */
Update_TargetVnodeStatus(targetptr, TVS_SLINK, client, InStatus,
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, parentptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
-
- rx_KeepAliveOn(acall);
+ assert_vnode_success_or_salvaging(errorCode);
/* break call back on the parent dir */
- BreakCallBack(client->host, DirFid, 0);
+ BreakCallBack(client->z.host, DirFid, 0);
Bad_SymLink:
/* Write the all modified vnodes (parent, new files) and volume back */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SYMLINK);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
goto Bad_Symlink;
code =
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, SymlinkEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, DirFid, AUD_STR, Name,
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, DirFid, AUD_STR, Name,
AUD_FID, OutFid, AUD_STR, LinkContents, AUD_END);
return code;
("SAFS_Link %s, Did = %u.%u.%u, Fid = %u.%u.%u, Host %s:%d, Id %d\n",
Name, DirFid->Volume, DirFid->Vnode, DirFid->Unique,
ExistingFid->Volume, ExistingFid->Vnode, ExistingFid->Unique,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.Link++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
SetVolumeSync(Sync, volptr);
/* Can the caller insert into the parent directory? */
- if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))) {
+ if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))) {
goto Bad_Link;
}
/* update the status in the parent vnode */
/**WARNING** --> disk.author SHOULDN'T be modified???? */
- Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+ Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
parentptr->disk.linkCount,
- client->InSameNetwork);
+ client->z.InSameNetwork);
targetptr->disk.linkCount++;
- targetptr->disk.author = client->ViceId;
+ targetptr->disk.author = client->z.ViceId;
targetptr->changed_newTime = 1; /* Status change of linked-to file */
/* set up return status */
/* convert the write locks to read locks before breaking callbacks */
VVnodeWriteToRead(&errorCode, targetptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
+ assert_vnode_success_or_salvaging(errorCode);
VVnodeWriteToRead(&errorCode, parentptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
-
- rx_KeepAliveOn(acall);
+ assert_vnode_success_or_salvaging(errorCode);
/* break call back on DirFid */
- BreakCallBack(client->host, DirFid, 0);
+ BreakCallBack(client->z.host, DirFid, 0);
/*
* We also need to break the callback for the file that is hard-linked since part
* of its status (like linkcount) is changed
*/
- BreakCallBack(client->host, ExistingFid, 0);
+ BreakCallBack(client->z.host, ExistingFid, 0);
Bad_Link:
/* Write the all modified vnodes (parent, new files) and volume back */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_LINK);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
goto Bad_Link;
code =
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, LinkEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, DirFid, AUD_STR, Name,
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, DirFid, AUD_STR, Name,
AUD_FID, ExistingFid, AUD_END);
return code;
ViceLog(1,
("SAFS_MakeDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
DirFid->Volume, DirFid->Vnode, DirFid->Unique,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.MakeDir++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
* implcit a access that goes with dir ownership, and proceed to
* subvert quota in the volume.
*/
- if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))
- || (errorCode = CheckWriteMode(parentptr, rights, PRSFS_WRITE))) {
+ if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))
+ || (errorCode = CheckWriteMode(parentptr, rights, PRSFS_WRITE,
+ client))) {
#else
- if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT))) {
+ if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_INSERT, client))) {
#endif /* DIRCREATE_NEED_WRITE */
goto Bad_MakeDir;
}
}
/* Update the status for the parent dir */
- Update_ParentVnodeStatus(parentptr, volptr, &parentdir, client->ViceId,
+ Update_ParentVnodeStatus(parentptr, volptr, &parentdir, client->z.ViceId,
parentptr->disk.linkCount + 1,
- client->InSameNetwork);
+ client->z.InSameNetwork);
/* Point to target's ACL buffer and copy the parent's ACL contents to it */
opr_Verify((SetAccessList(&targetptr, &volptr, &newACL, &newACLSize,
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, parentptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
-
- rx_KeepAliveOn(acall);
+ assert_vnode_success_or_salvaging(errorCode);
/* break call back on DirFid */
- BreakCallBack(client->host, DirFid, 0);
+ BreakCallBack(client->z.host, DirFid, 0);
/* Return a callback promise to caller */
- SetCallBackStruct(AddCallBack(client->host, OutFid), CallBack);
+ SetCallBackStruct(AddCallBack(client->z.host, OutFid), CallBack);
Bad_MakeDir:
/* Write the all modified vnodes (parent, new files) and volume back */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_MAKEDIR);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
goto Bad_MakeDir;
code =
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, MakeDirEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, DirFid, AUD_STR, Name,
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, DirFid, AUD_STR, Name,
AUD_FID, OutFid, AUD_END);
return code;
ViceLog(1,
("SAFS_RemoveDir %s, Did = %u.%u.%u, Host %s:%d, Id %d\n", Name,
DirFid->Volume, DirFid->Vnode, DirFid->Unique,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.RemoveDir++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
SetVolumeSync(Sync, volptr);
/* Does the caller has delete (&write) access to the parent dir? */
- if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE))) {
+ if ((errorCode = CheckWriteMode(parentptr, rights, PRSFS_DELETE, client))) {
goto Bad_RemoveDir;
}
}
/* Update the status for the parent dir; link count is also adjusted */
- Update_ParentVnodeStatus(parentptr, volptr, &dir, client->ViceId,
+ Update_ParentVnodeStatus(parentptr, volptr, &dir, client->z.ViceId,
parentptr->disk.linkCount - 1,
- client->InSameNetwork);
+ client->z.InSameNetwork);
/* Return to the caller the updated parent dir status */
GetStatus(parentptr, OutDirStatus, rights, anyrights, NULL);
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, parentptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
-
- rx_KeepAliveOn(acall);
+ assert_vnode_success_or_salvaging(errorCode);
/* break call back on DirFid and fileFid */
- BreakCallBack(client->host, DirFid, 0);
+ BreakCallBack(client->z.host, DirFid, 0);
Bad_RemoveDir:
/* Write the all modified vnodes (parent, new files) and volume back */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_REMOVEDIR);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, DirFid, &tcon, &thost)))
goto Bad_RemoveDir;
code = SAFSS_RemoveDir(acall, DirFid, Name, OutDirStatus, Sync);
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, RemoveDirEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, DirFid, AUD_STR, Name, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, DirFid, AUD_STR, Name, AUD_END);
return code;
} /*SRXAFS_RemoveDir */
ViceLog(1,
("SAFS_SetLock type = %s Fid = %u.%u.%u, Host %s:%d, Id %d\n",
locktype[(int)type], Fid->Volume, Fid->Vnode, Fid->Unique,
- inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ inet_ntoa(logHostAddr), ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.SetLock++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETLOCK);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_SetLock;
code = SAFSS_SetLock(acall, Fid, type, Sync);
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, SetLockEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_LONG, type, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_LONG, type, AUD_END);
return code;
} /*SRXAFS_SetLock */
ViceLog(1,
("SAFS_ExtendLock Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,
Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
- ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.ExtendLock++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_EXTENDLOCK);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_ExtendLock;
code = SAFSS_ExtendLock(acall, Fid, Sync);
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, ExtendLockEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_END);
return code;
} /*SRXAFS_ExtendLock */
ViceLog(1,
("SAFS_ReleaseLock Fid = %u.%u.%u, Host %s:%d, Id %d\n", Fid->Volume,
Fid->Vnode, Fid->Unique, inet_ntoa(logHostAddr),
- ntohs(rxr_PortOf(tcon)), t_client->ViceId));
+ ntohs(rxr_PortOf(tcon)), t_client->z.ViceId));
FS_LOCK;
AFSCallStats.ReleaseLock++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
/* if no more locks left, a callback would be triggered here */
if (targetptr->disk.lock.lockCount <= 0) {
- rx_KeepAliveOn(acall);
/* convert the write lock to a read lock before breaking callbacks */
VVnodeWriteToRead(&errorCode, targetptr);
- opr_Assert(!errorCode || errorCode == VSALVAGE);
- BreakCallBack(client->host, Fid, 0);
+ assert_vnode_success_or_salvaging(errorCode);
+ BreakCallBack(client->z.host, Fid, 0);
}
Bad_ReleaseLock:
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_RELEASELOCK);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, Fid, &tcon, &thost)))
goto Bad_ReleaseLock;
code = SAFSS_ReleaseLock(acall, Fid, Sync);
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, ReleaseLockEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_FID, Fid, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_FID, Fid, AUD_END);
return code;
} /*SRXAFS_ReleaseLock */
if (seconds <= 0)
seconds = 1;
stats->StoreDataRate = AFSCallStats.TotalStoredBytes / seconds;
-#ifdef AFS_NT40_ENV
- stats->ProcessSize = -1; /* TODO: */
-#else
- stats->ProcessSize = (afs_int32) ((long)sbrk(0) >> 10);
-#endif
+ stats->ProcessSize = opr_procsize();
FS_UNLOCK;
h_GetWorkStats((int *)&(stats->WorkStations),
(int *)&(stats->ActiveWorkStations), (int *)0,
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS);
- if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
goto Bad_GetStatistics;
ViceLog(1, ("SAFS_GetStatistics Received\n"));
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, GetStatisticsEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0, AUD_END);
return code;
} /*SRXAFS_GetStatistics */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETSTATISTICS);
- if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
+ goto Bad_GetStatistics64;
+
+ if (statsVersion != STATS64_VERSION) {
+ code = EINVAL;
goto Bad_GetStatistics64;
+ }
ViceLog(1, ("SAFS_GetStatistics64 Received\n"));
Statistics->ViceStatistics64_val =
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
+ Statistics->ViceStatistics64_val[STATS64_PROCESSSIZE] = opr_procsize();
FS_UNLOCK;
h_GetWorkStats64(&(Statistics->ViceStatistics64_val[STATS64_WORKSTATIONS]),
&(Statistics->ViceStatistics64_val[STATS64_ACTIVEWORKSTATIONS]),
fsstats_FinishOp(&fsstats, code);
osi_auditU(acall, GetStatisticsEvent, code,
- AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0, AUD_END);
return code;
} /*SRXAFS_GetStatistics */
fsstats_FinishOp(&fsstats, 0);
osi_auditU(a_call, XStatsVersionEvent, 0,
- AUD_ID, t_client ? t_client->ViceId : 0, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0, AUD_END);
return (0);
} /*SRXAFS_XStatsVersion */
afs_int32 * a_timeP, AFS_CollData * a_dataP)
{ /*SRXAFS_GetXStats */
+ struct client *t_client = NULL; /* tmp ptr to client data */
+ struct rx_connection *tcon = rx_ConnectionOf(a_call);
int code; /*Return value */
afs_int32 *dataBuffP; /*Ptr to data to be returned */
afs_int32 dataBytes; /*Bytes in data buffer */
struct fsstats fsstats;
- fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETXSTATS);
-
/*
- * Record the time of day and the server version number.
+ * Note: This function intentionally omits CallPreamble()
+ * to avoid issuing TellMeAboutYourself() calls to
+ * simple clients which are only gathering stats.
*/
+
+ fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETXSTATS);
+
+ t_client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
+
+ /* Return the server's time of day and xstat version number. */
*a_srvVersionNumP = AFS_XSTAT_VERSION;
*a_timeP = (afs_int32) time(NULL);
-
- /*
- * Stuff the appropriate data in there (assume victory)
- */
code = 0;
- ViceLog(1,
- ("Received GetXStats call for collection %d\n",
- a_collectionNumber));
-
-#if 0
- /*
- * We're not keeping stats, so just return successfully with
- * no data.
- */
- a_dataP->AFS_CollData_len = 0;
- a_dataP->AFS_CollData_val = NULL;
-#endif /* 0 */
+ osi_auditU(a_call, GetXStatsEvent,
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_INT, a_clientVersionNum,
+ AUD_INT, a_collectionNumber, AUD_END);
switch (a_collectionNumber) {
case AFS_XSTATSCOLL_CALL_INFO:
- /*
- * Pass back all the call-count-related data.
- *
- * >>> We are forced to allocate a separate area in which to
- * >>> put this stuff in by the RPC stub generator, since it
- * >>> will be freed at the tail end of the server stub code.
- */
-#if 0
- /*
- * I don't think call-level stats are being collected yet
- * for the File Server.
- */
- dataBytes = sizeof(struct afs_Stats);
- dataBuffP = malloc(dataBytes);
- memcpy(dataBuffP, &afs_cmstats, dataBytes);
- a_dataP->AFS_CollData_len = dataBytes >> 2;
- a_dataP->AFS_CollData_val = dataBuffP;
-#else
+ /* The call info collection type is not implemented. */
a_dataP->AFS_CollData_len = 0;
a_dataP->AFS_CollData_val = NULL;
-#endif /* 0 */
break;
case AFS_XSTATSCOLL_PERF_INFO:
/*
* Pass back all the regular performance-related data.
*
- * >>> We are forced to allocate a separate area in which to
- * >>> put this stuff in by the RPC stub generator, since it
- * >>> will be freed at the tail end of the server stub code.
+ * Allocate a separate area in which to put this stuff in
+ * by the RPC stub generator, since it will be freed at the
+ * tail end of the server stub code.
*/
-
afs_perfstats.numPerfCalls++;
FillPerfValues(&afs_perfstats);
-
- /*
- * Don't overwrite the spares at the end.
- */
-
dataBytes = sizeof(struct afs_PerfStats);
- dataBuffP = malloc(dataBytes);
+ dataBuffP = calloc(1, dataBytes);
memcpy(dataBuffP, &afs_perfstats, dataBytes);
- a_dataP->AFS_CollData_len = dataBytes >> 2;
+ a_dataP->AFS_CollData_len = dataBytes / sizeof(afs_int32);
a_dataP->AFS_CollData_val = dataBuffP;
break;
* We have to stuff the basic, overall numbers in, but the
* detailed numbers are kept in the structure already.
*
- * >>> We are forced to allocate a separate area in which to
- * >>> put this stuff in by the RPC stub generator, since it
- * >>> will be freed at the tail end of the server stub code.
+ * Allocate a separate area in which to put this stuff in
+ * by the RPC stub generator, since it will be freed at the
+ * tail end of the server stub code.
*/
-
afs_perfstats.numPerfCalls++;
afs_FullPerfStats.overall.numPerfCalls = afs_perfstats.numPerfCalls;
FillPerfValues(&afs_FullPerfStats.overall);
-
- /*
- * Don't overwrite the spares at the end.
- */
-
dataBytes = sizeof(struct fs_stats_FullPerfStats);
- dataBuffP = malloc(dataBytes);
+ dataBuffP = calloc(1, dataBytes);
memcpy(dataBuffP, &afs_FullPerfStats, dataBytes);
- a_dataP->AFS_CollData_len = dataBytes >> 2;
+ a_dataP->AFS_CollData_len = dataBytes / sizeof(afs_int32);
a_dataP->AFS_CollData_val = dataBuffP;
break;
afs_perfstats.numPerfCalls++;
dataBytes = sizeof(struct cbcounters);
- dataBuffP = malloc(dataBytes);
+ dataBuffP = calloc(1, dataBytes);
{
extern struct cbcounters cbstuff;
dataBuffP[0]=cbstuff.DeleteFiles;
dataBuffP[15]=cbstuff.GSS5;
}
- a_dataP->AFS_CollData_len = dataBytes >> 2;
+ a_dataP->AFS_CollData_len = dataBytes / sizeof(afs_int32);
a_dataP->AFS_CollData_val = dataBuffP;
break;
-
default:
- /*
- * Illegal collection number.
- */
+ /* Illegal collection number. */
a_dataP->AFS_CollData_len = 0;
a_dataP->AFS_CollData_val = NULL;
code = 1;
FS_LOCK;
AFSCallStats.GiveUpCallBacks++, AFSCallStats.TotalCalls++;
FS_UNLOCK;
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
goto Bad_GiveUpCallBacks;
if (!FidArray && !CallBackArray) {
errorCode = GetClient(tcon, &client);
if (!errorCode) {
H_LOCK;
- DeleteAllCallBacks_r(client->host, 1);
+ DeleteAllCallBacks_r(client->z.host, 1);
H_UNLOCK;
PutClient(&client);
}
if (!errorCode) {
for (i = 0; i < FidArray->AFSCBFids_len; i++) {
struct AFSFid *fid = &(FidArray->AFSCBFids_val[i]);
- DeleteCallBack(client->host, fid);
+ DeleteCallBack(client->z.host, fid);
}
PutClient(&client);
}
FS_UNLOCK;
ViceLog(2, ("SAFS_GetCapabilties\n"));
- if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
goto Bad_GetCaps;
dataBytes = 1 * sizeof(afs_int32);
code = CallPostamble(tcon, code, thost);
- return 0;
+ return code;
}
/* client is held, but not locked */
{
ObtainWriteLock(&client->lock);
- client->prfail = 2; /* Means re-eval client's cps */
+ client->z.prfail = 2; /* Means re-eval client's cps */
- 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->z.ViceId != ANONYMOUSID) && client->z.CPS.prlist_val) {
+ free(client->z.CPS.prlist_val);
+ client->z.CPS.prlist_val = NULL;
+ client->z.CPS.prlist_len = 0;
}
ReleaseWriteLock(&client->lock);
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMEINFO);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
goto Bad_GetVolumeInfo;
FS_LOCK;
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETVOLUMESTATUS);
ViceLog(1, ("SAFS_GetVolumeStatus for volume %u\n", avolid));
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
goto Bad_GetVolumeStatus;
FS_LOCK;
fsstats_FinishOp(&fsstats, errorCode);
osi_auditU(acall, GetVolumeStatusEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_LONG, avolid, AUD_STR, *Name, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_LONG, avolid, AUD_STR, *Name, AUD_END);
return (errorCode);
} /*SRXAFS_GetVolumeStatus */
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_SETVOLUMESTATUS);
ViceLog(1, ("SAFS_SetVolumeStatus for volume %u\n", avolid));
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
goto Bad_SetVolumeStatus;
FS_LOCK;
&rights, &anyrights)))
goto Bad_SetVolumeStatus;
- if (readonlyServer) {
+ if (!IsWriteAllowed(client)) {
errorCode = VREADONLY;
goto Bad_SetVolumeStatus;
}
fsstats_FinishOp(&fsstats, errorCode);
osi_auditU(acall, SetVolumeStatusEvent, errorCode,
- AUD_ID, t_client ? t_client->ViceId : 0,
- AUD_LONG, avolid, AUD_STR, Name, AUD_END);
+ AUD_ID, t_client ? t_client->z.ViceId : 0,
+ AUD_LONG, avolid, AUD_STR, Name, AUD_END);
return (errorCode);
} /*SRXAFS_SetVolumeStatus */
afs_int32
SRXAFS_GetRootVolume(struct rx_call * acall, char **VolumeName)
{
-#ifdef notdef
- int fd;
- int len;
- char *temp;
- struct rx_connection *tcon;
- struct host *thost;
- Error errorCode = 0;
-#endif
struct fsstats fsstats;
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETROOTVOLUME);
return FSERR_EOPNOTSUPP;
#ifdef notdef
- if (errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &thost))
+ if (errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost))
goto Bad_GetRootVolume;
FS_LOCK;
AFSCallStats.GetRootVolume++, AFSCallStats.TotalCalls++;
} /*SRXAFS_GetRootVolume */
-/* still works because a struct CBS is the same as a struct AFSOpaque */
afs_int32
SRXAFS_CheckToken(struct rx_call * acall, afs_int32 AfsId,
struct AFSOpaque * Token)
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_CHECKTOKEN);
- if ((code = CallPreamble(acall, ACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &thost)))
goto Bad_CheckToken;
code = FSERR_ECONNREFUSED;
fsstats_StartOp(&fsstats, FS_STATS_RPCIDX_GETTIME);
- if ((code = CallPreamble(acall, NOTACTIVECALL, &tcon, &thost)))
+ if ((code = CallPreamble(acall, NOTACTIVECALL, NULL, &tcon, &thost)))
goto Bad_GetTime;
FS_LOCK;
FDH_CLOSE(lhp);
if (*lc < 0)
return -1;
- *size = OS_SIZE(fdP->fd_fd);
+ *size = FDH_SIZE(fdP);
return (*size == -1) ? -1 : 0;
#else
struct afs_stat status;
* We break the callbacks here so that the following signal will not
* leave a window.
*/
- BreakCallBack(client->host, Fid, 0);
+ BreakCallBack(client->z.host, Fid, 0);
if (Pos == -1 || VN_GET_INO(targetptr) == 0) {
/* the inode should have been created in Alloc_NewVnode */
inet_ntoa(logHostAddr), ntohs(rxr_PortOf(rx_ConnectionOf(Call)))));
return ENOENT; /* is this proper error code? */
} else {
- rx_KeepAliveOff(Call);
/*
* See if the file has several links (from other volumes). If it
* does, then we have to make a copy before changing it to avoid
(afs_uintmax_t) Pos, (afs_uintmax_t) DataLength,
(afs_uintmax_t) FileLength, (afs_uintmax_t) Length));
- /* truncate the file iff it needs it (ftruncate is slow even when its a noop) */
- if (FileLength < DataLength)
- FDH_TRUNC(fdP, FileLength);
bytesTransfered = 0;
#ifndef HAVE_PIOV
tbuffer = AllocSendBuffer();
#endif /* HAVE_PIOV */
+ /* truncate the file iff it needs it (ftruncate is slow even when its a noop) */
+ if (FileLength < DataLength) {
+ errorCode = FDH_TRUNC(fdP, FileLength);
+ if (errorCode)
+ goto done;
+ }
+
/* if length == 0, the loop below isn't going to do anything, including
* extend the length of the inode, which it must do, since the file system
* assumes that the inode length == vnode's file length. So, we extend
/* Set the file's length; we've already done an lseek to the right
* spot above.
*/
+ tlen = 0; /* Just a source of data for the write */
nBytes = FDH_PWRITE(fdP, &tlen, 1, Pos);
if (nBytes != 1) {
errorCode = -1;
sys2et[EDQUOT] = UAEDQUOT;
sys2et[ENOMEDIUM] = UAENOMEDIUM;
sys2et[EMEDIUMTYPE] = UAEMEDIUMTYPE;
+ sys2et[ECANCELED] = UAECANCELED;
+ sys2et[ENOTRECOVERABLE] = UAENOTRECOVERABLE;
+ sys2et[ENOTSUP] = UAENOTSUP;
+ sys2et[EOTHER] = UAEOTHER;
+ sys2et[EOWNERDEAD] = UAEOWNERDEAD;
+ sys2et[EPROCLIM] = UAEPROCLIM;
+ sys2et[EDISCON] = UAEDISCON;
sys2et[EIO] = UAEIO;
}
static struct rx_securityClass *sc = 0;
int i,j;
struct rx_connection *conn;
+ afs_int32 viceid = -1;
#endif
- if ((errorCode = CallPreamble(acall, ACTIVECALL, &tcon, &tcallhost)))
+ if ((errorCode = CallPreamble(acall, ACTIVECALL, NULL, &tcon, &tcallhost)))
goto Bad_CallBackRxConnAddr1;
#ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING
errorCode = 1;
#else
H_LOCK;
- tclient = h_FindClient_r(tcon);
+ tclient = h_FindClient_r(tcon, &viceid);
if (!tclient) {
errorCode = VBUSY;
+ LogClientError("Client host too busy (CallBackRxConnAddr)", tcon, viceid, NULL);
goto Bad_CallBackRxConnAddr;
}
- thost = tclient->host;
+ thost = tclient->z.host;
/* nothing more can be done */
- if ( !thost->interface )
+ if ( !thost->z.interface )
goto Bad_CallBackRxConnAddr;
/* the only address is the primary interface */
/* can't change when there's only 1 address, anyway */
- if ( thost->interface->numberOfInterfaces <= 1 )
+ if ( thost->z.interface->numberOfInterfaces <= 1 )
goto Bad_CallBackRxConnAddr;
/* initialise a security object only once */
if ( !sc )
sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
- for ( i=0; i < thost->interface->numberOfInterfaces; i++)
+ for ( i=0; i < thost->z.interface->numberOfInterfaces; i++)
{
- if ( *addr == thost->interface->addr[i] ) {
+ if ( *addr == thost->z.interface->addr[i] ) {
break;
}
}
- if ( *addr != thost->interface->addr[i] )
+ if ( *addr != thost->z.interface->addr[i] )
goto Bad_CallBackRxConnAddr;
- conn = rx_NewConnection (thost->interface->addr[i],
- thost->port, 1, sc, 0);
+ conn = rx_NewConnection (thost->z.interface->addr[i],
+ thost->z.port, 1, sc, 0);
rx_SetConnDeadTime(conn, 2);
rx_SetConnHardDeadTime(conn, AFS_HARDDEADTIME);
H_UNLOCK;
errorCode = RXAFSCB_Probe(conn);
H_LOCK;
if (!errorCode) {
- if ( thost->callback_rxcon )
- rx_DestroyConnection(thost->callback_rxcon);
- thost->callback_rxcon = conn;
- thost->host = addr;
- rx_SetConnDeadTime(thost->callback_rxcon, 50);
- rx_SetConnHardDeadTime(thost->callback_rxcon, AFS_HARDDEADTIME);
+ if ( thost->z.callback_rxcon )
+ rx_DestroyConnection(thost->z.callback_rxcon);
+ thost->z.callback_rxcon = conn;
+ thost->z.host = addr;
+ rx_SetConnDeadTime(thost->z.callback_rxcon, 50);
+ rx_SetConnHardDeadTime(thost->z.callback_rxcon, AFS_HARDDEADTIME);
h_ReleaseClient_r(tclient);
/* The hold on thost will be released by CallPostamble */
H_UNLOCK;