mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-09 00:00:04 +03:00
add support for maximum journal entry size
also rip out prototype crypto support code - real code is in the dev branch, with the new superblock format
This commit is contained in:
parent
4e158e1553
commit
7f4191a202
11
Makefile
11
Makefile
@ -6,7 +6,7 @@ LDFLAGS+=-static
|
|||||||
|
|
||||||
PKGCONFIG_LIBS="blkid uuid"
|
PKGCONFIG_LIBS="blkid uuid"
|
||||||
CFLAGS+=`pkg-config --cflags ${PKGCONFIG_LIBS}`
|
CFLAGS+=`pkg-config --cflags ${PKGCONFIG_LIBS}`
|
||||||
LDLIBS+=`pkg-config --libs ${PKGCONFIG_LIBS}` -lscrypt -lsodium -lkeyutils -lm
|
LDLIBS+=`pkg-config --libs ${PKGCONFIG_LIBS}` -lm
|
||||||
|
|
||||||
ifeq ($(PREFIX),/usr)
|
ifeq ($(PREFIX),/usr)
|
||||||
ROOT_SBINDIR=/sbin
|
ROOT_SBINDIR=/sbin
|
||||||
@ -24,7 +24,7 @@ libccan.a: $(CCANOBJS)
|
|||||||
$(AR) r $@ $(CCANOBJS)
|
$(AR) r $@ $(CCANOBJS)
|
||||||
|
|
||||||
bcache-objs = bcache.o bcache-assemble.o bcache-device.o bcache-format.o\
|
bcache-objs = bcache.o bcache-assemble.o bcache-device.o bcache-format.o\
|
||||||
bcache-fs.o bcache-run.o bcache-key.o libbcache.o crypto.o util.o
|
bcache-fs.o bcache-run.o libbcache.o util.o
|
||||||
|
|
||||||
-include $(bcache-objs:.o=.d)
|
-include $(bcache-objs:.o=.d)
|
||||||
|
|
||||||
@ -44,4 +44,9 @@ clean:
|
|||||||
|
|
||||||
.PHONY: deb
|
.PHONY: deb
|
||||||
deb: all
|
deb: all
|
||||||
debuild -nc -us -uc -i -I
|
debuild --unsigned-source \
|
||||||
|
--unsigned-changes \
|
||||||
|
--no-pre-clean \
|
||||||
|
--build=binary \
|
||||||
|
--diff-ignore \
|
||||||
|
--tar-ignore
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include "bcache.h"
|
#include "bcache.h"
|
||||||
#include "libbcache.h"
|
#include "libbcache.h"
|
||||||
#include "crypto.h"
|
|
||||||
|
|
||||||
/* Open a block device, do magic blkid stuff: */
|
/* Open a block device, do magic blkid stuff: */
|
||||||
static int open_for_format(const char *dev, bool force)
|
static int open_for_format(const char *dev, bool force)
|
||||||
@ -80,9 +79,9 @@ static void usage(void)
|
|||||||
" --metadata_checksum_type=(none|crc32c|crc64)\n"
|
" --metadata_checksum_type=(none|crc32c|crc64)\n"
|
||||||
" --data_checksum_type=(none|crc32c|crc64)\n"
|
" --data_checksum_type=(none|crc32c|crc64)\n"
|
||||||
" --compression_type=(none|lz4|gzip)\n"
|
" --compression_type=(none|lz4|gzip)\n"
|
||||||
" --encrypted\n"
|
|
||||||
" --error_action=(continue|readonly|panic)\n"
|
" --error_action=(continue|readonly|panic)\n"
|
||||||
" Action to take on filesystem error\n"
|
" Action to take on filesystem error\n"
|
||||||
|
" --max_journal_entry_size=size\n"
|
||||||
" -l, --label=label\n"
|
" -l, --label=label\n"
|
||||||
" --uuid=uuid\n"
|
" --uuid=uuid\n"
|
||||||
" -f, --force\n"
|
" -f, --force\n"
|
||||||
@ -108,8 +107,8 @@ static void usage(void)
|
|||||||
OPT(0, metadata_checksum_type, required_argument) \
|
OPT(0, metadata_checksum_type, required_argument) \
|
||||||
OPT(0, data_checksum_type, required_argument) \
|
OPT(0, data_checksum_type, required_argument) \
|
||||||
OPT(0, compression_type, required_argument) \
|
OPT(0, compression_type, required_argument) \
|
||||||
OPT(0, encrypted, no_argument) \
|
|
||||||
OPT('e', error_action, required_argument) \
|
OPT('e', error_action, required_argument) \
|
||||||
|
OPT(0, max_journal_entry_size, required_argument) \
|
||||||
OPT('L', label, required_argument) \
|
OPT('L', label, required_argument) \
|
||||||
OPT('U', uuid, required_argument) \
|
OPT('U', uuid, required_argument) \
|
||||||
OPT('f', force, no_argument) \
|
OPT('f', force, no_argument) \
|
||||||
@ -144,7 +143,6 @@ int cmd_format(int argc, char *argv[])
|
|||||||
unsigned meta_csum_type = BCH_CSUM_CRC32C;
|
unsigned meta_csum_type = BCH_CSUM_CRC32C;
|
||||||
unsigned data_csum_type = BCH_CSUM_CRC32C;
|
unsigned data_csum_type = BCH_CSUM_CRC32C;
|
||||||
unsigned compression_type = BCH_COMPRESSION_NONE;
|
unsigned compression_type = BCH_COMPRESSION_NONE;
|
||||||
bool encrypted = false;
|
|
||||||
unsigned on_error_action = BCH_ON_ERROR_RO;
|
unsigned on_error_action = BCH_ON_ERROR_RO;
|
||||||
char *label = NULL;
|
char *label = NULL;
|
||||||
uuid_le uuid;
|
uuid_le uuid;
|
||||||
@ -155,6 +153,7 @@ int cmd_format(int argc, char *argv[])
|
|||||||
unsigned bucket_size = 0;
|
unsigned bucket_size = 0;
|
||||||
unsigned tier = 0;
|
unsigned tier = 0;
|
||||||
bool discard = false;
|
bool discard = false;
|
||||||
|
unsigned max_journal_entry_size = 0;
|
||||||
char *passphrase = NULL;
|
char *passphrase = NULL;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
@ -187,14 +186,15 @@ int cmd_format(int argc, char *argv[])
|
|||||||
compression_type = read_string_list_or_die(optarg,
|
compression_type = read_string_list_or_die(optarg,
|
||||||
compression_types, "compression type");
|
compression_types, "compression type");
|
||||||
break;
|
break;
|
||||||
case Opt_encrypted:
|
|
||||||
encrypted = true;
|
|
||||||
break;
|
|
||||||
case Opt_error_action:
|
case Opt_error_action:
|
||||||
case 'e':
|
case 'e':
|
||||||
on_error_action = read_string_list_or_die(optarg,
|
on_error_action = read_string_list_or_die(optarg,
|
||||||
error_actions, "error action");
|
error_actions, "error action");
|
||||||
break;
|
break;
|
||||||
|
case Opt_max_journal_entry_size:
|
||||||
|
max_journal_entry_size = hatoi_validate(optarg,
|
||||||
|
"journal entry size");
|
||||||
|
break;
|
||||||
case Opt_label:
|
case Opt_label:
|
||||||
case 'L':
|
case 'L':
|
||||||
label = strdup(optarg);
|
label = strdup(optarg);
|
||||||
@ -242,22 +242,6 @@ int cmd_format(int argc, char *argv[])
|
|||||||
if (uuid_is_null(uuid.b))
|
if (uuid_is_null(uuid.b))
|
||||||
uuid_generate(uuid.b);
|
uuid_generate(uuid.b);
|
||||||
|
|
||||||
if (encrypted) {
|
|
||||||
char *pass2;
|
|
||||||
|
|
||||||
passphrase = read_passphrase("Enter passphrase: ");
|
|
||||||
pass2 = read_passphrase("Enter same passphrase again: ");
|
|
||||||
|
|
||||||
if (strcmp(passphrase, pass2)) {
|
|
||||||
memzero_explicit(passphrase, strlen(passphrase));
|
|
||||||
memzero_explicit(pass2, strlen(pass2));
|
|
||||||
die("Passphrases do not match");
|
|
||||||
}
|
|
||||||
|
|
||||||
memzero_explicit(pass2, strlen(pass2));
|
|
||||||
free(pass2);
|
|
||||||
}
|
|
||||||
|
|
||||||
darray_foreach(dev, devices)
|
darray_foreach(dev, devices)
|
||||||
dev->fd = open_for_format(dev->path, force);
|
dev->fd = open_for_format(dev->path, force);
|
||||||
|
|
||||||
@ -267,10 +251,10 @@ int cmd_format(int argc, char *argv[])
|
|||||||
meta_csum_type,
|
meta_csum_type,
|
||||||
data_csum_type,
|
data_csum_type,
|
||||||
compression_type,
|
compression_type,
|
||||||
passphrase,
|
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
on_error_action,
|
on_error_action,
|
||||||
|
max_journal_entry_size,
|
||||||
label,
|
label,
|
||||||
uuid);
|
uuid);
|
||||||
|
|
||||||
|
52
bcache-key.c
52
bcache-key.c
@ -1,52 +0,0 @@
|
|||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <keyutils.h>
|
|
||||||
#include <uuid/uuid.h>
|
|
||||||
|
|
||||||
#include "bcache.h"
|
|
||||||
#include "libbcache.h"
|
|
||||||
#include "crypto.h"
|
|
||||||
|
|
||||||
int cmd_unlock(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct bcache_disk_key disk_key;
|
|
||||||
struct bcache_key key;
|
|
||||||
struct cache_sb *sb;
|
|
||||||
char *passphrase;
|
|
||||||
char uuid[40];
|
|
||||||
char description[60];
|
|
||||||
|
|
||||||
if (argc != 2)
|
|
||||||
die("please supply a single device");
|
|
||||||
|
|
||||||
sb = bcache_super_read(argv[1]);
|
|
||||||
|
|
||||||
if (!CACHE_SET_ENCRYPTION_KEY(sb))
|
|
||||||
die("filesystem is not encrypted");
|
|
||||||
|
|
||||||
memcpy(&disk_key, sb->encryption_key, sizeof(disk_key));
|
|
||||||
|
|
||||||
if (!memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
|
||||||
die("filesystem does not have encryption key");
|
|
||||||
|
|
||||||
passphrase = read_passphrase("Enter passphrase: ");
|
|
||||||
|
|
||||||
derive_passphrase(&key, passphrase);
|
|
||||||
disk_key_encrypt(sb, &disk_key, &key);
|
|
||||||
|
|
||||||
if (memcmp(&disk_key, bch_key_header, sizeof(bch_key_header)))
|
|
||||||
die("incorrect passphrase");
|
|
||||||
|
|
||||||
uuid_unparse_lower(sb->user_uuid.b, uuid);
|
|
||||||
sprintf(description, "bcache:%s", uuid);
|
|
||||||
|
|
||||||
if (add_key("logon", description, &key, sizeof(key),
|
|
||||||
KEY_SPEC_USER_KEYRING) < 0)
|
|
||||||
die("add_key error: %s", strerror(errno));
|
|
||||||
|
|
||||||
memzero_explicit(&disk_key, sizeof(disk_key));
|
|
||||||
memzero_explicit(&key, sizeof(key));
|
|
||||||
memzero_explicit(passphrase, strlen(passphrase));
|
|
||||||
free(passphrase);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -813,21 +813,7 @@ LE64_BITMASK(CACHE_SET_ROOT_RESERVE, struct cache_sb, flags2, 0, 6);
|
|||||||
*/
|
*/
|
||||||
LE64_BITMASK(CACHE_SET_CLEAN, struct cache_sb, flags2, 6, 7);
|
LE64_BITMASK(CACHE_SET_CLEAN, struct cache_sb, flags2, 6, 7);
|
||||||
|
|
||||||
/*
|
LE64_BITMASK(CACHE_SET_JOURNAL_ENTRY_SIZE, struct cache_sb, flags2, 7, 15);
|
||||||
* If nonzero, encryption is enabled; overrides DATA/META_CSUM_TYPE. Also
|
|
||||||
* indicates encryption algorithm in use, if/when we get more than one:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
LE64_BITMASK(CACHE_SET_ENCRYPTION_TYPE, struct cache_sb, flags2, 6, 10);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If nonzero, we have an encryption key in the superblock, which is the key
|
|
||||||
* used to encrypt all other data/metadata. The key will normally be encrypted
|
|
||||||
* with the key userspace provides, but if encryption has been turned off we'll
|
|
||||||
* just store the master key unencrypted in the superblock so we can access the
|
|
||||||
* previously encrypted data.
|
|
||||||
*/
|
|
||||||
LE64_BITMASK(CACHE_SET_ENCRYPTION_KEY, struct cache_sb, flags2, 10, 11);
|
|
||||||
|
|
||||||
/* options: */
|
/* options: */
|
||||||
|
|
||||||
|
4
bcache.c
4
bcache.c
@ -30,7 +30,6 @@ static void usage(void)
|
|||||||
"\n"
|
"\n"
|
||||||
"Commands for formatting, startup and shutdown\n"
|
"Commands for formatting, startup and shutdown\n"
|
||||||
" format Format a new filesystem\n"
|
" format Format a new filesystem\n"
|
||||||
" unlock Unlock an encrypted filesystem prior to running/mounting\n"
|
|
||||||
" assemble Assemble an existing multi device filesystem\n"
|
" assemble Assemble an existing multi device filesystem\n"
|
||||||
" incremental Incrementally assemble an existing multi device filesystem\n"
|
" incremental Incrementally assemble an existing multi device filesystem\n"
|
||||||
" run Start a partially assembled filesystem\n"
|
" run Start a partially assembled filesystem\n"
|
||||||
@ -84,9 +83,6 @@ int main(int argc, char *argv[])
|
|||||||
if (!strcmp(cmd, "device_remove"))
|
if (!strcmp(cmd, "device_remove"))
|
||||||
return cmd_device_remove(argc, argv);
|
return cmd_device_remove(argc, argv);
|
||||||
|
|
||||||
if (!strcmp(cmd, "unlock"))
|
|
||||||
return cmd_unlock(argc, argv);
|
|
||||||
|
|
||||||
usage();
|
usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
1
bcache.h
1
bcache.h
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
int cmd_format(int argc, char *argv[]);
|
int cmd_format(int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_unlock(int argc, char *argv[]);
|
|
||||||
int cmd_assemble(int argc, char *argv[]);
|
int cmd_assemble(int argc, char *argv[]);
|
||||||
int cmd_incremental(int argc, char *argv[]);
|
int cmd_incremental(int argc, char *argv[]);
|
||||||
int cmd_run(int argc, char *argv[]);
|
int cmd_run(int argc, char *argv[]);
|
||||||
|
132
crypto.c
132
crypto.c
@ -1,132 +0,0 @@
|
|||||||
#include <errno.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <linux/random.h>
|
|
||||||
#include <libscrypt.h>
|
|
||||||
#include <sodium/crypto_stream_chacha20.h>
|
|
||||||
|
|
||||||
#include "crypto.h"
|
|
||||||
|
|
||||||
char *read_passphrase(const char *prompt)
|
|
||||||
{
|
|
||||||
struct termios old, new;
|
|
||||||
char *buf = NULL;
|
|
||||||
size_t buflen = 0;
|
|
||||||
|
|
||||||
fprintf(stderr, "%s", prompt);
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
if (tcgetattr(fileno(stdin), &old))
|
|
||||||
die("error getting terminal attrs");
|
|
||||||
|
|
||||||
new = old;
|
|
||||||
new.c_lflag &= ~ECHO;
|
|
||||||
if (tcsetattr(fileno(stdin), TCSAFLUSH, &new))
|
|
||||||
die("error setting terminal attrs");
|
|
||||||
|
|
||||||
if (getline(&buf, &buflen, stdin) <= 0)
|
|
||||||
die("error reading passphrase");
|
|
||||||
|
|
||||||
tcsetattr(fileno(stdin), TCSAFLUSH, &old);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void derive_passphrase(struct bcache_key *key, const char *passphrase)
|
|
||||||
{
|
|
||||||
const unsigned char salt[] = "bcache";
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = libscrypt_scrypt((void *) passphrase, strlen(passphrase),
|
|
||||||
salt, sizeof(salt),
|
|
||||||
SCRYPT_N, SCRYPT_r, SCRYPT_p,
|
|
||||||
(void *) key, sizeof(*key));
|
|
||||||
if (ret)
|
|
||||||
die("scrypt error: %i", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disk_key_encrypt(struct cache_sb *sb,
|
|
||||||
struct bcache_disk_key *disk_key,
|
|
||||||
struct bcache_key *key)
|
|
||||||
{
|
|
||||||
__le32 nonce[2];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memcpy(nonce, &sb->set_magic, sizeof(sb->set_magic));
|
|
||||||
|
|
||||||
ret = crypto_stream_chacha20_xor((void *) disk_key,
|
|
||||||
(void *) disk_key, sizeof(*disk_key),
|
|
||||||
(void *) nonce,
|
|
||||||
(void *) key);
|
|
||||||
if (ret)
|
|
||||||
die("chacha20 error: %i", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disk_key_init(struct bcache_disk_key *disk_key)
|
|
||||||
{
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
memcpy(&disk_key->header, bch_key_header, sizeof(bch_key_header));
|
|
||||||
#if 0
|
|
||||||
ret = getrandom(disk_key->key, sizeof(disk_key->key), GRND_RANDOM);
|
|
||||||
if (ret != sizeof(disk_key->key))
|
|
||||||
die("error getting random bytes for key");
|
|
||||||
#else
|
|
||||||
int fd = open("/dev/random", O_RDONLY|O_NONBLOCK);
|
|
||||||
if (fd < 0)
|
|
||||||
die("error opening /dev/random");
|
|
||||||
|
|
||||||
size_t n = 0;
|
|
||||||
struct timespec start;
|
|
||||||
bool printed = false;
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
|
||||||
|
|
||||||
while (n < sizeof(disk_key->key)) {
|
|
||||||
struct timeval timeout = { 1, 0 };
|
|
||||||
fd_set set;
|
|
||||||
|
|
||||||
FD_ZERO(&set);
|
|
||||||
FD_SET(fd, &set);
|
|
||||||
|
|
||||||
if (select(fd + 1, &set, NULL, NULL, &timeout) < 0)
|
|
||||||
die("select error");
|
|
||||||
|
|
||||||
ret = read(fd,
|
|
||||||
(void *) disk_key->key + n,
|
|
||||||
sizeof(disk_key->key) - n);
|
|
||||||
if (ret == -1 && errno != EINTR && errno != EAGAIN)
|
|
||||||
die("error reading from /dev/random");
|
|
||||||
if (ret > 0)
|
|
||||||
n += ret;
|
|
||||||
|
|
||||||
struct timespec now;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
||||||
|
|
||||||
now.tv_sec -= start.tv_sec;
|
|
||||||
now.tv_nsec -= start.tv_nsec;
|
|
||||||
|
|
||||||
while (now.tv_nsec < 0) {
|
|
||||||
long nsec_per_sec = 1000 * 1000 * 1000;
|
|
||||||
long sec = now.tv_nsec / nsec_per_sec - 1;
|
|
||||||
now.tv_nsec -= sec * nsec_per_sec;
|
|
||||||
now.tv_sec += sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!printed && now.tv_sec >= 3) {
|
|
||||||
printf("Reading from /dev/random is taking a long time...\n)");
|
|
||||||
printed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
#endif
|
|
||||||
}
|
|
24
crypto.h
24
crypto.h
@ -1,24 +0,0 @@
|
|||||||
#ifndef _CRYPTO_H
|
|
||||||
#define _CRYPTO_H
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
struct bcache_key {
|
|
||||||
u64 key[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bcache_disk_key {
|
|
||||||
u64 header;
|
|
||||||
u64 key[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char bch_key_header[8] = BCACHE_MASTER_KEY_HEADER;
|
|
||||||
static const struct nonce bch_master_key_nonce = BCACHE_MASTER_KEY_NONCE;
|
|
||||||
|
|
||||||
char *read_passphrase(const char *);
|
|
||||||
void derive_passphrase(struct bcache_key *, const char *);
|
|
||||||
void disk_key_encrypt(struct cache_sb *sb, struct bcache_disk_key *,
|
|
||||||
struct bcache_key *);
|
|
||||||
void disk_key_init(struct bcache_disk_key *);
|
|
||||||
|
|
||||||
#endif /* _CRYPTO_H */
|
|
29
libbcache.c
29
libbcache.c
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include "bcache-ondisk.h"
|
#include "bcache-ondisk.h"
|
||||||
#include "libbcache.h"
|
#include "libbcache.h"
|
||||||
#include "crypto.h"
|
|
||||||
|
|
||||||
const char * const cache_state[] = {
|
const char * const cache_state[] = {
|
||||||
"active",
|
"active",
|
||||||
@ -125,10 +124,10 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
|||||||
unsigned meta_csum_type,
|
unsigned meta_csum_type,
|
||||||
unsigned data_csum_type,
|
unsigned data_csum_type,
|
||||||
unsigned compression_type,
|
unsigned compression_type,
|
||||||
const char *passphrase,
|
|
||||||
unsigned meta_replicas,
|
unsigned meta_replicas,
|
||||||
unsigned data_replicas,
|
unsigned data_replicas,
|
||||||
unsigned on_error_action,
|
unsigned on_error_action,
|
||||||
|
unsigned max_journal_entry_size,
|
||||||
char *label,
|
char *label,
|
||||||
uuid_le uuid)
|
uuid_le uuid)
|
||||||
{
|
{
|
||||||
@ -191,6 +190,13 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
|||||||
btree_node_size = min(btree_node_size, i->bucket_size);
|
btree_node_size = min(btree_node_size, i->bucket_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!max_journal_entry_size) {
|
||||||
|
/* 2 MB default: */
|
||||||
|
max_journal_entry_size = 4096;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_journal_entry_size = roundup_pow_of_two(max_journal_entry_size);
|
||||||
|
|
||||||
sb = calloc(1, sizeof(*sb) + sizeof(struct cache_member) * nr_devs);
|
sb = calloc(1, sizeof(*sb) + sizeof(struct cache_member) * nr_devs);
|
||||||
|
|
||||||
sb->offset = __cpu_to_le64(SB_SECTOR);
|
sb->offset = __cpu_to_le64(SB_SECTOR);
|
||||||
@ -221,22 +227,7 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
|||||||
SET_CACHE_SET_DATA_REPLICAS_HAVE(sb, data_replicas);
|
SET_CACHE_SET_DATA_REPLICAS_HAVE(sb, data_replicas);
|
||||||
SET_CACHE_SET_ERROR_ACTION(sb, on_error_action);
|
SET_CACHE_SET_ERROR_ACTION(sb, on_error_action);
|
||||||
SET_CACHE_SET_STR_HASH_TYPE(sb, BCH_STR_HASH_SIPHASH);
|
SET_CACHE_SET_STR_HASH_TYPE(sb, BCH_STR_HASH_SIPHASH);
|
||||||
|
SET_CACHE_SET_JOURNAL_ENTRY_SIZE(sb, ilog2(max_journal_entry_size));
|
||||||
if (passphrase) {
|
|
||||||
struct bcache_key key;
|
|
||||||
struct bcache_disk_key disk_key;
|
|
||||||
|
|
||||||
derive_passphrase(&key, passphrase);
|
|
||||||
disk_key_init(&disk_key);
|
|
||||||
disk_key_encrypt(sb, &disk_key, &key);
|
|
||||||
|
|
||||||
memcpy(sb->encryption_key, &disk_key, sizeof(disk_key));
|
|
||||||
SET_CACHE_SET_ENCRYPTION_TYPE(sb, 1);
|
|
||||||
SET_CACHE_SET_ENCRYPTION_KEY(sb, 1);
|
|
||||||
|
|
||||||
memzero_explicit(&disk_key, sizeof(disk_key));
|
|
||||||
memzero_explicit(&key, sizeof(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
@ -286,6 +277,7 @@ void bcache_super_print(struct cache_sb *sb, int units)
|
|||||||
"Version: %llu\n"
|
"Version: %llu\n"
|
||||||
"Block_size: %s\n"
|
"Block_size: %s\n"
|
||||||
"Btree node size: %s\n"
|
"Btree node size: %s\n"
|
||||||
|
"Max journal entry size: %s\n"
|
||||||
"Error action: %s\n"
|
"Error action: %s\n"
|
||||||
"Clean: %llu\n"
|
"Clean: %llu\n"
|
||||||
|
|
||||||
@ -308,6 +300,7 @@ void bcache_super_print(struct cache_sb *sb, int units)
|
|||||||
le64_to_cpu(sb->version),
|
le64_to_cpu(sb->version),
|
||||||
pr_units(le16_to_cpu(sb->block_size), units).b,
|
pr_units(le16_to_cpu(sb->block_size), units).b,
|
||||||
pr_units(CACHE_SET_BTREE_NODE_SIZE(sb), units).b,
|
pr_units(CACHE_SET_BTREE_NODE_SIZE(sb), units).b,
|
||||||
|
pr_units(1U << CACHE_SET_JOURNAL_ENTRY_SIZE(sb), units).b,
|
||||||
|
|
||||||
CACHE_SET_ERROR_ACTION(sb) < BCH_NR_ERROR_ACTIONS
|
CACHE_SET_ERROR_ACTION(sb) < BCH_NR_ERROR_ACTIONS
|
||||||
? error_actions[CACHE_SET_ERROR_ACTION(sb)]
|
? error_actions[CACHE_SET_ERROR_ACTION(sb)]
|
||||||
|
@ -31,10 +31,10 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs,
|
|||||||
unsigned meta_csum_type,
|
unsigned meta_csum_type,
|
||||||
unsigned data_csum_type,
|
unsigned data_csum_type,
|
||||||
unsigned compression_type,
|
unsigned compression_type,
|
||||||
const char *passphrase,
|
|
||||||
unsigned meta_replicas,
|
unsigned meta_replicas,
|
||||||
unsigned data_replicas,
|
unsigned data_replicas,
|
||||||
unsigned on_error_action,
|
unsigned on_error_action,
|
||||||
|
unsigned max_journal_entry_size,
|
||||||
char *label,
|
char *label,
|
||||||
uuid_le uuid);
|
uuid_le uuid);
|
||||||
|
|
||||||
|
27
util.c
27
util.c
@ -1,4 +1,5 @@
|
|||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -21,23 +22,13 @@
|
|||||||
|
|
||||||
/* Integer stuff: */
|
/* Integer stuff: */
|
||||||
|
|
||||||
u64 rounddown_pow_of_two(u64 n)
|
|
||||||
{
|
|
||||||
u64 ret;
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = n;
|
|
||||||
n &= n - 1;
|
|
||||||
} while (n);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ilog2(u64 n)
|
unsigned ilog2(u64 n)
|
||||||
{
|
{
|
||||||
unsigned ret = 0;
|
unsigned ret = 0;
|
||||||
|
|
||||||
while (n) {
|
assert(n > 0);
|
||||||
|
|
||||||
|
while (n > 1) {
|
||||||
ret++;
|
ret++;
|
||||||
n >>= 1;
|
n >>= 1;
|
||||||
}
|
}
|
||||||
@ -45,6 +36,16 @@ unsigned ilog2(u64 n)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 rounddown_pow_of_two(u64 n)
|
||||||
|
{
|
||||||
|
return 1ULL << ilog2(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 roundup_pow_of_two(u64 n)
|
||||||
|
{
|
||||||
|
return 1ULL << (ilog2(n - 1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
char *skip_spaces(const char *str)
|
char *skip_spaces(const char *str)
|
||||||
{
|
{
|
||||||
while (isspace(*str))
|
while (isspace(*str))
|
||||||
|
8
util.h
8
util.h
@ -58,14 +58,20 @@ static inline void le64_add_cpu(__le64 *var, u64 val)
|
|||||||
(void) (&_max1 == &_max2); \
|
(void) (&_max1 == &_max2); \
|
||||||
_max1 > _max2 ? _max1 : _max2; })
|
_max1 > _max2 ? _max1 : _max2; })
|
||||||
|
|
||||||
|
#define max_t(type, x, y) ({ \
|
||||||
|
type __max1 = (x); \
|
||||||
|
type __max2 = (y); \
|
||||||
|
__max1 > __max2 ? __max1: __max2; })
|
||||||
|
|
||||||
#define die(arg, ...) \
|
#define die(arg, ...) \
|
||||||
do { \
|
do { \
|
||||||
fprintf(stderr, arg "\n", ##__VA_ARGS__); \
|
fprintf(stderr, arg "\n", ##__VA_ARGS__); \
|
||||||
exit(EXIT_FAILURE); \
|
exit(EXIT_FAILURE); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
u64 rounddown_pow_of_two(u64);
|
|
||||||
unsigned ilog2(u64);
|
unsigned ilog2(u64);
|
||||||
|
u64 rounddown_pow_of_two(u64);
|
||||||
|
u64 roundup_pow_of_two(u64);
|
||||||
|
|
||||||
char *skip_spaces(const char *str);
|
char *skip_spaces(const char *str);
|
||||||
char *strim(char *s);
|
char *strim(char *s);
|
||||||
|
Loading…
Reference in New Issue
Block a user