Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Jan 2015 00:06:26 +0100
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Andrew Wilcox <AWilcox@Wilcox-Tech.com>
Cc:        freebsd-arch@FreeBSD.org
Subject:   Re: Current status of utimensat(2)
Message-ID:  <20150129230625.GA26181@stack.nl>
In-Reply-To: <005701d03b53$92796ce0$b76c46a0$@Wilcox-Tech.com>
References:  <005701d03b53$92796ce0$b76c46a0$@Wilcox-Tech.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--k+w/mQv8wyuph6w0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Jan 28, 2015 at 05:38:50PM -0600, Andrew Wilcox wrote:
> I am wondering about the current status of the utimensat(2) and
> futimens(2) patch set.  I saw some posts from early 2013 but nothing
> more recent.  In addition to improving POSIX 2008 compliance, this
> will additionally enable me to continue my work on the Linuxulator.
> As it stands, most Gentoo and Ubuntu binaries do not work in the
> Linuxulator because of the missing utimensat syscall.

> Is anyone currently working on this?  I'd be happy to help out.

I committed utimensat/futimens to head. I also made a start at
Linuxulator utimensat, see attached patch. Please complete it and test
it.

-- 
Jilles Tjoelker

--k+w/mQv8wyuph6w0
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="linuxulator-utimensat.patch"

commit 579d4ad12989f5ab88983d461156d16bb5bcdec1
Author: Jilles Tjoelker <jilles@stack.nl>
Date:   Sun Jan 25 01:09:37 2015 +0100

    Add Linux utimensat() syscall.
    
    Conflicts:
    	sys/compat/linux/linux_file.h

diff --git a/sys/compat/linux/linux_file.h b/sys/compat/linux/linux_file.h
index 2d3106f..58e80f1 100644
--- a/sys/compat/linux/linux_file.h
+++ b/sys/compat/linux/linux_file.h
@@ -54,4 +54,7 @@
 #define	LINUX_MS_NOEXEC		0x0008
 #define	LINUX_MS_REMOUNT	0x0020
 
+#define	LINUX_UTIME_NOW		0x3fffffff
+#define	LINUX_UTIME_OMIT	0x3ffffffe
+
 #endif	/* !_LINUX_FILE_H_ */
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 93dd80d..262ada9 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -851,6 +851,66 @@ linux_futimesat(struct thread *td, struct linux_futimesat_args *args)
 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
 
 int
+linux_utimensat(struct thread *td, struct linux_utimensat_args *args)
+{
+	struct l_timespec lts[2];
+	struct timespec ts[2], *tsp = NULL;
+	char *fname;
+	int error, fd, flag;
+
+	if (args->utimes != NULL) {
+		if ((error = copyin(args->utimes, lts, sizeof lts)))
+			return (error);
+		ts[0].tv_sec = lts[0].tv_sec;
+		if (lts[0].tv_nsec >= 0 && lts[0].tv_nsec < 1000000000)
+			ts[0].tv_nsec = lts[0].tv_nsec;
+		else if (lts[0].tv_nsec == LINUX_UTIME_NOW)
+			ts[0].tv_nsec = UTIME_NOW;
+		else if (lts[0].tv_nsec == LINUX_UTIME_OMIT)
+			ts[0].tv_nsec = UTIME_OMIT;
+		else
+			return (EINVAL);
+		ts[1].tv_sec = lts[1].tv_sec;
+		if (lts[1].tv_nsec >= 0 && lts[1].tv_nsec < 1000000000)
+			ts[1].tv_nsec = lts[1].tv_nsec;
+		else if (lts[1].tv_nsec == LINUX_UTIME_NOW)
+			ts[1].tv_nsec = UTIME_NOW;
+		else if (lts[1].tv_nsec == LINUX_UTIME_OMIT)
+			ts[1].tv_nsec = UTIME_OMIT;
+		else
+			return (EINVAL);
+		tsp = ts;
+	}
+
+	if (args->pathname == NULL) {
+		if (args->flag != 0)
+			return (EINVAL);
+		fname = NULL;
+		flag = 0;
+	} else {
+		if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
+			return (EINVAL);
+		fd = (args->fd == LINUX_AT_FDCWD) ? AT_FDCWD : args->fd;
+		LCONVPATHEXIST_AT(td, args->pathname, &fname, fd);
+		flag = args->flag & LINUX_AT_SYMLINK_NOFOLLOW ?
+		    AT_SYMLINK_NOFOLLOW : 0;
+	}
+
+#ifdef DEBUG
+	if (ldebug(utimensat))
+		printf(ARGS(utimensat, "%s, *"), fname);
+#endif
+
+	if (fname == NULL)
+		error = kern_futimens(td, fd, tsp, UIO_SYSSPACE);
+	else
+		error = kern_utimensat(td, fd, fname, UIO_SYSSPACE, tsp,
+		    UIO_SYSSPACE, flag);
+	LFREEPATH(fname);
+	return (error);
+}
+
+int
 linux_common_wait(struct thread *td, int pid, int *status,
     int options, struct rusage *ru)
 {
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 85d40f0..4a63994 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -107,7 +107,6 @@ DUMMY(move_pages);
 DUMMY(getcpu);
 DUMMY(epoll_pwait);
 /* linux 2.6.22: */
-DUMMY(utimensat);
 DUMMY(signalfd);
 DUMMY(timerfd_create);
 DUMMY(eventfd);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index 5b4f3a6..516980a 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -532,7 +532,7 @@
 318	AUE_NULL	STD	{ int linux_getcpu(void); }
 319	AUE_NULL	STD	{ int linux_epoll_pwait(void); }
 ; linux 2.6.22:
-320	AUE_NULL	STD	{ int linux_utimensat(void); }
+320	AUE_FUTIMESAT	STD	{ int linux_utimensat(l_int fd, const char *pathname, const struct l_timespec *utimes, l_int flag); }
 321	AUE_NULL	STD	{ int linux_signalfd(void); }
 322	AUE_NULL	STD	{ int linux_timerfd_create(void); }
 323	AUE_NULL	STD	{ int linux_eventfd(void); }

--k+w/mQv8wyuph6w0--



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