Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_format.h"
10 : #include "xfs_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_bit.h"
13 : #include "xfs_mount.h"
14 : #include "xfs_inode.h"
15 : #include "xfs_bmap.h"
16 : #include "xfs_trans.h"
17 : #include "xfs_rtalloc.h"
18 : #include "xfs_error.h"
19 : #include "xfs_health.h"
20 : #include "xfs_rtbitmap.h"
21 : #include "xfs_log.h"
22 : #include "xfs_buf_item.h"
23 : #include "xfs_errortag.h"
24 :
25 : /*
26 : * Realtime allocator bitmap functions shared with userspace.
27 : */
28 :
29 : static xfs_failaddr_t
30 2973225 : xfs_rtbuf_verify(
31 : struct xfs_buf *bp)
32 : {
33 2973225 : struct xfs_mount *mp = bp->b_mount;
34 2973225 : struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
35 :
36 2973225 : if (!xfs_verify_magic(bp, hdr->rt_magic))
37 0 : return __this_address;
38 2973225 : if (!xfs_has_rtgroups(mp))
39 0 : return __this_address;
40 2973225 : if (!xfs_has_crc(mp))
41 0 : return __this_address;
42 2973225 : if (!uuid_equal(&hdr->rt_uuid, &mp->m_sb.sb_meta_uuid))
43 0 : return __this_address;
44 2973225 : if (hdr->rt_blkno != cpu_to_be64(xfs_buf_daddr(bp)))
45 0 : return __this_address;
46 : return NULL;
47 : }
48 :
49 : static void
50 161293 : xfs_rtbuf_verify_read(
51 : struct xfs_buf *bp)
52 : {
53 161293 : struct xfs_mount *mp = bp->b_mount;
54 161293 : struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
55 161293 : xfs_failaddr_t fa;
56 :
57 161293 : if (!xfs_has_rtgroups(mp))
58 : return;
59 :
60 161293 : if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr->rt_lsn))) {
61 0 : fa = __this_address;
62 0 : goto fail;
63 : }
64 :
65 161293 : if (!xfs_buf_verify_cksum(bp, XFS_RTBUF_CRC_OFF)) {
66 0 : fa = __this_address;
67 0 : goto fail;
68 : }
69 :
70 161293 : fa = xfs_rtbuf_verify(bp);
71 161293 : if (fa)
72 0 : goto fail;
73 :
74 : return;
75 0 : fail:
76 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
77 : }
78 :
79 : static void
80 2811941 : xfs_rtbuf_verify_write(
81 : struct xfs_buf *bp)
82 : {
83 2811941 : struct xfs_mount *mp = bp->b_mount;
84 2811941 : struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
85 2811941 : struct xfs_buf_log_item *bip = bp->b_log_item;
86 2811941 : xfs_failaddr_t fa;
87 :
88 2811941 : if (!xfs_has_rtgroups(mp))
89 : return;
90 :
91 2811932 : fa = xfs_rtbuf_verify(bp);
92 2811932 : if (fa) {
93 0 : xfs_verifier_error(bp, -EFSCORRUPTED, fa);
94 0 : return;
95 : }
96 :
97 2811932 : if (bip)
98 856371 : hdr->rt_lsn = cpu_to_be64(bip->bli_item.li_lsn);
99 2811932 : xfs_buf_update_cksum(bp, XFS_RTBUF_CRC_OFF);
100 : }
101 :
102 : const struct xfs_buf_ops xfs_rtbuf_ops = {
103 : .name = "rtbuf",
104 : .verify_read = xfs_rtbuf_verify_read,
105 : .verify_write = xfs_rtbuf_verify_write,
106 : };
107 :
108 : const struct xfs_buf_ops xfs_rtbitmap_buf_ops = {
109 : .name = "xfs_rtbitmap",
110 : .magic = { 0, cpu_to_be32(XFS_RTBITMAP_MAGIC) },
111 : .verify_read = xfs_rtbuf_verify_read,
112 : .verify_write = xfs_rtbuf_verify_write,
113 : .verify_struct = xfs_rtbuf_verify,
114 : };
115 :
116 : const struct xfs_buf_ops xfs_rtsummary_buf_ops = {
117 : .name = "xfs_rtsummary",
118 : .magic = { 0, cpu_to_be32(XFS_RTSUMMARY_MAGIC) },
119 : .verify_read = xfs_rtbuf_verify_read,
120 : .verify_write = xfs_rtbuf_verify_write,
121 : .verify_struct = xfs_rtbuf_verify,
122 : };
123 :
124 : /*
125 : * Get a buffer for the bitmap or summary file block specified.
126 : * The buffer is returned read and locked.
127 : */
128 : int
129 2069118291 : xfs_rtbuf_get(
130 : xfs_mount_t *mp, /* file system mount structure */
131 : xfs_trans_t *tp, /* transaction pointer */
132 : xfs_fileoff_t block, /* block number in bitmap or summary */
133 : int issum, /* is summary not bitmap */
134 : struct xfs_buf **bpp) /* output: buffer for the block */
135 : {
136 2069118291 : struct xfs_buf *bp; /* block buffer, result */
137 2069118291 : xfs_inode_t *ip; /* bitmap or summary inode */
138 2069118291 : xfs_bmbt_irec_t map;
139 2069118291 : int nmap = 1;
140 2069118291 : int error; /* error value */
141 :
142 2069118291 : ip = issum ? mp->m_rsumip : mp->m_rbmip;
143 :
144 2069118291 : error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
145 2069117762 : if (error)
146 : return error;
147 :
148 2069117762 : if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
149 0 : xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
150 : XFS_SICK_RT_BITMAP);
151 0 : return -EFSCORRUPTED;
152 : }
153 :
154 2069117762 : ASSERT(map.br_startblock != NULLFSBLOCK);
155 2069117762 : error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
156 2069117762 : XFS_FSB_TO_DADDR(mp, map.br_startblock),
157 : mp->m_bsize, 0, &bp,
158 : xfs_rtblock_ops(mp, issum));
159 2069135059 : if (xfs_metadata_is_sick(error))
160 0 : xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
161 : XFS_SICK_RT_BITMAP);
162 2069135059 : if (error)
163 : return error;
164 :
165 2069135059 : if (xfs_has_rtgroups(mp)) {
166 2069135826 : struct xfs_rtbuf_blkinfo *hdr = bp->b_addr;
167 :
168 2069135826 : if (hdr->rt_owner != cpu_to_be64(ip->i_ino)) {
169 0 : xfs_buf_mark_corrupt(bp);
170 0 : xfs_trans_brelse(tp, bp);
171 0 : xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
172 : XFS_SICK_RT_BITMAP);
173 0 : return -EFSCORRUPTED;
174 : }
175 : }
176 :
177 4042737876 : xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
178 : : XFS_BLFT_RTBITMAP_BUF);
179 2069137333 : *bpp = bp;
180 2069137333 : return 0;
181 : }
182 :
183 : /* Convert an ondisk bitmap word to its incore representation. */
184 : inline xfs_rtword_t
185 839620 : xfs_rtbitmap_getword(
186 : struct xfs_mount *mp,
187 : union xfs_rtword_ondisk *wordptr)
188 : {
189 839620 : if (xfs_has_rtgroups(mp))
190 >19251*10^7 : return le32_to_cpu(wordptr->rtg);
191 :
192 0 : return wordptr->raw;
193 : }
194 :
195 : /* Set an ondisk bitmap word from an incore representation. */
196 : inline void
197 839620 : xfs_rtbitmap_setword(
198 : struct xfs_mount *mp,
199 : union xfs_rtword_ondisk *wordptr,
200 : xfs_rtword_t incore)
201 : {
202 839620 : if (xfs_has_rtgroups(mp))
203 54076703 : wordptr->rtg = cpu_to_le32(incore);
204 : else
205 0 : wordptr->raw = incore;
206 839620 : }
207 :
208 : /*
209 : * Searching backward from start to limit, find the first block whose
210 : * allocated/free state is different from start's.
211 : */
212 : int
213 39592179 : xfs_rtfind_back(
214 : xfs_mount_t *mp, /* file system mount point */
215 : xfs_trans_t *tp, /* transaction pointer */
216 : xfs_rtxnum_t start, /* starting rtext to look at */
217 : xfs_rtxnum_t limit, /* last rtext to look at */
218 : xfs_rtxnum_t *rtx) /* out: start rtext found */
219 : {
220 39592179 : union xfs_rtword_ondisk *b; /* current word in buffer */
221 39592179 : int bit; /* bit number in the word */
222 39592179 : xfs_fileoff_t block; /* bitmap block number */
223 39592179 : struct xfs_buf *bp; /* buf for the block */
224 39592179 : int error; /* error value */
225 39592179 : xfs_rtxnum_t firstbit; /* first useful bit in the word */
226 39592179 : xfs_rtxnum_t i; /* current bit number rel. to start */
227 39592179 : xfs_rtxnum_t len; /* length of inspected area */
228 39592179 : xfs_rtword_t mask; /* mask of relevant bits for value */
229 39592179 : xfs_rtword_t want; /* mask for "good" values */
230 39592179 : xfs_rtword_t wdiff; /* difference from wanted value */
231 39592179 : xfs_rtword_t incore;
232 39592179 : int word; /* word number in the buffer */
233 :
234 : /*
235 : * Compute and read in starting bitmap block for starting block.
236 : */
237 39592179 : block = xfs_rtx_to_rbmblock(mp, start);
238 39592179 : error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
239 39592179 : if (error) {
240 : return error;
241 : }
242 :
243 : /*
244 : * Get the first word's index & point to it.
245 : */
246 39592179 : word = xfs_rtx_to_rbmword(mp, start);
247 39592179 : b = xfs_rbmblock_wordptr(bp, word);
248 39592179 : bit = (int)(start & (XFS_NBWORD - 1));
249 39592179 : len = start - limit + 1;
250 : /*
251 : * Compute match value, based on the bit at start: if 1 (free)
252 : * then all-ones, else all-zeroes.
253 : */
254 39592179 : incore = xfs_rtbitmap_getword(mp, b);
255 39592179 : want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
256 : /*
257 : * If the starting position is not word-aligned, deal with the
258 : * partial word.
259 : */
260 39592179 : if (bit < XFS_NBWORD - 1) {
261 : /*
262 : * Calculate first (leftmost) bit number to look at,
263 : * and mask for all the relevant bits in this word.
264 : */
265 38364154 : firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
266 38364154 : mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
267 : firstbit;
268 : /*
269 : * Calculate the difference between the value there
270 : * and what we're looking for.
271 : */
272 38364154 : if ((wdiff = (incore ^ want) & mask)) {
273 : /*
274 : * Different. Mark where we are and return.
275 : */
276 36572906 : xfs_trans_brelse(tp, bp);
277 36572906 : i = bit - XFS_RTHIBIT(wdiff);
278 36572906 : *rtx = start - i + 1;
279 36572906 : return 0;
280 : }
281 1791248 : i = bit - firstbit + 1;
282 : /*
283 : * Go on to previous block if that's where the previous word is
284 : * and we need the previous word.
285 : */
286 1791248 : if (--word == -1 && i < len) {
287 : /*
288 : * If done with this block, get the previous one.
289 : */
290 113896 : xfs_trans_brelse(tp, bp);
291 113896 : error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
292 113896 : if (error) {
293 : return error;
294 : }
295 :
296 113896 : word = mp->m_blockwsize - 1;
297 227792 : b = xfs_rbmblock_wordptr(bp, word);
298 : } else {
299 : /*
300 : * Go on to the previous word in the buffer.
301 : */
302 1677352 : b--;
303 : }
304 : } else {
305 : /*
306 : * Starting on a word boundary, no partial word.
307 : */
308 : i = 0;
309 : }
310 : /*
311 : * Loop over whole words in buffers. When we use up one buffer
312 : * we move on to the previous one.
313 : */
314 5232166026 : while (len - i >= XFS_NBWORD) {
315 : /*
316 : * Compute difference between actual and desired value.
317 : */
318 5232166026 : incore = xfs_rtbitmap_getword(mp, b);
319 5232166026 : if ((wdiff = incore ^ want)) {
320 : /*
321 : * Different, mark where we are and return.
322 : */
323 3019273 : xfs_trans_brelse(tp, bp);
324 3019273 : i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
325 3019273 : *rtx = start - i + 1;
326 3019273 : return 0;
327 : }
328 5229146753 : i += XFS_NBWORD;
329 : /*
330 : * Go on to previous block if that's where the previous word is
331 : * and we need the previous word.
332 : */
333 5229146753 : if (--word == -1 && i < len) {
334 : /*
335 : * If done with this block, get the previous one.
336 : */
337 5094883 : xfs_trans_brelse(tp, bp);
338 5094883 : error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
339 5094883 : if (error) {
340 0 : return error;
341 : }
342 :
343 5094883 : word = mp->m_blockwsize - 1;
344 10189766 : b = xfs_rbmblock_wordptr(bp, word);
345 : } else {
346 : /*
347 : * Go on to the previous word in the buffer.
348 : */
349 5224051870 : b--;
350 : }
351 : }
352 : /*
353 : * If not ending on a word boundary, deal with the last
354 : * (partial) word.
355 : */
356 0 : if (len - i) {
357 : /*
358 : * Calculate first (leftmost) bit number to look at,
359 : * and mask for all the relevant bits in this word.
360 : */
361 0 : firstbit = XFS_NBWORD - (len - i);
362 0 : mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
363 : /*
364 : * Compute difference between actual and desired value.
365 : */
366 0 : incore = xfs_rtbitmap_getword(mp, b);
367 0 : if ((wdiff = (incore ^ want) & mask)) {
368 : /*
369 : * Different, mark where we are and return.
370 : */
371 0 : xfs_trans_brelse(tp, bp);
372 0 : i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
373 0 : *rtx = start - i + 1;
374 0 : return 0;
375 : } else
376 : i = len;
377 : }
378 : /*
379 : * No match, return that we scanned the whole area.
380 : */
381 0 : xfs_trans_brelse(tp, bp);
382 0 : *rtx = start - i + 1;
383 0 : return 0;
384 : }
385 :
386 : /*
387 : * Searching forward from start to limit, find the first block whose
388 : * allocated/free state is different from start's.
389 : */
390 : int
391 528791815 : xfs_rtfind_forw(
392 : xfs_mount_t *mp, /* file system mount point */
393 : xfs_trans_t *tp, /* transaction pointer */
394 : xfs_rtxnum_t start, /* starting rtext to look at */
395 : xfs_rtxnum_t limit, /* last rtext to look at */
396 : xfs_rtxnum_t *rtx) /* out: start rtext found */
397 : {
398 528791815 : union xfs_rtword_ondisk *b; /* current word in buffer */
399 528791815 : int bit; /* bit number in the word */
400 528791815 : xfs_fileoff_t block; /* bitmap block number */
401 528791815 : struct xfs_buf *bp; /* buf for the block */
402 528791815 : int error; /* error value */
403 528791815 : xfs_rtxnum_t i; /* current bit number rel. to start */
404 528791815 : xfs_rtxnum_t lastbit; /* last useful bit in the word */
405 528791815 : xfs_rtxnum_t len; /* length of inspected area */
406 528791815 : xfs_rtword_t mask; /* mask of relevant bits for value */
407 528791815 : xfs_rtword_t want; /* mask for "good" values */
408 528791815 : xfs_rtword_t wdiff; /* difference from wanted value */
409 528791815 : xfs_rtword_t incore;
410 528791815 : int word; /* word number in the buffer */
411 :
412 : /*
413 : * Compute and read in starting bitmap block for starting block.
414 : */
415 528791815 : block = xfs_rtx_to_rbmblock(mp, start);
416 528791815 : error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
417 528791806 : if (error) {
418 : return error;
419 : }
420 :
421 : /*
422 : * Get the first word's index & point to it.
423 : */
424 528791806 : word = xfs_rtx_to_rbmword(mp, start);
425 528791806 : b = xfs_rbmblock_wordptr(bp, word);
426 528791806 : bit = (int)(start & (XFS_NBWORD - 1));
427 528791806 : len = limit - start + 1;
428 : /*
429 : * Compute match value, based on the bit at start: if 1 (free)
430 : * then all-ones, else all-zeroes.
431 : */
432 528791806 : incore = xfs_rtbitmap_getword(mp, b);
433 528791806 : want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
434 : /*
435 : * If the starting position is not word-aligned, deal with the
436 : * partial word.
437 : */
438 528791806 : if (bit) {
439 : /*
440 : * Calculate last (rightmost) bit number to look at,
441 : * and mask for all the relevant bits in this word.
442 : */
443 444177016 : lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
444 444177016 : mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
445 : /*
446 : * Calculate the difference between the value there
447 : * and what we're looking for.
448 : */
449 444177016 : if ((wdiff = (incore ^ want) & mask)) {
450 : /*
451 : * Different. Mark where we are and return.
452 : */
453 151229296 : xfs_trans_brelse(tp, bp);
454 151229294 : i = XFS_RTLOBIT(wdiff) - bit;
455 151229294 : *rtx = start + i - 1;
456 151229294 : return 0;
457 : }
458 292947720 : i = lastbit - bit;
459 : /*
460 : * Go on to next block if that's where the next word is
461 : * and we need the next word.
462 : */
463 292947720 : if (++word == mp->m_blockwsize && i < len) {
464 : /*
465 : * If done with this block, get the previous one.
466 : */
467 493879 : xfs_trans_brelse(tp, bp);
468 493879 : error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
469 493879 : if (error) {
470 : return error;
471 : }
472 :
473 493879 : word = 0;
474 493879 : b = xfs_rbmblock_wordptr(bp, word);
475 : } else {
476 : /*
477 : * Go on to the previous word in the buffer.
478 : */
479 292453841 : b++;
480 : }
481 : } else {
482 : /*
483 : * Starting on a word boundary, no partial word.
484 : */
485 : i = 0;
486 : }
487 : /*
488 : * Loop over whole words in buffers. When we use up one buffer
489 : * we move on to the next one.
490 : */
491 >18545*10^7 : while (len - i >= XFS_NBWORD) {
492 : /*
493 : * Compute difference between actual and desired value.
494 : */
495 >18539*10^7 : incore = xfs_rtbitmap_getword(mp, b);
496 >18539*10^7 : if ((wdiff = incore ^ want)) {
497 : /*
498 : * Different, mark where we are and return.
499 : */
500 320200426 : xfs_trans_brelse(tp, bp);
501 320200464 : i += XFS_RTLOBIT(wdiff);
502 320200464 : *rtx = start + i - 1;
503 320200464 : return 0;
504 : }
505 >18507*10^7 : i += XFS_NBWORD;
506 : /*
507 : * Go on to next block if that's where the next word is
508 : * and we need the next word.
509 : */
510 >18507*10^7 : if (++word == mp->m_blockwsize && i < len) {
511 : /*
512 : * If done with this block, get the next one.
513 : */
514 122246324 : xfs_trans_brelse(tp, bp);
515 122246350 : error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
516 122246302 : if (error) {
517 0 : return error;
518 : }
519 :
520 122246302 : word = 0;
521 122246302 : b = xfs_rbmblock_wordptr(bp, word);
522 : } else {
523 : /*
524 : * Go on to the next word in the buffer.
525 : */
526 >18495*10^7 : b++;
527 : }
528 : }
529 : /*
530 : * If not ending on a word boundary, deal with the last
531 : * (partial) word.
532 : */
533 57362062 : if ((lastbit = len - i)) {
534 : /*
535 : * Calculate mask for all the relevant bits in this word.
536 : */
537 12 : mask = ((xfs_rtword_t)1 << lastbit) - 1;
538 : /*
539 : * Compute difference between actual and desired value.
540 : */
541 12 : incore = xfs_rtbitmap_getword(mp, b);
542 12 : if ((wdiff = (incore ^ want) & mask)) {
543 : /*
544 : * Different, mark where we are and return.
545 : */
546 6 : xfs_trans_brelse(tp, bp);
547 6 : i += XFS_RTLOBIT(wdiff);
548 6 : *rtx = start + i - 1;
549 6 : return 0;
550 : } else
551 : i = len;
552 : }
553 : /*
554 : * No match, return that we scanned the whole area.
555 : */
556 57362056 : xfs_trans_brelse(tp, bp);
557 57362056 : *rtx = start + i - 1;
558 57362056 : return 0;
559 : }
560 :
561 : inline xfs_suminfo_t
562 1740854650 : xfs_suminfo_get(
563 : struct xfs_mount *mp,
564 : union xfs_suminfo_ondisk *infoptr)
565 : {
566 1740854650 : if (xfs_has_rtgroups(mp))
567 1740854650 : return be32_to_cpu(infoptr->rtg);
568 :
569 0 : return infoptr->raw;
570 : }
571 :
572 : inline void
573 58989117 : xfs_suminfo_add(
574 : struct xfs_mount *mp,
575 : union xfs_suminfo_ondisk *infoptr,
576 : int delta)
577 : {
578 58989117 : if (xfs_has_rtgroups(mp))
579 58989117 : be32_add_cpu(&infoptr->rtg, delta);
580 : else
581 0 : infoptr->raw += delta;
582 58989117 : }
583 :
584 : /*
585 : * Read and/or modify the summary information for a given extent size,
586 : * bitmap block combination.
587 : * Keeps track of a current summary block, so we don't keep reading
588 : * it from the buffer cache.
589 : *
590 : * Summary information is returned in *sum if specified.
591 : * If no delta is specified, returns summary only.
592 : */
593 : int
594 1792461337 : xfs_rtmodify_summary_int(
595 : xfs_mount_t *mp, /* file system mount structure */
596 : xfs_trans_t *tp, /* transaction pointer */
597 : int log, /* log2 of extent size */
598 : xfs_fileoff_t bbno, /* bitmap block number */
599 : int delta, /* change to make to summary info */
600 : struct xfs_buf **rbpp, /* in/out: summary block buffer */
601 : xfs_fileoff_t *rsb, /* in/out: summary block number */
602 : xfs_suminfo_t *sum) /* out: summary info for this block */
603 : {
604 1792461337 : struct xfs_buf *bp; /* buffer for the summary block */
605 1792461337 : int error; /* error value */
606 1792461337 : xfs_fileoff_t sb; /* summary fsblock */
607 1792461337 : xfs_rtsumoff_t so; /* index into the summary file */
608 1792461337 : union xfs_suminfo_ondisk *sp; /* pointer to returned data */
609 1792461337 : unsigned int infoword;
610 :
611 : /*
612 : * Compute entry number in the summary file.
613 : */
614 1792461337 : so = xfs_rtsumoffs(mp, log, bbno);
615 : /*
616 : * Compute the block number in the summary file.
617 : */
618 1792461337 : sb = xfs_rtsumoffs_to_block(mp, so);
619 : /*
620 : * If we have an old buffer, and the block number matches, use that.
621 : */
622 1792461337 : if (*rbpp && *rsb == sb)
623 1697401713 : bp = *rbpp;
624 : /*
625 : * Otherwise we have to get the buffer.
626 : */
627 : else {
628 : /*
629 : * If there was an old one, get rid of it first.
630 : */
631 95059624 : if (*rbpp)
632 55467441 : xfs_trans_brelse(tp, *rbpp);
633 95059624 : error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
634 95059624 : if (error) {
635 : return error;
636 : }
637 : /*
638 : * Remember this buffer and block for the next call.
639 : */
640 95059624 : *rbpp = bp;
641 95059624 : *rsb = sb;
642 : }
643 : /*
644 : * Point to the summary information, modify/log it, and/or copy it out.
645 : */
646 1792461337 : infoword = xfs_rtsumoffs_to_infoword(mp, so);
647 1792461337 : sp = xfs_rsumblock_infoptr(bp, infoword);
648 1792461337 : if (delta) {
649 51606687 : uint first = (uint)((char *)sp - (char *)bp->b_addr);
650 :
651 51606687 : xfs_suminfo_add(mp, sp, delta);
652 51606687 : if (mp->m_rsum_cache) {
653 51606687 : if (sp->raw == 0 && log == mp->m_rsum_cache[bbno])
654 10472918 : mp->m_rsum_cache[bbno]++;
655 51606687 : if (sp->raw != 0 && log < mp->m_rsum_cache[bbno])
656 11769546 : mp->m_rsum_cache[bbno] = log;
657 : }
658 51606687 : xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
659 : }
660 1792461337 : if (sum)
661 1740854650 : *sum = xfs_suminfo_get(mp, sp);
662 : return 0;
663 : }
664 :
665 : int
666 33784901 : xfs_rtmodify_summary(
667 : xfs_mount_t *mp, /* file system mount structure */
668 : xfs_trans_t *tp, /* transaction pointer */
669 : int log, /* log2 of extent size */
670 : xfs_fileoff_t bbno, /* bitmap block number */
671 : int delta, /* change to make to summary info */
672 : struct xfs_buf **rbpp, /* in/out: summary block buffer */
673 : xfs_fileoff_t *rsb) /* in/out: summary block number */
674 : {
675 35784282 : return xfs_rtmodify_summary_int(mp, tp, log, bbno,
676 : delta, rbpp, rsb, NULL);
677 : }
678 :
679 : /*
680 : * Set the given range of bitmap bits to the given value.
681 : * Do whatever I/O and logging is required.
682 : */
683 : int
684 39592179 : xfs_rtmodify_range(
685 : xfs_mount_t *mp, /* file system mount point */
686 : xfs_trans_t *tp, /* transaction pointer */
687 : xfs_rtxnum_t start, /* starting rtext to modify */
688 : xfs_rtxlen_t len, /* length of extent to modify */
689 : int val) /* 1 for free, 0 for allocated */
690 : {
691 39592179 : union xfs_rtword_ondisk *b; /* current word in buffer */
692 39592179 : int bit; /* bit number in the word */
693 39592179 : xfs_fileoff_t block; /* bitmap block number */
694 39592179 : struct xfs_buf *bp; /* buf for the block */
695 39592179 : int error; /* error value */
696 39592179 : union xfs_rtword_ondisk *first; /* first used word in the buffer */
697 39592179 : int i; /* current bit number rel. to start */
698 39592179 : int lastbit; /* last useful bit in word */
699 39592179 : xfs_rtword_t mask; /* mask o frelevant bits for value */
700 39592179 : xfs_rtword_t incore;
701 39592179 : int word; /* word number in the buffer */
702 :
703 : /*
704 : * Compute starting bitmap block number.
705 : */
706 39592179 : block = xfs_rtx_to_rbmblock(mp, start);
707 : /*
708 : * Read the bitmap block, and point to its data.
709 : */
710 39592179 : error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
711 39592179 : if (error) {
712 : return error;
713 : }
714 :
715 : /*
716 : * Compute the starting word's address, and starting bit.
717 : */
718 39592179 : word = xfs_rtx_to_rbmword(mp, start);
719 39592179 : first = b = xfs_rbmblock_wordptr(bp, word);
720 39592179 : bit = (int)(start & (XFS_NBWORD - 1));
721 : /*
722 : * 0 (allocated) => all zeroes; 1 (free) => all ones.
723 : */
724 39592179 : val = -val;
725 : /*
726 : * If not starting on a word boundary, deal with the first
727 : * (partial) word.
728 : */
729 39592179 : if (bit) {
730 : /*
731 : * Compute first bit not changed and mask of relevant bits.
732 : */
733 38270484 : lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
734 38270484 : mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
735 : /*
736 : * Set/clear the active bits.
737 : */
738 38270484 : incore = xfs_rtbitmap_getword(mp, b);
739 38270484 : if (val)
740 15289984 : incore |= mask;
741 : else
742 22980500 : incore &= ~mask;
743 38270484 : xfs_rtbitmap_setword(mp, b, incore);
744 38270484 : i = lastbit - bit;
745 : /*
746 : * Go on to the next block if that's where the next word is
747 : * and we need the next word.
748 : */
749 38270484 : if (++word == mp->m_blockwsize && i < len) {
750 : /*
751 : * Log the changed part of this block.
752 : * Get the next one.
753 : */
754 8481 : xfs_trans_log_buf(tp, bp,
755 8481 : (uint)((char *)first - (char *)bp->b_addr),
756 : (uint)((char *)b - (char *)bp->b_addr));
757 8481 : error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
758 8481 : if (error) {
759 : return error;
760 : }
761 :
762 8481 : word = 0;
763 8481 : first = b = xfs_rbmblock_wordptr(bp, word);
764 : } else {
765 : /*
766 : * Go on to the next word in the buffer
767 : */
768 38262003 : b++;
769 : }
770 : } else {
771 : /*
772 : * Starting on a word boundary, no partial word.
773 : */
774 : i = 0;
775 : }
776 : /*
777 : * Loop over whole words in buffers. When we use up one buffer
778 : * we move on to the next one.
779 : */
780 43521434 : while (len - i >= XFS_NBWORD) {
781 : /*
782 : * Set the word value correctly.
783 : */
784 3929255 : xfs_rtbitmap_setword(mp, b, val);
785 3929255 : i += XFS_NBWORD;
786 : /*
787 : * Go on to the next block if that's where the next word is
788 : * and we need the next word.
789 : */
790 3929255 : if (++word == mp->m_blockwsize && i < len) {
791 : /*
792 : * Log the changed part of this block.
793 : * Get the next one.
794 : */
795 1656 : xfs_trans_log_buf(tp, bp,
796 1656 : (uint)((char *)first - (char *)bp->b_addr),
797 1656 : (uint)((char *)b - (char *)bp->b_addr));
798 1656 : error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
799 1656 : if (error) {
800 0 : return error;
801 : }
802 :
803 1656 : word = 0;
804 1656 : first = b = xfs_rbmblock_wordptr(bp, word);
805 : } else {
806 : /*
807 : * Go on to the next word in the buffer
808 : */
809 3927599 : b++;
810 : }
811 : }
812 : /*
813 : * If not ending on a word boundary, deal with the last
814 : * (partial) word.
815 : */
816 39592179 : if ((lastbit = len - i)) {
817 : /*
818 : * Compute a mask of relevant bits.
819 : */
820 11037344 : mask = ((xfs_rtword_t)1 << lastbit) - 1;
821 : /*
822 : * Set/clear the active bits.
823 : */
824 11037344 : incore = xfs_rtbitmap_getword(mp, b);
825 11037344 : if (val)
826 3813116 : incore |= mask;
827 : else
828 7224228 : incore &= ~mask;
829 11037344 : xfs_rtbitmap_setword(mp, b, incore);
830 11037344 : b++;
831 : }
832 : /*
833 : * Log any remaining changed bytes.
834 : */
835 39592179 : if (b > first)
836 39592179 : xfs_trans_log_buf(tp, bp,
837 39592179 : (uint)((char *)first - (char *)bp->b_addr),
838 39592179 : (uint)((char *)b - (char *)bp->b_addr - 1));
839 : return 0;
840 : }
841 :
842 : /*
843 : * Mark an extent specified by start and len freed.
844 : * Updates all the summary information as well as the bitmap.
845 : */
846 : int
847 15822405 : xfs_rtfree_range(
848 : xfs_mount_t *mp, /* file system mount point */
849 : xfs_trans_t *tp, /* transaction pointer */
850 : xfs_rtxnum_t start, /* starting rtext to free */
851 : xfs_rtxlen_t len, /* length to free */
852 : struct xfs_buf **rbpp, /* in/out: summary block buffer */
853 : xfs_fileoff_t *rsb) /* in/out: summary block number */
854 : {
855 15822405 : xfs_rtxnum_t end; /* end of the freed extent */
856 15822405 : int error; /* error value */
857 15822405 : xfs_rtxnum_t postblock; /* first rtext freed > end */
858 15822405 : xfs_rtxnum_t preblock; /* first rtext freed < start */
859 :
860 15822405 : end = start + len - 1;
861 : /*
862 : * Modify the bitmap to mark this extent freed.
863 : */
864 15822405 : error = xfs_rtmodify_range(mp, tp, start, len, 1);
865 15822405 : if (error) {
866 : return error;
867 : }
868 : /*
869 : * Assume we're freeing out of the middle of an allocated extent.
870 : * We need to find the beginning and end of the extent so we can
871 : * properly update the summary.
872 : */
873 15822405 : error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
874 15822405 : if (error) {
875 : return error;
876 : }
877 : /*
878 : * Find the next allocated block (end of allocated extent).
879 : */
880 15822405 : error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
881 : &postblock);
882 15822405 : if (error)
883 : return error;
884 : /*
885 : * If there are blocks not being freed at the front of the
886 : * old extent, add summary data for them to be allocated.
887 : */
888 15822405 : if (preblock < start) {
889 1069303 : error = xfs_rtmodify_summary(mp, tp,
890 : XFS_RTBLOCKLOG(start - preblock),
891 : xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb);
892 1069303 : if (error) {
893 : return error;
894 : }
895 : }
896 : /*
897 : * If there are blocks not being freed at the end of the
898 : * old extent, add summary data for them to be allocated.
899 : */
900 15822405 : if (postblock > end) {
901 930078 : error = xfs_rtmodify_summary(mp, tp,
902 : XFS_RTBLOCKLOG(postblock - end),
903 : xfs_rtx_to_rbmblock(mp, end + 1), -1, rbpp, rsb);
904 930078 : if (error) {
905 : return error;
906 : }
907 : }
908 : /*
909 : * Increment the summary information corresponding to the entire
910 : * (new) free extent.
911 : */
912 15822405 : error = xfs_rtmodify_summary(mp, tp,
913 15822405 : XFS_RTBLOCKLOG(postblock + 1 - preblock),
914 : xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb);
915 15822405 : return error;
916 : }
917 :
918 : /*
919 : * Check that the given range is either all allocated (val = 0) or
920 : * all free (val = 1).
921 : */
922 : int
923 1237556449 : xfs_rtcheck_range(
924 : xfs_mount_t *mp, /* file system mount point */
925 : xfs_trans_t *tp, /* transaction pointer */
926 : xfs_rtxnum_t start, /* starting rtext number of extent */
927 : xfs_rtxlen_t len, /* length of extent */
928 : int val, /* 1 for free, 0 for allocated */
929 : xfs_rtxnum_t *new, /* out: first rtext not matching */
930 : int *stat) /* out: 1 for matches, 0 for not */
931 : {
932 1237556449 : union xfs_rtword_ondisk *b; /* current word in buffer */
933 1237556449 : int bit; /* bit number in the word */
934 1237556449 : xfs_fileoff_t block; /* bitmap block number */
935 1237556449 : struct xfs_buf *bp; /* buf for the block */
936 1237556449 : int error; /* error value */
937 1237556449 : xfs_rtxnum_t i; /* current bit number rel. to start */
938 1237556449 : xfs_rtxnum_t lastbit; /* last useful bit in word */
939 1237556449 : xfs_rtword_t mask; /* mask of relevant bits for value */
940 1237556449 : xfs_rtword_t wdiff; /* difference from wanted value */
941 1237556449 : xfs_rtword_t incore;
942 1237556449 : int word; /* word number in the buffer */
943 :
944 : /*
945 : * Compute starting bitmap block number
946 : */
947 1237556449 : block = xfs_rtx_to_rbmblock(mp, start);
948 : /*
949 : * Read the bitmap block.
950 : */
951 1237556449 : error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
952 1237579296 : if (error) {
953 : return error;
954 : }
955 :
956 : /*
957 : * Compute the starting word's address, and starting bit.
958 : */
959 1237579296 : word = xfs_rtx_to_rbmword(mp, start);
960 1237579296 : b = xfs_rbmblock_wordptr(bp, word);
961 1237579296 : bit = (int)(start & (XFS_NBWORD - 1));
962 : /*
963 : * 0 (allocated) => all zero's; 1 (free) => all one's.
964 : */
965 1237579296 : val = -val;
966 : /*
967 : * If not starting on a word boundary, deal with the first
968 : * (partial) word.
969 : */
970 1237579296 : if (bit) {
971 : /*
972 : * Compute first bit not examined.
973 : */
974 1131656807 : lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
975 : /*
976 : * Mask of relevant bits.
977 : */
978 1131656807 : mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
979 : /*
980 : * Compute difference between actual and desired value.
981 : */
982 1131656807 : incore = xfs_rtbitmap_getword(mp, b);
983 1131656807 : if ((wdiff = (incore ^ val) & mask)) {
984 : /*
985 : * Different, compute first wrong bit and return.
986 : */
987 971525849 : xfs_trans_brelse(tp, bp);
988 971532552 : i = XFS_RTLOBIT(wdiff) - bit;
989 971532552 : *new = start + i;
990 971532552 : *stat = 0;
991 971532552 : return 0;
992 : }
993 160130958 : i = lastbit - bit;
994 : /*
995 : * Go on to next block if that's where the next word is
996 : * and we need the next word.
997 : */
998 160130958 : if (++word == mp->m_blockwsize && i < len) {
999 : /*
1000 : * If done with this block, get the next one.
1001 : */
1002 32600 : xfs_trans_brelse(tp, bp);
1003 32600 : error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1004 32600 : if (error) {
1005 : return error;
1006 : }
1007 :
1008 32600 : word = 0;
1009 32600 : b = xfs_rbmblock_wordptr(bp, word);
1010 : } else {
1011 : /*
1012 : * Go on to the next word in the buffer.
1013 : */
1014 160098358 : b++;
1015 : }
1016 : } else {
1017 : /*
1018 : * Starting on a word boundary, no partial word.
1019 : */
1020 : i = 0;
1021 : }
1022 : /*
1023 : * Loop over whole words in buffers. When we use up one buffer
1024 : * we move on to the next one.
1025 : */
1026 270191715 : while (len - i >= XFS_NBWORD) {
1027 : /*
1028 : * Compute difference between actual and desired value.
1029 : */
1030 28376891 : incore = xfs_rtbitmap_getword(mp, b);
1031 28376891 : if ((wdiff = incore ^ val)) {
1032 : /*
1033 : * Different, compute first wrong bit and return.
1034 : */
1035 24238479 : xfs_trans_brelse(tp, bp);
1036 24238479 : i += XFS_RTLOBIT(wdiff);
1037 24238479 : *new = start + i;
1038 24238479 : *stat = 0;
1039 24238479 : return 0;
1040 : }
1041 4138412 : i += XFS_NBWORD;
1042 : /*
1043 : * Go on to next block if that's where the next word is
1044 : * and we need the next word.
1045 : */
1046 4138412 : if (++word == mp->m_blockwsize && i < len) {
1047 : /*
1048 : * If done with this block, get the next one.
1049 : */
1050 3368 : xfs_trans_brelse(tp, bp);
1051 3224 : error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1052 3224 : if (error) {
1053 0 : return error;
1054 : }
1055 :
1056 3224 : word = 0;
1057 3224 : b = xfs_rbmblock_wordptr(bp, word);
1058 : } else {
1059 : /*
1060 : * Go on to the next word in the buffer.
1061 : */
1062 4135044 : b++;
1063 : }
1064 : }
1065 : /*
1066 : * If not ending on a word boundary, deal with the last
1067 : * (partial) word.
1068 : */
1069 241814824 : if ((lastbit = len - i)) {
1070 : /*
1071 : * Mask of relevant bits.
1072 : */
1073 108278256 : mask = ((xfs_rtword_t)1 << lastbit) - 1;
1074 : /*
1075 : * Compute difference between actual and desired value.
1076 : */
1077 108278256 : incore = xfs_rtbitmap_getword(mp, b);
1078 108278256 : if ((wdiff = (incore ^ val) & mask)) {
1079 : /*
1080 : * Different, compute first wrong bit and return.
1081 : */
1082 95467160 : xfs_trans_brelse(tp, bp);
1083 95467171 : i += XFS_RTLOBIT(wdiff);
1084 95467171 : *new = start + i;
1085 95467171 : *stat = 0;
1086 95467171 : return 0;
1087 : } else
1088 : i = len;
1089 : }
1090 : /*
1091 : * Successful, return.
1092 : */
1093 146347664 : xfs_trans_brelse(tp, bp);
1094 146347669 : *new = start + i;
1095 146347669 : *stat = 1;
1096 146347669 : return 0;
1097 : }
1098 :
1099 : #ifdef DEBUG
1100 : /*
1101 : * Check that the given extent (block range) is allocated already.
1102 : */
1103 : STATIC int /* error */
1104 15822390 : xfs_rtcheck_alloc_range(
1105 : xfs_mount_t *mp, /* file system mount point */
1106 : xfs_trans_t *tp, /* transaction pointer */
1107 : xfs_rtxnum_t start, /* starting rtext number of extent */
1108 : xfs_rtxlen_t len) /* length of extent */
1109 : {
1110 15822390 : xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */
1111 15822390 : int stat;
1112 15822390 : int error;
1113 :
1114 15822390 : error = xfs_rtcheck_range(mp, tp, start, len, 0, &new, &stat);
1115 15822390 : if (error)
1116 : return error;
1117 15822390 : ASSERT(stat);
1118 : return 0;
1119 : }
1120 : #else
1121 : #define xfs_rtcheck_alloc_range(m,t,b,l) (0)
1122 : #endif
1123 : /*
1124 : * Free an extent in the realtime subvolume. Length is expressed in
1125 : * realtime extents, as is the block number.
1126 : */
1127 : int /* error */
1128 15822390 : xfs_rtfree_extent(
1129 : xfs_trans_t *tp, /* transaction pointer */
1130 : xfs_rtxnum_t start, /* starting rtext number to free */
1131 : xfs_rtxlen_t len) /* length of extent freed */
1132 : {
1133 15822390 : int error; /* error value */
1134 15822390 : xfs_mount_t *mp; /* file system mount structure */
1135 15822390 : xfs_fsblock_t sb; /* summary file block number */
1136 15822390 : struct xfs_buf *sumbp = NULL; /* summary file block buffer */
1137 :
1138 15822390 : mp = tp->t_mountp;
1139 :
1140 15822390 : ASSERT(mp->m_rbmip->i_itemp != NULL);
1141 15822390 : ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
1142 :
1143 15822390 : if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_FREE_EXTENT))
1144 : return -EIO;
1145 :
1146 15822390 : error = xfs_rtcheck_alloc_range(mp, tp, start, len);
1147 15822390 : if (error)
1148 : return error;
1149 :
1150 : /*
1151 : * Free the range of realtime blocks.
1152 : */
1153 15822390 : error = xfs_rtfree_range(mp, tp, start, len, &sumbp, &sb);
1154 15822390 : if (error) {
1155 : return error;
1156 : }
1157 : /*
1158 : * Mark more blocks free in the superblock.
1159 : */
1160 15822390 : xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
1161 : /*
1162 : * If we've now freed all the blocks, reset the file sequence
1163 : * number to 0.
1164 : */
1165 15822390 : if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
1166 15822390 : mp->m_sb.sb_rextents) {
1167 894259 : if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
1168 0 : mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
1169 894259 : *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
1170 894259 : xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
1171 : }
1172 : return 0;
1173 : }
1174 :
1175 : /*
1176 : * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
1177 : * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
1178 : * cannot exceed XFS_MAX_BMBT_EXTLEN.
1179 : */
1180 : int
1181 15822390 : xfs_rtfree_blocks(
1182 : struct xfs_trans *tp,
1183 : xfs_fsblock_t rtbno,
1184 : xfs_filblks_t rtlen)
1185 : {
1186 15822390 : struct xfs_mount *mp = tp->t_mountp;
1187 15822390 : xfs_rtxnum_t start;
1188 15822390 : xfs_filblks_t len;
1189 15822390 : xfs_extlen_t mod;
1190 :
1191 15822390 : ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
1192 :
1193 15822390 : len = xfs_rtb_to_rtx(mp, rtlen, &mod);
1194 15822390 : if (mod) {
1195 0 : ASSERT(mod == 0);
1196 0 : return -EIO;
1197 : }
1198 :
1199 15822390 : start = xfs_rtb_to_rtx(mp, rtbno, &mod);
1200 15822390 : if (mod) {
1201 0 : ASSERT(mod == 0);
1202 0 : return -EIO;
1203 : }
1204 :
1205 15822390 : return xfs_rtfree_extent(tp, start, len);
1206 : }
1207 :
1208 : /* Find all the free records within a given range. */
1209 : int
1210 258091 : xfs_rtalloc_query_range(
1211 : struct xfs_mount *mp,
1212 : struct xfs_trans *tp,
1213 : const struct xfs_rtalloc_rec *low_rec,
1214 : const struct xfs_rtalloc_rec *high_rec,
1215 : xfs_rtalloc_query_range_fn fn,
1216 : void *priv)
1217 : {
1218 258091 : struct xfs_rtalloc_rec rec;
1219 258091 : xfs_rtxnum_t rtstart;
1220 258091 : xfs_rtxnum_t rtend;
1221 258091 : xfs_rtxnum_t high_key;
1222 258091 : int is_free;
1223 258091 : int error = 0;
1224 :
1225 258091 : if (low_rec->ar_startext > high_rec->ar_startext)
1226 : return -EINVAL;
1227 258091 : if (low_rec->ar_startext >= mp->m_sb.sb_rextents ||
1228 : low_rec->ar_startext == high_rec->ar_startext)
1229 : return 0;
1230 :
1231 257453 : high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1);
1232 :
1233 : /* Iterate the bitmap, looking for discrepancies. */
1234 257453 : rtstart = low_rec->ar_startext;
1235 238993808 : while (rtstart <= high_key) {
1236 : /* Is the first block free? */
1237 238736356 : error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend,
1238 : &is_free);
1239 238737183 : if (error)
1240 : break;
1241 :
1242 : /* How long does the extent go for? */
1243 238737183 : error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend);
1244 238736597 : if (error)
1245 : break;
1246 :
1247 238736597 : if (is_free) {
1248 119306737 : rec.ar_startext = rtstart;
1249 119306737 : rec.ar_extcount = rtend - rtstart + 1;
1250 :
1251 119306737 : error = fn(mp, tp, &rec, priv);
1252 119306495 : if (error)
1253 : break;
1254 : }
1255 :
1256 238736355 : rtstart = rtend + 1;
1257 : }
1258 :
1259 : return error;
1260 : }
1261 :
1262 : /* Find all the free records. */
1263 : int
1264 116770 : xfs_rtalloc_query_all(
1265 : struct xfs_mount *mp,
1266 : struct xfs_trans *tp,
1267 : xfs_rtalloc_query_range_fn fn,
1268 : void *priv)
1269 : {
1270 116770 : struct xfs_rtalloc_rec keys[2];
1271 :
1272 116770 : keys[0].ar_startext = 0;
1273 116770 : keys[1].ar_startext = mp->m_sb.sb_rextents - 1;
1274 116770 : keys[0].ar_extcount = keys[1].ar_extcount = 0;
1275 :
1276 116770 : return xfs_rtalloc_query_range(mp, tp, &keys[0], &keys[1], fn, priv);
1277 : }
1278 :
1279 : /* Is the given extent all free? */
1280 : int
1281 699644454 : xfs_rtalloc_extent_is_free(
1282 : struct xfs_mount *mp,
1283 : struct xfs_trans *tp,
1284 : xfs_rtxnum_t start,
1285 : xfs_rtxlen_t len,
1286 : bool *is_free)
1287 : {
1288 699644454 : xfs_rtxnum_t end;
1289 699644454 : int matches;
1290 699644454 : int error;
1291 :
1292 699644454 : error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches);
1293 699695761 : if (error)
1294 : return error;
1295 :
1296 699695761 : *is_free = matches;
1297 699695761 : return 0;
1298 : }
1299 :
1300 : /*
1301 : * Compute the number of rtbitmap blocks needed to track the given number of rt
1302 : * extents.
1303 : */
1304 : xfs_filblks_t
1305 68998 : xfs_rtbitmap_blockcount(
1306 : struct xfs_mount *mp,
1307 : xfs_rtbxlen_t rtextents)
1308 : {
1309 106457 : unsigned int rbmblock_bytes = mp->m_sb.sb_blocksize;
1310 :
1311 68998 : if (xfs_has_rtgroups(mp))
1312 106429 : rbmblock_bytes -= sizeof(struct xfs_rtbuf_blkinfo);
1313 :
1314 106457 : return howmany_64(rtextents, NBBY * rbmblock_bytes);
1315 : }
1316 :
1317 : /*
1318 : * Compute the number of rtbitmap words needed to populate every block of a
1319 : * bitmap that is large enough to track the given number of rt extents.
1320 : */
1321 : unsigned long long
1322 37459 : xfs_rtbitmap_wordcount(
1323 : struct xfs_mount *mp,
1324 : xfs_rtbxlen_t rtextents)
1325 : {
1326 37459 : xfs_filblks_t blocks;
1327 :
1328 37459 : blocks = xfs_rtbitmap_blockcount(mp, rtextents);
1329 37459 : return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
1330 : }
1331 :
1332 : /* Compute the number of rtsummary blocks needed to track the given rt space. */
1333 : xfs_filblks_t
1334 67771 : xfs_rtsummary_blockcount(
1335 : struct xfs_mount *mp,
1336 : unsigned int rsumlevels,
1337 : xfs_extlen_t rbmblocks)
1338 : {
1339 67771 : unsigned long long rsumwords;
1340 :
1341 67771 : rsumwords = (unsigned long long)rsumlevels * rbmblocks;
1342 :
1343 67771 : if (xfs_has_rtgroups(mp))
1344 67768 : return howmany_64(rsumwords, mp->m_blockwsize);
1345 :
1346 3 : return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
1347 : }
1348 :
1349 : /*
1350 : * Compute the number of rtsummary info words needed to populate every block of
1351 : * a summary file that is large enough to track the given rt space.
1352 : */
1353 : unsigned long long
1354 67522 : xfs_rtsummary_wordcount(
1355 : struct xfs_mount *mp,
1356 : unsigned int rsumlevels,
1357 : xfs_extlen_t rbmblocks)
1358 : {
1359 67522 : xfs_filblks_t blocks;
1360 :
1361 67522 : blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks);
1362 67522 : return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
1363 : }
1364 :
1365 : /*
1366 : * Lock both realtime free space metadata inodes for a freespace update. If a
1367 : * transaction is given, the inodes will be joined to the transaction and the
1368 : * ILOCKs will be released on transaction commit.
1369 : */
1370 : void
1371 58250662 : xfs_rtbitmap_lock(
1372 : struct xfs_trans *tp,
1373 : struct xfs_mount *mp)
1374 : {
1375 58250662 : xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
1376 58253660 : if (tp)
1377 58209897 : xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
1378 :
1379 58253660 : xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL);
1380 58253660 : if (tp)
1381 58209897 : xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
1382 58253660 : }
1383 :
1384 : /* Unlock both realtime free space metadata inodes after a freespace update. */
1385 : void
1386 43763 : xfs_rtbitmap_unlock(
1387 : struct xfs_mount *mp)
1388 : {
1389 43763 : xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL);
1390 43763 : xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL);
1391 43763 : }
1392 :
1393 : /*
1394 : * Lock the realtime free space metadata inodes for a freespace scan. Callers
1395 : * must walk metadata blocks in order of increasing file offset.
1396 : */
1397 : void
1398 29274509 : xfs_rtbitmap_lock_shared(
1399 : struct xfs_mount *mp,
1400 : unsigned int rbmlock_flags)
1401 : {
1402 29274509 : if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
1403 29274620 : xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED);
1404 :
1405 29275552 : if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
1406 0 : xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED);
1407 29275552 : }
1408 :
1409 : /* Unlock the realtime free space metadata inodes after a freespace scan. */
1410 : void
1411 29276590 : xfs_rtbitmap_unlock_shared(
1412 : struct xfs_mount *mp,
1413 : unsigned int rbmlock_flags)
1414 : {
1415 29276590 : if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
1416 0 : xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED);
1417 :
1418 29276590 : if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
1419 29276606 : xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED);
1420 29276851 : }
|