Deleted Added
full compact
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}