Linux Audio

Check our new training course

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