vfs_lookup.c (140779) | vfs_lookup.c (141471) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)vfs_lookup.c 8.4 (Berkeley) 2/16/94 35 */ 36 37#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)vfs_lookup.c 8.4 (Berkeley) 2/16/94 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/kern/vfs_lookup.c 140779 2005-01-24 23:53:54Z phk $"); | 38__FBSDID("$FreeBSD: head/sys/kern/vfs_lookup.c 141471 2005-02-07 18:44:55Z jhb $"); |
39 40#include "opt_ktrace.h" 41#include "opt_mac.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> 46#include <sys/lock.h> 47#include <sys/mac.h> 48#include <sys/mutex.h> 49#include <sys/namei.h> 50#include <sys/vnode.h> 51#include <sys/mount.h> 52#include <sys/filedesc.h> 53#include <sys/proc.h> | 39 40#include "opt_ktrace.h" 41#include "opt_mac.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> 46#include <sys/lock.h> 47#include <sys/mac.h> 48#include <sys/mutex.h> 49#include <sys/namei.h> 50#include <sys/vnode.h> 51#include <sys/mount.h> 52#include <sys/filedesc.h> 53#include <sys/proc.h> |
54#include <sys/syscallsubr.h> |
|
54#ifdef KTRACE 55#include <sys/ktrace.h> 56#endif 57 58#include <vm/uma.h> 59 60#define NAMEI_DIAGNOSTIC 1 61#undef NAMEI_DIAGNOSTIC --- 740 unchanged lines hidden (view full) --- 802 if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN)) 803 VOP_UNLOCK(dvp, 0, td); 804 vrele(dvp); 805bad: 806 vput(dp); 807 *vpp = NULL; 808 return (error); 809} | 55#ifdef KTRACE 56#include <sys/ktrace.h> 57#endif 58 59#include <vm/uma.h> 60 61#define NAMEI_DIAGNOSTIC 1 62#undef NAMEI_DIAGNOSTIC --- 740 unchanged lines hidden (view full) --- 803 if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN)) 804 VOP_UNLOCK(dvp, 0, td); 805 vrele(dvp); 806bad: 807 vput(dp); 808 *vpp = NULL; 809 return (error); 810} |
811 812/* 813 * Determine if there is a suitable alternate filename under the specified 814 * prefix for the specified path. If the create flag is set, then the 815 * alternate prefix will be used so long as the parent directory exists. 816 * This is used by the various compatiblity ABIs so that Linux binaries prefer 817 * files under /compat/linux for example. The chosen path (whether under 818 * the prefix or under /) is returned in a kernel malloc'd buffer pointed 819 * to by pathbuf. The caller is responsible for free'ing the buffer from 820 * the M_TEMP bucket if one is returned. 821 */ 822int 823kern_alternate_path(struct thread *td, const char *prefix, char *path, 824 enum uio_seg pathseg, char **pathbuf, int create) 825{ 826 struct nameidata nd, ndroot; 827 char *ptr, *buf, *cp; 828 size_t len, sz; 829 int error; 830 831 buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 832 *pathbuf = buf; 833 834 /* Copy the prefix into the new pathname as a starting point. */ 835 len = strlcpy(buf, prefix, MAXPATHLEN); 836 if (len >= MAXPATHLEN) { 837 *pathbuf = NULL; 838 free(buf, M_TEMP); 839 return (EINVAL); 840 } 841 sz = MAXPATHLEN - len; 842 ptr = buf + len; 843 844 /* Append the filename to the prefix. */ 845 if (pathseg == UIO_SYSSPACE) 846 error = copystr(path, ptr, sz, &len); 847 else 848 error = copyinstr(path, ptr, sz, &len); 849 850 if (error) { 851 *pathbuf = NULL; 852 free(buf, M_TEMP); 853 return (error); 854 } 855 856 /* Only use a prefix with absolute pathnames. */ 857 if (*ptr != '/') { 858 error = EINVAL; 859 goto keeporig; 860 } 861 862 /* XXX: VFS_LOCK_GIANT? */ 863 mtx_lock(&Giant); 864 865 /* 866 * We know that there is a / somewhere in this pathname. 867 * Search backwards for it, to find the file's parent dir 868 * to see if it exists in the alternate tree. If it does, 869 * and we want to create a file (cflag is set). We don't 870 * need to worry about the root comparison in this case. 871 */ 872 873 if (create) { 874 for (cp = &ptr[len] - 1; *cp != '/'; cp--); 875 *cp = '\0'; 876 877 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 878 error = namei(&nd); 879 *cp = '/'; 880 if (error != 0) 881 goto nd_failed; 882 } else { 883 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); 884 885 error = namei(&nd); 886 if (error != 0) 887 goto nd_failed; 888 889 /* 890 * We now compare the vnode of the prefix to the one 891 * vnode asked. If they resolve to be the same, then we 892 * ignore the match so that the real root gets used. 893 * This avoids the problem of traversing "../.." to find the 894 * root directory and never finding it, because "/" resolves 895 * to the emulation root directory. This is expensive :-( 896 */ 897 NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, prefix, td); 898 899 /* We shouldn't ever get an error from this namei(). */ 900 error = namei(&ndroot); 901 if (error == 0) { 902 if (nd.ni_vp == ndroot.ni_vp) 903 error = ENOENT; 904 905 NDFREE(&ndroot, NDF_ONLY_PNBUF); 906 vrele(ndroot.ni_vp); 907 } 908 } 909 910 NDFREE(&nd, NDF_ONLY_PNBUF); 911 vrele(nd.ni_vp); 912 913nd_failed: 914 /* XXX: VFS_UNLOCK_GIANT? */ 915 mtx_unlock(&Giant); 916 917keeporig: 918 /* If there was an error, use the original path name. */ 919 if (error) 920 bcopy(ptr, buf, len); 921 return (error); 922} |
|