Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152088422
D11185.id29578.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D11185.id29578.diff
View Options
Index: lib/libc/include/libc_private.h
===================================================================
--- lib/libc/include/libc_private.h
+++ lib/libc/include/libc_private.h
@@ -298,11 +298,81 @@
* ignores value of $OSVERSION and caches result.
*/
int __getosreldate(void);
+
+/*
+ * Forward compatibility shim to convert old stat buffer to
+ * new so we can call the old system call, but return data in
+ * the new system call's format.
+ */
+#define INO64_FIRST 12000031
+#ifdef _WANT_FREEBSD11_STAT
+struct fhandle;
+
+int freebsd11_fhstat(const struct fhandle *, struct freebsd11_stat *);
+int freebsd11_fstat(int, struct freebsd11_stat *);
+int freebsd11_fstatat(int, const char *, struct freebsd11_stat *, int);
+
+static __inline void
+__stat11_to_stat(const struct freebsd11_stat *sb11, struct stat *sb)
+{
+ sb->st_dev = sb11->st_dev & 0xffffu;
+ sb->st_ino = sb11->st_ino;
+ sb->st_mode = sb11->st_mode;
+ sb->st_nlink = sb11->st_nlink;
+ sb->st_uid = sb11->st_uid;
+ sb->st_gid = sb11->st_gid;
+ sb->st_rdev = sb11->st_rdev & 0xfffffu;
+ sb->st_size = sb11->st_size;
+ sb->st_atim = sb11->st_atim;
+ sb->st_mtim = sb11->st_mtim;
+ sb->st_ctim = sb11->st_ctim;
+ sb->st_blksize = sb11->st_blksize;
+ sb->st_blocks = sb11->st_blocks;
+ sb->st_flags = sb11->st_flags;
+ sb->st_gen = sb11->st_gen;
+ /* NB: st_birthtim not in new struct */
+}
+#endif
+
+#ifdef _WANT_FREEBSD11_STATFS
+#include <string.h>
+int freebsd11_fstatfs(int, struct freebsd11_statfs *);
+int freebsd11_statfs(const char *, struct freebsd11_statfs *);
+
+static __inline void
+__statfs11_to_statfs(const struct freebsd11_statfs *sf11, struct statfs *sf)
+{
+ sf->f_version = STATFS_VERSION;
+ sf->f_type = sf11->f_type;
+ sf->f_flags = sf11->f_flags;
+ sf->f_bsize = sf11->f_bsize;
+ sf->f_iosize = sf11->f_iosize;
+ sf->f_blocks = sf11->f_blocks;
+ sf->f_bfree = sf11->f_bfree;
+ sf->f_bavail = sf11->f_bavail;
+ sf->f_files = sf11->f_files;
+ sf->f_ffree = sf11->f_ffree;
+ sf->f_syncwrites = sf11->f_syncwrites;
+ sf->f_asyncwrites = sf11->f_asyncwrites;
+ sf->f_syncreads = sf11->f_syncreads;
+ sf->f_asyncreads = sf11->f_asyncreads;
+ sf->f_namemax = sf11->f_namemax;
+ sf->f_owner = sf11->f_owner;
+ sf->f_fsid = sf11->f_fsid;
+ memcpy(sf->f_spare, sf11->f_spare, sizeof(sf11->f_spare));
+ strlcpy(sf->f_charspare, sf11->f_charspare, sizeof(sf->f_charspare));
+ strlcpy(sf->f_fstypename, sf11->f_fstypename, sizeof(sf->f_fstypename));
+ strlcpy(sf->f_mntfromname, sf11->f_mntfromname, sizeof(sf->f_mntfromname));
+ strlcpy(sf->f_mntonname, sf11->f_mntonname, sizeof(sf->f_mntonname));
+}
+#endif
+
#include <sys/_types.h>
#include <sys/_sigset.h>
struct aiocb;
struct fd_set;
+struct fhandle;
struct iovec;
struct kevent;
struct msghdr;
@@ -311,6 +381,7 @@
struct sigaction;
struct sockaddr;
struct stat;
+struct statfs;
struct timespec;
struct timeval;
struct timezone;
@@ -330,6 +401,9 @@
__ssize_t __sys_getdirentries(int, char *, __size_t, __off_t *);
int __sys_fcntl(int, int, ...);
int __sys_fdatasync(int);
+int __sys_fhstat(const struct fhandle *, struct stat *);
+int __sys_fstat(int fd, struct stat *);
+int __sys_fstatfs(int fd, struct statfs *);
int __sys_fstatat(int, const char *, struct stat *, int);
int __sys_fsync(int);
__pid_t __sys_fork(void);
@@ -372,6 +446,7 @@
const struct timespec *);
int __sys_sigwait(const __sigset_t *, int *);
int __sys_sigwaitinfo(const __sigset_t *, struct __siginfo *);
+int __sys_statfs(const char *, struct statfs *);
int __sys_swapcontext(struct __ucontext *,
const struct __ucontext *);
int __sys_thr_kill(long, int);
Index: lib/libc/sys/Makefile.inc
===================================================================
--- lib/libc/sys/Makefile.inc
+++ lib/libc/sys/Makefile.inc
@@ -41,6 +41,20 @@
NOASM+= futimens.o utimensat.o
PSEUDO+= _futimens.o _utimensat.o
+# stat
+SRCS+= fstat.c fstatat.c fstatfs.c statfs.c
+NOASM+= fstat.o fstatat.o fstatfs.o statfs.o
+PSEUDO+= _fstat.o _fstatat.o _fstatfs.o _statfs.o
+
+SRCS+= getdirentries.c
+NOASM+= getdirentries.o
+PSEUDO+= _getdirentries.o
+
+# fhstat.c getfsstat.c statfs.c
+
+# MAYBE
+#SRCS+= mknod.c mknodat.c
+
SRCS+= pipe.c
INTERPOSED = \
Index: lib/libc/sys/fhstat.c
===================================================================
--- lib/libc/sys/fhstat.c
+++ lib/libc/sys/fhstat.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Gleb Kurtsou <gleb@FreeBSD.org>
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,17 +27,32 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define _WANT_FREEBSD11_STAT
+
#include "namespace.h"
#include <sys/param.h>
#include <sys/fcntl.h>
+#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "../gen/gen-compat.h"
+
#include "libc_private.h"
int
-stat(const char *path, struct stat *sb)
+fhstat(const fhandle_t *fhp, struct stat *sb)
{
+ static int osreldate;
+ struct freebsd11_stat stat11;
+ int rv;
- return (__sys_fstatat(AT_FDCWD, path, sb, 0));
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST)
+ return (__sys_fhstat(fhp, sb));
+ rv = freebsd11_fhstat(fhp, &stat11);
+ if (rv == 0)
+ __stat11_to_stat(&stat11, sb);
+ return (rv);
}
Index: lib/libc/sys/fstat.c
===================================================================
--- lib/libc/sys/fstat.c
+++ lib/libc/sys/fstat.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Gleb Kurtsou <gleb@FreeBSD.org>
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,17 +27,40 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define _WANT_FREEBSD11_STAT
+
#include "namespace.h"
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "../gen/gen-compat.h"
+
#include "libc_private.h"
+#undef fstat
int
-lstat(const char *path, struct stat *sb)
+_fstat(int fd, struct stat *sb)
+{
+ static int osreldate;
+ struct freebsd11_stat stat11;
+ int rv;
+
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST) {
+ return (__sys_fstat(fd, sb));
+ }
+ rv = freebsd11_fstat(fd, &stat11);
+ if (rv == 0) {
+ __stat11_to_stat(&stat11, sb);
+ }
+ return (rv);
+}
+
+int fstat(int fd, struct stat *sb)
{
- return (__sys_fstatat(AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW));
+ return _fstat(fd, sb);
}
Index: lib/libc/sys/fstatat.c
===================================================================
--- lib/libc/sys/fstatat.c
+++ lib/libc/sys/fstatat.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Gleb Kurtsou <gleb@FreeBSD.org>
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,17 +27,31 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define _WANT_FREEBSD11_STAT
+
#include "namespace.h"
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "../gen/gen-compat.h"
+
#include "libc_private.h"
int
-stat(const char *path, struct stat *sb)
+fstatat(int fd, const char *path, struct stat *sb, int flag)
{
+ static int osreldate;
+ struct freebsd11_stat stat11;
+ int rv;
- return (__sys_fstatat(AT_FDCWD, path, sb, 0));
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST)
+ return (__sys_fstatat(fd, path, sb, flag));
+ rv = freebsd11_fstatat(fd, path, &stat11, flag);
+ if (rv == 0)
+ __stat11_to_stat(&stat11, sb);
+ return (rv);
}
Index: lib/libc/sys/fstatfs.c
===================================================================
--- lib/libc/sys/fstatfs.c
+++ lib/libc/sys/fstatfs.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Gleb Kurtsou <gleb@FreeBSD.org>
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,17 +27,39 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define _WANT_FREEBSD11_STATFS
+
#include "namespace.h"
#include <sys/param.h>
#include <sys/fcntl.h>
+#include <sys/mount.h>
#include <sys/syscall.h>
-#include <sys/stat.h>
#include <unistd.h>
+#include "../gen/gen-compat.h"
+
#include "libc_private.h"
+#undef fstatfs
+
int
-lstat(const char *path, struct stat *sb)
+_fstatfs(int fd, struct statfs *buf)
{
+ static int osreldate;
+ struct freebsd11_statfs statfs11;
+ int rv;
- return (__sys_fstatat(AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW));
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST)
+ return (__sys_fstatfs(fd, buf));
+ rv = freebsd11_fstatfs(fd, &statfs11);
+ if (rv == 0)
+ __statfs11_to_statfs(&statfs11, buf);
+ return (rv);
+}
+
+int
+fstatfs(int fd, struct statfs *buf)
+{
+ return _fstatfs(fd, buf);
}
Index: lib/libc/sys/getdents.c
===================================================================
--- lib/libc/sys/getdents.c
+++ lib/libc/sys/getdents.c
@@ -36,6 +36,11 @@
ssize_t
getdents(int fd, char *buf, size_t nbytes)
{
+ /*
+ * _getdirentries knows how to call the right thing and
+ * return it in the new format. It assumes that the entire
+ * libc expecting the new format.
+ */
- return (__sys_getdirentries(fd, buf, nbytes, NULL));
+ return (_getdirentries(fd, buf, nbytes, NULL));
}
Index: lib/libc/sys/getdirentries.c
===================================================================
--- /dev/null
+++ lib/libc/sys/getdirentries.c
@@ -0,0 +1,115 @@
+/*-
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define _WANT_FREEBSD11_DIRENT
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <sys/syscall.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "libc_private.h"
+
+extern ssize_t freebsd11_getdirentries(int fd, char *buf, size_t nbytes, off_t *basep);
+
+static ssize_t
+__cvt_dirents_from11(const char *de11, ssize_t len11, char *de, ssize_t len)
+{
+ struct dirent *dst;
+ const struct freebsd11_dirent *src;
+ const char *edst, *esrc;
+ ssize_t rlen;
+
+ src = (const struct freebsd11_dirent *)de11;
+ dst = (struct dirent *)de;
+ esrc = de11 + len11;
+ edst = de + len;
+ while ((const char *)src < esrc && (const char *)dst < edst) {
+ rlen = roundup(offsetof(struct dirent, d_name) + src->d_namlen + 1, 8);
+ dst->d_fileno = src->d_fileno;
+ dst->d_off = 0; /* nothing uses it yet, so safe for now */
+ dst->d_reclen = rlen;
+ dst->d_type = src->d_type;
+ dst->d_pad0 = 0;
+ dst->d_namlen = src->d_namlen;
+ dst->d_pad1 = 0;
+ memset(dst->d_name, 0, roundup(dst->d_namlen + 1, 8));
+ memcpy(dst->d_name, src->d_name, src->d_namlen);
+ dst = (struct dirent *)((char *)dst + rlen);
+ src = (const struct freebsd11_dirent *)((const char *)src + src->d_reclen);
+ }
+ return ((char *)dst - de);
+}
+
+ssize_t
+getdirentries(int fd, char *buf, size_t nbytes, off_t *basep)
+{
+ static int osreldate;
+ char *oldbuf;
+ size_t len;
+ ssize_t rv;
+
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST)
+ return (__sys_getdirentries(fd, buf, nbytes, basep));
+
+ /*
+ * We know the new dirents is larger than the olddirents, so we know
+ * this will suffice.
+ * TBD: Will this difference matter to lseek?
+ */
+ oldbuf = malloc(nbytes);
+ if (oldbuf == NULL) {
+ errno = EINVAL; /* ENOMEM not permitted */
+ return (-1);
+ }
+ /*
+ * Because the old system call returns entries that are smaller than the
+ * new, we could wind up in a situation where we have too many to fit in
+ * the buffer with the new encoding. So sacrefice a small bit of
+ * efficiency to ensure that never happens. We pick 1/2 the size
+ * arbitrarily and round up to the next DIRBLKSIZ because that's what
+ * the readdir code does. We don't check against minimum dir size to
+ * avoid a lot of stat calls, we'll see if that's wise or not.
+ */
+ len = roundup(nbytes / 2, DIRBLKSIZ);
+ rv = freebsd11_getdirentries(fd, oldbuf, len, basep);
+ if (rv == -1)
+ return (rv);
+ rv = __cvt_dirents_from11(oldbuf, rv, buf, nbytes);
+ free(oldbuf);
+
+ return (rv);
+}
Index: lib/libc/sys/lstat.c
===================================================================
--- lib/libc/sys/lstat.c
+++ lib/libc/sys/lstat.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
* Copyright (c) 2012 Gleb Kurtsou <gleb@FreeBSD.org>
* All rights reserved.
*
@@ -27,17 +28,31 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define _WANT_FREEBSD11_STAT
+
#include "namespace.h"
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "../gen/gen-compat.h"
+
#include "libc_private.h"
int
lstat(const char *path, struct stat *sb)
{
+ static int osreldate;
+ struct freebsd11_stat stat11;
+ int rv;
- return (__sys_fstatat(AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW));
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST)
+ return (__sys_fstatat(AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW));
+ rv = freebsd11_lstat(path, &stat11);
+ if (rv == 0)
+ __stat11_to_stat(&stat11, sb);
+ return (rv);
}
Index: lib/libc/sys/stat.c
===================================================================
--- lib/libc/sys/stat.c
+++ lib/libc/sys/stat.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
* Copyright (c) 2012 Gleb Kurtsou <gleb@FreeBSD.org>
* All rights reserved.
*
@@ -27,17 +28,31 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define _WANT_FREEBSD11_STAT
+
#include "namespace.h"
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "../gen/gen-compat.h"
+
#include "libc_private.h"
int
stat(const char *path, struct stat *sb)
{
+ static int osreldate;
+ struct freebsd11_stat stat11;
+ int rv;
- return (__sys_fstatat(AT_FDCWD, path, sb, 0));
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST)
+ return (__sys_fstatat(AT_FDCWD, path, sb, 0));
+ rv = freebsd11_stat(path, &stat11);
+ if (rv == 0)
+ __stat11_to_stat(&stat11, sb);
+ return (rv);
}
Index: lib/libc/sys/statfs.c
===================================================================
--- lib/libc/sys/statfs.c
+++ lib/libc/sys/statfs.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Gleb Kurtsou <gleb@FreeBSD.org>
+ * Copyright (c) 2017 M. Warner Losh <imp@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,17 +27,31 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#define _WANT_FREEBSD11_STATFS
+
#include "namespace.h"
#include <sys/param.h>
#include <sys/fcntl.h>
+#include <sys/mount.h>
#include <sys/syscall.h>
-#include <sys/stat.h>
#include <unistd.h>
+#include "../gen/gen-compat.h"
+
#include "libc_private.h"
int
-lstat(const char *path, struct stat *sb)
+statfs(const char *path, struct statfs *buf)
{
+ static int osreldate;
+ struct freebsd11_statfs statfs11;
+ int rv;
- return (__sys_fstatat(AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW));
+ if (!osreldate)
+ osreldate = __getosreldate();
+ if (osreldate >= INO64_FIRST)
+ return (__sys_statfs(path, buf));
+ rv = freebsd11_statfs(path, &statfs11);
+ if (rv == 0)
+ __statfs11_to_statfs(&statfs11, buf);
+ return (rv);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 13, 3:54 PM (21 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31416008
Default Alt Text
D11185.id29578.diff (16 KB)
Attached To
Mode
D11185: Forward compatibility for ino64.
Attached
Detach File
Event Timeline
Log In to Comment