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