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_bmap_btree.h"
17 #include "xfs_alloc.h"
18 #include "xfs_trans.h"
19 #include "xfs_trans_space.h"
20 #include "xfs_trace.h"
24 * Realtime allocator bitmap functions shared with userspace.
28 * Real time buffers need verifiers to avoid runtime warnings during IO.
29 * We don't have anything to verify, however, so these are just dummy
33 xfs_rtbuf_verify_read(
40 xfs_rtbuf_verify_write(
46 const struct xfs_buf_ops xfs_rtbuf_ops
= {
48 .verify_read
= xfs_rtbuf_verify_read
,
49 .verify_write
= xfs_rtbuf_verify_write
,
53 * Get a buffer for the bitmap or summary file block specified.
54 * The buffer is returned read and locked.
58 xfs_mount_t
*mp
, /* file system mount structure */
59 xfs_trans_t
*tp
, /* transaction pointer */
60 xfs_rtblock_t block
, /* block number in bitmap or summary */
61 int issum
, /* is summary not bitmap */
62 xfs_buf_t
**bpp
) /* output: buffer for the block */
64 xfs_buf_t
*bp
; /* block buffer, result */
65 xfs_inode_t
*ip
; /* bitmap or summary inode */
68 int error
; /* error value */
70 ip
= issum
? mp
->m_rsumip
: mp
->m_rbmip
;
72 error
= xfs_bmapi_read(ip
, block
, 1, &map
, &nmap
, XFS_DATA_FORK
);
76 if (nmap
== 0 || !xfs_bmap_is_real_extent(&map
))
79 ASSERT(map
.br_startblock
!= NULLFSBLOCK
);
80 error
= xfs_trans_read_buf(mp
, tp
, mp
->m_ddev_targp
,
81 XFS_FSB_TO_DADDR(mp
, map
.br_startblock
),
82 mp
->m_bsize
, 0, &bp
, &xfs_rtbuf_ops
);
86 xfs_trans_buf_set_type(tp
, bp
, issum
? XFS_BLFT_RTSUMMARY_BUF
87 : XFS_BLFT_RTBITMAP_BUF
);
93 * Searching backward from start to limit, find the first block whose
94 * allocated/free state is different from start's.
98 xfs_mount_t
*mp
, /* file system mount point */
99 xfs_trans_t
*tp
, /* transaction pointer */
100 xfs_rtblock_t start
, /* starting block to look at */
101 xfs_rtblock_t limit
, /* last block to look at */
102 xfs_rtblock_t
*rtblock
) /* out: start block found */
104 xfs_rtword_t
*b
; /* current word in buffer */
105 int bit
; /* bit number in the word */
106 xfs_rtblock_t block
; /* bitmap block number */
107 xfs_buf_t
*bp
; /* buf for the block */
108 xfs_rtword_t
*bufp
; /* starting word in buffer */
109 int error
; /* error value */
110 xfs_rtblock_t firstbit
; /* first useful bit in the word */
111 xfs_rtblock_t i
; /* current bit number rel. to start */
112 xfs_rtblock_t len
; /* length of inspected area */
113 xfs_rtword_t mask
; /* mask of relevant bits for value */
114 xfs_rtword_t want
; /* mask for "good" values */
115 xfs_rtword_t wdiff
; /* difference from wanted value */
116 int word
; /* word number in the buffer */
119 * Compute and read in starting bitmap block for starting block.
121 block
= XFS_BITTOBLOCK(mp
, start
);
122 error
= xfs_rtbuf_get(mp
, tp
, block
, 0, &bp
);
128 * Get the first word's index & point to it.
130 word
= XFS_BITTOWORD(mp
, start
);
132 bit
= (int)(start
& (XFS_NBWORD
- 1));
133 len
= start
- limit
+ 1;
135 * Compute match value, based on the bit at start: if 1 (free)
136 * then all-ones, else all-zeroes.
138 want
= (*b
& ((xfs_rtword_t
)1 << bit
)) ? -1 : 0;
140 * If the starting position is not word-aligned, deal with the
143 if (bit
< XFS_NBWORD
- 1) {
145 * Calculate first (leftmost) bit number to look at,
146 * and mask for all the relevant bits in this word.
148 firstbit
= XFS_RTMAX((xfs_srtblock_t
)(bit
- len
+ 1), 0);
149 mask
= (((xfs_rtword_t
)1 << (bit
- firstbit
+ 1)) - 1) <<
152 * Calculate the difference between the value there
153 * and what we're looking for.
155 if ((wdiff
= (*b
^ want
) & mask
)) {
157 * Different. Mark where we are and return.
159 xfs_trans_brelse(tp
, bp
);
160 i
= bit
- XFS_RTHIBIT(wdiff
);
161 *rtblock
= start
- i
+ 1;
164 i
= bit
- firstbit
+ 1;
166 * Go on to previous block if that's where the previous word is
167 * and we need the previous word.
169 if (--word
== -1 && i
< len
) {
171 * If done with this block, get the previous one.
173 xfs_trans_brelse(tp
, bp
);
174 error
= xfs_rtbuf_get(mp
, tp
, --block
, 0, &bp
);
179 word
= XFS_BLOCKWMASK(mp
);
183 * Go on to the previous word in the buffer.
189 * Starting on a word boundary, no partial word.
194 * Loop over whole words in buffers. When we use up one buffer
195 * we move on to the previous one.
197 while (len
- i
>= XFS_NBWORD
) {
199 * Compute difference between actual and desired value.
201 if ((wdiff
= *b
^ want
)) {
203 * Different, mark where we are and return.
205 xfs_trans_brelse(tp
, bp
);
206 i
+= XFS_NBWORD
- 1 - XFS_RTHIBIT(wdiff
);
207 *rtblock
= start
- i
+ 1;
212 * Go on to previous block if that's where the previous word is
213 * and we need the previous word.
215 if (--word
== -1 && i
< len
) {
217 * If done with this block, get the previous one.
219 xfs_trans_brelse(tp
, bp
);
220 error
= xfs_rtbuf_get(mp
, tp
, --block
, 0, &bp
);
225 word
= XFS_BLOCKWMASK(mp
);
229 * Go on to the previous word in the buffer.
235 * If not ending on a word boundary, deal with the last
240 * Calculate first (leftmost) bit number to look at,
241 * and mask for all the relevant bits in this word.
243 firstbit
= XFS_NBWORD
- (len
- i
);
244 mask
= (((xfs_rtword_t
)1 << (len
- i
)) - 1) << firstbit
;
246 * Compute difference between actual and desired value.
248 if ((wdiff
= (*b
^ want
) & mask
)) {
250 * Different, mark where we are and return.
252 xfs_trans_brelse(tp
, bp
);
253 i
+= XFS_NBWORD
- 1 - XFS_RTHIBIT(wdiff
);
254 *rtblock
= start
- i
+ 1;
260 * No match, return that we scanned the whole area.
262 xfs_trans_brelse(tp
, bp
);
263 *rtblock
= start
- i
+ 1;
268 * Searching forward from start to limit, find the first block whose
269 * allocated/free state is different from start's.
273 xfs_mount_t
*mp
, /* file system mount point */
274 xfs_trans_t
*tp
, /* transaction pointer */
275 xfs_rtblock_t start
, /* starting block to look at */
276 xfs_rtblock_t limit
, /* last block to look at */
277 xfs_rtblock_t
*rtblock
) /* out: start block found */
279 xfs_rtword_t
*b
; /* current word in buffer */
280 int bit
; /* bit number in the word */
281 xfs_rtblock_t block
; /* bitmap block number */
282 xfs_buf_t
*bp
; /* buf for the block */
283 xfs_rtword_t
*bufp
; /* starting word in buffer */
284 int error
; /* error value */
285 xfs_rtblock_t i
; /* current bit number rel. to start */
286 xfs_rtblock_t lastbit
; /* last useful bit in the word */
287 xfs_rtblock_t len
; /* length of inspected area */
288 xfs_rtword_t mask
; /* mask of relevant bits for value */
289 xfs_rtword_t want
; /* mask for "good" values */
290 xfs_rtword_t wdiff
; /* difference from wanted value */
291 int word
; /* word number in the buffer */
294 * Compute and read in starting bitmap block for starting block.
296 block
= XFS_BITTOBLOCK(mp
, start
);
297 error
= xfs_rtbuf_get(mp
, tp
, block
, 0, &bp
);
303 * Get the first word's index & point to it.
305 word
= XFS_BITTOWORD(mp
, start
);
307 bit
= (int)(start
& (XFS_NBWORD
- 1));
308 len
= limit
- start
+ 1;
310 * Compute match value, based on the bit at start: if 1 (free)
311 * then all-ones, else all-zeroes.
313 want
= (*b
& ((xfs_rtword_t
)1 << bit
)) ? -1 : 0;
315 * If the starting position is not word-aligned, deal with the
320 * Calculate last (rightmost) bit number to look at,
321 * and mask for all the relevant bits in this word.
323 lastbit
= XFS_RTMIN(bit
+ len
, XFS_NBWORD
);
324 mask
= (((xfs_rtword_t
)1 << (lastbit
- bit
)) - 1) << bit
;
326 * Calculate the difference between the value there
327 * and what we're looking for.
329 if ((wdiff
= (*b
^ want
) & mask
)) {
331 * Different. Mark where we are and return.
333 xfs_trans_brelse(tp
, bp
);
334 i
= XFS_RTLOBIT(wdiff
) - bit
;
335 *rtblock
= start
+ i
- 1;
340 * Go on to next block if that's where the next word is
341 * and we need the next word.
343 if (++word
== XFS_BLOCKWSIZE(mp
) && i
< len
) {
345 * If done with this block, get the previous one.
347 xfs_trans_brelse(tp
, bp
);
348 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
352 b
= bufp
= bp
->b_addr
;
356 * Go on to the previous word in the buffer.
362 * Starting on a word boundary, no partial word.
367 * Loop over whole words in buffers. When we use up one buffer
368 * we move on to the next one.
370 while (len
- i
>= XFS_NBWORD
) {
372 * Compute difference between actual and desired value.
374 if ((wdiff
= *b
^ want
)) {
376 * Different, mark where we are and return.
378 xfs_trans_brelse(tp
, bp
);
379 i
+= XFS_RTLOBIT(wdiff
);
380 *rtblock
= start
+ i
- 1;
385 * Go on to next block if that's where the next word is
386 * and we need the next word.
388 if (++word
== XFS_BLOCKWSIZE(mp
) && i
< len
) {
390 * If done with this block, get the next one.
392 xfs_trans_brelse(tp
, bp
);
393 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
397 b
= bufp
= bp
->b_addr
;
401 * Go on to the next word in the buffer.
407 * If not ending on a word boundary, deal with the last
410 if ((lastbit
= len
- i
)) {
412 * Calculate mask for all the relevant bits in this word.
414 mask
= ((xfs_rtword_t
)1 << lastbit
) - 1;
416 * Compute difference between actual and desired value.
418 if ((wdiff
= (*b
^ want
) & mask
)) {
420 * Different, mark where we are and return.
422 xfs_trans_brelse(tp
, bp
);
423 i
+= XFS_RTLOBIT(wdiff
);
424 *rtblock
= start
+ i
- 1;
430 * No match, return that we scanned the whole area.
432 xfs_trans_brelse(tp
, bp
);
433 *rtblock
= start
+ i
- 1;
438 * Read and/or modify the summary information for a given extent size,
439 * bitmap block combination.
440 * Keeps track of a current summary block, so we don't keep reading
441 * it from the buffer cache.
443 * Summary information is returned in *sum if specified.
444 * If no delta is specified, returns summary only.
447 xfs_rtmodify_summary_int(
448 xfs_mount_t
*mp
, /* file system mount structure */
449 xfs_trans_t
*tp
, /* transaction pointer */
450 int log
, /* log2 of extent size */
451 xfs_rtblock_t bbno
, /* bitmap block number */
452 int delta
, /* change to make to summary info */
453 xfs_buf_t
**rbpp
, /* in/out: summary block buffer */
454 xfs_fsblock_t
*rsb
, /* in/out: summary block number */
455 xfs_suminfo_t
*sum
) /* out: summary info for this block */
457 xfs_buf_t
*bp
; /* buffer for the summary block */
458 int error
; /* error value */
459 xfs_fsblock_t sb
; /* summary fsblock */
460 int so
; /* index into the summary file */
461 xfs_suminfo_t
*sp
; /* pointer to returned data */
464 * Compute entry number in the summary file.
466 so
= XFS_SUMOFFS(mp
, log
, bbno
);
468 * Compute the block number in the summary file.
470 sb
= XFS_SUMOFFSTOBLOCK(mp
, so
);
472 * If we have an old buffer, and the block number matches, use that.
474 if (*rbpp
&& *rsb
== sb
)
477 * Otherwise we have to get the buffer.
481 * If there was an old one, get rid of it first.
484 xfs_trans_brelse(tp
, *rbpp
);
485 error
= xfs_rtbuf_get(mp
, tp
, sb
, 1, &bp
);
490 * Remember this buffer and block for the next call.
496 * Point to the summary information, modify/log it, and/or copy it out.
498 sp
= XFS_SUMPTR(mp
, bp
, so
);
500 uint first
= (uint
)((char *)sp
- (char *)bp
->b_addr
);
503 xfs_trans_log_buf(tp
, bp
, first
, first
+ sizeof(*sp
) - 1);
511 xfs_rtmodify_summary(
512 xfs_mount_t
*mp
, /* file system mount structure */
513 xfs_trans_t
*tp
, /* transaction pointer */
514 int log
, /* log2 of extent size */
515 xfs_rtblock_t bbno
, /* bitmap block number */
516 int delta
, /* change to make to summary info */
517 xfs_buf_t
**rbpp
, /* in/out: summary block buffer */
518 xfs_fsblock_t
*rsb
) /* in/out: summary block number */
520 return xfs_rtmodify_summary_int(mp
, tp
, log
, bbno
,
521 delta
, rbpp
, rsb
, NULL
);
525 * Set the given range of bitmap bits to the given value.
526 * Do whatever I/O and logging is required.
530 xfs_mount_t
*mp
, /* file system mount point */
531 xfs_trans_t
*tp
, /* transaction pointer */
532 xfs_rtblock_t start
, /* starting block to modify */
533 xfs_extlen_t len
, /* length of extent to modify */
534 int val
) /* 1 for free, 0 for allocated */
536 xfs_rtword_t
*b
; /* current word in buffer */
537 int bit
; /* bit number in the word */
538 xfs_rtblock_t block
; /* bitmap block number */
539 xfs_buf_t
*bp
; /* buf for the block */
540 xfs_rtword_t
*bufp
; /* starting word in buffer */
541 int error
; /* error value */
542 xfs_rtword_t
*first
; /* first used word in the buffer */
543 int i
; /* current bit number rel. to start */
544 int lastbit
; /* last useful bit in word */
545 xfs_rtword_t mask
; /* mask o frelevant bits for value */
546 int word
; /* word number in the buffer */
549 * Compute starting bitmap block number.
551 block
= XFS_BITTOBLOCK(mp
, start
);
553 * Read the bitmap block, and point to its data.
555 error
= xfs_rtbuf_get(mp
, tp
, block
, 0, &bp
);
561 * Compute the starting word's address, and starting bit.
563 word
= XFS_BITTOWORD(mp
, start
);
564 first
= b
= &bufp
[word
];
565 bit
= (int)(start
& (XFS_NBWORD
- 1));
567 * 0 (allocated) => all zeroes; 1 (free) => all ones.
571 * If not starting on a word boundary, deal with the first
576 * Compute first bit not changed and mask of relevant bits.
578 lastbit
= XFS_RTMIN(bit
+ len
, XFS_NBWORD
);
579 mask
= (((xfs_rtword_t
)1 << (lastbit
- bit
)) - 1) << bit
;
581 * Set/clear the active bits.
589 * Go on to the next block if that's where the next word is
590 * and we need the next word.
592 if (++word
== XFS_BLOCKWSIZE(mp
) && i
< len
) {
594 * Log the changed part of this block.
597 xfs_trans_log_buf(tp
, bp
,
598 (uint
)((char *)first
- (char *)bufp
),
599 (uint
)((char *)b
- (char *)bufp
));
600 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
604 first
= b
= bufp
= bp
->b_addr
;
608 * Go on to the next word in the buffer
614 * Starting on a word boundary, no partial word.
619 * Loop over whole words in buffers. When we use up one buffer
620 * we move on to the next one.
622 while (len
- i
>= XFS_NBWORD
) {
624 * Set the word value correctly.
629 * Go on to the next block if that's where the next word is
630 * and we need the next word.
632 if (++word
== XFS_BLOCKWSIZE(mp
) && i
< len
) {
634 * Log the changed part of this block.
637 xfs_trans_log_buf(tp
, bp
,
638 (uint
)((char *)first
- (char *)bufp
),
639 (uint
)((char *)b
- (char *)bufp
));
640 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
644 first
= b
= bufp
= bp
->b_addr
;
648 * Go on to the next word in the buffer
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.
672 * Log any remaining changed bytes.
675 xfs_trans_log_buf(tp
, bp
, (uint
)((char *)first
- (char *)bufp
),
676 (uint
)((char *)b
- (char *)bufp
- 1));
681 * Mark an extent specified by start and len freed.
682 * Updates all the summary information as well as the bitmap.
686 xfs_mount_t
*mp
, /* file system mount point */
687 xfs_trans_t
*tp
, /* transaction pointer */
688 xfs_rtblock_t start
, /* starting block to free */
689 xfs_extlen_t len
, /* length to free */
690 xfs_buf_t
**rbpp
, /* in/out: summary block buffer */
691 xfs_fsblock_t
*rsb
) /* in/out: summary block number */
693 xfs_rtblock_t end
; /* end of the freed extent */
694 int error
; /* error value */
695 xfs_rtblock_t postblock
; /* first block freed > end */
696 xfs_rtblock_t preblock
; /* first block freed < start */
698 end
= start
+ len
- 1;
700 * Modify the bitmap to mark this extent freed.
702 error
= xfs_rtmodify_range(mp
, tp
, start
, len
, 1);
707 * Assume we're freeing out of the middle of an allocated extent.
708 * We need to find the beginning and end of the extent so we can
709 * properly update the summary.
711 error
= xfs_rtfind_back(mp
, tp
, start
, 0, &preblock
);
716 * Find the next allocated block (end of allocated extent).
718 error
= xfs_rtfind_forw(mp
, tp
, end
, mp
->m_sb
.sb_rextents
- 1,
723 * If there are blocks not being freed at the front of the
724 * old extent, add summary data for them to be allocated.
726 if (preblock
< start
) {
727 error
= xfs_rtmodify_summary(mp
, tp
,
728 XFS_RTBLOCKLOG(start
- preblock
),
729 XFS_BITTOBLOCK(mp
, preblock
), -1, rbpp
, rsb
);
735 * If there are blocks not being freed at the end of the
736 * old extent, add summary data for them to be allocated.
738 if (postblock
> end
) {
739 error
= xfs_rtmodify_summary(mp
, tp
,
740 XFS_RTBLOCKLOG(postblock
- end
),
741 XFS_BITTOBLOCK(mp
, end
+ 1), -1, rbpp
, rsb
);
747 * Increment the summary information corresponding to the entire
750 error
= xfs_rtmodify_summary(mp
, tp
,
751 XFS_RTBLOCKLOG(postblock
+ 1 - preblock
),
752 XFS_BITTOBLOCK(mp
, preblock
), 1, rbpp
, rsb
);
757 * Check that the given range is either all allocated (val = 0) or
758 * all free (val = 1).
762 xfs_mount_t
*mp
, /* file system mount point */
763 xfs_trans_t
*tp
, /* transaction pointer */
764 xfs_rtblock_t start
, /* starting block number of extent */
765 xfs_extlen_t len
, /* length of extent */
766 int val
, /* 1 for free, 0 for allocated */
767 xfs_rtblock_t
*new, /* out: first block not matching */
768 int *stat
) /* out: 1 for matches, 0 for not */
770 xfs_rtword_t
*b
; /* current word in buffer */
771 int bit
; /* bit number in the word */
772 xfs_rtblock_t block
; /* bitmap block number */
773 xfs_buf_t
*bp
; /* buf for the block */
774 xfs_rtword_t
*bufp
; /* starting word in buffer */
775 int error
; /* error value */
776 xfs_rtblock_t i
; /* current bit number rel. to start */
777 xfs_rtblock_t lastbit
; /* last useful bit in word */
778 xfs_rtword_t mask
; /* mask of relevant bits for value */
779 xfs_rtword_t wdiff
; /* difference from wanted value */
780 int word
; /* word number in the buffer */
783 * Compute starting bitmap block number
785 block
= XFS_BITTOBLOCK(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_BITTOWORD(mp
, start
);
799 bit
= (int)(start
& (XFS_NBWORD
- 1));
801 * 0 (allocated) => all zero's; 1 (free) => all one's.
805 * If not starting on a word boundary, deal with the first
810 * Compute first bit not examined.
812 lastbit
= XFS_RTMIN(bit
+ len
, XFS_NBWORD
);
814 * Mask of relevant bits.
816 mask
= (((xfs_rtword_t
)1 << (lastbit
- bit
)) - 1) << bit
;
818 * Compute difference between actual and desired value.
820 if ((wdiff
= (*b
^ 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
== XFS_BLOCKWSIZE(mp
) && 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
);
844 b
= bufp
= bp
->b_addr
;
848 * Go on to the next word in the buffer.
854 * Starting on a word boundary, no partial word.
859 * Loop over whole words in buffers. When we use up one buffer
860 * we move on to the next one.
862 while (len
- i
>= XFS_NBWORD
) {
864 * Compute difference between actual and desired value.
866 if ((wdiff
= *b
^ val
)) {
868 * Different, compute first wrong bit and return.
870 xfs_trans_brelse(tp
, bp
);
871 i
+= XFS_RTLOBIT(wdiff
);
878 * Go on to next block if that's where the next word is
879 * and we need the next word.
881 if (++word
== XFS_BLOCKWSIZE(mp
) && i
< len
) {
883 * If done with this block, get the next one.
885 xfs_trans_brelse(tp
, bp
);
886 error
= xfs_rtbuf_get(mp
, tp
, ++block
, 0, &bp
);
890 b
= bufp
= bp
->b_addr
;
894 * Go on to the next word in the buffer.
900 * If not ending on a word boundary, deal with the last
903 if ((lastbit
= len
- i
)) {
905 * Mask of relevant bits.
907 mask
= ((xfs_rtword_t
)1 << lastbit
) - 1;
909 * Compute difference between actual and desired value.
911 if ((wdiff
= (*b
^ val
) & mask
)) {
913 * Different, compute first wrong bit and return.
915 xfs_trans_brelse(tp
, bp
);
916 i
+= XFS_RTLOBIT(wdiff
);
924 * Successful, return.
926 xfs_trans_brelse(tp
, bp
);
934 * Check that the given extent (block range) is allocated already.
936 STATIC
int /* error */
937 xfs_rtcheck_alloc_range(
938 xfs_mount_t
*mp
, /* file system mount point */
939 xfs_trans_t
*tp
, /* transaction pointer */
940 xfs_rtblock_t bno
, /* starting block number of extent */
941 xfs_extlen_t len
) /* length of extent */
943 xfs_rtblock_t
new; /* dummy for xfs_rtcheck_range */
947 error
= xfs_rtcheck_range(mp
, tp
, bno
, len
, 0, &new, &stat
);
954 #define xfs_rtcheck_alloc_range(m,t,b,l) (0)
957 * Free an extent in the realtime subvolume. Length is expressed in
958 * realtime extents, as is the block number.
962 xfs_trans_t
*tp
, /* transaction pointer */
963 xfs_rtblock_t bno
, /* starting block number to free */
964 xfs_extlen_t len
) /* length of extent freed */
966 int error
; /* error value */
967 xfs_mount_t
*mp
; /* file system mount structure */
968 xfs_fsblock_t sb
; /* summary file block number */
969 xfs_buf_t
*sumbp
= NULL
; /* summary file block buffer */
973 ASSERT(mp
->m_rbmip
->i_itemp
!= NULL
);
974 ASSERT(xfs_isilocked(mp
->m_rbmip
, XFS_ILOCK_EXCL
));
976 error
= xfs_rtcheck_alloc_range(mp
, tp
, bno
, len
);
981 * Free the range of realtime blocks.
983 error
= xfs_rtfree_range(mp
, tp
, bno
, len
, &sumbp
, &sb
);
988 * Mark more blocks free in the superblock.
990 xfs_trans_mod_sb(tp
, XFS_TRANS_SB_FREXTENTS
, (long)len
);
992 * If we've now freed all the blocks, reset the file sequence
995 if (tp
->t_frextents_delta
+ mp
->m_sb
.sb_frextents
==
996 mp
->m_sb
.sb_rextents
) {
997 if (!(mp
->m_rbmip
->i_d
.di_flags
& XFS_DIFLAG_NEWRTBM
))
998 mp
->m_rbmip
->i_d
.di_flags
|= XFS_DIFLAG_NEWRTBM
;
999 *(uint64_t *)&VFS_I(mp
->m_rbmip
)->i_atime
= 0;
1000 xfs_trans_log_inode(tp
, mp
->m_rbmip
, XFS_ILOG_CORE
);
1005 /* Find all the free records within a given range. */
1007 xfs_rtalloc_query_range(
1008 struct xfs_trans
*tp
,
1009 struct xfs_rtalloc_rec
*low_rec
,
1010 struct xfs_rtalloc_rec
*high_rec
,
1011 xfs_rtalloc_query_range_fn fn
,
1014 struct xfs_rtalloc_rec rec
;
1015 struct xfs_mount
*mp
= tp
->t_mountp
;
1016 xfs_rtblock_t rtstart
;
1017 xfs_rtblock_t rtend
;
1022 if (low_rec
->ar_startext
> high_rec
->ar_startext
)
1024 if (low_rec
->ar_startext
>= mp
->m_sb
.sb_rextents
||
1025 low_rec
->ar_startext
== high_rec
->ar_startext
)
1027 if (high_rec
->ar_startext
> mp
->m_sb
.sb_rextents
)
1028 high_rec
->ar_startext
= mp
->m_sb
.sb_rextents
;
1030 /* Iterate the bitmap, looking for discrepancies. */
1031 rtstart
= low_rec
->ar_startext
;
1032 rem
= high_rec
->ar_startext
- rtstart
;
1034 /* Is the first block free? */
1035 error
= xfs_rtcheck_range(mp
, tp
, rtstart
, 1, 1, &rtend
,
1040 /* How long does the extent go for? */
1041 error
= xfs_rtfind_forw(mp
, tp
, rtstart
,
1042 high_rec
->ar_startext
- 1, &rtend
);
1047 rec
.ar_startext
= rtstart
;
1048 rec
.ar_extcount
= rtend
- rtstart
+ 1;
1050 error
= fn(tp
, &rec
, priv
);
1055 rem
-= rtend
- rtstart
+ 1;
1056 rtstart
= rtend
+ 1;
1062 /* Find all the free records. */
1064 xfs_rtalloc_query_all(
1065 struct xfs_trans
*tp
,
1066 xfs_rtalloc_query_range_fn fn
,
1069 struct xfs_rtalloc_rec keys
[2];
1071 keys
[0].ar_startext
= 0;
1072 keys
[1].ar_startext
= tp
->t_mountp
->m_sb
.sb_rextents
- 1;
1073 keys
[0].ar_extcount
= keys
[1].ar_extcount
= 0;
1075 return xfs_rtalloc_query_range(tp
, &keys
[0], &keys
[1], fn
, priv
);
1078 /* Is the given extent all free? */
1080 xfs_rtalloc_extent_is_free(
1081 struct xfs_mount
*mp
,
1082 struct xfs_trans
*tp
,
1083 xfs_rtblock_t start
,
1091 error
= xfs_rtcheck_range(mp
, tp
, start
, len
, 1, &end
, &matches
);