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