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