]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/xfs/xfs_rtbitmap.c
arm: imx6: defconfig: update tx6 defconfigs
[karo-tx-linux.git] / fs / xfs / xfs_rtbitmap.c
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
24 #include "xfs_bit.h"
25 #include "xfs_sb.h"
26 #include "xfs_ag.h"
27 #include "xfs_mount.h"
28 #include "xfs_inode.h"
29 #include "xfs_bmap.h"
30 #include "xfs_bmap_util.h"
31 #include "xfs_bmap_btree.h"
32 #include "xfs_alloc.h"
33 #include "xfs_error.h"
34 #include "xfs_trans.h"
35 #include "xfs_trans_space.h"
36 #include "xfs_trace.h"
37 #include "xfs_buf.h"
38 #include "xfs_icache.h"
39 #include "xfs_dinode.h"
40
41
42 /*
43  * Realtime allocator bitmap functions shared with userspace.
44  */
45
46 /*
47  * Get a buffer for the bitmap or summary file block specified.
48  * The buffer is returned read and locked.
49  */
50 int
51 xfs_rtbuf_get(
52         xfs_mount_t     *mp,            /* file system mount structure */
53         xfs_trans_t     *tp,            /* transaction pointer */
54         xfs_rtblock_t   block,          /* block number in bitmap or summary */
55         int             issum,          /* is summary not bitmap */
56         xfs_buf_t       **bpp)          /* output: buffer for the block */
57 {
58         xfs_buf_t       *bp;            /* block buffer, result */
59         xfs_inode_t     *ip;            /* bitmap or summary inode */
60         xfs_bmbt_irec_t map;
61         int             nmap = 1;
62         int             error;          /* error value */
63
64         ip = issum ? mp->m_rsumip : mp->m_rbmip;
65
66         error = xfs_bmapi_read(ip, block, 1, &map, &nmap, XFS_DATA_FORK);
67         if (error)
68                 return error;
69
70         ASSERT(map.br_startblock != NULLFSBLOCK);
71         error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
72                                    XFS_FSB_TO_DADDR(mp, map.br_startblock),
73                                    mp->m_bsize, 0, &bp, NULL);
74         if (error)
75                 return error;
76         ASSERT(!xfs_buf_geterror(bp));
77         *bpp = bp;
78         return 0;
79 }
80
81 /*
82  * Searching backward from start to limit, find the first block whose
83  * allocated/free state is different from start's.
84  */
85 int
86 xfs_rtfind_back(
87         xfs_mount_t     *mp,            /* file system mount point */
88         xfs_trans_t     *tp,            /* transaction pointer */
89         xfs_rtblock_t   start,          /* starting block to look at */
90         xfs_rtblock_t   limit,          /* last block to look at */
91         xfs_rtblock_t   *rtblock)       /* out: start block found */
92 {
93         xfs_rtword_t    *b;             /* current word in buffer */
94         int             bit;            /* bit number in the word */
95         xfs_rtblock_t   block;          /* bitmap block number */
96         xfs_buf_t       *bp;            /* buf for the block */
97         xfs_rtword_t    *bufp;          /* starting word in buffer */
98         int             error;          /* error value */
99         xfs_rtblock_t   firstbit;       /* first useful bit in the word */
100         xfs_rtblock_t   i;              /* current bit number rel. to start */
101         xfs_rtblock_t   len;            /* length of inspected area */
102         xfs_rtword_t    mask;           /* mask of relevant bits for value */
103         xfs_rtword_t    want;           /* mask for "good" values */
104         xfs_rtword_t    wdiff;          /* difference from wanted value */
105         int             word;           /* word number in the buffer */
106
107         /*
108          * Compute and read in starting bitmap block for starting block.
109          */
110         block = XFS_BITTOBLOCK(mp, start);
111         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
112         if (error) {
113                 return error;
114         }
115         bufp = bp->b_addr;
116         /*
117          * Get the first word's index & point to it.
118          */
119         word = XFS_BITTOWORD(mp, start);
120         b = &bufp[word];
121         bit = (int)(start & (XFS_NBWORD - 1));
122         len = start - limit + 1;
123         /*
124          * Compute match value, based on the bit at start: if 1 (free)
125          * then all-ones, else all-zeroes.
126          */
127         want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
128         /*
129          * If the starting position is not word-aligned, deal with the
130          * partial word.
131          */
132         if (bit < XFS_NBWORD - 1) {
133                 /*
134                  * Calculate first (leftmost) bit number to look at,
135                  * and mask for all the relevant bits in this word.
136                  */
137                 firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
138                 mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
139                         firstbit;
140                 /*
141                  * Calculate the difference between the value there
142                  * and what we're looking for.
143                  */
144                 if ((wdiff = (*b ^ want) & mask)) {
145                         /*
146                          * Different.  Mark where we are and return.
147                          */
148                         xfs_trans_brelse(tp, bp);
149                         i = bit - XFS_RTHIBIT(wdiff);
150                         *rtblock = start - i + 1;
151                         return 0;
152                 }
153                 i = bit - firstbit + 1;
154                 /*
155                  * Go on to previous block if that's where the previous word is
156                  * and we need the previous word.
157                  */
158                 if (--word == -1 && i < len) {
159                         /*
160                          * If done with this block, get the previous one.
161                          */
162                         xfs_trans_brelse(tp, bp);
163                         error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
164                         if (error) {
165                                 return error;
166                         }
167                         bufp = bp->b_addr;
168                         word = XFS_BLOCKWMASK(mp);
169                         b = &bufp[word];
170                 } else {
171                         /*
172                          * Go on to the previous word in the buffer.
173                          */
174                         b--;
175                 }
176         } else {
177                 /*
178                  * Starting on a word boundary, no partial word.
179                  */
180                 i = 0;
181         }
182         /*
183          * Loop over whole words in buffers.  When we use up one buffer
184          * we move on to the previous one.
185          */
186         while (len - i >= XFS_NBWORD) {
187                 /*
188                  * Compute difference between actual and desired value.
189                  */
190                 if ((wdiff = *b ^ want)) {
191                         /*
192                          * Different, mark where we are and return.
193                          */
194                         xfs_trans_brelse(tp, bp);
195                         i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
196                         *rtblock = start - i + 1;
197                         return 0;
198                 }
199                 i += XFS_NBWORD;
200                 /*
201                  * Go on to previous block if that's where the previous word is
202                  * and we need the previous word.
203                  */
204                 if (--word == -1 && i < len) {
205                         /*
206                          * If done with this block, get the previous one.
207                          */
208                         xfs_trans_brelse(tp, bp);
209                         error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
210                         if (error) {
211                                 return error;
212                         }
213                         bufp = bp->b_addr;
214                         word = XFS_BLOCKWMASK(mp);
215                         b = &bufp[word];
216                 } else {
217                         /*
218                          * Go on to the previous word in the buffer.
219                          */
220                         b--;
221                 }
222         }
223         /*
224          * If not ending on a word boundary, deal with the last
225          * (partial) word.
226          */
227         if (len - i) {
228                 /*
229                  * Calculate first (leftmost) bit number to look at,
230                  * and mask for all the relevant bits in this word.
231                  */
232                 firstbit = XFS_NBWORD - (len - i);
233                 mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
234                 /*
235                  * Compute difference between actual and desired value.
236                  */
237                 if ((wdiff = (*b ^ want) & mask)) {
238                         /*
239                          * Different, mark where we are and return.
240                          */
241                         xfs_trans_brelse(tp, bp);
242                         i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
243                         *rtblock = start - i + 1;
244                         return 0;
245                 } else
246                         i = len;
247         }
248         /*
249          * No match, return that we scanned the whole area.
250          */
251         xfs_trans_brelse(tp, bp);
252         *rtblock = start - i + 1;
253         return 0;
254 }
255
256 /*
257  * Searching forward from start to limit, find the first block whose
258  * allocated/free state is different from start's.
259  */
260 int
261 xfs_rtfind_forw(
262         xfs_mount_t     *mp,            /* file system mount point */
263         xfs_trans_t     *tp,            /* transaction pointer */
264         xfs_rtblock_t   start,          /* starting block to look at */
265         xfs_rtblock_t   limit,          /* last block to look at */
266         xfs_rtblock_t   *rtblock)       /* out: start block found */
267 {
268         xfs_rtword_t    *b;             /* current word in buffer */
269         int             bit;            /* bit number in the word */
270         xfs_rtblock_t   block;          /* bitmap block number */
271         xfs_buf_t       *bp;            /* buf for the block */
272         xfs_rtword_t    *bufp;          /* starting word in buffer */
273         int             error;          /* error value */
274         xfs_rtblock_t   i;              /* current bit number rel. to start */
275         xfs_rtblock_t   lastbit;        /* last useful bit in the word */
276         xfs_rtblock_t   len;            /* length of inspected area */
277         xfs_rtword_t    mask;           /* mask of relevant bits for value */
278         xfs_rtword_t    want;           /* mask for "good" values */
279         xfs_rtword_t    wdiff;          /* difference from wanted value */
280         int             word;           /* word number in the buffer */
281
282         /*
283          * Compute and read in starting bitmap block for starting block.
284          */
285         block = XFS_BITTOBLOCK(mp, start);
286         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
287         if (error) {
288                 return error;
289         }
290         bufp = bp->b_addr;
291         /*
292          * Get the first word's index & point to it.
293          */
294         word = XFS_BITTOWORD(mp, start);
295         b = &bufp[word];
296         bit = (int)(start & (XFS_NBWORD - 1));
297         len = limit - start + 1;
298         /*
299          * Compute match value, based on the bit at start: if 1 (free)
300          * then all-ones, else all-zeroes.
301          */
302         want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
303         /*
304          * If the starting position is not word-aligned, deal with the
305          * partial word.
306          */
307         if (bit) {
308                 /*
309                  * Calculate last (rightmost) bit number to look at,
310                  * and mask for all the relevant bits in this word.
311                  */
312                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
313                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
314                 /*
315                  * Calculate the difference between the value there
316                  * and what we're looking for.
317                  */
318                 if ((wdiff = (*b ^ want) & mask)) {
319                         /*
320                          * Different.  Mark where we are and return.
321                          */
322                         xfs_trans_brelse(tp, bp);
323                         i = XFS_RTLOBIT(wdiff) - bit;
324                         *rtblock = start + i - 1;
325                         return 0;
326                 }
327                 i = lastbit - bit;
328                 /*
329                  * Go on to next block if that's where the next word is
330                  * and we need the next word.
331                  */
332                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
333                         /*
334                          * If done with this block, get the previous one.
335                          */
336                         xfs_trans_brelse(tp, bp);
337                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
338                         if (error) {
339                                 return error;
340                         }
341                         b = bufp = bp->b_addr;
342                         word = 0;
343                 } else {
344                         /*
345                          * Go on to the previous word in the buffer.
346                          */
347                         b++;
348                 }
349         } else {
350                 /*
351                  * Starting on a word boundary, no partial word.
352                  */
353                 i = 0;
354         }
355         /*
356          * Loop over whole words in buffers.  When we use up one buffer
357          * we move on to the next one.
358          */
359         while (len - i >= XFS_NBWORD) {
360                 /*
361                  * Compute difference between actual and desired value.
362                  */
363                 if ((wdiff = *b ^ want)) {
364                         /*
365                          * Different, mark where we are and return.
366                          */
367                         xfs_trans_brelse(tp, bp);
368                         i += XFS_RTLOBIT(wdiff);
369                         *rtblock = start + i - 1;
370                         return 0;
371                 }
372                 i += XFS_NBWORD;
373                 /*
374                  * Go on to next block if that's where the next word is
375                  * and we need the next word.
376                  */
377                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
378                         /*
379                          * If done with this block, get the next one.
380                          */
381                         xfs_trans_brelse(tp, bp);
382                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
383                         if (error) {
384                                 return error;
385                         }
386                         b = bufp = bp->b_addr;
387                         word = 0;
388                 } else {
389                         /*
390                          * Go on to the next word in the buffer.
391                          */
392                         b++;
393                 }
394         }
395         /*
396          * If not ending on a word boundary, deal with the last
397          * (partial) word.
398          */
399         if ((lastbit = len - i)) {
400                 /*
401                  * Calculate mask for all the relevant bits in this word.
402                  */
403                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
404                 /*
405                  * Compute difference between actual and desired value.
406                  */
407                 if ((wdiff = (*b ^ want) & mask)) {
408                         /*
409                          * Different, mark where we are and return.
410                          */
411                         xfs_trans_brelse(tp, bp);
412                         i += XFS_RTLOBIT(wdiff);
413                         *rtblock = start + i - 1;
414                         return 0;
415                 } else
416                         i = len;
417         }
418         /*
419          * No match, return that we scanned the whole area.
420          */
421         xfs_trans_brelse(tp, bp);
422         *rtblock = start + i - 1;
423         return 0;
424 }
425
426 /*
427  * Read and modify the summary information for a given extent size,
428  * bitmap block combination.
429  * Keeps track of a current summary block, so we don't keep reading
430  * it from the buffer cache.
431  */
432 int
433 xfs_rtmodify_summary(
434         xfs_mount_t     *mp,            /* file system mount point */
435         xfs_trans_t     *tp,            /* transaction pointer */
436         int             log,            /* log2 of extent size */
437         xfs_rtblock_t   bbno,           /* bitmap block number */
438         int             delta,          /* change to make to summary info */
439         xfs_buf_t       **rbpp,         /* in/out: summary block buffer */
440         xfs_fsblock_t   *rsb)           /* in/out: summary block number */
441 {
442         xfs_buf_t       *bp;            /* buffer for the summary block */
443         int             error;          /* error value */
444         xfs_fsblock_t   sb;             /* summary fsblock */
445         int             so;             /* index into the summary file */
446         xfs_suminfo_t   *sp;            /* pointer to returned data */
447
448         /*
449          * Compute entry number in the summary file.
450          */
451         so = XFS_SUMOFFS(mp, log, bbno);
452         /*
453          * Compute the block number in the summary file.
454          */
455         sb = XFS_SUMOFFSTOBLOCK(mp, so);
456         /*
457          * If we have an old buffer, and the block number matches, use that.
458          */
459         if (rbpp && *rbpp && *rsb == sb)
460                 bp = *rbpp;
461         /*
462          * Otherwise we have to get the buffer.
463          */
464         else {
465                 /*
466                  * If there was an old one, get rid of it first.
467                  */
468                 if (rbpp && *rbpp)
469                         xfs_trans_brelse(tp, *rbpp);
470                 error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
471                 if (error) {
472                         return error;
473                 }
474                 /*
475                  * Remember this buffer and block for the next call.
476                  */
477                 if (rbpp) {
478                         *rbpp = bp;
479                         *rsb = sb;
480                 }
481         }
482         /*
483          * Point to the summary information, modify and log it.
484          */
485         sp = XFS_SUMPTR(mp, bp, so);
486         *sp += delta;
487         xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)bp->b_addr),
488                 (uint)((char *)sp - (char *)bp->b_addr + sizeof(*sp) - 1));
489         return 0;
490 }
491
492 /*
493  * Set the given range of bitmap bits to the given value.
494  * Do whatever I/O and logging is required.
495  */
496 int
497 xfs_rtmodify_range(
498         xfs_mount_t     *mp,            /* file system mount point */
499         xfs_trans_t     *tp,            /* transaction pointer */
500         xfs_rtblock_t   start,          /* starting block to modify */
501         xfs_extlen_t    len,            /* length of extent to modify */
502         int             val)            /* 1 for free, 0 for allocated */
503 {
504         xfs_rtword_t    *b;             /* current word in buffer */
505         int             bit;            /* bit number in the word */
506         xfs_rtblock_t   block;          /* bitmap block number */
507         xfs_buf_t       *bp;            /* buf for the block */
508         xfs_rtword_t    *bufp;          /* starting word in buffer */
509         int             error;          /* error value */
510         xfs_rtword_t    *first;         /* first used word in the buffer */
511         int             i;              /* current bit number rel. to start */
512         int             lastbit;        /* last useful bit in word */
513         xfs_rtword_t    mask;           /* mask o frelevant bits for value */
514         int             word;           /* word number in the buffer */
515
516         /*
517          * Compute starting bitmap block number.
518          */
519         block = XFS_BITTOBLOCK(mp, start);
520         /*
521          * Read the bitmap block, and point to its data.
522          */
523         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
524         if (error) {
525                 return error;
526         }
527         bufp = bp->b_addr;
528         /*
529          * Compute the starting word's address, and starting bit.
530          */
531         word = XFS_BITTOWORD(mp, start);
532         first = b = &bufp[word];
533         bit = (int)(start & (XFS_NBWORD - 1));
534         /*
535          * 0 (allocated) => all zeroes; 1 (free) => all ones.
536          */
537         val = -val;
538         /*
539          * If not starting on a word boundary, deal with the first
540          * (partial) word.
541          */
542         if (bit) {
543                 /*
544                  * Compute first bit not changed and mask of relevant bits.
545                  */
546                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
547                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
548                 /*
549                  * Set/clear the active bits.
550                  */
551                 if (val)
552                         *b |= mask;
553                 else
554                         *b &= ~mask;
555                 i = lastbit - bit;
556                 /*
557                  * Go on to the next block if that's where the next word is
558                  * and we need the next word.
559                  */
560                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
561                         /*
562                          * Log the changed part of this block.
563                          * Get the next one.
564                          */
565                         xfs_trans_log_buf(tp, bp,
566                                 (uint)((char *)first - (char *)bufp),
567                                 (uint)((char *)b - (char *)bufp));
568                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
569                         if (error) {
570                                 return error;
571                         }
572                         first = b = bufp = bp->b_addr;
573                         word = 0;
574                 } else {
575                         /*
576                          * Go on to the next word in the buffer
577                          */
578                         b++;
579                 }
580         } else {
581                 /*
582                  * Starting on a word boundary, no partial word.
583                  */
584                 i = 0;
585         }
586         /*
587          * Loop over whole words in buffers.  When we use up one buffer
588          * we move on to the next one.
589          */
590         while (len - i >= XFS_NBWORD) {
591                 /*
592                  * Set the word value correctly.
593                  */
594                 *b = val;
595                 i += XFS_NBWORD;
596                 /*
597                  * Go on to the next block if that's where the next word is
598                  * and we need the next word.
599                  */
600                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
601                         /*
602                          * Log the changed part of this block.
603                          * Get the next one.
604                          */
605                         xfs_trans_log_buf(tp, bp,
606                                 (uint)((char *)first - (char *)bufp),
607                                 (uint)((char *)b - (char *)bufp));
608                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
609                         if (error) {
610                                 return error;
611                         }
612                         first = b = bufp = bp->b_addr;
613                         word = 0;
614                 } else {
615                         /*
616                          * Go on to the next word in the buffer
617                          */
618                         b++;
619                 }
620         }
621         /*
622          * If not ending on a word boundary, deal with the last
623          * (partial) word.
624          */
625         if ((lastbit = len - i)) {
626                 /*
627                  * Compute a mask of relevant bits.
628                  */
629                 bit = 0;
630                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
631                 /*
632                  * Set/clear the active bits.
633                  */
634                 if (val)
635                         *b |= mask;
636                 else
637                         *b &= ~mask;
638                 b++;
639         }
640         /*
641          * Log any remaining changed bytes.
642          */
643         if (b > first)
644                 xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),
645                         (uint)((char *)b - (char *)bufp - 1));
646         return 0;
647 }
648
649 /*
650  * Mark an extent specified by start and len freed.
651  * Updates all the summary information as well as the bitmap.
652  */
653 int
654 xfs_rtfree_range(
655         xfs_mount_t     *mp,            /* file system mount point */
656         xfs_trans_t     *tp,            /* transaction pointer */
657         xfs_rtblock_t   start,          /* starting block to free */
658         xfs_extlen_t    len,            /* length to free */
659         xfs_buf_t       **rbpp,         /* in/out: summary block buffer */
660         xfs_fsblock_t   *rsb)           /* in/out: summary block number */
661 {
662         xfs_rtblock_t   end;            /* end of the freed extent */
663         int             error;          /* error value */
664         xfs_rtblock_t   postblock;      /* first block freed > end */
665         xfs_rtblock_t   preblock;       /* first block freed < start */
666
667         end = start + len - 1;
668         /*
669          * Modify the bitmap to mark this extent freed.
670          */
671         error = xfs_rtmodify_range(mp, tp, start, len, 1);
672         if (error) {
673                 return error;
674         }
675         /*
676          * Assume we're freeing out of the middle of an allocated extent.
677          * We need to find the beginning and end of the extent so we can
678          * properly update the summary.
679          */
680         error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
681         if (error) {
682                 return error;
683         }
684         /*
685          * Find the next allocated block (end of allocated extent).
686          */
687         error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
688                 &postblock);
689         if (error)
690                 return error;
691         /*
692          * If there are blocks not being freed at the front of the
693          * old extent, add summary data for them to be allocated.
694          */
695         if (preblock < start) {
696                 error = xfs_rtmodify_summary(mp, tp,
697                         XFS_RTBLOCKLOG(start - preblock),
698                         XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
699                 if (error) {
700                         return error;
701                 }
702         }
703         /*
704          * If there are blocks not being freed at the end of the
705          * old extent, add summary data for them to be allocated.
706          */
707         if (postblock > end) {
708                 error = xfs_rtmodify_summary(mp, tp,
709                         XFS_RTBLOCKLOG(postblock - end),
710                         XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb);
711                 if (error) {
712                         return error;
713                 }
714         }
715         /*
716          * Increment the summary information corresponding to the entire
717          * (new) free extent.
718          */
719         error = xfs_rtmodify_summary(mp, tp,
720                 XFS_RTBLOCKLOG(postblock + 1 - preblock),
721                 XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
722         return error;
723 }
724
725 /*
726  * Check that the given range is either all allocated (val = 0) or
727  * all free (val = 1).
728  */
729 int
730 xfs_rtcheck_range(
731         xfs_mount_t     *mp,            /* file system mount point */
732         xfs_trans_t     *tp,            /* transaction pointer */
733         xfs_rtblock_t   start,          /* starting block number of extent */
734         xfs_extlen_t    len,            /* length of extent */
735         int             val,            /* 1 for free, 0 for allocated */
736         xfs_rtblock_t   *new,           /* out: first block not matching */
737         int             *stat)          /* out: 1 for matches, 0 for not */
738 {
739         xfs_rtword_t    *b;             /* current word in buffer */
740         int             bit;            /* bit number in the word */
741         xfs_rtblock_t   block;          /* bitmap block number */
742         xfs_buf_t       *bp;            /* buf for the block */
743         xfs_rtword_t    *bufp;          /* starting word in buffer */
744         int             error;          /* error value */
745         xfs_rtblock_t   i;              /* current bit number rel. to start */
746         xfs_rtblock_t   lastbit;        /* last useful bit in word */
747         xfs_rtword_t    mask;           /* mask of relevant bits for value */
748         xfs_rtword_t    wdiff;          /* difference from wanted value */
749         int             word;           /* word number in the buffer */
750
751         /*
752          * Compute starting bitmap block number
753          */
754         block = XFS_BITTOBLOCK(mp, start);
755         /*
756          * Read the bitmap block.
757          */
758         error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
759         if (error) {
760                 return error;
761         }
762         bufp = bp->b_addr;
763         /*
764          * Compute the starting word's address, and starting bit.
765          */
766         word = XFS_BITTOWORD(mp, start);
767         b = &bufp[word];
768         bit = (int)(start & (XFS_NBWORD - 1));
769         /*
770          * 0 (allocated) => all zero's; 1 (free) => all one's.
771          */
772         val = -val;
773         /*
774          * If not starting on a word boundary, deal with the first
775          * (partial) word.
776          */
777         if (bit) {
778                 /*
779                  * Compute first bit not examined.
780                  */
781                 lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
782                 /*
783                  * Mask of relevant bits.
784                  */
785                 mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
786                 /*
787                  * Compute difference between actual and desired value.
788                  */
789                 if ((wdiff = (*b ^ val) & mask)) {
790                         /*
791                          * Different, compute first wrong bit and return.
792                          */
793                         xfs_trans_brelse(tp, bp);
794                         i = XFS_RTLOBIT(wdiff) - bit;
795                         *new = start + i;
796                         *stat = 0;
797                         return 0;
798                 }
799                 i = lastbit - bit;
800                 /*
801                  * Go on to next block if that's where the next word is
802                  * and we need the next word.
803                  */
804                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
805                         /*
806                          * If done with this block, get the next one.
807                          */
808                         xfs_trans_brelse(tp, bp);
809                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
810                         if (error) {
811                                 return error;
812                         }
813                         b = bufp = bp->b_addr;
814                         word = 0;
815                 } else {
816                         /*
817                          * Go on to the next word in the buffer.
818                          */
819                         b++;
820                 }
821         } else {
822                 /*
823                  * Starting on a word boundary, no partial word.
824                  */
825                 i = 0;
826         }
827         /*
828          * Loop over whole words in buffers.  When we use up one buffer
829          * we move on to the next one.
830          */
831         while (len - i >= XFS_NBWORD) {
832                 /*
833                  * Compute difference between actual and desired value.
834                  */
835                 if ((wdiff = *b ^ val)) {
836                         /*
837                          * Different, compute first wrong bit and return.
838                          */
839                         xfs_trans_brelse(tp, bp);
840                         i += XFS_RTLOBIT(wdiff);
841                         *new = start + i;
842                         *stat = 0;
843                         return 0;
844                 }
845                 i += XFS_NBWORD;
846                 /*
847                  * Go on to next block if that's where the next word is
848                  * and we need the next word.
849                  */
850                 if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
851                         /*
852                          * If done with this block, get the next one.
853                          */
854                         xfs_trans_brelse(tp, bp);
855                         error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
856                         if (error) {
857                                 return error;
858                         }
859                         b = bufp = bp->b_addr;
860                         word = 0;
861                 } else {
862                         /*
863                          * Go on to the next word in the buffer.
864                          */
865                         b++;
866                 }
867         }
868         /*
869          * If not ending on a word boundary, deal with the last
870          * (partial) word.
871          */
872         if ((lastbit = len - i)) {
873                 /*
874                  * Mask of relevant bits.
875                  */
876                 mask = ((xfs_rtword_t)1 << lastbit) - 1;
877                 /*
878                  * Compute difference between actual and desired value.
879                  */
880                 if ((wdiff = (*b ^ val) & mask)) {
881                         /*
882                          * Different, compute first wrong bit and return.
883                          */
884                         xfs_trans_brelse(tp, bp);
885                         i += XFS_RTLOBIT(wdiff);
886                         *new = start + i;
887                         *stat = 0;
888                         return 0;
889                 } else
890                         i = len;
891         }
892         /*
893          * Successful, return.
894          */
895         xfs_trans_brelse(tp, bp);
896         *new = start + i;
897         *stat = 1;
898         return 0;
899 }
900
901 #ifdef DEBUG
902 /*
903  * Check that the given extent (block range) is allocated already.
904  */
905 STATIC int                              /* error */
906 xfs_rtcheck_alloc_range(
907         xfs_mount_t     *mp,            /* file system mount point */
908         xfs_trans_t     *tp,            /* transaction pointer */
909         xfs_rtblock_t   bno,            /* starting block number of extent */
910         xfs_extlen_t    len)            /* length of extent */
911 {
912         xfs_rtblock_t   new;            /* dummy for xfs_rtcheck_range */
913         int             stat;
914         int             error;
915
916         error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat);
917         if (error)
918                 return error;
919         ASSERT(stat);
920         return 0;
921 }
922 #else
923 #define xfs_rtcheck_alloc_range(m,t,b,l)        (0)
924 #endif
925 /*
926  * Free an extent in the realtime subvolume.  Length is expressed in
927  * realtime extents, as is the block number.
928  */
929 int                                     /* error */
930 xfs_rtfree_extent(
931         xfs_trans_t     *tp,            /* transaction pointer */
932         xfs_rtblock_t   bno,            /* starting block number to free */
933         xfs_extlen_t    len)            /* length of extent freed */
934 {
935         int             error;          /* error value */
936         xfs_mount_t     *mp;            /* file system mount structure */
937         xfs_fsblock_t   sb;             /* summary file block number */
938         xfs_buf_t       *sumbp = NULL;  /* summary file block buffer */
939
940         mp = tp->t_mountp;
941
942         ASSERT(mp->m_rbmip->i_itemp != NULL);
943         ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
944
945         error = xfs_rtcheck_alloc_range(mp, tp, bno, len);
946         if (error)
947                 return error;
948
949         /*
950          * Free the range of realtime blocks.
951          */
952         error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb);
953         if (error) {
954                 return error;
955         }
956         /*
957          * Mark more blocks free in the superblock.
958          */
959         xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
960         /*
961          * If we've now freed all the blocks, reset the file sequence
962          * number to 0.
963          */
964         if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
965             mp->m_sb.sb_rextents) {
966                 if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM))
967                         mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM;
968                 *(__uint64_t *)&mp->m_rbmip->i_d.di_atime = 0;
969                 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
970         }
971         return 0;
972 }
973