ext4_journal: journal write skeleton code.
[lwext4.git] / lwext4 / ext4_extent_full.c
index 2fe50162d7001ede1f581f290bbb383dc9d4c2a0..2d34d67a6026f7d8a46582140e6536d2cfb3922e 100644 (file)
@@ -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;