Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 53 additions & 7 deletions libblkid/src/superblocks/bcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,55 @@
#include "xxhash.h"

#define SB_LABEL_SIZE 32
#define SB_JOURNAL_BUCKETS 256U

/*
* The bcache_super_block is heavily simplified version of struct cache_sb in kernel.
* https://github.com/torvalds/linux/blob/master/include/uapi/linux/bcache.h
* The bcache_super_block is adapted from struct cache_sb in kernel.
* https://github.com/torvalds/linux/blob/master/drivers/md/bcache/bcache_ondisk.h
*/
struct bcache_super_block {
uint64_t csum;
uint64_t offset; /* where this super block was written */
uint64_t version;
uint8_t magic[16]; /* bcache file system identifier */
uint8_t uuid[16]; /* device identifier */
uint8_t set_info[16]; /* magic or uuid */
uint8_t label[SB_LABEL_SIZE];
uint64_t flags;
uint64_t seq;

uint64_t feature_compat;
uint64_t feature_incompat;
uint64_t feature_ro_compat;

uint64_t pad[5];

union {
struct {
/* Cache devices */
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;
};
struct {
/* Backing devices */
uint64_t data_offset;
};
};

uint32_t last_mount;

uint16_t first_bucket;
union {
uint16_t njournal_buckets;
uint16_t keys;
};
uint64_t d[SB_JOURNAL_BUCKETS]; /* journal buckets */
uint16_t obso_bucket_size_hi; /* obsoleted */
} __attribute__((packed));

struct bcachefs_sb_field {
Expand Down Expand Up @@ -102,8 +140,6 @@ struct bcachefs_super_block {
#define BCACHE_SB_MAGIC_OFF offsetof(struct bcache_super_block, magic)
/* start of checksummed data within superblock */
#define BCACHE_SB_CSUMMED_START 8
/* end of checksummed data within superblock */
#define BCACHE_SB_CSUMMED_END 208
/* granularity of offset and length fields within superblock */
#define BCACHEFS_SECTOR_SIZE 512
/* maximum superblock size */
Expand All @@ -118,9 +154,19 @@ struct bcachefs_super_block {
static int bcache_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag,
const struct bcache_super_block *bcs)
{
unsigned char *csummed = blkid_probe_get_sb_buffer(pr, mag, BCACHE_SB_CSUMMED_END);
uint64_t csum = ul_crc64_we(csummed + BCACHE_SB_CSUMMED_START,
BCACHE_SB_CSUMMED_END - BCACHE_SB_CSUMMED_START);
const unsigned char *csummed;
size_t csummed_size;
uint64_t csum;

if (le16_to_cpu(bcs->keys) > ARRAY_SIZE(bcs->d))
return 0;

/* up to the end of bcs->d[] */
csummed_size = offsetof(typeof(*bcs), d) +
sizeof(bcs->d[0]) * le16_to_cpu(bcs->keys);
csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size);
csum = ul_crc64_we(csummed + BCACHE_SB_CSUMMED_START,
csummed_size - BCACHE_SB_CSUMMED_START);
return blkid_probe_verify_csum(pr, csum, le64_to_cpu(bcs->csum));
}

Expand Down
4 changes: 4 additions & 0 deletions tests/expected/blkid/low-probe-bcache-journal
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ID_FS_TYPE=bcache
ID_FS_USAGE=other
ID_FS_UUID=fc6ea56f-372e-474e-bc5b-2ddc8430ddd1
ID_FS_UUID_ENC=fc6ea56f-372e-474e-bc5b-2ddc8430ddd1
Binary file added tests/ts/blkid/images-fs/bcache-journal.img.xz
Binary file not shown.