Linux Audio

Check our new training course

Loading...
v6.8
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2014 Red Hat, Inc.
   4 * All Rights Reserved.
 
 
 
 
 
 
 
 
 
 
 
 
 
   5 */
   6#include "xfs.h"
   7#include "xfs_fs.h"
   8#include "xfs_shared.h"
   9#include "xfs_format.h"
  10#include "xfs_log_format.h"
  11#include "xfs_trans_resv.h"
  12#include "xfs_bit.h"
  13#include "xfs_mount.h"
  14#include "xfs_sb.h"
 
  15#include "xfs_defer.h"
 
 
  16#include "xfs_btree.h"
  17#include "xfs_trans.h"
  18#include "xfs_alloc.h"
  19#include "xfs_rmap.h"
  20#include "xfs_rmap_btree.h"
 
  21#include "xfs_trace.h"
  22#include "xfs_errortag.h"
  23#include "xfs_error.h"
 
 
  24#include "xfs_inode.h"
  25#include "xfs_ag.h"
  26
  27struct kmem_cache	*xfs_rmap_intent_cache;
  28
  29/*
  30 * Lookup the first record less than or equal to [bno, len, owner, offset]
  31 * in the btree given by cur.
  32 */
  33int
  34xfs_rmap_lookup_le(
  35	struct xfs_btree_cur	*cur,
  36	xfs_agblock_t		bno,
 
  37	uint64_t		owner,
  38	uint64_t		offset,
  39	unsigned int		flags,
  40	struct xfs_rmap_irec	*irec,
  41	int			*stat)
  42{
  43	int			get_stat = 0;
  44	int			error;
  45
  46	cur->bc_rec.r.rm_startblock = bno;
  47	cur->bc_rec.r.rm_blockcount = 0;
  48	cur->bc_rec.r.rm_owner = owner;
  49	cur->bc_rec.r.rm_offset = offset;
  50	cur->bc_rec.r.rm_flags = flags;
  51
  52	error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
  53	if (error || !(*stat) || !irec)
  54		return error;
  55
  56	error = xfs_rmap_get_rec(cur, irec, &get_stat);
  57	if (error)
  58		return error;
  59	if (!get_stat)
  60		return -EFSCORRUPTED;
  61
  62	return 0;
  63}
  64
  65/*
  66 * Lookup the record exactly matching [bno, len, owner, offset]
  67 * in the btree given by cur.
  68 */
  69int
  70xfs_rmap_lookup_eq(
  71	struct xfs_btree_cur	*cur,
  72	xfs_agblock_t		bno,
  73	xfs_extlen_t		len,
  74	uint64_t		owner,
  75	uint64_t		offset,
  76	unsigned int		flags,
  77	int			*stat)
  78{
  79	cur->bc_rec.r.rm_startblock = bno;
  80	cur->bc_rec.r.rm_blockcount = len;
  81	cur->bc_rec.r.rm_owner = owner;
  82	cur->bc_rec.r.rm_offset = offset;
  83	cur->bc_rec.r.rm_flags = flags;
  84	return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
  85}
  86
  87/*
  88 * Update the record referred to by cur to the value given
  89 * by [bno, len, owner, offset].
  90 * This either works (return 0) or gets an EFSCORRUPTED error.
  91 */
  92STATIC int
  93xfs_rmap_update(
  94	struct xfs_btree_cur	*cur,
  95	struct xfs_rmap_irec	*irec)
  96{
  97	union xfs_btree_rec	rec;
  98	int			error;
  99
 100	trace_xfs_rmap_update(cur->bc_mp, cur->bc_ag.pag->pag_agno,
 101			irec->rm_startblock, irec->rm_blockcount,
 102			irec->rm_owner, irec->rm_offset, irec->rm_flags);
 103
 104	rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock);
 105	rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount);
 106	rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner);
 107	rec.rmap.rm_offset = cpu_to_be64(
 108			xfs_rmap_irec_offset_pack(irec));
 109	error = xfs_btree_update(cur, &rec);
 110	if (error)
 111		trace_xfs_rmap_update_error(cur->bc_mp,
 112				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
 113	return error;
 114}
 115
 116int
 117xfs_rmap_insert(
 118	struct xfs_btree_cur	*rcur,
 119	xfs_agblock_t		agbno,
 120	xfs_extlen_t		len,
 121	uint64_t		owner,
 122	uint64_t		offset,
 123	unsigned int		flags)
 124{
 125	int			i;
 126	int			error;
 127
 128	trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
 129			len, owner, offset, flags);
 130
 131	error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
 132	if (error)
 133		goto done;
 134	if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) {
 135		error = -EFSCORRUPTED;
 136		goto done;
 137	}
 138
 139	rcur->bc_rec.r.rm_startblock = agbno;
 140	rcur->bc_rec.r.rm_blockcount = len;
 141	rcur->bc_rec.r.rm_owner = owner;
 142	rcur->bc_rec.r.rm_offset = offset;
 143	rcur->bc_rec.r.rm_flags = flags;
 144	error = xfs_btree_insert(rcur, &i);
 145	if (error)
 146		goto done;
 147	if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
 148		error = -EFSCORRUPTED;
 149		goto done;
 150	}
 151done:
 152	if (error)
 153		trace_xfs_rmap_insert_error(rcur->bc_mp,
 154				rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
 155	return error;
 156}
 157
 158STATIC int
 159xfs_rmap_delete(
 160	struct xfs_btree_cur	*rcur,
 161	xfs_agblock_t		agbno,
 162	xfs_extlen_t		len,
 163	uint64_t		owner,
 164	uint64_t		offset,
 165	unsigned int		flags)
 166{
 167	int			i;
 168	int			error;
 169
 170	trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
 171			len, owner, offset, flags);
 172
 173	error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
 174	if (error)
 175		goto done;
 176	if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
 177		error = -EFSCORRUPTED;
 178		goto done;
 179	}
 180
 181	error = xfs_btree_delete(rcur, &i);
 182	if (error)
 183		goto done;
 184	if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
 185		error = -EFSCORRUPTED;
 186		goto done;
 187	}
 188done:
 189	if (error)
 190		trace_xfs_rmap_delete_error(rcur->bc_mp,
 191				rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
 192	return error;
 193}
 194
 195/* Convert an internal btree record to an rmap record. */
 196xfs_failaddr_t
 197xfs_rmap_btrec_to_irec(
 198	const union xfs_btree_rec	*rec,
 199	struct xfs_rmap_irec		*irec)
 200{
 
 201	irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock);
 202	irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount);
 203	irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner);
 204	return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset),
 205			irec);
 206}
 207
 208/* Simple checks for rmap records. */
 209xfs_failaddr_t
 210xfs_rmap_check_irec(
 211	struct xfs_btree_cur		*cur,
 212	const struct xfs_rmap_irec	*irec)
 213{
 214	struct xfs_mount		*mp = cur->bc_mp;
 215	bool				is_inode;
 216	bool				is_unwritten;
 217	bool				is_bmbt;
 218	bool				is_attr;
 219
 220	if (irec->rm_blockcount == 0)
 221		return __this_address;
 222	if (irec->rm_startblock <= XFS_AGFL_BLOCK(mp)) {
 223		if (irec->rm_owner != XFS_RMAP_OWN_FS)
 224			return __this_address;
 225		if (irec->rm_blockcount != XFS_AGFL_BLOCK(mp) + 1)
 226			return __this_address;
 227	} else {
 228		/* check for valid extent range, including overflow */
 229		if (!xfs_verify_agbext(cur->bc_ag.pag, irec->rm_startblock,
 230						       irec->rm_blockcount))
 231			return __this_address;
 232	}
 233
 234	if (!(xfs_verify_ino(mp, irec->rm_owner) ||
 235	      (irec->rm_owner <= XFS_RMAP_OWN_FS &&
 236	       irec->rm_owner >= XFS_RMAP_OWN_MIN)))
 237		return __this_address;
 238
 239	/* Check flags. */
 240	is_inode = !XFS_RMAP_NON_INODE_OWNER(irec->rm_owner);
 241	is_bmbt = irec->rm_flags & XFS_RMAP_BMBT_BLOCK;
 242	is_attr = irec->rm_flags & XFS_RMAP_ATTR_FORK;
 243	is_unwritten = irec->rm_flags & XFS_RMAP_UNWRITTEN;
 244
 245	if (is_bmbt && irec->rm_offset != 0)
 246		return __this_address;
 247
 248	if (!is_inode && irec->rm_offset != 0)
 249		return __this_address;
 250
 251	if (is_unwritten && (is_bmbt || !is_inode || is_attr))
 252		return __this_address;
 253
 254	if (!is_inode && (is_bmbt || is_unwritten || is_attr))
 255		return __this_address;
 256
 257	/* Check for a valid fork offset, if applicable. */
 258	if (is_inode && !is_bmbt &&
 259	    !xfs_verify_fileext(mp, irec->rm_offset, irec->rm_blockcount))
 260		return __this_address;
 261
 262	return NULL;
 263}
 264
 265static inline int
 266xfs_rmap_complain_bad_rec(
 267	struct xfs_btree_cur		*cur,
 268	xfs_failaddr_t			fa,
 269	const struct xfs_rmap_irec	*irec)
 270{
 271	struct xfs_mount		*mp = cur->bc_mp;
 272
 273	xfs_warn(mp,
 274		"Reverse Mapping BTree record corruption in AG %d detected at %pS!",
 275		cur->bc_ag.pag->pag_agno, fa);
 276	xfs_warn(mp,
 277		"Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
 278		irec->rm_owner, irec->rm_flags, irec->rm_startblock,
 279		irec->rm_blockcount);
 280	return -EFSCORRUPTED;
 281}
 282
 283/*
 284 * Get the data from the pointed-to record.
 285 */
 286int
 287xfs_rmap_get_rec(
 288	struct xfs_btree_cur	*cur,
 289	struct xfs_rmap_irec	*irec,
 290	int			*stat)
 291{
 292	union xfs_btree_rec	*rec;
 293	xfs_failaddr_t		fa;
 294	int			error;
 295
 296	error = xfs_btree_get_rec(cur, &rec, stat);
 297	if (error || !*stat)
 298		return error;
 299
 300	fa = xfs_rmap_btrec_to_irec(rec, irec);
 301	if (!fa)
 302		fa = xfs_rmap_check_irec(cur, irec);
 303	if (fa)
 304		return xfs_rmap_complain_bad_rec(cur, fa, irec);
 305
 306	return 0;
 307}
 308
 309struct xfs_find_left_neighbor_info {
 310	struct xfs_rmap_irec	high;
 311	struct xfs_rmap_irec	*irec;
 
 312};
 313
 314/* For each rmap given, figure out if it matches the key we want. */
 315STATIC int
 316xfs_rmap_find_left_neighbor_helper(
 317	struct xfs_btree_cur		*cur,
 318	const struct xfs_rmap_irec	*rec,
 319	void				*priv)
 320{
 321	struct xfs_find_left_neighbor_info	*info = priv;
 322
 323	trace_xfs_rmap_find_left_neighbor_candidate(cur->bc_mp,
 324			cur->bc_ag.pag->pag_agno, rec->rm_startblock,
 325			rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
 326			rec->rm_flags);
 327
 328	if (rec->rm_owner != info->high.rm_owner)
 329		return 0;
 330	if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
 331	    !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
 332	    rec->rm_offset + rec->rm_blockcount - 1 != info->high.rm_offset)
 333		return 0;
 334
 335	*info->irec = *rec;
 336	return -ECANCELED;
 
 337}
 338
 339/*
 340 * Find the record to the left of the given extent, being careful only to
 341 * return a match with the same owner and adjacent physical and logical
 342 * block ranges.
 343 */
 344STATIC int
 345xfs_rmap_find_left_neighbor(
 346	struct xfs_btree_cur	*cur,
 347	xfs_agblock_t		bno,
 348	uint64_t		owner,
 349	uint64_t		offset,
 350	unsigned int		flags,
 351	struct xfs_rmap_irec	*irec,
 352	int			*stat)
 353{
 354	struct xfs_find_left_neighbor_info	info;
 355	int			found = 0;
 356	int			error;
 357
 358	*stat = 0;
 359	if (bno == 0)
 360		return 0;
 361	info.high.rm_startblock = bno - 1;
 362	info.high.rm_owner = owner;
 363	if (!XFS_RMAP_NON_INODE_OWNER(owner) &&
 364	    !(flags & XFS_RMAP_BMBT_BLOCK)) {
 365		if (offset == 0)
 366			return 0;
 367		info.high.rm_offset = offset - 1;
 368	} else
 369		info.high.rm_offset = 0;
 370	info.high.rm_flags = flags;
 371	info.high.rm_blockcount = 0;
 372	info.irec = irec;
 
 373
 374	trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp,
 375			cur->bc_ag.pag->pag_agno, bno, 0, owner, offset, flags);
 376
 377	/*
 378	 * Historically, we always used the range query to walk every reverse
 379	 * mapping that could possibly overlap the key that the caller asked
 380	 * for, and filter out the ones that don't.  That is very slow when
 381	 * there are a lot of records.
 382	 *
 383	 * However, there are two scenarios where the classic btree search can
 384	 * produce correct results -- if the index contains a record that is an
 385	 * exact match for the lookup key; and if there are no other records
 386	 * between the record we want and the key we supplied.
 387	 *
 388	 * As an optimization, try a non-overlapped lookup first.  This makes
 389	 * extent conversion and remap operations run a bit faster if the
 390	 * physical extents aren't being shared.  If we don't find what we
 391	 * want, we fall back to the overlapped query.
 392	 */
 393	error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
 394			&found);
 395	if (error)
 396		return error;
 397	if (found)
 398		error = xfs_rmap_find_left_neighbor_helper(cur, irec, &info);
 399	if (!error)
 400		error = xfs_rmap_query_range(cur, &info.high, &info.high,
 401				xfs_rmap_find_left_neighbor_helper, &info);
 402	if (error != -ECANCELED)
 403		return error;
 404
 405	*stat = 1;
 406	trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
 407			cur->bc_ag.pag->pag_agno, irec->rm_startblock,
 408			irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
 409			irec->rm_flags);
 410	return 0;
 
 
 
 
 411}
 412
 413/* For each rmap given, figure out if it matches the key we want. */
 414STATIC int
 415xfs_rmap_lookup_le_range_helper(
 416	struct xfs_btree_cur		*cur,
 417	const struct xfs_rmap_irec	*rec,
 418	void				*priv)
 419{
 420	struct xfs_find_left_neighbor_info	*info = priv;
 421
 422	trace_xfs_rmap_lookup_le_range_candidate(cur->bc_mp,
 423			cur->bc_ag.pag->pag_agno, rec->rm_startblock,
 424			rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
 425			rec->rm_flags);
 426
 427	if (rec->rm_owner != info->high.rm_owner)
 428		return 0;
 429	if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
 430	    !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
 431	    (rec->rm_offset > info->high.rm_offset ||
 432	     rec->rm_offset + rec->rm_blockcount <= info->high.rm_offset))
 433		return 0;
 434
 435	*info->irec = *rec;
 436	return -ECANCELED;
 
 437}
 438
 439/*
 440 * Find the record to the left of the given extent, being careful only to
 441 * return a match with the same owner and overlapping physical and logical
 442 * block ranges.  This is the overlapping-interval version of
 443 * xfs_rmap_lookup_le.
 444 */
 445int
 446xfs_rmap_lookup_le_range(
 447	struct xfs_btree_cur	*cur,
 448	xfs_agblock_t		bno,
 449	uint64_t		owner,
 450	uint64_t		offset,
 451	unsigned int		flags,
 452	struct xfs_rmap_irec	*irec,
 453	int			*stat)
 454{
 455	struct xfs_find_left_neighbor_info	info;
 456	int			found = 0;
 457	int			error;
 458
 459	info.high.rm_startblock = bno;
 460	info.high.rm_owner = owner;
 461	if (!XFS_RMAP_NON_INODE_OWNER(owner) && !(flags & XFS_RMAP_BMBT_BLOCK))
 462		info.high.rm_offset = offset;
 463	else
 464		info.high.rm_offset = 0;
 465	info.high.rm_flags = flags;
 466	info.high.rm_blockcount = 0;
 467	*stat = 0;
 468	info.irec = irec;
 
 469
 470	trace_xfs_rmap_lookup_le_range(cur->bc_mp, cur->bc_ag.pag->pag_agno,
 471			bno, 0, owner, offset, flags);
 472
 473	/*
 474	 * Historically, we always used the range query to walk every reverse
 475	 * mapping that could possibly overlap the key that the caller asked
 476	 * for, and filter out the ones that don't.  That is very slow when
 477	 * there are a lot of records.
 478	 *
 479	 * However, there are two scenarios where the classic btree search can
 480	 * produce correct results -- if the index contains a record that is an
 481	 * exact match for the lookup key; and if there are no other records
 482	 * between the record we want and the key we supplied.
 483	 *
 484	 * As an optimization, try a non-overlapped lookup first.  This makes
 485	 * scrub run much faster on most filesystems because bmbt records are
 486	 * usually an exact match for rmap records.  If we don't find what we
 487	 * want, we fall back to the overlapped query.
 488	 */
 489	error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
 490			&found);
 491	if (error)
 492		return error;
 493	if (found)
 494		error = xfs_rmap_lookup_le_range_helper(cur, irec, &info);
 495	if (!error)
 496		error = xfs_rmap_query_range(cur, &info.high, &info.high,
 497				xfs_rmap_lookup_le_range_helper, &info);
 498	if (error != -ECANCELED)
 499		return error;
 500
 501	*stat = 1;
 502	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
 503			cur->bc_ag.pag->pag_agno, irec->rm_startblock,
 504			irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
 505			irec->rm_flags);
 506	return 0;
 507}
 508
 509/*
 510 * Perform all the relevant owner checks for a removal op.  If we're doing an
 511 * unknown-owner removal then we have no owner information to check.
 512 */
 513static int
 514xfs_rmap_free_check_owner(
 515	struct xfs_mount	*mp,
 516	uint64_t		ltoff,
 517	struct xfs_rmap_irec	*rec,
 518	xfs_filblks_t		len,
 519	uint64_t		owner,
 520	uint64_t		offset,
 521	unsigned int		flags)
 522{
 523	int			error = 0;
 524
 525	if (owner == XFS_RMAP_OWN_UNKNOWN)
 526		return 0;
 527
 528	/* Make sure the unwritten flag matches. */
 529	if (XFS_IS_CORRUPT(mp,
 530			   (flags & XFS_RMAP_UNWRITTEN) !=
 531			   (rec->rm_flags & XFS_RMAP_UNWRITTEN))) {
 532		error = -EFSCORRUPTED;
 533		goto out;
 534	}
 535
 536	/* Make sure the owner matches what we expect to find in the tree. */
 537	if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) {
 538		error = -EFSCORRUPTED;
 539		goto out;
 540	}
 541
 542	/* Check the offset, if necessary. */
 543	if (XFS_RMAP_NON_INODE_OWNER(owner))
 544		goto out;
 545
 546	if (flags & XFS_RMAP_BMBT_BLOCK) {
 547		if (XFS_IS_CORRUPT(mp,
 548				   !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) {
 549			error = -EFSCORRUPTED;
 550			goto out;
 551		}
 552	} else {
 553		if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) {
 554			error = -EFSCORRUPTED;
 555			goto out;
 556		}
 557		if (XFS_IS_CORRUPT(mp,
 558				   offset + len > ltoff + rec->rm_blockcount)) {
 559			error = -EFSCORRUPTED;
 560			goto out;
 561		}
 562	}
 563
 564out:
 565	return error;
 566}
 567
 568/*
 569 * Find the extent in the rmap btree and remove it.
 570 *
 571 * The record we find should always be an exact match for the extent that we're
 572 * looking for, since we insert them into the btree without modification.
 573 *
 574 * Special Case #1: when growing the filesystem, we "free" an extent when
 575 * growing the last AG. This extent is new space and so it is not tracked as
 576 * used space in the btree. The growfs code will pass in an owner of
 577 * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
 578 * extent. We verify that - the extent lookup result in a record that does not
 579 * overlap.
 580 *
 581 * Special Case #2: EFIs do not record the owner of the extent, so when
 582 * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
 583 * btree to ignore the owner (i.e. wildcard match) so we don't trigger
 584 * corruption checks during log recovery.
 585 */
 586STATIC int
 587xfs_rmap_unmap(
 588	struct xfs_btree_cur		*cur,
 589	xfs_agblock_t			bno,
 590	xfs_extlen_t			len,
 591	bool				unwritten,
 592	const struct xfs_owner_info	*oinfo)
 593{
 594	struct xfs_mount		*mp = cur->bc_mp;
 595	struct xfs_rmap_irec		ltrec;
 596	uint64_t			ltoff;
 597	int				error = 0;
 598	int				i;
 599	uint64_t			owner;
 600	uint64_t			offset;
 601	unsigned int			flags;
 602	bool				ignore_off;
 603
 604	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
 605	ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
 606			(flags & XFS_RMAP_BMBT_BLOCK);
 607	if (unwritten)
 608		flags |= XFS_RMAP_UNWRITTEN;
 609	trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
 610			unwritten, oinfo);
 611
 612	/*
 613	 * We should always have a left record because there's a static record
 614	 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
 615	 * will not ever be removed from the tree.
 616	 */
 617	error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &ltrec, &i);
 618	if (error)
 619		goto out_error;
 620	if (XFS_IS_CORRUPT(mp, i != 1)) {
 621		error = -EFSCORRUPTED;
 622		goto out_error;
 623	}
 624
 
 
 
 
 625	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
 626			cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
 627			ltrec.rm_blockcount, ltrec.rm_owner,
 628			ltrec.rm_offset, ltrec.rm_flags);
 629	ltoff = ltrec.rm_offset;
 630
 631	/*
 632	 * For growfs, the incoming extent must be beyond the left record we
 633	 * just found as it is new space and won't be used by anyone. This is
 634	 * just a corruption check as we don't actually do anything with this
 635	 * extent.  Note that we need to use >= instead of > because it might
 636	 * be the case that the "left" extent goes all the way to EOFS.
 637	 */
 638	if (owner == XFS_RMAP_OWN_NULL) {
 639		if (XFS_IS_CORRUPT(mp,
 640				   bno <
 641				   ltrec.rm_startblock + ltrec.rm_blockcount)) {
 642			error = -EFSCORRUPTED;
 643			goto out_error;
 644		}
 645		goto out_done;
 646	}
 647
 648	/*
 649	 * If we're doing an unknown-owner removal for EFI recovery, we expect
 650	 * to find the full range in the rmapbt or nothing at all.  If we
 651	 * don't find any rmaps overlapping either end of the range, we're
 652	 * done.  Hopefully this means that the EFI creator already queued
 653	 * (and finished) a RUI to remove the rmap.
 654	 */
 655	if (owner == XFS_RMAP_OWN_UNKNOWN &&
 656	    ltrec.rm_startblock + ltrec.rm_blockcount <= bno) {
 657		struct xfs_rmap_irec    rtrec;
 658
 659		error = xfs_btree_increment(cur, 0, &i);
 660		if (error)
 661			goto out_error;
 662		if (i == 0)
 663			goto out_done;
 664		error = xfs_rmap_get_rec(cur, &rtrec, &i);
 665		if (error)
 666			goto out_error;
 667		if (XFS_IS_CORRUPT(mp, i != 1)) {
 668			error = -EFSCORRUPTED;
 669			goto out_error;
 670		}
 671		if (rtrec.rm_startblock >= bno + len)
 672			goto out_done;
 673	}
 674
 675	/* Make sure the extent we found covers the entire freeing range. */
 676	if (XFS_IS_CORRUPT(mp,
 677			   ltrec.rm_startblock > bno ||
 678			   ltrec.rm_startblock + ltrec.rm_blockcount <
 679			   bno + len)) {
 680		error = -EFSCORRUPTED;
 681		goto out_error;
 682	}
 683
 684	/* Check owner information. */
 685	error = xfs_rmap_free_check_owner(mp, ltoff, &ltrec, len, owner,
 686			offset, flags);
 687	if (error)
 688		goto out_error;
 
 
 
 
 
 
 
 
 
 
 
 
 
 689
 690	if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
 691		/* exact match, simply remove the record from rmap tree */
 692		trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
 693				ltrec.rm_startblock, ltrec.rm_blockcount,
 694				ltrec.rm_owner, ltrec.rm_offset,
 695				ltrec.rm_flags);
 696		error = xfs_btree_delete(cur, &i);
 697		if (error)
 698			goto out_error;
 699		if (XFS_IS_CORRUPT(mp, i != 1)) {
 700			error = -EFSCORRUPTED;
 701			goto out_error;
 702		}
 703	} else if (ltrec.rm_startblock == bno) {
 704		/*
 705		 * overlap left hand side of extent: move the start, trim the
 706		 * length and update the current record.
 707		 *
 708		 *       ltbno                ltlen
 709		 * Orig:    |oooooooooooooooooooo|
 710		 * Freeing: |fffffffff|
 711		 * Result:            |rrrrrrrrrr|
 712		 *         bno       len
 713		 */
 714		ltrec.rm_startblock += len;
 715		ltrec.rm_blockcount -= len;
 716		if (!ignore_off)
 717			ltrec.rm_offset += len;
 718		error = xfs_rmap_update(cur, &ltrec);
 719		if (error)
 720			goto out_error;
 721	} else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
 722		/*
 723		 * overlap right hand side of extent: trim the length and update
 724		 * the current record.
 725		 *
 726		 *       ltbno                ltlen
 727		 * Orig:    |oooooooooooooooooooo|
 728		 * Freeing:            |fffffffff|
 729		 * Result:  |rrrrrrrrrr|
 730		 *                    bno       len
 731		 */
 732		ltrec.rm_blockcount -= len;
 733		error = xfs_rmap_update(cur, &ltrec);
 734		if (error)
 735			goto out_error;
 736	} else {
 737
 738		/*
 739		 * overlap middle of extent: trim the length of the existing
 740		 * record to the length of the new left-extent size, increment
 741		 * the insertion position so we can insert a new record
 742		 * containing the remaining right-extent space.
 743		 *
 744		 *       ltbno                ltlen
 745		 * Orig:    |oooooooooooooooooooo|
 746		 * Freeing:       |fffffffff|
 747		 * Result:  |rrrrr|         |rrrr|
 748		 *               bno       len
 749		 */
 750		xfs_extlen_t	orig_len = ltrec.rm_blockcount;
 751
 752		ltrec.rm_blockcount = bno - ltrec.rm_startblock;
 753		error = xfs_rmap_update(cur, &ltrec);
 754		if (error)
 755			goto out_error;
 756
 757		error = xfs_btree_increment(cur, 0, &i);
 758		if (error)
 759			goto out_error;
 760
 761		cur->bc_rec.r.rm_startblock = bno + len;
 762		cur->bc_rec.r.rm_blockcount = orig_len - len -
 763						     ltrec.rm_blockcount;
 764		cur->bc_rec.r.rm_owner = ltrec.rm_owner;
 765		if (ignore_off)
 766			cur->bc_rec.r.rm_offset = 0;
 767		else
 768			cur->bc_rec.r.rm_offset = offset + len;
 769		cur->bc_rec.r.rm_flags = flags;
 770		trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
 771				cur->bc_rec.r.rm_startblock,
 772				cur->bc_rec.r.rm_blockcount,
 773				cur->bc_rec.r.rm_owner,
 774				cur->bc_rec.r.rm_offset,
 775				cur->bc_rec.r.rm_flags);
 776		error = xfs_btree_insert(cur, &i);
 777		if (error)
 778			goto out_error;
 779	}
 780
 781out_done:
 782	trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
 783			unwritten, oinfo);
 784out_error:
 785	if (error)
 786		trace_xfs_rmap_unmap_error(mp, cur->bc_ag.pag->pag_agno,
 787				error, _RET_IP_);
 788	return error;
 789}
 790
 791/*
 792 * Remove a reference to an extent in the rmap btree.
 793 */
 794int
 795xfs_rmap_free(
 796	struct xfs_trans		*tp,
 797	struct xfs_buf			*agbp,
 798	struct xfs_perag		*pag,
 799	xfs_agblock_t			bno,
 800	xfs_extlen_t			len,
 801	const struct xfs_owner_info	*oinfo)
 802{
 803	struct xfs_mount		*mp = tp->t_mountp;
 804	struct xfs_btree_cur		*cur;
 805	int				error;
 806
 807	if (!xfs_has_rmapbt(mp))
 808		return 0;
 809
 810	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
 811
 812	error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
 
 
 813
 814	xfs_btree_del_cursor(cur, error);
 
 
 
 
 815	return error;
 816}
 817
 818/*
 819 * A mergeable rmap must have the same owner and the same values for
 820 * the unwritten, attr_fork, and bmbt flags.  The startblock and
 821 * offset are checked separately.
 822 */
 823static bool
 824xfs_rmap_is_mergeable(
 825	struct xfs_rmap_irec	*irec,
 826	uint64_t		owner,
 827	unsigned int		flags)
 828{
 829	if (irec->rm_owner == XFS_RMAP_OWN_NULL)
 830		return false;
 831	if (irec->rm_owner != owner)
 832		return false;
 833	if ((flags & XFS_RMAP_UNWRITTEN) ^
 834	    (irec->rm_flags & XFS_RMAP_UNWRITTEN))
 835		return false;
 836	if ((flags & XFS_RMAP_ATTR_FORK) ^
 837	    (irec->rm_flags & XFS_RMAP_ATTR_FORK))
 838		return false;
 839	if ((flags & XFS_RMAP_BMBT_BLOCK) ^
 840	    (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
 841		return false;
 842	return true;
 843}
 844
 845/*
 846 * When we allocate a new block, the first thing we do is add a reference to
 847 * the extent in the rmap btree. This takes the form of a [agbno, length,
 848 * owner, offset] record.  Flags are encoded in the high bits of the offset
 849 * field.
 850 */
 851STATIC int
 852xfs_rmap_map(
 853	struct xfs_btree_cur		*cur,
 854	xfs_agblock_t			bno,
 855	xfs_extlen_t			len,
 856	bool				unwritten,
 857	const struct xfs_owner_info	*oinfo)
 858{
 859	struct xfs_mount		*mp = cur->bc_mp;
 860	struct xfs_rmap_irec		ltrec;
 861	struct xfs_rmap_irec		gtrec;
 862	int				have_gt;
 863	int				have_lt;
 864	int				error = 0;
 865	int				i;
 866	uint64_t			owner;
 867	uint64_t			offset;
 868	unsigned int			flags = 0;
 869	bool				ignore_off;
 870
 871	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
 872	ASSERT(owner != 0);
 873	ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
 874			(flags & XFS_RMAP_BMBT_BLOCK);
 875	if (unwritten)
 876		flags |= XFS_RMAP_UNWRITTEN;
 877	trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
 878			unwritten, oinfo);
 879	ASSERT(!xfs_rmap_should_skip_owner_update(oinfo));
 880
 881	/*
 882	 * For the initial lookup, look for an exact match or the left-adjacent
 883	 * record for our insertion point. This will also give us the record for
 884	 * start block contiguity tests.
 885	 */
 886	error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &ltrec,
 887			&have_lt);
 888	if (error)
 889		goto out_error;
 890	if (have_lt) {
 891		trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
 892				cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
 893				ltrec.rm_blockcount, ltrec.rm_owner,
 894				ltrec.rm_offset, ltrec.rm_flags);
 895
 896		if (!xfs_rmap_is_mergeable(&ltrec, owner, flags))
 897			have_lt = 0;
 898	}
 899
 900	if (XFS_IS_CORRUPT(mp,
 901			   have_lt != 0 &&
 902			   ltrec.rm_startblock + ltrec.rm_blockcount > bno)) {
 903		error = -EFSCORRUPTED;
 904		goto out_error;
 905	}
 
 
 
 
 
 
 
 
 
 
 
 906
 907	/*
 908	 * Increment the cursor to see if we have a right-adjacent record to our
 909	 * insertion point. This will give us the record for end block
 910	 * contiguity tests.
 911	 */
 912	error = xfs_btree_increment(cur, 0, &have_gt);
 913	if (error)
 914		goto out_error;
 915	if (have_gt) {
 916		error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
 917		if (error)
 918			goto out_error;
 919		if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
 920			error = -EFSCORRUPTED;
 921			goto out_error;
 922		}
 923		if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) {
 924			error = -EFSCORRUPTED;
 925			goto out_error;
 926		}
 927		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
 928			cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
 929			gtrec.rm_blockcount, gtrec.rm_owner,
 930			gtrec.rm_offset, gtrec.rm_flags);
 931		if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
 932			have_gt = 0;
 933	}
 934
 935	/*
 936	 * Note: cursor currently points one record to the right of ltrec, even
 937	 * if there is no record in the tree to the right.
 938	 */
 939	if (have_lt &&
 940	    ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
 941	    (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
 942		/*
 943		 * left edge contiguous, merge into left record.
 944		 *
 945		 *       ltbno     ltlen
 946		 * orig:   |ooooooooo|
 947		 * adding:           |aaaaaaaaa|
 948		 * result: |rrrrrrrrrrrrrrrrrrr|
 949		 *                  bno       len
 950		 */
 951		ltrec.rm_blockcount += len;
 952		if (have_gt &&
 953		    bno + len == gtrec.rm_startblock &&
 954		    (ignore_off || offset + len == gtrec.rm_offset) &&
 955		    (unsigned long)ltrec.rm_blockcount + len +
 956				gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
 957			/*
 958			 * right edge also contiguous, delete right record
 959			 * and merge into left record.
 960			 *
 961			 *       ltbno     ltlen    gtbno     gtlen
 962			 * orig:   |ooooooooo|         |ooooooooo|
 963			 * adding:           |aaaaaaaaa|
 964			 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
 965			 */
 966			ltrec.rm_blockcount += gtrec.rm_blockcount;
 967			trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
 968					gtrec.rm_startblock,
 969					gtrec.rm_blockcount,
 970					gtrec.rm_owner,
 971					gtrec.rm_offset,
 972					gtrec.rm_flags);
 973			error = xfs_btree_delete(cur, &i);
 974			if (error)
 975				goto out_error;
 976			if (XFS_IS_CORRUPT(mp, i != 1)) {
 977				error = -EFSCORRUPTED;
 978				goto out_error;
 979			}
 980		}
 981
 982		/* point the cursor back to the left record and update */
 983		error = xfs_btree_decrement(cur, 0, &have_gt);
 984		if (error)
 985			goto out_error;
 986		error = xfs_rmap_update(cur, &ltrec);
 987		if (error)
 988			goto out_error;
 989	} else if (have_gt &&
 990		   bno + len == gtrec.rm_startblock &&
 991		   (ignore_off || offset + len == gtrec.rm_offset)) {
 992		/*
 993		 * right edge contiguous, merge into right record.
 994		 *
 995		 *                 gtbno     gtlen
 996		 * Orig:             |ooooooooo|
 997		 * adding: |aaaaaaaaa|
 998		 * Result: |rrrrrrrrrrrrrrrrrrr|
 999		 *        bno       len
1000		 */
1001		gtrec.rm_startblock = bno;
1002		gtrec.rm_blockcount += len;
1003		if (!ignore_off)
1004			gtrec.rm_offset = offset;
1005		error = xfs_rmap_update(cur, &gtrec);
1006		if (error)
1007			goto out_error;
1008	} else {
1009		/*
1010		 * no contiguous edge with identical owner, insert
1011		 * new record at current cursor position.
1012		 */
1013		cur->bc_rec.r.rm_startblock = bno;
1014		cur->bc_rec.r.rm_blockcount = len;
1015		cur->bc_rec.r.rm_owner = owner;
1016		cur->bc_rec.r.rm_offset = offset;
1017		cur->bc_rec.r.rm_flags = flags;
1018		trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1019			owner, offset, flags);
1020		error = xfs_btree_insert(cur, &i);
1021		if (error)
1022			goto out_error;
1023		if (XFS_IS_CORRUPT(mp, i != 1)) {
1024			error = -EFSCORRUPTED;
1025			goto out_error;
1026		}
1027	}
1028
1029	trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1030			unwritten, oinfo);
1031out_error:
1032	if (error)
1033		trace_xfs_rmap_map_error(mp, cur->bc_ag.pag->pag_agno,
1034				error, _RET_IP_);
1035	return error;
1036}
1037
1038/*
1039 * Add a reference to an extent in the rmap btree.
1040 */
1041int
1042xfs_rmap_alloc(
1043	struct xfs_trans		*tp,
1044	struct xfs_buf			*agbp,
1045	struct xfs_perag		*pag,
1046	xfs_agblock_t			bno,
1047	xfs_extlen_t			len,
1048	const struct xfs_owner_info	*oinfo)
1049{
1050	struct xfs_mount		*mp = tp->t_mountp;
1051	struct xfs_btree_cur		*cur;
1052	int				error;
1053
1054	if (!xfs_has_rmapbt(mp))
1055		return 0;
1056
1057	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
1058	error = xfs_rmap_map(cur, bno, len, false, oinfo);
 
 
1059
1060	xfs_btree_del_cursor(cur, error);
 
 
 
 
1061	return error;
1062}
1063
1064#define RMAP_LEFT_CONTIG	(1 << 0)
1065#define RMAP_RIGHT_CONTIG	(1 << 1)
1066#define RMAP_LEFT_FILLING	(1 << 2)
1067#define RMAP_RIGHT_FILLING	(1 << 3)
1068#define RMAP_LEFT_VALID		(1 << 6)
1069#define RMAP_RIGHT_VALID	(1 << 7)
1070
1071#define LEFT		r[0]
1072#define RIGHT		r[1]
1073#define PREV		r[2]
1074#define NEW		r[3]
1075
1076/*
1077 * Convert an unwritten extent to a real extent or vice versa.
1078 * Does not handle overlapping extents.
1079 */
1080STATIC int
1081xfs_rmap_convert(
1082	struct xfs_btree_cur		*cur,
1083	xfs_agblock_t			bno,
1084	xfs_extlen_t			len,
1085	bool				unwritten,
1086	const struct xfs_owner_info	*oinfo)
1087{
1088	struct xfs_mount		*mp = cur->bc_mp;
1089	struct xfs_rmap_irec		r[4];	/* neighbor extent entries */
1090						/* left is 0, right is 1, */
1091						/* prev is 2, new is 3 */
1092	uint64_t		owner;
1093	uint64_t		offset;
1094	uint64_t		new_endoff;
1095	unsigned int		oldext;
1096	unsigned int		newext;
1097	unsigned int		flags = 0;
1098	int			i;
1099	int			state = 0;
1100	int			error;
1101
1102	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1103	ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1104			(flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1105	oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1106	new_endoff = offset + len;
1107	trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1108			unwritten, oinfo);
1109
1110	/*
1111	 * For the initial lookup, look for an exact match or the left-adjacent
1112	 * record for our insertion point. This will also give us the record for
1113	 * start block contiguity tests.
1114	 */
1115	error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, &PREV, &i);
1116	if (error)
1117		goto done;
1118	if (XFS_IS_CORRUPT(mp, i != 1)) {
1119		error = -EFSCORRUPTED;
1120		goto done;
1121	}
1122
 
 
 
 
1123	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
1124			cur->bc_ag.pag->pag_agno, PREV.rm_startblock,
1125			PREV.rm_blockcount, PREV.rm_owner,
1126			PREV.rm_offset, PREV.rm_flags);
1127
1128	ASSERT(PREV.rm_offset <= offset);
1129	ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1130	ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1131	newext = ~oldext & XFS_RMAP_UNWRITTEN;
1132
1133	/*
1134	 * Set flags determining what part of the previous oldext allocation
1135	 * extent is being replaced by a newext allocation.
1136	 */
1137	if (PREV.rm_offset == offset)
1138		state |= RMAP_LEFT_FILLING;
1139	if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1140		state |= RMAP_RIGHT_FILLING;
1141
1142	/*
1143	 * Decrement the cursor to see if we have a left-adjacent record to our
1144	 * insertion point. This will give us the record for end block
1145	 * contiguity tests.
1146	 */
1147	error = xfs_btree_decrement(cur, 0, &i);
1148	if (error)
1149		goto done;
1150	if (i) {
1151		state |= RMAP_LEFT_VALID;
1152		error = xfs_rmap_get_rec(cur, &LEFT, &i);
1153		if (error)
1154			goto done;
1155		if (XFS_IS_CORRUPT(mp, i != 1)) {
1156			error = -EFSCORRUPTED;
1157			goto done;
1158		}
1159		if (XFS_IS_CORRUPT(mp,
1160				   LEFT.rm_startblock + LEFT.rm_blockcount >
1161				   bno)) {
1162			error = -EFSCORRUPTED;
1163			goto done;
1164		}
1165		trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
1166				cur->bc_ag.pag->pag_agno, LEFT.rm_startblock,
1167				LEFT.rm_blockcount, LEFT.rm_owner,
1168				LEFT.rm_offset, LEFT.rm_flags);
1169		if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
1170		    LEFT.rm_offset + LEFT.rm_blockcount == offset &&
1171		    xfs_rmap_is_mergeable(&LEFT, owner, newext))
1172			state |= RMAP_LEFT_CONTIG;
1173	}
1174
1175	/*
1176	 * Increment the cursor to see if we have a right-adjacent record to our
1177	 * insertion point. This will give us the record for end block
1178	 * contiguity tests.
1179	 */
1180	error = xfs_btree_increment(cur, 0, &i);
1181	if (error)
1182		goto done;
1183	if (XFS_IS_CORRUPT(mp, i != 1)) {
1184		error = -EFSCORRUPTED;
1185		goto done;
1186	}
1187	error = xfs_btree_increment(cur, 0, &i);
1188	if (error)
1189		goto done;
1190	if (i) {
1191		state |= RMAP_RIGHT_VALID;
1192		error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1193		if (error)
1194			goto done;
1195		if (XFS_IS_CORRUPT(mp, i != 1)) {
1196			error = -EFSCORRUPTED;
1197			goto done;
1198		}
1199		if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
1200			error = -EFSCORRUPTED;
1201			goto done;
1202		}
1203		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1204				cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
1205				RIGHT.rm_blockcount, RIGHT.rm_owner,
1206				RIGHT.rm_offset, RIGHT.rm_flags);
1207		if (bno + len == RIGHT.rm_startblock &&
1208		    offset + len == RIGHT.rm_offset &&
1209		    xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1210			state |= RMAP_RIGHT_CONTIG;
1211	}
1212
1213	/* check that left + prev + right is not too long */
1214	if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1215			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1216	    (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1217	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1218	    (unsigned long)LEFT.rm_blockcount + len +
1219	     RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1220		state &= ~RMAP_RIGHT_CONTIG;
1221
1222	trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
1223			_RET_IP_);
1224
1225	/* reset the cursor back to PREV */
1226	error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, NULL, &i);
1227	if (error)
1228		goto done;
1229	if (XFS_IS_CORRUPT(mp, i != 1)) {
1230		error = -EFSCORRUPTED;
1231		goto done;
1232	}
1233
1234	/*
1235	 * Switch out based on the FILLING and CONTIG state bits.
1236	 */
1237	switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1238			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1239	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1240	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1241		/*
1242		 * Setting all of a previous oldext extent to newext.
1243		 * The left and right neighbors are both contiguous with new.
1244		 */
1245		error = xfs_btree_increment(cur, 0, &i);
1246		if (error)
1247			goto done;
1248		if (XFS_IS_CORRUPT(mp, i != 1)) {
1249			error = -EFSCORRUPTED;
1250			goto done;
1251		}
1252		trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1253				RIGHT.rm_startblock, RIGHT.rm_blockcount,
1254				RIGHT.rm_owner, RIGHT.rm_offset,
1255				RIGHT.rm_flags);
1256		error = xfs_btree_delete(cur, &i);
1257		if (error)
1258			goto done;
1259		if (XFS_IS_CORRUPT(mp, i != 1)) {
1260			error = -EFSCORRUPTED;
1261			goto done;
1262		}
1263		error = xfs_btree_decrement(cur, 0, &i);
1264		if (error)
1265			goto done;
1266		if (XFS_IS_CORRUPT(mp, i != 1)) {
1267			error = -EFSCORRUPTED;
1268			goto done;
1269		}
1270		trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1271				PREV.rm_startblock, PREV.rm_blockcount,
1272				PREV.rm_owner, PREV.rm_offset,
1273				PREV.rm_flags);
1274		error = xfs_btree_delete(cur, &i);
1275		if (error)
1276			goto done;
1277		if (XFS_IS_CORRUPT(mp, i != 1)) {
1278			error = -EFSCORRUPTED;
1279			goto done;
1280		}
1281		error = xfs_btree_decrement(cur, 0, &i);
1282		if (error)
1283			goto done;
1284		if (XFS_IS_CORRUPT(mp, i != 1)) {
1285			error = -EFSCORRUPTED;
1286			goto done;
1287		}
1288		NEW = LEFT;
1289		NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1290		error = xfs_rmap_update(cur, &NEW);
1291		if (error)
1292			goto done;
1293		break;
1294
1295	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1296		/*
1297		 * Setting all of a previous oldext extent to newext.
1298		 * The left neighbor is contiguous, the right is not.
1299		 */
1300		trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1301				PREV.rm_startblock, PREV.rm_blockcount,
1302				PREV.rm_owner, PREV.rm_offset,
1303				PREV.rm_flags);
1304		error = xfs_btree_delete(cur, &i);
1305		if (error)
1306			goto done;
1307		if (XFS_IS_CORRUPT(mp, i != 1)) {
1308			error = -EFSCORRUPTED;
1309			goto done;
1310		}
1311		error = xfs_btree_decrement(cur, 0, &i);
1312		if (error)
1313			goto done;
1314		if (XFS_IS_CORRUPT(mp, i != 1)) {
1315			error = -EFSCORRUPTED;
1316			goto done;
1317		}
1318		NEW = LEFT;
1319		NEW.rm_blockcount += PREV.rm_blockcount;
1320		error = xfs_rmap_update(cur, &NEW);
1321		if (error)
1322			goto done;
1323		break;
1324
1325	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1326		/*
1327		 * Setting all of a previous oldext extent to newext.
1328		 * The right neighbor is contiguous, the left is not.
1329		 */
1330		error = xfs_btree_increment(cur, 0, &i);
1331		if (error)
1332			goto done;
1333		if (XFS_IS_CORRUPT(mp, i != 1)) {
1334			error = -EFSCORRUPTED;
1335			goto done;
1336		}
1337		trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1338				RIGHT.rm_startblock, RIGHT.rm_blockcount,
1339				RIGHT.rm_owner, RIGHT.rm_offset,
1340				RIGHT.rm_flags);
1341		error = xfs_btree_delete(cur, &i);
1342		if (error)
1343			goto done;
1344		if (XFS_IS_CORRUPT(mp, i != 1)) {
1345			error = -EFSCORRUPTED;
1346			goto done;
1347		}
1348		error = xfs_btree_decrement(cur, 0, &i);
1349		if (error)
1350			goto done;
1351		if (XFS_IS_CORRUPT(mp, i != 1)) {
1352			error = -EFSCORRUPTED;
1353			goto done;
1354		}
1355		NEW = PREV;
1356		NEW.rm_blockcount = len + RIGHT.rm_blockcount;
1357		NEW.rm_flags = newext;
1358		error = xfs_rmap_update(cur, &NEW);
1359		if (error)
1360			goto done;
1361		break;
1362
1363	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1364		/*
1365		 * Setting all of a previous oldext extent to newext.
1366		 * Neither the left nor right neighbors are contiguous with
1367		 * the new one.
1368		 */
1369		NEW = PREV;
1370		NEW.rm_flags = newext;
1371		error = xfs_rmap_update(cur, &NEW);
1372		if (error)
1373			goto done;
1374		break;
1375
1376	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1377		/*
1378		 * Setting the first part of a previous oldext extent to newext.
1379		 * The left neighbor is contiguous.
1380		 */
1381		NEW = PREV;
1382		NEW.rm_offset += len;
1383		NEW.rm_startblock += len;
1384		NEW.rm_blockcount -= len;
1385		error = xfs_rmap_update(cur, &NEW);
1386		if (error)
1387			goto done;
1388		error = xfs_btree_decrement(cur, 0, &i);
1389		if (error)
1390			goto done;
1391		NEW = LEFT;
1392		NEW.rm_blockcount += len;
1393		error = xfs_rmap_update(cur, &NEW);
1394		if (error)
1395			goto done;
1396		break;
1397
1398	case RMAP_LEFT_FILLING:
1399		/*
1400		 * Setting the first part of a previous oldext extent to newext.
1401		 * The left neighbor is not contiguous.
1402		 */
1403		NEW = PREV;
1404		NEW.rm_startblock += len;
1405		NEW.rm_offset += len;
1406		NEW.rm_blockcount -= len;
1407		error = xfs_rmap_update(cur, &NEW);
1408		if (error)
1409			goto done;
1410		NEW.rm_startblock = bno;
1411		NEW.rm_owner = owner;
1412		NEW.rm_offset = offset;
1413		NEW.rm_blockcount = len;
1414		NEW.rm_flags = newext;
1415		cur->bc_rec.r = NEW;
1416		trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
1417				len, owner, offset, newext);
1418		error = xfs_btree_insert(cur, &i);
1419		if (error)
1420			goto done;
1421		if (XFS_IS_CORRUPT(mp, i != 1)) {
1422			error = -EFSCORRUPTED;
1423			goto done;
1424		}
1425		break;
1426
1427	case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1428		/*
1429		 * Setting the last part of a previous oldext extent to newext.
1430		 * The right neighbor is contiguous with the new allocation.
1431		 */
1432		NEW = PREV;
1433		NEW.rm_blockcount -= len;
1434		error = xfs_rmap_update(cur, &NEW);
1435		if (error)
1436			goto done;
1437		error = xfs_btree_increment(cur, 0, &i);
1438		if (error)
1439			goto done;
1440		NEW = RIGHT;
1441		NEW.rm_offset = offset;
1442		NEW.rm_startblock = bno;
1443		NEW.rm_blockcount += len;
1444		error = xfs_rmap_update(cur, &NEW);
1445		if (error)
1446			goto done;
1447		break;
1448
1449	case RMAP_RIGHT_FILLING:
1450		/*
1451		 * Setting the last part of a previous oldext extent to newext.
1452		 * The right neighbor is not contiguous.
1453		 */
1454		NEW = PREV;
1455		NEW.rm_blockcount -= len;
1456		error = xfs_rmap_update(cur, &NEW);
1457		if (error)
1458			goto done;
1459		error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1460				oldext, &i);
1461		if (error)
1462			goto done;
1463		if (XFS_IS_CORRUPT(mp, i != 0)) {
1464			error = -EFSCORRUPTED;
1465			goto done;
1466		}
1467		NEW.rm_startblock = bno;
1468		NEW.rm_owner = owner;
1469		NEW.rm_offset = offset;
1470		NEW.rm_blockcount = len;
1471		NEW.rm_flags = newext;
1472		cur->bc_rec.r = NEW;
1473		trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
1474				len, owner, offset, newext);
1475		error = xfs_btree_insert(cur, &i);
1476		if (error)
1477			goto done;
1478		if (XFS_IS_CORRUPT(mp, i != 1)) {
1479			error = -EFSCORRUPTED;
1480			goto done;
1481		}
1482		break;
1483
1484	case 0:
1485		/*
1486		 * Setting the middle part of a previous oldext extent to
1487		 * newext.  Contiguity is impossible here.
1488		 * One extent becomes three extents.
1489		 */
1490		/* new right extent - oldext */
1491		NEW.rm_startblock = bno + len;
1492		NEW.rm_owner = owner;
1493		NEW.rm_offset = new_endoff;
1494		NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1495				new_endoff;
1496		NEW.rm_flags = PREV.rm_flags;
1497		error = xfs_rmap_update(cur, &NEW);
1498		if (error)
1499			goto done;
1500		/* new left extent - oldext */
1501		NEW = PREV;
1502		NEW.rm_blockcount = offset - PREV.rm_offset;
1503		cur->bc_rec.r = NEW;
1504		trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
1505				NEW.rm_startblock, NEW.rm_blockcount,
1506				NEW.rm_owner, NEW.rm_offset,
1507				NEW.rm_flags);
1508		error = xfs_btree_insert(cur, &i);
1509		if (error)
1510			goto done;
1511		if (XFS_IS_CORRUPT(mp, i != 1)) {
1512			error = -EFSCORRUPTED;
1513			goto done;
1514		}
1515		/*
1516		 * Reset the cursor to the position of the new extent
1517		 * we are about to insert as we can't trust it after
1518		 * the previous insert.
1519		 */
1520		error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1521				oldext, &i);
1522		if (error)
1523			goto done;
1524		if (XFS_IS_CORRUPT(mp, i != 0)) {
1525			error = -EFSCORRUPTED;
1526			goto done;
1527		}
1528		/* new middle extent - newext */
1529		cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
1530		cur->bc_rec.r.rm_flags |= newext;
1531		trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1532				owner, offset, newext);
1533		error = xfs_btree_insert(cur, &i);
1534		if (error)
1535			goto done;
1536		if (XFS_IS_CORRUPT(mp, i != 1)) {
1537			error = -EFSCORRUPTED;
1538			goto done;
1539		}
1540		break;
1541
1542	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1543	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1544	case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1545	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1546	case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1547	case RMAP_LEFT_CONTIG:
1548	case RMAP_RIGHT_CONTIG:
1549		/*
1550		 * These cases are all impossible.
1551		 */
1552		ASSERT(0);
1553	}
1554
1555	trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1556			unwritten, oinfo);
1557done:
1558	if (error)
1559		trace_xfs_rmap_convert_error(cur->bc_mp,
1560				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
1561	return error;
1562}
1563
1564/*
1565 * Convert an unwritten extent to a real extent or vice versa.  If there is no
1566 * possibility of overlapping extents, delegate to the simpler convert
1567 * function.
1568 */
1569STATIC int
1570xfs_rmap_convert_shared(
1571	struct xfs_btree_cur		*cur,
1572	xfs_agblock_t			bno,
1573	xfs_extlen_t			len,
1574	bool				unwritten,
1575	const struct xfs_owner_info	*oinfo)
1576{
1577	struct xfs_mount		*mp = cur->bc_mp;
1578	struct xfs_rmap_irec		r[4];	/* neighbor extent entries */
1579						/* left is 0, right is 1, */
1580						/* prev is 2, new is 3 */
1581	uint64_t		owner;
1582	uint64_t		offset;
1583	uint64_t		new_endoff;
1584	unsigned int		oldext;
1585	unsigned int		newext;
1586	unsigned int		flags = 0;
1587	int			i;
1588	int			state = 0;
1589	int			error;
1590
1591	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1592	ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1593			(flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1594	oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1595	new_endoff = offset + len;
1596	trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1597			unwritten, oinfo);
1598
1599	/*
1600	 * For the initial lookup, look for and exact match or the left-adjacent
1601	 * record for our insertion point. This will also give us the record for
1602	 * start block contiguity tests.
1603	 */
1604	error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, oldext,
1605			&PREV, &i);
1606	if (error)
1607		goto done;
1608	if (XFS_IS_CORRUPT(mp, i != 1)) {
1609		error = -EFSCORRUPTED;
1610		goto done;
1611	}
1612
1613	ASSERT(PREV.rm_offset <= offset);
1614	ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1615	ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1616	newext = ~oldext & XFS_RMAP_UNWRITTEN;
1617
1618	/*
1619	 * Set flags determining what part of the previous oldext allocation
1620	 * extent is being replaced by a newext allocation.
1621	 */
1622	if (PREV.rm_offset == offset)
1623		state |= RMAP_LEFT_FILLING;
1624	if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1625		state |= RMAP_RIGHT_FILLING;
1626
1627	/* Is there a left record that abuts our range? */
1628	error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
1629			&LEFT, &i);
1630	if (error)
1631		goto done;
1632	if (i) {
1633		state |= RMAP_LEFT_VALID;
1634		if (XFS_IS_CORRUPT(mp,
1635				   LEFT.rm_startblock + LEFT.rm_blockcount >
1636				   bno)) {
1637			error = -EFSCORRUPTED;
1638			goto done;
1639		}
1640		if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
1641			state |= RMAP_LEFT_CONTIG;
1642	}
1643
1644	/* Is there a right record that abuts our range? */
1645	error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1646			newext, &i);
1647	if (error)
1648		goto done;
1649	if (i) {
1650		state |= RMAP_RIGHT_VALID;
1651		error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1652		if (error)
1653			goto done;
1654		if (XFS_IS_CORRUPT(mp, i != 1)) {
1655			error = -EFSCORRUPTED;
1656			goto done;
1657		}
1658		if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
1659			error = -EFSCORRUPTED;
1660			goto done;
1661		}
1662		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1663				cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
1664				RIGHT.rm_blockcount, RIGHT.rm_owner,
1665				RIGHT.rm_offset, RIGHT.rm_flags);
1666		if (xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1667			state |= RMAP_RIGHT_CONTIG;
1668	}
1669
1670	/* check that left + prev + right is not too long */
1671	if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1672			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1673	    (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1674	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1675	    (unsigned long)LEFT.rm_blockcount + len +
1676	     RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1677		state &= ~RMAP_RIGHT_CONTIG;
1678
1679	trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
1680			_RET_IP_);
1681	/*
1682	 * Switch out based on the FILLING and CONTIG state bits.
1683	 */
1684	switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1685			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1686	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1687	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1688		/*
1689		 * Setting all of a previous oldext extent to newext.
1690		 * The left and right neighbors are both contiguous with new.
1691		 */
1692		error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1693				RIGHT.rm_blockcount, RIGHT.rm_owner,
1694				RIGHT.rm_offset, RIGHT.rm_flags);
1695		if (error)
1696			goto done;
1697		error = xfs_rmap_delete(cur, PREV.rm_startblock,
1698				PREV.rm_blockcount, PREV.rm_owner,
1699				PREV.rm_offset, PREV.rm_flags);
1700		if (error)
1701			goto done;
1702		NEW = LEFT;
1703		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1704				NEW.rm_blockcount, NEW.rm_owner,
1705				NEW.rm_offset, NEW.rm_flags, &i);
1706		if (error)
1707			goto done;
1708		if (XFS_IS_CORRUPT(mp, i != 1)) {
1709			error = -EFSCORRUPTED;
1710			goto done;
1711		}
1712		NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1713		error = xfs_rmap_update(cur, &NEW);
1714		if (error)
1715			goto done;
1716		break;
1717
1718	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1719		/*
1720		 * Setting all of a previous oldext extent to newext.
1721		 * The left neighbor is contiguous, the right is not.
1722		 */
1723		error = xfs_rmap_delete(cur, PREV.rm_startblock,
1724				PREV.rm_blockcount, PREV.rm_owner,
1725				PREV.rm_offset, PREV.rm_flags);
1726		if (error)
1727			goto done;
1728		NEW = LEFT;
1729		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1730				NEW.rm_blockcount, NEW.rm_owner,
1731				NEW.rm_offset, NEW.rm_flags, &i);
1732		if (error)
1733			goto done;
1734		if (XFS_IS_CORRUPT(mp, i != 1)) {
1735			error = -EFSCORRUPTED;
1736			goto done;
1737		}
1738		NEW.rm_blockcount += PREV.rm_blockcount;
1739		error = xfs_rmap_update(cur, &NEW);
1740		if (error)
1741			goto done;
1742		break;
1743
1744	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1745		/*
1746		 * Setting all of a previous oldext extent to newext.
1747		 * The right neighbor is contiguous, the left is not.
1748		 */
1749		error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1750				RIGHT.rm_blockcount, RIGHT.rm_owner,
1751				RIGHT.rm_offset, RIGHT.rm_flags);
1752		if (error)
1753			goto done;
1754		NEW = PREV;
1755		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1756				NEW.rm_blockcount, NEW.rm_owner,
1757				NEW.rm_offset, NEW.rm_flags, &i);
1758		if (error)
1759			goto done;
1760		if (XFS_IS_CORRUPT(mp, i != 1)) {
1761			error = -EFSCORRUPTED;
1762			goto done;
1763		}
1764		NEW.rm_blockcount += RIGHT.rm_blockcount;
1765		NEW.rm_flags = RIGHT.rm_flags;
1766		error = xfs_rmap_update(cur, &NEW);
1767		if (error)
1768			goto done;
1769		break;
1770
1771	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1772		/*
1773		 * Setting all of a previous oldext extent to newext.
1774		 * Neither the left nor right neighbors are contiguous with
1775		 * the new one.
1776		 */
1777		NEW = PREV;
1778		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1779				NEW.rm_blockcount, NEW.rm_owner,
1780				NEW.rm_offset, NEW.rm_flags, &i);
1781		if (error)
1782			goto done;
1783		if (XFS_IS_CORRUPT(mp, i != 1)) {
1784			error = -EFSCORRUPTED;
1785			goto done;
1786		}
1787		NEW.rm_flags = newext;
1788		error = xfs_rmap_update(cur, &NEW);
1789		if (error)
1790			goto done;
1791		break;
1792
1793	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1794		/*
1795		 * Setting the first part of a previous oldext extent to newext.
1796		 * The left neighbor is contiguous.
1797		 */
1798		NEW = PREV;
1799		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1800				NEW.rm_blockcount, NEW.rm_owner,
1801				NEW.rm_offset, NEW.rm_flags);
1802		if (error)
1803			goto done;
1804		NEW.rm_offset += len;
1805		NEW.rm_startblock += len;
1806		NEW.rm_blockcount -= len;
1807		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1808				NEW.rm_blockcount, NEW.rm_owner,
1809				NEW.rm_offset, NEW.rm_flags);
1810		if (error)
1811			goto done;
1812		NEW = LEFT;
1813		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1814				NEW.rm_blockcount, NEW.rm_owner,
1815				NEW.rm_offset, NEW.rm_flags, &i);
1816		if (error)
1817			goto done;
1818		if (XFS_IS_CORRUPT(mp, i != 1)) {
1819			error = -EFSCORRUPTED;
1820			goto done;
1821		}
1822		NEW.rm_blockcount += len;
1823		error = xfs_rmap_update(cur, &NEW);
1824		if (error)
1825			goto done;
1826		break;
1827
1828	case RMAP_LEFT_FILLING:
1829		/*
1830		 * Setting the first part of a previous oldext extent to newext.
1831		 * The left neighbor is not contiguous.
1832		 */
1833		NEW = PREV;
1834		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1835				NEW.rm_blockcount, NEW.rm_owner,
1836				NEW.rm_offset, NEW.rm_flags);
1837		if (error)
1838			goto done;
1839		NEW.rm_offset += len;
1840		NEW.rm_startblock += len;
1841		NEW.rm_blockcount -= len;
1842		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1843				NEW.rm_blockcount, NEW.rm_owner,
1844				NEW.rm_offset, NEW.rm_flags);
1845		if (error)
1846			goto done;
1847		error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1848		if (error)
1849			goto done;
1850		break;
1851
1852	case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1853		/*
1854		 * Setting the last part of a previous oldext extent to newext.
1855		 * The right neighbor is contiguous with the new allocation.
1856		 */
1857		NEW = PREV;
1858		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1859				NEW.rm_blockcount, NEW.rm_owner,
1860				NEW.rm_offset, NEW.rm_flags, &i);
1861		if (error)
1862			goto done;
1863		if (XFS_IS_CORRUPT(mp, i != 1)) {
1864			error = -EFSCORRUPTED;
1865			goto done;
1866		}
1867		NEW.rm_blockcount = offset - NEW.rm_offset;
1868		error = xfs_rmap_update(cur, &NEW);
1869		if (error)
1870			goto done;
1871		NEW = RIGHT;
1872		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1873				NEW.rm_blockcount, NEW.rm_owner,
1874				NEW.rm_offset, NEW.rm_flags);
1875		if (error)
1876			goto done;
1877		NEW.rm_offset = offset;
1878		NEW.rm_startblock = bno;
1879		NEW.rm_blockcount += len;
1880		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1881				NEW.rm_blockcount, NEW.rm_owner,
1882				NEW.rm_offset, NEW.rm_flags);
1883		if (error)
1884			goto done;
1885		break;
1886
1887	case RMAP_RIGHT_FILLING:
1888		/*
1889		 * Setting the last part of a previous oldext extent to newext.
1890		 * The right neighbor is not contiguous.
1891		 */
1892		NEW = PREV;
1893		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1894				NEW.rm_blockcount, NEW.rm_owner,
1895				NEW.rm_offset, NEW.rm_flags, &i);
1896		if (error)
1897			goto done;
1898		if (XFS_IS_CORRUPT(mp, i != 1)) {
1899			error = -EFSCORRUPTED;
1900			goto done;
1901		}
1902		NEW.rm_blockcount -= len;
1903		error = xfs_rmap_update(cur, &NEW);
1904		if (error)
1905			goto done;
1906		error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1907		if (error)
1908			goto done;
1909		break;
1910
1911	case 0:
1912		/*
1913		 * Setting the middle part of a previous oldext extent to
1914		 * newext.  Contiguity is impossible here.
1915		 * One extent becomes three extents.
1916		 */
1917		/* new right extent - oldext */
1918		NEW.rm_startblock = bno + len;
1919		NEW.rm_owner = owner;
1920		NEW.rm_offset = new_endoff;
1921		NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1922				new_endoff;
1923		NEW.rm_flags = PREV.rm_flags;
1924		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1925				NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1926				NEW.rm_flags);
1927		if (error)
1928			goto done;
1929		/* new left extent - oldext */
1930		NEW = PREV;
1931		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1932				NEW.rm_blockcount, NEW.rm_owner,
1933				NEW.rm_offset, NEW.rm_flags, &i);
1934		if (error)
1935			goto done;
1936		if (XFS_IS_CORRUPT(mp, i != 1)) {
1937			error = -EFSCORRUPTED;
1938			goto done;
1939		}
1940		NEW.rm_blockcount = offset - NEW.rm_offset;
1941		error = xfs_rmap_update(cur, &NEW);
1942		if (error)
1943			goto done;
1944		/* new middle extent - newext */
1945		NEW.rm_startblock = bno;
1946		NEW.rm_blockcount = len;
1947		NEW.rm_owner = owner;
1948		NEW.rm_offset = offset;
1949		NEW.rm_flags = newext;
1950		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1951				NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1952				NEW.rm_flags);
1953		if (error)
1954			goto done;
1955		break;
1956
1957	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1958	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1959	case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1960	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1961	case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1962	case RMAP_LEFT_CONTIG:
1963	case RMAP_RIGHT_CONTIG:
1964		/*
1965		 * These cases are all impossible.
1966		 */
1967		ASSERT(0);
1968	}
1969
1970	trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1971			unwritten, oinfo);
1972done:
1973	if (error)
1974		trace_xfs_rmap_convert_error(cur->bc_mp,
1975				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
1976	return error;
1977}
1978
1979#undef	NEW
1980#undef	LEFT
1981#undef	RIGHT
1982#undef	PREV
1983
1984/*
1985 * Find an extent in the rmap btree and unmap it.  For rmap extent types that
1986 * can overlap (data fork rmaps on reflink filesystems) we must be careful
1987 * that the prev/next records in the btree might belong to another owner.
1988 * Therefore we must use delete+insert to alter any of the key fields.
1989 *
1990 * For every other situation there can only be one owner for a given extent,
1991 * so we can call the regular _free function.
1992 */
1993STATIC int
1994xfs_rmap_unmap_shared(
1995	struct xfs_btree_cur		*cur,
1996	xfs_agblock_t			bno,
1997	xfs_extlen_t			len,
1998	bool				unwritten,
1999	const struct xfs_owner_info	*oinfo)
2000{
2001	struct xfs_mount		*mp = cur->bc_mp;
2002	struct xfs_rmap_irec		ltrec;
2003	uint64_t			ltoff;
2004	int				error = 0;
2005	int				i;
2006	uint64_t			owner;
2007	uint64_t			offset;
2008	unsigned int			flags;
2009
2010	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
2011	if (unwritten)
2012		flags |= XFS_RMAP_UNWRITTEN;
2013	trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
2014			unwritten, oinfo);
2015
2016	/*
2017	 * We should always have a left record because there's a static record
2018	 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
2019	 * will not ever be removed from the tree.
2020	 */
2021	error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
2022			&ltrec, &i);
2023	if (error)
2024		goto out_error;
2025	if (XFS_IS_CORRUPT(mp, i != 1)) {
2026		error = -EFSCORRUPTED;
2027		goto out_error;
2028	}
2029	ltoff = ltrec.rm_offset;
2030
2031	/* Make sure the extent we found covers the entire freeing range. */
2032	if (XFS_IS_CORRUPT(mp,
2033			   ltrec.rm_startblock > bno ||
2034			   ltrec.rm_startblock + ltrec.rm_blockcount <
2035			   bno + len)) {
2036		error = -EFSCORRUPTED;
2037		goto out_error;
2038	}
2039
2040	/* Make sure the owner matches what we expect to find in the tree. */
2041	if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) {
2042		error = -EFSCORRUPTED;
2043		goto out_error;
2044	}
2045
2046	/* Make sure the unwritten flag matches. */
2047	if (XFS_IS_CORRUPT(mp,
2048			   (flags & XFS_RMAP_UNWRITTEN) !=
2049			   (ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) {
2050		error = -EFSCORRUPTED;
2051		goto out_error;
2052	}
2053
2054	/* Check the offset. */
2055	if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) {
2056		error = -EFSCORRUPTED;
2057		goto out_error;
2058	}
2059	if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) {
2060		error = -EFSCORRUPTED;
2061		goto out_error;
2062	}
2063
2064	if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
2065		/* Exact match, simply remove the record from rmap tree. */
2066		error = xfs_rmap_delete(cur, ltrec.rm_startblock,
2067				ltrec.rm_blockcount, ltrec.rm_owner,
2068				ltrec.rm_offset, ltrec.rm_flags);
2069		if (error)
2070			goto out_error;
2071	} else if (ltrec.rm_startblock == bno) {
2072		/*
2073		 * Overlap left hand side of extent: move the start, trim the
2074		 * length and update the current record.
2075		 *
2076		 *       ltbno                ltlen
2077		 * Orig:    |oooooooooooooooooooo|
2078		 * Freeing: |fffffffff|
2079		 * Result:            |rrrrrrrrrr|
2080		 *         bno       len
2081		 */
2082
2083		/* Delete prev rmap. */
2084		error = xfs_rmap_delete(cur, ltrec.rm_startblock,
2085				ltrec.rm_blockcount, ltrec.rm_owner,
2086				ltrec.rm_offset, ltrec.rm_flags);
2087		if (error)
2088			goto out_error;
2089
2090		/* Add an rmap at the new offset. */
2091		ltrec.rm_startblock += len;
2092		ltrec.rm_blockcount -= len;
2093		ltrec.rm_offset += len;
2094		error = xfs_rmap_insert(cur, ltrec.rm_startblock,
2095				ltrec.rm_blockcount, ltrec.rm_owner,
2096				ltrec.rm_offset, ltrec.rm_flags);
2097		if (error)
2098			goto out_error;
2099	} else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
2100		/*
2101		 * Overlap right hand side of extent: trim the length and
2102		 * update the current record.
2103		 *
2104		 *       ltbno                ltlen
2105		 * Orig:    |oooooooooooooooooooo|
2106		 * Freeing:            |fffffffff|
2107		 * Result:  |rrrrrrrrrr|
2108		 *                    bno       len
2109		 */
2110		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2111				ltrec.rm_blockcount, ltrec.rm_owner,
2112				ltrec.rm_offset, ltrec.rm_flags, &i);
2113		if (error)
2114			goto out_error;
2115		if (XFS_IS_CORRUPT(mp, i != 1)) {
2116			error = -EFSCORRUPTED;
2117			goto out_error;
2118		}
2119		ltrec.rm_blockcount -= len;
2120		error = xfs_rmap_update(cur, &ltrec);
2121		if (error)
2122			goto out_error;
2123	} else {
2124		/*
2125		 * Overlap middle of extent: trim the length of the existing
2126		 * record to the length of the new left-extent size, increment
2127		 * the insertion position so we can insert a new record
2128		 * containing the remaining right-extent space.
2129		 *
2130		 *       ltbno                ltlen
2131		 * Orig:    |oooooooooooooooooooo|
2132		 * Freeing:       |fffffffff|
2133		 * Result:  |rrrrr|         |rrrr|
2134		 *               bno       len
2135		 */
2136		xfs_extlen_t	orig_len = ltrec.rm_blockcount;
2137
2138		/* Shrink the left side of the rmap */
2139		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2140				ltrec.rm_blockcount, ltrec.rm_owner,
2141				ltrec.rm_offset, ltrec.rm_flags, &i);
2142		if (error)
2143			goto out_error;
2144		if (XFS_IS_CORRUPT(mp, i != 1)) {
2145			error = -EFSCORRUPTED;
2146			goto out_error;
2147		}
2148		ltrec.rm_blockcount = bno - ltrec.rm_startblock;
2149		error = xfs_rmap_update(cur, &ltrec);
2150		if (error)
2151			goto out_error;
2152
2153		/* Add an rmap at the new offset */
2154		error = xfs_rmap_insert(cur, bno + len,
2155				orig_len - len - ltrec.rm_blockcount,
2156				ltrec.rm_owner, offset + len,
2157				ltrec.rm_flags);
2158		if (error)
2159			goto out_error;
2160	}
2161
2162	trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
2163			unwritten, oinfo);
2164out_error:
2165	if (error)
2166		trace_xfs_rmap_unmap_error(cur->bc_mp,
2167				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
2168	return error;
2169}
2170
2171/*
2172 * Find an extent in the rmap btree and map it.  For rmap extent types that
2173 * can overlap (data fork rmaps on reflink filesystems) we must be careful
2174 * that the prev/next records in the btree might belong to another owner.
2175 * Therefore we must use delete+insert to alter any of the key fields.
2176 *
2177 * For every other situation there can only be one owner for a given extent,
2178 * so we can call the regular _alloc function.
2179 */
2180STATIC int
2181xfs_rmap_map_shared(
2182	struct xfs_btree_cur		*cur,
2183	xfs_agblock_t			bno,
2184	xfs_extlen_t			len,
2185	bool				unwritten,
2186	const struct xfs_owner_info	*oinfo)
2187{
2188	struct xfs_mount		*mp = cur->bc_mp;
2189	struct xfs_rmap_irec		ltrec;
2190	struct xfs_rmap_irec		gtrec;
2191	int				have_gt;
2192	int				have_lt;
2193	int				error = 0;
2194	int				i;
2195	uint64_t			owner;
2196	uint64_t			offset;
2197	unsigned int			flags = 0;
2198
2199	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
2200	if (unwritten)
2201		flags |= XFS_RMAP_UNWRITTEN;
2202	trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
2203			unwritten, oinfo);
2204
2205	/* Is there a left record that abuts our range? */
2206	error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
2207			&ltrec, &have_lt);
2208	if (error)
2209		goto out_error;
2210	if (have_lt &&
2211	    !xfs_rmap_is_mergeable(&ltrec, owner, flags))
2212		have_lt = 0;
2213
2214	/* Is there a right record that abuts our range? */
2215	error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
2216			flags, &have_gt);
2217	if (error)
2218		goto out_error;
2219	if (have_gt) {
2220		error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
2221		if (error)
2222			goto out_error;
2223		if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
2224			error = -EFSCORRUPTED;
2225			goto out_error;
2226		}
2227		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
2228			cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
2229			gtrec.rm_blockcount, gtrec.rm_owner,
2230			gtrec.rm_offset, gtrec.rm_flags);
2231
2232		if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
2233			have_gt = 0;
2234	}
2235
2236	if (have_lt &&
2237	    ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
2238	    ltrec.rm_offset + ltrec.rm_blockcount == offset) {
2239		/*
2240		 * Left edge contiguous, merge into left record.
2241		 *
2242		 *       ltbno     ltlen
2243		 * orig:   |ooooooooo|
2244		 * adding:           |aaaaaaaaa|
2245		 * result: |rrrrrrrrrrrrrrrrrrr|
2246		 *                  bno       len
2247		 */
2248		ltrec.rm_blockcount += len;
2249		if (have_gt &&
2250		    bno + len == gtrec.rm_startblock &&
2251		    offset + len == gtrec.rm_offset) {
2252			/*
2253			 * Right edge also contiguous, delete right record
2254			 * and merge into left record.
2255			 *
2256			 *       ltbno     ltlen    gtbno     gtlen
2257			 * orig:   |ooooooooo|         |ooooooooo|
2258			 * adding:           |aaaaaaaaa|
2259			 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
2260			 */
2261			ltrec.rm_blockcount += gtrec.rm_blockcount;
2262			error = xfs_rmap_delete(cur, gtrec.rm_startblock,
2263					gtrec.rm_blockcount, gtrec.rm_owner,
2264					gtrec.rm_offset, gtrec.rm_flags);
2265			if (error)
2266				goto out_error;
2267		}
2268
2269		/* Point the cursor back to the left record and update. */
2270		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2271				ltrec.rm_blockcount, ltrec.rm_owner,
2272				ltrec.rm_offset, ltrec.rm_flags, &i);
2273		if (error)
2274			goto out_error;
2275		if (XFS_IS_CORRUPT(mp, i != 1)) {
2276			error = -EFSCORRUPTED;
2277			goto out_error;
2278		}
2279
2280		error = xfs_rmap_update(cur, &ltrec);
2281		if (error)
2282			goto out_error;
2283	} else if (have_gt &&
2284		   bno + len == gtrec.rm_startblock &&
2285		   offset + len == gtrec.rm_offset) {
2286		/*
2287		 * Right edge contiguous, merge into right record.
2288		 *
2289		 *                 gtbno     gtlen
2290		 * Orig:             |ooooooooo|
2291		 * adding: |aaaaaaaaa|
2292		 * Result: |rrrrrrrrrrrrrrrrrrr|
2293		 *        bno       len
2294		 */
2295		/* Delete the old record. */
2296		error = xfs_rmap_delete(cur, gtrec.rm_startblock,
2297				gtrec.rm_blockcount, gtrec.rm_owner,
2298				gtrec.rm_offset, gtrec.rm_flags);
2299		if (error)
2300			goto out_error;
2301
2302		/* Move the start and re-add it. */
2303		gtrec.rm_startblock = bno;
2304		gtrec.rm_blockcount += len;
2305		gtrec.rm_offset = offset;
2306		error = xfs_rmap_insert(cur, gtrec.rm_startblock,
2307				gtrec.rm_blockcount, gtrec.rm_owner,
2308				gtrec.rm_offset, gtrec.rm_flags);
2309		if (error)
2310			goto out_error;
2311	} else {
2312		/*
2313		 * No contiguous edge with identical owner, insert
2314		 * new record at current cursor position.
2315		 */
2316		error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
2317		if (error)
2318			goto out_error;
2319	}
2320
2321	trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
2322			unwritten, oinfo);
2323out_error:
2324	if (error)
2325		trace_xfs_rmap_map_error(cur->bc_mp,
2326				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
2327	return error;
2328}
2329
2330/* Insert a raw rmap into the rmapbt. */
2331int
2332xfs_rmap_map_raw(
2333	struct xfs_btree_cur	*cur,
2334	struct xfs_rmap_irec	*rmap)
2335{
2336	struct xfs_owner_info	oinfo;
2337
2338	oinfo.oi_owner = rmap->rm_owner;
2339	oinfo.oi_offset = rmap->rm_offset;
2340	oinfo.oi_flags = 0;
2341	if (rmap->rm_flags & XFS_RMAP_ATTR_FORK)
2342		oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
2343	if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK)
2344		oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
2345
2346	if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
2347		return xfs_rmap_map(cur, rmap->rm_startblock,
2348				rmap->rm_blockcount,
2349				rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2350				&oinfo);
2351
2352	return xfs_rmap_map_shared(cur, rmap->rm_startblock,
2353			rmap->rm_blockcount,
2354			rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2355			&oinfo);
2356}
2357
2358struct xfs_rmap_query_range_info {
2359	xfs_rmap_query_range_fn	fn;
2360	void				*priv;
2361};
2362
2363/* Format btree record and pass to our callback. */
2364STATIC int
2365xfs_rmap_query_range_helper(
2366	struct xfs_btree_cur		*cur,
2367	const union xfs_btree_rec	*rec,
2368	void				*priv)
2369{
2370	struct xfs_rmap_query_range_info	*query = priv;
2371	struct xfs_rmap_irec			irec;
2372	xfs_failaddr_t				fa;
2373
2374	fa = xfs_rmap_btrec_to_irec(rec, &irec);
2375	if (!fa)
2376		fa = xfs_rmap_check_irec(cur, &irec);
2377	if (fa)
2378		return xfs_rmap_complain_bad_rec(cur, fa, &irec);
2379
 
 
 
2380	return query->fn(cur, &irec, query->priv);
2381}
2382
2383/* Find all rmaps between two keys. */
2384int
2385xfs_rmap_query_range(
2386	struct xfs_btree_cur			*cur,
2387	const struct xfs_rmap_irec		*low_rec,
2388	const struct xfs_rmap_irec		*high_rec,
2389	xfs_rmap_query_range_fn			fn,
2390	void					*priv)
2391{
2392	union xfs_btree_irec			low_brec = { .r = *low_rec };
2393	union xfs_btree_irec			high_brec = { .r = *high_rec };
2394	struct xfs_rmap_query_range_info	query = { .priv = priv, .fn = fn };
2395
2396	return xfs_btree_query_range(cur, &low_brec, &high_brec,
2397			xfs_rmap_query_range_helper, &query);
2398}
2399
2400/* Find all rmaps. */
2401int
2402xfs_rmap_query_all(
2403	struct xfs_btree_cur			*cur,
2404	xfs_rmap_query_range_fn			fn,
2405	void					*priv)
2406{
 
 
2407	struct xfs_rmap_query_range_info	query;
2408
 
 
2409	query.priv = priv;
2410	query.fn = fn;
2411	return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query);
 
