From 6e97b1a8cc5dbebae197cf0515b6dc6968eee65d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 15 Jul 2024 15:34:45 +0200 Subject: [PATCH] repair: create a common helper to fill the bitmap and summary inodes fill_rbmino and fill_rsumino are almost identical. Merge them into a single common helper in rt.c, next to the code that computes the values that are written to the files. Signed-off-by: Christoph Hellwig --- repair/phase6.c | 190 +----------------------------------------------- repair/rt.c | 113 ++++++++++++++++++++++++++++ repair/rt.h | 2 + 3 files changed, 118 insertions(+), 187 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index 7b9c6b49b..04c4f18b3 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -21,6 +21,7 @@ #include "repair/pptr.h" #include "slab.h" #include "rmap.h" +#include "rt.h" static xfs_ino_t orphanage_ino; @@ -560,184 +561,6 @@ mk_rbmino( libxfs_irele(ip); } -static int -fill_rbmino(xfs_mount_t *mp) -{ - struct xfs_buf *bp; - xfs_trans_t *tp; - xfs_inode_t *ip; - union xfs_rtword_raw *bmp; - int nmap; - int error; - xfs_fileoff_t bno; - xfs_bmbt_irec_t map; - - bmp = btmcompute; - bno = 0; - - error = -libxfs_trans_alloc_rollable(mp, 10, &tp); - if (error) - res_failed(error); - - error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip); - if (error) { - do_error( - _("couldn't iget realtime bitmap inode -- error - %d\n"), - error); - } - - while (bno < mp->m_sb.sb_rbmblocks) { - struct xfs_rtalloc_args args = { - .mp = mp, - .tp = tp, - }; - union xfs_rtword_raw *ondisk; - xfs_daddr_t daddr; - - /* - * fill the file one block at a time - */ - nmap = 1; - error = -libxfs_bmapi_write(tp, ip, bno, 1, 0, 1, &map, &nmap); - if (error || nmap != 1) { - do_error( - _("couldn't map realtime bitmap block %" PRIu64 ", error = %d\n"), - bno, error); - } - - ASSERT(map.br_startblock != HOLESTARTBLOCK); - - daddr = XFS_FSB_TO_DADDR(mp, map.br_startblock); - error = -libxfs_trans_read_buf(mp, tp, mp->m_dev, daddr, - XFS_FSB_TO_BB(mp, 1), 1, &bp, NULL); - if (error) { - do_warn( -_("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime bitmap inode %" PRIu64 "\n"), - bno, map.br_startblock, mp->m_sb.sb_rbmino); - return(1); - } - - args.rbmbp = bp; - ondisk = xfs_rbmblock_wordptr(&args, 0); - memcpy(ondisk, bmp, mp->m_blockwsize << XFS_WORDLOG); - - if (xfs_has_rtgroups(mp)) { - struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; - - bp->b_ops = &xfs_rtbitmap_buf_ops; - hdr->rt_magic = cpu_to_be32(XFS_RTBITMAP_MAGIC); - hdr->rt_owner = cpu_to_be64(ip->i_ino); - hdr->rt_lsn = 0; - hdr->rt_blkno = cpu_to_be64(daddr); - platform_uuid_copy(&hdr->rt_uuid, - &mp->m_sb.sb_meta_uuid); - } - - libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); - - bmp += mp->m_blockwsize; - bno++; - } - - libxfs_trans_ijoin(tp, ip, 0); - error = -libxfs_trans_commit(tp); - if (error) - do_error(_("%s: commit failed, error %d\n"), __func__, error); - libxfs_irele(ip); - return(0); -} - -static int -fill_rsumino(xfs_mount_t *mp) -{ - struct xfs_buf *bp; - xfs_trans_t *tp; - xfs_inode_t *ip; - union xfs_suminfo_raw *smp; - int nmap; - int error; - xfs_fileoff_t bno; - xfs_fileoff_t end_bno; - xfs_bmbt_irec_t map; - - smp = sumcompute; - bno = 0; - end_bno = mp->m_rsumsize >> mp->m_sb.sb_blocklog; - - error = -libxfs_trans_alloc_rollable(mp, 10, &tp); - if (error) - res_failed(error); - - error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip); - if (error) { - do_error( - _("couldn't iget realtime summary inode -- error - %d\n"), - error); - } - - while (bno < end_bno) { - struct xfs_rtalloc_args args = { - .mp = mp, - .tp = tp, - }; - union xfs_suminfo_raw *ondisk; - xfs_daddr_t daddr; - - /* - * fill the file one block at a time - */ - nmap = 1; - error = -libxfs_bmapi_write(tp, ip, bno, 1, 0, 1, &map, &nmap); - if (error || nmap != 1) { - do_error( - _("couldn't map realtime summary inode block %" PRIu64 ", error = %d\n"), - bno, error); - } - - ASSERT(map.br_startblock != HOLESTARTBLOCK); - - daddr = XFS_FSB_TO_DADDR(mp, map.br_startblock); - error = -libxfs_trans_read_buf(mp, tp, mp->m_dev, daddr, - XFS_FSB_TO_BB(mp, 1), 1, &bp, NULL); - - if (error) { - do_warn( -_("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime summary inode %" PRIu64 "\n"), - bno, map.br_startblock, mp->m_sb.sb_rsumino); - libxfs_irele(ip); - return(1); - } - - args.sumbp = bp; - ondisk = xfs_rsumblock_infoptr(&args, 0); - memcpy(ondisk, smp, mp->m_blockwsize << XFS_WORDLOG); - - if (xfs_has_rtgroups(mp)) { - struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; - - bp->b_ops = &xfs_rtsummary_buf_ops; - hdr->rt_magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC); - hdr->rt_owner = cpu_to_be64(ip->i_ino); - hdr->rt_lsn = 0; - hdr->rt_blkno = cpu_to_be64(daddr); - platform_uuid_copy(&hdr->rt_uuid, - &mp->m_sb.sb_meta_uuid); - } - - libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); - - smp += mp->m_blockwsize; - bno++; - } - - libxfs_trans_ijoin(tp, ip, 0); - error = -libxfs_trans_commit(tp); - if (error) - do_error(_("%s: commit failed, error %d\n"), __func__, error); - libxfs_irele(ip); - return(0); -} - static void mk_rsumino( struct xfs_mount *mp) @@ -3734,15 +3557,8 @@ phase6(xfs_mount_t *mp) if (!no_modify) { do_log( _(" - resetting contents of realtime bitmap and summary inodes\n")); - if (fill_rbmino(mp)) { - do_warn( - _("Warning: realtime bitmap may be inconsistent\n")); - } - - if (fill_rsumino(mp)) { - do_warn( - _("Warning: realtime bitmap may be inconsistent\n")); - } + fill_rtino(mp, true); + fill_rtino(mp, false); } if (reserve_perag) diff --git a/repair/rt.c b/repair/rt.c index 4a39d4b1d..d29875cd0 100644 --- a/repair/rt.c +++ b/repair/rt.c @@ -302,6 +302,119 @@ check_rtsummary( check_rtfile_contents(mp, false); } +void +fill_rtino( + struct xfs_mount *mp, + bool is_bitmap) +{ + unsigned long data_size = mp->m_blockwsize << XFS_WORDLOG; + const struct xfs_buf_ops *buf_ops = NULL; + xfs_fileoff_t bno = 0; + struct xfs_inode *ip; + struct xfs_trans *tp; + const char *name; + void *data; + xfs_fileoff_t end_bno; + xfs_ino_t ino; + __be32 magic; + int error; + + if (is_bitmap) { + ino = mp->m_sb.sb_rbmino; + name = "bitmap"; + data = btmcompute; + end_bno = mp->m_sb.sb_rbmblocks; + magic = cpu_to_be32(XFS_RTBITMAP_MAGIC); + buf_ops = &xfs_rtbitmap_buf_ops; + } else { + ino = mp->m_sb.sb_rsumino; + name = "summary"; + data = sumcompute; + end_bno = mp->m_rsumsize >> mp->m_sb.sb_blocklog; + magic = cpu_to_be32(XFS_RTSUMMARY_MAGIC); + buf_ops = &xfs_rtsummary_buf_ops; + } + + /* + * Nothing to do for empty files, which are the normal case if there are + * no RT extents. + */ + if (!end_bno) + return; + + error = -libxfs_trans_alloc_rollable(mp, 10, &tp); + if (error) + do_error(_("xfs_trans_reserve returned %d\n"), error); + + error = -libxfs_iget(mp, tp, ino, 0, &ip); + if (error) { + do_error( + _("couldn't iget realtime %s inode -- error - %d\n"), + name, error); + } + + libxfs_trans_ijoin(tp, ip, 0); + while (bno < end_bno) { + struct xfs_buf *bp; + struct xfs_bmbt_irec map; + int nmap = 1; + unsigned int hdr_size = 0; + + /* + * Fill the file one block at a time. + */ + error = -libxfs_bmapi_write(tp, ip, bno, 1, 0, 1, &map, &nmap); + if (error || nmap != 1) { + do_error( + _("couldn't map realtime %s inode block %" PRIu64 ", error = %d\n"), + name, bno, error); + } + + ASSERT(map.br_startblock != HOLESTARTBLOCK); + + error = -libxfs_trans_read_buf(mp, tp, mp->m_dev, + XFS_FSB_TO_DADDR(mp, map.br_startblock), + XFS_FSB_TO_BB(mp, 1), 1, &bp, NULL); + + if (error) { + do_warn( +_("can't access block %" PRIu64 " (fsbno %" PRIu64 ") of realtime %s inode %" PRIu64 "\n"), + bno, map.br_startblock, name, ip->i_ino); + goto fail; + } + + if (xfs_has_rtgroups(mp)) { + struct xfs_rtbuf_blkinfo *hdr = bp->b_addr; + + hdr->rt_magic = magic; + hdr->rt_owner = cpu_to_be64(ip->i_ino); + hdr->rt_lsn = 0; + hdr->rt_blkno = cpu_to_be64(xfs_buf_daddr(bp)); + platform_uuid_copy(&hdr->rt_uuid, + &mp->m_sb.sb_meta_uuid); + + bp->b_ops = buf_ops; + hdr_size = sizeof(*hdr); + } + + memcpy(bp->b_addr + hdr_size, data, data_size); + libxfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); + + data += data_size; + bno++; + } + + error = -libxfs_trans_commit(tp); + if (error) + do_error(_("%s: commit failed, error %d\n"), __func__, error); + libxfs_irele(ip); + return; + +fail: + do_warn(_("Warning: realtime bitmap may be inconsistent\n")); + libxfs_irele(ip); +} + void check_rtsuper( struct xfs_mount *mp) diff --git a/repair/rt.h b/repair/rt.h index 225505331..256ba0a73 100644 --- a/repair/rt.h +++ b/repair/rt.h @@ -18,6 +18,8 @@ void check_rtbitmap(struct xfs_mount *mp); void check_rtsummary(struct xfs_mount *mp); void check_rtsuper(struct xfs_mount *mp); +void fill_rtino(struct xfs_mount *mp, bool is_bitmap); + void rewrite_primary_rt_super(struct xfs_mount *mp); void discover_rtgroup_inodes(struct xfs_mount *mp); -- 2.50.1