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 | |