Linux Audio

Check our new training course

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