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