2412}
2413
2414/* Clean up after calling xfs_rmap_finish_one. */
2415void
2416xfs_rmap_finish_one_cleanup(
2417	struct xfs_trans	*tp,
2418	struct xfs_btree_cur	*rcur,
2419	int			error)
2420{
2421	struct xfs_buf		*agbp;
2422
2423	if (rcur == NULL)
2424		return;
2425	agbp = rcur->bc_ag.agbp;
2426	xfs_btree_del_cursor(rcur, error);
2427	if (error)
2428		xfs_trans_brelse(tp, agbp);
2429}
2430
2431/*
2432 * Process one of the deferred rmap operations.  We pass back the
2433 * btree cursor to maintain our lock on the rmapbt between calls.
2434 * This saves time and eliminates a buffer deadlock between the
2435 * superblock and the AGF because we'll always grab them in the same
2436 * order.
2437 */
2438int
2439xfs_rmap_finish_one(
2440	struct xfs_trans		*tp,
2441	struct xfs_rmap_intent		*ri,
 
 
 
 
 
 
2442	struct xfs_btree_cur		**pcur)
2443{
2444	struct xfs_mount		*mp = tp->t_mountp;
2445	struct xfs_btree_cur		*rcur;
2446	struct xfs_buf			*agbp = NULL;
2447	int				error = 0;
 
2448	struct xfs_owner_info		oinfo;
2449	xfs_agblock_t			bno;
2450	bool				unwritten;
2451
2452	bno = XFS_FSB_TO_AGBNO(mp, ri->ri_bmap.br_startblock);
2453
2454	trace_xfs_rmap_deferred(mp, ri->ri_pag->pag_agno, ri->ri_type, bno,
2455			ri->ri_owner, ri->ri_whichfork,
2456			ri->ri_bmap.br_startoff, ri->ri_bmap.br_blockcount,
2457			ri->ri_bmap.br_state);
2458
2459	if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE))
 
 
2460		return -EIO;
2461
2462	/*
2463	 * If we haven't gotten a cursor or the cursor AG doesn't match
2464	 * the startblock, get one now.
2465	 */
2466	rcur = *pcur;
2467	if (rcur != NULL && rcur->bc_ag.pag != ri->ri_pag) {
2468		xfs_rmap_finish_one_cleanup(tp, rcur, 0);
2469		rcur = NULL;
2470		*pcur = NULL;
2471	}
2472	if (rcur == NULL) {
2473		/*
2474		 * Refresh the freelist before we start changing the
2475		 * rmapbt, because a shape change could cause us to
2476		 * allocate blocks.
2477		 */
2478		error = xfs_free_extent_fix_freelist(tp, ri->ri_pag, &agbp);
2479		if (error)
2480			return error;
2481		if (XFS_IS_CORRUPT(tp->t_mountp, !agbp))
2482			return -EFSCORRUPTED;
2483
2484		rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, ri->ri_pag);
 
 
 
 
2485	}
2486	*pcur = rcur;
2487
2488	xfs_rmap_ino_owner(&oinfo, ri->ri_owner, ri->ri_whichfork,
2489			ri->ri_bmap.br_startoff);
2490	unwritten = ri->ri_bmap.br_state == XFS_EXT_UNWRITTEN;
2491	bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, ri->ri_bmap.br_startblock);
2492
2493	switch (ri->ri_type) {
2494	case XFS_RMAP_ALLOC:
2495	case XFS_RMAP_MAP:
2496		error = xfs_rmap_map(rcur, bno, ri->ri_bmap.br_blockcount,
2497				unwritten, &oinfo);
2498		break;
2499	case XFS_RMAP_MAP_SHARED:
2500		error = xfs_rmap_map_shared(rcur, bno,
2501				ri->ri_bmap.br_blockcount, unwritten, &oinfo);
2502		break;
2503	case XFS_RMAP_FREE:
2504	case XFS_RMAP_UNMAP:
2505		error = xfs_rmap_unmap(rcur, bno, ri->ri_bmap.br_blockcount,
2506				unwritten, &oinfo);
2507		break;
2508	case XFS_RMAP_UNMAP_SHARED:
2509		error = xfs_rmap_unmap_shared(rcur, bno,
2510				ri->ri_bmap.br_blockcount, unwritten, &oinfo);
2511		break;
2512	case XFS_RMAP_CONVERT:
2513		error = xfs_rmap_convert(rcur, bno, ri->ri_bmap.br_blockcount,
2514				!unwritten, &oinfo);
2515		break;
2516	case XFS_RMAP_CONVERT_SHARED:
2517		error = xfs_rmap_convert_shared(rcur, bno,
2518				ri->ri_bmap.br_blockcount, !unwritten, &oinfo);
2519		break;
2520	default:
2521		ASSERT(0);
2522		error = -EFSCORRUPTED;
2523	}
 
 
 
 
2524
2525	return error;
2526}
2527
2528/*
2529 * Don't defer an rmap if we aren't an rmap filesystem.
2530 */
2531static bool
2532xfs_rmap_update_is_needed(
2533	struct xfs_mount	*mp,
2534	int			whichfork)
2535{
2536	return xfs_has_rmapbt(mp) && whichfork != XFS_COW_FORK;
2537}
2538
2539/*
2540 * Record a rmap intent; the list is kept sorted first by AG and then by
2541 * increasing age.
2542 */
2543static void
2544__xfs_rmap_add(
2545	struct xfs_trans		*tp,
 
2546	enum xfs_rmap_intent_type	type,
2547	uint64_t			owner,
2548	int				whichfork,
2549	struct xfs_bmbt_irec		*bmap)
2550{
2551	struct xfs_rmap_intent		*ri;
2552
2553	trace_xfs_rmap_defer(tp->t_mountp,
2554			XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
2555			type,
2556			XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
2557			owner, whichfork,
2558			bmap->br_startoff,
2559			bmap->br_blockcount,
2560			bmap->br_state);
2561
2562	ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
2563	INIT_LIST_HEAD(&ri->ri_list);
2564	ri->ri_type = type;
2565	ri->ri_owner = owner;
2566	ri->ri_whichfork = whichfork;
2567	ri->ri_bmap = *bmap;
2568
2569	xfs_rmap_update_get_group(tp->t_mountp, ri);
2570	xfs_defer_add(tp, &ri->ri_list, &xfs_rmap_update_defer_type);
2571}
2572
2573/* Map an extent into a file. */
2574void
2575xfs_rmap_map_extent(
2576	struct xfs_trans	*tp,
 
2577	struct xfs_inode	*ip,
2578	int			whichfork,
2579	struct xfs_bmbt_irec	*PREV)
2580{
2581	enum xfs_rmap_intent_type type = XFS_RMAP_MAP;
2582
2583	if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
2584		return;
2585
2586	if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2587		type = XFS_RMAP_MAP_SHARED;
2588
2589	__xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
 
 
2590}
2591
2592/* Unmap an extent out of a file. */
2593void
2594xfs_rmap_unmap_extent(
2595	struct xfs_trans	*tp,
 
2596	struct xfs_inode	*ip,
2597	int			whichfork,
2598	struct xfs_bmbt_irec	*PREV)
2599{
2600	enum xfs_rmap_intent_type type = XFS_RMAP_UNMAP;
2601
2602	if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
2603		return;
2604
2605	if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2606		type = XFS_RMAP_UNMAP_SHARED;
2607
2608	__xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
 
 
2609}
2610
2611/*
2612 * Convert a data fork extent from unwritten to real or vice versa.
2613 *
2614 * Note that tp can be NULL here as no transaction is used for COW fork
2615 * unwritten conversion.
2616 */
2617void
2618xfs_rmap_convert_extent(
2619	struct xfs_mount	*mp,
2620	struct xfs_trans	*tp,
2621	struct xfs_inode	*ip,
2622	int			whichfork,
2623	struct xfs_bmbt_irec	*PREV)
2624{
2625	enum xfs_rmap_intent_type type = XFS_RMAP_CONVERT;
2626
2627	if (!xfs_rmap_update_is_needed(mp, whichfork))
2628		return;
2629
2630	if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2631		type = XFS_RMAP_CONVERT_SHARED;
2632
2633	__xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
 
 
2634}
2635
2636/* Schedule the creation of an rmap for non-file data. */
2637void
2638xfs_rmap_alloc_extent(
2639	struct xfs_trans	*tp,
 
2640	xfs_agnumber_t		agno,
2641	xfs_agblock_t		bno,
2642	xfs_extlen_t		len,
2643	uint64_t		owner)
2644{
2645	struct xfs_bmbt_irec	bmap;
2646
2647	if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
2648		return;
2649
2650	bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
2651	bmap.br_blockcount = len;
2652	bmap.br_startoff = 0;
2653	bmap.br_state = XFS_EXT_NORM;
2654
2655	__xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, XFS_DATA_FORK, &bmap);
 
