summaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
authorchristos <christos@NetBSD.org>2002-03-22 14:54:49 +0000
committerchristos <christos@NetBSD.org>2002-03-22 14:54:49 +0000
commitb02cb6b16fcf28fee2d089c7e5977a35150269d7 (patch)
tree1b4976d80ff5c0189f59c97c11e360fb8157d327 /sys/compat/linux
parent3b57c6607c173e319267b15510eed497490bad73 (diff)
implement the locking calls for linux_file64.
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/common/linux_fcntl.h9
-rw-r--r--sys/compat/linux/common/linux_file64.c123
2 files changed, 106 insertions, 26 deletions
diff --git a/sys/compat/linux/common/linux_fcntl.h b/sys/compat/linux/common/linux_fcntl.h
index 7e6ad93a078..b4fbe9a7e79 100644
--- a/sys/compat/linux/common/linux_fcntl.h
+++ b/sys/compat/linux/common/linux_fcntl.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_fcntl.h,v 1.8 2002/01/14 23:14:42 bjh21 Exp $ */
+/* $NetBSD: linux_fcntl.h,v 1.9 2002/03/22 14:54:49 christos Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -58,6 +58,13 @@ struct linux_flock {
linux_pid_t l_pid;
};
+struct linux_flock64 {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ linux_pid_t l_pid;
+};
#if defined(__i386__)
#include <compat/linux/arch/i386/linux_fcntl.h>
#elif defined(__m68k__)
diff --git a/sys/compat/linux/common/linux_file64.c b/sys/compat/linux/common/linux_file64.c
index ddcc1f197dc..fe237a129b1 100644
--- a/sys/compat/linux/common/linux_file64.c
+++ b/sys/compat/linux/common/linux_file64.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_file64.c,v 1.8 2002/03/16 20:43:53 christos Exp $ */
+/* $NetBSD: linux_file64.c,v 1.9 2002/03/22 14:54:49 christos Exp $ */
/*-
* Copyright (c) 1995, 1998, 2000 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.8 2002/03/16 20:43:53 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.9 2002/03/22 14:54:49 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -225,7 +225,57 @@ linux_sys_truncate64(p, v, retval)
return sys_truncate(p, uap, retval);
}
-#ifdef __mips__ /* i386 and powerpc could use it too */
+#if defined(__mips__) || defined(__i386__) /* powerpc could use it too */
+static void bsd_to_linux_flock64 __P((struct linux_flock64 *,
+ const struct flock *));
+static void linux_to_bsd_flock64 __P((struct flock *,
+ const struct linux_flock64 *));
+
+static void
+bsd_to_linux_flock64(lfp, bfp)
+ struct linux_flock64 *lfp;
+ const struct flock *bfp;
+{
+
+ lfp->l_start = bfp->l_start;
+ lfp->l_len = bfp->l_len;
+ lfp->l_pid = bfp->l_pid;
+ lfp->l_whence = bfp->l_whence;
+ switch (bfp->l_type) {
+ case F_RDLCK:
+ lfp->l_type = LINUX_F_RDLCK;
+ break;
+ case F_UNLCK:
+ lfp->l_type = LINUX_F_UNLCK;
+ break;
+ case F_WRLCK:
+ lfp->l_type = LINUX_F_WRLCK;
+ break;
+ }
+}
+
+static void
+linux_to_bsd_flock64(bfp, lfp)
+ struct flock *bfp;
+ const struct linux_flock64 *lfp;
+{
+
+ bfp->l_start = lfp->l_start;
+ bfp->l_len = lfp->l_len;
+ bfp->l_pid = lfp->l_pid;
+ bfp->l_whence = lfp->l_whence;
+ switch (lfp->l_type) {
+ case LINUX_F_RDLCK:
+ bfp->l_type = F_RDLCK;
+ break;
+ case LINUX_F_UNLCK:
+ bfp->l_type = F_UNLCK;
+ break;
+ case LINUX_F_WRLCK:
+ bfp->l_type = F_WRLCK;
+ break;
+ }
+}
int
linux_sys_fcntl64(p, v, retval)
struct proc *p;
@@ -233,34 +283,57 @@ linux_sys_fcntl64(p, v, retval)
register_t *retval;
{
struct linux_sys_fcntl64_args /* {
- syscallarg(unsigned int) fd;
- syscallarg(unsigned int) cmd;
- syscallarg(unsigned long) arg;
+ syscallarg(int) fd;
+ syscallarg(int) cmd;
+ syscallarg(void *) arg;
} */ *uap = v;
- unsigned int fd, cmd;
- unsigned long arg;
+ struct sys_fcntl_args fca;
+ struct linux_flock64 lfl;
+ struct flock bfl, *bfp;
int error;
+ caddr_t sg;
+ void *arg = SCARG(uap, arg);
+ int cmd = SCARG(uap, cmd);
+ int fd = SCARG(uap, fd);
- fd = SCARG(uap, fd);
- cmd = SCARG(uap, cmd);
- arg = SCARG(uap, arg);
+ printf("fcntl(%d, %d, %p)\n", fd, cmd, arg);
switch (cmd) {
- /* XXX implement this later */
- case LINUX_F_GETLK64:
- error = 0;
- break;
- case LINUX_F_SETLK64:
- error = 0;
- break;
- case LINUX_F_SETLKW64:
- error = 0;
- break;
- default:
- error = linux_sys_fcntl(p, v, retval);
- break;
+ case LINUX_F_GETLK64:
+ sg = stackgap_init(p, 0);
+ bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp);
+ if ((error = copyin(arg, &lfl, sizeof lfl)) != 0)
+ return error;
+ linux_to_bsd_flock64(&bfl, &lfl);
+ if ((error = copyout(&bfl, bfp, sizeof bfl)) != 0)
+ return error;
+ SCARG(&fca, fd) = fd;
+ SCARG(&fca, cmd) = F_GETLK;
+ SCARG(&fca, arg) = bfp;
+ if ((error = sys_fcntl(p, &fca, retval)) != 0)
+ return error;
+ if ((error = copyin(bfp, &bfl, sizeof bfl)) != 0)
+ return error;
+ bsd_to_linux_flock64(&lfl, &bfl);
+ return copyout(&lfl, arg, sizeof lfl);
+ case LINUX_F_SETLK64:
+ case LINUX_F_SETLKW64:
+ cmd = (cmd == LINUX_F_SETLK64 ? F_SETLK : F_SETLKW);
+ if ((error = copyin(arg, &lfl, sizeof lfl)) != 0)
+ return error;
+ linux_to_bsd_flock64(&bfl, &lfl);
+ sg = stackgap_init(p, 0);
+ bfp = (struct flock *) stackgap_alloc(p, &sg, sizeof *bfp);
+ if ((error = copyout(&bfl, bfp, sizeof bfl)) != 0)
+ return error;
+ SCARG(&fca, fd) = fd;
+ SCARG(&fca, cmd) = cmd;
+ SCARG(&fca, arg) = bfp;
+ return sys_fcntl(p, &fca, retval);
+ default:
+ return linux_sys_fcntl(p, v, retval);
}
return error;
}
-#endif /* __mips__ */
+#endif /* __mips__ || __i386__ */