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