2656}
2657
2658/* Schedule the deletion of an rmap for non-file data. */
2659void
2660xfs_rmap_free_extent(
2661	struct xfs_trans	*tp,
 
2662	xfs_agnumber_t		agno,
2663	xfs_agblock_t		bno,
2664	xfs_extlen_t		len,
2665	uint64_t		owner)
2666{
2667	struct xfs_bmbt_irec	bmap;
2668
2669	if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
2670		return;
2671
2672	bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
2673	bmap.br_blockcount = len;
2674	bmap.br_startoff = 0;
2675	bmap.br_state = XFS_EXT_NORM;
2676
2677	__xfs_rmap_add(tp, XFS_RMAP_FREE, owner, XFS_DATA_FORK, &bmap);
2678}
2679
2680/* Compare rmap records.  Returns -1 if a < b, 1 if a > b, and 0 if equal. */
2681int
2682xfs_rmap_compare(
2683	const struct xfs_rmap_irec	*a,
2684	const struct xfs_rmap_irec	*b)
2685{
2686	__u64				oa;
2687	__u64				ob;
2688
2689	oa = xfs_rmap_irec_offset_pack(a);
2690	ob = xfs_rmap_irec_offset_pack(b);
2691
2692	if (a->rm_startblock < b->rm_startblock)
2693		return -1;
2694	else if (a->rm_startblock > b->rm_startblock)
2695		return 1;
2696	else if (a->rm_owner < b->rm_owner)
2697		return -1;
2698	else if (a->rm_owner > b->rm_owner)
2699		return 1;
2700	else if (oa < ob)
2701		return -1;
2702	else if (oa > ob)
2703		return 1;
2704	else
2705		return 0;
2706}
2707
2708/*
2709 * Scan the physical storage part of the keyspace of the reverse mapping index
2710 * and tell us if the area has no records, is fully mapped by records, or is
2711 * partially filled.
2712 */
2713int
2714xfs_rmap_has_records(
2715	struct xfs_btree_cur	*cur,
2716	xfs_agblock_t		bno,
2717	xfs_extlen_t		len,
2718	enum xbtree_recpacking	*outcome)
2719{
2720	union xfs_btree_key	mask = {
2721		.rmap.rm_startblock = cpu_to_be32(-1U),
2722	};
2723	union xfs_btree_irec	low;
2724	union xfs_btree_irec	high;
2725
2726	memset(&low, 0, sizeof(low));
2727	low.r.rm_startblock = bno;
2728	memset(&high, 0xFF, sizeof(high));
2729	high.r.rm_startblock = bno + len - 1;
2730
2731	return xfs_btree_has_records(cur, &low, &high, &mask, outcome);
2732}
2733
2734struct xfs_rmap_ownercount {
2735	/* Owner that we're looking for. */
2736	struct xfs_rmap_irec	good;
2737
2738	/* rmap search keys */
2739	struct xfs_rmap_irec	low;
2740	struct xfs_rmap_irec	high;
2741
2742	struct xfs_rmap_matches	*results;
2743
2744	/* Stop early if we find a nonmatch? */
2745	bool			stop_on_nonmatch;
2746};
2747
2748/* Does this rmap represent space that can have multiple owners? */
2749static inline bool
2750xfs_rmap_shareable(
2751	struct xfs_mount		*mp,
2752	const struct xfs_rmap_irec	*rmap)
2753{
2754	if (!xfs_has_reflink(mp))
2755		return false;
2756	if (XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
2757		return false;
2758	if (rmap->rm_flags & (XFS_RMAP_ATTR_FORK |
2759			      XFS_RMAP_BMBT_BLOCK))
2760		return false;
2761	return true;
2762}
2763
2764static inline void
2765xfs_rmap_ownercount_init(
2766	struct xfs_rmap_ownercount	*roc,
2767	xfs_agblock_t			bno,
2768	xfs_extlen_t			len,
2769	const struct xfs_owner_info	*oinfo,
2770	struct xfs_rmap_matches		*results)
2771{
2772	memset(roc, 0, sizeof(*roc));
2773	roc->results = results;
2774
2775	roc->low.rm_startblock = bno;
2776	memset(&roc->high, 0xFF, sizeof(roc->high));
2777	roc->high.rm_startblock = bno + len - 1;
2778
2779	memset(results, 0, sizeof(*results));
2780	roc->good.rm_startblock = bno;
2781	roc->good.rm_blockcount = len;
2782	roc->good.rm_owner = oinfo->oi_owner;
2783	roc->good.rm_offset = oinfo->oi_offset;
2784	if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
2785		roc->good.rm_flags |= XFS_RMAP_ATTR_FORK;
2786	if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
2787		roc->good.rm_flags |= XFS_RMAP_BMBT_BLOCK;
2788}
2789
2790/* Figure out if this is a match for the owner. */
2791STATIC int
2792xfs_rmap_count_owners_helper(
2793	struct xfs_btree_cur		*cur,
2794	const struct xfs_rmap_irec	*rec,
2795	void				*priv)
2796{
2797	struct xfs_rmap_ownercount	*roc = priv;
2798	struct xfs_rmap_irec		check = *rec;
2799	unsigned int			keyflags;
2800	bool				filedata;
2801	int64_t				delta;
2802
2803	filedata = !XFS_RMAP_NON_INODE_OWNER(check.rm_owner) &&
2804		   !(check.rm_flags & XFS_RMAP_BMBT_BLOCK);
2805
2806	/* Trim the part of check that comes before the comparison range. */
2807	delta = (int64_t)roc->good.rm_startblock - check.rm_startblock;
2808	if (delta > 0) {
2809		check.rm_startblock += delta;
2810		check.rm_blockcount -= delta;
2811		if (filedata)
2812			check.rm_offset += delta;
2813	}
2814
2815	/* Trim the part of check that comes after the comparison range. */
2816	delta = (check.rm_startblock + check.rm_blockcount) -
2817		(roc->good.rm_startblock + roc->good.rm_blockcount);
2818	if (delta > 0)
2819		check.rm_blockcount -= delta;
2820
2821	/* Don't care about unwritten status for establishing ownership. */
2822	keyflags = check.rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK);
2823
2824	if (check.rm_startblock	== roc->good.rm_startblock &&
2825	    check.rm_blockcount	== roc->good.rm_blockcount &&
2826	    check.rm_owner	== roc->good.rm_owner &&
2827	    check.rm_offset	== roc->good.rm_offset &&
2828	    keyflags		== roc->good.rm_flags) {
2829		roc->results->matches++;
2830	} else {
2831		roc->results->non_owner_matches++;
2832		if (xfs_rmap_shareable(cur->bc_mp, &roc->good) ^
2833		    xfs_rmap_shareable(cur->bc_mp, &check))
2834			roc->results->bad_non_owner_matches++;
2835	}
2836
2837	if (roc->results->non_owner_matches && roc->stop_on_nonmatch)
2838		return -ECANCELED;
2839
2840	return 0;
2841}
2842
2843/* Count the number of owners and non-owners of this range of blocks. */
2844int
2845xfs_rmap_count_owners(
2846	struct xfs_btree_cur		*cur,
2847	xfs_agblock_t			bno,
2848	xfs_extlen_t			len,
2849	const struct xfs_owner_info	*oinfo,
2850	struct xfs_rmap_matches		*results)
2851{
2852	struct xfs_rmap_ownercount	roc;
2853	int				error;
2854
2855	xfs_rmap_ownercount_init(&roc, bno, len, oinfo, results);
2856	error = xfs_rmap_query_range(cur, &roc.low, &roc.high,
2857			xfs_rmap_count_owners_helper, &roc);
2858	if (error)
2859		return error;
2860
2861	/*
2862	 * There can't be any non-owner rmaps that conflict with the given
2863	 * owner if we didn't find any rmaps matching the owner.
2864	 */
2865	if (!results->matches)
2866		results->bad_non_owner_matches = 0;
2867
2868	return 0;
2869}
2870
2871/*
2872 * Given an extent and some owner info, can we find records overlapping
2873 * the extent whose owner info does not match the given owner?
2874 */
2875int
2876xfs_rmap_has_other_keys(
2877	struct xfs_btree_cur		*cur,
2878	xfs_agblock_t			bno,
2879	xfs_extlen_t			len,
2880	const struct xfs_owner_info	*oinfo,
2881	bool				*has_other)
2882{
2883	struct xfs_rmap_matches		res;
2884	struct xfs_rmap_ownercount	roc;
2885	int				error;
2886
2887	xfs_rmap_ownercount_init(&roc, bno, len, oinfo, &res);
2888	roc.stop_on_nonmatch = true;
2889
2890	error = xfs_rmap_query_range(cur, &roc.low, &roc.high,
2891			xfs_rmap_count_owners_helper, &roc);
2892	if (error == -ECANCELED) {
2893		*has_other = true;
2894		return 0;
2895	}
2896	if (error)
2897		return error;
2898
2899	*has_other = false;
2900	return 0;
2901}
2902
2903const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE = {
2904	.oi_owner = XFS_RMAP_OWN_NULL,
2905};
2906const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER = {
2907	.oi_owner = XFS_RMAP_OWN_UNKNOWN,
2908};
2909const struct xfs_owner_info XFS_RMAP_OINFO_FS = {
2910	.oi_owner = XFS_RMAP_OWN_FS,
2911};
2912const struct xfs_owner_info XFS_RMAP_OINFO_LOG = {
2913	.oi_owner = XFS_RMAP_OWN_LOG,
2914};
2915const struct xfs_owner_info XFS_RMAP_OINFO_AG = {
2916	.oi_owner = XFS_RMAP_OWN_AG,
2917};
2918const struct xfs_owner_info XFS_RMAP_OINFO_INOBT = {
2919	.oi_owner = XFS_RMAP_OWN_INOBT,
2920};
2921const struct xfs_owner_info XFS_RMAP_OINFO_INODES = {
2922	.oi_owner = XFS_RMAP_OWN_INODES,
2923};
2924const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
2925	.oi_owner = XFS_RMAP_OWN_REFC,
2926};
2927const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
2928	.oi_owner = XFS_RMAP_OWN_COW,
2929};
2930
2931int __init
2932xfs_rmap_intent_init_cache(void)
2933{
2934	xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
2935			sizeof(struct xfs_rmap_intent),
2936			0, 0, NULL);
2937
2938	return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
2939}
2940
2941void
2942xfs_rmap_intent_destroy_cache(void)
2943{
2944	kmem_cache_destroy(xfs_rmap_intent_cache);
2945	xfs_rmap_intent_cache = NULL;
2946}
v4.10.11
 
   1/*
   2 * Copyright (c) 2014 Red Hat, Inc.
   3 * All Rights Reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it would be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write the Free Software Foundation,
  16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17 */
  18#include "xfs.h"
  19#include "xfs_fs.h"
  20#include "xfs_shared.h"
  21#include "xfs_format.h"
  22#include "xfs_log_format.h"
  23#include "xfs_trans_resv.h"
  24#include "xfs_bit.h"
 
  25#include "xfs_sb.h"
  26#include "xfs_mount.h"
  27#include "xfs_defer.h"
  28#include "xfs_da_format.h"
  29#include "xfs_da_btree.h"
  30#include "xfs_btree.h"
  31#include "xfs_trans.h"
  32#include "xfs_alloc.h"
  33#include "xfs_rmap.h"
  34#include "xfs_rmap_btree.h"
  35#include "xfs_trans_space.h"
  36#include "xfs_trace.h"
 
  37#include "xfs_error.h"
  38#include "xfs_extent_busy.h"
  39#include "xfs_bmap.h"
  40#include "xfs_inode.h"
 
 
 
  41
  42/*
  43 * Lookup the first record less than or equal to [bno, len, owner, offset]
  44 * in the btree given by cur.
  45 */
  46int
  47xfs_rmap_lookup_le(
  48	struct xfs_btree_cur	*cur,
  49	xfs_agblock_t		bno,
  50	xfs_extlen_t		len,
  51	uint64_t		owner,
  52	uint64_t		offset,
  53	unsigned int		flags,
 
  54	int			*stat)
  55{
 
 
 
  56	cur->bc_rec.r.rm_startblock = bno;
  57	cur->bc_rec.r.rm_blockcount = len;
  58	cur->bc_rec.r.rm_owner = owner;
  59	cur->bc_rec.r.rm_offset = offset;
  60	cur->bc_rec.r.rm_flags = flags;
  61	return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
 
 
 
 
 
 
 
 
 
 
 
  62}
  63
  64/*
  65 * Lookup the record exactly matching [bno, len, owner, offset]
  66 * in the btree given by cur.
  67 */
  68int
  69xfs_rmap_lookup_eq(
  70	struct xfs_btree_cur	*cur,
  71	xfs_agblock_t		bno,
  72	xfs_extlen_t		len,
  73	uint64_t		owner,
  74	uint64_t		offset,
  75	unsigned int		flags,
  76	int			*stat)
  77{
  78	cur->bc_rec.r.rm_startblock = bno;
  79	cur->bc_rec.r.rm_blockcount = len;
  80	cur->bc_rec.r.rm_owner = owner;
  81	cur->bc_rec.r.rm_offset = offset;
  82	cur->bc_rec.r.rm_flags = flags;
  83	return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
  84}
  85
  86/*
  87 * Update the record referred to by cur to the value given
  88 * by [bno, len, owner, offset].
  89 * This either works (return 0) or gets an EFSCORRUPTED error.
  90 */
  91STATIC int
  92xfs_rmap_update(
  93	struct xfs_btree_cur	*cur,
  94	struct xfs_rmap_irec	*irec)
  95{
  96	union xfs_btree_rec	rec;
  97	int			error;
  98
  99	trace_xfs_rmap_update(cur->bc_mp, cur->bc_private.a.agno,
 100			irec->rm_startblock, irec->rm_blockcount,
 101			irec->rm_owner, irec->rm_offset, irec->rm_flags);
 102
 103	rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock);
 104	rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount);
 105	rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner);
 106	rec.rmap.rm_offset = cpu_to_be64(
 107			xfs_rmap_irec_offset_pack(irec));
 108	error = xfs_btree_update(cur, &rec);
 109	if (error)
 110		trace_xfs_rmap_update_error(cur->bc_mp,
 111				cur->bc_private.a.agno, error, _RET_IP_);
 112	return error;
 113}
 114
 115int
 116xfs_rmap_insert(
 117	struct xfs_btree_cur	*rcur,
 118	xfs_agblock_t		agbno,
 119	xfs_extlen_t		len,
 120	uint64_t		owner,
 121	uint64_t		offset,
 122	unsigned int		flags)
 123{
 124	int			i;
 125	int			error;
 126
 127	trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_private.a.agno, agbno,
 128			len, owner, offset, flags);
 129
 130	error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
 131	if (error)
 132		goto done;
 133	XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 0, done);
 
 
 
 134
 135	rcur->bc_rec.r.rm_startblock = agbno;
 136	rcur->bc_rec.r.rm_blockcount = len;
 137	rcur->bc_rec.r.rm_owner = owner;
 138	rcur->bc_rec.r.rm_offset = offset;
 139	rcur->bc_rec.r.rm_flags = flags;
 140	error = xfs_btree_insert(rcur, &i);
 141	if (error)
 142		goto done;
 143	XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
 
 
 
 144done:
 145	if (error)
 146		trace_xfs_rmap_insert_error(rcur->bc_mp,
 147				rcur->bc_private.a.agno, error, _RET_IP_);
 148	return error;
 149}
 150
 151STATIC int
 152xfs_rmap_delete(
 153	struct xfs_btree_cur	*rcur,
 154	xfs_agblock_t		agbno,
 155	xfs_extlen_t		len,
 156	uint64_t		owner,
 157	uint64_t		offset,
 158	unsigned int		flags)
 159{
 160	int			i;
 161	int			error;
 162
 163	trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_private.a.agno, agbno,
 164			len, owner, offset, flags);
 165
 166	error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
 167	if (error)
 168		goto done;
 169	XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
 
 
 
 170
 171	error = xfs_btree_delete(rcur, &i);
 172	if (error)
 173		goto done;
 174	XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
 
 
 
 175done:
 176	if (error)
 177		trace_xfs_rmap_delete_error(rcur->bc_mp,
 178				rcur->bc_private.a.agno, error, _RET_IP_);
 179	return error;
 180}
 181
 182static int
 
 183xfs_rmap_btrec_to_irec(
 184	union xfs_btree_rec	*rec,
 185	struct xfs_rmap_irec	*irec)
 186{
 187	irec->rm_flags = 0;
 188	irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock);
 189	irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount);
 190	irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner);
 191	return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset),
 192			irec);
 193}
 194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 195/*
 196 * Get the data from the pointed-to record.
 197 */
 198int
 199xfs_rmap_get_rec(
 200	struct xfs_btree_cur	*cur,
 201	struct xfs_rmap_irec	*irec,
 202	int			*stat)
 203{
 204	union xfs_btree_rec	*rec;
 
 205	int			error;
 206
 207	error = xfs_btree_get_rec(cur, &rec, stat);
 208	if (error || !*stat)
 209		return error;
 210
 211	return xfs_rmap_btrec_to_irec(rec, irec);
 
 
 
 
 
 
 212}
 213
 214struct xfs_find_left_neighbor_info {
 215	struct xfs_rmap_irec	high;
 216	struct xfs_rmap_irec	*irec;
 217	int			*stat;
 218};
 219
 220/* For each rmap given, figure out if it matches the key we want. */
 221STATIC int
 222xfs_rmap_find_left_neighbor_helper(
 223	struct xfs_btree_cur	*cur,
 224	struct xfs_rmap_irec	*rec,
 225	void			*priv)
 226{
 227	struct xfs_find_left_neighbor_info	*info = priv;
 228
 229	trace_xfs_rmap_find_left_neighbor_candidate(cur->bc_mp,
 230			cur->bc_private.a.agno, rec->rm_startblock,
 231			rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
 232			rec->rm_flags);
 233
 234	if (rec->rm_owner != info->high.rm_owner)
 235		return XFS_BTREE_QUERY_RANGE_CONTINUE;
 236	if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
 237	    !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
 238	    rec->rm_offset + rec->rm_blockcount - 1 != info->high.rm_offset)
 239		return XFS_BTREE_QUERY_RANGE_CONTINUE;
 240
 241	*info->irec = *rec;
 242	*info->stat = 1;
 243	return XFS_BTREE_QUERY_RANGE_ABORT;
 244}
 245
 246/*
 247 * Find the record to the left of the given extent, being careful only to
 248 * return a match with the same owner and adjacent physical and logical
 249 * block ranges.
 250 */
 251int
 252xfs_rmap_find_left_neighbor(
 253	struct xfs_btree_cur	*cur,
 254	xfs_agblock_t		bno,
 255	uint64_t		owner,
 256	uint64_t		offset,
 257	unsigned int		flags,
 258	struct xfs_rmap_irec	*irec,
 259	int			*stat)
 260{
 261	struct xfs_find_left_neighbor_info	info;
 
 262	int			error;
 263
 264	*stat = 0;
 265	if (bno == 0)
 266		return 0;
 267	info.high.rm_startblock = bno - 1;
 268	info.high.rm_owner = owner;
 269	if (!XFS_RMAP_NON_INODE_OWNER(owner) &&
 270	    !(flags & XFS_RMAP_BMBT_BLOCK)) {
 271		if (offset == 0)
 272			return 0;
 273		info.high.rm_offset = offset - 1;
 274	} else
 275		info.high.rm_offset = 0;
 276	info.high.rm_flags = flags;
 277	info.high.rm_blockcount = 0;
 278	info.irec = irec;
 279	info.stat = stat;
 280
 281	trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp,
 282			cur->bc_private.a.agno, bno, 0, owner, offset, flags);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 283
 284	error = xfs_rmap_query_range(cur, &info.high, &info.high,
 285			xfs_rmap_find_left_neighbor_helper, &info);
 286	if (error == XFS_BTREE_QUERY_RANGE_ABORT)
 287		error = 0;
 288	if (*stat)
 289		trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
 290				cur->bc_private.a.agno, irec->rm_startblock,
 291				irec->rm_blockcount, irec->rm_owner,
 292				irec->rm_offset, irec->rm_flags);
 293	return error;
 294}
 295
 296/* For each rmap given, figure out if it matches the key we want. */
 297STATIC int
 298xfs_rmap_lookup_le_range_helper(
 299	struct xfs_btree_cur	*cur,
 300	struct xfs_rmap_irec	*rec,
 301	void			*priv)
 302{
 303	struct xfs_find_left_neighbor_info	*info = priv;
 304
 305	trace_xfs_rmap_lookup_le_range_candidate(cur->bc_mp,
 306			cur->bc_private.a.agno, rec->rm_startblock,
 307			rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
 308			rec->rm_flags);
 309
 310	if (rec->rm_owner != info->high.rm_owner)
 311		return XFS_BTREE_QUERY_RANGE_CONTINUE;
 312	if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
 313	    !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
 314	    (rec->rm_offset > info->high.rm_offset ||
 315	     rec->rm_offset + rec->rm_blockcount <= info->high.rm_offset))
 316		return XFS_BTREE_QUERY_RANGE_CONTINUE;
 317
 318	*info->irec = *rec;
 319	*info->stat = 1;
 320	return XFS_BTREE_QUERY_RANGE_ABORT;
 321}
 322
 323/*
 324 * Find the record to the left of the given extent, being careful only to
 325 * return a match with the same owner and overlapping physical and logical
 326 * block ranges.  This is the overlapping-interval version of
 327 * xfs_rmap_lookup_le.
 328 */
 329int
 330xfs_rmap_lookup_le_range(
 331	struct xfs_btree_cur	*cur,
 332	xfs_agblock_t		bno,
 333	uint64_t		owner,
 334	uint64_t		offset,
 335	unsigned int		flags,
 336	struct xfs_rmap_irec	*irec,
 337	int			*stat)
 338{
 339	struct xfs_find_left_neighbor_info	info;
 
 340	int			error;
 341
 342	info.high.rm_startblock = bno;
 343	info.high.rm_owner = owner;
 344	if (!XFS_RMAP_NON_INODE_OWNER(owner) && !(flags & XFS_RMAP_BMBT_BLOCK))
 345		info.high.rm_offset = offset;
 346	else
 347		info.high.rm_offset = 0;
 348	info.high.rm_flags = flags;
 349	info.high.rm_blockcount = 0;
 350	*stat = 0;
 351	info.irec = irec;
 352	info.stat = stat;
 353
 354	trace_xfs_rmap_lookup_le_range(cur->bc_mp,
 355			cur->bc_private.a.agno, bno, 0, owner, offset, flags);
 356	error = xfs_rmap_query_range(cur, &info.high, &info.high,
 357			xfs_rmap_lookup_le_range_helper, &info);
 358	if (error == XFS_BTREE_QUERY_RANGE_ABORT)
 359		error = 0;
 360	if (*stat)
 361		trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
 362				cur->bc_private.a.agno, irec->rm_startblock,
 363				irec->rm_blockcount, irec->rm_owner,
 364				irec->rm_offset, irec->rm_flags);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 365	return error;
 366}
 367
 368/*
 369 * Find the extent in the rmap btree and remove it.
 370 *
 371 * The record we find should always be an exact match for the extent that we're
 372 * looking for, since we insert them into the btree without modification.
 373 *
 374 * Special Case #1: when growing the filesystem, we "free" an extent when
 375 * growing the last AG. This extent is new space and so it is not tracked as
 376 * used space in the btree. The growfs code will pass in an owner of
 377 * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
 378 * extent. We verify that - the extent lookup result in a record that does not
 379 * overlap.
 380 *
 381 * Special Case #2: EFIs do not record the owner of the extent, so when
 382 * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
 383 * btree to ignore the owner (i.e. wildcard match) so we don't trigger
 384 * corruption checks during log recovery.
 385 */
 386STATIC int
 387xfs_rmap_unmap(
 388	struct xfs_btree_cur	*cur,
 389	xfs_agblock_t		bno,
 390	xfs_extlen_t		len,
 391	bool			unwritten,
 392	struct xfs_owner_info	*oinfo)
 393{
 394	struct xfs_mount	*mp = cur->bc_mp;
 395	struct xfs_rmap_irec	ltrec;
 396	uint64_t		ltoff;
 397	int			error = 0;
 398	int			i;
 399	uint64_t		owner;
 400	uint64_t		offset;
 401	unsigned int		flags;
 402	bool			ignore_off;
 403
 404	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
 405	ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
 406			(flags & XFS_RMAP_BMBT_BLOCK);
 407	if (unwritten)
 408		flags |= XFS_RMAP_UNWRITTEN;
 409	trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
 410			unwritten, oinfo);
 411
 412	/*
 413	 * We should always have a left record because there's a static record
 414	 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
 415	 * will not ever be removed from the tree.
 416	 */
 417	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, &i);
 418	if (error)
 419		goto out_error;
 420	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
 421
 422	error = xfs_rmap_get_rec(cur, &ltrec, &i);
 423	if (error)
 424		goto out_error;
 425	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 426	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
 427			cur->bc_private.a.agno, ltrec.rm_startblock,
 428			ltrec.rm_blockcount, ltrec.rm_owner,
 429			ltrec.rm_offset, ltrec.rm_flags);
 430	ltoff = ltrec.rm_offset;
 431
 432	/*
 433	 * For growfs, the incoming extent must be beyond the left record we
 434	 * just found as it is new space and won't be used by anyone. This is
 435	 * just a corruption check as we don't actually do anything with this
 436	 * extent.  Note that we need to use >= instead of > because it might
 437	 * be the case that the "left" extent goes all the way to EOFS.
 438	 */
 439	if (owner == XFS_RMAP_OWN_NULL) {
 440		XFS_WANT_CORRUPTED_GOTO(mp, bno >= ltrec.rm_startblock +
 441						ltrec.rm_blockcount, out_error);
 
 
 
 
 442		goto out_done;
 443	}
 444
 445	/* Make sure the unwritten flag matches. */
 446	XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
 447			(ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 448
 449	/* Make sure the extent we found covers the entire freeing range. */
 450	XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
 451		ltrec.rm_startblock + ltrec.rm_blockcount >=
 452		bno + len, out_error);
 
 
 
 
 453
 454	/* Make sure the owner matches what we expect to find in the tree. */
 455	XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner ||
 456				    XFS_RMAP_NON_INODE_OWNER(owner), out_error);
 457
 458	/* Check the offset, if necessary. */
 459	if (!XFS_RMAP_NON_INODE_OWNER(owner)) {
 460		if (flags & XFS_RMAP_BMBT_BLOCK) {
 461			XFS_WANT_CORRUPTED_GOTO(mp,
 462					ltrec.rm_flags & XFS_RMAP_BMBT_BLOCK,
 463					out_error);
 464		} else {
 465			XFS_WANT_CORRUPTED_GOTO(mp,
 466					ltrec.rm_offset <= offset, out_error);
 467			XFS_WANT_CORRUPTED_GOTO(mp,
 468					ltoff + ltrec.rm_blockcount >= offset + len,
 469					out_error);
 470		}
 471	}
 472
 473	if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
 474		/* exact match, simply remove the record from rmap tree */
 475		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
 476				ltrec.rm_startblock, ltrec.rm_blockcount,
 477				ltrec.rm_owner, ltrec.rm_offset,
 478				ltrec.rm_flags);
 479		error = xfs_btree_delete(cur, &i);
 480		if (error)
 481			goto out_error;
 482		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
 483	} else if (ltrec.rm_startblock == bno) {
 484		/*
 485		 * overlap left hand side of extent: move the start, trim the
 486		 * length and update the current record.
 487		 *
 488		 *       ltbno                ltlen
 489		 * Orig:    |oooooooooooooooooooo|
 490		 * Freeing: |fffffffff|
 491		 * Result:            |rrrrrrrrrr|
 492		 *         bno       len
 493		 */
 494		ltrec.rm_startblock += len;
 495		ltrec.rm_blockcount -= len;
 496		if (!ignore_off)
 497			ltrec.rm_offset += len;
 498		error = xfs_rmap_update(cur, &ltrec);
 499		if (error)
 500			goto out_error;
 501	} else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
 502		/*
 503		 * overlap right hand side of extent: trim the length and update
 504		 * the current record.
 505		 *
 506		 *       ltbno                ltlen
 507		 * Orig:    |oooooooooooooooooooo|
 508		 * Freeing:            |fffffffff|
 509		 * Result:  |rrrrrrrrrr|
 510		 *                    bno       len
 511		 */
 512		ltrec.rm_blockcount -= len;
 513		error = xfs_rmap_update(cur, &ltrec);
 514		if (error)
 515			goto out_error;
 516	} else {
 517
 518		/*
 519		 * overlap middle of extent: trim the length of the existing
 520		 * record to the length of the new left-extent size, increment
 521		 * the insertion position so we can insert a new record
 522		 * containing the remaining right-extent space.
 523		 *
 524		 *       ltbno                ltlen
 525		 * Orig:    |oooooooooooooooooooo|
 526		 * Freeing:       |fffffffff|
 527		 * Result:  |rrrrr|         |rrrr|
 528		 *               bno       len
 529		 */
 530		xfs_extlen_t	orig_len = ltrec.rm_blockcount;
 531
 532		ltrec.rm_blockcount = bno - ltrec.rm_startblock;
 533		error = xfs_rmap_update(cur, &ltrec);
 534		if (error)
 535			goto out_error;
 536
 537		error = xfs_btree_increment(cur, 0, &i);
 538		if (error)
 539			goto out_error;
 540
 541		cur->bc_rec.r.rm_startblock = bno + len;
 542		cur->bc_rec.r.rm_blockcount = orig_len - len -
 543						     ltrec.rm_blockcount;
 544		cur->bc_rec.r.rm_owner = ltrec.rm_owner;
 545		if (ignore_off)
 546			cur->bc_rec.r.rm_offset = 0;
 547		else
 548			cur->bc_rec.r.rm_offset = offset + len;
 549		cur->bc_rec.r.rm_flags = flags;
 550		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
 551				cur->bc_rec.r.rm_startblock,
 552				cur->bc_rec.r.rm_blockcount,
 553				cur->bc_rec.r.rm_owner,
 554				cur->bc_rec.r.rm_offset,
 555				cur->bc_rec.r.rm_flags);
 556		error = xfs_btree_insert(cur, &i);
 557		if (error)
 558			goto out_error;
 559	}
 560
 561out_done:
 562	trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
 563			unwritten, oinfo);
 564out_error:
 565	if (error)
 566		trace_xfs_rmap_unmap_error(mp, cur->bc_private.a.agno,
 567				error, _RET_IP_);
 568	return error;
 569}
 570
 571/*
 572 * Remove a reference to an extent in the rmap btree.
 573 */
 574int
 575xfs_rmap_free(
 576	struct xfs_trans	*tp,
 577	struct xfs_buf		*agbp,
 578	xfs_agnumber_t		agno,
 579	xfs_agblock_t		bno,
 580	xfs_extlen_t		len,
 581	struct xfs_owner_info	*oinfo)
 582{
 583	struct xfs_mount	*mp = tp->t_mountp;
 584	struct xfs_btree_cur	*cur;
 585	int			error;
 586
 587	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
 588		return 0;
 589
 590	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
 591
 592	error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
 593	if (error)
 594		goto out_error;
 595
 596	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
 597	return 0;
 598
 599out_error:
 600	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
 601	return error;
 602}
 603
 604/*
 605 * A mergeable rmap must have the same owner and the same values for
 606 * the unwritten, attr_fork, and bmbt flags.  The startblock and
 607 * offset are checked separately.
 608 */
 609static bool
 610xfs_rmap_is_mergeable(
 611	struct xfs_rmap_irec	*irec,
 612	uint64_t		owner,
 613	unsigned int		flags)
 614{
 615	if (irec->rm_owner == XFS_RMAP_OWN_NULL)
 616		return false;
 617	if (irec->rm_owner != owner)
 618		return false;
 619	if ((flags & XFS_RMAP_UNWRITTEN) ^
 620	    (irec->rm_flags & XFS_RMAP_UNWRITTEN))
 621		return false;
 622	if ((flags & XFS_RMAP_ATTR_FORK) ^
 623	    (irec->rm_flags & XFS_RMAP_ATTR_FORK))
 624		return false;
 625	if ((flags & XFS_RMAP_BMBT_BLOCK) ^
 626	    (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
 627		return false;
 628	return true;
 629}
 630
 631/*
 632 * When we allocate a new block, the first thing we do is add a reference to
 633 * the extent in the rmap btree. This takes the form of a [agbno, length,
 634 * owner, offset] record.  Flags are encoded in the high bits of the offset
 635 * field.
 636 */
 637STATIC int
 638xfs_rmap_map(
 639	struct xfs_btree_cur	*cur,
 640	xfs_agblock_t		bno,
 641	xfs_extlen_t		len,
 642	bool			unwritten,
 643	struct xfs_owner_info	*oinfo)
 644{
 645	struct xfs_mount	*mp = cur->bc_mp;
 646	struct xfs_rmap_irec	ltrec;
 647	struct xfs_rmap_irec	gtrec;
 648	int			have_gt;
 649	int			have_lt;
 650	int			error = 0;
 651	int			i;
 652	uint64_t		owner;
 653	uint64_t		offset;
 654	unsigned int		flags = 0;
 655	bool			ignore_off;
 656
 657	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
 658	ASSERT(owner != 0);
 659	ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
 660			(flags & XFS_RMAP_BMBT_BLOCK);
 661	if (unwritten)
 662		flags |= XFS_RMAP_UNWRITTEN;
 663	trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
 664			unwritten, oinfo);
 
 665
 666	/*
 667	 * For the initial lookup, look for an exact match or the left-adjacent
 668	 * record for our insertion point. This will also give us the record for
 669	 * start block contiguity tests.
 670	 */
 671	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags,
 672			&have_lt);
 673	if (error)
 674		goto out_error;
 675	XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
 
 
 
 
 
 
 
 
 676
 677	error = xfs_rmap_get_rec(cur, &ltrec, &have_lt);
 678	if (error)
 
 
 679		goto out_error;
 680	XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
 681	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
 682			cur->bc_private.a.agno, ltrec.rm_startblock,
 683			ltrec.rm_blockcount, ltrec.rm_owner,
 684			ltrec.rm_offset, ltrec.rm_flags);
 685
 686	if (!xfs_rmap_is_mergeable(&ltrec, owner, flags))
 687		have_lt = 0;
 688
 689	XFS_WANT_CORRUPTED_GOTO(mp,
 690		have_lt == 0 ||
 691		ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error);
 692
 693	/*
 694	 * Increment the cursor to see if we have a right-adjacent record to our
 695	 * insertion point. This will give us the record for end block
 696	 * contiguity tests.
 697	 */
 698	error = xfs_btree_increment(cur, 0, &have_gt);
 699	if (error)
 700		goto out_error;
 701	if (have_gt) {
 702		error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
 703		if (error)
 704			goto out_error;
 705		XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
 706		XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock,
 707					out_error);
 
 
 
 
 
 708		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
 709			cur->bc_private.a.agno, gtrec.rm_startblock,
 710			gtrec.rm_blockcount, gtrec.rm_owner,
 711			gtrec.rm_offset, gtrec.rm_flags);
 712		if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
 713			have_gt = 0;
 714	}
 715
 716	/*
 717	 * Note: cursor currently points one record to the right of ltrec, even
 718	 * if there is no record in the tree to the right.
 719	 */
 720	if (have_lt &&
 721	    ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
 722	    (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
 723		/*
 724		 * left edge contiguous, merge into left record.
 725		 *
 726		 *       ltbno     ltlen
 727		 * orig:   |ooooooooo|
 728		 * adding:           |aaaaaaaaa|
 729		 * result: |rrrrrrrrrrrrrrrrrrr|
 730		 *                  bno       len
 731		 */
 732		ltrec.rm_blockcount += len;
 733		if (have_gt &&
 734		    bno + len == gtrec.rm_startblock &&
 735		    (ignore_off || offset + len == gtrec.rm_offset) &&
 736		    (unsigned long)ltrec.rm_blockcount + len +
 737				gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
 738			/*
 739			 * right edge also contiguous, delete right record
 740			 * and merge into left record.
 741			 *
 742			 *       ltbno     ltlen    gtbno     gtlen
 743			 * orig:   |ooooooooo|         |ooooooooo|
 744			 * adding:           |aaaaaaaaa|
 745			 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
 746			 */
 747			ltrec.rm_blockcount += gtrec.rm_blockcount;
 748			trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
 749					gtrec.rm_startblock,
 750					gtrec.rm_blockcount,
 751					gtrec.rm_owner,
 752					gtrec.rm_offset,
 753					gtrec.rm_flags);
 754			error = xfs_btree_delete(cur, &i);
 755			if (error)
 756				goto out_error;
 757			XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
 758		}
 759
 760		/* point the cursor back to the left record and update */
 761		error = xfs_btree_decrement(cur, 0, &have_gt);
 762		if (error)
 763			goto out_error;
 764		error = xfs_rmap_update(cur, &ltrec);
 765		if (error)
 766			goto out_error;
 767	} else if (have_gt &&
 768		   bno + len == gtrec.rm_startblock &&
 769		   (ignore_off || offset + len == gtrec.rm_offset)) {
 770		/*
 771		 * right edge contiguous, merge into right record.
 772		 *
 773		 *                 gtbno     gtlen
 774		 * Orig:             |ooooooooo|
 775		 * adding: |aaaaaaaaa|
 776		 * Result: |rrrrrrrrrrrrrrrrrrr|
 777		 *        bno       len
 778		 */
 779		gtrec.rm_startblock = bno;
 780		gtrec.rm_blockcount += len;
 781		if (!ignore_off)
 782			gtrec.rm_offset = offset;
 783		error = xfs_rmap_update(cur, &gtrec);
 784		if (error)
 785			goto out_error;
 786	} else {
 787		/*
 788		 * no contiguous edge with identical owner, insert
 789		 * new record at current cursor position.
 790		 */
 791		cur->bc_rec.r.rm_startblock = bno;
 792		cur->bc_rec.r.rm_blockcount = len;
 793		cur->bc_rec.r.rm_owner = owner;
 794		cur->bc_rec.r.rm_offset = offset;
 795		cur->bc_rec.r.rm_flags = flags;
 796		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
 797			owner, offset, flags);
 798		error = xfs_btree_insert(cur, &i);
 799		if (error)
 800			goto out_error;
 801		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
 802	}
 803
 804	trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
 805			unwritten, oinfo);
 806out_error:
 807	if (error)
 808		trace_xfs_rmap_map_error(mp, cur->bc_private.a.agno,
 809				error, _RET_IP_);
 810	return error;
 811}
 812
 813/*
 814 * Add a reference to an extent in the rmap btree.
 815 */
 816int
 817xfs_rmap_alloc(
 818	struct xfs_trans	*tp,
 819	struct xfs_buf		*agbp,
 820	xfs_agnumber_t		agno,
 821	xfs_agblock_t		bno,
 822	xfs_extlen_t		len,
 823	struct xfs_owner_info	*oinfo)
 824{
 825	struct xfs_mount	*mp = tp->t_mountp;
 826	struct xfs_btree_cur	*cur;
 827	int			error;
 828
 829	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
 830		return 0;
 831
 832	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
 833	error = xfs_rmap_map(cur, bno, len, false, oinfo);
 834	if (error)
 835		goto out_error;
 836
 837	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
 838	return 0;
 839
 840out_error:
 841	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
 842	return error;
 843}
 844
 845#define RMAP_LEFT_CONTIG	(1 << 0)
 846#define RMAP_RIGHT_CONTIG	(1 << 1)
 847#define RMAP_LEFT_FILLING	(1 << 2)
 848#define RMAP_RIGHT_FILLING	(1 << 3)
 849#define RMAP_LEFT_VALID		(1 << 6)
 850#define RMAP_RIGHT_VALID	(1 << 7)
 851
 852#define LEFT		r[0]
 853#define RIGHT		r[1]
 854#define PREV		r[2]
 855#define NEW		r[3]
 856
 857/*
 858 * Convert an unwritten extent to a real extent or vice versa.
 859 * Does not handle overlapping extents.
 860 */
 861STATIC int
 862xfs_rmap_convert(
 863	struct xfs_btree_cur	*cur,
 864	xfs_agblock_t		bno,
 865	xfs_extlen_t		len,
 866	bool			unwritten,
 867	struct xfs_owner_info	*oinfo)
 868{
 869	struct xfs_mount	*mp = cur->bc_mp;
 870	struct xfs_rmap_irec	r[4];	/* neighbor extent entries */
 871					/* left is 0, right is 1, prev is 2 */
 872					/* new is 3 */
 873	uint64_t		owner;
 874	uint64_t		offset;
 875	uint64_t		new_endoff;
 876	unsigned int		oldext;
 877	unsigned int		newext;
 878	unsigned int		flags = 0;
 879	int			i;
 880	int			state = 0;
 881	int			error;
 882
 883	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
 884	ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
 885			(flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
 886	oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
 887	new_endoff = offset + len;
 888	trace_xfs_rmap_convert(mp, cur->bc_private.a.agno, bno, len,
 889			unwritten, oinfo);
 890
 891	/*
 892	 * For the initial lookup, look for an exact match or the left-adjacent
 893	 * record for our insertion point. This will also give us the record for
 894	 * start block contiguity tests.
 895	 */
 896	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
 897	if (error)
 898		goto done;
 899	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
 900
 901	error = xfs_rmap_get_rec(cur, &PREV, &i);
 902	if (error)
 903		goto done;
 904	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 905	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
 906			cur->bc_private.a.agno, PREV.rm_startblock,
 907			PREV.rm_blockcount, PREV.rm_owner,
 908			PREV.rm_offset, PREV.rm_flags);
 909
 910	ASSERT(PREV.rm_offset <= offset);
 911	ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
 912	ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
 913	newext = ~oldext & XFS_RMAP_UNWRITTEN;
 914
 915	/*
 916	 * Set flags determining what part of the previous oldext allocation
 917	 * extent is being replaced by a newext allocation.
 918	 */
 919	if (PREV.rm_offset == offset)
 920		state |= RMAP_LEFT_FILLING;
 921	if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
 922		state |= RMAP_RIGHT_FILLING;
 923
 924	/*
 925	 * Decrement the cursor to see if we have a left-adjacent record to our
 926	 * insertion point. This will give us the record for end block
 927	 * contiguity tests.
 928	 */
 929	error = xfs_btree_decrement(cur, 0, &i);
 930	if (error)
 931		goto done;
 932	if (i) {
 933		state |= RMAP_LEFT_VALID;
 934		error = xfs_rmap_get_rec(cur, &LEFT, &i);
 935		if (error)
 936			goto done;
 937		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 938		XFS_WANT_CORRUPTED_GOTO(mp,
 939				LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
 940				done);
 
 
 
 
 
 
 941		trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
 942				cur->bc_private.a.agno, LEFT.rm_startblock,
 943				LEFT.rm_blockcount, LEFT.rm_owner,
 944				LEFT.rm_offset, LEFT.rm_flags);
 945		if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
 946		    LEFT.rm_offset + LEFT.rm_blockcount == offset &&
 947		    xfs_rmap_is_mergeable(&LEFT, owner, newext))
 948			state |= RMAP_LEFT_CONTIG;
 949	}
 950
 951	/*
 952	 * Increment the cursor to see if we have a right-adjacent record to our
 953	 * insertion point. This will give us the record for end block
 954	 * contiguity tests.
 955	 */
 956	error = xfs_btree_increment(cur, 0, &i);
 957	if (error)
 958		goto done;
 959	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
 960	error = xfs_btree_increment(cur, 0, &i);
 961	if (error)
 962		goto done;
 963	if (i) {
 964		state |= RMAP_RIGHT_VALID;
 965		error = xfs_rmap_get_rec(cur, &RIGHT, &i);
 966		if (error)
 967			goto done;
 968		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 969		XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
 970					done);
 
 
 
 
 
 971		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
 972				cur->bc_private.a.agno, RIGHT.rm_startblock,
 973				RIGHT.rm_blockcount, RIGHT.rm_owner,
 974				RIGHT.rm_offset, RIGHT.rm_flags);
 975		if (bno + len == RIGHT.rm_startblock &&
 976		    offset + len == RIGHT.rm_offset &&
 977		    xfs_rmap_is_mergeable(&RIGHT, owner, newext))
 978			state |= RMAP_RIGHT_CONTIG;
 979	}
 980
 981	/* check that left + prev + right is not too long */
 982	if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
 983			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
 984	    (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
 985	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
 986	    (unsigned long)LEFT.rm_blockcount + len +
 987	     RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
 988		state &= ~RMAP_RIGHT_CONTIG;
 989
 990	trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
 991			_RET_IP_);
 992
 993	/* reset the cursor back to PREV */
 994	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
 995	if (error)
 996		goto done;
 997	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
 998
 999	/*
1000	 * Switch out based on the FILLING and CONTIG state bits.
1001	 */
1002	switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1003			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1004	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1005	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1006		/*
1007		 * Setting all of a previous oldext extent to newext.
1008		 * The left and right neighbors are both contiguous with new.
1009		 */
1010		error = xfs_btree_increment(cur, 0, &i);
1011		if (error)
1012			goto done;
1013		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1014		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
 
 
 
