aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2012-08-22 20:05:34 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2012-08-22 20:05:34 +0000
commit258f94423bdbe5dfc8c9880bdec8cccae617f5ab (patch)
tree680839fceab7454a9813e3b941e8a18ac21baf37 /sys/kern/vfs_subr.c
parent7e690c1f79a0eb5a8d831ecf9a35bcd3f103a398 (diff)
downloadsrc-258f94423bdbe5dfc8c9880bdec8cccae617f5ab.tar.gz
src-258f94423bdbe5dfc8c9880bdec8cccae617f5ab.zip
Provide some compat32 shims for sysctl vfs.conflist. It is required
for getvfsbyname(3) operation when called from 32bit process, and getvfsbyname(3) is used by recent bsdtar import. Reported by: many Tested by: David Naylor <naylor.b.david@gmail.com> MFC after: 5 days
Notes
Notes: svn path=/head/; revision=239588
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r--sys/kern/vfs_subr.c65
1 files changed, 49 insertions, 16 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 1d6136aed28a..631d3f205d85 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -41,6 +41,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_compat.h"
#include "opt_ddb.h"
#include "opt_watchdog.h"
@@ -3111,21 +3112,49 @@ DB_SHOW_COMMAND(mount, db_show_mount)
/*
* Fill in a struct xvfsconf based on a struct vfsconf.
*/
-static void
-vfsconf2x(struct vfsconf *vfsp, struct xvfsconf *xvfsp)
+static int
+vfsconf2x(struct sysctl_req *req, struct vfsconf *vfsp)
{
+ struct xvfsconf xvfsp;
- strcpy(xvfsp->vfc_name, vfsp->vfc_name);
- xvfsp->vfc_typenum = vfsp->vfc_typenum;
- xvfsp->vfc_refcount = vfsp->vfc_refcount;
- xvfsp->vfc_flags = vfsp->vfc_flags;
+ bzero(&xvfsp, sizeof(xvfsp));
+ strcpy(xvfsp.vfc_name, vfsp->vfc_name);
+ xvfsp.vfc_typenum = vfsp->vfc_typenum;
+ xvfsp.vfc_refcount = vfsp->vfc_refcount;
+ xvfsp.vfc_flags = vfsp->vfc_flags;
/*
* These are unused in userland, we keep them
* to not break binary compatibility.
*/
- xvfsp->vfc_vfsops = NULL;
- xvfsp->vfc_next = NULL;
+ xvfsp.vfc_vfsops = NULL;
+ xvfsp.vfc_next = NULL;
+ return (SYSCTL_OUT(req, &xvfsp, sizeof(xvfsp)));
+}
+
+#ifdef COMPAT_FREEBSD32
+struct xvfsconf32 {
+ uint32_t vfc_vfsops;
+ char vfc_name[MFSNAMELEN];
+ int32_t vfc_typenum;
+ int32_t vfc_refcount;
+ int32_t vfc_flags;
+ uint32_t vfc_next;
+};
+
+static int
+vfsconf2x32(struct sysctl_req *req, struct vfsconf *vfsp)
+{
+ struct xvfsconf32 xvfsp;
+
+ strcpy(xvfsp.vfc_name, vfsp->vfc_name);
+ xvfsp.vfc_typenum = vfsp->vfc_typenum;
+ xvfsp.vfc_refcount = vfsp->vfc_refcount;
+ xvfsp.vfc_flags = vfsp->vfc_flags;
+ xvfsp.vfc_vfsops = 0;
+ xvfsp.vfc_next = 0;
+ return (SYSCTL_OUT(req, &xvfsp, sizeof(xvfsp)));
}
+#endif
/*
* Top level filesystem related information gathering.
@@ -3134,14 +3163,16 @@ static int
sysctl_vfs_conflist(SYSCTL_HANDLER_ARGS)
{
struct vfsconf *vfsp;
- struct xvfsconf xvfsp;
int error;
error = 0;
TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) {
- bzero(&xvfsp, sizeof(xvfsp));
- vfsconf2x(vfsp, &xvfsp);
- error = SYSCTL_OUT(req, &xvfsp, sizeof xvfsp);
+#ifdef COMPAT_FREEBSD32
+ if (req->flags & SCTL_MASK32)
+ error = vfsconf2x32(req, vfsp);
+ else
+#endif
+ error = vfsconf2x(req, vfsp);
if (error)
break;
}
@@ -3161,7 +3192,6 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS)
int *name = (int *)arg1 - 1; /* XXX */
u_int namelen = arg2 + 1; /* XXX */
struct vfsconf *vfsp;
- struct xvfsconf xvfsp;
log(LOG_WARNING, "userland calling deprecated sysctl, "
"please rebuild world\n");
@@ -3185,9 +3215,12 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS)
break;
if (vfsp == NULL)
return (EOPNOTSUPP);
- bzero(&xvfsp, sizeof(xvfsp));
- vfsconf2x(vfsp, &xvfsp);
- return (SYSCTL_OUT(req, &xvfsp, sizeof(xvfsp)));
+#ifdef COMPAT_FREEBSD32
+ if (req->flags & SCTL_MASK32)
+ return (vfsconf2x32(req, vfsp));
+ else
+#endif
+ return (vfsconf2x(req, vfsp));
}
return (EOPNOTSUPP);
}