| 78 | */ |
| 79 | enum { IO_BUFSIZE = 256 * 1024 }; |
| 80 | static inline idx_t |
| 81 | io_blksize (struct stat const *st) |
| 82 | { |
| 83 | /* Treat impossible blocksizes as if they were IO_BUFSIZE. */ |
| 84 | idx_t blocksize = STP_BLKSIZE (st) <= 0 ? IO_BUFSIZE : STP_BLKSIZE (st); |
| 85 | |
| 86 | /* Use a blocksize of at least IO_BUFSIZE bytes, keeping it a |
| 87 | multiple of the original blocksize. */ |
| 88 | blocksize += (IO_BUFSIZE - 1) - (IO_BUFSIZE - 1) % blocksize; |
| 89 | |
| 90 | /* For regular files we can ignore the blocksize if we think we know better. |
| 91 | ZFS sometimes understates the blocksize, because it thinks |
| 92 | apps stupidly allocate a block that large even for small files. |
| 93 | This misinformation can cause coreutils to use wrong-sized blocks. |
| 94 | Work around some of the performance bug by substituting the next |
| 95 | power of two when the reported blocksize is not a power of two. */ |
| 96 | if (S_ISREG (st->st_mode) && blocksize & (blocksize - 1)) |
| 97 | { |
| 98 | int leading_zeros = stdc_leading_zeros_ull (blocksize); |
| 99 | if (IDX_MAX < ULLONG_MAX || leading_zeros) |
| 100 | { |
| 101 | unsigned long long power = 1ull << (ULLONG_WIDTH - leading_zeros); |
| 102 | if (power <= IDX_MAX) |
| 103 | blocksize = power; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | /* Don’t go above the maximum number of bytes |
| 108 | to read or write in a single system call, |
| 109 | as that is asking for trouble. */ |
| 110 | return MIN (SYS_BUFSIZE_MAX, blocksize); |
| 111 | } |
no outgoing calls
no test coverage detected