mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 06:49:45 -04:00
bcachefs: Improve jset_validate()
Previously, jset_validate() was formatting the initial part of an error string for every entry it validating - expensive. This moves that code to journal_entry_err_msg(), which is now only called if there's an actual error. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
@@ -186,30 +186,57 @@ static void journal_entry_null_range(void *start, void *end)
|
||||
#define JOURNAL_ENTRY_NONE 6
|
||||
#define JOURNAL_ENTRY_BAD 7
|
||||
|
||||
#define journal_entry_err(c, msg, ...) \
|
||||
static void journal_entry_err_msg(struct printbuf *out,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry)
|
||||
{
|
||||
prt_str(out, "invalid journal entry ");
|
||||
if (entry)
|
||||
prt_printf(out, "%s ", bch2_jset_entry_types[entry->type]);
|
||||
|
||||
if (!jset)
|
||||
prt_printf(out, "in superblock");
|
||||
else if (!entry)
|
||||
prt_printf(out, "at seq %llu", le64_to_cpu(jset->seq));
|
||||
else
|
||||
prt_printf(out, "at offset %zi/%u seq %llu",
|
||||
(u64 *) entry - jset->_data,
|
||||
le32_to_cpu(jset->u64s),
|
||||
le64_to_cpu(jset->seq));
|
||||
prt_str(out, ": ");
|
||||
}
|
||||
|
||||
#define journal_entry_err(c, jset, entry, msg, ...) \
|
||||
({ \
|
||||
struct printbuf buf = PRINTBUF; \
|
||||
\
|
||||
journal_entry_err_msg(&buf, jset, entry); \
|
||||
prt_printf(&buf, msg, ##__VA_ARGS__); \
|
||||
\
|
||||
switch (write) { \
|
||||
case READ: \
|
||||
mustfix_fsck_err(c, msg, ##__VA_ARGS__); \
|
||||
mustfix_fsck_err(c, "%s", buf.buf); \
|
||||
break; \
|
||||
case WRITE: \
|
||||
bch_err(c, "corrupt metadata before write:\n" \
|
||||
msg, ##__VA_ARGS__); \
|
||||
bch_err(c, "corrupt metadata before write: %s\n", buf.buf);\
|
||||
if (bch2_fs_inconsistent(c)) { \
|
||||
ret = -BCH_ERR_fsck_errors_not_fixed; \
|
||||
goto fsck_err; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
printbuf_exit(&buf); \
|
||||
true; \
|
||||
})
|
||||
|
||||
#define journal_entry_err_on(cond, c, msg, ...) \
|
||||
((cond) ? journal_entry_err(c, msg, ##__VA_ARGS__) : false)
|
||||
#define journal_entry_err_on(cond, c, jset, entry, msg, ...) \
|
||||
((cond) ? journal_entry_err(c, jset, entry, msg, ##__VA_ARGS__) : false)
|
||||
|
||||
#define FSCK_DELETED_KEY 5
|
||||
|
||||
static int journal_validate_key(struct bch_fs *c, const char *where,
|
||||
static int journal_validate_key(struct bch_fs *c,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned level, enum btree_id btree_id,
|
||||
struct bkey_i *k,
|
||||
@@ -219,33 +246,24 @@ static int journal_validate_key(struct bch_fs *c, const char *where,
|
||||
struct printbuf buf = PRINTBUF;
|
||||
int ret = 0;
|
||||
|
||||
if (journal_entry_err_on(!k->k.u64s, c,
|
||||
"invalid key in %s at %s offset %zi/%u: k->u64s 0",
|
||||
bch2_jset_entry_types[entry->type], where,
|
||||
(u64 *) k - entry->_data,
|
||||
le16_to_cpu(entry->u64s))) {
|
||||
if (journal_entry_err_on(!k->k.u64s, c, jset, entry, "k->u64s 0")) {
|
||||
entry->u64s = cpu_to_le16((u64 *) k - entry->_data);
|
||||
journal_entry_null_range(vstruct_next(entry), next);
|
||||
return FSCK_DELETED_KEY;
|
||||
}
|
||||
|
||||
if (journal_entry_err_on((void *) bkey_next(k) >
|
||||
(void *) vstruct_next(entry), c,
|
||||
"invalid key in %s at %s offset %zi/%u: extends past end of journal entry",
|
||||
bch2_jset_entry_types[entry->type], where,
|
||||
(u64 *) k - entry->_data,
|
||||
le16_to_cpu(entry->u64s))) {
|
||||
(void *) vstruct_next(entry),
|
||||
c, jset, entry,
|
||||
"extends past end of journal entry")) {
|
||||
entry->u64s = cpu_to_le16((u64 *) k - entry->_data);
|
||||
journal_entry_null_range(vstruct_next(entry), next);
|
||||
return FSCK_DELETED_KEY;
|
||||
}
|
||||
|
||||
if (journal_entry_err_on(k->k.format != KEY_FORMAT_CURRENT, c,
|
||||
"invalid key in %s at %s offset %zi/%u: bad format %u",
|
||||
bch2_jset_entry_types[entry->type], where,
|
||||
(u64 *) k - entry->_data,
|
||||
le16_to_cpu(entry->u64s),
|
||||
k->k.format)) {
|
||||
if (journal_entry_err_on(k->k.format != KEY_FORMAT_CURRENT,
|
||||
c, jset, entry,
|
||||
"bad format %u", k->k.format)) {
|
||||
le16_add_cpu(&entry->u64s, -((u16) k->k.u64s));
|
||||
memmove(k, bkey_next(k), next - (void *) bkey_next(k));
|
||||
journal_entry_null_range(vstruct_next(entry), next);
|
||||
@@ -259,10 +277,11 @@ static int journal_validate_key(struct bch_fs *c, const char *where,
|
||||
if (bch2_bkey_invalid(c, bkey_i_to_s_c(k),
|
||||
__btree_node_type(level, btree_id), write, &buf)) {
|
||||
printbuf_reset(&buf);
|
||||
prt_printf(&buf, "invalid key in %s at %s offset %zi/%u:",
|
||||
bch2_jset_entry_types[entry->type], where,
|
||||
(u64 *) k - entry->_data,
|
||||
le16_to_cpu(entry->u64s));
|
||||
prt_printf(&buf, "invalid journal entry %s at offset %zi/%u seq %llu:",
|
||||
bch2_jset_entry_types[entry->type],
|
||||
(u64 *) entry - jset->_data,
|
||||
le32_to_cpu(jset->u64s),
|
||||
le64_to_cpu(jset->seq));
|
||||
prt_newline(&buf);
|
||||
printbuf_indent_add(&buf, 2);
|
||||
|
||||
@@ -290,14 +309,14 @@ static int journal_validate_key(struct bch_fs *c, const char *where,
|
||||
}
|
||||
|
||||
static int journal_entry_btree_keys_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
struct bkey_i *k = entry->start;
|
||||
|
||||
while (k != vstruct_last(entry)) {
|
||||
int ret = journal_validate_key(c, where, entry,
|
||||
int ret = journal_validate_key(c, jset, entry,
|
||||
entry->level,
|
||||
entry->btree_id,
|
||||
k, version, big_endian, write);
|
||||
@@ -328,7 +347,7 @@ static void journal_entry_btree_keys_to_text(struct printbuf *out, struct bch_fs
|
||||
}
|
||||
|
||||
static int journal_entry_btree_root_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
@@ -336,7 +355,8 @@ static int journal_entry_btree_root_validate(struct bch_fs *c,
|
||||
int ret = 0;
|
||||
|
||||
if (journal_entry_err_on(!entry->u64s ||
|
||||
le16_to_cpu(entry->u64s) != k->k.u64s, c,
|
||||
le16_to_cpu(entry->u64s) != k->k.u64s,
|
||||
c, jset, entry,
|
||||
"invalid btree root journal entry: wrong number of keys")) {
|
||||
void *next = vstruct_next(entry);
|
||||
/*
|
||||
@@ -349,7 +369,7 @@ static int journal_entry_btree_root_validate(struct bch_fs *c,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return journal_validate_key(c, where, entry, 1, entry->btree_id, k,
|
||||
return journal_validate_key(c, jset, entry, 1, entry->btree_id, k,
|
||||
version, big_endian, write);
|
||||
fsck_err:
|
||||
return ret;
|
||||
@@ -362,7 +382,7 @@ static void journal_entry_btree_root_to_text(struct printbuf *out, struct bch_fs
|
||||
}
|
||||
|
||||
static int journal_entry_prio_ptrs_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
@@ -376,13 +396,14 @@ static void journal_entry_prio_ptrs_to_text(struct printbuf *out, struct bch_fs
|
||||
}
|
||||
|
||||
static int journal_entry_blacklist_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (journal_entry_err_on(le16_to_cpu(entry->u64s) != 1, c,
|
||||
if (journal_entry_err_on(le16_to_cpu(entry->u64s) != 1,
|
||||
c, jset, entry,
|
||||
"invalid journal seq blacklist entry: bad size")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
}
|
||||
@@ -400,14 +421,15 @@ static void journal_entry_blacklist_to_text(struct printbuf *out, struct bch_fs
|
||||
}
|
||||
|
||||
static int journal_entry_blacklist_v2_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
struct jset_entry_blacklist_v2 *bl_entry;
|
||||
int ret = 0;
|
||||
|
||||
if (journal_entry_err_on(le16_to_cpu(entry->u64s) != 2, c,
|
||||
if (journal_entry_err_on(le16_to_cpu(entry->u64s) != 2,
|
||||
c, jset, entry,
|
||||
"invalid journal seq blacklist entry: bad size")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
goto out;
|
||||
@@ -416,7 +438,8 @@ static int journal_entry_blacklist_v2_validate(struct bch_fs *c,
|
||||
bl_entry = container_of(entry, struct jset_entry_blacklist_v2, entry);
|
||||
|
||||
if (journal_entry_err_on(le64_to_cpu(bl_entry->start) >
|
||||
le64_to_cpu(bl_entry->end), c,
|
||||
le64_to_cpu(bl_entry->end),
|
||||
c, jset, entry,
|
||||
"invalid journal seq blacklist entry: start > end")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
}
|
||||
@@ -437,7 +460,7 @@ static void journal_entry_blacklist_v2_to_text(struct printbuf *out, struct bch_
|
||||
}
|
||||
|
||||
static int journal_entry_usage_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
@@ -447,7 +470,7 @@ static int journal_entry_usage_validate(struct bch_fs *c,
|
||||
int ret = 0;
|
||||
|
||||
if (journal_entry_err_on(bytes < sizeof(*u),
|
||||
c,
|
||||
c, jset, entry,
|
||||
"invalid journal entry usage: bad size")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
return ret;
|
||||
@@ -469,7 +492,7 @@ static void journal_entry_usage_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
}
|
||||
|
||||
static int journal_entry_data_usage_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
@@ -480,7 +503,7 @@ static int journal_entry_data_usage_validate(struct bch_fs *c,
|
||||
|
||||
if (journal_entry_err_on(bytes < sizeof(*u) ||
|
||||
bytes < sizeof(*u) + u->r.nr_devs,
|
||||
c,
|
||||
c, jset, entry,
|
||||
"invalid journal entry usage: bad size")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
return ret;
|
||||
@@ -501,7 +524,7 @@ static void journal_entry_data_usage_to_text(struct printbuf *out, struct bch_fs
|
||||
}
|
||||
|
||||
static int journal_entry_clock_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
@@ -511,13 +534,13 @@ static int journal_entry_clock_validate(struct bch_fs *c,
|
||||
int ret = 0;
|
||||
|
||||
if (journal_entry_err_on(bytes != sizeof(*clock),
|
||||
c, "invalid journal entry clock: bad size")) {
|
||||
c, jset, entry, "bad size")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (journal_entry_err_on(clock->rw > 1,
|
||||
c, "invalid journal entry clock: bad rw")) {
|
||||
c, jset, entry, "bad rw")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
return ret;
|
||||
}
|
||||
@@ -536,7 +559,7 @@ static void journal_entry_clock_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
}
|
||||
|
||||
static int journal_entry_dev_usage_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
@@ -548,7 +571,7 @@ static int journal_entry_dev_usage_validate(struct bch_fs *c,
|
||||
int ret = 0;
|
||||
|
||||
if (journal_entry_err_on(bytes < expected,
|
||||
c, "invalid journal entry dev usage: bad size (%u < %u)",
|
||||
c, jset, entry, "bad size (%u < %u)",
|
||||
bytes, expected)) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
return ret;
|
||||
@@ -557,13 +580,13 @@ static int journal_entry_dev_usage_validate(struct bch_fs *c,
|
||||
dev = le32_to_cpu(u->dev);
|
||||
|
||||
if (journal_entry_err_on(!bch2_dev_exists2(c, dev),
|
||||
c, "invalid journal entry dev usage: bad dev")) {
|
||||
c, jset, entry, "bad dev")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (journal_entry_err_on(u->pad,
|
||||
c, "invalid journal entry dev usage: bad pad")) {
|
||||
c, jset, entry, "bad pad")) {
|
||||
journal_entry_null_range(entry, vstruct_next(entry));
|
||||
return ret;
|
||||
}
|
||||
@@ -596,7 +619,7 @@ static void journal_entry_dev_usage_to_text(struct printbuf *out, struct bch_fs
|
||||
}
|
||||
|
||||
static int journal_entry_log_validate(struct bch_fs *c,
|
||||
const char *where,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
@@ -612,11 +635,12 @@ static void journal_entry_log_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
prt_printf(out, "%.*s", bytes, l->d);
|
||||
}
|
||||
|
||||
static int journal_entry_overwrite_validate(struct bch_fs *c, const char *where,
|
||||
static int journal_entry_overwrite_validate(struct bch_fs *c,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
return journal_entry_btree_keys_validate(c, where, entry, version, big_endian, write);
|
||||
return journal_entry_btree_keys_validate(c, jset, entry, version, big_endian, write);
|
||||
}
|
||||
|
||||
static void journal_entry_overwrite_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
@@ -626,7 +650,7 @@ static void journal_entry_overwrite_to_text(struct printbuf *out, struct bch_fs
|
||||
}
|
||||
|
||||
struct jset_entry_ops {
|
||||
int (*validate)(struct bch_fs *, const char *,
|
||||
int (*validate)(struct bch_fs *, struct jset *,
|
||||
struct jset_entry *, unsigned, int, int);
|
||||
void (*to_text)(struct printbuf *, struct bch_fs *, struct jset_entry *);
|
||||
};
|
||||
@@ -641,12 +665,13 @@ static const struct jset_entry_ops bch2_jset_entry_ops[] = {
|
||||
#undef x
|
||||
};
|
||||
|
||||
int bch2_journal_entry_validate(struct bch_fs *c, const char *where,
|
||||
int bch2_journal_entry_validate(struct bch_fs *c,
|
||||
struct jset *jset,
|
||||
struct jset_entry *entry,
|
||||
unsigned version, int big_endian, int write)
|
||||
{
|
||||
return entry->type < BCH_JSET_ENTRY_NR
|
||||
? bch2_jset_entry_ops[entry->type].validate(c, where, entry,
|
||||
? bch2_jset_entry_ops[entry->type].validate(c, jset, entry,
|
||||
version, big_endian, write)
|
||||
: 0;
|
||||
}
|
||||
@@ -665,24 +690,18 @@ void bch2_journal_entry_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
static int jset_validate_entries(struct bch_fs *c, struct jset *jset,
|
||||
int write)
|
||||
{
|
||||
char buf[100];
|
||||
struct jset_entry *entry;
|
||||
int ret = 0;
|
||||
|
||||
vstruct_for_each(jset, entry) {
|
||||
scnprintf(buf, sizeof(buf), "jset %llu entry offset %zi/%u",
|
||||
le64_to_cpu(jset->seq),
|
||||
(u64 *) entry - jset->_data,
|
||||
le32_to_cpu(jset->u64s));
|
||||
|
||||
if (journal_entry_err_on(vstruct_next(entry) >
|
||||
vstruct_last(jset), c,
|
||||
vstruct_last(jset), c, jset, entry,
|
||||
"journal entry extends past end of jset")) {
|
||||
jset->u64s = cpu_to_le32((u64 *) entry - jset->_data);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bch2_journal_entry_validate(c, buf, entry,
|
||||
ret = bch2_journal_entry_validate(c, jset, entry,
|
||||
le32_to_cpu(jset->version),
|
||||
JSET_BIG_ENDIAN(jset), write);
|
||||
if (ret)
|
||||
@@ -710,7 +729,8 @@ static int jset_validate(struct bch_fs *c,
|
||||
version = le32_to_cpu(jset->version);
|
||||
if (journal_entry_err_on((version != BCH_JSET_VERSION_OLD &&
|
||||
version < bcachefs_metadata_version_min) ||
|
||||
version >= bcachefs_metadata_version_max, c,
|
||||
version >= bcachefs_metadata_version_max,
|
||||
c, jset, NULL,
|
||||
"%s sector %llu seq %llu: unknown journal entry version %u",
|
||||
ca ? ca->name : c->name,
|
||||
sector, le64_to_cpu(jset->seq),
|
||||
@@ -723,7 +743,8 @@ static int jset_validate(struct bch_fs *c,
|
||||
sectors_read < bucket_sectors_left)
|
||||
return JOURNAL_ENTRY_REREAD;
|
||||
|
||||
if (journal_entry_err_on(bytes > bucket_sectors_left << 9, c,
|
||||
if (journal_entry_err_on(bytes > bucket_sectors_left << 9,
|
||||
c, jset, NULL,
|
||||
"%s sector %llu seq %llu: journal entry too big (%zu bytes)",
|
||||
ca ? ca->name : c->name,
|
||||
sector, le64_to_cpu(jset->seq), bytes)) {
|
||||
@@ -732,7 +753,8 @@ static int jset_validate(struct bch_fs *c,
|
||||
-((bytes - (bucket_sectors_left << 9)) / 8));
|
||||
}
|
||||
|
||||
if (journal_entry_err_on(!bch2_checksum_type_valid(c, JSET_CSUM_TYPE(jset)), c,
|
||||
if (journal_entry_err_on(!bch2_checksum_type_valid(c, JSET_CSUM_TYPE(jset)),
|
||||
c, jset, NULL,
|
||||
"%s sector %llu seq %llu: journal entry with unknown csum type %llu",
|
||||
ca ? ca->name : c->name,
|
||||
sector, le64_to_cpu(jset->seq),
|
||||
@@ -745,7 +767,8 @@ static int jset_validate(struct bch_fs *c,
|
||||
goto csum_done;
|
||||
|
||||
csum = csum_vstruct(c, JSET_CSUM_TYPE(jset), journal_nonce(jset), jset);
|
||||
if (journal_entry_err_on(bch2_crc_cmp(csum, jset->csum), c,
|
||||
if (journal_entry_err_on(bch2_crc_cmp(csum, jset->csum),
|
||||
c, jset, NULL,
|
||||
"%s sector %llu seq %llu: journal checksum bad",
|
||||
ca ? ca->name : c->name,
|
||||
sector, le64_to_cpu(jset->seq)))
|
||||
@@ -759,7 +782,8 @@ static int jset_validate(struct bch_fs *c,
|
||||
csum_done:
|
||||
/* last_seq is ignored when JSET_NO_FLUSH is true */
|
||||
if (journal_entry_err_on(!JSET_NO_FLUSH(jset) &&
|
||||
le64_to_cpu(jset->last_seq) > le64_to_cpu(jset->seq), c,
|
||||
le64_to_cpu(jset->last_seq) > le64_to_cpu(jset->seq),
|
||||
c, jset, NULL,
|
||||
"invalid journal entry: last_seq > seq (%llu > %llu)",
|
||||
le64_to_cpu(jset->last_seq),
|
||||
le64_to_cpu(jset->seq))) {
|
||||
|
||||
@@ -44,7 +44,7 @@ static inline struct jset_entry *__jset_entry_type_next(struct jset *jset,
|
||||
for_each_jset_entry_type(entry, jset, BCH_JSET_ENTRY_btree_keys) \
|
||||
vstruct_for_each_safe(entry, k, _n)
|
||||
|
||||
int bch2_journal_entry_validate(struct bch_fs *, const char *,
|
||||
int bch2_journal_entry_validate(struct bch_fs *, struct jset *,
|
||||
struct jset_entry *, unsigned, int, int);
|
||||
void bch2_journal_entry_to_text(struct printbuf *, struct bch_fs *,
|
||||
struct jset_entry *);
|
||||
|
||||
@@ -1161,7 +1161,7 @@ int bch2_sb_clean_validate_late(struct bch_fs *c, struct bch_sb_field_clean *cle
|
||||
for (entry = clean->start;
|
||||
entry < (struct jset_entry *) vstruct_end(&clean->field);
|
||||
entry = vstruct_next(entry)) {
|
||||
ret = bch2_journal_entry_validate(c, "superblock", entry,
|
||||
ret = bch2_journal_entry_validate(c, NULL, entry,
|
||||
le16_to_cpu(c->disk_sb.sb->version),
|
||||
BCH_SB_BIG_ENDIAN(c->disk_sb.sb),
|
||||
write);
|
||||
|
||||
Reference in New Issue
Block a user