1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
6 #include "libxfs_priv.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_inode.h"
16 #include "xfs_trans.h"
17 #include "xfs_rtbitmap.h"
20 * Realtime allocator bitmap functions shared with userspace.
24 * Real time buffers need verifiers to avoid runtime warnings during IO.
25 * We don't have anything to verify, however, so these are just dummy
29 xfs_rtbuf_verify_read(
36 xfs_rtbuf_verify_write(
42 const struct xfs_buf_ops xfs_rtbuf_ops
= {
44 .verify_read
= xfs_rtbuf_verify_read
,
45 .verify_write
= xfs_rtbuf_verify_write
,
49 * Get a buffer for the bitmap or summary file block specified.
50 * The buffer is returned read and locked.
54 xfs_mount_t
*mp
, /* file system mount structure */
55 xfs_trans_t
*tp
, /* transaction pointer */
56 xfs_fileoff_t block
, /* block number in bitmap or summary */
57 int issum
, /* is summary not bitmap */
58 struct xfs_buf
**bpp
) /* output: buffer for the block */
60 struct xfs_buf
*bp
; /* block buffer, result */
61 xfs_inode_t
*ip
; /* bitmap or summary inode */
64 int error
; /* error value */
66 ip
= issum
? mp
->m_rsumip
: mp
->m_rbmip
;
68 error
= xfs_bmapi_read(ip
, block
, 1, &map
, &nmap
, 0);
72 if (XFS_IS_CORRUPT(mp
, nmap
== 0 || !xfs_bmap_is_written_extent(&map
)))
75 ASSERT(map
.br_startblock
!= NULLFSBLOCK
);
76 error
= xfs_trans_read_buf(mp
, tp
, mp
->m_ddev_targp
,
77 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
78 mp
->m_bsize
, 0, &bp
, &xfs_rtbuf_ops
);
82 xfs_trans_buf_set_type(tp
, bp
, issum
? XFS_BLFT_RTSUMMARY_BUF
83 : XFS_BLFT_RTBITMAP_BUF
);
89 * Searching backward from start to limit, find the first block whose
90 * allocated/free state is different from start's.
94 xfs_mount_t
*mp
, /* file system mount point */
95 xfs_trans_t
*tp
, /* transaction pointer */
96 xfs_rtxnum_t start
, /* starting rtext to look at */
97 xfs_rtxnum_t limit
, /* last rtext to look at */
98 xfs_rtxnum_t
*rtx
) /* out: start rtext found */
100 int bit
; /* bit number in the word */
101 xfs_fileoff_t block
; /* bitmap block number */
102 struct xfs_buf
*bp
; /* buf for the block */
103 int error
; /* error value */
104 xfs_rtxnum_t firstbit
; /* first useful bit in the word */
105 xfs_rtxnum_t i
; /* current bit number rel. to start */
106 xfs_rtxnum_t len
; /* length of inspected area */
107 xfs_rtword_t mask
; /* mask of relevant bits for value */
108 xfs_rtword_t want
; /* mask for "good" values */
109 xfs_rtword_t wdiff
; /* difference from wanted value */
111 unsigned int word
; /* word number in the buffer */
114 * Compute and read in starting bitmap block for starting block.
116 block
= xfs_rtx_to_rbmblock(mp
, start
);
117 error
= xfs_rtbuf_get(mp
, tp
, block
, 0, &bp
);
123 * Get the first word's index & point to it.
125 word
= xfs_rtx_to_rbmword(mp
, start
);
126 bit
= (int)(start
& (XFS_NBWORD
- 1));
127 len
= start
- limit
+ 1;
129 * Compute match value, based on the bit at start: if 1 (free)
130 * then all-ones, else all-zeroes.
132 incore
= xfs_rtbitmap_getword(bp
, word
);
133 want
= (incore
& ((xfs_rtword_t
)1 << bit
)) ? -1 : 0;
135 * If the starting position is not word-aligned, deal with the
138 if (bit
< XFS_NBWORD
- 1) {
140 * Calculate first (leftmost) bit number to look at,
141 * and mask for all the relevant bits in this word.
143 firstbit
= XFS_RTMAX((xfs_srtblock_t
)(bit
- len
+ 1), 0);
144 mask
= (((xfs_rtword_t
)1 << (bit
- firstbit
+ 1)) - 1) <<
147 * Calculate the difference between the value there
148 * and what we're looking for.
150 if ((wdiff
= (incore
^ want
) & mask
)) {
152 * Different. Mark where we are and return.
154 xfs_trans_brelse(tp
, bp
);
155 i
= bit
- XFS_RTHIBIT(wdiff
);
156 *rtx
= start
- i
+ 1;
159 i
= bit
- firstbit
+ 1;
161 * Go on to previous block if that's where the previous word is
162 * and we need the previous word.
164 if (--word
== -1 && i
< len
) {
166 * If done with this block, get the previous one.
168 xfs_trans_brelse(tp
, bp
);
169 error
= xfs_rtbuf_get(mp
, tp
, --block
, 0, &bp
);
174 word
= mp
->m_blockwsize
- 1;
178 * Starting on a word boundary, no partial word.
183 * Loop over whole words in buffers. When we use up one buffer
184 * we move on to the previous one.
186 while (len
- i
>= XFS_NBWORD
) {
188 * Compute difference between actual and desired value.
190 incore
= xfs_rtbitmap_getword(bp
, word
);
191 if ((wdiff
= incore
^ want
)) {
193 * Different, mark where we are and return.
195 xfs_trans_brelse(tp
, bp
);
196 i
+= XFS_NBWORD
- 1 - XFS_RTHIBIT(wdiff
);
197 *rtx
= start
- i
+ 1;
202 * Go on to previous block if that's where the previous word is
203 * and we need the previous word.
205 if (--word
== -1 && i
< len
) {
207 * If done with this block, get the previous one.
209 xfs_trans_brelse(tp
, bp
);
210 error
= xfs_rtbuf_get(mp
, tp
, --block
, 0, &bp
);
215 word
= mp
->m_blockwsize
- 1;
219 * If not ending on a word boundary, deal with the last
224 * Calculate first (leftmost) bit number to look at,
225 * and mask for all the relevant bits in this word.
227 firstbit
= XFS_NBWORD
- (len
- i
);
228 mask
= (((xfs_rtword_t
)1 << (len
- i
)) - 1) << firstbit
;
230 * Compute difference between actual and desired value.
232 incore
= xfs_rtbitmap_getword(bp
, word
);
233 if ((wdiff
= (incore
^ want
) & mask
)) {
235 * Different, mark where we are and return.
237 xfs_trans_brelse(tp
, bp
);
238 i
+= XFS_NBWORD
- 1 - XFS_RTHIBIT(wdiff
);
239 *rtx
= start
- i
+ 1;
245 * No match, return that we scanned the whole area.
247 xfs_trans_brelse(tp
, bp
);
248 *rtx
= start
- i
+ 1;
253 * Searching forward from start to limit, find the first block whose
254 * allocated/free state is different from start's.
258 xfs_mount_t
*mp
, /* file system mount point */
259 xfs_trans_t
*tp
, /* transaction pointer */
260 xfs_rtxnum_t start
, /* starting rtext to look at */
261 xfs_rtxnum_t limit
, /* last rtext to look at */
262 xfs_rtxnum_t
*rtx
) /* out: start rtext found */
264 int bit
; /* bit number in the word */
265 xfs_fileoff_t block
; /* bitmap block number */
266 struct xfs_buf
*bp
; /* buf for the block */
267 int error
; /* error value */
268 xfs_rtxnum_t i
; /* current bit number rel. to start */
269 xfs_rtxnum_t lastbit
; /* last useful bit in the word */
270 xfs_rtxnum_t len
; /* length of inspected area */
271 xfs_rtword_t mask
; /* mask of relevant bits for value */
272 xfs_rtword_t want
; /* mask for "good" values */
273 xfs_rtword_t wdiff
; /* difference from wanted value */
275 unsigned int word
; /* word number in the buffer */
278 * Compute and read in starting bitmap block for starting block.
280 block
= xfs_rtx_to_rbmblock(mp
, start
);
281 error
= xfs_rtbuf_get(mp
, tp
, block
, 0, &bp
);
287 * Get the first word's index & point to it.
289 word
= xfs_rtx_to_rbmword(mp
, start
);
290 bit
= (int)(start
& (XFS_NBWORD
- 1));
291 len
= limit
- start
+ 1;
293 * Compute match value, based on the bit at start: if 1 (free)
294 * then all-ones, else all-zeroes.
296 incore
= xfs_rtbitmap_getword(bp
, word
);
297 want
= (incore
& ((xfs_rtword_t
)1 << bit
)) ? -1 : 0;
299 * If the starting position is not word-aligned, deal with the
304 * Calculate last (rightmost) bit number to look at,
305 * and mask for all the relevant bits in this word.
307 lastbit
= XFS_RTMIN(bit
+ len
, XFS_NBWORD
);
308 mask
= (((xfs_rtword_t
)1 << (lastbit
- bit
)) - 1) << bit
;
310 * Calculate the difference between the value there
311 * and what we're looking for.
313 if ((wdiff
= (incore
^ want
) & mask
)) {
315 * Different. Mark where we are and return.
317 xfs_trans_brelse(tp
, bp
);
318 i
= XFS_RTLOBIT(wdiff
) - bit
;
319 *rtx
= start
+ i
- 1;
324 * Go on to next block if that's where the next word is
325 * and we need the next word.
327 if (++word
== mp
->m_blockwsize
&& i
< len
) {
329 * If done with this block, get the previous one.
331 xfs_trans_brelse(tp
, bp
);
332 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
341 * Starting on a word boundary, no partial word.
346 * Loop over whole words in buffers. When we use up one buffer
347 * we move on to the next one.
349 while (len
- i
>= XFS_NBWORD
) {
351 * Compute difference between actual and desired value.
353 incore
= xfs_rtbitmap_getword(bp
, word
);
354 if ((wdiff
= incore
^ want
)) {
356 * Different, mark where we are and return.
358 xfs_trans_brelse(tp
, bp
);
359 i
+= XFS_RTLOBIT(wdiff
);
360 *rtx
= start
+ i
- 1;
365 * Go on to next block if that's where the next word is
366 * and we need the next word.
368 if (++word
== mp
->m_blockwsize
&& i
< len
) {
370 * If done with this block, get the next one.
372 xfs_trans_brelse(tp
, bp
);
373 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
382 * If not ending on a word boundary, deal with the last
385 if ((lastbit
= len
- i
)) {
387 * Calculate mask for all the relevant bits in this word.
389 mask
= ((xfs_rtword_t
)1 << lastbit
) - 1;
391 * Compute difference between actual and desired value.
393 incore
= xfs_rtbitmap_getword(bp
, word
);
394 if ((wdiff
= (incore
^ want
) & mask
)) {
396 * Different, mark where we are and return.
398 xfs_trans_brelse(tp
, bp
);
399 i
+= XFS_RTLOBIT(wdiff
);
400 *rtx
= start
+ i
- 1;
406 * No match, return that we scanned the whole area.
408 xfs_trans_brelse(tp
, bp
);
409 *rtx
= start
+ i
- 1;
413 /* Log rtsummary counter at @infoword. */
415 xfs_trans_log_rtsummary(
416 struct xfs_trans
*tp
,
418 unsigned int infoword
)
422 first
= (void *)xfs_rsumblock_infoptr(bp
, infoword
) - bp
->b_addr
;
423 last
= first
+ sizeof(xfs_suminfo_t
) - 1;
425 xfs_trans_log_buf(tp
, bp
, first
, last
);
429 * Read and/or modify the summary information for a given extent size,
430 * bitmap block combination.
431 * Keeps track of a current summary block, so we don't keep reading
432 * it from the buffer cache.
434 * Summary information is returned in *sum if specified.
435 * If no delta is specified, returns summary only.
438 xfs_rtmodify_summary_int(
439 xfs_mount_t
*mp
, /* file system mount structure */
440 xfs_trans_t
*tp
, /* transaction pointer */
441 int log
, /* log2 of extent size */
442 xfs_fileoff_t bbno
, /* bitmap block number */
443 int delta
, /* change to make to summary info */
444 struct xfs_buf
**rbpp
, /* in/out: summary block buffer */
445 xfs_fileoff_t
*rsb
, /* in/out: summary block number */
446 xfs_suminfo_t
*sum
) /* out: summary info for this block */
448 struct xfs_buf
*bp
; /* buffer for the summary block */
449 int error
; /* error value */
450 xfs_fileoff_t sb
; /* summary fsblock */
451 xfs_rtsumoff_t so
; /* index into the summary file */
452 unsigned int infoword
;
455 * Compute entry number in the summary file.
457 so
= xfs_rtsumoffs(mp
, log
, bbno
);
459 * Compute the block number in the summary file.
461 sb
= xfs_rtsumoffs_to_block(mp
, so
);
463 * If we have an old buffer, and the block number matches, use that.
465 if (*rbpp
&& *rsb
== sb
)
468 * Otherwise we have to get the buffer.
472 * If there was an old one, get rid of it first.
475 xfs_trans_brelse(tp
, *rbpp
);
476 error
= xfs_rtbuf_get(mp
, tp
, sb
, 1, &bp
);
481 * Remember this buffer and block for the next call.
487 * Point to the summary information, modify/log it, and/or copy it out.
489 infoword
= xfs_rtsumoffs_to_infoword(mp
, so
);
491 xfs_suminfo_t val
= xfs_suminfo_add(bp
, infoword
, delta
);
493 if (mp
->m_rsum_cache
) {
494 if (val
== 0 && log
== mp
->m_rsum_cache
[bbno
])
495 mp
->m_rsum_cache
[bbno
]++;
496 if (val
!= 0 && log
< mp
->m_rsum_cache
[bbno
])
497 mp
->m_rsum_cache
[bbno
] = log
;
499 xfs_trans_log_rtsummary(tp
, bp
, infoword
);
503 *sum
= xfs_suminfo_get(bp
, infoword
);
509 xfs_rtmodify_summary(
510 xfs_mount_t
*mp
, /* file system mount structure */
511 xfs_trans_t
*tp
, /* transaction pointer */
512 int log
, /* log2 of extent size */
513 xfs_fileoff_t bbno
, /* bitmap block number */
514 int delta
, /* change to make to summary info */
515 struct xfs_buf
**rbpp
, /* in/out: summary block buffer */
516 xfs_fileoff_t
*rsb
) /* in/out: summary block number */
518 return xfs_rtmodify_summary_int(mp
, tp
, log
, bbno
,
519 delta
, rbpp
, rsb
, NULL
);
522 /* Log rtbitmap block from the word @from to the byte before @next. */
524 xfs_trans_log_rtbitmap(
525 struct xfs_trans
*tp
,
532 first
= (void *)xfs_rbmblock_wordptr(bp
, from
) - bp
->b_addr
;
533 last
= ((void *)xfs_rbmblock_wordptr(bp
, next
) - 1) - bp
->b_addr
;
535 xfs_trans_log_buf(tp
, bp
, first
, last
);
539 * Set the given range of bitmap bits to the given value.
540 * Do whatever I/O and logging is required.
544 xfs_mount_t
*mp
, /* file system mount point */
545 xfs_trans_t
*tp
, /* transaction pointer */
546 xfs_rtxnum_t start
, /* starting rtext to modify */
547 xfs_rtxlen_t len
, /* length of extent to modify */
548 int val
) /* 1 for free, 0 for allocated */
550 int bit
; /* bit number in the word */
551 xfs_fileoff_t block
; /* bitmap block number */
552 struct xfs_buf
*bp
; /* buf for the block */
553 int error
; /* error value */
554 int i
; /* current bit number rel. to start */
555 int lastbit
; /* last useful bit in word */
556 xfs_rtword_t mask
; /* mask o frelevant bits for value */
558 unsigned int firstword
; /* first word used in the buffer */
559 unsigned int word
; /* word number in the buffer */
562 * Compute starting bitmap block number.
564 block
= xfs_rtx_to_rbmblock(mp
, start
);
566 * Read the bitmap block, and point to its data.
568 error
= xfs_rtbuf_get(mp
, tp
, block
, 0, &bp
);
574 * Compute the starting word's address, and starting bit.
576 firstword
= word
= xfs_rtx_to_rbmword(mp
, start
);
577 bit
= (int)(start
& (XFS_NBWORD
- 1));
579 * 0 (allocated) => all zeroes; 1 (free) => all ones.
583 * If not starting on a word boundary, deal with the first
588 * Compute first bit not changed and mask of relevant bits.
590 lastbit
= XFS_RTMIN(bit
+ len
, XFS_NBWORD
);
591 mask
= (((xfs_rtword_t
)1 << (lastbit
- bit
)) - 1) << bit
;
593 * Set/clear the active bits.
595 incore
= xfs_rtbitmap_getword(bp
, word
);
600 xfs_rtbitmap_setword(bp
, word
, incore
);
603 * Go on to the next block if that's where the next word is
604 * and we need the next word.
606 if (++word
== mp
->m_blockwsize
&& i
< len
) {
608 * Log the changed part of this block.
611 xfs_trans_log_rtbitmap(tp
, bp
, firstword
, word
);
612 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
617 firstword
= word
= 0;
621 * Starting on a word boundary, no partial word.
626 * Loop over whole words in buffers. When we use up one buffer
627 * we move on to the next one.
629 while (len
- i
>= XFS_NBWORD
) {
631 * Set the word value correctly.
633 xfs_rtbitmap_setword(bp
, word
, val
);
636 * Go on to the next block if that's where the next word is
637 * and we need the next word.
639 if (++word
== mp
->m_blockwsize
&& i
< len
) {
641 * Log the changed part of this block.
644 xfs_trans_log_rtbitmap(tp
, bp
, firstword
, word
);
645 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
650 firstword
= word
= 0;
654 * If not ending on a word boundary, deal with the last
657 if ((lastbit
= len
- i
)) {
659 * Compute a mask of relevant bits.
661 mask
= ((xfs_rtword_t
)1 << lastbit
) - 1;
663 * Set/clear the active bits.
665 incore
= xfs_rtbitmap_getword(bp
, word
);
670 xfs_rtbitmap_setword(bp
, word
, incore
);
674 * Log any remaining changed bytes.
676 if (word
> firstword
)
677 xfs_trans_log_rtbitmap(tp
, bp
, firstword
, word
);
682 * Mark an extent specified by start and len freed.
683 * Updates all the summary information as well as the bitmap.
687 xfs_mount_t
*mp
, /* file system mount point */
688 xfs_trans_t
*tp
, /* transaction pointer */
689 xfs_rtxnum_t start
, /* starting rtext to free */
690 xfs_rtxlen_t len
, /* length to free */
691 struct xfs_buf
**rbpp
, /* in/out: summary block buffer */
692 xfs_fileoff_t
*rsb
) /* in/out: summary block number */
694 xfs_rtxnum_t end
; /* end of the freed extent */
695 int error
; /* error value */
696 xfs_rtxnum_t postblock
; /* first rtext freed > end */
697 xfs_rtxnum_t preblock
; /* first rtext freed < start */
699 end
= start
+ len
- 1;
701 * Modify the bitmap to mark this extent freed.
703 error
= xfs_rtmodify_range(mp
, tp
, start
, len
, 1);
708 * Assume we're freeing out of the middle of an allocated extent.
709 * We need to find the beginning and end of the extent so we can
710 * properly update the summary.
712 error
= xfs_rtfind_back(mp
, tp
, start
, 0, &preblock
);
717 * Find the next allocated block (end of allocated extent).
719 error
= xfs_rtfind_forw(mp
, tp
, end
, mp
->m_sb
.sb_rextents
- 1,
724 * If there are blocks not being freed at the front of the
725 * old extent, add summary data for them to be allocated.
727 if (preblock
< start
) {
728 error
= xfs_rtmodify_summary(mp
, tp
,
729 XFS_RTBLOCKLOG(start
- preblock
),
730 xfs_rtx_to_rbmblock(mp
, preblock
), -1, rbpp
, rsb
);
736 * If there are blocks not being freed at the end of the
737 * old extent, add summary data for them to be allocated.
739 if (postblock
> end
) {
740 error
= xfs_rtmodify_summary(mp
, tp
,
741 XFS_RTBLOCKLOG(postblock
- end
),
742 xfs_rtx_to_rbmblock(mp
, end
+ 1), -1, rbpp
, rsb
);
748 * Increment the summary information corresponding to the entire
751 error
= xfs_rtmodify_summary(mp
, tp
,
752 XFS_RTBLOCKLOG(postblock
+ 1 - preblock
),
753 xfs_rtx_to_rbmblock(mp
, preblock
), 1, rbpp
, rsb
);
758 * Check that the given range is either all allocated (val = 0) or
759 * all free (val = 1).
763 xfs_mount_t
*mp
, /* file system mount point */
764 xfs_trans_t
*tp
, /* transaction pointer */
765 xfs_rtxnum_t start
, /* starting rtext number of extent */
766 xfs_rtxlen_t len
, /* length of extent */
767 int val
, /* 1 for free, 0 for allocated */
768 xfs_rtxnum_t
*new, /* out: first rtext not matching */
769 int *stat
) /* out: 1 for matches, 0 for not */
771 int bit
; /* bit number in the word */
772 xfs_fileoff_t block
; /* bitmap block number */
773 struct xfs_buf
*bp
; /* buf for the block */
774 int error
; /* error value */
775 xfs_rtxnum_t i
; /* current bit number rel. to start */
776 xfs_rtxnum_t lastbit
; /* last useful bit in word */
777 xfs_rtword_t mask
; /* mask of relevant bits for value */
778 xfs_rtword_t wdiff
; /* difference from wanted value */
780 unsigned int word
; /* word number in the buffer */
783 * Compute starting bitmap block number
785 block
= xfs_rtx_to_rbmblock(mp
, start
);
787 * Read the bitmap block.
789 error
= xfs_rtbuf_get(mp
, tp
, block
, 0, &bp
);
795 * Compute the starting word's address, and starting bit.
797 word
= xfs_rtx_to_rbmword(mp
, start
);
798 bit
= (int)(start
& (XFS_NBWORD
- 1));
800 * 0 (allocated) => all zero's; 1 (free) => all one's.
804 * If not starting on a word boundary, deal with the first
809 * Compute first bit not examined.
811 lastbit
= XFS_RTMIN(bit
+ len
, XFS_NBWORD
);
813 * Mask of relevant bits.
815 mask
= (((xfs_rtword_t
)1 << (lastbit
- bit
)) - 1) << bit
;
817 * Compute difference between actual and desired value.
819 incore
= xfs_rtbitmap_getword(bp
, word
);
820 if ((wdiff
= (incore
^ val
) & mask
)) {
822 * Different, compute first wrong bit and return.
824 xfs_trans_brelse(tp
, bp
);
825 i
= XFS_RTLOBIT(wdiff
) - bit
;
832 * Go on to next block if that's where the next word is
833 * and we need the next word.
835 if (++word
== mp
->m_blockwsize
&& i
< len
) {
837 * If done with this block, get the next one.
839 xfs_trans_brelse(tp
, bp
);
840 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
849 * Starting on a word boundary, no partial word.
854 * Loop over whole words in buffers. When we use up one buffer
855 * we move on to the next one.
857 while (len
- i
>= XFS_NBWORD
) {
859 * Compute difference between actual and desired value.
861 incore
= xfs_rtbitmap_getword(bp
, word
);
862 if ((wdiff
= incore
^ val
)) {
864 * Different, compute first wrong bit and return.
866 xfs_trans_brelse(tp
, bp
);
867 i
+= XFS_RTLOBIT(wdiff
);
874 * Go on to next block if that's where the next word is
875 * and we need the next word.
877 if (++word
== mp
->m_blockwsize
&& i
< len
) {
879 * If done with this block, get the next one.
881 xfs_trans_brelse(tp
, bp
);
882 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
891 * If not ending on a word boundary, deal with the last
894 if ((lastbit
= len
- i
)) {
896 * Mask of relevant bits.
898 mask
= ((xfs_rtword_t
)1 << lastbit
) - 1;
900 * Compute difference between actual and desired value.
902 incore
= xfs_rtbitmap_getword(bp
, word
);
903 if ((wdiff
= (incore
^ val
) & mask
)) {
905 * Different, compute first wrong bit and return.
907 xfs_trans_brelse(tp
, bp
);
908 i
+= XFS_RTLOBIT(wdiff
);
916 * Successful, return.
918 xfs_trans_brelse(tp
, bp
);
926 * Check that the given extent (block range) is allocated already.
928 STATIC
int /* error */
929 xfs_rtcheck_alloc_range(
930 xfs_mount_t
*mp
, /* file system mount point */
931 xfs_trans_t
*tp
, /* transaction pointer */
932 xfs_rtxnum_t start
, /* starting rtext number of extent */
933 xfs_rtxlen_t len
) /* length of extent */
935 xfs_rtxnum_t
new; /* dummy for xfs_rtcheck_range */
939 error
= xfs_rtcheck_range(mp
, tp
, start
, len
, 0, &new, &stat
);
946 #define xfs_rtcheck_alloc_range(m,t,b,l) (0)
949 * Free an extent in the realtime subvolume. Length is expressed in
950 * realtime extents, as is the block number.
954 xfs_trans_t
*tp
, /* transaction pointer */
955 xfs_rtxnum_t start
, /* starting rtext number to free */
956 xfs_rtxlen_t len
) /* length of extent freed */
958 int error
; /* error value */
959 xfs_mount_t
*mp
; /* file system mount structure */
960 xfs_fsblock_t sb
; /* summary file block number */
961 struct xfs_buf
*sumbp
= NULL
; /* summary file block buffer */
962 struct timespec64 atime
;
966 ASSERT(mp
->m_rbmip
->i_itemp
!= NULL
);
967 ASSERT(xfs_isilocked(mp
->m_rbmip
, XFS_ILOCK_EXCL
));
969 error
= xfs_rtcheck_alloc_range(mp
, tp
, start
, len
);
974 * Free the range of realtime blocks.
976 error
= xfs_rtfree_range(mp
, tp
, start
, len
, &sumbp
, &sb
);
981 * Mark more blocks free in the superblock.
983 xfs_trans_mod_sb(tp
, XFS_TRANS_SB_FREXTENTS
, (long)len
);
985 * If we've now freed all the blocks, reset the file sequence
988 if (tp
->t_frextents_delta
+ mp
->m_sb
.sb_frextents
==
989 mp
->m_sb
.sb_rextents
) {
990 if (!(mp
->m_rbmip
->i_diflags
& XFS_DIFLAG_NEWRTBM
))
991 mp
->m_rbmip
->i_diflags
|= XFS_DIFLAG_NEWRTBM
;
993 atime
= inode_get_atime(VFS_I(mp
->m_rbmip
));
995 inode_set_atime_to_ts(VFS_I(mp
->m_rbmip
), atime
);
996 xfs_trans_log_inode(tp
, mp
->m_rbmip
, XFS_ILOG_CORE
);
1002 * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
1003 * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
1004 * cannot exceed XFS_MAX_BMBT_EXTLEN.
1008 struct xfs_trans
*tp
,
1009 xfs_fsblock_t rtbno
,
1010 xfs_filblks_t rtlen
)
1012 struct xfs_mount
*mp
= tp
->t_mountp
;
1017 ASSERT(rtlen
<= XFS_MAX_BMBT_EXTLEN
);
1019 len
= xfs_rtb_to_rtxrem(mp
, rtlen
, &mod
);
1025 start
= xfs_rtb_to_rtxrem(mp
, rtbno
, &mod
);
1031 return xfs_rtfree_extent(tp
, start
, len
);
1034 /* Find all the free records within a given range. */
1036 xfs_rtalloc_query_range(
1037 struct xfs_mount
*mp
,
1038 struct xfs_trans
*tp
,
1039 const struct xfs_rtalloc_rec
*low_rec
,
1040 const struct xfs_rtalloc_rec
*high_rec
,
1041 xfs_rtalloc_query_range_fn fn
,
1044 struct xfs_rtalloc_rec rec
;
1045 xfs_rtxnum_t rtstart
;
1047 xfs_rtxnum_t high_key
;
1051 if (low_rec
->ar_startext
> high_rec
->ar_startext
)
1053 if (low_rec
->ar_startext
>= mp
->m_sb
.sb_rextents
||
1054 low_rec
->ar_startext
== high_rec
->ar_startext
)
1057 high_key
= min(high_rec
->ar_startext
, mp
->m_sb
.sb_rextents
- 1);
1059 /* Iterate the bitmap, looking for discrepancies. */
1060 rtstart
= low_rec
->ar_startext
;
1061 while (rtstart
<= high_key
) {
1062 /* Is the first block free? */
1063 error
= xfs_rtcheck_range(mp
, tp
, rtstart
, 1, 1, &rtend
,
1068 /* How long does the extent go for? */
1069 error
= xfs_rtfind_forw(mp
, tp
, rtstart
, high_key
, &rtend
);
1074 rec
.ar_startext
= rtstart
;
1075 rec
.ar_extcount
= rtend
- rtstart
+ 1;
1077 error
= fn(mp
, tp
, &rec
, priv
);
1082 rtstart
= rtend
+ 1;
1088 /* Find all the free records. */
1090 xfs_rtalloc_query_all(
1091 struct xfs_mount
*mp
,
1092 struct xfs_trans
*tp
,
1093 xfs_rtalloc_query_range_fn fn
,
1096 struct xfs_rtalloc_rec keys
[2];
1098 keys
[0].ar_startext
= 0;
1099 keys
[1].ar_startext
= mp
->m_sb
.sb_rextents
- 1;
1100 keys
[0].ar_extcount
= keys
[1].ar_extcount
= 0;
1102 return xfs_rtalloc_query_range(mp
, tp
, &keys
[0], &keys
[1], fn
, priv
);
1105 /* Is the given extent all free? */
1107 xfs_rtalloc_extent_is_free(
1108 struct xfs_mount
*mp
,
1109 struct xfs_trans
*tp
,
1118 error
= xfs_rtcheck_range(mp
, tp
, start
, len
, 1, &end
, &matches
);
1127 * Compute the number of rtbitmap blocks needed to track the given number of rt
1131 xfs_rtbitmap_blockcount(
1132 struct xfs_mount
*mp
,
1133 xfs_rtbxlen_t rtextents
)
1135 return howmany_64(rtextents
, NBBY
* mp
->m_sb
.sb_blocksize
);
1139 * Compute the number of rtbitmap words needed to populate every block of a
1140 * bitmap that is large enough to track the given number of rt extents.
1143 xfs_rtbitmap_wordcount(
1144 struct xfs_mount
*mp
,
1145 xfs_rtbxlen_t rtextents
)
1147 xfs_filblks_t blocks
;
1149 blocks
= xfs_rtbitmap_blockcount(mp
, rtextents
);
1150 return XFS_FSB_TO_B(mp
, blocks
) >> XFS_WORDLOG
;
1153 /* Compute the number of rtsummary blocks needed to track the given rt space. */
1155 xfs_rtsummary_blockcount(
1156 struct xfs_mount
*mp
,
1157 unsigned int rsumlevels
,
1158 xfs_extlen_t rbmblocks
)
1160 unsigned long long rsumwords
;
1162 rsumwords
= (unsigned long long)rsumlevels
* rbmblocks
;
1163 return XFS_B_TO_FSB(mp
, rsumwords
<< XFS_WORDLOG
);
1167 * Compute the number of rtsummary info words needed to populate every block of
1168 * a summary file that is large enough to track the given rt space.
1171 xfs_rtsummary_wordcount(
1172 struct xfs_mount
*mp
,
1173 unsigned int rsumlevels
,
1174 xfs_extlen_t rbmblocks
)
1176 xfs_filblks_t blocks
;
1178 blocks
= xfs_rtsummary_blockcount(mp
, rsumlevels
, rbmblocks
);
1179 return XFS_FSB_TO_B(mp
, blocks
) >> XFS_WORDLOG
;