extern afs_int32 afs_mariner, afs_marinerHost;
extern struct srvAddr *afs_srvAddrs[NSERVERS];
extern int afs_resourceinit_flag;
+extern afs_int32 cryptall;
static int PBogus(), PSetAcl(), PGetAcl(), PSetTokens(), PGetVolumeStatus();
static int PSetVolumeStatus(), PFlush(), PNewStatMount(), PGetTokens(), PUnlog();
static int PSetSPrefs33(), PStoreBehind(), PGCPAGs();
static int PGetCPrefs(), PSetCPrefs(); /* client network addresses */
static int PGetInitParams(), PFlushMount(), PRxStatProc(), PRxStatPeer();
+static int PGetRxkcrypt(), PSetRxkcrypt();
+static int PPrefetchFromTape(), PResidencyCmd();
int PExportAfs();
static int HandleClientContext(struct afs_ioctl *ablob, int *com, struct AFS_UCRED **acred, struct AFS_UCRED *credp);
PNoop, /* 63 -- arla: print xfs status */
PNoop, /* 64 -- arla: force cache check */
PNoop, /* 65 -- arla: break callback */
+ PPrefetchFromTape, /* 66 -- MR-AFS: prefetch file from tape */
+ PResidencyCmd, /* 67 -- MR-AFS: generic commnd interface */
};
#define PSetClientContext 99 /* Special pioctl to setup caller's creds */
}
#endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */
-#if defined(AFS_LINUX_64BIT_KERNEL)
+#if defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV)
struct afs_ioctl32 dst32;
#ifdef AFS_SPARC64_LINUX20_ENV
- if (current->tss.flags & SPARC_FLAG_32BIT) {
+ if (current->tss.flags & SPARC_FLAG_32BIT)
#else
#error Not done for this linux type
-#endif
+#endif /* AFS_SPARC64_LINUX20_ENV */
+ {
AFS_COPYIN(cmarg, (caddr_t) &dst32, sizeof dst32, code);
if (!code)
afs_ioctl32_to_afs_ioctl(&dst32, dst);
caddr_t arg;
} *uap = (struct a *)args;
#else /* AFS_OSF_ENV */
+#ifdef AFS_DARWIN_ENV
+struct ioctl_args {
+ int fd;
+ u_long com;
+ caddr_t arg;
+};
+afs_xioctl(p, uap, retval)
+ struct proc *p;
+ register struct ioctl_args *uap;
+ register_t *retval;
+{
+#else
#ifdef AFS_LINUX22_ENV
struct afs_ioctl_sys {
unsigned int com;
caddr_t arg;
} *uap = (struct a *)u.u_ap;
#endif /* AFS_LINUX22_ENV */
+#endif /* AFS_DARWIN_ENV */
#endif /* AFS_OSF_ENV */
#endif /* AFS_SUN5_ENV */
#endif
#ifndef AFS_LINUX22_ENV
-#if defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV)
+#if defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
struct file *fd;
#else
register struct file *fd;
register int ioctlDone = 0, code = 0;
AFS_STATCNT(afs_xioctl);
+#ifdef AFS_DARWIN_ENV
+ if ((code=fdgetf(p, uap->fd, &fd)))
+ return code;
+#else
#ifdef AFS_LINUX22_ENV
ua.com = com;
ua.arg = arg;
#endif
#endif
#endif
+#endif
/* first determine whether this is any sort of vnode */
#ifdef AFS_LINUX22_ENV
if (code) {
osi_FreeSmallSpace(datap);
AFS_GUNLOCK();
+#ifdef AFS_DARWIN_ENV
+ return code;
+#else
#if defined(AFS_SUN5_ENV)
#ifdef AFS_SUN54_ENV
releasef(uap->fd);
#endif
#endif
#endif
+#endif
}
code = HandleIoctl(tvc, uap->com, datap);
osi_FreeSmallSpace(datap);
#endif
code = ioctl(uap, rvp);
#else
+#if defined(AFS_DARWIN_ENV)
+ return ioctl(p, uap, retval);
+#else
#ifdef AFS_OSF_ENV
code = ioctl(p, args, retval);
#ifdef AFS_OSF30_ENV
#endif
#endif
#endif
+#endif
}
#ifdef AFS_SUN5_ENV
if (ioctlDone)
#ifdef AFS_LINUX22_ENV
return -code;
#else
-#if !defined(AFS_OSF_ENV)
+#if !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN_ENV)
if (!getuerror())
setuerror(code);
#if defined(AFS_AIX32_ENV) && !defined(AFS_AIX41_ENV)
#endif
#endif /* AFS_LINUX22_ENV */
#endif /* AFS_SUN5_ENV */
-#ifdef AFS_OSF_ENV
+#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
return (code);
#endif
}
extern struct mount *afs_globalVFS;
#else /* AFS_OSF_ENV */
+#ifdef AFS_DARWIN_ENV
+afs_pioctl(p, args, retval)
+ struct proc *p;
+ void *args;
+ int *retval;
+{
+ struct a {
+ char *path;
+ int cmd;
+ caddr_t cmarg;
+ int follow;
+ } *uap = (struct a *) args;
+
+ AFS_STATCNT(afs_pioctl);
+ return (afs_syscall_pioctl(uap->path, uap->cmd, uap->cmarg, uap->follow, p->p_cred->pc_ucred));
+}
+
+extern struct mount *afs_globalVFS;
+#else /* AFS_OSF_ENV */
extern struct vfs *afs_globalVFS;
#endif
+#endif
/* macro to avoid adding any more #ifdef's to pioctl code. */
#if defined(AFS_LINUX22_ENV) || defined(AFS_AIX41_ENV)
rval_t *rvp;
struct AFS_UCRED *credp;
#else
+#ifdef AFS_DARWIN_ENV
+afs_syscall_pioctl(path, com, cmarg, follow, credp)
+ struct AFS_UCRED *credp;
+#else
afs_syscall_pioctl(path, com, cmarg, follow)
#endif
+#endif
char *path;
- int com;
+ unsigned int com;
caddr_t cmarg;
int follow;
{
#ifndef AFS_SUN5_ENV
if (! _VALIDVICEIOCTL(com)) {
PIOCTL_FREE_CRED();
-#ifdef AFS_OSF_ENV
+#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
return EINVAL;
#else /* AFS_OSF_ENV */
#if defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
code = copyin_afs_ioctl(cmarg, &data);
if (code) {
PIOCTL_FREE_CRED();
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
return (code);
#else
setuerror(code);
#endif
}
if ((com & 0xff) == PSetClientContext) {
-#ifdef AFS_LINUX22_ENV
+#if defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
return EINVAL; /* Not handling these yet. */
-#endif
+#else
#if defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_LINUX22_ENV)
code = HandleClientContext(&data, &com, &foreigncreds, credp);
#else
#endif /* AFS_SGI_ENV */
#endif
#endif
+#endif
if (code) {
if (foreigncreds) {
crfree(foreigncreds);
}
PIOCTL_FREE_CRED();
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
return (code);
#else
return (setuerror(code), code);
#endif
}
}
-#ifndef AFS_LINUX22_ENV
+#if !defined(AFS_LINUX22_ENV) && !defined(AFS_DARWIN_ENV)
if (foreigncreds) {
/*
* We could have done without temporary setting the u.u_cred below
if ((com & 0xff) == 15) {
/* special case prefetch so entire pathname eval occurs in helper process.
otherwise, the pioctl call is essentially useless */
-#if defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
code = Prefetch(path, &data, follow,
foreigncreds ? foreigncreds : credp);
#else
#endif /* AFS_SGI64_ENV */
#endif /* AFS_HPUX101_ENV */
#endif
-#ifndef AFS_LINUX22_ENV
+#if !defined(AFS_LINUX22_ENV) && !defined(AFS_DARWIN_ENV)
if (foreigncreds) {
#ifdef AFS_AIX41_ENV
crset(tmpcred); /* restore original credentials */
}
#endif /* AFS_LINUX22_ENV */
PIOCTL_FREE_CRED();
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
return (code);
#else
return (setuerror(code), code);
#endif /* AFS_AIX41_ENV */
AFS_GLOCK();
if (code) {
-#ifndef AFS_LINUX22_ENV
+#if !defined(AFS_LINUX22_ENV) && !defined(AFS_DARWIN_ENV)
if (foreigncreds) {
#ifdef AFS_AIX41_ENV
crset(tmpcred); /* restore original credentials */
}
#endif /* AFS_LINUX22_ENV */
PIOCTL_FREE_CRED();
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
return (code);
#else
return(setuerror(code), code);
code = afs_HandlePioctl(vp, com, &data, follow, &credp);
}
#else
-#ifdef AFS_LINUX22_ENV
+#if defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
code = afs_HandlePioctl(vp, com, &data, follow, &credp);
#else
code = afs_HandlePioctl(vp, com, &data, follow, &u.u_cred);
#endif /* AFS_AIX41_ENV */
#endif /* AFS_SUN5_ENV */
} else {
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
code = EINVAL; /* not in /afs */
#else
setuerror(EINVAL);
#endif
}
-#ifndef AFS_LINUX22_ENV
+#if !defined(AFS_LINUX22_ENV) && !defined(AFS_DARWIN_ENV)
if (foreigncreds) {
#ifdef AFS_AIX41_ENV
crset(tmpcred);
#endif
}
PIOCTL_FREE_CRED();
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
return (code);
#else
if (!getuerror())
afs_PutCell(tcell, READ_LOCK);
if (set_parent_pag) {
int pag;
+#ifdef AFS_DARWIN_ENV
+ struct proc *p=current_proc(); /* XXX */
+ uprintf("Process %d (%s) tried to change pags in PSetTokens\n",
+ p->p_pid, p->p_comm);
+ if (!setpag(p, acred, -1, &pag, 1)) {
+#else
#ifdef AFS_OSF_ENV
if (!setpag(u.u_procp, acred, -1, &pag, 1)) { /* XXX u.u_procp is a no-op XXX */
#else
if (!setpag(acred, -1, &pag, 1)) {
#endif
+#endif
afs_InitReq(&treq, *acred);
areq = &treq;
}
cp = ain;
bcopy(cp, (char *)&volstat, sizeof(AFSFetchVolumeStatus));
cp += sizeof(AFSFetchVolumeStatus);
+ if (strlen(cp) >= sizeof(volName))
+ return E2BIG;
strcpy(volName, cp);
cp += strlen(volName)+1;
+ if (strlen(cp) >= sizeof(offLineMsg))
+ return E2BIG;
strcpy(offLineMsg, cp);
cp += strlen(offLineMsg)+1;
+ if (strlen(cp) >= sizeof(motd))
+ return E2BIG;
strcpy(motd, cp);
storeStat.Mask = 0;
if (volstat.MinQuota != -1) {
register struct vcache *tvc;
register struct dcache *tdc;
struct VenusFid tfid;
- char *bufp = 0;
- afs_int32 offset, len, hasatsys=0;
+ char *bufp;
+ struct sysname_info sysState;
+ afs_int32 offset, len;
AFS_STATCNT(PNewStatMount);
if (!avc) return EINVAL;
}
tdc = afs_GetDCache(avc, 0, areq, &offset, &len, 1);
if (!tdc) return ENOENT;
- hasatsys = Check_AtSys(avc, ain, &bufp, areq);
- code = afs_dir_Lookup(&tdc->f.inode, bufp, &tfid.Fid);
+ Check_AtSys(avc, ain, &sysState, areq);
+ do {
+ code = afs_dir_Lookup(&tdc->f.inode, sysState.name, &tfid.Fid);
+ } while (code == ENOENT && Next_AtSys(avc, areq, &sysState));
+ bufp = sysState.name;
if (code) {
afs_PutDCache(tdc);
goto out;
ReleaseWriteLock(&tvc->lock);
afs_PutVCache(tvc, WRITE_LOCK);
out:
- if (hasatsys) osi_FreeLargeSpace(bufp);
+ if (sysState.allocked) osi_FreeLargeSpace(bufp);
return code;
}
afs_ResetUserConns(tu);
tu->refCount--;
ObtainWriteLock(&afs_xuser,228);
+#ifdef UKERNEL
+ /* set the expire times to 0, causes
+ * afs_GCUserData to remove this entry
+ */
+ tu->ct.EndTimestamp = 0;
+ tu->tokenTime = 0;
+#endif /* UKERNEL */
}
}
ReleaseWriteLock(&afs_xuser);
{
register char *tp;
register afs_int32 code;
+#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV)
+ size_t bufferSize;
+#else
u_int bufferSize;
+#endif
AFS_STATCNT(Prefetch);
if (!apath) return EINVAL;
}
linkedstate |= CNoSUID; /* setuid is disabled by default for fs newcell */
- code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport);
+ code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0);
return code;
}
afs_int32 ainSize;
afs_int32 *aoutSize; /* set this */ {
register afs_int32 code;
- char *bufp = 0;
- afs_int32 offset, len, hasatsys = 0;
+ char *bufp;
+ struct sysname_info sysState;
+ afs_int32 offset, len;
register struct conn *tc;
register struct dcache *tdc;
register struct vcache *tvc;
tdc = afs_GetDCache(avc, 0, areq, &offset, &len, 1); /* test for error below */
if (!tdc) return ENOENT;
- hasatsys = Check_AtSys(avc, ain, &bufp, areq);
- code = afs_dir_Lookup(&tdc->f.inode, bufp, &tfid.Fid);
+ Check_AtSys(avc, ain, &sysState, areq);
+ do {
+ code = afs_dir_Lookup(&tdc->f.inode, sysState.name, &tfid.Fid);
+ } while (code == ENOENT && Next_AtSys(avc, areq, &sysState));
+ bufp = sysState.name;
if (code) {
afs_PutDCache(tdc);
goto out;
ReleaseWriteLock(&avc->lock);
code = 0;
out:
- if (hasatsys) osi_FreeLargeSpace(bufp);
+ if (sysState.allocked) osi_FreeLargeSpace(bufp);
return code;
}
#if defined(AFS_SGI_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_HPUX_ENV)
VN_HOLD((struct vnode *)tvc);
#else
+#if defined(AFS_DARWIN_ENV)
+ osi_vnhold(tvc, 0);
+#else
tvc->vrefCount++;
#endif
+#endif
ReleaseReadLock(&afs_xvcache);
#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
afs_BozonLock(&tvc->pvnLock, tvc); /* Since afs_TryToSmush will do a pvn_vptrunc */
/* (since we don't really believe remote uids anyway) */
/* outname[] shouldn't really be needed- this is left as an excercise */
/* for the reader. */
-
static PSetSysName(avc, afun, areq, ain, aout, ainSize, aoutSize, acred)
struct vcache *avc;
int afun;
register struct afs_exporter *exporter;
extern struct unixuser *afs_FindUser();
extern char *afs_sysname;
+ extern char *afs_sysnamelist[];
+ extern int afs_sysnamecount;
register struct unixuser *au;
register afs_int32 pag, error;
- int t;
+ int t, count;
AFS_STATCNT(PSetSysName);
if (!afs_globalVFS) {
/* Afsd is NOT running; disable it */
-#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
+#if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_DARWIN_ENV)
return (EINVAL);
#else
return (setuerror(EINVAL), EINVAL);
bcopy(ain, (char *)&setsysname, sizeof(afs_int32));
ain += sizeof(afs_int32);
if (setsysname) {
- t = strlen(ain);
- if (t > MAXSYSNAME)
+
+ /* Check my args */
+ if (setsysname < 0 || setsysname > MAXNUMSYSNAMES)
return EINVAL;
+ for(cp = ain,count = 0;count < setsysname;count++) {
+ /* won't go past end of ain since maxsysname*num < ain length */
+ t = strlen(cp);
+ if (t >= MAXSYSNAME || t <= 0)
+ return EINVAL;
+ /* check for names that can shoot us in the foot */
+ if (*cp == '.' && (cp[1] == 0 || (cp[1] == '.' && cp[2] == 0)))
+ return EINVAL;
+ cp += t+1;
+ }
+ /* args ok */
+
+ /* inname gets first entry in case we're being a translater */
+ t = strlen(ain);
bcopy(ain, inname, t+1); /* include terminating null */
ain += t + 1;
}
else foundname = 1;
afs_PutUser(au, READ_LOCK);
} else {
+
+ /* Not xlating, so local case */
if (!afs_sysname) osi_Panic("PSetSysName: !afs_sysname\n");
- if (!setsysname) {
+ if (!setsysname) { /* user just wants the info */
strcpy(outname, afs_sysname);
- foundname = 1;
- } else {
- if (!afs_osi_suser(acred)) /* Local guy; only root can change sysname */
+ foundname = afs_sysnamecount;
+ } else { /* Local guy; only root can change sysname */
+ if (!afs_osi_suser(acred))
return EACCES;
+
+ /* clear @sys entries from the dnlc, once afs_lookup can
+ do lookups of @sys entries and thinks it can trust them */
+ /* privs ok, store the entry, ... */
strcpy(afs_sysname, inname);
+ if (setsysname > 1) { /* ... or list */
+ cp = ain;
+ for(count=1; count < setsysname;++count) {
+ if (!afs_sysnamelist[count])
+ osi_Panic("PSetSysName: no afs_sysnamelist entry to write\n");
+ t = strlen(cp);
+ bcopy(cp, afs_sysnamelist[count], t+1); /* include null */
+ cp += t+1;
+ }
+ }
+ afs_sysnamecount = setsysname;
}
}
if (!setsysname) {
- cp = aout;
+ cp = aout; /* not changing so report back the count and ... */
bcopy((char *)&foundname, cp, sizeof(afs_int32));
cp += sizeof(afs_int32);
if (foundname) {
- strcpy(cp, outname);
+ strcpy(cp, outname); /* ... the entry, ... */
cp += strlen(outname)+1;
+ for(count=1; count < foundname; ++count) { /* ... or list. */
+ /* Note: we don't support @sys lists for exporters */
+ if (!afs_sysnamelist[count])
+ osi_Panic("PSetSysName: no afs_sysnamelist entry to read\n");
+ t = strlen(afs_sysnamelist[count]);
+ if (t >= MAXSYSNAME)
+ osi_Panic("PSetSysName: sysname entry garbled\n");
+ strcpy(cp, afs_sysnamelist[count]);
+ cp += t + 1;
+ }
}
*aoutSize = cp - aout;
}
return cr;
}
#endif
+
+static int
+PGetRxkcrypt(avc, afun, areq, ain, aout, ainSize, aoutSize, acred)
+struct vcache *avc;
+int afun;
+struct vrequest *areq;
+char *ain, *aout;
+afs_int32 ainSize;
+afs_int32 *aoutSize;
+struct AFS_UCRED *acred;
+{
+ bcopy((char *)&cryptall, aout, sizeof(afs_int32));
+ *aoutSize=sizeof(afs_int32);
+ return 0;
+}
+
+static int
+PSetRxkcrypt(avc, afun, areq, ain, aout, ainSize, aoutSize, acred)
+struct vcache *avc;
+int afun;
+struct vrequest *areq;
+char *ain, *aout;
+afs_int32 ainSize;
+afs_int32 *aoutSize;
+struct AFS_UCRED *acred;
+{
+ afs_int32 tmpval;
+
+ if (!afs_osi_suser(acred))
+ return EPERM;
+ if (ainSize != sizeof(afs_int32) || ain == NULL)
+ return EINVAL;
+ bcopy(ain, (char *)&tmpval, sizeof(afs_int32));
+ /* if new mappings added later this will need to be changed */
+ if (tmpval != 0 && tmpval != 1)
+ return EINVAL;
+ cryptall = tmpval;
+ return 0;
+}
+
/*
* Create new credentials to correspond to a remote user with given
* <hostaddr, uid, g0, g1>. This allows a server running as root to
register struct vcache *tvc;
register struct dcache *tdc;
struct VenusFid tfid;
- char *bufp = 0;
- afs_int32 offset, len, hasatsys=0;
+ char *bufp;
+ struct sysname_info sysState;
+ afs_int32 offset, len;
AFS_STATCNT(PFlushMount);
if (!avc) return EINVAL;
}
tdc = afs_GetDCache(avc, 0, areq, &offset, &len, 1);
if (!tdc) return ENOENT;
- hasatsys = Check_AtSys(avc, ain, &bufp, areq);
- code = afs_dir_Lookup(&tdc->f.inode, bufp, &tfid.Fid);
+ Check_AtSys(avc, ain, &sysState, areq);
+ do {
+ code = afs_dir_Lookup(&tdc->f.inode, sysState.name, &tfid.Fid);
+ } while (code == ENOENT && Next_AtSys(avc, areq, &sysState));
+ bufp = sysState.name;
if (code) {
afs_PutDCache(tdc);
goto out;
#endif
afs_PutVCache(tvc, WRITE_LOCK);
out:
- if (hasatsys) osi_FreeLargeSpace(bufp);
+ if (sysState.allocked) osi_FreeLargeSpace(bufp);
return code;
}
return code;
}
+static PPrefetchFromTape(avc, afun, areq, ain, aout, ainSize, aoutSize)
+ struct vcache *avc;
+ int afun;
+ struct vrequest *areq;
+ char *ain, *aout;
+ afs_int32 ainSize;
+ afs_int32 *aoutSize; /* set this */
+{
+ register afs_int32 code, code1;
+ afs_int32 bytes;
+ struct conn *tc;
+ struct rx_call *tcall;
+ struct AFSVolSync tsync;
+ struct AFSFetchStatus OutStatus;
+ struct AFSCallBack CallBack;
+ struct VenusFid tfid;
+ struct AFSFid *Fid;
+ struct vcache *tvc;
+ XSTATS_DECLS;
+
+ AFS_STATCNT(PSetAcl);
+ if (!avc)
+ return EINVAL;
+
+ if (ain && (ainSize == 3 * sizeof(afs_int32)))
+ Fid = (struct AFSFid *) ain;
+ else
+ Fid = &avc->fid.Fid;
+ tfid.Cell = avc->fid.Cell;
+ tfid.Fid.Volume = Fid->Volume;
+ tfid.Fid.Vnode = Fid->Vnode;
+ tfid.Fid.Unique = Fid->Unique;
+
+ tvc = afs_GetVCache(&tfid, areq, (afs_int32 *)0, (struct vcache *)0,
+ WRITE_LOCK);
+ if (!tvc) {
+ afs_Trace3(afs_iclSetp, CM_TRACE_PREFETCHCMD,
+ ICL_TYPE_POINTER, tvc,
+ ICL_TYPE_FID, &tfid,
+ ICL_TYPE_FID, &avc->fid);
+ return ENOENT;
+ }
+ afs_Trace3(afs_iclSetp, CM_TRACE_PREFETCHCMD,
+ ICL_TYPE_POINTER, tvc,
+ ICL_TYPE_FID, &tfid,
+ ICL_TYPE_FID, &tvc->fid);
+
+ do {
+ tc = afs_Conn(&tvc->fid, areq, SHARED_LOCK);
+ if (tc) {
+
+#ifdef RX_ENABLE_LOCKS
+ AFS_GUNLOCK();
+#endif /* RX_ENABLE_LOCKS */
+ tcall = rx_NewCall(tc->id);
+ code = StartRXAFS_FetchData(tcall,
+ (struct AFSFid *) &tvc->fid.Fid, 0, 0);
+ if (!code) {
+ bytes = rx_Read(tcall, (char *) aout, sizeof(afs_int32));
+ code = EndRXAFS_FetchData(tcall, &OutStatus, &CallBack, &tsync);
+ }
+ code1 = rx_EndCall(tcall, code);
+#ifdef RX_ENABLE_LOCKS
+ AFS_GLOCK();
+#endif /* RX_ENABLE_LOCKS */
+ } else
+ code = -1;
+ } while
+ (afs_Analyze(tc, code, &tvc->fid, areq,
+ AFS_STATS_FS_RPCIDX_RESIDENCYRPCS, SHARED_LOCK,
+ (struct cell *)0));
+ /* This call is done only to have the callback things handled correctly */
+ afs_FetchStatus(tvc, &tfid, areq, &OutStatus);
+ afs_PutVCache(tvc, WRITE_LOCK);
+
+ if (!code) {
+ *aoutSize = sizeof(afs_int32);
+ }
+ return code;
+}
+
+static PResidencyCmd(avc, afun, areq, ain, aout, ainSize, aoutSize)
+struct vcache *avc;
+int afun;
+struct vrequest *areq;
+char *ain, *aout;
+afs_int32 ainSize;
+afs_int32 *aoutSize; /* set this */
+{
+ register afs_int32 code;
+ struct conn *tc;
+ struct vcache *tvc;
+ struct ResidencyCmdInputs *Inputs;
+ struct ResidencyCmdOutputs *Outputs;
+ struct VenusFid tfid;
+ struct AFSFid *Fid;
+
+ Inputs = (struct ResidencyCmdInputs *) ain;
+ Outputs = (struct ResidencyCmdOutputs *) aout;
+ if (!avc) return EINVAL;
+ if (!ain || ainSize != sizeof(struct ResidencyCmdInputs)) return EINVAL;
+
+ Fid = &Inputs->fid;
+ if (!Fid->Volume)
+ Fid = &avc->fid.Fid;
+
+ tfid.Cell = avc->fid.Cell;
+ tfid.Fid.Volume = Fid->Volume;
+ tfid.Fid.Vnode = Fid->Vnode;
+ tfid.Fid.Unique = Fid->Unique;
+
+ tvc = afs_GetVCache(&tfid, areq, (afs_int32 *)0, (struct vcache *)0,
+ WRITE_LOCK);
+ afs_Trace3(afs_iclSetp, CM_TRACE_RESIDCMD,
+ ICL_TYPE_POINTER, tvc,
+ ICL_TYPE_INT32, Inputs->command,
+ ICL_TYPE_FID, &tfid);
+ if (!tvc)
+ return ENOENT;
+
+ if (Inputs->command) {
+ do {
+ tc = afs_Conn(&tvc->fid, areq, SHARED_LOCK);
+ if (tc) {
+#ifdef RX_ENABLE_LOCKS
+ AFS_GUNLOCK();
+#endif /* RX_ENABLE_LOCKS */
+ code = RXAFS_ResidencyCmd(tc->id, Fid,
+ Inputs,
+ (struct ResidencyCmdOutputs *) aout);
+#ifdef RX_ENABLE_LOCKS
+ AFS_GLOCK();
+#endif /* RX_ENABLE_LOCKS */
+ } else
+ code = -1;
+ } while
+ (afs_Analyze(tc, code, &tvc->fid, areq,
+ AFS_STATS_FS_RPCIDX_RESIDENCYRPCS, SHARED_LOCK,
+ (struct cell *)0));
+ /* This call is done to have the callback things handled correctly */
+ afs_FetchStatus(tvc, &tfid, areq, &Outputs->status);
+ } else { /* just a status request, return also link data */
+ code = 0;
+ Outputs->code = afs_FetchStatus(tvc, &tfid, areq, &Outputs->status);
+ Outputs->chars[0] = 0;
+ if (vType(tvc) == VLNK) {
+ ObtainWriteLock(&tvc->lock,555);
+ if (afs_HandleLink(tvc, areq) == 0)
+ strncpy((char *) &Outputs->chars, tvc->linkData, MAXCMDCHARS);
+ ReleaseWriteLock(&tvc->lock);
+ }
+ }
+
+ afs_PutVCache(tvc, WRITE_LOCK);
+
+ if (!code) {
+ *aoutSize = sizeof(struct ResidencyCmdOutputs);
+ }
+ return code;
+}