Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat - Add compat_linux statx(2) syscall.



details:   https://anonhg.NetBSD.org/src/rev/5194e6eac144
branches:  trunk
changeset: 1026432:5194e6eac144
user:      ryo <ryo%NetBSD.org@localhost>
date:      Thu Nov 25 02:27:08 2021 +0000

description:
- Add compat_linux statx(2) syscall.
- The AT_EMPTY_PATH processing from the modification of
  sys/compat/linux/common/linux_file64.c r1.63 has been separated, and made
  common to linux_statat(), so that it can be used not only by
  linux32_sys_fstatat64() but also by other *statat() variants.

diffstat:

 sys/compat/linux/common/linux_fcntl.h     |    4 +-
 sys/compat/linux/common/linux_file64.c    |  190 +++++++++++++++++++++++------
 sys/compat/linux/common/linux_types.h     |   61 +++++++++-
 sys/compat/linux32/common/linux32_stat.c  |   50 ++++++-
 sys/compat/linux32/common/linux32_types.h |    3 +-
 5 files changed, 253 insertions(+), 55 deletions(-)

diffs (truncated from 440 to 300 lines):

diff -r 92664ab9052c -r 5194e6eac144 sys/compat/linux/common/linux_fcntl.h
--- a/sys/compat/linux/common/linux_fcntl.h     Thu Nov 25 02:09:23 2021 +0000
+++ b/sys/compat/linux/common/linux_fcntl.h     Thu Nov 25 02:27:08 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_fcntl.h,v 1.19 2021/09/23 06:56:27 ryo Exp $     */
+/*     $NetBSD: linux_fcntl.h,v 1.20 2021/11/25 02:27:08 ryo Exp $     */
 
 /*-
  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -52,6 +52,8 @@
 
 int linux_to_bsd_ioflags(int);
 int linux_to_bsd_atflags(int);
+int bsd_to_linux_statx(struct stat *, struct linux_statx *, unsigned int);
+int linux_statat(struct lwp *, int, const char *, int, struct stat *);
 
 struct linux_flock {
        short       l_type;
diff -r 92664ab9052c -r 5194e6eac144 sys/compat/linux/common/linux_file64.c
--- a/sys/compat/linux/common/linux_file64.c    Thu Nov 25 02:09:23 2021 +0000
+++ b/sys/compat/linux/common/linux_file64.c    Thu Nov 25 02:27:08 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_file64.c,v 1.66 2021/11/25 02:09:23 ryo Exp $    */
+/*     $NetBSD: linux_file64.c,v 1.67 2021/11/25 02:27:08 ryo Exp $    */
 
 /*-
  * Copyright (c) 1995, 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.66 2021/11/25 02:09:23 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.67 2021/11/25 02:27:08 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -65,6 +65,7 @@
 #include <compat/linux/common/linux_ipc.h>
 #include <compat/linux/common/linux_sem.h>
 
+#include <compat/linux/linux_syscall.h>
 #include <compat/linux/linux_syscallargs.h>
 
 static void bsd_to_linux_stat64(struct stat *, struct linux_stat64 *);
@@ -107,6 +108,73 @@
 #  endif
 }
 
+int
+bsd_to_linux_statx(struct stat *st, struct linux_statx *stx,
+    unsigned int mask)
+{
+       if (mask & STATX__RESERVED)
+               return EINVAL;
+
+       /* XXX: STATX_MNT_ID is not supported */
+       unsigned int rmask = STATX_TYPE | STATX_MODE | STATX_NLINK |
+           STATX_UID | STATX_GID | STATX_ATIME | STATX_MTIME | STATX_CTIME |
+           STATX_INO | STATX_SIZE | STATX_BLOCKS | STATX_BTIME;
+
+       memset(stx, 0, sizeof(*stx));
+
+       if ((st->st_flags & UF_NODUMP) != 0)
+               stx->stx_attributes |= STATX_ATTR_NODUMP;
+       if ((st->st_flags & (UF_IMMUTABLE|SF_IMMUTABLE)) != 0)
+               stx->stx_attributes |= STATX_ATTR_IMMUTABLE;
+       if ((st->st_flags & (UF_APPEND|SF_APPEND)) != 0)
+               stx->stx_attributes |= STATX_ATTR_APPEND;
+
+       stx->stx_attributes_mask =
+           STATX_ATTR_NODUMP | STATX_ATTR_IMMUTABLE | STATX_ATTR_APPEND;
+
+       stx->stx_blksize = st->st_blksize;
+
+       stx->stx_nlink = st->st_nlink;
+       stx->stx_uid = st->st_uid;
+       stx->stx_gid = st->st_gid;
+       stx->stx_mode |= st->st_mode & S_IFMT;
+       stx->stx_mode |= st->st_mode & ~S_IFMT;
+       stx->stx_ino = st->st_ino;
+       stx->stx_size = st->st_size;
+       stx->stx_blocks = st->st_blocks;
+
+       stx->stx_atime.tv_sec = st->st_atime;
+       stx->stx_atime.tv_nsec = st->st_atimensec;
+
+       /* some filesystem has no birthtime returns 0 or -1 */
+       if ((st->st_birthtime == 0 && st->st_birthtimensec == 0) ||
+           (st->st_birthtime == (time_t)-1 &&
+           st->st_birthtimensec == (long)-1)) {
+               rmask &= ~STATX_BTIME;
+       } else {
+               stx->stx_btime.tv_sec = st->st_birthtime;
+               stx->stx_btime.tv_nsec = st->st_birthtimensec;
+       }
+
+       stx->stx_ctime.tv_sec = st->st_ctime;
+       stx->stx_ctime.tv_nsec = st->st_ctimensec;
+
+       stx->stx_mtime.tv_sec = st->st_mtime;
+       stx->stx_mtime.tv_nsec = st->st_mtimensec;
+
+       if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
+               stx->stx_rdev_major = major(st->st_rdev);
+               stx->stx_rdev_minor = minor(st->st_rdev);
+       } else {
+               stx->stx_dev_major = major(st->st_rdev);
+               stx->stx_dev_minor = minor(st->st_rdev);
+       }
+
+       stx->stx_mask = rmask;
+
+       return 0;
+}
+
 /*
  * The stat functions below are plain sailing. stat and lstat are handled
  * by one function to avoid code duplication.
@@ -171,6 +239,53 @@
 }
 #endif
 
+/*
+ * This is an internal function for the *statat() variant of linux,
+ * which returns struct stat, but flags and other handling are
+ * the same as in linux.
+ */
+int
+linux_statat(struct lwp *l, int fd, const char *path, int lflag,
+    struct stat *st)
+{
+       struct vnode *vp;
+       int error, nd_flag;
+       uint8_t c;
+
+       if (lflag & LINUX_AT_EMPTY_PATH) {
+               /*
+                * If path is null string:
+                */
+               error = ufetch_8(path, &c);
+               if (error != 0)
+                       return error;
+               if (c == '\0') {
+                       if (fd == LINUX_AT_FDCWD) {
+                               /*
+                                * operate on current directory
+                                */
+                               vp = l->l_proc->p_cwdi->cwdi_cdir;
+                               vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+                               error = vn_stat(vp, st);
+                               VOP_UNLOCK(vp);
+                       } else {
+                               /*
+                                * operate on fd
+                                */
+                               error = do_sys_fstat(fd, st);
+                       }
+                       return error;
+               }
+       }
+
+       if (lflag & LINUX_AT_SYMLINK_NOFOLLOW)
+               nd_flag = NOFOLLOW;
+       else
+               nd_flag = FOLLOW;
+
+       return do_sys_statat(l, fd, path, nd_flag, st);
+}
+
 int
 linux_sys_fstatat64(struct lwp *l, const struct linux_sys_fstatat64_args *uap, register_t *retval)
 {
@@ -182,54 +297,47 @@
        } */
        struct linux_stat64 tmplst;
        struct stat tmpst;
