Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Jun 2007 20:17:50 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 120927 for review
Message-ID:  <200706042017.l54KHohh053993@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=120927

Change 120927 by rdivacky@rdivacky_witten on 2007/06/04 20:16:51

	Implement the rest of the *at syscalls.

Affected files ...

.. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_dummy.c#8 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_proto.h#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_syscall.h#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysent.c#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/syscalls.master#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#10 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_misc.c#3 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.h#3 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_dummy.c#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_proto.h#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_syscall.h#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysent.c#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/syscalls.master#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#16 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#9 edit

Differences ...

==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_dummy.c#8 (text+ko) ====

@@ -96,10 +96,6 @@
 DUMMY(inotify_add_watch);
 DUMMY(inotify_rm_watch);
 DUMMY(migrate_pages);
-DUMMY(mkdirat);
-DUMMY(mknodat);
-DUMMY(futimesat);
-DUMMY(renameat);
 DUMMY(pselect6);
 DUMMY(ppoll);
 DUMMY(unshare);

==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_proto.h#7 (text+ko) ====

@@ -880,10 +880,15 @@
 	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
 };
 struct linux_mkdirat_args {
-	register_t dummy;
+	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+	char pathname_l_[PADL_(char *)]; char * pathname; char pathname_r_[PADR_(char *)];
+	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
 };
 struct linux_mknodat_args {
-	register_t dummy;
+	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+	char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+	char dev_l_[PADL_(l_uint)]; l_uint dev; char dev_r_[PADR_(l_uint)];
 };
 struct linux_fchownat_args {
 	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -893,7 +898,9 @@
 	char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
 };
 struct linux_futimesat_args {
-	register_t dummy;
+	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+	char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+	char utimes_l_[PADL_(struct l_timeval *)]; struct l_timeval * utimes; char utimes_r_[PADR_(struct l_timeval *)];
 };
 struct linux_fstatat64_args {
 	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -907,7 +914,10 @@
 	char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
 };
 struct linux_renameat_args {
-	register_t dummy;
+	char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)];
+	char oldname_l_[PADL_(char *)]; char * oldname; char oldname_r_[PADR_(char *)];
+	char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)];
+	char newname_l_[PADL_(char *)]; char * newname; char newname_r_[PADR_(char *)];
 };
 struct linux_linkat_args {
 	char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)];

==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_syscall.h#7 (text+ko) ====


==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysent.c#7 (text+ko) ====

@@ -316,13 +316,13 @@
 	{ 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0 },	/* 293 = linux_inotify_rm_watch */
 	{ 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0 },	/* 294 = linux_migrate_pages */
 	{ AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0 },	/* 295 = linux_openat */
