summaryrefslogtreecommitdiffstats
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
parentc7ba1f9694fa8b0335305d6b36f179a03a55fee9 (diff)
downloadFreeBSD-src-065a73369e7e9928b0d617ca8787a109245552e2.zip
FreeBSD-src-065a73369e7e9928b0d617ca8787a109245552e2.tar.gz
Add mount syscall to linux emulation. Also improve emulation of reboot.
-rw-r--r--sys/alpha/linux/linux.h9
-rw-r--r--sys/alpha/linux/syscalls.master10
-rw-r--r--sys/compat/linux/linux_file.c89
-rw-r--r--sys/compat/linux/linux_misc.c20
-rw-r--r--sys/i386/linux/linux.h9
-rw-r--r--sys/i386/linux/syscalls.master10
6 files changed, 139 insertions, 8 deletions
diff --git a/sys/alpha/linux/linux.h b/sys/alpha/linux/linux.h
index b76ef59..92628e9 100644
--- a/sys/alpha/linux/linux.h
+++ b/sys/alpha/linux/linux.h
@@ -282,6 +282,15 @@ int linux_ioctl_unregister_handlers(struct linker_set *s);
#define LINUX_F_UNLCK 8
/*
+ * mount flags
+ */
+#define LINUX_MS_RDONLY 0x0001
+#define LINUX_MS_NOSUID 0x0002
+#define LINUX_MS_NODEV 0x0004
+#define LINUX_MS_NOEXEC 0x0008
+#define LINUX_MS_REMOUNT 0x0020
+
+/*
* SystemV IPC defines
*/
#define LINUX_SEMOP 1
diff --git a/sys/alpha/linux/syscalls.master b/sys/alpha/linux/syscalls.master
index 3af0e83..038fe94 100644
--- a/sys/alpha/linux/syscalls.master
+++ b/sys/alpha/linux/syscalls.master
@@ -59,8 +59,10 @@
18 UNIMPL LINUX
19 STD LINUX { int linux_lseek(int fdes, long off, int whence); }
20 NOPROTO LINUX { int getpid(void); }
-21 UNIMPL LINUX
-22 STD LINUX { int linux_umount(void); }
+21 STD LINUX { int linux_mount(char *specialfile, char *dir, \
+ char *filesystemtype, u_long rwflag, \
+ void *data); }
+22 STD LINUX { int linux_umount(char *path); }
23 NOPROTO LINUX { int setuid(uid_t uid); }
24 NOPROTO LINUX { int getuid(void); }
25 UNIMPL LINUX
@@ -90,7 +92,7 @@
49 UNIMPL LINUX
50 UNIMPL LINUX
51 NOPROTO LINUX { int acct(char *path); }
-52 UNIMPL LINUX
+52 STD LINUX { int linux_umount2(char *path, int flags); }
53 UNIMPL LINUX
54 STD LINUX { int linux_ioctl(int fd, u_long cmd, u_long arg); }
55 UNIMPL LINUX
@@ -393,7 +395,7 @@
308 STD LINUX { int linux_delete_module(void); }
309 STD LINUX { int linux_get_kernel_syms(void); }
310 STD LINUX { int linux_ksyslog(int what); }
-311 NOPROTO LINUX { int reboot(int opt); }
+311 STD LINUX { int linux_reboot(int magic1, int magic2, int opt); }
312 STD LINUX { int linux_clone(int flags, void *stack); }
313 STD LINUX { int linux_uselib(char *library); }
314 NOPROTO BSD { int mlock(const void *addr, size_t len); }
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));
+}
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index 8aff68a..88371d4 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -406,6 +406,15 @@ int linux_ioctl_unregister_handlers(struct linker_set *s);
#define LINUX_F_UNLCK 2
/*
+ * mount flags
+ */
+#define LINUX_MS_RDONLY 0x0001
+#define LINUX_MS_NOSUID 0x0002
+#define LINUX_MS_NODEV 0x0004
+#define LINUX_MS_NOEXEC 0x0008
+#define LINUX_MS_REMOUNT 0x0020
+
+/*
* SystemV IPC defines
*/
#define LINUX_SEMOP 1
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index e5c8e36..c81a746 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -54,8 +54,10 @@
18 STD LINUX { int linux_stat(char *path, struct ostat *up); }
19 STD LINUX { int linux_lseek(int fdes, long off, int whence); }
20 NOPROTO LINUX { int getpid(void); }
-21 STD LINUX { int linux_mount(void); }
-22 STD LINUX { int linux_umount(void); }
+21 STD LINUX { int linux_mount(char *specialfile, char *dir, \
+ char *filesystemtype, u_long rwflag, \
+ void *data); }
+22 STD LINUX { int linux_umount(char *path); }
23 NOPROTO LINUX { int setuid(uid_t uid); }
24 NOPROTO LINUX { int getuid(void); }
25 STD LINUX { int linux_stime(void); }
@@ -86,7 +88,7 @@
49 NOPROTO LINUX { int geteuid(void); }
50 NOPROTO LINUX { int getegid(void); }
51 NOPROTO LINUX { int acct(char *path); }
-52 STD LINUX { int linux_umount2(void); }
+52 STD LINUX { int linux_umount2(char *path, int flags); }
53 STD LINUX { int linux_lock(void); }
54 STD LINUX { int linux_ioctl(int fd, u_long cmd, int arg); }
55 STD LINUX { int linux_fcntl(int fd, int cmd, int arg); }
@@ -135,7 +137,7 @@
int count); }
86 STD LINUX { int linux_uselib(char *library); }
87 NOPROTO LINUX { int swapon(char *name); }
-88 NOPROTO LINUX { int reboot(int opt); }
+88 STD LINUX { int linux_reboot(int magic1, int magic2, int opt); }
89 STD LINUX { int linux_readdir(int fd, \
struct linux_dirent *dent, \
unsigned int count); }
OpenPOWER on IntegriCloud