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_rtblock_t start, /* starting block to look at */
99 xfs_rtblock_t limit, /* last block to look at */
100 xfs_rtblock_t *rtblock) /* out: start block 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 xfs_rtword_t *bufp; /* starting word in buffer */
107 int error; /* error value */
108 xfs_rtblock_t firstbit; /* first useful bit in the word */
109 xfs_rtblock_t i; /* current bit number rel. to start */
110 xfs_rtblock_t len; /* length of inspected area */
111 xfs_rtword_t mask; /* mask of relevant bits for value */
112 xfs_rtword_t want; /* mask for "good" values */
113 xfs_rtword_t wdiff; /* difference from wanted value */
114 int word; /* word number in the buffer */
117 * Compute and read in starting bitmap block for starting block.
119 block = XFS_BITTOBLOCK(mp, start);
120 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
126 * Get the first word's index & point to it.
128 word = XFS_BITTOWORD(mp, start);
130 bit = (int)(start & (XFS_NBWORD - 1));
131 len = start - limit + 1;
133 * Compute match value, based on the bit at start: if 1 (free)
134 * then all-ones, else all-zeroes.
136 want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
138 * If the starting position is not word-aligned, deal with the
141 if (bit < XFS_NBWORD - 1) {
143 * Calculate first (leftmost) bit number to look at,
144 * and mask for all the relevant bits in this word.
146 firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
147 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
150 * Calculate the difference between the value there
151 * and what we're looking for.
153 if ((wdiff = (*b ^ want) & mask)) {
155 * Different. Mark where we are and return.
157 xfs_trans_brelse(tp, bp);
158 i = bit - XFS_RTHIBIT(wdiff);
159 *rtblock = start - i + 1;
162 i = bit - firstbit + 1;
164 * Go on to previous block if that's where the previous word is
165 * and we need the previous word.
167 if (--word == -1 && i < len) {
169 * If done with this block, get the previous one.
171 xfs_trans_brelse(tp, bp);
172 error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
177 word = XFS_BLOCKWMASK(mp);
181 * Go on to the previous word in the buffer.
187 * Starting on a word boundary, no partial word.
192 * Loop over whole words in buffers. When we use up one buffer
193 * we move on to the previous one.
195 while (len - i >= XFS_NBWORD) {
197 * Compute difference between actual and desired value.
199 if ((wdiff = *b ^ want)) {
201 * Different, mark where we are and return.
203 xfs_trans_brelse(tp, bp);
204 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
205 *rtblock = start - i + 1;
210 * Go on to previous block if that's where the previous word is
211 * and we need the previous word.
213 if (--word == -1 && i < len) {
215 * If done with this block, get the previous one.
217 xfs_trans_brelse(tp, bp);
218 error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
223 word = XFS_BLOCKWMASK(mp);
227 * Go on to the previous word in the buffer.
233 * If not ending on a word boundary, deal with the last
238 * Calculate first (leftmost) bit number to look at,
239 * and mask for all the relevant bits in this word.
241 firstbit = XFS_NBWORD - (len - i);
242 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
244 * Compute difference between actual and desired value.
246 if ((wdiff = (*b ^ want) & mask)) {
248 * Different, mark where we are and return.
250 xfs_trans_brelse(tp, bp);
251 i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
252 *rtblock = start - i + 1;
258 * No match, return that we scanned the whole area.
260 xfs_trans_brelse(tp, bp);
261 *rtblock = start - i + 1;
266 * Searching forward from start to limit, find the first block whose
267 * allocated/free state is different from start's.
271 xfs_mount_t *mp, /* file system mount point */
272 xfs_trans_t *tp, /* transaction pointer */
273 xfs_rtblock_t start, /* starting block to look at */
274 xfs_rtblock_t limit, /* last block to look at */
275 xfs_rtblock_t *rtblock) /* out: start block found */
277 xfs_rtword_t *b; /* current word in buffer */
278 int bit; /* bit number in the word */
279 xfs_fileoff_t block; /* bitmap block number */
280 struct xfs_buf *bp; /* buf for the block */
281 xfs_rtword_t *bufp; /* starting word in buffer */
282 int error; /* error value */
283 xfs_rtblock_t i; /* current bit number rel. to start */
284 xfs_rtblock_t lastbit; /* last useful bit in the word */
285 xfs_rtblock_t len; /* length of inspected area */
286 xfs_rtword_t mask; /* mask of relevant bits for value */
287 xfs_rtword_t want; /* mask for "good" values */
288 xfs_rtword_t wdiff; /* difference from wanted value */
289 int word; /* word number in the buffer */
292 * Compute and read in starting bitmap block for starting block.
294 block = XFS_BITTOBLOCK(mp, start);
295 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
301 * Get the first word's index & point to it.
303 word = XFS_BITTOWORD(mp, start);
305 bit = (int)(start & (XFS_NBWORD - 1));
306 len = limit - start + 1;
308 * Compute match value, based on the bit at start: if 1 (free)
309 * then all-ones, else all-zeroes.
311 want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
313 * If the starting position is not word-aligned, deal with the
318 * Calculate last (rightmost) bit number to look at,
319 * and mask for all the relevant bits in this word.
321 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
322 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
324 * Calculate the difference between the value there
325 * and what we're looking for.
327 if ((wdiff = (*b ^ want) & mask)) {
329 * Different. Mark where we are and return.
331 xfs_trans_brelse(tp, bp);
332 i = XFS_RTLOBIT(wdiff) - bit;
333 *rtblock = start + i - 1;
338 * Go on to next block if that's where the next word is
339 * and we need the next word.
341 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
343 * If done with this block, get the previous one.
345 xfs_trans_brelse(tp, bp);
346 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
350 b = bufp = bp->b_addr;
354 * Go on to the previous word in the buffer.
360 * Starting on a word boundary, no partial word.
365 * Loop over whole words in buffers. When we use up one buffer
366 * we move on to the next one.
368 while (len - i >= XFS_NBWORD) {
370 * Compute difference between actual and desired value.
372 if ((wdiff = *b ^ want)) {
374 * Different, mark where we are and return.
376 xfs_trans_brelse(tp, bp);
377 i += XFS_RTLOBIT(wdiff);
378 *rtblock = start + i - 1;
383 * Go on to next block if that's where the next word is
384 * and we need the next word.
386 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
388 * If done with this block, get the next one.
390 xfs_trans_brelse(tp, bp);
391 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
395 b = bufp = bp->b_addr;
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 *rtblock = start + i - 1;
428 * No match, return that we scanned the whole area.
430 xfs_trans_brelse(tp, bp);
431 *rtblock = 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 int so; /* index into the summary file */
459 xfs_suminfo_t *sp; /* pointer to returned data */
462 * Compute entry number in the summary file.
464 so = XFS_SUMOFFS(mp, log, bbno);
466 * Compute the block number in the summary file.
468 sb = XFS_SUMOFFSTOBLOCK(mp, so);
470 * If we have an old buffer, and the block number matches, use that.
472 if (*rbpp && *rsb == sb)
475 * Otherwise we have to get the buffer.
479 * If there was an old one, get rid of it first.
482 xfs_trans_brelse(tp, *rbpp);
483 error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
488 * Remember this buffer and block for the next call.
494 * Point to the summary information, modify/log it, and/or copy it out.
496 sp = XFS_SUMPTR(mp, bp, so);
498 uint first = (uint)((char *)sp - (char *)bp->b_addr);
501 if (mp->m_rsum_cache) {
502 if (*sp == 0 && log == mp->m_rsum_cache[bbno])
503 mp->m_rsum_cache[bbno]++;
504 if (*sp != 0 && log < mp->m_rsum_cache[bbno])
505 mp->m_rsum_cache[bbno] = log;
507 xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
515 xfs_rtmodify_summary(
516 xfs_mount_t *mp, /* file system mount structure */
517 xfs_trans_t *tp, /* transaction pointer */
518 int log, /* log2 of extent size */
519 xfs_fileoff_t bbno, /* bitmap block number */
520 int delta, /* change to make to summary info */
521 struct xfs_buf **rbpp, /* in/out: summary block buffer */
522 xfs_fileoff_t *rsb) /* in/out: summary block number */
524 return xfs_rtmodify_summary_int(mp, tp, log, bbno,
525 delta, rbpp, rsb, NULL);
529 * Set the given range of bitmap bits to the given value.
530 * Do whatever I/O and logging is required.
534 xfs_mount_t *mp, /* file system mount point */
535 xfs_trans_t *tp, /* transaction pointer */
536 xfs_rtblock_t start, /* starting block to modify */
537 xfs_rtxlen_t len, /* length of extent to modify */
538 int val) /* 1 for free, 0 for allocated */
540 xfs_rtword_t *b; /* current word in buffer */
541 int bit; /* bit number in the word */
542 xfs_fileoff_t block; /* bitmap block number */
543 struct xfs_buf *bp; /* buf for the block */
544 xfs_rtword_t *bufp; /* starting word in buffer */
545 int error; /* error value */
546 xfs_rtword_t *first; /* first used word in the buffer */
547 int i; /* current bit number rel. to start */
548 int lastbit; /* last useful bit in word */
549 xfs_rtword_t mask; /* mask o frelevant bits for value */
550 int word; /* word number in the buffer */
553 * Compute starting bitmap block number.
555 block = XFS_BITTOBLOCK(mp, start);
557 * Read the bitmap block, and point to its data.
559 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
565 * Compute the starting word's address, and starting bit.
567 word = XFS_BITTOWORD(mp, start);
568 first = b = &bufp[word];
569 bit = (int)(start & (XFS_NBWORD - 1));
571 * 0 (allocated) => all zeroes; 1 (free) => all ones.
575 * If not starting on a word boundary, deal with the first
580 * Compute first bit not changed and mask of relevant bits.
582 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
583 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
585 * Set/clear the active bits.
593 * Go on to the next block if that's where the next word is
594 * and we need the next word.
596 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
598 * Log the changed part of this block.
601 xfs_trans_log_buf(tp, bp,
602 (uint)((char *)first - (char *)bufp),
603 (uint)((char *)b - (char *)bufp));
604 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
608 first = b = bufp = bp->b_addr;
612 * Go on to the next word in the buffer
618 * Starting on a word boundary, no partial word.
623 * Loop over whole words in buffers. When we use up one buffer
624 * we move on to the next one.
626 while (len - i >= XFS_NBWORD) {
628 * Set the word value correctly.
633 * Go on to the next block if that's where the next word is
634 * and we need the next word.
636 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
638 * Log the changed part of this block.
641 xfs_trans_log_buf(tp, bp,
642 (uint)((char *)first - (char *)bufp),
643 (uint)((char *)b - (char *)bufp));
644 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
648 first = b = bufp = bp->b_addr;
652 * Go on to the next word in the buffer
658 * If not ending on a word boundary, deal with the last
661 if ((lastbit = len - i)) {
663 * Compute a mask of relevant bits.
665 mask = ((xfs_rtword_t)1 << lastbit) - 1;
667 * Set/clear the active bits.
676 * Log any remaining changed bytes.
679 xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),
680 (uint)((char *)b - (char *)bufp - 1));
685 * Mark an extent specified by start and len freed.
686 * Updates all the summary information as well as the bitmap.
690 xfs_mount_t *mp, /* file system mount point */
691 xfs_trans_t *tp, /* transaction pointer */
692 xfs_rtblock_t start, /* starting block to free */
693 xfs_rtxlen_t len, /* length to free */
694 struct xfs_buf **rbpp, /* in/out: summary block buffer */
695 xfs_fileoff_t *rsb) /* in/out: summary block number */
697 xfs_rtblock_t end; /* end of the freed extent */
698 int error; /* error value */
699 xfs_rtblock_t postblock; /* first block freed > end */
700 xfs_rtblock_t preblock; /* first block freed < start */
702 end = start + len - 1;
704 * Modify the bitmap to mark this extent freed.
706 error = xfs_rtmodify_range(mp, tp, start, len, 1);
711 * Assume we're freeing out of the middle of an allocated extent.
712 * We need to find the beginning and end of the extent so we can
713 * properly update the summary.
715 error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
720 * Find the next allocated block (end of allocated extent).
722 error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
727 * If there are blocks not being freed at the front of the
728 * old extent, add summary data for them to be allocated.
730 if (preblock < start) {
731 error = xfs_rtmodify_summary(mp, tp,
732 XFS_RTBLOCKLOG(start - preblock),
733 XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
739 * If there are blocks not being freed at the end of the
740 * old extent, add summary data for them to be allocated.
742 if (postblock > end) {
743 error = xfs_rtmodify_summary(mp, tp,
744 XFS_RTBLOCKLOG(postblock - end),
745 XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb);
751 * Increment the summary information corresponding to the entire
754 error = xfs_rtmodify_summary(mp, tp,
755 XFS_RTBLOCKLOG(postblock + 1 - preblock),
756 XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
761 * Check that the given range is either all allocated (val = 0) or
762 * all free (val = 1).
766 xfs_mount_t *mp, /* file system mount point */
767 xfs_trans_t *tp, /* transaction pointer */
768 xfs_rtblock_t start, /* starting block number of extent */
769 xfs_rtxlen_t len, /* length of extent */
770 int val, /* 1 for free, 0 for allocated */
771 xfs_rtblock_t *new, /* out: first block not matching */
772 int *stat) /* out: 1 for matches, 0 for not */
774 xfs_rtword_t *b; /* current word in buffer */
775 int bit; /* bit number in the word */
776 xfs_fileoff_t block; /* bitmap block number */
777 struct xfs_buf *bp; /* buf for the block */
778 xfs_rtword_t *bufp; /* starting word in buffer */
779 int error; /* error value */
780 xfs_rtblock_t i; /* current bit number rel. to start */
781 xfs_rtblock_t lastbit; /* last useful bit in word */
782 xfs_rtword_t mask; /* mask of relevant bits for value */
783 xfs_rtword_t wdiff; /* difference from wanted value */
784 int word; /* word number in the buffer */
787 * Compute starting bitmap block number
789 block = XFS_BITTOBLOCK(mp, start);
791 * Read the bitmap block.
793 error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
799 * Compute the starting word's address, and starting bit.
801 word = XFS_BITTOWORD(mp, start);
803 bit = (int)(start & (XFS_NBWORD - 1));
805 * 0 (allocated) => all zero's; 1 (free) => all one's.
809 * If not starting on a word boundary, deal with the first
814 * Compute first bit not examined.
816 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
818 * Mask of relevant bits.
820 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
822 * Compute difference between actual and desired value.
824 if ((wdiff = (*b ^ val) & mask)) {
826 * Different, compute first wrong bit and return.
828 xfs_trans_brelse(tp, bp);
829 i = XFS_RTLOBIT(wdiff) - bit;
836 * Go on to next block if that's where the next word is
837 * and we need the next word.
839 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
841 * If done with this block, get the next one.
843 xfs_trans_brelse(tp, bp);
844 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
848 b = bufp = bp->b_addr;
852 * Go on to the next word in the buffer.
858 * Starting on a word boundary, no partial word.
863 * Loop over whole words in buffers. When we use up one buffer
864 * we move on to the next one.
866 while (len - i >= XFS_NBWORD) {
868 * Compute difference between actual and desired value.
870 if ((wdiff = *b ^ val)) {
872 * Different, compute first wrong bit and return.
874 xfs_trans_brelse(tp, bp);
875 i += XFS_RTLOBIT(wdiff);
882 * Go on to next block if that's where the next word is
883 * and we need the next word.
885 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
887 * If done with this block, get the next one.
889 xfs_trans_brelse(tp, bp);
890 error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
894 b = bufp = bp->b_addr;
898 * Go on to the next word in the buffer.
904 * If not ending on a word boundary, deal with the last
907 if ((lastbit = len - i)) {
909 * Mask of relevant bits.
911 mask = ((xfs_rtword_t)1 << lastbit) - 1;
913 * Compute difference between actual and desired value.
915 if ((wdiff = (*b ^ val) & mask)) {
917 * Different, compute first wrong bit and return.
919 xfs_trans_brelse(tp, bp);
920 i += XFS_RTLOBIT(wdiff);
928 * Successful, return.
930 xfs_trans_brelse(tp, bp);
938 * Check that the given extent (block range) is allocated already.
940 STATIC int /* error */
941 xfs_rtcheck_alloc_range(
942 xfs_mount_t *mp, /* file system mount point */
943 xfs_trans_t *tp, /* transaction pointer */
944 xfs_rtblock_t bno, /* starting block number of extent */
945 xfs_rtxlen_t len) /* length of extent */
947 xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */
951 error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat);
958 #define xfs_rtcheck_alloc_range(m,t,b,l) (0)
961 * Free an extent in the realtime subvolume. Length is expressed in
962 * realtime extents, as is the block number.
966 xfs_trans_t *tp, /* transaction pointer */
967 xfs_rtblock_t bno, /* starting block number to free */
968 xfs_rtxlen_t len) /* length of extent freed */
970 int error; /* error value */
971 xfs_mount_t *mp; /* file system mount structure */
972 xfs_fsblock_t sb; /* summary file block number */
973 struct xfs_buf *sumbp = NULL; /* summary file block buffer */
977 ASSERT(mp->m_rbmip->i_itemp != NULL);
978 ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
980 error = xfs_rtcheck_alloc_range(mp, tp, bno, len);
985 * Free the range of realtime blocks.
987 error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb);
992 * Mark more blocks free in the superblock.
994 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
996 * If we've now freed all the blocks, reset the file sequence
999 if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
1000 mp->m_sb.sb_rextents) {
1001 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
1002 mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
1003 *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
1004 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
1010 * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
1011 * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
1012 * cannot exceed XFS_MAX_BMBT_EXTLEN.
1016 struct xfs_trans *tp,
1017 xfs_fsblock_t rtbno,
1018 xfs_filblks_t rtlen)
1020 struct xfs_mount *mp = tp->t_mountp;
1025 ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
1027 len = div_u64_rem(rtlen, mp->m_sb.sb_rextsize, &mod);
1033 bno = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod);
1039 return xfs_rtfree_extent(tp, bno, len);
1042 /* Find all the free records within a given range. */
1044 xfs_rtalloc_query_range(
1045 struct xfs_mount *mp,
1046 struct xfs_trans *tp,
1047 const struct xfs_rtalloc_rec *low_rec,
1048 const struct xfs_rtalloc_rec *high_rec,
1049 xfs_rtalloc_query_range_fn fn,
1052 struct xfs_rtalloc_rec rec;
1053 xfs_rtblock_t rtstart;
1054 xfs_rtblock_t rtend;
1055 xfs_rtblock_t high_key;
1059 if (low_rec->ar_startext > high_rec->ar_startext)
1061 if (low_rec->ar_startext >= mp->m_sb.sb_rextents ||
1062 low_rec->ar_startext == high_rec->ar_startext)
1065 high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1);
1067 /* Iterate the bitmap, looking for discrepancies. */
1068 rtstart = low_rec->ar_startext;
1069 while (rtstart <= high_key) {
1070 /* Is the first block free? */
1071 error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend,
1076 /* How long does the extent go for? */
1077 error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend);
1082 rec.ar_startext = rtstart;
1083 rec.ar_extcount = rtend - rtstart + 1;
1085 error = fn(mp, tp, &rec, priv);
1090 rtstart = rtend + 1;
1096 /* Find all the free records. */
1098 xfs_rtalloc_query_all(
1099 struct xfs_mount *mp,
1100 struct xfs_trans *tp,
1101 xfs_rtalloc_query_range_fn fn,
1104 struct xfs_rtalloc_rec keys[2];
1106 keys[0].ar_startext = 0;
1107 keys[1].ar_startext = mp->m_sb.sb_rextents - 1;
1108 keys[0].ar_extcount = keys[1].ar_extcount = 0;
1110 return xfs_rtalloc_query_range(mp, tp, &keys[0], &keys[1], fn, priv);
1113 /* Is the given extent all free? */
1115 xfs_rtalloc_extent_is_free(
1116 struct xfs_mount *mp,
1117 struct xfs_trans *tp,
1118 xfs_rtblock_t start,
1126 error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches);