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