X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=lwext4%2Fext4_extent_full.c;h=2d34d67a6026f7d8a46582140e6536d2cfb3922e;hb=4b25da872742a15a49343f758e16d5e0447d1c48;hp=2fe50162d7001ede1f581f290bbb383dc9d4c2a0;hpb=f60d62d6cd364c09aef1c0ec94232183cf6f2b91;p=lwext4.git diff --git a/lwext4/ext4_extent_full.c b/lwext4/ext4_extent_full.c index 2fe5016..2d34d67 100644 --- a/lwext4/ext4_extent_full.c +++ b/lwext4/ext4_extent_full.c @@ -309,19 +309,20 @@ static ext4_fsblk_t ext4_ext_new_meta_block(struct ext4_inode_ref *inode_ref, return newblock; } +#if CONFIG_META_CSUM_ENABLE static uint32_t ext4_ext_block_csum(struct ext4_inode_ref *inode_ref, struct ext4_extent_header *eh) { uint32_t checksum = 0; struct ext4_sblock *sb = &inode_ref->fs->sb; - if (ext4_sb_has_feature_read_only(sb, - EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) { uint32_t ino_index = to_le32(inode_ref->index); uint32_t ino_gen = to_le32(ext4_inode_get_generation(inode_ref->inode)); /* First calculate crc32 checksum against fs uuid */ - checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid)); + checksum = ext4_crc32c(EXT4_CRC32_INIT, sb->uuid, + sizeof(sb->uuid)); /* Then calculate crc32 checksum against inode number * and inode generation */ checksum = ext4_crc32c(checksum, &ino_index, @@ -335,23 +336,25 @@ static uint32_t ext4_ext_block_csum(struct ext4_inode_ref *inode_ref, } return checksum; } +#else +#define ext4_ext_block_csum(...) 0 +#endif -static void ext4_extent_block_csum_set(struct ext4_inode_ref *inode_ref, +static void ext4_extent_block_csum_set(struct ext4_inode_ref *inode_ref __unused, struct ext4_extent_header *eh) { struct ext4_extent_tail *tail; tail = find_ext4_extent_tail(eh); - tail->et_checksum = ext4_ext_block_csum(inode_ref, eh); + tail->et_checksum = to_le32(ext4_ext_block_csum(inode_ref, eh)); } static int ext4_ext_dirty(struct ext4_inode_ref *inode_ref, struct ext4_extent_path *path) { - if (path->block.lb_id) { - ext4_extent_block_csum_set(inode_ref, path->header); - path->block.dirty = true; - } else + if (path->block.lb_id) + ext4_bcache_set_dirty(path->block.buf); + else inode_ref->dirty = true; return EOK; @@ -371,6 +374,10 @@ static void ext4_ext_drop_refs(struct ext4_inode_ref *inode_ref, for (i = 0; i <= depth; i++, path++) { if (path->block.lb_id) { + if (ext4_bcache_test_flag(path->block.buf, BC_DIRTY)) + ext4_extent_block_csum_set(inode_ref, + path->header); + ext4_block_set(inode_ref->fs->bdev, &path->block); } } @@ -385,6 +392,7 @@ static int ext4_ext_check(struct ext4_inode_ref *inode_ref, ext4_fsblk_t pblk __unused) { struct ext4_extent_tail *tail; + struct ext4_sblock *sb = &inode_ref->fs->sb; const char *error_msg; (void)error_msg; @@ -406,8 +414,14 @@ static int ext4_ext_check(struct ext4_inode_ref *inode_ref, } tail = find_ext4_extent_tail(eh); - if (tail->et_checksum != ext4_ext_block_csum(inode_ref, eh)) { - /* FIXME: Warning: extent checksum damaged? */ + if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) { + if (tail->et_checksum != to_le32(ext4_ext_block_csum(inode_ref, eh))) { + ext4_dbg(DEBUG_EXTENT, + DBG_WARN "Extent block checksum failed." + "Blocknr: %" PRIu64"\n", + pblk); + + } } return EOK; @@ -613,7 +627,7 @@ static int ext4_ext_split_node(struct ext4_inode_ref *inode_ref, goto cleanup; /* For write access.# */ - ret = ext4_block_get(inode_ref->fs->bdev, &bh, newblock); + ret = ext4_block_get_noread(inode_ref->fs->bdev, &bh, newblock); if (ret != EOK) goto cleanup; @@ -784,7 +798,7 @@ out: } else if (bh.lb_id) { /* If we got a sibling leaf. */ ext4_extent_block_csum_set(inode_ref, ext_block_hdr(&bh)); - bh.dirty = true; + ext4_bcache_set_dirty(bh.buf); spt->path.p_block = ext4_idx_pblock(ix); spt->path.depth = to_le16(eh->depth); @@ -1056,7 +1070,7 @@ out: } else if (bh.lb_id) { /* If we got a sibling leaf. */ ext4_extent_block_csum_set(inode_ref, ext_block_hdr(&bh)); - bh.dirty = true; + ext4_bcache_set_dirty(bh.buf); spt->path.p_block = ext4_ext_pblock(ex); spt->path.depth = to_le16(eh->depth); @@ -1115,7 +1129,7 @@ static int ext4_ext_grow_indepth(struct ext4_inode_ref *inode_ref, return err; /* # */ - err = ext4_block_get(inode_ref->fs->bdev, &bh, newblock); + err = ext4_block_get_noread(inode_ref->fs->bdev, &bh, newblock); if (err != EOK) { ext4_ext_free_blocks(inode_ref, newblock, 1, 0); return err; @@ -1137,6 +1151,7 @@ static int ext4_ext_grow_indepth(struct ext4_inode_ref *inode_ref, to_le16(ext4_ext_space_block(inode_ref)); neh->magic = to_le16(EXT4_EXTENT_MAGIC); + ext4_extent_block_csum_set(inode_ref, neh); /* Update top-level index: num,max,pointer */ neh = ext_inode_hdr(inode_ref->inode); @@ -1151,8 +1166,7 @@ static int ext4_ext_grow_indepth(struct ext4_inode_ref *inode_ref, } neh->depth = to_le16(to_le16(neh->depth) + 1); - ext4_extent_block_csum_set(inode_ref, neh); - bh.dirty = true; + ext4_bcache_set_dirty(bh.buf); inode_ref->dirty = true; ext4_block_set(inode_ref->fs->bdev, &bh); @@ -1709,12 +1723,12 @@ static int ext4_ext_zero_unwritten_range(struct ext4_inode_ref *inode_ref, uint32_t block_size = ext4_sb_get_block_size(&inode_ref->fs->sb); for (i = 0; i < blocks_count; i++) { struct ext4_block bh = EXT4_BLOCK_ZERO(); - err = ext4_block_get(inode_ref->fs->bdev, &bh, block + i); + err = ext4_block_get_noread(inode_ref->fs->bdev, &bh, block + i); if (err != EOK) break; memset(bh.data, 0, block_size); - bh.dirty = true; + ext4_bcache_set_dirty(bh.buf); err = ext4_block_set(inode_ref->fs->bdev, &bh); if (err != EOK) break;