cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfs_rmap.c (74989B)


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