opensolaris_lookup.c revision 185029
11541Srgrimes/*- 21541Srgrimes * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> 31541Srgrimes * All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 141541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 151541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 181541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241541Srgrimes * SUCH DAMAGE. 251541Srgrimes */ 261541Srgrimes 271541Srgrimes#include <sys/cdefs.h> 281541Srgrimes__FBSDID("$FreeBSD: head/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c 185029 2008-11-17 20:49:29Z pjd $"); 291541Srgrimes 301541Srgrimes#include <sys/param.h> 311541Srgrimes#include <sys/kernel.h> 321541Srgrimes#include <sys/systm.h> 331541Srgrimes#include <sys/pathname.h> 341541Srgrimes#include <sys/vfs.h> 351541Srgrimes#include <sys/vnode.h> 3636503Speter 371541Srgrimesint 381541Srgrimeslookupname(char *dirname, enum uio_seg seg, enum symfollow follow, 3983651Speter vnode_t **dirvpp, vnode_t **compvpp) 4083651Speter{ 4183651Speter 421541Srgrimes return (lookupnameat(dirname, seg, follow, dirvpp, compvpp, NULL)); 431541Srgrimes} 441541Srgrimes 451541Srgrimesint 461541Srgrimeslookupnameat(char *dirname, enum uio_seg seg, enum symfollow follow, 4783651Speter vnode_t **dirvpp, vnode_t **compvpp, vnode_t *startvp) 481541Srgrimes{ 4948274Speter struct nameidata nd; 5048274Speter int error, ltype; 5160041Sphk 5231886Sbde ASSERT(dirvpp == NULL); 531541Srgrimes 541541Srgrimes vref(startvp); 551541Srgrimes ltype = VOP_ISLOCKED(startvp); 561541Srgrimes VOP_UNLOCK(startvp, 0); 571541Srgrimes NDINIT_ATVP(&nd, LOOKUP, LOCKLEAF | MPSAFE | follow, seg, dirname, 581541Srgrimes startvp, curthread); 591541Srgrimes error = namei(&nd); 609336Sdfr *compvpp = nd.ni_vp; 612997Swollman NDFREE(&nd, NDF_ONLY_PNBUF); 622997Swollman vn_lock(startvp, ltype | LK_RETRY); 6383651Speter return (error); 641541Srgrimes} 653305Sphk 6612662Sdgint 6712662Sdgtraverse(vnode_t **cvpp, int lktype) 6892783Sjeff{ 693305Sphk kthread_t *td = curthread; 701541Srgrimes vnode_t *cvp; 719336Sdfr vnode_t *tvp; 7283651Speter vfs_t *vfsp; 7383651Speter int error; 741541Srgrimes 7583651Speter cvp = *cvpp; 7683651Speter tvp = NULL; 771541Srgrimes 781541Srgrimes /* 791541Srgrimes * If this vnode is mounted on, then we transparently indirect 801541Srgrimes * to the vnode which is the root of the mounted file system. 811541Srgrimes * Before we do this we must check that an unmount is not in 821541Srgrimes * progress on this vnode. 831541Srgrimes */ 8483651Speter 8583651Speter for (;;) { 8683651Speter /* 8783651Speter * Reached the end of the mount chain? 881541Srgrimes */ 891541Srgrimes vfsp = vn_mountedvfs(cvp); 9036541Speter if (vfsp == NULL) 9112911Sphk break; 9283651Speter /* 9312911Sphk * tvp is NULL for *cvpp vnode, which we can't unlock. 9412911Sphk */ 9583651Speter if (tvp != NULL) 9683651Speter vput(cvp); 979336Sdfr else 9883651Speter vrele(cvp); 9983651Speter 1009759Sbde /* 10183651Speter * The read lock must be held across the call to VFS_ROOT() to 10283651Speter * prevent a concurrent unmount from destroying the vfs. 10338894Sbde */ 1049336Sdfr error = VFS_ROOT(vfsp, lktype, &tvp, td); 1059336Sdfr if (error != 0) 1069336Sdfr return (error); 1079336Sdfr cvp = tvp; 1089336Sdfr } 1099336Sdfr 1109336Sdfr *cvpp = cvp; 1119336Sdfr return (0); 1129336Sdfr} 1139336Sdfr