Linux Audio

Check our new training course

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