PageRenderTime 8ms CodeModel.GetById 2ms app.highlight 63ms RepoModel.GetById 1ms app.codeStats 1ms

/fs/xfs/xfs_rtalloc.c

https://bitbucket.org/evzijst/gittest
C | 2469 lines | 1495 code | 69 blank | 905 comment | 293 complexity | d804284312fe0d3edb8a8c4c1967d33c MD5 | raw file

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

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

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