1 // SPDX-License-Identifier: GPL-2.0 2 #include <unistd.h> 3 #include <stdbool.h> 4 #include <errno.h> 5 #include <linux/kernel.h> 6 #include <internal/lib.h> 7 8 unsigned int page_size; 9 10 static ssize_t ion(bool is_read, int fd, void *buf, size_t n) 11 { 12 void *buf_start = buf; 13 size_t left = n; 14 15 while (left) { 16 /* buf must be treated as const if !is_read. */ 17 ssize_t ret = is_read ? read(fd, buf, left) : 18 write(fd, buf, left); 19 20 if (ret < 0 && errno == EINTR) 21 continue; 22 if (ret <= 0) 23 return ret; 24 25 left -= ret; 26 buf += ret; 27 } 28 29 BUG_ON((size_t)(buf - buf_start) != n); 30 return n; 31 } 32 33 /* 34 * Read exactly 'n' bytes or return an error. 35 */ 36 ssize_t readn(int fd, void *buf, size_t n) 37 { 38 return ion(true, fd, buf, n); 39 } 40 41 ssize_t preadn(int fd, void *buf, size_t n, off_t offs) 42 { 43 size_t left = n; 44 45 while (left) { 46 ssize_t ret = pread(fd, buf, left, offs); 47 48 if (ret < 0 && errno == EINTR) 49 continue; 50 if (ret <= 0) 51 return ret; 52 53 left -= ret; 54 buf += ret; 55 offs += ret; 56 } 57 58 return n; 59 } 60 61 /* 62 * Write exactly 'n' bytes or return an error. 63 */ 64 ssize_t writen(int fd, const void *buf, size_t n) 65 { 66 /* ion does not modify buf. */ 67 return ion(false, fd, (void *)buf, n); 68 } 69