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