void * osi_UFSOpen(afs_dcache_id_t *ainode) { struct inode *ip; struct osi_file *afile = NULL; extern int cacheDiskType; afs_int32 code = 0; int dummy; AFS_STATCNT(osi_UFSOpen); if (cacheDiskType != AFS_FCACHE_TYPE_UFS) { osi_Panic("UFSOpen called for non-UFS cache\n"); } if (!afs_osicred_initialized) { /* valid for alpha_osf, SunOS, Ultrix */ memset(&afs_osi_cred, 0, sizeof(afs_ucred_t)); crhold(&afs_osi_cred); /* don't let it evaporate, since it is static */ afs_osicred_initialized = 1; } afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file)); setuerror(0); AFS_GUNLOCK(); ip = (struct inode *)igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, (ino_t) ainode->ufs, &dummy); AFS_GLOCK(); if (getuerror()) { osi_FreeSmallSpace(afile); osi_Panic("UFSOpen: igetinode failed"); } iunlock(ip); afile->vnode = ITOV(ip); afile->size = VTOI(afile->vnode)->i_size; afile->offset = 0; afile->proc = (int (*)())0; return (void *)afile; }
/* called with the GLOCK held */ int afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow) { cred_t *credp = crref(); /* don't free until done! */ struct afs_ioctl data; struct clientcred ccred; struct rmtbulk idata, odata; short in_size, out_size; afs_int32 code = 0, pag, err; gid_t g0, g1; char *abspath, *pathbuf = 0; AFS_STATCNT(afs_syscall_pioctl); if (follow) follow = 1; /* compat. with old venus */ code = copyin_afs_ioctl(cmarg, &data); if (code) goto out; if ((com & 0xff) == 90) { /* PSetClientContext, in any space */ code = EINVAL; goto out; } /* Special handling for a few pioctls */ switch (com & 0xffff) { case (0x5600 | 3): /* VIOCSETTOK */ code = afspag_PSetTokens(data.in, data.in_size, &credp); if (code) goto out; break; case (0x5600 | 9): /* VIOCUNLOG */ case (0x5600 | 21): /* VIOCUNPAG */ code = afspag_PUnlog(data.in, data.in_size, &credp); if (code) goto out; break; case (0x5600 | 38): /* VIOC_AFS_SYSNAME */ code = afspag_PSetSysName(data.in, data.in_size, &credp); if (code) goto out; break; } /* Set up credentials */ memset(&ccred, 0, sizeof(ccred)); pag = PagInCred(credp); ccred.uid = afs_cr_uid(credp); if (pag != NOPAG) { afs_get_groups_from_pag(pag, &g0, &g1); ccred.group0 = g0; ccred.group1 = g1; } /* * Copy the path and convert to absolute, if one was given. * NB: We can only use osI_AllocLargeSpace here as long as * RMTSYS_MAXPATHLEN is less than AFS_LRALLOCSIZ. */ if (path) { pathbuf = osi_AllocLargeSpace(RMTSYS_MAXPATHLEN); if (!pathbuf) { code = ENOMEM; goto out; } code = osi_abspath(path, pathbuf, RMTSYS_MAXPATHLEN, 0, &abspath); if (code) goto out_path; } else { abspath = NIL_PATHP; } /* Allocate, copy, and convert incoming data */ idata.rmtbulk_len = in_size = data.in_size; if (in_size < 0 || in_size > MAXBUFFERLEN) { code = EINVAL; goto out_path; } if (in_size > AFS_LRALLOCSIZ) idata.rmtbulk_val = osi_Alloc(in_size); else idata.rmtbulk_val = osi_AllocLargeSpace(AFS_LRALLOCSIZ); if (!idata.rmtbulk_val) { code = ENOMEM; goto out_path; } if (in_size) { AFS_COPYIN(data.in, idata.rmtbulk_val, in_size, code); if (code) goto out_idata; inparam_conversion(com, idata.rmtbulk_val, in_size, 0); } /* Allocate space for outgoing data */ odata.rmtbulk_len = out_size = data.out_size; if (out_size < 0 || out_size > MAXBUFFERLEN) { code = EINVAL; goto out_idata; } if (out_size > AFS_LRALLOCSIZ) odata.rmtbulk_val = osi_Alloc(out_size); else odata.rmtbulk_val = osi_AllocLargeSpace(AFS_LRALLOCSIZ); if (!odata.rmtbulk_val) { code = ENOMEM; goto out_idata; } AFS_GUNLOCK(); code = RMTSYS_Pioctl(rmtsys_conn, &ccred, abspath, com, follow, &idata, &odata, &err); AFS_GLOCK(); if (code) goto out_odata; /* Convert and copy out the result */ if (odata.rmtbulk_len > out_size) { code = E2BIG; goto out_odata; } if (odata.rmtbulk_len) { outparam_conversion(com, odata.rmtbulk_val, odata.rmtbulk_len, 1); AFS_COPYOUT(odata.rmtbulk_val, data.out, odata.rmtbulk_len, code); } if (!code) code = err; out_odata: if (out_size > AFS_LRALLOCSIZ) osi_Free(odata.rmtbulk_val, out_size); else osi_FreeLargeSpace(odata.rmtbulk_val); out_idata: if (in_size > AFS_LRALLOCSIZ) osi_Free(idata.rmtbulk_val, in_size); else osi_FreeLargeSpace(idata.rmtbulk_val); out_path: if (path) osi_FreeLargeSpace(pathbuf); out: crfree(credp); #if defined(KERNEL_HAVE_UERROR) if (!getuerror()) setuerror(code); return (getuerror()); #else return (code); #endif }
/* * syscall - this is the VRMIX system call entry point. * * NOTE: * THIS SHOULD BE CHANGED TO afs_syscall(), but requires * all the user-level calls to `syscall' to change. */ syscall(syscall, p1, p2, p3, p4, p5, p6) { int rval1 = 0, code; int monster; int retval = 0; #ifndef AFS_AIX41_ENV extern lock_t kernel_lock; monster = lockl(&kernel_lock, LOCK_SHORT); #endif /* !AFS_AIX41_ENV */ AFS_STATCNT(syscall); setuerror(0); switch (syscall) { case AFSCALL_CALL: rval1 = afs_syscall_call(p1, p2, p3, p4, p5, p6); break; case AFSCALL_SETPAG: AFS_GLOCK(); rval1 = afs_setpag(); AFS_GUNLOCK(); break; case AFSCALL_PIOCTL: AFS_GLOCK(); rval1 = afs_syscall_pioctl(p1, p2, p3, p4); AFS_GUNLOCK(); break; case AFSCALL_ICREATE: rval1 = afs_syscall_icreate(p1, p2, p3, p4, p5, p6); break; case AFSCALL_IOPEN: rval1 = afs_syscall_iopen(p1, p2, p3); break; case AFSCALL_IDEC: rval1 = afs_syscall_iincdec(p1, p2, p3, -1); break; case AFSCALL_IINC: rval1 = afs_syscall_iincdec(p1, p2, p3, 1); break; case AFSCALL_ICL: AFS_GLOCK(); code = Afscall_icl(p1, p2, p3, p4, p5, &retval); AFS_GUNLOCK(); if (!code) rval1 = retval; if (!rval1) rval1 = code; break; default: rval1 = EINVAL; setuerror(EINVAL); break; } out: #ifndef AFS_AIX41_ENV if (monster != LOCK_NEST) unlockl(&kernel_lock); #endif /* !AFS_AIX41_ENV */ return getuerror()? -1 : rval1; }