| 405 | } |
| 406 | |
| 407 | static int |
| 408 | shm_write(struct file *fp, struct uio *uio, struct ucred *active_cred, |
| 409 | int flags, struct thread *td) |
| 410 | { |
| 411 | struct shmfd *shmfd; |
| 412 | void *rl_cookie; |
| 413 | int error; |
| 414 | off_t size; |
| 415 | |
| 416 | shmfd = fp->f_data; |
| 417 | #ifdef MAC |
| 418 | error = mac_posixshm_check_write(active_cred, fp->f_cred, shmfd); |
| 419 | if (error) |
| 420 | return (error); |
| 421 | #endif |
| 422 | if (shm_largepage(shmfd) && shmfd->shm_lp_psind == 0) |
| 423 | return (EINVAL); |
| 424 | foffset_lock_uio(fp, uio, flags); |
| 425 | if (uio->uio_resid > OFF_MAX - uio->uio_offset) { |
| 426 | /* |
| 427 | * Overflow is only an error if we're supposed to expand on |
| 428 | * write. Otherwise, we'll just truncate the write to the |
| 429 | * size of the file, which can only grow up to OFF_MAX. |
| 430 | */ |
| 431 | if ((shmfd->shm_flags & SHM_GROW_ON_WRITE) != 0) { |
| 432 | foffset_unlock_uio(fp, uio, flags); |
| 433 | return (EFBIG); |
| 434 | } |
| 435 | |
| 436 | size = shmfd->shm_size; |
| 437 | } else { |
| 438 | size = uio->uio_offset + uio->uio_resid; |
| 439 | } |
| 440 | if ((flags & FOF_OFFSET) == 0) { |
| 441 | rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX, |
| 442 | &shmfd->shm_mtx); |
| 443 | } else { |
| 444 | rl_cookie = rangelock_wlock(&shmfd->shm_rl, uio->uio_offset, |
| 445 | size, &shmfd->shm_mtx); |
| 446 | } |
| 447 | if ((shmfd->shm_seals & F_SEAL_WRITE) != 0) { |
| 448 | error = EPERM; |
| 449 | } else { |
| 450 | error = 0; |
| 451 | if ((shmfd->shm_flags & SHM_GROW_ON_WRITE) != 0 && |
| 452 | size > shmfd->shm_size) { |
| 453 | error = shm_dotruncate_cookie(shmfd, size, rl_cookie); |
| 454 | } |
| 455 | if (error == 0) |
| 456 | error = uiomove_object(shmfd->shm_object, |
| 457 | shmfd->shm_size, uio); |
| 458 | } |
| 459 | rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx); |
| 460 | foffset_unlock_uio(fp, uio, flags); |
| 461 | return (error); |
| 462 | } |
| 463 | |
| 464 | static int |
nothing calls this directly
no test coverage detected