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}
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}