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