* Used by statfs conversion routines to scale the block size up if * necessary so that all of the block counts are <= 'max_size'. Note * that 'max_size' should be a bitmask, i.e. 2^n - 1 for some non-zero * value of 'n'. */
| 238 | * value of 'n'. |
| 239 | */ |
| 240 | void |
| 241 | statfs_scale_blocks(struct statfs *sf, long max_size) |
| 242 | { |
| 243 | uint64_t count; |
| 244 | int shift; |
| 245 | |
| 246 | KASSERT(powerof2(max_size + 1), ("%s: invalid max_size", __func__)); |
| 247 | |
| 248 | /* |
| 249 | * Attempt to scale the block counts to give a more accurate |
| 250 | * overview to userland of the ratio of free space to used |
| 251 | * space. To do this, find the largest block count and compute |
| 252 | * a divisor that lets it fit into a signed integer <= max_size. |
| 253 | */ |
| 254 | if (sf->f_bavail < 0) |
| 255 | count = -sf->f_bavail; |
| 256 | else |
| 257 | count = sf->f_bavail; |
| 258 | count = MAX(sf->f_blocks, MAX(sf->f_bfree, count)); |
| 259 | if (count <= max_size) |
| 260 | return; |
| 261 | |
| 262 | count >>= flsl(max_size); |
| 263 | shift = 0; |
| 264 | while (count > 0) { |
| 265 | shift++; |
| 266 | count >>=1; |
| 267 | } |
| 268 | |
| 269 | sf->f_bsize <<= shift; |
| 270 | sf->f_blocks >>= shift; |
| 271 | sf->f_bfree >>= shift; |
| 272 | sf->f_bavail >>= shift; |
| 273 | } |
| 274 | |
| 275 | static int |
| 276 | kern_do_statfs(struct thread *td, struct mount *mp, struct statfs *buf) |
no test coverage detected