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_inode.h"
29 #include "xfs_trans.h"
30 #include "xfs_alloc.h"
31 #include "xfs_btree.h"
32 #include "xfs_rmap_btree.h"
33 #include "xfs_trace.h"
34 #include "xfs_cksum.h"
35 #include "xfs_error.h"
36 #include "xfs_extent_busy.h"
38 static struct xfs_btree_cur *
39 xfs_rmapbt_dup_cursor(
40 struct xfs_btree_cur *cur)
42 return xfs_rmapbt_init_cursor(cur->bc_mp, cur->bc_tp,
43 cur->bc_private.a.agbp, cur->bc_private.a.agno);
50 struct xfs_mount *mp = bp->b_target->bt_mount;
51 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
52 struct xfs_perag *pag = bp->b_pag;
56 * magic number and level verification
58 * During growfs operations, we can't verify the exact level or owner as
59 * the perag is not fully initialised and hence not attached to the
60 * buffer. In this case, check against the maximum tree depth.
62 * Similarly, during log recovery we will have a perag structure
63 * attached, but the agf information will not yet have been initialised
64 * from the on disk AGF. Again, we can only check against maximum limits
67 if (block->bb_magic != cpu_to_be32(XFS_RMAP_CRC_MAGIC))
70 if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
72 if (!xfs_btree_sblock_v5hdr_verify(bp))
75 level = be16_to_cpu(block->bb_level);
76 if (pag && pag->pagf_init) {
77 if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi])
79 } else if (level >= mp->m_rmap_maxlevels)
82 return xfs_btree_sblock_verify(bp, mp->m_rmap_mxr[level != 0]);
86 xfs_rmapbt_read_verify(
89 if (!xfs_btree_sblock_verify_crc(bp))
90 xfs_buf_ioerror(bp, -EFSBADCRC);
91 else if (!xfs_rmapbt_verify(bp))
92 xfs_buf_ioerror(bp, -EFSCORRUPTED);
95 trace_xfs_btree_corrupt(bp, _RET_IP_);
96 xfs_verifier_error(bp);
101 xfs_rmapbt_write_verify(
104 if (!xfs_rmapbt_verify(bp)) {
105 trace_xfs_btree_corrupt(bp, _RET_IP_);
106 xfs_buf_ioerror(bp, -EFSCORRUPTED);
107 xfs_verifier_error(bp);
110 xfs_btree_sblock_calc_crc(bp);
114 const struct xfs_buf_ops xfs_rmapbt_buf_ops = {
115 .name = "xfs_rmapbt",
116 .verify_read = xfs_rmapbt_read_verify,
117 .verify_write = xfs_rmapbt_write_verify,
120 static const struct xfs_btree_ops xfs_rmapbt_ops = {
121 .rec_len = sizeof(struct xfs_rmap_rec),
122 .key_len = 2 * sizeof(struct xfs_rmap_key),
124 .dup_cursor = xfs_rmapbt_dup_cursor,
125 .buf_ops = &xfs_rmapbt_buf_ops,
127 .get_leaf_keys = xfs_btree_get_leaf_keys_overlapped,
128 .get_node_keys = xfs_btree_get_node_keys_overlapped,
129 .update_keys = xfs_btree_update_keys_overlapped,
133 * Allocate a new allocation btree cursor.
135 struct xfs_btree_cur *
136 xfs_rmapbt_init_cursor(
137 struct xfs_mount *mp,
138 struct xfs_trans *tp,
139 struct xfs_buf *agbp,
142 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
143 struct xfs_btree_cur *cur;
145 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS);
148 cur->bc_btnum = XFS_BTNUM_RMAP;
149 cur->bc_flags = XFS_BTREE_CRC_BLOCKS;
150 cur->bc_blocklog = mp->m_sb.sb_blocklog;
151 cur->bc_ops = &xfs_rmapbt_ops;
152 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
154 cur->bc_private.a.agbp = agbp;
155 cur->bc_private.a.agno = agno;
161 * Calculate number of records in an rmap btree block.
165 struct xfs_mount *mp,
169 blocklen -= XFS_RMAP_BLOCK_LEN;
172 return blocklen / sizeof(struct xfs_rmap_rec);
174 (sizeof(struct xfs_rmap_key) + sizeof(xfs_rmap_ptr_t));
177 /* Compute the maximum height of an rmap btree. */
179 xfs_rmapbt_compute_maxlevels(
180 struct xfs_mount *mp)
182 mp->m_rmap_maxlevels = xfs_btree_compute_maxlevels(mp,
183 mp->m_rmap_mnr, mp->m_sb.sb_agblocks);