Linux Audio

Check our new training course

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