mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-09 00:00:04 +03:00
bcache device_show now dumps superblocks
This commit is contained in:
parent
837a476cc1
commit
f3a8d54837
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ LDFLAGS+=-static
|
|||||||
|
|
||||||
PKGCONFIG_LIBS="blkid uuid libnih"
|
PKGCONFIG_LIBS="blkid uuid libnih"
|
||||||
CFLAGS+=`pkg-config --cflags ${PKGCONFIG_LIBS}`
|
CFLAGS+=`pkg-config --cflags ${PKGCONFIG_LIBS}`
|
||||||
LDLIBS+=`pkg-config --libs ${PKGCONFIG_LIBS}` -lscrypt -lsodium -lkeyutils
|
LDLIBS+=`pkg-config --libs ${PKGCONFIG_LIBS}` -lscrypt -lsodium -lkeyutils -lm
|
||||||
|
|
||||||
ifeq ($(PREFIX),/usr)
|
ifeq ($(PREFIX),/usr)
|
||||||
ROOT_SBINDIR=/sbin
|
ROOT_SBINDIR=/sbin
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
#include <nih/option.h>
|
#include <nih/option.h>
|
||||||
|
|
||||||
#include "bcache.h"
|
#include "bcache.h"
|
||||||
|
#include "libbcache.h"
|
||||||
|
|
||||||
|
/* This code belongs under show_fs */
|
||||||
|
#if 0
|
||||||
|
|
||||||
struct bcache_dev {
|
struct bcache_dev {
|
||||||
unsigned nr;
|
unsigned nr;
|
||||||
@ -162,6 +166,20 @@ int cmd_device_show(int argc, char *argv[])
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int cmd_device_show(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct cache_sb *sb;
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
die("please supply a single device");
|
||||||
|
|
||||||
|
sb = bcache_super_read(argv[1]);
|
||||||
|
bcache_super_print(sb, HUMAN_READABLE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cmd_device_add(int argc, char *argv[])
|
int cmd_device_add(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
12
bcache-key.c
12
bcache-key.c
@ -18,7 +18,7 @@ int cmd_unlock(int argc, char *argv[])
|
|||||||
|
|
||||||
struct bcache_disk_key disk_key;
|
struct bcache_disk_key disk_key;
|
||||||
struct bcache_key key;
|
struct bcache_key key;
|
||||||
struct cache_sb sb;
|
struct cache_sb *sb;
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
char uuid[40];
|
char uuid[40];
|
||||||
char description[60];
|
char description[60];
|
||||||
@ -26,12 +26,12 @@ int cmd_unlock(int argc, char *argv[])
|
|||||||
if (!args[0] || args[1])
|
if (!args[0] || args[1])
|
||||||
die("please supply a single device");
|
die("please supply a single device");
|
||||||
|
|
||||||
bcache_super_read(args[0], &sb);
|
sb = bcache_super_read(args[0]);
|
||||||
|
|
||||||
if (!CACHE_SET_ENCRYPTION_KEY(&sb))
|
if (!CACHE_SET_ENCRYPTION_KEY(sb))
|
||||||
die("filesystem is not encrypted");
|
die("filesystem is not encrypted");
|
||||||
|
|
||||||
memcpy(&disk_key, sb.encryption_key, sizeof(disk_key));
|
memcpy(&disk_key, sb->encryption_key, sizeof(disk_key));
|
||||||
|
|
||||||
if (!memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
if (!memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
||||||
die("filesystem does not have encryption key");
|
die("filesystem does not have encryption key");
|
||||||
@ -39,12 +39,12 @@ int cmd_unlock(int argc, char *argv[])
|
|||||||
passphrase = read_passphrase("Enter passphrase: ");
|
passphrase = read_passphrase("Enter passphrase: ");
|
||||||
|
|
||||||
derive_passphrase(&key, passphrase);
|
derive_passphrase(&key, passphrase);
|
||||||
disk_key_encrypt(&sb, &disk_key, &key);
|
disk_key_encrypt(sb, &disk_key, &key);
|
||||||
|
|
||||||
if (memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
if (memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
||||||
die("incorrect passphrase");
|
die("incorrect passphrase");
|
||||||
|
|
||||||
uuid_unparse_lower(sb.user_uuid.b, uuid);
|
uuid_unparse_lower(sb->user_uuid.b, uuid);
|
||||||
sprintf(description, "bcache:%s", uuid);
|
sprintf(description, "bcache:%s", uuid);
|
||||||
|
|
||||||
if (add_key("logon", description, &key, sizeof(key),
|
if (add_key("logon", description, &key, sizeof(key),
|
||||||
|
@ -670,6 +670,7 @@ LE64_BITMASK(CACHE_STATE, struct cache_member, f1, 0, 4)
|
|||||||
#define CACHE_RO 1U
|
#define CACHE_RO 1U
|
||||||
#define CACHE_FAILED 2U
|
#define CACHE_FAILED 2U
|
||||||
#define CACHE_SPARE 3U
|
#define CACHE_SPARE 3U
|
||||||
|
#define CACHE_STATE_NR 4U
|
||||||
|
|
||||||
LE64_BITMASK(CACHE_TIER, struct cache_member, f1, 4, 8)
|
LE64_BITMASK(CACHE_TIER, struct cache_member, f1, 4, 8)
|
||||||
#define CACHE_TIERS 4U
|
#define CACHE_TIERS 4U
|
||||||
@ -683,6 +684,7 @@ LE64_BITMASK(CACHE_REPLACEMENT, struct cache_member, f1, 26, 30)
|
|||||||
#define CACHE_REPLACEMENT_LRU 0U
|
#define CACHE_REPLACEMENT_LRU 0U
|
||||||
#define CACHE_REPLACEMENT_FIFO 1U
|
#define CACHE_REPLACEMENT_FIFO 1U
|
||||||
#define CACHE_REPLACEMENT_RANDOM 2U
|
#define CACHE_REPLACEMENT_RANDOM 2U
|
||||||
|
#define CACHE_REPLACEMENT_NR 3U
|
||||||
|
|
||||||
LE64_BITMASK(CACHE_DISCARD, struct cache_member, f1, 30, 31);
|
LE64_BITMASK(CACHE_DISCARD, struct cache_member, f1, 30, 31);
|
||||||
|
|
||||||
@ -770,18 +772,7 @@ LE64_BITMASK(CACHE_SET_META_CSUM_TYPE,struct cache_sb, flags, 16, 20);
|
|||||||
#define BCH_CSUM_NONE 0U
|
#define BCH_CSUM_NONE 0U
|
||||||
#define BCH_CSUM_CRC32C 1U
|
#define BCH_CSUM_CRC32C 1U
|
||||||
#define BCH_CSUM_CRC64 2U
|
#define BCH_CSUM_CRC64 2U
|
||||||
#define BCH_CSUM_CHACHA20_POLY1305 3U
|
#define BCH_CSUM_NR 3U
|
||||||
#define BCH_CSUM_NR 4U
|
|
||||||
|
|
||||||
static inline _Bool bch_csum_type_is_encryption(unsigned type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case BCH_CSUM_CHACHA20_POLY1305:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LE64_BITMASK(CACHE_SET_BTREE_NODE_SIZE, struct cache_sb, flags, 20, 36);
|
LE64_BITMASK(CACHE_SET_BTREE_NODE_SIZE, struct cache_sb, flags, 20, 36);
|
||||||
|
|
||||||
@ -816,6 +807,12 @@ LE64_BITMASK(CACHE_SET_GC_RESERVE, struct cache_sb, flags, 57, 63);
|
|||||||
|
|
||||||
LE64_BITMASK(CACHE_SET_ROOT_RESERVE, struct cache_sb, flags2, 0, 6);
|
LE64_BITMASK(CACHE_SET_ROOT_RESERVE, struct cache_sb, flags2, 0, 6);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Did we shut down cleanly? Just a hint, doesn't affect behaviour of
|
||||||
|
* mount/recovery path:
|
||||||
|
*/
|
||||||
|
LE64_BITMASK(CACHE_SET_CLEAN, struct cache_sb, flags2, 6, 7);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If nonzero, encryption is enabled; overrides DATA/META_CSUM_TYPE. Also
|
* If nonzero, encryption is enabled; overrides DATA/META_CSUM_TYPE. Also
|
||||||
* indicates encryption algorithm in use, if/when we get more than one:
|
* indicates encryption algorithm in use, if/when we get more than one:
|
||||||
|
52
bcache.c
52
bcache.c
@ -23,58 +23,6 @@
|
|||||||
|
|
||||||
#include "bcache.h"
|
#include "bcache.h"
|
||||||
|
|
||||||
const char * const cache_state[] = {
|
|
||||||
"active",
|
|
||||||
"ro",
|
|
||||||
"failed",
|
|
||||||
"spare",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
const char * const replacement_policies[] = {
|
|
||||||
"lru",
|
|
||||||
"fifo",
|
|
||||||
"random",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
const char * const csum_types[] = {
|
|
||||||
"none",
|
|
||||||
"crc32c",
|
|
||||||
"crc64",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
const char * const compression_types[] = {
|
|
||||||
"none",
|
|
||||||
"lz4",
|
|
||||||
"gzip",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
const char * const error_actions[] = {
|
|
||||||
"continue",
|
|
||||||
"readonly",
|
|
||||||
"panic",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
const char * const bdev_cache_mode[] = {
|
|
||||||
"writethrough",
|
|
||||||
"writeback",
|
|
||||||
"writearound",
|
|
||||||
"none",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
const char * const bdev_state[] = {
|
|
||||||
"detached",
|
|
||||||
"clean",
|
|
||||||
"dirty",
|
|
||||||
"inconsistent",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
puts("bcache - tool for managing bcache volumes/filesystems\n"
|
puts("bcache - tool for managing bcache volumes/filesystems\n"
|
||||||
|
8
bcache.h
8
bcache.h
@ -9,14 +9,6 @@
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
extern const char * const cache_state[];
|
|
||||||
extern const char * const replacement_policies[];
|
|
||||||
extern const char * const csum_types[];
|
|
||||||
extern const char * const compression_types[];
|
|
||||||
extern const char * const error_actions[];
|
|
||||||
extern const char * const bdev_cache_mode[];
|
|
||||||
extern const char * const bdev_state[];
|
|
||||||
|
|
||||||
int cmd_format(int argc, char *argv[]);
|
int cmd_format(int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_unlock(int argc, char *argv[]);
|
int cmd_unlock(int argc, char *argv[]);
|
||||||
|
223
libbcache.c
223
libbcache.c
@ -17,6 +17,74 @@
|
|||||||
#include "libbcache.h"
|
#include "libbcache.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
|
const char * const cache_state[] = {
|
||||||
|
"active",
|
||||||
|
"ro",
|
||||||
|
"failed",
|
||||||
|
"spare",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const replacement_policies[] = {
|
||||||
|
"lru",
|
||||||
|
"fifo",
|
||||||
|
"random",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const csum_types[] = {
|
||||||
|
"none",
|
||||||
|
"crc32c",
|
||||||
|
"crc64",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const compression_types[] = {
|
||||||
|
"none",
|
||||||
|
"lz4",
|
||||||
|
"gzip",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const str_hash_types[] = {
|
||||||
|
"crc32c",
|
||||||
|
"crc64",
|
||||||
|
"siphash",
|
||||||
|
"sha1",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const error_actions[] = {
|
||||||
|
"continue",
|
||||||
|
"readonly",
|
||||||
|
"panic",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const member_states[] = {
|
||||||
|
"active",
|
||||||
|
"ro",
|
||||||
|
"failed",
|
||||||
|
"spare",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const bdev_cache_mode[] = {
|
||||||
|
"writethrough",
|
||||||
|
"writeback",
|
||||||
|
"writearound",
|
||||||
|
"none",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char * const bdev_state[] = {
|
||||||
|
"detached",
|
||||||
|
"clean",
|
||||||
|
"dirty",
|
||||||
|
"inconsistent",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
#define BCH_MIN_NR_NBUCKETS (1 << 10)
|
#define BCH_MIN_NR_NBUCKETS (1 << 10)
|
||||||
|
|
||||||
/* first bucket should start 1 mb in, in sectors: */
|
/* first bucket should start 1 mb in, in sectors: */
|
||||||
@ -187,48 +255,155 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
|||||||
|
|
||||||
for (i = devs; i < devs + nr_devs; i++) {
|
for (i = devs; i < devs + nr_devs; i++) {
|
||||||
struct cache_member *m = sb->members + (i - devs);
|
struct cache_member *m = sb->members + (i - devs);
|
||||||
char uuid_str[40], set_uuid_str[40];
|
|
||||||
|
|
||||||
sb->disk_uuid = m->uuid;
|
sb->disk_uuid = m->uuid;
|
||||||
sb->nr_this_dev = i - devs;
|
sb->nr_this_dev = i - devs;
|
||||||
sb->csum = __cpu_to_le64(__csum_set(sb, __le16_to_cpu(sb->u64s),
|
sb->csum = __cpu_to_le64(__csum_set(sb, __le16_to_cpu(sb->u64s),
|
||||||
CACHE_SB_CSUM_TYPE(sb)));
|
CACHE_SB_CSUM_TYPE(sb)));
|
||||||
|
|
||||||
uuid_unparse(sb->disk_uuid.b, uuid_str);
|
|
||||||
uuid_unparse(sb->user_uuid.b, set_uuid_str);
|
|
||||||
printf("UUID: %s\n"
|
|
||||||
"Set UUID: %s\n"
|
|
||||||
"version: %u\n"
|
|
||||||
"nbuckets: %llu\n"
|
|
||||||
"block_size: %u\n"
|
|
||||||
"bucket_size: %u\n"
|
|
||||||
"nr_in_set: %u\n"
|
|
||||||
"nr_this_dev: %u\n"
|
|
||||||
"first_bucket: %u\n",
|
|
||||||
uuid_str, set_uuid_str,
|
|
||||||
(unsigned) sb->version,
|
|
||||||
__le64_to_cpu(m->nbuckets),
|
|
||||||
__le16_to_cpu(sb->block_size),
|
|
||||||
__le16_to_cpu(m->bucket_size),
|
|
||||||
sb->nr_in_set,
|
|
||||||
sb->nr_this_dev,
|
|
||||||
__le16_to_cpu(m->first_bucket));
|
|
||||||
|
|
||||||
do_write_sb(i->fd, sb);
|
do_write_sb(i->fd, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bcache_super_print(sb, HUMAN_READABLE);
|
||||||
|
|
||||||
free(sb);
|
free(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bcache_super_read(const char *path, struct cache_sb *sb)
|
void bcache_super_print(struct cache_sb *sb, int units)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
char user_uuid_str[40], internal_uuid_str[40], member_uuid_str[40];
|
||||||
|
char label[SB_LABEL_SIZE + 1];
|
||||||
|
|
||||||
|
memset(label, 0, sizeof(label));
|
||||||
|
memcpy(label, sb->label, sizeof(sb->label));
|
||||||
|
uuid_unparse(sb->user_uuid.b, user_uuid_str);
|
||||||
|
uuid_unparse(sb->set_uuid.b, internal_uuid_str);
|
||||||
|
|
||||||
|
printf("External UUID: %s\n"
|
||||||
|
"Internal UUID: %s\n"
|
||||||
|
"Label: %s\n"
|
||||||
|
"Version: %llu\n"
|
||||||
|
"Block_size: %s\n"
|
||||||
|
"Btree node size: %s\n"
|
||||||
|
"Error action: %s\n"
|
||||||
|
"Clean: %llu\n"
|
||||||
|
|
||||||
|
"Metadata replicas: have %llu, want %llu\n"
|
||||||
|
"Data replicas: have %llu, want %llu\n"
|
||||||
|
|
||||||
|
"Metadata checksum type: %s\n"
|
||||||
|
"Data checksum type: %s\n"
|
||||||
|
"Compression type: %s\n"
|
||||||
|
|
||||||
|
"String hash type: %s\n"
|
||||||
|
"32 bit inodes: %llu\n"
|
||||||
|
"GC reserve percentage: %llu%%\n"
|
||||||
|
"Root reserve percentage: %llu%%\n"
|
||||||
|
|
||||||
|
"Devices: %u\n",
|
||||||
|
user_uuid_str,
|
||||||
|
internal_uuid_str,
|
||||||
|
label,
|
||||||
|
le64_to_cpu(sb->version),
|
||||||
|
pr_units(le16_to_cpu(sb->block_size), units).b,
|
||||||
|
pr_units(CACHE_SET_BTREE_NODE_SIZE(sb), units).b,
|
||||||
|
|
||||||
|
CACHE_SET_ERROR_ACTION(sb) < BCH_NR_ERROR_ACTIONS
|
||||||
|
? error_actions[CACHE_SET_ERROR_ACTION(sb)]
|
||||||
|
: "unknown",
|
||||||
|
|
||||||
|
CACHE_SET_CLEAN(sb),
|
||||||
|
|
||||||
|
CACHE_SET_META_REPLICAS_HAVE(sb),
|
||||||
|
CACHE_SET_META_REPLICAS_WANT(sb),
|
||||||
|
CACHE_SET_DATA_REPLICAS_HAVE(sb),
|
||||||
|
CACHE_SET_DATA_REPLICAS_WANT(sb),
|
||||||
|
|
||||||
|
CACHE_SET_META_CSUM_TYPE(sb) < BCH_CSUM_NR
|
||||||
|
? csum_types[CACHE_SET_META_CSUM_TYPE(sb)]
|
||||||
|
: "unknown",
|
||||||
|
|
||||||
|
CACHE_SET_DATA_CSUM_TYPE(sb) < BCH_CSUM_NR
|
||||||
|
? csum_types[CACHE_SET_DATA_CSUM_TYPE(sb)]
|
||||||
|
: "unknown",
|
||||||
|
|
||||||
|
CACHE_SET_COMPRESSION_TYPE(sb) < BCH_COMPRESSION_NR
|
||||||
|
? compression_types[CACHE_SET_COMPRESSION_TYPE(sb)]
|
||||||
|
: "unknown",
|
||||||
|
|
||||||
|
CACHE_SET_STR_HASH_TYPE(sb) < BCH_STR_HASH_NR
|
||||||
|
? str_hash_types[CACHE_SET_STR_HASH_TYPE(sb)]
|
||||||
|
: "unknown",
|
||||||
|
|
||||||
|
CACHE_INODE_32BIT(sb),
|
||||||
|
CACHE_SET_GC_RESERVE(sb),
|
||||||
|
CACHE_SET_ROOT_RESERVE(sb),
|
||||||
|
|
||||||
|
sb->nr_in_set);
|
||||||
|
|
||||||
|
for (i = 0; i < sb->nr_in_set; i++) {
|
||||||
|
struct cache_member *m = sb->members + i;
|
||||||
|
time_t last_mount = le64_to_cpu(m->last_mount);
|
||||||
|
|
||||||
|
uuid_unparse(m->uuid.b, member_uuid_str);
|
||||||
|
|
||||||
|
printf("\n"
|
||||||
|
"Device %u:\n"
|
||||||
|
" UUID: %s\n"
|
||||||
|
" bucket_size: %s\n"
|
||||||
|
" first_bucket: %u\n"
|
||||||
|
" nbuckets: %llu\n"
|
||||||
|
" Last mount: %s\n"
|
||||||
|
" State: %s\n"
|
||||||
|
" Tier: %llu\n"
|
||||||
|
" Has metadata: %llu\n"
|
||||||
|
" Has data: %llu\n"
|
||||||
|
" Replacement policy: %s\n"
|
||||||
|
" Discard: %llu\n",
|
||||||
|
i, member_uuid_str,
|
||||||
|
pr_units(le16_to_cpu(m->bucket_size), units).b,
|
||||||
|
le16_to_cpu(m->first_bucket),
|
||||||
|
le64_to_cpu(m->nbuckets),
|
||||||
|
last_mount ? ctime(&last_mount) : "(never)",
|
||||||
|
|
||||||
|
CACHE_STATE(m) < CACHE_STATE_NR
|
||||||
|
? member_states[CACHE_STATE(m)]
|
||||||
|
: "unknown",
|
||||||
|
|
||||||
|
CACHE_TIER(m),
|
||||||
|
CACHE_HAS_METADATA(m),
|
||||||
|
CACHE_HAS_DATA(m),
|
||||||
|
|
||||||
|
CACHE_REPLACEMENT(m) < CACHE_REPLACEMENT_NR
|
||||||
|
? replacement_policies[CACHE_REPLACEMENT(m)]
|
||||||
|
: "unknown",
|
||||||
|
|
||||||
|
CACHE_DISCARD(m));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cache_sb *bcache_super_read(const char *path)
|
||||||
|
{
|
||||||
|
struct cache_sb sb, *ret;
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
int fd = open(path, O_RDONLY);
|
int fd = open(path, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
die("couldn't open %s", path);
|
die("couldn't open %s", path);
|
||||||
|
|
||||||
if (pread(fd, sb, sizeof(*sb), SB_SECTOR << 9) != sizeof(*sb))
|
if (pread(fd, &sb, sizeof(sb), SB_SECTOR << 9) != sizeof(sb))
|
||||||
die("error reading superblock");
|
die("error reading superblock");
|
||||||
|
|
||||||
if (memcmp(&sb->magic, &BCACHE_MAGIC, sizeof(sb->magic)))
|
if (memcmp(&sb.magic, &BCACHE_MAGIC, sizeof(sb.magic)))
|
||||||
die("not a bcache superblock");
|
die("not a bcache superblock");
|
||||||
|
|
||||||
|
bytes = sizeof(sb) + le16_to_cpu(sb.u64s) * sizeof(u64);
|
||||||
|
|
||||||
|
ret = calloc(1, bytes);
|
||||||
|
|
||||||
|
if (pread(fd, ret, bytes, SB_SECTOR << 9) != bytes)
|
||||||
|
die("error reading superblock");
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
13
libbcache.h
13
libbcache.h
@ -4,6 +4,15 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
extern const char * const cache_state[];
|
||||||
|
extern const char * const replacement_policies[];
|
||||||
|
extern const char * const csum_types[];
|
||||||
|
extern const char * const compression_types[];
|
||||||
|
extern const char * const str_hash_types[];
|
||||||
|
extern const char * const error_actions[];
|
||||||
|
extern const char * const bdev_cache_mode[];
|
||||||
|
extern const char * const bdev_state[];
|
||||||
|
|
||||||
struct dev_opts {
|
struct dev_opts {
|
||||||
int fd;
|
int fd;
|
||||||
const char *path;
|
const char *path;
|
||||||
@ -29,6 +38,8 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
|||||||
char *label,
|
char *label,
|
||||||
uuid_le uuid);
|
uuid_le uuid);
|
||||||
|
|
||||||
void bcache_super_read(const char *, struct cache_sb *);
|
void bcache_super_print(struct cache_sb *, int);
|
||||||
|
|
||||||
|
struct cache_sb *bcache_super_read(const char *);
|
||||||
|
|
||||||
#endif /* _LIBBCACHE_H */
|
#endif /* _LIBBCACHE_H */
|
||||||
|
30
util.c
30
util.c
@ -4,6 +4,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -69,6 +70,35 @@ char *strim(char *s)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct units_buf pr_units(u64 v, enum units units)
|
||||||
|
{
|
||||||
|
struct units_buf ret;
|
||||||
|
|
||||||
|
switch (units) {
|
||||||
|
case BYTES:
|
||||||
|
snprintf(ret.b, sizeof(ret.b), "%llu", v << 9);
|
||||||
|
break;
|
||||||
|
case SECTORS:
|
||||||
|
snprintf(ret.b, sizeof(ret.b), "%llu", v);
|
||||||
|
break;
|
||||||
|
case HUMAN_READABLE:
|
||||||
|
v <<= 9;
|
||||||
|
|
||||||
|
if (v >= 1024) {
|
||||||
|
int exp = log(v) / log(1024);
|
||||||
|
snprintf(ret.b, sizeof(ret.b), "%.1f%c",
|
||||||
|
v / pow(1024, exp),
|
||||||
|
"KMGTPE"[exp-1]);
|
||||||
|
} else {
|
||||||
|
snprintf(ret.b, sizeof(ret.b), "%llu", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Argument parsing stuff: */
|
/* Argument parsing stuff: */
|
||||||
|
|
||||||
long strtoul_or_die(const char *p, size_t max, const char *msg)
|
long strtoul_or_die(const char *p, size_t max, const char *msg)
|
||||||
|
37
util.h
37
util.h
@ -9,6 +9,7 @@
|
|||||||
/* linux kernel style types: */
|
/* linux kernel style types: */
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
typedef __u8 u8;
|
typedef __u8 u8;
|
||||||
typedef __u16 u16;
|
typedef __u16 u16;
|
||||||
@ -20,6 +21,29 @@ typedef __s16 s16;
|
|||||||
typedef __s32 s32;
|
typedef __s32 s32;
|
||||||
typedef __s64 s64;
|
typedef __s64 s64;
|
||||||
|
|
||||||
|
#define cpu_to_le16 __cpu_to_le16
|
||||||
|
#define cpu_to_le32 __cpu_to_le32
|
||||||
|
#define cpu_to_le64 __cpu_to_le64
|
||||||
|
|
||||||
|
#define le16_to_cpu __le16_to_cpu
|
||||||
|
#define le32_to_cpu __le32_to_cpu
|
||||||
|
#define le64_to_cpu __le64_to_cpu
|
||||||
|
|
||||||
|
static inline void le16_add_cpu(__le16 *var, u16 val)
|
||||||
|
{
|
||||||
|
*var = cpu_to_le16(le16_to_cpu(*var) + val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le32_add_cpu(__le32 *var, u32 val)
|
||||||
|
{
|
||||||
|
*var = cpu_to_le32(le32_to_cpu(*var) + val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void le64_add_cpu(__le64 *var, u64 val)
|
||||||
|
{
|
||||||
|
*var = cpu_to_le64(le64_to_cpu(*var) + val);
|
||||||
|
}
|
||||||
|
|
||||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||||
|
|
||||||
#define min(x, y) ({ \
|
#define min(x, y) ({ \
|
||||||
@ -46,7 +70,20 @@ unsigned ilog2(u64);
|
|||||||
char *skip_spaces(const char *str);
|
char *skip_spaces(const char *str);
|
||||||
char *strim(char *s);
|
char *strim(char *s);
|
||||||
|
|
||||||
|
enum units {
|
||||||
|
BYTES,
|
||||||
|
SECTORS,
|
||||||
|
HUMAN_READABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct units_buf pr_units(u64, enum units);
|
||||||
|
|
||||||
|
struct units_buf {
|
||||||
|
char b[20];
|
||||||
|
};
|
||||||
|
|
||||||
long strtoul_or_die(const char *, size_t, const char *);
|
long strtoul_or_die(const char *, size_t, const char *);
|
||||||
|
|
||||||
u64 hatoi(const char *);
|
u64 hatoi(const char *);
|
||||||
unsigned hatoi_validate(const char *, const char *);
|
unsigned hatoi_validate(const char *, const char *);
|
||||||
unsigned nr_args(char * const *);
|
unsigned nr_args(char * const *);
|
||||||
|
Loading…
Reference in New Issue
Block a user