1/*
2 * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <SupportDefs.h>
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <ctype.h>
13
14
15static const uint32 kDesiredAllocationGroups = 56;
16
17
18int
19main(int argc, char **argv)
20{
21	if (argc != 3 || !isdigit(argv[1][0]) || !isdigit(argv[2][0])) {
22		const char *name = strrchr(argv[0], '/');
23		name = name ? name + 1 : argv[0];
24
25		fprintf(stderr, "usage: %s <num blocks> <block size>\n", name);
26		return -1;
27	}
28
29	off_t numBlocks = atoll(argv[1]);
30	uint32 blockSize = (uint32)atol(argv[2]);
31
32	if (blockSize != 1024 && blockSize != 2048 && blockSize != 4096 && blockSize != 8192) {
33		fprintf(stderr, "valid values for <block size> are: 1024, 2048, 4096, 8192\n");
34		return -1;
35	}
36
37	int32 blockShift = 9;
38	while ((1UL << blockShift) < blockSize) {
39		blockShift++;
40	}
41
42	uint32 blocks_per_ag = 1;
43	uint32 ag_shift = 13;
44	uint32 num_ags = 0;
45
46	uint32 bitsPerBlock = blockSize << 3;
47	off_t bitmapBlocks = (numBlocks + bitsPerBlock - 1) / bitsPerBlock;
48	for (uint32 i = 8192; i < bitsPerBlock; i *= 2) {
49		ag_shift++;
50	}
51
52	// Many allocation groups help applying allocation policies, but if
53	// they are too small, we will need to many block_runs to cover large
54	// files
55
56	while (true) {
57		num_ags = (bitmapBlocks + blocks_per_ag - 1) / blocks_per_ag;
58		if (num_ags > kDesiredAllocationGroups) {
59			if (ag_shift == 16)
60				break;
61
62			ag_shift++;
63			blocks_per_ag *= 2;
64		} else
65			break;
66	}
67
68	printf("blocks = %Ld\n", numBlocks);
69	printf("block shift = %ld\n", blockShift);
70	printf("bits per block = %lu\n", bitsPerBlock);
71	printf("bitmap blocks = %Ld\n", bitmapBlocks);
72	printf("allocation groups = %lu\n", num_ags);
73	printf("shift = %lu (%lu)\n", ag_shift, 1UL << ag_shift);
74	printf("blocks per group = %lu\n", blocks_per_ag);
75
76	uint32 bitsPerGroup = 8 * (blocks_per_ag << blockShift);
77
78	printf("\nBits per group: %ld\n", bitsPerGroup);
79	printf("Bits in last group: %ld\n", numBlocks - (num_ags - 1) * bitsPerGroup);
80
81	return 0;
82}
83
84