-	{ 0, (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 },	/* 296 = linux_mkdirat */
-	{ 0, (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 },	/* 297 = linux_mknodat */
+	{ AS(linux_mkdirat_args), (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 },	/* 296 = linux_mkdirat */
+	{ AS(linux_mknodat_args), (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 },	/* 297 = linux_mknodat */
 	{ AS(linux_fchownat_args), (sy_call_t *)linux_fchownat, AUE_NULL, NULL, 0, 0 },	/* 298 = linux_fchownat */
-	{ 0, (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 },	/* 299 = linux_futimesat */
+	{ AS(linux_futimesat_args), (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 },	/* 299 = linux_futimesat */
 	{ AS(linux_fstatat64_args), (sy_call_t *)linux_fstatat64, AUE_NULL, NULL, 0, 0 },	/* 300 = linux_fstatat64 */
 	{ AS(linux_unlinkat_args), (sy_call_t *)linux_unlinkat, AUE_NULL, NULL, 0, 0 },	/* 301 = linux_unlinkat */
-	{ 0, (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 },	/* 302 = linux_renameat */
+	{ AS(linux_renameat_args), (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 },	/* 302 = linux_renameat */
 	{ AS(linux_linkat_args), (sy_call_t *)linux_linkat, AUE_NULL, NULL, 0, 0 },	/* 303 = linux_linkat */
 	{ AS(linux_symlinkat_args), (sy_call_t *)linux_symlinkat, AUE_NULL, NULL, 0, 0 },	/* 304 = linux_symlinkat */
 	{ AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 },	/* 305 = linux_readlinkat */

==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/syscalls.master#7 (text+ko) ====

@@ -465,15 +465,16 @@
 294	AUE_NULL	STD	{ int linux_migrate_pages(void); }
 295	AUE_OPEN_RWTC	STD	{ int linux_openat(l_int dfd, char *filename, \
 					l_int flags, l_int mode); }
-296	AUE_NULL	STD	{ int linux_mkdirat(void); }
-297	AUE_NULL	STD	{ int linux_mknodat(void); }
+296	AUE_NULL	STD	{ int linux_mkdirat(l_int dfd, char *pathname, l_int mode); }
+297	AUE_NULL	STD	{ int linux_mknodat(l_int dfd, char *filename, l_int mode, l_uint dev); }
 298	AUE_NULL	STD	{ int linux_fchownat(l_int dfd, char *filename, \
 					l_uid16_t uid, l_gid16_t gid, l_int flag); }
-299	AUE_NULL	STD	{ int linux_futimesat(void); }
+299	AUE_NULL	STD	{ int linux_futimesat(l_int dfd, char *filename, struct l_timeval *utimes); }
 300	AUE_NULL	STD	{ int linux_fstatat64(l_int dfd, char *pathname, \
 					struct l_stat64 *statbuf, l_int flag); }
 301	AUE_NULL	STD	{ int linux_unlinkat(l_int dfd, char *pathname, l_int flag); }
-302	AUE_NULL	STD	{ int linux_renameat(void); }
+302	AUE_NULL	STD	{ int linux_renameat(l_int olddfd, char *oldname, l_int newdfd, \
+					char *newname); }
 303	AUE_NULL	STD	{ int linux_linkat(l_int olddfd, char *oldname, \
 					l_int newdfd, char *newname, l_int flags); }
 304	AUE_NULL	STD	{ int linux_symlinkat(char *oldname, l_int newdfd, char *newname); }

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

@@ -712,6 +712,7 @@
 	LFREEPATH(path);
 	return (error);
 }
+
 int
 linux_mkdir(struct thread *td, struct linux_mkdir_args *args)
 {
@@ -730,6 +731,28 @@
 }
 
 int
+linux_mkdirat(struct thread *td, struct linux_mkdirat_args *args)
+{
+	char *path;
+	int error, dfd;
+
+	if (args->dfd == LINUX_AT_FDCWD)
+		dfd = AT_FDCWD;
+	else
+		dfd = args->dfd;
+
+	LCONVPATHCREAT_AT(td, args->pathname, &path, dfd);
+
+#ifdef DEBUG
+	if (ldebug(mkdirat))
+		printf(ARGS(mkdirat, "%s, %d"), path, args->mode);
+#endif
+	error = kern_mkdirat(td, path, UIO_SYSSPACE, args->mode, dfd);
+	LFREEPATH(path);
+	return (error);
+}
+
+int
 linux_rmdir(struct thread *td, struct linux_rmdir_args *args)
 {
 	char *path;
@@ -771,6 +794,40 @@
 }
 
 int
+linux_renameat(struct thread *td, struct linux_renameat_args *args)
+{
+	char *from, *to;
+	int error, olddfd, newdfd;
+
+	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, &from, olddfd);
+	/* Expand LCONVPATHCREATE so that `from' can be freed on errors */
+	error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd);
+	if (to == NULL) {
+		LFREEPATH(from);
+		return (error);
+	}
+
+#ifdef DEBUG
+	if (ldebug(renameat))
+		printf(ARGS(renameat, "%s, %s"), from, to);
+#endif
+	error = kern_renameat(td, from, to, UIO_SYSSPACE, olddfd, newdfd);
+	LFREEPATH(from);
+	LFREEPATH(to);
+	return (error);
+}
+
+int
 linux_symlink(struct thread *td, struct linux_symlink_args *args)
 {
 	char *path, *to;

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

@@ -86,6 +86,7 @@
 #include <machine/../linux/linux_proto.h>
 #endif
 
+#include <compat/linux/linux_file.h>
 #include <compat/linux/linux_mib.h>
 #include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_util.h>
@@ -818,6 +819,43 @@
 	LFREEPATH(fname);
 	return (error);
 }
+
+int
+linux_futimesat(struct thread *td, struct linux_futimesat_args *args)
+{
+	l_timeval ltv[2];
+	struct timeval tv[2], *tvp = NULL;
+	char *fname;
+	int error, dfd;
+
+	if (args->dfd == LINUX_AT_FDCWD)
+		dfd = AT_FDCWD;
+	else
+		dfd = args->dfd;
+
+	LCONVPATHEXIST_AT(td, args->filename, &fname, dfd);
+
+#ifdef DEBUG
+	if (ldebug(futimesat))
+		printf(ARGS(futimesat, "%s, *"), fname);
+#endif
+
+	if (args->utimes!= NULL) {
+		if ((error = copyin(args->utimes, ltv, sizeof ltv))) {
+			LFREEPATH(fname);
+			return (error);
+		}
+		tv[0].tv_sec = ltv[0].tv_sec;
+		tv[0].tv_usec = ltv[0].tv_usec;
+		tv[1].tv_sec = ltv[1].tv_sec;
+		tv[1].tv_usec = ltv[1].tv_usec;
+		tvp = tv;
+	}
+
+	error = kern_utimesat(td, fname, UIO_SYSSPACE, tvp, UIO_SYSSPACE, dfd);
+	LFREEPATH(fname);
+	return (error);
+}
 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
 
 #define __WCLONE 0x80000000
@@ -955,6 +993,56 @@
 	return (error);
 }
 
+int
+linux_mknodat(struct thread *td, struct linux_mknodat_args *args)
+{
+	char *path;
+	int error, dfd;
+
+	if (args->dfd == LINUX_AT_FDCWD)
+		dfd = AT_FDCWD;
+	else
+		dfd = args->dfd;
+
+	LCONVPATHCREAT_AT(td, args->filename, &path, dfd);
+
+#ifdef DEBUG
+	if (ldebug(mknodat))
+		printf(ARGS(mknodat, "%s, %d, %d"), path, args->mode, args->dev);
+#endif
+
+	switch (args->mode & S_IFMT) {
+	case S_IFIFO:
+	case S_IFSOCK:
+		error = kern_mkfifoat(td, path, UIO_SYSSPACE, args->mode, dfd);
+		break;
+
+	case S_IFCHR:
+	case S_IFBLK:
+		error = kern_mknodat(td, path, UIO_SYSSPACE, args->mode,
+		    args->dev, dfd);
+		break;
+
+	case S_IFDIR:
+		error = EPERM;
+		break;
+
+	case 0:
+		args->mode |= S_IFREG;
+		/* FALLTHROUGH */
+	case S_IFREG:
+		error = kern_openat(td, path, UIO_SYSSPACE,
+		    O_WRONLY | O_CREAT | O_TRUNC, args->mode, dfd);
+		break;
+
+	default:
+		error = EINVAL;
+		break;
+	}
+	LFREEPATH(path);
+	return (error);
+}
+
 /*
  * UGH! This is just about the dumbest idea I've ever heard!!
  */

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

@@ -69,6 +69,7 @@
 #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 LCONVPATHCREAT_AT(td, upath, pathp, dfd) LCONVPATH_AT(td, upath, pathp, 1, dfd)
 #define LFREEPATH(path)	free(path, M_TEMP)
 
 #define DUMMY(s)							\

==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_dummy.c#7 (text+ko) ====

@@ -87,10 +87,6 @@
 DUMMY(inotify_add_watch);
 DUMMY(inotify_rm_watch);
 DUMMY(migrate_pages);
-DUMMY(mkdirat);
-DUMMY(mknodat);
-DUMMY(futimesat);
-DUMMY(renameat);
 DUMMY(pselect6);
 DUMMY(ppoll);
 DUMMY(unshare);

==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_proto.h#7 (text+ko) ====

@@ -899,10 +899,15 @@
 	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
 };
 struct linux_mkdirat_args {
-	register_t dummy;
+	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+	char pathname_l_[PADL_(char *)]; char * pathname; char pathname_r_[PADR_(char *)];
+	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
 };
 struct linux_mknodat_args {
-	register_t dummy;
+	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+	char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+	char dev_l_[PADL_(l_uint)]; l_uint dev; char dev_r_[PADR_(l_uint)];
 };
 struct linux_fchownat_args {
 	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -912,7 +917,9 @@
 	char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
 };
 struct linux_futimesat_args {
-	register_t dummy;
+	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+	char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+	char utimes_l_[PADL_(struct l_timeval *)]; struct l_timeval * utimes; char utimes_r_[PADR_(struct l_timeval *)];
 };
 struct linux_fstatat64_args {
 	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -926,7 +933,10 @@
 	char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
 };
 struct linux_renameat_args {
-	register_t dummy;
+	char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)];
+	char oldname_l_[PADL_(char *)]; char * oldname; char oldname_r_[PADR_(char *)];
+	char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)];
+	char newname_l_[PADL_(char *)]; char * newname; char newname_r_[PADR_(char *)];
 };
 struct linux_linkat_args {
 	char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)];

