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);