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_bmap_btree.h"
17 #include "xfs_trans_space.h"
18 #include "xfs_trans.h"
19 #include "xfs_rtalloc.h"
20 #include "xfs_error.h"
21 #include "xfs_rtbitmap.h"
22 #include "xfs_health.h"
23
24 /*
25 * Realtime allocator bitmap functions shared with userspace.
26 */
27
28 /*
29 * Real time buffers need verifiers to avoid runtime warnings during IO.
30 * We don't have anything to verify, however, so these are just dummy
31 * operations.
32 */
33 static void
xfs_rtbuf_verify_read(struct xfs_buf * bp)34 xfs_rtbuf_verify_read(
35 struct xfs_buf *bp)
36 {
37 return;
38 }
39
40 static void
xfs_rtbuf_verify_write(struct xfs_buf * bp)41 xfs_rtbuf_verify_write(
42 struct xfs_buf *bp)
43 {
44 return;
45 }
46
47 const struct xfs_buf_ops xfs_rtbuf_ops = {
48 .name = "rtbuf",
49 .verify_read = xfs_rtbuf_verify_read,
50 .verify_write = xfs_rtbuf_verify_write,
51 };
52
53 /* Release cached rt bitmap and summary buffers. */
54 void
xfs_rtbuf_cache_relse(struct xfs_rtalloc_args * args)55 xfs_rtbuf_cache_relse(
56 struct xfs_rtalloc_args *args)
57 {
58 if (args->rbmbp) {
59 xfs_trans_brelse(args->tp, args->rbmbp);
60 args->rbmbp = NULL;
61 args->rbmoff = NULLFILEOFF;
62 }
63 if (args->sumbp) {
64 xfs_trans_brelse(args->tp, args->sumbp);
65 args->sumbp = NULL;
66 args->sumoff = NULLFILEOFF;
67 }
68 }
69
70 /*
71 * Get a buffer for the bitmap or summary file block specified.
72 * The buffer is returned read and locked.
73 */
74 static int
xfs_rtbuf_get(struct xfs_rtalloc_args * args,xfs_fileoff_t block,int issum)75 xfs_rtbuf_get(
76 struct xfs_rtalloc_args *args,
77 xfs_fileoff_t block, /* block number in bitmap or summary */
78 int issum) /* is summary not bitmap */
79 {
80 struct xfs_mount *mp = args->mp;
81 struct xfs_buf **cbpp; /* cached block buffer */
82 xfs_fileoff_t *coffp; /* cached block number */
83 struct xfs_buf *bp; /* block buffer, result */
84 struct xfs_inode *ip; /* bitmap or summary inode */
85 struct xfs_bmbt_irec map;
86 enum xfs_blft type;
87 int nmap = 1;
88 int error;
89
90 if (issum) {
91 cbpp = &args->sumbp;
92 coffp = &args->sumoff;
93 ip = mp->m_rsumip;
94 type = XFS_BLFT_RTSUMMARY_BUF;
95 } else {
96 cbpp = &args->rbmbp;
97 coffp = &args->rbmoff;
98 ip = mp->m_rbmip;
99 type = XFS_BLFT_RTBITMAP_BUF;
100 }
101
102 /*
103 * If we have a cached buffer, and the block number matches, use that.
104 */
105 if (*cbpp && *coffp == block)
106 return 0;
107
108 /*
109 * Otherwise we have to have to get the buffer. If there was an old
110 * one, get rid of it first.
111 */
112 if (*cbpp) {
113 xfs_trans_brelse(args->tp, *cbpp);
114 *cbpp = NULL;
115 }
116
117 error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0);
118 if (error)
119 return error;
120
121 if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
122 xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
123 XFS_SICK_RT_BITMAP);
124 return -EFSCORRUPTED;
125 }
126
127 ASSERT(map.br_startblock != NULLFSBLOCK);
128 error = xfs_trans_read_buf(mp, args->tp, mp->m_ddev_targp,
129 XFS_FSB_TO_DADDR(mp, map.br_startblock),
130 mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
131 if (xfs_metadata_is_sick(error))
132 xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
133 XFS_SICK_RT_BITMAP);
134 if (error)
135 return error;
136
137 xfs_trans_buf_set_type(args->tp, bp, type);
138 *cbpp = bp;
139 *coffp = block;
140 return 0;
141 }
142
143 int
xfs_rtbitmap_read_buf(struct xfs_rtalloc_args * args,xfs_fileoff_t block)144 xfs_rtbitmap_read_buf(
145 struct xfs_rtalloc_args *args,
146 xfs_fileoff_t block)
147 {
148 struct xfs_mount *mp = args->mp;
149
150 if (XFS_IS_CORRUPT(mp, block >= mp->m_sb.sb_rbmblocks)) {
151 xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP);
152 return -EFSCORRUPTED;
153 }
154
155 return xfs_rtbuf_get(args, block, 0);
156 }
157
158 int
xfs_rtsummary_read_buf(struct xfs_rtalloc_args * args,xfs_fileoff_t block)159 xfs_rtsummary_read_buf(
160 struct xfs_rtalloc_args *args,
161 xfs_fileoff_t block)
162 {
163 struct xfs_mount *mp = args->mp;
164
165 if (XFS_IS_CORRUPT(mp, block >= mp->m_rsumblocks)) {
166 xfs_rt_mark_sick(args->mp, XFS_SICK_RT_SUMMARY);
167 return -EFSCORRUPTED;
168 }
169 return xfs_rtbuf_get(args, block, 1);
170 }
171
172 /*
173 * Searching backward from start find the first block whose allocated/free state
174 * is different from start's.
175 */
176 int
xfs_rtfind_back(struct xfs_rtalloc_args * args,xfs_rtxnum_t start,xfs_rtxnum_t * rtx)177 xfs_rtfind_back(
178 struct xfs_rtalloc_args *args,
179 xfs_rtxnum_t start, /* starting rtext to look at */
180 xfs_rtxnum_t *rtx) /* out: start rtext found */
181 {
182 struct xfs_mount *mp = args->mp;
183 int bit; /* bit number in the word */
184 xfs_fileoff_t block; /* bitmap block number */
185 int error; /* error value */
186 xfs_rtxnum_t firstbit; /* first useful bit in the word */
187 xfs_rtxnum_t i; /* current bit number rel. to start */
188 xfs_rtxnum_t len; /* length of inspected area */
189 xfs_rtword_t mask; /* mask of relevant bits for value */
190 xfs_rtword_t want; /* mask for "good" values */
191 xfs_rtword_t wdiff; /* difference from wanted value */
192 xfs_rtword_t incore;
193 unsigned int word; /* word number in the buffer */
194
195 /*
196 * Compute and read in starting bitmap block for starting block.
197 */
198 block = xfs_rtx_to_rbmblock(mp, start);
199 error = xfs_rtbitmap_read_buf(args, block);
200 if (error)
201 return error;
202
203 /*
204 * Get the first word's index & point to it.
205 */
206 word = xfs_rtx_to_rbmword(mp, start);
207 bit = (int)(start & (XFS_NBWORD - 1));
208 len = start + 1;
209 /*
210 * Compute match value, based on the bit at start: if 1 (free)
211 * then all-ones, else all-zeroes.
212 */
213 incore = xfs_rtbitmap_getword(args, word);
214 want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
215 /*
216 * If the starting position is not word-aligned, deal with the
217 * partial word.
218 */
219 if (bit < XFS_NBWORD - 1) {
220 /*
221 * Calculate first (leftmost) bit number to look at,
222 * and mask for all the relevant bits in this word.
223 */
224 firstbit = max_t(xfs_srtblock_t, bit - len + 1, 0);
225 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
226 firstbit;
227 /*
228 * Calculate the difference between the value there
229 * and what we're looking for.
230 */
231 if ((wdiff = (incore ^ want) & mask)) {
232 /*
233 * Different. Mark where we are and return.
234 */
235 i = bit - xfs_highbit32(wdiff);
236 *rtx = start - i + 1;
237 return 0;
238 }
239 i = bit - firstbit + 1;
240 /*
241 * Go on to previous block if that's where the previous word is
242 * and we need the previous word.
243 */
244 if (--word == -1 && i < len) {
245 /*
246 * If done with this block, get the previous one.
247 */
248 error = xfs_rtbitmap_read_buf(args, --block);
249 if (error)
250 return error;
251
252 word = mp->m_blockwsize - 1;
253 }
254 } else {
255 /*
256 * Starting on a word boundary, no partial word.
257 */
258 i = 0;
259 }
260 /*
261 * Loop over whole words in buffers. When we use up one buffer
262 * we move on to the previous one.
263 */
264 while (len - i >= XFS_NBWORD) {
265 /*
266 * Compute difference between actual and desired value.
267 */
268 incore = xfs_rtbitmap_getword(args, word);
269 if ((wdiff = incore ^ want)) {
270 /*
271 * Different, mark where we are and return.
272 */
273 i += XFS_NBWORD - 1 - xfs_highbit32(wdiff);
274 *rtx = start - i + 1;
275 return 0;
276 }
277 i += XFS_NBWORD;
278 /*
279 * Go on to previous block if that's where the previous word is
280 * and we need the previous word.
281 */
282 if (--word == -1 && i < len) {
283 /*
284 * If done with this block, get the previous one.
285 */
286 error = xfs_rtbitmap_read_buf(args, --block);
287 if (error)
288 return error;
289
290 word = mp->m_blockwsize - 1;
291 }
292 }
293 /*
294 * If not ending on a word boundary, deal with the last
295 * (partial) word.
296 */
297 if (len - i) {
298 /*
299 * Calculate first (leftmost) bit number to look at,
300 * and mask for all the relevant bits in this word.
301 */
302 firstbit = XFS_NBWORD - (len - i);
303 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
304 /*
305 * Compute difference between actual and desired value.
306 */
307 incore = xfs_rtbitmap_getword(args, word);
308 if ((wdiff = (incore ^ want) & mask)) {
309 /*
310 * Different, mark where we are and return.
311 */
312 i += XFS_NBWORD - 1 - xfs_highbit32(wdiff);
313 *rtx = start - i + 1;
314 return 0;
315 } else
316 i = len;
317 }
318 /*
319 * No match, return that we scanned the whole area.
320 */
321 *rtx = start - i + 1;
322 return 0;
323 }
324
325 /*
326 * Searching forward from start to limit, find the first block whose
327 * allocated/free state is different from start's.
328 */
329 int
xfs_rtfind_forw(struct xfs_rtalloc_args * args,xfs_rtxnum_t start,xfs_rtxnum_t limit,xfs_rtxnum_t * rtx)330 xfs_rtfind_forw(
331 struct xfs_rtalloc_args *args,
332 xfs_rtxnum_t start, /* starting rtext to look at */
333 xfs_rtxnum_t limit, /* last rtext to look at */
334 xfs_rtxnum_t *rtx) /* out: start rtext found */
335 {
336 struct xfs_mount *mp = args->mp;
337 int bit; /* bit number in the word */
338 xfs_fileoff_t block; /* bitmap block number */
339 int error;
340 xfs_rtxnum_t i; /* current bit number rel. to start */
341 xfs_rtxnum_t lastbit;/* last useful bit in the word */
342 xfs_rtxnum_t len; /* length of inspected area */
343 xfs_rtword_t mask; /* mask of relevant bits for value */
344 xfs_rtword_t want; /* mask for "good" values */
345 xfs_rtword_t wdiff; /* difference from wanted value */
346 xfs_rtword_t incore;
347 unsigned int word; /* word number in the buffer */
348
349 ASSERT(start <= limit);
350
351 /*
352 * Compute and read in starting bitmap block for starting block.
353 */
354 block = xfs_rtx_to_rbmblock(mp, start);
355 error = xfs_rtbitmap_read_buf(args, block);
356 if (error)
357 return error;
358
359 /*
360 * Get the first word's index & point to it.
361 */
362 word = xfs_rtx_to_rbmword(mp, start);
363 bit = (int)(start & (XFS_NBWORD - 1));
364 len = limit - start + 1;
365 /*
366 * Compute match value, based on the bit at start: if 1 (free)
367 * then all-ones, else all-zeroes.
368 */
369 incore = xfs_rtbitmap_getword(args, word);
370 want = (incore & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
371 /*
372 * If the starting position is not word-aligned, deal with the
373 * partial word.
374 */
375 if (bit) {
376 /*
377 * Calculate last (rightmost) bit number to look at,
378 * and mask for all the relevant bits in this word.
379 */
380 lastbit = min(bit + len, XFS_NBWORD);
381 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
382 /*
383 * Calculate the difference between the value there
384 * and what we're looking for.
385 */
386 if ((wdiff = (incore ^ want) & mask)) {
387 /*
388 * Different. Mark where we are and return.
389 */
390 i = xfs_lowbit32(wdiff) - bit;
391 *rtx = start + i - 1;
392 return 0;
393 }
394 i = lastbit - bit;
395 /*
396 * Go on to next block if that's where the next word is
397 * and we need the next word.
398 */
399 if (++word == mp->m_blockwsize && i < len) {
400 /*
401 * If done with this block, get the previous one.
402 */
403 error = xfs_rtbitmap_read_buf(args, ++block);
404 if (error)
405 return error;
406
407 word = 0;
408 }
409 } else {
410 /*
411 * Starting on a word boundary, no partial word.
412 */
413 i = 0;
414 }
415 /*
416 * Loop over whole words in buffers. When we use up one buffer
417 * we move on to the next one.
418 */
419 while (len - i >= XFS_NBWORD) {
420 /*
421 * Compute difference between actual and desired value.
422 */
423 incore = xfs_rtbitmap_getword(args, word);
424 if ((wdiff = incore ^ want)) {
425 /*
426 * Different, mark where we are and return.
427 */
428 i += xfs_lowbit32(wdiff);
429 *rtx = start + i - 1;
430 return 0;
431 }
432 i += XFS_NBWORD;
433 /*
434 * Go on to next block if that's where the next word is
435 * and we need the next word.
436 */
437 if (++word == mp->m_blockwsize && i < len) {
438 /*
439 * If done with this block, get the next one.
440 */
441 error = xfs_rtbitmap_read_buf(args, ++block);
442 if (error)
443 return error;
444
445 word = 0;
446 }
447 }
448 /*
449 * If not ending on a word boundary, deal with the last
450 * (partial) word.
451 */
452 if ((lastbit = len - i)) {
453 /*
454 * Calculate mask for all the relevant bits in this word.
455 */
456 mask = ((xfs_rtword_t)1 << lastbit) - 1;
457 /*
458 * Compute difference between actual and desired value.
459 */
460 incore = xfs_rtbitmap_getword(args, word);
461 if ((wdiff = (incore ^ want) & mask)) {
462 /*
463 * Different, mark where we are and return.
464 */
465 i += xfs_lowbit32(wdiff);
466 *rtx = start + i - 1;
467 return 0;
468 } else
469 i = len;
470 }
471 /*
472 * No match, return that we scanned the whole area.
473 */
474 *rtx = start + i - 1;
475 return 0;
476 }
477
478 /* Log rtsummary counter at @infoword. */
479 static inline void
xfs_trans_log_rtsummary(struct xfs_rtalloc_args * args,unsigned int infoword)480 xfs_trans_log_rtsummary(
481 struct xfs_rtalloc_args *args,
482 unsigned int infoword)
483 {
484 struct xfs_buf *bp = args->sumbp;
485 size_t first, last;
486
487 first = (void *)xfs_rsumblock_infoptr(args, infoword) - bp->b_addr;
488 last = first + sizeof(xfs_suminfo_t) - 1;
489
490 xfs_trans_log_buf(args->tp, bp, first, last);
491 }
492
493 /*
494 * Modify the summary information for a given extent size, bitmap block
495 * combination.
496 */
497 int
xfs_rtmodify_summary(struct xfs_rtalloc_args * args,int log,xfs_fileoff_t bbno,int delta)498 xfs_rtmodify_summary(
499 struct xfs_rtalloc_args *args,
500 int log, /* log2 of extent size */
501 xfs_fileoff_t bbno, /* bitmap block number */
502 int delta) /* in/out: summary block number */
503 {
504 struct xfs_mount *mp = args->mp;
505 xfs_rtsumoff_t so = xfs_rtsumoffs(mp, log, bbno);
506 unsigned int infoword;
507 xfs_suminfo_t val;
508 int error;
509
510 error = xfs_rtsummary_read_buf(args, xfs_rtsumoffs_to_block(mp, so));
511 if (error)
512 return error;
513
514 infoword = xfs_rtsumoffs_to_infoword(mp, so);
515 val = xfs_suminfo_add(args, infoword, delta);
516
517 if (mp->m_rsum_cache) {
518 if (val == 0 && log + 1 == mp->m_rsum_cache[bbno])
519 mp->m_rsum_cache[bbno] = log;
520 if (val != 0 && log >= mp->m_rsum_cache[bbno])
521 mp->m_rsum_cache[bbno] = log + 1;
522 }
523
524 xfs_trans_log_rtsummary(args, infoword);
525 return 0;
526 }
527
528 /*
529 * Read and return the summary information for a given extent size, bitmap block
530 * combination.
531 */
532 int
xfs_rtget_summary(struct xfs_rtalloc_args * args,int log,xfs_fileoff_t bbno,xfs_suminfo_t * sum)533 xfs_rtget_summary(
534 struct xfs_rtalloc_args *args,
535 int log, /* log2 of extent size */
536 xfs_fileoff_t bbno, /* bitmap block number */
537 xfs_suminfo_t *sum) /* out: summary info for this block */
538 {
539 struct xfs_mount *mp = args->mp;
540 xfs_rtsumoff_t so = xfs_rtsumoffs(mp, log, bbno);
541 int error;
542
543 error = xfs_rtsummary_read_buf(args, xfs_rtsumoffs_to_block(mp, so));
544 if (!error)
545 *sum = xfs_suminfo_get(args, xfs_rtsumoffs_to_infoword(mp, so));
546 return error;
547 }
548
549 /* Log rtbitmap block from the word @from to the byte before @next. */
550 static inline void
xfs_trans_log_rtbitmap(struct xfs_rtalloc_args * args,unsigned int from,unsigned int next)551 xfs_trans_log_rtbitmap(
552 struct xfs_rtalloc_args *args,
553 unsigned int from,
554 unsigned int next)
555 {
556 struct xfs_buf *bp = args->rbmbp;
557 size_t first, last;
558
559 first = (void *)xfs_rbmblock_wordptr(args, from) - bp->b_addr;
560 last = ((void *)xfs_rbmblock_wordptr(args, next) - 1) - bp->b_addr;
561
562 xfs_trans_log_buf(args->tp, bp, first, last);
563 }
564
565 /*
566 * Set the given range of bitmap bits to the given value.
567 * Do whatever I/O and logging is required.
568 */
569 int
xfs_rtmodify_range(struct xfs_rtalloc_args * args,xfs_rtxnum_t start,xfs_rtxlen_t len,int val)570 xfs_rtmodify_range(
571 struct xfs_rtalloc_args *args,
572 xfs_rtxnum_t start, /* starting rtext to modify */
573 xfs_rtxlen_t len, /* length of extent to modify */
574 int val) /* 1 for free, 0 for allocated */
575 {
576 struct xfs_mount *mp = args->mp;
577 int bit; /* bit number in the word */
578 xfs_fileoff_t block; /* bitmap block number */
579 int error;
580 int i; /* current bit number rel. to start */
581 int lastbit; /* last useful bit in word */
582 xfs_rtword_t mask; /* mask of relevant bits for value */
583 xfs_rtword_t incore;
584 unsigned int firstword; /* first word used in the buffer */
585 unsigned int word; /* word number in the buffer */
586
587 /*
588 * Compute starting bitmap block number.
589 */
590 block = xfs_rtx_to_rbmblock(mp, start);
591 /*
592 * Read the bitmap block, and point to its data.
593 */
594 error = xfs_rtbitmap_read_buf(args, block);
595 if (error)
596 return error;
597
598 /*
599 * Compute the starting word's address, and starting bit.
600 */
601 firstword = word = xfs_rtx_to_rbmword(mp, start);
602 bit = (int)(start & (XFS_NBWORD - 1));
603 /*
604 * 0 (allocated) => all zeroes; 1 (free) => all ones.
605 */
606 val = -val;
607 /*
608 * If not starting on a word boundary, deal with the first
609 * (partial) word.
610 */
611 if (bit) {
612 /*
613 * Compute first bit not changed and mask of relevant bits.
614 */
615 lastbit = min(bit + len, XFS_NBWORD);
616 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
617 /*
618 * Set/clear the active bits.
619 */
620 incore = xfs_rtbitmap_getword(args, word);
621 if (val)
622 incore |= mask;
623 else
624 incore &= ~mask;
625 xfs_rtbitmap_setword(args, word, incore);
626 i = lastbit - bit;
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 } else {
644 /*
645 * Starting on a word boundary, no partial word.
646 */
647 i = 0;
648 }
649 /*
650 * Loop over whole words in buffers. When we use up one buffer
651 * we move on to the next one.
652 */
653 while (len - i >= XFS_NBWORD) {
654 /*
655 * Set the word value correctly.
656 */
657 xfs_rtbitmap_setword(args, word, val);
658 i += XFS_NBWORD;
659 /*
660 * Go on to the next block if that's where the next word is
661 * and we need the next word.
662 */
663 if (++word == mp->m_blockwsize && i < len) {
664 /*
665 * Log the changed part of this block.
666 * Get the next one.
667 */
668 xfs_trans_log_rtbitmap(args, firstword, word);
669 error = xfs_rtbitmap_read_buf(args, ++block);
670 if (error)
671 return error;
672
673 firstword = word = 0;
674 }
675 }
676 /*
677 * If not ending on a word boundary, deal with the last
678 * (partial) word.
679 */
680 if ((lastbit = len - i)) {
681 /*
682 * Compute a mask of relevant bits.
683 */
684 mask = ((xfs_rtword_t)1 << lastbit) - 1;
685 /*
686 * Set/clear the active bits.
687 */
688 incore = xfs_rtbitmap_getword(args, word);
689 if (val)
690 incore |= mask;
691 else
692 incore &= ~mask;
693 xfs_rtbitmap_setword(args, word, incore);
694 word++;
695 }
696 /*
697 * Log any remaining changed bytes.
698 */
699 if (word > firstword)
700 xfs_trans_log_rtbitmap(args, firstword, word);
701 return 0;
702 }
703
704 /*
705 * Mark an extent specified by start and len freed.
706 * Updates all the summary information as well as the bitmap.
707 */
708 int
xfs_rtfree_range(struct xfs_rtalloc_args * args,xfs_rtxnum_t start,xfs_rtxlen_t len)709 xfs_rtfree_range(
710 struct xfs_rtalloc_args *args,
711 xfs_rtxnum_t start, /* starting rtext to free */
712 xfs_rtxlen_t len) /* in/out: summary block number */
713 {
714 struct xfs_mount *mp = args->mp;
715 xfs_rtxnum_t end; /* end of the freed extent */
716 int error; /* error value */
717 xfs_rtxnum_t postblock; /* first rtext freed > end */
718 xfs_rtxnum_t preblock; /* first rtext freed < start */
719
720 end = start + len - 1;
721 /*
722 * Modify the bitmap to mark this extent freed.
723 */
724 error = xfs_rtmodify_range(args, start, len, 1);
725 if (error) {
726 return error;
727 }
728 /*
729 * Assume we're freeing out of the middle of an allocated extent.
730 * We need to find the beginning and end of the extent so we can
731 * properly update the summary.
732 */
733 error = xfs_rtfind_back(args, start, &preblock);
734 if (error) {
735 return error;
736 }
737 /*
738 * Find the next allocated block (end of allocated extent).
739 */
740 error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1,
741 &postblock);
742 if (error)
743 return error;
744 /*
745 * If there are blocks not being freed at the front of the
746 * old extent, add summary data for them to be allocated.
747 */
748 if (preblock < start) {
749 error = xfs_rtmodify_summary(args,
750 xfs_highbit64(start - preblock),
751 xfs_rtx_to_rbmblock(mp, preblock), -1);
752 if (error) {
753 return error;
754 }
755 }
756 /*
757 * If there are blocks not being freed at the end of the
758 * old extent, add summary data for them to be allocated.
759 */
760 if (postblock > end) {
761 error = xfs_rtmodify_summary(args,
762 xfs_highbit64(postblock - end),
763 xfs_rtx_to_rbmblock(mp, end + 1), -1);
764 if (error) {
765 return error;
766 }
767 }
768 /*
769 * Increment the summary information corresponding to the entire
770 * (new) free extent.
771 */
772 return xfs_rtmodify_summary(args,
773 xfs_highbit64(postblock + 1 - preblock),
774 xfs_rtx_to_rbmblock(mp, preblock), 1);
775 }
776
777 /*
778 * Check that the given range is either all allocated (val = 0) or
779 * all free (val = 1).
780 */
781 int
xfs_rtcheck_range(struct xfs_rtalloc_args * args,xfs_rtxnum_t start,xfs_rtxlen_t len,int val,xfs_rtxnum_t * new,int * stat)782 xfs_rtcheck_range(
783 struct xfs_rtalloc_args *args,
784 xfs_rtxnum_t start, /* starting rtext number of extent */
785 xfs_rtxlen_t len, /* length of extent */
786 int val, /* 1 for free, 0 for allocated */
787 xfs_rtxnum_t *new, /* out: first rtext not matching */
788 int *stat) /* out: 1 for matches, 0 for not */
789 {
790 struct xfs_mount *mp = args->mp;
791 int bit; /* bit number in the word */
792 xfs_fileoff_t block; /* bitmap block number */
793 int error;
794 xfs_rtxnum_t i; /* current bit number rel. to start */
795 xfs_rtxnum_t lastbit; /* last useful bit in word */
796 xfs_rtword_t mask; /* mask of relevant bits for value */
797 xfs_rtword_t wdiff; /* difference from wanted value */
798 xfs_rtword_t incore;
799 unsigned int word; /* word number in the buffer */
800
801 /*
802 * Compute starting bitmap block number
803 */
804 block = xfs_rtx_to_rbmblock(mp, start);
805 /*
806 * Read the bitmap block.
807 */
808 error = xfs_rtbitmap_read_buf(args, block);
809 if (error)
810 return error;
811
812 /*
813 * Compute the starting word's address, and starting bit.
814 */
815 word = xfs_rtx_to_rbmword(mp, start);
816 bit = (int)(start & (XFS_NBWORD - 1));
817 /*
818 * 0 (allocated) => all zero's; 1 (free) => all one's.
819 */
820 val = -val;
821 /*
822 * If not starting on a word boundary, deal with the first
823 * (partial) word.
824 */
825 if (bit) {
826 /*
827 * Compute first bit not examined.
828 */
829 lastbit = min(bit + len, XFS_NBWORD);
830 /*
831 * Mask of relevant bits.
832 */
833 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
834 /*
835 * Compute difference between actual and desired value.
836 */
837 incore = xfs_rtbitmap_getword(args, word);
838 if ((wdiff = (incore ^ val) & mask)) {
839 /*
840 * Different, compute first wrong bit and return.
841 */
842 i = xfs_lowbit32(wdiff) - bit;
843 *new = start + i;
844 *stat = 0;
845 return 0;
846 }
847 i = lastbit - bit;
848 /*
849 * Go on to next block if that's where the next word is
850 * and we need the next word.
851 */
852 if (++word == mp->m_blockwsize && i < len) {
853 /*
854 * If done with this block, get the next one.
855 */
856 error = xfs_rtbitmap_read_buf(args, ++block);
857 if (error)
858 return error;
859
860 word = 0;
861 }
862 } else {
863 /*
864 * Starting on a word boundary, no partial word.
865 */
866 i = 0;
867 }
868 /*
869 * Loop over whole words in buffers. When we use up one buffer
870 * we move on to the next one.
871 */
872 while (len - i >= XFS_NBWORD) {
873 /*
874 * Compute difference between actual and desired value.
875 */
876 incore = xfs_rtbitmap_getword(args, word);
877 if ((wdiff = incore ^ val)) {
878 /*
879 * Different, compute first wrong bit and return.
880 */
881 i += xfs_lowbit32(wdiff);
882 *new = start + i;
883 *stat = 0;
884 return 0;
885 }
886 i += XFS_NBWORD;
887 /*
888 * Go on to next block if that's where the next word is
889 * and we need the next word.
890 */
891 if (++word == mp->m_blockwsize && i < len) {
892 /*
893 * If done with this block, get the next one.
894 */
895 error = xfs_rtbitmap_read_buf(args, ++block);
896 if (error)
897 return error;
898
899 word = 0;
900 }
901 }
902 /*
903 * If not ending on a word boundary, deal with the last
904 * (partial) word.
905 */
906 if ((lastbit = len - i)) {
907 /*
908 * Mask of relevant bits.
909 */
910 mask = ((xfs_rtword_t)1 << lastbit) - 1;
911 /*
912 * Compute difference between actual and desired value.
913 */
914 incore = xfs_rtbitmap_getword(args, word);
915 if ((wdiff = (incore ^ val) & mask)) {
916 /*
917 * Different, compute first wrong bit and return.
918 */
919 i += xfs_lowbit32(wdiff);
920 *new = start + i;
921 *stat = 0;
922 return 0;
923 } else
924 i = len;
925 }
926 /*
927 * Successful, return.
928 */
929 *new = start + i;
930 *stat = 1;
931 return 0;
932 }
933
934 #ifdef DEBUG
935 /*
936 * Check that the given extent (block range) is allocated already.
937 */
938 STATIC int
xfs_rtcheck_alloc_range(struct xfs_rtalloc_args * args,xfs_rtxnum_t start,xfs_rtxlen_t len)939 xfs_rtcheck_alloc_range(
940 struct xfs_rtalloc_args *args,
941 xfs_rtxnum_t start, /* starting rtext number of extent */
942 xfs_rtxlen_t len) /* length of extent */
943 {
944 xfs_rtxnum_t new; /* dummy for xfs_rtcheck_range */
945 int stat;
946 int error;
947
948 error = xfs_rtcheck_range(args, start, len, 0, &new, &stat);
949 if (error)
950 return error;
951 ASSERT(stat);
952 return 0;
953 }
954 #else
955 #define xfs_rtcheck_alloc_range(a,b,l) (0)
956 #endif
957 /*
958 * Free an extent in the realtime subvolume. Length is expressed in
959 * realtime extents, as is the block number.
960 */
961 int
xfs_rtfree_extent(struct xfs_trans * tp,xfs_rtxnum_t start,xfs_rtxlen_t len)962 xfs_rtfree_extent(
963 struct xfs_trans *tp, /* transaction pointer */
964 xfs_rtxnum_t start, /* starting rtext number to free */
965 xfs_rtxlen_t len) /* length of extent freed */
966 {
967 struct xfs_mount *mp = tp->t_mountp;
968 struct xfs_rtalloc_args args = {
969 .mp = mp,
970 .tp = tp,
971 };
972 int error;
973 struct timespec64 atime;
974
975 ASSERT(mp->m_rbmip->i_itemp != NULL);
976 xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL);
977
978 error = xfs_rtcheck_alloc_range(&args, start, len);
979 if (error)
980 return error;
981
982 /*
983 * Free the range of realtime blocks.
984 */
985 error = xfs_rtfree_range(&args, start, len);
986 if (error)
987 goto out;
988
989 /*
990 * Mark more blocks free in the superblock.
991 */
992 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
993 /*
994 * If we've now freed all the blocks, reset the file sequence
995 * number to 0.
996 */
997 if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
998 mp->m_sb.sb_rextents) {
999 if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
1000 mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
1001
1002 atime = inode_get_atime(VFS_I(mp->m_rbmip));
1003 atime.tv_sec = 0;
1004 inode_set_atime_to_ts(VFS_I(mp->m_rbmip), atime);
1005 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
1006 }
1007 error = 0;
1008 out:
1009 xfs_rtbuf_cache_relse(&args);
1010 return error;
1011 }
1012
1013 /*
1014 * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of
1015 * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
1016 * cannot exceed XFS_MAX_BMBT_EXTLEN.
1017 */
1018 int
xfs_rtfree_blocks(struct xfs_trans * tp,xfs_fsblock_t rtbno,xfs_filblks_t rtlen)1019 xfs_rtfree_blocks(
1020 struct xfs_trans *tp,
1021 xfs_fsblock_t rtbno,
1022 xfs_filblks_t rtlen)
1023 {
1024 struct xfs_mount *mp = tp->t_mountp;
1025 xfs_extlen_t mod;
1026
1027 ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
1028
1029 mod = xfs_rtb_to_rtxoff(mp, rtlen);
1030 if (mod) {
1031 ASSERT(mod == 0);
1032 return -EIO;
1033 }
1034
1035 mod = xfs_rtb_to_rtxoff(mp, rtbno);
1036 if (mod) {
1037 ASSERT(mod == 0);
1038 return -EIO;
1039 }
1040
1041 return xfs_rtfree_extent(tp, xfs_rtb_to_rtx(mp, rtbno),
1042 xfs_rtb_to_rtx(mp, rtlen));
1043 }
1044
1045 /* Find all the free records within a given range. */
1046 int
xfs_rtalloc_query_range(struct xfs_mount * mp,struct xfs_trans * tp,xfs_rtxnum_t start,xfs_rtxnum_t end,xfs_rtalloc_query_range_fn fn,void * priv)1047 xfs_rtalloc_query_range(
1048 struct xfs_mount *mp,
1049 struct xfs_trans *tp,
1050 xfs_rtxnum_t start,
1051 xfs_rtxnum_t end,
1052 xfs_rtalloc_query_range_fn fn,
1053 void *priv)
1054 {
1055 struct xfs_rtalloc_args args = {
1056 .mp = mp,
1057 .tp = tp,
1058 };
1059 int error = 0;
1060
1061 if (start > end)
1062 return -EINVAL;
1063 if (start == end || start >= mp->m_sb.sb_rextents)
1064 return 0;
1065
1066 end = min(end, mp->m_sb.sb_rextents - 1);
1067
1068 /* Iterate the bitmap, looking for discrepancies. */
1069 while (start <= end) {
1070 struct xfs_rtalloc_rec rec;
1071 int is_free;
1072 xfs_rtxnum_t rtend;
1073
1074 /* Is the first block free? */
1075 error = xfs_rtcheck_range(&args, start, 1, 1, &rtend,
1076 &is_free);
1077 if (error)
1078 break;
1079
1080 /* How long does the extent go for? */
1081 error = xfs_rtfind_forw(&args, start, end, &rtend);
1082 if (error)
1083 break;
1084
1085 if (is_free) {
1086 rec.ar_startext = start;
1087 rec.ar_extcount = rtend - start + 1;
1088
1089 error = fn(mp, tp, &rec, priv);
1090 if (error)
1091 break;
1092 }
1093
1094 start = rtend + 1;
1095 }
1096
1097 xfs_rtbuf_cache_relse(&args);
1098 return error;
1099 }
1100
1101 /* Find all the free records. */
1102 int
xfs_rtalloc_query_all(struct xfs_mount * mp,struct xfs_trans * tp,xfs_rtalloc_query_range_fn fn,void * priv)1103 xfs_rtalloc_query_all(
1104 struct xfs_mount *mp,
1105 struct xfs_trans *tp,
1106 xfs_rtalloc_query_range_fn fn,
1107 void *priv)
1108 {
1109 return xfs_rtalloc_query_range(mp, tp, 0, mp->m_sb.sb_rextents - 1, fn,
1110 priv);
1111 }
1112
1113 /* Is the given extent all free? */
1114 int
xfs_rtalloc_extent_is_free(struct xfs_mount * mp,struct xfs_trans * tp,xfs_rtxnum_t start,xfs_rtxlen_t len,bool * is_free)1115 xfs_rtalloc_extent_is_free(
1116 struct xfs_mount *mp,
1117 struct xfs_trans *tp,
1118 xfs_rtxnum_t start,
1119 xfs_rtxlen_t len,
1120 bool *is_free)
1121 {
1122 struct xfs_rtalloc_args args = {
1123 .mp = mp,
1124 .tp = tp,
1125 };
1126 xfs_rtxnum_t end;
1127 int matches;
1128 int error;
1129
1130 error = xfs_rtcheck_range(&args, start, len, 1, &end, &matches);
1131 xfs_rtbuf_cache_relse(&args);
1132 if (error)
1133 return error;
1134
1135 *is_free = matches;
1136 return 0;
1137 }
1138
1139 /*
1140 * Compute the number of rtbitmap blocks needed to track the given number of rt
1141 * extents.
1142 */
1143 xfs_filblks_t
xfs_rtbitmap_blockcount(struct xfs_mount * mp,xfs_rtbxlen_t rtextents)1144 xfs_rtbitmap_blockcount(
1145 struct xfs_mount *mp,
1146 xfs_rtbxlen_t rtextents)
1147 {
1148 return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize);
1149 }
1150
1151 /* Compute the number of rtsummary blocks needed to track the given rt space. */
1152 xfs_filblks_t
xfs_rtsummary_blockcount(struct xfs_mount * mp,unsigned int rsumlevels,xfs_extlen_t rbmblocks)1153 xfs_rtsummary_blockcount(
1154 struct xfs_mount *mp,
1155 unsigned int rsumlevels,
1156 xfs_extlen_t rbmblocks)
1157 {
1158 unsigned long long rsumwords;
1159
1160 rsumwords = (unsigned long long)rsumlevels * rbmblocks;
1161 return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
1162 }
1163
1164 /* Lock both realtime free space metadata inodes for a freespace update. */
1165 void
xfs_rtbitmap_lock(struct xfs_mount * mp)1166 xfs_rtbitmap_lock(
1167 struct xfs_mount *mp)
1168 {
1169 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
1170 xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
1171 }
1172
1173 /*
1174 * Join both realtime free space metadata inodes to the transaction. The
1175 * ILOCKs will be released on transaction commit.
1176 */
1177 void
xfs_rtbitmap_trans_join(struct xfs_trans * tp)1178 xfs_rtbitmap_trans_join(
1179 struct xfs_trans *tp)
1180 {
1181 xfs_trans_ijoin(tp, tp->t_mountp->m_rbmip, XFS_ILOCK_EXCL);
1182 xfs_trans_ijoin(tp, tp->t_mountp->m_rsumip, XFS_ILOCK_EXCL);
1183 }
1184
1185 /* Unlock both realtime free space metadata inodes after a freespace update. */
1186 void
xfs_rtbitmap_unlock(struct xfs_mount * mp)1187 xfs_rtbitmap_unlock(
1188 struct xfs_mount *mp)
1189 {
1190 xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
1191 xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
1192 }
1193
1194 /*
1195 * Lock the realtime free space metadata inodes for a freespace scan. Callers
1196 * must walk metadata blocks in order of increasing file offset.
1197 */
1198 void
xfs_rtbitmap_lock_shared(struct xfs_mount * mp,unsigned int rbmlock_flags)1199 xfs_rtbitmap_lock_shared(
1200 struct xfs_mount *mp,
1201 unsigned int rbmlock_flags)
1202 {
1203 if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
1204 xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
1205
1206 if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
1207 xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
1208 }
1209
1210 /* Unlock the realtime free space metadata inodes after a freespace scan. */
1211 void
xfs_rtbitmap_unlock_shared(struct xfs_mount * mp,unsigned int rbmlock_flags)1212 xfs_rtbitmap_unlock_shared(
1213 struct xfs_mount *mp,
1214 unsigned int rbmlock_flags)
1215 {
1216 if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
1217 xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
1218
1219 if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
1220 xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
1221 }
1222
1223 static int
xfs_rtfile_alloc_blocks(struct xfs_inode * ip,xfs_fileoff_t offset_fsb,xfs_filblks_t count_fsb,struct xfs_bmbt_irec * map)1224 xfs_rtfile_alloc_blocks(
1225 struct xfs_inode *ip,
1226 xfs_fileoff_t offset_fsb,
1227 xfs_filblks_t count_fsb,
1228 struct xfs_bmbt_irec *map)
1229 {
1230 struct xfs_mount *mp = ip->i_mount;
1231 struct xfs_trans *tp;
1232 int nmap = 1;
1233 int error;
1234
1235 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc,
1236 XFS_GROWFSRT_SPACE_RES(mp, count_fsb), 0, 0, &tp);
1237 if (error)
1238 return error;
1239
1240 xfs_ilock(ip, XFS_ILOCK_EXCL);
1241 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1242
1243 error = xfs_iext_count_extend(tp, ip, XFS_DATA_FORK,
1244 XFS_IEXT_ADD_NOSPLIT_CNT);
1245 if (error)
1246 goto out_trans_cancel;
1247
1248 error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
1249 XFS_BMAPI_METADATA, 0, map, &nmap);
1250 if (error)
1251 goto out_trans_cancel;
1252
1253 return xfs_trans_commit(tp);
1254
1255 out_trans_cancel:
1256 xfs_trans_cancel(tp);
1257 return error;
1258 }
1259
1260 /* Get a buffer for the block. */
1261 static int
xfs_rtfile_initialize_block(struct xfs_inode * ip,xfs_fsblock_t fsbno,void * data)1262 xfs_rtfile_initialize_block(
1263 struct xfs_inode *ip,
1264 xfs_fsblock_t fsbno,
1265 void *data)
1266 {
1267 struct xfs_mount *mp = ip->i_mount;
1268 struct xfs_trans *tp;
1269 struct xfs_buf *bp;
1270 const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
1271 enum xfs_blft buf_type;
1272 int error;
1273
1274 if (ip == mp->m_rsumip)
1275 buf_type = XFS_BLFT_RTSUMMARY_BUF;
1276 else
1277 buf_type = XFS_BLFT_RTBITMAP_BUF;
1278
1279 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 0, 0, 0, &tp);
1280 if (error)
1281 return error;
1282 xfs_ilock(ip, XFS_ILOCK_EXCL);
1283 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1284
1285 error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
1286 XFS_FSB_TO_DADDR(mp, fsbno), mp->m_bsize, 0, &bp);
1287 if (error) {
1288 xfs_trans_cancel(tp);
1289 return error;
1290 }
1291
1292 xfs_trans_buf_set_type(tp, bp, buf_type);
1293 bp->b_ops = &xfs_rtbuf_ops;
1294 if (data)
1295 memcpy(bp->b_addr, data, copylen);
1296 else
1297 memset(bp->b_addr, 0, copylen);
1298 xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
1299 return xfs_trans_commit(tp);
1300 }
1301
1302 /*
1303 * Allocate space to the bitmap or summary file, and zero it, for growfs.
1304 * @data must be a contiguous buffer large enough to fill all blocks in the
1305 * file; or NULL to initialize the contents to zeroes.
1306 */
1307 int
xfs_rtfile_initialize_blocks(struct xfs_inode * ip,xfs_fileoff_t offset_fsb,xfs_fileoff_t end_fsb,void * data)1308 xfs_rtfile_initialize_blocks(
1309 struct xfs_inode *ip, /* inode (bitmap/summary) */
1310 xfs_fileoff_t offset_fsb, /* offset to start from */
1311 xfs_fileoff_t end_fsb, /* offset to allocate to */
1312 void *data) /* data to fill the blocks */
1313 {
1314 struct xfs_mount *mp = ip->i_mount;
1315 const size_t copylen = mp->m_blockwsize << XFS_WORDLOG;
1316
1317 while (offset_fsb < end_fsb) {
1318 struct xfs_bmbt_irec map;
1319 xfs_filblks_t i;
1320 int error;
1321
1322 error = xfs_rtfile_alloc_blocks(ip, offset_fsb,
1323 end_fsb - offset_fsb, &map);
1324 if (error)
1325 return error;
1326
1327 /*
1328 * Now we need to clear the allocated blocks.
1329 *
1330 * Do this one block per transaction, to keep it simple.
1331 */
1332 for (i = 0; i < map.br_blockcount; i++) {
1333 error = xfs_rtfile_initialize_block(ip,
1334 map.br_startblock + i, data);
1335 if (error)
1336 return error;
1337 if (data)
1338 data += copylen;
1339 }
1340
1341 offset_fsb = map.br_startoff + map.br_blockcount;
1342 }
1343
1344 return 0;
1345 }
1346