xref: /openbmc/linux/fs/xfs/libxfs/xfs_rmap.c (revision 65417d9f)
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  * Find the extent in the rmap btree and remove it.
372  *
373  * The record we find should always be an exact match for the extent that we're
374  * looking for, since we insert them into the btree without modification.
375  *
376  * Special Case #1: when growing the filesystem, we "free" an extent when
377  * growing the last AG. This extent is new space and so it is not tracked as
378  * used space in the btree. The growfs code will pass in an owner of
379  * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
380  * extent. We verify that - the extent lookup result in a record that does not
381  * overlap.
382  *
383  * Special Case #2: EFIs do not record the owner of the extent, so when
384  * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
385  * btree to ignore the owner (i.e. wildcard match) so we don't trigger
386  * corruption checks during log recovery.
387  */
388 STATIC int
389 xfs_rmap_unmap(
390 	struct xfs_btree_cur	*cur,
391 	xfs_agblock_t		bno,
392 	xfs_extlen_t		len,
393 	bool			unwritten,
394 	struct xfs_owner_info	*oinfo)
395 {
396 	struct xfs_mount	*mp = cur->bc_mp;
397 	struct xfs_rmap_irec	ltrec;
398 	uint64_t		ltoff;
399 	int			error = 0;
400 	int			i;
401 	uint64_t		owner;
402 	uint64_t		offset;
403 	unsigned int		flags;
404 	bool			ignore_off;
405 
406 	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
407 	ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
408 			(flags & XFS_RMAP_BMBT_BLOCK);
409 	if (unwritten)
410 		flags |= XFS_RMAP_UNWRITTEN;
411 	trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
412 			unwritten, oinfo);
413 
414 	/*
415 	 * We should always have a left record because there's a static record
416 	 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
417 	 * will not ever be removed from the tree.
418 	 */
419 	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, &i);
420 	if (error)
421 		goto out_error;
422 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
423 
424 	error = xfs_rmap_get_rec(cur, &ltrec, &i);
425 	if (error)
426 		goto out_error;
427 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
428 	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
429 			cur->bc_private.a.agno, ltrec.rm_startblock,
430 			ltrec.rm_blockcount, ltrec.rm_owner,
431 			ltrec.rm_offset, ltrec.rm_flags);
432 	ltoff = ltrec.rm_offset;
433 
434 	/*
435 	 * For growfs, the incoming extent must be beyond the left record we
436 	 * just found as it is new space and won't be used by anyone. This is
437 	 * just a corruption check as we don't actually do anything with this
438 	 * extent.  Note that we need to use >= instead of > because it might
439 	 * be the case that the "left" extent goes all the way to EOFS.
440 	 */
441 	if (owner == XFS_RMAP_OWN_NULL) {
442 		XFS_WANT_CORRUPTED_GOTO(mp, bno >= ltrec.rm_startblock +
443 						ltrec.rm_blockcount, out_error);
444 		goto out_done;
445 	}
446 
447 	/* Make sure the unwritten flag matches. */
448 	XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
449 			(ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
450 
451 	/* Make sure the extent we found covers the entire freeing range. */
452 	XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
453 		ltrec.rm_startblock + ltrec.rm_blockcount >=
454 		bno + len, out_error);
455 
456 	/* Make sure the owner matches what we expect to find in the tree. */
457 	XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner ||
458 				    XFS_RMAP_NON_INODE_OWNER(owner), out_error);
459 
460 	/* Check the offset, if necessary. */
461 	if (!XFS_RMAP_NON_INODE_OWNER(owner)) {
462 		if (flags & XFS_RMAP_BMBT_BLOCK) {
463 			XFS_WANT_CORRUPTED_GOTO(mp,
464 					ltrec.rm_flags & XFS_RMAP_BMBT_BLOCK,
465 					out_error);
466 		} else {
467 			XFS_WANT_CORRUPTED_GOTO(mp,
468 					ltrec.rm_offset <= offset, out_error);
469 			XFS_WANT_CORRUPTED_GOTO(mp,
470 					ltoff + ltrec.rm_blockcount >= offset + len,
471 					out_error);
472 		}
473 	}
474 
475 	if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
476 		/* exact match, simply remove the record from rmap tree */
477 		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
478 				ltrec.rm_startblock, ltrec.rm_blockcount,
479 				ltrec.rm_owner, ltrec.rm_offset,
480 				ltrec.rm_flags);
481 		error = xfs_btree_delete(cur, &i);
482 		if (error)
483 			goto out_error;
484 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
485 	} else if (ltrec.rm_startblock == bno) {
486 		/*
487 		 * overlap left hand side of extent: move the start, trim the
488 		 * length and update the current record.
489 		 *
490 		 *       ltbno                ltlen
491 		 * Orig:    |oooooooooooooooooooo|
492 		 * Freeing: |fffffffff|
493 		 * Result:            |rrrrrrrrrr|
494 		 *         bno       len
495 		 */
496 		ltrec.rm_startblock += len;
497 		ltrec.rm_blockcount -= len;
498 		if (!ignore_off)
499 			ltrec.rm_offset += len;
500 		error = xfs_rmap_update(cur, &ltrec);
501 		if (error)
502 			goto out_error;
503 	} else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
504 		/*
505 		 * overlap right hand side of extent: trim the length and update
506 		 * the current record.
507 		 *
508 		 *       ltbno                ltlen
509 		 * Orig:    |oooooooooooooooooooo|
510 		 * Freeing:            |fffffffff|
511 		 * Result:  |rrrrrrrrrr|
512 		 *                    bno       len
513 		 */
514 		ltrec.rm_blockcount -= len;
515 		error = xfs_rmap_update(cur, &ltrec);
516 		if (error)
517 			goto out_error;
518 	} else {
519 
520 		/*
521 		 * overlap middle of extent: trim the length of the existing
522 		 * record to the length of the new left-extent size, increment
523 		 * the insertion position so we can insert a new record
524 		 * containing the remaining right-extent space.
525 		 *
526 		 *       ltbno                ltlen
527 		 * Orig:    |oooooooooooooooooooo|
528 		 * Freeing:       |fffffffff|
529 		 * Result:  |rrrrr|         |rrrr|
530 		 *               bno       len
531 		 */
532 		xfs_extlen_t	orig_len = ltrec.rm_blockcount;
533 
534 		ltrec.rm_blockcount = bno - ltrec.rm_startblock;
535 		error = xfs_rmap_update(cur, &ltrec);
536 		if (error)
537 			goto out_error;
538 
539 		error = xfs_btree_increment(cur, 0, &i);
540 		if (error)
541 			goto out_error;
542 
543 		cur->bc_rec.r.rm_startblock = bno + len;
544 		cur->bc_rec.r.rm_blockcount = orig_len - len -
545 						     ltrec.rm_blockcount;
546 		cur->bc_rec.r.rm_owner = ltrec.rm_owner;
547 		if (ignore_off)
548 			cur->bc_rec.r.rm_offset = 0;
549 		else
550 			cur->bc_rec.r.rm_offset = offset + len;
551 		cur->bc_rec.r.rm_flags = flags;
552 		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
553 				cur->bc_rec.r.rm_startblock,
554 				cur->bc_rec.r.rm_blockcount,
555 				cur->bc_rec.r.rm_owner,
556 				cur->bc_rec.r.rm_offset,
557 				cur->bc_rec.r.rm_flags);
558 		error = xfs_btree_insert(cur, &i);
559 		if (error)
560 			goto out_error;
561 	}
562 
563 out_done:
564 	trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
565 			unwritten, oinfo);
566 out_error:
567 	if (error)
568 		trace_xfs_rmap_unmap_error(mp, cur->bc_private.a.agno,
569 				error, _RET_IP_);
570 	return error;
571 }
572 
573 /*
574  * Remove a reference to an extent in the rmap btree.
575  */
576 int
577 xfs_rmap_free(
578 	struct xfs_trans	*tp,
579 	struct xfs_buf		*agbp,
580 	xfs_agnumber_t		agno,
581 	xfs_agblock_t		bno,
582 	xfs_extlen_t		len,
583 	struct xfs_owner_info	*oinfo)
584 {
585 	struct xfs_mount	*mp = tp->t_mountp;
586 	struct xfs_btree_cur	*cur;
587 	int			error;
588 
589 	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
590 		return 0;
591 
592 	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
593 
594 	error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
595 	if (error)
596 		goto out_error;
597 
598 	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
599 	return 0;
600 
601 out_error:
602 	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
603 	return error;
604 }
605 
606 /*
607  * A mergeable rmap must have the same owner and the same values for
608  * the unwritten, attr_fork, and bmbt flags.  The startblock and
609  * offset are checked separately.
610  */
611 static bool
612 xfs_rmap_is_mergeable(
613 	struct xfs_rmap_irec	*irec,
614 	uint64_t		owner,
615 	unsigned int		flags)
616 {
617 	if (irec->rm_owner == XFS_RMAP_OWN_NULL)
618 		return false;
619 	if (irec->rm_owner != owner)
620 		return false;
621 	if ((flags & XFS_RMAP_UNWRITTEN) ^
622 	    (irec->rm_flags & XFS_RMAP_UNWRITTEN))
623 		return false;
624 	if ((flags & XFS_RMAP_ATTR_FORK) ^
625 	    (irec->rm_flags & XFS_RMAP_ATTR_FORK))
626 		return false;
627 	if ((flags & XFS_RMAP_BMBT_BLOCK) ^
628 	    (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
629 		return false;
630 	return true;
631 }
632 
633 /*
634  * When we allocate a new block, the first thing we do is add a reference to
635  * the extent in the rmap btree. This takes the form of a [agbno, length,
636  * owner, offset] record.  Flags are encoded in the high bits of the offset
637  * field.
638  */
639 STATIC int
640 xfs_rmap_map(
641 	struct xfs_btree_cur	*cur,
642 	xfs_agblock_t		bno,
643 	xfs_extlen_t		len,
644 	bool			unwritten,
645 	struct xfs_owner_info	*oinfo)
646 {
647 	struct xfs_mount	*mp = cur->bc_mp;
648 	struct xfs_rmap_irec	ltrec;
649 	struct xfs_rmap_irec	gtrec;
650 	int			have_gt;
651 	int			have_lt;
652 	int			error = 0;
653 	int			i;
654 	uint64_t		owner;
655 	uint64_t		offset;
656 	unsigned int		flags = 0;
657 	bool			ignore_off;
658 
659 	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
660 	ASSERT(owner != 0);
661 	ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
662 			(flags & XFS_RMAP_BMBT_BLOCK);
663 	if (unwritten)
664 		flags |= XFS_RMAP_UNWRITTEN;
665 	trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
666 			unwritten, oinfo);
667 
668 	/*
669 	 * For the initial lookup, look for an exact match or the left-adjacent
670 	 * record for our insertion point. This will also give us the record for
671 	 * start block contiguity tests.
672 	 */
673 	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags,
674 			&have_lt);
675 	if (error)
676 		goto out_error;
677 	XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
678 
679 	error = xfs_rmap_get_rec(cur, &ltrec, &have_lt);
680 	if (error)
681 		goto out_error;
682 	XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
683 	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
684 			cur->bc_private.a.agno, ltrec.rm_startblock,
685 			ltrec.rm_blockcount, ltrec.rm_owner,
686 			ltrec.rm_offset, ltrec.rm_flags);
687 
688 	if (!xfs_rmap_is_mergeable(&ltrec, owner, flags))
689 		have_lt = 0;
690 
691 	XFS_WANT_CORRUPTED_GOTO(mp,
692 		have_lt == 0 ||
693 		ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error);
694 
695 	/*
696 	 * Increment the cursor to see if we have a right-adjacent record to our
697 	 * insertion point. This will give us the record for end block
698 	 * contiguity tests.
699 	 */
700 	error = xfs_btree_increment(cur, 0, &have_gt);
701 	if (error)
702 		goto out_error;
703 	if (have_gt) {
704 		error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
705 		if (error)
706 			goto out_error;
707 		XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
708 		XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock,
709 					out_error);
710 		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
711 			cur->bc_private.a.agno, gtrec.rm_startblock,
712 			gtrec.rm_blockcount, gtrec.rm_owner,
713 			gtrec.rm_offset, gtrec.rm_flags);
714 		if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
715 			have_gt = 0;
716 	}
717 
718 	/*
719 	 * Note: cursor currently points one record to the right of ltrec, even
720 	 * if there is no record in the tree to the right.
721 	 */
722 	if (have_lt &&
723 	    ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
724 	    (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
725 		/*
726 		 * left edge contiguous, merge into left record.
727 		 *
728 		 *       ltbno     ltlen
729 		 * orig:   |ooooooooo|
730 		 * adding:           |aaaaaaaaa|
731 		 * result: |rrrrrrrrrrrrrrrrrrr|
732 		 *                  bno       len
733 		 */
734 		ltrec.rm_blockcount += len;
735 		if (have_gt &&
736 		    bno + len == gtrec.rm_startblock &&
737 		    (ignore_off || offset + len == gtrec.rm_offset) &&
738 		    (unsigned long)ltrec.rm_blockcount + len +
739 				gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
740 			/*
741 			 * right edge also contiguous, delete right record
742 			 * and merge into left record.
743 			 *
744 			 *       ltbno     ltlen    gtbno     gtlen
745 			 * orig:   |ooooooooo|         |ooooooooo|
746 			 * adding:           |aaaaaaaaa|
747 			 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
748 			 */
749 			ltrec.rm_blockcount += gtrec.rm_blockcount;
750 			trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
751 					gtrec.rm_startblock,
752 					gtrec.rm_blockcount,
753 					gtrec.rm_owner,
754 					gtrec.rm_offset,
755 					gtrec.rm_flags);
756 			error = xfs_btree_delete(cur, &i);
757 			if (error)
758 				goto out_error;
759 			XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
760 		}
761 
762 		/* point the cursor back to the left record and update */
763 		error = xfs_btree_decrement(cur, 0, &have_gt);
764 		if (error)
765 			goto out_error;
766 		error = xfs_rmap_update(cur, &ltrec);
767 		if (error)
768 			goto out_error;
769 	} else if (have_gt &&
770 		   bno + len == gtrec.rm_startblock &&
771 		   (ignore_off || offset + len == gtrec.rm_offset)) {
772 		/*
773 		 * right edge contiguous, merge into right record.
774 		 *
775 		 *                 gtbno     gtlen
776 		 * Orig:             |ooooooooo|
777 		 * adding: |aaaaaaaaa|
778 		 * Result: |rrrrrrrrrrrrrrrrrrr|
779 		 *        bno       len
780 		 */
781 		gtrec.rm_startblock = bno;
782 		gtrec.rm_blockcount += len;
783 		if (!ignore_off)
784 			gtrec.rm_offset = offset;
785 		error = xfs_rmap_update(cur, &gtrec);
786 		if (error)
787 			goto out_error;
788 	} else {
789 		/*
790 		 * no contiguous edge with identical owner, insert
791 		 * new record at current cursor position.
792 		 */
793 		cur->bc_rec.r.rm_startblock = bno;
794 		cur->bc_rec.r.rm_blockcount = len;
795 		cur->bc_rec.r.rm_owner = owner;
796 		cur->bc_rec.r.rm_offset = offset;
797 		cur->bc_rec.r.rm_flags = flags;
798 		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
799 			owner, offset, flags);
800 		error = xfs_btree_insert(cur, &i);
801 		if (error)
802 			goto out_error;
803 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
804 	}
805 
806 	trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
807 			unwritten, oinfo);
808 out_error:
809 	if (error)
810 		trace_xfs_rmap_map_error(mp, cur->bc_private.a.agno,
811 				error, _RET_IP_);
812 	return error;
813 }
814 
815 /*
816  * Add a reference to an extent in the rmap btree.
817  */
818 int
819 xfs_rmap_alloc(
820 	struct xfs_trans	*tp,
821 	struct xfs_buf		*agbp,
822 	xfs_agnumber_t		agno,
823 	xfs_agblock_t		bno,
824 	xfs_extlen_t		len,
825 	struct xfs_owner_info	*oinfo)
826 {
827 	struct xfs_mount	*mp = tp->t_mountp;
828 	struct xfs_btree_cur	*cur;
829 	int			error;
830 
831 	if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
832 		return 0;
833 
834 	cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
835 	error = xfs_rmap_map(cur, bno, len, false, oinfo);
836 	if (error)
837 		goto out_error;
838 
839 	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
840 	return 0;
841 
842 out_error:
843 	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
844 	return error;
845 }
846 
847 #define RMAP_LEFT_CONTIG	(1 << 0)
848 #define RMAP_RIGHT_CONTIG	(1 << 1)
849 #define RMAP_LEFT_FILLING	(1 << 2)
850 #define RMAP_RIGHT_FILLING	(1 << 3)
851 #define RMAP_LEFT_VALID		(1 << 6)
852 #define RMAP_RIGHT_VALID	(1 << 7)
853 
854 #define LEFT		r[0]
855 #define RIGHT		r[1]
856 #define PREV		r[2]
857 #define NEW		r[3]
858 
859 /*
860  * Convert an unwritten extent to a real extent or vice versa.
861  * Does not handle overlapping extents.
862  */
863 STATIC int
864 xfs_rmap_convert(
865 	struct xfs_btree_cur	*cur,
866 	xfs_agblock_t		bno,
867 	xfs_extlen_t		len,
868 	bool			unwritten,
869 	struct xfs_owner_info	*oinfo)
870 {
871 	struct xfs_mount	*mp = cur->bc_mp;
872 	struct xfs_rmap_irec	r[4];	/* neighbor extent entries */
873 					/* left is 0, right is 1, prev is 2 */
874 					/* new is 3 */
875 	uint64_t		owner;
876 	uint64_t		offset;
877 	uint64_t		new_endoff;
878 	unsigned int		oldext;
879 	unsigned int		newext;
880 	unsigned int		flags = 0;
881 	int			i;
882 	int			state = 0;
883 	int			error;
884 
885 	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
886 	ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
887 			(flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
888 	oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
889 	new_endoff = offset + len;
890 	trace_xfs_rmap_convert(mp, cur->bc_private.a.agno, bno, len,
891 			unwritten, oinfo);
892 
893 	/*
894 	 * For the initial lookup, look for an exact match or the left-adjacent
895 	 * record for our insertion point. This will also give us the record for
896 	 * start block contiguity tests.
897 	 */
898 	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
899 	if (error)
900 		goto done;
901 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
902 
903 	error = xfs_rmap_get_rec(cur, &PREV, &i);
904 	if (error)
905 		goto done;
906 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
907 	trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
908 			cur->bc_private.a.agno, PREV.rm_startblock,
909 			PREV.rm_blockcount, PREV.rm_owner,
910 			PREV.rm_offset, PREV.rm_flags);
911 
912 	ASSERT(PREV.rm_offset <= offset);
913 	ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
914 	ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
915 	newext = ~oldext & XFS_RMAP_UNWRITTEN;
916 
917 	/*
918 	 * Set flags determining what part of the previous oldext allocation
919 	 * extent is being replaced by a newext allocation.
920 	 */
921 	if (PREV.rm_offset == offset)
922 		state |= RMAP_LEFT_FILLING;
923 	if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
924 		state |= RMAP_RIGHT_FILLING;
925 
926 	/*
927 	 * Decrement the cursor to see if we have a left-adjacent record to our
928 	 * insertion point. This will give us the record for end block
929 	 * contiguity tests.
930 	 */
931 	error = xfs_btree_decrement(cur, 0, &i);
932 	if (error)
933 		goto done;
934 	if (i) {
935 		state |= RMAP_LEFT_VALID;
936 		error = xfs_rmap_get_rec(cur, &LEFT, &i);
937 		if (error)
938 			goto done;
939 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
940 		XFS_WANT_CORRUPTED_GOTO(mp,
941 				LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
942 				done);
943 		trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
944 				cur->bc_private.a.agno, LEFT.rm_startblock,
945 				LEFT.rm_blockcount, LEFT.rm_owner,
946 				LEFT.rm_offset, LEFT.rm_flags);
947 		if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
948 		    LEFT.rm_offset + LEFT.rm_blockcount == offset &&
949 		    xfs_rmap_is_mergeable(&LEFT, owner, newext))
950 			state |= RMAP_LEFT_CONTIG;
951 	}
952 
953 	/*
954 	 * Increment the cursor to see if we have a right-adjacent record to our
955 	 * insertion point. This will give us the record for end block
956 	 * contiguity tests.
957 	 */
958 	error = xfs_btree_increment(cur, 0, &i);
959 	if (error)
960 		goto done;
961 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
962 	error = xfs_btree_increment(cur, 0, &i);
963 	if (error)
964 		goto done;
965 	if (i) {
966 		state |= RMAP_RIGHT_VALID;
967 		error = xfs_rmap_get_rec(cur, &RIGHT, &i);
968 		if (error)
969 			goto done;
970 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
971 		XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
972 					done);
973 		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
974 				cur->bc_private.a.agno, RIGHT.rm_startblock,
975 				RIGHT.rm_blockcount, RIGHT.rm_owner,
976 				RIGHT.rm_offset, RIGHT.rm_flags);
977 		if (bno + len == RIGHT.rm_startblock &&
978 		    offset + len == RIGHT.rm_offset &&
979 		    xfs_rmap_is_mergeable(&RIGHT, owner, newext))
980 			state |= RMAP_RIGHT_CONTIG;
981 	}
982 
983 	/* check that left + prev + right is not too long */
984 	if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
985 			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
986 	    (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
987 	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
988 	    (unsigned long)LEFT.rm_blockcount + len +
989 	     RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
990 		state &= ~RMAP_RIGHT_CONTIG;
991 
992 	trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
993 			_RET_IP_);
994 
995 	/* reset the cursor back to PREV */
996 	error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
997 	if (error)
998 		goto done;
999 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1000 
1001 	/*
1002 	 * Switch out based on the FILLING and CONTIG state bits.
1003 	 */
1004 	switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1005 			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1006 	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1007 	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1008 		/*
1009 		 * Setting all of a previous oldext extent to newext.
1010 		 * The left and right neighbors are both contiguous with new.
1011 		 */
1012 		error = xfs_btree_increment(cur, 0, &i);
1013 		if (error)
1014 			goto done;
1015 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1016 		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1017 				RIGHT.rm_startblock, RIGHT.rm_blockcount,
1018 				RIGHT.rm_owner, RIGHT.rm_offset,
1019 				RIGHT.rm_flags);
1020 		error = xfs_btree_delete(cur, &i);
1021 		if (error)
1022 			goto done;
1023 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1024 		error = xfs_btree_decrement(cur, 0, &i);
1025 		if (error)
1026 			goto done;
1027 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1028 		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1029 				PREV.rm_startblock, PREV.rm_blockcount,
1030 				PREV.rm_owner, PREV.rm_offset,
1031 				PREV.rm_flags);
1032 		error = xfs_btree_delete(cur, &i);
1033 		if (error)
1034 			goto done;
1035 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1036 		error = xfs_btree_decrement(cur, 0, &i);
1037 		if (error)
1038 			goto done;
1039 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1040 		NEW = LEFT;
1041 		NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1042 		error = xfs_rmap_update(cur, &NEW);
1043 		if (error)
1044 			goto done;
1045 		break;
1046 
1047 	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1048 		/*
1049 		 * Setting all of a previous oldext extent to newext.
1050 		 * The left neighbor is contiguous, the right is not.
1051 		 */
1052 		trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
1053 				PREV.rm_startblock, PREV.rm_blockcount,
1054 				PREV.rm_owner, PREV.rm_offset,
1055 				PREV.rm_flags);
1056 		error = xfs_btree_delete(cur, &i);
1057 		if (error)
1058 			goto done;
1059 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1060 		error = xfs_btree_decrement(cur, 0, &i);
1061 		if (error)
1062 			goto done;
1063 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1064 		NEW = LEFT;
1065 		NEW.rm_blockcount += PREV.rm_blockcount;
1066 		error = xfs_rmap_update(cur, &NEW);
1067 		if (error)
1068 			goto done;
1069 		break;
1070 
1071 	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1072 		/*
1073 		 * Setting all of a previous oldext extent to newext.
1074 		 * The right neighbor is contiguous, the left is not.
1075 		 */
1076 		error = xfs_btree_increment(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 				RIGHT.rm_startblock, RIGHT.rm_blockcount,
1082 				RIGHT.rm_owner, RIGHT.rm_offset,
1083 				RIGHT.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 = PREV;
1093 		NEW.rm_blockcount = len + RIGHT.rm_blockcount;
1094 		NEW.rm_flags = newext;
1095 		error = xfs_rmap_update(cur, &NEW);
1096 		if (error)
1097 			goto done;
1098 		break;
1099 
1100 	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1101 		/*
1102 		 * Setting all of a previous oldext extent to newext.
1103 		 * Neither the left nor right neighbors are contiguous with
1104 		 * the new one.
1105 		 */
1106 		NEW = PREV;
1107 		NEW.rm_flags = newext;
1108 		error = xfs_rmap_update(cur, &NEW);
1109 		if (error)
1110 			goto done;
1111 		break;
1112 
1113 	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1114 		/*
1115 		 * Setting the first part of a previous oldext extent to newext.
1116 		 * The left neighbor is contiguous.
1117 		 */
1118 		NEW = PREV;
1119 		NEW.rm_offset += len;
1120 		NEW.rm_startblock += len;
1121 		NEW.rm_blockcount -= len;
1122 		error = xfs_rmap_update(cur, &NEW);
1123 		if (error)
1124 			goto done;
1125 		error = xfs_btree_decrement(cur, 0, &i);
1126 		if (error)
1127 			goto done;
1128 		NEW = LEFT;
1129 		NEW.rm_blockcount += len;
1130 		error = xfs_rmap_update(cur, &NEW);
1131 		if (error)
1132 			goto done;
1133 		break;
1134 
1135 	case RMAP_LEFT_FILLING:
1136 		/*
1137 		 * Setting the first part of a previous oldext extent to newext.
1138 		 * The left neighbor is not contiguous.
1139 		 */
1140 		NEW = PREV;
1141 		NEW.rm_startblock += len;
1142 		NEW.rm_offset += len;
1143 		NEW.rm_blockcount -= len;
1144 		error = xfs_rmap_update(cur, &NEW);
1145 		if (error)
1146 			goto done;
1147 		NEW.rm_startblock = bno;
1148 		NEW.rm_owner = owner;
1149 		NEW.rm_offset = offset;
1150 		NEW.rm_blockcount = len;
1151 		NEW.rm_flags = newext;
1152 		cur->bc_rec.r = NEW;
1153 		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
1154 				len, owner, offset, newext);
1155 		error = xfs_btree_insert(cur, &i);
1156 		if (error)
1157 			goto done;
1158 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1159 		break;
1160 
1161 	case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1162 		/*
1163 		 * Setting the last part of a previous oldext extent to newext.
1164 		 * The right neighbor is contiguous with the new allocation.
1165 		 */
1166 		NEW = PREV;
1167 		NEW.rm_blockcount -= len;
1168 		error = xfs_rmap_update(cur, &NEW);
1169 		if (error)
1170 			goto done;
1171 		error = xfs_btree_increment(cur, 0, &i);
1172 		if (error)
1173 			goto done;
1174 		NEW = RIGHT;
1175 		NEW.rm_offset = offset;
1176 		NEW.rm_startblock = bno;
1177 		NEW.rm_blockcount += len;
1178 		error = xfs_rmap_update(cur, &NEW);
1179 		if (error)
1180 			goto done;
1181 		break;
1182 
1183 	case RMAP_RIGHT_FILLING:
1184 		/*
1185 		 * Setting the last part of a previous oldext extent to newext.
1186 		 * The right neighbor is not contiguous.
1187 		 */
1188 		NEW = PREV;
1189 		NEW.rm_blockcount -= len;
1190 		error = xfs_rmap_update(cur, &NEW);
1191 		if (error)
1192 			goto done;
1193 		error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1194 				oldext, &i);
1195 		if (error)
1196 			goto done;
1197 		XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done);
1198 		NEW.rm_startblock = bno;
1199 		NEW.rm_owner = owner;
1200 		NEW.rm_offset = offset;
1201 		NEW.rm_blockcount = len;
1202 		NEW.rm_flags = newext;
1203 		cur->bc_rec.r = NEW;
1204 		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno,
1205 				len, owner, offset, newext);
1206 		error = xfs_btree_insert(cur, &i);
1207 		if (error)
1208 			goto done;
1209 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1210 		break;
1211 
1212 	case 0:
1213 		/*
1214 		 * Setting the middle part of a previous oldext extent to
1215 		 * newext.  Contiguity is impossible here.
1216 		 * One extent becomes three extents.
1217 		 */
1218 		/* new right extent - oldext */
1219 		NEW.rm_startblock = bno + len;
1220 		NEW.rm_owner = owner;
1221 		NEW.rm_offset = new_endoff;
1222 		NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1223 				new_endoff;
1224 		NEW.rm_flags = PREV.rm_flags;
1225 		error = xfs_rmap_update(cur, &NEW);
1226 		if (error)
1227 			goto done;
1228 		/* new left extent - oldext */
1229 		NEW = PREV;
1230 		NEW.rm_blockcount = offset - PREV.rm_offset;
1231 		cur->bc_rec.r = NEW;
1232 		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno,
1233 				NEW.rm_startblock, NEW.rm_blockcount,
1234 				NEW.rm_owner, NEW.rm_offset,
1235 				NEW.rm_flags);
1236 		error = xfs_btree_insert(cur, &i);
1237 		if (error)
1238 			goto done;
1239 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1240 		/*
1241 		 * Reset the cursor to the position of the new extent
1242 		 * we are about to insert as we can't trust it after
1243 		 * the previous insert.
1244 		 */
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 middle extent - newext */
1251 		cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
1252 		cur->bc_rec.r.rm_flags |= newext;
1253 		trace_xfs_rmap_insert(mp, cur->bc_private.a.agno, bno, len,
1254 				owner, offset, newext);
1255 		error = xfs_btree_insert(cur, &i);
1256 		if (error)
1257 			goto done;
1258 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1259 		break;
1260 
1261 	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1262 	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1263 	case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1264 	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1265 	case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1266 	case RMAP_LEFT_CONTIG:
1267 	case RMAP_RIGHT_CONTIG:
1268 		/*
1269 		 * These cases are all impossible.
1270 		 */
1271 		ASSERT(0);
1272 	}
1273 
1274 	trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1275 			unwritten, oinfo);
1276 done:
1277 	if (error)
1278 		trace_xfs_rmap_convert_error(cur->bc_mp,
1279 				cur->bc_private.a.agno, error, _RET_IP_);
1280 	return error;
1281 }
1282 
1283 /*
1284  * Convert an unwritten extent to a real extent or vice versa.  If there is no
1285  * possibility of overlapping extents, delegate to the simpler convert
1286  * function.
1287  */
1288 STATIC int
1289 xfs_rmap_convert_shared(
1290 	struct xfs_btree_cur	*cur,
1291 	xfs_agblock_t		bno,
1292 	xfs_extlen_t		len,
1293 	bool			unwritten,
1294 	struct xfs_owner_info	*oinfo)
1295 {
1296 	struct xfs_mount	*mp = cur->bc_mp;
1297 	struct xfs_rmap_irec	r[4];	/* neighbor extent entries */
1298 					/* left is 0, right is 1, prev is 2 */
1299 					/* new is 3 */
1300 	uint64_t		owner;
1301 	uint64_t		offset;
1302 	uint64_t		new_endoff;
1303 	unsigned int		oldext;
1304 	unsigned int		newext;
1305 	unsigned int		flags = 0;
1306 	int			i;
1307 	int			state = 0;
1308 	int			error;
1309 
1310 	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1311 	ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1312 			(flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1313 	oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1314 	new_endoff = offset + len;
1315 	trace_xfs_rmap_convert(mp, cur->bc_private.a.agno, bno, len,
1316 			unwritten, oinfo);
1317 
1318 	/*
1319 	 * For the initial lookup, look for and exact match or the left-adjacent
1320 	 * record for our insertion point. This will also give us the record for
1321 	 * start block contiguity tests.
1322 	 */
1323 	error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1324 			&PREV, &i);
1325 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1326 
1327 	ASSERT(PREV.rm_offset <= offset);
1328 	ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1329 	ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1330 	newext = ~oldext & XFS_RMAP_UNWRITTEN;
1331 
1332 	/*
1333 	 * Set flags determining what part of the previous oldext allocation
1334 	 * extent is being replaced by a newext allocation.
1335 	 */
1336 	if (PREV.rm_offset == offset)
1337 		state |= RMAP_LEFT_FILLING;
1338 	if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1339 		state |= RMAP_RIGHT_FILLING;
1340 
1341 	/* Is there a left record that abuts our range? */
1342 	error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
1343 			&LEFT, &i);
1344 	if (error)
1345 		goto done;
1346 	if (i) {
1347 		state |= RMAP_LEFT_VALID;
1348 		XFS_WANT_CORRUPTED_GOTO(mp,
1349 				LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
1350 				done);
1351 		if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
1352 			state |= RMAP_LEFT_CONTIG;
1353 	}
1354 
1355 	/* Is there a right record that abuts our range? */
1356 	error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1357 			newext, &i);
1358 	if (error)
1359 		goto done;
1360 	if (i) {
1361 		state |= RMAP_RIGHT_VALID;
1362 		error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1363 		if (error)
1364 			goto done;
1365 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1366 		XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
1367 				done);
1368 		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1369 				cur->bc_private.a.agno, RIGHT.rm_startblock,
1370 				RIGHT.rm_blockcount, RIGHT.rm_owner,
1371 				RIGHT.rm_offset, RIGHT.rm_flags);
1372 		if (xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1373 			state |= RMAP_RIGHT_CONTIG;
1374 	}
1375 
1376 	/* check that left + prev + right is not too long */
1377 	if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1378 			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1379 	    (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1380 	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1381 	    (unsigned long)LEFT.rm_blockcount + len +
1382 	     RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1383 		state &= ~RMAP_RIGHT_CONTIG;
1384 
1385 	trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
1386 			_RET_IP_);
1387 	/*
1388 	 * Switch out based on the FILLING and CONTIG state bits.
1389 	 */
1390 	switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1391 			 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1392 	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1393 	     RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1394 		/*
1395 		 * Setting all of a previous oldext extent to newext.
1396 		 * The left and right neighbors are both contiguous with new.
1397 		 */
1398 		error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1399 				RIGHT.rm_blockcount, RIGHT.rm_owner,
1400 				RIGHT.rm_offset, RIGHT.rm_flags);
1401 		if (error)
1402 			goto done;
1403 		error = xfs_rmap_delete(cur, PREV.rm_startblock,
1404 				PREV.rm_blockcount, PREV.rm_owner,
1405 				PREV.rm_offset, PREV.rm_flags);
1406 		if (error)
1407 			goto done;
1408 		NEW = LEFT;
1409 		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1410 				NEW.rm_blockcount, NEW.rm_owner,
1411 				NEW.rm_offset, NEW.rm_flags, &i);
1412 		if (error)
1413 			goto done;
1414 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1415 		NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1416 		error = xfs_rmap_update(cur, &NEW);
1417 		if (error)
1418 			goto done;
1419 		break;
1420 
1421 	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1422 		/*
1423 		 * Setting all of a previous oldext extent to newext.
1424 		 * The left neighbor is contiguous, the right is not.
1425 		 */
1426 		error = xfs_rmap_delete(cur, PREV.rm_startblock,
1427 				PREV.rm_blockcount, PREV.rm_owner,
1428 				PREV.rm_offset, PREV.rm_flags);
1429 		if (error)
1430 			goto done;
1431 		NEW = LEFT;
1432 		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1433 				NEW.rm_blockcount, NEW.rm_owner,
1434 				NEW.rm_offset, NEW.rm_flags, &i);
1435 		if (error)
1436 			goto done;
1437 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1438 		NEW.rm_blockcount += PREV.rm_blockcount;
1439 		error = xfs_rmap_update(cur, &NEW);
1440 		if (error)
1441 			goto done;
1442 		break;
1443 
1444 	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1445 		/*
1446 		 * Setting all of a previous oldext extent to newext.
1447 		 * The right neighbor is contiguous, the left is not.
1448 		 */
1449 		error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1450 				RIGHT.rm_blockcount, RIGHT.rm_owner,
1451 				RIGHT.rm_offset, RIGHT.rm_flags);
1452 		if (error)
1453 			goto done;
1454 		NEW = PREV;
1455 		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1456 				NEW.rm_blockcount, NEW.rm_owner,
1457 				NEW.rm_offset, NEW.rm_flags, &i);
1458 		if (error)
1459 			goto done;
1460 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1461 		NEW.rm_blockcount += RIGHT.rm_blockcount;
1462 		NEW.rm_flags = RIGHT.rm_flags;
1463 		error = xfs_rmap_update(cur, &NEW);
1464 		if (error)
1465 			goto done;
1466 		break;
1467 
1468 	case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1469 		/*
1470 		 * Setting all of a previous oldext extent to newext.
1471 		 * Neither the left nor right neighbors are contiguous with
1472 		 * the new one.
1473 		 */
1474 		NEW = PREV;
1475 		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1476 				NEW.rm_blockcount, NEW.rm_owner,
1477 				NEW.rm_offset, NEW.rm_flags, &i);
1478 		if (error)
1479 			goto done;
1480 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1481 		NEW.rm_flags = newext;
1482 		error = xfs_rmap_update(cur, &NEW);
1483 		if (error)
1484 			goto done;
1485 		break;
1486 
1487 	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1488 		/*
1489 		 * Setting the first part of a previous oldext extent to newext.
1490 		 * The left neighbor is contiguous.
1491 		 */
1492 		NEW = PREV;
1493 		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1494 				NEW.rm_blockcount, NEW.rm_owner,
1495 				NEW.rm_offset, NEW.rm_flags);
1496 		if (error)
1497 			goto done;
1498 		NEW.rm_offset += len;
1499 		NEW.rm_startblock += len;
1500 		NEW.rm_blockcount -= len;
1501 		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1502 				NEW.rm_blockcount, NEW.rm_owner,
1503 				NEW.rm_offset, NEW.rm_flags);
1504 		if (error)
1505 			goto done;
1506 		NEW = LEFT;
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 += len;
1514 		error = xfs_rmap_update(cur, &NEW);
1515 		if (error)
1516 			goto done;
1517 		break;
1518 
1519 	case RMAP_LEFT_FILLING:
1520 		/*
1521 		 * Setting the first part of a previous oldext extent to newext.
1522 		 * The left neighbor is not contiguous.
1523 		 */
1524 		NEW = PREV;
1525 		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1526 				NEW.rm_blockcount, NEW.rm_owner,
1527 				NEW.rm_offset, NEW.rm_flags);
1528 		if (error)
1529 			goto done;
1530 		NEW.rm_offset += len;
1531 		NEW.rm_startblock += len;
1532 		NEW.rm_blockcount -= len;
1533 		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1534 				NEW.rm_blockcount, NEW.rm_owner,
1535 				NEW.rm_offset, NEW.rm_flags);
1536 		if (error)
1537 			goto done;
1538 		error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1539 		if (error)
1540 			goto done;
1541 		break;
1542 
1543 	case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1544 		/*
1545 		 * Setting the last part of a previous oldext extent to newext.
1546 		 * The right neighbor is contiguous with the new allocation.
1547 		 */
1548 		NEW = PREV;
1549 		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1550 				NEW.rm_blockcount, NEW.rm_owner,
1551 				NEW.rm_offset, NEW.rm_flags, &i);
1552 		if (error)
1553 			goto done;
1554 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1555 		NEW.rm_blockcount = offset - NEW.rm_offset;
1556 		error = xfs_rmap_update(cur, &NEW);
1557 		if (error)
1558 			goto done;
1559 		NEW = RIGHT;
1560 		error = xfs_rmap_delete(cur, NEW.rm_startblock,
1561 				NEW.rm_blockcount, NEW.rm_owner,
1562 				NEW.rm_offset, NEW.rm_flags);
1563 		if (error)
1564 			goto done;
1565 		NEW.rm_offset = offset;
1566 		NEW.rm_startblock = bno;
1567 		NEW.rm_blockcount += len;
1568 		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1569 				NEW.rm_blockcount, NEW.rm_owner,
1570 				NEW.rm_offset, NEW.rm_flags);
1571 		if (error)
1572 			goto done;
1573 		break;
1574 
1575 	case RMAP_RIGHT_FILLING:
1576 		/*
1577 		 * Setting the last part of a previous oldext extent to newext.
1578 		 * The right neighbor is not contiguous.
1579 		 */
1580 		NEW = PREV;
1581 		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1582 				NEW.rm_blockcount, NEW.rm_owner,
1583 				NEW.rm_offset, NEW.rm_flags, &i);
1584 		if (error)
1585 			goto done;
1586 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1587 		NEW.rm_blockcount -= len;
1588 		error = xfs_rmap_update(cur, &NEW);
1589 		if (error)
1590 			goto done;
1591 		error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1592 		if (error)
1593 			goto done;
1594 		break;
1595 
1596 	case 0:
1597 		/*
1598 		 * Setting the middle part of a previous oldext extent to
1599 		 * newext.  Contiguity is impossible here.
1600 		 * One extent becomes three extents.
1601 		 */
1602 		/* new right extent - oldext */
1603 		NEW.rm_startblock = bno + len;
1604 		NEW.rm_owner = owner;
1605 		NEW.rm_offset = new_endoff;
1606 		NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1607 				new_endoff;
1608 		NEW.rm_flags = PREV.rm_flags;
1609 		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1610 				NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1611 				NEW.rm_flags);
1612 		if (error)
1613 			goto done;
1614 		/* new left extent - oldext */
1615 		NEW = PREV;
1616 		error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1617 				NEW.rm_blockcount, NEW.rm_owner,
1618 				NEW.rm_offset, NEW.rm_flags, &i);
1619 		if (error)
1620 			goto done;
1621 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1622 		NEW.rm_blockcount = offset - NEW.rm_offset;
1623 		error = xfs_rmap_update(cur, &NEW);
1624 		if (error)
1625 			goto done;
1626 		/* new middle extent - newext */
1627 		NEW.rm_startblock = bno;
1628 		NEW.rm_blockcount = len;
1629 		NEW.rm_owner = owner;
1630 		NEW.rm_offset = offset;
1631 		NEW.rm_flags = newext;
1632 		error = xfs_rmap_insert(cur, NEW.rm_startblock,
1633 				NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1634 				NEW.rm_flags);
1635 		if (error)
1636 			goto done;
1637 		break;
1638 
1639 	case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1640 	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1641 	case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1642 	case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1643 	case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1644 	case RMAP_LEFT_CONTIG:
1645 	case RMAP_RIGHT_CONTIG:
1646 		/*
1647 		 * These cases are all impossible.
1648 		 */
1649 		ASSERT(0);
1650 	}
1651 
1652 	trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1653 			unwritten, oinfo);
1654 done:
1655 	if (error)
1656 		trace_xfs_rmap_convert_error(cur->bc_mp,
1657 				cur->bc_private.a.agno, error, _RET_IP_);
1658 	return error;
1659 }
1660 
1661 #undef	NEW
1662 #undef	LEFT
1663 #undef	RIGHT
1664 #undef	PREV
1665 
1666 /*
1667  * Find an extent in the rmap btree and unmap it.  For rmap extent types that
1668  * can overlap (data fork rmaps on reflink filesystems) we must be careful
1669  * that the prev/next records in the btree might belong to another owner.
1670  * Therefore we must use delete+insert to alter any of the key fields.
1671  *
1672  * For every other situation there can only be one owner for a given extent,
1673  * so we can call the regular _free function.
1674  */
1675 STATIC int
1676 xfs_rmap_unmap_shared(
1677 	struct xfs_btree_cur	*cur,
1678 	xfs_agblock_t		bno,
1679 	xfs_extlen_t		len,
1680 	bool			unwritten,
1681 	struct xfs_owner_info	*oinfo)
1682 {
1683 	struct xfs_mount	*mp = cur->bc_mp;
1684 	struct xfs_rmap_irec	ltrec;
1685 	uint64_t		ltoff;
1686 	int			error = 0;
1687 	int			i;
1688 	uint64_t		owner;
1689 	uint64_t		offset;
1690 	unsigned int		flags;
1691 
1692 	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1693 	if (unwritten)
1694 		flags |= XFS_RMAP_UNWRITTEN;
1695 	trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
1696 			unwritten, oinfo);
1697 
1698 	/*
1699 	 * We should always have a left record because there's a static record
1700 	 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
1701 	 * will not ever be removed from the tree.
1702 	 */
1703 	error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1704 			&ltrec, &i);
1705 	if (error)
1706 		goto out_error;
1707 	XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1708 	ltoff = ltrec.rm_offset;
1709 
1710 	/* Make sure the extent we found covers the entire freeing range. */
1711 	XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno &&
1712 		ltrec.rm_startblock + ltrec.rm_blockcount >=
1713 		bno + len, out_error);
1714 
1715 	/* Make sure the owner matches what we expect to find in the tree. */
1716 	XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner, out_error);
1717 
1718 	/* Make sure the unwritten flag matches. */
1719 	XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) ==
1720 			(ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error);
1721 
1722 	/* Check the offset. */
1723 	XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_offset <= offset, out_error);
1724 	XFS_WANT_CORRUPTED_GOTO(mp, offset <= ltoff + ltrec.rm_blockcount,
1725 			out_error);
1726 
1727 	if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
1728 		/* Exact match, simply remove the record from rmap tree. */
1729 		error = xfs_rmap_delete(cur, ltrec.rm_startblock,
1730 				ltrec.rm_blockcount, ltrec.rm_owner,
1731 				ltrec.rm_offset, ltrec.rm_flags);
1732 		if (error)
1733 			goto out_error;
1734 	} else if (ltrec.rm_startblock == bno) {
1735 		/*
1736 		 * Overlap left hand side of extent: move the start, trim the
1737 		 * length and update the current record.
1738 		 *
1739 		 *       ltbno                ltlen
1740 		 * Orig:    |oooooooooooooooooooo|
1741 		 * Freeing: |fffffffff|
1742 		 * Result:            |rrrrrrrrrr|
1743 		 *         bno       len
1744 		 */
1745 
1746 		/* Delete prev rmap. */
1747 		error = xfs_rmap_delete(cur, ltrec.rm_startblock,
1748 				ltrec.rm_blockcount, ltrec.rm_owner,
1749 				ltrec.rm_offset, ltrec.rm_flags);
1750 		if (error)
1751 			goto out_error;
1752 
1753 		/* Add an rmap at the new offset. */
1754 		ltrec.rm_startblock += len;
1755 		ltrec.rm_blockcount -= len;
1756 		ltrec.rm_offset += len;
1757 		error = xfs_rmap_insert(cur, ltrec.rm_startblock,
1758 				ltrec.rm_blockcount, ltrec.rm_owner,
1759 				ltrec.rm_offset, ltrec.rm_flags);
1760 		if (error)
1761 			goto out_error;
1762 	} else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
1763 		/*
1764 		 * Overlap right hand side of extent: trim the length and
1765 		 * update the current record.
1766 		 *
1767 		 *       ltbno                ltlen
1768 		 * Orig:    |oooooooooooooooooooo|
1769 		 * Freeing:            |fffffffff|
1770 		 * Result:  |rrrrrrrrrr|
1771 		 *                    bno       len
1772 		 */
1773 		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1774 				ltrec.rm_blockcount, ltrec.rm_owner,
1775 				ltrec.rm_offset, ltrec.rm_flags, &i);
1776 		if (error)
1777 			goto out_error;
1778 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1779 		ltrec.rm_blockcount -= len;
1780 		error = xfs_rmap_update(cur, &ltrec);
1781 		if (error)
1782 			goto out_error;
1783 	} else {
1784 		/*
1785 		 * Overlap middle of extent: trim the length of the existing
1786 		 * record to the length of the new left-extent size, increment
1787 		 * the insertion position so we can insert a new record
1788 		 * containing the remaining right-extent space.
1789 		 *
1790 		 *       ltbno                ltlen
1791 		 * Orig:    |oooooooooooooooooooo|
1792 		 * Freeing:       |fffffffff|
1793 		 * Result:  |rrrrr|         |rrrr|
1794 		 *               bno       len
1795 		 */
1796 		xfs_extlen_t	orig_len = ltrec.rm_blockcount;
1797 
1798 		/* Shrink the left side of the rmap */
1799 		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1800 				ltrec.rm_blockcount, ltrec.rm_owner,
1801 				ltrec.rm_offset, ltrec.rm_flags, &i);
1802 		if (error)
1803 			goto out_error;
1804 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1805 		ltrec.rm_blockcount = bno - ltrec.rm_startblock;
1806 		error = xfs_rmap_update(cur, &ltrec);
1807 		if (error)
1808 			goto out_error;
1809 
1810 		/* Add an rmap at the new offset */
1811 		error = xfs_rmap_insert(cur, bno + len,
1812 				orig_len - len - ltrec.rm_blockcount,
1813 				ltrec.rm_owner, offset + len,
1814 				ltrec.rm_flags);
1815 		if (error)
1816 			goto out_error;
1817 	}
1818 
1819 	trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
1820 			unwritten, oinfo);
1821 out_error:
1822 	if (error)
1823 		trace_xfs_rmap_unmap_error(cur->bc_mp,
1824 				cur->bc_private.a.agno, error, _RET_IP_);
1825 	return error;
1826 }
1827 
1828 /*
1829  * Find an extent in the rmap btree and map it.  For rmap extent types that
1830  * can overlap (data fork rmaps on reflink filesystems) we must be careful
1831  * that the prev/next records in the btree might belong to another owner.
1832  * Therefore we must use delete+insert to alter any of the key fields.
1833  *
1834  * For every other situation there can only be one owner for a given extent,
1835  * so we can call the regular _alloc function.
1836  */
1837 STATIC int
1838 xfs_rmap_map_shared(
1839 	struct xfs_btree_cur	*cur,
1840 	xfs_agblock_t		bno,
1841 	xfs_extlen_t		len,
1842 	bool			unwritten,
1843 	struct xfs_owner_info	*oinfo)
1844 {
1845 	struct xfs_mount	*mp = cur->bc_mp;
1846 	struct xfs_rmap_irec	ltrec;
1847 	struct xfs_rmap_irec	gtrec;
1848 	int			have_gt;
1849 	int			have_lt;
1850 	int			error = 0;
1851 	int			i;
1852 	uint64_t		owner;
1853 	uint64_t		offset;
1854 	unsigned int		flags = 0;
1855 
1856 	xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1857 	if (unwritten)
1858 		flags |= XFS_RMAP_UNWRITTEN;
1859 	trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
1860 			unwritten, oinfo);
1861 
1862 	/* Is there a left record that abuts our range? */
1863 	error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
1864 			&ltrec, &have_lt);
1865 	if (error)
1866 		goto out_error;
1867 	if (have_lt &&
1868 	    !xfs_rmap_is_mergeable(&ltrec, owner, flags))
1869 		have_lt = 0;
1870 
1871 	/* Is there a right record that abuts our range? */
1872 	error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1873 			flags, &have_gt);
1874 	if (error)
1875 		goto out_error;
1876 	if (have_gt) {
1877 		error = xfs_rmap_get_rec(cur, &gtrec, &have_gt);
1878 		if (error)
1879 			goto out_error;
1880 		XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
1881 		trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1882 			cur->bc_private.a.agno, gtrec.rm_startblock,
1883 			gtrec.rm_blockcount, gtrec.rm_owner,
1884 			gtrec.rm_offset, gtrec.rm_flags);
1885 
1886 		if (!xfs_rmap_is_mergeable(&gtrec, owner, flags))
1887 			have_gt = 0;
1888 	}
1889 
1890 	if (have_lt &&
1891 	    ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
1892 	    ltrec.rm_offset + ltrec.rm_blockcount == offset) {
1893 		/*
1894 		 * Left edge contiguous, merge into left record.
1895 		 *
1896 		 *       ltbno     ltlen
1897 		 * orig:   |ooooooooo|
1898 		 * adding:           |aaaaaaaaa|
1899 		 * result: |rrrrrrrrrrrrrrrrrrr|
1900 		 *                  bno       len
1901 		 */
1902 		ltrec.rm_blockcount += len;
1903 		if (have_gt &&
1904 		    bno + len == gtrec.rm_startblock &&
1905 		    offset + len == gtrec.rm_offset) {
1906 			/*
1907 			 * Right edge also contiguous, delete right record
1908 			 * and merge into left record.
1909 			 *
1910 			 *       ltbno     ltlen    gtbno     gtlen
1911 			 * orig:   |ooooooooo|         |ooooooooo|
1912 			 * adding:           |aaaaaaaaa|
1913 			 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
1914 			 */
1915 			ltrec.rm_blockcount += gtrec.rm_blockcount;
1916 			error = xfs_rmap_delete(cur, gtrec.rm_startblock,
1917 					gtrec.rm_blockcount, gtrec.rm_owner,
1918 					gtrec.rm_offset, gtrec.rm_flags);
1919 			if (error)
1920 				goto out_error;
1921 		}
1922 
1923 		/* Point the cursor back to the left record and update. */
1924 		error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
1925 				ltrec.rm_blockcount, ltrec.rm_owner,
1926 				ltrec.rm_offset, ltrec.rm_flags, &i);
1927 		if (error)
1928 			goto out_error;
1929 		XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1930 
1931 		error = xfs_rmap_update(cur, &ltrec);
1932 		if (error)
1933 			goto out_error;
1934 	} else if (have_gt &&
1935 		   bno + len == gtrec.rm_startblock &&
1936 		   offset + len == gtrec.rm_offset) {
1937 		/*
1938 		 * Right edge contiguous, merge into right record.
1939 		 *
1940 		 *                 gtbno     gtlen
1941 		 * Orig:             |ooooooooo|
1942 		 * adding: |aaaaaaaaa|
1943 		 * Result: |rrrrrrrrrrrrrrrrrrr|
1944 		 *        bno       len
1945 		 */
1946 		/* Delete the old record. */
1947 		error = xfs_rmap_delete(cur, gtrec.rm_startblock,
1948 				gtrec.rm_blockcount, gtrec.rm_owner,
1949 				gtrec.rm_offset, gtrec.rm_flags);
1950 		if (error)
1951 			goto out_error;
1952 
1953 		/* Move the start and re-add it. */
1954 		gtrec.rm_startblock = bno;
1955 		gtrec.rm_blockcount += len;
1956 		gtrec.rm_offset = offset;
1957 		error = xfs_rmap_insert(cur, gtrec.rm_startblock,
1958 				gtrec.rm_blockcount, gtrec.rm_owner,
1959 				gtrec.rm_offset, gtrec.rm_flags);
1960 		if (error)
1961 			goto out_error;
1962 	} else {
1963 		/*
1964 		 * No contiguous edge with identical owner, insert
1965 		 * new record at current cursor position.
1966 		 */
1967 		error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
1968 		if (error)
1969 			goto out_error;
1970 	}
1971 
1972 	trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
1973 			unwritten, oinfo);
1974 out_error:
1975 	if (error)
1976 		trace_xfs_rmap_map_error(cur->bc_mp,
1977 				cur->bc_private.a.agno, error, _RET_IP_);
1978 	return error;
1979 }
1980 
1981 struct xfs_rmap_query_range_info {
1982 	xfs_rmap_query_range_fn	fn;
1983 	void				*priv;
1984 };
1985 
1986 /* Format btree record and pass to our callback. */
1987 STATIC int
1988 xfs_rmap_query_range_helper(
1989 	struct xfs_btree_cur	*cur,
1990 	union xfs_btree_rec	*rec,
1991 	void			*priv)
1992 {
1993 	struct xfs_rmap_query_range_info	*query = priv;
1994 	struct xfs_rmap_irec			irec;
1995 	int					error;
1996 
1997 	error = xfs_rmap_btrec_to_irec(rec, &irec);
1998 	if (error)
1999 		return error;
2000 	return query->fn(cur, &irec, query->priv);
2001 }
2002 
2003 /* Find all rmaps between two keys. */
2004 int
2005 xfs_rmap_query_range(
2006 	struct xfs_btree_cur			*cur,
2007 	struct xfs_rmap_irec			*low_rec,
2008 	struct xfs_rmap_irec			*high_rec,
2009 	xfs_rmap_query_range_fn			fn,
2010 	void					*priv)
2011 {
2012 	union xfs_btree_irec			low_brec;
2013 	union xfs_btree_irec			high_brec;
2014 	struct xfs_rmap_query_range_info	query;
2015 
2016 	low_brec.r = *low_rec;
2017 	high_brec.r = *high_rec;
2018 	query.priv = priv;
2019 	query.fn = fn;
2020 	return xfs_btree_query_range(cur, &low_brec, &high_brec,
2021 			xfs_rmap_query_range_helper, &query);
2022 }
2023 
2024 /* Find all rmaps. */
2025 int
2026 xfs_rmap_query_all(
2027 	struct xfs_btree_cur			*cur,
2028 	xfs_rmap_query_range_fn			fn,
2029 	void					*priv)
2030 {
2031 	struct xfs_rmap_query_range_info	query;
2032 
2033 	query.priv = priv;
2034 	query.fn = fn;
2035 	return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query);
2036 }
2037 
2038 /* Clean up after calling xfs_rmap_finish_one. */
2039 void
2040 xfs_rmap_finish_one_cleanup(
2041 	struct xfs_trans	*tp,
2042 	struct xfs_btree_cur	*rcur,
2043 	int			error)
2044 {
2045 	struct xfs_buf		*agbp;
2046 
2047 	if (rcur == NULL)
2048 		return;
2049 	agbp = rcur->bc_private.a.agbp;
2050 	xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
2051 	if (error)
2052 		xfs_trans_brelse(tp, agbp);
2053 }
2054 
2055 /*
2056  * Process one of the deferred rmap operations.  We pass back the
2057  * btree cursor to maintain our lock on the rmapbt between calls.
2058  * This saves time and eliminates a buffer deadlock between the
2059  * superblock and the AGF because we'll always grab them in the same
2060  * order.
2061  */
2062 int
2063 xfs_rmap_finish_one(
2064 	struct xfs_trans		*tp,
2065 	enum xfs_rmap_intent_type	type,
2066 	uint64_t			owner,
2067 	int				whichfork,
2068 	xfs_fileoff_t			startoff,
2069 	xfs_fsblock_t			startblock,
2070 	xfs_filblks_t			blockcount,
2071 	xfs_exntst_t			state,
2072 	struct xfs_btree_cur		**pcur)
2073 {
2074 	struct xfs_mount		*mp = tp->t_mountp;
2075 	struct xfs_btree_cur		*rcur;
2076 	struct xfs_buf			*agbp = NULL;
2077 	int				error = 0;
2078 	xfs_agnumber_t			agno;
2079 	struct xfs_owner_info		oinfo;
2080 	xfs_agblock_t			bno;
2081 	bool				unwritten;
2082 
2083 	agno = XFS_FSB_TO_AGNO(mp, startblock);
2084 	ASSERT(agno != NULLAGNUMBER);
2085 	bno = XFS_FSB_TO_AGBNO(mp, startblock);
2086 
2087 	trace_xfs_rmap_deferred(mp, agno, type, bno, owner, whichfork,
2088 			startoff, blockcount, state);
2089 
2090 	if (XFS_TEST_ERROR(false, mp,
2091 			XFS_ERRTAG_RMAP_FINISH_ONE))
2092 		return -EIO;
2093 
2094 	/*
2095 	 * If we haven't gotten a cursor or the cursor AG doesn't match
2096 	 * the startblock, get one now.
2097 	 */
2098 	rcur = *pcur;
2099 	if (rcur != NULL && rcur->bc_private.a.agno != agno) {
2100 		xfs_rmap_finish_one_cleanup(tp, rcur, 0);
2101 		rcur = NULL;
2102 		*pcur = NULL;
2103 	}
2104 	if (rcur == NULL) {
2105 		/*
2106 		 * Refresh the freelist before we start changing the
2107 		 * rmapbt, because a shape change could cause us to
2108 		 * allocate blocks.
2109 		 */
2110 		error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
2111 		if (error)
2112 			return error;
2113 		if (!agbp)
2114 			return -EFSCORRUPTED;
2115 
2116 		rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
2117 		if (!rcur) {
2118 			error = -ENOMEM;
2119 			goto out_cur;
2120 		}
2121 	}
2122 	*pcur = rcur;
2123 
2124 	xfs_rmap_ino_owner(&oinfo, owner, whichfork, startoff);
2125 	unwritten = state == XFS_EXT_UNWRITTEN;
2126 	bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, startblock);
2127 
2128 	switch (type) {
2129 	case XFS_RMAP_ALLOC:
2130 	case XFS_RMAP_MAP:
2131 		error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo);
2132 		break;
2133 	case XFS_RMAP_MAP_SHARED:
2134 		error = xfs_rmap_map_shared(rcur, bno, blockcount, unwritten,
2135 				&oinfo);
2136 		break;
2137 	case XFS_RMAP_FREE:
2138 	case XFS_RMAP_UNMAP:
2139 		error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten,
2140 				&oinfo);
2141 		break;
2142 	case XFS_RMAP_UNMAP_SHARED:
2143 		error = xfs_rmap_unmap_shared(rcur, bno, blockcount, unwritten,
2144 				&oinfo);
2145 		break;
2146 	case XFS_RMAP_CONVERT:
2147 		error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten,
2148 				&oinfo);
2149 		break;
2150 	case XFS_RMAP_CONVERT_SHARED:
2151 		error = xfs_rmap_convert_shared(rcur, bno, blockcount,
2152 				!unwritten, &oinfo);
2153 		break;
2154 	default:
2155 		ASSERT(0);
2156 		error = -EFSCORRUPTED;
2157 	}
2158 	return error;
2159 
2160 out_cur:
2161 	xfs_trans_brelse(tp, agbp);
2162 
2163 	return error;
2164 }
2165 
2166 /*
2167  * Don't defer an rmap if we aren't an rmap filesystem.
2168  */
2169 static bool
2170 xfs_rmap_update_is_needed(
2171 	struct xfs_mount	*mp,
2172 	int			whichfork)
2173 {
2174 	return xfs_sb_version_hasrmapbt(&mp->m_sb) && whichfork != XFS_COW_FORK;
2175 }
2176 
2177 /*
2178  * Record a rmap intent; the list is kept sorted first by AG and then by
2179  * increasing age.
2180  */
2181 static int
2182 __xfs_rmap_add(
2183 	struct xfs_mount		*mp,
2184 	struct xfs_defer_ops		*dfops,
2185 	enum xfs_rmap_intent_type	type,
2186 	uint64_t			owner,
2187 	int				whichfork,
2188 	struct xfs_bmbt_irec		*bmap)
2189 {
2190 	struct xfs_rmap_intent	*ri;
2191 
2192 	trace_xfs_rmap_defer(mp, XFS_FSB_TO_AGNO(mp, bmap->br_startblock),
2193 			type,
2194 			XFS_FSB_TO_AGBNO(mp, bmap->br_startblock),
2195 			owner, whichfork,
2196 			bmap->br_startoff,
2197 			bmap->br_blockcount,
2198 			bmap->br_state);
2199 
2200 	ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_SLEEP | KM_NOFS);
2201 	INIT_LIST_HEAD(&ri->ri_list);
2202 	ri->ri_type = type;
2203 	ri->ri_owner = owner;
2204 	ri->ri_whichfork = whichfork;
2205 	ri->ri_bmap = *bmap;
2206 
2207 	xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
2208 	return 0;
2209 }
2210 
2211 /* Map an extent into a file. */
2212 int
2213 xfs_rmap_map_extent(
2214 	struct xfs_mount	*mp,
2215 	struct xfs_defer_ops	*dfops,
2216 	struct xfs_inode	*ip,
2217 	int			whichfork,
2218 	struct xfs_bmbt_irec	*PREV)
2219 {
2220 	if (!xfs_rmap_update_is_needed(mp, whichfork))
2221 		return 0;
2222 
2223 	return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2224 			XFS_RMAP_MAP_SHARED : XFS_RMAP_MAP, ip->i_ino,
2225 			whichfork, PREV);
2226 }
2227 
2228 /* Unmap an extent out of a file. */
2229 int
2230 xfs_rmap_unmap_extent(
2231 	struct xfs_mount	*mp,
2232 	struct xfs_defer_ops	*dfops,
2233 	struct xfs_inode	*ip,
2234 	int			whichfork,
2235 	struct xfs_bmbt_irec	*PREV)
2236 {
2237 	if (!xfs_rmap_update_is_needed(mp, whichfork))
2238 		return 0;
2239 
2240 	return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2241 			XFS_RMAP_UNMAP_SHARED : XFS_RMAP_UNMAP, ip->i_ino,
2242 			whichfork, PREV);
2243 }
2244 
2245 /* Convert a data fork extent from unwritten to real or vice versa. */
2246 int
2247 xfs_rmap_convert_extent(
2248 	struct xfs_mount	*mp,
2249 	struct xfs_defer_ops	*dfops,
2250 	struct xfs_inode	*ip,
2251 	int			whichfork,
2252 	struct xfs_bmbt_irec	*PREV)
2253 {
2254 	if (!xfs_rmap_update_is_needed(mp, whichfork))
2255 		return 0;
2256 
2257 	return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2258 			XFS_RMAP_CONVERT_SHARED : XFS_RMAP_CONVERT, ip->i_ino,
2259 			whichfork, PREV);
2260 }
2261 
2262 /* Schedule the creation of an rmap for non-file data. */
2263 int
2264 xfs_rmap_alloc_extent(
2265 	struct xfs_mount	*mp,
2266 	struct xfs_defer_ops	*dfops,
2267 	xfs_agnumber_t		agno,
2268 	xfs_agblock_t		bno,
2269 	xfs_extlen_t		len,
2270 	uint64_t		owner)
2271 {
2272 	struct xfs_bmbt_irec	bmap;
2273 
2274 	if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
2275 		return 0;
2276 
2277 	bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
2278 	bmap.br_blockcount = len;
2279 	bmap.br_startoff = 0;
2280 	bmap.br_state = XFS_EXT_NORM;
2281 
2282 	return __xfs_rmap_add(mp, dfops, XFS_RMAP_ALLOC, owner,
2283 			XFS_DATA_FORK, &bmap);
2284 }
2285 
2286 /* Schedule the deletion of an rmap for non-file data. */
2287 int
2288 xfs_rmap_free_extent(
2289 	struct xfs_mount	*mp,
2290 	struct xfs_defer_ops	*dfops,
2291 	xfs_agnumber_t		agno,
2292 	xfs_agblock_t		bno,
2293 	xfs_extlen_t		len,
2294 	uint64_t		owner)
2295 {
2296 	struct xfs_bmbt_irec	bmap;
2297 
2298 	if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
2299 		return 0;
2300 
2301 	bmap.br_startblock = XFS_AGB_TO_FSB(mp, agno, bno);
2302 	bmap.br_blockcount = len;
2303 	bmap.br_startoff = 0;
2304 	bmap.br_state = XFS_EXT_NORM;
2305 
2306 	return __xfs_rmap_add(mp, dfops, XFS_RMAP_FREE, owner,
2307 			XFS_DATA_FORK, &bmap);
2308 }
2309 
2310 /* Compare rmap records.  Returns -1 if a < b, 1 if a > b, and 0 if equal. */
2311 int
2312 xfs_rmap_compare(
2313 	const struct xfs_rmap_irec	*a,
2314 	const struct xfs_rmap_irec	*b)
2315 {
2316 	__u64				oa;
2317 	__u64				ob;
2318 
2319 	oa = xfs_rmap_irec_offset_pack(a);
2320 	ob = xfs_rmap_irec_offset_pack(b);
2321 
2322 	if (a->rm_startblock < b->rm_startblock)
2323 		return -1;
2324 	else if (a->rm_startblock > b->rm_startblock)
2325 		return 1;
2326 	else if (a->rm_owner < b->rm_owner)
2327 		return -1;
2328 	else if (a->rm_owner > b->rm_owner)
2329 		return 1;
2330 	else if (oa < ob)
2331 		return -1;
2332 	else if (oa > ob)
2333 		return 1;
2334 	else
2335 		return 0;
2336 }
2337