diff --git a/utils/src/crc.c b/utils/src/crc.c index 6f40350a..38640fbc 100644 --- a/utils/src/crc.c +++ b/utils/src/crc.c @@ -32,8 +32,8 @@ u64 crc32c_64(u32 crc, const void *data, unsigned int len) crc32c(~crc, data + len - half, half); } -u32 crc_header(struct scoutfs_header *hdr, size_t size) +u32 crc_block(struct scoutfs_block_header *hdr) { return crc32c(~0, (char *)hdr + sizeof(hdr->crc), - size - sizeof(hdr->crc)); + SCOUTFS_BLOCK_SIZE - sizeof(hdr->crc)); } diff --git a/utils/src/crc.h b/utils/src/crc.h index d9e370e7..6878bf2f 100644 --- a/utils/src/crc.h +++ b/utils/src/crc.h @@ -7,6 +7,6 @@ u32 crc32c(u32 crc, const void *data, unsigned int len); u64 crc32c_64(u32 crc, const void *data, unsigned int len); -u32 crc_header(struct scoutfs_header *hdr, size_t size); +u32 crc_block(struct scoutfs_block_header *hdr); #endif diff --git a/utils/src/format.h b/utils/src/format.h index bff0b7cb..88d228a8 100644 --- a/utils/src/format.h +++ b/utils/src/format.h @@ -7,53 +7,66 @@ #define SCOUTFS_SUPER_ID 0x2e736674756f6373ULL /* "scoutfs." */ /* - * Some fs structures are stored in smaller fixed size 4k bricks. + * Structures are stored and referenced in fixed 4k chunks to + * simplify block buffer access at run time. */ -#define SCOUTFS_BRICK_SHIFT 12 -#define SCOUTFS_BRICK_SIZE (1 << SCOUTFS_BRICK_SHIFT) - -/* - * A large block size reduces the amount of per-block overhead throughout - * the system: block IO, manifest communications and storage, etc. - */ -#define SCOUTFS_BLOCK_SHIFT 22 +#define SCOUTFS_BLOCK_SHIFT 12 #define SCOUTFS_BLOCK_SIZE (1 << SCOUTFS_BLOCK_SHIFT) -/* for shifting between brick and block numbers */ -#define SCOUTFS_BLOCK_BRICK (SCOUTFS_BLOCK_SHIFT - SCOUTFS_BRICK_SHIFT) +/* + * Logs are a logical structure that is made up of a fixed number of + * contiguously allocated blocks. + * + * The allocator manages log-sized regions. Smaller metadata blocks + * like the ring and super blocks are stored inside large log + * allocations. + */ +#define SCOUTFS_LOG_SHIFT 22 +#define SCOUTFS_LOG_SIZE (1 << SCOUTFS_LOG_SHIFT) +#define SCOUTFS_LOG_BLOCK_SHIFT (SCOUTFS_LOG_SHIFT - SCOUTFS_BLOCK_SHIFT) +#define SCOUTFS_BLOCKS_PER_LOG (1 << SCOUTFS_LOG_BLOCK_SHIFT) /* - * The super bricks leave a bunch of room at the start of the first - * block for platform structures like boot loaders. + * The super blocks leave some room at the start of the first block for + * platform structures like boot loaders. */ -#define SCOUTFS_SUPER_BRICK 16 +#define SCOUTFS_SUPER_BLKNO ((64 * 1024) >> SCOUTFS_BLOCK_SHIFT) +#define SCOUTFS_SUPER_NR 2 /* - * This header is found at the start of every brick and block - * so that we can verify that it's what we were looking for. + * This header is found at the start of every block so that we can + * verify that it's what we were looking for. The crc and padding + * starts the block so that its calculation operations on a nice 64bit + * aligned region. */ -struct scoutfs_header { +struct scoutfs_block_header { __le32 crc; + __le32 _pad; __le64 fsid; __le64 seq; - __le64 nr; + __le64 blkno; } __packed; #define SCOUTFS_UUID_BYTES 16 /* - * The super is stored in a pair of bricks in the first block. + * The super is stored in a pair of blocks in log 0 on the device. + * + * The ring layout blocks describe the location of the ring blocks. The + * ring start and length refers to the logical ring blocks within that + * storage which contain live data. */ -struct scoutfs_super { - struct scoutfs_header hdr; +struct scoutfs_super_block { + struct scoutfs_block_header hdr; __le64 id; __u8 uuid[SCOUTFS_UUID_BYTES]; - __le64 total_blocks; - __le64 ring_layout_block; + __le64 total_logs; + __le64 ring_layout_blkno; + __le64 ring_layout_nr_blocks; __le64 ring_layout_seq; - __le64 last_ring_brick; - __le64 last_ring_seq; - __le64 last_block_seq; + __le64 ring_block; + __le64 ring_nr_blocks; + __le64 ring_seq; } __packed; /* @@ -71,10 +84,10 @@ struct scoutfs_key { #define SCOUTFS_INODE_KEY 128 #define SCOUTFS_DIRENT_KEY 192 -struct scoutfs_ring_layout { - struct scoutfs_header hdr; +struct scoutfs_layout_block { + struct scoutfs_block_header hdr; __le32 nr_blocks; - __le64 blocks[0]; + __le64 blknos[0]; } __packed; struct scoutfs_ring_entry { @@ -83,16 +96,16 @@ struct scoutfs_ring_entry { } __packed; /* - * Ring blocks are 4k blocks stored inside the large ring blocks - * referenced by the ring descriptor block. + * Ring blocks are 4k blocks stored inside the regions described by the + * ring layout block referenced by the super. * * The manifest entries describe the position of a given block in the * manifest. They're keyed by the block number so that we can log * movement of a block in the manifest with one log entry and we can log * deletion with just the block number. */ -struct scoutfs_ring_brick { - struct scoutfs_header hdr; +struct scoutfs_ring_block { + struct scoutfs_block_header hdr; __le16 nr_entries; } __packed; @@ -108,7 +121,7 @@ enum { * without the key. */ struct scoutfs_ring_remove_manifest { - __le64 block; + __le64 blkno; } __packed; /* @@ -119,7 +132,7 @@ struct scoutfs_ring_remove_manifest { * blocks when we didn't need to. */ struct scoutfs_ring_add_manifest { - __le64 block; + __le64 blkno; __le64 seq; __u8 level; struct scoutfs_key first; @@ -132,23 +145,15 @@ struct scoutfs_ring_bitmap { } __packed; /* - * This bloom size is chosen to have a roughly 1% false positive rate - * for ~90k items which is roughly the worst case for a block full of - * dirents with reasonably small names. Pathologically smaller items - * could be even more dense. + * To start the logs are a trivial single item block. We'll flesh this out + * into larger blocks once the rest of the architecture is in + * place. */ -#define SCOUTFS_BLOOM_FILTER_BYTES (128 * 1024) -#define SCOUTFS_BLOOM_FILTER_BITS (SCOUTFS_BLOOM_FILTER_BYTES * 8) -#define SCOUTFS_BLOOM_INDEX_BITS (ilog2(SCOUTFS_BLOOM_FILTER_BITS)) -#define SCOUTFS_BLOOM_INDEX_MASK ((1 << SCOUTFS_BLOOM_INDEX_BITS) - 1) -#define SCOUTFS_BLOOM_INDEX_NR 7 - -struct scoutfs_lsm_block { - struct scoutfs_header hdr; +struct scoutfs_item_block { + struct scoutfs_block_header hdr; struct scoutfs_key first; struct scoutfs_key last; __le32 nr_items; - /* u8 bloom[SCOUTFS_BLOOM_BYTES]; */ /* struct scoutfs_item_header items[0] .. */ } __packed; diff --git a/utils/src/mkfs.c b/utils/src/mkfs.c index 0c4e0198..60eb83dd 100644 --- a/utils/src/mkfs.c +++ b/utils/src/mkfs.c @@ -17,77 +17,56 @@ #include "crc.h" #include "rand.h" - /* - * Update the buffer's header and write it out. + * Update the block's header and write it out. */ -static int write_header(int fd, u64 nr, struct scoutfs_header *hdr, size_t size) +static int write_block(int fd, u64 blkno, struct scoutfs_block_header *hdr) { - off_t off = nr * size; ssize_t ret; - hdr->nr = cpu_to_le64(nr); - hdr->crc = cpu_to_le32(crc_header(hdr, size)); + hdr->blkno = cpu_to_le64(blkno); + hdr->crc = cpu_to_le32(crc_block(hdr)); - ret = pwrite(fd, hdr, size, off); - if (ret != size) { - fprintf(stderr, "write at nr %llu (offset %llu, size %zu) returned %zd: %s (%d)\n", - nr, (long long)off, size, ret, strerror(errno), errno); + ret = pwrite(fd, hdr, SCOUTFS_BLOCK_SIZE, blkno << SCOUTFS_BLOCK_SHIFT); + if (ret != SCOUTFS_BLOCK_SIZE) { + fprintf(stderr, "write to blkno %llu returned %zd: %s (%d)\n", + blkno, ret, strerror(errno), errno); return -errno; } return 0; } -static int write_brick(int fd, u64 nr, struct scoutfs_header *hdr) -{ - return write_header(fd, nr, hdr, SCOUTFS_BRICK_SIZE); -} - -static int write_block(int fd, u64 nr, struct scoutfs_header *hdr) -{ - return write_header(fd, nr, hdr, SCOUTFS_BLOCK_SIZE); -} - -/* - * - config blocks that describe ring - * - ring entries for lots of free blocks - * - manifest that references single block - * - block with inode - */ -/* - * So what does mkfs really need to do? - * - * - super blocks that describe ring log - * - ring log with free bitmap entries - * - ring log with manifest entries - * - single item block with root dir - */ static int write_new_fs(char *path, int fd) { - struct scoutfs_super *super; + struct scoutfs_super_block *super; + struct scoutfs_block_header hdr; struct scoutfs_inode *inode; - struct scoutfs_ring_layout *rlo; - struct scoutfs_ring_brick *ring; + struct scoutfs_layout_block *lout; + struct scoutfs_ring_block *ring; struct scoutfs_ring_entry *ent; struct scoutfs_ring_add_manifest *mani; struct scoutfs_ring_bitmap *bm; - struct scoutfs_lsm_block *lblk; + struct scoutfs_item_block *iblk; struct scoutfs_item_header *ihdr; struct scoutfs_key root_key; struct timeval tv; char uuid_str[37]; struct stat st; unsigned int i; - u64 total_blocks; + u64 total_logs; + u64 blkno; void *buf; int ret; gettimeofday(&tv, NULL); + /* crc and blkno written for each write */ + hdr._pad = 0; + pseudo_random_bytes(&hdr.fsid, sizeof(hdr.fsid)); + hdr.seq = cpu_to_le64(1); - super = malloc(SCOUTFS_BRICK_SIZE); buf = malloc(SCOUTFS_BLOCK_SIZE); - if (!super || !buf) { + if (!buf) { ret = -errno; fprintf(stderr, "failed to allocate a block: %s (%d)\n", strerror(errno), errno); @@ -101,75 +80,23 @@ static int write_new_fs(char *path, int fd) goto out; } - total_blocks = st.st_size >> SCOUTFS_BLOCK_SHIFT; + total_logs = st.st_size >> SCOUTFS_LOG_SHIFT; root_key.inode = cpu_to_le64(SCOUTFS_ROOT_INO); root_key.type = SCOUTFS_INODE_KEY; root_key.offset = 0; - /* initialize the super */ - memset(super, 0, sizeof(struct scoutfs_super)); - pseudo_random_bytes(&super->hdr.fsid, sizeof(super->hdr.fsid)); - super->hdr.seq = cpu_to_le64(1); - super->id = cpu_to_le64(SCOUTFS_SUPER_ID); - uuid_generate(super->uuid); - super->total_blocks = cpu_to_le64(total_blocks); - super->ring_layout_block = cpu_to_le64(1); - super->ring_layout_seq = cpu_to_le64(1); - super->last_ring_brick = cpu_to_le64(1); - super->last_ring_seq = cpu_to_le64(1); - super->last_block_seq = cpu_to_le64(1); + /* super in log 0, first fs log block in log 1 */ + blkno = 1 << SCOUTFS_LOG_BLOCK_SHIFT; - /* the ring has a single block for now */ + /* write a single log block with the root inode item */ memset(buf, 0, SCOUTFS_BLOCK_SIZE); - rlo = buf; - rlo->hdr.fsid = super->hdr.fsid; - rlo->hdr.seq = super->ring_layout_seq; - rlo->nr_blocks = cpu_to_le32(1); - rlo->blocks[0] = cpu_to_le64(2); - - ret = write_block(fd, 1, &rlo->hdr); - if (ret) - goto out; - - /* log the root inode block manifest and free bitmap */ - memset(buf, 0, SCOUTFS_BLOCK_SIZE); - ring = buf; - ring->hdr.fsid = super->hdr.fsid; - ring->hdr.seq = super->last_ring_seq; - ring->nr_entries = cpu_to_le16(2); - ent = (void *)(ring + 1); - ent->type = SCOUTFS_RING_ADD_MANIFEST; - ent->len = cpu_to_le16(sizeof(*mani)); - mani = (void *)(ent + 1); - mani->block = cpu_to_le64(3); - mani->seq = super->last_block_seq; - mani->level = 0; - mani->first = root_key; - mani->last = root_key; - ent = (void *)(mani + 1); - ent->type = SCOUTFS_RING_BITMAP; - ent->len = cpu_to_le16(sizeof(*bm)); - bm = (void *)(ent + 1); - memset(bm->bits, 0xff, sizeof(bm->bits)); - /* the first three blocks are allocated */ - bm->bits[0] = cpu_to_le64(~7ULL); - bm->bits[1] = cpu_to_le64(~0ULL); - - ret = write_brick(fd, 2 << SCOUTFS_BLOCK_BRICK, &ring->hdr); - if (ret) - goto out; - - /* write a single lsm block with the root inode item */ - memset(buf, 0, SCOUTFS_BLOCK_SIZE); - lblk = buf; - lblk->hdr.fsid = super->hdr.fsid; - lblk->hdr.seq = super->last_block_seq; - lblk->first = root_key; - lblk->last = root_key; - lblk->nr_items = cpu_to_le32(1); - /* XXX set bloom */ - ihdr = (void *)((char *)(lblk + 1) + SCOUTFS_BLOOM_FILTER_BYTES); + iblk = buf; + iblk->hdr = hdr; + iblk->first = root_key; + iblk->last = root_key; + iblk->nr_items = cpu_to_le32(1); + ihdr = (void *)(iblk + 1); ihdr->key = root_key; ihdr->len = cpu_to_le16(sizeof(struct scoutfs_inode)); inode = (void *)(ihdr + 1); @@ -182,14 +109,67 @@ static int write_new_fs(char *path, int fd) inode->mtime.sec = inode->atime.sec; inode->mtime.nsec = inode->atime.nsec; - ret = write_block(fd, 3, &ring->hdr); + ret = write_block(fd, blkno, &iblk->hdr); if (ret) goto out; - /* write the two super bricks */ - for (i = 0; i < 2; i++) { - super->hdr.seq = cpu_to_le64(i); - ret = write_brick(fd, SCOUTFS_SUPER_BRICK + i, &super->hdr); + /* write the ring block whose manifest entry references the log block */ + memset(buf, 0, SCOUTFS_BLOCK_SIZE); + ring = buf; + ring->hdr = hdr; + ring->nr_entries = cpu_to_le16(2); + ent = (void *)(ring + 1); + ent->type = SCOUTFS_RING_ADD_MANIFEST; + ent->len = cpu_to_le16(sizeof(*mani)); + mani = (void *)(ent + 1); + mani->blkno = cpu_to_le64(blkno); + mani->seq = hdr.seq; + mani->level = 0; + mani->first = root_key; + mani->last = root_key; + ent = (void *)(mani + 1); + ent->type = SCOUTFS_RING_BITMAP; + ent->len = cpu_to_le16(sizeof(*bm)); + bm = (void *)(ent + 1); + memset(bm->bits, 0xff, sizeof(bm->bits)); + /* the first three blocks are allocated */ + bm->bits[0] = cpu_to_le64(~7ULL); + bm->bits[1] = cpu_to_le64(~0ULL); + + blkno += SCOUTFS_BLOCKS_PER_LOG; + ret = write_block(fd, blkno, &ring->hdr); + if (ret) + goto out; + + /* the ring has a single block for now */ + memset(buf, 0, SCOUTFS_BLOCK_SIZE); + lout = buf; + lout->hdr = hdr; + lout->nr_blocks = cpu_to_le32(1); + lout->blknos[0] = cpu_to_le64(blkno); + + blkno += SCOUTFS_BLOCKS_PER_LOG; + ret = write_block(fd, blkno, &lout->hdr); + if (ret) + goto out; + + /* write the two super blocks */ + memset(buf, 0, SCOUTFS_BLOCK_SIZE); + super = buf; + super->hdr = hdr; + super->id = cpu_to_le64(SCOUTFS_SUPER_ID); + uuid_generate(super->uuid); + super->total_logs = cpu_to_le64(total_logs); + super->ring_layout_blkno = cpu_to_le64(blkno); + super->ring_layout_nr_blocks = cpu_to_le64(1); + super->ring_layout_seq = hdr.seq; + super->ring_block = cpu_to_le64(0); + super->ring_nr_blocks = cpu_to_le64(1); + super->ring_seq = hdr.seq; + + for (i = 0; i < SCOUTFS_SUPER_NR; i++) { + super->hdr.seq = cpu_to_le64(i + 1); + ret = write_block(fd, SCOUTFS_SUPER_BLKNO + i, &super->hdr); if (ret) goto out; } @@ -204,14 +184,13 @@ static int write_new_fs(char *path, int fd) uuid_unparse(super->uuid, uuid_str); printf("Created scoutfs filesystem:\n" - " total blocks: %llu\n" + " total logs: %llu\n" " fsid: %llx\n" " uuid: %s\n", - total_blocks, le64_to_cpu(super->hdr.fsid), uuid_str); + total_logs, le64_to_cpu(super->hdr.fsid), uuid_str); ret = 0; out: - free(super); free(buf); return ret; } diff --git a/utils/src/print.c b/utils/src/print.c index df74bc67..503eacda 100644 --- a/utils/src/print.c +++ b/utils/src/print.c @@ -22,20 +22,19 @@ #define SKA(k) le64_to_cpu((k)->inode), (k)->type, \ le64_to_cpu((k)->offset) -static void *read_buf(int fd, u64 nr, size_t size) +static void *read_block(int fd, u64 blkno) { - off_t off = nr * size; ssize_t ret; void *buf; - buf = malloc(size); + buf = malloc(SCOUTFS_BLOCK_SIZE); if (!buf) return NULL; - ret = pread(fd, buf, size, off); - if (ret != size) { - fprintf(stderr, "read at blkno %llu (offset %llu) returned %zd: %s (%d)\n", - nr, (long long)off, ret, strerror(errno), errno); + ret = pread(fd, buf, SCOUTFS_BLOCK_SIZE, blkno << SCOUTFS_BLOCK_SHIFT); + if (ret != SCOUTFS_BLOCK_SIZE) { + fprintf(stderr, "read blkno %llu returned %zd: %s (%d)\n", + blkno, ret, strerror(errno), errno); free(buf); buf = NULL; } @@ -43,19 +42,9 @@ static void *read_buf(int fd, u64 nr, size_t size) return buf; } -static void *read_brick(int fd, u64 nr) +static void print_block_header(struct scoutfs_block_header *hdr) { - return read_buf(fd, nr, SCOUTFS_BRICK_SIZE); -} - -static void *read_block(int fd, u64 nr) -{ - return read_buf(fd, nr, SCOUTFS_BLOCK_SIZE); -} - -static void print_header(struct scoutfs_header *hdr, size_t size) -{ - u32 crc = crc_header(hdr, size); + u32 crc = crc_block(hdr); char valid_str[40]; if (crc != le32_to_cpu(hdr->crc)) @@ -67,19 +56,9 @@ static void print_header(struct scoutfs_header *hdr, size_t size) " crc: %08x %s\n" " fsid: %llx\n" " seq: %llu\n" - " nr: %llu\n", + " blkno: %llu\n", le32_to_cpu(hdr->crc), valid_str, le64_to_cpu(hdr->fsid), - le64_to_cpu(hdr->seq), le64_to_cpu(hdr->nr)); -} - -static void print_brick_header(struct scoutfs_header *hdr) -{ - return print_header(hdr, SCOUTFS_BRICK_SIZE); -} - -static void print_block_header(struct scoutfs_header *hdr) -{ - return print_header(hdr, SCOUTFS_BLOCK_SIZE); + le64_to_cpu(hdr->seq), le64_to_cpu(hdr->blkno)); } static void print_inode(struct scoutfs_inode *inode) @@ -108,12 +87,12 @@ static void print_inode(struct scoutfs_inode *inode) le32_to_cpu(inode->mtime.nsec)); } -static void print_item(struct scoutfs_item_header *ihdr, size_t off) +static void print_item(struct scoutfs_item_header *ihdr) { - printf(" item: &%zu\n" + printf(" item:\n" " key: "SKF"\n" " len: %u\n", - off, SKA(&ihdr->key), le16_to_cpu(ihdr->len)); + SKA(&ihdr->key), le16_to_cpu(ihdr->len)); switch(ihdr->key.type) { case SCOUTFS_INODE_KEY: @@ -122,49 +101,49 @@ static void print_item(struct scoutfs_item_header *ihdr, size_t off) } } -static int print_block(int fd, u64 nr) +static int print_item_block(int fd, u64 nr) { struct scoutfs_item_header *ihdr; - struct scoutfs_lsm_block *lblk; + struct scoutfs_item_block *iblk; size_t off; int i; - lblk = read_block(fd, nr); - if (!lblk) + iblk = read_block(fd, nr); + if (!iblk) return -ENOMEM; - printf("block: &%llu\n", le64_to_cpu(lblk->hdr.nr)); - print_block_header(&lblk->hdr); + printf("item block:\n"); + print_block_header(&iblk->hdr); printf(" first: "SKF"\n" " last: "SKF"\n" " nr_items: %u\n", - SKA(&lblk->first), SKA(&lblk->last), - le32_to_cpu(lblk->nr_items)); - off = (char *)(lblk + 1) - (char *)lblk + SCOUTFS_BLOOM_FILTER_BYTES; + SKA(&iblk->first), SKA(&iblk->last), + le32_to_cpu(iblk->nr_items)); - for (i = 0; i < le32_to_cpu(lblk->nr_items); i++) { - ihdr = (void *)((char *)lblk + off); - print_item(ihdr, off); + off = sizeof(struct scoutfs_item_block); + for (i = 0; i < le32_to_cpu(iblk->nr_items); i++) { + ihdr = (void *)((char *)iblk + off); + print_item(ihdr); off += sizeof(struct scoutfs_item_header) + le16_to_cpu(ihdr->len); } - free(lblk); + free(iblk); return 0; } -static int print_blocks(int fd, __le64 *live_blocks, u64 total_blocks) +static int print_log_blocks(int fd, __le64 *live_logs, u64 total_logs) { int ret = 0; int err; s64 nr; - while ((nr = find_first_le_bit(live_blocks, total_blocks)) >= 0) { - clear_le_bit(live_blocks, nr); + while ((nr = find_first_le_bit(live_logs, total_logs)) >= 0) { + clear_le_bit(live_logs, nr); - err = print_block(fd, nr); + err = print_item_block(fd, nr << SCOUTFS_LOG_BLOCK_SHIFT); if (!ret && err) ret = err; } @@ -186,32 +165,31 @@ static char *ent_type_str(u8 type) } } -static void print_ring_entry(int fd, struct scoutfs_ring_entry *ent, - size_t off) +static void print_ring_entry(int fd, struct scoutfs_ring_entry *ent) { struct scoutfs_ring_remove_manifest *rem; struct scoutfs_ring_add_manifest *add; struct scoutfs_ring_bitmap *bm; - printf(" entry: &%zu\n" + printf(" entry:\n" " type: %u # %s\n" " len: %u\n", - off, ent->type, ent_type_str(ent->type), le16_to_cpu(ent->len)); + ent->type, ent_type_str(ent->type), le16_to_cpu(ent->len)); switch(ent->type) { case SCOUTFS_RING_REMOVE_MANIFEST: rem = (void *)(ent + 1); - printf(" block: %llu\n", - le64_to_cpu(rem->block)); + printf(" blkno: %llu\n", + le64_to_cpu(rem->blkno)); break; case SCOUTFS_RING_ADD_MANIFEST: add = (void *)(ent + 1); - printf(" block: %llu\n" + printf(" blkno: %llu\n" " seq: %llu\n" " level: %u\n" " first: "SKF"\n" " last: "SKF"\n", - le64_to_cpu(add->block), le64_to_cpu(add->seq), + le64_to_cpu(add->blkno), le64_to_cpu(add->seq), add->level, SKA(&add->first), SKA(&add->last)); break; case SCOUTFS_RING_BITMAP: @@ -224,51 +202,51 @@ static void print_ring_entry(int fd, struct scoutfs_ring_entry *ent, } } -static void update_live_blocks(struct scoutfs_ring_entry *ent, - __le64 *live_blocks) +static void update_live_logs(struct scoutfs_ring_entry *ent, + __le64 *live_logs) { struct scoutfs_ring_remove_manifest *rem; struct scoutfs_ring_add_manifest *add; + u64 bit; switch(ent->type) { case SCOUTFS_RING_REMOVE_MANIFEST: rem = (void *)(ent + 1); - clear_le_bit(live_blocks, le64_to_cpu(rem->block)); + bit = le64_to_cpu(rem->blkno) >> SCOUTFS_LOG_BLOCK_SHIFT; + clear_le_bit(live_logs, bit); break; case SCOUTFS_RING_ADD_MANIFEST: add = (void *)(ent + 1); - set_le_bit(live_blocks, le64_to_cpu(add->block)); + bit = le64_to_cpu(add->blkno) >> SCOUTFS_LOG_BLOCK_SHIFT; + set_le_bit(live_logs, bit); break; } } -static int print_ring_block(int fd, u64 block_nr, __le64 *live_blocks) +static int print_ring_block(int fd, u64 blkno, __le64 *live_logs) { - struct scoutfs_ring_brick *ring; + struct scoutfs_ring_block *ring; struct scoutfs_ring_entry *ent; size_t off; int ret = 0; - u64 nr; int i; - /* XXX just printing the first brick for now */ + /* XXX just printing the first block for now */ - nr = block_nr << SCOUTFS_BLOCK_BRICK; - ring = read_brick(fd, nr); + ring = read_block(fd, blkno); if (!ring) return -ENOMEM; - printf("ring brick: &%llu\n", nr); - print_brick_header(&ring->hdr); + printf("ring block:\n"); + print_block_header(&ring->hdr); printf(" nr_entries: %u\n", le16_to_cpu(ring->nr_entries)); - off = sizeof(struct scoutfs_ring_brick); + off = sizeof(struct scoutfs_ring_block); for (i = 0; i < le16_to_cpu(ring->nr_entries); i++) { ent = (void *)((char *)ring + off); - update_live_blocks(ent, live_blocks); - - print_ring_entry(fd, ent, off); + update_live_logs(ent, live_logs); + print_ring_entry(fd, ent); off += sizeof(struct scoutfs_ring_entry) + le16_to_cpu(ent->len); @@ -278,95 +256,97 @@ static int print_ring_block(int fd, u64 block_nr, __le64 *live_blocks) return ret; } -static int print_ring_layout(int fd, u64 blkno, __le64 *live_blocks) +static int print_layout_block(int fd, u64 blkno, __le64 *live_logs) { - struct scoutfs_ring_layout *rlo; + struct scoutfs_layout_block *lout; int ret = 0; int err; int i; - rlo = read_block(fd, blkno); - if (!rlo) + lout = read_block(fd, blkno); + if (!lout) return -ENOMEM; - printf("ring layout: &%llu\n", blkno); - print_block_header(&rlo->hdr); - printf(" nr_blocks: %u\n", le32_to_cpu(rlo->nr_blocks)); + printf("layout block:\n"); + print_block_header(&lout->hdr); + printf(" nr_blocks: %u\n", le32_to_cpu(lout->nr_blocks)); - printf(" blocks: "); - for (i = 0; i < le32_to_cpu(rlo->nr_blocks); i++) - printf(" %llu\n", le64_to_cpu(rlo->blocks[i])); + printf(" blknos: "); + for (i = 0; i < le32_to_cpu(lout->nr_blocks); i++) + printf(" %llu\n", le64_to_cpu(lout->blknos[i])); - for (i = 0; i < le32_to_cpu(rlo->nr_blocks); i++) { - err = print_ring_block(fd, le64_to_cpu(rlo->blocks[i]), - live_blocks); + for (i = 0; i < le32_to_cpu(lout->nr_blocks); i++) { + err = print_ring_block(fd, le64_to_cpu(lout->blknos[i]), + live_logs); if (err && !ret) ret = err; } - free(rlo); + free(lout); return 0; } static int print_super_brick(int fd) { - struct scoutfs_super *super; + struct scoutfs_super_block *super; char uuid_str[37]; - __le64 *live_blocks; - u64 total_blocks; + __le64 *live_logs; + u64 total_logs; size_t bytes; int ret = 0; int err; /* XXX print both */ - super = read_brick(fd, SCOUTFS_SUPER_BRICK); + super = read_block(fd, SCOUTFS_SUPER_BLKNO); if (!super) return -ENOMEM; uuid_unparse(super->uuid, uuid_str); - total_blocks = le64_to_cpu(super->total_blocks); + total_logs = le64_to_cpu(super->total_logs); - printf("super: &%llu\n", le64_to_cpu(super->hdr.nr)); - print_brick_header(&super->hdr); + printf("super:\n"); + print_block_header(&super->hdr); printf(" id: %llx\n" " uuid: %s\n" - " total_blocks: %llu\n" - " ring_layout_block: %llu\n" + " total_logs: %llu\n" + " ring_layout_blkno: %llu\n" + " ring_layout_nr_blocks: %llu\n" " ring_layout_seq: %llu\n" - " last_ring_brick: %llu\n" - " last_ring_seq: %llu\n" - " last_block_seq: %llu\n", + " ring_block: %llu\n" + " ring_seq: %llu\n" + " ring_nr_blocks: %llu\n", le64_to_cpu(super->id), uuid_str, - total_blocks, - le64_to_cpu(super->ring_layout_block), + total_logs, + le64_to_cpu(super->ring_layout_blkno), + le64_to_cpu(super->ring_layout_nr_blocks), le64_to_cpu(super->ring_layout_seq), - le64_to_cpu(super->last_ring_brick), - le64_to_cpu(super->last_ring_seq), - le64_to_cpu(super->last_block_seq)); + le64_to_cpu(super->ring_block), + le64_to_cpu(super->ring_nr_blocks), + le64_to_cpu(super->ring_seq)); /* XXX by hand? */ - bytes = (total_blocks + 63) / 8; - live_blocks = malloc(bytes); - if (!live_blocks) { + bytes = (total_logs + 63) / 8; + live_logs = malloc(bytes); + if (!live_logs) { ret = -ENOMEM; goto out; } - memset(live_blocks, 0, bytes); + memset(live_logs, 0, bytes); - err = print_ring_layout(fd, le64_to_cpu(super->ring_layout_block), - live_blocks); + err = print_layout_block(fd, le64_to_cpu(super->ring_layout_blkno), + live_logs); if (err && !ret) ret = err; - err = print_blocks(fd, live_blocks, total_blocks); + err = print_log_blocks(fd, live_logs, total_logs); if (err && !ret) ret = err; out: free(super); - free(live_blocks); + free(live_logs); return ret; }