.. | .. |
---|
| 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 | +} |
---|