[Cluster-devel] [PATCH 8/8] libgfs2: Add support for rg_crc
Steven Whitehouse
swhiteho at redhat.com
Thu Dec 7 12:06:05 UTC 2017
Excellent - looks really good :-)
Steve.
On 07/12/17 11:53, Andrew Price wrote:
> This new field in the resource group headers is set on write and checked
> on read so that fsck.gfs2 now considers a resource group with a bad,
> non-zero crc to be corrupted. gfs2_grow, gfs2_edit, and mkfs.gfs2 all
> now support the rg_crc field, including save/restoremeta.
>
> Signed-off-by: Andrew Price <anprice at redhat.com>
> ---
> gfs2/libgfs2/libgfs2.h | 2 ++
> gfs2/libgfs2/meta.c | 1 +
> gfs2/libgfs2/ondisk.c | 7 +++++--
> gfs2/libgfs2/rgrp.c | 54 +++++++++++++++++++++++++++++++++++++++++++-----
> tests/rgrifieldscheck.sh | 3 +++
> 5 files changed, 60 insertions(+), 7 deletions(-)
>
> diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
> index 50dc3f56..5309e6d6 100644
> --- a/gfs2/libgfs2/libgfs2.h
> +++ b/gfs2/libgfs2/libgfs2.h
> @@ -667,6 +667,8 @@ extern int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
> /* rgrp.c */
> extern int gfs2_compute_bitstructs(const uint32_t bsize, struct rgrp_tree *rgd);
> extern struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
> +extern int lgfs2_rgrp_crc_check(const struct gfs2_rgrp *rg, char *buf);
> +extern void lgfs2_rgrp_crc_set(char *buf);
> extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd);
> extern void gfs2_rgrp_relse(struct rgrp_tree *rgd);
> extern struct rgrp_tree *rgrp_insert(struct osi_root *rgtree,
> diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c
> index 1b771f30..82c8c6be 100644
> --- a/gfs2/libgfs2/meta.c
> +++ b/gfs2/libgfs2/meta.c
> @@ -211,6 +211,7 @@ F(rg_igeneration)
> FP(rg_data0, .points_to = ANY_GFS2_BLOCK|(1 << LGFS2_MT_FREE))
> F(rg_data, .flags = LGFS2_MFF_FSBLOCKS)
> F(rg_bitbytes, .flags = LGFS2_MFF_BYTES)
> +F(rg_crc, .flags = LGFS2_MFF_CHECK)
> #endif
> RF(rg_reserved)
> };
> diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
> index fd25a860..dfb99d14 100644
> --- a/gfs2/libgfs2/ondisk.c
> +++ b/gfs2/libgfs2/ondisk.c
> @@ -237,7 +237,8 @@ void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
> CPIN_64(rg, str, rg_data0);
> CPIN_32(rg, str, rg_data);
> CPIN_32(rg, str, rg_bitbytes);
> - CPIN_08(rg, str, rg_reserved, 64);
> + CPIN_32(rg, str, rg_crc);
> + CPIN_08(rg, str, rg_reserved, 60);
> #else
> CPIN_08(rg, str, rg_reserved, 80);
> #endif
> @@ -261,7 +262,8 @@ void gfs2_rgrp_out(const struct gfs2_rgrp *rg, char *buf)
> CPOUT_64(rg, str, rg_data0);
> CPOUT_32(rg, str, rg_data);
> CPOUT_32(rg, str, rg_bitbytes);
> - CPOUT_08(rg, str, rg_reserved, 64);
> + CPOUT_08(rg, str, rg_reserved, 60);
> + lgfs2_rgrp_crc_set(buf);
> #else
> CPOUT_08(rg, str, rg_reserved, 80);
> #endif
> @@ -289,6 +291,7 @@ void gfs2_rgrp_print(const struct gfs2_rgrp *rg)
> pv(rg, rg_data0, "%llu", "0x%llx");
> pv(rg, rg_data, "%u", "0x%x");
> pv(rg, rg_bitbytes, "%u", "0x%x");
> + pv(rg, rg_crc, "%u", "0x%x");
> #endif
> }
>
> diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
> index 17178bd9..03861d14 100644
> --- a/gfs2/libgfs2/rgrp.c
> +++ b/gfs2/libgfs2/rgrp.c
> @@ -158,6 +158,42 @@ void lgfs2_rgrp_bitbuf_free(lgfs2_rgrp_t rg)
> }
>
> /**
> + * Check a resource group's crc
> + * Returns 0 on success, non-zero if crc is bad
> + */
> +int lgfs2_rgrp_crc_check(const struct gfs2_rgrp *rg, char *buf)
> +{
> + int ret = 0;
> +#ifdef GFS2_HAS_RG_RI_FIELDS
> + uint32_t crc = rg->rg_crc;
> +
> + if (crc == 0)
> + return 0;
> +
> + ((struct gfs2_rgrp *)buf)->rg_crc = 0;
> + if (crc != gfs2_disk_hash(buf, sizeof(struct gfs2_rgrp)))
> + ret = 1;
> + ((struct gfs2_rgrp *)buf)->rg_crc = cpu_to_be32(crc);
> +#endif
> + return ret;
> +}
> +
> +/**
> + * Set the crc of an on-disk resource group
> + */
> +void lgfs2_rgrp_crc_set(char *buf)
> +{
> +#ifdef GFS2_HAS_RG_RI_FIELDS
> + struct gfs2_rgrp *rg = (struct gfs2_rgrp *)buf;
> + uint32_t crc;
> +
> + rg->rg_crc = 0;
> + crc = gfs2_disk_hash(buf, sizeof(struct gfs2_rgrp));
> + rg->rg_crc = cpu_to_be32(crc);
> +#endif
> +}
> +
> +/**
> * gfs2_rgrp_read - read in the resource group information from disk.
> * @rgd - resource group structure
> * returns: 0 if no error, otherwise the block number that failed
> @@ -194,11 +230,18 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
> return rgd->ri.ri_addr + err;
> }
> }
> - if (x > 0) {
> - if (sdp->gfs1)
> - gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
> - else
> - gfs2_rgrp_in(&rgd->rg, rgd->bits[0].bi_bh);
> + if (x <= 0) {
> + free(bhs);
> + return 0;
> + }
> + if (sdp->gfs1)
> + gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
> + else {
> + gfs2_rgrp_in(&rgd->rg, rgd->bits[0].bi_bh);
> + if (lgfs2_rgrp_crc_check(&rgd->rg, rgd->bits[0].bi_bh->b_data)) {
> + free(bhs);
> + return rgd->ri.ri_addr;
> + }
> }
> free(bhs);
> return 0;
> @@ -623,6 +666,7 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry, ui
> rg->rg.rg_data0 = rg->ri.ri_data0;
> rg->rg.rg_data = rg->ri.ri_data;
> rg->rg.rg_bitbytes = rg->ri.ri_bitbytes;
> + rg->rg.rg_crc = 0;
> #endif
> compute_bitmaps(rg, rgs->sdp->bsize);
> rg->rgrps = rgs;
> diff --git a/tests/rgrifieldscheck.sh b/tests/rgrifieldscheck.sh
> index c99470a9..85f6408e 100755
> --- a/tests/rgrifieldscheck.sh
> +++ b/tests/rgrifieldscheck.sh
> @@ -1,6 +1,9 @@
> #!/bin/sh
> dev=$1
> i=0
> +gfs2_edit -p rg 0 $dev | grep rg_data0 > /dev/null 2>&1
> +# New fields not present in /usr/include/linux/gfs2_ondisk.h
> +test $? = 0 || exit 0
> gfs2_edit -p rindex $dev | while read field rival unused
> do
> test $field = ri_data0 -o $field = ri_data -o $field = ri_bitbytes || continue
More information about the Cluster-devel
mailing list