1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
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_rtalloc.h"
18 #include "xfs_error.h"
19 #include "xfs_rtbitmap.h"
22 * Realtime allocator bitmap functions shared with userspace.
26 * Real time buffers need verifiers to avoid runtime warnings during IO.
27 * We don't have anything to verify, however, so these are just dummy
31 xfs_rtbuf_verify_read(
38 xfs_rtbuf_verify_write(
44 const struct xfs_buf_ops xfs_rtbuf_ops = {
46 .verify_read = xfs_rtbuf_verify_read,
47 .verify_write = xfs_rtbuf_verify_write,
51 * Get a buffer for the bitmap or summary file block specified.
52 * The buffer is returned read and locked.
56 xfs_mount_t *mp, /* file system mount structure */
57 xfs_trans_t *tp, /* transaction pointer */
58 xfs_fileoff_t block, /* block number in bitmap or summary */
59 int issum, /* is summary not bitmap */
60 struct xfs_buf **bpp) /* output: buffer for the block */
62 struct xfs_buf *bp; /* block buffer, result */
63 xfs_inode_t *ip; /* bitmap or summary inode */
66 int error; /* error value */
68 ip = issum ? mp->m_rsumip : mp->m_rbmip;
70 error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
74 if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map)))
77 ASSERT(map.br_startblock != NULLFSBLOCK);
78 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
79 XFS_FSB_TO_DADDR(mp, map.br_startblock),
80 mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
84 xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF
85 : XFS_BLFT_RTBITMAP_BUF);
91 * Searching backward from start to limit, find the first block whose
92 * allocated/free state is different from start's.
96 xfs_mount_t *mp, /* file system mount point */
97 xfs_trans_t *tp, /* transaction pointer */
98 xfs_rtxnum_t start, /* starting rtext to look at */
99 xfs_rtxnum_t limit, /* last rtext to look at */
100 xfs_rtxnum_t *rtx) /* out: start rtext found */
102 xfs_rtword_t *b; /* current word in buffer */
103 int bit; /* bit number in the word */
104 xfs_fileoff_t block; /* bitmap block number */
105 struct xfs_buf *bp; /* buf for the block */
106 int error; /* error value */
107 xfs_rtxnum_t firstbit; /* first useful bit in the word */
108 xfs_rtxnum_t i; /* current bit number rel. to start */
109 xfs_rtxnum_t len; /* length of inspected area */
110 xfs_rtword_t mask; /* mask of relevant bits for value */
111 xfs_rtword_t want; /* mask for "good" values */
112 xfs_rtword_t wdiff; /* difference from wanted value */
113 unsigned int word; /* word number in the buffer */
116 * Compute and read in starting bitmap block for starting block.
118 block = xfs_rtx_to_rbmblock(mp, start);
119 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
125 * Get the first word's index & point to it.
127 word = xfs_rtx_to_rbmword(mp, start);
128 b = xfs_rbmblock_wordptr(bp, word);
129 bit = (int)(start & (XFS_NBWORD - 1));
130 len = start - limit + 1;
132 * Compute match value, based on the bit at start: if 1 (free)
133 * then all-ones, else all-zeroes.
135 want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
137 * If the starting position is not word-aligned, deal with the
140 if (bit < XFS_NBWORD - 1) {
142 * Calculate first (leftmost) bit number to look at,
143 * and mask for all the relevant bits in this word.
145 firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
146 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
149 * Calculate the difference between the value there
150 * and what we're looking for.
152 if ((wdiff = (*b ^ want) & mask)) {
154 * Different. Mark where we are and return.
156 xfs_trans_brelse(tp, bp);
157 i = bit - XFS_RTHIBIT(wdiff);
158 *rtx = start - i + 1;
161 i = bit - firstbit + 1;
163 * Go on to previous block if that's where the previous word is
164 * and we need the previous word.
166 if (--word == -1 && i < len) {
168 * If done with this block, get the previous one.
170 xfs_trans_brelse(tp, bp);
171 error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
176 word = mp->m_blockwsize - 1;
177 b = xfs_rbmblock_wordptr(bp, word);
180 * Go on to the previous word in the buffer.
186 * Starting on a word boundary, no partial word.
191 * Loop over whole words in buffers. When we use up one buffer
192 * we move on to the previous one.
194 while (len - i >= XFS_NBWORD) {
196 * Compute difference between actual and desired value.
198 if ((wdiff = *b ^ want)) {
200 * Different, mark where we are and return.
202 xfs_trans_brelse(tp, bp);
203 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
204 *rtx = start - i + 1;
209 * Go on to previous block if that's where the previous word is
210 * and we need the previous word.
212 if (--word == -1 && i < len) {
214 * If done with this block, get the previous one.
216 xfs_trans_brelse(tp, bp);
217 error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
222 word = mp->m_blockwsize - 1;
223 b = xfs_rbmblock_wordptr(bp, word);
226 * Go on to the previous word in the buffer.
232 * If not ending on a word boundary, deal with the last
237 * Calculate first (leftmost) bit number to look at,
238 * and mask for all the relevant bits in this word.
240 firstbit = XFS_NBWORD - (len - i);
241 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
243 * Compute difference between actual and desired value.
245 if ((wdiff = (*b ^ want) & mask)) {
247 * Different, mark where we are and return.
249 xfs_trans_brelse(tp, bp);
250 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
251 *rtx = start - i + 1;
257 * No match, return that we scanned the whole area.
259 xfs_trans_brelse(tp, bp);
260 *rtx = start - i + 1;
265 * Searching forward from start to limit, find the first block whose
266 * allocated/free state is different from start's.
270 xfs_mount_t *mp, /* file system mount point */
271 xfs_trans_t *tp, /* transaction pointer */
272 xfs_rtxnum_t start, /* starting rtext to look at */
273 xfs_rtxnum_t limit, /* last rtext to look at */
274 xfs_rtxnum_t *rtx) /* out: start rtext found */
276 xfs_rtword_t *b; /* current word in buffer */
277 int bit; /* bit number in the word */
278 xfs_fileoff_t block; /* bitmap block number */
279 struct xfs_buf *bp; /* buf for the block */
280 int error; /* error value */
281 xfs_rtxnum_t i; /* current bit number rel. to start */
282 xfs_rtxnum_t lastbit; /* last useful bit in the word */
283 xfs_rtxnum_t len; /* length of inspected area */
284 xfs_rtword_t mask; /* mask of relevant bits for value */
285 xfs_rtword_t want; /* mask for "good" values */
286 xfs_rtword_t wdiff; /* difference from wanted value */
287 unsigned int word; /* word number in the buffer */
290 * Compute and read in starting bitmap block for starting block.
292 block = xfs_rtx_to_rbmblock(mp, start);
293 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
299 * Get the first word's index & point to it.
301 word = xfs_rtx_to_rbmword(mp, start);
302 b = xfs_rbmblock_wordptr(bp, word);
303 bit = (int)(start & (XFS_NBWORD - 1));
304 len = limit - start + 1;
306 * Compute match value, based on the bit at start: if 1 (free)
307 * then all-ones, else all-zeroes.
309 want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
311 * If the starting position is not word-aligned, deal with the
316 * Calculate last (rightmost) bit number to look at,
317 * and mask for all the relevant bits in this word.
319 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
320 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
322 * Calculate the difference between the value there
323 * and what we're looking for.
325 if ((wdiff = (*b ^ want) & mask)) {
327 * Different. Mark where we are and return.
329 xfs_trans_brelse(tp, bp);
330 i = XFS_RTLOBIT(wdiff) - bit;
331 *rtx = start + i - 1;
336 * Go on to next block if that's where the next word is
337 * and we need the next word.
339 if (++word == mp->m_blockwsize && i < len) {
341 * If done with this block, get the previous one.
343 xfs_trans_brelse(tp, bp);
344 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
350 b = xfs_rbmblock_wordptr(bp, word);
353 * Go on to the previous word in the buffer.
359 * Starting on a word boundary, no partial word.
364 * Loop over whole words in buffers. When we use up one buffer
365 * we move on to the next one.
367 while (len - i >= XFS_NBWORD) {
369 * Compute difference between actual and desired value.
371 if ((wdiff = *b ^ want)) {
373 * Different, mark where we are and return.
375 xfs_trans_brelse(tp, bp);
376 i += XFS_RTLOBIT(wdiff);
377 *rtx = start + i - 1;
382 * Go on to next block if that's where the next word is
383 * and we need the next word.
385 if (++word == mp->m_blockwsize && i < len) {
387 * If done with this block, get the next one.
389 xfs_trans_brelse(tp, bp);
390 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
396 b = xfs_rbmblock_wordptr(bp, word);
399 * Go on to the next word in the buffer.
405 * If not ending on a word boundary, deal with the last
408 if ((lastbit = len - i)) {
410 * Calculate mask for all the relevant bits in this word.
412 mask = ((xfs_rtword_t)1 << lastbit) - 1;
414 * Compute difference between actual and desired value.
416 if ((wdiff = (*b ^ want) & mask)) {
418 * Different, mark where we are and return.
420 xfs_trans_brelse(tp, bp);
421 i += XFS_RTLOBIT(wdiff);
422 *rtx = start + i - 1;
428 * No match, return that we scanned the whole area.
430 xfs_trans_brelse(tp, bp);
431 *rtx = start + i - 1;
436 * Read and/or modify the summary information for a given extent size,
437 * bitmap block combination.
438 * Keeps track of a current summary block, so we don't keep reading
439 * it from the buffer cache.
441 * Summary information is returned in *sum if specified.
442 * If no delta is specified, returns summary only.
445 xfs_rtmodify_summary_int(
446 xfs_mount_t *mp, /* file system mount structure */
447 xfs_trans_t *tp, /* transaction pointer */
448 int log, /* log2 of extent size */
449 xfs_fileoff_t bbno, /* bitmap block number */
450 int delta, /* change to make to summary info */
451 struct xfs_buf **rbpp, /* in/out: summary block buffer */
452 xfs_fileoff_t *rsb, /* in/out: summary block number */
453 xfs_suminfo_t *sum) /* out: summary info for this block */
455 struct xfs_buf *bp; /* buffer for the summary block */
456 int error; /* error value */
457 xfs_fileoff_t sb; /* summary fsblock */
458 xfs_rtsumoff_t so; /* index into the summary file */
459 xfs_suminfo_t *sp; /* pointer to returned data */
460 unsigned int infoword;
463 * Compute entry number in the summary file.
465 so = xfs_rtsumoffs(mp, log, bbno);
467 * Compute the block number in the summary file.
469 sb = xfs_rtsumoffs_to_block(mp, so);
471 * If we have an old buffer, and the block number matches, use that.
473 if (*rbpp && *rsb == sb)
476 * Otherwise we have to get the buffer.
480 * If there was an old one, get rid of it first.
483 xfs_trans_brelse(tp, *rbpp);
484 error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
489 * Remember this buffer and block for the next call.
495 * Point to the summary information, modify/log it, and/or copy it out.
497 infoword = xfs_rtsumoffs_to_infoword(mp, so);
498 sp = xfs_rsumblock_infoptr(bp, infoword);
500 uint first = (uint)((char *)sp - (char *)bp->b_addr);
503 if (mp->m_rsum_cache) {
504 if (*sp == 0 && log == mp->m_rsum_cache[bbno])
505 mp->m_rsum_cache[bbno]++;
506 if (*sp != 0 && log < mp->m_rsum_cache[bbno])
507 mp->m_rsum_cache[bbno] = log;
509 xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
517 xfs_rtmodify_summary(
518 xfs_mount_t *mp, /* file system mount structure */
519 xfs_trans_t *tp, /* transaction pointer */
520 int log, /* log2 of extent size */
521 xfs_fileoff_t bbno, /* bitmap block number */
522 int delta, /* change to make to summary info */
523 struct xfs_buf **rbpp, /* in/out: summary block buffer */
524 xfs_fileoff_t *rsb) /* in/out: summary block number */
526 return xfs_rtmodify_summary_int(mp, tp, log, bbno,
527 delta, rbpp, rsb, NULL);
531 * Set the given range of bitmap bits to the given value.
532 * Do whatever I/O and logging is required.
536 xfs_mount_t *mp, /* file system mount point */
537 xfs_trans_t *tp, /* transaction pointer */
538 xfs_rtxnum_t start, /* starting rtext to modify */
539 xfs_rtxlen_t len, /* length of extent to modify */
540 int val) /* 1 for free, 0 for allocated */
542 xfs_rtword_t *b; /* current word in buffer */
543 int bit; /* bit number in the word */
544 xfs_fileoff_t block; /* bitmap block number */
545 struct xfs_buf *bp; /* buf for the block */
546 int error; /* error value */
547 xfs_rtword_t *first; /* first used word in the buffer */
548 int i; /* current bit number rel. to start */
549 int lastbit; /* last useful bit in word */
550 xfs_rtword_t mask; /* mask o frelevant bits for value */
551 unsigned int word; /* word number in the buffer */
554 * Compute starting bitmap block number.
556 block = xfs_rtx_to_rbmblock(mp, start);
558 * Read the bitmap block, and point to its data.
560 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
566 * Compute the starting word's address, and starting bit.
568 word = xfs_rtx_to_rbmword(mp, start);
569 first = b = xfs_rbmblock_wordptr(bp, word);
570 bit = (int)(start & (XFS_NBWORD - 1));
572 * 0 (allocated) => all zeroes; 1 (free) => all ones.
576 * If not starting on a word boundary, deal with the first
581 * Compute first bit not changed and mask of relevant bits.
583 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
584 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
586 * Set/clear the active bits.
594 * Go on to the next block if that's where the next word is
595 * and we need the next word.
597 if (++word == mp->m_blockwsize && i < len) {
599 * Log the changed part of this block.
602 xfs_trans_log_buf(tp, bp,
603 (uint)((char *)first - (char *)bp->b_addr),
604 (uint)((char *)b - (char *)bp->b_addr));
605 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
611 first = b = xfs_rbmblock_wordptr(bp, word);
614 * Go on to the next word in the buffer
620 * Starting on a word boundary, no partial word.
625 * Loop over whole words in buffers. When we use up one buffer
626 * we move on to the next one.
628 while (len - i >= XFS_NBWORD) {
630 * Set the word value correctly.
635 * Go on to the next block if that's where the next word is
636 * and we need the next word.
638 if (++word == mp->m_blockwsize && i < len) {
640 * Log the changed part of this block.
643 xfs_trans_log_buf(tp, bp,
644 (uint)((char *)first - (char *)bp->b_addr),
645 (uint)((char *)b - (char *)bp->b_addr));
646 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
652 first = b = xfs_rbmblock_wordptr(bp, word);
655 * Go on to the next word in the buffer
661 * If not ending on a word boundary, deal with the last
664 if ((lastbit = len - i)) {
666 * Compute a mask of relevant bits.
668 mask = ((xfs_rtword_t)1 << lastbit) - 1;
670 * Set/clear the active bits.
679 * Log any remaining changed bytes.
682 xfs_trans_log_buf(tp, bp,
683 (uint)((char *)first - (char *)bp->b_addr),
684 (uint)((char *)b - (char *)bp->b_addr - 1));
689 * Mark an extent specified by start and len freed.
690 * Updates all the summary information as well as the bitmap.
694 xfs_mount_t *mp, /* file system mount point */
695 xfs_trans_t *tp, /* transaction pointer */
696 xfs_rtxnum_t start, /* starting rtext to free */
697 xfs_rtxlen_t len, /* length to free */
698 struct xfs_buf **rbpp, /* in/out: summary block buffer */
699 xfs_fileoff_t *rsb) /* in/out: summary block number */
701 xfs_rtxnum_t end; /* end of the freed extent */
702 int error; /* error value */
703 xfs_rtxnum_t postblock; /* first rtext freed > end */
704 xfs_rtxnum_t preblock; /* first rtext freed < start */
706 end = start + len - 1;
708 * Modify the bitmap to mark this extent freed.
710 error = xfs_rtmodify_range(mp, tp, start, len, 1);
715 * Assume we're freeing out of the middle of an allocated extent.
716 * We need to find the beginning and end of the extent so we can
717 * properly update the summary.
719 error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
724 * Find the next allocated block (end of allocated extent).
726 error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
731 * If there are blocks not being freed at the front of the
732 * old extent, add summary data for them to be allocated.
734 if (preblock < start) {
735 error = xfs_rtmodify_summary(mp, tp,
736 XFS_RTBLOCKLOG(start - preblock),
737 xfs_rtx_to_rbmblock(mp, preblock), -1, rbpp, rsb);
743 * If there are blocks not being freed at the end of the
744 * old extent, add summary data for them to be allocated.
746 if (postblock > end) {
747 error = xfs_rtmodify_summary(mp, tp,
748 XFS_RTBLOCKLOG(postblock - end),
749 xfs_rtx_to_rbmblock(mp, end + 1), -1, rbpp, rsb);
755 * Increment the summary information corresponding to the entire
758 error = xfs_rtmodify_summary(mp, tp,
759 XFS_RTBLOCKLOG(postblock + 1 - preblock),
760 xfs_rtx_to_rbmblock(mp, preblock), 1, rbpp, rsb);
765 * Check that the given range is either all allocated (val = 0) or
766 * all free (val = 1).
770 xfs_mount_t *mp, /* file system mount point */
771 xfs_trans_t *tp, /* transaction pointer */
772 xfs_rtxnum_t start, /* starting rtext number of extent */
773 xfs_rtxlen_t len, /* length of extent */
774 int val, /* 1 for free, 0 for allocated */
775 xfs_rtxnum_t *new, /* out: first rtext not matching */
776 int *stat) /* out: 1 for matches, 0 for not */
778 xfs_rtword_t *b; /* current word in buffer */
779 int bit; /* bit number in the word */
780 xfs_fileoff_t block; /* bitmap block number */
781 struct xfs_buf *bp; /* buf for the block */
782 int error; /* error value */
783 xfs_rtxnum_t i; /* current bit number rel. to start */
784 xfs_rtxnum_t lastbit; /* last useful bit in word */
785 xfs_rtword_t mask; /* mask of relevant bits for value */
786 xfs_rtword_t wdiff; /* difference from wanted value */
787 unsigned int word; /* word number in the buffer */
790 * Compute starting bitmap block number
792 block = xfs_rtx_to_rbmblock(mp, start);
794 * Read the bitmap block.
796 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
802 * Compute the starting word's address, and starting bit.
804 word = xfs_rtx_to_rbmword(mp, start);
805 b = xfs_rbmblock_wordptr(bp, word);
806 bit = (int)(start & (XFS_NBWORD - 1));
808 * 0 (allocated) => all zero's; 1 (free) => all one's.
812 * If not starting on a word boundary, deal with the first
817 * Compute first bit not examined.
819 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
821 * Mask of relevant bits.
823 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
825 * Compute difference between actual and desired value.
827 if ((wdiff = (*b ^ val) & mask)) {
829 * Different, compute first wrong bit and return.
831 xfs_trans_brelse(tp, bp);
832 i = XFS_RTLOBIT(wdiff) - bit;
839 * Go on to next block if that's where the next word is
840 * and we need the next word.
842 if (++word == mp->m_blockwsize && i < len) {
844 * If done with this block, get the next one.
846 xfs_trans_brelse(tp, bp);
847 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
853 b = xfs_rbmblock_wordptr(bp, word);
856 * Go on to the next word in the buffer.
862 * Starting on a word boundary, no partial word.
867 * Loop over whole words in buffers. When we use up one buffer
868 * we move on to the next one.
870 while (len - i >= XFS_NBWORD) {
872 * Compute difference between actual and desired value.
874 if ((wdiff = *b ^ val)) {
876 * Different, compute first wrong bit and return.
878 xfs_trans_brelse(tp, bp);
879 i += XFS_RTLOBIT(wdiff);
886 * Go on to next block if that's where the next word is
887 * and we need the next word.
889 if (++word == mp->m_blockwsize && i < len) {
891 * If done with this block, get the next one.
893 xfs_trans_brelse(tp, bp);
894 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
900 b = xfs_rbmblock_wordptr(bp, word);
903 * Go on to the next word in the buffer.
909 * If not ending on a word boundary, deal with the last
912 if ((lastbit = len - i)) {
914 * Mask of relevant bits.
916 mask = ((xfs_rtword_t)1 << lastbit) - 1;
918 * Compute difference between actual and desired value.
920 if ((wdiff = (*b ^ val) & mask)) {
922 * Different, compute first wrong bit and return.
924 xfs_trans_brelse(tp, bp);
925 i += XFS_RTLOBIT(wdiff);
933 * Successful, return.
935 xfs_trans_brelse(tp, bp);
943 * Check that the given extent (block range) is allocated already.
945 STATIC int /* error */
946 xfs_rtcheck_alloc_range(
947 xfs_mount_t *mp, /* file system mount point */
948 xfs_trans_t *tp, /* transaction pointer */
949 xfs_rtxnum_t start, /* starting rtext number of extent */
950 xfs_rtxlen_t len) /* length of extent */
952 xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */
956 error = xfs_rtcheck_range(mp, tp, start, len, 0, &new, &stat);
963 #define xfs_rtcheck_alloc_range(m,t,b,l) (0)
966 * Free an extent in the realtime subvolume. Length is expressed in
967 * realtime extents, as is the block number.
971 xfs_trans_t *tp, /* transaction pointer */
972 xfs_rtxnum_t start, /* starting rtext number to free */
973 xfs_rtxlen_t len) /* length of extent freed */
975 int error; /* error value */
976 xfs_mount_t *mp; /* file system mount structure */
977 xfs_fsblock_t sb; /* summary file block number */
978 struct xfs_buf *sumbp = NULL; /* summary file block buffer */
982 ASSERT(mp->m_rbmip->i_itemp != NULL);
983 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
985 error = xfs_rtcheck_alloc_range(mp, tp, start, len);
990 * Free the range of realtime blocks.
992 error = xfs_rtfree_range(mp, tp, start, len, &sumbp, &sb);
997 * Mark more blocks free in the superblock.
999 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
1001 * If we've now freed all the blocks, reset the file sequence
1004 if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
1005 mp->m_sb.sb_rextents) {
1006 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
1007 mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
1008 *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
1009 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
1015 * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
1016 * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
1017 * cannot exceed XFS_MAX_BMBT_EXTLEN.
1021 struct xfs_trans *tp,
1022 xfs_fsblock_t rtbno,
1023 xfs_filblks_t rtlen)
1025 struct xfs_mount *mp = tp->t_mountp;
1030 ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
1032 len = xfs_rtb_to_rtxrem(mp, rtlen, &mod);
1038 start = xfs_rtb_to_rtxrem(mp, rtbno, &mod);
1044 return xfs_rtfree_extent(tp, start, len);
1047 /* Find all the free records within a given range. */
1049 xfs_rtalloc_query_range(
1050 struct xfs_mount *mp,
1051 struct xfs_trans *tp,
1052 const struct xfs_rtalloc_rec *low_rec,
1053 const struct xfs_rtalloc_rec *high_rec,
1054 xfs_rtalloc_query_range_fn fn,
1057 struct xfs_rtalloc_rec rec;
1058 xfs_rtxnum_t rtstart;
1060 xfs_rtxnum_t high_key;
1064 if (low_rec->ar_startext > high_rec->ar_startext)
1066 if (low_rec->ar_startext >= mp->m_sb.sb_rextents ||
1067 low_rec->ar_startext == high_rec->ar_startext)
1070 high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1);
1072 /* Iterate the bitmap, looking for discrepancies. */
1073 rtstart = low_rec->ar_startext;
1074 while (rtstart <= high_key) {
1075 /* Is the first block free? */
1076 error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend,
1081 /* How long does the extent go for? */
1082 error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend);
1087 rec.ar_startext = rtstart;
1088 rec.ar_extcount = rtend - rtstart + 1;
1090 error = fn(mp, tp, &rec, priv);
1095 rtstart = rtend + 1;
1101 /* Find all the free records. */
1103 xfs_rtalloc_query_all(
1104 struct xfs_mount *mp,
1105 struct xfs_trans *tp,
1106 xfs_rtalloc_query_range_fn fn,
1109 struct xfs_rtalloc_rec keys[2];
1111 keys[0].ar_startext = 0;
1112 keys[1].ar_startext = mp->m_sb.sb_rextents - 1;
1113 keys[0].ar_extcount = keys[1].ar_extcount = 0;
1115 return xfs_rtalloc_query_range(mp, tp, &keys[0], &keys[1], fn, priv);
1118 /* Is the given extent all free? */
1120 xfs_rtalloc_extent_is_free(
1121 struct xfs_mount *mp,
1122 struct xfs_trans *tp,
1131 error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches);
1140 * Compute the number of rtbitmap blocks needed to track the given number of rt
1144 xfs_rtbitmap_blockcount(
1145 struct xfs_mount *mp,
1146 xfs_rtbxlen_t rtextents)
1148 return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize);
1152 * Compute the number of rtbitmap words needed to populate every block of a
1153 * bitmap that is large enough to track the given number of rt extents.
1156 xfs_rtbitmap_wordcount(
1157 struct xfs_mount *mp,
1158 xfs_rtbxlen_t rtextents)
1160 xfs_filblks_t blocks;
1162 blocks = xfs_rtbitmap_blockcount(mp, rtextents);
1163 return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;