/* * Lookup the user file name, * Handle allocation and freeing of pathname buffer, return error. */ int lookupnameatcred( char *fnamep, /* user pathname */ enum uio_seg seg, /* addr space that name is in */ int followlink, /* follow sym links */ vnode_t **dirvpp, /* ret for ptr to parent dir vnode */ vnode_t **compvpp, /* ret for ptr to component vnode */ vnode_t *startvp, /* start path search from vp */ cred_t *cr) /* credential */ { char namebuf[TYPICALMAXPATHLEN]; struct pathname lookpn; int error; error = pn_get_buf(fnamep, seg, &lookpn, namebuf, sizeof (namebuf)); if (error == 0) { error = lookuppnatcred(&lookpn, NULL, followlink, dirvpp, compvpp, startvp, cr); } if (error == ENAMETOOLONG) { /* * This thread used a pathname > TYPICALMAXPATHLEN bytes long. */ if (error = pn_get(fnamep, seg, &lookpn)) return (error); error = lookuppnatcred(&lookpn, NULL, followlink, dirvpp, compvpp, startvp, cr); pn_free(&lookpn); } return (error); }
/* * Pull a path name from user or kernel space. */ int pn_get(char *str, enum uio_seg seg, struct pathname *pnp) { int error; void *buf; buf = kmem_alloc(MAXPATHLEN, KM_SLEEP); if ((error = pn_get_buf(str, seg, pnp, buf, MAXPATHLEN)) != 0) pn_free(pnp); return (error); }
void * osi_UfsOpen(afs_dcache_id_t *ainode) { #ifdef AFS_CACHE_VNODE_PATH struct vnode *vp; #else struct inode *ip; #endif struct osi_file *afile = NULL; afs_int32 code = 0; int dummy; #ifdef AFS_CACHE_VNODE_PATH char namebuf[1024]; struct pathname lookpn; #endif struct osi_stat tstat; afile = osi_AllocSmallSpace(sizeof(struct osi_file)); AFS_GUNLOCK(); /* * AFS_CACHE_VNODE_PATH can be used with any file system, including ZFS or tmpfs. * The ainode is not an inode number but a path. */ #ifdef AFS_CACHE_VNODE_PATH /* Can not use vn_open or lookupname, they use user's CRED() * We need to run as root So must use low level lookuppnvp * assume fname starts with / */ code = pn_get_buf(ainode->ufs, AFS_UIOSYS, &lookpn, namebuf, sizeof(namebuf)); if (code != 0) osi_Panic("UfsOpen: pn_get_buf failed %ld %s", code, ainode->ufs); VN_HOLD(rootdir); /* released in loopuppnvp */ code = lookuppnvp(&lookpn, NULL, FOLLOW, NULL, &vp, rootdir, rootdir, afs_osi_credp); if (code != 0) osi_Panic("UfsOpen: lookuppnvp failed %ld %s", code, ainode->ufs); #ifdef AFS_SUN511_ENV code = VOP_OPEN(&vp, FREAD|FWRITE, afs_osi_credp, NULL); #else code = VOP_OPEN(&vp, FREAD|FWRITE, afs_osi_credp); #endif if (code != 0) osi_Panic("UfsOpen: VOP_OPEN failed %ld %s", code, ainode->ufs); #else code = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, ainode->ufs, &ip, CRED(), &dummy); #endif AFS_GLOCK(); if (code) { osi_FreeSmallSpace(afile); osi_Panic("UfsOpen: igetinode failed %ld %s", code, ainode->ufs); } #ifdef AFS_CACHE_VNODE_PATH afile->vnode = vp; code = afs_osi_Stat(afile, &tstat); afile->size = tstat.size; #else afile->vnode = ITOV(ip); afile->size = VTOI(afile->vnode)->i_size; #endif afile->offset = 0; afile->proc = (int (*)())0; return (void *)afile; }