diff options
-rw-r--r-- | lib/libc/sys/msync.2 | 61 | ||||
-rw-r--r-- | sys/compat/bsdos/syscalls.master | 4 | ||||
-rw-r--r-- | sys/compat/freebsd/freebsd_misc.c | 25 | ||||
-rw-r--r-- | sys/compat/freebsd/syscalls.master | 4 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 23 | ||||
-rw-r--r-- | sys/compat/linux/syscalls.master | 4 | ||||
-rw-r--r-- | sys/compat/sunos/sunos_misc.c | 19 | ||||
-rw-r--r-- | sys/compat/sunos/syscalls.master | 4 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 5 | ||||
-rw-r--r-- | sys/sys/mman.h | 11 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 9 | ||||
-rw-r--r-- | sys/vm/vm_mmap.c | 39 | ||||
-rw-r--r-- | sys/vm/vm_param.h | 3 | ||||
-rw-r--r-- | sys/vm/vm_swap.c | 21 |
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)); +} |