[Ocfs2-tools-devel] [PATCH 08/12] libocfs2: Add support for metadata checksums and error correction.
Sunil Mushran
sunil.mushran at oracle.com
Wed Jan 7 17:44:50 PST 2009
Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
Joel Becker wrote:
> Use the functions in blockcheck.[ch] to add checksums and error
> correction to libocfs2.
>
> Signed-off-by: Joel Becker <joel.becker at oracle.com>
> ---
> libocfs2/chain.c | 5 +++++
> libocfs2/dirblock.c | 13 +++++++++----
> libocfs2/extents.c | 5 +++++
> libocfs2/feature_string.c | 12 +++++++++++-
> libocfs2/inode.c | 4 ++++
> libocfs2/openfs.c | 37 +++++++++++++++++++++++++++++++++----
> 6 files changed, 67 insertions(+), 9 deletions(-)
>
> diff --git a/libocfs2/chain.c b/libocfs2/chain.c
> index 7af61fe..e9d3873 100644
> --- a/libocfs2/chain.c
> +++ b/libocfs2/chain.c
> @@ -67,6 +67,10 @@ errcode_t ocfs2_read_group_desc(ocfs2_filesys *fs, uint64_t blkno,
>
> gd = (struct ocfs2_group_desc *)blk;
>
> + ret = ocfs2_validate_meta_ecc(fs, blk, &gd->bg_check);
> + if (ret)
> + goto out;
> +
> ret = OCFS2_ET_BAD_GROUP_DESC_MAGIC;
> if (memcmp(gd->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
> strlen(OCFS2_GROUP_DESC_SIGNATURE)))
> @@ -107,6 +111,7 @@ errcode_t ocfs2_write_group_desc(ocfs2_filesys *fs, uint64_t blkno,
> gd = (struct ocfs2_group_desc *)blk;
> ocfs2_swap_group_desc(gd);
>
> + ocfs2_compute_meta_ecc(fs, blk, &gd->bg_check);
> ret = io_write_block(fs->fs_io, blkno, 1, blk);
> if (ret)
> goto out;
> diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
> index d1a9a45..fec8ffc 100644
> --- a/libocfs2/dirblock.c
> +++ b/libocfs2/dirblock.c
> @@ -54,12 +54,12 @@ int ocfs2_dir_has_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di)
> (di->i_dyn_features & OCFS2_INLINE_DATA_FL))
> return 0;
>
> - return 0;
> + return ocfs2_meta_ecc(OCFS2_RAW_SB(fs->fs_super));
> }
>
> int ocfs2_supports_dir_trailer(ocfs2_filesys *fs)
> {
> - return 0;
> + return ocfs2_meta_ecc(OCFS2_RAW_SB(fs->fs_super));
> }
>
> int ocfs2_skip_dir_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di,
> @@ -165,6 +165,10 @@ errcode_t ocfs2_read_dir_block(ocfs2_filesys *fs, struct ocfs2_dinode *di,
> end = ocfs2_dir_trailer_blk_off(fs);
> trailer = ocfs2_dir_trailer_from_block(fs, buf);
>
> + retval = ocfs2_validate_meta_ecc(fs, buf, &trailer->db_check);
> + if (retval)
> + goto out;
> +
> if (memcmp(trailer->db_signature, OCFS2_DIR_TRAILER_SIGNATURE,
> strlen(OCFS2_DIR_TRAILER_SIGNATURE))) {
> retval = OCFS2_ET_BAD_DIR_BLOCK_MAGIC;
> @@ -205,13 +209,14 @@ errcode_t ocfs2_write_dir_block(ocfs2_filesys *fs, struct ocfs2_dinode *di,
> goto out;
>
> /*
> - * We can always set trailer - Nothing happens if it isn't actually
> - * used.
> + * We can always set trailer - ocfs2_compute_meta_ecc() does
> + * nothing if the filesystem doesn't have the feature turned on
> */
> trailer = ocfs2_dir_trailer_from_block(fs, buf);
> if (ocfs2_dir_has_trailer(fs, di))
> ocfs2_swap_dir_trailer(trailer);
>
> + ocfs2_compute_meta_ecc(fs, buf, &trailer->db_check);
> retval = io_write_block(fs->fs_io, block, 1, buf);
> out:
> ocfs2_free(&buf);
> diff --git a/libocfs2/extents.c b/libocfs2/extents.c
> index 51b1aae..5f16789 100644
> --- a/libocfs2/extents.c
> +++ b/libocfs2/extents.c
> @@ -124,6 +124,10 @@ errcode_t ocfs2_read_extent_block_nocheck(ocfs2_filesys *fs,
>
> eb = (struct ocfs2_extent_block *)blk;
>
> + ret = ocfs2_validate_meta_ecc(fs, blk, &eb->h_check);
> + if (ret)
> + goto out;
> +
> if (memcmp(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
> strlen(OCFS2_EXTENT_BLOCK_SIGNATURE))) {
> ret = OCFS2_ET_BAD_EXTENT_BLOCK_MAGIC;
> @@ -179,6 +183,7 @@ errcode_t ocfs2_write_extent_block(ocfs2_filesys *fs, uint64_t blkno,
> eb = (struct ocfs2_extent_block *) blk;
> ocfs2_swap_extent_block_from_cpu(eb);
>
> + ocfs2_compute_meta_ecc(fs, blk, &eb->h_check);
> ret = io_write_block(fs->fs_io, blkno, 1, blk);
> if (ret)
> goto out;
> diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
> index 7b1f93e..56618db 100644
> --- a/libocfs2/feature_string.c
> +++ b/libocfs2/feature_string.c
> @@ -72,7 +72,8 @@ static ocfs2_fs_options feature_level_defaults[] = {
> {OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
> OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
> OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP |
> - OCFS2_FEATURE_INCOMPAT_INLINE_DATA,
> + OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
> + OCFS2_FEATURE_INCOMPAT_META_ECC,
> OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* OCFS2_FEATURE_LEVEL_MAX_FEATURES */
> };
>
> @@ -110,6 +111,11 @@ static struct fs_feature_flags ocfs2_supported_features[] = {
> {0, OCFS2_FEATURE_INCOMPAT_INLINE_DATA, 0},
> },
> {
> + "metaecc",
> + {0, OCFS2_FEATURE_INCOMPAT_META_ECC, 0},
> + {0, OCFS2_FEATURE_INCOMPAT_META_ECC, 0},
> + },
> + {
> NULL,
> {0, 0, 0},
> {0, 0, 0}
> @@ -169,6 +175,10 @@ static struct feature_name ocfs2_feature_names[] = {
> .fn_flag = {OCFS2_FEATURE_COMPAT_JBD2_SB, 0, 0},
> },
> {
> + .fn_name = "MetaECC",
> + .fn_flag = {0, OCFS2_FEATURE_INCOMPAT_META_ECC, 0},
> + },
> + {
> .fn_name = NULL,
> },
> };
> diff --git a/libocfs2/inode.c b/libocfs2/inode.c
> index d351658..25d14b7 100644
> --- a/libocfs2/inode.c
> +++ b/libocfs2/inode.c
> @@ -256,6 +256,9 @@ errcode_t ocfs2_read_inode(ocfs2_filesys *fs, uint64_t blkno,
> goto out;
>
> di = (struct ocfs2_dinode *)blk;
> + ret = ocfs2_validate_meta_ecc(fs, blk, &di->i_check);
> + if (ret)
> + goto out;
>
> ret = OCFS2_ET_BAD_INODE_MAGIC;
> if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
> @@ -297,6 +300,7 @@ errcode_t ocfs2_write_inode(ocfs2_filesys *fs, uint64_t blkno,
> di = (struct ocfs2_dinode *)blk;
> ocfs2_swap_inode_from_cpu(di);
>
> + ocfs2_compute_meta_ecc(fs, blk, &di->i_check);
> ret = io_write_block(fs->fs_io, blkno, 1, blk);
> if (ret)
> goto out;
> diff --git a/libocfs2/openfs.c b/libocfs2/openfs.c
> index 4044757..0f6d048 100644
> --- a/libocfs2/openfs.c
> +++ b/libocfs2/openfs.c
> @@ -102,8 +102,10 @@ out:
> errcode_t ocfs2_read_super(ocfs2_filesys *fs, uint64_t superblock, char *sb)
> {
> errcode_t ret;
> - char *blk;
> - struct ocfs2_dinode *di;
> + char *blk, *swapblk;
> + struct ocfs2_dinode *di, *orig_super;
> + int orig_blocksize;
> + int blocksize = io_get_blksize(fs->fs_io);
>
> ret = ocfs2_malloc_block(fs->fs_io, &blk);
> if (ret)
> @@ -112,6 +114,7 @@ errcode_t ocfs2_read_super(ocfs2_filesys *fs, uint64_t superblock, char *sb)
> ret = ocfs2_read_blocks(fs, superblock, 1, blk);
> if (ret)
> goto out_blk;
> +
> di = (struct ocfs2_dinode *)blk;
>
> ret = OCFS2_ET_BAD_MAGIC;
> @@ -119,8 +122,33 @@ errcode_t ocfs2_read_super(ocfs2_filesys *fs, uint64_t superblock, char *sb)
> strlen(OCFS2_SUPER_BLOCK_SIGNATURE)))
> goto out_blk;
>
> - ocfs2_swap_inode_to_cpu(di);
> + /*
> + * We want to use the latest superblock to validate. We need
> + * a local-endian copy in fs->fs_super, and the unswapped copy to
> + * check in blk. ocfs2_validate_meta_ecc() uses fs->fs_super and
> + * fs->fs_blocksize.
> + */
> + ret = ocfs2_malloc_block(fs->fs_io, &swapblk);
> + if (ret)
> + goto out_blk;
>
> + memcpy(swapblk, blk, blocksize);
> + orig_super = fs->fs_super;
> + orig_blocksize = fs->fs_blocksize;
> + fs->fs_super = (struct ocfs2_dinode *)swapblk;
> + fs->fs_blocksize = blocksize;
> + ocfs2_swap_inode_to_cpu(fs->fs_super);
> +
> + ret = ocfs2_validate_meta_ecc(fs, blk, &di->i_check);
> +
> + fs->fs_super = orig_super;
> + fs->fs_blocksize = orig_blocksize;
> + ocfs2_free(&swapblk);
> +
> + if (ret)
> + goto out_blk;
> +
> + ocfs2_swap_inode_to_cpu(di);
> if (!sb)
> fs->fs_super = di;
> else {
> @@ -288,7 +316,8 @@ errcode_t ocfs2_open(const char *name, int flags,
> io_set_blksize(fs->fs_io, block_size);
> ret = ocfs2_read_super(fs, (uint64_t)superblock,
> NULL);
> - if (ret == OCFS2_ET_BAD_MAGIC)
> + if ((ret == OCFS2_ET_BAD_MAGIC) ||
> + (ret == OCFS2_ET_IO))
> continue;
> break;
> }
>
More information about the Ocfs2-tools-devel
mailing list