summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2001-02-16 14:42:11 +0000
committerjlemon <jlemon@FreeBSD.org>2001-02-16 14:42:11 +0000
commit065a73369e7e9928b0d617ca8787a109245552e2 (patch)
tree27a55687c63b9b43bba2b369cc417272006db376 /sys/compat
parentc7ba1f9694fa8b0335305d6b36f179a03a55fee9 (diff)
downloadFreeBSD-src-065a73369e7e9928b0d617ca8787a109245552e2.zip
FreeBSD-src-065a73369e7e9928b0d617ca8787a109245552e2.tar.gz
Add mount syscall to linux emulation. Also improve emulation of reboot.
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_file.c89
-rw-r--r--sys/compat/linux/linux_misc.c20
2 files changed, 109 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 4736ddc..441aeb7 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -40,10 +40,15 @@
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
+#include <sys/mount.h>
#include <sys/dirent.h>
#include <sys/conf.h>
#include <sys/tty.h>
+#include <ufs/ufs/extattr.h>
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/ufsmount.h>
+
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#include <compat/linux/linux_util.h>
@@ -885,3 +890,87 @@ linux_pwrite(p, uap)
bsd.offset = uap->offset;
return pwrite(p, &bsd);
}
+
+int
+linux_mount(struct proc *p, struct linux_mount_args *args)
+{
+ struct mount_args bsd_args;
+ struct ufs_args ufs;
+ char fstypename[MFSNAMELEN];
+ char mntonname[MNAMELEN], mntfromname[MNAMELEN];
+ int error = 0;
+
+ error = copyinstr(args->filesystemtype, fstypename,
+ MFSNAMELEN - 1, NULL);
+ if (error)
+ return (error);
+ error = copyinstr(args->specialfile, mntfromname, MFSNAMELEN - 1, NULL);
+ if (error)
+ return (error);
+ error = copyinstr(args->dir, mntonname, MFSNAMELEN - 1, NULL);
+ if (error)
+ return (error);
+
+#ifdef DEBUG
+ if (ldebug(mount))
+ printf(ARGS(mount, "%s, %s, %s"),
+ fstypename, mntfromname, mntonname);
+#endif
+
+ if (strcmp(fstypename, "ext2") == 0) {
+ bsd_args.type = "ext2fs";
+ bsd_args.data = (void *)&ufs;
+ ufs.fspec = mntfromname;
+#define DEFAULT_ROOTID -2
+ ufs.export.ex_root = DEFAULT_ROOTID;
+ ufs.export.ex_flags =
+ args->rwflag & LINUX_MS_RDONLY ? MNT_EXRDONLY : 0;
+ } else if (strcmp(fstypename, "proc") == 0) {
+ bsd_args.type = "linprocfs";
+ bsd_args.data = NULL;
+ } else {
+ return (ENODEV);
+ }
+
+ bsd_args.path = mntonname;
+ bsd_args.flags = 0;
+
+ if ((args->rwflag & 0xffff0000) == 0xc0ed0000) {
+ /*
+ * Linux SYNC flag is not included; the closest equivalent
+ * FreeBSD has is !ASYNC, which is our default.
+ */
+ if (args->rwflag & LINUX_MS_RDONLY)
+ bsd_args.flags |= MNT_RDONLY;
+ if (args->rwflag & LINUX_MS_NOSUID)
+ bsd_args.flags |= MNT_NOSUID;
+ if (args->rwflag & LINUX_MS_NODEV)
+ bsd_args.flags |= MNT_NODEV;
+ if (args->rwflag & LINUX_MS_NOEXEC)
+ bsd_args.flags |= MNT_NOEXEC;
+ if (args->rwflag & LINUX_MS_REMOUNT)
+ bsd_args.flags |= MNT_UPDATE;
+ }
+
+ return (mount1(p, &bsd_args, UIO_SYSSPACE));
+}
+
+int
+linux_umount(struct proc *p, struct linux_umount_args *args)
+{
+ struct linux_umount2_args args2;
+
+ args2.path = args->path;
+ args2.flags = 0;
+ return (linux_umount2(p, &args2));
+}
+
+int
+linux_umount2(struct proc *p, struct linux_umount2_args *args)
+{
+ struct unmount_args bsd;
+
+ bsd.path = args->path;
+ bsd.flags = args->flags; /* XXX correct? */
+ return (unmount(p, &bsd));
+}
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 822ef8b..552d5f4 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -40,6 +40,7 @@
#include <sys/imgact_aout.h>
#include <sys/mount.h>
#include <sys/namei.h>
+#include <sys/reboot.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
@@ -1145,3 +1146,22 @@ linux_sched_getscheduler(p, uap)
return error;
}
+
+#define REBOOT_CAD_ON 0x89abcdef
+#define REBOOT_CAD_OFF 0
+#define REBOOT_HALT 0xcdef0123
+
+int
+linux_reboot(struct proc *p, struct linux_reboot_args *args)
+{
+ struct reboot_args bsd_args;
+
+#ifdef DEBUG
+ if (ldebug(reboot))
+ printf(ARGS(reboot, "%p"), args->opt);
+#endif
+ if (args->opt == REBOOT_CAD_ON || args->opt == REBOOT_CAD_OFF)
+ return (0);
+ bsd_args.opt = args->opt == REBOOT_HALT ? RB_HALT : 0;
+ return (reboot(p, &bsd_args));
+}
OpenPOWER on IntegriCloud