PageRenderTime 83ms CodeModel.GetById 3ms app.highlight 68ms RepoModel.GetById 1ms app.codeStats 0ms

/linux-2.6.21.x/fs/xfs/xfs_rtalloc.c

https://bitbucket.org/altlc/wive-rtnl-ralink-rt305x-routers-firmware-amod
C | 2333 lines | 1400 code | 61 blank | 872 comment | 287 complexity | 7b9a9073d812fe56530bee49e9893a77 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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_types.h"
  21#include "xfs_bit.h"
  22#include "xfs_log.h"
  23#include "xfs_inum.h"
  24#include "xfs_trans.h"
  25#include "xfs_sb.h"
  26#include "xfs_ag.h"
  27#include "xfs_dir2.h"
  28#include "xfs_dmapi.h"
  29#include "xfs_mount.h"
  30#include "xfs_bmap_btree.h"
  31#include "xfs_alloc_btree.h"
  32#include "xfs_ialloc_btree.h"
  33#include "xfs_dir2_sf.h"
  34#include "xfs_attr_sf.h"
  35#include "xfs_dinode.h"
  36#include "xfs_inode.h"
  37#include "xfs_btree.h"
  38#include "xfs_ialloc.h"
  39#include "xfs_alloc.h"
  40#include "xfs_bmap.h"
  41#include "xfs_rtalloc.h"
  42#include "xfs_fsops.h"
  43#include "xfs_error.h"
  44#include "xfs_rw.h"
  45#include "xfs_inode_item.h"
  46#include "xfs_trans_space.h"
  47
  48
  49/*
  50 * Prototypes for internal functions.
  51 */
  52
  53
  54STATIC int xfs_rtallocate_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
  55		xfs_extlen_t, xfs_buf_t **, xfs_fsblock_t *);
  56STATIC int xfs_rtany_summary(xfs_mount_t *, xfs_trans_t *, int, int,
  57		xfs_rtblock_t, xfs_buf_t **, xfs_fsblock_t *, int *);
  58STATIC int xfs_rtcheck_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
  59		xfs_extlen_t, int, xfs_rtblock_t *, int *);
  60STATIC int xfs_rtfind_back(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
  61		xfs_rtblock_t, xfs_rtblock_t *);
  62STATIC int xfs_rtfind_forw(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
  63		xfs_rtblock_t, xfs_rtblock_t *);
  64STATIC int xfs_rtget_summary( xfs_mount_t *, xfs_trans_t *, int,
  65		xfs_rtblock_t, xfs_buf_t **, xfs_fsblock_t *, xfs_suminfo_t *);
  66STATIC int xfs_rtmodify_range(xfs_mount_t *, xfs_trans_t *, xfs_rtblock_t,
  67		xfs_extlen_t, int);
  68STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int,
  69		xfs_rtblock_t, int, xfs_buf_t **, xfs_fsblock_t *);
  70
  71/*
  72 * Internal functions.
  73 */
  74
  75/*
  76 * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set.
  77 */
  78STATIC int
  79xfs_lowbit32(
  80	__uint32_t	v)
  81{
  82	if (v)
  83		return ffs(v) - 1;
  84	return -1;
  85}
  86
  87/*
  88 * Allocate space to the bitmap or summary file, and zero it, for growfs.
  89 */
  90STATIC int				/* error */
  91xfs_growfs_rt_alloc(
  92	xfs_mount_t	*mp,		/* file system mount point */
  93	xfs_extlen_t	oblocks,	/* old count of blocks */
  94	xfs_extlen_t	nblocks,	/* new count of blocks */
  95	xfs_ino_t	ino)		/* inode number (bitmap/summary) */
  96{
  97	xfs_fileoff_t	bno;		/* block number in file */
  98	xfs_buf_t	*bp;		/* temporary buffer for zeroing */
  99	int		cancelflags;	/* flags for xfs_trans_cancel */
 100	int		committed;	/* transaction committed flag */
 101	xfs_daddr_t	d;		/* disk block address */
 102	int		error;		/* error return value */
 103	xfs_fsblock_t	firstblock;	/* first block allocated in xaction */
 104	xfs_bmap_free_t	flist;		/* list of freed blocks */
 105	xfs_fsblock_t	fsbno;		/* filesystem block for bno */
 106	xfs_inode_t	*ip;		/* pointer to incore inode */
 107	xfs_bmbt_irec_t	map;		/* block map output */
 108	int		nmap;		/* number of block maps */
 109	int		resblks;	/* space reservation */
 110	xfs_trans_t	*tp;		/* transaction pointer */
 111
 112	/*
 113	 * Allocate space to the file, as necessary.
 114	 */
 115	while (oblocks < nblocks) {
 116		tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ALLOC);
 117		resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks);
 118		cancelflags = 0;
 119		/*
 120		 * Reserve space & log for one extent added to the file.
 121		 */
 122		if ((error = xfs_trans_reserve(tp, resblks,
 123				XFS_GROWRTALLOC_LOG_RES(mp), 0,
 124				XFS_TRANS_PERM_LOG_RES,
 125				XFS_DEFAULT_PERM_LOG_COUNT)))
 126			goto error_exit;
 127		cancelflags = XFS_TRANS_RELEASE_LOG_RES;
 128		/*
 129		 * Lock the inode.
 130		 */
 131		if ((error = xfs_trans_iget(mp, tp, ino, 0,
 132						XFS_ILOCK_EXCL, &ip)))
 133			goto error_exit;
 134		XFS_BMAP_INIT(&flist, &firstblock);
 135		/*
 136		 * Allocate blocks to the bitmap file.
 137		 */
 138		nmap = 1;
 139		cancelflags |= XFS_TRANS_ABORT;
 140		error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
 141			XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
 142			resblks, &map, &nmap, &flist, NULL);
 143		if (!error && nmap < 1)
 144			error = XFS_ERROR(ENOSPC);
 145		if (error)
 146			goto error_exit;
 147		/*
 148		 * Free any blocks freed up in the transaction, then commit.
 149		 */
 150		error = xfs_bmap_finish(&tp, &flist, &committed);
 151		if (error)
 152			goto error_exit;
 153		xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
 154		/*
 155		 * Now we need to clear the allocated blocks.
 156		 * Do this one block per transaction, to keep it simple.
 157		 */
 158		cancelflags = 0;
 159		for (bno = map.br_startoff, fsbno = map.br_startblock;
 160		     bno < map.br_startoff + map.br_blockcount;
 161		     bno++, fsbno++) {
 162			tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFSRT_ZERO);
 163			/*
 164			 * Reserve log for one block zeroing.
 165			 */
 166			if ((error = xfs_trans_reserve(tp, 0,
 167					XFS_GROWRTZERO_LOG_RES(mp), 0, 0, 0)))
 168				goto error_exit;
 169			/*
 170			 * Lock the bitmap inode.
 171			 */
 172			if ((error = xfs_trans_iget(mp, tp, ino, 0,
 173							XFS_ILOCK_EXCL, &ip)))
 174				goto error_exit;
 175			/*
 176			 * Get a buffer for the block.
 177			 */
 178			d = XFS_FSB_TO_DADDR(mp, fsbno);
 179			bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
 180				mp->m_bsize, 0);
 181			if (bp == NULL) {
 182				error = XFS_ERROR(EIO);
 183				goto error_exit;
 184			}
 185			memset(XFS_BUF_PTR(bp), 0, mp->m_sb.sb_blocksize);
 186			xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
 187			/*
 188			 * Commit the transaction.
 189			 */
 190			xfs_trans_commit(tp, 0, NULL);
 191		}
 192		/*
 193		 * Go on to the next extent, if any.
 194		 */
 195		oblocks = map.br_startoff + map.br_blockcount;
 196	}
 197	return 0;
 198error_exit:
 199	xfs_trans_cancel(tp, cancelflags);
 200	return error;
 201}
 202
 203/*
 204 * Attempt to allocate an extent minlen<=len<=maxlen starting from
 205 * bitmap block bbno.  If we don't get maxlen then use prod to trim
 206 * the length, if given.  Returns error; returns starting block in *rtblock.
 207 * The lengths are all in rtextents.
 208 */
 209STATIC int				/* error */
 210xfs_rtallocate_extent_block(
 211	xfs_mount_t	*mp,		/* file system mount point */
 212	xfs_trans_t	*tp,		/* transaction pointer */
 213	xfs_rtblock_t	bbno,		/* bitmap block number */
 214	xfs_extlen_t	minlen,		/* minimum length to allocate */
 215	xfs_extlen_t	maxlen,		/* maximum length to allocate */
 216	xfs_extlen_t	*len,		/* out: actual length allocated */
 217	xfs_rtblock_t	*nextp,		/* out: next block to try */
 218	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
 219	xfs_fsblock_t	*rsb,		/* in/out: summary block number */
 220	xfs_extlen_t	prod,		/* extent product factor */
 221	xfs_rtblock_t	*rtblock)	/* out: start block allocated */
 222{
 223	xfs_rtblock_t	besti;		/* best rtblock found so far */
 224	xfs_rtblock_t	bestlen;	/* best length found so far */
 225	xfs_rtblock_t	end;		/* last rtblock in chunk */
 226	int		error;		/* error value */
 227	xfs_rtblock_t	i;		/* current rtblock trying */
 228	xfs_rtblock_t	next;		/* next rtblock to try */
 229	int		stat;		/* status from internal calls */
 230
 231	/*
 232	 * Loop over all the extents starting in this bitmap block,
 233	 * looking for one that's long enough.
 234	 */
 235	for (i = XFS_BLOCKTOBIT(mp, bbno), besti = -1, bestlen = 0,
 236		end = XFS_BLOCKTOBIT(mp, bbno + 1) - 1;
 237	     i <= end;
 238	     i++) {
 239		/*
 240		 * See if there's a free extent of maxlen starting at i.
 241		 * If it's not so then next will contain the first non-free.
 242		 */
 243		error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, &next, &stat);
 244		if (error) {
 245			return error;
 246		}
 247		if (stat) {
 248			/*
 249			 * i for maxlen is all free, allocate and return that.
 250			 */
 251			error = xfs_rtallocate_range(mp, tp, i, maxlen, rbpp,
 252				rsb);
 253			if (error) {
 254				return error;
 255			}
 256			*len = maxlen;
 257			*rtblock = i;
 258			return 0;
 259		}
 260		/*
 261		 * In the case where we have a variable-sized allocation
 262		 * request, figure out how big this free piece is,
 263		 * and if it's big enough for the minimum, and the best
 264		 * so far, remember it.
 265		 */
 266		if (minlen < maxlen) {
 267			xfs_rtblock_t	thislen;	/* this extent size */
 268
 269			thislen = next - i;
 270			if (thislen >= minlen && thislen > bestlen) {
 271				besti = i;
 272				bestlen = thislen;
 273			}
 274		}
 275		/*
 276		 * If not done yet, find the start of the next free space.
 277		 */
 278		if (next < end) {
 279			error = xfs_rtfind_forw(mp, tp, next, end, &i);
 280			if (error) {
 281				return error;
 282			}
 283		} else
 284			break;
 285	}
 286	/*
 287	 * Searched the whole thing & didn't find a maxlen free extent.
 288	 */
 289	if (minlen < maxlen && besti != -1) {
 290		xfs_extlen_t	p;	/* amount to trim length by */
 291
 292		/*
 293		 * If size should be a multiple of prod, make that so.
 294		 */
 295		if (prod > 1 && (p = do_mod(bestlen, prod)))
 296			bestlen -= p;
 297		/*
 298		 * Allocate besti for bestlen & return that.
 299		 */
 300		error = xfs_rtallocate_range(mp, tp, besti, bestlen, rbpp, rsb);
 301		if (error) {
 302			return error;
 303		}
 304		*len = bestlen;
 305		*rtblock = besti;
 306		return 0;
 307	}
 308	/*
 309	 * Allocation failed.  Set *nextp to the next block to try.
 310	 */
 311	*nextp = next;
 312	*rtblock = NULLRTBLOCK;
 313	return 0;
 314}
 315
 316/*
 317 * Allocate an extent of length minlen<=len<=maxlen, starting at block
 318 * bno.  If we don't get maxlen then use prod to trim the length, if given.
 319 * Returns error; returns starting block in *rtblock.
 320 * The lengths are all in rtextents.
 321 */
 322STATIC int				/* error */
 323xfs_rtallocate_extent_exact(
 324	xfs_mount_t	*mp,		/* file system mount point */
 325	xfs_trans_t	*tp,		/* transaction pointer */
 326	xfs_rtblock_t	bno,		/* starting block number to allocate */
 327	xfs_extlen_t	minlen,		/* minimum length to allocate */
 328	xfs_extlen_t	maxlen,		/* maximum length to allocate */
 329	xfs_extlen_t	*len,		/* out: actual length allocated */
 330	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
 331	xfs_fsblock_t	*rsb,		/* in/out: summary block number */
 332	xfs_extlen_t	prod,		/* extent product factor */
 333	xfs_rtblock_t	*rtblock)	/* out: start block allocated */
 334{
 335	int		error;		/* error value */
 336	xfs_extlen_t	i;		/* extent length trimmed due to prod */
 337	int		isfree;		/* extent is free */
 338	xfs_rtblock_t	next;		/* next block to try (dummy) */
 339
 340	ASSERT(minlen % prod == 0 && maxlen % prod == 0);
 341	/*
 342	 * Check if the range in question (for maxlen) is free.
 343	 */
 344	error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, &next, &isfree);
 345	if (error) {
 346		return error;
 347	}
 348	if (isfree) {
 349		/*
 350		 * If it is, allocate it and return success.
 351		 */
 352		error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
 353		if (error) {
 354			return error;
 355		}
 356		*len = maxlen;
 357		*rtblock = bno;
 358		return 0;
 359	}
 360	/*
 361	 * If not, allocate what there is, if it's at least minlen.
 362	 */
 363	maxlen = next - bno;
 364	if (maxlen < minlen) {
 365		/*
 366		 * Failed, return failure status.
 367		 */
 368		*rtblock = NULLRTBLOCK;
 369		return 0;
 370	}
 371	/*
 372	 * Trim off tail of extent, if prod is specified.
 373	 */
 374	if (prod > 1 && (i = maxlen % prod)) {
 375		maxlen -= i;
 376		if (maxlen < minlen) {
 377			/*
 378			 * Now we can't do it, return failure status.
 379			 */
 380			*rtblock = NULLRTBLOCK;
 381			return 0;
 382		}
 383	}
 384	/*
 385	 * Allocate what we can and return it.
 386	 */
 387	error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb);
 388	if (error) {
 389		return error;
 390	}
 391	*len = maxlen;
 392	*rtblock = bno;
 393	return 0;
 394}
 395
 396/*
 397 * Allocate an extent of length minlen<=len<=maxlen, starting as near
 398 * to bno as possible.  If we don't get maxlen then use prod to trim
 399 * the length, if given.  The lengths are all in rtextents.
 400 */
 401STATIC int				/* error */
 402xfs_rtallocate_extent_near(
 403	xfs_mount_t	*mp,		/* file system mount point */
 404	xfs_trans_t	*tp,		/* transaction pointer */
 405	xfs_rtblock_t	bno,		/* starting block number to allocate */
 406	xfs_extlen_t	minlen,		/* minimum length to allocate */
 407	xfs_extlen_t	maxlen,		/* maximum length to allocate */
 408	xfs_extlen_t	*len,		/* out: actual length allocated */
 409	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
 410	xfs_fsblock_t	*rsb,		/* in/out: summary block number */
 411	xfs_extlen_t	prod,		/* extent product factor */
 412	xfs_rtblock_t	*rtblock)	/* out: start block allocated */
 413{
 414	int		any;		/* any useful extents from summary */
 415	xfs_rtblock_t	bbno;		/* bitmap block number */
 416	int		error;		/* error value */
 417	int		i;		/* bitmap block offset (loop control) */
 418	int		j;		/* secondary loop control */
 419	int		log2len;	/* log2 of minlen */
 420	xfs_rtblock_t	n;		/* next block to try */
 421	xfs_rtblock_t	r;		/* result block */
 422
 423	ASSERT(minlen % prod == 0 && maxlen % prod == 0);
 424	/*
 425	 * If the block number given is off the end, silently set it to
 426	 * the last block.
 427	 */
 428	if (bno >= mp->m_sb.sb_rextents)
 429		bno = mp->m_sb.sb_rextents - 1;
 430	/*
 431	 * Try the exact allocation first.
 432	 */
 433	error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, len,
 434		rbpp, rsb, prod, &r);
 435	if (error) {
 436		return error;
 437	}
 438	/*
 439	 * If the exact allocation worked, return that.
 440	 */
 441	if (r != NULLRTBLOCK) {
 442		*rtblock = r;
 443		return 0;
 444	}
 445	bbno = XFS_BITTOBLOCK(mp, bno);
 446	i = 0;
 447	log2len = xfs_highbit32(minlen);
 448	/*
 449	 * Loop over all bitmap blocks (bbno + i is current block).
 450	 */
 451	for (;;) {
 452		/*
 453		 * Get summary information of extents of all useful levels
 454		 * starting in this bitmap block.
 455		 */
 456		error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1,
 457			bbno + i, rbpp, rsb, &any);
 458		if (error) {
 459			return error;
 460		}
 461		/*
 462		 * If there are any useful extents starting here, try
 463		 * allocating one.
 464		 */
 465		if (any) {
 466			/*
 467			 * On the positive side of the starting location.
 468			 */
 469			if (i >= 0) {
 470				/*
 471				 * Try to allocate an extent starting in
 472				 * this block.
 473				 */
 474				error = xfs_rtallocate_extent_block(mp, tp,
 475					bbno + i, minlen, maxlen, len, &n, rbpp,
 476					rsb, prod, &r);
 477				if (error) {
 478					return error;
 479				}
 480				/*
 481				 * If it worked, return it.
 482				 */
 483				if (r != NULLRTBLOCK) {
 484					*rtblock = r;
 485					return 0;
 486				}
 487			}
 488			/*
 489			 * On the negative side of the starting location.
 490			 */
 491			else {		/* i < 0 */
 492				/*
 493				 * Loop backwards through the bitmap blocks from
 494				 * the starting point-1 up to where we are now.
 495				 * There should be an extent which ends in this
 496				 * bitmap block and is long enough.
 497				 */
 498				for (j = -1; j > i; j--) {
 499					/*
 500					 * Grab the summary information for
 501					 * this bitmap block.
 502					 */
 503					error = xfs_rtany_summary(mp, tp,
 504						log2len, mp->m_rsumlevels - 1,
 505						bbno + j, rbpp, rsb, &any);
 506					if (error) {
 507						return error;
 508					}
 509					/*
 510					 * If there's no extent given in the
 511					 * summary that means the extent we
 512					 * found must carry over from an
 513					 * earlier block.  If there is an
 514					 * extent given, we've already tried
 515					 * that allocation, don't do it again.
 516					 */
 517					if (any)
 518						continue;
 519					error = xfs_rtallocate_extent_block(mp,
 520						tp, bbno + j, minlen, maxlen,
 521						len, &n, rbpp, rsb, prod, &r);
 522					if (error) {
 523						return error;
 524					}
 525					/*
 526					 * If it works, return the extent.
 527					 */
 528					if (r != NULLRTBLOCK) {
 529						*rtblock = r;
 530						return 0;
 531					}
 532				}
 533				/*
 534				 * There weren't intervening bitmap blocks
 535				 * with a long enough extent, or the
 536				 * allocation didn't work for some reason
 537				 * (i.e. it's a little * too short).
 538				 * Try to allocate from the summary block
 539				 * that we found.
 540				 */
 541				error = xfs_rtallocate_extent_block(mp, tp,
 542					bbno + i, minlen, maxlen, len, &n, rbpp,
 543					rsb, prod, &r);
 544				if (error) {
 545					return error;
 546				}
 547				/*
 548				 * If it works, return the extent.
 549				 */
 550				if (r != NULLRTBLOCK) {
 551					*rtblock = r;
 552					return 0;
 553				}
 554			}
 555		}
 556		/*
 557		 * Loop control.  If we were on the positive side, and there's
 558		 * still more blocks on the negative side, go there.
 559		 */
 560		if (i > 0 && (int)bbno - i >= 0)
 561			i = -i;
 562		/*
 563		 * If positive, and no more negative, but there are more
 564		 * positive, go there.
 565		 */
 566		else if (i > 0 && (int)bbno + i < mp->m_sb.sb_rbmblocks - 1)
 567			i++;
 568		/*
 569		 * If negative or 0 (just started), and there are positive
 570		 * blocks to go, go there.  The 0 case moves to block 1.
 571		 */
 572		else if (i <= 0 && (int)bbno - i < mp->m_sb.sb_rbmblocks - 1)
 573			i = 1 - i;
 574		/*
 575		 * If negative or 0 and there are more negative blocks,
 576		 * go there.
 577		 */
 578		else if (i <= 0 && (int)bbno + i > 0)
 579			i--;
 580		/*
 581		 * Must be done.  Return failure.
 582		 */
 583		else
 584			break;
 585	}
 586	*rtblock = NULLRTBLOCK;
 587	return 0;
 588}
 589
 590/*
 591 * Allocate an extent of length minlen<=len<=maxlen, with no position
 592 * specified.  If we don't get maxlen then use prod to trim
 593 * the length, if given.  The lengths are all in rtextents.
 594 */
 595STATIC int				/* error */
 596xfs_rtallocate_extent_size(
 597	xfs_mount_t	*mp,		/* file system mount point */
 598	xfs_trans_t	*tp,		/* transaction pointer */
 599	xfs_extlen_t	minlen,		/* minimum length to allocate */
 600	xfs_extlen_t	maxlen,		/* maximum length to allocate */
 601	xfs_extlen_t	*len,		/* out: actual length allocated */
 602	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
 603	xfs_fsblock_t	*rsb,		/* in/out: summary block number */
 604	xfs_extlen_t	prod,		/* extent product factor */
 605	xfs_rtblock_t	*rtblock)	/* out: start block allocated */
 606{
 607	int		error;		/* error value */
 608	int		i;		/* bitmap block number */
 609	int		l;		/* level number (loop control) */
 610	xfs_rtblock_t	n;		/* next block to be tried */
 611	xfs_rtblock_t	r;		/* result block number */
 612	xfs_suminfo_t	sum;		/* summary information for extents */
 613
 614	ASSERT(minlen % prod == 0 && maxlen % prod == 0);
 615	/*
 616	 * Loop over all the levels starting with maxlen.
 617	 * At each level, look at all the bitmap blocks, to see if there
 618	 * are extents starting there that are long enough (>= maxlen).
 619	 * Note, only on the initial level can the allocation fail if
 620	 * the summary says there's an extent.
 621	 */
 622	for (l = xfs_highbit32(maxlen); l < mp->m_rsumlevels; l++) {
 623		/*
 624		 * Loop over all the bitmap blocks.
 625		 */
 626		for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
 627			/*
 628			 * Get the summary for this level/block.
 629			 */
 630			error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
 631				&sum);
 632			if (error) {
 633				return error;
 634			}
 635			/*
 636			 * Nothing there, on to the next block.
 637			 */
 638			if (!sum)
 639				continue;
 640			/*
 641			 * Try allocating the extent.
 642			 */
 643			error = xfs_rtallocate_extent_block(mp, tp, i, maxlen,
 644				maxlen, len, &n, rbpp, rsb, prod, &r);
 645			if (error) {
 646				return error;
 647			}
 648			/*
 649			 * If it worked, return that.
 650			 */
 651			if (r != NULLRTBLOCK) {
 652				*rtblock = r;
 653				return 0;
 654			}
 655			/*
 656			 * If the "next block to try" returned from the
 657			 * allocator is beyond the next bitmap block,
 658			 * skip to that bitmap block.
 659			 */
 660			if (XFS_BITTOBLOCK(mp, n) > i + 1)
 661				i = XFS_BITTOBLOCK(mp, n) - 1;
 662		}
 663	}
 664	/*
 665	 * Didn't find any maxlen blocks.  Try smaller ones, unless
 666	 * we're asking for a fixed size extent.
 667	 */
 668	if (minlen > --maxlen) {
 669		*rtblock = NULLRTBLOCK;
 670		return 0;
 671	}
 672	/*
 673	 * Loop over sizes, from maxlen down to minlen.
 674	 * This time, when we do the allocations, allow smaller ones
 675	 * to succeed.
 676	 */
 677	for (l = xfs_highbit32(maxlen); l >= xfs_highbit32(minlen); l--) {
 678		/*
 679		 * Loop over all the bitmap blocks, try an allocation
 680		 * starting in that block.
 681		 */
 682		for (i = 0; i < mp->m_sb.sb_rbmblocks; i++) {
 683			/*
 684			 * Get the summary information for this level/block.
 685			 */
 686			error =	xfs_rtget_summary(mp, tp, l, i, rbpp, rsb,
 687						  &sum);
 688			if (error) {
 689				return error;
 690			}
 691			/*
 692			 * If nothing there, go on to next.
 693			 */
 694			if (!sum)
 695				continue;
 696			/*
 697			 * Try the allocation.  Make sure the specified
 698			 * minlen/maxlen are in the possible range for
 699			 * this summary level.
 700			 */
 701			error = xfs_rtallocate_extent_block(mp, tp, i,
 702					XFS_RTMAX(minlen, 1 << l),
 703					XFS_RTMIN(maxlen, (1 << (l + 1)) - 1),
 704					len, &n, rbpp, rsb, prod, &r);
 705			if (error) {
 706				return error;
 707			}
 708			/*
 709			 * If it worked, return that extent.
 710			 */
 711			if (r != NULLRTBLOCK) {
 712				*rtblock = r;
 713				return 0;
 714			}
 715			/*
 716			 * If the "next block to try" returned from the
 717			 * allocator is beyond the next bitmap block,
 718			 * skip to that bitmap block.
 719			 */
 720			if (XFS_BITTOBLOCK(mp, n) > i + 1)
 721				i = XFS_BITTOBLOCK(mp, n) - 1;
 722		}
 723	}
 724	/*
 725	 * Got nothing, return failure.
 726	 */
 727	*rtblock = NULLRTBLOCK;
 728	return 0;
 729}
 730
 731/*
 732 * Mark an extent specified by start and len allocated.
 733 * Updates all the summary information as well as the bitmap.
 734 */
 735STATIC int				/* error */
 736xfs_rtallocate_range(
 737	xfs_mount_t	*mp,		/* file system mount point */
 738	xfs_trans_t	*tp,		/* transaction pointer */
 739	xfs_rtblock_t	start,		/* start block to allocate */
 740	xfs_extlen_t	len,		/* length to allocate */
 741	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
 742	xfs_fsblock_t	*rsb)		/* in/out: summary block number */
 743{
 744	xfs_rtblock_t	end;		/* end of the allocated extent */
 745	int		error;		/* error value */
 746	xfs_rtblock_t	postblock;	/* first block allocated > end */
 747	xfs_rtblock_t	preblock;	/* first block allocated < start */
 748
 749	end = start + len - 1;
 750	/*
 751	 * Assume we're allocating out of the middle of a free extent.
 752	 * We need to find the beginning and end of the extent so we can
 753	 * properly update the summary.
 754	 */
 755	error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
 756	if (error) {
 757		return error;
 758	}
 759	/*
 760	 * Find the next allocated block (end of free extent).
 761	 */
 762	error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
 763		&postblock);
 764	if (error) {
 765		return error;
 766	}
 767	/*
 768	 * Decrement the summary information corresponding to the entire
 769	 * (old) free extent.
 770	 */
 771	error = xfs_rtmodify_summary(mp, tp,
 772		XFS_RTBLOCKLOG(postblock + 1 - preblock),
 773		XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
 774	if (error) {
 775		return error;
 776	}
 777	/*
 778	 * If there are blocks not being allocated at the front of the
 779	 * old extent, add summary data for them to be free.
 780	 */
 781	if (preblock < start) {
 782		error = xfs_rtmodify_summary(mp, tp,
 783			XFS_RTBLOCKLOG(start - preblock),
 784			XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
 785		if (error) {
 786			return error;
 787		}
 788	}
 789	/*
 790	 * If there are blocks not being allocated at the end of the
 791	 * old extent, add summary data for them to be free.
 792	 */
 793	if (postblock > end) {
 794		error = xfs_rtmodify_summary(mp, tp,
 795			XFS_RTBLOCKLOG(postblock - end),
 796			XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb);
 797		if (error) {
 798			return error;
 799		}
 800	}
 801	/*
 802	 * Modify the bitmap to mark this extent allocated.
 803	 */
 804	error = xfs_rtmodify_range(mp, tp, start, len, 0);
 805	return error;
 806}
 807
 808/*
 809 * Return whether there are any free extents in the size range given
 810 * by low and high, for the bitmap block bbno.
 811 */
 812STATIC int				/* error */
 813xfs_rtany_summary(
 814	xfs_mount_t	*mp,		/* file system mount structure */
 815	xfs_trans_t	*tp,		/* transaction pointer */
 816	int		low,		/* low log2 extent size */
 817	int		high,		/* high log2 extent size */
 818	xfs_rtblock_t	bbno,		/* bitmap block number */
 819	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
 820	xfs_fsblock_t	*rsb,		/* in/out: summary block number */
 821	int		*stat)		/* out: any good extents here? */
 822{
 823	int		error;		/* error value */
 824	int		log;		/* loop counter, log2 of ext. size */
 825	xfs_suminfo_t	sum;		/* summary data */
 826
 827	/*
 828	 * Loop over logs of extent sizes.  Order is irrelevant.
 829	 */
 830	for (log = low; log <= high; log++) {
 831		/*
 832		 * Get one summary datum.
 833		 */
 834		error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum);
 835		if (error) {
 836			return error;
 837		}
 838		/*
 839		 * If there are any, return success.
 840		 */
 841		if (sum) {
 842			*stat = 1;
 843			return 0;
 844		}
 845	}
 846	/*
 847	 * Found nothing, return failure.
 848	 */
 849	*stat = 0;
 850	return 0;
 851}
 852
 853/*
 854 * Get a buffer for the bitmap or summary file block specified.
 855 * The buffer is returned read and locked.
 856 */
 857STATIC int				/* error */
 858xfs_rtbuf_get(
 859	xfs_mount_t	*mp,		/* file system mount structure */
 860	xfs_trans_t	*tp,		/* transaction pointer */
 861	xfs_rtblock_t	block,		/* block number in bitmap or summary */
 862	int		issum,		/* is summary not bitmap */
 863	xfs_buf_t	**bpp)		/* output: buffer for the block */
 864{
 865	xfs_buf_t	*bp;		/* block buffer, result */
 866	xfs_daddr_t	d;		/* disk addr of block */
 867	int		error;		/* error value */
 868	xfs_fsblock_t	fsb;		/* fs block number for block */
 869	xfs_inode_t	*ip;		/* bitmap or summary inode */
 870
 871	ip = issum ? mp->m_rsumip : mp->m_rbmip;
 872	/*
 873	 * Map from the file offset (block) and inode number to the
 874	 * file system block.
 875	 */
 876	error = xfs_bmapi_single(tp, ip, XFS_DATA_FORK, &fsb, block);
 877	if (error) {
 878		return error;
 879	}
 880	ASSERT(fsb != NULLFSBLOCK);
 881	/*
 882	 * Convert to disk address for buffer cache.
 883	 */
 884	d = XFS_FSB_TO_DADDR(mp, fsb);
 885	/*
 886	 * Read the buffer.
 887	 */
 888	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
 889				   mp->m_bsize, 0, &bp);
 890	if (error) {
 891		return error;
 892	}
 893	ASSERT(bp && !XFS_BUF_GETERROR(bp));
 894	*bpp = bp;
 895	return 0;
 896}
 897
 898#ifdef DEBUG
 899/*
 900 * Check that the given extent (block range) is allocated already.
 901 */
 902STATIC int				/* error */
 903xfs_rtcheck_alloc_range(
 904	xfs_mount_t	*mp,		/* file system mount point */
 905	xfs_trans_t	*tp,		/* transaction pointer */
 906	xfs_rtblock_t	bno,		/* starting block number of extent */
 907	xfs_extlen_t	len,		/* length of extent */
 908	int		*stat)		/* out: 1 for allocated, 0 for not */
 909{
 910	xfs_rtblock_t	new;		/* dummy for xfs_rtcheck_range */
 911
 912	return xfs_rtcheck_range(mp, tp, bno, len, 0, &new, stat);
 913}
 914#endif
 915
 916/*
 917 * Check that the given range is either all allocated (val = 0) or
 918 * all free (val = 1).
 919 */
 920STATIC int				/* error */
 921xfs_rtcheck_range(
 922	xfs_mount_t	*mp,		/* file system mount point */
 923	xfs_trans_t	*tp,		/* transaction pointer */
 924	xfs_rtblock_t	start,		/* starting block number of extent */
 925	xfs_extlen_t	len,		/* length of extent */
 926	int		val,		/* 1 for free, 0 for allocated */
 927	xfs_rtblock_t	*new,		/* out: first block not matching */
 928	int		*stat)		/* out: 1 for matches, 0 for not */
 929{
 930	xfs_rtword_t	*b;		/* current word in buffer */
 931	int		bit;		/* bit number in the word */
 932	xfs_rtblock_t	block;		/* bitmap block number */
 933	xfs_buf_t	*bp;		/* buf for the block */
 934	xfs_rtword_t	*bufp;		/* starting word in buffer */
 935	int		error;		/* error value */
 936	xfs_rtblock_t	i;		/* current bit number rel. to start */
 937	xfs_rtblock_t	lastbit;	/* last useful bit in word */
 938	xfs_rtword_t	mask;		/* mask of relevant bits for value */
 939	xfs_rtword_t	wdiff;		/* difference from wanted value */
 940	int		word;		/* word number in the buffer */
 941
 942	/*
 943	 * Compute starting bitmap block number
 944	 */
 945	block = XFS_BITTOBLOCK(mp, start);
 946	/*
 947	 * Read the bitmap block.
 948	 */
 949	error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
 950	if (error) {
 951		return error;
 952	}
 953	bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
 954	/*
 955	 * Compute the starting word's address, and starting bit.
 956	 */
 957	word = XFS_BITTOWORD(mp, start);
 958	b = &bufp[word];
 959	bit = (int)(start & (XFS_NBWORD - 1));
 960	/*
 961	 * 0 (allocated) => all zero's; 1 (free) => all one's.
 962	 */
 963	val = -val;
 964	/*
 965	 * If not starting on a word boundary, deal with the first
 966	 * (partial) word.
 967	 */
 968	if (bit) {
 969		/*
 970		 * Compute first bit not examined.
 971		 */
 972		lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
 973		/*
 974		 * Mask of relevant bits.
 975		 */
 976		mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
 977		/*
 978		 * Compute difference between actual and desired value.
 979		 */
 980		if ((wdiff = (*b ^ val) & mask)) {
 981			/*
 982			 * Different, compute first wrong bit and return.
 983			 */
 984			xfs_trans_brelse(tp, bp);
 985			i = XFS_RTLOBIT(wdiff) - bit;
 986			*new = start + i;
 987			*stat = 0;
 988			return 0;
 989		}
 990		i = lastbit - bit;
 991		/*
 992		 * Go on to next block if that's where the next word is
 993		 * and we need the next word.
 994		 */
 995		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
 996			/*
 997			 * If done with this block, get the next one.
 998			 */
 999			xfs_trans_brelse(tp, bp);
1000			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1001			if (error) {
1002				return error;
1003			}
1004			b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1005			word = 0;
1006		} else {
1007			/*
1008			 * Go on to the next word in the buffer.
1009			 */
1010			b++;
1011		}
1012	} else {
1013		/*
1014		 * Starting on a word boundary, no partial word.
1015		 */
1016		i = 0;
1017	}
1018	/*
1019	 * Loop over whole words in buffers.  When we use up one buffer
1020	 * we move on to the next one.
1021	 */
1022	while (len - i >= XFS_NBWORD) {
1023		/*
1024		 * Compute difference between actual and desired value.
1025		 */
1026		if ((wdiff = *b ^ val)) {
1027			/*
1028			 * Different, compute first wrong bit and return.
1029			 */
1030			xfs_trans_brelse(tp, bp);
1031			i += XFS_RTLOBIT(wdiff);
1032			*new = start + i;
1033			*stat = 0;
1034			return 0;
1035		}
1036		i += XFS_NBWORD;
1037		/*
1038		 * Go on to next block if that's where the next word is
1039		 * and we need the next word.
1040		 */
1041		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
1042			/*
1043			 * If done with this block, get the next one.
1044			 */
1045			xfs_trans_brelse(tp, bp);
1046			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1047			if (error) {
1048				return error;
1049			}
1050			b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1051			word = 0;
1052		} else {
1053			/*
1054			 * Go on to the next word in the buffer.
1055			 */
1056			b++;
1057		}
1058	}
1059	/*
1060	 * If not ending on a word boundary, deal with the last
1061	 * (partial) word.
1062	 */
1063	if ((lastbit = len - i)) {
1064		/*
1065		 * Mask of relevant bits.
1066		 */
1067		mask = ((xfs_rtword_t)1 << lastbit) - 1;
1068		/*
1069		 * Compute difference between actual and desired value.
1070		 */
1071		if ((wdiff = (*b ^ val) & mask)) {
1072			/*
1073			 * Different, compute first wrong bit and return.
1074			 */
1075			xfs_trans_brelse(tp, bp);
1076			i += XFS_RTLOBIT(wdiff);
1077			*new = start + i;
1078			*stat = 0;
1079			return 0;
1080		} else
1081			i = len;
1082	}
1083	/*
1084	 * Successful, return.
1085	 */
1086	xfs_trans_brelse(tp, bp);
1087	*new = start + i;
1088	*stat = 1;
1089	return 0;
1090}
1091
1092/*
1093 * Copy and transform the summary file, given the old and new
1094 * parameters in the mount structures.
1095 */
1096STATIC int				/* error */
1097xfs_rtcopy_summary(
1098	xfs_mount_t	*omp,		/* old file system mount point */
1099	xfs_mount_t	*nmp,		/* new file system mount point */
1100	xfs_trans_t	*tp)		/* transaction pointer */
1101{
1102	xfs_rtblock_t	bbno;		/* bitmap block number */
1103	xfs_buf_t	*bp;		/* summary buffer */
1104	int		error;		/* error return value */
1105	int		log;		/* summary level number (log length) */
1106	xfs_suminfo_t	sum;		/* summary data */
1107	xfs_fsblock_t	sumbno;		/* summary block number */
1108
1109	bp = NULL;
1110	for (log = omp->m_rsumlevels - 1; log >= 0; log--) {
1111		for (bbno = omp->m_sb.sb_rbmblocks - 1;
1112		     (xfs_srtblock_t)bbno >= 0;
1113		     bbno--) {
1114			error = xfs_rtget_summary(omp, tp, log, bbno, &bp,
1115				&sumbno, &sum);
1116			if (error)
1117				return error;
1118			if (sum == 0)
1119				continue;
1120			error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum,
1121				&bp, &sumbno);
1122			if (error)
1123				return error;
1124			error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum,
1125				&bp, &sumbno);
1126			if (error)
1127				return error;
1128			ASSERT(sum > 0);
1129		}
1130	}
1131	return 0;
1132}
1133
1134/*
1135 * Searching backward from start to limit, find the first block whose
1136 * allocated/free state is different from start's.
1137 */
1138STATIC int				/* error */
1139xfs_rtfind_back(
1140	xfs_mount_t	*mp,		/* file system mount point */
1141	xfs_trans_t	*tp,		/* transaction pointer */
1142	xfs_rtblock_t	start,		/* starting block to look at */
1143	xfs_rtblock_t	limit,		/* last block to look at */
1144	xfs_rtblock_t	*rtblock)	/* out: start block found */
1145{
1146	xfs_rtword_t	*b;		/* current word in buffer */
1147	int		bit;		/* bit number in the word */
1148	xfs_rtblock_t	block;		/* bitmap block number */
1149	xfs_buf_t	*bp;		/* buf for the block */
1150	xfs_rtword_t	*bufp;		/* starting word in buffer */
1151	int		error;		/* error value */
1152	xfs_rtblock_t	firstbit;	/* first useful bit in the word */
1153	xfs_rtblock_t	i;		/* current bit number rel. to start */
1154	xfs_rtblock_t	len;		/* length of inspected area */
1155	xfs_rtword_t	mask;		/* mask of relevant bits for value */
1156	xfs_rtword_t	want;		/* mask for "good" values */
1157	xfs_rtword_t	wdiff;		/* difference from wanted value */
1158	int		word;		/* word number in the buffer */
1159
1160	/*
1161	 * Compute and read in starting bitmap block for starting block.
1162	 */
1163	block = XFS_BITTOBLOCK(mp, start);
1164	error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
1165	if (error) {
1166		return error;
1167	}
1168	bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1169	/*
1170	 * Get the first word's index & point to it.
1171	 */
1172	word = XFS_BITTOWORD(mp, start);
1173	b = &bufp[word];
1174	bit = (int)(start & (XFS_NBWORD - 1));
1175	len = start - limit + 1;
1176	/*
1177	 * Compute match value, based on the bit at start: if 1 (free)
1178	 * then all-ones, else all-zeroes.
1179	 */
1180	want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
1181	/*
1182	 * If the starting position is not word-aligned, deal with the
1183	 * partial word.
1184	 */
1185	if (bit < XFS_NBWORD - 1) {
1186		/*
1187		 * Calculate first (leftmost) bit number to look at,
1188		 * and mask for all the relevant bits in this word.
1189		 */
1190		firstbit = XFS_RTMAX((xfs_srtblock_t)(bit - len + 1), 0);
1191		mask = (((xfs_rtword_t)1 << (bit - firstbit + 1)) - 1) <<
1192			firstbit;
1193		/*
1194		 * Calculate the difference between the value there
1195		 * and what we're looking for.
1196		 */
1197		if ((wdiff = (*b ^ want) & mask)) {
1198			/*
1199			 * Different.  Mark where we are and return.
1200			 */
1201			xfs_trans_brelse(tp, bp);
1202			i = bit - XFS_RTHIBIT(wdiff);
1203			*rtblock = start - i + 1;
1204			return 0;
1205		}
1206		i = bit - firstbit + 1;
1207		/*
1208		 * Go on to previous block if that's where the previous word is
1209		 * and we need the previous word.
1210		 */
1211		if (--word == -1 && i < len) {
1212			/*
1213			 * If done with this block, get the previous one.
1214			 */
1215			xfs_trans_brelse(tp, bp);
1216			error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
1217			if (error) {
1218				return error;
1219			}
1220			bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1221			word = XFS_BLOCKWMASK(mp);
1222			b = &bufp[word];
1223		} else {
1224			/*
1225			 * Go on to the previous word in the buffer.
1226			 */
1227			b--;
1228		}
1229	} else {
1230		/*
1231		 * Starting on a word boundary, no partial word.
1232		 */
1233		i = 0;
1234	}
1235	/*
1236	 * Loop over whole words in buffers.  When we use up one buffer
1237	 * we move on to the previous one.
1238	 */
1239	while (len - i >= XFS_NBWORD) {
1240		/*
1241		 * Compute difference between actual and desired value.
1242		 */
1243		if ((wdiff = *b ^ want)) {
1244			/*
1245			 * Different, mark where we are and return.
1246			 */
1247			xfs_trans_brelse(tp, bp);
1248			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
1249			*rtblock = start - i + 1;
1250			return 0;
1251		}
1252		i += XFS_NBWORD;
1253		/*
1254		 * Go on to previous block if that's where the previous word is
1255		 * and we need the previous word.
1256		 */
1257		if (--word == -1 && i < len) {
1258			/*
1259			 * If done with this block, get the previous one.
1260			 */
1261			xfs_trans_brelse(tp, bp);
1262			error = xfs_rtbuf_get(mp, tp, --block, 0, &bp);
1263			if (error) {
1264				return error;
1265			}
1266			bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1267			word = XFS_BLOCKWMASK(mp);
1268			b = &bufp[word];
1269		} else {
1270			/*
1271			 * Go on to the previous word in the buffer.
1272			 */
1273			b--;
1274		}
1275	}
1276	/*
1277	 * If not ending on a word boundary, deal with the last
1278	 * (partial) word.
1279	 */
1280	if (len - i) {
1281		/*
1282		 * Calculate first (leftmost) bit number to look at,
1283		 * and mask for all the relevant bits in this word.
1284		 */
1285		firstbit = XFS_NBWORD - (len - i);
1286		mask = (((xfs_rtword_t)1 << (len - i)) - 1) << firstbit;
1287		/*
1288		 * Compute difference between actual and desired value.
1289		 */
1290		if ((wdiff = (*b ^ want) & mask)) {
1291			/*
1292			 * Different, mark where we are and return.
1293			 */
1294			xfs_trans_brelse(tp, bp);
1295			i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff);
1296			*rtblock = start - i + 1;
1297			return 0;
1298		} else
1299			i = len;
1300	}
1301	/*
1302	 * No match, return that we scanned the whole area.
1303	 */
1304	xfs_trans_brelse(tp, bp);
1305	*rtblock = start - i + 1;
1306	return 0;
1307}
1308
1309/*
1310 * Searching forward from start to limit, find the first block whose
1311 * allocated/free state is different from start's.
1312 */
1313STATIC int				/* error */
1314xfs_rtfind_forw(
1315	xfs_mount_t	*mp,		/* file system mount point */
1316	xfs_trans_t	*tp,		/* transaction pointer */
1317	xfs_rtblock_t	start,		/* starting block to look at */
1318	xfs_rtblock_t	limit,		/* last block to look at */
1319	xfs_rtblock_t	*rtblock)	/* out: start block found */
1320{
1321	xfs_rtword_t	*b;		/* current word in buffer */
1322	int		bit;		/* bit number in the word */
1323	xfs_rtblock_t	block;		/* bitmap block number */
1324	xfs_buf_t	*bp;		/* buf for the block */
1325	xfs_rtword_t	*bufp;		/* starting word in buffer */
1326	int		error;		/* error value */
1327	xfs_rtblock_t	i;		/* current bit number rel. to start */
1328	xfs_rtblock_t	lastbit;	/* last useful bit in the word */
1329	xfs_rtblock_t	len;		/* length of inspected area */
1330	xfs_rtword_t	mask;		/* mask of relevant bits for value */
1331	xfs_rtword_t	want;		/* mask for "good" values */
1332	xfs_rtword_t	wdiff;		/* difference from wanted value */
1333	int		word;		/* word number in the buffer */
1334
1335	/*
1336	 * Compute and read in starting bitmap block for starting block.
1337	 */
1338	block = XFS_BITTOBLOCK(mp, start);
1339	error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
1340	if (error) {
1341		return error;
1342	}
1343	bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1344	/*
1345	 * Get the first word's index & point to it.
1346	 */
1347	word = XFS_BITTOWORD(mp, start);
1348	b = &bufp[word];
1349	bit = (int)(start & (XFS_NBWORD - 1));
1350	len = limit - start + 1;
1351	/*
1352	 * Compute match value, based on the bit at start: if 1 (free)
1353	 * then all-ones, else all-zeroes.
1354	 */
1355	want = (*b & ((xfs_rtword_t)1 << bit)) ? -1 : 0;
1356	/*
1357	 * If the starting position is not word-aligned, deal with the
1358	 * partial word.
1359	 */
1360	if (bit) {
1361		/*
1362		 * Calculate last (rightmost) bit number to look at,
1363		 * and mask for all the relevant bits in this word.
1364		 */
1365		lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
1366		mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
1367		/*
1368		 * Calculate the difference between the value there
1369		 * and what we're looking for.
1370		 */
1371		if ((wdiff = (*b ^ want) & mask)) {
1372			/*
1373			 * Different.  Mark where we are and return.
1374			 */
1375			xfs_trans_brelse(tp, bp);
1376			i = XFS_RTLOBIT(wdiff) - bit;
1377			*rtblock = start + i - 1;
1378			return 0;
1379		}
1380		i = lastbit - bit;
1381		/*
1382		 * Go on to next block if that's where the next word is
1383		 * and we need the next word.
1384		 */
1385		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
1386			/*
1387			 * If done with this block, get the previous one.
1388			 */
1389			xfs_trans_brelse(tp, bp);
1390			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1391			if (error) {
1392				return error;
1393			}
1394			b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1395			word = 0;
1396		} else {
1397			/*
1398			 * Go on to the previous word in the buffer.
1399			 */
1400			b++;
1401		}
1402	} else {
1403		/*
1404		 * Starting on a word boundary, no partial word.
1405		 */
1406		i = 0;
1407	}
1408	/*
1409	 * Loop over whole words in buffers.  When we use up one buffer
1410	 * we move on to the next one.
1411	 */
1412	while (len - i >= XFS_NBWORD) {
1413		/*
1414		 * Compute difference between actual and desired value.
1415		 */
1416		if ((wdiff = *b ^ want)) {
1417			/*
1418			 * Different, mark where we are and return.
1419			 */
1420			xfs_trans_brelse(tp, bp);
1421			i += XFS_RTLOBIT(wdiff);
1422			*rtblock = start + i - 1;
1423			return 0;
1424		}
1425		i += XFS_NBWORD;
1426		/*
1427		 * Go on to next block if that's where the next word is
1428		 * and we need the next word.
1429		 */
1430		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
1431			/*
1432			 * If done with this block, get the next one.
1433			 */
1434			xfs_trans_brelse(tp, bp);
1435			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1436			if (error) {
1437				return error;
1438			}
1439			b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1440			word = 0;
1441		} else {
1442			/*
1443			 * Go on to the next word in the buffer.
1444			 */
1445			b++;
1446		}
1447	}
1448	/*
1449	 * If not ending on a word boundary, deal with the last
1450	 * (partial) word.
1451	 */
1452	if ((lastbit = len - i)) {
1453		/*
1454		 * Calculate mask for all the relevant bits in this word.
1455		 */
1456		mask = ((xfs_rtword_t)1 << lastbit) - 1;
1457		/*
1458		 * Compute difference between actual and desired value.
1459		 */
1460		if ((wdiff = (*b ^ want) & mask)) {
1461			/*
1462			 * Different, mark where we are and return.
1463			 */
1464			xfs_trans_brelse(tp, bp);
1465			i += XFS_RTLOBIT(wdiff);
1466			*rtblock = start + i - 1;
1467			return 0;
1468		} else
1469			i = len;
1470	}
1471	/*
1472	 * No match, return that we scanned the whole area.
1473	 */
1474	xfs_trans_brelse(tp, bp);
1475	*rtblock = start + i - 1;
1476	return 0;
1477}
1478
1479/*
1480 * Mark an extent specified by start and len freed.
1481 * Updates all the summary information as well as the bitmap.
1482 */
1483STATIC int				/* error */
1484xfs_rtfree_range(
1485	xfs_mount_t	*mp,		/* file system mount point */
1486	xfs_trans_t	*tp,		/* transaction pointer */
1487	xfs_rtblock_t	start,		/* starting block to free */
1488	xfs_extlen_t	len,		/* length to free */
1489	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
1490	xfs_fsblock_t	*rsb)		/* in/out: summary block number */
1491{
1492	xfs_rtblock_t	end;		/* end of the freed extent */
1493	int		error;		/* error value */
1494	xfs_rtblock_t	postblock;	/* first block freed > end */
1495	xfs_rtblock_t	preblock;	/* first block freed < start */
1496
1497	end = start + len - 1;
1498	/*
1499	 * Modify the bitmap to mark this extent freed.
1500	 */
1501	error = xfs_rtmodify_range(mp, tp, start, len, 1);
1502	if (error) {
1503		return error;
1504	}
1505	/*
1506	 * Assume we're freeing out of the middle of an allocated extent.
1507	 * We need to find the beginning and end of the extent so we can
1508	 * properly update the summary.
1509	 */
1510	error = xfs_rtfind_back(mp, tp, start, 0, &preblock);
1511	if (error) {
1512		return error;
1513	}
1514	/*
1515	 * Find the next allocated block (end of allocated extent).
1516	 */
1517	error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1,
1518		&postblock);
1519	/*
1520	 * If there are blocks not being freed at the front of the
1521	 * old extent, add summary data for them to be allocated.
1522	 */
1523	if (preblock < start) {
1524		error = xfs_rtmodify_summary(mp, tp,
1525			XFS_RTBLOCKLOG(start - preblock),
1526			XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb);
1527		if (error) {
1528			return error;
1529		}
1530	}
1531	/*
1532	 * If there are blocks not being freed at the end of the
1533	 * old extent, add summary data for them to be allocated.
1534	 */
1535	if (postblock > end) {
1536		error = xfs_rtmodify_summary(mp, tp,
1537			XFS_RTBLOCKLOG(postblock - end),
1538			XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb);
1539		if (error) {
1540			return error;
1541		}
1542	}
1543	/*
1544	 * Increment the summary information corresponding to the entire
1545	 * (new) free extent.
1546	 */
1547	error = xfs_rtmodify_summary(mp, tp,
1548		XFS_RTBLOCKLOG(postblock + 1 - preblock),
1549		XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb);
1550	return error;
1551}
1552
1553/*
1554 * Read and return the summary information for a given extent size,
1555 * bitmap block combination.
1556 * Keeps track of a current summary block, so we don't keep reading
1557 * it from the buffer cache.
1558 */
1559STATIC int				/* error */
1560xfs_rtget_summary(
1561	xfs_mount_t	*mp,		/* file system mount structure */
1562	xfs_trans_t	*tp,		/* transaction pointer */
1563	int		log,		/* log2 of extent size */
1564	xfs_rtblock_t	bbno,		/* bitmap block number */
1565	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
1566	xfs_fsblock_t	*rsb,		/* in/out: summary block number */
1567	xfs_suminfo_t	*sum)		/* out: summary info for this block */
1568{
1569	xfs_buf_t	*bp;		/* buffer for summary block */
1570	int		error;		/* error value */
1571	xfs_fsblock_t	sb;		/* summary fsblock */
1572	int		so;		/* index into the summary file */
1573	xfs_suminfo_t	*sp;		/* pointer to returned data */
1574
1575	/*
1576	 * Compute entry number in the summary file.
1577	 */
1578	so = XFS_SUMOFFS(mp, log, bbno);
1579	/*
1580	 * Compute the block number in the summary file.
1581	 */
1582	sb = XFS_SUMOFFSTOBLOCK(mp, so);
1583	/*
1584	 * If we have an old buffer, and the block number matches, use that.
1585	 */
1586	if (rbpp && *rbpp && *rsb == sb)
1587		bp = *rbpp;
1588	/*
1589	 * Otherwise we have to get the buffer.
1590	 */
1591	else {
1592		/*
1593		 * If there was an old one, get rid of it first.
1594		 */
1595		if (rbpp && *rbpp)
1596			xfs_trans_brelse(tp, *rbpp);
1597		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
1598		if (error) {
1599			return error;
1600		}
1601		/*
1602		 * Remember this buffer and block for the next call.
1603		 */
1604		if (rbpp) {
1605			*rbpp = bp;
1606			*rsb = sb;
1607		}
1608	}
1609	/*
1610	 * Point to the summary information & copy it out.
1611	 */
1612	sp = XFS_SUMPTR(mp, bp, so);
1613	*sum = *sp;
1614	/*
1615	 * Drop the buffer if we're not asked to remember it.
1616	 */
1617	if (!rbpp)
1618		xfs_trans_brelse(tp, bp);
1619	return 0;
1620}
1621
1622/*
1623 * Set the given range of bitmap bits to the given value.
1624 * Do whatever I/O and logging is required.
1625 */
1626STATIC int				/* error */
1627xfs_rtmodify_range(
1628	xfs_mount_t	*mp,		/* file system mount point */
1629	xfs_trans_t	*tp,		/* transaction pointer */
1630	xfs_rtblock_t	start,		/* starting block to modify */
1631	xfs_extlen_t	len,		/* length of extent to modify */
1632	int		val)		/* 1 for free, 0 for allocated */
1633{
1634	xfs_rtword_t	*b;		/* current word in buffer */
1635	int		bit;		/* bit number in the word */
1636	xfs_rtblock_t	block;		/* bitmap block number */
1637	xfs_buf_t	*bp;		/* buf for the block */
1638	xfs_rtword_t	*bufp;		/* starting word in buffer */
1639	int		error;		/* error value */
1640	xfs_rtword_t	*first;		/* first used word in the buffer */
1641	int		i;		/* current bit number rel. to start */
1642	int		lastbit;	/* last useful bit in word */
1643	xfs_rtword_t	mask;		/* mask o frelevant bits for value */
1644	int		word;		/* word number in the buffer */
1645
1646	/*
1647	 * Compute starting bitmap block number.
1648	 */
1649	block = XFS_BITTOBLOCK(mp, start);
1650	/*
1651	 * Read the bitmap block, and point to its data.
1652	 */
1653	error = xfs_rtbuf_get(mp, tp, block, 0, &bp);
1654	if (error) {
1655		return error;
1656	}
1657	bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1658	/*
1659	 * Compute the starting word's address, and starting bit.
1660	 */
1661	word = XFS_BITTOWORD(mp, start);
1662	first = b = &bufp[word];
1663	bit = (int)(start & (XFS_NBWORD - 1));
1664	/*
1665	 * 0 (allocated) => all zeroes; 1 (free) => all ones.
1666	 */
1667	val = -val;
1668	/*
1669	 * If not starting on a word boundary, deal with the first
1670	 * (partial) word.
1671	 */
1672	if (bit) {
1673		/*
1674		 * Compute first bit not changed and mask of relevant bits.
1675		 */
1676		lastbit = XFS_RTMIN(bit + len, XFS_NBWORD);
1677		mask = (((xfs_rtword_t)1 << (lastbit - bit)) - 1) << bit;
1678		/*
1679		 * Set/clear the active bits.
1680		 */
1681		if (val)
1682			*b |= mask;
1683		else
1684			*b &= ~mask;
1685		i = lastbit - bit;
1686		/*
1687		 * Go on to the next block if that's where the next word is
1688		 * and we need the next word.
1689		 */
1690		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
1691			/*
1692			 * Log the changed part of this block.
1693			 * Get the next one.
1694			 */
1695			xfs_trans_log_buf(tp, bp,
1696				(uint)((char *)first - (char *)bufp),
1697				(uint)((char *)b - (char *)bufp));
1698			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1699			if (error) {
1700				return error;
1701			}
1702			first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1703			word = 0;
1704		} else {
1705			/*
1706			 * Go on to the next word in the buffer
1707			 */
1708			b++;
1709		}
1710	} else {
1711		/*
1712		 * Starting on a word boundary, no partial word.
1713		 */
1714		i = 0;
1715	}
1716	/*
1717	 * Loop over whole words in buffers.  When we use up one buffer
1718	 * we move on to the next one.
1719	 */
1720	while (len - i >= XFS_NBWORD) {
1721		/*
1722		 * Set the word value correctly.
1723		 */
1724		*b = val;
1725		i += XFS_NBWORD;
1726		/*
1727		 * Go on to the next block if that's where the next word is
1728		 * and we need the next word.
1729		 */
1730		if (++word == XFS_BLOCKWSIZE(mp) && i < len) {
1731			/*
1732			 * Log the changed part of this block.
1733			 * Get the next one.
1734			 */
1735			xfs_trans_log_buf(tp, bp,
1736				(uint)((char *)first - (char *)bufp),
1737				(uint)((char *)b - (char *)bufp));
1738			error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp);
1739			if (error) {
1740				return error;
1741			}
1742			first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp);
1743			word = 0;
1744		} else {
1745			/*
1746			 * Go on to the next word in the buffer
1747			 */
1748			b++;
1749		}
1750	}
1751	/*
1752	 * If not ending on a word boundary, deal with the last
1753	 * (partial) word.
1754	 */
1755	if ((lastbit = len - i)) {
1756		/*
1757		 * Compute a mask of relevant bits.
1758		 */
1759		bit = 0;
1760		mask = ((xfs_rtword_t)1 << lastbit) - 1;
1761		/*
1762		 * Set/clear the active bits.
1763		 */
1764		if (val)
1765			*b |= mask;
1766		else
1767			*b &= ~mask;
1768		b++;
1769	}
1770	/*
1771	 * Log any remaining changed bytes.
1772	 */
1773	if (b > first)
1774		xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp),
1775			(uint)((char *)b - (char *)bufp - 1));
1776	return 0;
1777}
1778
1779/*
1780 * Read and modify the summary information for a given extent size,
1781 * bitmap block combination.
1782 * Keeps track of a current summary block, so we don't keep reading
1783 * it from the buffer cache.
1784 */
1785STATIC int				/* error */
1786xfs_rtmodify_summary(
1787	xfs_mount_t	*mp,		/* file system mount point */
1788	xfs_trans_t	*tp,		/* transaction pointer */
1789	int		log,		/* log2 of extent size */
1790	xfs_rtblock_t	bbno,		/* bitmap block number */
1791	int		delta,		/* change to make to summary info */
1792	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
1793	xfs_fsblock_t	*rsb)		/* in/out: summary block number */
1794{
1795	xfs_buf_t	*bp;		/* buffer for the summary block */
1796	int		error;		/* error value */
1797	xfs_fsblock_t	sb;		/* summary fsblock */
1798	int		so;		/* index into the summary file */
1799	xfs_suminfo_t	*sp;		/* pointer to returned data */
1800
1801	/*
1802	 * Compute entry number in the summary file.
1803	 */
1804	so = XFS_SUMOFFS(mp, log, bbno);
1805	/*
1806	 * Compute the block number in the summary file.
1807	 */
1808	sb = XFS_SUMOFFSTOBLOCK(mp, so);
1809	/*
1810	 * If we have an old buffer, and the block number matches, use that.
1811	 */
1812	if (rbpp && *rbpp && *rsb == sb)
1813		bp = *rbpp;
1814	/*
1815	 * Otherwise we have to get the buffer.
1816	 */
1817	else {
1818		/*
1819		 * If there was an old one, get rid of it first.
1820		 */
1821		if (rbpp && *rbpp)
1822			xfs_trans_brelse(tp, *rbpp);
1823		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
1824		if (error) {
1825			return error;
1826		}
1827		/*
1828		 * Remember this buffer and block for the next call.
1829		 */
1830		if (rbpp) {
1831			*rbpp = bp;
1832			*rsb = sb;
1833		}
1834	}
1835	/*
1836	 * Point to the summary information, modify and log it.
1837	 */
1838	sp = XFS_SUMPTR(mp, bp, so);
1839	*sp += delta;
1840	xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)XFS_BUF_PTR(bp)),
1841		(uint)((char *)sp - (char *)XFS_BUF_PTR(bp) + sizeof(*sp) - 1));
1842	return 0;
1843}
1844
1845/*
1846 * Visible (exported) functions.
1847 */
1848
1849/*
1850 * Grow the realtime area of the filesystem.
1851 */
1852int
1853xfs_growfs_rt(
1854	xfs_mount_t	*mp,		/* mount point for filesystem */
1855	xfs_growfs_rt_t	*in)		/* growfs rt input struct */
1856{
1857	xfs_rtblock_t	bmbno;		/* bitmap block number */
1858	xfs_buf_t	*bp;		/* temporary buffer */
1859	int		cancelflags;	/* flags for xfs_trans_cancel */
1860	int		error;		/* error return value */
1861	xfs_inode_t	*ip;		/* bitmap inode, used as lock */
1862	xfs_mount_t	*nmp;		/* new (fake) mount structure */
1863	xfs_drfsbno_t	nrblocks;	/* new number of realtime blocks */
1864	xfs_extlen_t	nrbmblocks;	/* new number of rt bitmap blocks */
1865	xfs_drtbno_t	nrextents;	/* new number of realtime extents */
1866	uint8_t		nrextslog;	/* new log2 of sb_rextents */
1867	xfs_extlen_t	nrsumblocks;	/* new number of summary blocks */
1868	uint		nrsumlevels;	/* new rt summary levels */
1869	uint		nrsumsize;	/* new size of rt summary, bytes */
1870	xfs_sb_t	*nsbp;		/* new superblock */
1871	xfs_extlen_t	rbmblocks;	/* current number of rt bitmap blocks */
1872	xfs_extlen_t	rsumblocks;	/* current number of rt summary blks */
1873

Large files files are truncated, but you can click here to view the full file