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