==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_syscall.h#7 (text+ko) ====


==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysent.c#7 (text+ko) ====

@@ -315,13 +315,13 @@
 	{ 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0 },	/* 293 = linux_inotify_rm_watch */
 	{ 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0 },	/* 294 = linux_migrate_pages */
 	{ AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0 },	/* 295 = linux_openat */
-	{ 0, (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 },	/* 296 = linux_mkdirat */
-	{ 0, (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 },	/* 297 = linux_mknodat */
+	{ AS(linux_mkdirat_args), (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 },	/* 296 = linux_mkdirat */
+	{ AS(linux_mknodat_args), (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 },	/* 297 = linux_mknodat */
 	{ AS(linux_fchownat_args), (sy_call_t *)linux_fchownat, AUE_NULL, NULL, 0, 0 },	/* 298 = linux_fchownat */
-	{ 0, (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 },	/* 299 = linux_futimesat */
+	{ AS(linux_futimesat_args), (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 },	/* 299 = linux_futimesat */
 	{ AS(linux_fstatat64_args), (sy_call_t *)linux_fstatat64, AUE_NULL, NULL, 0, 0 },	/* 300 = linux_fstatat64 */
 	{ AS(linux_unlinkat_args), (sy_call_t *)linux_unlinkat, AUE_NULL, NULL, 0, 0 },	/* 301 = linux_unlinkat */
-	{ 0, (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 },	/* 302 = linux_renameat */
+	{ AS(linux_renameat_args), (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 },	/* 302 = linux_renameat */
 	{ AS(linux_linkat_args), (sy_call_t *)linux_linkat, AUE_NULL, NULL, 0, 0 },	/* 303 = linux_linkat */
 	{ AS(linux_symlinkat_args), (sy_call_t *)linux_symlinkat, AUE_NULL, NULL, 0, 0 },	/* 304 = linux_symlinkat */
 	{ AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 },	/* 305 = linux_readlinkat */

==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/syscalls.master#7 (text+ko) ====

@@ -475,15 +475,16 @@
 294	AUE_NULL	STD	{ int linux_migrate_pages(void); }
 295	AUE_OPEN_RWTC	STD	{ int linux_openat(l_int dfd, char *filename, \
 					l_int flags, l_int mode); }
-296	AUE_NULL	STD	{ int linux_mkdirat(void); }
-297	AUE_NULL	STD	{ int linux_mknodat(void); }
+296	AUE_NULL	STD	{ int linux_mkdirat(l_int dfd, char *pathname, l_int mode); }
+297	AUE_NULL	STD	{ int linux_mknodat(l_int dfd, char *filename, l_int mode, l_uint dev); }
 298	AUE_NULL	STD	{ int linux_fchownat(l_int dfd, char *filename, \
 					l_uid16_t uid, l_gid16_t gid, l_int flag); }
-299	AUE_NULL	STD	{ int linux_futimesat(void); }
+299	AUE_NULL	STD	{ int linux_futimesat(l_int dfd, char *filename, struct l_timeval *utimes); }
 300	AUE_NULL	STD	{ int linux_fstatat64(l_int dfd, char *pathname, \
 					struct l_stat64 *statbuf, l_int flag); }
 301	AUE_NULL	STD	{ int linux_unlinkat(l_int dfd, char *pathname, l_int flag); }
-302	AUE_NULL	STD	{ int linux_renameat(void); }
+302	AUE_NULL	STD	{ int linux_renameat(l_int olddfd, char *oldname, l_int newdfd, \
+					char *newname); }
 303	AUE_NULL	STD	{ int linux_linkat(l_int olddfd, char *oldname, \
 					l_int newdfd, char *newname, l_int flags); }
 304	AUE_NULL	STD	{ int linux_symlinkat(char *oldname, l_int newdfd, char *newname); }

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#16 (text+ko) ====

@@ -105,6 +105,10 @@
     enum uio_seg bufseg, int count, struct nameidata *nd);
 static int kern_common_link(struct thread *td, struct nameidata *ndp,
     struct nameidata *ndl);
+static int kern_common_utimes(struct thread *td, char *path, enum uio_seg pathseg,
+    struct timeval *tptr, enum uio_seg tptrseg, struct nameidata *nd);
+static int kern_common_rename(struct thread *td, char *from, char *to,
+    enum uio_seg pathseg, struct nameidata *fromnd, struct nameidata *tond);
 
 /*
  * The module initialization routine for POSIX asynchronous I/O will
@@ -1208,7 +1212,14 @@
 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
     int dev)
 {
-	struct vnode *vp;
+	return kern_mknodat(td, path, pathseg, mode, dev, AT_FDCWD);
+}
+
+int
+kern_mknodat(struct thread *td, char *path, enum uio_seg pathseg, int mode,
+    int dev, int dirfd)
+{
+	struct vnode *vp, *dir_vn = NULL;
 	struct mount *mp;
 	struct vattr vattr;
 	int error;
@@ -1236,11 +1247,19 @@
 	if (error)
 		return (error);
 restart:
+	if (dir_vn)
+		vrele(dir_vn);
+	error = kern_get_at(td, dirfd, &dir_vn);
+	if (error)
+		return (error);
 	bwillwrite();
-	NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
-	    pathseg, path, td);
-	if ((error = namei(&nd)) != 0)
+	NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
+	    pathseg, path, td, dir_vn);
+	if ((error = namei(&nd)) != 0) {
+		if (dir_vn)
+			vrele(dir_vn);
 		return (error);
+	}
 	vfslocked = NDHASGIANT(&nd);
 	vp = nd.ni_vp;
 	if (vp != NULL) {
@@ -1251,6 +1270,8 @@
 			vput(nd.ni_dvp);
 		vrele(vp);
 		VFS_UNLOCK_GIANT(vfslocked);
+		if (dir_vn)
+			vrele(dir_vn);
 		return (EEXIST);
 	} else {
 		VATTR_NULL(&vattr);
@@ -1282,8 +1303,11 @@
 		NDFREE(&nd, NDF_ONLY_PNBUF);
 		vput(nd.ni_dvp);
 		VFS_UNLOCK_GIANT(vfslocked);
-		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
+		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) {
+			if (dir_vn)
+				vrele(dir_vn);
 			return (error);
+		}
 		goto restart;
 	}
 #ifdef MAC
@@ -1302,6 +1326,8 @@
 				vput(nd.ni_vp);
 		}
 	}
+	if (dir_vn)
+		vrele(dir_vn);
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vput(nd.ni_dvp);
 	vn_finished_write(mp);
@@ -1333,19 +1359,34 @@
 int
 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode)
 {
+	return kern_mkfifoat(td, path, pathseg, mode, AT_FDCWD);
+}
+
+int
+kern_mkfifoat(struct thread *td, char *path, enum uio_seg pathseg, int mode, int dirfd)
+{
 	struct mount *mp;
 	struct vattr vattr;
 	int error;
 	struct nameidata nd;
 	int vfslocked;
+	struct vnode *dir_vn = NULL;
 
 	AUDIT_ARG(mode, mode);
 restart:
+	if (dir_vn)
+		vrele(dir_vn);
+	error = kern_get_at(td, dirfd, &dir_vn);
+	if (error)
+		return (error);
 	bwillwrite();
-	NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
-	    pathseg, path, td);
-	if ((error = namei(&nd)) != 0)
+	NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
+	    pathseg, path, td, dir_vn);
+	if ((error = namei(&nd)) != 0) {
+		if (dir_vn)
+			vrele(dir_vn);
 		return (error);
+	}
 	vfslocked = NDHASGIANT(&nd);
 	if (nd.ni_vp != NULL) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);
@@ -1355,14 +1396,19 @@
 			vput(nd.ni_dvp);
 		vrele(nd.ni_vp);
 		VFS_UNLOCK_GIANT(vfslocked);
+		if (dir_vn)
+			vrele(dir_vn);
 		return (EEXIST);
 	}
 	if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);
 		vput(nd.ni_dvp);
 		VFS_UNLOCK_GIANT(vfslocked);
-		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
+		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) {
+			if (dir_vn)
+				vrele(dir_vn);
 			return (error);
+	}
 		goto restart;
 	}
 	VATTR_NULL(&vattr);
@@ -1383,6 +1429,8 @@
 #ifdef MAC
 out:
 #endif
+	if (dir_vn)
+		vrele(dir_vn);
 	vput(nd.ni_dvp);
 	vn_finished_write(mp);
 	VFS_UNLOCK_GIANT(vfslocked);
@@ -3199,20 +3247,49 @@
 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg,
     struct timeval *tptr, enum uio_seg tptrseg)
 {
+	struct nameidata nd;
+
+	NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
+
+	return kern_common_utimes(td, path, pathseg, tptr, tptrseg, &nd);
+}
+
+int
+kern_utimesat(struct thread *td, char *path, enum uio_seg pathseg,
+    struct timeval *tptr, enum uio_seg tptrseg, int dirfd)
+{
+	int error;
+	struct nameidata nd;
+	struct vnode *dir_vn;
+
+   	error = kern_get_at(td, dirfd, &dir_vn);
+	if (error)
+		return (error);
+
+	NDINIT_AT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td, dir_vn);
+
+	error = kern_common_utimes(td, path, pathseg, tptr, tptrseg, &nd);
+	if (dir_vn)
+		vrele(dir_vn);
+	return (error);
+}
+
+static int
+kern_common_utimes(struct thread *td, char *path, enum uio_seg pathseg,
+    struct timeval *tptr, enum uio_seg tptrseg, struct nameidata *nd)
+{
 	struct timespec ts[2];
 	int error;
-	struct nameidata nd;
 	int vfslocked;
 
 	if ((error = getutimes(tptr, tptrseg, ts)) != 0)
 		return (error);
-	NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
-	if ((error = namei(&nd)) != 0)
+	if ((error = namei(nd)) != 0)
 		return (error);
-	vfslocked = NDHASGIANT(&nd);
-	NDFREE(&nd, NDF_ONLY_PNBUF);
-	error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
-	vrele(nd.ni_vp);
+	vfslocked = NDHASGIANT(nd);
+	NDFREE(nd, NDF_ONLY_PNBUF);
+	error = setutimes(td, nd->ni_vp, ts, 2, tptr == NULL);
+	vrele(nd->ni_vp);
 	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
@@ -3564,14 +3641,8 @@
 int
 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg)
 {
-	struct mount *mp = NULL;
-	struct vnode *tvp, *fvp, *tdvp;
 	struct nameidata fromnd, tond;
-	int tvfslocked;
-	int fvfslocked;
-	int error;
 
-	bwillwrite();
 #ifdef MAC
 	NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE |
 	    AUDITVNODE1, pathseg, from, td);
@@ -3579,43 +3650,92 @@
 	NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE |
 	    AUDITVNODE1, pathseg, from, td);
 #endif
-	if ((error = namei(&fromnd)) != 0)
+	NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART |
+	    MPSAFE | AUDITVNODE2, pathseg, to, td);
+
+	return kern_common_rename(td, from, to, pathseg, &fromnd, &tond);
+}
+
+int
+kern_renameat(struct thread *td, char *from, char *to, enum uio_seg pathseg, int fdirfd, int tdirfd)
+{
+	struct nameidata fromnd, tond;
+	struct vnode *fdir_vn, *tdir_vn;
+	int error;
+
+	error = kern_get_at(td, fdirfd, &fdir_vn);
+	if (error)
+		return (error);
+	error = kern_get_at(td, tdirfd, &tdir_vn);
+	if (error)
+		return (error);
+
+#ifdef MAC
+	NDINIT_AT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE |
+	    AUDITVNODE1, pathseg, from, td, fdir_vn);
+#else
+	NDINIT_AT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE |
+	    AUDITVNODE1, pathseg, from, td, fdir_vn);
+#endif
+	NDINIT_AT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART |
+	    MPSAFE | AUDITVNODE2, pathseg, to, td, tdir_vn);
+
+	error = kern_common_rename(td, from, to, pathseg, &fromnd, &tond);
+
+	if (fdir_vn)
+		vrele(fdir_vn);
+	if (tdir_vn)
+		vrele(tdir_vn);
+
+	return (error);
+}
+
+static int
+kern_common_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg,
+    struct nameidata *fromnd, struct nameidata *tond)
+{
+	struct mount *mp = NULL;
+	struct vnode *tvp, *fvp, *tdvp;
+	int tvfslocked;
+	int fvfslocked;
+	int error;
+
+	bwillwrite();
+	if ((error = namei(fromnd)) != 0)
 		return (error);
-	fvfslocked = NDHASGIANT(&fromnd);
+	fvfslocked = NDHASGIANT(fromnd);
 	tvfslocked = 0;
 #ifdef MAC
-	error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp,
-	    fromnd.ni_vp, &fromnd.ni_cnd);
-	VOP_UNLOCK(fromnd.ni_dvp, 0, td);
-	if (fromnd.ni_dvp != fromnd.ni_vp)
-		VOP_UNLOCK(fromnd.ni_vp, 0, td);
+	error = mac_check_vnode_rename_from(td->td_ucred, fromnd->ni_dvp,
+	    fromnd->ni_vp, &(fromnd->ni_cnd));
+	VOP_UNLOCK(fromnd->ni_dvp, 0, td);
+	if (fromnd->ni_dvp != fromnd->ni_vp)
+		VOP_UNLOCK(fromnd->ni_vp, 0, td);
 #endif
-	fvp = fromnd.ni_vp;
+	fvp = fromnd->ni_vp;
 	if (error == 0)
 		error = vn_start_write(fvp, &mp, V_WAIT | PCATCH);
 	if (error != 0) {
-		NDFREE(&fromnd, NDF_ONLY_PNBUF);
-		vrele(fromnd.ni_dvp);
+		NDFREE(fromnd, NDF_ONLY_PNBUF);
+		vrele(fromnd->ni_dvp);
 		vrele(fvp);
 		goto out1;
 	}
-	NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART |
-	    MPSAFE | AUDITVNODE2, pathseg, to, td);
-	if (fromnd.ni_vp->v_type == VDIR)
-		tond.ni_cnd.cn_flags |= WILLBEDIR;
-	if ((error = namei(&tond)) != 0) {
+	if (fromnd->ni_vp->v_type == VDIR)
+		tond->ni_cnd.cn_flags |= WILLBEDIR;
+	if ((error = namei(tond)) != 0) {
 		/* Translate error code for rename("dir1", "dir2/."). */
 		if (error == EISDIR && fvp->v_type == VDIR)
 			error = EINVAL;
-		NDFREE(&fromnd, NDF_ONLY_PNBUF);
-		vrele(fromnd.ni_dvp);
+		NDFREE(fromnd, NDF_ONLY_PNBUF);
+		vrele(fromnd->ni_dvp);
 		vrele(fvp);
 		vn_finished_write(mp);
 		goto out1;
 	}
-	tvfslocked = NDHASGIANT(&tond);
-	tdvp = tond.ni_dvp;
-	tvp = tond.ni_vp;
+	tvfslocked = NDHASGIANT(tond);
+	tdvp = tond->ni_dvp;
+	tvp = tond->ni_vp;
 	if (tvp != NULL) {
 		if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
 			error = ENOTDIR;
@@ -3636,38 +3756,38 @@
 #ifdef MAC
 	else
 		error = mac_check_vnode_rename_to(td->td_ucred, tdvp,
-		    tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd);
+		    tond->ni_vp, fromnd->ni_dvp == tdvp, &(tond->ni_cnd));
 #endif
 out:
 	if (!error) {
 		VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE);
-		if (fromnd.ni_dvp != tdvp) {
-			VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
+		if (fromnd->ni_dvp != tdvp) {
+			VOP_LEASE(fromnd->ni_dvp, td, td->td_ucred, LEASE_WRITE);
 		}
 		if (tvp) {
 			VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE);
 		}
-		error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
-				   tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
-		NDFREE(&fromnd, NDF_ONLY_PNBUF);
-		NDFREE(&tond, NDF_ONLY_PNBUF);
+		error = VOP_RENAME(fromnd->ni_dvp, fromnd->ni_vp, &(fromnd->ni_cnd),
+				   tond->ni_dvp, tond->ni_vp, &(tond->ni_cnd));
+		NDFREE(fromnd, NDF_ONLY_PNBUF);
+		NDFREE(tond, NDF_ONLY_PNBUF);
 	} else {
-		NDFREE(&fromnd, NDF_ONLY_PNBUF);
-		NDFREE(&tond, NDF_ONLY_PNBUF);
+		NDFREE(fromnd, NDF_ONLY_PNBUF);
+		NDFREE(tond, NDF_ONLY_PNBUF);
 		if (tvp)
 			vput(tvp);
 		if (tdvp == tvp)
 			vrele(tdvp);
 		else
 			vput(tdvp);
-		vrele(fromnd.ni_dvp);
+		vrele(fromnd->ni_dvp);
 		vrele(fvp);
 	}
-	vrele(tond.ni_startdir);
+	vrele(tond->ni_startdir);
 	vn_finished_write(mp);
 out1:
-	if (fromnd.ni_startdir)
-		vrele(fromnd.ni_startdir);
+	if (fromnd->ni_startdir)
+		vrele(fromnd->ni_startdir);
 	VFS_UNLOCK_GIANT(fvfslocked);
 	VFS_UNLOCK_GIANT(tvfslocked);
 	if (error == -1)
@@ -3699,8 +3819,14 @@
 int
 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode)
 {
+	return kern_mkdirat(td, path, segflg, mode, AT_FDCWD);
+}
+
+int
+kern_mkdirat(struct thread *td, char *path, enum uio_seg segflg, int mode, int dirfd)
+{
 	struct mount *mp;
-	struct vnode *vp;
+	struct vnode *vp, *dir_vn = NULL;
 	struct vattr vattr;
 	int error;
 	struct nameidata nd;
@@ -3708,12 +3834,20 @@
 
 	AUDIT_ARG(mode, mode);
 restart:
+	if (dir_vn)
+		vrele(dir_vn);
+	error = kern_get_at(td, dirfd, &dir_vn);
+	if (error)
+		return (error);
 	bwillwrite();
-	NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
-	    segflg, path, td);
+	NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
+	    segflg, path, td, dir_vn);
 	nd.ni_cnd.cn_flags |= WILLBEDIR;
-	if ((error = namei(&nd)) != 0)
+	if ((error = namei(&nd)) != 0) {
+		if (dir_vn)
+			vrele(dir_vn);
 		return (error);
+	}
 	vfslocked = NDHASGIANT(&nd);
 	vp = nd.ni_vp;
 	if (vp != NULL) {
@@ -3729,14 +3863,19 @@
 			vput(nd.ni_dvp);
 		vrele(vp);
 		VFS_UNLOCK_GIANT(vfslocked);
+		if (dir_vn)
+			vrele(dir_vn);
 		return (EEXIST);
 	}
 	if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);
 		vput(nd.ni_dvp);
 		VFS_UNLOCK_GIANT(vfslocked);
-		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
+		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) {
+			if (dir_vn)
+				vrele(dir_vn);
 			return (error);
+		}
 		goto restart;
 	}
 	VATTR_NULL(&vattr);
