| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
|---|
| 3 | | - * Licensed under the GPL |
|---|
| 4 | 4 | */ |
|---|
| 5 | 5 | |
|---|
| 6 | 6 | #include <stdio.h> |
|---|
| 7 | 7 | #include <unistd.h> |
|---|
| 8 | +#include <stdlib.h> |
|---|
| 9 | +#include <string.h> |
|---|
| 8 | 10 | #include <errno.h> |
|---|
| 9 | 11 | #include <fcntl.h> |
|---|
| 10 | 12 | #include <signal.h> |
|---|
| 13 | +#include <linux/falloc.h> |
|---|
| 11 | 14 | #include <sys/ioctl.h> |
|---|
| 12 | 15 | #include <sys/mount.h> |
|---|
| 13 | 16 | #include <sys/socket.h> |
|---|
| .. | .. |
|---|
| 15 | 18 | #include <sys/sysmacros.h> |
|---|
| 16 | 19 | #include <sys/un.h> |
|---|
| 17 | 20 | #include <sys/types.h> |
|---|
| 21 | +#include <sys/eventfd.h> |
|---|
| 22 | +#include <poll.h> |
|---|
| 18 | 23 | #include <os.h> |
|---|
| 19 | 24 | |
|---|
| 20 | 25 | static void copy_stat(struct uml_stat *dst, const struct stat64 *src) |
|---|
| .. | .. |
|---|
| 285 | 290 | |
|---|
| 286 | 291 | int os_sync_file(int fd) |
|---|
| 287 | 292 | { |
|---|
| 288 | | - int n = fsync(fd); |
|---|
| 293 | + int n = fdatasync(fd); |
|---|
| 289 | 294 | |
|---|
| 290 | 295 | if (n < 0) |
|---|
| 291 | 296 | return -errno; |
|---|
| .. | .. |
|---|
| 340 | 345 | return 0; |
|---|
| 341 | 346 | } |
|---|
| 342 | 347 | |
|---|
| 343 | | -int os_file_modtime(const char *file, unsigned long *modtime) |
|---|
| 348 | +int os_file_modtime(const char *file, long long *modtime) |
|---|
| 344 | 349 | { |
|---|
| 345 | 350 | struct uml_stat buf; |
|---|
| 346 | 351 | int err; |
|---|
| .. | .. |
|---|
| 610 | 615 | { |
|---|
| 611 | 616 | return makedev(major, minor); |
|---|
| 612 | 617 | } |
|---|
| 618 | + |
|---|
| 619 | +int os_falloc_punch(int fd, unsigned long long offset, int len) |
|---|
| 620 | +{ |
|---|
| 621 | + int n = fallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, offset, len); |
|---|
| 622 | + |
|---|
| 623 | + if (n < 0) |
|---|
| 624 | + return -errno; |
|---|
| 625 | + return n; |
|---|
| 626 | +} |
|---|
| 627 | + |
|---|
| 628 | +int os_eventfd(unsigned int initval, int flags) |
|---|
| 629 | +{ |
|---|
| 630 | + int fd = eventfd(initval, flags); |
|---|
| 631 | + |
|---|
| 632 | + if (fd < 0) |
|---|
| 633 | + return -errno; |
|---|
| 634 | + return fd; |
|---|
| 635 | +} |
|---|
| 636 | + |
|---|
| 637 | +int os_sendmsg_fds(int fd, const void *buf, unsigned int len, const int *fds, |
|---|
| 638 | + unsigned int fds_num) |
|---|
| 639 | +{ |
|---|
| 640 | + struct iovec iov = { |
|---|
| 641 | + .iov_base = (void *) buf, |
|---|
| 642 | + .iov_len = len, |
|---|
| 643 | + }; |
|---|
| 644 | + union { |
|---|
| 645 | + char control[CMSG_SPACE(sizeof(*fds) * OS_SENDMSG_MAX_FDS)]; |
|---|
| 646 | + struct cmsghdr align; |
|---|
| 647 | + } u; |
|---|
| 648 | + unsigned int fds_size = sizeof(*fds) * fds_num; |
|---|
| 649 | + struct msghdr msg = { |
|---|
| 650 | + .msg_iov = &iov, |
|---|
| 651 | + .msg_iovlen = 1, |
|---|
| 652 | + .msg_control = u.control, |
|---|
| 653 | + .msg_controllen = CMSG_SPACE(fds_size), |
|---|
| 654 | + }; |
|---|
| 655 | + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); |
|---|
| 656 | + int err; |
|---|
| 657 | + |
|---|
| 658 | + if (fds_num > OS_SENDMSG_MAX_FDS) |
|---|
| 659 | + return -EINVAL; |
|---|
| 660 | + memset(u.control, 0, sizeof(u.control)); |
|---|
| 661 | + cmsg->cmsg_level = SOL_SOCKET; |
|---|
| 662 | + cmsg->cmsg_type = SCM_RIGHTS; |
|---|
| 663 | + cmsg->cmsg_len = CMSG_LEN(fds_size); |
|---|
| 664 | + memcpy(CMSG_DATA(cmsg), fds, fds_size); |
|---|
| 665 | + err = sendmsg(fd, &msg, 0); |
|---|
| 666 | + |
|---|
| 667 | + if (err < 0) |
|---|
| 668 | + return -errno; |
|---|
| 669 | + return err; |
|---|
| 670 | +} |
|---|
| 671 | + |
|---|
| 672 | +int os_poll(unsigned int n, const int *fds) |
|---|
| 673 | +{ |
|---|
| 674 | + /* currently need 2 FDs at most so avoid dynamic allocation */ |
|---|
| 675 | + struct pollfd pollfds[2] = {}; |
|---|
| 676 | + unsigned int i; |
|---|
| 677 | + int ret; |
|---|
| 678 | + |
|---|
| 679 | + if (n > ARRAY_SIZE(pollfds)) |
|---|
| 680 | + return -EINVAL; |
|---|
| 681 | + |
|---|
| 682 | + for (i = 0; i < n; i++) { |
|---|
| 683 | + pollfds[i].fd = fds[i]; |
|---|
| 684 | + pollfds[i].events = POLLIN; |
|---|
| 685 | + } |
|---|
| 686 | + |
|---|
| 687 | + ret = poll(pollfds, n, -1); |
|---|
| 688 | + if (ret < 0) |
|---|
| 689 | + return -errno; |
|---|
| 690 | + |
|---|
| 691 | + /* Return the index of the available FD */ |
|---|
| 692 | + for (i = 0; i < n; i++) { |
|---|
| 693 | + if (pollfds[i].revents) |
|---|
| 694 | + return i; |
|---|
| 695 | + } |
|---|
| 696 | + |
|---|
| 697 | + return -EIO; |
|---|
| 698 | +} |
|---|