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