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