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