diff options
-rw-r--r-- | sys/alpha/linux/linux.h | 9 | ||||
-rw-r--r-- | sys/alpha/linux/syscalls.master | 10 | ||||
-rw-r--r-- | sys/compat/linux/linux_file.c | 89 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 20 | ||||
-rw-r--r-- | sys/i386/linux/linux.h | 9 | ||||
-rw-r--r-- | sys/i386/linux/syscalls.master | 10 |
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); } |