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