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