]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_db: write values into dir/attr blocks and recalculate CRCs
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 4 Aug 2017 21:33:52 +0000 (16:33 -0500)
committerEric Sandeen <sandeen@redhat.com>
Fri, 4 Aug 2017 21:33:52 +0000 (16:33 -0500)
Extend typ_t to (optionally) store a pointer to a function to calculate
the CRC of the block, provide functions to do this for the dir3 and
attr3 types, and then wire up the write command so that we can modify
directory and extended attribute block fields.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
db/attr.c
db/attr.h
db/dir2.c
db/dir2.h
db/type.c
db/type.h
db/write.c

index 0284fd420131739eab06deadd11ef0118ac1cd2d..75fe239364c49171cc905b6be11eccc106ac81db 100644 (file)
--- a/db/attr.c
+++ b/db/attr.c
@@ -606,6 +606,38 @@ const struct field attr3_remote_crc_flds[] = {
        { NULL }
 };
 
+/* Set the CRC. */
+void
+xfs_attr3_set_crc(
+       struct xfs_buf          *bp)
+{
+       __be32                  magic32;
+       __be16                  magic16;
+
+       magic32 = *(__be32 *)bp->b_addr;
+       magic16 = ((struct xfs_da_blkinfo *)bp->b_addr)->magic;
+
+       switch (magic16) {
+       case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC):
+               xfs_buf_update_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF);
+               return;
+       case cpu_to_be16(XFS_DA3_NODE_MAGIC):
+               xfs_buf_update_cksum(bp, XFS_DA3_NODE_CRC_OFF);
+               return;
+       default:
+               break;
+       }
+
+       switch (magic32) {
+       case cpu_to_be32(XFS_ATTR3_RMT_MAGIC):
+               xfs_buf_update_cksum(bp, XFS_ATTR3_RMT_CRC_OFF);
+               return;
+       default:
+               dbprintf(_("Unknown attribute buffer type!\n"));
+               break;
+       }
+}
+
 /*
  * Special read verifier for attribute buffers. Detect the magic number
  * appropriately and set the correct verifier and call it.
index 565d6d8abefefecd3dd1f60baae64c2332158811..ba23480cde80cfb2881f0a93fa1e590f90b5b19a 100644 (file)
--- a/db/attr.h
+++ b/db/attr.h
@@ -36,5 +36,6 @@ extern const field_t  attr3_remote_crc_flds[];
 
 extern int     attr_leaf_name_size(void *obj, int startoff, int idx);
 extern int     attr_size(void *obj, int startoff, int idx);
+extern void    xfs_attr3_set_crc(struct xfs_buf *bp);
 
 extern const struct xfs_buf_ops xfs_attr3_db_buf_ops;
index 533f705f7b1da3c4486c99e05f947decd3b9a2ae..3e21a7b7018f9c2edca160624ac66d22761a4a9b 100644 (file)
--- a/db/dir2.c
+++ b/db/dir2.c
@@ -981,6 +981,43 @@ const field_t      da3_node_hdr_flds[] = {
        { NULL }
 };
 
+/* Set the CRC. */
+void
+xfs_dir3_set_crc(
+       struct xfs_buf          *bp)
+{
+       __be32                  magic32;
+       __be16                  magic16;
+
+       magic32 = *(__be32 *)bp->b_addr;
+       magic16 = ((struct xfs_da_blkinfo *)bp->b_addr)->magic;
+
+       switch (magic32) {
+       case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
+       case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
+               xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
+               return;
+       case cpu_to_be32(XFS_DIR3_FREE_MAGIC):
+               xfs_buf_update_cksum(bp, XFS_DIR3_FREE_CRC_OFF);
+               return;
+       default:
+               break;
+       }
+
+       switch (magic16) {
+       case cpu_to_be16(XFS_DIR3_LEAF1_MAGIC):
+       case cpu_to_be16(XFS_DIR3_LEAFN_MAGIC):
+               xfs_buf_update_cksum(bp, XFS_DIR3_LEAF_CRC_OFF);
+               return;
+       case cpu_to_be16(XFS_DA3_NODE_MAGIC):
+               xfs_buf_update_cksum(bp, XFS_DA3_NODE_CRC_OFF);
+               return;
+       default:
+               dbprintf(_("Unknown directory buffer type! %x %x\n"), magic32, magic16);
+               break;
+       }
+}
+
 /*
  * Special read verifier for directory buffers. Detect the magic number
  * appropriately and set the correct verifier and call it.
index 0c2a62ec7f778d1ee293745e8c24504036a8f6ab..1b87cd2a30aa6c55337e2321763470d29f25e53f 100644 (file)
--- a/db/dir2.h
+++ b/db/dir2.h
@@ -60,5 +60,6 @@ static inline uint8_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep)
 
 extern int     dir2_data_union_size(void *obj, int startoff, int idx);
 extern int     dir2_size(void *obj, int startoff, int idx);
+extern void    xfs_dir3_set_crc(struct xfs_buf *bp);
 
 extern const struct xfs_buf_ops xfs_dir3_db_buf_ops;
index 10fa54ee9a9d1debc299bfa06228307844d25f96..bf31e0419e0cfb4d0d4012e9e47b4fd6b279cce4 100644 (file)
--- a/db/type.c
+++ b/db/type.c
@@ -87,7 +87,7 @@ static const typ_t    __typtab_crc[] = {
        { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops,
                XFS_AGI_CRC_OFF },
        { TYP_ATTR, "attr3", handle_struct, attr3_hfld,
-               &xfs_attr3_db_buf_ops, TYP_F_NO_CRC_OFF },
+               &xfs_attr3_db_buf_ops, TYP_F_CRC_FUNC, xfs_attr3_set_crc },
        { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld,
                &xfs_bmbt_buf_ops, XFS_BTREE_LBLOCK_CRC_OFF },
        { TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_crc_hfld,
@@ -102,7 +102,7 @@ static const typ_t  __typtab_crc[] = {
                &xfs_refcountbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
        { TYP_DATA, "data", handle_block, NULL, NULL, TYP_F_NO_CRC_OFF },
        { TYP_DIR2, "dir3", handle_struct, dir3_hfld,
-               &xfs_dir3_db_buf_ops, TYP_F_NO_CRC_OFF },
+               &xfs_dir3_db_buf_ops, TYP_F_CRC_FUNC, xfs_dir3_set_crc },
        { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld,
                &xfs_dquot_buf_ops, TYP_F_NO_CRC_OFF },
        { TYP_INOBT, "inobt", handle_struct, inobt_crc_hfld,
@@ -131,7 +131,7 @@ static const typ_t  __typtab_spcrc[] = {
        { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops ,
                XFS_AGI_CRC_OFF },
        { TYP_ATTR, "attr3", handle_struct, attr3_hfld,
-               &xfs_attr3_db_buf_ops, TYP_F_NO_CRC_OFF },
+               &xfs_attr3_db_buf_ops, TYP_F_CRC_FUNC, xfs_attr3_set_crc },
        { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld,
                &xfs_bmbt_buf_ops, XFS_BTREE_LBLOCK_CRC_OFF },
        { TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_crc_hfld,
@@ -146,7 +146,7 @@ static const typ_t  __typtab_spcrc[] = {
                &xfs_refcountbt_buf_ops, XFS_BTREE_SBLOCK_CRC_OFF },
        { TYP_DATA, "data", handle_block, NULL, NULL, TYP_F_NO_CRC_OFF },
        { TYP_DIR2, "dir3", handle_struct, dir3_hfld,
-               &xfs_dir3_db_buf_ops, TYP_F_NO_CRC_OFF },
+               &xfs_dir3_db_buf_ops, TYP_F_CRC_FUNC, xfs_dir3_set_crc },
        { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld,
                &xfs_dquot_buf_ops, TYP_F_NO_CRC_OFF },
        { TYP_INOBT, "inobt", handle_struct, inobt_spcrc_hfld,
index 87ff1079ec48c940be052415d14b3506e499a824..85d89c74eedfa6b010aac6ffa0e8e0895a3e2c41 100644 (file)
--- a/db/type.h
+++ b/db/type.h
@@ -45,6 +45,8 @@ typedef struct typ
        const struct xfs_buf_ops *bops;
        unsigned long           crc_off;
 #define TYP_F_NO_CRC_OFF       (-1UL)
+#define TYP_F_CRC_FUNC         (-2UL)
+       void                    (*set_crc)(struct xfs_buf *);
 } typ_t;
 extern const typ_t     *typtab, *cur_typ;
 
index d24ea05943aeacaaaced3fbd021f24fd47c7d3e2..266bde470a9de7786ddcd1e7cfbf1f1357960cd6 100644 (file)
@@ -173,6 +173,9 @@ write_f(
        } else if (iocur_top->dquot_buf) {
                local_ops.verify_write = xfs_verify_recalc_dquot_crc;
                dbprintf(_("Allowing write of corrupted dquot with good CRC\n"));
+       } else if (iocur_top->typ->crc_off == TYP_F_CRC_FUNC) {
+               local_ops.verify_write = iocur_top->typ->set_crc;
+               dbprintf(_("Allowing write of corrupted data with good CRC\n"));
        } else { /* invalid data */
                local_ops.verify_write = xfs_verify_recalc_crc;
                dbprintf(_("Allowing write of corrupted data with good CRC\n"));