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_rtbitmap.h"
20#include "xfs_health.h"
21
22/*
23 * Realtime allocator bitmap functions shared with userspace.
24 */
25
26/*
27 * Real time buffers need verifiers to avoid runtime warnings during IO.
28 * We don't have anything to verify, however, so these are just dummy
29 * operations.
30 */
31static void
32xfs_rtbuf_verify_read(
33 struct xfs_buf *bp)
34{
35 return;
36}
37
38static void
39xfs_rtbuf_verify_write(
40 struct xfs_buf *bp)
41{
42 return;
43}
44
45const struct xfs_buf_ops xfs_rtbuf_ops = {
46 .name = "rtbuf",
47 .verify_read = xfs_rtbuf_verify_read,
48 .verify_write = xfs_rtbuf_verify_write,
49};
50
51/* Release cached rt bitmap and summary buffers. */
52void
53xfs_rtbuf_cache_relse(
54 struct xfs_rtalloc_args *args)
55{
56 if (args->rbmbp) {
57 xfs_trans_brelse(args->tp, args->rbmbp);
58 args->rbmbp = NULL;
59 args->rbmoff = NULLFILEOFF;
60 }
61 if (args->sumbp) {
62 xfs_trans_brelse(args->tp, args->sumbp);
63 args->sumbp = NULL;
64 args->sumoff = NULLFILEOFF;
65 }
66}
67
68/*
69 * Get a buffer for the bitmap or summary file block specified.
70 * The buffer is returned read and locked.
71 */
72int
73xfs_rtbuf_get(
74 struct xfs_rtalloc_args *args,
75 xfs_fileoff_t block, /* block number in bitmap or summary */
76 int issum) /* is summary not bitmap */
77{
78 struct xfs_mount *mp = args->mp;
79 struct xfs_buf **cbpp; /* cached block buffer */
80 xfs_fileoff_t *coffp; /* cached block number */
81 struct xfs_buf *bp; /* block buffer, result */
82 struct xfs_inode *ip; /* bitmap or summary inode */
83 struct xfs_bmbt_irec map;
84 enum xfs_blft type;
85 int nmap = 1;
86 int error;
87
88 if (issum) {
89 cbpp = &args->sumbp;
90 coffp = &args->sumoff;
91 ip = mp->m_rsumip;
92 type = XFS_BLFT_RTSUMMARY_BUF;
93 } else {
94 cbpp = &args->rbmbp;
95 coffp = &args->rbmoff;
96 ip = mp->m_rbmip;
97 type = XFS_BLFT_RTBITMAP_BUF;
98 }
99
100 /*
101 * If we have a cached buffer, and the block number matches, use that.
102 */
103 if (*cbpp && *coffp == block)
104 return 0;
105
106 /*
107 * Otherwise we have to have to get the buffer. If there was an old
108 * one, get rid of it first.
109 */
110 if (*cbpp) {
111 xfs_trans_brelse(args->tp, *cbpp);
112 *cbpp = NULL;
113 }
114
115 error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
116 if (error)
117 return error;
118
119 if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
120 xfs_rt_mark_sick(mp, mask: issum ? XFS_SICK_RT_SUMMARY :
121 XFS_SICK_RT_BITMAP);
122 return -EFSCORRUPTED;
123 }
124
125 ASSERT(map.br_startblock != NULLFSBLOCK);
126 error = xfs_trans_read_buf(mp, args->tp, mp->m_ddev_targp,
127 XFS_FSB_TO_DADDR(mp, map.br_startblock),
128 mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
129 if (xfs_metadata_is_sick(error))
130 xfs_rt_mark_sick(mp, mask: issum ? XFS_SICK_RT_SUMMARY :
131 XFS_SICK_RT_BITMAP);
132 if (error)
133 return error;
134
135 xfs_trans_buf_set_type(args->tp, bp, type);
136 *cbpp = bp;
137 *coffp = block;
138 return 0;
139}
140
141/*
142 * Searching backward from start to limit, find the first block whose
143 * allocated/free state is different from start's.
144 */
145int
146xfs_rtfind_back(
147 struct xfs_rtalloc_args *args,
148 xfs_rtxnum_t start, /* starting rtext to look at */
149 xfs_rtxnum_t limit, /* last rtext to look at */
150 xfs_rtxnum_t *rtx) /* out: start rtext found */
151{
152 struct xfs_mount *mp = args->mp;
153 int bit; /* bit number in the word */
154 xfs_fileoff_t block; /* bitmap block number */
155 int error; /* error value */
156 xfs_rtxnum_t firstbit; /* first useful bit in the word */
157 xfs_rtxnum_t i; /* current bit number rel. to start */
158 xfs_rtxnum_t len; /* length of inspected area */
159 xfs_rtword_t mask; /* mask of relevant bits for value */
160 xfs_rtword_t want; /* mask for "good" values */
161 xfs_rtword_t wdiff; /* difference from wanted value */
162 xfs_rtword_t incore;
163 unsigned int word; /* word number in the buffer */
164
165 /*
166 * Compute and read in starting bitmap block for starting block.
167 */
168 block = xfs_rtx_to_rbmblock(mp, start);
169 error = xfs_rtbitmap_read_buf(args, block);
170 if (error)
171 return error;
172
173 /*
174 * Get the first word's index & point to it.
175 */
176 word = xfs_rtx_to_rbmword(mp, start);
177 bit = (int)(start & (XFS_NBWORD - 1));
178 len = start - limit + 1;
179 /*
180 * Compute match value, based on the bit at start: if 1 (free)
181 * then all-ones, else all-zeroes.
182 */
183 incore = xfs_rtbitmap_getword(args, word);
184 want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
185 /*
186 * If the starting position is not word-aligned, deal with the
187 * partial word.
188 */
189 if (bit < XFS_NBWORD - 1) {
190 /*
191 * Calculate first (leftmost) bit number to look at,
192 * and mask for all the relevant bits in this word.
193 */
194 firstbit = max_t(xfs_srtblock_t, bit - len + 1, 0);
195 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
196 firstbit;
197 /*
198 * Calculate the difference between the value there
199 * and what we're looking for.
200 */
201 if ((wdiff = (incore ^ want) & mask)) {
202 /*
203 * Different. Mark where we are and return.
204 */
205 i = bit - xfs_highbit32(wdiff);
206 *rtx = start - i + 1;
207 return 0;
208 }
209 i = bit - firstbit + 1;
210 /*
211 * Go on to previous block if that's where the previous word is
212 * and we need the previous word.
213 */
214 if (--word == -1 && i < len) {
215 /*
216 * If done with this block, get the previous one.
217 */
218 error = xfs_rtbitmap_read_buf(args, --block);
219 if (error)
220 return error;
221
222 word = mp->m_blockwsize - 1;
223 }
224 } else {
225 /*
226 * Starting on a word boundary, no partial word.
227 */
228 i = 0;
229 }
230 /*
231 * Loop over whole words in buffers. When we use up one buffer
232 * we move on to the previous one.
233 */
234 while (len - i >= XFS_NBWORD) {
235 /*
236 * Compute difference between actual and desired value.
237 */
238 incore = xfs_rtbitmap_getword(args, word);
239 if ((wdiff = incore ^ want)) {
240 /*
241 * Different, mark where we are and return.
242 */
243 i += XFS_NBWORD - 1 - xfs_highbit32(wdiff);
244 *rtx = start - i + 1;
245 return 0;
246 }
247 i += XFS_NBWORD;
248 /*
249 * Go on to previous block if that's where the previous word is
250 * and we need the previous word.
251 */
252 if (--word == -1 && i < len) {
253 /*
254 * If done with this block, get the previous one.
255 */
256 error = xfs_rtbitmap_read_buf(args, --block);
257 if (error)
258 return error;
259
260 word = mp->m_blockwsize - 1;
261 }
262 }
263 /*
264 * If not ending on a word boundary, deal with the last
265 * (partial) word.
266 */
267 if (len - i) {
268 /*
269 * Calculate first (leftmost) bit number to look at,
270 * and mask for all the relevant bits in this word.
271 */
272 firstbit = XFS_NBWORD - (len - i);
273 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
274 /*
275 * Compute difference between actual and desired value.
276 */
277 incore = xfs_rtbitmap_getword(args, word);
278 if ((wdiff = (incore ^ want) & mask)) {
279 /*
280 * Different, mark where we are and return.
281 */
282 i += XFS_NBWORD - 1 - xfs_highbit32(wdiff);
283 *rtx = start - i + 1;
284 return 0;
285 } else
286 i = len;
287 }
288 /*
289 * No match, return that we scanned the whole area.
290 */
291 *rtx = start - i + 1;
292 return 0;
293}
294
295/*
296 * Searching forward from start to limit, find the first block whose
297 * allocated/free state is different from start's.
298 */
299int
300xfs_rtfind_forw(
301 struct xfs_rtalloc_args *args,
302 xfs_rtxnum_t start, /* starting rtext to look at */
303 xfs_rtxnum_t limit, /* last rtext to look at */
304 xfs_rtxnum_t *rtx) /* out: start rtext found */
305{
306 struct xfs_mount *mp = args->mp;
307 int bit; /* bit number in the word */
308 xfs_fileoff_t block; /* bitmap block number */
309 int error;
310 xfs_rtxnum_t i; /* current bit number rel. to start */
311 xfs_rtxnum_t lastbit;/* last useful bit in the word */
312 xfs_rtxnum_t len; /* length of inspected area */
313 xfs_rtword_t mask; /* mask of relevant bits for value */
314 xfs_rtword_t want; /* mask for "good" values */
315 xfs_rtword_t wdiff; /* difference from wanted value */
316 xfs_rtword_t incore;
317 unsigned int word; /* word number in the buffer */
318
319 /*
320 * Compute and read in starting bitmap block for starting block.
321 */
322 block = xfs_rtx_to_rbmblock(mp, start);
323 error = xfs_rtbitmap_read_buf(args, block);
324 if (error)
325 return error;
326
327 /*
328 * Get the first word's index & point to it.
329 */
330 word = xfs_rtx_to_rbmword(mp, start);
331 bit = (int)(start & (XFS_NBWORD - 1));
332 len = limit - start + 1;
333 /*
334 * Compute match value, based on the bit at start: if 1 (free)
335 * then all-ones, else all-zeroes.
336 */
337 incore = xfs_rtbitmap_getword(args, word);
338 want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
339 /*
340 * If the starting position is not word-aligned, deal with the
341 * partial word.
342 */
343 if (bit) {
344 /*
345 * Calculate last (rightmost) bit number to look at,
346 * and mask for all the relevant bits in this word.
347 */
348 lastbit = min(bit + len, XFS_NBWORD);
349 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
350 /*
351 * Calculate the difference between the value there
352 * and what we're looking for.
353 */
354 if ((wdiff = (incore ^ want) & mask)) {
355 /*
356 * Different. Mark where we are and return.
357 */
358 i = xfs_lowbit32(wdiff) - bit;
359 *rtx = start + i - 1;
360 return 0;
361 }
362 i = lastbit - bit;
363 /*
364 * Go on to next block if that's where the next word is
365 * and we need the next word.
366 */
367 if (++word == mp->m_blockwsize && i < len) {
368 /*
369 * If done with this block, get the previous one.
370 */
371 error = xfs_rtbitmap_read_buf(args, ++block);
372 if (error)
373 return error;
374
375 word = 0;
376 }
377 } else {
378 /*
379 * Starting on a word boundary, no partial word.
380 */
381 i = 0;
382 }
383 /*
384 * Loop over whole words in buffers. When we use up one buffer
385 * we move on to the next one.
386 */
387 while (len - i >= XFS_NBWORD) {
388 /*
389 * Compute difference between actual and desired value.
390 */
391 incore = xfs_rtbitmap_getword(args, word);
392 if ((wdiff = incore ^ want)) {
393 /*
394 * Different, mark where we are and return.
395 */
396 i += xfs_lowbit32(wdiff);
397 *rtx = start + i - 1;
398 return 0;
399 }
400 i += XFS_NBWORD;
401 /*
402 * Go on to next block if that's where the next word is
403 * and we need the next word.
404 */
405 if (++word == mp->m_blockwsize && i < len) {
406 /*
407 * If done with this block, get the next one.
408 */
409 error = xfs_rtbitmap_read_buf(args, ++block);
410 if (error)
411 return error;
412
413 word = 0;
414 }
415 }
416 /*
417 * If not ending on a word boundary, deal with the last
418 * (partial) word.
419 */
420 if ((lastbit = len - i)) {
421 /*
422 * Calculate mask for all the relevant bits in this word.
423 */
424 mask = ((xfs_rtword_t)1 << lastbit) - 1;
425 /*
426 * Compute difference between actual and desired value.
427 */
428 incore = xfs_rtbitmap_getword(args, word);
429 if ((wdiff = (incore ^ want) & mask)) {
430 /*
431 * Different, mark where we are and return.
432 */
433 i += xfs_lowbit32(wdiff);
434 *rtx = start + i - 1;
435 return 0;
436 } else
437 i = len;
438 }
439 /*
440 * No match, return that we scanned the whole area.
441 */
442 *rtx = start + i - 1;
443 return 0;
444}
445
446/* Log rtsummary counter at @infoword. */
447static inline void
448xfs_trans_log_rtsummary(
449 struct xfs_rtalloc_args *args,
450 unsigned int infoword)
451{
452 struct xfs_buf *bp = args->sumbp;
453 size_t first, last;
454
455 first = (void *)xfs_rsumblock_infoptr(args, infoword) - bp->b_addr;
456 last = first + sizeof(xfs_suminfo_t) - 1;
457
458 xfs_trans_log_buf(args->tp, bp, first, last);
459}
460
461/*
462 * Modify the summary information for a given extent size, bitmap block
463 * combination.
464 */
465int
466xfs_rtmodify_summary(
467 struct xfs_rtalloc_args *args,
468 int log, /* log2 of extent size */
469 xfs_fileoff_t bbno, /* bitmap block number */
470 int delta) /* in/out: summary block number */
471{
472 struct xfs_mount *mp = args->mp;
473 xfs_rtsumoff_t so = xfs_rtsumoffs(mp, log, bbno);
474 unsigned int infoword;
475 xfs_suminfo_t val;
476 int error;
477
478 error = xfs_rtsummary_read_buf(args, xfs_rtsumoffs_to_block(mp, so));
479 if (error)
480 return error;
481
482 infoword = xfs_rtsumoffs_to_infoword(mp, so);
483 val = xfs_suminfo_add(args, infoword, delta);
484
485 if (mp->m_rsum_cache) {
486 if (val == 0 && log + 1 == mp->m_rsum_cache[bbno])
487 mp->m_rsum_cache[bbno] = log;
488 if (val != 0 && log >= mp->m_rsum_cache[bbno])
489 mp->m_rsum_cache[bbno] = log + 1;
490 }
491
492 xfs_trans_log_rtsummary(args, infoword);
493 return 0;
494}
495
496/*
497 * Read and return the summary information for a given extent size, bitmap block
498 * combination.
499 */
500int
501xfs_rtget_summary(
502 struct xfs_rtalloc_args *args,
503 int log, /* log2 of extent size */
504 xfs_fileoff_t bbno, /* bitmap block number */
505 xfs_suminfo_t *sum) /* out: summary info for this block */
506{
507 struct xfs_mount *mp = args->mp;
508 xfs_rtsumoff_t so = xfs_rtsumoffs(mp, log, bbno);
509 int error;
510
511 error = xfs_rtsummary_read_buf(args, xfs_rtsumoffs_to_block(mp, so));
512 if (!error)
513 *sum = xfs_suminfo_get(args, xfs_rtsumoffs_to_infoword(mp, so));
514 return error;
515}
516
517/* Log rtbitmap block from the word @from to the byte before @next. */
518static inline void
519xfs_trans_log_rtbitmap(
520 struct xfs_rtalloc_args *args,
521 unsigned int from,
522 unsigned int next)
523{
524 struct xfs_buf *bp = args->rbmbp;
525 size_t first, last;
526
527 first = (void *)xfs_rbmblock_wordptr(args, from) - bp->b_addr;
528 last = ((void *)xfs_rbmblock_wordptr(args, next) - 1) - bp->b_addr;
529
530 xfs_trans_log_buf(args->tp, bp, first, last);
531}
532
533/*
534 * Set the given range of bitmap bits to the given value.
535 * Do whatever I/O and logging is required.
536 */
537int
538xfs_rtmodify_range(
539 struct xfs_rtalloc_args *args,
540 xfs_rtxnum_t start, /* starting rtext to modify */
541 xfs_rtxlen_t len, /* length of extent to modify */
542 int val) /* 1 for free, 0 for allocated */
543{
544 struct xfs_mount *mp = args->mp;
545 int bit; /* bit number in the word */
546 xfs_fileoff_t block; /* bitmap block number */
547 int error;
548 int i; /* current bit number rel. to start */
549 int lastbit; /* last useful bit in word */
550 xfs_rtword_t mask; /* mask of relevant bits for value */
551 xfs_rtword_t incore;
552 unsigned int firstword; /* first word used in the buffer */
553 unsigned int word; /* word number in the buffer */
554
555 /*
556 * Compute starting bitmap block number.
557 */
558 block = xfs_rtx_to_rbmblock(mp, start);
559 /*
560 * Read the bitmap block, and point to its data.
561 */
562 error = xfs_rtbitmap_read_buf(args, block);
563 if (error)
564 return error;
565
566 /*
567 * Compute the starting word's address, and starting bit.
568 */
569 firstword = word = xfs_rtx_to_rbmword(mp, start);
570 bit = (int)(start & (XFS_NBWORD - 1));
571 /*
572 * 0 (allocated) => all zeroes; 1 (free) => all ones.
573 */
574 val = -val;
575 /*
576 * If not starting on a word boundary, deal with the first
577 * (partial) word.
578 */
579 if (bit) {
580 /*
581 * Compute first bit not changed and mask of relevant bits.
582 */
583 lastbit = min(bit + len, XFS_NBWORD);
584 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
585 /*
586 * Set/clear the active bits.
587 */
588 incore = xfs_rtbitmap_getword(args, word);
589 if (val)
590 incore |= mask;
591 else
592 incore &= ~mask;
593 xfs_rtbitmap_setword(args, word, incore);
594 i = lastbit - bit;
595 /*
596 * Go on to the next block if that's where the next word is
597 * and we need the next word.
598 */
599 if (++word == mp->m_blockwsize && i < len) {
600 /*
601 * Log the changed part of this block.
602 * Get the next one.
603 */
604 xfs_trans_log_rtbitmap(args, from: firstword, next: word);
605 error = xfs_rtbitmap_read_buf(args, ++block);
606 if (error)
607 return error;
608
609 firstword = word = 0;
610 }
611 } else {
612 /*
613 * Starting on a word boundary, no partial word.
614 */
615 i = 0;
616 }
617 /*
618 * Loop over whole words in buffers. When we use up one buffer
619 * we move on to the next one.
620 */
621 while (len - i >= XFS_NBWORD) {
622 /*
623 * Set the word value correctly.
624 */
625 xfs_rtbitmap_setword(args, word, val);
626 i += XFS_NBWORD;
627 /*
628 * Go on to the next block if that's where the next word is
629 * and we need the next word.
630 */
631 if (++word == mp->m_blockwsize && i < len) {
632 /*
633 * Log the changed part of this block.
634 * Get the next one.
635 */
636 xfs_trans_log_rtbitmap(args, from: firstword, next: word);
637 error = xfs_rtbitmap_read_buf(args, ++block);
638 if (error)
639 return error;
640
641 firstword = word = 0;
642 }
643 }
644 /*
645 * If not ending on a word boundary, deal with the last
646 * (partial) word.
647 */
648 if ((lastbit = len - i)) {
649 /*
650 * Compute a mask of relevant bits.
651 */
652 mask = ((xfs_rtword_t)1 << lastbit) - 1;
653 /*
654 * Set/clear the active bits.
655 */
656 incore = xfs_rtbitmap_getword(args, word);
657 if (val)
658 incore |= mask;
659 else
660 incore &= ~mask;
661 xfs_rtbitmap_setword(args, word, incore);
662 word++;
663 }
664 /*
665 * Log any remaining changed bytes.
666 */
667 if (word > firstword)
668 xfs_trans_log_rtbitmap(args, from: firstword, next: word);
669 return 0;
670}
671
672/*
673 * Mark an extent specified by start and len freed.
674 * Updates all the summary information as well as the bitmap.
675 */
676int
677xfs_rtfree_range(
678 struct xfs_rtalloc_args *args,
679 xfs_rtxnum_t start, /* starting rtext to free */
680 xfs_rtxlen_t len) /* in/out: summary block number */
681{
682 struct xfs_mount *mp = args->mp;
683 xfs_rtxnum_t end; /* end of the freed extent */
684 int error; /* error value */
685 xfs_rtxnum_t postblock; /* first rtext freed > end */
686 xfs_rtxnum_t preblock; /* first rtext freed < start */
687
688 end = start + len - 1;
689 /*
690 * Modify the bitmap to mark this extent freed.
691 */
692 error = xfs_rtmodify_range(args, start, len, 1);
693 if (error) {
694 return error;
695 }
696 /*
697 * Assume we're freeing out of the middle of an allocated extent.
698 * We need to find the beginning and end of the extent so we can
699 * properly update the summary.
700 */
701 error = xfs_rtfind_back(args, start, 0, &preblock);
702 if (error) {
703 return error;
704 }
705 /*
706 * Find the next allocated block (end of allocated extent).
707 */
708 error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1,
709 &postblock);
710 if (error)
711 return error;
712 /*
713 * If there are blocks not being freed at the front of the
714 * old extent, add summary data for them to be allocated.
715 */
716 if (preblock < start) {
717 error = xfs_rtmodify_summary(args,
718 xfs_highbit64(start - preblock),
719 xfs_rtx_to_rbmblock(mp, preblock), -1);
720 if (error) {
721 return error;
722 }
723 }
724 /*
725 * If there are blocks not being freed at the end of the
726 * old extent, add summary data for them to be allocated.
727 */
728 if (postblock > end) {
729 error = xfs_rtmodify_summary(args,
730 xfs_highbit64(postblock - end),
731 xfs_rtx_to_rbmblock(mp, end + 1), -1);
732 if (error) {
733 return error;
734 }
735 }
736 /*
737 * Increment the summary information corresponding to the entire
738 * (new) free extent.
739 */
740 return xfs_rtmodify_summary(args,
741 xfs_highbit64(postblock + 1 - preblock),
742 xfs_rtx_to_rbmblock(mp, preblock), 1);
743}
744
745/*
746 * Check that the given range is either all allocated (val = 0) or
747 * all free (val = 1).
748 */
749int
750xfs_rtcheck_range(
751 struct xfs_rtalloc_args *args,
752 xfs_rtxnum_t start, /* starting rtext number of extent */
753 xfs_rtxlen_t len, /* length of extent */
754 int val, /* 1 for free, 0 for allocated */
755 xfs_rtxnum_t *new, /* out: first rtext not matching */
756 int *stat) /* out: 1 for matches, 0 for not */
757{
758 struct xfs_mount *mp = args->mp;
759 int bit; /* bit number in the word */
760 xfs_fileoff_t block; /* bitmap block number */
761 int error;
762 xfs_rtxnum_t i; /* current bit number rel. to start */
763 xfs_rtxnum_t lastbit; /* last useful bit in word */
764 xfs_rtword_t mask; /* mask of relevant bits for value */
765 xfs_rtword_t wdiff; /* difference from wanted value */
766 xfs_rtword_t incore;
767 unsigned int word; /* word number in the buffer */
768
769 /*
770 * Compute starting bitmap block number
771 */
772 block = xfs_rtx_to_rbmblock(mp, start);
773 /*
774 * Read the bitmap block.
775 */
776 error = xfs_rtbitmap_read_buf(args, block);
777 if (error)
778 return error;
779
780 /*
781 * Compute the starting word's address, and starting bit.
782 */
783 word = xfs_rtx_to_rbmword(mp, start);
784 bit = (int)(start & (XFS_NBWORD - 1));
785 /*
786 * 0 (allocated) => all zero's; 1 (free) => all one's.
787 */
788 val = -val;
789 /*
790 * If not starting on a word boundary, deal with the first
791 * (partial) word.
792 */
793 if (bit) {
794 /*
795 * Compute first bit not examined.
796 */
797 lastbit = min(bit + len, XFS_NBWORD);
798 /*
799 * Mask of relevant bits.
800 */
801 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
802 /*
803 * Compute difference between actual and desired value.
804 */
805 incore = xfs_rtbitmap_getword(args, word);
806 if ((wdiff = (incore ^ val) & mask)) {
807 /*
808 * Different, compute first wrong bit and return.
809 */
810 i = xfs_lowbit32(wdiff) - bit;
811 *new = start + i;
812 *stat = 0;
813 return 0;
814 }
815 i = lastbit - bit;
816 /*
817 * Go on to next block if that's where the next word is
818 * and we need the next word.
819 */
820 if (++word == mp->m_blockwsize && i < len) {
821 /*
822 * If done with this block, get the next one.
823 */
824 error = xfs_rtbitmap_read_buf(args, ++block);
825 if (error)
826 return error;
827
828 word = 0;
829 }
830 } else {
831 /*
832 * Starting on a word boundary, no partial word.
833 */
834 i = 0;
835 }
836 /*
837 * Loop over whole words in buffers. When we use up one buffer
838 * we move on to the next one.
839 */
840 while (len - i >= XFS_NBWORD) {
841 /*
842 * Compute difference between actual and desired value.
843 */
844 incore = xfs_rtbitmap_getword(args, word);
845 if ((wdiff = incore ^ val)) {
846 /*
847 * Different, compute first wrong bit and return.
848 */
849 i += xfs_lowbit32(wdiff);
850 *new = start + i;
851 *stat = 0;
852 return 0;
853 }
854 i += XFS_NBWORD;
855 /*
856 * Go on to next block if that's where the next word is
857 * and we need the next word.
858 */
859 if (++word == mp->m_blockwsize && i < len) {
860 /*
861 * If done with this block, get the next one.
862 */
863 error = xfs_rtbitmap_read_buf(args, ++block);
864 if (error)
865 return error;
866
867 word = 0;
868 }
869 }
870 /*
871 * If not ending on a word boundary, deal with the last
872 * (partial) word.
873 */
874 if ((lastbit = len - i)) {
875 /*
876 * Mask of relevant bits.
877 */
878 mask = ((xfs_rtword_t)1 << lastbit) - 1;
879 /*
880 * Compute difference between actual and desired value.
881 */
882 incore = xfs_rtbitmap_getword(args, word);
883 if ((wdiff = (incore ^ val) & mask)) {
884 /*
885 * Different, compute first wrong bit and return.
886 */
887 i += xfs_lowbit32(wdiff);
888 *new = start + i;
889 *stat = 0;
890 return 0;
891 } else
892 i = len;
893 }
894 /*
895 * Successful, return.
896 */
897 *new = start + i;
898 *stat = 1;
899 return 0;
900}
901
902#ifdef DEBUG
903/*
904 * Check that the given extent (block range) is allocated already.
905 */
906STATIC int
907xfs_rtcheck_alloc_range(
908 struct xfs_rtalloc_args *args,
909 xfs_rtxnum_t start, /* starting rtext number of extent */
910 xfs_rtxlen_t len) /* length of extent */
911{
912 xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */
913 int stat;
914 int error;
915
916 error = xfs_rtcheck_range(args, start, len, 0, &new, &stat);
917 if (error)
918 return error;
919 ASSERT(stat);
920 return 0;
921}
922#else
923#define xfs_rtcheck_alloc_range(a,b,l) (0)
924#endif
925/*
926 * Free an extent in the realtime subvolume. Length is expressed in
927 * realtime extents, as is the block number.
928 */
929int
930xfs_rtfree_extent(
931 struct xfs_trans *tp, /* transaction pointer */
932 xfs_rtxnum_t start, /* starting rtext number to free */
933 xfs_rtxlen_t len) /* length of extent freed */
934{
935 struct xfs_mount *mp = tp->t_mountp;
936 struct xfs_rtalloc_args args = {
937 .mp = mp,
938 .tp = tp,
939 };
940 int error;
941 struct timespec64 atime;
942
943 ASSERT(mp->m_rbmip->i_itemp != NULL);
944 xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL);
945
946 error = xfs_rtcheck_alloc_range(&args, start, len);
947 if (error)
948 return error;
949
950 /*
951 * Free the range of realtime blocks.
952 */
953 error = xfs_rtfree_range(&args, start, len);
954 if (error)
955 goto out;
956
957 /*
958 * Mark more blocks free in the superblock.
959 */
960 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
961 /*
962 * If we've now freed all the blocks, reset the file sequence
963 * number to 0.
964 */
965 if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
966 mp->m_sb.sb_rextents) {
967 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
968 mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
969
970 atime = inode_get_atime(VFS_I(mp->m_rbmip));
971 atime.tv_sec = 0;
972 inode_set_atime_to_ts(VFS_I(mp->m_rbmip), atime);
973 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
974 }
975 error = 0;
976out:
977 xfs_rtbuf_cache_relse(args: &args);
978 return error;
979}
980
981/*
982 * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
983 * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
984 * cannot exceed XFS_MAX_BMBT_EXTLEN.
985 */
986int
987xfs_rtfree_blocks(
988 struct xfs_trans *tp,
989 xfs_fsblock_t rtbno,
990 xfs_filblks_t rtlen)
991{
992 struct xfs_mount *mp = tp->t_mountp;
993 xfs_rtxnum_t start;
994 xfs_filblks_t len;
995 xfs_extlen_t mod;
996
997 ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
998
999 len = xfs_rtb_to_rtxrem(mp, rtlen, &mod);
1000 if (mod) {
1001 ASSERT(mod == 0);
1002 return -EIO;
1003 }
1004
1005 start = xfs_rtb_to_rtxrem(mp, rtbno, &mod);
1006 if (mod) {
1007 ASSERT(mod == 0);
1008 return -EIO;
1009 }
1010
1011 return xfs_rtfree_extent(tp, start, len);
1012}
1013
1014/* Find all the free records within a given range. */
1015int
1016xfs_rtalloc_query_range(
1017 struct xfs_mount *mp,
1018 struct xfs_trans *tp,
1019 const struct xfs_rtalloc_rec *low_rec,
1020 const struct xfs_rtalloc_rec *high_rec,
1021 xfs_rtalloc_query_range_fn fn,
1022 void *priv)
1023{
1024 struct xfs_rtalloc_args args = {
1025 .mp = mp,
1026 .tp = tp,
1027 };
1028 struct xfs_rtalloc_rec rec;
1029 xfs_rtxnum_t rtstart;
1030 xfs_rtxnum_t rtend;
1031 xfs_rtxnum_t high_key;
1032 int is_free;
1033 int error = 0;
1034
1035 if (low_rec->ar_startext > high_rec->ar_startext)
1036 return -EINVAL;
1037 if (low_rec->ar_startext >= mp->m_sb.sb_rextents ||
1038 low_rec->ar_startext == high_rec->ar_startext)
1039 return 0;
1040
1041 high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1);
1042
1043 /* Iterate the bitmap, looking for discrepancies. */
1044 rtstart = low_rec->ar_startext;
1045 while (rtstart <= high_key) {
1046 /* Is the first block free? */
1047 error = xfs_rtcheck_range(&args, rtstart, 1, 1, &rtend,
1048 &is_free);
1049 if (error)
1050 break;
1051
1052 /* How long does the extent go for? */
1053 error = xfs_rtfind_forw(&args, rtstart, high_key, &rtend);
1054 if (error)
1055 break;
1056
1057 if (is_free) {
1058 rec.ar_startext = rtstart;
1059 rec.ar_extcount = rtend - rtstart + 1;
1060
1061 error = fn(mp, tp, &rec, priv);
1062 if (error)
1063 break;
1064 }
1065
1066 rtstart = rtend + 1;
1067 }
1068
1069 xfs_rtbuf_cache_relse(args: &args);
1070 return error;
1071}
1072
1073/* Find all the free records. */
1074int
1075xfs_rtalloc_query_all(
1076 struct xfs_mount *mp,
1077 struct xfs_trans *tp,
1078 xfs_rtalloc_query_range_fn fn,
1079 void *priv)
1080{
1081 struct xfs_rtalloc_rec keys[2];
1082
1083 keys[0].ar_startext = 0;
1084 keys[1].ar_startext = mp->m_sb.sb_rextents - 1;
1085 keys[0].ar_extcount = keys[1].ar_extcount = 0;
1086
1087 return xfs_rtalloc_query_range(mp, tp, low_rec: &keys[0], high_rec: &keys[1], fn, priv);
1088}
1089
1090/* Is the given extent all free? */
1091int
1092xfs_rtalloc_extent_is_free(
1093 struct xfs_mount *mp,
1094 struct xfs_trans *tp,
1095 xfs_rtxnum_t start,
1096 xfs_rtxlen_t len,
1097 bool *is_free)
1098{
1099 struct xfs_rtalloc_args args = {
1100 .mp = mp,
1101 .tp = tp,
1102 };
1103 xfs_rtxnum_t end;
1104 int matches;
1105 int error;
1106
1107 error = xfs_rtcheck_range(&args, start, len, 1, &end, &matches);
1108 xfs_rtbuf_cache_relse(args: &args);
1109 if (error)
1110 return error;
1111
1112 *is_free = matches;
1113 return 0;
1114}
1115
1116/*
1117 * Compute the number of rtbitmap blocks needed to track the given number of rt
1118 * extents.
1119 */
1120xfs_filblks_t
1121xfs_rtbitmap_blockcount(
1122 struct xfs_mount *mp,
1123 xfs_rtbxlen_t rtextents)
1124{
1125 return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize);
1126}
1127
1128/*
1129 * Compute the number of rtbitmap words needed to populate every block of a
1130 * bitmap that is large enough to track the given number of rt extents.
1131 */
1132unsigned long long
1133xfs_rtbitmap_wordcount(
1134 struct xfs_mount *mp,
1135 xfs_rtbxlen_t rtextents)
1136{
1137 xfs_filblks_t blocks;
1138
1139 blocks = xfs_rtbitmap_blockcount(mp, rtextents);
1140 return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
1141}
1142
1143/* Compute the number of rtsummary blocks needed to track the given rt space. */
1144xfs_filblks_t
1145xfs_rtsummary_blockcount(
1146 struct xfs_mount *mp,
1147 unsigned int rsumlevels,
1148 xfs_extlen_t rbmblocks)
1149{
1150 unsigned long long rsumwords;
1151
1152 rsumwords = (unsigned long long)rsumlevels * rbmblocks;
1153 return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
1154}
1155
1156/*
1157 * Compute the number of rtsummary info words needed to populate every block of
1158 * a summary file that is large enough to track the given rt space.
1159 */
1160unsigned long long
1161xfs_rtsummary_wordcount(
1162 struct xfs_mount *mp,
1163 unsigned int rsumlevels,
1164 xfs_extlen_t rbmblocks)
1165{
1166 xfs_filblks_t blocks;
1167
1168 blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks);
1169 return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
1170}
1171

source code of linux/fs/xfs/libxfs/xfs_rtbitmap.c