2 * Copyright (c) 2014 Red Hat, Inc.
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.
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.
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
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.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"
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"
41 #include "xfs_inode.h"
44 * Lookup the first record less than or equal to [bno, len, owner, offset]
45 * in the btree given by cur.
49 struct xfs_btree_cur *cur,
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);
66 * Lookup the record exactly matching [bno, len, owner, offset]
67 * in the btree given by cur.
71 struct xfs_btree_cur *cur,
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);
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.
94 struct xfs_btree_cur *cur,
95 struct xfs_rmap_irec *irec)
97 union xfs_btree_rec rec;
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);
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);
111 trace_xfs_rmap_update_error(cur->bc_mp,
112 cur->bc_private.a.agno, error, _RET_IP_);
118 struct xfs_btree_cur *rcur,
128 trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_private.a.agno, agbno,
129 len, owner, offset, flags);
131 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
134 XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 0, done);
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);
144 XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
147 trace_xfs_rmap_insert_error(rcur->bc_mp,
148 rcur->bc_private.a.agno, error, _RET_IP_);
154 struct xfs_btree_cur *rcur,
164 trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_private.a.agno, agbno,
165 len, owner, offset, flags);
167 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
170 XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
172 error = xfs_btree_delete(rcur, &i);
175 XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done);
178 trace_xfs_rmap_delete_error(rcur->bc_mp,
179 rcur->bc_private.a.agno, error, _RET_IP_);
183 /* Convert an internal btree record to an rmap record. */
185 xfs_rmap_btrec_to_irec(
186 union xfs_btree_rec *rec,
187 struct xfs_rmap_irec *irec)
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),
198 * Get the data from the pointed-to record.
202 struct xfs_btree_cur *cur,
203 struct xfs_rmap_irec *irec,
206 union xfs_btree_rec *rec;
209 error = xfs_btree_get_rec(cur, &rec, stat);
213 return xfs_rmap_btrec_to_irec(rec, irec);
216 struct xfs_find_left_neighbor_info {
217 struct xfs_rmap_irec high;
218 struct xfs_rmap_irec *irec;
222 /* For each rmap given, figure out if it matches the key we want. */
224 xfs_rmap_find_left_neighbor_helper(
225 struct xfs_btree_cur *cur,
226 struct xfs_rmap_irec *rec,
229 struct xfs_find_left_neighbor_info *info = priv;
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,
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;
245 return XFS_BTREE_QUERY_RANGE_ABORT;
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
254 xfs_rmap_find_left_neighbor(
255 struct xfs_btree_cur *cur,
260 struct xfs_rmap_irec *irec,
263 struct xfs_find_left_neighbor_info info;
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)) {
275 info.high.rm_offset = offset - 1;
277 info.high.rm_offset = 0;
278 info.high.rm_flags = flags;
279 info.high.rm_blockcount = 0;
283 trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp,
284 cur->bc_private.a.agno, bno, 0, owner, offset, flags);
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)
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);
298 /* For each rmap given, figure out if it matches the key we want. */
300 xfs_rmap_lookup_le_range_helper(
301 struct xfs_btree_cur *cur,
302 struct xfs_rmap_irec *rec,
305 struct xfs_find_left_neighbor_info *info = priv;
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,
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;
322 return XFS_BTREE_QUERY_RANGE_ABORT;
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.
332 xfs_rmap_lookup_le_range(
333 struct xfs_btree_cur *cur,
338 struct xfs_rmap_irec *irec,
341 struct xfs_find_left_neighbor_info info;
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;
349 info.high.rm_offset = 0;
350 info.high.rm_flags = flags;
351 info.high.rm_blockcount = 0;
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)
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);
371 * Find the extent in the rmap btree and remove it.
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.
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
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.
390 struct xfs_btree_cur *cur,
394 struct xfs_owner_info *oinfo)
396 struct xfs_mount *mp = cur->bc_mp;
397 struct xfs_rmap_irec ltrec;
406 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
407 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
408 (flags & XFS_RMAP_BMBT_BLOCK);
410 flags |= XFS_RMAP_UNWRITTEN;
411 trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
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.
419 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, &i);
422 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
424 error = xfs_rmap_get_rec(cur, <rec, &i);
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;
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.
441 if (owner == XFS_RMAP_OWN_NULL) {
442 XFS_WANT_CORRUPTED_GOTO(mp, bno >= ltrec.rm_startblock +
443 ltrec.rm_blockcount, out_error);
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);
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);
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);
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,
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,
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,
481 error = xfs_btree_delete(cur, &i);
484 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
485 } else if (ltrec.rm_startblock == bno) {
487 * overlap left hand side of extent: move the start, trim the
488 * length and update the current record.
491 * Orig: |oooooooooooooooooooo|
492 * Freeing: |fffffffff|
493 * Result: |rrrrrrrrrr|
496 ltrec.rm_startblock += len;
497 ltrec.rm_blockcount -= len;
499 ltrec.rm_offset += len;
500 error = xfs_rmap_update(cur, <rec);
503 } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
505 * overlap right hand side of extent: trim the length and update
506 * the current record.
509 * Orig: |oooooooooooooooooooo|
510 * Freeing: |fffffffff|
511 * Result: |rrrrrrrrrr|
514 ltrec.rm_blockcount -= len;
515 error = xfs_rmap_update(cur, <rec);
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.
527 * Orig: |oooooooooooooooooooo|
528 * Freeing: |fffffffff|
529 * Result: |rrrrr| |rrrr|
532 xfs_extlen_t orig_len = ltrec.rm_blockcount;
534 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
535 error = xfs_rmap_update(cur, <rec);
539 error = xfs_btree_increment(cur, 0, &i);
543 cur->bc_rec.r.rm_startblock = bno + len;
544 cur->bc_rec.r.rm_blockcount = orig_len - len -
546 cur->bc_rec.r.rm_owner = ltrec.rm_owner;
548 cur->bc_rec.r.rm_offset = 0;
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);
564 trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
568 trace_xfs_rmap_unmap_error(mp, cur->bc_private.a.agno,
574 * Remove a reference to an extent in the rmap btree.
578 struct xfs_trans *tp,
579 struct xfs_buf *agbp,
583 struct xfs_owner_info *oinfo)
585 struct xfs_mount *mp = tp->t_mountp;
586 struct xfs_btree_cur *cur;
589 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
592 cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
594 error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
598 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
602 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
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.
612 xfs_rmap_is_mergeable(
613 struct xfs_rmap_irec *irec,
617 if (irec->rm_owner == XFS_RMAP_OWN_NULL)
619 if (irec->rm_owner != owner)
621 if ((flags & XFS_RMAP_UNWRITTEN) ^
622 (irec->rm_flags & XFS_RMAP_UNWRITTEN))
624 if ((flags & XFS_RMAP_ATTR_FORK) ^
625 (irec->rm_flags & XFS_RMAP_ATTR_FORK))
627 if ((flags & XFS_RMAP_BMBT_BLOCK) ^
628 (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
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
641 struct xfs_btree_cur *cur,
645 struct xfs_owner_info *oinfo)
647 struct xfs_mount *mp = cur->bc_mp;
648 struct xfs_rmap_irec ltrec;
649 struct xfs_rmap_irec gtrec;
656 unsigned int flags = 0;
659 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
661 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
662 (flags & XFS_RMAP_BMBT_BLOCK);
664 flags |= XFS_RMAP_UNWRITTEN;
665 trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
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.
673 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags,
677 XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error);
679 error = xfs_rmap_get_rec(cur, <rec, &have_lt);
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);
688 if (!xfs_rmap_is_mergeable(<rec, owner, flags))
691 XFS_WANT_CORRUPTED_GOTO(mp,
693 ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error);
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
700 error = xfs_btree_increment(cur, 0, &have_gt);
704 error = xfs_rmap_get_rec(cur, >rec, &have_gt);
707 XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error);
708 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock,
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(>rec, owner, flags))
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.
723 ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
724 (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
726 * left edge contiguous, merge into left record.
730 * adding: |aaaaaaaaa|
731 * result: |rrrrrrrrrrrrrrrrrrr|
734 ltrec.rm_blockcount += len;
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) {
741 * right edge also contiguous, delete right record
742 * and merge into left record.
744 * ltbno ltlen gtbno gtlen
745 * orig: |ooooooooo| |ooooooooo|
746 * adding: |aaaaaaaaa|
747 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
749 ltrec.rm_blockcount += gtrec.rm_blockcount;
750 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno,
756 error = xfs_btree_delete(cur, &i);
759 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
762 /* point the cursor back to the left record and update */
763 error = xfs_btree_decrement(cur, 0, &have_gt);
766 error = xfs_rmap_update(cur, <rec);
769 } else if (have_gt &&
770 bno + len == gtrec.rm_startblock &&
771 (ignore_off || offset + len == gtrec.rm_offset)) {
773 * right edge contiguous, merge into right record.
777 * adding: |aaaaaaaaa|
778 * Result: |rrrrrrrrrrrrrrrrrrr|
781 gtrec.rm_startblock = bno;
782 gtrec.rm_blockcount += len;
784 gtrec.rm_offset = offset;
785 error = xfs_rmap_update(cur, >rec);
790 * no contiguous edge with identical owner, insert
791 * new record at current cursor position.
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);
803 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
806 trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
810 trace_xfs_rmap_map_error(mp, cur->bc_private.a.agno,
816 * Add a reference to an extent in the rmap btree.
820 struct xfs_trans *tp,
821 struct xfs_buf *agbp,
825 struct xfs_owner_info *oinfo)
827 struct xfs_mount *mp = tp->t_mountp;
828 struct xfs_btree_cur *cur;
831 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
834 cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
835 error = xfs_rmap_map(cur, bno, len, false, oinfo);
839 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
843 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
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)
860 * Convert an unwritten extent to a real extent or vice versa.
861 * Does not handle overlapping extents.
865 struct xfs_btree_cur *cur,
869 struct xfs_owner_info *oinfo)
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 */
880 unsigned int flags = 0;
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,
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.
898 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
901 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
903 error = xfs_rmap_get_rec(cur, &PREV, &i);
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);
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;
918 * Set flags determining what part of the previous oldext allocation
919 * extent is being replaced by a newext allocation.
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;
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
931 error = xfs_btree_decrement(cur, 0, &i);
935 state |= RMAP_LEFT_VALID;
936 error = xfs_rmap_get_rec(cur, &LEFT, &i);
939 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
940 XFS_WANT_CORRUPTED_GOTO(mp,
941 LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
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;
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
958 error = xfs_btree_increment(cur, 0, &i);
961 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
962 error = xfs_btree_increment(cur, 0, &i);
966 state |= RMAP_RIGHT_VALID;
967 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
970 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
971 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
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;
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;
992 trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
995 /* reset the cursor back to PREV */
996 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i);
999 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1002 * Switch out based on the FILLING and CONTIG state bits.
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:
1009 * Setting all of a previous oldext extent to newext.
1010 * The left and right neighbors are both contiguous with new.
1012 error = xfs_btree_increment(cur, 0, &i);
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,
1020 error = xfs_btree_delete(cur, &i);
1023 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1024 error = xfs_btree_decrement(cur, 0, &i);
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,
1032 error = xfs_btree_delete(cur, &i);
1035 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1036 error = xfs_btree_decrement(cur, 0, &i);
1039 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1041 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1042 error = xfs_rmap_update(cur, &NEW);
1047 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1049 * Setting all of a previous oldext extent to newext.
1050 * The left neighbor is contiguous, the right is not.
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,
1056 error = xfs_btree_delete(cur, &i);
1059 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1060 error = xfs_btree_decrement(cur, 0, &i);
1063 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1065 NEW.rm_blockcount += PREV.rm_blockcount;
1066 error = xfs_rmap_update(cur, &NEW);
1071 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1073 * Setting all of a previous oldext extent to newext.
1074 * The right neighbor is contiguous, the left is not.
1076 error = xfs_btree_increment(cur, 0, &i);
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,
1084 error = xfs_btree_delete(cur, &i);
1087 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1088 error = xfs_btree_decrement(cur, 0, &i);
1091 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1093 NEW.rm_blockcount = len + RIGHT.rm_blockcount;
1094 NEW.rm_flags = newext;
1095 error = xfs_rmap_update(cur, &NEW);
1100 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1102 * Setting all of a previous oldext extent to newext.
1103 * Neither the left nor right neighbors are contiguous with
1107 NEW.rm_flags = newext;
1108 error = xfs_rmap_update(cur, &NEW);
1113 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1115 * Setting the first part of a previous oldext extent to newext.
1116 * The left neighbor is contiguous.
1119 NEW.rm_offset += len;
1120 NEW.rm_startblock += len;
1121 NEW.rm_blockcount -= len;
1122 error = xfs_rmap_update(cur, &NEW);
1125 error = xfs_btree_decrement(cur, 0, &i);
1129 NEW.rm_blockcount += len;
1130 error = xfs_rmap_update(cur, &NEW);
1135 case RMAP_LEFT_FILLING:
1137 * Setting the first part of a previous oldext extent to newext.
1138 * The left neighbor is not contiguous.
1141 NEW.rm_startblock += len;
1142 NEW.rm_offset += len;
1143 NEW.rm_blockcount -= len;
1144 error = xfs_rmap_update(cur, &NEW);
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);
1158 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1161 case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1163 * Setting the last part of a previous oldext extent to newext.
1164 * The right neighbor is contiguous with the new allocation.
1167 NEW.rm_blockcount -= len;
1168 error = xfs_rmap_update(cur, &NEW);
1171 error = xfs_btree_increment(cur, 0, &i);
1175 NEW.rm_offset = offset;
1176 NEW.rm_startblock = bno;
1177 NEW.rm_blockcount += len;
1178 error = xfs_rmap_update(cur, &NEW);
1183 case RMAP_RIGHT_FILLING:
1185 * Setting the last part of a previous oldext extent to newext.
1186 * The right neighbor is not contiguous.
1189 NEW.rm_blockcount -= len;
1190 error = xfs_rmap_update(cur, &NEW);
1193 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
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);
1209 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1214 * Setting the middle part of a previous oldext extent to
1215 * newext. Contiguity is impossible here.
1216 * One extent becomes three extents.
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 -
1224 NEW.rm_flags = PREV.rm_flags;
1225 error = xfs_rmap_update(cur, &NEW);
1228 /* new left extent - oldext */
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,
1236 error = xfs_btree_insert(cur, &i);
1239 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
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.
1245 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
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);
1258 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
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:
1269 * These cases are all impossible.
1274 trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1278 trace_xfs_rmap_convert_error(cur->bc_mp,
1279 cur->bc_private.a.agno, error, _RET_IP_);
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
1289 xfs_rmap_convert_shared(
1290 struct xfs_btree_cur *cur,
1294 struct xfs_owner_info *oinfo)
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 */
1302 uint64_t new_endoff;
1303 unsigned int oldext;
1304 unsigned int newext;
1305 unsigned int flags = 0;
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,
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.
1323 error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1325 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
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;
1333 * Set flags determining what part of the previous oldext allocation
1334 * extent is being replaced by a newext allocation.
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;
1341 /* Is there a left record that abuts our range? */
1342 error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
1347 state |= RMAP_LEFT_VALID;
1348 XFS_WANT_CORRUPTED_GOTO(mp,
1349 LEFT.rm_startblock + LEFT.rm_blockcount <= bno,
1351 if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
1352 state |= RMAP_LEFT_CONTIG;
1355 /* Is there a right record that abuts our range? */
1356 error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1361 state |= RMAP_RIGHT_VALID;
1362 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1365 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1366 XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock,
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;
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;
1385 trace_xfs_rmap_convert_state(mp, cur->bc_private.a.agno, state,
1388 * Switch out based on the FILLING and CONTIG state bits.
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:
1395 * Setting all of a previous oldext extent to newext.
1396 * The left and right neighbors are both contiguous with new.
1398 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1399 RIGHT.rm_blockcount, RIGHT.rm_owner,
1400 RIGHT.rm_offset, RIGHT.rm_flags);
1403 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1404 PREV.rm_blockcount, PREV.rm_owner,
1405 PREV.rm_offset, PREV.rm_flags);
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);
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);
1421 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1423 * Setting all of a previous oldext extent to newext.
1424 * The left neighbor is contiguous, the right is not.
1426 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1427 PREV.rm_blockcount, PREV.rm_owner,
1428 PREV.rm_offset, PREV.rm_flags);
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);
1437 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1438 NEW.rm_blockcount += PREV.rm_blockcount;
1439 error = xfs_rmap_update(cur, &NEW);
1444 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1446 * Setting all of a previous oldext extent to newext.
1447 * The right neighbor is contiguous, the left is not.
1449 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1450 RIGHT.rm_blockcount, RIGHT.rm_owner,
1451 RIGHT.rm_offset, RIGHT.rm_flags);
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);
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);
1468 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1470 * Setting all of a previous oldext extent to newext.
1471 * Neither the left nor right neighbors are contiguous with
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);
1480 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1481 NEW.rm_flags = newext;
1482 error = xfs_rmap_update(cur, &NEW);
1487 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1489 * Setting the first part of a previous oldext extent to newext.
1490 * The left neighbor is contiguous.
1493 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1494 NEW.rm_blockcount, NEW.rm_owner,
1495 NEW.rm_offset, NEW.rm_flags);
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);
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);
1512 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1513 NEW.rm_blockcount += len;
1514 error = xfs_rmap_update(cur, &NEW);
1519 case RMAP_LEFT_FILLING:
1521 * Setting the first part of a previous oldext extent to newext.
1522 * The left neighbor is not contiguous.
1525 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1526 NEW.rm_blockcount, NEW.rm_owner,
1527 NEW.rm_offset, NEW.rm_flags);
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);
1538 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1543 case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1545 * Setting the last part of a previous oldext extent to newext.
1546 * The right neighbor is contiguous with the new allocation.
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);
1554 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1555 NEW.rm_blockcount = offset - NEW.rm_offset;
1556 error = xfs_rmap_update(cur, &NEW);
1560 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1561 NEW.rm_blockcount, NEW.rm_owner,
1562 NEW.rm_offset, NEW.rm_flags);
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);
1575 case RMAP_RIGHT_FILLING:
1577 * Setting the last part of a previous oldext extent to newext.
1578 * The right neighbor is not contiguous.
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);
1586 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1587 NEW.rm_blockcount -= len;
1588 error = xfs_rmap_update(cur, &NEW);
1591 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1598 * Setting the middle part of a previous oldext extent to
1599 * newext. Contiguity is impossible here.
1600 * One extent becomes three extents.
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 -
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,
1614 /* new left extent - oldext */
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);
1621 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done);
1622 NEW.rm_blockcount = offset - NEW.rm_offset;
1623 error = xfs_rmap_update(cur, &NEW);
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,
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:
1647 * These cases are all impossible.
1652 trace_xfs_rmap_convert_done(mp, cur->bc_private.a.agno, bno, len,
1656 trace_xfs_rmap_convert_error(cur->bc_mp,
1657 cur->bc_private.a.agno, error, _RET_IP_);
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.
1672 * For every other situation there can only be one owner for a given extent,
1673 * so we can call the regular _free function.
1676 xfs_rmap_unmap_shared(
1677 struct xfs_btree_cur *cur,
1681 struct xfs_owner_info *oinfo)
1683 struct xfs_mount *mp = cur->bc_mp;
1684 struct xfs_rmap_irec ltrec;
1692 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1694 flags |= XFS_RMAP_UNWRITTEN;
1695 trace_xfs_rmap_unmap(mp, cur->bc_private.a.agno, bno, len,
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.
1703 error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1707 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1708 ltoff = ltrec.rm_offset;
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);
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);
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);
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,
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);
1734 } else if (ltrec.rm_startblock == bno) {
1736 * Overlap left hand side of extent: move the start, trim the
1737 * length and update the current record.
1740 * Orig: |oooooooooooooooooooo|
1741 * Freeing: |fffffffff|
1742 * Result: |rrrrrrrrrr|
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);
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);
1762 } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
1764 * Overlap right hand side of extent: trim the length and
1765 * update the current record.
1768 * Orig: |oooooooooooooooooooo|
1769 * Freeing: |fffffffff|
1770 * Result: |rrrrrrrrrr|
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);
1778 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1779 ltrec.rm_blockcount -= len;
1780 error = xfs_rmap_update(cur, <rec);
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.
1791 * Orig: |oooooooooooooooooooo|
1792 * Freeing: |fffffffff|
1793 * Result: |rrrrr| |rrrr|
1796 xfs_extlen_t orig_len = ltrec.rm_blockcount;
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);
1804 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1805 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
1806 error = xfs_rmap_update(cur, <rec);
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,
1819 trace_xfs_rmap_unmap_done(mp, cur->bc_private.a.agno, bno, len,
1823 trace_xfs_rmap_unmap_error(cur->bc_mp,
1824 cur->bc_private.a.agno, error, _RET_IP_);
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.
1834 * For every other situation there can only be one owner for a given extent,
1835 * so we can call the regular _alloc function.
1838 xfs_rmap_map_shared(
1839 struct xfs_btree_cur *cur,
1843 struct xfs_owner_info *oinfo)
1845 struct xfs_mount *mp = cur->bc_mp;
1846 struct xfs_rmap_irec ltrec;
1847 struct xfs_rmap_irec gtrec;
1854 unsigned int flags = 0;
1856 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1858 flags |= XFS_RMAP_UNWRITTEN;
1859 trace_xfs_rmap_map(mp, cur->bc_private.a.agno, bno, len,
1862 /* Is there a left record that abuts our range? */
1863 error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
1868 !xfs_rmap_is_mergeable(<rec, owner, flags))
1871 /* Is there a right record that abuts our range? */
1872 error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1877 error = xfs_rmap_get_rec(cur, >rec, &have_gt);
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);
1886 if (!xfs_rmap_is_mergeable(>rec, owner, flags))
1891 ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
1892 ltrec.rm_offset + ltrec.rm_blockcount == offset) {
1894 * Left edge contiguous, merge into left record.
1898 * adding: |aaaaaaaaa|
1899 * result: |rrrrrrrrrrrrrrrrrrr|
1902 ltrec.rm_blockcount += len;
1904 bno + len == gtrec.rm_startblock &&
1905 offset + len == gtrec.rm_offset) {
1907 * Right edge also contiguous, delete right record
1908 * and merge into left record.
1910 * ltbno ltlen gtbno gtlen
1911 * orig: |ooooooooo| |ooooooooo|
1912 * adding: |aaaaaaaaa|
1913 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
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);
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);
1929 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error);
1931 error = xfs_rmap_update(cur, <rec);
1934 } else if (have_gt &&
1935 bno + len == gtrec.rm_startblock &&
1936 offset + len == gtrec.rm_offset) {
1938 * Right edge contiguous, merge into right record.
1942 * adding: |aaaaaaaaa|
1943 * Result: |rrrrrrrrrrrrrrrrrrr|
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);
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);
1964 * No contiguous edge with identical owner, insert
1965 * new record at current cursor position.
1967 error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
1972 trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len,
1976 trace_xfs_rmap_map_error(cur->bc_mp,
1977 cur->bc_private.a.agno, error, _RET_IP_);
1981 struct xfs_rmap_query_range_info {
1982 xfs_rmap_query_range_fn fn;
1986 /* Format btree record and pass to our callback. */
1988 xfs_rmap_query_range_helper(
1989 struct xfs_btree_cur *cur,
1990 union xfs_btree_rec *rec,
1993 struct xfs_rmap_query_range_info *query = priv;
1994 struct xfs_rmap_irec irec;
1997 error = xfs_rmap_btrec_to_irec(rec, &irec);
2000 return query->fn(cur, &irec, query->priv);
2003 /* Find all rmaps between two keys. */
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,
2012 union xfs_btree_irec low_brec;
2013 union xfs_btree_irec high_brec;
2014 struct xfs_rmap_query_range_info query;
2016 low_brec.r = *low_rec;
2017 high_brec.r = *high_rec;
2020 return xfs_btree_query_range(cur, &low_brec, &high_brec,
2021 xfs_rmap_query_range_helper, &query);
2024 /* Find all rmaps. */
2027 struct xfs_btree_cur *cur,
2028 xfs_rmap_query_range_fn fn,
2031 struct xfs_rmap_query_range_info query;
2035 return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query);
2038 /* Clean up after calling xfs_rmap_finish_one. */
2040 xfs_rmap_finish_one_cleanup(
2041 struct xfs_trans *tp,
2042 struct xfs_btree_cur *rcur,
2045 struct xfs_buf *agbp;
2049 agbp = rcur->bc_private.a.agbp;
2050 xfs_btree_del_cursor(rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
2052 xfs_trans_brelse(tp, agbp);
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
2063 xfs_rmap_finish_one(
2064 struct xfs_trans *tp,
2065 enum xfs_rmap_intent_type type,
2068 xfs_fileoff_t startoff,
2069 xfs_fsblock_t startblock,
2070 xfs_filblks_t blockcount,
2072 struct xfs_btree_cur **pcur)
2074 struct xfs_mount *mp = tp->t_mountp;
2075 struct xfs_btree_cur *rcur;
2076 struct xfs_buf *agbp = NULL;
2078 xfs_agnumber_t agno;
2079 struct xfs_owner_info oinfo;
2083 agno = XFS_FSB_TO_AGNO(mp, startblock);
2084 ASSERT(agno != NULLAGNUMBER);
2085 bno = XFS_FSB_TO_AGBNO(mp, startblock);
2087 trace_xfs_rmap_deferred(mp, agno, type, bno, owner, whichfork,
2088 startoff, blockcount, state);
2090 if (XFS_TEST_ERROR(false, mp,
2091 XFS_ERRTAG_RMAP_FINISH_ONE))
2095 * If we haven't gotten a cursor or the cursor AG doesn't match
2096 * the startblock, get one now.
2099 if (rcur != NULL && rcur->bc_private.a.agno != agno) {
2100 xfs_rmap_finish_one_cleanup(tp, rcur, 0);
2106 * Refresh the freelist before we start changing the
2107 * rmapbt, because a shape change could cause us to
2110 error = xfs_free_extent_fix_freelist(tp, agno, &agbp);
2114 return -EFSCORRUPTED;
2116 rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
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);
2129 case XFS_RMAP_ALLOC:
2131 error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo);
2133 case XFS_RMAP_MAP_SHARED:
2134 error = xfs_rmap_map_shared(rcur, bno, blockcount, unwritten,
2138 case XFS_RMAP_UNMAP:
2139 error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten,
2142 case XFS_RMAP_UNMAP_SHARED:
2143 error = xfs_rmap_unmap_shared(rcur, bno, blockcount, unwritten,
2146 case XFS_RMAP_CONVERT:
2147 error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten,
2150 case XFS_RMAP_CONVERT_SHARED:
2151 error = xfs_rmap_convert_shared(rcur, bno, blockcount,
2152 !unwritten, &oinfo);
2156 error = -EFSCORRUPTED;
2161 xfs_trans_brelse(tp, agbp);
2167 * Don't defer an rmap if we aren't an rmap filesystem.
2170 xfs_rmap_update_is_needed(
2171 struct xfs_mount *mp,
2174 return xfs_sb_version_hasrmapbt(&mp->m_sb) && whichfork != XFS_COW_FORK;
2178 * Record a rmap intent; the list is kept sorted first by AG and then by
2183 struct xfs_mount *mp,
2184 struct xfs_defer_ops *dfops,
2185 enum xfs_rmap_intent_type type,
2188 struct xfs_bmbt_irec *bmap)
2190 struct xfs_rmap_intent *ri;
2192 trace_xfs_rmap_defer(mp, XFS_FSB_TO_AGNO(mp, bmap->br_startblock),
2194 XFS_FSB_TO_AGBNO(mp, bmap->br_startblock),
2197 bmap->br_blockcount,
2200 ri = kmem_alloc(sizeof(struct xfs_rmap_intent), KM_SLEEP | KM_NOFS);
2201 INIT_LIST_HEAD(&ri->ri_list);
2203 ri->ri_owner = owner;
2204 ri->ri_whichfork = whichfork;
2205 ri->ri_bmap = *bmap;
2207 xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
2211 /* Map an extent into a file. */
2213 xfs_rmap_map_extent(
2214 struct xfs_mount *mp,
2215 struct xfs_defer_ops *dfops,
2216 struct xfs_inode *ip,
2218 struct xfs_bmbt_irec *PREV)
2220 if (!xfs_rmap_update_is_needed(mp, whichfork))
2223 return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2224 XFS_RMAP_MAP_SHARED : XFS_RMAP_MAP, ip->i_ino,
2228 /* Unmap an extent out of a file. */
2230 xfs_rmap_unmap_extent(
2231 struct xfs_mount *mp,
2232 struct xfs_defer_ops *dfops,
2233 struct xfs_inode *ip,
2235 struct xfs_bmbt_irec *PREV)
2237 if (!xfs_rmap_update_is_needed(mp, whichfork))
2240 return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2241 XFS_RMAP_UNMAP_SHARED : XFS_RMAP_UNMAP, ip->i_ino,
2245 /* Convert a data fork extent from unwritten to real or vice versa. */
2247 xfs_rmap_convert_extent(
2248 struct xfs_mount *mp,
2249 struct xfs_defer_ops *dfops,
2250 struct xfs_inode *ip,
2252 struct xfs_bmbt_irec *PREV)
2254 if (!xfs_rmap_update_is_needed(mp, whichfork))
2257 return __xfs_rmap_add(mp, dfops, xfs_is_reflink_inode(ip) ?
2258 XFS_RMAP_CONVERT_SHARED : XFS_RMAP_CONVERT, ip->i_ino,
2262 /* Schedule the creation of an rmap for non-file data. */
2264 xfs_rmap_alloc_extent(
2265 struct xfs_mount *mp,
2266 struct xfs_defer_ops *dfops,
2267 xfs_agnumber_t agno,
2272 struct xfs_bmbt_irec bmap;
2274 if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
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;
2282 return __xfs_rmap_add(mp, dfops, XFS_RMAP_ALLOC, owner,
2283 XFS_DATA_FORK, &bmap);
2286 /* Schedule the deletion of an rmap for non-file data. */
2288 xfs_rmap_free_extent(
2289 struct xfs_mount *mp,
2290 struct xfs_defer_ops *dfops,
2291 xfs_agnumber_t agno,
2296 struct xfs_bmbt_irec bmap;
2298 if (!xfs_rmap_update_is_needed(mp, XFS_DATA_FORK))
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;
2306 return __xfs_rmap_add(mp, dfops, XFS_RMAP_FREE, owner,
2307 XFS_DATA_FORK, &bmap);
2310 /* Compare rmap records. Returns -1 if a < b, 1 if a > b, and 0 if equal. */
2313 const struct xfs_rmap_irec *a,
2314 const struct xfs_rmap_irec *b)
2319 oa = xfs_rmap_irec_offset_pack(a);
2320 ob = xfs_rmap_irec_offset_pack(b);
2322 if (a->rm_startblock < b->rm_startblock)
2324 else if (a->rm_startblock > b->rm_startblock)
2326 else if (a->rm_owner < b->rm_owner)
2328 else if (a->rm_owner > b->rm_owner)