From 35e4ab92f0ee4be8d79f4c6dc3579c42a99b5b91 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 6 Apr 2018 15:38:28 -0700 Subject: [PATCH] scoutfs-utils: support file and node free extents Add support for printing the items used to track file mapping extents and free extents. Signed-off-by: Zach Brown --- utils/src/format.h | 76 +++++++++++++--------------------------------- utils/src/key.c | 6 ++-- utils/src/print.c | 45 ++++++++++++++------------- 3 files changed, 46 insertions(+), 81 deletions(-) diff --git a/utils/src/format.h b/utils/src/format.h index ee636150..c91b4a4b 100644 --- a/utils/src/format.h +++ b/utils/src/format.h @@ -15,6 +15,7 @@ #define SCOUTFS_BLOCKS_PER_PAGE (PAGE_SIZE / SCOUTFS_BLOCK_SIZE) #define SCOUTFS_BLOCK_SECTOR_SHIFT (SCOUTFS_BLOCK_SHIFT - 9) #define SCOUTFS_BLOCK_SECTORS (1 << SCOUTFS_BLOCK_SECTOR_SHIFT) +#define SCOUTFS_BLOCK_MAX (U64_MAX >> SCOUTFS_BLOCK_SHIFT) /* * FS data is stored in segments, for now they're fixed size. They'll @@ -78,9 +79,10 @@ struct scoutfs_key { #define skii_major _sk_second #define skii_ino _sk_third -/* node free bit map */ -#define skf_node_id _sk_first -#define skf_base _sk_second +/* node free extent */ +#define sknf_node_id _sk_first +#define sknf_major _sk_second +#define sknf_minor _sk_third /* node orphan inode */ #define sko_node_id _sk_first @@ -104,9 +106,9 @@ struct scoutfs_key { #define sks_ino _sk_first #define sks_nr _sk_second -/* file data mapping */ -#define skm_ino _sk_first -#define skm_base _sk_second +/* file extent */ +#define skfe_ino _sk_first +#define skfe_last _sk_second /* * The btree still uses memcmp() to compare keys. We should fix that @@ -302,8 +304,8 @@ struct scoutfs_segment_block { #define SCOUTFS_INODE_INDEX_NR 3 /* don't forget to update */ /* node zone */ -#define SCOUTFS_FREE_BITS_SEGNO_TYPE 1 -#define SCOUTFS_FREE_BITS_BLKNO_TYPE 2 +#define SCOUTFS_FREE_EXTENT_BLKNO_TYPE 1 +#define SCOUTFS_FREE_EXTENT_BLOCKS_TYPE 2 /* fs zone */ #define SCOUTFS_INODE_TYPE 1 @@ -312,60 +314,23 @@ struct scoutfs_segment_block { #define SCOUTFS_READDIR_TYPE 4 #define SCOUTFS_LINK_BACKREF_TYPE 5 #define SCOUTFS_SYMLINK_TYPE 6 -#define SCOUTFS_BLOCK_MAPPING_TYPE 7 +#define SCOUTFS_FILE_EXTENT_TYPE 7 #define SCOUTFS_ORPHAN_TYPE 8 #define SCOUTFS_MAX_TYPE 16 /* power of 2 is efficient */ -/* each mapping item describes a fixed number of blocks */ -#define SCOUTFS_BLOCK_MAPPING_SHIFT 6 -#define SCOUTFS_BLOCK_MAPPING_BLOCKS (1 << SCOUTFS_BLOCK_MAPPING_SHIFT) -#define SCOUTFS_BLOCK_MAPPING_MASK (SCOUTFS_BLOCK_MAPPING_BLOCKS - 1) - /* - * The mapping item value is a byte stream that encodes the value of the - * mapped blocks. The first byte contains the last index that contains - * a mapped block in its low bits. The high bits contain the control - * bits for the first (and possibly only) mapped block. - * - * From then on we consume the control bits in the current control byte - * for each mapped block. Each block has two bits that describe the - * block: zero, incremental from previous block, delta encoded, and - * offline. If we run out of control bits then we consume the next byte - * in the stream for additional control bits. If we have a delta - * encoded block then we consume its encoded bytes from the byte stream. + * File extents have more data than easily fits in the key so we move + * the non-indexed fields into the value. */ - -#define SCOUTFS_BLOCK_ENC_ZERO 0 -#define SCOUTFS_BLOCK_ENC_INC 1 -#define SCOUTFS_BLOCK_ENC_DELTA 2 -#define SCOUTFS_BLOCK_ENC_OFFLINE 3 -#define SCOUTFS_BLOCK_ENC_MASK 3 - -#define SCOUTFS_ZIGZAG_MAX_BYTES (DIV_ROUND_UP(64, 7)) - -/* - * the largest block mapping has: nr byte, ctl bytes for all blocks, and - * worst case zigzag encodings for all blocks. - */ -#define SCOUTFS_BLOCK_MAPPING_MAX_BYTES \ - (1 + (SCOUTFS_BLOCK_MAPPING_BLOCKS / 4) + \ - (SCOUTFS_BLOCK_MAPPING_BLOCKS * SCOUTFS_ZIGZAG_MAX_BYTES)) - -/* free bit bitmaps contain a segment's worth of blocks */ -#define SCOUTFS_FREE_BITS_SHIFT \ - SCOUTFS_SEGMENT_BLOCK_SHIFT -#define SCOUTFS_FREE_BITS_BITS \ - (1 << SCOUTFS_FREE_BITS_SHIFT) -#define SCOUTFS_FREE_BITS_MASK \ - (SCOUTFS_FREE_BITS_BITS - 1) -#define SCOUTFS_FREE_BITS_U64S \ - DIV_ROUND_UP(SCOUTFS_FREE_BITS_BITS, 64) - -struct scoutfs_free_bits { - __le64 bits[SCOUTFS_FREE_BITS_U64S]; +struct scoutfs_file_extent { + __le64 blkno; + __le64 len; + __u8 flags; } __packed; +#define SEF_OFFLINE 0x1 + /* * The first xattr part item has a header that describes the xattr. The * name and value are then packed into the following bytes in the first @@ -509,7 +474,6 @@ enum { SCOUTFS_DT_WHT, }; -#define SCOUTFS_MAX_VAL_SIZE SCOUTFS_BLOCK_MAPPING_MAX_BYTES #define SCOUTFS_XATTR_MAX_NAME_LEN 255 #define SCOUTFS_XATTR_MAX_VAL_LEN 65535 @@ -519,6 +483,8 @@ enum { DIV_ROUND_UP(sizeof(struct scoutfs_xattr) + name_len + val_len, \ SCOUTFS_XATTR_MAX_PART_SIZE); +#define SCOUTFS_MAX_VAL_SIZE SCOUTFS_XATTR_MAX_PART_SIZE + /* * structures used by dlm */ diff --git a/utils/src/key.c b/utils/src/key.c index b19b6cd0..2afc855f 100644 --- a/utils/src/key.c +++ b/utils/src/key.c @@ -28,8 +28,8 @@ char *scoutfs_zone_strings[SCOUTFS_MAX_ZONE] = { char *scoutfs_type_strings[SCOUTFS_MAX_ZONE][SCOUTFS_MAX_TYPE] = { [SCOUTFS_INODE_INDEX_ZONE][SCOUTFS_INODE_INDEX_META_SEQ_TYPE] = "msq", [SCOUTFS_INODE_INDEX_ZONE][SCOUTFS_INODE_INDEX_DATA_SEQ_TYPE] = "dsq", - [SCOUTFS_NODE_ZONE][SCOUTFS_FREE_BITS_SEGNO_TYPE] = "fsg", - [SCOUTFS_NODE_ZONE][SCOUTFS_FREE_BITS_BLKNO_TYPE] = "fbk", + [SCOUTFS_NODE_ZONE][SCOUTFS_FREE_EXTENT_BLKNO_TYPE] = "fbn", + [SCOUTFS_NODE_ZONE][SCOUTFS_FREE_EXTENT_BLOCKS_TYPE] = "fbs", [SCOUTFS_NODE_ZONE][SCOUTFS_ORPHAN_TYPE] = "orp", [SCOUTFS_FS_ZONE][SCOUTFS_INODE_TYPE] = "ino", [SCOUTFS_FS_ZONE][SCOUTFS_XATTR_TYPE] = "xat", @@ -37,7 +37,7 @@ char *scoutfs_type_strings[SCOUTFS_MAX_ZONE][SCOUTFS_MAX_TYPE] = { [SCOUTFS_FS_ZONE][SCOUTFS_READDIR_TYPE] = "rdr", [SCOUTFS_FS_ZONE][SCOUTFS_LINK_BACKREF_TYPE] = "lbr", [SCOUTFS_FS_ZONE][SCOUTFS_SYMLINK_TYPE] = "sym", - [SCOUTFS_FS_ZONE][SCOUTFS_BLOCK_MAPPING_TYPE] = "bmp", + [SCOUTFS_FS_ZONE][SCOUTFS_FILE_EXTENT_TYPE] = "fex", }; char scoutfs_unknown_u8_strings[U8_MAX][U8_STR_MAX]; diff --git a/utils/src/print.c b/utils/src/print.c index 02e125e5..10dc7122 100644 --- a/utils/src/print.c +++ b/utils/src/print.c @@ -161,30 +161,30 @@ static void print_symlink(struct scoutfs_key *key, void *val, int val_len) le64_to_cpu(key->sks_ino), le64_to_cpu(key->sks_nr), name); } -/* - * XXX not decoding the bytes yet - */ -static void print_block_mapping(struct scoutfs_key *key, void *val, int val_len) +static void print_file_extent(struct scoutfs_key *key, void *val, int val_len) { - u64 blk_off = le64_to_cpu(key->skm_base) << SCOUTFS_BLOCK_MAPPING_SHIFT; - u8 nr = *((u8 *)val) & 63; + struct scoutfs_file_extent *fex = val; + u64 iblock = le64_to_cpu(key->skfe_last) - le64_to_cpu(fex->len) + 1; - printf(" block mapping: ino %llu blk_off %llu blocks %u\n", - le64_to_cpu(key->skm_ino), blk_off, nr); + printf(" extent: ino %llu (last %llu) iblock %llu len %llu " + "blkno %llu flags 0x%x\n", + le64_to_cpu(key->skfe_ino), le64_to_cpu(key->skfe_last), + iblock, le64_to_cpu(fex->len), le64_to_cpu(fex->blkno), + fex->flags); } -static void print_free_bits(struct scoutfs_key *key, void *val, int val_len) +static void print_free_extent(struct scoutfs_key *key, void *val, int val_len) { - struct scoutfs_free_bits *frb = val; - int i; + u64 start = le64_to_cpu(key->sknf_major); + u64 len = le64_to_cpu(key->sknf_minor); + if (key->sk_type == SCOUTFS_FREE_EXTENT_BLOCKS_TYPE) + swap(start, len); + start -= (len - 1); - printf(" node_id %llx base %llu\n", - le64_to_cpu(key->skf_node_id), le64_to_cpu(key->skf_base)); - - printf(" bits:"); - for (i = 0; i < array_size(frb->bits); i++) - printf(" %016llx", le64_to_cpu(frb->bits[i])); - printf("\n"); + printf(" free extent: major %llu minor %llu (start %llu " + "len %llu)\n", + le64_to_cpu(key->sknf_major), le64_to_cpu(key->sknf_minor), + start, len); } static void print_inode_index(struct scoutfs_key *key, void *val, int val_len) @@ -203,9 +203,9 @@ static print_func_t find_printer(u8 zone, u8 type) return print_inode_index; if (zone == SCOUTFS_NODE_ZONE) { - if (type == SCOUTFS_FREE_BITS_SEGNO_TYPE || - type == SCOUTFS_FREE_BITS_BLKNO_TYPE) - return print_free_bits; + if (type == SCOUTFS_FREE_EXTENT_BLKNO_TYPE || + type == SCOUTFS_FREE_EXTENT_BLOCKS_TYPE) + return print_free_extent; if (type == SCOUTFS_ORPHAN_TYPE) return print_orphan; } @@ -218,8 +218,7 @@ static print_func_t find_printer(u8 zone, u8 type) case SCOUTFS_READDIR_TYPE: return print_dirent; case SCOUTFS_SYMLINK_TYPE: return print_symlink; case SCOUTFS_LINK_BACKREF_TYPE: return print_dirent; - case SCOUTFS_BLOCK_MAPPING_TYPE: - return print_block_mapping; + case SCOUTFS_FILE_EXTENT_TYPE: return print_file_extent; } }