@@ -3755,6 +3894,8 @@
 #ifdef MAC
 out:
 #endif
+	if (dir_vn)
+		vrele(dir_vn);
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vput(nd.ni_dvp);
 	if (!error)
@@ -3793,7 +3934,7 @@
 kern_rmdirat(struct thread *td, char *path, enum uio_seg pathseg, int dirfd)
 {
 	struct mount *mp;
-	struct vnode *vp, *dir_vn;
+	struct vnode *vp, *dir_vn = NULL;
 	int error;
 	struct nameidata nd;
 	int vfslocked;

==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#9 (text+ko) ====

@@ -121,10 +121,16 @@
 	    struct timeval *tptr, enum uio_seg tptrseg);
 int	kern_mkdir(struct thread *td, char *path, enum uio_seg segflg,
 	    int mode);
+int	kern_mkdirat(struct thread *td, char *path, enum uio_seg segflg,
+	    int mode, int dirfd);
 int	kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg,
 	    int mode);
+int	kern_mkfifoat(struct thread *td, char *path, enum uio_seg pathseg,
+	    int mode, int dirfd);
 int	kern_mknod(struct thread *td, char *path, enum uio_seg pathseg,
 	    int mode, int dev);
+int	kern_mknodat(struct thread *td, char *path, enum uio_seg pathseg,
+	    int mode, int dev, int dirfd);
 int	kern_msgctl(struct thread *, int, int, struct msqid_ds *);
 int	kern_msgsnd(struct thread *, int, const void *, size_t, int, long);
 int	kern_msgrcv(struct thread *, int, void *, size_t, long, int, long *);
@@ -149,6 +155,8 @@
 	    enum uio_seg fromseg, struct mbuf **controlp);
 int	kern_rename(struct thread *td, char *from, char *to,
 	    enum uio_seg pathseg);
+int	kern_renameat(struct thread *td, char *from, char *to,
+	    enum uio_seg pathseg, int fdirfd, int tdirfd);
 int	kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg);
 int	kern_rmdirat(struct thread *td, char *path, enum uio_seg pathseg, int dirfd);
 int	kern_sched_rr_get_interval(struct thread *td, pid_t pid,
@@ -195,6 +203,8 @@
 int	kern_unlinkat(struct thread *td, char *path, enum uio_seg pathseg, int dirfd);
 int	kern_utimes(struct thread *td, char *path, enum uio_seg pathseg,
 	    struct timeval *tptr, enum uio_seg tptrseg);
+int	kern_utimesat(struct thread *td, char *path, enum uio_seg pathseg,
+	    struct timeval *tptr, enum uio_seg tptrseg, int dirfd);
 int	kern_wait(struct thread *td, pid_t pid, int *status, int options,
 	    struct rusage *rup);
 int	kern_writev(struct thread *td, int fd, struct uio *auio);



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