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
18 #include "libxfs_priv.h"
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"
38 #include "xfs_inode.h"
41 * Lookup the first record less than or equal to [bno, len, owner, offset]
42 * in the btree given by cur.
46 struct xfs_btree_cur
*cur
,
54 cur
->bc_rec
.r
.rm_startblock
= bno
;
55 cur
->bc_rec
.r
.rm_blockcount
= len
;
56 cur
->bc_rec
.r
.rm_owner
= owner
;
57 cur
->bc_rec
.r
.rm_offset
= offset
;
58 cur
->bc_rec
.r
.rm_flags
= flags
;
59 return xfs_btree_lookup(cur
, XFS_LOOKUP_LE
, stat
);
63 * Lookup the record exactly matching [bno, len, owner, offset]
64 * in the btree given by cur.
68 struct xfs_btree_cur
*cur
,
76 cur
->bc_rec
.r
.rm_startblock
= bno
;
77 cur
->bc_rec
.r
.rm_blockcount
= len
;
78 cur
->bc_rec
.r
.rm_owner
= owner
;
79 cur
->bc_rec
.r
.rm_offset
= offset
;
80 cur
->bc_rec
.r
.rm_flags
= flags
;
81 return xfs_btree_lookup(cur
, XFS_LOOKUP_EQ
, stat
);
85 * Update the record referred to by cur to the value given
86 * by [bno, len, owner, offset].
87 * This either works (return 0) or gets an EFSCORRUPTED error.
91 struct xfs_btree_cur
*cur
,
92 struct xfs_rmap_irec
*irec
)
94 union xfs_btree_rec rec
;
97 trace_xfs_rmap_update(cur
->bc_mp
, cur
->bc_private
.a
.agno
,
98 irec
->rm_startblock
, irec
->rm_blockcount
,
99 irec
->rm_owner
, irec
->rm_offset
, irec
->rm_flags
);
101 rec
.rmap
.rm_startblock
= cpu_to_be32(irec
->rm_startblock
);
102 rec
.rmap
.rm_blockcount
= cpu_to_be32(irec
->rm_blockcount
);
103 rec
.rmap
.rm_owner
= cpu_to_be64(irec
->rm_owner
);
104 rec
.rmap
.rm_offset
= cpu_to_be64(
105 xfs_rmap_irec_offset_pack(irec
));
106 error
= xfs_btree_update(cur
, &rec
);
108 trace_xfs_rmap_update_error(cur
->bc_mp
,
109 cur
->bc_private
.a
.agno
, error
, _RET_IP_
);
115 struct xfs_btree_cur
*rcur
,
125 trace_xfs_rmap_insert(rcur
->bc_mp
, rcur
->bc_private
.a
.agno
, agbno
,
126 len
, owner
, offset
, flags
);
128 error
= xfs_rmap_lookup_eq(rcur
, agbno
, len
, owner
, offset
, flags
, &i
);
131 XFS_WANT_CORRUPTED_GOTO(rcur
->bc_mp
, i
== 0, done
);
133 rcur
->bc_rec
.r
.rm_startblock
= agbno
;
134 rcur
->bc_rec
.r
.rm_blockcount
= len
;
135 rcur
->bc_rec
.r
.rm_owner
= owner
;
136 rcur
->bc_rec
.r
.rm_offset
= offset
;
137 rcur
->bc_rec
.r
.rm_flags
= flags
;
138 error
= xfs_btree_insert(rcur
, &i
);
141 XFS_WANT_CORRUPTED_GOTO(rcur
->bc_mp
, i
== 1, done
);
144 trace_xfs_rmap_insert_error(rcur
->bc_mp
,
145 rcur
->bc_private
.a
.agno
, error
, _RET_IP_
);
150 xfs_rmap_btrec_to_irec(
151 union xfs_btree_rec
*rec
,
152 struct xfs_rmap_irec
*irec
)
155 irec
->rm_startblock
= be32_to_cpu(rec
->rmap
.rm_startblock
);
156 irec
->rm_blockcount
= be32_to_cpu(rec
->rmap
.rm_blockcount
);
157 irec
->rm_owner
= be64_to_cpu(rec
->rmap
.rm_owner
);
158 return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec
->rmap
.rm_offset
),
163 * Get the data from the pointed-to record.
167 struct xfs_btree_cur
*cur
,
168 struct xfs_rmap_irec
*irec
,
171 union xfs_btree_rec
*rec
;
174 error
= xfs_btree_get_rec(cur
, &rec
, stat
);
178 return xfs_rmap_btrec_to_irec(rec
, irec
);
182 * Find the extent in the rmap btree and remove it.
184 * The record we find should always be an exact match for the extent that we're
185 * looking for, since we insert them into the btree without modification.
187 * Special Case #1: when growing the filesystem, we "free" an extent when
188 * growing the last AG. This extent is new space and so it is not tracked as
189 * used space in the btree. The growfs code will pass in an owner of
190 * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
191 * extent. We verify that - the extent lookup result in a record that does not
194 * Special Case #2: EFIs do not record the owner of the extent, so when
195 * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
196 * btree to ignore the owner (i.e. wildcard match) so we don't trigger
197 * corruption checks during log recovery.
201 struct xfs_btree_cur
*cur
,
205 struct xfs_owner_info
*oinfo
)
207 struct xfs_mount
*mp
= cur
->bc_mp
;
208 struct xfs_rmap_irec ltrec
;
217 xfs_owner_info_unpack(oinfo
, &owner
, &offset
, &flags
);
218 ignore_off
= XFS_RMAP_NON_INODE_OWNER(owner
) ||
219 (flags
& XFS_RMAP_BMBT_BLOCK
);
221 flags
|= XFS_RMAP_UNWRITTEN
;
222 trace_xfs_rmap_unmap(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
226 * We should always have a left record because there's a static record
227 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
228 * will not ever be removed from the tree.
230 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, flags
, &i
);
233 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
235 error
= xfs_rmap_get_rec(cur
, <rec
, &i
);
238 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
239 trace_xfs_rmap_lookup_le_range_result(cur
->bc_mp
,
240 cur
->bc_private
.a
.agno
, ltrec
.rm_startblock
,
241 ltrec
.rm_blockcount
, ltrec
.rm_owner
,
242 ltrec
.rm_offset
, ltrec
.rm_flags
);
243 ltoff
= ltrec
.rm_offset
;
246 * For growfs, the incoming extent must be beyond the left record we
247 * just found as it is new space and won't be used by anyone. This is
248 * just a corruption check as we don't actually do anything with this
249 * extent. Note that we need to use >= instead of > because it might
250 * be the case that the "left" extent goes all the way to EOFS.
252 if (owner
== XFS_RMAP_OWN_NULL
) {
253 XFS_WANT_CORRUPTED_GOTO(mp
, bno
>= ltrec
.rm_startblock
+
254 ltrec
.rm_blockcount
, out_error
);
258 /* Make sure the unwritten flag matches. */
259 XFS_WANT_CORRUPTED_GOTO(mp
, (flags
& XFS_RMAP_UNWRITTEN
) ==
260 (ltrec
.rm_flags
& XFS_RMAP_UNWRITTEN
), out_error
);
262 /* Make sure the extent we found covers the entire freeing range. */
263 XFS_WANT_CORRUPTED_GOTO(mp
, ltrec
.rm_startblock
<= bno
&&
264 ltrec
.rm_startblock
+ ltrec
.rm_blockcount
>=
265 bno
+ len
, out_error
);
267 /* Make sure the owner matches what we expect to find in the tree. */
268 XFS_WANT_CORRUPTED_GOTO(mp
, owner
== ltrec
.rm_owner
||
269 XFS_RMAP_NON_INODE_OWNER(owner
), out_error
);
271 /* Check the offset, if necessary. */
272 if (!XFS_RMAP_NON_INODE_OWNER(owner
)) {
273 if (flags
& XFS_RMAP_BMBT_BLOCK
) {
274 XFS_WANT_CORRUPTED_GOTO(mp
,
275 ltrec
.rm_flags
& XFS_RMAP_BMBT_BLOCK
,
278 XFS_WANT_CORRUPTED_GOTO(mp
,
279 ltrec
.rm_offset
<= offset
, out_error
);
280 XFS_WANT_CORRUPTED_GOTO(mp
,
281 ltoff
+ ltrec
.rm_blockcount
>= offset
+ len
,
286 if (ltrec
.rm_startblock
== bno
&& ltrec
.rm_blockcount
== len
) {
287 /* exact match, simply remove the record from rmap tree */
288 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
289 ltrec
.rm_startblock
, ltrec
.rm_blockcount
,
290 ltrec
.rm_owner
, ltrec
.rm_offset
,
292 error
= xfs_btree_delete(cur
, &i
);
295 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
296 } else if (ltrec
.rm_startblock
== bno
) {
298 * overlap left hand side of extent: move the start, trim the
299 * length and update the current record.
302 * Orig: |oooooooooooooooooooo|
303 * Freeing: |fffffffff|
304 * Result: |rrrrrrrrrr|
307 ltrec
.rm_startblock
+= len
;
308 ltrec
.rm_blockcount
-= len
;
310 ltrec
.rm_offset
+= len
;
311 error
= xfs_rmap_update(cur
, <rec
);
314 } else if (ltrec
.rm_startblock
+ ltrec
.rm_blockcount
== bno
+ len
) {
316 * overlap right hand side of extent: trim the length and update
317 * the current record.
320 * Orig: |oooooooooooooooooooo|
321 * Freeing: |fffffffff|
322 * Result: |rrrrrrrrrr|
325 ltrec
.rm_blockcount
-= len
;
326 error
= xfs_rmap_update(cur
, <rec
);
332 * overlap middle of extent: trim the length of the existing
333 * record to the length of the new left-extent size, increment
334 * the insertion position so we can insert a new record
335 * containing the remaining right-extent space.
338 * Orig: |oooooooooooooooooooo|
339 * Freeing: |fffffffff|
340 * Result: |rrrrr| |rrrr|
343 xfs_extlen_t orig_len
= ltrec
.rm_blockcount
;
345 ltrec
.rm_blockcount
= bno
- ltrec
.rm_startblock
;
346 error
= xfs_rmap_update(cur
, <rec
);
350 error
= xfs_btree_increment(cur
, 0, &i
);
354 cur
->bc_rec
.r
.rm_startblock
= bno
+ len
;
355 cur
->bc_rec
.r
.rm_blockcount
= orig_len
- len
-
357 cur
->bc_rec
.r
.rm_owner
= ltrec
.rm_owner
;
359 cur
->bc_rec
.r
.rm_offset
= 0;
361 cur
->bc_rec
.r
.rm_offset
= offset
+ len
;
362 cur
->bc_rec
.r
.rm_flags
= flags
;
363 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
,
364 cur
->bc_rec
.r
.rm_startblock
,
365 cur
->bc_rec
.r
.rm_blockcount
,
366 cur
->bc_rec
.r
.rm_owner
,
367 cur
->bc_rec
.r
.rm_offset
,
368 cur
->bc_rec
.r
.rm_flags
);
369 error
= xfs_btree_insert(cur
, &i
);
375 trace_xfs_rmap_unmap_done(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
379 trace_xfs_rmap_unmap_error(mp
, cur
->bc_private
.a
.agno
,
385 * Remove a reference to an extent in the rmap btree.
389 struct xfs_trans
*tp
,
390 struct xfs_buf
*agbp
,
394 struct xfs_owner_info
*oinfo
)
396 struct xfs_mount
*mp
= tp
->t_mountp
;
397 struct xfs_btree_cur
*cur
;
400 if (!xfs_sb_version_hasrmapbt(&mp
->m_sb
))
403 cur
= xfs_rmapbt_init_cursor(mp
, tp
, agbp
, agno
);
405 error
= xfs_rmap_unmap(cur
, bno
, len
, false, oinfo
);
409 xfs_btree_del_cursor(cur
, XFS_BTREE_NOERROR
);
413 xfs_btree_del_cursor(cur
, XFS_BTREE_ERROR
);
418 * A mergeable rmap must have the same owner and the same values for
419 * the unwritten, attr_fork, and bmbt flags. The startblock and
420 * offset are checked separately.
423 xfs_rmap_is_mergeable(
424 struct xfs_rmap_irec
*irec
,
428 if (irec
->rm_owner
== XFS_RMAP_OWN_NULL
)
430 if (irec
->rm_owner
!= owner
)
432 if ((flags
& XFS_RMAP_UNWRITTEN
) ^
433 (irec
->rm_flags
& XFS_RMAP_UNWRITTEN
))
435 if ((flags
& XFS_RMAP_ATTR_FORK
) ^
436 (irec
->rm_flags
& XFS_RMAP_ATTR_FORK
))
438 if ((flags
& XFS_RMAP_BMBT_BLOCK
) ^
439 (irec
->rm_flags
& XFS_RMAP_BMBT_BLOCK
))
445 * When we allocate a new block, the first thing we do is add a reference to
446 * the extent in the rmap btree. This takes the form of a [agbno, length,
447 * owner, offset] record. Flags are encoded in the high bits of the offset
452 struct xfs_btree_cur
*cur
,
456 struct xfs_owner_info
*oinfo
)
458 struct xfs_mount
*mp
= cur
->bc_mp
;
459 struct xfs_rmap_irec ltrec
;
460 struct xfs_rmap_irec gtrec
;
467 unsigned int flags
= 0;
470 xfs_owner_info_unpack(oinfo
, &owner
, &offset
, &flags
);
472 ignore_off
= XFS_RMAP_NON_INODE_OWNER(owner
) ||
473 (flags
& XFS_RMAP_BMBT_BLOCK
);
475 flags
|= XFS_RMAP_UNWRITTEN
;
476 trace_xfs_rmap_map(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
480 * For the initial lookup, look for an exact match or the left-adjacent
481 * record for our insertion point. This will also give us the record for
482 * start block contiguity tests.
484 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, flags
,
488 XFS_WANT_CORRUPTED_GOTO(mp
, have_lt
== 1, out_error
);
490 error
= xfs_rmap_get_rec(cur
, <rec
, &have_lt
);
493 XFS_WANT_CORRUPTED_GOTO(mp
, have_lt
== 1, out_error
);
494 trace_xfs_rmap_lookup_le_range_result(cur
->bc_mp
,
495 cur
->bc_private
.a
.agno
, ltrec
.rm_startblock
,
496 ltrec
.rm_blockcount
, ltrec
.rm_owner
,
497 ltrec
.rm_offset
, ltrec
.rm_flags
);
499 if (!xfs_rmap_is_mergeable(<rec
, owner
, flags
))
502 XFS_WANT_CORRUPTED_GOTO(mp
,
504 ltrec
.rm_startblock
+ ltrec
.rm_blockcount
<= bno
, out_error
);
507 * Increment the cursor to see if we have a right-adjacent record to our
508 * insertion point. This will give us the record for end block
511 error
= xfs_btree_increment(cur
, 0, &have_gt
);
515 error
= xfs_rmap_get_rec(cur
, >rec
, &have_gt
);
518 XFS_WANT_CORRUPTED_GOTO(mp
, have_gt
== 1, out_error
);
519 XFS_WANT_CORRUPTED_GOTO(mp
, bno
+ len
<= gtrec
.rm_startblock
,
521 trace_xfs_rmap_find_right_neighbor_result(cur
->bc_mp
,
522 cur
->bc_private
.a
.agno
, gtrec
.rm_startblock
,
523 gtrec
.rm_blockcount
, gtrec
.rm_owner
,
524 gtrec
.rm_offset
, gtrec
.rm_flags
);
525 if (!xfs_rmap_is_mergeable(>rec
, owner
, flags
))
530 * Note: cursor currently points one record to the right of ltrec, even
531 * if there is no record in the tree to the right.
534 ltrec
.rm_startblock
+ ltrec
.rm_blockcount
== bno
&&
535 (ignore_off
|| ltrec
.rm_offset
+ ltrec
.rm_blockcount
== offset
)) {
537 * left edge contiguous, merge into left record.
541 * adding: |aaaaaaaaa|
542 * result: |rrrrrrrrrrrrrrrrrrr|
545 ltrec
.rm_blockcount
+= len
;
547 bno
+ len
== gtrec
.rm_startblock
&&
548 (ignore_off
|| offset
+ len
== gtrec
.rm_offset
) &&
549 (unsigned long)ltrec
.rm_blockcount
+ len
+
550 gtrec
.rm_blockcount
<= XFS_RMAP_LEN_MAX
) {
552 * right edge also contiguous, delete right record
553 * and merge into left record.
555 * ltbno ltlen gtbno gtlen
556 * orig: |ooooooooo| |ooooooooo|
557 * adding: |aaaaaaaaa|
558 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
560 ltrec
.rm_blockcount
+= gtrec
.rm_blockcount
;
561 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
567 error
= xfs_btree_delete(cur
, &i
);
570 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
573 /* point the cursor back to the left record and update */
574 error
= xfs_btree_decrement(cur
, 0, &have_gt
);
577 error
= xfs_rmap_update(cur
, <rec
);
580 } else if (have_gt
&&
581 bno
+ len
== gtrec
.rm_startblock
&&
582 (ignore_off
|| offset
+ len
== gtrec
.rm_offset
)) {
584 * right edge contiguous, merge into right record.
588 * adding: |aaaaaaaaa|
589 * Result: |rrrrrrrrrrrrrrrrrrr|
592 gtrec
.rm_startblock
= bno
;
593 gtrec
.rm_blockcount
+= len
;
595 gtrec
.rm_offset
= offset
;
596 error
= xfs_rmap_update(cur
, >rec
);
601 * no contiguous edge with identical owner, insert
602 * new record at current cursor position.
604 cur
->bc_rec
.r
.rm_startblock
= bno
;
605 cur
->bc_rec
.r
.rm_blockcount
= len
;
606 cur
->bc_rec
.r
.rm_owner
= owner
;
607 cur
->bc_rec
.r
.rm_offset
= offset
;
608 cur
->bc_rec
.r
.rm_flags
= flags
;
609 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
610 owner
, offset
, flags
);
611 error
= xfs_btree_insert(cur
, &i
);
614 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
617 trace_xfs_rmap_map_done(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
621 trace_xfs_rmap_map_error(mp
, cur
->bc_private
.a
.agno
,
627 * Add a reference to an extent in the rmap btree.
631 struct xfs_trans
*tp
,
632 struct xfs_buf
*agbp
,
636 struct xfs_owner_info
*oinfo
)
638 struct xfs_mount
*mp
= tp
->t_mountp
;
639 struct xfs_btree_cur
*cur
;
642 if (!xfs_sb_version_hasrmapbt(&mp
->m_sb
))
645 cur
= xfs_rmapbt_init_cursor(mp
, tp
, agbp
, agno
);
646 error
= xfs_rmap_map(cur
, bno
, len
, false, oinfo
);
650 xfs_btree_del_cursor(cur
, XFS_BTREE_NOERROR
);
654 xfs_btree_del_cursor(cur
, XFS_BTREE_ERROR
);
658 #define RMAP_LEFT_CONTIG (1 << 0)
659 #define RMAP_RIGHT_CONTIG (1 << 1)
660 #define RMAP_LEFT_FILLING (1 << 2)
661 #define RMAP_RIGHT_FILLING (1 << 3)
662 #define RMAP_LEFT_VALID (1 << 6)
663 #define RMAP_RIGHT_VALID (1 << 7)
671 * Convert an unwritten extent to a real extent or vice versa.
672 * Does not handle overlapping extents.
676 struct xfs_btree_cur
*cur
,
680 struct xfs_owner_info
*oinfo
)
682 struct xfs_mount
*mp
= cur
->bc_mp
;
683 struct xfs_rmap_irec r
[4]; /* neighbor extent entries */
684 /* left is 0, right is 1, prev is 2 */
691 unsigned int flags
= 0;
696 xfs_owner_info_unpack(oinfo
, &owner
, &offset
, &flags
);
697 ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner
) ||
698 (flags
& (XFS_RMAP_ATTR_FORK
| XFS_RMAP_BMBT_BLOCK
))));
699 oldext
= unwritten
? XFS_RMAP_UNWRITTEN
: 0;
700 new_endoff
= offset
+ len
;
701 trace_xfs_rmap_convert(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
705 * For the initial lookup, look for an exact match or the left-adjacent
706 * record for our insertion point. This will also give us the record for
707 * start block contiguity tests.
709 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, oldext
, &i
);
712 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
714 error
= xfs_rmap_get_rec(cur
, &PREV
, &i
);
717 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
718 trace_xfs_rmap_lookup_le_range_result(cur
->bc_mp
,
719 cur
->bc_private
.a
.agno
, PREV
.rm_startblock
,
720 PREV
.rm_blockcount
, PREV
.rm_owner
,
721 PREV
.rm_offset
, PREV
.rm_flags
);
723 ASSERT(PREV
.rm_offset
<= offset
);
724 ASSERT(PREV
.rm_offset
+ PREV
.rm_blockcount
>= new_endoff
);
725 ASSERT((PREV
.rm_flags
& XFS_RMAP_UNWRITTEN
) == oldext
);
726 newext
= ~oldext
& XFS_RMAP_UNWRITTEN
;
729 * Set flags determining what part of the previous oldext allocation
730 * extent is being replaced by a newext allocation.
732 if (PREV
.rm_offset
== offset
)
733 state
|= RMAP_LEFT_FILLING
;
734 if (PREV
.rm_offset
+ PREV
.rm_blockcount
== new_endoff
)
735 state
|= RMAP_RIGHT_FILLING
;
738 * Decrement the cursor to see if we have a left-adjacent record to our
739 * insertion point. This will give us the record for end block
742 error
= xfs_btree_decrement(cur
, 0, &i
);
746 state
|= RMAP_LEFT_VALID
;
747 error
= xfs_rmap_get_rec(cur
, &LEFT
, &i
);
750 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
751 XFS_WANT_CORRUPTED_GOTO(mp
,
752 LEFT
.rm_startblock
+ LEFT
.rm_blockcount
<= bno
,
754 trace_xfs_rmap_find_left_neighbor_result(cur
->bc_mp
,
755 cur
->bc_private
.a
.agno
, LEFT
.rm_startblock
,
756 LEFT
.rm_blockcount
, LEFT
.rm_owner
,
757 LEFT
.rm_offset
, LEFT
.rm_flags
);
758 if (LEFT
.rm_startblock
+ LEFT
.rm_blockcount
== bno
&&
759 LEFT
.rm_offset
+ LEFT
.rm_blockcount
== offset
&&
760 xfs_rmap_is_mergeable(&LEFT
, owner
, newext
))
761 state
|= RMAP_LEFT_CONTIG
;
765 * Increment the cursor to see if we have a right-adjacent record to our
766 * insertion point. This will give us the record for end block
769 error
= xfs_btree_increment(cur
, 0, &i
);
772 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
773 error
= xfs_btree_increment(cur
, 0, &i
);
777 state
|= RMAP_RIGHT_VALID
;
778 error
= xfs_rmap_get_rec(cur
, &RIGHT
, &i
);
781 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
782 XFS_WANT_CORRUPTED_GOTO(mp
, bno
+ len
<= RIGHT
.rm_startblock
,
784 trace_xfs_rmap_find_right_neighbor_result(cur
->bc_mp
,
785 cur
->bc_private
.a
.agno
, RIGHT
.rm_startblock
,
786 RIGHT
.rm_blockcount
, RIGHT
.rm_owner
,
787 RIGHT
.rm_offset
, RIGHT
.rm_flags
);
788 if (bno
+ len
== RIGHT
.rm_startblock
&&
789 offset
+ len
== RIGHT
.rm_offset
&&
790 xfs_rmap_is_mergeable(&RIGHT
, owner
, newext
))
791 state
|= RMAP_RIGHT_CONTIG
;
794 /* check that left + prev + right is not too long */
795 if ((state
& (RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
796 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
)) ==
797 (RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
798 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
) &&
799 (unsigned long)LEFT
.rm_blockcount
+ len
+
800 RIGHT
.rm_blockcount
> XFS_RMAP_LEN_MAX
)
801 state
&= ~RMAP_RIGHT_CONTIG
;
803 trace_xfs_rmap_convert_state(mp
, cur
->bc_private
.a
.agno
, state
,
806 /* reset the cursor back to PREV */
807 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, oldext
, &i
);
810 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
813 * Switch out based on the FILLING and CONTIG state bits.
815 switch (state
& (RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
816 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
)) {
817 case RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
818 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
:
820 * Setting all of a previous oldext extent to newext.
821 * The left and right neighbors are both contiguous with new.
823 error
= xfs_btree_increment(cur
, 0, &i
);
826 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
827 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
828 RIGHT
.rm_startblock
, RIGHT
.rm_blockcount
,
829 RIGHT
.rm_owner
, RIGHT
.rm_offset
,
831 error
= xfs_btree_delete(cur
, &i
);
834 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
835 error
= xfs_btree_decrement(cur
, 0, &i
);
838 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
839 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
840 PREV
.rm_startblock
, PREV
.rm_blockcount
,
841 PREV
.rm_owner
, PREV
.rm_offset
,
843 error
= xfs_btree_delete(cur
, &i
);
846 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
847 error
= xfs_btree_decrement(cur
, 0, &i
);
850 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
852 NEW
.rm_blockcount
+= PREV
.rm_blockcount
+ RIGHT
.rm_blockcount
;
853 error
= xfs_rmap_update(cur
, &NEW
);
858 case RMAP_LEFT_FILLING
| RMAP_RIGHT_FILLING
| RMAP_LEFT_CONTIG
:
860 * Setting all of a previous oldext extent to newext.
861 * The left neighbor is contiguous, the right is not.
863 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
864 PREV
.rm_startblock
, PREV
.rm_blockcount
,
865 PREV
.rm_owner
, PREV
.rm_offset
,
867 error
= xfs_btree_delete(cur
, &i
);
870 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
871 error
= xfs_btree_decrement(cur
, 0, &i
);
874 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
876 NEW
.rm_blockcount
+= PREV
.rm_blockcount
;
877 error
= xfs_rmap_update(cur
, &NEW
);
882 case RMAP_LEFT_FILLING
| RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
:
884 * Setting all of a previous oldext extent to newext.
885 * The right neighbor is contiguous, the left is not.
887 error
= xfs_btree_increment(cur
, 0, &i
);
890 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
891 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
892 RIGHT
.rm_startblock
, RIGHT
.rm_blockcount
,
893 RIGHT
.rm_owner
, RIGHT
.rm_offset
,
895 error
= xfs_btree_delete(cur
, &i
);
898 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
899 error
= xfs_btree_decrement(cur
, 0, &i
);
902 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
904 NEW
.rm_blockcount
= len
+ RIGHT
.rm_blockcount
;
905 NEW
.rm_flags
= newext
;
906 error
= xfs_rmap_update(cur
, &NEW
);
911 case RMAP_LEFT_FILLING
| RMAP_RIGHT_FILLING
:
913 * Setting all of a previous oldext extent to newext.
914 * Neither the left nor right neighbors are contiguous with
918 NEW
.rm_flags
= newext
;
919 error
= xfs_rmap_update(cur
, &NEW
);
924 case RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
:
926 * Setting the first part of a previous oldext extent to newext.
927 * The left neighbor is contiguous.
930 NEW
.rm_offset
+= len
;
931 NEW
.rm_startblock
+= len
;
932 NEW
.rm_blockcount
-= len
;
933 error
= xfs_rmap_update(cur
, &NEW
);
936 error
= xfs_btree_decrement(cur
, 0, &i
);
940 NEW
.rm_blockcount
+= len
;
941 error
= xfs_rmap_update(cur
, &NEW
);
946 case RMAP_LEFT_FILLING
:
948 * Setting the first part of a previous oldext extent to newext.
949 * The left neighbor is not contiguous.
952 NEW
.rm_startblock
+= len
;
953 NEW
.rm_offset
+= len
;
954 NEW
.rm_blockcount
-= len
;
955 error
= xfs_rmap_update(cur
, &NEW
);
958 NEW
.rm_startblock
= bno
;
959 NEW
.rm_owner
= owner
;
960 NEW
.rm_offset
= offset
;
961 NEW
.rm_blockcount
= len
;
962 NEW
.rm_flags
= newext
;
964 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
,
965 len
, owner
, offset
, newext
);
966 error
= xfs_btree_insert(cur
, &i
);
969 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
972 case RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
:
974 * Setting the last part of a previous oldext extent to newext.
975 * The right neighbor is contiguous with the new allocation.
978 NEW
.rm_blockcount
-= len
;
979 error
= xfs_rmap_update(cur
, &NEW
);
982 error
= xfs_btree_increment(cur
, 0, &i
);
986 NEW
.rm_offset
= offset
;
987 NEW
.rm_startblock
= bno
;
988 NEW
.rm_blockcount
+= len
;
989 error
= xfs_rmap_update(cur
, &NEW
);
994 case RMAP_RIGHT_FILLING
:
996 * Setting the last part of a previous oldext extent to newext.
997 * The right neighbor is not contiguous.
1000 NEW
.rm_blockcount
-= len
;
1001 error
= xfs_rmap_update(cur
, &NEW
);
1004 error
= xfs_rmap_lookup_eq(cur
, bno
, len
, owner
, offset
,
1008 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 0, done
);
1009 NEW
.rm_startblock
= bno
;
1010 NEW
.rm_owner
= owner
;
1011 NEW
.rm_offset
= offset
;
1012 NEW
.rm_blockcount
= len
;
1013 NEW
.rm_flags
= newext
;
1014 cur
->bc_rec
.r
= NEW
;
1015 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
,
1016 len
, owner
, offset
, newext
);
1017 error
= xfs_btree_insert(cur
, &i
);
1020 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
1025 * Setting the middle part of a previous oldext extent to
1026 * newext. Contiguity is impossible here.
1027 * One extent becomes three extents.
1029 /* new right extent - oldext */
1030 NEW
.rm_startblock
= bno
+ len
;
1031 NEW
.rm_owner
= owner
;
1032 NEW
.rm_offset
= new_endoff
;
1033 NEW
.rm_blockcount
= PREV
.rm_offset
+ PREV
.rm_blockcount
-
1035 NEW
.rm_flags
= PREV
.rm_flags
;
1036 error
= xfs_rmap_update(cur
, &NEW
);
1039 /* new left extent - oldext */
1041 NEW
.rm_blockcount
= offset
- PREV
.rm_offset
;
1042 cur
->bc_rec
.r
= NEW
;
1043 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
,
1044 NEW
.rm_startblock
, NEW
.rm_blockcount
,
1045 NEW
.rm_owner
, NEW
.rm_offset
,
1047 error
= xfs_btree_insert(cur
, &i
);
1050 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
1052 * Reset the cursor to the position of the new extent
1053 * we are about to insert as we can't trust it after
1054 * the previous insert.
1056 error
= xfs_rmap_lookup_eq(cur
, bno
, len
, owner
, offset
,
1060 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 0, done
);
1061 /* new middle extent - newext */
1062 cur
->bc_rec
.r
.rm_flags
&= ~XFS_RMAP_UNWRITTEN
;
1063 cur
->bc_rec
.r
.rm_flags
|= newext
;
1064 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
1065 owner
, offset
, newext
);
1066 error
= xfs_btree_insert(cur
, &i
);
1069 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
1072 case RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
| RMAP_RIGHT_CONTIG
:
1073 case RMAP_RIGHT_FILLING
| RMAP_LEFT_CONTIG
| RMAP_RIGHT_CONTIG
:
1074 case RMAP_LEFT_FILLING
| RMAP_RIGHT_CONTIG
:
1075 case RMAP_RIGHT_FILLING
| RMAP_LEFT_CONTIG
:
1076 case RMAP_LEFT_CONTIG
| RMAP_RIGHT_CONTIG
:
1077 case RMAP_LEFT_CONTIG
:
1078 case RMAP_RIGHT_CONTIG
:
1080 * These cases are all impossible.
1085 trace_xfs_rmap_convert_done(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
1089 trace_xfs_rmap_convert_error(cur
->bc_mp
,
1090 cur
->bc_private
.a
.agno
, error
, _RET_IP_
);
1099 struct xfs_rmap_query_range_info
{
1100 xfs_rmap_query_range_fn fn
;
1104 /* Format btree record and pass to our callback. */
1106 xfs_rmap_query_range_helper(
1107 struct xfs_btree_cur
*cur
,
1108 union xfs_btree_rec
*rec
,
1111 struct xfs_rmap_query_range_info
*query
= priv
;
1112 struct xfs_rmap_irec irec
;
1115 error
= xfs_rmap_btrec_to_irec(rec
, &irec
);
1118 return query
->fn(cur
, &irec
, query
->priv
);
1121 /* Find all rmaps between two keys. */
1123 xfs_rmap_query_range(
1124 struct xfs_btree_cur
*cur
,
1125 struct xfs_rmap_irec
*low_rec
,
1126 struct xfs_rmap_irec
*high_rec
,
1127 xfs_rmap_query_range_fn fn
,
1130 union xfs_btree_irec low_brec
;
1131 union xfs_btree_irec high_brec
;
1132 struct xfs_rmap_query_range_info query
;
1134 low_brec
.r
= *low_rec
;
1135 high_brec
.r
= *high_rec
;
1138 return xfs_btree_query_range(cur
, &low_brec
, &high_brec
,
1139 xfs_rmap_query_range_helper
, &query
);
1142 /* Clean up after calling xfs_rmap_finish_one. */
1144 xfs_rmap_finish_one_cleanup(
1145 struct xfs_trans
*tp
,
1146 struct xfs_btree_cur
*rcur
,
1149 struct xfs_buf
*agbp
;
1153 agbp
= rcur
->bc_private
.a
.agbp
;
1154 xfs_btree_del_cursor(rcur
, error
? XFS_BTREE_ERROR
: XFS_BTREE_NOERROR
);
1156 xfs_trans_brelse(tp
, agbp
);
1160 * Process one of the deferred rmap operations. We pass back the
1161 * btree cursor to maintain our lock on the rmapbt between calls.
1162 * This saves time and eliminates a buffer deadlock between the
1163 * superblock and the AGF because we'll always grab them in the same
1167 xfs_rmap_finish_one(
1168 struct xfs_trans
*tp
,
1169 enum xfs_rmap_intent_type type
,
1172 xfs_fileoff_t startoff
,
1173 xfs_fsblock_t startblock
,
1174 xfs_filblks_t blockcount
,
1176 struct xfs_btree_cur
**pcur
)
1178 struct xfs_mount
*mp
= tp
->t_mountp
;
1179 struct xfs_btree_cur
*rcur
;
1180 struct xfs_buf
*agbp
= NULL
;
1182 xfs_agnumber_t agno
;
1183 struct xfs_owner_info oinfo
;
1187 agno
= XFS_FSB_TO_AGNO(mp
, startblock
);
1188 ASSERT(agno
!= NULLAGNUMBER
);
1189 bno
= XFS_FSB_TO_AGBNO(mp
, startblock
);
1191 trace_xfs_rmap_deferred(mp
, agno
, type
, bno
, owner
, whichfork
,
1192 startoff
, blockcount
, state
);
1194 if (XFS_TEST_ERROR(false, mp
,
1195 XFS_ERRTAG_RMAP_FINISH_ONE
,
1196 XFS_RANDOM_RMAP_FINISH_ONE
))
1200 * If we haven't gotten a cursor or the cursor AG doesn't match
1201 * the startblock, get one now.
1204 if (rcur
!= NULL
&& rcur
->bc_private
.a
.agno
!= agno
) {
1205 xfs_rmap_finish_one_cleanup(tp
, rcur
, 0);
1211 * Refresh the freelist before we start changing the
1212 * rmapbt, because a shape change could cause us to
1215 error
= xfs_free_extent_fix_freelist(tp
, agno
, &agbp
);
1219 return -EFSCORRUPTED
;
1221 rcur
= xfs_rmapbt_init_cursor(mp
, tp
, agbp
, agno
);
1229 xfs_rmap_ino_owner(&oinfo
, owner
, whichfork
, startoff
);
1230 unwritten
= state
== XFS_EXT_UNWRITTEN
;
1231 bno
= XFS_FSB_TO_AGBNO(rcur
->bc_mp
, startblock
);
1234 case XFS_RMAP_ALLOC
:
1236 error
= xfs_rmap_map(rcur
, bno
, blockcount
, unwritten
, &oinfo
);
1239 case XFS_RMAP_UNMAP
:
1240 error
= xfs_rmap_unmap(rcur
, bno
, blockcount
, unwritten
,
1243 case XFS_RMAP_CONVERT
:
1244 error
= xfs_rmap_convert(rcur
, bno
, blockcount
, !unwritten
,
1249 error
= -EFSCORRUPTED
;
1254 xfs_trans_brelse(tp
, agbp
);
1260 * Don't defer an rmap if we aren't an rmap filesystem.
1263 xfs_rmap_update_is_needed(
1264 struct xfs_mount
*mp
)
1266 return xfs_sb_version_hasrmapbt(&mp
->m_sb
);
1270 * Record a rmap intent; the list is kept sorted first by AG and then by
1275 struct xfs_mount
*mp
,
1276 struct xfs_defer_ops
*dfops
,
1277 enum xfs_rmap_intent_type type
,
1280 struct xfs_bmbt_irec
*bmap
)
1282 struct xfs_rmap_intent
*ri
;
1284 trace_xfs_rmap_defer(mp
, XFS_FSB_TO_AGNO(mp
, bmap
->br_startblock
),
1286 XFS_FSB_TO_AGBNO(mp
, bmap
->br_startblock
),
1289 bmap
->br_blockcount
,
1292 ri
= kmem_alloc(sizeof(struct xfs_rmap_intent
), KM_SLEEP
| KM_NOFS
);
1293 INIT_LIST_HEAD(&ri
->ri_list
);
1295 ri
->ri_owner
= owner
;
1296 ri
->ri_whichfork
= whichfork
;
1297 ri
->ri_bmap
= *bmap
;
1299 xfs_defer_add(dfops
, XFS_DEFER_OPS_TYPE_RMAP
, &ri
->ri_list
);
1303 /* Map an extent into a file. */
1305 xfs_rmap_map_extent(
1306 struct xfs_mount
*mp
,
1307 struct xfs_defer_ops
*dfops
,
1308 struct xfs_inode
*ip
,
1310 struct xfs_bmbt_irec
*PREV
)
1312 if (!xfs_rmap_update_is_needed(mp
))
1315 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_MAP
, ip
->i_ino
,
1319 /* Unmap an extent out of a file. */
1321 xfs_rmap_unmap_extent(
1322 struct xfs_mount
*mp
,
1323 struct xfs_defer_ops
*dfops
,
1324 struct xfs_inode
*ip
,
1326 struct xfs_bmbt_irec
*PREV
)
1328 if (!xfs_rmap_update_is_needed(mp
))
1331 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_UNMAP
, ip
->i_ino
,
1335 /* Convert a data fork extent from unwritten to real or vice versa. */
1337 xfs_rmap_convert_extent(
1338 struct xfs_mount
*mp
,
1339 struct xfs_defer_ops
*dfops
,
1340 struct xfs_inode
*ip
,
1342 struct xfs_bmbt_irec
*PREV
)
1344 if (!xfs_rmap_update_is_needed(mp
))
1347 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_CONVERT
, ip
->i_ino
,
1351 /* Schedule the creation of an rmap for non-file data. */
1353 xfs_rmap_alloc_extent(
1354 struct xfs_mount
*mp
,
1355 struct xfs_defer_ops
*dfops
,
1356 xfs_agnumber_t agno
,
1361 struct xfs_bmbt_irec bmap
;
1363 if (!xfs_rmap_update_is_needed(mp
))
1366 bmap
.br_startblock
= XFS_AGB_TO_FSB(mp
, agno
, bno
);
1367 bmap
.br_blockcount
= len
;
1368 bmap
.br_startoff
= 0;
1369 bmap
.br_state
= XFS_EXT_NORM
;
1371 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_ALLOC
, owner
,
1372 XFS_DATA_FORK
, &bmap
);
1375 /* Schedule the deletion of an rmap for non-file data. */
1377 xfs_rmap_free_extent(
1378 struct xfs_mount
*mp
,
1379 struct xfs_defer_ops
*dfops
,
1380 xfs_agnumber_t agno
,
1385 struct xfs_bmbt_irec bmap
;
1387 if (!xfs_rmap_update_is_needed(mp
))
1390 bmap
.br_startblock
= XFS_AGB_TO_FSB(mp
, agno
, bno
);
1391 bmap
.br_blockcount
= len
;
1392 bmap
.br_startoff
= 0;
1393 bmap
.br_state
= XFS_EXT_NORM
;
1395 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_FREE
, owner
,
1396 XFS_DATA_FORK
, &bmap
);