1015				RIGHT.rm_startblock, RIGHT.rm_blockcount,
1016				RIGHT.rm_owner, RIGHT.rm_offset,
1017				RIGHT.rm_flags);
1018		error = xfs_btree_delete(cur, &i);
1019		if (error)
1020			goto done;
1021		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1022		error = xfs_btree_decrement(cur, 0, &i);
1023		if (error)
1024			goto done;
1025		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1026		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
 
 
 
1027				PREV.rm_startblock, PREV.rm_blockcount,
1028				PREV.rm_owner, PREV.rm_offset,
1029				PREV.rm_flags);
1030		error = xfs_btree_delete(cur, &i);
1031		if (error)
1032			goto done;
1033		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1034		error = xfs_btree_decrement(cur, 0, &i);
1035		if (error)
1036			goto done;
1037		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1038		NEW = LEFT;
1039		NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1040		error = xfs_rmap_update(cur, &NEW);
1041		if (error)
1042			goto done;
1043		break;
1044
1045	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1046		/*
1047		 * Setting all of a previous oldext extent to newext.
1048		 * The left neighbor is contiguous, the right is not.
1049		 */
1050		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1051				PREV.rm_startblock, PREV.rm_blockcount,
1052				PREV.rm_owner, PREV.rm_offset,
1053				PREV.rm_flags);
1054		error = xfs_btree_delete(cur, &i);
1055		if (error)
1056			goto done;
1057		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1058		error = xfs_btree_decrement(cur, 0, &i);
1059		if (error)
1060			goto done;
1061		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1062		NEW = LEFT;
1063		NEW.rm_blockcount += PREV.rm_blockcount;
1064		error = xfs_rmap_update(cur, &NEW);
1065		if (error)
1066			goto done;
1067		break;
1068
1069	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1070		/*
1071		 * Setting all of a previous oldext extent to newext.
1072		 * The right neighbor is contiguous, the left is not.
1073		 */
1074		error = xfs_btree_increment(cur, 0, &i);
1075		if (error)
1076			goto done;
1077		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1078		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
 
 
 
