Date: Fri, 10 Jul 2020 00:43:45 +0000 (UTC) From: Kyle Evans <kevans@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r363065 - in head/sys: kern sys Message-ID: <202007100043.06A0hjo1093130@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007100043.06A0hjo1093130>