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