summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/msync.261
-rw-r--r--sys/compat/bsdos/syscalls.master4
-rw-r--r--sys/compat/freebsd/freebsd_misc.c25
-rw-r--r--sys/compat/freebsd/syscalls.master4
-rw-r--r--sys/compat/linux/linux_misc.c23
-rw-r--r--sys/compat/linux/syscalls.master4
-rw-r--r--sys/compat/sunos/sunos_misc.c19
-rw-r--r--sys/compat/sunos/syscalls.master4
-rw-r--r--sys/kern/syscalls.master5
-rw-r--r--sys/sys/mman.h11
-rw-r--r--sys/vm/vm_map.c9
-rw-r--r--sys/vm/vm_mmap.c39
-rw-r--r--sys/vm/vm_param.h3
-rw-r--r--sys/vm/vm_swap.c21
14 files changed, 127 insertions, 105 deletions
diff --git a/lib/libc/sys/msync.2 b/lib/libc/sys/msync.2
index 8b5f326760a..fbee0821d38 100644
--- a/lib/libc/sys/msync.2
+++ b/lib/libc/sys/msync.2
@@ -33,7 +33,7 @@
.\"
.\" @(#)msync.2 8.1 (Berkeley) 6/9/93
.\"
-.Dd June 9, 1993
+.Dd October 10, 1997
.Dt MSYNC 2
.Os
.Sh NAME
@@ -43,13 +43,15 @@
.Fd #include <sys/types.h>
.Fd #include <sys/mman.h>
.Ft int
-.Fn msync "caddr_t addr" "size_t len"
+.Fn msync "void *addr" "size_t len" "int flags"
.Sh DESCRIPTION
The
.Fn msync
-system call
-writes any modified pages back to the filesystem and updates
-the file modification time.
+system call writes all pages with shared modifications
+in the specified
+region of the process's address space back to permanent
+storage, and, if requested, invalidates cached data mapped
+in the region.
If
.Fa len
is 0, all modified pages within the region containing
@@ -57,16 +59,28 @@ is 0, all modified pages within the region containing
will be flushed;
if
.Fa len
-is non-zero, only the pages containing
+is non-zero, only modified pages containing
.Fa addr
and
.Fa len
-succeeding locations will be examined.
+succeeding locations will be flushed.
Any required synchronization of memory caches
will also take place at this time.
Filesystem operations on a file that is mapped for shared modifications
are unpredictable except after an
.Fn msync .
+.Pp
+The
+.Fa flags
+argument is formed by
+.Em or Ns 'ing
+the following values
+.Pp
+.Bd -literal -offset indent -compact
+MS_ASYNC Perform asynchronous writes.
+MS_SYNC Perform synchronous writes.
+MS_INVALIDATE Invalidate cached data after writing.
+.Ed
.Sh RETURN VALUES
Upon successful completion,
a value of 0 is returned.
@@ -76,20 +90,30 @@ is set to indicate the error.
.Sh ERRORS
The following errors may be reported:
.Bl -tag -width Er
-.It Bq Er EINVAL
+.It Bq Er EBUSY
The
-.Fa addr
-parameter was not page aligned.
+.Dv MS_INVALIDATE
+flag was specified and a portion of the specified region
+was locked with
+.Xr mlock 2 .
.It Bq Er EINVAL
-The
-.Fa addr
-parameter did not specify an address part of a mapped region.
+The specified
+.Fa flags
+argument was invalid.
.It Bq Er EINVAL
The
-.Fa len
-parameter was negative.
+.Fa addr
+parameter was not page aligned.
+.It Bq Er ENOMEM
+Addresses in the specified region are outside the range allowed
+for the address space of the process, or specify one or more pages
+which are unmapped.
.It Bq Er EIO
-An I/O error occured while writing to the file system.
+An I/O error occured while writing.
+.Sh BUGS
+Writes are currently done synchronously even if the
+.Dv MS_ASYNC
+flag is specified.
.Sh SEE ALSO
.Xr madvise 2 ,
.Xr minherit 2 ,
@@ -100,3 +124,8 @@ An I/O error occured while writing to the file system.
The
.Fn msync
function first appeared in 4.4BSD.
+It was modified to conform to
+.St -p1003.1b-93
+in
+.Nx 1.3 .
+.P
diff --git a/sys/compat/bsdos/syscalls.master b/sys/compat/bsdos/syscalls.master
index 3e0a4a84474..09d51e08eed 100644
--- a/sys/compat/bsdos/syscalls.master
+++ b/sys/compat/bsdos/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.2 1997/09/03 13:20:55 downsj Exp $
+ $OpenBSD: syscalls.master,v 1.3 1997/11/13 18:35:21 deraadt Exp $
; OpenBSD COMPAT_BSDOS system call name/number "master" file.
; (See syscalls.conf to see what it is processed into.)
@@ -131,7 +131,7 @@
63 NOARGS { int compat_43_sys_getkerninfo(int op, char *where, \
int *size, int arg); } ogetkerninfo
64 NOARGS { int compat_43_sys_getpagesize(void); } ogetpagesize
-65 NOARGS { int sys_msync(caddr_t addr, size_t len, int flags); }
+65 NOARGS { int sys_msync(void *addr, size_t len, int flags); }
66 NOARGS { int sys_vfork(void); }
67 OBSOL vread
68 OBSOL vwrite
diff --git a/sys/compat/freebsd/freebsd_misc.c b/sys/compat/freebsd/freebsd_misc.c
index a89018fcad1..fbf4c0d9414 100644
--- a/sys/compat/freebsd/freebsd_misc.c
+++ b/sys/compat/freebsd/freebsd_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: freebsd_misc.c,v 1.4 1997/11/13 07:35:38 deraadt Exp $ */
+/* $OpenBSD: freebsd_misc.c,v 1.5 1997/11/13 18:35:24 deraadt Exp $ */
/* $NetBSD: freebsd_misc.c,v 1.2 1996/05/03 17:03:10 christos Exp $ */
/*
@@ -48,29 +48,6 @@
#include <compat/freebsd/freebsd_rtprio.h>
#include <compat/freebsd/freebsd_timex.h>
-int
-freebsd_sys_msync(p, v, retval)
- struct proc *p;
- void *v;
- register_t *retval;
-{
- struct freebsd_sys_msync_args /* {
- syscallarg(caddr_t) addr;
- syscallarg(size_t) len;
- syscallarg(int) flags;
- } */ *uap = v;
- struct sys_msync_args bma;
-
- /*
- * FreeBSD-2.0-RELEASE's msync(2) is compatible with NetBSD's.
- * FreeBSD-2.0.5-RELEASE's msync(2) has addtional argument `flags',
- * but syscall number is not changed. :-<
- */
- SCARG(&bma, addr) = SCARG(uap, addr);
- SCARG(&bma, len) = SCARG(uap, len);
- return sys_msync(p, &bma, retval); /* XXX - simply ignores `flags' */
-}
-
/* just a place holder */
int
diff --git a/sys/compat/freebsd/syscalls.master b/sys/compat/freebsd/syscalls.master
index 8e06d188bdd..1b3e5f23e34 100644
--- a/sys/compat/freebsd/syscalls.master
+++ b/sys/compat/freebsd/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.7 1997/11/13 07:35:38 deraadt Exp $
+ $OpenBSD: syscalls.master,v 1.8 1997/11/13 18:35:23 deraadt Exp $
; $NetBSD: syscalls.master,v 1.3 1995/10/10 18:28:40 mycroft Exp $
; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -140,7 +140,7 @@
63 NOARGS { int compat_43_sys_getkerninfo(int op, char *where, \
int *size, int arg); } ogetkerninfo
64 NOARGS { int compat_43_sys_getpagesize(void); } ogetpagesize
-65 STD { int freebsd_sys_msync(caddr_t addr, size_t len, \
+65 NOARGS { int sys_msync(void *addr, size_t len, \
int flags); }
66 NOARGS { int sys_vfork(void); }
67 OBSOL vread
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index bace5aa9cd3..83bae49e180 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_misc.c,v 1.11 1997/11/13 06:37:49 deraadt Exp $ */
+/* $OpenBSD: linux_misc.c,v 1.12 1997/11/13 18:35:26 deraadt Exp $ */
/* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */
/*
@@ -529,27 +529,6 @@ linux_sys_mremap(p, v, retval)
return (ENOMEM);
}
-int
-linux_sys_msync(p, v, retval)
- struct proc *p;
- void *v;
- register_t *retval;
-{
- struct linux_sys_msync_args /* {
- syscallarg(caddr_t) addr;
- syscallarg(int) len;
- syscallarg(int) fl;
- } */ *uap = v;
-
- struct sys_msync_args bma;
-
- /* flags are ignored */
- SCARG(&bma, addr) = SCARG(uap, addr);
- SCARG(&bma, len) = SCARG(uap, len);
-
- return sys_msync(p, &bma, retval);
-}
-
/*
* This code is partly stolen from src/lib/libc/compat-43/times.c
* XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
diff --git a/sys/compat/linux/syscalls.master b/sys/compat/linux/syscalls.master
index d180fb8ae1f..fb52401620d 100644
--- a/sys/compat/linux/syscalls.master
+++ b/sys/compat/linux/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.11 1997/07/28 10:21:31 deraadt Exp $
+ $OpenBSD: syscalls.master,v 1.12 1997/11/13 18:35:27 deraadt Exp $
; $NetBSD: syscalls.master,v 1.15 1995/12/18 14:35:10 fvdl Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@@ -235,7 +235,7 @@
fd_set *writefds, fd_set *exceptfds, \
struct timeval *timeout); }
143 NOARGS { int sys_flock(int fd, int how); }
-144 STD { int linux_sys_msync(caddr_t addr, int len, int fl); }
+144 NOARGS { int sys_msync(void *addr, int len, int fl); }
145 NOARGS { int sys_readv(int fd, struct iovec *iovp, \
u_int iovcnt); }
146 NOARGS { int sys_writev(int fd, struct iovec *iovp, \
diff --git a/sys/compat/sunos/sunos_misc.c b/sys/compat/sunos/sunos_misc.c
index b092f7e5781..fabf8a01055 100644
--- a/sys/compat/sunos/sunos_misc.c
+++ b/sys/compat/sunos/sunos_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sunos_misc.c,v 1.15 1997/11/06 22:15:51 millert Exp $ */
+/* $OpenBSD: sunos_misc.c,v 1.16 1997/11/13 18:35:28 deraadt Exp $ */
/* $NetBSD: sunos_misc.c,v 1.65 1996/04/22 01:44:31 christos Exp $ */
/*
@@ -220,23 +220,6 @@ sunos_sys_execv(p, v, retval)
}
int
-sunos_sys_omsync(p, v, retval)
- struct proc *p;
- void *v;
- register_t *retval;
-{
- struct sunos_sys_omsync_args *uap = v;
- struct sys_msync_args ouap;
-
- if (SCARG(uap, flags))
- return (EINVAL);
- SCARG(&ouap, addr) = SCARG(uap, addr);
- SCARG(&ouap, len) = SCARG(uap, len);
-
- return (sys_msync(p, &ouap, retval));
-}
-
-int
sunos_sys_unmount(p, v, retval)
struct proc *p;
void *v;
diff --git a/sys/compat/sunos/syscalls.master b/sys/compat/sunos/syscalls.master
index 5f36e6d009b..2eb3d5c6d35 100644
--- a/sys/compat/sunos/syscalls.master
+++ b/sys/compat/sunos/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.7 1997/07/28 09:53:13 deraadt Exp $
+ $OpenBSD: syscalls.master,v 1.8 1997/11/13 18:35:29 deraadt Exp $
; $NetBSD: syscalls.master,v 1.33 1996/02/28 16:05:43 pk Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@@ -113,7 +113,7 @@
62 NOARGS { int compat_43_sys_fstat(int fd, struct ostat *sb); }
63 UNIMPL
64 NOARGS { int compat_43_sys_getpagesize(void); }
-65 STD { int sunos_sys_omsync(caddr_t addr, size_t len, \
+65 NOARGS { int sys_msync(void *addr, size_t len, \
int flags); }
66 NOARGS { int sys_vfork(void); }
67 OBSOL vread
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 8794f0f6483..71000ca1dd2 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.17 1997/11/13 07:11:12 deraadt Exp $
+ $OpenBSD: syscalls.master,v 1.18 1997/11/13 18:35:31 deraadt Exp $
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -129,7 +129,7 @@
63 COMPAT_43 { int sys_getkerninfo(int op, char *where, int *size, \
int arg); } ogetkerninfo
64 COMPAT_43 { int sys_getpagesize(void); } ogetpagesize
-65 STD { int sys_msync(caddr_t addr, size_t len); }
+65 STD { int sys_omsync(caddr_t addr, size_t len); }
66 STD { int sys_vfork(void); }
67 OBSOL vread
68 OBSOL vwrite
@@ -464,3 +464,4 @@
253 STD { int sys_issetugid(void); }
254 STD { int sys_lchown(char *path, int uid, int gid); }
255 STD { int sys_getsid(pid_t pid); }
+256 STD { int sys_msync(void *addr, size_t len, int flags); }
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
index 4f847f1ccbb..1354ce8f36a 100644
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mman.h,v 1.3 1996/03/24 17:01:33 tholo Exp $ */
+/* $OpenBSD: mman.h,v 1.4 1997/11/13 18:35:33 deraadt Exp $ */
/* $NetBSD: mman.h,v 1.11 1995/03/26 20:24:23 jtc Exp $ */
/*-
@@ -77,6 +77,13 @@
#define MADV_WILLNEED 3 /* will need these pages */
#define MADV_DONTNEED 4 /* dont need these pages */
+/*
+ * Flags to msync
+ */
+#define MS_ASYNC 0x01 /* perform asynchronous writes */
+#define MS_SYNC 0x02 /* perform synchronous writes */
+#define MS_INVALIDATE 0x04 /* invalidate cached data */
+
#ifndef _KERNEL
#include <sys/cdefs.h>
@@ -86,7 +93,7 @@ __BEGIN_DECLS
caddr_t mmap __P((caddr_t, size_t, int, int, int, off_t));
int mprotect __P((caddr_t, size_t, int));
int munmap __P((caddr_t, size_t));
-int msync __P((caddr_t, size_t));
+int msync __P((void *, size_t, int));
int mlock __P((caddr_t, size_t));
int munlock __P((caddr_t, size_t));
int madvise __P((caddr_t, size_t, int));
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index aaf57575b52..f28d379c66c 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_map.c,v 1.8 1997/11/06 05:59:34 csapuntz Exp $ */
+/* $OpenBSD: vm_map.c,v 1.9 1997/11/13 18:35:36 deraadt Exp $ */
/* $NetBSD: vm_map.c,v 1.23 1996/02/10 00:08:08 christos Exp $ */
/*
@@ -1394,7 +1394,8 @@ vm_map_clean(map, start, end, syncio, invalidate)
}
/*
- * Make a first pass to check for holes.
+ * Make a first pass to check for holes, and (if invalidating)
+ * wired pages.
*/
for (current = entry; current->start < end; current = current->next) {
if (current->is_sub_map) {
@@ -1407,6 +1408,10 @@ vm_map_clean(map, start, end, syncio, invalidate)
vm_map_unlock_read(map);
return(KERN_INVALID_ADDRESS);
}
+ if (current->wired_count) {
+ vm_map_unlock_read(map);
+ return(KERN_PAGES_LOCKED);
+ }
}
/*
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index afba8d0181b..4d9ff6b8a0c 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_mmap.c,v 1.8 1997/07/25 06:03:08 mickey Exp $ */
+/* $OpenBSD: vm_mmap.c,v 1.9 1997/11/13 18:35:38 deraadt Exp $ */
/* $NetBSD: vm_mmap.c,v 1.47 1996/03/16 23:15:23 christos Exp $ */
/*
@@ -271,22 +271,32 @@ sys_msync(p, v, retval)
register_t *retval;
{
struct sys_msync_args /* {
- syscallarg(caddr_t) addr;
+ syscallarg(void *) addr;
syscallarg(size_t) len;
+ syscallarg(int) flags;
} */ *uap = v;
vm_offset_t addr;
vm_size_t size, pageoff;
vm_map_t map;
- int rv;
+ int rv, flags;
boolean_t syncio, invalidate;
addr = (vm_offset_t)SCARG(uap, addr);
size = (vm_size_t)SCARG(uap, len);
+ flags = SCARG(uap, flags);
#ifdef DEBUG
if (mmapdebug & (MDB_FOLLOW|MDB_SYNC))
printf("msync(%d): addr 0x%lx len %lx\n", p->p_pid, addr, size);
#endif
+ /* sanity check flags */
+ if ((flags & ~(MS_ASYNC | MS_SYNC | MS_INVALIDATE)) != 0 ||
+ (flags & (MS_ASYNC | MS_SYNC | MS_INVALIDATE)) == 0 ||
+ (flags & (MS_ASYNC | MS_SYNC)) == (MS_ASYNC | MS_SYNC))
+ return (EINVAL);
+ if ((flags & (MS_ASYNC | MS_SYNC)) == 0)
+ flags |= MS_SYNC;
+
/*
* Align the address to a page boundary,
* and adjust the size accordingly.
@@ -297,8 +307,8 @@ sys_msync(p, v, retval)
size = (vm_size_t) round_page(size);
/* Disallow wrap-around. */
- if (addr + (int)size < addr)
- return (EINVAL);
+ if (addr + size < addr)
+ return (ENOMEM);
map = &p->p_vmspace->vm_map;
/*
@@ -316,7 +326,7 @@ sys_msync(p, v, retval)
rv = vm_map_lookup_entry(map, addr, &entry);
vm_map_unlock_read(map);
if (rv == FALSE)
- return (EINVAL);
+ return (ENOMEM);
addr = entry->start;
size = entry->end - entry->start;
}
@@ -325,11 +335,20 @@ sys_msync(p, v, retval)
printf("msync: cleaning/flushing address range [0x%lx-0x%lx)\n",
addr, addr+size);
#endif
+
+#if 0
/*
- * Could pass this in as a third flag argument to implement
- * Sun's MS_ASYNC.
+ * XXX Asynchronous msync() causes:
+ * . the process to hang on wchan "vospgw", and
+ * . a "vm_object_page_clean: pager_put error" message to
+ * be printed by the kernel.
*/
+ syncio = (flags & MS_SYNC) ? TRUE : FALSE;
+#else
syncio = TRUE;
+#endif
+ invalidate = (flags & MS_INVALIDATE) ? TRUE : FALSE;
+
/*
* XXX bummer, gotta flush all cached pages to ensure
* consistency with the file system cache. Otherwise, we could
@@ -344,9 +363,11 @@ sys_msync(p, v, retval)
case KERN_SUCCESS:
break;
case KERN_INVALID_ADDRESS:
- return (EINVAL); /* Sun returns ENOMEM? */
+ return (ENOMEM);
case KERN_FAILURE:
return (EIO);
+ case KERN_PAGES_LOCKED:
+ return (EBUSY);
default:
return (EINVAL);
}
diff --git a/sys/vm/vm_param.h b/sys/vm/vm_param.h
index 92b70fb3eed..eb413701e6b 100644
--- a/sys/vm/vm_param.h
+++ b/sys/vm/vm_param.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_param.h,v 1.11 1997/11/06 05:59:38 csapuntz Exp $ */
+/* $OpenBSD: vm_param.h,v 1.12 1997/11/13 18:35:39 deraadt Exp $ */
/* $NetBSD: vm_param.h,v 1.12 1995/03/26 20:39:16 jtc Exp $ */
/*
@@ -133,6 +133,7 @@ struct _ps_strings {
#define KERN_RESOURCE_SHORTAGE 6
#define KERN_NOT_RECEIVER 7
#define KERN_NO_ACCESS 8
+#define KERN_PAGES_LOCKED 9
#ifndef ASSEMBLER
/*
diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c
index 47bd8ba7ac1..eb2d6223778 100644
--- a/sys/vm/vm_swap.c
+++ b/sys/vm/vm_swap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_swap.c,v 1.6 1997/08/18 13:55:59 niklas Exp $ */
+/* $OpenBSD: vm_swap.c,v 1.7 1997/11/13 18:35:40 deraadt Exp $ */
/* $NetBSD: vm_swap.c,v 1.32 1996/02/05 01:54:09 christos Exp $ */
/*
@@ -45,6 +45,7 @@
#include <sys/vnode.h>
#include <sys/map.h>
#include <sys/file.h>
+#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
@@ -492,3 +493,21 @@ swfree(p, index)
return (0);
}
+
+int
+sys_omsync(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_msync_args ua;
+ struct sys_omsync_args /* {
+ syscallarg(caddr_t) addr;
+ syscallarg(size_t) len;
+ } */ *uap = v;
+
+ SCARG(&ua, addr) = SCARG(uap, addr);;
+ SCARG(&ua, len) = SCARG(uap, len);;
+ SCARG(&ua, flags) = MS_SYNC | MS_INVALIDATE;
+ return (sys_msync(p, &ua, retval));
+}