1079				RIGHT.rm_startblock, RIGHT.rm_blockcount,
1080				RIGHT.rm_owner, RIGHT.rm_offset,
1081				RIGHT.rm_flags);
1082		error = xfs_btree_delete(cur, &i);
1083		if (error)
1084			goto done;
1085		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1086		error = xfs_btree_decrement(cur, 0, &i);
1087		if (error)
1088			goto done;
1089		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1090		NEW = PREV;
1091		NEW.rm_blockcount = len + RIGHT.rm_blockcount;
1092		NEW.rm_flags = newext;
1093		error = xfs_rmap_update(cur, &NEW);
1094		if (error)
1095			goto done;
1096		break;
1097
1098	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1099		/*
1100		 * Setting all of a previous oldext extent to newext.
1101		 * Neither the left nor right neighbors are contiguous with
1102		 * the new one.
1103		 */
1104		NEW = PREV;
1105		NEW.rm_flags = newext;
1106		error = xfs_rmap_update(cur, &NEW);
1107		if (error)
1108			goto done;
1109		break;
1110
1111	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1112		/*
1113		 * Setting the first part of a previous oldext extent to newext.
1114		 * The left neighbor is contiguous.
1115		 */
1116		NEW = PREV;
1117		NEW.rm_offset += len;
1118		NEW.rm_startblock += len;
1119		NEW.rm_blockcount -= len;
1120		error = xfs_rmap_update(cur, &NEW);
1121		if (error)
1122			goto done;
1123		error = xfs_btree_decrement(cur, 0, &i);
1124		if (error)
1125			goto done;
1126		NEW = LEFT;
1127		NEW.rm_blockcount += len;
1128		error = xfs_rmap_update(cur, &NEW);
1129		if (error)
1130			goto done;
1131		break;
1132
1133	case RMAP_LEFT_FILLING:
1134		/*
1135		 * Setting the first part of a previous oldext extent to newext.
1136		 * The left neighbor is not contiguous.
1137		 */
1138		NEW = PREV;
1139		NEW.rm_startblock += len;
1140		NEW.rm_offset += len;
1141		NEW.rm_blockcount -= len;
1142		error = xfs_rmap_update(cur, &NEW);
1143		if (error)
1144			goto done;
1145		NEW.rm_startblock = bno;
1146		NEW.rm_owner = owner;
1147		NEW.rm_offset = offset;
1148		NEW.rm_blockcount = len;
1149		NEW.rm_flags = newext;
1150		cur->bc_rec.r = NEW;
1151		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
1152				len, owner, offset, newext);
1153		error = xfs_btree_insert(cur, &i);
1154		if (error)
1155			goto done;
1156		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1157		break;
1158
1159	case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1160		/*
1161		 * Setting the last part of a previous oldext extent to newext.
1162		 * The right neighbor is contiguous with the new allocation.
1163		 */
1164		NEW = PREV;
1165		NEW.rm_blockcount -= len;
1166		error = xfs_rmap_update(cur, &NEW);
1167		if (error)
1168			goto done;
1169		error = xfs_btree_increment(cur, 0, &i);
1170		if (error)
1171			goto done;
1172		NEW = RIGHT;
1173		NEW.rm_offset = offset;
1174		NEW.rm_startblock = bno;
1175		NEW.rm_blockcount += len;
1176		error = xfs_rmap_update(cur, &NEW);
1177		if (error)
1178			goto done;
1179		break;
1180
1181	case RMAP_RIGHT_FILLING:
1182		/*
1183		 * Setting the last part of a previous oldext extent to newext.
1184		 * The right neighbor is not contiguous.
1185		 */
1186		NEW = PREV;
1187		NEW.rm_blockcount -= len;
1188		error = xfs_rmap_update(cur, &NEW);
1189		if (error)
1190			goto done;
1191		error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1192				oldext, &i);
1193		if (error)
1194			goto done;
1195		XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
 
 
 
