Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
/*-
|
2017-11-27 15:20:12 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
|
|
*
|
2017-03-31 13:43:00 +00:00
|
|
|
* Copyright (c) 2006, 2011, 2016-2017 Robert N. M. Watson
|
2020-09-09 22:12:51 +00:00
|
|
|
* Copyright 2020 The FreeBSD Foundation
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2017-03-31 13:43:00 +00:00
|
|
|
* Portions of this software were developed by BAE Systems, the University of
|
|
|
|
* Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
|
|
|
|
* contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
|
|
|
|
* Computing (TC) research program.
|
|
|
|
*
|
2020-09-09 22:12:51 +00:00
|
|
|
* Portions of this software were developed by Konstantin Belousov
|
|
|
|
* under sponsorship from the FreeBSD Foundation.
|
|
|
|
*
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Support for shared swap-backed anonymous memory objects via
|
2019-09-26 15:32:28 +00:00
|
|
|
* shm_open(2), shm_rename(2), and shm_unlink(2).
|
|
|
|
* While most of the implementation is here, vm_mmap.c contains
|
|
|
|
* mapping logic changes.
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
*
|
2019-05-30 16:04:00 +00:00
|
|
|
* posixshmcontrol(1) allows users to inspect the state of the memory
|
|
|
|
* objects. Per-uid swap resource limit controls total amount of
|
|
|
|
* memory that user can consume for anonymous objects, including
|
|
|
|
* shared.
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
2011-06-30 10:56:02 +00:00
|
|
|
#include "opt_capsicum.h"
|
2014-08-01 23:29:04 +00:00
|
|
|
#include "opt_ktrace.h"
|
2011-06-30 10:56:02 +00:00
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/param.h>
|
2014-03-16 10:55:57 +00:00
|
|
|
#include <sys/capsicum.h>
|
2014-08-29 18:18:29 +00:00
|
|
|
#include <sys/conf.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#include <sys/file.h>
|
|
|
|
#include <sys/filedesc.h>
|
2019-02-28 22:00:36 +00:00
|
|
|
#include <sys/filio.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/fnv_hash.h>
|
|
|
|
#include <sys/kernel.h>
|
2019-07-29 20:26:01 +00:00
|
|
|
#include <sys/limits.h>
|
2014-08-01 23:29:04 +00:00
|
|
|
#include <sys/uio.h>
|
|
|
|
#include <sys/signal.h>
|
2016-04-13 20:14:13 +00:00
|
|
|
#include <sys/jail.h>
|
2014-08-01 23:29:04 +00:00
|
|
|
#include <sys/ktrace.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/lock.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/mutex.h>
|
2011-08-16 20:07:47 +00:00
|
|
|
#include <sys/priv.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/proc.h>
|
|
|
|
#include <sys/refcount.h>
|
|
|
|
#include <sys/resourcevar.h>
|
2013-03-09 02:32:23 +00:00
|
|
|
#include <sys/rwlock.h>
|
2019-05-23 12:35:40 +00:00
|
|
|
#include <sys/sbuf.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/stat.h>
|
2015-08-01 07:21:14 +00:00
|
|
|
#include <sys/syscallsubr.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <sys/sysproto.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/sx.h>
|
|
|
|
#include <sys/time.h>
|
2020-09-09 22:12:51 +00:00
|
|
|
#include <sys/vmmeter.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <sys/vnode.h>
|
2013-08-21 17:45:00 +00:00
|
|
|
#include <sys/unistd.h>
|
2014-09-22 16:20:47 +00:00
|
|
|
#include <sys/user.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2017-03-31 13:43:00 +00:00
|
|
|
#include <security/audit/audit.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <security/mac/mac_framework.h>
|
|
|
|
|
|
|
|
#include <vm/vm.h>
|
|
|
|
#include <vm/vm_param.h>
|
|
|
|
#include <vm/pmap.h>
|
2011-12-15 15:17:19 +00:00
|
|
|
#include <vm/vm_extern.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <vm/vm_map.h>
|
2011-12-14 22:22:19 +00:00
|
|
|
#include <vm/vm_kern.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <vm/vm_object.h>
|
|
|
|
#include <vm/vm_page.h>
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
#include <vm/vm_pageout.h>
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#include <vm/vm_pager.h>
|
|
|
|
#include <vm/swap_pager.h>
|
|
|
|
|
|
|
|
struct shm_mapping {
|
|
|
|
char *sm_path;
|
|
|
|
Fnv32_t sm_fnv;
|
|
|
|
struct shmfd *sm_shmfd;
|
|
|
|
LIST_ENTRY(shm_mapping) sm_link;
|
|
|
|
};
|
|
|
|
|
|
|
|
static MALLOC_DEFINE(M_SHMFD, "shmfd", "shared memory file descriptor");
|
|
|
|
static LIST_HEAD(, shm_mapping) *shm_dictionary;
|
|
|
|
static struct sx shm_dict_lock;
|
|
|
|
static struct mtx shm_timestamp_lock;
|
|
|
|
static u_long shm_hash;
|
2018-11-21 22:01:06 +00:00
|
|
|
static struct unrhdr64 shm_ino_unr;
|
2014-08-29 18:18:29 +00:00
|
|
|
static dev_t shm_dev_ino;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
|
|
|
#define SHM_HASH(fnv) (&shm_dictionary[(fnv) & shm_hash])
|
|
|
|
|
2014-08-29 21:50:32 +00:00
|
|
|
static void shm_init(void *arg);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
static void shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd);
|
|
|
|
static struct shmfd *shm_lookup(char *path, Fnv32_t fnv);
|
|
|
|
static int shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred);
|
2020-09-09 22:12:51 +00:00
|
|
|
static int shm_dotruncate_cookie(struct shmfd *shmfd, off_t length,
|
|
|
|
void *rl_cookie);
|
2019-09-25 17:32:43 +00:00
|
|
|
static int shm_dotruncate_locked(struct shmfd *shmfd, off_t length,
|
|
|
|
void *rl_cookie);
|
2019-11-18 13:31:16 +00:00
|
|
|
static int shm_copyin_path(struct thread *td, const char *userpath_in,
|
|
|
|
char **path_out);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
|
|
|
static fo_rdwr_t shm_read;
|
|
|
|
static fo_rdwr_t shm_write;
|
|
|
|
static fo_truncate_t shm_truncate;
|
2019-02-28 22:00:36 +00:00
|
|
|
static fo_ioctl_t shm_ioctl;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
static fo_stat_t shm_stat;
|
|
|
|
static fo_close_t shm_close;
|
2011-08-16 20:07:47 +00:00
|
|
|
static fo_chmod_t shm_chmod;
|
|
|
|
static fo_chown_t shm_chown;
|
2013-08-21 17:45:00 +00:00
|
|
|
static fo_seek_t shm_seek;
|
2014-09-22 16:20:47 +00:00
|
|
|
static fo_fill_kinfo_t shm_fill_kinfo;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
static fo_mmap_t shm_mmap;
|
2019-09-25 17:32:43 +00:00
|
|
|
static fo_get_seals_t shm_get_seals;
|
|
|
|
static fo_add_seals_t shm_add_seals;
|
2020-01-08 19:08:44 +00:00
|
|
|
static fo_fallocate_t shm_fallocate;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
|
|
|
/* File descriptor operations. */
|
2016-02-28 17:52:33 +00:00
|
|
|
struct fileops shm_ops = {
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
.fo_read = shm_read,
|
|
|
|
.fo_write = shm_write,
|
|
|
|
.fo_truncate = shm_truncate,
|
2019-02-28 22:00:36 +00:00
|
|
|
.fo_ioctl = shm_ioctl,
|
2014-09-12 21:29:10 +00:00
|
|
|
.fo_poll = invfo_poll,
|
|
|
|
.fo_kqfilter = invfo_kqfilter,
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
.fo_stat = shm_stat,
|
|
|
|
.fo_close = shm_close,
|
2011-08-16 20:07:47 +00:00
|
|
|
.fo_chmod = shm_chmod,
|
|
|
|
.fo_chown = shm_chown,
|
2013-09-11 06:41:15 +00:00
|
|
|
.fo_sendfile = vn_sendfile,
|
2013-08-21 17:45:00 +00:00
|
|
|
.fo_seek = shm_seek,
|
2014-09-22 16:20:47 +00:00
|
|
|
.fo_fill_kinfo = shm_fill_kinfo,
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
.fo_mmap = shm_mmap,
|
2019-09-25 17:32:43 +00:00
|
|
|
.fo_get_seals = shm_get_seals,
|
|
|
|
.fo_add_seals = shm_add_seals,
|
2020-01-08 19:08:44 +00:00
|
|
|
.fo_fallocate = shm_fallocate,
|
2020-09-09 22:12:51 +00:00
|
|
|
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE,
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
FEATURE(posix_shm, "POSIX shared memory");
|
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
static SYSCTL_NODE(_vm, OID_AUTO, largepages, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
|
|
|
|
"");
|
|
|
|
|
|
|
|
static int largepage_reclaim_tries = 1;
|
|
|
|
SYSCTL_INT(_vm_largepages, OID_AUTO, reclaim_tries,
|
|
|
|
CTLFLAG_RWTUN, &largepage_reclaim_tries, 0,
|
|
|
|
"Number of contig reclaims before giving up for default alloc policy");
|
|
|
|
|
2013-08-21 17:23:24 +00:00
|
|
|
static int
|
|
|
|
uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio)
|
|
|
|
{
|
|
|
|
vm_page_t m;
|
|
|
|
vm_pindex_t idx;
|
|
|
|
size_t tlen;
|
|
|
|
int error, offset, rv;
|
|
|
|
|
|
|
|
idx = OFF_TO_IDX(uio->uio_offset);
|
|
|
|
offset = uio->uio_offset & PAGE_MASK;
|
|
|
|
tlen = MIN(PAGE_SIZE - offset, len);
|
|
|
|
|
2020-02-28 20:33:28 +00:00
|
|
|
rv = vm_page_grab_valid_unlocked(&m, obj, idx,
|
|
|
|
VM_ALLOC_SBUSY | VM_ALLOC_IGN_SBUSY | VM_ALLOC_NOCREAT);
|
|
|
|
if (rv == VM_PAGER_OK)
|
|
|
|
goto found;
|
2013-08-21 17:23:24 +00:00
|
|
|
|
2015-04-11 18:51:41 +00:00
|
|
|
/*
|
|
|
|
* Read I/O without either a corresponding resident page or swap
|
|
|
|
* page: use zero_region. This is intended to avoid instantiating
|
|
|
|
* pages on read from a sparse region.
|
|
|
|
*/
|
2020-02-28 20:33:28 +00:00
|
|
|
VM_OBJECT_WLOCK(obj);
|
|
|
|
m = vm_page_lookup(obj, idx);
|
|
|
|
if (uio->uio_rw == UIO_READ && m == NULL &&
|
2015-04-11 18:51:41 +00:00
|
|
|
!vm_pager_has_page(obj, idx, NULL, NULL)) {
|
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
2015-04-24 22:05:12 +00:00
|
|
|
return (uiomove(__DECONST(void *, zero_region), tlen, uio));
|
2015-04-11 18:51:41 +00:00
|
|
|
}
|
|
|
|
|
2013-08-21 17:23:24 +00:00
|
|
|
/*
|
|
|
|
* Although the tmpfs vnode lock is held here, it is
|
|
|
|
* nonetheless safe to sleep waiting for a free page. The
|
|
|
|
* pageout daemon does not need to acquire the tmpfs vnode
|
|
|
|
* lock to page out tobj's pages because tobj is a OBJT_SWAP
|
|
|
|
* type object.
|
|
|
|
*/
|
2019-09-10 19:08:01 +00:00
|
|
|
rv = vm_page_grab_valid(&m, obj, idx,
|
2019-12-15 03:15:06 +00:00
|
|
|
VM_ALLOC_NORMAL | VM_ALLOC_SBUSY | VM_ALLOC_IGN_SBUSY);
|
2019-09-10 19:08:01 +00:00
|
|
|
if (rv != VM_PAGER_OK) {
|
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
|
|
|
printf("uiomove_object: vm_obj %p idx %jd pager error %d\n",
|
|
|
|
obj, idx, rv);
|
|
|
|
return (EIO);
|
2013-08-21 17:23:24 +00:00
|
|
|
}
|
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
2020-02-28 20:33:28 +00:00
|
|
|
|
|
|
|
found:
|
2013-08-21 17:23:24 +00:00
|
|
|
error = uiomove_fromphys(&m, offset, tlen, uio);
|
2019-12-15 03:15:06 +00:00
|
|
|
if (uio->uio_rw == UIO_WRITE && error == 0)
|
|
|
|
vm_page_set_dirty(m);
|
2019-12-15 06:26:47 +00:00
|
|
|
vm_page_activate(m);
|
2019-12-15 03:15:06 +00:00
|
|
|
vm_page_sunbusy(m);
|
2013-08-21 17:23:24 +00:00
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
uiomove_object(vm_object_t obj, off_t obj_size, struct uio *uio)
|
|
|
|
{
|
|
|
|
ssize_t resid;
|
|
|
|
size_t len;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = 0;
|
|
|
|
while ((resid = uio->uio_resid) > 0) {
|
|
|
|
if (obj_size <= uio->uio_offset)
|
|
|
|
break;
|
|
|
|
len = MIN(obj_size - uio->uio_offset, resid);
|
|
|
|
if (len == 0)
|
|
|
|
break;
|
|
|
|
error = uiomove_object_page(obj, len, uio);
|
|
|
|
if (error != 0 || resid == uio->uio_resid)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
static u_long count_largepages[MAXPAGESIZES];
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_largepage_phys_populate(vm_object_t object, vm_pindex_t pidx,
|
|
|
|
int fault_type, vm_prot_t max_prot, vm_pindex_t *first, vm_pindex_t *last)
|
|
|
|
{
|
|
|
|
vm_page_t m;
|
|
|
|
int psind;
|
|
|
|
|
|
|
|
psind = object->un_pager.phys.data_val;
|
|
|
|
if (psind == 0 || pidx >= object->size)
|
|
|
|
return (VM_PAGER_FAIL);
|
|
|
|
*first = rounddown2(pidx, pagesizes[psind] / PAGE_SIZE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We only busy the first page in the superpage run. It is
|
|
|
|
* useless to busy whole run since we only remove full
|
|
|
|
* superpage, and it takes too long to busy e.g. 512 * 512 ==
|
|
|
|
* 262144 pages constituing 1G amd64 superage.
|
|
|
|
*/
|
|
|
|
m = vm_page_grab(object, *first, VM_ALLOC_NORMAL | VM_ALLOC_NOCREAT);
|
|
|
|
MPASS(m != NULL);
|
|
|
|
|
|
|
|
*last = *first + atop(pagesizes[psind]) - 1;
|
|
|
|
return (VM_PAGER_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
static boolean_t
|
|
|
|
shm_largepage_phys_haspage(vm_object_t object, vm_pindex_t pindex,
|
|
|
|
int *before, int *after)
|
|
|
|
{
|
|
|
|
int psind;
|
|
|
|
|
|
|
|
psind = object->un_pager.phys.data_val;
|
|
|
|
if (psind == 0 || pindex >= object->size)
|
|
|
|
return (FALSE);
|
|
|
|
if (before != NULL) {
|
|
|
|
*before = pindex - rounddown2(pindex, pagesizes[psind] /
|
|
|
|
PAGE_SIZE);
|
|
|
|
}
|
|
|
|
if (after != NULL) {
|
|
|
|
*after = roundup2(pindex, pagesizes[psind] / PAGE_SIZE) -
|
|
|
|
pindex;
|
|
|
|
}
|
|
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shm_largepage_phys_ctor(vm_object_t object, vm_prot_t prot,
|
|
|
|
vm_ooffset_t foff, struct ucred *cred)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shm_largepage_phys_dtor(vm_object_t object)
|
|
|
|
{
|
|
|
|
int psind;
|
|
|
|
|
|
|
|
psind = object->un_pager.phys.data_val;
|
|
|
|
if (psind != 0) {
|
|
|
|
atomic_subtract_long(&count_largepages[psind],
|
|
|
|
object->size / (pagesizes[psind] / PAGE_SIZE));
|
|
|
|
vm_wire_sub(object->size);
|
|
|
|
} else {
|
|
|
|
KASSERT(object->size == 0,
|
|
|
|
("largepage phys obj %p not initialized bit size %#jx > 0",
|
|
|
|
object, (uintmax_t)object->size));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct phys_pager_ops shm_largepage_phys_ops = {
|
|
|
|
.phys_pg_populate = shm_largepage_phys_populate,
|
|
|
|
.phys_pg_haspage = shm_largepage_phys_haspage,
|
|
|
|
.phys_pg_ctor = shm_largepage_phys_ctor,
|
|
|
|
.phys_pg_dtor = shm_largepage_phys_dtor,
|
|
|
|
};
|
|
|
|
|
|
|
|
bool
|
|
|
|
shm_largepage(struct shmfd *shmfd)
|
|
|
|
{
|
|
|
|
return (shmfd->shm_object->type == OBJT_PHYS);
|
|
|
|
}
|
|
|
|
|
2013-08-21 17:45:00 +00:00
|
|
|
static int
|
|
|
|
shm_seek(struct file *fp, off_t offset, int whence, struct thread *td)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
off_t foffset;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
foffset = foffset_lock(fp, 0);
|
|
|
|
error = 0;
|
|
|
|
switch (whence) {
|
|
|
|
case L_INCR:
|
|
|
|
if (foffset < 0 ||
|
|
|
|
(offset > 0 && foffset > OFF_MAX - offset)) {
|
|
|
|
error = EOVERFLOW;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
offset += foffset;
|
|
|
|
break;
|
|
|
|
case L_XTND:
|
|
|
|
if (offset > 0 && shmfd->shm_size > OFF_MAX - offset) {
|
|
|
|
error = EOVERFLOW;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
offset += shmfd->shm_size;
|
|
|
|
break;
|
|
|
|
case L_SET:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error = EINVAL;
|
|
|
|
}
|
|
|
|
if (error == 0) {
|
|
|
|
if (offset < 0 || offset > shmfd->shm_size)
|
|
|
|
error = EINVAL;
|
|
|
|
else
|
2014-03-16 00:53:40 +00:00
|
|
|
td->td_uretoff.tdu_off = offset;
|
2013-08-21 17:45:00 +00:00
|
|
|
}
|
|
|
|
foffset_unlock(fp, offset, error != 0 ? FOF_NOUPDATE : 0);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
static int
|
|
|
|
shm_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
|
|
|
int flags, struct thread *td)
|
|
|
|
{
|
2013-08-21 17:45:00 +00:00
|
|
|
struct shmfd *shmfd;
|
|
|
|
void *rl_cookie;
|
|
|
|
int error;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2013-08-21 17:45:00 +00:00
|
|
|
shmfd = fp->f_data;
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_read(active_cred, fp->f_cred, shmfd);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
#endif
|
2016-06-23 20:59:13 +00:00
|
|
|
foffset_lock_uio(fp, uio, flags);
|
|
|
|
rl_cookie = rangelock_rlock(&shmfd->shm_rl, uio->uio_offset,
|
|
|
|
uio->uio_offset + uio->uio_resid, &shmfd->shm_mtx);
|
2013-08-21 17:45:00 +00:00
|
|
|
error = uiomove_object(shmfd->shm_object, shmfd->shm_size, uio);
|
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
|
|
|
foffset_unlock_uio(fp, uio, flags);
|
|
|
|
return (error);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
|
|
|
|
int flags, struct thread *td)
|
|
|
|
{
|
2013-08-21 17:45:00 +00:00
|
|
|
struct shmfd *shmfd;
|
|
|
|
void *rl_cookie;
|
|
|
|
int error;
|
2020-07-10 00:43:45 +00:00
|
|
|
off_t size;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2013-08-21 17:45:00 +00:00
|
|
|
shmfd = fp->f_data;
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_write(active_cred, fp->f_cred, shmfd);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
#endif
|
2020-09-09 22:12:51 +00:00
|
|
|
if (shm_largepage(shmfd) && shmfd->shm_lp_psind == 0)
|
|
|
|
return (EINVAL);
|
2013-08-21 17:45:00 +00:00
|
|
|
foffset_lock_uio(fp, uio, flags);
|
2020-07-10 00:43:45 +00:00
|
|
|
if (uio->uio_resid > OFF_MAX - uio->uio_offset) {
|
|
|
|
/*
|
|
|
|
* Overflow is only an error if we're supposed to expand on
|
|
|
|
* write. Otherwise, we'll just truncate the write to the
|
|
|
|
* size of the file, which can only grow up to OFF_MAX.
|
|
|
|
*/
|
|
|
|
if ((shmfd->shm_flags & SHM_GROW_ON_WRITE) != 0) {
|
|
|
|
foffset_unlock_uio(fp, uio, flags);
|
|
|
|
return (EFBIG);
|
|
|
|
}
|
|
|
|
|
|
|
|
size = shmfd->shm_size;
|
|
|
|
} else {
|
|
|
|
size = uio->uio_offset + uio->uio_resid;
|
|
|
|
}
|
2013-08-21 17:45:00 +00:00
|
|
|
if ((flags & FOF_OFFSET) == 0) {
|
|
|
|
rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX,
|
|
|
|
&shmfd->shm_mtx);
|
|
|
|
} else {
|
|
|
|
rl_cookie = rangelock_wlock(&shmfd->shm_rl, uio->uio_offset,
|
2020-07-10 00:43:45 +00:00
|
|
|
size, &shmfd->shm_mtx);
|
2013-08-21 17:45:00 +00:00
|
|
|
}
|
2020-07-10 00:43:45 +00:00
|
|
|
if ((shmfd->shm_seals & F_SEAL_WRITE) != 0) {
|
2019-09-25 17:32:43 +00:00
|
|
|
error = EPERM;
|
2020-07-10 00:43:45 +00:00
|
|
|
} else {
|
|
|
|
error = 0;
|
|
|
|
if ((shmfd->shm_flags & SHM_GROW_ON_WRITE) != 0 &&
|
|
|
|
size > shmfd->shm_size) {
|
2020-09-10 20:54:44 +00:00
|
|
|
error = shm_dotruncate_cookie(shmfd, size, rl_cookie);
|
2020-07-10 00:43:45 +00:00
|
|
|
}
|
|
|
|
if (error == 0)
|
|
|
|
error = uiomove_object(shmfd->shm_object,
|
|
|
|
shmfd->shm_size, uio);
|
|
|
|
}
|
2013-08-21 17:45:00 +00:00
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
|
|
|
foffset_unlock_uio(fp, uio, flags);
|
|
|
|
return (error);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_truncate(struct file *fp, off_t length, struct ucred *active_cred,
|
|
|
|
struct thread *td)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
#ifdef MAC
|
|
|
|
int error;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_truncate(active_cred, fp->f_cred, shmfd);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
#endif
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
return (shm_dotruncate(shmfd, length));
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
|
2019-02-28 22:00:36 +00:00
|
|
|
int
|
|
|
|
shm_ioctl(struct file *fp, u_long com, void *data, struct ucred *active_cred,
|
|
|
|
struct thread *td)
|
|
|
|
{
|
2020-09-09 22:12:51 +00:00
|
|
|
struct shmfd *shmfd;
|
|
|
|
struct shm_largepage_conf *conf;
|
|
|
|
void *rl_cookie;
|
2019-02-28 22:00:36 +00:00
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
shmfd = fp->f_data;
|
2019-02-28 22:00:36 +00:00
|
|
|
switch (com) {
|
|
|
|
case FIONBIO:
|
|
|
|
case FIOASYNC:
|
|
|
|
/*
|
|
|
|
* Allow fcntl(fd, F_SETFL, O_NONBLOCK) to work,
|
|
|
|
* just like it would on an unlinked regular file
|
|
|
|
*/
|
|
|
|
return (0);
|
2020-09-09 22:12:51 +00:00
|
|
|
case FIOSSHMLPGCNF:
|
|
|
|
if (!shm_largepage(shmfd))
|
|
|
|
return (ENOTTY);
|
|
|
|
conf = data;
|
|
|
|
if (shmfd->shm_lp_psind != 0 &&
|
|
|
|
conf->psind != shmfd->shm_lp_psind)
|
|
|
|
return (EINVAL);
|
|
|
|
if (conf->psind <= 0 || conf->psind >= MAXPAGESIZES ||
|
|
|
|
pagesizes[conf->psind] == 0)
|
|
|
|
return (EINVAL);
|
|
|
|
if (conf->alloc_policy != SHM_LARGEPAGE_ALLOC_DEFAULT &&
|
|
|
|
conf->alloc_policy != SHM_LARGEPAGE_ALLOC_NOWAIT &&
|
|
|
|
conf->alloc_policy != SHM_LARGEPAGE_ALLOC_HARD)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX,
|
|
|
|
&shmfd->shm_mtx);
|
|
|
|
shmfd->shm_lp_psind = conf->psind;
|
|
|
|
shmfd->shm_lp_alloc_policy = conf->alloc_policy;
|
|
|
|
shmfd->shm_object->un_pager.phys.data_val = conf->psind;
|
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
|
|
|
return (0);
|
|
|
|
case FIOGSHMLPGCNF:
|
|
|
|
if (!shm_largepage(shmfd))
|
|
|
|
return (ENOTTY);
|
|
|
|
conf = data;
|
|
|
|
rl_cookie = rangelock_rlock(&shmfd->shm_rl, 0, OFF_MAX,
|
|
|
|
&shmfd->shm_mtx);
|
|
|
|
conf->psind = shmfd->shm_lp_psind;
|
|
|
|
conf->alloc_policy = shmfd->shm_lp_alloc_policy;
|
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
|
|
|
return (0);
|
2019-02-28 22:00:36 +00:00
|
|
|
default:
|
|
|
|
return (ENOTTY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
static int
|
|
|
|
shm_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
|
|
|
|
struct thread *td)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
#ifdef MAC
|
|
|
|
int error;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_stat(active_cred, fp->f_cred, shmfd);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
#endif
|
2020-09-01 22:12:32 +00:00
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
/*
|
|
|
|
* Attempt to return sanish values for fstat() on a memory file
|
|
|
|
* descriptor.
|
|
|
|
*/
|
|
|
|
bzero(sb, sizeof(*sb));
|
|
|
|
sb->st_blksize = PAGE_SIZE;
|
|
|
|
sb->st_size = shmfd->shm_size;
|
2016-04-26 15:38:17 +00:00
|
|
|
sb->st_blocks = howmany(sb->st_size, sb->st_blksize);
|
2011-08-16 20:07:47 +00:00
|
|
|
mtx_lock(&shm_timestamp_lock);
|
2010-03-28 13:13:22 +00:00
|
|
|
sb->st_atim = shmfd->shm_atime;
|
|
|
|
sb->st_ctim = shmfd->shm_ctime;
|
|
|
|
sb->st_mtim = shmfd->shm_mtime;
|
2011-08-16 20:07:47 +00:00
|
|
|
sb->st_birthtim = shmfd->shm_birthtime;
|
|
|
|
sb->st_mode = S_IFREG | shmfd->shm_mode; /* XXX */
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
sb->st_uid = shmfd->shm_uid;
|
|
|
|
sb->st_gid = shmfd->shm_gid;
|
2011-08-16 20:07:47 +00:00
|
|
|
mtx_unlock(&shm_timestamp_lock);
|
2014-08-29 18:18:29 +00:00
|
|
|
sb->st_dev = shm_dev_ino;
|
|
|
|
sb->st_ino = shmfd->shm_ino;
|
2019-05-23 12:27:45 +00:00
|
|
|
sb->st_nlink = shmfd->shm_object->ref_count;
|
2020-09-09 22:12:51 +00:00
|
|
|
sb->st_blocks = shmfd->shm_object->size /
|
|
|
|
(pagesizes[shmfd->shm_lp_psind] >> PAGE_SHIFT);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_close(struct file *fp, struct thread *td)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
fp->f_data = NULL;
|
|
|
|
shm_drop(shmfd);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2019-11-18 13:31:16 +00:00
|
|
|
static int
|
|
|
|
shm_copyin_path(struct thread *td, const char *userpath_in, char **path_out) {
|
|
|
|
int error;
|
|
|
|
char *path;
|
|
|
|
const char *pr_path;
|
|
|
|
size_t pr_pathlen;
|
|
|
|
|
|
|
|
path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK);
|
|
|
|
pr_path = td->td_ucred->cr_prison->pr_path;
|
|
|
|
|
|
|
|
/* Construct a full pathname for jailed callers. */
|
|
|
|
pr_pathlen = strcmp(pr_path, "/") ==
|
|
|
|
0 ? 0 : strlcpy(path, pr_path, MAXPATHLEN);
|
|
|
|
error = copyinstr(userpath_in, path + pr_pathlen,
|
|
|
|
MAXPATHLEN - pr_pathlen, NULL);
|
|
|
|
if (error != 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
#ifdef KTRACE
|
|
|
|
if (KTRPOINT(curthread, KTR_NAMEI))
|
|
|
|
ktrnamei(path);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Require paths to start with a '/' character. */
|
|
|
|
if (path[pr_pathlen] != '/') {
|
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
*path_out = path;
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (error != 0)
|
|
|
|
free(path, M_SHMFD);
|
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2019-09-25 17:32:43 +00:00
|
|
|
static int
|
|
|
|
shm_dotruncate_locked(struct shmfd *shmfd, off_t length, void *rl_cookie)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
{
|
|
|
|
vm_object_t object;
|
2015-06-12 11:32:20 +00:00
|
|
|
vm_page_t m;
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
vm_pindex_t idx, nobjsize;
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
vm_ooffset_t delta;
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
int base, rv;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2017-03-20 05:15:55 +00:00
|
|
|
KASSERT(length >= 0, ("shm_dotruncate: length < 0"));
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
object = shmfd->shm_object;
|
2019-09-25 17:32:43 +00:00
|
|
|
VM_OBJECT_ASSERT_WLOCKED(object);
|
|
|
|
rangelock_cookie_assert(rl_cookie, RA_WLOCKED);
|
|
|
|
if (length == shmfd->shm_size)
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
return (0);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
nobjsize = OFF_TO_IDX(length + PAGE_MASK);
|
|
|
|
|
|
|
|
/* Are we shrinking? If so, trim the end. */
|
|
|
|
if (length < shmfd->shm_size) {
|
2019-09-25 17:32:43 +00:00
|
|
|
if ((shmfd->shm_seals & F_SEAL_SHRINK) != 0)
|
|
|
|
return (EPERM);
|
|
|
|
|
2011-12-14 22:22:19 +00:00
|
|
|
/*
|
|
|
|
* Disallow any requests to shrink the size if this
|
|
|
|
* object is mapped into the kernel.
|
|
|
|
*/
|
2019-09-25 17:32:43 +00:00
|
|
|
if (shmfd->shm_kmappings > 0)
|
2011-12-14 22:22:19 +00:00
|
|
|
return (EBUSY);
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Zero the truncated part of the last page.
|
|
|
|
*/
|
|
|
|
base = length & PAGE_MASK;
|
|
|
|
if (base != 0) {
|
|
|
|
idx = OFF_TO_IDX(length);
|
|
|
|
retry:
|
2019-10-15 03:35:11 +00:00
|
|
|
m = vm_page_grab(object, idx, VM_ALLOC_NOCREAT);
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
if (m != NULL) {
|
2019-10-15 03:45:41 +00:00
|
|
|
MPASS(vm_page_all_valid(m));
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
} else if (vm_pager_has_page(object, idx, NULL, NULL)) {
|
2017-11-08 02:39:37 +00:00
|
|
|
m = vm_page_alloc(object, idx,
|
|
|
|
VM_ALLOC_NORMAL | VM_ALLOC_WAITFAIL);
|
|
|
|
if (m == NULL)
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
goto retry;
|
2020-01-19 23:47:32 +00:00
|
|
|
vm_object_pip_add(object, 1);
|
|
|
|
VM_OBJECT_WUNLOCK(object);
|
2016-11-15 18:22:50 +00:00
|
|
|
rv = vm_pager_get_pages(object, &m, 1, NULL,
|
|
|
|
NULL);
|
2020-01-19 23:47:32 +00:00
|
|
|
VM_OBJECT_WLOCK(object);
|
|
|
|
vm_object_pip_wakeup(object);
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
if (rv == VM_PAGER_OK) {
|
2016-12-11 19:24:41 +00:00
|
|
|
/*
|
|
|
|
* Since the page was not resident,
|
|
|
|
* and therefore not recently
|
|
|
|
* accessed, immediately enqueue it
|
|
|
|
* for asynchronous laundering. The
|
|
|
|
* current operation is not regarded
|
|
|
|
* as an access.
|
|
|
|
*/
|
|
|
|
vm_page_launder(m);
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
} else {
|
|
|
|
vm_page_free(m);
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(object);
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
return (EIO);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m != NULL) {
|
|
|
|
pmap_zero_page_area(m, base, PAGE_SIZE - base);
|
2019-10-15 03:45:41 +00:00
|
|
|
KASSERT(vm_page_all_valid(m),
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
("shm_dotruncate: page %p is invalid", m));
|
2019-12-15 03:15:06 +00:00
|
|
|
vm_page_set_dirty(m);
|
2019-10-15 03:35:11 +00:00
|
|
|
vm_page_xunbusy(m);
|
Correct an error of omission in the implementation of the truncation
operation on POSIX shared memory objects and tmpfs. Previously, neither of
these modules correctly handled the case in which the new size of the object
or file was not a multiple of the page size. Specifically, they did not
handle partial page truncation of data stored on swap. As a result, stale
data might later be returned to an application.
Interestingly, a data inconsistency was less likely to occur under tmpfs
than POSIX shared memory objects. The reason being that a different mistake
by the tmpfs truncation operation helped avoid a data inconsistency. If the
data was still resident in memory in a PG_CACHED page, then the tmpfs
truncation operation would reactivate that page, zero the truncated portion,
and leave the page pinned in memory. More precisely, the benevolent error
was that the truncation operation didn't add the reactivated page to any of
the paging queues, effectively pinning the page. This page would remain
pinned until the file was destroyed or the page was read or written. With
this change, the page is now added to the inactive queue.
Discussed with: jhb
Reviewed by: kib (an earlier version)
MFC after: 3 weeks
2012-01-08 20:09:26 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-20 05:15:55 +00:00
|
|
|
delta = IDX_TO_OFF(object->size - nobjsize);
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
if (nobjsize < object->size)
|
|
|
|
vm_object_page_remove(object, nobjsize, object->size,
|
2011-06-29 16:40:41 +00:00
|
|
|
0);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
/* Free the swap accounted for shm */
|
2010-12-02 17:37:16 +00:00
|
|
|
swap_release_by_cred(delta, object->cred);
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
object->charge -= delta;
|
|
|
|
} else {
|
2019-09-25 17:32:43 +00:00
|
|
|
if ((shmfd->shm_seals & F_SEAL_GROW) != 0)
|
|
|
|
return (EPERM);
|
|
|
|
|
2017-03-20 05:15:55 +00:00
|
|
|
/* Try to reserve additional swap space. */
|
|
|
|
delta = IDX_TO_OFF(nobjsize - object->size);
|
2019-09-25 17:32:43 +00:00
|
|
|
if (!swap_reserve_by_cred(delta, object->cred))
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
return (ENOMEM);
|
|
|
|
object->charge += delta;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
shmfd->shm_size = length;
|
|
|
|
mtx_lock(&shm_timestamp_lock);
|
|
|
|
vfs_timestamp(&shmfd->shm_ctime);
|
|
|
|
shmfd->shm_mtime = shmfd->shm_ctime;
|
|
|
|
mtx_unlock(&shm_timestamp_lock);
|
|
|
|
object->size = nobjsize;
|
Implement global and per-uid accounting of the anonymous memory. Add
rlimit RLIMIT_SWAP that limits the amount of swap that may be reserved
for the uid.
The accounting information (charge) is associated with either map entry,
or vm object backing the entry, assuming the object is the first one
in the shadow chain and entry does not require COW. Charge is moved
from entry to object on allocation of the object, e.g. during the mmap,
assuming the object is allocated, or on the first page fault on the
entry. It moves back to the entry on forks due to COW setup.
The per-entry granularity of accounting makes the charge process fair
for processes that change uid during lifetime, and decrements charge
for proper uid when region is unmapped.
The interface of vm_pager_allocate(9) is extended by adding struct ucred *,
that is used to charge appropriate uid when allocation if performed by
kernel, e.g. md(4).
Several syscalls, among them is fork(2), may now return ENOMEM when
global or per-uid limits are enforced.
In collaboration with: pho
Reviewed by: alc
Approved by: re (kensmith)
2009-06-23 20:45:22 +00:00
|
|
|
return (0);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
static int
|
|
|
|
shm_dotruncate_largepage(struct shmfd *shmfd, off_t length, void *rl_cookie)
|
|
|
|
{
|
|
|
|
vm_object_t object;
|
|
|
|
vm_page_t m;
|
|
|
|
vm_pindex_t newobjsz, oldobjsz;
|
|
|
|
int aflags, error, i, psind, try;
|
|
|
|
|
|
|
|
KASSERT(length >= 0, ("shm_dotruncate: length < 0"));
|
|
|
|
object = shmfd->shm_object;
|
|
|
|
VM_OBJECT_ASSERT_WLOCKED(object);
|
|
|
|
rangelock_cookie_assert(rl_cookie, RA_WLOCKED);
|
|
|
|
|
|
|
|
oldobjsz = object->size;
|
|
|
|
newobjsz = OFF_TO_IDX(length);
|
|
|
|
if (length == shmfd->shm_size)
|
|
|
|
return (0);
|
|
|
|
psind = shmfd->shm_lp_psind;
|
|
|
|
if (psind == 0 && length != 0)
|
|
|
|
return (EINVAL);
|
|
|
|
if ((length & (pagesizes[psind] - 1)) != 0)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
if (length < shmfd->shm_size) {
|
|
|
|
if ((shmfd->shm_seals & F_SEAL_SHRINK) != 0)
|
|
|
|
return (EPERM);
|
|
|
|
if (shmfd->shm_kmappings > 0)
|
|
|
|
return (EBUSY);
|
|
|
|
return (ENOTSUP); /* Pages are unmanaged. */
|
|
|
|
#if 0
|
|
|
|
vm_object_page_remove(object, newobjsz, oldobjsz, 0);
|
|
|
|
object->size = newobjsz;
|
|
|
|
shmfd->shm_size = length;
|
|
|
|
return (0);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-09-10 20:54:44 +00:00
|
|
|
if ((shmfd->shm_seals & F_SEAL_GROW) != 0)
|
|
|
|
return (EPERM);
|
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO;
|
|
|
|
if (shmfd->shm_lp_alloc_policy == SHM_LARGEPAGE_ALLOC_NOWAIT)
|
|
|
|
aflags |= VM_ALLOC_WAITFAIL;
|
|
|
|
try = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Extend shmfd and object, keeping all already fully
|
|
|
|
* allocated large pages intact even on error, because dropped
|
|
|
|
* object lock might allowed mapping of them.
|
|
|
|
*/
|
|
|
|
while (object->size < newobjsz) {
|
|
|
|
m = vm_page_alloc_contig(object, object->size, aflags,
|
|
|
|
pagesizes[psind] / PAGE_SIZE, 0, ~0,
|
|
|
|
pagesizes[psind], 0,
|
|
|
|
VM_MEMATTR_DEFAULT);
|
|
|
|
if (m == NULL) {
|
|
|
|
VM_OBJECT_WUNLOCK(object);
|
|
|
|
if (shmfd->shm_lp_alloc_policy ==
|
|
|
|
SHM_LARGEPAGE_ALLOC_NOWAIT ||
|
|
|
|
(shmfd->shm_lp_alloc_policy ==
|
|
|
|
SHM_LARGEPAGE_ALLOC_DEFAULT &&
|
|
|
|
try >= largepage_reclaim_tries)) {
|
|
|
|
VM_OBJECT_WLOCK(object);
|
|
|
|
return (ENOMEM);
|
|
|
|
}
|
|
|
|
error = vm_page_reclaim_contig(aflags,
|
|
|
|
pagesizes[psind] / PAGE_SIZE, 0, ~0,
|
|
|
|
pagesizes[psind], 0) ? 0 :
|
|
|
|
vm_wait_intr(object);
|
|
|
|
if (error != 0) {
|
|
|
|
VM_OBJECT_WLOCK(object);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
try++;
|
|
|
|
VM_OBJECT_WLOCK(object);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
try = 0;
|
|
|
|
for (i = 0; i < pagesizes[psind] / PAGE_SIZE; i++) {
|
|
|
|
if ((m[i].flags & PG_ZERO) == 0)
|
|
|
|
pmap_zero_page(&m[i]);
|
|
|
|
vm_page_valid(&m[i]);
|
|
|
|
vm_page_xunbusy(&m[i]);
|
|
|
|
}
|
|
|
|
object->size += OFF_TO_IDX(pagesizes[psind]);
|
|
|
|
shmfd->shm_size += pagesizes[psind];
|
|
|
|
atomic_add_long(&count_largepages[psind], 1);
|
|
|
|
vm_wire_add(atop(pagesizes[psind]));
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_dotruncate_cookie(struct shmfd *shmfd, off_t length, void *rl_cookie)
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
|
|
|
VM_OBJECT_WLOCK(shmfd->shm_object);
|
|
|
|
error = shm_largepage(shmfd) ? shm_dotruncate_largepage(shmfd,
|
|
|
|
length, rl_cookie) : shm_dotruncate_locked(shmfd, length,
|
|
|
|
rl_cookie);
|
|
|
|
VM_OBJECT_WUNLOCK(shmfd->shm_object);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2019-09-25 17:32:43 +00:00
|
|
|
int
|
|
|
|
shm_dotruncate(struct shmfd *shmfd, off_t length)
|
|
|
|
{
|
|
|
|
void *rl_cookie;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX,
|
|
|
|
&shmfd->shm_mtx);
|
2020-09-09 22:12:51 +00:00
|
|
|
error = shm_dotruncate_cookie(shmfd, length, rl_cookie);
|
2019-09-25 17:32:43 +00:00
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
/*
|
|
|
|
* shmfd object management including creation and reference counting
|
|
|
|
* routines.
|
|
|
|
*/
|
2016-02-28 17:52:33 +00:00
|
|
|
struct shmfd *
|
2020-09-09 22:12:51 +00:00
|
|
|
shm_alloc(struct ucred *ucred, mode_t mode, bool largepage)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
|
|
|
|
shmfd = malloc(sizeof(*shmfd), M_SHMFD, M_WAITOK | M_ZERO);
|
|
|
|
shmfd->shm_size = 0;
|
|
|
|
shmfd->shm_uid = ucred->cr_uid;
|
|
|
|
shmfd->shm_gid = ucred->cr_gid;
|
|
|
|
shmfd->shm_mode = mode;
|
2020-09-09 22:12:51 +00:00
|
|
|
if (largepage) {
|
|
|
|
shmfd->shm_object = phys_pager_allocate(NULL,
|
|
|
|
&shm_largepage_phys_ops, NULL, shmfd->shm_size,
|
|
|
|
VM_PROT_DEFAULT, 0, ucred);
|
|
|
|
shmfd->shm_lp_alloc_policy = SHM_LARGEPAGE_ALLOC_DEFAULT;
|
|
|
|
} else {
|
|
|
|
shmfd->shm_object = vm_pager_allocate(OBJT_SWAP, NULL,
|
|
|
|
shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred);
|
|
|
|
}
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate"));
|
|
|
|
vfs_timestamp(&shmfd->shm_birthtime);
|
|
|
|
shmfd->shm_atime = shmfd->shm_mtime = shmfd->shm_ctime =
|
|
|
|
shmfd->shm_birthtime;
|
2018-11-21 22:01:06 +00:00
|
|
|
shmfd->shm_ino = alloc_unr64(&shm_ino_unr);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
refcount_init(&shmfd->shm_refs, 1);
|
2013-08-21 17:45:00 +00:00
|
|
|
mtx_init(&shmfd->shm_mtx, "shmrl", NULL, MTX_DEF);
|
|
|
|
rangelock_init(&shmfd->shm_rl);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#ifdef MAC
|
|
|
|
mac_posixshm_init(shmfd);
|
|
|
|
mac_posixshm_create(ucred, shmfd);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return (shmfd);
|
|
|
|
}
|
|
|
|
|
2016-02-28 17:52:33 +00:00
|
|
|
struct shmfd *
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
shm_hold(struct shmfd *shmfd)
|
|
|
|
{
|
|
|
|
|
|
|
|
refcount_acquire(&shmfd->shm_refs);
|
|
|
|
return (shmfd);
|
|
|
|
}
|
|
|
|
|
2016-02-28 17:52:33 +00:00
|
|
|
void
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
shm_drop(struct shmfd *shmfd)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (refcount_release(&shmfd->shm_refs)) {
|
|
|
|
#ifdef MAC
|
|
|
|
mac_posixshm_destroy(shmfd);
|
|
|
|
#endif
|
2013-08-21 17:45:00 +00:00
|
|
|
rangelock_destroy(&shmfd->shm_rl);
|
|
|
|
mtx_destroy(&shmfd->shm_mtx);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
vm_object_deallocate(shmfd->shm_object);
|
|
|
|
free(shmfd, M_SHMFD);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine if the credentials have sufficient permissions for a
|
|
|
|
* specified combination of FREAD and FWRITE.
|
|
|
|
*/
|
2016-02-28 17:52:33 +00:00
|
|
|
int
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
shm_access(struct shmfd *shmfd, struct ucred *ucred, int flags)
|
|
|
|
{
|
2008-10-28 13:44:11 +00:00
|
|
|
accmode_t accmode;
|
2011-08-16 20:07:47 +00:00
|
|
|
int error;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2008-10-28 13:44:11 +00:00
|
|
|
accmode = 0;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
if (flags & FREAD)
|
2008-10-28 13:44:11 +00:00
|
|
|
accmode |= VREAD;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
if (flags & FWRITE)
|
2008-10-28 13:44:11 +00:00
|
|
|
accmode |= VWRITE;
|
2011-08-16 20:07:47 +00:00
|
|
|
mtx_lock(&shm_timestamp_lock);
|
|
|
|
error = vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid, shmfd->shm_gid,
|
2020-08-05 09:27:03 +00:00
|
|
|
accmode, ucred);
|
2011-08-16 20:07:47 +00:00
|
|
|
mtx_unlock(&shm_timestamp_lock);
|
|
|
|
return (error);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-08-29 18:18:29 +00:00
|
|
|
shm_init(void *arg)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
{
|
2020-09-09 22:12:51 +00:00
|
|
|
char name[32];
|
|
|
|
int i;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
|
|
|
mtx_init(&shm_timestamp_lock, "shm timestamps", NULL, MTX_DEF);
|
|
|
|
sx_init(&shm_dict_lock, "shm dictionary");
|
|
|
|
shm_dictionary = hashinit(1024, M_SHMFD, &shm_hash);
|
2018-11-21 22:01:06 +00:00
|
|
|
new_unrhdr64(&shm_ino_unr, 1);
|
2014-08-29 18:18:29 +00:00
|
|
|
shm_dev_ino = devfs_alloc_cdp_inode();
|
|
|
|
KASSERT(shm_dev_ino > 0, ("shm dev inode not initialized"));
|
2020-09-09 22:12:51 +00:00
|
|
|
|
|
|
|
for (i = 1; i < MAXPAGESIZES; i++) {
|
|
|
|
if (pagesizes[i] == 0)
|
|
|
|
break;
|
|
|
|
#define M (1024 * 1024)
|
|
|
|
#define G (1024 * M)
|
|
|
|
if (pagesizes[i] >= G)
|
|
|
|
snprintf(name, sizeof(name), "%luG", pagesizes[i] / G);
|
|
|
|
else if (pagesizes[i] >= M)
|
|
|
|
snprintf(name, sizeof(name), "%luM", pagesizes[i] / M);
|
|
|
|
else
|
|
|
|
snprintf(name, sizeof(name), "%lu", pagesizes[i]);
|
|
|
|
#undef G
|
|
|
|
#undef M
|
|
|
|
SYSCTL_ADD_ULONG(NULL, SYSCTL_STATIC_CHILDREN(_vm_largepages),
|
|
|
|
OID_AUTO, name, CTLFLAG_RD, &count_largepages[i],
|
|
|
|
"number of non-transient largepages allocated");
|
|
|
|
}
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
2014-08-29 18:18:29 +00:00
|
|
|
SYSINIT(shm_init, SI_SUB_SYSV_SHM, SI_ORDER_ANY, shm_init, NULL);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2020-09-09 21:00:11 +00:00
|
|
|
/*
|
|
|
|
* Dictionary management. We maintain an in-kernel dictionary to map
|
|
|
|
* paths to shmfd objects. We use the FNV hash on the path to store
|
|
|
|
* the mappings in a hash table.
|
|
|
|
*/
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
static struct shmfd *
|
|
|
|
shm_lookup(char *path, Fnv32_t fnv)
|
|
|
|
{
|
|
|
|
struct shm_mapping *map;
|
|
|
|
|
|
|
|
LIST_FOREACH(map, SHM_HASH(fnv), sm_link) {
|
|
|
|
if (map->sm_fnv != fnv)
|
|
|
|
continue;
|
|
|
|
if (strcmp(map->sm_path, path) == 0)
|
|
|
|
return (map->sm_shmfd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd)
|
|
|
|
{
|
|
|
|
struct shm_mapping *map;
|
|
|
|
|
|
|
|
map = malloc(sizeof(struct shm_mapping), M_SHMFD, M_WAITOK);
|
|
|
|
map->sm_path = path;
|
|
|
|
map->sm_fnv = fnv;
|
|
|
|
map->sm_shmfd = shm_hold(shmfd);
|
2012-04-01 18:22:48 +00:00
|
|
|
shmfd->shm_path = path;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
LIST_INSERT_HEAD(SHM_HASH(fnv), map, sm_link);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
|
|
|
|
{
|
|
|
|
struct shm_mapping *map;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
LIST_FOREACH(map, SHM_HASH(fnv), sm_link) {
|
|
|
|
if (map->sm_fnv != fnv)
|
|
|
|
continue;
|
|
|
|
if (strcmp(map->sm_path, path) == 0) {
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_unlink(ucred, map->sm_shmfd);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
#endif
|
|
|
|
error = shm_access(map->sm_shmfd, ucred,
|
|
|
|
FREAD | FWRITE);
|
|
|
|
if (error)
|
|
|
|
return (error);
|
2012-04-01 18:22:48 +00:00
|
|
|
map->sm_shmfd->shm_path = NULL;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
LIST_REMOVE(map, sm_link);
|
|
|
|
shm_drop(map->sm_shmfd);
|
|
|
|
free(map->sm_path, M_SHMFD);
|
|
|
|
free(map, M_SHMFD);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (ENOENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2020-01-05 04:06:40 +00:00
|
|
|
kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode,
|
|
|
|
int shmflags, struct filecaps *fcaps, const char *name __unused)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
{
|
2020-11-17 21:14:13 +00:00
|
|
|
struct pwddesc *pdp;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
struct shmfd *shmfd;
|
|
|
|
struct file *fp;
|
|
|
|
char *path;
|
2019-09-25 17:35:03 +00:00
|
|
|
void *rl_cookie;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
Fnv32_t fnv;
|
|
|
|
mode_t cmode;
|
2020-01-05 04:06:40 +00:00
|
|
|
int error, fd, initial_seals;
|
2020-09-09 22:12:51 +00:00
|
|
|
bool largepage;
|
2020-01-05 04:06:40 +00:00
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
if ((shmflags & ~(SHM_ALLOW_SEALING | SHM_GROW_ON_WRITE |
|
|
|
|
SHM_LARGEPAGE)) != 0)
|
2020-01-05 04:06:40 +00:00
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
initial_seals = F_SEAL_SEAL;
|
|
|
|
if ((shmflags & SHM_ALLOW_SEALING) != 0)
|
|
|
|
initial_seals &= ~F_SEAL_SEAL;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2011-06-30 10:56:02 +00:00
|
|
|
#ifdef CAPABILITY_MODE
|
|
|
|
/*
|
|
|
|
* shm_open(2) is only allowed for anonymous objects.
|
|
|
|
*/
|
2015-08-01 07:21:14 +00:00
|
|
|
if (IN_CAPABILITY_MODE(td) && (userpath != SHM_ANON))
|
2011-06-30 10:56:02 +00:00
|
|
|
return (ECAPMODE);
|
|
|
|
#endif
|
|
|
|
|
2017-03-31 13:43:00 +00:00
|
|
|
AUDIT_ARG_FFLAGS(flags);
|
|
|
|
AUDIT_ARG_MODE(mode);
|
|
|
|
|
2015-08-01 07:21:14 +00:00
|
|
|
if ((flags & O_ACCMODE) != O_RDONLY && (flags & O_ACCMODE) != O_RDWR)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
return (EINVAL);
|
|
|
|
|
2015-08-01 07:21:14 +00:00
|
|
|
if ((flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)) != 0)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
return (EINVAL);
|
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
largepage = (shmflags & SHM_LARGEPAGE) != 0;
|
2020-09-23 19:34:21 +00:00
|
|
|
if (largepage && !PMAP_HAS_LARGEPAGES)
|
2020-09-09 22:12:51 +00:00
|
|
|
return (ENOTTY);
|
|
|
|
|
2019-09-25 17:35:03 +00:00
|
|
|
/*
|
|
|
|
* Currently only F_SEAL_SEAL may be set when creating or opening shmfd.
|
|
|
|
* If the decision is made later to allow additional seals, care must be
|
|
|
|
* taken below to ensure that the seals are properly set if the shmfd
|
|
|
|
* already existed -- this currently assumes that only F_SEAL_SEAL can
|
|
|
|
* be set and doesn't take further precautions to ensure the validity of
|
|
|
|
* the seals being added with respect to current mappings.
|
|
|
|
*/
|
|
|
|
if ((initial_seals & ~F_SEAL_SEAL) != 0)
|
|
|
|
return (EINVAL);
|
|
|
|
|
2020-11-17 21:14:13 +00:00
|
|
|
pdp = td->td_proc->p_pd;
|
|
|
|
cmode = (mode & ~pdp->pd_cmask) & ACCESSPERMS;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2019-07-31 15:16:51 +00:00
|
|
|
/*
|
|
|
|
* shm_open(2) created shm should always have O_CLOEXEC set, as mandated
|
|
|
|
* by POSIX. We allow it to be unset here so that an in-kernel
|
|
|
|
* interface may be written as a thin layer around shm, optionally not
|
|
|
|
* setting CLOEXEC. For shm_open(2), O_CLOEXEC is set unconditionally
|
|
|
|
* in sys_shm_open() to keep this implementation compliant.
|
|
|
|
*/
|
|
|
|
error = falloc_caps(td, &fp, &fd, flags & O_CLOEXEC, fcaps);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
/* A SHM_ANON path pointer creates an anonymous object. */
|
2015-08-01 07:21:14 +00:00
|
|
|
if (userpath == SHM_ANON) {
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
/* A read-only anonymous object is pointless. */
|
2015-08-01 07:21:14 +00:00
|
|
|
if ((flags & O_ACCMODE) == O_RDONLY) {
|
2015-04-11 15:40:28 +00:00
|
|
|
fdclose(td, fp, fd);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
fdrop(fp, td);
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
2020-09-09 22:12:51 +00:00
|
|
|
shmfd = shm_alloc(td->td_ucred, cmode, largepage);
|
2019-09-25 17:35:03 +00:00
|
|
|
shmfd->shm_seals = initial_seals;
|
2020-08-31 15:07:15 +00:00
|
|
|
shmfd->shm_flags = shmflags;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
} else {
|
2019-11-18 13:31:16 +00:00
|
|
|
error = shm_copyin_path(td, userpath, &path);
|
|
|
|
if (error != 0) {
|
2015-04-11 15:40:28 +00:00
|
|
|
fdclose(td, fp, fd);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
fdrop(fp, td);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2017-03-31 13:43:00 +00:00
|
|
|
AUDIT_ARG_UPATH1_CANON(path);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
fnv = fnv_32_str(path, FNV1_32_INIT);
|
|
|
|
sx_xlock(&shm_dict_lock);
|
|
|
|
shmfd = shm_lookup(path, fnv);
|
|
|
|
if (shmfd == NULL) {
|
|
|
|
/* Object does not yet exist, create it if requested. */
|
2015-08-01 07:21:14 +00:00
|
|
|
if (flags & O_CREAT) {
|
2011-09-02 17:40:39 +00:00
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_create(td->td_ucred,
|
|
|
|
path);
|
|
|
|
if (error == 0) {
|
|
|
|
#endif
|
2020-09-09 22:12:51 +00:00
|
|
|
shmfd = shm_alloc(td->td_ucred, cmode,
|
|
|
|
largepage);
|
2019-09-25 17:35:03 +00:00
|
|
|
shmfd->shm_seals = initial_seals;
|
2020-08-31 15:07:15 +00:00
|
|
|
shmfd->shm_flags = shmflags;
|
2011-09-02 17:40:39 +00:00
|
|
|
shm_insert(path, fnv, shmfd);
|
|
|
|
#ifdef MAC
|
|
|
|
}
|
|
|
|
#endif
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
} else {
|
|
|
|
free(path, M_SHMFD);
|
|
|
|
error = ENOENT;
|
|
|
|
}
|
|
|
|
} else {
|
2019-09-25 17:35:03 +00:00
|
|
|
rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX,
|
|
|
|
&shmfd->shm_mtx);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* kern_shm_open() likely shouldn't ever error out on
|
|
|
|
* trying to set a seal that already exists, unlike
|
|
|
|
* F_ADD_SEALS. This would break terribly as
|
|
|
|
* shm_open(2) actually sets F_SEAL_SEAL to maintain
|
|
|
|
* historical behavior where the underlying file could
|
|
|
|
* not be sealed.
|
|
|
|
*/
|
|
|
|
initial_seals &= ~shmfd->shm_seals;
|
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
/*
|
|
|
|
* Object already exists, obtain a new
|
|
|
|
* reference if requested and permitted.
|
|
|
|
*/
|
|
|
|
free(path, M_SHMFD);
|
2019-09-25 17:35:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* initial_seals can't set additional seals if we've
|
|
|
|
* already been set F_SEAL_SEAL. If F_SEAL_SEAL is set,
|
|
|
|
* then we've already removed that one from
|
|
|
|
* initial_seals. This is currently redundant as we
|
|
|
|
* only allow setting F_SEAL_SEAL at creation time, but
|
|
|
|
* it's cheap to check and decreases the effort required
|
|
|
|
* to allow additional seals.
|
|
|
|
*/
|
|
|
|
if ((shmfd->shm_seals & F_SEAL_SEAL) != 0 &&
|
|
|
|
initial_seals != 0)
|
|
|
|
error = EPERM;
|
|
|
|
else if ((flags & (O_CREAT | O_EXCL)) ==
|
|
|
|
(O_CREAT | O_EXCL))
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
error = EEXIST;
|
2020-08-31 15:07:15 +00:00
|
|
|
else if (shmflags != 0 && shmflags != shmfd->shm_flags)
|
|
|
|
error = EINVAL;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
else {
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_open(td->td_ucred,
|
2015-08-01 07:21:14 +00:00
|
|
|
shmfd, FFLAGS(flags & O_ACCMODE));
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
if (error == 0)
|
|
|
|
#endif
|
|
|
|
error = shm_access(shmfd, td->td_ucred,
|
2015-08-01 07:21:14 +00:00
|
|
|
FFLAGS(flags & O_ACCMODE));
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Truncate the file back to zero length if
|
|
|
|
* O_TRUNC was specified and the object was
|
|
|
|
* opened with read/write.
|
|
|
|
*/
|
|
|
|
if (error == 0 &&
|
2015-08-01 07:21:14 +00:00
|
|
|
(flags & (O_ACCMODE | O_TRUNC)) ==
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
(O_RDWR | O_TRUNC)) {
|
2019-09-25 17:35:03 +00:00
|
|
|
VM_OBJECT_WLOCK(shmfd->shm_object);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_truncate(
|
|
|
|
td->td_ucred, fp->f_cred, shmfd);
|
|
|
|
if (error == 0)
|
|
|
|
#endif
|
2019-09-25 17:35:03 +00:00
|
|
|
error = shm_dotruncate_locked(shmfd, 0,
|
|
|
|
rl_cookie);
|
|
|
|
VM_OBJECT_WUNLOCK(shmfd->shm_object);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
2019-09-25 17:35:03 +00:00
|
|
|
if (error == 0) {
|
|
|
|
/*
|
|
|
|
* Currently we only allow F_SEAL_SEAL to be
|
|
|
|
* set initially. As noted above, this would
|
|
|
|
* need to be reworked should that change.
|
|
|
|
*/
|
|
|
|
shmfd->shm_seals |= initial_seals;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
shm_hold(shmfd);
|
2019-09-25 17:35:03 +00:00
|
|
|
}
|
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie,
|
|
|
|
&shmfd->shm_mtx);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
|
|
|
sx_xunlock(&shm_dict_lock);
|
|
|
|
|
|
|
|
if (error) {
|
2015-04-11 15:40:28 +00:00
|
|
|
fdclose(td, fp, fd);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
fdrop(fp, td);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-01 07:21:14 +00:00
|
|
|
finit(fp, FFLAGS(flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
|
|
|
td->td_retval[0] = fd;
|
|
|
|
fdrop(fp, td);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2015-08-01 07:21:14 +00:00
|
|
|
/* System calls. */
|
2019-09-25 18:09:19 +00:00
|
|
|
#ifdef COMPAT_FREEBSD12
|
2015-08-01 07:21:14 +00:00
|
|
|
int
|
2019-09-25 18:09:19 +00:00
|
|
|
freebsd12_shm_open(struct thread *td, struct freebsd12_shm_open_args *uap)
|
2015-08-01 07:21:14 +00:00
|
|
|
{
|
|
|
|
|
2020-01-05 04:06:40 +00:00
|
|
|
return (kern_shm_open(td, uap->path, uap->flags | O_CLOEXEC,
|
|
|
|
uap->mode, NULL));
|
2015-08-01 07:21:14 +00:00
|
|
|
}
|
2019-09-25 18:09:19 +00:00
|
|
|
#endif
|
2015-08-01 07:21:14 +00:00
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
int
|
2011-09-16 13:58:51 +00:00
|
|
|
sys_shm_unlink(struct thread *td, struct shm_unlink_args *uap)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
{
|
|
|
|
char *path;
|
|
|
|
Fnv32_t fnv;
|
|
|
|
int error;
|
|
|
|
|
2019-11-18 13:31:16 +00:00
|
|
|
error = shm_copyin_path(td, uap->path, &path);
|
|
|
|
if (error != 0)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
return (error);
|
2019-11-18 13:31:16 +00:00
|
|
|
|
2017-03-31 13:43:00 +00:00
|
|
|
AUDIT_ARG_UPATH1_CANON(path);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
fnv = fnv_32_str(path, FNV1_32_INIT);
|
|
|
|
sx_xlock(&shm_dict_lock);
|
|
|
|
error = shm_remove(path, fnv, td->td_ucred);
|
|
|
|
sx_xunlock(&shm_dict_lock);
|
2020-03-03 00:28:37 +00:00
|
|
|
free(path, M_SHMFD);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2019-09-26 15:32:28 +00:00
|
|
|
int
|
|
|
|
sys_shm_rename(struct thread *td, struct shm_rename_args *uap)
|
|
|
|
{
|
|
|
|
char *path_from = NULL, *path_to = NULL;
|
|
|
|
Fnv32_t fnv_from, fnv_to;
|
|
|
|
struct shmfd *fd_from;
|
|
|
|
struct shmfd *fd_to;
|
|
|
|
int error;
|
|
|
|
int flags;
|
|
|
|
|
|
|
|
flags = uap->flags;
|
2019-11-18 13:31:16 +00:00
|
|
|
AUDIT_ARG_FFLAGS(flags);
|
2019-09-26 15:32:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure the user passed only valid flags.
|
|
|
|
* If you add a new flag, please add a new term here.
|
|
|
|
*/
|
|
|
|
if ((flags & ~(
|
|
|
|
SHM_RENAME_NOREPLACE |
|
|
|
|
SHM_RENAME_EXCHANGE
|
|
|
|
)) != 0) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* EXCHANGE and NOREPLACE don't quite make sense together. Let's
|
|
|
|
* force the user to choose one or the other.
|
|
|
|
*/
|
|
|
|
if ((flags & SHM_RENAME_NOREPLACE) != 0 &&
|
|
|
|
(flags & SHM_RENAME_EXCHANGE) != 0) {
|
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2019-11-18 13:31:16 +00:00
|
|
|
/* Renaming to or from anonymous makes no sense */
|
|
|
|
if (uap->path_from == SHM_ANON || uap->path_to == SHM_ANON) {
|
|
|
|
error = EINVAL;
|
2019-09-26 15:32:28 +00:00
|
|
|
goto out;
|
2019-11-18 13:31:16 +00:00
|
|
|
}
|
2019-09-26 15:32:28 +00:00
|
|
|
|
2019-11-18 13:31:16 +00:00
|
|
|
error = shm_copyin_path(td, uap->path_from, &path_from);
|
|
|
|
if (error != 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
error = shm_copyin_path(td, uap->path_to, &path_to);
|
|
|
|
if (error != 0)
|
2019-09-26 15:32:28 +00:00
|
|
|
goto out;
|
|
|
|
|
2019-11-18 13:31:16 +00:00
|
|
|
AUDIT_ARG_UPATH1_CANON(path_from);
|
|
|
|
AUDIT_ARG_UPATH2_CANON(path_to);
|
|
|
|
|
2019-09-26 15:32:28 +00:00
|
|
|
/* Rename with from/to equal is a no-op */
|
2019-11-18 13:31:16 +00:00
|
|
|
if (strcmp(path_from, path_to) == 0)
|
2019-09-26 15:32:28 +00:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
fnv_from = fnv_32_str(path_from, FNV1_32_INIT);
|
|
|
|
fnv_to = fnv_32_str(path_to, FNV1_32_INIT);
|
|
|
|
|
|
|
|
sx_xlock(&shm_dict_lock);
|
|
|
|
|
|
|
|
fd_from = shm_lookup(path_from, fnv_from);
|
|
|
|
if (fd_from == NULL) {
|
|
|
|
error = ENOENT;
|
2019-11-18 13:31:16 +00:00
|
|
|
goto out_locked;
|
2019-09-26 15:32:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fd_to = shm_lookup(path_to, fnv_to);
|
|
|
|
if ((flags & SHM_RENAME_NOREPLACE) != 0 && fd_to != NULL) {
|
|
|
|
error = EEXIST;
|
2019-11-18 13:31:16 +00:00
|
|
|
goto out_locked;
|
2019-09-26 15:32:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unconditionally prevents shm_remove from invalidating the 'from'
|
|
|
|
* shm's state.
|
|
|
|
*/
|
|
|
|
shm_hold(fd_from);
|
|
|
|
error = shm_remove(path_from, fnv_from, td->td_ucred);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* One of my assumptions failed if ENOENT (e.g. locking didn't
|
|
|
|
* protect us)
|
|
|
|
*/
|
|
|
|
KASSERT(error != ENOENT, ("Our shm disappeared during shm_rename: %s",
|
|
|
|
path_from));
|
2019-11-18 13:31:16 +00:00
|
|
|
if (error != 0) {
|
2019-09-26 15:32:28 +00:00
|
|
|
shm_drop(fd_from);
|
2019-11-18 13:31:16 +00:00
|
|
|
goto out_locked;
|
2019-09-26 15:32:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we are exchanging, we need to ensure the shm_remove below
|
|
|
|
* doesn't invalidate the dest shm's state.
|
|
|
|
*/
|
|
|
|
if ((flags & SHM_RENAME_EXCHANGE) != 0 && fd_to != NULL)
|
|
|
|
shm_hold(fd_to);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE: if path_to is not already in the hash, c'est la vie;
|
|
|
|
* it simply means we have nothing already at path_to to unlink.
|
|
|
|
* That is the ENOENT case.
|
|
|
|
*
|
|
|
|
* If we somehow don't have access to unlink this guy, but
|
|
|
|
* did for the shm at path_from, then relink the shm to path_from
|
|
|
|
* and abort with EACCES.
|
|
|
|
*
|
|
|
|
* All other errors: that is weird; let's relink and abort the
|
|
|
|
* operation.
|
|
|
|
*/
|
|
|
|
error = shm_remove(path_to, fnv_to, td->td_ucred);
|
2019-11-18 13:31:16 +00:00
|
|
|
if (error != 0 && error != ENOENT) {
|
2019-09-26 15:32:28 +00:00
|
|
|
shm_insert(path_from, fnv_from, fd_from);
|
|
|
|
shm_drop(fd_from);
|
|
|
|
/* Don't free path_from now, since the hash references it */
|
|
|
|
path_from = NULL;
|
2019-11-18 13:31:16 +00:00
|
|
|
goto out_locked;
|
2019-09-26 15:32:28 +00:00
|
|
|
}
|
|
|
|
|
2019-11-18 13:31:16 +00:00
|
|
|
error = 0;
|
|
|
|
|
2019-09-26 15:32:28 +00:00
|
|
|
shm_insert(path_to, fnv_to, fd_from);
|
|
|
|
|
|
|
|
/* Don't free path_to now, since the hash references it */
|
|
|
|
path_to = NULL;
|
|
|
|
|
|
|
|
/* We kept a ref when we removed, and incremented again in insert */
|
|
|
|
shm_drop(fd_from);
|
|
|
|
KASSERT(fd_from->shm_refs > 0, ("Expected >0 refs; got: %d\n",
|
|
|
|
fd_from->shm_refs));
|
|
|
|
|
|
|
|
if ((flags & SHM_RENAME_EXCHANGE) != 0 && fd_to != NULL) {
|
|
|
|
shm_insert(path_from, fnv_from, fd_to);
|
|
|
|
path_from = NULL;
|
|
|
|
shm_drop(fd_to);
|
|
|
|
KASSERT(fd_to->shm_refs > 0, ("Expected >0 refs; got: %d\n",
|
|
|
|
fd_to->shm_refs));
|
|
|
|
}
|
|
|
|
|
2019-11-18 13:31:16 +00:00
|
|
|
out_locked:
|
2019-09-26 15:32:28 +00:00
|
|
|
sx_xunlock(&shm_dict_lock);
|
|
|
|
|
|
|
|
out:
|
2019-11-18 13:31:16 +00:00
|
|
|
free(path_from, M_SHMFD);
|
|
|
|
free(path_to, M_SHMFD);
|
|
|
|
return (error);
|
2019-09-26 15:32:28 +00:00
|
|
|
}
|
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
static int
|
|
|
|
shm_mmap_large(struct shmfd *shmfd, vm_map_t map, vm_offset_t *addr,
|
|
|
|
vm_size_t size, vm_prot_t prot, vm_prot_t max_prot, int flags,
|
2020-09-10 20:54:44 +00:00
|
|
|
vm_ooffset_t foff, struct thread *td)
|
2020-09-09 22:12:51 +00:00
|
|
|
{
|
|
|
|
struct vmspace *vms;
|
|
|
|
vm_map_entry_t next_entry, prev_entry;
|
|
|
|
vm_offset_t align, mask, maxaddr;
|
|
|
|
int docow, error, rv, try;
|
|
|
|
bool curmap;
|
|
|
|
|
|
|
|
if (shmfd->shm_lp_psind == 0)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
/* MAP_PRIVATE is disabled */
|
|
|
|
if ((flags & ~(MAP_SHARED | MAP_FIXED | MAP_EXCL |
|
|
|
|
MAP_NOCORE |
|
|
|
|
#ifdef MAP_32BIT
|
|
|
|
MAP_32BIT |
|
|
|
|
#endif
|
|
|
|
MAP_ALIGNMENT_MASK)) != 0)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
vms = td->td_proc->p_vmspace;
|
|
|
|
curmap = map == &vms->vm_map;
|
|
|
|
if (curmap) {
|
|
|
|
error = kern_mmap_racct_check(td, map, size);
|
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
docow = shmfd->shm_lp_psind << MAP_SPLIT_BOUNDARY_SHIFT;
|
|
|
|
docow |= MAP_INHERIT_SHARE;
|
|
|
|
if ((flags & MAP_NOCORE) != 0)
|
|
|
|
docow |= MAP_DISABLE_COREDUMP;
|
|
|
|
|
|
|
|
mask = pagesizes[shmfd->shm_lp_psind] - 1;
|
|
|
|
if ((foff & mask) != 0)
|
|
|
|
return (EINVAL);
|
|
|
|
maxaddr = vm_map_max(map);
|
|
|
|
#ifdef MAP_32BIT
|
|
|
|
if ((flags & MAP_32BIT) != 0 && maxaddr > MAP_32BIT_MAX_ADDR)
|
|
|
|
maxaddr = MAP_32BIT_MAX_ADDR;
|
|
|
|
#endif
|
|
|
|
if (size == 0 || (size & mask) != 0 ||
|
|
|
|
(*addr != 0 && ((*addr & mask) != 0 ||
|
|
|
|
*addr + size < *addr || *addr + size > maxaddr)))
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
align = flags & MAP_ALIGNMENT_MASK;
|
|
|
|
if (align == 0) {
|
|
|
|
align = pagesizes[shmfd->shm_lp_psind];
|
|
|
|
} else if (align == MAP_ALIGNED_SUPER) {
|
|
|
|
if (shmfd->shm_lp_psind != 1)
|
|
|
|
return (EINVAL);
|
|
|
|
align = pagesizes[1];
|
|
|
|
} else {
|
|
|
|
align >>= MAP_ALIGNMENT_SHIFT;
|
|
|
|
align = 1ULL << align;
|
|
|
|
/* Also handles overflow. */
|
|
|
|
if (align < pagesizes[shmfd->shm_lp_psind])
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
vm_map_lock(map);
|
|
|
|
if ((flags & MAP_FIXED) == 0) {
|
|
|
|
try = 1;
|
|
|
|
if (curmap && (*addr == 0 ||
|
|
|
|
(*addr >= round_page((vm_offset_t)vms->vm_taddr) &&
|
|
|
|
*addr < round_page((vm_offset_t)vms->vm_daddr +
|
|
|
|
lim_max(td, RLIMIT_DATA))))) {
|
|
|
|
*addr = roundup2((vm_offset_t)vms->vm_daddr +
|
|
|
|
lim_max(td, RLIMIT_DATA),
|
|
|
|
pagesizes[shmfd->shm_lp_psind]);
|
|
|
|
}
|
|
|
|
again:
|
|
|
|
rv = vm_map_find_aligned(map, addr, size, maxaddr, align);
|
|
|
|
if (rv != KERN_SUCCESS) {
|
|
|
|
if (try == 1) {
|
|
|
|
try = 2;
|
|
|
|
*addr = vm_map_min(map);
|
|
|
|
if ((*addr & mask) != 0)
|
|
|
|
*addr = (*addr + mask) & mask;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
goto fail1;
|
|
|
|
}
|
|
|
|
} else if ((flags & MAP_EXCL) == 0) {
|
|
|
|
rv = vm_map_delete(map, *addr, *addr + size);
|
|
|
|
if (rv != KERN_SUCCESS)
|
|
|
|
goto fail1;
|
|
|
|
} else {
|
|
|
|
error = ENOSPC;
|
|
|
|
if (vm_map_lookup_entry(map, *addr, &prev_entry))
|
|
|
|
goto fail;
|
|
|
|
next_entry = vm_map_entry_succ(prev_entry);
|
|
|
|
if (next_entry->start < *addr + size)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = vm_map_insert(map, shmfd->shm_object, foff, *addr, *addr + size,
|
|
|
|
prot, max_prot, docow);
|
|
|
|
fail1:
|
|
|
|
error = vm_mmap_to_errno(rv);
|
|
|
|
fail:
|
|
|
|
vm_map_unlock(map);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t objsize,
|
|
|
|
vm_prot_t prot, vm_prot_t cap_maxprot, int flags,
|
|
|
|
vm_ooffset_t foff, struct thread *td)
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
{
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
struct shmfd *shmfd;
|
|
|
|
vm_prot_t maxprot;
|
|
|
|
int error;
|
2019-09-03 20:33:38 +00:00
|
|
|
bool writecnt;
|
2019-09-25 17:32:43 +00:00
|
|
|
void *rl_cookie;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
maxprot = VM_PROT_NONE;
|
|
|
|
|
2019-09-25 17:32:43 +00:00
|
|
|
rl_cookie = rangelock_rlock(&shmfd->shm_rl, 0, objsize,
|
|
|
|
&shmfd->shm_mtx);
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
/* FREAD should always be set. */
|
|
|
|
if ((fp->f_flag & FREAD) != 0)
|
|
|
|
maxprot |= VM_PROT_EXECUTE | VM_PROT_READ;
|
2020-01-05 03:15:16 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If FWRITE's set, we can allow VM_PROT_WRITE unless it's a shared
|
2020-04-13 19:20:39 +00:00
|
|
|
* mapping with a write seal applied. Private mappings are always
|
|
|
|
* writeable.
|
2020-01-05 03:15:16 +00:00
|
|
|
*/
|
2020-04-13 19:20:39 +00:00
|
|
|
if ((flags & MAP_SHARED) == 0) {
|
|
|
|
cap_maxprot |= VM_PROT_WRITE;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
maxprot |= VM_PROT_WRITE;
|
2020-04-13 19:20:39 +00:00
|
|
|
writecnt = false;
|
|
|
|
} else {
|
|
|
|
if ((fp->f_flag & FWRITE) != 0 &&
|
|
|
|
(shmfd->shm_seals & F_SEAL_WRITE) == 0)
|
|
|
|
maxprot |= VM_PROT_WRITE;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
|
2020-04-14 13:32:03 +00:00
|
|
|
/*
|
|
|
|
* Any mappings from a writable descriptor may be upgraded to
|
|
|
|
* VM_PROT_WRITE with mprotect(2), unless a write-seal was
|
|
|
|
* applied between the open and subsequent mmap(2). We want to
|
|
|
|
* reject application of a write seal as long as any such
|
|
|
|
* mapping exists so that the seal cannot be trivially bypassed.
|
|
|
|
*/
|
|
|
|
writecnt = (maxprot & VM_PROT_WRITE) != 0;
|
|
|
|
if (!writecnt && (prot & VM_PROT_WRITE) != 0) {
|
2020-04-13 19:20:39 +00:00
|
|
|
error = EACCES;
|
|
|
|
goto out;
|
|
|
|
}
|
2019-09-25 17:32:43 +00:00
|
|
|
}
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
maxprot &= cap_maxprot;
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
|
2017-02-12 21:05:44 +00:00
|
|
|
/* See comment in vn_mmap(). */
|
|
|
|
if (
|
|
|
|
#ifdef _LP64
|
|
|
|
objsize > OFF_MAX ||
|
|
|
|
#endif
|
2020-09-18 16:48:08 +00:00
|
|
|
foff > OFF_MAX - objsize) {
|
2019-09-25 17:32:43 +00:00
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
2017-02-12 21:05:44 +00:00
|
|
|
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, flags);
|
|
|
|
if (error != 0)
|
2019-09-25 17:32:43 +00:00
|
|
|
goto out;
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
#endif
|
2020-09-01 22:12:32 +00:00
|
|
|
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
mtx_lock(&shm_timestamp_lock);
|
|
|
|
vfs_timestamp(&shmfd->shm_atime);
|
|
|
|
mtx_unlock(&shm_timestamp_lock);
|
|
|
|
vm_object_reference(shmfd->shm_object);
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
|
2020-09-09 22:12:51 +00:00
|
|
|
if (shm_largepage(shmfd)) {
|
2020-09-10 20:54:44 +00:00
|
|
|
writecnt = false;
|
2020-09-09 22:12:51 +00:00
|
|
|
error = shm_mmap_large(shmfd, map, addr, objsize, prot,
|
2020-09-10 20:54:44 +00:00
|
|
|
maxprot, flags, foff, td);
|
2020-09-09 22:12:51 +00:00
|
|
|
} else {
|
2020-09-10 20:54:44 +00:00
|
|
|
if (writecnt) {
|
|
|
|
vm_pager_update_writecount(shmfd->shm_object, 0,
|
|
|
|
objsize);
|
|
|
|
}
|
2020-09-09 22:12:51 +00:00
|
|
|
error = vm_mmap_object(map, addr, objsize, prot, maxprot, flags,
|
|
|
|
shmfd->shm_object, foff, writecnt, td);
|
|
|
|
}
|
2019-09-03 20:33:38 +00:00
|
|
|
if (error != 0) {
|
|
|
|
if (writecnt)
|
|
|
|
vm_pager_release_writecount(shmfd->shm_object, 0,
|
|
|
|
objsize);
|
Add a new file operations hook for mmap operations. File type-specific
logic is now placed in the mmap hook implementation rather than requiring
it to be placed in sys/vm/vm_mmap.c. This hook allows new file types to
support mmap() as well as potentially allowing mmap() for existing file
types that do not currently support any mapping.
The vm_mmap() function is now split up into two functions. A new
vm_mmap_object() function handles the "back half" of vm_mmap() and accepts
a referenced VM object to map rather than a (handle, handle_type) tuple.
vm_mmap() is now reduced to converting a (handle, handle_type) tuple to a
a VM object and then calling vm_mmap_object() to handle the actual mapping.
The vm_mmap() function remains for use by other parts of the kernel
(e.g. device drivers and exec) but now only supports mapping vnodes,
character devices, and anonymous memory.
The mmap() system call invokes vm_mmap_object() directly with a NULL object
for anonymous mappings. For mappings using a file descriptor, the
descriptors fo_mmap() hook is invoked instead. The fo_mmap() hook is
responsible for performing type-specific checks and adjustments to
arguments as well as possibly modifying mapping parameters such as flags
or the object offset. The fo_mmap() hook routines then call
vm_mmap_object() to handle the actual mapping.
The fo_mmap() hook is optional. If it is not set, then fo_mmap() will
fail with ENODEV. A fo_mmap() hook is implemented for regular files,
character devices, and shared memory objects (created via shm_open()).
While here, consistently use the VM_PROT_* constants for the vm_prot_t
type for the 'prot' variable passed to vm_mmap() and vm_mmap_object()
as well as the vm_mmap_vnode() and vm_mmap_cdev() helper routines.
Previously some places were using the mmap()-specific PROT_* constants
instead. While this happens to work because PROT_xx == VM_PROT_xx,
using VM_PROT_* is more correct.
Differential Revision: https://reviews.freebsd.org/D2658
Reviewed by: alc (glanced over), kib
MFC after: 1 month
Sponsored by: Chelsio
2015-06-04 19:41:15 +00:00
|
|
|
vm_object_deallocate(shmfd->shm_object);
|
2019-09-03 20:33:38 +00:00
|
|
|
}
|
2019-09-25 17:32:43 +00:00
|
|
|
out:
|
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
2017-06-27 20:12:13 +00:00
|
|
|
return (error);
|
Add a new file descriptor type for IPC shared memory objects and use it to
implement shm_open(2) and shm_unlink(2) in the kernel:
- Each shared memory file descriptor is associated with a swap-backed vm
object which provides the backing store. Each descriptor starts off with
a size of zero, but the size can be altered via ftruncate(2). The shared
memory file descriptors also support fstat(2). read(2), write(2),
ioctl(2), select(2), poll(2), and kevent(2) are not supported on shared
memory file descriptors.
- shm_open(2) and shm_unlink(2) are now implemented as system calls that
manage shared memory file descriptors. The virtual namespace that maps
pathnames to shared memory file descriptors is implemented as a hash
table where the hash key is generated via the 32-bit Fowler/Noll/Vo hash
of the pathname.
- As an extension, the constant 'SHM_ANON' may be specified in place of the
path argument to shm_open(2). In this case, an unnamed shared memory
file descriptor will be created similar to the IPC_PRIVATE key for
shmget(2). Note that the shared memory object can still be shared among
processes by sharing the file descriptor via fork(2) or sendmsg(2), but
it is unnamed. This effectively serves to implement the getmemfd() idea
bandied about the lists several times over the years.
- The backing store for shared memory file descriptors are garbage
collected when they are not referenced by any open file descriptors or
the shm_open(2) virtual namespace.
Submitted by: dillon, peter (previous versions)
Submitted by: rwatson (I based this on his version)
Reviewed by: alc (suggested converting getmemfd() to shm_open())
2008-01-08 21:58:16 +00:00
|
|
|
}
|
2011-08-16 20:07:47 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
shm_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
|
|
|
|
struct thread *td)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = 0;
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
mtx_lock(&shm_timestamp_lock);
|
|
|
|
/*
|
|
|
|
* SUSv4 says that x bits of permission need not be affected.
|
|
|
|
* Be consistent with our shm_open there.
|
|
|
|
*/
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_setmode(active_cred, shmfd, mode);
|
|
|
|
if (error != 0)
|
|
|
|
goto out;
|
|
|
|
#endif
|
2020-08-05 09:27:03 +00:00
|
|
|
error = vaccess(VREG, shmfd->shm_mode, shmfd->shm_uid, shmfd->shm_gid,
|
|
|
|
VADMIN, active_cred);
|
2011-08-16 20:07:47 +00:00
|
|
|
if (error != 0)
|
|
|
|
goto out;
|
|
|
|
shmfd->shm_mode = mode & ACCESSPERMS;
|
|
|
|
out:
|
|
|
|
mtx_unlock(&shm_timestamp_lock);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
|
|
|
|
struct thread *td)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
int error;
|
|
|
|
|
2011-08-17 12:37:14 +00:00
|
|
|
error = 0;
|
2011-08-16 20:07:47 +00:00
|
|
|
shmfd = fp->f_data;
|
|
|
|
mtx_lock(&shm_timestamp_lock);
|
|
|
|
#ifdef MAC
|
|
|
|
error = mac_posixshm_check_setowner(active_cred, shmfd, uid, gid);
|
|
|
|
if (error != 0)
|
|
|
|
goto out;
|
|
|
|
#endif
|
|
|
|
if (uid == (uid_t)-1)
|
|
|
|
uid = shmfd->shm_uid;
|
|
|
|
if (gid == (gid_t)-1)
|
|
|
|
gid = shmfd->shm_gid;
|
|
|
|
if (((uid != shmfd->shm_uid && uid != active_cred->cr_uid) ||
|
|
|
|
(gid != shmfd->shm_gid && !groupmember(gid, active_cred))) &&
|
2018-12-11 19:32:16 +00:00
|
|
|
(error = priv_check_cred(active_cred, PRIV_VFS_CHOWN)))
|
2011-08-16 20:07:47 +00:00
|
|
|
goto out;
|
|
|
|
shmfd->shm_uid = uid;
|
|
|
|
shmfd->shm_gid = gid;
|
|
|
|
out:
|
|
|
|
mtx_unlock(&shm_timestamp_lock);
|
|
|
|
return (error);
|
|
|
|
}
|
2011-12-14 22:22:19 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper routines to allow the backing object of a shared memory file
|
|
|
|
* descriptor to be mapped in the kernel.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
shm_map(struct file *fp, size_t size, off_t offset, void **memp)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
vm_offset_t kva, ofs;
|
|
|
|
vm_object_t obj;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
if (fp->f_type != DTYPE_SHM)
|
|
|
|
return (EINVAL);
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
obj = shmfd->shm_object;
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WLOCK(obj);
|
2011-12-14 22:22:19 +00:00
|
|
|
/*
|
|
|
|
* XXXRW: This validation is probably insufficient, and subject to
|
|
|
|
* sign errors. It should be fixed.
|
|
|
|
*/
|
|
|
|
if (offset >= shmfd->shm_size ||
|
|
|
|
offset + size > round_page(shmfd->shm_size)) {
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
2011-12-14 22:22:19 +00:00
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
shmfd->shm_kmappings++;
|
|
|
|
vm_object_reference_locked(obj);
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
2011-12-14 22:22:19 +00:00
|
|
|
|
|
|
|
/* Map the object into the kernel_map and wire it. */
|
|
|
|
kva = vm_map_min(kernel_map);
|
|
|
|
ofs = offset & PAGE_MASK;
|
|
|
|
offset = trunc_page(offset);
|
|
|
|
size = round_page(size + ofs);
|
2013-09-09 18:11:59 +00:00
|
|
|
rv = vm_map_find(kernel_map, obj, offset, &kva, size, 0,
|
2013-07-24 20:34:25 +00:00
|
|
|
VMFS_OPTIMAL_SPACE, VM_PROT_READ | VM_PROT_WRITE,
|
2011-12-14 22:22:19 +00:00
|
|
|
VM_PROT_READ | VM_PROT_WRITE, 0);
|
|
|
|
if (rv == KERN_SUCCESS) {
|
|
|
|
rv = vm_map_wire(kernel_map, kva, kva + size,
|
|
|
|
VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
|
|
|
|
if (rv == KERN_SUCCESS) {
|
|
|
|
*memp = (void *)(kva + ofs);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
vm_map_remove(kernel_map, kva, kva + size);
|
|
|
|
} else
|
|
|
|
vm_object_deallocate(obj);
|
|
|
|
|
|
|
|
/* On failure, drop our mapping reference. */
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WLOCK(obj);
|
2011-12-14 22:22:19 +00:00
|
|
|
shmfd->shm_kmappings--;
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
2011-12-14 22:22:19 +00:00
|
|
|
|
2011-12-15 15:17:19 +00:00
|
|
|
return (vm_mmap_to_errno(rv));
|
2011-12-14 22:22:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We require the caller to unmap the entire entry. This allows us to
|
|
|
|
* safely decrement shm_kmappings when a mapping is removed.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
shm_unmap(struct file *fp, void *mem, size_t size)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
vm_map_entry_t entry;
|
|
|
|
vm_offset_t kva, ofs;
|
|
|
|
vm_object_t obj;
|
|
|
|
vm_pindex_t pindex;
|
|
|
|
vm_prot_t prot;
|
|
|
|
boolean_t wired;
|
|
|
|
vm_map_t map;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
if (fp->f_type != DTYPE_SHM)
|
|
|
|
return (EINVAL);
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
kva = (vm_offset_t)mem;
|
|
|
|
ofs = kva & PAGE_MASK;
|
|
|
|
kva = trunc_page(kva);
|
|
|
|
size = round_page(size + ofs);
|
|
|
|
map = kernel_map;
|
|
|
|
rv = vm_map_lookup(&map, kva, VM_PROT_READ | VM_PROT_WRITE, &entry,
|
|
|
|
&obj, &pindex, &prot, &wired);
|
|
|
|
if (rv != KERN_SUCCESS)
|
|
|
|
return (EINVAL);
|
|
|
|
if (entry->start != kva || entry->end != kva + size) {
|
|
|
|
vm_map_lookup_done(map, entry);
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
vm_map_lookup_done(map, entry);
|
|
|
|
if (obj != shmfd->shm_object)
|
|
|
|
return (EINVAL);
|
|
|
|
vm_map_remove(map, kva, kva + size);
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WLOCK(obj);
|
2011-12-14 22:22:19 +00:00
|
|
|
KASSERT(shmfd->shm_kmappings > 0, ("shm_unmap: object not mapped"));
|
|
|
|
shmfd->shm_kmappings--;
|
2013-03-09 02:32:23 +00:00
|
|
|
VM_OBJECT_WUNLOCK(obj);
|
2011-12-14 22:22:19 +00:00
|
|
|
return (0);
|
|
|
|
}
|
2012-04-01 18:22:48 +00:00
|
|
|
|
2014-09-22 16:20:47 +00:00
|
|
|
static int
|
2019-05-23 12:35:40 +00:00
|
|
|
shm_fill_kinfo_locked(struct shmfd *shmfd, struct kinfo_file *kif, bool list)
|
2012-04-01 18:22:48 +00:00
|
|
|
{
|
2016-04-13 20:14:13 +00:00
|
|
|
const char *path, *pr_path;
|
|
|
|
size_t pr_pathlen;
|
2019-05-23 12:35:40 +00:00
|
|
|
bool visible;
|
2014-09-22 16:20:47 +00:00
|
|
|
|
2019-05-23 12:35:40 +00:00
|
|
|
sx_assert(&shm_dict_lock, SA_LOCKED);
|
2014-09-22 16:20:47 +00:00
|
|
|
kif->kf_type = KF_TYPE_SHM;
|
2019-05-23 12:35:40 +00:00
|
|
|
kif->kf_un.kf_file.kf_file_mode = S_IFREG | shmfd->shm_mode;
|
2014-09-22 16:20:47 +00:00
|
|
|
kif->kf_un.kf_file.kf_file_size = shmfd->shm_size;
|
|
|
|
if (shmfd->shm_path != NULL) {
|
2016-04-14 17:07:26 +00:00
|
|
|
if (shmfd->shm_path != NULL) {
|
2016-04-13 20:14:13 +00:00
|
|
|
path = shmfd->shm_path;
|
|
|
|
pr_path = curthread->td_ucred->cr_prison->pr_path;
|
2016-04-14 17:07:26 +00:00
|
|
|
if (strcmp(pr_path, "/") != 0) {
|
|
|
|
/* Return the jail-rooted pathname. */
|
2016-04-13 20:14:13 +00:00
|
|
|
pr_pathlen = strlen(pr_path);
|
2019-05-23 12:35:40 +00:00
|
|
|
visible = strncmp(path, pr_path, pr_pathlen)
|
|
|
|
== 0 && path[pr_pathlen] == '/';
|
|
|
|
if (list && !visible)
|
|
|
|
return (EPERM);
|
|
|
|
if (visible)
|
2016-04-13 20:14:13 +00:00
|
|
|
path += pr_pathlen;
|
|
|
|
}
|
|
|
|
strlcpy(kif->kf_path, path, sizeof(kif->kf_path));
|
|
|
|
}
|
2014-09-22 16:20:47 +00:00
|
|
|
}
|
|
|
|
return (0);
|
2012-04-01 18:22:48 +00:00
|
|
|
}
|
2019-05-23 12:35:40 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
shm_fill_kinfo(struct file *fp, struct kinfo_file *kif,
|
|
|
|
struct filedesc *fdp __unused)
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
|
|
|
|
sx_slock(&shm_dict_lock);
|
|
|
|
res = shm_fill_kinfo_locked(fp->f_data, kif, false);
|
|
|
|
sx_sunlock(&shm_dict_lock);
|
|
|
|
return (res);
|
|
|
|
}
|
|
|
|
|
2019-09-25 17:32:43 +00:00
|
|
|
static int
|
|
|
|
shm_add_seals(struct file *fp, int seals)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
void *rl_cookie;
|
|
|
|
vm_ooffset_t writemappings;
|
|
|
|
int error, nseals;
|
|
|
|
|
|
|
|
error = 0;
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX,
|
|
|
|
&shmfd->shm_mtx);
|
|
|
|
|
|
|
|
/* Even already-set seals should result in EPERM. */
|
|
|
|
if ((shmfd->shm_seals & F_SEAL_SEAL) != 0) {
|
|
|
|
error = EPERM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
nseals = seals & ~shmfd->shm_seals;
|
|
|
|
if ((nseals & F_SEAL_WRITE) != 0) {
|
2020-09-10 20:54:44 +00:00
|
|
|
if (shm_largepage(shmfd)) {
|
|
|
|
error = ENOTSUP;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2019-09-25 17:32:43 +00:00
|
|
|
/*
|
|
|
|
* The rangelock above prevents writable mappings from being
|
|
|
|
* added after we've started applying seals. The RLOCK here
|
|
|
|
* is to avoid torn reads on ILP32 arches as unmapping/reducing
|
|
|
|
* writemappings will be done without a rangelock.
|
|
|
|
*/
|
|
|
|
VM_OBJECT_RLOCK(shmfd->shm_object);
|
|
|
|
writemappings = shmfd->shm_object->un_pager.swp.writemappings;
|
|
|
|
VM_OBJECT_RUNLOCK(shmfd->shm_object);
|
|
|
|
/* kmappings are also writable */
|
|
|
|
if (writemappings > 0) {
|
|
|
|
error = EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
shmfd->shm_seals |= nseals;
|
|
|
|
out:
|
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
shm_get_seals(struct file *fp, int *seals)
|
|
|
|
{
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
*seals = shmfd->shm_seals;
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2020-01-08 19:08:44 +00:00
|
|
|
static int
|
|
|
|
shm_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td)
|
|
|
|
{
|
|
|
|
void *rl_cookie;
|
|
|
|
struct shmfd *shmfd;
|
|
|
|
size_t size;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
/* This assumes that the caller already checked for overflow. */
|
|
|
|
error = 0;
|
|
|
|
shmfd = fp->f_data;
|
|
|
|
size = offset + len;
|
2020-01-09 04:03:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Just grab the rangelock for the range that we may be attempting to
|
|
|
|
* grow, rather than blocking read/write for regions we won't be
|
|
|
|
* touching while this (potential) resize is in progress. Other
|
|
|
|
* attempts to resize the shmfd will have to take a write lock from 0 to
|
|
|
|
* OFF_MAX, so this being potentially beyond the current usable range of
|
|
|
|
* the shmfd is not necessarily a concern. If other mechanisms are
|
|
|
|
* added to grow a shmfd, this may need to be re-evaluated.
|
|
|
|
*/
|
|
|
|
rl_cookie = rangelock_wlock(&shmfd->shm_rl, offset, size,
|
2020-01-08 19:08:44 +00:00
|
|
|
&shmfd->shm_mtx);
|
2020-09-09 22:12:51 +00:00
|
|
|
if (size > shmfd->shm_size)
|
|
|
|
error = shm_dotruncate_cookie(shmfd, size, rl_cookie);
|
2020-01-08 19:08:44 +00:00
|
|
|
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx);
|
|
|
|
/* Translate to posix_fallocate(2) return value as needed. */
|
|
|
|
if (error == ENOMEM)
|
|
|
|
error = ENOSPC;
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2019-05-23 12:35:40 +00:00
|
|
|
static int
|
|
|
|
sysctl_posix_shm_list(SYSCTL_HANDLER_ARGS)
|
|
|
|
{
|
|
|
|
struct shm_mapping *shmm;
|
|
|
|
struct sbuf sb;
|
|
|
|
struct kinfo_file kif;
|
|
|
|
u_long i;
|
|
|
|
ssize_t curlen;
|
|
|
|
int error, error2;
|
|
|
|
|
|
|
|
sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_file) * 5, req);
|
|
|
|
sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
|
|
|
|
curlen = 0;
|
|
|
|
error = 0;
|
|
|
|
sx_slock(&shm_dict_lock);
|
|
|
|
for (i = 0; i < shm_hash + 1; i++) {
|
|
|
|
LIST_FOREACH(shmm, &shm_dictionary[i], sm_link) {
|
|
|
|
error = shm_fill_kinfo_locked(shmm->sm_shmfd,
|
|
|
|
&kif, true);
|
|
|
|
if (error == EPERM)
|
|
|
|
continue;
|
|
|
|
if (error != 0)
|
|
|
|
break;
|
|
|
|
pack_kinfo(&kif);
|
|
|
|
if (req->oldptr != NULL &&
|
|
|
|
kif.kf_structsize + curlen > req->oldlen)
|
|
|
|
break;
|
|
|
|
error = sbuf_bcat(&sb, &kif, kif.kf_structsize) == 0 ?
|
|
|
|
0 : ENOMEM;
|
|
|
|
if (error != 0)
|
|
|
|
break;
|
|
|
|
curlen += kif.kf_structsize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sx_sunlock(&shm_dict_lock);
|
|
|
|
error2 = sbuf_finish(&sb);
|
|
|
|
sbuf_delete(&sb);
|
|
|
|
return (error != 0 ? error : error2);
|
|
|
|
}
|
|
|
|
|
|
|
|
SYSCTL_PROC(_kern_ipc, OID_AUTO, posix_shm_list,
|
|
|
|
CTLFLAG_RD | CTLFLAG_MPSAFE | CTLTYPE_OPAQUE,
|
|
|
|
NULL, 0, sysctl_posix_shm_list, "",
|
|
|
|
"POSIX SHM list");
|
2019-09-25 17:59:15 +00:00
|
|
|
|
|
|
|
int
|
2020-01-05 04:06:40 +00:00
|
|
|
kern_shm_open(struct thread *td, const char *path, int flags, mode_t mode,
|
|
|
|
struct filecaps *caps)
|
2019-09-25 17:59:15 +00:00
|
|
|
{
|
|
|
|
|
2020-01-05 04:06:40 +00:00
|
|
|
return (kern_shm_open2(td, path, flags, mode, 0, caps, NULL));
|
2019-09-25 17:59:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This version of the shm_open() interface leaves CLOEXEC behavior up to the
|
|
|
|
* caller, and libc will enforce it for the traditional shm_open() call. This
|
|
|
|
* allows other consumers, like memfd_create(), to opt-in for CLOEXEC. This
|
|
|
|
* interface also includes a 'name' argument that is currently unused, but could
|
|
|
|
* potentially be exported later via some interface for debugging purposes.
|
|
|
|
* From the kernel's perspective, it is optional. Individual consumers like
|
|
|
|
* memfd_create() may require it in order to be compatible with other systems
|
|
|
|
* implementing the same function.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
sys_shm_open2(struct thread *td, struct shm_open2_args *uap)
|
|
|
|
{
|
|
|
|
|
|
|
|
return (kern_shm_open2(td, uap->path, uap->flags, uap->mode,
|
2020-01-05 04:06:40 +00:00
|
|
|
uap->shmflags, NULL, uap->name));
|
2019-09-25 17:59:15 +00:00
|
|
|
}
|