svn commit: r361823 - in stable/12/lib/libprocstat: . zfs
Andriy Gapon
avg at FreeBSD.org
Fri Jun 5 06:34:07 UTC 2020
Author: avg
Date: Fri Jun 5 06:34:04 2020
New Revision: 361823
URL: https://svnweb.freebsd.org/changeset/base/361823
Log:
MFC r361363,r361434: libprocstat: fix ZFS support
First of all, znode_phys_t hasn't been used for storing file attributes
for a long time now. Modern ZFS versions use a System Attribute table
with a flexible layout. But more importantly all the required
information is available in znode_t itself.
It's not easy to include zfs_znode.h in userland without breaking code
because the most interesting parts of the header are kernel-only. And
hardcoding field offsets is too fragile. So, I created a new
compilation unit that includes zfs_znode.h using some mild kludges to
get it and its dependencies to compile in userland. The compilation
unit exports interesting field offsets and does not have any other code.
PR: 194117
Sponsored by: Panzura
Added:
stable/12/lib/libprocstat/zfs_defs.c
- copied, changed from r361363, head/lib/libprocstat/zfs_defs.c
stable/12/lib/libprocstat/zfs_defs.h
- copied unchanged from r361363, head/lib/libprocstat/zfs_defs.h
Modified:
stable/12/lib/libprocstat/Makefile
stable/12/lib/libprocstat/zfs.c
stable/12/lib/libprocstat/zfs/Makefile
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/lib/libprocstat/Makefile
==============================================================================
--- stable/12/lib/libprocstat/Makefile Fri Jun 5 06:21:23 2020 (r361822)
+++ stable/12/lib/libprocstat/Makefile Fri Jun 5 06:34:04 2020 (r361823)
@@ -61,16 +61,17 @@ MLINKS+=libprocstat.3 procstat_close.3 \
# XXX This is a hack.
.if ${MK_CDDL} != "no"
CFLAGS+= -DLIBPROCSTAT_ZFS
-OBJS+= zfs/zfs.o
-SOBJS+= zfs/zfs.pico
-POBJS+= zfs/zfs.po
+SRCS+= zfs.c
+OBJS+= zfs/zfs_defs.o
+SOBJS+= zfs/zfs_defs.pico
+POBJS+= zfs/zfs_defs.po
SUBDIR= zfs
-zfs/zfs.o: .PHONY
- @cd ${.CURDIR}/zfs && ${MAKE} zfs.o
-zfs/zfs.pico: .PHONY
- @cd ${.CURDIR}/zfs && ${MAKE} zfs.pico
-zfs/zfs.po: .PHONY
- @cd ${.CURDIR}/zfs && ${MAKE} zfs.po
+zfs/zfs_defs.o: .PHONY
+ @cd ${.CURDIR}/zfs && ${MAKE} zfs_defs.o
+zfs/zfs_defs.pico: .PHONY
+ @cd ${.CURDIR}/zfs && ${MAKE} zfs_defs.pico
+zfs/zfs_defs.po: .PHONY
+ @cd ${.CURDIR}/zfs && ${MAKE} zfs_defs.po
.endif
.include <bsd.lib.mk>
Modified: stable/12/lib/libprocstat/zfs.c
==============================================================================
--- stable/12/lib/libprocstat/zfs.c Fri Jun 5 06:21:23 2020 (r361822)
+++ stable/12/lib/libprocstat/zfs.c Fri Jun 5 06:34:04 2020 (r361823)
@@ -31,22 +31,13 @@
#include <sys/param.h>
#define _KERNEL
#include <sys/mount.h>
-#include <sys/taskqueue.h>
#undef _KERNEL
+#include <sys/queue.h>
+#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/vnode.h>
-#undef lbolt
-#undef lbolt64
-#undef gethrestime_sec
-#include <sys/zfs_context.h>
-#include <sys/spa.h>
-#include <sys/spa_impl.h>
-#include <sys/dmu.h>
-#include <sys/zap.h>
-#include <sys/fs/zfs.h>
-#include <sys/zfs_znode.h>
-#include <sys/zfs_sa.h>
-
#include <netinet/in.h>
#include <err.h>
@@ -57,24 +48,15 @@
#define ZFS
#include "libprocstat.h"
#include "common_kvm.h"
+#include "zfs_defs.h"
-/*
- * Offset calculations that are used to get data from znode without having the
- * definition.
- */
-#define LOCATION_ZID (2 * sizeof(void *))
-#define LOCATION_ZPHYS(zsize) ((zsize) - (2 * sizeof(void *) + sizeof(struct task)))
-
int
zfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn)
{
- znode_phys_t zphys;
struct mount mount, *mountptr;
- uint64_t *zid;
- void *znodeptr, *vnodeptr;
+ void *znodeptr;
char *dataptr;
- void *zphys_addr;
size_t len;
int size;
@@ -83,33 +65,27 @@ zfs_filestat(kvm_t *kd, struct vnode *vp, struct vnsta
warnx("error getting sysctl");
return (1);
}
- znodeptr = malloc(size);
- if (znodeptr == NULL) {
+ dataptr = malloc(size);
+ if (dataptr == NULL) {
warnx("error allocating memory for znode storage");
return (1);
}
- /* Since we have problems including vnode.h, we'll use the wrappers. */
- vnodeptr = getvnodedata(vp);
- if (!kvm_read_all(kd, (unsigned long)vnodeptr, znodeptr,
- (size_t)size)) {
- warnx("can't read znode at %p", (void *)vnodeptr);
+
+ if ((size_t)size < offsetof_z_id + sizeof(uint64_t) ||
+ (size_t)size < offsetof_z_mode + sizeof(mode_t) ||
+ (size_t)size < offsetof_z_size + sizeof(uint64_t)) {
+ warnx("znode_t size is too small");
goto bad;
}
- /*
- * z_id field is stored in the third pointer. We therefore skip the two
- * first bytes.
- *
- * Pointer to the z_phys structure is the next last pointer. Therefore
- * go back two bytes from the end.
- */
- dataptr = znodeptr;
- zid = (uint64_t *)(dataptr + LOCATION_ZID);
- zphys_addr = *(void **)(dataptr + LOCATION_ZPHYS(size));
+ if ((size_t)size != sizeof_znode_t)
+ warnx("znode_t size mismatch, data could be wrong");
- if (!kvm_read_all(kd, (unsigned long)zphys_addr, &zphys,
- sizeof(zphys))) {
- warnx("can't read znode_phys at %p", zphys_addr);
+ /* Since we have problems including vnode.h, we'll use the wrappers. */
+ znodeptr = getvnodedata(vp);
+ if (!kvm_read_all(kd, (unsigned long)znodeptr, dataptr,
+ (size_t)size)) {
+ warnx("can't read znode at %p", (void *)znodeptr);
goto bad;
}
@@ -119,18 +95,18 @@ zfs_filestat(kvm_t *kd, struct vnode *vp, struct vnsta
warnx("can't read mount at %p", (void *)mountptr);
goto bad;
}
- vn->vn_fsid = mount.mnt_stat.f_fsid.val[0];
- vn->vn_fileid = *zid;
+
/*
- * XXX: Shows up wrong in output, but UFS has this error too. Could
- * be that we're casting mode-variables from 64-bit to 8-bit or simply
- * error in the mode-to-string function.
+ * XXX Assume that this is a znode, but it can be a special node
+ * under .zfs/.
*/
- vn->vn_mode = (mode_t)zphys.zp_mode;
- vn->vn_size = (u_long)zphys.zp_size;
- free(znodeptr);
+ vn->vn_fsid = mount.mnt_stat.f_fsid.val[0];
+ vn->vn_fileid = *(uint64_t *)(void *)(dataptr + offsetof_z_id);
+ vn->vn_mode = *(mode_t *)(void *)(dataptr + offsetof_z_mode);
+ vn->vn_size = *(uint64_t *)(void *)(dataptr + offsetof_z_size);
+ free(dataptr);
return (0);
bad:
- free(znodeptr);
+ free(dataptr);
return (1);
}
Modified: stable/12/lib/libprocstat/zfs/Makefile
==============================================================================
--- stable/12/lib/libprocstat/zfs/Makefile Fri Jun 5 06:21:23 2020 (r361822)
+++ stable/12/lib/libprocstat/zfs/Makefile Fri Jun 5 06:34:04 2020 (r361823)
@@ -2,20 +2,20 @@
.PATH: ${.CURDIR:H}
-SRCS= zfs.c
-OBJS= zfs.o
+SRCS= zfs_defs.c
+OBJS= zfs_defs.o
WARNS?= 1
CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
-CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR:H}
CFLAGS+= -DNEED_SOLARIS_BOOLEAN
+CFLAGS+= -fno-builtin -nostdlib
all: ${OBJS}
CLEANFILES= ${OBJS}
Copied and modified: stable/12/lib/libprocstat/zfs_defs.c (from r361363, head/lib/libprocstat/zfs_defs.c)
==============================================================================
--- head/lib/libprocstat/zfs_defs.c Fri May 22 11:20:23 2020 (r361363, copy source)
+++ stable/12/lib/libprocstat/zfs_defs.c Fri Jun 5 06:34:04 2020 (r361823)
@@ -57,3 +57,7 @@ size_t sizeof_znode_t = sizeof(znode_t);
size_t offsetof_z_id = offsetof(znode_t, z_id);
size_t offsetof_z_size = offsetof(znode_t, z_size);
size_t offsetof_z_mode = offsetof(znode_t, z_mode);
+
+/* Keep pcpu.h satisfied. */
+uintptr_t *__start_set_pcpu;
+uintptr_t *__stop_set_pcpu;
Copied: stable/12/lib/libprocstat/zfs_defs.h (from r361363, head/lib/libprocstat/zfs_defs.h)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/12/lib/libprocstat/zfs_defs.h Fri Jun 5 06:34:04 2020 (r361823, copy of r361363, head/lib/libprocstat/zfs_defs.h)
@@ -0,0 +1,38 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Andriy Gapon <avg at FreeBSD.org>
+ *
+ * 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 REGENTS 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 REGENTS 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LIBPROCSTAT_ZFS_DEFS_H
+#define _LIBPROCSTAT_ZFS_DEFS_H
+
+extern size_t sizeof_znode_t;
+extern size_t offsetof_z_id;
+extern size_t offsetof_z_size;
+extern size_t offsetof_z_mode;
+
+#endif /* _LIBPROCSTAT_ZFS_DEFS_H */
More information about the svn-src-stable-12
mailing list