1196		NEW.rm_startblock = bno;
1197		NEW.rm_owner = owner;
1198		NEW.rm_offset = offset;
1199		NEW.rm_blockcount = len;
1200		NEW.rm_flags = newext;
1201		cur->bc_rec.r = NEW;
1202		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
1203				len, owner, offset, newext);
1204		error = xfs_btree_insert(cur, &i);
1205		if (error)
1206			goto done;
1207		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1208		break;
1209
1210	case 0:
1211		/*
1212		 * Setting the middle part of a previous oldext extent to
1213		 * newext.  Contiguity is impossible here.
1214		 * One extent becomes three extents.
1215		 */
1216		/* new right extent - oldext */
1217		NEW.rm_startblock = bno + len;
1218		NEW.rm_owner = owner;
1219		NEW.rm_offset = new_endoff;
1220		NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1221				new_endoff;
1222		NEW.rm_flags = PREV.rm_flags;
1223		error = xfs_rmap_update(cur, &NEW);
1224		if (error)
1225			goto done;
1226		/* new left extent - oldext */
1227		NEW = PREV;
1228		NEW.rm_blockcount = offset - PREV.rm_offset;
1229		cur->bc_rec.r = NEW;
1230		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
1231				NEW.rm_startblock, NEW.rm_blockcount,
1232				NEW.rm_owner, NEW.rm_offset,
1233				NEW.rm_flags);
1234		error = xfs_btree_insert(cur, &i);
1235		if (error)
1236			goto done;
1237		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1238		/*
1239		 * Reset the cursor to the position of the new extent
1240		 * we are about to insert as we can't trust it after
1241		 * the previous insert.
1242		 */
1243		error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1244				oldext, &i);
1245		if (error)
1246			goto done;
1247		XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
 
 
 
