1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2014 Red Hat, Inc.
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
15 #include "xfs_defer.h"
16 #include "xfs_btree.h"
17 #include "xfs_trans.h"
18 #include "xfs_alloc.h"
20 #include "xfs_rmap_btree.h"
21 #include "xfs_trace.h"
22 #include "xfs_errortag.h"
23 #include "xfs_error.h"
24 #include "xfs_inode.h"
27 struct kmem_cache *xfs_rmap_intent_cache;
30 * Lookup the first record less than or equal to [bno, len, owner, offset]
31 * in the btree given by cur.
35 struct xfs_btree_cur *cur,
40 struct xfs_rmap_irec *irec,
46 cur->bc_rec.r.rm_startblock = bno;
47 cur->bc_rec.r.rm_blockcount = 0;
48 cur->bc_rec.r.rm_owner = owner;
49 cur->bc_rec.r.rm_offset = offset;
50 cur->bc_rec.r.rm_flags = flags;
52 error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
53 if (error || !(*stat) || !irec)
56 error = xfs_rmap_get_rec(cur, irec, &get_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_ag.pag->pag_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_ag.pag->pag_agno, error, _RET_IP_);
118 struct xfs_btree_cur *rcur,
128 trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
129 len, owner, offset, flags);
131 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
134 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) {
135 error = -EFSCORRUPTED;
139 rcur->bc_rec.r.rm_startblock = agbno;
140 rcur->bc_rec.r.rm_blockcount = len;
141 rcur->bc_rec.r.rm_owner = owner;
142 rcur->bc_rec.r.rm_offset = offset;
143 rcur->bc_rec.r.rm_flags = flags;
144 error = xfs_btree_insert(rcur, &i);
147 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
148 error = -EFSCORRUPTED;
153 trace_xfs_rmap_insert_error(rcur->bc_mp,
154 rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
160 struct xfs_btree_cur *rcur,
170 trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_ag.pag->pag_agno, agbno,
171 len, owner, offset, flags);
173 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i);
176 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
177 error = -EFSCORRUPTED;
181 error = xfs_btree_delete(rcur, &i);
184 if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
185 error = -EFSCORRUPTED;
190 trace_xfs_rmap_delete_error(rcur->bc_mp,
191 rcur->bc_ag.pag->pag_agno, error, _RET_IP_);
195 /* Convert an internal btree record to an rmap record. */
197 xfs_rmap_btrec_to_irec(
198 const union xfs_btree_rec *rec,
199 struct xfs_rmap_irec *irec)
201 irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock);
202 irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount);
203 irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner);
204 return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec->rmap.rm_offset),
209 * Get the data from the pointed-to record.
213 struct xfs_btree_cur *cur,
214 struct xfs_rmap_irec *irec,
217 struct xfs_mount *mp = cur->bc_mp;
218 xfs_agnumber_t agno = cur->bc_ag.pag->pag_agno;
219 union xfs_btree_rec *rec;
222 error = xfs_btree_get_rec(cur, &rec, stat);
226 if (xfs_rmap_btrec_to_irec(rec, irec))
229 if (irec->rm_blockcount == 0)
231 if (irec->rm_startblock <= XFS_AGFL_BLOCK(mp)) {
232 if (irec->rm_owner != XFS_RMAP_OWN_FS)
234 if (irec->rm_blockcount != XFS_AGFL_BLOCK(mp) + 1)
237 /* check for valid extent range, including overflow */
238 if (!xfs_verify_agbno(mp, agno, irec->rm_startblock))
240 if (irec->rm_startblock >
241 irec->rm_startblock + irec->rm_blockcount)
243 if (!xfs_verify_agbno(mp, agno,
244 irec->rm_startblock + irec->rm_blockcount - 1))
248 if (!(xfs_verify_ino(mp, irec->rm_owner) ||
249 (irec->rm_owner <= XFS_RMAP_OWN_FS &&
250 irec->rm_owner >= XFS_RMAP_OWN_MIN)))
256 "Reverse Mapping BTree record corruption in AG %d detected!",
259 "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x",
260 irec->rm_owner, irec->rm_flags, irec->rm_startblock,
261 irec->rm_blockcount);
262 return -EFSCORRUPTED;
265 struct xfs_find_left_neighbor_info {
266 struct xfs_rmap_irec high;
267 struct xfs_rmap_irec *irec;
270 /* For each rmap given, figure out if it matches the key we want. */
272 xfs_rmap_find_left_neighbor_helper(
273 struct xfs_btree_cur *cur,
274 const struct xfs_rmap_irec *rec,
277 struct xfs_find_left_neighbor_info *info = priv;
279 trace_xfs_rmap_find_left_neighbor_candidate(cur->bc_mp,
280 cur->bc_ag.pag->pag_agno, rec->rm_startblock,
281 rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
284 if (rec->rm_owner != info->high.rm_owner)
286 if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
287 !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
288 rec->rm_offset + rec->rm_blockcount - 1 != info->high.rm_offset)
296 * Find the record to the left of the given extent, being careful only to
297 * return a match with the same owner and adjacent physical and logical
301 xfs_rmap_find_left_neighbor(
302 struct xfs_btree_cur *cur,
307 struct xfs_rmap_irec *irec,
310 struct xfs_find_left_neighbor_info info;
317 info.high.rm_startblock = bno - 1;
318 info.high.rm_owner = owner;
319 if (!XFS_RMAP_NON_INODE_OWNER(owner) &&
320 !(flags & XFS_RMAP_BMBT_BLOCK)) {
323 info.high.rm_offset = offset - 1;
325 info.high.rm_offset = 0;
326 info.high.rm_flags = flags;
327 info.high.rm_blockcount = 0;
330 trace_xfs_rmap_find_left_neighbor_query(cur->bc_mp,
331 cur->bc_ag.pag->pag_agno, bno, 0, owner, offset, flags);
334 * Historically, we always used the range query to walk every reverse
335 * mapping that could possibly overlap the key that the caller asked
336 * for, and filter out the ones that don't. That is very slow when
337 * there are a lot of records.
339 * However, there are two scenarios where the classic btree search can
340 * produce correct results -- if the index contains a record that is an
341 * exact match for the lookup key; and if there are no other records
342 * between the record we want and the key we supplied.
344 * As an optimization, try a non-overlapped lookup first. This makes
345 * extent conversion and remap operations run a bit faster if the
346 * physical extents aren't being shared. If we don't find what we
347 * want, we fall back to the overlapped query.
349 error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
354 error = xfs_rmap_find_left_neighbor_helper(cur, irec, &info);
356 error = xfs_rmap_query_range(cur, &info.high, &info.high,
357 xfs_rmap_find_left_neighbor_helper, &info);
358 if (error != -ECANCELED)
362 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
363 cur->bc_ag.pag->pag_agno, irec->rm_startblock,
364 irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
369 /* For each rmap given, figure out if it matches the key we want. */
371 xfs_rmap_lookup_le_range_helper(
372 struct xfs_btree_cur *cur,
373 const struct xfs_rmap_irec *rec,
376 struct xfs_find_left_neighbor_info *info = priv;
378 trace_xfs_rmap_lookup_le_range_candidate(cur->bc_mp,
379 cur->bc_ag.pag->pag_agno, rec->rm_startblock,
380 rec->rm_blockcount, rec->rm_owner, rec->rm_offset,
383 if (rec->rm_owner != info->high.rm_owner)
385 if (!XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) &&
386 !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK) &&
387 (rec->rm_offset > info->high.rm_offset ||
388 rec->rm_offset + rec->rm_blockcount <= info->high.rm_offset))
396 * Find the record to the left of the given extent, being careful only to
397 * return a match with the same owner and overlapping physical and logical
398 * block ranges. This is the overlapping-interval version of
399 * xfs_rmap_lookup_le.
402 xfs_rmap_lookup_le_range(
403 struct xfs_btree_cur *cur,
408 struct xfs_rmap_irec *irec,
411 struct xfs_find_left_neighbor_info info;
415 info.high.rm_startblock = bno;
416 info.high.rm_owner = owner;
417 if (!XFS_RMAP_NON_INODE_OWNER(owner) && !(flags & XFS_RMAP_BMBT_BLOCK))
418 info.high.rm_offset = offset;
420 info.high.rm_offset = 0;
421 info.high.rm_flags = flags;
422 info.high.rm_blockcount = 0;
426 trace_xfs_rmap_lookup_le_range(cur->bc_mp, cur->bc_ag.pag->pag_agno,
427 bno, 0, owner, offset, flags);
430 * Historically, we always used the range query to walk every reverse
431 * mapping that could possibly overlap the key that the caller asked
432 * for, and filter out the ones that don't. That is very slow when
433 * there are a lot of records.
435 * However, there are two scenarios where the classic btree search can
436 * produce correct results -- if the index contains a record that is an
437 * exact match for the lookup key; and if there are no other records
438 * between the record we want and the key we supplied.
440 * As an optimization, try a non-overlapped lookup first. This makes
441 * scrub run much faster on most filesystems because bmbt records are
442 * usually an exact match for rmap records. If we don't find what we
443 * want, we fall back to the overlapped query.
445 error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, irec,
450 error = xfs_rmap_lookup_le_range_helper(cur, irec, &info);
452 error = xfs_rmap_query_range(cur, &info.high, &info.high,
453 xfs_rmap_lookup_le_range_helper, &info);
454 if (error != -ECANCELED)
458 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
459 cur->bc_ag.pag->pag_agno, irec->rm_startblock,
460 irec->rm_blockcount, irec->rm_owner, irec->rm_offset,
466 * Perform all the relevant owner checks for a removal op. If we're doing an
467 * unknown-owner removal then we have no owner information to check.
470 xfs_rmap_free_check_owner(
471 struct xfs_mount *mp,
473 struct xfs_rmap_irec *rec,
481 if (owner == XFS_RMAP_OWN_UNKNOWN)
484 /* Make sure the unwritten flag matches. */
485 if (XFS_IS_CORRUPT(mp,
486 (flags & XFS_RMAP_UNWRITTEN) !=
487 (rec->rm_flags & XFS_RMAP_UNWRITTEN))) {
488 error = -EFSCORRUPTED;
492 /* Make sure the owner matches what we expect to find in the tree. */
493 if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) {
494 error = -EFSCORRUPTED;
498 /* Check the offset, if necessary. */
499 if (XFS_RMAP_NON_INODE_OWNER(owner))
502 if (flags & XFS_RMAP_BMBT_BLOCK) {
503 if (XFS_IS_CORRUPT(mp,
504 !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) {
505 error = -EFSCORRUPTED;
509 if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) {
510 error = -EFSCORRUPTED;
513 if (XFS_IS_CORRUPT(mp,
514 offset + len > ltoff + rec->rm_blockcount)) {
515 error = -EFSCORRUPTED;
525 * Find the extent in the rmap btree and remove it.
527 * The record we find should always be an exact match for the extent that we're
528 * looking for, since we insert them into the btree without modification.
530 * Special Case #1: when growing the filesystem, we "free" an extent when
531 * growing the last AG. This extent is new space and so it is not tracked as
532 * used space in the btree. The growfs code will pass in an owner of
533 * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
534 * extent. We verify that - the extent lookup result in a record that does not
537 * Special Case #2: EFIs do not record the owner of the extent, so when
538 * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
539 * btree to ignore the owner (i.e. wildcard match) so we don't trigger
540 * corruption checks during log recovery.
544 struct xfs_btree_cur *cur,
548 const struct xfs_owner_info *oinfo)
550 struct xfs_mount *mp = cur->bc_mp;
551 struct xfs_rmap_irec ltrec;
560 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
561 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
562 (flags & XFS_RMAP_BMBT_BLOCK);
564 flags |= XFS_RMAP_UNWRITTEN;
565 trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
569 * We should always have a left record because there's a static record
570 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
571 * will not ever be removed from the tree.
573 error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, <rec, &i);
576 if (XFS_IS_CORRUPT(mp, i != 1)) {
577 error = -EFSCORRUPTED;
581 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
582 cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
583 ltrec.rm_blockcount, ltrec.rm_owner,
584 ltrec.rm_offset, ltrec.rm_flags);
585 ltoff = ltrec.rm_offset;
588 * For growfs, the incoming extent must be beyond the left record we
589 * just found as it is new space and won't be used by anyone. This is
590 * just a corruption check as we don't actually do anything with this
591 * extent. Note that we need to use >= instead of > because it might
592 * be the case that the "left" extent goes all the way to EOFS.
594 if (owner == XFS_RMAP_OWN_NULL) {
595 if (XFS_IS_CORRUPT(mp,
597 ltrec.rm_startblock + ltrec.rm_blockcount)) {
598 error = -EFSCORRUPTED;
605 * If we're doing an unknown-owner removal for EFI recovery, we expect
606 * to find the full range in the rmapbt or nothing at all. If we
607 * don't find any rmaps overlapping either end of the range, we're
608 * done. Hopefully this means that the EFI creator already queued
609 * (and finished) a RUI to remove the rmap.
611 if (owner == XFS_RMAP_OWN_UNKNOWN &&
612 ltrec.rm_startblock + ltrec.rm_blockcount <= bno) {
613 struct xfs_rmap_irec rtrec;
615 error = xfs_btree_increment(cur, 0, &i);
620 error = xfs_rmap_get_rec(cur, &rtrec, &i);
623 if (XFS_IS_CORRUPT(mp, i != 1)) {
624 error = -EFSCORRUPTED;
627 if (rtrec.rm_startblock >= bno + len)
631 /* Make sure the extent we found covers the entire freeing range. */
632 if (XFS_IS_CORRUPT(mp,
633 ltrec.rm_startblock > bno ||
634 ltrec.rm_startblock + ltrec.rm_blockcount <
636 error = -EFSCORRUPTED;
640 /* Check owner information. */
641 error = xfs_rmap_free_check_owner(mp, ltoff, <rec, len, owner,
646 if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
647 /* exact match, simply remove the record from rmap tree */
648 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
649 ltrec.rm_startblock, ltrec.rm_blockcount,
650 ltrec.rm_owner, ltrec.rm_offset,
652 error = xfs_btree_delete(cur, &i);
655 if (XFS_IS_CORRUPT(mp, i != 1)) {
656 error = -EFSCORRUPTED;
659 } else if (ltrec.rm_startblock == bno) {
661 * overlap left hand side of extent: move the start, trim the
662 * length and update the current record.
665 * Orig: |oooooooooooooooooooo|
666 * Freeing: |fffffffff|
667 * Result: |rrrrrrrrrr|
670 ltrec.rm_startblock += len;
671 ltrec.rm_blockcount -= len;
673 ltrec.rm_offset += len;
674 error = xfs_rmap_update(cur, <rec);
677 } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
679 * overlap right hand side of extent: trim the length and update
680 * the current record.
683 * Orig: |oooooooooooooooooooo|
684 * Freeing: |fffffffff|
685 * Result: |rrrrrrrrrr|
688 ltrec.rm_blockcount -= len;
689 error = xfs_rmap_update(cur, <rec);
695 * overlap middle of extent: trim the length of the existing
696 * record to the length of the new left-extent size, increment
697 * the insertion position so we can insert a new record
698 * containing the remaining right-extent space.
701 * Orig: |oooooooooooooooooooo|
702 * Freeing: |fffffffff|
703 * Result: |rrrrr| |rrrr|
706 xfs_extlen_t orig_len = ltrec.rm_blockcount;
708 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
709 error = xfs_rmap_update(cur, <rec);
713 error = xfs_btree_increment(cur, 0, &i);
717 cur->bc_rec.r.rm_startblock = bno + len;
718 cur->bc_rec.r.rm_blockcount = orig_len - len -
720 cur->bc_rec.r.rm_owner = ltrec.rm_owner;
722 cur->bc_rec.r.rm_offset = 0;
724 cur->bc_rec.r.rm_offset = offset + len;
725 cur->bc_rec.r.rm_flags = flags;
726 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
727 cur->bc_rec.r.rm_startblock,
728 cur->bc_rec.r.rm_blockcount,
729 cur->bc_rec.r.rm_owner,
730 cur->bc_rec.r.rm_offset,
731 cur->bc_rec.r.rm_flags);
732 error = xfs_btree_insert(cur, &i);
738 trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
742 trace_xfs_rmap_unmap_error(mp, cur->bc_ag.pag->pag_agno,
748 * Remove a reference to an extent in the rmap btree.
752 struct xfs_trans *tp,
753 struct xfs_buf *agbp,
754 struct xfs_perag *pag,
757 const struct xfs_owner_info *oinfo)
759 struct xfs_mount *mp = tp->t_mountp;
760 struct xfs_btree_cur *cur;
763 if (!xfs_has_rmapbt(mp))
766 cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
768 error = xfs_rmap_unmap(cur, bno, len, false, oinfo);
770 xfs_btree_del_cursor(cur, error);
775 * A mergeable rmap must have the same owner and the same values for
776 * the unwritten, attr_fork, and bmbt flags. The startblock and
777 * offset are checked separately.
780 xfs_rmap_is_mergeable(
781 struct xfs_rmap_irec *irec,
785 if (irec->rm_owner == XFS_RMAP_OWN_NULL)
787 if (irec->rm_owner != owner)
789 if ((flags & XFS_RMAP_UNWRITTEN) ^
790 (irec->rm_flags & XFS_RMAP_UNWRITTEN))
792 if ((flags & XFS_RMAP_ATTR_FORK) ^
793 (irec->rm_flags & XFS_RMAP_ATTR_FORK))
795 if ((flags & XFS_RMAP_BMBT_BLOCK) ^
796 (irec->rm_flags & XFS_RMAP_BMBT_BLOCK))
802 * When we allocate a new block, the first thing we do is add a reference to
803 * the extent in the rmap btree. This takes the form of a [agbno, length,
804 * owner, offset] record. Flags are encoded in the high bits of the offset
809 struct xfs_btree_cur *cur,
813 const struct xfs_owner_info *oinfo)
815 struct xfs_mount *mp = cur->bc_mp;
816 struct xfs_rmap_irec ltrec;
817 struct xfs_rmap_irec gtrec;
824 unsigned int flags = 0;
827 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
829 ignore_off = XFS_RMAP_NON_INODE_OWNER(owner) ||
830 (flags & XFS_RMAP_BMBT_BLOCK);
832 flags |= XFS_RMAP_UNWRITTEN;
833 trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
835 ASSERT(!xfs_rmap_should_skip_owner_update(oinfo));
838 * For the initial lookup, look for an exact match or the left-adjacent
839 * record for our insertion point. This will also give us the record for
840 * start block contiguity tests.
842 error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, <rec,
847 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
848 cur->bc_ag.pag->pag_agno, ltrec.rm_startblock,
849 ltrec.rm_blockcount, ltrec.rm_owner,
850 ltrec.rm_offset, ltrec.rm_flags);
852 if (!xfs_rmap_is_mergeable(<rec, owner, flags))
856 if (XFS_IS_CORRUPT(mp,
858 ltrec.rm_startblock + ltrec.rm_blockcount > bno)) {
859 error = -EFSCORRUPTED;
864 * Increment the cursor to see if we have a right-adjacent record to our
865 * insertion point. This will give us the record for end block
868 error = xfs_btree_increment(cur, 0, &have_gt);
872 error = xfs_rmap_get_rec(cur, >rec, &have_gt);
875 if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
876 error = -EFSCORRUPTED;
879 if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) {
880 error = -EFSCORRUPTED;
883 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
884 cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
885 gtrec.rm_blockcount, gtrec.rm_owner,
886 gtrec.rm_offset, gtrec.rm_flags);
887 if (!xfs_rmap_is_mergeable(>rec, owner, flags))
892 * Note: cursor currently points one record to the right of ltrec, even
893 * if there is no record in the tree to the right.
896 ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
897 (ignore_off || ltrec.rm_offset + ltrec.rm_blockcount == offset)) {
899 * left edge contiguous, merge into left record.
903 * adding: |aaaaaaaaa|
904 * result: |rrrrrrrrrrrrrrrrrrr|
907 ltrec.rm_blockcount += len;
909 bno + len == gtrec.rm_startblock &&
910 (ignore_off || offset + len == gtrec.rm_offset) &&
911 (unsigned long)ltrec.rm_blockcount + len +
912 gtrec.rm_blockcount <= XFS_RMAP_LEN_MAX) {
914 * right edge also contiguous, delete right record
915 * and merge into left record.
917 * ltbno ltlen gtbno gtlen
918 * orig: |ooooooooo| |ooooooooo|
919 * adding: |aaaaaaaaa|
920 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
922 ltrec.rm_blockcount += gtrec.rm_blockcount;
923 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
929 error = xfs_btree_delete(cur, &i);
932 if (XFS_IS_CORRUPT(mp, i != 1)) {
933 error = -EFSCORRUPTED;
938 /* point the cursor back to the left record and update */
939 error = xfs_btree_decrement(cur, 0, &have_gt);
942 error = xfs_rmap_update(cur, <rec);
945 } else if (have_gt &&
946 bno + len == gtrec.rm_startblock &&
947 (ignore_off || offset + len == gtrec.rm_offset)) {
949 * right edge contiguous, merge into right record.
953 * adding: |aaaaaaaaa|
954 * Result: |rrrrrrrrrrrrrrrrrrr|
957 gtrec.rm_startblock = bno;
958 gtrec.rm_blockcount += len;
960 gtrec.rm_offset = offset;
961 error = xfs_rmap_update(cur, >rec);
966 * no contiguous edge with identical owner, insert
967 * new record at current cursor position.
969 cur->bc_rec.r.rm_startblock = bno;
970 cur->bc_rec.r.rm_blockcount = len;
971 cur->bc_rec.r.rm_owner = owner;
972 cur->bc_rec.r.rm_offset = offset;
973 cur->bc_rec.r.rm_flags = flags;
974 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
975 owner, offset, flags);
976 error = xfs_btree_insert(cur, &i);
979 if (XFS_IS_CORRUPT(mp, i != 1)) {
980 error = -EFSCORRUPTED;
985 trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
989 trace_xfs_rmap_map_error(mp, cur->bc_ag.pag->pag_agno,
995 * Add a reference to an extent in the rmap btree.
999 struct xfs_trans *tp,
1000 struct xfs_buf *agbp,
1001 struct xfs_perag *pag,
1004 const struct xfs_owner_info *oinfo)
1006 struct xfs_mount *mp = tp->t_mountp;
1007 struct xfs_btree_cur *cur;
1010 if (!xfs_has_rmapbt(mp))
1013 cur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
1014 error = xfs_rmap_map(cur, bno, len, false, oinfo);
1016 xfs_btree_del_cursor(cur, error);
1020 #define RMAP_LEFT_CONTIG (1 << 0)
1021 #define RMAP_RIGHT_CONTIG (1 << 1)
1022 #define RMAP_LEFT_FILLING (1 << 2)
1023 #define RMAP_RIGHT_FILLING (1 << 3)
1024 #define RMAP_LEFT_VALID (1 << 6)
1025 #define RMAP_RIGHT_VALID (1 << 7)
1033 * Convert an unwritten extent to a real extent or vice versa.
1034 * Does not handle overlapping extents.
1038 struct xfs_btree_cur *cur,
1042 const struct xfs_owner_info *oinfo)
1044 struct xfs_mount *mp = cur->bc_mp;
1045 struct xfs_rmap_irec r[4]; /* neighbor extent entries */
1046 /* left is 0, right is 1, */
1047 /* prev is 2, new is 3 */
1050 uint64_t new_endoff;
1051 unsigned int oldext;
1052 unsigned int newext;
1053 unsigned int flags = 0;
1058 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1059 ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1060 (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1061 oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1062 new_endoff = offset + len;
1063 trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1067 * For the initial lookup, look for an exact match or the left-adjacent
1068 * record for our insertion point. This will also give us the record for
1069 * start block contiguity tests.
1071 error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, &PREV, &i);
1074 if (XFS_IS_CORRUPT(mp, i != 1)) {
1075 error = -EFSCORRUPTED;
1079 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp,
1080 cur->bc_ag.pag->pag_agno, PREV.rm_startblock,
1081 PREV.rm_blockcount, PREV.rm_owner,
1082 PREV.rm_offset, PREV.rm_flags);
1084 ASSERT(PREV.rm_offset <= offset);
1085 ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1086 ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1087 newext = ~oldext & XFS_RMAP_UNWRITTEN;
1090 * Set flags determining what part of the previous oldext allocation
1091 * extent is being replaced by a newext allocation.
1093 if (PREV.rm_offset == offset)
1094 state |= RMAP_LEFT_FILLING;
1095 if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1096 state |= RMAP_RIGHT_FILLING;
1099 * Decrement the cursor to see if we have a left-adjacent record to our
1100 * insertion point. This will give us the record for end block
1103 error = xfs_btree_decrement(cur, 0, &i);
1107 state |= RMAP_LEFT_VALID;
1108 error = xfs_rmap_get_rec(cur, &LEFT, &i);
1111 if (XFS_IS_CORRUPT(mp, i != 1)) {
1112 error = -EFSCORRUPTED;
1115 if (XFS_IS_CORRUPT(mp,
1116 LEFT.rm_startblock + LEFT.rm_blockcount >
1118 error = -EFSCORRUPTED;
1121 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp,
1122 cur->bc_ag.pag->pag_agno, LEFT.rm_startblock,
1123 LEFT.rm_blockcount, LEFT.rm_owner,
1124 LEFT.rm_offset, LEFT.rm_flags);
1125 if (LEFT.rm_startblock + LEFT.rm_blockcount == bno &&
1126 LEFT.rm_offset + LEFT.rm_blockcount == offset &&
1127 xfs_rmap_is_mergeable(&LEFT, owner, newext))
1128 state |= RMAP_LEFT_CONTIG;
1132 * Increment the cursor to see if we have a right-adjacent record to our
1133 * insertion point. This will give us the record for end block
1136 error = xfs_btree_increment(cur, 0, &i);
1139 if (XFS_IS_CORRUPT(mp, i != 1)) {
1140 error = -EFSCORRUPTED;
1143 error = xfs_btree_increment(cur, 0, &i);
1147 state |= RMAP_RIGHT_VALID;
1148 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1151 if (XFS_IS_CORRUPT(mp, i != 1)) {
1152 error = -EFSCORRUPTED;
1155 if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
1156 error = -EFSCORRUPTED;
1159 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1160 cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
1161 RIGHT.rm_blockcount, RIGHT.rm_owner,
1162 RIGHT.rm_offset, RIGHT.rm_flags);
1163 if (bno + len == RIGHT.rm_startblock &&
1164 offset + len == RIGHT.rm_offset &&
1165 xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1166 state |= RMAP_RIGHT_CONTIG;
1169 /* check that left + prev + right is not too long */
1170 if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1171 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1172 (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1173 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1174 (unsigned long)LEFT.rm_blockcount + len +
1175 RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1176 state &= ~RMAP_RIGHT_CONTIG;
1178 trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
1181 /* reset the cursor back to PREV */
1182 error = xfs_rmap_lookup_le(cur, bno, owner, offset, oldext, NULL, &i);
1185 if (XFS_IS_CORRUPT(mp, i != 1)) {
1186 error = -EFSCORRUPTED;
1191 * Switch out based on the FILLING and CONTIG state bits.
1193 switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1194 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1195 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1196 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1198 * Setting all of a previous oldext extent to newext.
1199 * The left and right neighbors are both contiguous with new.
1201 error = xfs_btree_increment(cur, 0, &i);
1204 if (XFS_IS_CORRUPT(mp, i != 1)) {
1205 error = -EFSCORRUPTED;
1208 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1209 RIGHT.rm_startblock, RIGHT.rm_blockcount,
1210 RIGHT.rm_owner, RIGHT.rm_offset,
1212 error = xfs_btree_delete(cur, &i);
1215 if (XFS_IS_CORRUPT(mp, i != 1)) {
1216 error = -EFSCORRUPTED;
1219 error = xfs_btree_decrement(cur, 0, &i);
1222 if (XFS_IS_CORRUPT(mp, i != 1)) {
1223 error = -EFSCORRUPTED;
1226 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1227 PREV.rm_startblock, PREV.rm_blockcount,
1228 PREV.rm_owner, PREV.rm_offset,
1230 error = xfs_btree_delete(cur, &i);
1233 if (XFS_IS_CORRUPT(mp, i != 1)) {
1234 error = -EFSCORRUPTED;
1237 error = xfs_btree_decrement(cur, 0, &i);
1240 if (XFS_IS_CORRUPT(mp, i != 1)) {
1241 error = -EFSCORRUPTED;
1245 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1246 error = xfs_rmap_update(cur, &NEW);
1251 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1253 * Setting all of a previous oldext extent to newext.
1254 * The left neighbor is contiguous, the right is not.
1256 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1257 PREV.rm_startblock, PREV.rm_blockcount,
1258 PREV.rm_owner, PREV.rm_offset,
1260 error = xfs_btree_delete(cur, &i);
1263 if (XFS_IS_CORRUPT(mp, i != 1)) {
1264 error = -EFSCORRUPTED;
1267 error = xfs_btree_decrement(cur, 0, &i);
1270 if (XFS_IS_CORRUPT(mp, i != 1)) {
1271 error = -EFSCORRUPTED;
1275 NEW.rm_blockcount += PREV.rm_blockcount;
1276 error = xfs_rmap_update(cur, &NEW);
1281 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1283 * Setting all of a previous oldext extent to newext.
1284 * The right neighbor is contiguous, the left is not.
1286 error = xfs_btree_increment(cur, 0, &i);
1289 if (XFS_IS_CORRUPT(mp, i != 1)) {
1290 error = -EFSCORRUPTED;
1293 trace_xfs_rmap_delete(mp, cur->bc_ag.pag->pag_agno,
1294 RIGHT.rm_startblock, RIGHT.rm_blockcount,
1295 RIGHT.rm_owner, RIGHT.rm_offset,
1297 error = xfs_btree_delete(cur, &i);
1300 if (XFS_IS_CORRUPT(mp, i != 1)) {
1301 error = -EFSCORRUPTED;
1304 error = xfs_btree_decrement(cur, 0, &i);
1307 if (XFS_IS_CORRUPT(mp, i != 1)) {
1308 error = -EFSCORRUPTED;
1312 NEW.rm_blockcount = len + RIGHT.rm_blockcount;
1313 NEW.rm_flags = newext;
1314 error = xfs_rmap_update(cur, &NEW);
1319 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1321 * Setting all of a previous oldext extent to newext.
1322 * Neither the left nor right neighbors are contiguous with
1326 NEW.rm_flags = newext;
1327 error = xfs_rmap_update(cur, &NEW);
1332 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1334 * Setting the first part of a previous oldext extent to newext.
1335 * The left neighbor is contiguous.
1338 NEW.rm_offset += len;
1339 NEW.rm_startblock += len;
1340 NEW.rm_blockcount -= len;
1341 error = xfs_rmap_update(cur, &NEW);
1344 error = xfs_btree_decrement(cur, 0, &i);
1348 NEW.rm_blockcount += len;
1349 error = xfs_rmap_update(cur, &NEW);
1354 case RMAP_LEFT_FILLING:
1356 * Setting the first part of a previous oldext extent to newext.
1357 * The left neighbor is not contiguous.
1360 NEW.rm_startblock += len;
1361 NEW.rm_offset += len;
1362 NEW.rm_blockcount -= len;
1363 error = xfs_rmap_update(cur, &NEW);
1366 NEW.rm_startblock = bno;
1367 NEW.rm_owner = owner;
1368 NEW.rm_offset = offset;
1369 NEW.rm_blockcount = len;
1370 NEW.rm_flags = newext;
1371 cur->bc_rec.r = NEW;
1372 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
1373 len, owner, offset, newext);
1374 error = xfs_btree_insert(cur, &i);
1377 if (XFS_IS_CORRUPT(mp, i != 1)) {
1378 error = -EFSCORRUPTED;
1383 case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1385 * Setting the last part of a previous oldext extent to newext.
1386 * The right neighbor is contiguous with the new allocation.
1389 NEW.rm_blockcount -= len;
1390 error = xfs_rmap_update(cur, &NEW);
1393 error = xfs_btree_increment(cur, 0, &i);
1397 NEW.rm_offset = offset;
1398 NEW.rm_startblock = bno;
1399 NEW.rm_blockcount += len;
1400 error = xfs_rmap_update(cur, &NEW);
1405 case RMAP_RIGHT_FILLING:
1407 * Setting the last part of a previous oldext extent to newext.
1408 * The right neighbor is not contiguous.
1411 NEW.rm_blockcount -= len;
1412 error = xfs_rmap_update(cur, &NEW);
1415 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1419 if (XFS_IS_CORRUPT(mp, i != 0)) {
1420 error = -EFSCORRUPTED;
1423 NEW.rm_startblock = bno;
1424 NEW.rm_owner = owner;
1425 NEW.rm_offset = offset;
1426 NEW.rm_blockcount = len;
1427 NEW.rm_flags = newext;
1428 cur->bc_rec.r = NEW;
1429 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno,
1430 len, owner, offset, newext);
1431 error = xfs_btree_insert(cur, &i);
1434 if (XFS_IS_CORRUPT(mp, i != 1)) {
1435 error = -EFSCORRUPTED;
1442 * Setting the middle part of a previous oldext extent to
1443 * newext. Contiguity is impossible here.
1444 * One extent becomes three extents.
1446 /* new right extent - oldext */
1447 NEW.rm_startblock = bno + len;
1448 NEW.rm_owner = owner;
1449 NEW.rm_offset = new_endoff;
1450 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1452 NEW.rm_flags = PREV.rm_flags;
1453 error = xfs_rmap_update(cur, &NEW);
1456 /* new left extent - oldext */
1458 NEW.rm_blockcount = offset - PREV.rm_offset;
1459 cur->bc_rec.r = NEW;
1460 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno,
1461 NEW.rm_startblock, NEW.rm_blockcount,
1462 NEW.rm_owner, NEW.rm_offset,
1464 error = xfs_btree_insert(cur, &i);
1467 if (XFS_IS_CORRUPT(mp, i != 1)) {
1468 error = -EFSCORRUPTED;
1472 * Reset the cursor to the position of the new extent
1473 * we are about to insert as we can't trust it after
1474 * the previous insert.
1476 error = xfs_rmap_lookup_eq(cur, bno, len, owner, offset,
1480 if (XFS_IS_CORRUPT(mp, i != 0)) {
1481 error = -EFSCORRUPTED;
1484 /* new middle extent - newext */
1485 cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN;
1486 cur->bc_rec.r.rm_flags |= newext;
1487 trace_xfs_rmap_insert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1488 owner, offset, newext);
1489 error = xfs_btree_insert(cur, &i);
1492 if (XFS_IS_CORRUPT(mp, i != 1)) {
1493 error = -EFSCORRUPTED;
1498 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1499 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1500 case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1501 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1502 case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1503 case RMAP_LEFT_CONTIG:
1504 case RMAP_RIGHT_CONTIG:
1506 * These cases are all impossible.
1511 trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1515 trace_xfs_rmap_convert_error(cur->bc_mp,
1516 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
1521 * Convert an unwritten extent to a real extent or vice versa. If there is no
1522 * possibility of overlapping extents, delegate to the simpler convert
1526 xfs_rmap_convert_shared(
1527 struct xfs_btree_cur *cur,
1531 const struct xfs_owner_info *oinfo)
1533 struct xfs_mount *mp = cur->bc_mp;
1534 struct xfs_rmap_irec r[4]; /* neighbor extent entries */
1535 /* left is 0, right is 1, */
1536 /* prev is 2, new is 3 */
1539 uint64_t new_endoff;
1540 unsigned int oldext;
1541 unsigned int newext;
1542 unsigned int flags = 0;
1547 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1548 ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner) ||
1549 (flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))));
1550 oldext = unwritten ? XFS_RMAP_UNWRITTEN : 0;
1551 new_endoff = offset + len;
1552 trace_xfs_rmap_convert(mp, cur->bc_ag.pag->pag_agno, bno, len,
1556 * For the initial lookup, look for and exact match or the left-adjacent
1557 * record for our insertion point. This will also give us the record for
1558 * start block contiguity tests.
1560 error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, oldext,
1564 if (XFS_IS_CORRUPT(mp, i != 1)) {
1565 error = -EFSCORRUPTED;
1569 ASSERT(PREV.rm_offset <= offset);
1570 ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff);
1571 ASSERT((PREV.rm_flags & XFS_RMAP_UNWRITTEN) == oldext);
1572 newext = ~oldext & XFS_RMAP_UNWRITTEN;
1575 * Set flags determining what part of the previous oldext allocation
1576 * extent is being replaced by a newext allocation.
1578 if (PREV.rm_offset == offset)
1579 state |= RMAP_LEFT_FILLING;
1580 if (PREV.rm_offset + PREV.rm_blockcount == new_endoff)
1581 state |= RMAP_RIGHT_FILLING;
1583 /* Is there a left record that abuts our range? */
1584 error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, newext,
1589 state |= RMAP_LEFT_VALID;
1590 if (XFS_IS_CORRUPT(mp,
1591 LEFT.rm_startblock + LEFT.rm_blockcount >
1593 error = -EFSCORRUPTED;
1596 if (xfs_rmap_is_mergeable(&LEFT, owner, newext))
1597 state |= RMAP_LEFT_CONTIG;
1600 /* Is there a right record that abuts our range? */
1601 error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
1606 state |= RMAP_RIGHT_VALID;
1607 error = xfs_rmap_get_rec(cur, &RIGHT, &i);
1610 if (XFS_IS_CORRUPT(mp, i != 1)) {
1611 error = -EFSCORRUPTED;
1614 if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
1615 error = -EFSCORRUPTED;
1618 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
1619 cur->bc_ag.pag->pag_agno, RIGHT.rm_startblock,
1620 RIGHT.rm_blockcount, RIGHT.rm_owner,
1621 RIGHT.rm_offset, RIGHT.rm_flags);
1622 if (xfs_rmap_is_mergeable(&RIGHT, owner, newext))
1623 state |= RMAP_RIGHT_CONTIG;
1626 /* check that left + prev + right is not too long */
1627 if ((state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1628 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) ==
1629 (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1630 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG) &&
1631 (unsigned long)LEFT.rm_blockcount + len +
1632 RIGHT.rm_blockcount > XFS_RMAP_LEN_MAX)
1633 state &= ~RMAP_RIGHT_CONTIG;
1635 trace_xfs_rmap_convert_state(mp, cur->bc_ag.pag->pag_agno, state,
1638 * Switch out based on the FILLING and CONTIG state bits.
1640 switch (state & (RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1641 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG)) {
1642 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG |
1643 RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1645 * Setting all of a previous oldext extent to newext.
1646 * The left and right neighbors are both contiguous with new.
1648 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1649 RIGHT.rm_blockcount, RIGHT.rm_owner,
1650 RIGHT.rm_offset, RIGHT.rm_flags);
1653 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1654 PREV.rm_blockcount, PREV.rm_owner,
1655 PREV.rm_offset, PREV.rm_flags);
1659 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1660 NEW.rm_blockcount, NEW.rm_owner,
1661 NEW.rm_offset, NEW.rm_flags, &i);
1664 if (XFS_IS_CORRUPT(mp, i != 1)) {
1665 error = -EFSCORRUPTED;
1668 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount;
1669 error = xfs_rmap_update(cur, &NEW);
1674 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1676 * Setting all of a previous oldext extent to newext.
1677 * The left neighbor is contiguous, the right is not.
1679 error = xfs_rmap_delete(cur, PREV.rm_startblock,
1680 PREV.rm_blockcount, PREV.rm_owner,
1681 PREV.rm_offset, PREV.rm_flags);
1685 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1686 NEW.rm_blockcount, NEW.rm_owner,
1687 NEW.rm_offset, NEW.rm_flags, &i);
1690 if (XFS_IS_CORRUPT(mp, i != 1)) {
1691 error = -EFSCORRUPTED;
1694 NEW.rm_blockcount += PREV.rm_blockcount;
1695 error = xfs_rmap_update(cur, &NEW);
1700 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1702 * Setting all of a previous oldext extent to newext.
1703 * The right neighbor is contiguous, the left is not.
1705 error = xfs_rmap_delete(cur, RIGHT.rm_startblock,
1706 RIGHT.rm_blockcount, RIGHT.rm_owner,
1707 RIGHT.rm_offset, RIGHT.rm_flags);
1711 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1712 NEW.rm_blockcount, NEW.rm_owner,
1713 NEW.rm_offset, NEW.rm_flags, &i);
1716 if (XFS_IS_CORRUPT(mp, i != 1)) {
1717 error = -EFSCORRUPTED;
1720 NEW.rm_blockcount += RIGHT.rm_blockcount;
1721 NEW.rm_flags = RIGHT.rm_flags;
1722 error = xfs_rmap_update(cur, &NEW);
1727 case RMAP_LEFT_FILLING | RMAP_RIGHT_FILLING:
1729 * Setting all of a previous oldext extent to newext.
1730 * Neither the left nor right neighbors are contiguous with
1734 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1735 NEW.rm_blockcount, NEW.rm_owner,
1736 NEW.rm_offset, NEW.rm_flags, &i);
1739 if (XFS_IS_CORRUPT(mp, i != 1)) {
1740 error = -EFSCORRUPTED;
1743 NEW.rm_flags = newext;
1744 error = xfs_rmap_update(cur, &NEW);
1749 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG:
1751 * Setting the first part of a previous oldext extent to newext.
1752 * The left neighbor is contiguous.
1755 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1756 NEW.rm_blockcount, NEW.rm_owner,
1757 NEW.rm_offset, NEW.rm_flags);
1760 NEW.rm_offset += len;
1761 NEW.rm_startblock += len;
1762 NEW.rm_blockcount -= len;
1763 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1764 NEW.rm_blockcount, NEW.rm_owner,
1765 NEW.rm_offset, NEW.rm_flags);
1769 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1770 NEW.rm_blockcount, NEW.rm_owner,
1771 NEW.rm_offset, NEW.rm_flags, &i);
1774 if (XFS_IS_CORRUPT(mp, i != 1)) {
1775 error = -EFSCORRUPTED;
1778 NEW.rm_blockcount += len;
1779 error = xfs_rmap_update(cur, &NEW);
1784 case RMAP_LEFT_FILLING:
1786 * Setting the first part of a previous oldext extent to newext.
1787 * The left neighbor is not contiguous.
1790 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1791 NEW.rm_blockcount, NEW.rm_owner,
1792 NEW.rm_offset, NEW.rm_flags);
1795 NEW.rm_offset += len;
1796 NEW.rm_startblock += len;
1797 NEW.rm_blockcount -= len;
1798 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1799 NEW.rm_blockcount, NEW.rm_owner,
1800 NEW.rm_offset, NEW.rm_flags);
1803 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1808 case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG:
1810 * Setting the last part of a previous oldext extent to newext.
1811 * The right neighbor is contiguous with the new allocation.
1814 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1815 NEW.rm_blockcount, NEW.rm_owner,
1816 NEW.rm_offset, NEW.rm_flags, &i);
1819 if (XFS_IS_CORRUPT(mp, i != 1)) {
1820 error = -EFSCORRUPTED;
1823 NEW.rm_blockcount = offset - NEW.rm_offset;
1824 error = xfs_rmap_update(cur, &NEW);
1828 error = xfs_rmap_delete(cur, NEW.rm_startblock,
1829 NEW.rm_blockcount, NEW.rm_owner,
1830 NEW.rm_offset, NEW.rm_flags);
1833 NEW.rm_offset = offset;
1834 NEW.rm_startblock = bno;
1835 NEW.rm_blockcount += len;
1836 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1837 NEW.rm_blockcount, NEW.rm_owner,
1838 NEW.rm_offset, NEW.rm_flags);
1843 case RMAP_RIGHT_FILLING:
1845 * Setting the last part of a previous oldext extent to newext.
1846 * The right neighbor is not contiguous.
1849 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1850 NEW.rm_blockcount, NEW.rm_owner,
1851 NEW.rm_offset, NEW.rm_flags, &i);
1854 if (XFS_IS_CORRUPT(mp, i != 1)) {
1855 error = -EFSCORRUPTED;
1858 NEW.rm_blockcount -= len;
1859 error = xfs_rmap_update(cur, &NEW);
1862 error = xfs_rmap_insert(cur, bno, len, owner, offset, newext);
1869 * Setting the middle part of a previous oldext extent to
1870 * newext. Contiguity is impossible here.
1871 * One extent becomes three extents.
1873 /* new right extent - oldext */
1874 NEW.rm_startblock = bno + len;
1875 NEW.rm_owner = owner;
1876 NEW.rm_offset = new_endoff;
1877 NEW.rm_blockcount = PREV.rm_offset + PREV.rm_blockcount -
1879 NEW.rm_flags = PREV.rm_flags;
1880 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1881 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1885 /* new left extent - oldext */
1887 error = xfs_rmap_lookup_eq(cur, NEW.rm_startblock,
1888 NEW.rm_blockcount, NEW.rm_owner,
1889 NEW.rm_offset, NEW.rm_flags, &i);
1892 if (XFS_IS_CORRUPT(mp, i != 1)) {
1893 error = -EFSCORRUPTED;
1896 NEW.rm_blockcount = offset - NEW.rm_offset;
1897 error = xfs_rmap_update(cur, &NEW);
1900 /* new middle extent - newext */
1901 NEW.rm_startblock = bno;
1902 NEW.rm_blockcount = len;
1903 NEW.rm_owner = owner;
1904 NEW.rm_offset = offset;
1905 NEW.rm_flags = newext;
1906 error = xfs_rmap_insert(cur, NEW.rm_startblock,
1907 NEW.rm_blockcount, NEW.rm_owner, NEW.rm_offset,
1913 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1914 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1915 case RMAP_LEFT_FILLING | RMAP_RIGHT_CONTIG:
1916 case RMAP_RIGHT_FILLING | RMAP_LEFT_CONTIG:
1917 case RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG:
1918 case RMAP_LEFT_CONTIG:
1919 case RMAP_RIGHT_CONTIG:
1921 * These cases are all impossible.
1926 trace_xfs_rmap_convert_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
1930 trace_xfs_rmap_convert_error(cur->bc_mp,
1931 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
1941 * Find an extent in the rmap btree and unmap it. For rmap extent types that
1942 * can overlap (data fork rmaps on reflink filesystems) we must be careful
1943 * that the prev/next records in the btree might belong to another owner.
1944 * Therefore we must use delete+insert to alter any of the key fields.
1946 * For every other situation there can only be one owner for a given extent,
1947 * so we can call the regular _free function.
1950 xfs_rmap_unmap_shared(
1951 struct xfs_btree_cur *cur,
1955 const struct xfs_owner_info *oinfo)
1957 struct xfs_mount *mp = cur->bc_mp;
1958 struct xfs_rmap_irec ltrec;
1966 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
1968 flags |= XFS_RMAP_UNWRITTEN;
1969 trace_xfs_rmap_unmap(mp, cur->bc_ag.pag->pag_agno, bno, len,
1973 * We should always have a left record because there's a static record
1974 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
1975 * will not ever be removed from the tree.
1977 error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
1981 if (XFS_IS_CORRUPT(mp, i != 1)) {
1982 error = -EFSCORRUPTED;
1985 ltoff = ltrec.rm_offset;
1987 /* Make sure the extent we found covers the entire freeing range. */
1988 if (XFS_IS_CORRUPT(mp,
1989 ltrec.rm_startblock > bno ||
1990 ltrec.rm_startblock + ltrec.rm_blockcount <
1992 error = -EFSCORRUPTED;
1996 /* Make sure the owner matches what we expect to find in the tree. */
1997 if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) {
1998 error = -EFSCORRUPTED;
2002 /* Make sure the unwritten flag matches. */
2003 if (XFS_IS_CORRUPT(mp,
2004 (flags & XFS_RMAP_UNWRITTEN) !=
2005 (ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) {
2006 error = -EFSCORRUPTED;
2010 /* Check the offset. */
2011 if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) {
2012 error = -EFSCORRUPTED;
2015 if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) {
2016 error = -EFSCORRUPTED;
2020 if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) {
2021 /* Exact match, simply remove the record from rmap tree. */
2022 error = xfs_rmap_delete(cur, ltrec.rm_startblock,
2023 ltrec.rm_blockcount, ltrec.rm_owner,
2024 ltrec.rm_offset, ltrec.rm_flags);
2027 } else if (ltrec.rm_startblock == bno) {
2029 * Overlap left hand side of extent: move the start, trim the
2030 * length and update the current record.
2033 * Orig: |oooooooooooooooooooo|
2034 * Freeing: |fffffffff|
2035 * Result: |rrrrrrrrrr|
2039 /* Delete prev rmap. */
2040 error = xfs_rmap_delete(cur, ltrec.rm_startblock,
2041 ltrec.rm_blockcount, ltrec.rm_owner,
2042 ltrec.rm_offset, ltrec.rm_flags);
2046 /* Add an rmap at the new offset. */
2047 ltrec.rm_startblock += len;
2048 ltrec.rm_blockcount -= len;
2049 ltrec.rm_offset += len;
2050 error = xfs_rmap_insert(cur, ltrec.rm_startblock,
2051 ltrec.rm_blockcount, ltrec.rm_owner,
2052 ltrec.rm_offset, ltrec.rm_flags);
2055 } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) {
2057 * Overlap right hand side of extent: trim the length and
2058 * update the current record.
2061 * Orig: |oooooooooooooooooooo|
2062 * Freeing: |fffffffff|
2063 * Result: |rrrrrrrrrr|
2066 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2067 ltrec.rm_blockcount, ltrec.rm_owner,
2068 ltrec.rm_offset, ltrec.rm_flags, &i);
2071 if (XFS_IS_CORRUPT(mp, i != 1)) {
2072 error = -EFSCORRUPTED;
2075 ltrec.rm_blockcount -= len;
2076 error = xfs_rmap_update(cur, <rec);
2081 * Overlap middle of extent: trim the length of the existing
2082 * record to the length of the new left-extent size, increment
2083 * the insertion position so we can insert a new record
2084 * containing the remaining right-extent space.
2087 * Orig: |oooooooooooooooooooo|
2088 * Freeing: |fffffffff|
2089 * Result: |rrrrr| |rrrr|
2092 xfs_extlen_t orig_len = ltrec.rm_blockcount;
2094 /* Shrink the left side of the rmap */
2095 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2096 ltrec.rm_blockcount, ltrec.rm_owner,
2097 ltrec.rm_offset, ltrec.rm_flags, &i);
2100 if (XFS_IS_CORRUPT(mp, i != 1)) {
2101 error = -EFSCORRUPTED;
2104 ltrec.rm_blockcount = bno - ltrec.rm_startblock;
2105 error = xfs_rmap_update(cur, <rec);
2109 /* Add an rmap at the new offset */
2110 error = xfs_rmap_insert(cur, bno + len,
2111 orig_len - len - ltrec.rm_blockcount,
2112 ltrec.rm_owner, offset + len,
2118 trace_xfs_rmap_unmap_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
2122 trace_xfs_rmap_unmap_error(cur->bc_mp,
2123 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
2128 * Find an extent in the rmap btree and map it. For rmap extent types that
2129 * can overlap (data fork rmaps on reflink filesystems) we must be careful
2130 * that the prev/next records in the btree might belong to another owner.
2131 * Therefore we must use delete+insert to alter any of the key fields.
2133 * For every other situation there can only be one owner for a given extent,
2134 * so we can call the regular _alloc function.
2137 xfs_rmap_map_shared(
2138 struct xfs_btree_cur *cur,
2142 const struct xfs_owner_info *oinfo)
2144 struct xfs_mount *mp = cur->bc_mp;
2145 struct xfs_rmap_irec ltrec;
2146 struct xfs_rmap_irec gtrec;
2153 unsigned int flags = 0;
2155 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
2157 flags |= XFS_RMAP_UNWRITTEN;
2158 trace_xfs_rmap_map(mp, cur->bc_ag.pag->pag_agno, bno, len,
2161 /* Is there a left record that abuts our range? */
2162 error = xfs_rmap_find_left_neighbor(cur, bno, owner, offset, flags,
2167 !xfs_rmap_is_mergeable(<rec, owner, flags))
2170 /* Is there a right record that abuts our range? */
2171 error = xfs_rmap_lookup_eq(cur, bno + len, len, owner, offset + len,
2176 error = xfs_rmap_get_rec(cur, >rec, &have_gt);
2179 if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
2180 error = -EFSCORRUPTED;
2183 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp,
2184 cur->bc_ag.pag->pag_agno, gtrec.rm_startblock,
2185 gtrec.rm_blockcount, gtrec.rm_owner,
2186 gtrec.rm_offset, gtrec.rm_flags);
2188 if (!xfs_rmap_is_mergeable(>rec, owner, flags))
2193 ltrec.rm_startblock + ltrec.rm_blockcount == bno &&
2194 ltrec.rm_offset + ltrec.rm_blockcount == offset) {
2196 * Left edge contiguous, merge into left record.
2200 * adding: |aaaaaaaaa|
2201 * result: |rrrrrrrrrrrrrrrrrrr|
2204 ltrec.rm_blockcount += len;
2206 bno + len == gtrec.rm_startblock &&
2207 offset + len == gtrec.rm_offset) {
2209 * Right edge also contiguous, delete right record
2210 * and merge into left record.
2212 * ltbno ltlen gtbno gtlen
2213 * orig: |ooooooooo| |ooooooooo|
2214 * adding: |aaaaaaaaa|
2215 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
2217 ltrec.rm_blockcount += gtrec.rm_blockcount;
2218 error = xfs_rmap_delete(cur, gtrec.rm_startblock,
2219 gtrec.rm_blockcount, gtrec.rm_owner,
2220 gtrec.rm_offset, gtrec.rm_flags);
2225 /* Point the cursor back to the left record and update. */
2226 error = xfs_rmap_lookup_eq(cur, ltrec.rm_startblock,
2227 ltrec.rm_blockcount, ltrec.rm_owner,
2228 ltrec.rm_offset, ltrec.rm_flags, &i);
2231 if (XFS_IS_CORRUPT(mp, i != 1)) {
2232 error = -EFSCORRUPTED;
2236 error = xfs_rmap_update(cur, <rec);
2239 } else if (have_gt &&
2240 bno + len == gtrec.rm_startblock &&
2241 offset + len == gtrec.rm_offset) {
2243 * Right edge contiguous, merge into right record.
2247 * adding: |aaaaaaaaa|
2248 * Result: |rrrrrrrrrrrrrrrrrrr|
2251 /* Delete the old record. */
2252 error = xfs_rmap_delete(cur, gtrec.rm_startblock,
2253 gtrec.rm_blockcount, gtrec.rm_owner,
2254 gtrec.rm_offset, gtrec.rm_flags);
2258 /* Move the start and re-add it. */
2259 gtrec.rm_startblock = bno;
2260 gtrec.rm_blockcount += len;
2261 gtrec.rm_offset = offset;
2262 error = xfs_rmap_insert(cur, gtrec.rm_startblock,
2263 gtrec.rm_blockcount, gtrec.rm_owner,
2264 gtrec.rm_offset, gtrec.rm_flags);
2269 * No contiguous edge with identical owner, insert
2270 * new record at current cursor position.
2272 error = xfs_rmap_insert(cur, bno, len, owner, offset, flags);
2277 trace_xfs_rmap_map_done(mp, cur->bc_ag.pag->pag_agno, bno, len,
2281 trace_xfs_rmap_map_error(cur->bc_mp,
2282 cur->bc_ag.pag->pag_agno, error, _RET_IP_);
2286 /* Insert a raw rmap into the rmapbt. */
2289 struct xfs_btree_cur *cur,
2290 struct xfs_rmap_irec *rmap)
2292 struct xfs_owner_info oinfo;
2294 oinfo.oi_owner = rmap->rm_owner;
2295 oinfo.oi_offset = rmap->rm_offset;
2297 if (rmap->rm_flags & XFS_RMAP_ATTR_FORK)
2298 oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
2299 if (rmap->rm_flags & XFS_RMAP_BMBT_BLOCK)
2300 oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
2302 if (rmap->rm_flags || XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner))
2303 return xfs_rmap_map(cur, rmap->rm_startblock,
2304 rmap->rm_blockcount,
2305 rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2308 return xfs_rmap_map_shared(cur, rmap->rm_startblock,
2309 rmap->rm_blockcount,
2310 rmap->rm_flags & XFS_RMAP_UNWRITTEN,
2314 struct xfs_rmap_query_range_info {
2315 xfs_rmap_query_range_fn fn;
2319 /* Format btree record and pass to our callback. */
2321 xfs_rmap_query_range_helper(
2322 struct xfs_btree_cur *cur,
2323 const union xfs_btree_rec *rec,
2326 struct xfs_rmap_query_range_info *query = priv;
2327 struct xfs_rmap_irec irec;
2330 error = xfs_rmap_btrec_to_irec(rec, &irec);
2333 return query->fn(cur, &irec, query->priv);
2336 /* Find all rmaps between two keys. */
2338 xfs_rmap_query_range(
2339 struct xfs_btree_cur *cur,
2340 const struct xfs_rmap_irec *low_rec,
2341 const struct xfs_rmap_irec *high_rec,
2342 xfs_rmap_query_range_fn fn,
2345 union xfs_btree_irec low_brec;
2346 union xfs_btree_irec high_brec;
2347 struct xfs_rmap_query_range_info query;
2349 low_brec.r = *low_rec;
2350 high_brec.r = *high_rec;
2353 return xfs_btree_query_range(cur, &low_brec, &high_brec,
2354 xfs_rmap_query_range_helper, &query);
2357 /* Find all rmaps. */
2360 struct xfs_btree_cur *cur,
2361 xfs_rmap_query_range_fn fn,
2364 struct xfs_rmap_query_range_info query;
2368 return xfs_btree_query_all(cur, xfs_rmap_query_range_helper, &query);
2371 /* Clean up after calling xfs_rmap_finish_one. */
2373 xfs_rmap_finish_one_cleanup(
2374 struct xfs_trans *tp,
2375 struct xfs_btree_cur *rcur,
2378 struct xfs_buf *agbp;
2382 agbp = rcur->bc_ag.agbp;
2383 xfs_btree_del_cursor(rcur, error);
2385 xfs_trans_brelse(tp, agbp);
2389 * Process one of the deferred rmap operations. We pass back the
2390 * btree cursor to maintain our lock on the rmapbt between calls.
2391 * This saves time and eliminates a buffer deadlock between the
2392 * superblock and the AGF because we'll always grab them in the same
2396 xfs_rmap_finish_one(
2397 struct xfs_trans *tp,
2398 enum xfs_rmap_intent_type type,
2401 xfs_fileoff_t startoff,
2402 xfs_fsblock_t startblock,
2403 xfs_filblks_t blockcount,
2405 struct xfs_btree_cur **pcur)
2407 struct xfs_mount *mp = tp->t_mountp;
2408 struct xfs_perag *pag;
2409 struct xfs_btree_cur *rcur;
2410 struct xfs_buf *agbp = NULL;
2412 struct xfs_owner_info oinfo;
2416 pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
2417 bno = XFS_FSB_TO_AGBNO(mp, startblock);
2419 trace_xfs_rmap_deferred(mp, pag->pag_agno, type, bno, owner, whichfork,
2420 startoff, blockcount, state);
2422 if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_RMAP_FINISH_ONE)) {
2429 * If we haven't gotten a cursor or the cursor AG doesn't match
2430 * the startblock, get one now.
2433 if (rcur != NULL && rcur->bc_ag.pag != pag) {
2434 xfs_rmap_finish_one_cleanup(tp, rcur, 0);
2440 * Refresh the freelist before we start changing the
2441 * rmapbt, because a shape change could cause us to
2444 error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
2447 if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) {
2448 error = -EFSCORRUPTED;
2452 rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
2456 xfs_rmap_ino_owner(&oinfo, owner, whichfork, startoff);
2457 unwritten = state == XFS_EXT_UNWRITTEN;
2458 bno = XFS_FSB_TO_AGBNO(rcur->bc_mp, startblock);
2461 case XFS_RMAP_ALLOC:
2463 error = xfs_rmap_map(rcur, bno, blockcount, unwritten, &oinfo);
2465 case XFS_RMAP_MAP_SHARED:
2466 error = xfs_rmap_map_shared(rcur, bno, blockcount, unwritten,
2470 case XFS_RMAP_UNMAP:
2471 error = xfs_rmap_unmap(rcur, bno, blockcount, unwritten,
2474 case XFS_RMAP_UNMAP_SHARED:
2475 error = xfs_rmap_unmap_shared(rcur, bno, blockcount, unwritten,
2478 case XFS_RMAP_CONVERT:
2479 error = xfs_rmap_convert(rcur, bno, blockcount, !unwritten,
2482 case XFS_RMAP_CONVERT_SHARED:
2483 error = xfs_rmap_convert_shared(rcur, bno, blockcount,
2484 !unwritten, &oinfo);
2488 error = -EFSCORRUPTED;
2496 * Don't defer an rmap if we aren't an rmap filesystem.
2499 xfs_rmap_update_is_needed(
2500 struct xfs_mount *mp,
2503 return xfs_has_rmapbt(mp) && whichfork != XFS_COW_FORK;
2507 * Record a rmap intent; the list is kept sorted first by AG and then by
2512 struct xfs_trans *tp,
2513 enum xfs_rmap_intent_type type,
2516 struct xfs_bmbt_irec *bmap)
2518 struct xfs_rmap_intent *ri;
2520 trace_xfs_rmap_defer(tp->t_mountp,
2521 XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
2523 XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
2526 bmap->br_blockcount,
2529 ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
2530 INIT_LIST_HEAD(&ri->ri_list);
2532 ri->ri_owner = owner;
2533 ri->ri_whichfork = whichfork;
2534 ri->ri_bmap = *bmap;
2536 xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_RMAP, &ri->ri_list);
2539 /* Map an extent into a file. */
2541 xfs_rmap_map_extent(
2542 struct xfs_trans *tp,
2543 struct xfs_inode *ip,
2545 struct xfs_bmbt_irec *PREV)
2547 enum xfs_rmap_intent_type type = XFS_RMAP_MAP;
2549 if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
2552 if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2553 type = XFS_RMAP_MAP_SHARED;
2555 __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
2558 /* Unmap an extent out of a file. */
2560 xfs_rmap_unmap_extent(
2561 struct xfs_trans *tp,
2562 struct xfs_inode *ip,
2564 struct xfs_bmbt_irec *PREV)
2566 enum xfs_rmap_intent_type type = XFS_RMAP_UNMAP;
2568 if (!xfs_rmap_update_is_needed(tp->t_mountp, whichfork))
2571 if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2572 type = XFS_RMAP_UNMAP_SHARED;
2574 __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
2578 * Convert a data fork extent from unwritten to real or vice versa.
2580 * Note that tp can be NULL here as no transaction is used for COW fork
2581 * unwritten conversion.
2584 xfs_rmap_convert_extent(
2585 struct xfs_mount *mp,
2586 struct xfs_trans *tp,
2587 struct xfs_inode *ip,
2589 struct xfs_bmbt_irec *PREV)
2591 enum xfs_rmap_intent_type type = XFS_RMAP_CONVERT;
2593 if (!xfs_rmap_update_is_needed(mp, whichfork))
2596 if (whichfork != XFS_ATTR_FORK && xfs_is_reflink_inode(ip))
2597 type = XFS_RMAP_CONVERT_SHARED;
2599 __xfs_rmap_add(tp, type, ip->i_ino, whichfork, PREV);
2602 /* Schedule the creation of an rmap for non-file data. */
2604 xfs_rmap_alloc_extent(
2605 struct xfs_trans *tp,
2606 xfs_agnumber_t agno,
2611 struct xfs_bmbt_irec bmap;
2613 if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
2616 bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
2617 bmap.br_blockcount = len;
2618 bmap.br_startoff = 0;
2619 bmap.br_state = XFS_EXT_NORM;
2621 __xfs_rmap_add(tp, XFS_RMAP_ALLOC, owner, XFS_DATA_FORK, &bmap);
2624 /* Schedule the deletion of an rmap for non-file data. */
2626 xfs_rmap_free_extent(
2627 struct xfs_trans *tp,
2628 xfs_agnumber_t agno,
2633 struct xfs_bmbt_irec bmap;
2635 if (!xfs_rmap_update_is_needed(tp->t_mountp, XFS_DATA_FORK))
2638 bmap.br_startblock = XFS_AGB_TO_FSB(tp->t_mountp, agno, bno);
2639 bmap.br_blockcount = len;
2640 bmap.br_startoff = 0;
2641 bmap.br_state = XFS_EXT_NORM;
2643 __xfs_rmap_add(tp, XFS_RMAP_FREE, owner, XFS_DATA_FORK, &bmap);
2646 /* Compare rmap records. Returns -1 if a < b, 1 if a > b, and 0 if equal. */
2649 const struct xfs_rmap_irec *a,
2650 const struct xfs_rmap_irec *b)
2655 oa = xfs_rmap_irec_offset_pack(a);
2656 ob = xfs_rmap_irec_offset_pack(b);
2658 if (a->rm_startblock < b->rm_startblock)
2660 else if (a->rm_startblock > b->rm_startblock)
2662 else if (a->rm_owner < b->rm_owner)
2664 else if (a->rm_owner > b->rm_owner)
2674 /* Is there a record covering a given extent? */
2676 xfs_rmap_has_record(
2677 struct xfs_btree_cur *cur,
2682 union xfs_btree_irec low;
2683 union xfs_btree_irec high;
2685 memset(&low, 0, sizeof(low));
2686 low.r.rm_startblock = bno;
2687 memset(&high, 0xFF, sizeof(high));
2688 high.r.rm_startblock = bno + len - 1;
2690 return xfs_btree_has_record(cur, &low, &high, exists);
2694 * Is there a record for this owner completely covering a given physical
2695 * extent? If so, *has_rmap will be set to true. If there is no record
2696 * or the record only covers part of the range, we set *has_rmap to false.
2697 * This function doesn't perform range lookups or offset checks, so it is
2698 * not suitable for checking data fork blocks.
2701 xfs_rmap_record_exists(
2702 struct xfs_btree_cur *cur,
2705 const struct xfs_owner_info *oinfo,
2712 struct xfs_rmap_irec irec;
2715 xfs_owner_info_unpack(oinfo, &owner, &offset, &flags);
2716 ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) ||
2717 (flags & XFS_RMAP_BMBT_BLOCK));
2719 error = xfs_rmap_lookup_le(cur, bno, owner, offset, flags, &irec,
2728 *has_rmap = (irec.rm_owner == owner && irec.rm_startblock <= bno &&
2729 irec.rm_startblock + irec.rm_blockcount >= bno + len);
2733 struct xfs_rmap_key_state {
2739 /* For each rmap given, figure out if it doesn't match the key we want. */
2741 xfs_rmap_has_other_keys_helper(
2742 struct xfs_btree_cur *cur,
2743 const struct xfs_rmap_irec *rec,
2746 struct xfs_rmap_key_state *rks = priv;
2748 if (rks->owner == rec->rm_owner && rks->offset == rec->rm_offset &&
2749 ((rks->flags & rec->rm_flags) & XFS_RMAP_KEY_FLAGS) == rks->flags)
2755 * Given an extent and some owner info, can we find records overlapping
2756 * the extent whose owner info does not match the given owner?
2759 xfs_rmap_has_other_keys(
2760 struct xfs_btree_cur *cur,
2763 const struct xfs_owner_info *oinfo,
2766 struct xfs_rmap_irec low = {0};
2767 struct xfs_rmap_irec high;
2768 struct xfs_rmap_key_state rks;
2771 xfs_owner_info_unpack(oinfo, &rks.owner, &rks.offset, &rks.flags);
2774 low.rm_startblock = bno;
2775 memset(&high, 0xFF, sizeof(high));
2776 high.rm_startblock = bno + len - 1;
2778 error = xfs_rmap_query_range(cur, &low, &high,
2779 xfs_rmap_has_other_keys_helper, &rks);
2780 if (error == -ECANCELED) {
2788 const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE = {
2789 .oi_owner = XFS_RMAP_OWN_NULL,
2791 const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER = {
2792 .oi_owner = XFS_RMAP_OWN_UNKNOWN,
2794 const struct xfs_owner_info XFS_RMAP_OINFO_FS = {
2795 .oi_owner = XFS_RMAP_OWN_FS,
2797 const struct xfs_owner_info XFS_RMAP_OINFO_LOG = {
2798 .oi_owner = XFS_RMAP_OWN_LOG,
2800 const struct xfs_owner_info XFS_RMAP_OINFO_AG = {
2801 .oi_owner = XFS_RMAP_OWN_AG,
2803 const struct xfs_owner_info XFS_RMAP_OINFO_INOBT = {
2804 .oi_owner = XFS_RMAP_OWN_INOBT,
2806 const struct xfs_owner_info XFS_RMAP_OINFO_INODES = {
2807 .oi_owner = XFS_RMAP_OWN_INODES,
2809 const struct xfs_owner_info XFS_RMAP_OINFO_REFC = {
2810 .oi_owner = XFS_RMAP_OWN_REFC,
2812 const struct xfs_owner_info XFS_RMAP_OINFO_COW = {
2813 .oi_owner = XFS_RMAP_OWN_COW,
2817 xfs_rmap_intent_init_cache(void)
2819 xfs_rmap_intent_cache = kmem_cache_create("xfs_rmap_intent",
2820 sizeof(struct xfs_rmap_intent),
2823 return xfs_rmap_intent_cache != NULL ? 0 : -ENOMEM;
2827 xfs_rmap_intent_destroy_cache(void)
2829 kmem_cache_destroy(xfs_rmap_intent_cache);
2830 xfs_rmap_intent_cache = NULL;