1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2020-2023 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <djwong@kernel.org> 5 */ 6 #include "xfs.h" 7 #include "xfs_fs.h" 8 #include "xfs_shared.h" 9 #include "xfs_format.h" 10 #include "xfs_trans_resv.h" 11 #include "xfs_mount.h" 12 #include "xfs_btree.h" 13 #include "xfs_log_format.h" 14 #include "xfs_trans.h" 15 #include "xfs_inode.h" 16 #include "xfs_bit.h" 17 #include "xfs_bmap.h" 18 #include "xfs_bmap_btree.h" 19 #include "scrub/scrub.h" 20 #include "scrub/common.h" 21 #include "scrub/trace.h" 22 #include "scrub/repair.h" 23 #include "scrub/xfile.h" 24 #include "scrub/rtbitmap.h" 25 26 /* Set up to repair the realtime bitmap file metadata. */ 27 int 28 xrep_setup_rtbitmap( 29 struct xfs_scrub *sc, 30 struct xchk_rtbitmap *rtb) 31 { 32 struct xfs_mount *mp = sc->mp; 33 unsigned long long blocks = 0; 34 35 /* 36 * Reserve enough blocks to write out a completely new bmbt for a 37 * maximally fragmented bitmap file. We do not hold the rtbitmap 38 * ILOCK yet, so this is entirely speculative. 39 */ 40 blocks = xfs_bmbt_calc_size(mp, mp->m_sb.sb_rbmblocks); 41 if (blocks > UINT_MAX) 42 return -EOPNOTSUPP; 43 44 rtb->resblks += blocks; 45 return 0; 46 } 47 48 /* 49 * Make sure that the given range of the data fork of the realtime file is 50 * mapped to written blocks. The caller must ensure that the inode is joined 51 * to the transaction. 52 */ 53 STATIC int 54 xrep_rtbitmap_data_mappings( 55 struct xfs_scrub *sc, 56 xfs_filblks_t len) 57 { 58 struct xfs_bmbt_irec map; 59 xfs_fileoff_t off = 0; 60 int error; 61 62 ASSERT(sc->ip != NULL); 63 64 while (off < len) { 65 int nmaps = 1; 66 67 /* 68 * If we have a real extent mapping this block then we're 69 * in ok shape. 70 */ 71 error = xfs_bmapi_read(sc->ip, off, len - off, &map, &nmaps, 72 XFS_DATA_FORK); 73 if (error) 74 return error; 75 if (nmaps == 0) { 76 ASSERT(nmaps != 0); 77 return -EFSCORRUPTED; 78 } 79 80 /* 81 * Written extents are ok. Holes are not filled because we 82 * do not know the freespace information. 83 */ 84 if (xfs_bmap_is_written_extent(&map) || 85 map.br_startblock == HOLESTARTBLOCK) { 86 off = map.br_startoff + map.br_blockcount; 87 continue; 88 } 89 90 /* 91 * If we find a delalloc reservation then something is very 92 * very wrong. Bail out. 93 */ 94 if (map.br_startblock == DELAYSTARTBLOCK) 95 return -EFSCORRUPTED; 96 97 /* Make sure we're really converting an unwritten extent. */ 98 if (map.br_state != XFS_EXT_UNWRITTEN) { 99 ASSERT(map.br_state == XFS_EXT_UNWRITTEN); 100 return -EFSCORRUPTED; 101 } 102 103 /* Make sure this block has a real zeroed extent mapped. */ 104 nmaps = 1; 105 error = xfs_bmapi_write(sc->tp, sc->ip, map.br_startoff, 106 map.br_blockcount, 107 XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO, 108 0, &map, &nmaps); 109 if (error) 110 return error; 111 if (nmaps != 1) 112 return -EFSCORRUPTED; 113 114 /* Commit new extent and all deferred work. */ 115 error = xrep_defer_finish(sc); 116 if (error) 117 return error; 118 119 off = map.br_startoff + map.br_blockcount; 120 } 121 122 return 0; 123 } 124 125 /* Fix broken rt volume geometry. */ 126 STATIC int 127 xrep_rtbitmap_geometry( 128 struct xfs_scrub *sc, 129 struct xchk_rtbitmap *rtb) 130 { 131 struct xfs_mount *mp = sc->mp; 132 struct xfs_trans *tp = sc->tp; 133 134 /* Superblock fields */ 135 if (mp->m_sb.sb_rextents != rtb->rextents) 136 xfs_trans_mod_sb(sc->tp, XFS_TRANS_SB_REXTENTS, 137 rtb->rextents - mp->m_sb.sb_rextents); 138 139 if (mp->m_sb.sb_rbmblocks != rtb->rbmblocks) 140 xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBMBLOCKS, 141 rtb->rbmblocks - mp->m_sb.sb_rbmblocks); 142 143 if (mp->m_sb.sb_rextslog != rtb->rextslog) 144 xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG, 145 rtb->rextslog - mp->m_sb.sb_rextslog); 146 147 /* Fix broken isize */ 148 sc->ip->i_disk_size = roundup_64(sc->ip->i_disk_size, 149 mp->m_sb.sb_blocksize); 150 151 if (sc->ip->i_disk_size < XFS_FSB_TO_B(mp, rtb->rbmblocks)) 152 sc->ip->i_disk_size = XFS_FSB_TO_B(mp, rtb->rbmblocks); 153 154 xfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); 155 return xrep_roll_trans(sc); 156 } 157 158 /* Repair the realtime bitmap file metadata. */ 159 int 160 xrep_rtbitmap( 161 struct xfs_scrub *sc) 162 { 163 struct xchk_rtbitmap *rtb = sc->buf; 164 struct xfs_mount *mp = sc->mp; 165 unsigned long long blocks = 0; 166 int error; 167 168 /* Impossibly large rtbitmap means we can't touch the filesystem. */ 169 if (rtb->rbmblocks > U32_MAX) 170 return 0; 171 172 /* 173 * If the size of the rt bitmap file is larger than what we reserved, 174 * figure out if we need to adjust the block reservation in the 175 * transaction. 176 */ 177 blocks = xfs_bmbt_calc_size(mp, rtb->rbmblocks); 178 if (blocks > UINT_MAX) 179 return -EOPNOTSUPP; 180 if (blocks > rtb->resblks) { 181 error = xfs_trans_reserve_more(sc->tp, blocks, 0); 182 if (error) 183 return error; 184 185 rtb->resblks += blocks; 186 } 187 188 /* Fix inode core and forks. */ 189 error = xrep_metadata_inode_forks(sc); 190 if (error) 191 return error; 192 193 xfs_trans_ijoin(sc->tp, sc->ip, 0); 194 195 /* Ensure no unwritten extents. */ 196 error = xrep_rtbitmap_data_mappings(sc, rtb->rbmblocks); 197 if (error) 198 return error; 199 200 /* Fix inconsistent bitmap geometry */ 201 return xrep_rtbitmap_geometry(sc, rtb); 202 } 203