1248		/* new middle extent - newext */
1249		cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
1250		cur->bc_rec.r.rm_flags |= newext;
1251		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
1252				owner, offset, newext);
1253		error = xfs_btree_insert(cur, &i);
1254		if (error)
1255			goto done;
1256		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1257		break;
1258
1259	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1260	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1261	case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1262	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1263	case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1264	case RMAP_LEFT_CONTIG:
1265	case RMAP_RIGHT_CONTIG:
1266		/*
1267		 * These cases are all impossible.
1268		 */
1269		ASSERT(0);
1270	}
1271
1272	trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1273			unwritten, oinfo);
1274done:
1275	if (error)
1276		trace_xfs_rmap_convert_error(cur->bc_mp,
1277				cur->bc_private.a.agno, error, _RET_IP_);
1278	return error;
1279}
1280
1281/*
1282 * Convert an unwritten extent to a real extent or vice versa.  If there is no
1283 * possibility of overlapping extents, delegate to the simpler convert
1284 * function.
1285 */
1286STATIC int
1287xfs_rmap_convert_shared(
1288	struct xfs_btree_cur	*cur,
1289	xfs_agblock_t		bno,
1290	xfs_extlen_t		len,
1291	bool			unwritten,
1292	struct xfs_owner_info	*oinfo)
1293{
1294	struct xfs_mount	*mp = cur->bc_mp;
1295	struct xfs_rmap_irec	r[4];	/* neighbor extent entries */
1296					/* left is 0, right is 1, prev is 2 */
1297					/* new is 3 */
1298	uint64_t		owner;
1299	uint64_t		offset;
1300	uint64_t		new_endoff;
1301	unsigned int		oldext;
1302	unsigned int		newext;
1303	unsigned int		flags = 0;
1304	int			i;
1305	int			state = 0;
1306	int			error;
1307
1308	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1309	ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1310			(flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1311	oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1312	new_endoff = offset + len;
1313	trace_xfs_rmap_convert(mp, cur->bc_private.a.agno, bno, len,
1314			unwritten, oinfo);
1315
1316	/*
1317	 * For the initial lookup, look for and exact match or the left-adjacent
1318	 * record for our insertion point. This will also give us the record for
1319	 * start block contiguity tests.
1320	 */
1321	error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1322			&PREV, &i);
1323	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
 
 
1324
1325	ASSERT(PREV.rm_offset <= offset);
1326	ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1327	ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1328	newext = ~oldext & XFS_RMAP_UNWRITTEN;
1329
1330	/*
1331	 * Set flags determining what part of the previous oldext allocation
1332	 * extent is being replaced by a newext allocation.
1333	 */
1334	if (PREV.rm_offset == offset)
1335		state |= RMAP_LEFT_FILLING;
1336	if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1337		state |= RMAP_RIGHT_FILLING;
1338
1339	/* Is there a left record that abuts our range? */
1340	error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
1341			&LEFT, &i);
1342	if (error)
1343		goto done;
1344	if (i) {
1345		state |= RMAP_LEFT_VALID;
1346		XFS_WANT_CORRUPTED_GOTO(mp,
1347				LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
1348				done);
 
 
 
1349		if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
1350			state |= RMAP_LEFT_CONTIG;
1351	}
1352
1353	/* Is there a right record that abuts our range? */
1354	error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1355			newext, &i);
1356	if (error)
1357		goto done;
1358	if (i) {
1359		state |= RMAP_RIGHT_VALID;
1360		error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1361		if (error)
1362			goto done;
1363		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1364		XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
1365				done);
 
 
 
 
 
1366		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1367				cur->bc_private.a.agno, RIGHT.rm_startblock,
1368				RIGHT.rm_blockcount, RIGHT.rm_owner,
1369				RIGHT.rm_offset, RIGHT.rm_flags);
1370		if (xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1371			state |= RMAP_RIGHT_CONTIG;
1372	}
1373
1374	/* check that left + prev + right is not too long */
1375	if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1376			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1377	    (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1378	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1379	    (unsigned long)LEFT.rm_blockcount + len +
1380	     RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1381		state &= ~RMAP_RIGHT_CONTIG;
1382
1383	trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
1384			_RET_IP_);
1385	/*
1386	 * Switch out based on the FILLING and CONTIG state bits.
1387	 */
1388	switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1389			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1390	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1391	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1392		/*
1393		 * Setting all of a previous oldext extent to newext.
1394		 * The left and right neighbors are both contiguous with new.
1395		 */
1396		error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1397				RIGHT.rm_blockcount, RIGHT.rm_owner,
1398				RIGHT.rm_offset, RIGHT.rm_flags);
1399		if (error)
1400			goto done;
1401		error = xfs_rmap_delete(cur, PREV.rm_startblock,
1402				PREV.rm_blockcount, PREV.rm_owner,
1403				PREV.rm_offset, PREV.rm_flags);
1404		if (error)
1405			goto done;
1406		NEW = LEFT;
1407		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1408				NEW.rm_blockcount, NEW.rm_owner,
1409				NEW.rm_offset, NEW.rm_flags, &i);
1410		if (error)
1411			goto done;
1412		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1413		NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1414		error = xfs_rmap_update(cur, &NEW);
1415		if (error)
1416			goto done;
1417		break;
1418
1419	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1420		/*
1421		 * Setting all of a previous oldext extent to newext.
1422		 * The left neighbor is contiguous, the right is not.
1423		 */
1424		error = xfs_rmap_delete(cur, PREV.rm_startblock,
1425				PREV.rm_blockcount, PREV.rm_owner,
1426				PREV.rm_offset, PREV.rm_flags);
1427		if (error)
1428			goto done;
1429		NEW = LEFT;
1430		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1431				NEW.rm_blockcount, NEW.rm_owner,
1432				NEW.rm_offset, NEW.rm_flags, &i);
1433		if (error)
1434			goto done;
1435		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1436		NEW.rm_blockcount += PREV.rm_blockcount;
1437		error = xfs_rmap_update(cur, &NEW);
1438		if (error)
1439			goto done;
1440		break;
1441
1442	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1443		/*
1444		 * Setting all of a previous oldext extent to newext.
1445		 * The right neighbor is contiguous, the left is not.
1446		 */
1447		error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1448				RIGHT.rm_blockcount, RIGHT.rm_owner,
1449				RIGHT.rm_offset, RIGHT.rm_flags);
1450		if (error)
1451			goto done;
1452		NEW = PREV;
1453		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1454				NEW.rm_blockcount, NEW.rm_owner,
1455				NEW.rm_offset, NEW.rm_flags, &i);
1456		if (error)
1457			goto done;
1458		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1459		NEW.rm_blockcount += RIGHT.rm_blockcount;
1460		NEW.rm_flags = RIGHT.rm_flags;
1461		error = xfs_rmap_update(cur, &NEW);
1462		if (error)
1463			goto done;
1464		break;
1465
1466	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1467		/*
1468		 * Setting all of a previous oldext extent to newext.
1469		 * Neither the left nor right neighbors are contiguous with
1470		 * the new one.
1471		 */
1472		NEW = PREV;
1473		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1474				NEW.rm_blockcount, NEW.rm_owner,
1475				NEW.rm_offset, NEW.rm_flags, &i);
1476		if (error)
1477			goto done;
1478		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1479		NEW.rm_flags = newext;
1480		error = xfs_rmap_update(cur, &NEW);
1481		if (error)
1482			goto done;
1483		break;
1484
1485	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1486		/*
1487		 * Setting the first part of a previous oldext extent to newext.
1488		 * The left neighbor is contiguous.
1489		 */
1490		NEW = PREV;
1491		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1492				NEW.rm_blockcount, NEW.rm_owner,
1493				NEW.rm_offset, NEW.rm_flags);
1494		if (error)
1495			goto done;
1496		NEW.rm_offset += len;
1497		NEW.rm_startblock += len;
1498		NEW.rm_blockcount -= len;
1499		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1500				NEW.rm_blockcount, NEW.rm_owner,
1501				NEW.rm_offset, NEW.rm_flags);
1502		if (error)
1503			goto done;
1504		NEW = LEFT;
1505		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1506				NEW.rm_blockcount, NEW.rm_owner,
1507				NEW.rm_offset, NEW.rm_flags, &i);
1508		if (error)
1509			goto done;
1510		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1511		NEW.rm_blockcount += len;
1512		error = xfs_rmap_update(cur, &NEW);
1513		if (error)
1514			goto done;
1515		break;
1516
1517	case RMAP_LEFT_FILLING:
1518		/*
1519		 * Setting the first part of a previous oldext extent to newext.
1520		 * The left neighbor is not contiguous.
1521		 */
1522		NEW = PREV;
1523		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1524				NEW.rm_blockcount, NEW.rm_owner,
1525				NEW.rm_offset, NEW.rm_flags);
1526		if (error)
1527			goto done;
1528		NEW.rm_offset += len;
1529		NEW.rm_startblock += len;
1530		NEW.rm_blockcount -= len;
1531		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1532				NEW.rm_blockcount, NEW.rm_owner,
1533				NEW.rm_offset, NEW.rm_flags);
1534		if (error)
1535			goto done;
1536		error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1537		if (error)
1538			goto done;
1539		break;
1540
1541	case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1542		/*
1543		 * Setting the last part of a previous oldext extent to newext.
1544		 * The right neighbor is contiguous with the new allocation.
1545		 */
1546		NEW = PREV;
1547		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1548				NEW.rm_blockcount, NEW.rm_owner,
1549				NEW.rm_offset, NEW.rm_flags, &i);
1550		if (error)
1551			goto done;
1552		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1553		NEW.rm_blockcount = offset - NEW.rm_offset;
1554		error = xfs_rmap_update(cur, &NEW);
1555		if (error)
1556			goto done;
1557		NEW = RIGHT;
1558		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1559				NEW.rm_blockcount, NEW.rm_owner,
1560				NEW.rm_offset, NEW.rm_flags);
1561		if (error)
1562			goto done;
1563		NEW.rm_offset = offset;
1564		NEW.rm_startblock = bno;
1565		NEW.rm_blockcount += len;
1566		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1567				NEW.rm_blockcount, NEW.rm_owner,
1568				NEW.rm_offset, NEW.rm_flags);
1569		if (error)
1570			goto done;
1571		break;
1572
1573	case RMAP_RIGHT_FILLING:
1574		/*
1575		 * Setting the last part of a previous oldext extent to newext.
1576		 * The right neighbor is not contiguous.
1577		 */
1578		NEW = PREV;
1579		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1580				NEW.rm_blockcount, NEW.rm_owner,
1581				NEW.rm_offset, NEW.rm_flags, &i);
1582		if (error)
1583			goto done;
1584		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1585		NEW.rm_blockcount -= len;
1586		error = xfs_rmap_update(cur, &NEW);
1587		if (error)
1588			goto done;
1589		error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1590		if (error)
1591			goto done;
1592		break;
1593
1594	case 0:
1595		/*
1596		 * Setting the middle part of a previous oldext extent to
1597		 * newext.  Contiguity is impossible here.
1598		 * One extent becomes three extents.
1599		 */
1600		/* new right extent - oldext */
1601		NEW.rm_startblock = bno + len;
1602		NEW.rm_owner = owner;
1603		NEW.rm_offset = new_endoff;
1604		NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1605				new_endoff;
1606		NEW.rm_flags = PREV.rm_flags;
1607		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1608				NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1609				NEW.rm_flags);
1610		if (error)
1611			goto done;
1612		/* new left extent - oldext */
1613		NEW = PREV;
1614		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1615				NEW.rm_blockcount, NEW.rm_owner,
1616				NEW.rm_offset, NEW.rm_flags, &i);
1617		if (error)
1618			goto done;
1619		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
 
 
 
