errcode_t ocfs2_write_extent_block(ocfs2_filesys *fs, uint64_t blkno, char *eb_buf) { errcode_t ret; char *blk; struct ocfs2_extent_block *eb; if (!(fs->fs_flags & OCFS2_FLAG_RW)) return OCFS2_ET_RO_FILESYS; if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) || (blkno > fs->fs_blocks)) return OCFS2_ET_BAD_BLKNO; ret = ocfs2_malloc_block(fs->fs_io, &blk); if (ret) return ret; memcpy(blk, eb_buf, fs->fs_blocksize); eb = (struct ocfs2_extent_block *) blk; ocfs2_swap_extent_block_from_cpu(fs, eb); ocfs2_compute_meta_ecc(fs, blk, &eb->h_check); ret = io_write_block(fs->fs_io, blkno, 1, blk); if (ret) goto out; fs->fs_flags |= OCFS2_FLAG_CHANGED; ret = 0; out: ocfs2_free(&blk); return ret; }
/* * dump_block_check * */ void dump_block_check(FILE *out, struct ocfs2_block_check *bc, void *block) { struct ocfs2_block_check tmp = *bc; int crc_fail; enum ocfs2_block_type bt = ocfs2_detect_block(block); /* Swap block to little endian for compute_meta_ecc */ switch (bt) { case OCFS2_BLOCK_INODE: case OCFS2_BLOCK_SUPERBLOCK: ocfs2_swap_inode_from_cpu(gbls.fs, block); break; case OCFS2_BLOCK_EXTENT_BLOCK: ocfs2_swap_extent_block_from_cpu(gbls.fs, block); break; case OCFS2_BLOCK_GROUP_DESCRIPTOR: ocfs2_swap_group_desc_from_cpu(gbls.fs, block); break; case OCFS2_BLOCK_DIR_BLOCK: ocfs2_swap_dir_entries_from_cpu(block, gbls.fs->fs_blocksize); break; case OCFS2_BLOCK_XATTR: ocfs2_swap_xattr_block_from_cpu(gbls.fs, block); break; case OCFS2_BLOCK_REFCOUNT: ocfs2_swap_refcount_block_from_cpu(gbls.fs, block); break; case OCFS2_BLOCK_DXROOT: ocfs2_swap_dx_root_from_cpu(gbls.fs, block); break; case OCFS2_BLOCK_DXLEAF: ocfs2_swap_dx_leaf_from_cpu(block); break; default: fprintf(out, "Unable to determine block type"); return; } /* Re-compute based on what we got from disk */ ocfs2_compute_meta_ecc(gbls.fs, block, bc); /* Swap block back to CPU */ switch (bt) { case OCFS2_BLOCK_INODE: case OCFS2_BLOCK_SUPERBLOCK: ocfs2_swap_inode_to_cpu(gbls.fs, block); break; case OCFS2_BLOCK_EXTENT_BLOCK: ocfs2_swap_extent_block_to_cpu(gbls.fs, block); break; case OCFS2_BLOCK_GROUP_DESCRIPTOR: ocfs2_swap_group_desc_to_cpu(gbls.fs, block); break; case OCFS2_BLOCK_DIR_BLOCK: ocfs2_swap_dir_entries_to_cpu(block, gbls.fs->fs_blocksize); break; case OCFS2_BLOCK_XATTR: ocfs2_swap_xattr_block_to_cpu(gbls.fs, block); break; case OCFS2_BLOCK_REFCOUNT: ocfs2_swap_refcount_block_to_cpu(gbls.fs, block); break; case OCFS2_BLOCK_DXROOT: ocfs2_swap_dx_root_to_cpu(gbls.fs, block); break; case OCFS2_BLOCK_DXLEAF: ocfs2_swap_dx_leaf_to_cpu(block); break; default: break; } crc_fail = memcmp(bc, &tmp, sizeof(*bc)); fprintf(out, "\tCRC32: %.8"PRIx32" ECC: %.4"PRIx16"\n", le32_to_cpu(tmp.bc_crc32e), le16_to_cpu(tmp.bc_ecc)); if (crc_fail) fprintf(out, "\t**FAILED CHECKSUM** Computed CRC32: %.8" PRIx32" ECC: %.4"PRIx16"\n", le32_to_cpu(bc->bc_crc32e), le16_to_cpu(bc->bc_ecc)); /* Leave the block as we found it. */ *bc = tmp; }