#include #include #include #include #include #include #include #include #include #include namespace { int createMemfd(size_t bytes, unsigned int flags) { int fd(memfd_create("memfd_test", flags)); if (fd == -1) { perror("memfd_create"); return -1; } int rc = ftruncate(fd, bytes); if (rc == -1) { perror("ftruncate"); return -1; } return fd; } int createUdmabuf(size_t bytes, int memfd) { int udmabuf_dev_fd(open("/dev/udmabuf", O_RDONLY)); if (udmabuf_dev_fd == -1) { perror("udmabuf open"); return -1; } struct udmabuf_create create; create.memfd = memfd; create.flags = UDMABUF_FLAGS_CLOEXEC; create.offset = 0; create.size = bytes; int dmabuf_fd(ioctl(udmabuf_dev_fd, UDMABUF_CREATE, &create)); if (dmabuf_fd == -1) perror("UDMABUF_CREATE"); return dmabuf_fd; } } // anonymous namespace int main(int argc, char **argv) { size_t bytes = 1ull << 30; int memfd = createMemfd(bytes, MFD_ALLOW_SEALING); if (memfd < 0) return EXIT_FAILURE; if (fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK) < 0) { perror("F_SEAL_SHRINK"); return EXIT_FAILURE; } if (ftruncate(memfd, bytes)) { perror("ftruncate"); return EXIT_FAILURE; } int bigfile = open(argv[1], O_RDONLY | O_DIRECT); if (bigfile < 0) { perror("open"); return EXIT_FAILURE; } off_t offset = 0; for (ssize_t n = sendfile(memfd, bigfile, &offset, bytes - offset); offset < bytes && n > 0; n = sendfile(memfd, bigfile, &offset, bytes - offset)) {} printf("Offset %ld\n", offset); int udmabuf = createUdmabuf(bytes, memfd); if (udmabuf < 0) return EXIT_FAILURE; return EXIT_SUCCESS; }