]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/rt.c
libxfs: refactor manage_zones()
[thirdparty/xfsprogs-dev.git] / repair / rt.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18
NS
5 */
6
6b803e5a 7#include "libxfs.h"
2bd0ea18
NS
8#include "avl.h"
9#include "globals.h"
10#include "agheader.h"
11#include "incore.h"
12#include "dinode.h"
13#include "protos.h"
14#include "err_protos.h"
15#include "rt.h"
16
17#define xfs_highbit64 libxfs_highbit64 /* for XFS_RTBLOCKLOG macro */
18
19void
20rtinit(xfs_mount_t *mp)
21{
22 if (mp->m_sb.sb_rblocks == 0)
23 return;
dfc130f3 24
2bd0ea18
NS
25 /*
26 * realtime init -- blockmap initialization is
27 * handled by incore_init()
28 */
29 /*
30 sumfile = calloc(mp->m_rsumsize, 1);
31 */
32 if ((btmcompute = calloc(mp->m_sb.sb_rbmblocks *
33 mp->m_sb.sb_blocksize, 1)) == NULL)
34 do_error(
507f4e33 35 _("couldn't allocate memory for incore realtime bitmap.\n"));
2bd0ea18
NS
36
37 if ((sumcompute = calloc(mp->m_rsumsize, 1)) == NULL)
38 do_error(
507f4e33 39 _("couldn't allocate memory for incore realtime summary info.\n"));
2bd0ea18
NS
40}
41
42/*
43 * generate the real-time bitmap and summary info based on the
44 * incore realtime extent map.
45 */
46int
47generate_rtinfo(xfs_mount_t *mp,
48 xfs_rtword_t *words,
49 xfs_suminfo_t *sumcompute)
50{
5a35bf2c
DC
51 xfs_rtblock_t extno;
52 xfs_rtblock_t start_ext;
2bd0ea18
NS
53 int bitsperblock;
54 int bmbno;
55 xfs_rtword_t freebit;
56 xfs_rtword_t bits;
57 int start_bmbno;
58 int i;
59 int offs;
60 int log;
61 int len;
62 int in_extent;
63
64 ASSERT(mp->m_rbmip == NULL);
65
66 bitsperblock = mp->m_sb.sb_blocksize * NBBY;
67 extno = start_ext = 0;
68 bmbno = in_extent = start_bmbno = 0;
69
70 /*
71 * slower but simple, don't play around with trying to set
72 * things one word at a time, just set bit as required.
73 * Have to * track start and end (size) of each range of
74 * free extents to set the summary info properly.
75 */
76 while (extno < mp->m_sb.sb_rextents) {
77 freebit = 1;
78 *words = 0;
79 bits = 0;
80 for (i = 0; i < sizeof(xfs_rtword_t) * NBBY &&
81 extno < mp->m_sb.sb_rextents; i++, extno++) {
95650c4d 82 if (get_rtbmap(extno) == XR_E_FREE) {
2bd0ea18
NS
83 sb_frextents++;
84 bits |= freebit;
85
86 if (in_extent == 0) {
87 start_ext = extno;
88 start_bmbno = bmbno;
89 in_extent = 1;
90 }
91 } else if (in_extent == 1) {
92 len = (int) (extno - start_ext);
93 log = XFS_RTBLOCKLOG(len);
94 offs = XFS_SUMOFFS(mp, log, start_bmbno);
95 sumcompute[offs]++;
96 in_extent = 0;
97 }
98
99 freebit <<= 1;
100 }
101 *words = bits;
102 words++;
103
104 if (extno % bitsperblock == 0)
105 bmbno++;
106 }
107 if (in_extent == 1) {
108 len = (int) (extno - start_ext);
109 log = XFS_RTBLOCKLOG(len);
110 offs = XFS_SUMOFFS(mp, log, start_bmbno);
111 sumcompute[offs]++;
112 }
113
114 return(0);
115}
116
117#if 0
118/*
119 * returns 1 if bad, 0 if good
120 */
121int
122check_summary(xfs_mount_t *mp)
123{
5a35bf2c 124 xfs_rfsblock_t bno;
2bd0ea18
NS
125 xfs_suminfo_t *csp;
126 xfs_suminfo_t *fsp;
127 int log;
128 int error = 0;
129
130 error = 0;
131 csp = sumcompute;
132 fsp = sumfile;
133 for (log = 0; log < mp->m_rsumlevels; log++) {
134 for (bno = 0;
135 bno < mp->m_sb.sb_rbmblocks;
136 bno++, csp++, fsp++) {
137 if (*csp != *fsp) {
138 do_warn(
507f4e33 139 _("rt summary mismatch, size %d block %llu, file: %d, computed: %d\n"),
2bd0ea18
NS
140 log, bno, *fsp, *csp);
141 error = 1;
142 }
143 }
144 }
145
146 return(error);
147}
148
149/*
150 * examine the real-time bitmap file and compute summary
151 * info off it. Should probably be changed to compute
152 * the summary information off the incore computed bitmap
153 * instead of the realtime bitmap file
154 */
155void
156process_rtbitmap(xfs_mount_t *mp,
157 xfs_dinode_t *dino,
158 blkmap_t *blkmap)
159{
160 int error;
161 int bit;
162 int bitsperblock;
163 int bmbno;
164 int end_bmbno;
5a35bf2c 165 xfs_fsblock_t bno;
2bd0ea18 166 xfs_buf_t *bp;
5a35bf2c 167 xfs_rtblock_t extno;
2bd0ea18
NS
168 int i;
169 int len;
170 int log;
171 int offs;
172 int prevbit;
173 int start_bmbno;
174 int start_bit;
175 xfs_rtword_t *words;
176
177 ASSERT(mp->m_rbmip == NULL);
178
179 bitsperblock = mp->m_sb.sb_blocksize * NBBY;
180 prevbit = 0;
181 extno = 0;
182 error = 0;
183
56b2de80 184 end_bmbno = howmany(be64_to_cpu(dino->di_size),
5e656dbb 185 mp->m_sb.sb_blocksize);
2bd0ea18
NS
186
187 for (bmbno = 0; bmbno < end_bmbno; bmbno++) {
188 bno = blkmap_get(blkmap, bmbno);
189
5a35bf2c 190 if (bno == NULLFSBLOCK) {
507f4e33 191 do_warn(_("can't find block %d for rtbitmap inode\n"),
2bd0ea18
NS
192 bmbno);
193 error = 1;
194 continue;
195 }
196 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
75c8b434 197 XFS_FSB_TO_BB(mp, 1), NULL);
2bd0ea18 198 if (!bp) {
507f4e33 199 do_warn(_("can't read block %d for rtbitmap inode\n"),
2bd0ea18
NS
200 bmbno);
201 error = 1;
202 continue;
203 }
204 words = (xfs_rtword_t *)bp->b_un.b_addr;
205 for (bit = 0;
206 bit < bitsperblock && extno < mp->m_sb.sb_rextents;
207 bit++, extno++) {
a580302f 208 if (xfs_isset(words, bit)) {
95650c4d 209 set_rtbmap(extno, XR_E_FREE);
2bd0ea18
NS
210 sb_frextents++;
211 if (prevbit == 0) {
212 start_bmbno = bmbno;
213 start_bit = bit;
214 prevbit = 1;
215 }
216 } else if (prevbit == 1) {
217 len = (bmbno - start_bmbno) * bitsperblock +
218 (bit - start_bit);
219 log = XFS_RTBLOCKLOG(len);
220 offs = XFS_SUMOFFS(mp, log, start_bmbno);
221 sumcompute[offs]++;
222 prevbit = 0;
223 }
224 }
225 libxfs_putbuf(bp);
226 if (extno == mp->m_sb.sb_rextents)
227 break;
228 }
229 if (prevbit == 1) {
230 len = (bmbno - start_bmbno) * bitsperblock + (bit - start_bit);
231 log = XFS_RTBLOCKLOG(len);
232 offs = XFS_SUMOFFS(mp, log, start_bmbno);
233 sumcompute[offs]++;
234 }
235}
236
237/*
238 * copy the real-time summary file data into memory
239 */
240void
241process_rtsummary(xfs_mount_t *mp,
242 xfs_dinode_t *dino,
243 blkmap_t *blkmap)
244{
245 xfs_fsblock_t bno;
246 xfs_buf_t *bp;
247 char *bytes;
248 int sumbno;
249
250 for (sumbno = 0; sumbno < blkmap->count; sumbno++) {
251 bno = blkmap_get(blkmap, sumbno);
5a35bf2c 252 if (bno == NULLFSBLOCK) {
507f4e33 253 do_warn(_("block %d for rtsummary inode is missing\n"),
2bd0ea18
NS
254 sumbno);
255 error++;
256 continue;
257 }
258 bp = libxfs_readbuf(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
75c8b434 259 XFS_FSB_TO_BB(mp, 1), NULL);
2bd0ea18 260 if (!bp) {
507f4e33 261 do_warn(_("can't read block %d for rtsummary inode\n"),
2bd0ea18
NS
262 sumbno);
263 error++;
264 continue;
265 }
266 bytes = bp->b_un.b_addr;
dab9b8d6 267 memmove((char *)sumfile + sumbno * mp->m_sb.sb_blocksize, bytes,
2bd0ea18
NS
268 mp->m_sb.sb_blocksize);
269 libxfs_putbuf(bp);
270 }
271}
272#endif