mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +03:00
New superblock format
This commit is contained in:
parent
d1404a0cf1
commit
c798b43ade
68
bcache.h
68
bcache.h
@ -5,40 +5,52 @@ static const char bcache_magic[] = {
|
|||||||
0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca,
|
0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca,
|
||||||
0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 };
|
0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 };
|
||||||
|
|
||||||
|
#define SB_LABEL_SIZE 32
|
||||||
|
|
||||||
|
struct cache_sb {
|
||||||
|
uint64_t csum;
|
||||||
|
uint64_t offset_this_sb;
|
||||||
|
uint64_t version;
|
||||||
|
#define CACHE_BACKING_DEV 1
|
||||||
|
|
||||||
|
uint8_t magic[16];
|
||||||
|
|
||||||
|
uint8_t uuid[16];
|
||||||
|
uint8_t set_uuid[16];
|
||||||
|
uint8_t label[SB_LABEL_SIZE];
|
||||||
|
|
||||||
|
#define CACHE_SYNC (1U << 0)
|
||||||
|
|
||||||
|
#define BDEV_WRITEBACK_BIT 0U
|
||||||
|
|
||||||
|
#define BDEV_STATE_NONE 0U
|
||||||
|
#define BDEV_STATE_CLEAN 1U
|
||||||
|
#define BDEV_STATE_DIRTY 2U
|
||||||
|
#define BDEV_STATE_STALE 3U
|
||||||
|
uint64_t flags;
|
||||||
|
uint64_t sequence;
|
||||||
|
uint64_t pad[8];
|
||||||
|
|
||||||
|
uint64_t nbuckets; /* device size */
|
||||||
|
uint16_t block_size; /* sectors */
|
||||||
|
uint16_t bucket_size; /* sectors */
|
||||||
|
|
||||||
|
uint16_t nr_in_set;
|
||||||
|
uint16_t nr_this_dev;
|
||||||
|
|
||||||
|
uint32_t last_mount; /* time_t */
|
||||||
|
|
||||||
|
uint16_t first_bucket;
|
||||||
|
uint16_t njournal_buckets;
|
||||||
|
uint64_t journal_buckets[];
|
||||||
|
};
|
||||||
|
|
||||||
struct bkey {
|
struct bkey {
|
||||||
uint64_t header;
|
uint64_t header;
|
||||||
uint64_t key;
|
uint64_t key;
|
||||||
uint64_t ptr[];
|
uint64_t ptr[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cache_sb {
|
|
||||||
uint8_t magic[16];
|
|
||||||
uint8_t uuid[16];
|
|
||||||
uint8_t set_uuid[16];
|
|
||||||
uint64_t sequence;
|
|
||||||
|
|
||||||
#define CACHE_CLEAN 1
|
|
||||||
#define CACHE_SYNC 2
|
|
||||||
#define CACHE_BACKING_DEV 4
|
|
||||||
uint32_t version;
|
|
||||||
uint16_t block_size; /* sectors */
|
|
||||||
uint16_t bucket_size; /* sectors */
|
|
||||||
uint32_t journal_start; /* buckets */
|
|
||||||
uint32_t first_bucket; /* start of data */
|
|
||||||
uint64_t nbuckets; /* device size */
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct bkey btree_root;
|
|
||||||
uint64_t _pad[8];
|
|
||||||
};
|
|
||||||
uint16_t btree_level;
|
|
||||||
uint16_t nr_in_set;
|
|
||||||
uint16_t nr_this_dev;
|
|
||||||
uint16_t _pad[1];
|
|
||||||
#define SB_LABEL_SIZE 32
|
|
||||||
uint8_t label[SB_LABEL_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bucket_disk {
|
struct bucket_disk {
|
||||||
uint16_t priority;
|
uint16_t priority;
|
||||||
uint8_t generation;
|
uint8_t generation;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#define __USE_FILE_OFFSET64
|
#define __USE_FILE_OFFSET64
|
||||||
#define _XOPEN_SOURCE 600
|
#define _XOPEN_SOURCE 600
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -64,7 +66,6 @@ void usage()
|
|||||||
" -B Format a backing device\n"
|
" -B Format a backing device\n"
|
||||||
" -b bucket size\n"
|
" -b bucket size\n"
|
||||||
" -w block size (hard sector size of SSD, often 2k)\n"
|
" -w block size (hard sector size of SSD, often 2k)\n"
|
||||||
" -j journal size, in buckets\n"
|
|
||||||
" -U UUID\n"
|
" -U UUID\n"
|
||||||
" -S Set UUID\n");
|
" -S Set UUID\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@ -73,9 +74,9 @@ void usage()
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool cache = false, backingdev = false;
|
bool cache = false, backingdev = false;
|
||||||
int64_t nblocks, journal = 0;
|
int fd, c;
|
||||||
int fd, i, c;
|
int64_t nblocks;
|
||||||
char uuid[40], set_uuid[40];
|
char uuid[40], set_uuid[40], *dev;
|
||||||
struct cache_sb sb;
|
struct cache_sb sb;
|
||||||
|
|
||||||
memset(&sb, 0, sizeof(struct cache_sb));
|
memset(&sb, 0, sizeof(struct cache_sb));
|
||||||
@ -97,9 +98,6 @@ int main(int argc, char **argv)
|
|||||||
case 'w':
|
case 'w':
|
||||||
sb.block_size = hatoi(optarg) / 512;
|
sb.block_size = hatoi(optarg) / 512;
|
||||||
break;
|
break;
|
||||||
case 'j':
|
|
||||||
journal = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'U':
|
case 'U':
|
||||||
if (uuid_parse(optarg, sb.uuid)) {
|
if (uuid_parse(optarg, sb.uuid)) {
|
||||||
printf("Bad uuid\n");
|
printf("Bad uuid\n");
|
||||||
@ -130,51 +128,49 @@ int main(int argc, char **argv)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(argv[optind], O_RDWR);
|
dev = argv[optind];
|
||||||
|
fd = open(dev, O_RDWR);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("Can't open dev\n");
|
printf("Can't open dev %s: %s\n", dev, strerror(errno));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
nblocks = getblocks(fd);
|
nblocks = getblocks(fd);
|
||||||
printf("device is %ju sectors\n", nblocks);
|
printf("device is %ju sectors\n", nblocks);
|
||||||
|
|
||||||
if (sb.bucket_size < sb.block_size ||
|
sb.offset_this_sb = 8;
|
||||||
sb.bucket_size > nblocks / 8) {
|
|
||||||
printf("Bad bucket size %i\n", sb.bucket_size);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(sb.magic, bcache_magic, 16);
|
memcpy(sb.magic, bcache_magic, 16);
|
||||||
sb.version = backingdev ? CACHE_BACKING_DEV : 0;
|
sb.version = backingdev ? CACHE_BACKING_DEV : 0;
|
||||||
sb.nbuckets = nblocks / sb.bucket_size;
|
sb.nbuckets = nblocks / sb.bucket_size;
|
||||||
sb.nr_in_set = 1;
|
sb.nr_in_set = 1;
|
||||||
uuid_unparse(sb.uuid, uuid);
|
uuid_unparse(sb.uuid, uuid);
|
||||||
uuid_unparse(sb.set_uuid, set_uuid);
|
uuid_unparse(sb.set_uuid, set_uuid);
|
||||||
|
|
||||||
sb.journal_start = ((sb.nbuckets * sizeof(struct bucket_disk)) + (24 << 9)) / (sb.bucket_size << 9) + 1;
|
sb.first_bucket = (23 / sb.bucket_size) + 1;
|
||||||
sb.first_bucket = sb.journal_start + journal;
|
|
||||||
|
|
||||||
printf("block_size: %u\n"
|
if (cache)
|
||||||
"bucket_size: %u\n"
|
if (sb.bucket_size < sb.block_size ||
|
||||||
"journal_start: %u\n"
|
sb.bucket_size > nblocks / 8) {
|
||||||
"first_bucket: %u\n"
|
printf("Bad bucket size %i\n", sb.bucket_size);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("UUID: %s\n"
|
||||||
|
"Set UUID: %s\n"
|
||||||
"nbuckets: %ju\n"
|
"nbuckets: %ju\n"
|
||||||
"UUID: %s\n"
|
"block_size: %u\n"
|
||||||
"Set UUID: %s\n",
|
"bucket_size: %u\n"
|
||||||
|
"nr_in_set: %u\n"
|
||||||
|
"nr_this_dev: %u\n"
|
||||||
|
"first_bucket: %u\n"
|
||||||
|
"sizeof sb: %lu\n",
|
||||||
|
uuid, set_uuid,
|
||||||
|
sb.nbuckets,
|
||||||
sb.block_size,
|
sb.block_size,
|
||||||
sb.bucket_size,
|
sb.bucket_size,
|
||||||
sb.journal_start,
|
sb.nr_in_set,
|
||||||
|
sb.nr_this_dev,
|
||||||
sb.first_bucket,
|
sb.first_bucket,
|
||||||
sb.nbuckets,
|
sizeof(sb));
|
||||||
uuid, set_uuid);
|
|
||||||
|
|
||||||
if (!backingdev) {
|
|
||||||
/* Zero out priorities */
|
|
||||||
lseek(fd, 4096, SEEK_SET);
|
|
||||||
for (i = 8; i < sb.first_bucket * sb.bucket_size; i++)
|
|
||||||
if (write(fd, zero, 512) != 512)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pwrite(fd, &sb, sizeof(sb), 4096) != sizeof(sb))
|
if (pwrite(fd, &sb, sizeof(sb), 4096) != sizeof(sb))
|
||||||
goto err;
|
goto err;
|
||||||
|
Loading…
Reference in New Issue
Block a user