2 * Copyright (c) 2014 Red Hat, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
26 #include "xfs_mount.h"
27 #include "xfs_defer.h"
28 #include "xfs_da_format.h"
29 #include "xfs_da_btree.h"
30 #include "xfs_btree.h"
31 #include "xfs_trans.h"
32 #include "xfs_alloc.h"
34 #include "xfs_rmap_btree.h"
35 #include "xfs_trans_space.h"
36 #include "xfs_trace.h"
37 #include "xfs_error.h"
38 #include "xfs_extent_busy.h"
40 #include "xfs_inode.h"
43 * Lookup the first record less than or equal to [bno, len, owner, offset]
44 * in the btree given by cur.
48 struct xfs_btree_cur
*cur
,
56 cur
->bc_rec
.r
.rm_startblock
= bno
;
57 cur
->bc_rec
.r
.rm_blockcount
= len
;
58 cur
->bc_rec
.r
.rm_owner
= owner
;
59 cur
->bc_rec
.r
.rm_offset
= offset
;
60 cur
->bc_rec
.r
.rm_flags
= flags
;
61 return xfs_btree_lookup(cur
, XFS_LOOKUP_LE
, stat
);
65 * Lookup the record exactly matching [bno, len, owner, offset]
66 * in the btree given by cur.
70 struct xfs_btree_cur
*cur
,
78 cur
->bc_rec
.r
.rm_startblock
= bno
;
79 cur
->bc_rec
.r
.rm_blockcount
= len
;
80 cur
->bc_rec
.r
.rm_owner
= owner
;
81 cur
->bc_rec
.r
.rm_offset
= offset
;
82 cur
->bc_rec
.r
.rm_flags
= flags
;
83 return xfs_btree_lookup(cur
, XFS_LOOKUP_EQ
, stat
);
87 * Update the record referred to by cur to the value given
88 * by [bno, len, owner, offset].
89 * This either works (return 0) or gets an EFSCORRUPTED error.
93 struct xfs_btree_cur
*cur
,
94 struct xfs_rmap_irec
*irec
)
96 union xfs_btree_rec rec
;
99 trace_xfs_rmap_update(cur
->bc_mp
, cur
->bc_private
.a
.agno
,
100 irec
->rm_startblock
, irec
->rm_blockcount
,
101 irec
->rm_owner
, irec
->rm_offset
, irec
->rm_flags
);
103 rec
.rmap
.rm_startblock
= cpu_to_be32(irec
->rm_startblock
);
104 rec
.rmap
.rm_blockcount
= cpu_to_be32(irec
->rm_blockcount
);
105 rec
.rmap
.rm_owner
= cpu_to_be64(irec
->rm_owner
);
106 rec
.rmap
.rm_offset
= cpu_to_be64(
107 xfs_rmap_irec_offset_pack(irec
));
108 error
= xfs_btree_update(cur
, &rec
);
110 trace_xfs_rmap_update_error(cur
->bc_mp
,
111 cur
->bc_private
.a
.agno
, error
, _RET_IP_
);
117 struct xfs_btree_cur
*rcur
,
127 trace_xfs_rmap_insert(rcur
->bc_mp
, rcur
->bc_private
.a
.agno
, agbno
,
128 len
, owner
, offset
, flags
);
130 error
= xfs_rmap_lookup_eq(rcur
, agbno
, len
, owner
, offset
, flags
, &i
);
133 XFS_WANT_CORRUPTED_GOTO(rcur
->bc_mp
, i
== 0, done
);
135 rcur
->bc_rec
.r
.rm_startblock
= agbno
;
136 rcur
->bc_rec
.r
.rm_blockcount
= len
;
137 rcur
->bc_rec
.r
.rm_owner
= owner
;
138 rcur
->bc_rec
.r
.rm_offset
= offset
;
139 rcur
->bc_rec
.r
.rm_flags
= flags
;
140 error
= xfs_btree_insert(rcur
, &i
);
143 XFS_WANT_CORRUPTED_GOTO(rcur
->bc_mp
, i
== 1, done
);
146 trace_xfs_rmap_insert_error(rcur
->bc_mp
,
147 rcur
->bc_private
.a
.agno
, error
, _RET_IP_
);
152 xfs_rmap_btrec_to_irec(
153 union xfs_btree_rec
*rec
,
154 struct xfs_rmap_irec
*irec
)
157 irec
->rm_startblock
= be32_to_cpu(rec
->rmap
.rm_startblock
);
158 irec
->rm_blockcount
= be32_to_cpu(rec
->rmap
.rm_blockcount
);
159 irec
->rm_owner
= be64_to_cpu(rec
->rmap
.rm_owner
);
160 return xfs_rmap_irec_offset_unpack(be64_to_cpu(rec
->rmap
.rm_offset
),
165 * Get the data from the pointed-to record.
169 struct xfs_btree_cur
*cur
,
170 struct xfs_rmap_irec
*irec
,
173 union xfs_btree_rec
*rec
;
176 error
= xfs_btree_get_rec(cur
, &rec
, stat
);
180 return xfs_rmap_btrec_to_irec(rec
, irec
);
184 * Find the extent in the rmap btree and remove it.
186 * The record we find should always be an exact match for the extent that we're
187 * looking for, since we insert them into the btree without modification.
189 * Special Case #1: when growing the filesystem, we "free" an extent when
190 * growing the last AG. This extent is new space and so it is not tracked as
191 * used space in the btree. The growfs code will pass in an owner of
192 * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this
193 * extent. We verify that - the extent lookup result in a record that does not
196 * Special Case #2: EFIs do not record the owner of the extent, so when
197 * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap
198 * btree to ignore the owner (i.e. wildcard match) so we don't trigger
199 * corruption checks during log recovery.
203 struct xfs_btree_cur
*cur
,
207 struct xfs_owner_info
*oinfo
)
209 struct xfs_mount
*mp
= cur
->bc_mp
;
210 struct xfs_rmap_irec ltrec
;
219 xfs_owner_info_unpack(oinfo
, &owner
, &offset
, &flags
);
220 ignore_off
= XFS_RMAP_NON_INODE_OWNER(owner
) ||
221 (flags
& XFS_RMAP_BMBT_BLOCK
);
223 flags
|= XFS_RMAP_UNWRITTEN
;
224 trace_xfs_rmap_unmap(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
228 * We should always have a left record because there's a static record
229 * for the AG headers at rm_startblock == 0 created by mkfs/growfs that
230 * will not ever be removed from the tree.
232 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, flags
, &i
);
235 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
237 error
= xfs_rmap_get_rec(cur
, <rec
, &i
);
240 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
241 trace_xfs_rmap_lookup_le_range_result(cur
->bc_mp
,
242 cur
->bc_private
.a
.agno
, ltrec
.rm_startblock
,
243 ltrec
.rm_blockcount
, ltrec
.rm_owner
,
244 ltrec
.rm_offset
, ltrec
.rm_flags
);
245 ltoff
= ltrec
.rm_offset
;
248 * For growfs, the incoming extent must be beyond the left record we
249 * just found as it is new space and won't be used by anyone. This is
250 * just a corruption check as we don't actually do anything with this
251 * extent. Note that we need to use >= instead of > because it might
252 * be the case that the "left" extent goes all the way to EOFS.
254 if (owner
== XFS_RMAP_OWN_NULL
) {
255 XFS_WANT_CORRUPTED_GOTO(mp
, bno
>= ltrec
.rm_startblock
+
256 ltrec
.rm_blockcount
, out_error
);
260 /* Make sure the unwritten flag matches. */
261 XFS_WANT_CORRUPTED_GOTO(mp
, (flags
& XFS_RMAP_UNWRITTEN
) ==
262 (ltrec
.rm_flags
& XFS_RMAP_UNWRITTEN
), out_error
);
264 /* Make sure the extent we found covers the entire freeing range. */
265 XFS_WANT_CORRUPTED_GOTO(mp
, ltrec
.rm_startblock
<= bno
&&
266 ltrec
.rm_startblock
+ ltrec
.rm_blockcount
>=
267 bno
+ len
, out_error
);
269 /* Make sure the owner matches what we expect to find in the tree. */
270 XFS_WANT_CORRUPTED_GOTO(mp
, owner
== ltrec
.rm_owner
||
271 XFS_RMAP_NON_INODE_OWNER(owner
), out_error
);
273 /* Check the offset, if necessary. */
274 if (!XFS_RMAP_NON_INODE_OWNER(owner
)) {
275 if (flags
& XFS_RMAP_BMBT_BLOCK
) {
276 XFS_WANT_CORRUPTED_GOTO(mp
,
277 ltrec
.rm_flags
& XFS_RMAP_BMBT_BLOCK
,
280 XFS_WANT_CORRUPTED_GOTO(mp
,
281 ltrec
.rm_offset
<= offset
, out_error
);
282 XFS_WANT_CORRUPTED_GOTO(mp
,
283 ltoff
+ ltrec
.rm_blockcount
>= offset
+ len
,
288 if (ltrec
.rm_startblock
== bno
&& ltrec
.rm_blockcount
== len
) {
289 /* exact match, simply remove the record from rmap tree */
290 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
291 ltrec
.rm_startblock
, ltrec
.rm_blockcount
,
292 ltrec
.rm_owner
, ltrec
.rm_offset
,
294 error
= xfs_btree_delete(cur
, &i
);
297 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
298 } else if (ltrec
.rm_startblock
== bno
) {
300 * overlap left hand side of extent: move the start, trim the
301 * length and update the current record.
304 * Orig: |oooooooooooooooooooo|
305 * Freeing: |fffffffff|
306 * Result: |rrrrrrrrrr|
309 ltrec
.rm_startblock
+= len
;
310 ltrec
.rm_blockcount
-= len
;
312 ltrec
.rm_offset
+= len
;
313 error
= xfs_rmap_update(cur
, <rec
);
316 } else if (ltrec
.rm_startblock
+ ltrec
.rm_blockcount
== bno
+ len
) {
318 * overlap right hand side of extent: trim the length and update
319 * the current record.
322 * Orig: |oooooooooooooooooooo|
323 * Freeing: |fffffffff|
324 * Result: |rrrrrrrrrr|
327 ltrec
.rm_blockcount
-= len
;
328 error
= xfs_rmap_update(cur
, <rec
);
334 * overlap middle of extent: trim the length of the existing
335 * record to the length of the new left-extent size, increment
336 * the insertion position so we can insert a new record
337 * containing the remaining right-extent space.
340 * Orig: |oooooooooooooooooooo|
341 * Freeing: |fffffffff|
342 * Result: |rrrrr| |rrrr|
345 xfs_extlen_t orig_len
= ltrec
.rm_blockcount
;
347 ltrec
.rm_blockcount
= bno
- ltrec
.rm_startblock
;
348 error
= xfs_rmap_update(cur
, <rec
);
352 error
= xfs_btree_increment(cur
, 0, &i
);
356 cur
->bc_rec
.r
.rm_startblock
= bno
+ len
;
357 cur
->bc_rec
.r
.rm_blockcount
= orig_len
- len
-
359 cur
->bc_rec
.r
.rm_owner
= ltrec
.rm_owner
;
361 cur
->bc_rec
.r
.rm_offset
= 0;
363 cur
->bc_rec
.r
.rm_offset
= offset
+ len
;
364 cur
->bc_rec
.r
.rm_flags
= flags
;
365 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
,
366 cur
->bc_rec
.r
.rm_startblock
,
367 cur
->bc_rec
.r
.rm_blockcount
,
368 cur
->bc_rec
.r
.rm_owner
,
369 cur
->bc_rec
.r
.rm_offset
,
370 cur
->bc_rec
.r
.rm_flags
);
371 error
= xfs_btree_insert(cur
, &i
);
377 trace_xfs_rmap_unmap_done(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
381 trace_xfs_rmap_unmap_error(mp
, cur
->bc_private
.a
.agno
,
387 * Remove a reference to an extent in the rmap btree.
391 struct xfs_trans
*tp
,
392 struct xfs_buf
*agbp
,
396 struct xfs_owner_info
*oinfo
)
398 struct xfs_mount
*mp
= tp
->t_mountp
;
399 struct xfs_btree_cur
*cur
;
402 if (!xfs_sb_version_hasrmapbt(&mp
->m_sb
))
405 cur
= xfs_rmapbt_init_cursor(mp
, tp
, agbp
, agno
);
407 error
= xfs_rmap_unmap(cur
, bno
, len
, false, oinfo
);
411 xfs_btree_del_cursor(cur
, XFS_BTREE_NOERROR
);
415 xfs_btree_del_cursor(cur
, XFS_BTREE_ERROR
);
420 * A mergeable rmap must have the same owner and the same values for
421 * the unwritten, attr_fork, and bmbt flags. The startblock and
422 * offset are checked separately.
425 xfs_rmap_is_mergeable(
426 struct xfs_rmap_irec
*irec
,
430 if (irec
->rm_owner
== XFS_RMAP_OWN_NULL
)
432 if (irec
->rm_owner
!= owner
)
434 if ((flags
& XFS_RMAP_UNWRITTEN
) ^
435 (irec
->rm_flags
& XFS_RMAP_UNWRITTEN
))
437 if ((flags
& XFS_RMAP_ATTR_FORK
) ^
438 (irec
->rm_flags
& XFS_RMAP_ATTR_FORK
))
440 if ((flags
& XFS_RMAP_BMBT_BLOCK
) ^
441 (irec
->rm_flags
& XFS_RMAP_BMBT_BLOCK
))
447 * When we allocate a new block, the first thing we do is add a reference to
448 * the extent in the rmap btree. This takes the form of a [agbno, length,
449 * owner, offset] record. Flags are encoded in the high bits of the offset
454 struct xfs_btree_cur
*cur
,
458 struct xfs_owner_info
*oinfo
)
460 struct xfs_mount
*mp
= cur
->bc_mp
;
461 struct xfs_rmap_irec ltrec
;
462 struct xfs_rmap_irec gtrec
;
469 unsigned int flags
= 0;
472 xfs_owner_info_unpack(oinfo
, &owner
, &offset
, &flags
);
474 ignore_off
= XFS_RMAP_NON_INODE_OWNER(owner
) ||
475 (flags
& XFS_RMAP_BMBT_BLOCK
);
477 flags
|= XFS_RMAP_UNWRITTEN
;
478 trace_xfs_rmap_map(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
482 * For the initial lookup, look for an exact match or the left-adjacent
483 * record for our insertion point. This will also give us the record for
484 * start block contiguity tests.
486 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, flags
,
490 XFS_WANT_CORRUPTED_GOTO(mp
, have_lt
== 1, out_error
);
492 error
= xfs_rmap_get_rec(cur
, <rec
, &have_lt
);
495 XFS_WANT_CORRUPTED_GOTO(mp
, have_lt
== 1, out_error
);
496 trace_xfs_rmap_lookup_le_range_result(cur
->bc_mp
,
497 cur
->bc_private
.a
.agno
, ltrec
.rm_startblock
,
498 ltrec
.rm_blockcount
, ltrec
.rm_owner
,
499 ltrec
.rm_offset
, ltrec
.rm_flags
);
501 if (!xfs_rmap_is_mergeable(<rec
, owner
, flags
))
504 XFS_WANT_CORRUPTED_GOTO(mp
,
506 ltrec
.rm_startblock
+ ltrec
.rm_blockcount
<= bno
, out_error
);
509 * Increment the cursor to see if we have a right-adjacent record to our
510 * insertion point. This will give us the record for end block
513 error
= xfs_btree_increment(cur
, 0, &have_gt
);
517 error
= xfs_rmap_get_rec(cur
, >rec
, &have_gt
);
520 XFS_WANT_CORRUPTED_GOTO(mp
, have_gt
== 1, out_error
);
521 XFS_WANT_CORRUPTED_GOTO(mp
, bno
+ len
<= gtrec
.rm_startblock
,
523 trace_xfs_rmap_find_right_neighbor_result(cur
->bc_mp
,
524 cur
->bc_private
.a
.agno
, gtrec
.rm_startblock
,
525 gtrec
.rm_blockcount
, gtrec
.rm_owner
,
526 gtrec
.rm_offset
, gtrec
.rm_flags
);
527 if (!xfs_rmap_is_mergeable(>rec
, owner
, flags
))
532 * Note: cursor currently points one record to the right of ltrec, even
533 * if there is no record in the tree to the right.
536 ltrec
.rm_startblock
+ ltrec
.rm_blockcount
== bno
&&
537 (ignore_off
|| ltrec
.rm_offset
+ ltrec
.rm_blockcount
== offset
)) {
539 * left edge contiguous, merge into left record.
543 * adding: |aaaaaaaaa|
544 * result: |rrrrrrrrrrrrrrrrrrr|
547 ltrec
.rm_blockcount
+= len
;
549 bno
+ len
== gtrec
.rm_startblock
&&
550 (ignore_off
|| offset
+ len
== gtrec
.rm_offset
) &&
551 (unsigned long)ltrec
.rm_blockcount
+ len
+
552 gtrec
.rm_blockcount
<= XFS_RMAP_LEN_MAX
) {
554 * right edge also contiguous, delete right record
555 * and merge into left record.
557 * ltbno ltlen gtbno gtlen
558 * orig: |ooooooooo| |ooooooooo|
559 * adding: |aaaaaaaaa|
560 * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr|
562 ltrec
.rm_blockcount
+= gtrec
.rm_blockcount
;
563 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
569 error
= xfs_btree_delete(cur
, &i
);
572 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
575 /* point the cursor back to the left record and update */
576 error
= xfs_btree_decrement(cur
, 0, &have_gt
);
579 error
= xfs_rmap_update(cur
, <rec
);
582 } else if (have_gt
&&
583 bno
+ len
== gtrec
.rm_startblock
&&
584 (ignore_off
|| offset
+ len
== gtrec
.rm_offset
)) {
586 * right edge contiguous, merge into right record.
590 * adding: |aaaaaaaaa|
591 * Result: |rrrrrrrrrrrrrrrrrrr|
594 gtrec
.rm_startblock
= bno
;
595 gtrec
.rm_blockcount
+= len
;
597 gtrec
.rm_offset
= offset
;
598 error
= xfs_rmap_update(cur
, >rec
);
603 * no contiguous edge with identical owner, insert
604 * new record at current cursor position.
606 cur
->bc_rec
.r
.rm_startblock
= bno
;
607 cur
->bc_rec
.r
.rm_blockcount
= len
;
608 cur
->bc_rec
.r
.rm_owner
= owner
;
609 cur
->bc_rec
.r
.rm_offset
= offset
;
610 cur
->bc_rec
.r
.rm_flags
= flags
;
611 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
612 owner
, offset
, flags
);
613 error
= xfs_btree_insert(cur
, &i
);
616 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, out_error
);
619 trace_xfs_rmap_map_done(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
623 trace_xfs_rmap_map_error(mp
, cur
->bc_private
.a
.agno
,
629 * Add a reference to an extent in the rmap btree.
633 struct xfs_trans
*tp
,
634 struct xfs_buf
*agbp
,
638 struct xfs_owner_info
*oinfo
)
640 struct xfs_mount
*mp
= tp
->t_mountp
;
641 struct xfs_btree_cur
*cur
;
644 if (!xfs_sb_version_hasrmapbt(&mp
->m_sb
))
647 cur
= xfs_rmapbt_init_cursor(mp
, tp
, agbp
, agno
);
648 error
= xfs_rmap_map(cur
, bno
, len
, false, oinfo
);
652 xfs_btree_del_cursor(cur
, XFS_BTREE_NOERROR
);
656 xfs_btree_del_cursor(cur
, XFS_BTREE_ERROR
);
660 #define RMAP_LEFT_CONTIG (1 << 0)
661 #define RMAP_RIGHT_CONTIG (1 << 1)
662 #define RMAP_LEFT_FILLING (1 << 2)
663 #define RMAP_RIGHT_FILLING (1 << 3)
664 #define RMAP_LEFT_VALID (1 << 6)
665 #define RMAP_RIGHT_VALID (1 << 7)
673 * Convert an unwritten extent to a real extent or vice versa.
674 * Does not handle overlapping extents.
678 struct xfs_btree_cur
*cur
,
682 struct xfs_owner_info
*oinfo
)
684 struct xfs_mount
*mp
= cur
->bc_mp
;
685 struct xfs_rmap_irec r
[4]; /* neighbor extent entries */
686 /* left is 0, right is 1, prev is 2 */
693 unsigned int flags
= 0;
698 xfs_owner_info_unpack(oinfo
, &owner
, &offset
, &flags
);
699 ASSERT(!(XFS_RMAP_NON_INODE_OWNER(owner
) ||
700 (flags
& (XFS_RMAP_ATTR_FORK
| XFS_RMAP_BMBT_BLOCK
))));
701 oldext
= unwritten
? XFS_RMAP_UNWRITTEN
: 0;
702 new_endoff
= offset
+ len
;
703 trace_xfs_rmap_convert(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
707 * For the initial lookup, look for an exact match or the left-adjacent
708 * record for our insertion point. This will also give us the record for
709 * start block contiguity tests.
711 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, oldext
, &i
);
714 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
716 error
= xfs_rmap_get_rec(cur
, &PREV
, &i
);
719 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
720 trace_xfs_rmap_lookup_le_range_result(cur
->bc_mp
,
721 cur
->bc_private
.a
.agno
, PREV
.rm_startblock
,
722 PREV
.rm_blockcount
, PREV
.rm_owner
,
723 PREV
.rm_offset
, PREV
.rm_flags
);
725 ASSERT(PREV
.rm_offset
<= offset
);
726 ASSERT(PREV
.rm_offset
+ PREV
.rm_blockcount
>= new_endoff
);
727 ASSERT((PREV
.rm_flags
& XFS_RMAP_UNWRITTEN
) == oldext
);
728 newext
= ~oldext
& XFS_RMAP_UNWRITTEN
;
731 * Set flags determining what part of the previous oldext allocation
732 * extent is being replaced by a newext allocation.
734 if (PREV
.rm_offset
== offset
)
735 state
|= RMAP_LEFT_FILLING
;
736 if (PREV
.rm_offset
+ PREV
.rm_blockcount
== new_endoff
)
737 state
|= RMAP_RIGHT_FILLING
;
740 * Decrement the cursor to see if we have a left-adjacent record to our
741 * insertion point. This will give us the record for end block
744 error
= xfs_btree_decrement(cur
, 0, &i
);
748 state
|= RMAP_LEFT_VALID
;
749 error
= xfs_rmap_get_rec(cur
, &LEFT
, &i
);
752 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
753 XFS_WANT_CORRUPTED_GOTO(mp
,
754 LEFT
.rm_startblock
+ LEFT
.rm_blockcount
<= bno
,
756 trace_xfs_rmap_find_left_neighbor_result(cur
->bc_mp
,
757 cur
->bc_private
.a
.agno
, LEFT
.rm_startblock
,
758 LEFT
.rm_blockcount
, LEFT
.rm_owner
,
759 LEFT
.rm_offset
, LEFT
.rm_flags
);
760 if (LEFT
.rm_startblock
+ LEFT
.rm_blockcount
== bno
&&
761 LEFT
.rm_offset
+ LEFT
.rm_blockcount
== offset
&&
762 xfs_rmap_is_mergeable(&LEFT
, owner
, newext
))
763 state
|= RMAP_LEFT_CONTIG
;
767 * Increment the cursor to see if we have a right-adjacent record to our
768 * insertion point. This will give us the record for end block
771 error
= xfs_btree_increment(cur
, 0, &i
);
774 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
775 error
= xfs_btree_increment(cur
, 0, &i
);
779 state
|= RMAP_RIGHT_VALID
;
780 error
= xfs_rmap_get_rec(cur
, &RIGHT
, &i
);
783 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
784 XFS_WANT_CORRUPTED_GOTO(mp
, bno
+ len
<= RIGHT
.rm_startblock
,
786 trace_xfs_rmap_find_right_neighbor_result(cur
->bc_mp
,
787 cur
->bc_private
.a
.agno
, RIGHT
.rm_startblock
,
788 RIGHT
.rm_blockcount
, RIGHT
.rm_owner
,
789 RIGHT
.rm_offset
, RIGHT
.rm_flags
);
790 if (bno
+ len
== RIGHT
.rm_startblock
&&
791 offset
+ len
== RIGHT
.rm_offset
&&
792 xfs_rmap_is_mergeable(&RIGHT
, owner
, newext
))
793 state
|= RMAP_RIGHT_CONTIG
;
796 /* check that left + prev + right is not too long */
797 if ((state
& (RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
798 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
)) ==
799 (RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
800 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
) &&
801 (unsigned long)LEFT
.rm_blockcount
+ len
+
802 RIGHT
.rm_blockcount
> XFS_RMAP_LEN_MAX
)
803 state
&= ~RMAP_RIGHT_CONTIG
;
805 trace_xfs_rmap_convert_state(mp
, cur
->bc_private
.a
.agno
, state
,
808 /* reset the cursor back to PREV */
809 error
= xfs_rmap_lookup_le(cur
, bno
, len
, owner
, offset
, oldext
, &i
);
812 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
815 * Switch out based on the FILLING and CONTIG state bits.
817 switch (state
& (RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
818 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
)) {
819 case RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
|
820 RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
:
822 * Setting all of a previous oldext extent to newext.
823 * The left and right neighbors are both contiguous with new.
825 error
= xfs_btree_increment(cur
, 0, &i
);
828 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
829 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
830 RIGHT
.rm_startblock
, RIGHT
.rm_blockcount
,
831 RIGHT
.rm_owner
, RIGHT
.rm_offset
,
833 error
= xfs_btree_delete(cur
, &i
);
836 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
837 error
= xfs_btree_decrement(cur
, 0, &i
);
840 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
841 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
842 PREV
.rm_startblock
, PREV
.rm_blockcount
,
843 PREV
.rm_owner
, PREV
.rm_offset
,
845 error
= xfs_btree_delete(cur
, &i
);
848 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
849 error
= xfs_btree_decrement(cur
, 0, &i
);
852 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
854 NEW
.rm_blockcount
+= PREV
.rm_blockcount
+ RIGHT
.rm_blockcount
;
855 error
= xfs_rmap_update(cur
, &NEW
);
860 case RMAP_LEFT_FILLING
| RMAP_RIGHT_FILLING
| RMAP_LEFT_CONTIG
:
862 * Setting all of a previous oldext extent to newext.
863 * The left neighbor is contiguous, the right is not.
865 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
866 PREV
.rm_startblock
, PREV
.rm_blockcount
,
867 PREV
.rm_owner
, PREV
.rm_offset
,
869 error
= xfs_btree_delete(cur
, &i
);
872 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
873 error
= xfs_btree_decrement(cur
, 0, &i
);
876 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
878 NEW
.rm_blockcount
+= PREV
.rm_blockcount
;
879 error
= xfs_rmap_update(cur
, &NEW
);
884 case RMAP_LEFT_FILLING
| RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
:
886 * Setting all of a previous oldext extent to newext.
887 * The right neighbor is contiguous, the left is not.
889 error
= xfs_btree_increment(cur
, 0, &i
);
892 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
893 trace_xfs_rmap_delete(mp
, cur
->bc_private
.a
.agno
,
894 RIGHT
.rm_startblock
, RIGHT
.rm_blockcount
,
895 RIGHT
.rm_owner
, RIGHT
.rm_offset
,
897 error
= xfs_btree_delete(cur
, &i
);
900 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
901 error
= xfs_btree_decrement(cur
, 0, &i
);
904 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
906 NEW
.rm_blockcount
= len
+ RIGHT
.rm_blockcount
;
907 NEW
.rm_flags
= newext
;
908 error
= xfs_rmap_update(cur
, &NEW
);
913 case RMAP_LEFT_FILLING
| RMAP_RIGHT_FILLING
:
915 * Setting all of a previous oldext extent to newext.
916 * Neither the left nor right neighbors are contiguous with
920 NEW
.rm_flags
= newext
;
921 error
= xfs_rmap_update(cur
, &NEW
);
926 case RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
:
928 * Setting the first part of a previous oldext extent to newext.
929 * The left neighbor is contiguous.
932 NEW
.rm_offset
+= len
;
933 NEW
.rm_startblock
+= len
;
934 NEW
.rm_blockcount
-= len
;
935 error
= xfs_rmap_update(cur
, &NEW
);
938 error
= xfs_btree_decrement(cur
, 0, &i
);
942 NEW
.rm_blockcount
+= len
;
943 error
= xfs_rmap_update(cur
, &NEW
);
948 case RMAP_LEFT_FILLING
:
950 * Setting the first part of a previous oldext extent to newext.
951 * The left neighbor is not contiguous.
954 NEW
.rm_startblock
+= len
;
955 NEW
.rm_offset
+= len
;
956 NEW
.rm_blockcount
-= len
;
957 error
= xfs_rmap_update(cur
, &NEW
);
960 NEW
.rm_startblock
= bno
;
961 NEW
.rm_owner
= owner
;
962 NEW
.rm_offset
= offset
;
963 NEW
.rm_blockcount
= len
;
964 NEW
.rm_flags
= newext
;
966 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
,
967 len
, owner
, offset
, newext
);
968 error
= xfs_btree_insert(cur
, &i
);
971 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
974 case RMAP_RIGHT_FILLING
| RMAP_RIGHT_CONTIG
:
976 * Setting the last part of a previous oldext extent to newext.
977 * The right neighbor is contiguous with the new allocation.
980 NEW
.rm_blockcount
-= len
;
981 error
= xfs_rmap_update(cur
, &NEW
);
984 error
= xfs_btree_increment(cur
, 0, &i
);
988 NEW
.rm_offset
= offset
;
989 NEW
.rm_startblock
= bno
;
990 NEW
.rm_blockcount
+= len
;
991 error
= xfs_rmap_update(cur
, &NEW
);
996 case RMAP_RIGHT_FILLING
:
998 * Setting the last part of a previous oldext extent to newext.
999 * The right neighbor is not contiguous.
1002 NEW
.rm_blockcount
-= len
;
1003 error
= xfs_rmap_update(cur
, &NEW
);
1006 error
= xfs_rmap_lookup_eq(cur
, bno
, len
, owner
, offset
,
1010 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 0, done
);
1011 NEW
.rm_startblock
= bno
;
1012 NEW
.rm_owner
= owner
;
1013 NEW
.rm_offset
= offset
;
1014 NEW
.rm_blockcount
= len
;
1015 NEW
.rm_flags
= newext
;
1016 cur
->bc_rec
.r
= NEW
;
1017 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
,
1018 len
, owner
, offset
, newext
);
1019 error
= xfs_btree_insert(cur
, &i
);
1022 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
1027 * Setting the middle part of a previous oldext extent to
1028 * newext. Contiguity is impossible here.
1029 * One extent becomes three extents.
1031 /* new right extent - oldext */
1032 NEW
.rm_startblock
= bno
+ len
;
1033 NEW
.rm_owner
= owner
;
1034 NEW
.rm_offset
= new_endoff
;
1035 NEW
.rm_blockcount
= PREV
.rm_offset
+ PREV
.rm_blockcount
-
1037 NEW
.rm_flags
= PREV
.rm_flags
;
1038 error
= xfs_rmap_update(cur
, &NEW
);
1041 /* new left extent - oldext */
1043 NEW
.rm_blockcount
= offset
- PREV
.rm_offset
;
1044 cur
->bc_rec
.r
= NEW
;
1045 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
,
1046 NEW
.rm_startblock
, NEW
.rm_blockcount
,
1047 NEW
.rm_owner
, NEW
.rm_offset
,
1049 error
= xfs_btree_insert(cur
, &i
);
1052 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
1054 * Reset the cursor to the position of the new extent
1055 * we are about to insert as we can't trust it after
1056 * the previous insert.
1058 error
= xfs_rmap_lookup_eq(cur
, bno
, len
, owner
, offset
,
1062 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 0, done
);
1063 /* new middle extent - newext */
1064 cur
->bc_rec
.r
.rm_flags
&= ~XFS_RMAP_UNWRITTEN
;
1065 cur
->bc_rec
.r
.rm_flags
|= newext
;
1066 trace_xfs_rmap_insert(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
1067 owner
, offset
, newext
);
1068 error
= xfs_btree_insert(cur
, &i
);
1071 XFS_WANT_CORRUPTED_GOTO(mp
, i
== 1, done
);
1074 case RMAP_LEFT_FILLING
| RMAP_LEFT_CONTIG
| RMAP_RIGHT_CONTIG
:
1075 case RMAP_RIGHT_FILLING
| RMAP_LEFT_CONTIG
| RMAP_RIGHT_CONTIG
:
1076 case RMAP_LEFT_FILLING
| RMAP_RIGHT_CONTIG
:
1077 case RMAP_RIGHT_FILLING
| RMAP_LEFT_CONTIG
:
1078 case RMAP_LEFT_CONTIG
| RMAP_RIGHT_CONTIG
:
1079 case RMAP_LEFT_CONTIG
:
1080 case RMAP_RIGHT_CONTIG
:
1082 * These cases are all impossible.
1087 trace_xfs_rmap_convert_done(mp
, cur
->bc_private
.a
.agno
, bno
, len
,
1091 trace_xfs_rmap_convert_error(cur
->bc_mp
,
1092 cur
->bc_private
.a
.agno
, error
, _RET_IP_
);
1101 struct xfs_rmap_query_range_info
{
1102 xfs_rmap_query_range_fn fn
;
1106 /* Format btree record and pass to our callback. */
1108 xfs_rmap_query_range_helper(
1109 struct xfs_btree_cur
*cur
,
1110 union xfs_btree_rec
*rec
,
1113 struct xfs_rmap_query_range_info
*query
= priv
;
1114 struct xfs_rmap_irec irec
;
1117 error
= xfs_rmap_btrec_to_irec(rec
, &irec
);
1120 return query
->fn(cur
, &irec
, query
->priv
);
1123 /* Find all rmaps between two keys. */
1125 xfs_rmap_query_range(
1126 struct xfs_btree_cur
*cur
,
1127 struct xfs_rmap_irec
*low_rec
,
1128 struct xfs_rmap_irec
*high_rec
,
1129 xfs_rmap_query_range_fn fn
,
1132 union xfs_btree_irec low_brec
;
1133 union xfs_btree_irec high_brec
;
1134 struct xfs_rmap_query_range_info query
;
1136 low_brec
.r
= *low_rec
;
1137 high_brec
.r
= *high_rec
;
1140 return xfs_btree_query_range(cur
, &low_brec
, &high_brec
,
1141 xfs_rmap_query_range_helper
, &query
);
1144 /* Clean up after calling xfs_rmap_finish_one. */
1146 xfs_rmap_finish_one_cleanup(
1147 struct xfs_trans
*tp
,
1148 struct xfs_btree_cur
*rcur
,
1151 struct xfs_buf
*agbp
;
1155 agbp
= rcur
->bc_private
.a
.agbp
;
1156 xfs_btree_del_cursor(rcur
, error
? XFS_BTREE_ERROR
: XFS_BTREE_NOERROR
);
1158 xfs_trans_brelse(tp
, agbp
);
1162 * Process one of the deferred rmap operations. We pass back the
1163 * btree cursor to maintain our lock on the rmapbt between calls.
1164 * This saves time and eliminates a buffer deadlock between the
1165 * superblock and the AGF because we'll always grab them in the same
1169 xfs_rmap_finish_one(
1170 struct xfs_trans
*tp
,
1171 enum xfs_rmap_intent_type type
,
1174 xfs_fileoff_t startoff
,
1175 xfs_fsblock_t startblock
,
1176 xfs_filblks_t blockcount
,
1178 struct xfs_btree_cur
**pcur
)
1180 struct xfs_mount
*mp
= tp
->t_mountp
;
1181 struct xfs_btree_cur
*rcur
;
1182 struct xfs_buf
*agbp
= NULL
;
1184 xfs_agnumber_t agno
;
1185 struct xfs_owner_info oinfo
;
1189 agno
= XFS_FSB_TO_AGNO(mp
, startblock
);
1190 ASSERT(agno
!= NULLAGNUMBER
);
1191 bno
= XFS_FSB_TO_AGBNO(mp
, startblock
);
1193 trace_xfs_rmap_deferred(mp
, agno
, type
, bno
, owner
, whichfork
,
1194 startoff
, blockcount
, state
);
1196 if (XFS_TEST_ERROR(false, mp
,
1197 XFS_ERRTAG_RMAP_FINISH_ONE
,
1198 XFS_RANDOM_RMAP_FINISH_ONE
))
1202 * If we haven't gotten a cursor or the cursor AG doesn't match
1203 * the startblock, get one now.
1206 if (rcur
!= NULL
&& rcur
->bc_private
.a
.agno
!= agno
) {
1207 xfs_rmap_finish_one_cleanup(tp
, rcur
, 0);
1213 * Refresh the freelist before we start changing the
1214 * rmapbt, because a shape change could cause us to
1217 error
= xfs_free_extent_fix_freelist(tp
, agno
, &agbp
);
1221 return -EFSCORRUPTED
;
1223 rcur
= xfs_rmapbt_init_cursor(mp
, tp
, agbp
, agno
);
1231 xfs_rmap_ino_owner(&oinfo
, owner
, whichfork
, startoff
);
1232 unwritten
= state
== XFS_EXT_UNWRITTEN
;
1233 bno
= XFS_FSB_TO_AGBNO(rcur
->bc_mp
, startblock
);
1236 case XFS_RMAP_ALLOC
:
1238 error
= xfs_rmap_map(rcur
, bno
, blockcount
, unwritten
, &oinfo
);
1241 case XFS_RMAP_UNMAP
:
1242 error
= xfs_rmap_unmap(rcur
, bno
, blockcount
, unwritten
,
1245 case XFS_RMAP_CONVERT
:
1246 error
= xfs_rmap_convert(rcur
, bno
, blockcount
, !unwritten
,
1251 error
= -EFSCORRUPTED
;
1256 xfs_trans_brelse(tp
, agbp
);
1262 * Don't defer an rmap if we aren't an rmap filesystem.
1265 xfs_rmap_update_is_needed(
1266 struct xfs_mount
*mp
)
1268 return xfs_sb_version_hasrmapbt(&mp
->m_sb
);
1272 * Record a rmap intent; the list is kept sorted first by AG and then by
1277 struct xfs_mount
*mp
,
1278 struct xfs_defer_ops
*dfops
,
1279 enum xfs_rmap_intent_type type
,
1282 struct xfs_bmbt_irec
*bmap
)
1284 struct xfs_rmap_intent
*ri
;
1286 trace_xfs_rmap_defer(mp
, XFS_FSB_TO_AGNO(mp
, bmap
->br_startblock
),
1288 XFS_FSB_TO_AGBNO(mp
, bmap
->br_startblock
),
1291 bmap
->br_blockcount
,
1294 ri
= kmem_alloc(sizeof(struct xfs_rmap_intent
), KM_SLEEP
| KM_NOFS
);
1295 INIT_LIST_HEAD(&ri
->ri_list
);
1297 ri
->ri_owner
= owner
;
1298 ri
->ri_whichfork
= whichfork
;
1299 ri
->ri_bmap
= *bmap
;
1301 xfs_defer_add(dfops
, XFS_DEFER_OPS_TYPE_RMAP
, &ri
->ri_list
);
1305 /* Map an extent into a file. */
1307 xfs_rmap_map_extent(
1308 struct xfs_mount
*mp
,
1309 struct xfs_defer_ops
*dfops
,
1310 struct xfs_inode
*ip
,
1312 struct xfs_bmbt_irec
*PREV
)
1314 if (!xfs_rmap_update_is_needed(mp
))
1317 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_MAP
, ip
->i_ino
,
1321 /* Unmap an extent out of a file. */
1323 xfs_rmap_unmap_extent(
1324 struct xfs_mount
*mp
,
1325 struct xfs_defer_ops
*dfops
,
1326 struct xfs_inode
*ip
,
1328 struct xfs_bmbt_irec
*PREV
)
1330 if (!xfs_rmap_update_is_needed(mp
))
1333 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_UNMAP
, ip
->i_ino
,
1337 /* Convert a data fork extent from unwritten to real or vice versa. */
1339 xfs_rmap_convert_extent(
1340 struct xfs_mount
*mp
,
1341 struct xfs_defer_ops
*dfops
,
1342 struct xfs_inode
*ip
,
1344 struct xfs_bmbt_irec
*PREV
)
1346 if (!xfs_rmap_update_is_needed(mp
))
1349 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_CONVERT
, ip
->i_ino
,
1353 /* Schedule the creation of an rmap for non-file data. */
1355 xfs_rmap_alloc_extent(
1356 struct xfs_mount
*mp
,
1357 struct xfs_defer_ops
*dfops
,
1358 xfs_agnumber_t agno
,
1363 struct xfs_bmbt_irec bmap
;
1365 if (!xfs_rmap_update_is_needed(mp
))
1368 bmap
.br_startblock
= XFS_AGB_TO_FSB(mp
, agno
, bno
);
1369 bmap
.br_blockcount
= len
;
1370 bmap
.br_startoff
= 0;
1371 bmap
.br_state
= XFS_EXT_NORM
;
1373 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_ALLOC
, owner
,
1374 XFS_DATA_FORK
, &bmap
);
1377 /* Schedule the deletion of an rmap for non-file data. */
1379 xfs_rmap_free_extent(
1380 struct xfs_mount
*mp
,
1381 struct xfs_defer_ops
*dfops
,
1382 xfs_agnumber_t agno
,
1387 struct xfs_bmbt_irec bmap
;
1389 if (!xfs_rmap_update_is_needed(mp
))
1392 bmap
.br_startblock
= XFS_AGB_TO_FSB(mp
, agno
, bno
);
1393 bmap
.br_blockcount
= len
;
1394 bmap
.br_startoff
= 0;
1395 bmap
.br_state
= XFS_EXT_NORM
;
1397 return __xfs_rmap_add(mp
, dfops
, XFS_RMAP_FREE
, owner
,
1398 XFS_DATA_FORK
, &bmap
);