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