-       struct vnode *vp;
-       int error, nd_flag, fd;
-       uint8_t c;
+       int error;
 
-       if (SCARG(uap, flag) & LINUX_AT_EMPTY_PATH) {
-               /*
-                * If path is null string:
-                */
-               error = ufetch_8(SCARG(uap, path), &c);
-               if (error != 0)
-                       return error;
-               if (c == '\0') {
-                       fd = SCARG(uap, fd);
-                       if (fd == AT_FDCWD) {
-                               /*
-                                * operate on current directory
-                                */
-                               vp = l->l_proc->p_cwdi->cwdi_cdir;
-                               vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-                               error = vn_stat(vp, &tmpst);
-                               VOP_UNLOCK(vp);
-                       } else {
-                               /*
-                                * operate on fd
-                                */
-                               error = do_sys_fstat(fd, &tmpst);
-                       }
-                       if (error != 0)
-                               return error;
-                       goto done;
-               }
-       }
-
-       if (SCARG(uap, flag) & LINUX_AT_SYMLINK_NOFOLLOW)
-               nd_flag = NOFOLLOW;
-       else
-               nd_flag = FOLLOW;
-
-       error = do_sys_statat(l, SCARG(uap, fd), SCARG(uap, path), nd_flag, &tmpst);
+       error = linux_statat(l, SCARG(uap, fd), SCARG(uap, path),
+           SCARG(uap, flag), &tmpst);
        if (error != 0)
                return error;
 
-done:
        bsd_to_linux_stat64(&tmpst, &tmplst);
 
        return copyout(&tmplst, SCARG(uap, sp), sizeof tmplst);
 }
 
+#ifdef LINUX_SYS_statx
+int
+linux_sys_statx(struct lwp *l, const struct linux_sys_statx_args *uap,
+    register_t *retval)
+{
+       /* {
+               syscallarg(int) fd;
+               syscallarg(const char *) path;
+               syscallarg(int) flag;
+               syscallarg(unsigned int) mask;
+               syscallarg(struct linux_statx *) sp;
+       } */
+       struct linux_statx stx;
+       struct stat st;
+       int error;
+
+       error = linux_statat(l, SCARG(uap, fd), SCARG(uap, path),
+           SCARG(uap, flag), &st);
+       if (error != 0)
+               return error;
+
+       error = bsd_to_linux_statx(&st, &stx, SCARG(uap, mask));
+       if (error != 0)
+               return error;
+
+       return copyout(&stx, SCARG(uap, sp), sizeof stx);
+}
+#endif /* LINUX_SYS_statx */
+
 #ifndef __alpha__
 int
 linux_sys_truncate64(struct lwp *l, const struct linux_sys_truncate64_args *uap, register_t *retval)
diff -r 92664ab9052c -r 5194e6eac144 sys/compat/linux/common/linux_types.h
--- a/sys/compat/linux/common/linux_types.h     Thu Nov 25 02:09:23 2021 +0000
+++ b/sys/compat/linux/common/linux_types.h     Thu Nov 25 02:27:08 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_types.h,v 1.32 2021/09/23 06:56:27 ryo Exp $     */
+/*     $NetBSD: linux_types.h,v 1.33 2021/11/25 02:27:08 ryo Exp $     */
 
 /*-
  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -173,4 +173,63 @@
 };
 #endif /* !LINUX_STATFS_64BIT */
 
+struct linux_statx_timestamp {
+       int64_t tv_sec;
+       uint32_t tv_nsec;
+       int32_t __reserved;
+};
+
+#define STATX_TYPE             0x00000001
+#define STATX_MODE             0x00000002
+#define STATX_NLINK            0x00000004
+#define STATX_UID              0x00000008
+#define STATX_GID              0x00000010
+#define STATX_ATIME            0x00000020
+#define STATX_MTIME            0x00000040
+#define STATX_CTIME            0x00000080
+#define STATX_INO              0x00000100
+#define STATX_SIZE             0x00000200
+#define STATX_BLOCKS           0x00000400
+#define STATX_BASIC_STATS      0x000007ff
+#define STATX_BTIME            0x00000800
+#define STATX_MNT_ID           0x00001000
+#define STATX_ALL              0x00000fff
+#define STATX__RESERVED                0x80000000
+
+#define STATX_ATTR_COMPRESSED  0x00000004
+#define STATX_ATTR_IMMUTABLE   0x00000010
+#define STATX_ATTR_APPEND      0x00000020
+#define STATX_ATTR_NODUMP      0x00000040
+#define STATX_ATTR_ENCRYPTED   0x00000800



Home | Main Index | Thread Index | Old Index