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