a9ddc191aa2d083c0279bd6b0626efef6087a5b9
[cascardo/linux.git] / fs / xfs / libxfs / xfs_rmap_btree.c
1 /*
2  * Copyright (c) 2014 Red Hat, Inc.
3  * All Rights Reserved.
4  *
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.
8  *
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.
13  *
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
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_shared.h"
21 #include "xfs_format.h"
22 #include "xfs_log_format.h"
23 #include "xfs_trans_resv.h"
24 #include "xfs_bit.h"
25 #include "xfs_sb.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"
37
38 static struct xfs_btree_cur *
39 xfs_rmapbt_dup_cursor(
40         struct xfs_btree_cur    *cur)
41 {
42         return xfs_rmapbt_init_cursor(cur->bc_mp, cur->bc_tp,
43                         cur->bc_private.a.agbp, cur->bc_private.a.agno);
44 }
45
46 static bool
47 xfs_rmapbt_verify(
48         struct xfs_buf          *bp)
49 {
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;
53         unsigned int            level;
54
55         /*
56          * magic number and level verification
57          *
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.
61          *
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
65          * in this case.
66          */
67         if (block->bb_magic != cpu_to_be32(XFS_RMAP_CRC_MAGIC))
68                 return false;
69
70         if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
71                 return false;
72         if (!xfs_btree_sblock_v5hdr_verify(bp))
73                 return false;
74
75         level = be16_to_cpu(block->bb_level);
76         if (pag && pag->pagf_init) {
77                 if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi])
78                         return false;
79         } else if (level >= mp->m_rmap_maxlevels)
80                 return false;
81
82         return xfs_btree_sblock_verify(bp, mp->m_rmap_mxr[level != 0]);
83 }
84
85 static void
86 xfs_rmapbt_read_verify(
87         struct xfs_buf  *bp)
88 {
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);
93
94         if (bp->b_error) {
95                 trace_xfs_btree_corrupt(bp, _RET_IP_);
96                 xfs_verifier_error(bp);
97         }
98 }
99
100 static void
101 xfs_rmapbt_write_verify(
102         struct xfs_buf  *bp)
103 {
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);
108                 return;
109         }
110         xfs_btree_sblock_calc_crc(bp);
111
112 }
113
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,
118 };
119
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),
123
124         .dup_cursor             = xfs_rmapbt_dup_cursor,
125         .buf_ops                = &xfs_rmapbt_buf_ops,
126
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,
130 };
131
132 /*
133  * Allocate a new allocation btree cursor.
134  */
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,
140         xfs_agnumber_t          agno)
141 {
142         struct xfs_agf          *agf = XFS_BUF_TO_AGF(agbp);
143         struct xfs_btree_cur    *cur;
144
145         cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS);
146         cur->bc_tp = tp;
147         cur->bc_mp = mp;
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]);
153
154         cur->bc_private.a.agbp = agbp;
155         cur->bc_private.a.agno = agno;
156
157         return cur;
158 }
159
160 /*
161  * Calculate number of records in an rmap btree block.
162  */
163 int
164 xfs_rmapbt_maxrecs(
165         struct xfs_mount        *mp,
166         int                     blocklen,
167         int                     leaf)
168 {
169         blocklen -= XFS_RMAP_BLOCK_LEN;
170
171         if (leaf)
172                 return blocklen / sizeof(struct xfs_rmap_rec);
173         return blocklen /
174                 (sizeof(struct xfs_rmap_key) + sizeof(xfs_rmap_ptr_t));
175 }
176
177 /* Compute the maximum height of an rmap btree. */
178 void
179 xfs_rmapbt_compute_maxlevels(
180         struct xfs_mount                *mp)
181 {
182         mp->m_rmap_maxlevels = xfs_btree_compute_maxlevels(mp,
183                         mp->m_rmap_mnr, mp->m_sb.sb_agblocks);
184 }