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