From owner-p4-projects@FreeBSD.ORG Mon Jun 4 19:05:07 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id BE3D916A421; Mon, 4 Jun 2007 19:05:07 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 7859B16A400 for ; Mon, 4 Jun 2007 19:05:07 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 674D613C43E for ; Mon, 4 Jun 2007 19:05:07 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l54J5756082726 for ; Mon, 4 Jun 2007 19:05:07 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l54J57TX082696 for perforce@freebsd.org; Mon, 4 Jun 2007 19:05:07 GMT (envelope-from rdivacky@FreeBSD.org) Date: Mon, 4 Jun 2007 19:05:07 GMT Message-Id: <200706041905.l54J57TX082696@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 120925 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Jun 2007 19:05:08 -0000 http://perforce.freebsd.org/chv.cgi?CH=120925 Change 120925 by rdivacky@rdivacky_witten on 2007/06/04 19:04:41 Modify kern_alternate_path() to take dirfd argument as this is needed for linuxulator. Use it as such for *at syscalls. Finally those functions work reliably. Affected files ... .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysvec.c#3 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#9 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_stats.c#8 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_uid16.c#2 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.c#2 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.h#2 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/svr4/svr4_sysvec.c#2 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/ibcs2/ibcs2_util.c#2 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysvec.c#2 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_lookup.c#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#8 edit Differences ... ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysvec.c#3 (text+ko) ==== @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -787,7 +788,7 @@ */ if ((error = exec_shell_imgact(imgp)) == 0) { linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), - imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0); + imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD); if (rpath != NULL) { len = strlen(rpath) + 1; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#9 (text+ko) ==== @@ -183,33 +183,26 @@ int linux_openat(struct thread *td, struct linux_openat_args *args) { - char *newpath, *path; - int error, dirfd; + char *path; + int dfd; - path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - error = copyinstr(args->filename, path, MAXPATHLEN, NULL); - if (error) { - free(path, M_TEMP); - return (error); - } + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; if (args->flags & LINUX_O_CREAT) - LCONVPATH_SEG(td, path, &newpath, 1, UIO_SYSSPACE); + LCONVPATH_AT(td, args->filename, &path, 1, dfd); else - LCONVPATH_SEG(td, path, &newpath, 0, UIO_SYSSPACE); - free(path, M_TEMP); + LCONVPATH_AT(td, args->filename, &path, 0, dfd); #ifdef DEBUG if (ldebug(openat)) +#endif printf(ARGS(openat, "%i, %s, 0x%x, 0x%x"), args->dfd, - newpath, args->flags, args->mode); -#endif - if (args->dfd == LINUX_AT_FDCWD) - dirfd = AT_FDCWD; - else - dirfd = args->dfd; + path, args->flags, args->mode); - return linux_common_open(td, path, args->flags, args->mode, dirfd); + return linux_common_open(td, path, args->flags, args->mode, dfd); } int @@ -587,18 +580,18 @@ if (args->mode & ~(F_OK | X_OK | W_OK | R_OK)) return (EINVAL); - LCONVPATHEXIST(td, args->filename, &path); + if (args->dfd == LINUX_AT_FDCWD) + dfd = -1; + else + dfd = args->dfd; + + LCONVPATHEXIST_AT(td, args->filename, &path, dfd); #ifdef DEBUG if (ldebug(access)) printf(ARGS(access, "%s, %d"), path, args->mode); #endif - if (args->dfd == LINUX_AT_FDCWD) - dfd = -1; - else - dfd = args->dfd; - error = kern_accessat(td, path, UIO_SYSSPACE, args->mode, dfd); LFREEPATH(path); @@ -639,25 +632,25 @@ if (args->flag & ~LINUX_AT_REMOVEDIR) return (EINVAL); - LCONVPATHEXIST(td, args->pathname, &path); + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHEXIST_AT(td, args->pathname, &path, dfd); #ifdef DEBUG if (ldebug(unlinkat)) printf(ARGS(unlinkat, "%s"), path); #endif - if (args->dfd == LINUX_AT_FDCWD) - dfd = AT_FDCWD; - else - dfd = args->dfd; - if (args->flag & LINUX_AT_REMOVEDIR) error = kern_rmdirat(td, path, UIO_SYSSPACE, dfd); else error = kern_unlinkat(td, path, UIO_SYSSPACE, dfd); if (error == EPERM) /* Introduce POSIX noncompliant behaviour of Linux */ - if (kern_stat(td, path, UIO_SYSSPACE, &st) == 0) + if (kern_statat(td, path, UIO_SYSSPACE, &st, dfd) == 0) if (S_ISDIR(st.st_mode)) error = EISDIR; LFREEPATH(path); @@ -703,17 +696,17 @@ char *path; int error, dfd; - LCONVPATHEXIST(td, args->filename, &path); + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHEXIST_AT(td, args->filename, &path, dfd); #ifdef DEBUG if (ldebug(fchmodat)) printf(ARGS(fchmodat, "%s, %d"), path, args->mode); #endif - - if (args->dfd == LINUX_AT_FDCWD) - dfd = AT_FDCWD; - else - dfd = args->dfd; error = kern_chmodat(td, path, UIO_SYSSPACE, args->mode, dfd); LFREEPATH(path); @@ -761,7 +754,7 @@ LCONVPATHEXIST(td, args->from, &from); /* Expand LCONVPATHCREATE so that `from' can be freed on errors */ - error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1); + error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(from); return (error); @@ -785,7 +778,7 @@ LCONVPATHEXIST(td, args->path, &path); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ - error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1); + error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(path); return (error); @@ -807,9 +800,14 @@ char *path, *to; int error, dfd; - LCONVPATHEXIST(td, args->oldname, &path); + if (args->newdfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->newdfd; + + LCONVPATHEXIST_AT(td, args->oldname, &path, dfd); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ - error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1); + error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, dfd); if (to == NULL) { LFREEPATH(path); return (error); @@ -819,10 +817,6 @@ if (ldebug(symlinkat)) printf(ARGS(symlinkat, "%s, %s"), path, to); #endif - if (args->newdfd == LINUX_AT_FDCWD) - dfd = AT_FDCWD; - else - dfd = args->newdfd; error = kern_symlinkat(td, path, to, UIO_SYSSPACE, dfd); LFREEPATH(path); @@ -855,7 +849,12 @@ char *name; int error, dfd; - LCONVPATHEXIST(td, args->path, &name); + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHEXIST_AT(td, args->path, &name, dfd); #ifdef DEBUG if (ldebug(readlinkat)) @@ -863,11 +862,6 @@ args->bufsiz); #endif - if (args->dfd == LINUX_AT_FDCWD) - dfd = AT_FDCWD; - else - dfd = args->dfd; - error = kern_readlinkat(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, args->bufsiz, dfd); LFREEPATH(name); @@ -914,7 +908,7 @@ LCONVPATHEXIST(td, args->path, &path); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ - error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1); + error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); if (to == NULL) { LFREEPATH(path); return (error); @@ -943,9 +937,19 @@ if (args->flags != 0) return (EINVAL); - LCONVPATHEXIST(td, args->oldname, &path); + if (args->olddfd == LINUX_AT_FDCWD) + olddfd = AT_FDCWD; + else + olddfd = args->olddfd; + + if (args->newdfd == LINUX_AT_FDCWD) + newdfd = AT_FDCWD; + else + newdfd = args->newdfd; + + LCONVPATHEXIST_AT(td, args->oldname, &path, olddfd); /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ - error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1); + error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd); if (to == NULL) { LFREEPATH(path); return (error); @@ -956,16 +960,7 @@ printf(ARGS(linkat, "%i, %s, %i, %s, %i"), args->olddfd, path, args->newdfd, to, args->flags); #endif - if (args->olddfd == LINUX_AT_FDCWD) - olddfd = AT_FDCWD; - else - olddfd = args->olddfd; - if (args->newdfd == LINUX_AT_FDCWD) - newdfd = AT_FDCWD; - else - newdfd = args->newdfd; - error = kern_linkat(td, path, to, UIO_SYSSPACE, olddfd, newdfd); LFREEPATH(path); LFREEPATH(to); @@ -1446,17 +1441,17 @@ if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW) return (EINVAL); - LCONVPATHEXIST(td, args->filename, &path); + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHEXIST_AT(td, args->filename, &path, dfd); #ifdef DEBUG if (ldebug(fchownat)) printf(ARGS(fchownat, "%s, %d, %d"), path, args->uid, args->gid); #endif - - if (args->dfd == LINUX_AT_FDCWD) - dfd = AT_FDCWD; - else - dfd = args->dfd; if (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) error = kern_lchownat(td, path, UIO_SYSSPACE, args->uid, args->gid, dfd); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_stats.c#8 (text+ko) ==== @@ -608,18 +608,18 @@ if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW) return (EINVAL); - LCONVPATHEXIST(td, args->pathname, &path); + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHEXIST_AT(td, args->pathname, &path, dfd); #ifdef DEBUG if (ldebug(fstatat64)) printf(ARGS(fstatat64, "%i, %s, %i"), args->dfd, path, args->flag); #endif - if (args->dfd == LINUX_AT_FDCWD) - dfd = AT_FDCWD; - else - dfd = args->dfd; - if (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) error = kern_lstatat(td, path, UIO_SYSSPACE, &buf, dfd); else ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_uid16.c#2 (text+ko) ==== @@ -29,6 +29,7 @@ #include "opt_compat.h" +#include #include #include #include ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.c#2 (text+ko) ==== @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -65,16 +66,17 @@ * named file, i.e. we check if the directory it should be in exists. */ int -linux_emul_convpath(td, path, pathseg, pbuf, cflag) +linux_emul_convpath(td, path, pathseg, pbuf, cflag, dfd) struct thread *td; char *path; enum uio_seg pathseg; char **pbuf; int cflag; + int dfd; { - return (kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf, - cflag)); + return kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf, + cflag, dfd); } void ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.h#2 (text+ko) ==== @@ -51,22 +51,23 @@ extern const char linux_emul_path[]; -int linux_emul_convpath(struct thread *, char *, enum uio_seg, char **, int); +int linux_emul_convpath(struct thread *, char *, enum uio_seg, char **, int, int); -#define LCONVPATH_SEG(td, upath, pathp, i, seg) \ +#define LCONVPATH_AT(td, upath, pathp, i, dfd) \ do { \ int _error; \ \ - _error = linux_emul_convpath(td, upath, seg, \ - pathp, i); \ + _error = linux_emul_convpath(td, upath, UIO_USERSPACE, \ + pathp, i, dfd); \ if (*(pathp) == NULL) \ return (_error); \ } while (0) #define LCONVPATH(td, upath, pathp, i) \ - LCONVPATH_SEG(td, upath, pathp, i, UIO_USERSPACE) + LCONVPATH_AT(td, upath, pathp, i, AT_FDCWD) #define LCONVPATHEXIST(td, upath, pathp) LCONVPATH(td, upath, pathp, 0) +#define LCONVPATHEXIST_AT(td, upath, pathp, dfd) LCONVPATH_AT(td, upath, pathp, 0, dfd) #define LCONVPATHCREAT(td, upath, pathp) LCONVPATH(td, upath, pathp, 1) #define LFREEPATH(path) free(path, M_TEMP) ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/svr4/svr4_sysvec.c#2 (text+ko) ==== @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -258,7 +259,7 @@ { return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf, - create)); + create, AT_FDCWD)); } static int ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/ibcs2/ibcs2_util.c#2 (text+ko) ==== @@ -32,6 +32,7 @@ #include __FBSDID("$FreeBSD: src/sys/i386/ibcs2/ibcs2_util.c,v 1.19 2005/02/07 22:02:18 jhb Exp $"); +#include #include #include #include @@ -55,5 +56,5 @@ { return (kern_alternate_path(td, ibcs2_emul_path, path, pathseg, pbuf, - cflag)); + cflag, AT_FDCWD)); } ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysvec.c#2 (text+ko) ==== @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -775,7 +776,7 @@ */ if ((error = exec_shell_imgact(imgp)) == 0) { linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc), - imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0); + imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD); if (rpath != NULL) { len = strlen(rpath) + 1; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_lookup.c#5 (text+ko) ==== @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -1004,12 +1005,13 @@ */ int kern_alternate_path(struct thread *td, const char *prefix, char *path, - enum uio_seg pathseg, char **pathbuf, int create) + enum uio_seg pathseg, char **pathbuf, int create, int dirfd) { struct nameidata nd, ndroot; char *ptr, *buf, *cp; size_t len, sz; int error; + struct vnode *dir_vn; buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); *pathbuf = buf; @@ -1042,6 +1044,18 @@ goto keeporig; } + if (dirfd == AT_FDCWD) + dir_vn = NULL; + else { + /* + * we want the original because the "prefix" + * is included in the already opened dirfd + */ + bcopy(ptr, buf, len); + return (0); + } + + /* * We know that there is a / somewhere in this pathname. * Search backwards for it, to find the file's parent dir @@ -1054,13 +1068,13 @@ for (cp = &ptr[len] - 1; *cp != '/'; cp--); *cp = '\0'; - NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td); + NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td, dir_vn); error = namei(&nd); *cp = '/'; if (error != 0) goto keeporig; } else { - NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td); + NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td, dir_vn); error = namei(&nd); if (error != 0) ==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#8 (text+ko) ==== @@ -60,7 +60,7 @@ int kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta); int kern_alternate_path(struct thread *td, const char *prefix, char *path, - enum uio_seg pathseg, char **pathbuf, int create); + enum uio_seg pathseg, char **pathbuf, int create, int dirfd); int kern_bind(struct thread *td, int fd, struct sockaddr *sa); int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg); int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg,