FS_LOCK;
/* date volume instance was created */
if (async) {
- if (avol)
+ if (avol && avol->header)
async->spare1 = avol->header->diskstuff.creationDate;
else
async->spare1 = 0;
* locktype : indicates what kind of lock to take on vnodes
* rights : returns a pointer to caller's rights
* anyrights : returns a pointer to anonymous' rights
+ * remote : indicates that the volume is a remote RW replica
*
* Returns:
* 0 on success
AFSFid * Fid, Volume ** volptr, Vnode ** targetptr,
int chkforDir, Vnode ** parent,
struct client **client, int locktype,
- afs_int32 * rights, afs_int32 * anyrights)
+ afs_int32 * rights, afs_int32 * anyrights, int remote)
{
struct acl_accessList *aCL; /* Internal access List */
int aCLSize; /* size of the access list */
goto gvpdone;
}
}
- if ((errorCode =
- SetAccessList(targetptr, volptr, &aCL, &aCLSize, parent,
- (chkforDir == MustBeDIR ? (AFSFid *) 0 : Fid),
- (chkforDir == MustBeDIR ? 0 : locktype))) != 0)
- goto gvpdone;
- if (chkforDir == MustBeDIR)
- osi_Assert((*parent) == 0);
- if (!(*client)) {
- if ((errorCode = GetClient(tcon, client)) != 0)
+ /*
+ * If the remote flag is set, the current call is dealing with a remote RW
+ * replica, and it can be assumed that the appropriate access checks were
+ * done by the calling server hosting the master volume.
+ */
+ if (!remote) {
+ if ((errorCode = SetAccessList(targetptr, volptr, &aCL, &aCLSize, parent,
+ (chkforDir == MustBeDIR ? (AFSFid *) 0 : Fid),
+ (chkforDir == MustBeDIR ? 0 : locktype))) != 0)
goto gvpdone;
+ if (chkforDir == MustBeDIR)
+ osi_Assert((*parent) == 0);
if (!(*client)) {
- errorCode = EINVAL;
- goto gvpdone;
+ if ((errorCode = GetClient(tcon, client)) != 0)
+ goto gvpdone;
+ if (!(*client))
+ errorCode = EINVAL;
+ goto gvpdone;
+ }
+ GetRights(*client, aCL, rights, anyrights);
+ /* ok, if this is not a dir, set the PRSFS_ADMINISTER bit iff we're the owner */
+ if ((*targetptr)->disk.type != vDirectory) {
+ /* anyuser can't be owner, so only have to worry about rights, not anyrights */
+ if ((*targetptr)->disk.owner == (*client)->ViceId)
+ (*rights) |= PRSFS_ADMINISTER;
+ else
+ (*rights) &= ~PRSFS_ADMINISTER;
}
- }
- GetRights(*client, aCL, rights, anyrights);
- /* ok, if this is not a dir, set the PRSFS_ADMINISTER bit iff we're the owner */
- if ((*targetptr)->disk.type != vDirectory) {
- /* anyuser can't be owner, so only have to worry about rights, not anyrights */
- if ((*targetptr)->disk.owner == (*client)->ViceId)
- (*rights) |= PRSFS_ADMINISTER;
- else
- (*rights) &= ~PRSFS_ADMINISTER;
- }
#ifdef ADMIN_IMPLICIT_LOOKUP
- /* admins get automatic lookup on everything */
- if (!VanillaUser(*client))
- (*rights) |= PRSFS_LOOKUP;
+ /* admins get automatic lookup on everything */
+ if (!VanillaUser(*client))
+ (*rights) |= PRSFS_LOOKUP;
#endif /* ADMIN_IMPLICIT_LOOKUP */
gvpdone:
if (errorCode)
rx_KeepAliveOn(acall);
+ }
return errorCode;
} /*GetVolumePackage */
{
return GetVolumePackageWithCall(acall, NULL, Fid, volptr, targetptr,
chkforDir, parent, client, locktype,
- rights, anyrights);
+ rights, anyrights, 0);
}
IH_RELEASE(newH);
FDH_REALLYCLOSE(targFdP);
rc = IH_DEC(V_linkHandle(volptr), ino, V_parentId(volptr));
- if (!rc) {
+ if (rc) {
ViceLog(0,
("CopyOnWrite failed: error %u after i_dec on disk full, volume %u in partition %s needs salvage\n",
rc, V_id(volptr), volptr->partition->name));
* Update the target file's (or dir's) status block after the specified
* operation is complete. Note that some other fields maybe updated by
* the individual module.
+ * If remote is set, the volume is a RW replica and access checks can
+ * be skipped.
*/
/* XXX INCOMPLETE - More attention is needed here! */
Update_TargetVnodeStatus(Vnode * targetptr, afs_uint32 Caller,
struct client *client, AFSStoreStatus * InStatus,
Vnode * parentptr, Volume * volptr,
- afs_fsize_t length)
+ afs_fsize_t length, int remote)
{
Date currDate; /*Current date */
int writeIdx; /*Write index to bump */
targetptr->disk.author = client->ViceId;
if (Caller & TVS_SDATA) {
targetptr->disk.dataVersion++;
- if (VanillaUser(client)) {
+ if (!remote && VanillaUser(client)) {
targetptr->disk.modeBits &= ~04000; /* turn off suid for file. */
#ifdef CREATE_SGUID_ADMIN_ONLY
targetptr->disk.modeBits &= ~02000; /* turn off sgid for file. */
}
if (InStatus->Mask & AFS_SETOWNER) {
/* admin is allowed to do chmod, chown as well as chown, chmod. */
- if (VanillaUser(client)) {
+ if (!remote && VanillaUser(client)) {
targetptr->disk.modeBits &= ~04000; /* turn off suid for file. */
#ifdef CREATE_SGUID_ADMIN_ONLY
targetptr->disk.modeBits &= ~02000; /* turn off sgid for file. */
int modebits = InStatus->UnixModeBits;
#define CREATE_SGUID_ADMIN_ONLY 1
#ifdef CREATE_SGUID_ADMIN_ONLY
- if (VanillaUser(client))
+ if (!remote && VanillaUser(client))
modebits = modebits & 0777;
#endif
- if (VanillaUser(client)) {
+ if (!remote && VanillaUser(client)) {
targetptr->disk.modeBits = modebits;
} else {
targetptr->disk.modeBits = modebits;
return VSALVAGE;
}
- *targetptr = VAllocVnode(&errorCode, volptr, FileType);
+ *targetptr = VAllocVnode(&errorCode, volptr, FileType, 0, 0);
if (errorCode != 0) {
VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
return (errorCode);
status->MinQuota = V_minquota(volptr);
status->MaxQuota = V_maxquota(volptr);
status->BlocksInUse = V_diskused(volptr);
- status->PartBlocksAvail = RoundInt64ToInt32(volptr->partition->free);
- status->PartMaxBlocks = RoundInt64ToInt32(volptr->partition->totalUsable);
+ status->PartBlocksAvail = RoundInt64ToInt31(volptr->partition->free);
+ status->PartMaxBlocks = RoundInt64ToInt31(volptr->partition->totalUsable);
/* now allocate and copy these things; they're freed by the RXGEN stub */
temp = strlen(V_name(volptr)) + 1;
if ((errorCode =
GetVolumePackageWithCall(acall, cbv, Fid, &volptr, &targetptr, DONTCHECK,
&parentwhentargetnotdir, &client, READ_LOCK,
- &rights, &anyrights)))
+ &rights, &anyrights, 0)))
goto Bad_FetchData;
SetVolumeSync(Sync, volptr);
&parentwhentargetnotdir, &client, READ_LOCK,
&rights, &anyrights))) {
tstatus = &OutStats->AFSBulkStats_val[i];
- tstatus->errorCode = errorCode;
+
+ if (thost->hostFlags & HERRORTRANS) {
+ tstatus->errorCode = sys_error_to_et(errorCode);
+ } else {
+ tstatus->errorCode = errorCode;
+ }
+
PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
(Vnode *) 0, volptr, &client);
parentwhentargetnotdir = (Vnode *) 0;
Check_PermissionRights(targetptr, client, rights,
CHK_FETCHSTATUS, 0))) {
tstatus = &OutStats->AFSBulkStats_val[i];
- tstatus->errorCode = errorCode;
+
+ if (thost->hostFlags & HERRORTRANS) {
+ tstatus->errorCode = sys_error_to_et(errorCode);
+ } else {
+ tstatus->errorCode = errorCode;
+ }
+
(void)PutVolumePackage(acall, parentwhentargetnotdir,
targetptr, (Vnode *) 0, volptr,
&client);
/* set volume synchronization information */
SetVolumeSync(Sync, volptr);
- if ((targetptr->disk.type == vSymlink)) {
+ if (targetptr->disk.type == vSymlink) {
/* Should we return a better error code here??? */
errorCode = EISDIR;
goto Bad_StoreData;
rx_KeepAliveOff(acall);
/* Update the status of the target's vnode */
Update_TargetVnodeStatus(targetptr, TVS_SDATA, client, InStatus,
- targetptr, volptr, 0);
+ targetptr, volptr, 0, 0);
rx_KeepAliveOn(acall);
/* Get the updated File's status back to the caller */
/* Update the status of the target's vnode */
Update_TargetVnodeStatus(targetptr, TVS_SSTATUS, client, InStatus,
(parentwhentargetnotdir ? parentwhentargetnotdir
- : targetptr), volptr, 0);
+ : targetptr), volptr, 0, 0);
rx_KeepAliveOn(acall);
/* update the status of the new file's vnode */
Update_TargetVnodeStatus(targetptr, TVS_CFILE, client, InStatus,
- parentptr, volptr, 0);
+ parentptr, volptr, 0, 0);
rx_KeepAliveOn(acall);
/* update the status of the new symbolic link file vnode */
Update_TargetVnodeStatus(targetptr, TVS_SLINK, client, InStatus,
- parentptr, volptr, strlen((char *)LinkContents));
+ parentptr, volptr, strlen((char *)LinkContents), 0);
/* Write the contents of the symbolic link name into the target inode */
fdP = IH_OPEN(targetptr->handle);
/* update the status for the target vnode */
Update_TargetVnodeStatus(targetptr, TVS_MKDIR, client, InStatus,
- parentptr, volptr, 0);
+ parentptr, volptr, 0, 0);
/* Actually create the New directory in the directory package */
SetDirHandle(&dir, targetptr);
(void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
(Vnode *) 0, volptr, &client);
- if ((errorCode == VREADONLY)) /* presumably, we already granted this lock */
+ if (errorCode == VREADONLY) /* presumably, we already granted this lock */
errorCode = 0; /* under our generous policy re RO vols */
ViceLog(2, ("SAFS_ExtendLock returns %d\n", errorCode));
(void)PutVolumePackage(acall, parentwhentargetnotdir, targetptr,
(Vnode *) 0, volptr, &client);
- if ((errorCode == VREADONLY)) /* presumably, we already granted this lock */
+ if (errorCode == VREADONLY) /* presumably, we already granted this lock */
errorCode = 0; /* under our generous policy re RO vols */
ViceLog(2, ("SAFS_ReleaseLock returns %d\n", errorCode));
for (part = DiskPartitionList; part && i < AFS_MSTATDISKS;
part = part->next) {
- stats->Disks[i].TotalBlocks = RoundInt64ToInt32(part->totalUsable);
- stats->Disks[i].BlocksAvailable = RoundInt64ToInt32(part->free);
+ stats->Disks[i].TotalBlocks = RoundInt64ToInt31(part->totalUsable);
+ stats->Disks[i].BlocksAvailable = RoundInt64ToInt31(part->free);
memset(stats->Disks[i].Name, 0, AFS_DISKNAMESIZE);
strncpy(stats->Disks[i].Name, part->name, AFS_DISKNAMESIZE);
i++;
if (!FidArray && !CallBackArray) {
ViceLog(1,
("SAFS_GiveUpAllCallBacks: host=%x\n",
- (rx_PeerOf(tcon) ? rx_PeerOf(tcon)->host : 0)));
+ (rx_PeerOf(tcon) ? rx_HostOf(rx_PeerOf(tcon)) : 0)));
errorCode = GetClient(tcon, &client);
if (!errorCode) {
H_LOCK;
ViceLog(0,
("GiveUpCallBacks: #Fids %d < #CallBacks %d, host=%x\n",
FidArray->AFSCBFids_len, CallBackArray->AFSCBs_len,
- (rx_PeerOf(tcon) ? rx_PeerOf(tcon)->host : 0)));
+ (rx_PeerOf(tcon) ? rx_HostOf(rx_PeerOf(tcon)) : 0)));
errorCode = EINVAL;
goto Bad_GiveUpCallBacks;
}
FreeSendBuffer((struct afs_buffer *)tbuffer);
#endif /* HAVE_PIOV */
if (sync) {
- FDH_SYNC(fdP);
+ (void) FDH_SYNC(fdP);
}
if (errorCode) {
Error tmp_errorCode = 0;