1 #define _FILE_OFFSET_BITS 64
2 #define __USE_FILE_OFFSET64
3 #define _XOPEN_SOURCE 600
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
16 #include <uuid/uuid.h>
22 uint64_t getblocks(int fd)
26 if (fstat(fd, &statbuf)) {
27 perror("stat error\n");
30 ret = statbuf.st_size / 512;
31 if (S_ISBLK(statbuf.st_mode))
32 if (ioctl(fd, BLKGETSIZE, &ret)) {
33 perror("ioctl error");
39 uint64_t hatoi(const char *s)
42 long long i = strtoll(s, &e, 10);
62 printf("Usage: make-bcache [options] device\n"
63 " -C Format a cache device\n"
64 " -B Format a backing device\n"
66 " -w block size (hard sector size of SSD, often 2k)\n"
67 " -j journal size, in buckets\n"
73 int main(int argc, char **argv)
75 bool cache = false, backingdev = false;
76 int64_t nblocks, journal = 0;
78 char uuid[40], set_uuid[40];
81 memset(&sb, 0, sizeof(struct cache_sb));
83 uuid_generate(sb.uuid);
84 uuid_generate(sb.set_uuid);
86 while ((c = getopt(argc, argv, "CBU:w:b:j:")) != -1)
95 sb.bucket_size = hatoi(optarg) / 512;
98 sb.block_size = hatoi(optarg) / 512;
101 journal = atoi(optarg);
104 if (uuid_parse(optarg, sb.uuid)) {
105 printf("Bad uuid\n");
110 if (uuid_parse(optarg, sb.set_uuid)) {
111 printf("Bad uuid\n");
121 sb.bucket_size = cache ? 256 : 8192;
123 if (cache == backingdev) {
124 printf("Must specify one of -C or -B\n");
128 if (argc <= optind) {
129 printf("Please supply a device\n");
133 fd = open(argv[optind], O_RDWR);
135 perror("Can't open dev\n");
138 nblocks = getblocks(fd);
139 printf("device is %ju sectors\n", nblocks);
141 if (sb.bucket_size < sb.block_size ||
142 sb.bucket_size > nblocks / 8) {
143 printf("Bad bucket size %i\n", sb.bucket_size);
147 memcpy(sb.magic, bcache_magic, 16);
148 sb.version = backingdev ? CACHE_BACKING_DEV : 0;
149 sb.nbuckets = nblocks / sb.bucket_size;
151 uuid_unparse(sb.uuid, uuid);
152 uuid_unparse(sb.set_uuid, set_uuid);
154 sb.journal_start = ((sb.nbuckets * sizeof(struct bucket_disk)) + (24 << 9)) / (sb.bucket_size << 9) + 1;
155 sb.first_bucket = sb.journal_start + journal;
157 printf("block_size: %u\n"
159 "journal_start: %u\n"
172 /* Zero out priorities */
173 lseek(fd, 4096, SEEK_SET);
174 for (i = 8; i < sb.first_bucket * sb.bucket_size; i++)
175 if (write(fd, zero, 512) != 512)
179 if (pwrite(fd, &sb, sizeof(sb), 4096) != sizeof(sb))
185 perror("write error\n");