Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jun 2007 19:05:07 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 120925 for review
Message-ID:  <200706041905.l54J57TX082696@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/param.h>
 #include <sys/systm.h>
 #include <sys/exec.h>
+#include <sys/fcntl.h>
 #include <sys/imgact.h>
 #include <sys/imgact_elf.h>
 #include <sys/kernel.h>
@@ -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 <sys/fcntl.h>
 #include <sys/param.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.c#2 (text+ko) ====

@@ -36,6 +36,7 @@
 
 #include <sys/param.h>
 #include <sys/bus.h>
+#include <sys/fcntl.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/linker_set.h>
@@ -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 <sys/sysent.h>
 #include <sys/imgact.h>
 #include <sys/imgact_elf.h>
+#include <sys/fcntl.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
@@ -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 <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/sys/i386/ibcs2/ibcs2_util.c,v 1.19 2005/02/07 22:02:18 jhb Exp $");
 
+#include <sys/fcntl.h>
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/syscallsubr.h>
@@ -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 <sys/param.h>
 #include <sys/systm.h>
 #include <sys/exec.h>
+#include <sys/fcntl.h>
 #include <sys/imgact.h>
 #include <sys/imgact_aout.h>
 #include <sys/imgact_elf.h>
@@ -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 <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/fcntl.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/namei.h>
@@ -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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706041905.l54J57TX082696>