1620		NEW.rm_blockcount = offset - NEW.rm_offset;
1621		error = xfs_rmap_update(cur, &NEW);
1622		if (error)
1623			goto done;
1624		/* new middle extent - newext */
1625		NEW.rm_startblock = bno;
1626		NEW.rm_blockcount = len;
1627		NEW.rm_owner = owner;
1628		NEW.rm_offset = offset;
1629		NEW.rm_flags = newext;
1630		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1631				NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1632				NEW.rm_flags);
1633		if (error)
1634			goto done;
1635		break;
1636
1637	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1638	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1639	case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1640	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1641	case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1642	case RMAP_LEFT_CONTIG:
1643	case RMAP_RIGHT_CONTIG:
1644		/*
1645		 * These cases are all impossible.
1646		 */
1647		ASSERT(0);
1648	}
1649
1650	trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1651			unwritten, oinfo);
1652done:
1653	if (error)
1654		trace_xfs_rmap_convert_error(cur->bc_mp,
1655				cur->bc_private.a.agno, error, _RET_IP_);
1656	return error;
1657}
1658
1659#undef	NEW
1660#undef	LEFT
1661#undef	RIGHT
1662#undef	PREV
1663
1664/*
1665 * Find an extent in the rmap btree and unmap it.  For rmap extent types that
1666 * can overlap (data fork rmaps on reflink filesystems) we must be careful
1667 * that the prev/next records in the btree might belong to another owner.
1668 * Therefore we must use delete+insert to alter any of the key fields.
1669 *
1670 * For every other situation there can only be one owner for a given extent,
1671 * so we can call the regular _free function.
1672 */
1673STATIC int
1674xfs_rmap_unmap_shared(
1675	struct xfs_btree_cur	*cur,
1676	xfs_agblock_t		bno,
1677	xfs_extlen_t		len,
1678	bool			unwritten,
1679	struct xfs_owner_info	*oinfo)
1680{
1681	struct xfs_mount	*mp = cur->bc_mp;
1682	struct xfs_rmap_irec	ltrec;
1683	uint64_t		ltoff;
1684	int			error = 0;
1685	int			i;
1686	uint64_t		owner;
1687	uint64_t		offset;
1688	unsigned int		flags;
1689
1690	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1691	if (unwritten)
1692		flags |= XFS_RMAP_UNWRITTEN;
1693	trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
1694			unwritten, oinfo);
1695
1696	/*
1697	 * We should always have a left record because there's a static record
1698	 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
1699	 * will not ever be removed from the tree.
1700	 */
1701	error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1702			&ltrec, &i);
1703	if (error)
1704		goto out_error;
1705	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
1706	ltoff = ltrec.rm_offset;
1707
1708	/* Make sure the extent we found covers the entire freeing range. */
1709	XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
1710		ltrec.rm_startblock + ltrec.rm_blockcount >=
1711		bno + len, out_error);
 
 
 
 
1712
1713	/* Make sure the owner matches what we expect to find in the tree. */
1714	XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner, out_error);
 
 
 
1715
1716	/* Make sure the unwritten flag matches. */
1717	XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
1718			(ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
 
 
 
 
1719
1720	/* Check the offset. */
1721	XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_offset <= offset, out_error);
1722	XFS_WANT_CORRUPTED_GOTO(mp, offset <= ltoff + ltrec.rm_blockcount,
1723			out_error);
 
 
 
 
 
1724
1725	if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
1726		/* Exact match, simply remove the record from rmap tree. */
1727		error = xfs_rmap_delete(cur, ltrec.rm_startblock,
1728				ltrec.rm_blockcount, ltrec.rm_owner,
1729				ltrec.rm_offset, ltrec.rm_flags);
1730		if (error)
1731			goto out_error;
1732	} else if (ltrec.rm_startblock == bno) {
1733		/*
1734		 * Overlap left hand side of extent: move the start, trim the
1735		 * length and update the current record.
1736		 *
1737		 *       ltbno                ltlen
1738		 * Orig:    |oooooooooooooooooooo|
1739		 * Freeing: |fffffffff|
1740		 * Result:            |rrrrrrrrrr|
1741		 *         bno       len
1742		 */
1743
1744		/* Delete prev rmap. */
1745		error = xfs_rmap_delete(cur, ltrec.rm_startblock,
1746				ltrec.rm_blockcount, ltrec.rm_owner,
1747				ltrec.rm_offset, ltrec.rm_flags);
1748		if (error)
1749			goto out_error;
1750
1751		/* Add an rmap at the new offset. */
1752		ltrec.rm_startblock += len;
1753		ltrec.rm_blockcount -= len;
1754		ltrec.rm_offset += len;
1755		error = xfs_rmap_insert(cur, ltrec.rm_startblock,
1756				ltrec.rm_blockcount, ltrec.rm_owner,
1757				ltrec.rm_offset, ltrec.rm_flags);
1758		if (error)
1759			goto out_error;
1760	} else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
1761		/*
1762		 * Overlap right hand side of extent: trim the length and
1763		 * update the current record.
1764		 *
1765		 *       ltbno                ltlen
1766		 * Orig:    |oooooooooooooooooooo|
1767		 * Freeing:            |fffffffff|
1768		 * Result:  |rrrrrrrrrr|
1769		 *                    bno       len
1770		 */
1771		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1772				ltrec.rm_blockcount, ltrec.rm_owner,
1773				ltrec.rm_offset, ltrec.rm_flags, &i);
1774		if (error)
1775			goto out_error;
1776		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
1777		ltrec.rm_blockcount -= len;
1778		error = xfs_rmap_update(cur, &ltrec);
1779		if (error)
1780			goto out_error;
1781	} else {
1782		/*
1783		 * Overlap middle of extent: trim the length of the existing
1784		 * record to the length of the new left-extent size, increment
1785		 * the insertion position so we can insert a new record
1786		 * containing the remaining right-extent space.
1787		 *
1788		 *       ltbno                ltlen
1789		 * Orig:    |oooooooooooooooooooo|
1790		 * Freeing:       |fffffffff|
1791		 * Result:  |rrrrr|         |rrrr|
1792		 *               bno       len
1793		 */
1794		xfs_extlen_t	orig_len = ltrec.rm_blockcount;
1795
1796		/* Shrink the left side of the rmap */
1797		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1798				ltrec.rm_blockcount, ltrec.rm_owner,
1799				ltrec.rm_offset, ltrec.rm_flags, &i);
1800		if (error)
1801			goto out_error;
1802		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
1803		ltrec.rm_blockcount = bno - ltrec.rm_startblock;
1804		error = xfs_rmap_update(cur, &ltrec);
1805		if (error)
1806			goto out_error;
1807
1808		/* Add an rmap at the new offset */
1809		error = xfs_rmap_insert(cur, bno + len,
1810				orig_len - len - ltrec.rm_blockcount,
1811				ltrec.rm_owner, offset + len,
1812				ltrec.rm_flags);
1813		if (error)
1814			goto out_error;
1815	}
1816
1817	trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
1818			unwritten, oinfo);
1819out_error:
1820	if (error)
1821		trace_xfs_rmap_unmap_error(cur->bc_mp,
1822				cur->bc_private.a.agno, error, _RET_IP_);
1823	return error;
1824}
1825
1826/*
1827 * Find an extent in the rmap btree and map it.  For rmap extent types that
1828 * can overlap (data fork rmaps on reflink filesystems) we must be careful
1829 * that the prev/next records in the btree might belong to another owner.
1830 * Therefore we must use delete+insert to alter any of the key fields.
1831 *
1832 * For every other situation there can only be one owner for a given extent,
1833 * so we can call the regular _alloc function.
1834 */
1835STATIC int
1836xfs_rmap_map_shared(
1837	struct xfs_btree_cur	*cur,
1838	xfs_agblock_t		bno,
1839	xfs_extlen_t		len,
1840	bool			unwritten,
1841	struct xfs_owner_info	*oinfo)
1842{
1843	struct xfs_mount	*mp = cur->bc_mp;
1844	struct xfs_rmap_irec	ltrec;
1845	struct xfs_rmap_irec	gtrec;
1846	int			have_gt;
1847	int			have_lt;
1848	int			error = 0;
1849	int			i;
1850	uint64_t		owner;
1851	uint64_t		offset;
1852	unsigned int		flags = 0;
1853
1854	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1855	if (unwritten)
1856		flags |= XFS_RMAP_UNWRITTEN;
1857	trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
1858			unwritten, oinfo);
1859
1860	/* Is there a left record that abuts our range? */
1861	error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
1862			&ltrec, &have_lt);
1863	if (error)
1864		goto out_error;
1865	if (have_lt &&
1866	    !xfs_rmap_is_mergeable(&ltrec, owner, flags))
1867		have_lt = 0;
1868
1869	/* Is there a right record that abuts our range? */
1870	error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1871			flags, &have_gt);
1872	if (error)
1873		goto out_error;
1874	if (have_gt) {
1875		error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
1876		if (error)
1877			goto out_error;
1878		XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
 
 
 
1879		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1880			cur->bc_private.a.agno, gtrec.rm_startblock,
1881			gtrec.rm_blockcount, gtrec.rm_owner,
1882			gtrec.rm_offset, gtrec.rm_flags);
1883
1884		if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
1885			have_gt = 0;
1886	}
1887
1888	if (have_lt &&
1889	    ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
1890	    ltrec.rm_offset + ltrec.rm_blockcount == offset) {
1891		/*
1892		 * Left edge contiguous, merge into left record.
1893		 *
1894		 *       ltbno     ltlen
1895		 * orig:   |ooooooooo|
1896		 * adding:           |aaaaaaaaa|
1897		 * result: |rrrrrrrrrrrrrrrrrrr|
1898		 *                  bno       len
1899		 */
1900		ltrec.rm_blockcount += len;
1901		if (have_gt &&
1902		    bno + len == gtrec.rm_startblock &&
1903		    offset + len == gtrec.rm_offset) {
1904			/*
1905			 * Right edge also contiguous, delete right record
1906			 * and merge into left record.
1907			 *
1908			 *       ltbno     ltlen    gtbno     gtlen
1909			 * orig:   |ooooooooo|         |ooooooooo|
1910			 * adding:           |aaaaaaaaa|
1911			 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
1912			 */
1913			ltrec.rm_blockcount += gtrec.rm_blockcount;
1914			error = xfs_rmap_delete(cur, gtrec.rm_startblock,
1915					gtrec.rm_blockcount, gtrec.rm_owner,
1916					gtrec.rm_offset, gtrec.rm_flags);
1917			if (error)
1918				goto out_error;
1919		}
1920
1921		/* Point the cursor back to the left record and update. */
1922		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1923				ltrec.rm_blockcount, ltrec.rm_owner,
1924				ltrec.rm_offset, ltrec.rm_flags, &i);
1925		if (error)
1926			goto out_error;
1927		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
 
 
 
1928
1929		error = xfs_rmap_update(cur, &ltrec);
1930		if (error)
1931			goto out_error;
1932	} else if (have_gt &&
1933		   bno + len == gtrec.rm_startblock &&
1934		   offset + len == gtrec.rm_offset) {
1935		/*
1936		 * Right edge contiguous, merge into right record.
1937		 *
1938		 *                 gtbno     gtlen
1939		 * Orig:             |ooooooooo|
1940		 * adding: |aaaaaaaaa|
1941		 * Result: |rrrrrrrrrrrrrrrrrrr|
1942		 *        bno       len
1943		 */
1944		/* Delete the old record. */
1945		error = xfs_rmap_delete(cur, gtrec.rm_startblock,
1946				gtrec.rm_blockcount, gtrec.rm_owner,
1947				gtrec.rm_offset, gtrec.rm_flags);
1948		if (error)
1949			goto out_error;
1950
1951		/* Move the start and re-add it. */
1952		gtrec.rm_startblock = bno;
1953		gtrec.rm_blockcount += len;
1954		gtrec.rm_offset = offset;
1955		error = xfs_rmap_insert(cur, gtrec.rm_startblock,
1956				gtrec.rm_blockcount, gtrec.rm_owner,
1957				gtrec.rm_offset, gtrec.rm_flags);
1958		if (error)
1959			goto out_error;
1960	} else {
1961		/*
1962		 * No contiguous edge with identical owner, insert
1963		 * new record at current cursor position.
1964		 */
1965		error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
1966		if (error)
1967			goto out_error;
1968	}
1969
1970	trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
1971			unwritten, oinfo);
1972out_error:
1973	if (error)
1974		trace_xfs_rmap_map_error(cur->bc_mp,
1975				cur->bc_private.a.agno, error, _RET_IP_);
1976	return error;
1977}
1978
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1979struct xfs_rmap_query_range_info {
1980	xfs_rmap_query_range_fn	fn;
1981	void				*priv;
1982};
1983
1984/* Format btree record and pass to our callback. */
1985STATIC int
1986xfs_rmap_query_range_helper(
1987	struct xfs_btree_cur	*cur,
1988	union xfs_btree_rec	*rec,
1989	void			*priv)
1990{
1991	struct xfs_rmap_query_range_info	*query = priv;
1992	struct xfs_rmap_irec			irec;
1993	int					error;
 
 
 
 
 
 
1994
1995	error = xfs_rmap_btrec_to_irec(rec, &irec);
1996	if (error)
1997		return error;
1998	return query->fn(cur, &irec, query->priv);
1999}
2000
2001/* Find all rmaps between two keys. */
2002int
2003xfs_rmap_query_range(
2004	struct xfs_btree_cur		*cur,
2005	struct xfs_rmap_irec		*low_rec,
2006	struct xfs_rmap_irec		*high_rec,
2007	xfs_rmap_query_range_fn	fn,
2008	void				*priv)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2009{
2010	union xfs_btree_irec		low_brec;
2011	union xfs_btree_irec		high_brec;
2012	struct xfs_rmap_query_range_info	query;
2013
2014	low_brec.r = *low_rec;
2015	high_brec.r = *high_rec;
2016	query.priv = priv;
2017	query.fn = fn;
2018	return xfs_btree_query_range(cur, &low_brec, &high_brec,
2019			xfs_rmap_query_range_helper, &query);
2020}
2021
2022/* Clean up after calling xfs_rmap_finish_one. */
2023void
2024xfs_rmap_finish_one_cleanup(
2025	struct xfs_trans	*tp,
2026	struct xfs_btree_cur	*rcur,
2027	int			error)
2028{
2029	struct xfs_buf		*agbp;
2030
2031	if (rcur == NULL)
2032		return;
2033	agbp = rcur->bc_private.a.agbp;
2034	xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
2035	if (error)
2036		xfs_trans_brelse(tp, agbp);
2037}
2038
2039/*
2040 * Process one of the deferred rmap operations.  We pass back the
2041 * btree cursor to maintain our lock on the rmapbt between calls.
2042 * This saves time and eliminates a buffer deadlock between the
2043 * superblock and the AGF because we'll always grab them in the same
2044 * order.
2045 */
2046int
2047xfs_rmap_finish_one(
2048	struct xfs_trans		*tp,
2049	enum xfs_rmap_intent_type	type,
2050	__uint64_t			owner,
2051	int				whichfork,
2052	xfs_fileoff_t			startoff,
2053	xfs_fsblock_t			startblock,
2054	xfs_filblks_t			blockcount,
2055	xfs_exntst_t			state,
2056	struct xfs_btree_cur		**pcur)
2057{
2058	struct xfs_mount		*mp = tp->t_mountp;
2059	struct xfs_btree_cur		*rcur;
2060	struct xfs_buf			*agbp = NULL;
2061	int				error = 0;
2062	xfs_agnumber_t			agno;
2063	struct xfs_owner_info		oinfo;
2064	xfs_agblock_t			bno;
2065	bool				unwritten;
2066
2067	agno = XFS_FSB_TO_AGNO(mp, startblock);
2068	ASSERT(agno != NULLAGNUMBER);
2069	bno = XFS_FSB_TO_AGBNO(mp, startblock);
2070
2071	trace_xfs_rmap_deferred(mp, agno, type, bno, owner, whichfork,
2072			startoff, blockcount, state);
2073
2074	if (XFS_TEST_ERROR(false, mp,
2075			XFS_ERRTAG_RMAP_FINISH_ONE,
2076			XFS_RANDOM_RMAP_FINISH_ONE))
2077		return -EIO;
2078
2079	/*
2080	 * If we haven't gotten a cursor or the cursor AG doesn't match
2081	 * the startblock, get one now.
2082	 */
2083	rcur = *pcur;
2084	if (rcur != NULL && rcur->bc_private.a.agno != agno) {
2085		xfs_rmap_finish_one_cleanup(tp, rcur, 0);
2086		rcur = NULL;
2087		*pcur = NULL;
2088	}
2089	if (rcur == NULL) {
2090		/*
2091		 * Refresh the freelist before we start changing the
2092		 * rmapbt, because a shape change could cause us to
2093		 * allocate blocks.
2094		 */
2095		error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
2096		if (error)
2097			return error;
2098		if (!agbp)
2099			return -EFSCORRUPTED;
2100
2101		rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
2102		if (!rcur) {
2103			error = -ENOMEM;
2104			goto out_cur;
2105		}
2106	}
2107	*pcur = rcur;
2108
2109	xfs_rmap_ino_owner(&oinfo, owner, whichfork, startoff);
2110	unwritten = state == XFS_EXT_UNWRITTEN;
2111	bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, startblock);
 
2112
2113	switch (type) {
2114	case XFS_RMAP_ALLOC:
2115	case XFS_RMAP_MAP:
2116		error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo);
 
2117		break;
2118	case XFS_RMAP_MAP_SHARED:
2119		error = xfs_rmap_map_shared(rcur, bno, blockcount, unwritten,
2120				&oinfo);
2121		break;
2122	case XFS_RMAP_FREE:
2123	case XFS_RMAP_UNMAP:
2124		error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten,
2125				&oinfo);
2126		break;
2127	case XFS_RMAP_UNMAP_SHARED:
2128		error = xfs_rmap_unmap_shared(rcur, bno, blockcount, unwritten,
2129				&oinfo);
2130		break;
2131	case XFS_RMAP_CONVERT:
2132		error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten,
2133				&oinfo);
2134		break;
2135	case XFS_RMAP_CONVERT_SHARED:
2136		error = xfs_rmap_convert_shared(rcur, bno, blockcount,
2137				!unwritten, &oinfo);
2138		break;
2139	default:
2140		ASSERT(0);
2141		error = -EFSCORRUPTED;
2142	}
2143	return error;
2144
2145out_cur:
2146	xfs_trans_brelse(tp, agbp);
2147
2148	return error;
2149}
2150
2151/*
2152 * Don't defer an rmap if we aren't an rmap filesystem.
2153 */
2154static bool
2155xfs_rmap_update_is_needed(
2156	struct xfs_mount	*mp,
2157	int			whichfork)
2158{
2159	return xfs_sb_version_hasrmapbt(&mp->m_sb) && whichfork != XFS_COW_FORK;
2160}
2161
2162/*
2163 * Record a rmap intent; the list is kept sorted first by AG and then by
2164 * increasing age.
2165 */
2166static int
2167__xfs_rmap_add(
2168	struct xfs_mount		*mp,
2169	struct xfs_defer_ops		*dfops,
2170	enum xfs_rmap_intent_type	type,
2171	__uint64_t			owner,
2172	int				whichfork,
2173	struct xfs_bmbt_irec		*bmap)
2174{
2175	struct xfs_rmap_intent	*ri;
2176
2177	trace_xfs_rmap_defer(mp, XFS_FSB_TO_AGNO(mp, bmap->br_startblock),
 
2178			type,
2179			XFS_FSB_TO_AGBNO(mp, bmap->br_startblock),
2180			owner, whichfork,
2181			bmap->br_startoff,
2182			bmap->br_blockcount,
2183			bmap->br_state);
2184
2185	ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_SLEEP | KM_NOFS);
2186	INIT_LIST_HEAD(&ri->ri_list);
2187	ri->ri_type = type;
2188	ri->ri_owner = owner;
2189	ri->ri_whichfork = whichfork;
2190	ri->ri_bmap = *bmap;
2191
2192	xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
2193	return 0;
2194}
2195
2196/* Map an extent into a file. */
2197int
2198xfs_rmap_map_extent(
2199	struct xfs_mount	*mp,
2200	struct xfs_defer_ops	*dfops,
2201	struct xfs_inode	*ip,
2202	int			whichfork,
2203	struct xfs_bmbt_irec	*PREV)
2204{
2205	if (!xfs_rmap_update_is_needed(mp, whichfork))
2206		return 0;
 
 
 
 
 
2207
2208	return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2209			XFS_RMAP_MAP_SHARED : XFS_RMAP_MAP, ip->i_ino,
2210			whichfork, PREV);
2211}
2212
2213/* Unmap an extent out of a file. */
2214int
2215xfs_rmap_unmap_extent(
2216	struct xfs_mount	*mp,
2217	struct xfs_defer_ops	*dfops,
2218	struct xfs_inode	*ip,
2219	int			whichfork,
2220	struct xfs_bmbt_irec	*PREV)
2221{
2222	if (!xfs_rmap_update_is_needed(mp, whichfork))
2223		return 0;
 
 
 
 
 
2224
2225	return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2226			XFS_RMAP_UNMAP_SHARED : XFS_RMAP_UNMAP, ip->i_ino,
2227			whichfork, PREV);
2228}
2229
2230/* Convert a data fork extent from unwritten to real or vice versa. */
2231int
 
 
 
 
 
2232xfs_rmap_convert_extent(
2233	struct xfs_mount	*mp,
2234	struct xfs_defer_ops	*dfops,
2235	struct xfs_inode	*ip,
2236	int			whichfork,
2237	struct xfs_bmbt_irec	*PREV)
2238{
 
 
2239	if (!xfs_rmap_update_is_needed(mp, whichfork))
2240		return 0;
 
 
 
2241
2242	return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2243			XFS_RMAP_CONVERT_SHARED : XFS_RMAP_CONVERT, ip->i_ino,
2244			whichfork, PREV);
2245}
2246
2247/* Schedule the creation of an rmap for non-file data. */
2248int
2249xfs_rmap_alloc_extent(
2250	struct xfs_mount	*mp,
2251	struct xfs_defer_ops	*dfops,
2252	xfs_agnumber_t		agno,
2253	xfs_agblock_t		bno,
2254	xfs_extlen_t		len,
2255	__uint64_t		owner)
2256{
2257	struct xfs_bmbt_irec	bmap;
2258
2259	if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
2260		return 0;
2261
2262	bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
2263	bmap.br_blockcount = len;
2264	bmap.br_startoff = 0;
2265	bmap.br_state = XFS_EXT_NORM;
2266
2267	return __xfs_rmap_add(mp, dfops, XFS_RMAP_ALLOC, owner,
2268			XFS_DATA_FORK, &bmap);
2269}
2270
2271/* Schedule the deletion of an rmap for non-file data. */
2272int
2273xfs_rmap_free_extent(
2274	struct xfs_mount	*mp,
2275	struct xfs_defer_ops	*dfops,
2276	xfs_agnumber_t		agno,
2277	xfs_agblock_t		bno,
2278	xfs_extlen_t		len,
2279	__uint64_t		owner)
2280{
2281	struct xfs_bmbt_irec	bmap;
2282
2283	if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
2284		return 0;
2285
2286	bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
2287	bmap.br_blockcount = len;
2288	bmap.br_startoff = 0;
2289	bmap.br_state = XFS_EXT_NORM;
2290
2291	return __xfs_rmap_add(mp, dfops, XFS_RMAP_FREE, owner,
2292			XFS_DATA_FORK, &bmap);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2293}