svn commit: r363065 - in head/sys: kern sys
Kyle Evans
kevans at FreeBSD.org
Fri Jul 10 00:43:46 UTC 2020
Author: kevans
Date: Fri Jul 10 00:43:45 2020
New Revision: 363065
URL: https://svnweb.freebsd.org/changeset/base/363065
Log:
shm_open2: Implement SHM_GROW_ON_WRITE
Lack of SHM_GROW_ON_WRITE is actively breaking Python's memfd_create tests,
so go ahead and implement it. A future change will make memfd_create always
set SHM_GROW_ON_WRITE, to match Linux behavior and unbreak Python's tests
on -CURRENT.
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D25502
Modified:
head/sys/kern/uipc_shm.c
head/sys/sys/mman.h
Modified: head/sys/kern/uipc_shm.c
==============================================================================
--- head/sys/kern/uipc_shm.c Fri Jul 10 00:24:42 2020 (r363064)
+++ head/sys/kern/uipc_shm.c Fri Jul 10 00:43:45 2020 (r363065)
@@ -313,6 +313,7 @@ shm_write(struct file *fp, struct uio *uio, struct ucr
struct shmfd *shmfd;
void *rl_cookie;
int error;
+ off_t size;
shmfd = fp->f_data;
#ifdef MAC
@@ -321,17 +322,42 @@ shm_write(struct file *fp, struct uio *uio, struct ucr
return (error);
#endif
foffset_lock_uio(fp, uio, flags);
+ 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;
+ }
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,
- uio->uio_offset + uio->uio_resid, &shmfd->shm_mtx);
+ size, &shmfd->shm_mtx);
}
- if ((shmfd->shm_seals & F_SEAL_WRITE) != 0)
+ if ((shmfd->shm_seals & F_SEAL_WRITE) != 0) {
error = EPERM;
- else
- error = uiomove_object(shmfd->shm_object, shmfd->shm_size, uio);
+ } else {
+ error = 0;
+ if ((shmfd->shm_flags & SHM_GROW_ON_WRITE) != 0 &&
+ size > shmfd->shm_size) {
+ VM_OBJECT_WLOCK(shmfd->shm_object);
+ error = shm_dotruncate_locked(shmfd, size, rl_cookie);
+ VM_OBJECT_WUNLOCK(shmfd->shm_object);
+ }
+ if (error == 0)
+ 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);
@@ -748,7 +774,7 @@ kern_shm_open2(struct thread *td, const char *userpath
mode_t cmode;
int error, fd, initial_seals;
- if ((shmflags & ~SHM_ALLOW_SEALING) != 0)
+ if ((shmflags & ~(SHM_ALLOW_SEALING | SHM_GROW_ON_WRITE)) != 0)
return (EINVAL);
initial_seals = F_SEAL_SEAL;
@@ -921,6 +947,7 @@ kern_shm_open2(struct thread *td, const char *userpath
}
}
+ shmfd->shm_flags = shmflags;
finit(fp, FFLAGS(flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops);
td->td_retval[0] = fd;
Modified: head/sys/sys/mman.h
==============================================================================
--- head/sys/sys/mman.h Fri Jul 10 00:24:42 2020 (r363064)
+++ head/sys/sys/mman.h Fri Jul 10 00:43:45 2020 (r363065)
@@ -190,6 +190,7 @@
* shmflags for shm_open2()
*/
#define SHM_ALLOW_SEALING 0x00000001
+#define SHM_GROW_ON_WRITE 0x00000002
/*
* Flags for memfd_create().
@@ -278,6 +279,7 @@ struct shmfd {
struct rangelock shm_rl;
struct mtx shm_mtx;
+ int shm_flags;
int shm_seals;
};
#endif
More information about the svn-src-head
mailing list