Linux Audio

Check our new training course

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