Commit 687b890a184fef263ebb773926e1f4aa69240d01

Authored by Christoph Hellwig
Committed by Lachlan McIlroy
1 parent 9eaead51be

[XFS] implement generic xfs_btree_lshift

Make the btree left shift code generic. Based on a patch from David
Chinner with lots of changes to follow the original btree implementations
more closely. While this loses some of the generic helper routines for
inserting/moving/removing records it also solves some of the one off bugs
in the original code and makes it easier to verify.

SGI-PV: 985583

SGI-Modid: xfs-linux-melb:xfs-kern:32197a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Bill O'Donnell <billodo@sgi.com>
Signed-off-by: David Chinner <david@fromorbit.com>

Showing 5 changed files with 192 additions and 425 deletions Inline Diff

fs/xfs/xfs_alloc_btree.c
1 /* 1 /*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_inum.h" 23 #include "xfs_inum.h"
24 #include "xfs_trans.h" 24 #include "xfs_trans.h"
25 #include "xfs_sb.h" 25 #include "xfs_sb.h"
26 #include "xfs_ag.h" 26 #include "xfs_ag.h"
27 #include "xfs_dir2.h" 27 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h" 28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h" 29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h" 31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h" 32 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h" 33 #include "xfs_dir2_sf.h"
34 #include "xfs_attr_sf.h" 34 #include "xfs_attr_sf.h"
35 #include "xfs_dinode.h" 35 #include "xfs_dinode.h"
36 #include "xfs_inode.h" 36 #include "xfs_inode.h"
37 #include "xfs_btree.h" 37 #include "xfs_btree.h"
38 #include "xfs_ialloc.h" 38 #include "xfs_ialloc.h"
39 #include "xfs_alloc.h" 39 #include "xfs_alloc.h"
40 #include "xfs_error.h" 40 #include "xfs_error.h"
41 41
42 /* 42 /*
43 * Prototypes for internal functions. 43 * Prototypes for internal functions.
44 */ 44 */
45 45
46 STATIC void xfs_alloc_log_block(xfs_trans_t *, xfs_buf_t *, int); 46 STATIC void xfs_alloc_log_block(xfs_trans_t *, xfs_buf_t *, int);
47 STATIC void xfs_alloc_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); 47 STATIC void xfs_alloc_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
48 STATIC void xfs_alloc_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); 48 STATIC void xfs_alloc_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
49 STATIC void xfs_alloc_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int); 49 STATIC void xfs_alloc_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
50 STATIC int xfs_alloc_lshift(xfs_btree_cur_t *, int, int *);
51 STATIC int xfs_alloc_newroot(xfs_btree_cur_t *, int *); 50 STATIC int xfs_alloc_newroot(xfs_btree_cur_t *, int *);
52 STATIC int xfs_alloc_split(xfs_btree_cur_t *, int, xfs_agblock_t *, 51 STATIC int xfs_alloc_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
53 xfs_alloc_key_t *, xfs_btree_cur_t **, int *); 52 xfs_alloc_key_t *, xfs_btree_cur_t **, int *);
54 53
55 /* 54 /*
56 * Internal functions. 55 * Internal functions.
57 */ 56 */
58 57
59 /* 58 /*
60 * Single level of the xfs_alloc_delete record deletion routine. 59 * Single level of the xfs_alloc_delete record deletion routine.
61 * Delete record pointed to by cur/level. 60 * Delete record pointed to by cur/level.
62 * Remove the record from its block then rebalance the tree. 61 * Remove the record from its block then rebalance the tree.
63 * Return 0 for error, 1 for done, 2 to go on to the next level. 62 * Return 0 for error, 1 for done, 2 to go on to the next level.
64 */ 63 */
65 STATIC int /* error */ 64 STATIC int /* error */
66 xfs_alloc_delrec( 65 xfs_alloc_delrec(
67 xfs_btree_cur_t *cur, /* btree cursor */ 66 xfs_btree_cur_t *cur, /* btree cursor */
68 int level, /* level removing record from */ 67 int level, /* level removing record from */
69 int *stat) /* fail/done/go-on */ 68 int *stat) /* fail/done/go-on */
70 { 69 {
71 xfs_agf_t *agf; /* allocation group freelist header */ 70 xfs_agf_t *agf; /* allocation group freelist header */
72 xfs_alloc_block_t *block; /* btree block record/key lives in */ 71 xfs_alloc_block_t *block; /* btree block record/key lives in */
73 xfs_agblock_t bno; /* btree block number */ 72 xfs_agblock_t bno; /* btree block number */
74 xfs_buf_t *bp; /* buffer for block */ 73 xfs_buf_t *bp; /* buffer for block */
75 int error; /* error return value */ 74 int error; /* error return value */
76 int i; /* loop index */ 75 int i; /* loop index */
77 xfs_alloc_key_t key; /* kp points here if block is level 0 */ 76 xfs_alloc_key_t key; /* kp points here if block is level 0 */
78 xfs_agblock_t lbno; /* left block's block number */ 77 xfs_agblock_t lbno; /* left block's block number */
79 xfs_buf_t *lbp; /* left block's buffer pointer */ 78 xfs_buf_t *lbp; /* left block's buffer pointer */
80 xfs_alloc_block_t *left; /* left btree block */ 79 xfs_alloc_block_t *left; /* left btree block */
81 xfs_alloc_key_t *lkp=NULL; /* left block key pointer */ 80 xfs_alloc_key_t *lkp=NULL; /* left block key pointer */
82 xfs_alloc_ptr_t *lpp=NULL; /* left block address pointer */ 81 xfs_alloc_ptr_t *lpp=NULL; /* left block address pointer */
83 int lrecs=0; /* number of records in left block */ 82 int lrecs=0; /* number of records in left block */
84 xfs_alloc_rec_t *lrp; /* left block record pointer */ 83 xfs_alloc_rec_t *lrp; /* left block record pointer */
85 xfs_mount_t *mp; /* mount structure */ 84 xfs_mount_t *mp; /* mount structure */
86 int ptr; /* index in btree block for this rec */ 85 int ptr; /* index in btree block for this rec */
87 xfs_agblock_t rbno; /* right block's block number */ 86 xfs_agblock_t rbno; /* right block's block number */
88 xfs_buf_t *rbp; /* right block's buffer pointer */ 87 xfs_buf_t *rbp; /* right block's buffer pointer */
89 xfs_alloc_block_t *right; /* right btree block */ 88 xfs_alloc_block_t *right; /* right btree block */
90 xfs_alloc_key_t *rkp; /* right block key pointer */ 89 xfs_alloc_key_t *rkp; /* right block key pointer */
91 xfs_alloc_ptr_t *rpp; /* right block address pointer */ 90 xfs_alloc_ptr_t *rpp; /* right block address pointer */
92 int rrecs=0; /* number of records in right block */ 91 int rrecs=0; /* number of records in right block */
93 int numrecs; 92 int numrecs;
94 xfs_alloc_rec_t *rrp; /* right block record pointer */ 93 xfs_alloc_rec_t *rrp; /* right block record pointer */
95 xfs_btree_cur_t *tcur; /* temporary btree cursor */ 94 xfs_btree_cur_t *tcur; /* temporary btree cursor */
96 95
97 /* 96 /*
98 * Get the index of the entry being deleted, check for nothing there. 97 * Get the index of the entry being deleted, check for nothing there.
99 */ 98 */
100 ptr = cur->bc_ptrs[level]; 99 ptr = cur->bc_ptrs[level];
101 if (ptr == 0) { 100 if (ptr == 0) {
102 *stat = 0; 101 *stat = 0;
103 return 0; 102 return 0;
104 } 103 }
105 /* 104 /*
106 * Get the buffer & block containing the record or key/ptr. 105 * Get the buffer & block containing the record or key/ptr.
107 */ 106 */
108 bp = cur->bc_bufs[level]; 107 bp = cur->bc_bufs[level];
109 block = XFS_BUF_TO_ALLOC_BLOCK(bp); 108 block = XFS_BUF_TO_ALLOC_BLOCK(bp);
110 #ifdef DEBUG 109 #ifdef DEBUG
111 if ((error = xfs_btree_check_sblock(cur, block, level, bp))) 110 if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
112 return error; 111 return error;
113 #endif 112 #endif
114 /* 113 /*
115 * Fail if we're off the end of the block. 114 * Fail if we're off the end of the block.
116 */ 115 */
117 numrecs = be16_to_cpu(block->bb_numrecs); 116 numrecs = be16_to_cpu(block->bb_numrecs);
118 if (ptr > numrecs) { 117 if (ptr > numrecs) {
119 *stat = 0; 118 *stat = 0;
120 return 0; 119 return 0;
121 } 120 }
122 XFS_STATS_INC(xs_abt_delrec); 121 XFS_STATS_INC(xs_abt_delrec);
123 /* 122 /*
124 * It's a nonleaf. Excise the key and ptr being deleted, by 123 * It's a nonleaf. Excise the key and ptr being deleted, by
125 * sliding the entries past them down one. 124 * sliding the entries past them down one.
126 * Log the changed areas of the block. 125 * Log the changed areas of the block.
127 */ 126 */
128 if (level > 0) { 127 if (level > 0) {
129 lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur); 128 lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
130 lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur); 129 lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
131 #ifdef DEBUG 130 #ifdef DEBUG
132 for (i = ptr; i < numrecs; i++) { 131 for (i = ptr; i < numrecs; i++) {
133 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level))) 132 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
134 return error; 133 return error;
135 } 134 }
136 #endif 135 #endif
137 if (ptr < numrecs) { 136 if (ptr < numrecs) {
138 memmove(&lkp[ptr - 1], &lkp[ptr], 137 memmove(&lkp[ptr - 1], &lkp[ptr],
139 (numrecs - ptr) * sizeof(*lkp)); 138 (numrecs - ptr) * sizeof(*lkp));
140 memmove(&lpp[ptr - 1], &lpp[ptr], 139 memmove(&lpp[ptr - 1], &lpp[ptr],
141 (numrecs - ptr) * sizeof(*lpp)); 140 (numrecs - ptr) * sizeof(*lpp));
142 xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1); 141 xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1);
143 xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1); 142 xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1);
144 } 143 }
145 } 144 }
146 /* 145 /*
147 * It's a leaf. Excise the record being deleted, by sliding the 146 * It's a leaf. Excise the record being deleted, by sliding the
148 * entries past it down one. Log the changed areas of the block. 147 * entries past it down one. Log the changed areas of the block.
149 */ 148 */
150 else { 149 else {
151 lrp = XFS_ALLOC_REC_ADDR(block, 1, cur); 150 lrp = XFS_ALLOC_REC_ADDR(block, 1, cur);
152 if (ptr < numrecs) { 151 if (ptr < numrecs) {
153 memmove(&lrp[ptr - 1], &lrp[ptr], 152 memmove(&lrp[ptr - 1], &lrp[ptr],
154 (numrecs - ptr) * sizeof(*lrp)); 153 (numrecs - ptr) * sizeof(*lrp));
155 xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1); 154 xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1);
156 } 155 }
157 /* 156 /*
158 * If it's the first record in the block, we'll need a key 157 * If it's the first record in the block, we'll need a key
159 * structure to pass up to the next level (updkey). 158 * structure to pass up to the next level (updkey).
160 */ 159 */
161 if (ptr == 1) { 160 if (ptr == 1) {
162 key.ar_startblock = lrp->ar_startblock; 161 key.ar_startblock = lrp->ar_startblock;
163 key.ar_blockcount = lrp->ar_blockcount; 162 key.ar_blockcount = lrp->ar_blockcount;
164 lkp = &key; 163 lkp = &key;
165 } 164 }
166 } 165 }
167 /* 166 /*
168 * Decrement and log the number of entries in the block. 167 * Decrement and log the number of entries in the block.
169 */ 168 */
170 numrecs--; 169 numrecs--;
171 block->bb_numrecs = cpu_to_be16(numrecs); 170 block->bb_numrecs = cpu_to_be16(numrecs);
172 xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); 171 xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
173 /* 172 /*
174 * See if the longest free extent in the allocation group was 173 * See if the longest free extent in the allocation group was
175 * changed by this operation. True if it's the by-size btree, and 174 * changed by this operation. True if it's the by-size btree, and
176 * this is the leaf level, and there is no right sibling block, 175 * this is the leaf level, and there is no right sibling block,
177 * and this was the last record. 176 * and this was the last record.
178 */ 177 */
179 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 178 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
180 mp = cur->bc_mp; 179 mp = cur->bc_mp;
181 180
182 if (level == 0 && 181 if (level == 0 &&
183 cur->bc_btnum == XFS_BTNUM_CNT && 182 cur->bc_btnum == XFS_BTNUM_CNT &&
184 be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK && 183 be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
185 ptr > numrecs) { 184 ptr > numrecs) {
186 ASSERT(ptr == numrecs + 1); 185 ASSERT(ptr == numrecs + 1);
187 /* 186 /*
188 * There are still records in the block. Grab the size 187 * There are still records in the block. Grab the size
189 * from the last one. 188 * from the last one.
190 */ 189 */
191 if (numrecs) { 190 if (numrecs) {
192 rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur); 191 rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur);
193 agf->agf_longest = rrp->ar_blockcount; 192 agf->agf_longest = rrp->ar_blockcount;
194 } 193 }
195 /* 194 /*
196 * No free extents left. 195 * No free extents left.
197 */ 196 */
198 else 197 else
199 agf->agf_longest = 0; 198 agf->agf_longest = 0;
200 mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest = 199 mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest =
201 be32_to_cpu(agf->agf_longest); 200 be32_to_cpu(agf->agf_longest);
202 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, 201 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
203 XFS_AGF_LONGEST); 202 XFS_AGF_LONGEST);
204 } 203 }
205 /* 204 /*
206 * Is this the root level? If so, we're almost done. 205 * Is this the root level? If so, we're almost done.
207 */ 206 */
208 if (level == cur->bc_nlevels - 1) { 207 if (level == cur->bc_nlevels - 1) {
209 /* 208 /*
210 * If this is the root level, 209 * If this is the root level,
211 * and there's only one entry left, 210 * and there's only one entry left,
212 * and it's NOT the leaf level, 211 * and it's NOT the leaf level,
213 * then we can get rid of this level. 212 * then we can get rid of this level.
214 */ 213 */
215 if (numrecs == 1 && level > 0) { 214 if (numrecs == 1 && level > 0) {
216 /* 215 /*
217 * lpp is still set to the first pointer in the block. 216 * lpp is still set to the first pointer in the block.
218 * Make it the new root of the btree. 217 * Make it the new root of the btree.
219 */ 218 */
220 bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]); 219 bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
221 agf->agf_roots[cur->bc_btnum] = *lpp; 220 agf->agf_roots[cur->bc_btnum] = *lpp;
222 be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1); 221 be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1);
223 mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--; 222 mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--;
224 /* 223 /*
225 * Put this buffer/block on the ag's freelist. 224 * Put this buffer/block on the ag's freelist.
226 */ 225 */
227 error = xfs_alloc_put_freelist(cur->bc_tp, 226 error = xfs_alloc_put_freelist(cur->bc_tp,
228 cur->bc_private.a.agbp, NULL, bno, 1); 227 cur->bc_private.a.agbp, NULL, bno, 1);
229 if (error) 228 if (error)
230 return error; 229 return error;
231 /* 230 /*
232 * Since blocks move to the free list without the 231 * Since blocks move to the free list without the
233 * coordination used in xfs_bmap_finish, we can't allow 232 * coordination used in xfs_bmap_finish, we can't allow
234 * block to be available for reallocation and 233 * block to be available for reallocation and
235 * non-transaction writing (user data) until we know 234 * non-transaction writing (user data) until we know
236 * that the transaction that moved it to the free list 235 * that the transaction that moved it to the free list
237 * is permanently on disk. We track the blocks by 236 * is permanently on disk. We track the blocks by
238 * declaring these blocks as "busy"; the busy list is 237 * declaring these blocks as "busy"; the busy list is
239 * maintained on a per-ag basis and each transaction 238 * maintained on a per-ag basis and each transaction
240 * records which entries should be removed when the 239 * records which entries should be removed when the
241 * iclog commits to disk. If a busy block is 240 * iclog commits to disk. If a busy block is
242 * allocated, the iclog is pushed up to the LSN 241 * allocated, the iclog is pushed up to the LSN
243 * that freed the block. 242 * that freed the block.
244 */ 243 */
245 xfs_alloc_mark_busy(cur->bc_tp, 244 xfs_alloc_mark_busy(cur->bc_tp,
246 be32_to_cpu(agf->agf_seqno), bno, 1); 245 be32_to_cpu(agf->agf_seqno), bno, 1);
247 246
248 xfs_trans_agbtree_delta(cur->bc_tp, -1); 247 xfs_trans_agbtree_delta(cur->bc_tp, -1);
249 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, 248 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
250 XFS_AGF_ROOTS | XFS_AGF_LEVELS); 249 XFS_AGF_ROOTS | XFS_AGF_LEVELS);
251 /* 250 /*
252 * Update the cursor so there's one fewer level. 251 * Update the cursor so there's one fewer level.
253 */ 252 */
254 xfs_btree_setbuf(cur, level, NULL); 253 xfs_btree_setbuf(cur, level, NULL);
255 cur->bc_nlevels--; 254 cur->bc_nlevels--;
256 } else if (level > 0 && 255 } else if (level > 0 &&
257 (error = xfs_btree_decrement(cur, level, &i))) 256 (error = xfs_btree_decrement(cur, level, &i)))
258 return error; 257 return error;
259 *stat = 1; 258 *stat = 1;
260 return 0; 259 return 0;
261 } 260 }
262 /* 261 /*
263 * If we deleted the leftmost entry in the block, update the 262 * If we deleted the leftmost entry in the block, update the
264 * key values above us in the tree. 263 * key values above us in the tree.
265 */ 264 */
266 if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)lkp, level + 1))) 265 if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)lkp, level + 1)))
267 return error; 266 return error;
268 /* 267 /*
269 * If the number of records remaining in the block is at least 268 * If the number of records remaining in the block is at least
270 * the minimum, we're done. 269 * the minimum, we're done.
271 */ 270 */
272 if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { 271 if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
273 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) 272 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
274 return error; 273 return error;
275 *stat = 1; 274 *stat = 1;
276 return 0; 275 return 0;
277 } 276 }
278 /* 277 /*
279 * Otherwise, we have to move some records around to keep the 278 * Otherwise, we have to move some records around to keep the
280 * tree balanced. Look at the left and right sibling blocks to 279 * tree balanced. Look at the left and right sibling blocks to
281 * see if we can re-balance by moving only one record. 280 * see if we can re-balance by moving only one record.
282 */ 281 */
283 rbno = be32_to_cpu(block->bb_rightsib); 282 rbno = be32_to_cpu(block->bb_rightsib);
284 lbno = be32_to_cpu(block->bb_leftsib); 283 lbno = be32_to_cpu(block->bb_leftsib);
285 bno = NULLAGBLOCK; 284 bno = NULLAGBLOCK;
286 ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK); 285 ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
287 /* 286 /*
288 * Duplicate the cursor so our btree manipulations here won't 287 * Duplicate the cursor so our btree manipulations here won't
289 * disrupt the next level up. 288 * disrupt the next level up.
290 */ 289 */
291 if ((error = xfs_btree_dup_cursor(cur, &tcur))) 290 if ((error = xfs_btree_dup_cursor(cur, &tcur)))
292 return error; 291 return error;
293 /* 292 /*
294 * If there's a right sibling, see if it's ok to shift an entry 293 * If there's a right sibling, see if it's ok to shift an entry
295 * out of it. 294 * out of it.
296 */ 295 */
297 if (rbno != NULLAGBLOCK) { 296 if (rbno != NULLAGBLOCK) {
298 /* 297 /*
299 * Move the temp cursor to the last entry in the next block. 298 * Move the temp cursor to the last entry in the next block.
300 * Actually any entry but the first would suffice. 299 * Actually any entry but the first would suffice.
301 */ 300 */
302 i = xfs_btree_lastrec(tcur, level); 301 i = xfs_btree_lastrec(tcur, level);
303 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 302 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
304 if ((error = xfs_btree_increment(tcur, level, &i))) 303 if ((error = xfs_btree_increment(tcur, level, &i)))
305 goto error0; 304 goto error0;
306 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 305 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
307 i = xfs_btree_lastrec(tcur, level); 306 i = xfs_btree_lastrec(tcur, level);
308 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 307 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
309 /* 308 /*
310 * Grab a pointer to the block. 309 * Grab a pointer to the block.
311 */ 310 */
312 rbp = tcur->bc_bufs[level]; 311 rbp = tcur->bc_bufs[level];
313 right = XFS_BUF_TO_ALLOC_BLOCK(rbp); 312 right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
314 #ifdef DEBUG 313 #ifdef DEBUG
315 if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) 314 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
316 goto error0; 315 goto error0;
317 #endif 316 #endif
318 /* 317 /*
319 * Grab the current block number, for future use. 318 * Grab the current block number, for future use.
320 */ 319 */
321 bno = be32_to_cpu(right->bb_leftsib); 320 bno = be32_to_cpu(right->bb_leftsib);
322 /* 321 /*
323 * If right block is full enough so that removing one entry 322 * If right block is full enough so that removing one entry
324 * won't make it too empty, and left-shifting an entry out 323 * won't make it too empty, and left-shifting an entry out
325 * of right to us works, we're done. 324 * of right to us works, we're done.
326 */ 325 */
327 if (be16_to_cpu(right->bb_numrecs) - 1 >= 326 if (be16_to_cpu(right->bb_numrecs) - 1 >=
328 XFS_ALLOC_BLOCK_MINRECS(level, cur)) { 327 XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
329 if ((error = xfs_alloc_lshift(tcur, level, &i))) 328 if ((error = xfs_btree_lshift(tcur, level, &i)))
330 goto error0; 329 goto error0;
331 if (i) { 330 if (i) {
332 ASSERT(be16_to_cpu(block->bb_numrecs) >= 331 ASSERT(be16_to_cpu(block->bb_numrecs) >=
333 XFS_ALLOC_BLOCK_MINRECS(level, cur)); 332 XFS_ALLOC_BLOCK_MINRECS(level, cur));
334 xfs_btree_del_cursor(tcur, 333 xfs_btree_del_cursor(tcur,
335 XFS_BTREE_NOERROR); 334 XFS_BTREE_NOERROR);
336 if (level > 0 && 335 if (level > 0 &&
337 (error = xfs_btree_decrement(cur, level, 336 (error = xfs_btree_decrement(cur, level,
338 &i))) 337 &i)))
339 return error; 338 return error;
340 *stat = 1; 339 *stat = 1;
341 return 0; 340 return 0;
342 } 341 }
343 } 342 }
344 /* 343 /*
345 * Otherwise, grab the number of records in right for 344 * Otherwise, grab the number of records in right for
346 * future reference, and fix up the temp cursor to point 345 * future reference, and fix up the temp cursor to point
347 * to our block again (last record). 346 * to our block again (last record).
348 */ 347 */
349 rrecs = be16_to_cpu(right->bb_numrecs); 348 rrecs = be16_to_cpu(right->bb_numrecs);
350 if (lbno != NULLAGBLOCK) { 349 if (lbno != NULLAGBLOCK) {
351 i = xfs_btree_firstrec(tcur, level); 350 i = xfs_btree_firstrec(tcur, level);
352 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 351 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
353 if ((error = xfs_btree_decrement(tcur, level, &i))) 352 if ((error = xfs_btree_decrement(tcur, level, &i)))
354 goto error0; 353 goto error0;
355 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 354 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
356 } 355 }
357 } 356 }
358 /* 357 /*
359 * If there's a left sibling, see if it's ok to shift an entry 358 * If there's a left sibling, see if it's ok to shift an entry
360 * out of it. 359 * out of it.
361 */ 360 */
362 if (lbno != NULLAGBLOCK) { 361 if (lbno != NULLAGBLOCK) {
363 /* 362 /*
364 * Move the temp cursor to the first entry in the 363 * Move the temp cursor to the first entry in the
365 * previous block. 364 * previous block.
366 */ 365 */
367 i = xfs_btree_firstrec(tcur, level); 366 i = xfs_btree_firstrec(tcur, level);
368 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 367 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
369 if ((error = xfs_btree_decrement(tcur, level, &i))) 368 if ((error = xfs_btree_decrement(tcur, level, &i)))
370 goto error0; 369 goto error0;
371 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 370 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
372 xfs_btree_firstrec(tcur, level); 371 xfs_btree_firstrec(tcur, level);
373 /* 372 /*
374 * Grab a pointer to the block. 373 * Grab a pointer to the block.
375 */ 374 */
376 lbp = tcur->bc_bufs[level]; 375 lbp = tcur->bc_bufs[level];
377 left = XFS_BUF_TO_ALLOC_BLOCK(lbp); 376 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
378 #ifdef DEBUG 377 #ifdef DEBUG
379 if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) 378 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
380 goto error0; 379 goto error0;
381 #endif 380 #endif
382 /* 381 /*
383 * Grab the current block number, for future use. 382 * Grab the current block number, for future use.
384 */ 383 */
385 bno = be32_to_cpu(left->bb_rightsib); 384 bno = be32_to_cpu(left->bb_rightsib);
386 /* 385 /*
387 * If left block is full enough so that removing one entry 386 * If left block is full enough so that removing one entry
388 * won't make it too empty, and right-shifting an entry out 387 * won't make it too empty, and right-shifting an entry out
389 * of left to us works, we're done. 388 * of left to us works, we're done.
390 */ 389 */
391 if (be16_to_cpu(left->bb_numrecs) - 1 >= 390 if (be16_to_cpu(left->bb_numrecs) - 1 >=
392 XFS_ALLOC_BLOCK_MINRECS(level, cur)) { 391 XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
393 if ((error = xfs_btree_rshift(tcur, level, &i))) 392 if ((error = xfs_btree_rshift(tcur, level, &i)))
394 goto error0; 393 goto error0;
395 if (i) { 394 if (i) {
396 ASSERT(be16_to_cpu(block->bb_numrecs) >= 395 ASSERT(be16_to_cpu(block->bb_numrecs) >=
397 XFS_ALLOC_BLOCK_MINRECS(level, cur)); 396 XFS_ALLOC_BLOCK_MINRECS(level, cur));
398 xfs_btree_del_cursor(tcur, 397 xfs_btree_del_cursor(tcur,
399 XFS_BTREE_NOERROR); 398 XFS_BTREE_NOERROR);
400 if (level == 0) 399 if (level == 0)
401 cur->bc_ptrs[0]++; 400 cur->bc_ptrs[0]++;
402 *stat = 1; 401 *stat = 1;
403 return 0; 402 return 0;
404 } 403 }
405 } 404 }
406 /* 405 /*
407 * Otherwise, grab the number of records in right for 406 * Otherwise, grab the number of records in right for
408 * future reference. 407 * future reference.
409 */ 408 */
410 lrecs = be16_to_cpu(left->bb_numrecs); 409 lrecs = be16_to_cpu(left->bb_numrecs);
411 } 410 }
412 /* 411 /*
413 * Delete the temp cursor, we're done with it. 412 * Delete the temp cursor, we're done with it.
414 */ 413 */
415 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); 414 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
416 /* 415 /*
417 * If here, we need to do a join to keep the tree balanced. 416 * If here, we need to do a join to keep the tree balanced.
418 */ 417 */
419 ASSERT(bno != NULLAGBLOCK); 418 ASSERT(bno != NULLAGBLOCK);
420 /* 419 /*
421 * See if we can join with the left neighbor block. 420 * See if we can join with the left neighbor block.
422 */ 421 */
423 if (lbno != NULLAGBLOCK && 422 if (lbno != NULLAGBLOCK &&
424 lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { 423 lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
425 /* 424 /*
426 * Set "right" to be the starting block, 425 * Set "right" to be the starting block,
427 * "left" to be the left neighbor. 426 * "left" to be the left neighbor.
428 */ 427 */
429 rbno = bno; 428 rbno = bno;
430 right = block; 429 right = block;
431 rrecs = be16_to_cpu(right->bb_numrecs); 430 rrecs = be16_to_cpu(right->bb_numrecs);
432 rbp = bp; 431 rbp = bp;
433 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 432 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
434 cur->bc_private.a.agno, lbno, 0, &lbp, 433 cur->bc_private.a.agno, lbno, 0, &lbp,
435 XFS_ALLOC_BTREE_REF))) 434 XFS_ALLOC_BTREE_REF)))
436 return error; 435 return error;
437 left = XFS_BUF_TO_ALLOC_BLOCK(lbp); 436 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
438 lrecs = be16_to_cpu(left->bb_numrecs); 437 lrecs = be16_to_cpu(left->bb_numrecs);
439 if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) 438 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
440 return error; 439 return error;
441 } 440 }
442 /* 441 /*
443 * If that won't work, see if we can join with the right neighbor block. 442 * If that won't work, see if we can join with the right neighbor block.
444 */ 443 */
445 else if (rbno != NULLAGBLOCK && 444 else if (rbno != NULLAGBLOCK &&
446 rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { 445 rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
447 /* 446 /*
448 * Set "left" to be the starting block, 447 * Set "left" to be the starting block,
449 * "right" to be the right neighbor. 448 * "right" to be the right neighbor.
450 */ 449 */
451 lbno = bno; 450 lbno = bno;
452 left = block; 451 left = block;
453 lrecs = be16_to_cpu(left->bb_numrecs); 452 lrecs = be16_to_cpu(left->bb_numrecs);
454 lbp = bp; 453 lbp = bp;
455 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 454 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
456 cur->bc_private.a.agno, rbno, 0, &rbp, 455 cur->bc_private.a.agno, rbno, 0, &rbp,
457 XFS_ALLOC_BTREE_REF))) 456 XFS_ALLOC_BTREE_REF)))
458 return error; 457 return error;
459 right = XFS_BUF_TO_ALLOC_BLOCK(rbp); 458 right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
460 rrecs = be16_to_cpu(right->bb_numrecs); 459 rrecs = be16_to_cpu(right->bb_numrecs);
461 if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) 460 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
462 return error; 461 return error;
463 } 462 }
464 /* 463 /*
465 * Otherwise, we can't fix the imbalance. 464 * Otherwise, we can't fix the imbalance.
466 * Just return. This is probably a logic error, but it's not fatal. 465 * Just return. This is probably a logic error, but it's not fatal.
467 */ 466 */
468 else { 467 else {
469 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) 468 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
470 return error; 469 return error;
471 *stat = 1; 470 *stat = 1;
472 return 0; 471 return 0;
473 } 472 }
474 /* 473 /*
475 * We're now going to join "left" and "right" by moving all the stuff 474 * We're now going to join "left" and "right" by moving all the stuff
476 * in "right" to "left" and deleting "right". 475 * in "right" to "left" and deleting "right".
477 */ 476 */
478 if (level > 0) { 477 if (level > 0) {
479 /* 478 /*
480 * It's a non-leaf. Move keys and pointers. 479 * It's a non-leaf. Move keys and pointers.
481 */ 480 */
482 lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur); 481 lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur);
483 lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur); 482 lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur);
484 rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur); 483 rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
485 rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur); 484 rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
486 #ifdef DEBUG 485 #ifdef DEBUG
487 for (i = 0; i < rrecs; i++) { 486 for (i = 0; i < rrecs; i++) {
488 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level))) 487 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
489 return error; 488 return error;
490 } 489 }
491 #endif 490 #endif
492 memcpy(lkp, rkp, rrecs * sizeof(*lkp)); 491 memcpy(lkp, rkp, rrecs * sizeof(*lkp));
493 memcpy(lpp, rpp, rrecs * sizeof(*lpp)); 492 memcpy(lpp, rpp, rrecs * sizeof(*lpp));
494 xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs); 493 xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
495 xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs); 494 xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
496 } else { 495 } else {
497 /* 496 /*
498 * It's a leaf. Move records. 497 * It's a leaf. Move records.
499 */ 498 */
500 lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur); 499 lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur);
501 rrp = XFS_ALLOC_REC_ADDR(right, 1, cur); 500 rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
502 memcpy(lrp, rrp, rrecs * sizeof(*lrp)); 501 memcpy(lrp, rrp, rrecs * sizeof(*lrp));
503 xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs); 502 xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
504 } 503 }
505 /* 504 /*
506 * If we joined with the left neighbor, set the buffer in the 505 * If we joined with the left neighbor, set the buffer in the
507 * cursor to the left block, and fix up the index. 506 * cursor to the left block, and fix up the index.
508 */ 507 */
509 if (bp != lbp) { 508 if (bp != lbp) {
510 xfs_btree_setbuf(cur, level, lbp); 509 xfs_btree_setbuf(cur, level, lbp);
511 cur->bc_ptrs[level] += lrecs; 510 cur->bc_ptrs[level] += lrecs;
512 } 511 }
513 /* 512 /*
514 * If we joined with the right neighbor and there's a level above 513 * If we joined with the right neighbor and there's a level above
515 * us, increment the cursor at that level. 514 * us, increment the cursor at that level.
516 */ 515 */
517 else if (level + 1 < cur->bc_nlevels && 516 else if (level + 1 < cur->bc_nlevels &&
518 (error = xfs_btree_increment(cur, level + 1, &i))) 517 (error = xfs_btree_increment(cur, level + 1, &i)))
519 return error; 518 return error;
520 /* 519 /*
521 * Fix up the number of records in the surviving block. 520 * Fix up the number of records in the surviving block.
522 */ 521 */
523 lrecs += rrecs; 522 lrecs += rrecs;
524 left->bb_numrecs = cpu_to_be16(lrecs); 523 left->bb_numrecs = cpu_to_be16(lrecs);
525 /* 524 /*
526 * Fix up the right block pointer in the surviving block, and log it. 525 * Fix up the right block pointer in the surviving block, and log it.
527 */ 526 */
528 left->bb_rightsib = right->bb_rightsib; 527 left->bb_rightsib = right->bb_rightsib;
529 xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); 528 xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
530 /* 529 /*
531 * If there is a right sibling now, make it point to the 530 * If there is a right sibling now, make it point to the
532 * remaining block. 531 * remaining block.
533 */ 532 */
534 if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) { 533 if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
535 xfs_alloc_block_t *rrblock; 534 xfs_alloc_block_t *rrblock;
536 xfs_buf_t *rrbp; 535 xfs_buf_t *rrbp;
537 536
538 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 537 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
539 cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0, 538 cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0,
540 &rrbp, XFS_ALLOC_BTREE_REF))) 539 &rrbp, XFS_ALLOC_BTREE_REF)))
541 return error; 540 return error;
542 rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp); 541 rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp);
543 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp))) 542 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
544 return error; 543 return error;
545 rrblock->bb_leftsib = cpu_to_be32(lbno); 544 rrblock->bb_leftsib = cpu_to_be32(lbno);
546 xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB); 545 xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
547 } 546 }
548 /* 547 /*
549 * Free the deleting block by putting it on the freelist. 548 * Free the deleting block by putting it on the freelist.
550 */ 549 */
551 error = xfs_alloc_put_freelist(cur->bc_tp, 550 error = xfs_alloc_put_freelist(cur->bc_tp,
552 cur->bc_private.a.agbp, NULL, rbno, 1); 551 cur->bc_private.a.agbp, NULL, rbno, 1);
553 if (error) 552 if (error)
554 return error; 553 return error;
555 /* 554 /*
556 * Since blocks move to the free list without the coordination 555 * Since blocks move to the free list without the coordination
557 * used in xfs_bmap_finish, we can't allow block to be available 556 * used in xfs_bmap_finish, we can't allow block to be available
558 * for reallocation and non-transaction writing (user data) 557 * for reallocation and non-transaction writing (user data)
559 * until we know that the transaction that moved it to the free 558 * until we know that the transaction that moved it to the free
560 * list is permanently on disk. We track the blocks by declaring 559 * list is permanently on disk. We track the blocks by declaring
561 * these blocks as "busy"; the busy list is maintained on a 560 * these blocks as "busy"; the busy list is maintained on a
562 * per-ag basis and each transaction records which entries 561 * per-ag basis and each transaction records which entries
563 * should be removed when the iclog commits to disk. If a 562 * should be removed when the iclog commits to disk. If a
564 * busy block is allocated, the iclog is pushed up to the 563 * busy block is allocated, the iclog is pushed up to the
565 * LSN that freed the block. 564 * LSN that freed the block.
566 */ 565 */
567 xfs_alloc_mark_busy(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1); 566 xfs_alloc_mark_busy(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1);
568 xfs_trans_agbtree_delta(cur->bc_tp, -1); 567 xfs_trans_agbtree_delta(cur->bc_tp, -1);
569 568
570 /* 569 /*
571 * Adjust the current level's cursor so that we're left referring 570 * Adjust the current level's cursor so that we're left referring
572 * to the right node, after we're done. 571 * to the right node, after we're done.
573 * If this leaves the ptr value 0 our caller will fix it up. 572 * If this leaves the ptr value 0 our caller will fix it up.
574 */ 573 */
575 if (level > 0) 574 if (level > 0)
576 cur->bc_ptrs[level]--; 575 cur->bc_ptrs[level]--;
577 /* 576 /*
578 * Return value means the next level up has something to do. 577 * Return value means the next level up has something to do.
579 */ 578 */
580 *stat = 2; 579 *stat = 2;
581 return 0; 580 return 0;
582 581
583 error0: 582 error0:
584 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); 583 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
585 return error; 584 return error;
586 } 585 }
587 586
588 /* 587 /*
589 * Insert one record/level. Return information to the caller 588 * Insert one record/level. Return information to the caller
590 * allowing the next level up to proceed if necessary. 589 * allowing the next level up to proceed if necessary.
591 */ 590 */
592 STATIC int /* error */ 591 STATIC int /* error */
593 xfs_alloc_insrec( 592 xfs_alloc_insrec(
594 xfs_btree_cur_t *cur, /* btree cursor */ 593 xfs_btree_cur_t *cur, /* btree cursor */
595 int level, /* level to insert record at */ 594 int level, /* level to insert record at */
596 xfs_agblock_t *bnop, /* i/o: block number inserted */ 595 xfs_agblock_t *bnop, /* i/o: block number inserted */
597 xfs_alloc_rec_t *recp, /* i/o: record data inserted */ 596 xfs_alloc_rec_t *recp, /* i/o: record data inserted */
598 xfs_btree_cur_t **curp, /* output: new cursor replacing cur */ 597 xfs_btree_cur_t **curp, /* output: new cursor replacing cur */
599 int *stat) /* output: success/failure */ 598 int *stat) /* output: success/failure */
600 { 599 {
601 xfs_agf_t *agf; /* allocation group freelist header */ 600 xfs_agf_t *agf; /* allocation group freelist header */
602 xfs_alloc_block_t *block; /* btree block record/key lives in */ 601 xfs_alloc_block_t *block; /* btree block record/key lives in */
603 xfs_buf_t *bp; /* buffer for block */ 602 xfs_buf_t *bp; /* buffer for block */
604 int error; /* error return value */ 603 int error; /* error return value */
605 int i; /* loop index */ 604 int i; /* loop index */
606 xfs_alloc_key_t key; /* key value being inserted */ 605 xfs_alloc_key_t key; /* key value being inserted */
607 xfs_alloc_key_t *kp; /* pointer to btree keys */ 606 xfs_alloc_key_t *kp; /* pointer to btree keys */
608 xfs_agblock_t nbno; /* block number of allocated block */ 607 xfs_agblock_t nbno; /* block number of allocated block */
609 xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */ 608 xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
610 xfs_alloc_key_t nkey; /* new key value, from split */ 609 xfs_alloc_key_t nkey; /* new key value, from split */
611 xfs_alloc_rec_t nrec; /* new record value, for caller */ 610 xfs_alloc_rec_t nrec; /* new record value, for caller */
612 int numrecs; 611 int numrecs;
613 int optr; /* old ptr value */ 612 int optr; /* old ptr value */
614 xfs_alloc_ptr_t *pp; /* pointer to btree addresses */ 613 xfs_alloc_ptr_t *pp; /* pointer to btree addresses */
615 int ptr; /* index in btree block for this rec */ 614 int ptr; /* index in btree block for this rec */
616 xfs_alloc_rec_t *rp; /* pointer to btree records */ 615 xfs_alloc_rec_t *rp; /* pointer to btree records */
617 616
618 ASSERT(be32_to_cpu(recp->ar_blockcount) > 0); 617 ASSERT(be32_to_cpu(recp->ar_blockcount) > 0);
619 618
620 /* 619 /*
621 * GCC doesn't understand the (arguably complex) control flow in 620 * GCC doesn't understand the (arguably complex) control flow in
622 * this function and complains about uninitialized structure fields 621 * this function and complains about uninitialized structure fields
623 * without this. 622 * without this.
624 */ 623 */
625 memset(&nrec, 0, sizeof(nrec)); 624 memset(&nrec, 0, sizeof(nrec));
626 625
627 /* 626 /*
628 * If we made it to the root level, allocate a new root block 627 * If we made it to the root level, allocate a new root block
629 * and we're done. 628 * and we're done.
630 */ 629 */
631 if (level >= cur->bc_nlevels) { 630 if (level >= cur->bc_nlevels) {
632 XFS_STATS_INC(xs_abt_insrec); 631 XFS_STATS_INC(xs_abt_insrec);
633 if ((error = xfs_alloc_newroot(cur, &i))) 632 if ((error = xfs_alloc_newroot(cur, &i)))
634 return error; 633 return error;
635 *bnop = NULLAGBLOCK; 634 *bnop = NULLAGBLOCK;
636 *stat = i; 635 *stat = i;
637 return 0; 636 return 0;
638 } 637 }
639 /* 638 /*
640 * Make a key out of the record data to be inserted, and save it. 639 * Make a key out of the record data to be inserted, and save it.
641 */ 640 */
642 key.ar_startblock = recp->ar_startblock; 641 key.ar_startblock = recp->ar_startblock;
643 key.ar_blockcount = recp->ar_blockcount; 642 key.ar_blockcount = recp->ar_blockcount;
644 optr = ptr = cur->bc_ptrs[level]; 643 optr = ptr = cur->bc_ptrs[level];
645 /* 644 /*
646 * If we're off the left edge, return failure. 645 * If we're off the left edge, return failure.
647 */ 646 */
648 if (ptr == 0) { 647 if (ptr == 0) {
649 *stat = 0; 648 *stat = 0;
650 return 0; 649 return 0;
651 } 650 }
652 XFS_STATS_INC(xs_abt_insrec); 651 XFS_STATS_INC(xs_abt_insrec);
653 /* 652 /*
654 * Get pointers to the btree buffer and block. 653 * Get pointers to the btree buffer and block.
655 */ 654 */
656 bp = cur->bc_bufs[level]; 655 bp = cur->bc_bufs[level];
657 block = XFS_BUF_TO_ALLOC_BLOCK(bp); 656 block = XFS_BUF_TO_ALLOC_BLOCK(bp);
658 numrecs = be16_to_cpu(block->bb_numrecs); 657 numrecs = be16_to_cpu(block->bb_numrecs);
659 #ifdef DEBUG 658 #ifdef DEBUG
660 if ((error = xfs_btree_check_sblock(cur, block, level, bp))) 659 if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
661 return error; 660 return error;
662 /* 661 /*
663 * Check that the new entry is being inserted in the right place. 662 * Check that the new entry is being inserted in the right place.
664 */ 663 */
665 if (ptr <= numrecs) { 664 if (ptr <= numrecs) {
666 if (level == 0) { 665 if (level == 0) {
667 rp = XFS_ALLOC_REC_ADDR(block, ptr, cur); 666 rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
668 xfs_btree_check_rec(cur->bc_btnum, recp, rp); 667 xfs_btree_check_rec(cur->bc_btnum, recp, rp);
669 } else { 668 } else {
670 kp = XFS_ALLOC_KEY_ADDR(block, ptr, cur); 669 kp = XFS_ALLOC_KEY_ADDR(block, ptr, cur);
671 xfs_btree_check_key(cur->bc_btnum, &key, kp); 670 xfs_btree_check_key(cur->bc_btnum, &key, kp);
672 } 671 }
673 } 672 }
674 #endif 673 #endif
675 nbno = NULLAGBLOCK; 674 nbno = NULLAGBLOCK;
676 ncur = NULL; 675 ncur = NULL;
677 /* 676 /*
678 * If the block is full, we can't insert the new entry until we 677 * If the block is full, we can't insert the new entry until we
679 * make the block un-full. 678 * make the block un-full.
680 */ 679 */
681 if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { 680 if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
682 /* 681 /*
683 * First, try shifting an entry to the right neighbor. 682 * First, try shifting an entry to the right neighbor.
684 */ 683 */
685 if ((error = xfs_btree_rshift(cur, level, &i))) 684 if ((error = xfs_btree_rshift(cur, level, &i)))
686 return error; 685 return error;
687 if (i) { 686 if (i) {
688 /* nothing */ 687 /* nothing */
689 } 688 }
690 /* 689 /*
691 * Next, try shifting an entry to the left neighbor. 690 * Next, try shifting an entry to the left neighbor.
692 */ 691 */
693 else { 692 else {
694 if ((error = xfs_alloc_lshift(cur, level, &i))) 693 if ((error = xfs_btree_lshift(cur, level, &i)))
695 return error; 694 return error;
696 if (i) 695 if (i)
697 optr = ptr = cur->bc_ptrs[level]; 696 optr = ptr = cur->bc_ptrs[level];
698 else { 697 else {
699 /* 698 /*
700 * Next, try splitting the current block in 699 * Next, try splitting the current block in
701 * half. If this works we have to re-set our 700 * half. If this works we have to re-set our
702 * variables because we could be in a 701 * variables because we could be in a
703 * different block now. 702 * different block now.
704 */ 703 */
705 if ((error = xfs_alloc_split(cur, level, &nbno, 704 if ((error = xfs_alloc_split(cur, level, &nbno,
706 &nkey, &ncur, &i))) 705 &nkey, &ncur, &i)))
707 return error; 706 return error;
708 if (i) { 707 if (i) {
709 bp = cur->bc_bufs[level]; 708 bp = cur->bc_bufs[level];
710 block = XFS_BUF_TO_ALLOC_BLOCK(bp); 709 block = XFS_BUF_TO_ALLOC_BLOCK(bp);
711 #ifdef DEBUG 710 #ifdef DEBUG
712 if ((error = 711 if ((error =
713 xfs_btree_check_sblock(cur, 712 xfs_btree_check_sblock(cur,
714 block, level, bp))) 713 block, level, bp)))
715 return error; 714 return error;
716 #endif 715 #endif
717 ptr = cur->bc_ptrs[level]; 716 ptr = cur->bc_ptrs[level];
718 nrec.ar_startblock = nkey.ar_startblock; 717 nrec.ar_startblock = nkey.ar_startblock;
719 nrec.ar_blockcount = nkey.ar_blockcount; 718 nrec.ar_blockcount = nkey.ar_blockcount;
720 } 719 }
721 /* 720 /*
722 * Otherwise the insert fails. 721 * Otherwise the insert fails.
723 */ 722 */
724 else { 723 else {
725 *stat = 0; 724 *stat = 0;
726 return 0; 725 return 0;
727 } 726 }
728 } 727 }
729 } 728 }
730 } 729 }
731 /* 730 /*
732 * At this point we know there's room for our new entry in the block 731 * At this point we know there's room for our new entry in the block
733 * we're pointing at. 732 * we're pointing at.
734 */ 733 */
735 numrecs = be16_to_cpu(block->bb_numrecs); 734 numrecs = be16_to_cpu(block->bb_numrecs);
736 if (level > 0) { 735 if (level > 0) {
737 /* 736 /*
738 * It's a non-leaf entry. Make a hole for the new data 737 * It's a non-leaf entry. Make a hole for the new data
739 * in the key and ptr regions of the block. 738 * in the key and ptr regions of the block.
740 */ 739 */
741 kp = XFS_ALLOC_KEY_ADDR(block, 1, cur); 740 kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
742 pp = XFS_ALLOC_PTR_ADDR(block, 1, cur); 741 pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
743 #ifdef DEBUG 742 #ifdef DEBUG
744 for (i = numrecs; i >= ptr; i--) { 743 for (i = numrecs; i >= ptr; i--) {
745 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level))) 744 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
746 return error; 745 return error;
747 } 746 }
748 #endif 747 #endif
749 memmove(&kp[ptr], &kp[ptr - 1], 748 memmove(&kp[ptr], &kp[ptr - 1],
750 (numrecs - ptr + 1) * sizeof(*kp)); 749 (numrecs - ptr + 1) * sizeof(*kp));
751 memmove(&pp[ptr], &pp[ptr - 1], 750 memmove(&pp[ptr], &pp[ptr - 1],
752 (numrecs - ptr + 1) * sizeof(*pp)); 751 (numrecs - ptr + 1) * sizeof(*pp));
753 #ifdef DEBUG 752 #ifdef DEBUG
754 if ((error = xfs_btree_check_sptr(cur, *bnop, level))) 753 if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
755 return error; 754 return error;
756 #endif 755 #endif
757 /* 756 /*
758 * Now stuff the new data in, bump numrecs and log the new data. 757 * Now stuff the new data in, bump numrecs and log the new data.
759 */ 758 */
760 kp[ptr - 1] = key; 759 kp[ptr - 1] = key;
761 pp[ptr - 1] = cpu_to_be32(*bnop); 760 pp[ptr - 1] = cpu_to_be32(*bnop);
762 numrecs++; 761 numrecs++;
763 block->bb_numrecs = cpu_to_be16(numrecs); 762 block->bb_numrecs = cpu_to_be16(numrecs);
764 xfs_alloc_log_keys(cur, bp, ptr, numrecs); 763 xfs_alloc_log_keys(cur, bp, ptr, numrecs);
765 xfs_alloc_log_ptrs(cur, bp, ptr, numrecs); 764 xfs_alloc_log_ptrs(cur, bp, ptr, numrecs);
766 #ifdef DEBUG 765 #ifdef DEBUG
767 if (ptr < numrecs) 766 if (ptr < numrecs)
768 xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1, 767 xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
769 kp + ptr); 768 kp + ptr);
770 #endif 769 #endif
771 } else { 770 } else {
772 /* 771 /*
773 * It's a leaf entry. Make a hole for the new record. 772 * It's a leaf entry. Make a hole for the new record.
774 */ 773 */
775 rp = XFS_ALLOC_REC_ADDR(block, 1, cur); 774 rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
776 memmove(&rp[ptr], &rp[ptr - 1], 775 memmove(&rp[ptr], &rp[ptr - 1],
777 (numrecs - ptr + 1) * sizeof(*rp)); 776 (numrecs - ptr + 1) * sizeof(*rp));
778 /* 777 /*
779 * Now stuff the new record in, bump numrecs 778 * Now stuff the new record in, bump numrecs
780 * and log the new data. 779 * and log the new data.
781 */ 780 */
782 rp[ptr - 1] = *recp; 781 rp[ptr - 1] = *recp;
783 numrecs++; 782 numrecs++;
784 block->bb_numrecs = cpu_to_be16(numrecs); 783 block->bb_numrecs = cpu_to_be16(numrecs);
785 xfs_alloc_log_recs(cur, bp, ptr, numrecs); 784 xfs_alloc_log_recs(cur, bp, ptr, numrecs);
786 #ifdef DEBUG 785 #ifdef DEBUG
787 if (ptr < numrecs) 786 if (ptr < numrecs)
788 xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1, 787 xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
789 rp + ptr); 788 rp + ptr);
790 #endif 789 #endif
791 } 790 }
792 /* 791 /*
793 * Log the new number of records in the btree header. 792 * Log the new number of records in the btree header.
794 */ 793 */
795 xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); 794 xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
796 /* 795 /*
797 * If we inserted at the start of a block, update the parents' keys. 796 * If we inserted at the start of a block, update the parents' keys.
798 */ 797 */
799 if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1))) 798 if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1)))
800 return error; 799 return error;
801 /* 800 /*
802 * Look to see if the longest extent in the allocation group 801 * Look to see if the longest extent in the allocation group
803 * needs to be updated. 802 * needs to be updated.
804 */ 803 */
805 804
806 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 805 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
807 if (level == 0 && 806 if (level == 0 &&
808 cur->bc_btnum == XFS_BTNUM_CNT && 807 cur->bc_btnum == XFS_BTNUM_CNT &&
809 be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK && 808 be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
810 be32_to_cpu(recp->ar_blockcount) > be32_to_cpu(agf->agf_longest)) { 809 be32_to_cpu(recp->ar_blockcount) > be32_to_cpu(agf->agf_longest)) {
811 /* 810 /*
812 * If this is a leaf in the by-size btree and there 811 * If this is a leaf in the by-size btree and there
813 * is no right sibling block and this block is bigger 812 * is no right sibling block and this block is bigger
814 * than the previous longest block, update it. 813 * than the previous longest block, update it.
815 */ 814 */
816 agf->agf_longest = recp->ar_blockcount; 815 agf->agf_longest = recp->ar_blockcount;
817 cur->bc_mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest 816 cur->bc_mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest
818 = be32_to_cpu(recp->ar_blockcount); 817 = be32_to_cpu(recp->ar_blockcount);
819 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, 818 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
820 XFS_AGF_LONGEST); 819 XFS_AGF_LONGEST);
821 } 820 }
822 /* 821 /*
823 * Return the new block number, if any. 822 * Return the new block number, if any.
824 * If there is one, give back a record value and a cursor too. 823 * If there is one, give back a record value and a cursor too.
825 */ 824 */
826 *bnop = nbno; 825 *bnop = nbno;
827 if (nbno != NULLAGBLOCK) { 826 if (nbno != NULLAGBLOCK) {
828 *recp = nrec; 827 *recp = nrec;
829 *curp = ncur; 828 *curp = ncur;
830 } 829 }
831 *stat = 1; 830 *stat = 1;
832 return 0; 831 return 0;
833 } 832 }
834 833
835 /* 834 /*
836 * Log header fields from a btree block. 835 * Log header fields from a btree block.
837 */ 836 */
838 STATIC void 837 STATIC void
839 xfs_alloc_log_block( 838 xfs_alloc_log_block(
840 xfs_trans_t *tp, /* transaction pointer */ 839 xfs_trans_t *tp, /* transaction pointer */
841 xfs_buf_t *bp, /* buffer containing btree block */ 840 xfs_buf_t *bp, /* buffer containing btree block */
842 int fields) /* mask of fields: XFS_BB_... */ 841 int fields) /* mask of fields: XFS_BB_... */
843 { 842 {
844 int first; /* first byte offset logged */ 843 int first; /* first byte offset logged */
845 int last; /* last byte offset logged */ 844 int last; /* last byte offset logged */
846 static const short offsets[] = { /* table of offsets */ 845 static const short offsets[] = { /* table of offsets */
847 offsetof(xfs_alloc_block_t, bb_magic), 846 offsetof(xfs_alloc_block_t, bb_magic),
848 offsetof(xfs_alloc_block_t, bb_level), 847 offsetof(xfs_alloc_block_t, bb_level),
849 offsetof(xfs_alloc_block_t, bb_numrecs), 848 offsetof(xfs_alloc_block_t, bb_numrecs),
850 offsetof(xfs_alloc_block_t, bb_leftsib), 849 offsetof(xfs_alloc_block_t, bb_leftsib),
851 offsetof(xfs_alloc_block_t, bb_rightsib), 850 offsetof(xfs_alloc_block_t, bb_rightsib),
852 sizeof(xfs_alloc_block_t) 851 sizeof(xfs_alloc_block_t)
853 }; 852 };
854 853
855 xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last); 854 xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last);
856 xfs_trans_log_buf(tp, bp, first, last); 855 xfs_trans_log_buf(tp, bp, first, last);
857 } 856 }
858 857
859 /* 858 /*
860 * Log keys from a btree block (nonleaf). 859 * Log keys from a btree block (nonleaf).
861 */ 860 */
862 STATIC void 861 STATIC void
863 xfs_alloc_log_keys( 862 xfs_alloc_log_keys(
864 xfs_btree_cur_t *cur, /* btree cursor */ 863 xfs_btree_cur_t *cur, /* btree cursor */
865 xfs_buf_t *bp, /* buffer containing btree block */ 864 xfs_buf_t *bp, /* buffer containing btree block */
866 int kfirst, /* index of first key to log */ 865 int kfirst, /* index of first key to log */
867 int klast) /* index of last key to log */ 866 int klast) /* index of last key to log */
868 { 867 {
869 xfs_alloc_block_t *block; /* btree block to log from */ 868 xfs_alloc_block_t *block; /* btree block to log from */
870 int first; /* first byte offset logged */ 869 int first; /* first byte offset logged */
871 xfs_alloc_key_t *kp; /* key pointer in btree block */ 870 xfs_alloc_key_t *kp; /* key pointer in btree block */
872 int last; /* last byte offset logged */ 871 int last; /* last byte offset logged */
873 872
874 block = XFS_BUF_TO_ALLOC_BLOCK(bp); 873 block = XFS_BUF_TO_ALLOC_BLOCK(bp);
875 kp = XFS_ALLOC_KEY_ADDR(block, 1, cur); 874 kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
876 first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block); 875 first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
877 last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block); 876 last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
878 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 877 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
879 } 878 }
880 879
881 /* 880 /*
882 * Log block pointer fields from a btree block (nonleaf). 881 * Log block pointer fields from a btree block (nonleaf).
883 */ 882 */
884 STATIC void 883 STATIC void
885 xfs_alloc_log_ptrs( 884 xfs_alloc_log_ptrs(
886 xfs_btree_cur_t *cur, /* btree cursor */ 885 xfs_btree_cur_t *cur, /* btree cursor */
887 xfs_buf_t *bp, /* buffer containing btree block */ 886 xfs_buf_t *bp, /* buffer containing btree block */
888 int pfirst, /* index of first pointer to log */ 887 int pfirst, /* index of first pointer to log */
889 int plast) /* index of last pointer to log */ 888 int plast) /* index of last pointer to log */
890 { 889 {
891 xfs_alloc_block_t *block; /* btree block to log from */ 890 xfs_alloc_block_t *block; /* btree block to log from */
892 int first; /* first byte offset logged */ 891 int first; /* first byte offset logged */
893 int last; /* last byte offset logged */ 892 int last; /* last byte offset logged */
894 xfs_alloc_ptr_t *pp; /* block-pointer pointer in btree blk */ 893 xfs_alloc_ptr_t *pp; /* block-pointer pointer in btree blk */
895 894
896 block = XFS_BUF_TO_ALLOC_BLOCK(bp); 895 block = XFS_BUF_TO_ALLOC_BLOCK(bp);
897 pp = XFS_ALLOC_PTR_ADDR(block, 1, cur); 896 pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
898 first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block); 897 first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
899 last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block); 898 last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
900 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 899 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
901 } 900 }
902 901
903 /* 902 /*
904 * Log records from a btree block (leaf). 903 * Log records from a btree block (leaf).
905 */ 904 */
906 STATIC void 905 STATIC void
907 xfs_alloc_log_recs( 906 xfs_alloc_log_recs(
908 xfs_btree_cur_t *cur, /* btree cursor */ 907 xfs_btree_cur_t *cur, /* btree cursor */
909 xfs_buf_t *bp, /* buffer containing btree block */ 908 xfs_buf_t *bp, /* buffer containing btree block */
910 int rfirst, /* index of first record to log */ 909 int rfirst, /* index of first record to log */
911 int rlast) /* index of last record to log */ 910 int rlast) /* index of last record to log */
912 { 911 {
913 xfs_alloc_block_t *block; /* btree block to log from */ 912 xfs_alloc_block_t *block; /* btree block to log from */
914 int first; /* first byte offset logged */ 913 int first; /* first byte offset logged */
915 int last; /* last byte offset logged */ 914 int last; /* last byte offset logged */
916 xfs_alloc_rec_t *rp; /* record pointer for btree block */ 915 xfs_alloc_rec_t *rp; /* record pointer for btree block */
917 916
918 917
919 block = XFS_BUF_TO_ALLOC_BLOCK(bp); 918 block = XFS_BUF_TO_ALLOC_BLOCK(bp);
920 rp = XFS_ALLOC_REC_ADDR(block, 1, cur); 919 rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
921 #ifdef DEBUG 920 #ifdef DEBUG
922 { 921 {
923 xfs_agf_t *agf; 922 xfs_agf_t *agf;
924 xfs_alloc_rec_t *p; 923 xfs_alloc_rec_t *p;
925 924
926 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 925 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
927 for (p = &rp[rfirst - 1]; p <= &rp[rlast - 1]; p++) 926 for (p = &rp[rfirst - 1]; p <= &rp[rlast - 1]; p++)
928 ASSERT(be32_to_cpu(p->ar_startblock) + 927 ASSERT(be32_to_cpu(p->ar_startblock) +
929 be32_to_cpu(p->ar_blockcount) <= 928 be32_to_cpu(p->ar_blockcount) <=
930 be32_to_cpu(agf->agf_length)); 929 be32_to_cpu(agf->agf_length));
931 } 930 }
932 #endif 931 #endif
933 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block); 932 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
934 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block); 933 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
935 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 934 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
936 }
937
938 /*
939 * Move 1 record left from cur/level if possible.
940 * Update cur to reflect the new path.
941 */
942 STATIC int /* error */
943 xfs_alloc_lshift(
944 xfs_btree_cur_t *cur, /* btree cursor */
945 int level, /* level to shift record on */
946 int *stat) /* success/failure */
947 {
948 int error; /* error return value */
949 #ifdef DEBUG
950 int i; /* loop index */
951 #endif
952 xfs_alloc_key_t key; /* key value for leaf level upward */
953 xfs_buf_t *lbp; /* buffer for left neighbor block */
954 xfs_alloc_block_t *left; /* left neighbor btree block */
955 int nrec; /* new number of left block entries */
956 xfs_buf_t *rbp; /* buffer for right (current) block */
957 xfs_alloc_block_t *right; /* right (current) btree block */
958 xfs_alloc_key_t *rkp=NULL; /* key pointer for right block */
959 xfs_alloc_ptr_t *rpp=NULL; /* address pointer for right block */
960 xfs_alloc_rec_t *rrp=NULL; /* record pointer for right block */
961
962 /*
963 * Set up variables for this block as "right".
964 */
965 rbp = cur->bc_bufs[level];
966 right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
967 #ifdef DEBUG
968 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
969 return error;
970 #endif
971 /*
972 * If we've got no left sibling then we can't shift an entry left.
973 */
974 if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
975 *stat = 0;
976 return 0;
977 }
978 /*
979 * If the cursor entry is the one that would be moved, don't
980 * do it... it's too complicated.
981 */
982 if (cur->bc_ptrs[level] <= 1) {
983 *stat = 0;
984 return 0;
985 }
986 /*
987 * Set up the left neighbor as "left".
988 */
989 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
990 cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
991 0, &lbp, XFS_ALLOC_BTREE_REF)))
992 return error;
993 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
994 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
995 return error;
996 /*
997 * If it's full, it can't take another entry.
998 */
999 if (be16_to_cpu(left->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
1000 *stat = 0;
1001 return 0;
1002 }
1003 nrec = be16_to_cpu(left->bb_numrecs) + 1;
1004 /*
1005 * If non-leaf, copy a key and a ptr to the left block.
1006 */
1007 if (level > 0) {
1008 xfs_alloc_key_t *lkp; /* key pointer for left block */
1009 xfs_alloc_ptr_t *lpp; /* address pointer for left block */
1010
1011 lkp = XFS_ALLOC_KEY_ADDR(left, nrec, cur);
1012 rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
1013 *lkp = *rkp;
1014 xfs_alloc_log_keys(cur, lbp, nrec, nrec);
1015 lpp = XFS_ALLOC_PTR_ADDR(left, nrec, cur);
1016 rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
1017 #ifdef DEBUG
1018 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
1019 return error;
1020 #endif
1021 *lpp = *rpp;
1022 xfs_alloc_log_ptrs(cur, lbp, nrec, nrec);
1023 xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
1024 }
1025 /*
1026 * If leaf, copy a record to the left block.
1027 */
1028 else {
1029 xfs_alloc_rec_t *lrp; /* record pointer for left block */
1030
1031 lrp = XFS_ALLOC_REC_ADDR(left, nrec, cur);
1032 rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
1033 *lrp = *rrp;
1034 xfs_alloc_log_recs(cur, lbp, nrec, nrec);
1035 xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
1036 }
1037 /*
1038 * Bump and log left's numrecs, decrement and log right's numrecs.
1039 */
1040 be16_add_cpu(&left->bb_numrecs, 1);
1041 xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
1042 be16_add_cpu(&right->bb_numrecs, -1);
1043 xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
1044 /*
1045 * Slide the contents of right down one entry.
1046 */
1047 if (level > 0) {
1048 #ifdef DEBUG
1049 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
1050 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
1051 level)))
1052 return error;
1053 }
1054 #endif
1055 memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
1056 memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
1057 xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1058 xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1059 } else {
1060 memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
1061 xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1062 key.ar_startblock = rrp->ar_startblock;
1063 key.ar_blockcount = rrp->ar_blockcount;
1064 rkp = &key;
1065 }
1066 /*
1067 * Update the parent key values of right.
1068 */
1069 if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
1070 return error;
1071 /*
1072 * Slide the cursor value left one.
1073 */
1074 cur->bc_ptrs[level]--;
1075 *stat = 1;
1076 return 0;
1077 } 935 }
1078 936
1079 /* 937 /*
1080 * Allocate a new root block, fill it in. 938 * Allocate a new root block, fill it in.
1081 */ 939 */
1082 STATIC int /* error */ 940 STATIC int /* error */
1083 xfs_alloc_newroot( 941 xfs_alloc_newroot(
1084 xfs_btree_cur_t *cur, /* btree cursor */ 942 xfs_btree_cur_t *cur, /* btree cursor */
1085 int *stat) /* success/failure */ 943 int *stat) /* success/failure */
1086 { 944 {
1087 int error; /* error return value */ 945 int error; /* error return value */
1088 xfs_agblock_t lbno; /* left block number */ 946 xfs_agblock_t lbno; /* left block number */
1089 xfs_buf_t *lbp; /* left btree buffer */ 947 xfs_buf_t *lbp; /* left btree buffer */
1090 xfs_alloc_block_t *left; /* left btree block */ 948 xfs_alloc_block_t *left; /* left btree block */
1091 xfs_mount_t *mp; /* mount structure */ 949 xfs_mount_t *mp; /* mount structure */
1092 xfs_agblock_t nbno; /* new block number */ 950 xfs_agblock_t nbno; /* new block number */
1093 xfs_buf_t *nbp; /* new (root) buffer */ 951 xfs_buf_t *nbp; /* new (root) buffer */
1094 xfs_alloc_block_t *new; /* new (root) btree block */ 952 xfs_alloc_block_t *new; /* new (root) btree block */
1095 int nptr; /* new value for key index, 1 or 2 */ 953 int nptr; /* new value for key index, 1 or 2 */
1096 xfs_agblock_t rbno; /* right block number */ 954 xfs_agblock_t rbno; /* right block number */
1097 xfs_buf_t *rbp; /* right btree buffer */ 955 xfs_buf_t *rbp; /* right btree buffer */
1098 xfs_alloc_block_t *right; /* right btree block */ 956 xfs_alloc_block_t *right; /* right btree block */
1099 957
1100 mp = cur->bc_mp; 958 mp = cur->bc_mp;
1101 959
1102 ASSERT(cur->bc_nlevels < XFS_AG_MAXLEVELS(mp)); 960 ASSERT(cur->bc_nlevels < XFS_AG_MAXLEVELS(mp));
1103 /* 961 /*
1104 * Get a buffer from the freelist blocks, for the new root. 962 * Get a buffer from the freelist blocks, for the new root.
1105 */ 963 */
1106 error = xfs_alloc_get_freelist(cur->bc_tp, 964 error = xfs_alloc_get_freelist(cur->bc_tp,
1107 cur->bc_private.a.agbp, &nbno, 1); 965 cur->bc_private.a.agbp, &nbno, 1);
1108 if (error) 966 if (error)
1109 return error; 967 return error;
1110 /* 968 /*
1111 * None available, we fail. 969 * None available, we fail.
1112 */ 970 */
1113 if (nbno == NULLAGBLOCK) { 971 if (nbno == NULLAGBLOCK) {
1114 *stat = 0; 972 *stat = 0;
1115 return 0; 973 return 0;
1116 } 974 }
1117 xfs_trans_agbtree_delta(cur->bc_tp, 1); 975 xfs_trans_agbtree_delta(cur->bc_tp, 1);
1118 nbp = xfs_btree_get_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, nbno, 976 nbp = xfs_btree_get_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, nbno,
1119 0); 977 0);
1120 new = XFS_BUF_TO_ALLOC_BLOCK(nbp); 978 new = XFS_BUF_TO_ALLOC_BLOCK(nbp);
1121 /* 979 /*
1122 * Set the root data in the a.g. freespace structure. 980 * Set the root data in the a.g. freespace structure.
1123 */ 981 */
1124 { 982 {
1125 xfs_agf_t *agf; /* a.g. freespace header */ 983 xfs_agf_t *agf; /* a.g. freespace header */
1126 xfs_agnumber_t seqno; 984 xfs_agnumber_t seqno;
1127 985
1128 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 986 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
1129 agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno); 987 agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno);
1130 be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1); 988 be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1);
1131 seqno = be32_to_cpu(agf->agf_seqno); 989 seqno = be32_to_cpu(agf->agf_seqno);
1132 mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++; 990 mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++;
1133 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, 991 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
1134 XFS_AGF_ROOTS | XFS_AGF_LEVELS); 992 XFS_AGF_ROOTS | XFS_AGF_LEVELS);
1135 } 993 }
1136 /* 994 /*
1137 * At the previous root level there are now two blocks: the old 995 * At the previous root level there are now two blocks: the old
1138 * root, and the new block generated when it was split. 996 * root, and the new block generated when it was split.
1139 * We don't know which one the cursor is pointing at, so we 997 * We don't know which one the cursor is pointing at, so we
1140 * set up variables "left" and "right" for each case. 998 * set up variables "left" and "right" for each case.
1141 */ 999 */
1142 lbp = cur->bc_bufs[cur->bc_nlevels - 1]; 1000 lbp = cur->bc_bufs[cur->bc_nlevels - 1];
1143 left = XFS_BUF_TO_ALLOC_BLOCK(lbp); 1001 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
1144 #ifdef DEBUG 1002 #ifdef DEBUG
1145 if ((error = xfs_btree_check_sblock(cur, left, cur->bc_nlevels - 1, lbp))) 1003 if ((error = xfs_btree_check_sblock(cur, left, cur->bc_nlevels - 1, lbp)))
1146 return error; 1004 return error;
1147 #endif 1005 #endif
1148 if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) { 1006 if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
1149 /* 1007 /*
1150 * Our block is left, pick up the right block. 1008 * Our block is left, pick up the right block.
1151 */ 1009 */
1152 lbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(lbp)); 1010 lbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(lbp));
1153 rbno = be32_to_cpu(left->bb_rightsib); 1011 rbno = be32_to_cpu(left->bb_rightsib);
1154 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 1012 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
1155 cur->bc_private.a.agno, rbno, 0, &rbp, 1013 cur->bc_private.a.agno, rbno, 0, &rbp,
1156 XFS_ALLOC_BTREE_REF))) 1014 XFS_ALLOC_BTREE_REF)))
1157 return error; 1015 return error;
1158 right = XFS_BUF_TO_ALLOC_BLOCK(rbp); 1016 right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
1159 if ((error = xfs_btree_check_sblock(cur, right, 1017 if ((error = xfs_btree_check_sblock(cur, right,
1160 cur->bc_nlevels - 1, rbp))) 1018 cur->bc_nlevels - 1, rbp)))
1161 return error; 1019 return error;
1162 nptr = 1; 1020 nptr = 1;
1163 } else { 1021 } else {
1164 /* 1022 /*
1165 * Our block is right, pick up the left block. 1023 * Our block is right, pick up the left block.
1166 */ 1024 */
1167 rbp = lbp; 1025 rbp = lbp;
1168 right = left; 1026 right = left;
1169 rbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(rbp)); 1027 rbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(rbp));
1170 lbno = be32_to_cpu(right->bb_leftsib); 1028 lbno = be32_to_cpu(right->bb_leftsib);
1171 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 1029 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
1172 cur->bc_private.a.agno, lbno, 0, &lbp, 1030 cur->bc_private.a.agno, lbno, 0, &lbp,
1173 XFS_ALLOC_BTREE_REF))) 1031 XFS_ALLOC_BTREE_REF)))
1174 return error; 1032 return error;
1175 left = XFS_BUF_TO_ALLOC_BLOCK(lbp); 1033 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
1176 if ((error = xfs_btree_check_sblock(cur, left, 1034 if ((error = xfs_btree_check_sblock(cur, left,
1177 cur->bc_nlevels - 1, lbp))) 1035 cur->bc_nlevels - 1, lbp)))
1178 return error; 1036 return error;
1179 nptr = 2; 1037 nptr = 2;
1180 } 1038 }
1181 /* 1039 /*
1182 * Fill in the new block's btree header and log it. 1040 * Fill in the new block's btree header and log it.
1183 */ 1041 */
1184 new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); 1042 new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
1185 new->bb_level = cpu_to_be16(cur->bc_nlevels); 1043 new->bb_level = cpu_to_be16(cur->bc_nlevels);
1186 new->bb_numrecs = cpu_to_be16(2); 1044 new->bb_numrecs = cpu_to_be16(2);
1187 new->bb_leftsib = cpu_to_be32(NULLAGBLOCK); 1045 new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
1188 new->bb_rightsib = cpu_to_be32(NULLAGBLOCK); 1046 new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
1189 xfs_alloc_log_block(cur->bc_tp, nbp, XFS_BB_ALL_BITS); 1047 xfs_alloc_log_block(cur->bc_tp, nbp, XFS_BB_ALL_BITS);
1190 ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK); 1048 ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
1191 /* 1049 /*
1192 * Fill in the key data in the new root. 1050 * Fill in the key data in the new root.
1193 */ 1051 */
1194 { 1052 {
1195 xfs_alloc_key_t *kp; /* btree key pointer */ 1053 xfs_alloc_key_t *kp; /* btree key pointer */
1196 1054
1197 kp = XFS_ALLOC_KEY_ADDR(new, 1, cur); 1055 kp = XFS_ALLOC_KEY_ADDR(new, 1, cur);
1198 if (be16_to_cpu(left->bb_level) > 0) { 1056 if (be16_to_cpu(left->bb_level) > 0) {
1199 kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); 1057 kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur);
1200 kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur); 1058 kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);
1201 } else { 1059 } else {
1202 xfs_alloc_rec_t *rp; /* btree record pointer */ 1060 xfs_alloc_rec_t *rp; /* btree record pointer */
1203 1061
1204 rp = XFS_ALLOC_REC_ADDR(left, 1, cur); 1062 rp = XFS_ALLOC_REC_ADDR(left, 1, cur);
1205 kp[0].ar_startblock = rp->ar_startblock; 1063 kp[0].ar_startblock = rp->ar_startblock;
1206 kp[0].ar_blockcount = rp->ar_blockcount; 1064 kp[0].ar_blockcount = rp->ar_blockcount;
1207 rp = XFS_ALLOC_REC_ADDR(right, 1, cur); 1065 rp = XFS_ALLOC_REC_ADDR(right, 1, cur);
1208 kp[1].ar_startblock = rp->ar_startblock; 1066 kp[1].ar_startblock = rp->ar_startblock;
1209 kp[1].ar_blockcount = rp->ar_blockcount; 1067 kp[1].ar_blockcount = rp->ar_blockcount;
1210 } 1068 }
1211 } 1069 }
1212 xfs_alloc_log_keys(cur, nbp, 1, 2); 1070 xfs_alloc_log_keys(cur, nbp, 1, 2);
1213 /* 1071 /*
1214 * Fill in the pointer data in the new root. 1072 * Fill in the pointer data in the new root.
1215 */ 1073 */
1216 { 1074 {
1217 xfs_alloc_ptr_t *pp; /* btree address pointer */ 1075 xfs_alloc_ptr_t *pp; /* btree address pointer */
1218 1076
1219 pp = XFS_ALLOC_PTR_ADDR(new, 1, cur); 1077 pp = XFS_ALLOC_PTR_ADDR(new, 1, cur);
1220 pp[0] = cpu_to_be32(lbno); 1078 pp[0] = cpu_to_be32(lbno);
1221 pp[1] = cpu_to_be32(rbno); 1079 pp[1] = cpu_to_be32(rbno);
1222 } 1080 }
1223 xfs_alloc_log_ptrs(cur, nbp, 1, 2); 1081 xfs_alloc_log_ptrs(cur, nbp, 1, 2);
1224 /* 1082 /*
1225 * Fix up the cursor. 1083 * Fix up the cursor.
1226 */ 1084 */
1227 xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); 1085 xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
1228 cur->bc_ptrs[cur->bc_nlevels] = nptr; 1086 cur->bc_ptrs[cur->bc_nlevels] = nptr;
1229 cur->bc_nlevels++; 1087 cur->bc_nlevels++;
1230 *stat = 1; 1088 *stat = 1;
1231 return 0; 1089 return 0;
1232 } 1090 }
1233 1091
1234 /* 1092 /*
1235 * Split cur/level block in half. 1093 * Split cur/level block in half.
1236 * Return new block number and its first record (to be inserted into parent). 1094 * Return new block number and its first record (to be inserted into parent).
1237 */ 1095 */
1238 STATIC int /* error */ 1096 STATIC int /* error */
1239 xfs_alloc_split( 1097 xfs_alloc_split(
1240 xfs_btree_cur_t *cur, /* btree cursor */ 1098 xfs_btree_cur_t *cur, /* btree cursor */
1241 int level, /* level to split */ 1099 int level, /* level to split */
1242 xfs_agblock_t *bnop, /* output: block number allocated */ 1100 xfs_agblock_t *bnop, /* output: block number allocated */
1243 xfs_alloc_key_t *keyp, /* output: first key of new block */ 1101 xfs_alloc_key_t *keyp, /* output: first key of new block */
1244 xfs_btree_cur_t **curp, /* output: new cursor */ 1102 xfs_btree_cur_t **curp, /* output: new cursor */
1245 int *stat) /* success/failure */ 1103 int *stat) /* success/failure */
1246 { 1104 {
1247 int error; /* error return value */ 1105 int error; /* error return value */
1248 int i; /* loop index/record number */ 1106 int i; /* loop index/record number */
1249 xfs_agblock_t lbno; /* left (current) block number */ 1107 xfs_agblock_t lbno; /* left (current) block number */
1250 xfs_buf_t *lbp; /* buffer for left block */ 1108 xfs_buf_t *lbp; /* buffer for left block */
1251 xfs_alloc_block_t *left; /* left (current) btree block */ 1109 xfs_alloc_block_t *left; /* left (current) btree block */
1252 xfs_agblock_t rbno; /* right (new) block number */ 1110 xfs_agblock_t rbno; /* right (new) block number */
1253 xfs_buf_t *rbp; /* buffer for right block */ 1111 xfs_buf_t *rbp; /* buffer for right block */
1254 xfs_alloc_block_t *right; /* right (new) btree block */ 1112 xfs_alloc_block_t *right; /* right (new) btree block */
1255 1113
1256 /* 1114 /*
1257 * Allocate the new block from the freelist. 1115 * Allocate the new block from the freelist.
1258 * If we can't do it, we're toast. Give up. 1116 * If we can't do it, we're toast. Give up.
1259 */ 1117 */
1260 error = xfs_alloc_get_freelist(cur->bc_tp, 1118 error = xfs_alloc_get_freelist(cur->bc_tp,
1261 cur->bc_private.a.agbp, &rbno, 1); 1119 cur->bc_private.a.agbp, &rbno, 1);
1262 if (error) 1120 if (error)
1263 return error; 1121 return error;
1264 if (rbno == NULLAGBLOCK) { 1122 if (rbno == NULLAGBLOCK) {
1265 *stat = 0; 1123 *stat = 0;
1266 return 0; 1124 return 0;
1267 } 1125 }
1268 xfs_trans_agbtree_delta(cur->bc_tp, 1); 1126 xfs_trans_agbtree_delta(cur->bc_tp, 1);
1269 rbp = xfs_btree_get_bufs(cur->bc_mp, cur->bc_tp, cur->bc_private.a.agno, 1127 rbp = xfs_btree_get_bufs(cur->bc_mp, cur->bc_tp, cur->bc_private.a.agno,
1270 rbno, 0); 1128 rbno, 0);
1271 /* 1129 /*
1272 * Set up the new block as "right". 1130 * Set up the new block as "right".
1273 */ 1131 */
1274 right = XFS_BUF_TO_ALLOC_BLOCK(rbp); 1132 right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
1275 /* 1133 /*
1276 * "Left" is the current (according to the cursor) block. 1134 * "Left" is the current (according to the cursor) block.
1277 */ 1135 */
1278 lbp = cur->bc_bufs[level]; 1136 lbp = cur->bc_bufs[level];
1279 left = XFS_BUF_TO_ALLOC_BLOCK(lbp); 1137 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
1280 #ifdef DEBUG 1138 #ifdef DEBUG
1281 if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) 1139 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
1282 return error; 1140 return error;
1283 #endif 1141 #endif
1284 /* 1142 /*
1285 * Fill in the btree header for the new block. 1143 * Fill in the btree header for the new block.
1286 */ 1144 */
1287 right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); 1145 right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
1288 right->bb_level = left->bb_level; 1146 right->bb_level = left->bb_level;
1289 right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2); 1147 right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
1290 /* 1148 /*
1291 * Make sure that if there's an odd number of entries now, that 1149 * Make sure that if there's an odd number of entries now, that
1292 * each new block will have the same number of entries. 1150 * each new block will have the same number of entries.
1293 */ 1151 */
1294 if ((be16_to_cpu(left->bb_numrecs) & 1) && 1152 if ((be16_to_cpu(left->bb_numrecs) & 1) &&
1295 cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) 1153 cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
1296 be16_add_cpu(&right->bb_numrecs, 1); 1154 be16_add_cpu(&right->bb_numrecs, 1);
1297 i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; 1155 i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
1298 /* 1156 /*
1299 * For non-leaf blocks, copy keys and addresses over to the new block. 1157 * For non-leaf blocks, copy keys and addresses over to the new block.
1300 */ 1158 */
1301 if (level > 0) { 1159 if (level > 0) {
1302 xfs_alloc_key_t *lkp; /* left btree key pointer */ 1160 xfs_alloc_key_t *lkp; /* left btree key pointer */
1303 xfs_alloc_ptr_t *lpp; /* left btree address pointer */ 1161 xfs_alloc_ptr_t *lpp; /* left btree address pointer */
1304 xfs_alloc_key_t *rkp; /* right btree key pointer */ 1162 xfs_alloc_key_t *rkp; /* right btree key pointer */
1305 xfs_alloc_ptr_t *rpp; /* right btree address pointer */ 1163 xfs_alloc_ptr_t *rpp; /* right btree address pointer */
1306 1164
1307 lkp = XFS_ALLOC_KEY_ADDR(left, i, cur); 1165 lkp = XFS_ALLOC_KEY_ADDR(left, i, cur);
1308 lpp = XFS_ALLOC_PTR_ADDR(left, i, cur); 1166 lpp = XFS_ALLOC_PTR_ADDR(left, i, cur);
1309 rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur); 1167 rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
1310 rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur); 1168 rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
1311 #ifdef DEBUG 1169 #ifdef DEBUG
1312 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { 1170 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
1313 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level))) 1171 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
1314 return error; 1172 return error;
1315 } 1173 }
1316 #endif 1174 #endif
1317 memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); 1175 memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
1318 memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); 1176 memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
1319 xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 1177 xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1320 xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 1178 xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1321 *keyp = *rkp; 1179 *keyp = *rkp;
1322 } 1180 }
1323 /* 1181 /*
1324 * For leaf blocks, copy records over to the new block. 1182 * For leaf blocks, copy records over to the new block.
1325 */ 1183 */
1326 else { 1184 else {
1327 xfs_alloc_rec_t *lrp; /* left btree record pointer */ 1185 xfs_alloc_rec_t *lrp; /* left btree record pointer */
1328 xfs_alloc_rec_t *rrp; /* right btree record pointer */ 1186 xfs_alloc_rec_t *rrp; /* right btree record pointer */
1329 1187
1330 lrp = XFS_ALLOC_REC_ADDR(left, i, cur); 1188 lrp = XFS_ALLOC_REC_ADDR(left, i, cur);
1331 rrp = XFS_ALLOC_REC_ADDR(right, 1, cur); 1189 rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
1332 memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); 1190 memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
1333 xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 1191 xfs_alloc_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1334 keyp->ar_startblock = rrp->ar_startblock; 1192 keyp->ar_startblock = rrp->ar_startblock;
1335 keyp->ar_blockcount = rrp->ar_blockcount; 1193 keyp->ar_blockcount = rrp->ar_blockcount;
1336 } 1194 }
1337 /* 1195 /*
1338 * Find the left block number by looking in the buffer. 1196 * Find the left block number by looking in the buffer.
1339 * Adjust numrecs, sibling pointers. 1197 * Adjust numrecs, sibling pointers.
1340 */ 1198 */
1341 lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp)); 1199 lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp));
1342 be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); 1200 be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
1343 right->bb_rightsib = left->bb_rightsib; 1201 right->bb_rightsib = left->bb_rightsib;
1344 left->bb_rightsib = cpu_to_be32(rbno); 1202 left->bb_rightsib = cpu_to_be32(rbno);
1345 right->bb_leftsib = cpu_to_be32(lbno); 1203 right->bb_leftsib = cpu_to_be32(lbno);
1346 xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_ALL_BITS); 1204 xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_ALL_BITS);
1347 xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); 1205 xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
1348 /* 1206 /*
1349 * If there's a block to the new block's right, make that block 1207 * If there's a block to the new block's right, make that block
1350 * point back to right instead of to left. 1208 * point back to right instead of to left.
1351 */ 1209 */
1352 if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) { 1210 if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
1353 xfs_alloc_block_t *rrblock; /* rr btree block */ 1211 xfs_alloc_block_t *rrblock; /* rr btree block */
1354 xfs_buf_t *rrbp; /* buffer for rrblock */ 1212 xfs_buf_t *rrbp; /* buffer for rrblock */
1355 1213
1356 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, 1214 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
1357 cur->bc_private.a.agno, be32_to_cpu(right->bb_rightsib), 0, 1215 cur->bc_private.a.agno, be32_to_cpu(right->bb_rightsib), 0,
1358 &rrbp, XFS_ALLOC_BTREE_REF))) 1216 &rrbp, XFS_ALLOC_BTREE_REF)))
1359 return error; 1217 return error;
1360 rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp); 1218 rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp);
1361 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp))) 1219 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
1362 return error; 1220 return error;
1363 rrblock->bb_leftsib = cpu_to_be32(rbno); 1221 rrblock->bb_leftsib = cpu_to_be32(rbno);
1364 xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB); 1222 xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
1365 } 1223 }
1366 /* 1224 /*
1367 * If the cursor is really in the right block, move it there. 1225 * If the cursor is really in the right block, move it there.
1368 * If it's just pointing past the last entry in left, then we'll 1226 * If it's just pointing past the last entry in left, then we'll
1369 * insert there, so don't change anything in that case. 1227 * insert there, so don't change anything in that case.
1370 */ 1228 */
1371 if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) { 1229 if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
1372 xfs_btree_setbuf(cur, level, rbp); 1230 xfs_btree_setbuf(cur, level, rbp);
1373 cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs); 1231 cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
1374 } 1232 }
1375 /* 1233 /*
1376 * If there are more levels, we'll need another cursor which refers to 1234 * If there are more levels, we'll need another cursor which refers to
1377 * the right block, no matter where this cursor was. 1235 * the right block, no matter where this cursor was.
1378 */ 1236 */
1379 if (level + 1 < cur->bc_nlevels) { 1237 if (level + 1 < cur->bc_nlevels) {
1380 if ((error = xfs_btree_dup_cursor(cur, curp))) 1238 if ((error = xfs_btree_dup_cursor(cur, curp)))
1381 return error; 1239 return error;
1382 (*curp)->bc_ptrs[level + 1]++; 1240 (*curp)->bc_ptrs[level + 1]++;
1383 } 1241 }
1384 *bnop = rbno; 1242 *bnop = rbno;
1385 *stat = 1; 1243 *stat = 1;
1386 return 0; 1244 return 0;
1387 } 1245 }
1388 1246
1389 /* 1247 /*
1390 * Externally visible routines. 1248 * Externally visible routines.
1391 */ 1249 */
1392 1250
1393 /* 1251 /*
1394 * Delete the record pointed to by cur. 1252 * Delete the record pointed to by cur.
1395 * The cursor refers to the place where the record was (could be inserted) 1253 * The cursor refers to the place where the record was (could be inserted)
1396 * when the operation returns. 1254 * when the operation returns.
1397 */ 1255 */
1398 int /* error */ 1256 int /* error */
1399 xfs_alloc_delete( 1257 xfs_alloc_delete(
1400 xfs_btree_cur_t *cur, /* btree cursor */ 1258 xfs_btree_cur_t *cur, /* btree cursor */
1401 int *stat) /* success/failure */ 1259 int *stat) /* success/failure */
1402 { 1260 {
1403 int error; /* error return value */ 1261 int error; /* error return value */
1404 int i; /* result code */ 1262 int i; /* result code */
1405 int level; /* btree level */ 1263 int level; /* btree level */
1406 1264
1407 /* 1265 /*
1408 * Go up the tree, starting at leaf level. 1266 * Go up the tree, starting at leaf level.
1409 * If 2 is returned then a join was done; go to the next level. 1267 * If 2 is returned then a join was done; go to the next level.
1410 * Otherwise we are done. 1268 * Otherwise we are done.
1411 */ 1269 */
1412 for (level = 0, i = 2; i == 2; level++) { 1270 for (level = 0, i = 2; i == 2; level++) {
1413 if ((error = xfs_alloc_delrec(cur, level, &i))) 1271 if ((error = xfs_alloc_delrec(cur, level, &i)))
1414 return error; 1272 return error;
1415 } 1273 }
1416 if (i == 0) { 1274 if (i == 0) {
1417 for (level = 1; level < cur->bc_nlevels; level++) { 1275 for (level = 1; level < cur->bc_nlevels; level++) {
1418 if (cur->bc_ptrs[level] == 0) { 1276 if (cur->bc_ptrs[level] == 0) {
1419 if ((error = xfs_btree_decrement(cur, level, &i))) 1277 if ((error = xfs_btree_decrement(cur, level, &i)))
1420 return error; 1278 return error;
1421 break; 1279 break;
1422 } 1280 }
1423 } 1281 }
1424 } 1282 }
1425 *stat = i; 1283 *stat = i;
1426 return 0; 1284 return 0;
1427 } 1285 }
1428 1286
1429 /* 1287 /*
1430 * Get the data from the pointed-to record. 1288 * Get the data from the pointed-to record.
1431 */ 1289 */
1432 int /* error */ 1290 int /* error */
1433 xfs_alloc_get_rec( 1291 xfs_alloc_get_rec(
1434 xfs_btree_cur_t *cur, /* btree cursor */ 1292 xfs_btree_cur_t *cur, /* btree cursor */
1435 xfs_agblock_t *bno, /* output: starting block of extent */ 1293 xfs_agblock_t *bno, /* output: starting block of extent */
1436 xfs_extlen_t *len, /* output: length of extent */ 1294 xfs_extlen_t *len, /* output: length of extent */
1437 int *stat) /* output: success/failure */ 1295 int *stat) /* output: success/failure */
1438 { 1296 {
1439 xfs_alloc_block_t *block; /* btree block */ 1297 xfs_alloc_block_t *block; /* btree block */
1440 #ifdef DEBUG 1298 #ifdef DEBUG
1441 int error; /* error return value */ 1299 int error; /* error return value */
1442 #endif 1300 #endif
1443 int ptr; /* record number */ 1301 int ptr; /* record number */
1444 1302
1445 ptr = cur->bc_ptrs[0]; 1303 ptr = cur->bc_ptrs[0];
1446 block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[0]); 1304 block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[0]);
1447 #ifdef DEBUG 1305 #ifdef DEBUG
1448 if ((error = xfs_btree_check_sblock(cur, block, 0, cur->bc_bufs[0]))) 1306 if ((error = xfs_btree_check_sblock(cur, block, 0, cur->bc_bufs[0])))
1449 return error; 1307 return error;
1450 #endif 1308 #endif
1451 /* 1309 /*
1452 * Off the right end or left end, return failure. 1310 * Off the right end or left end, return failure.
1453 */ 1311 */
1454 if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) { 1312 if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
1455 *stat = 0; 1313 *stat = 0;
1456 return 0; 1314 return 0;
1457 } 1315 }
1458 /* 1316 /*
1459 * Point to the record and extract its data. 1317 * Point to the record and extract its data.
1460 */ 1318 */
1461 { 1319 {
1462 xfs_alloc_rec_t *rec; /* record data */ 1320 xfs_alloc_rec_t *rec; /* record data */
1463 1321
1464 rec = XFS_ALLOC_REC_ADDR(block, ptr, cur); 1322 rec = XFS_ALLOC_REC_ADDR(block, ptr, cur);
1465 *bno = be32_to_cpu(rec->ar_startblock); 1323 *bno = be32_to_cpu(rec->ar_startblock);
1466 *len = be32_to_cpu(rec->ar_blockcount); 1324 *len = be32_to_cpu(rec->ar_blockcount);
1467 } 1325 }
1468 *stat = 1; 1326 *stat = 1;
1469 return 0; 1327 return 0;
1470 } 1328 }
1471 1329
1472 /* 1330 /*
1473 * Insert the current record at the point referenced by cur. 1331 * Insert the current record at the point referenced by cur.
1474 * The cursor may be inconsistent on return if splits have been done. 1332 * The cursor may be inconsistent on return if splits have been done.
1475 */ 1333 */
1476 int /* error */ 1334 int /* error */
1477 xfs_alloc_insert( 1335 xfs_alloc_insert(
1478 xfs_btree_cur_t *cur, /* btree cursor */ 1336 xfs_btree_cur_t *cur, /* btree cursor */
1479 int *stat) /* success/failure */ 1337 int *stat) /* success/failure */
1480 { 1338 {
1481 int error; /* error return value */ 1339 int error; /* error return value */
1482 int i; /* result value, 0 for failure */ 1340 int i; /* result value, 0 for failure */
1483 int level; /* current level number in btree */ 1341 int level; /* current level number in btree */
1484 xfs_agblock_t nbno; /* new block number (split result) */ 1342 xfs_agblock_t nbno; /* new block number (split result) */
1485 xfs_btree_cur_t *ncur; /* new cursor (split result) */ 1343 xfs_btree_cur_t *ncur; /* new cursor (split result) */
1486 xfs_alloc_rec_t nrec; /* record being inserted this level */ 1344 xfs_alloc_rec_t nrec; /* record being inserted this level */
1487 xfs_btree_cur_t *pcur; /* previous level's cursor */ 1345 xfs_btree_cur_t *pcur; /* previous level's cursor */
1488 1346
1489 level = 0; 1347 level = 0;
1490 nbno = NULLAGBLOCK; 1348 nbno = NULLAGBLOCK;
1491 nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock); 1349 nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
1492 nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount); 1350 nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
1493 ncur = NULL; 1351 ncur = NULL;
1494 pcur = cur; 1352 pcur = cur;
1495 /* 1353 /*
1496 * Loop going up the tree, starting at the leaf level. 1354 * Loop going up the tree, starting at the leaf level.
1497 * Stop when we don't get a split block, that must mean that 1355 * Stop when we don't get a split block, that must mean that
1498 * the insert is finished with this level. 1356 * the insert is finished with this level.
1499 */ 1357 */
1500 do { 1358 do {
1501 /* 1359 /*
1502 * Insert nrec/nbno into this level of the tree. 1360 * Insert nrec/nbno into this level of the tree.
1503 * Note if we fail, nbno will be null. 1361 * Note if we fail, nbno will be null.
1504 */ 1362 */
1505 if ((error = xfs_alloc_insrec(pcur, level++, &nbno, &nrec, &ncur, 1363 if ((error = xfs_alloc_insrec(pcur, level++, &nbno, &nrec, &ncur,
1506 &i))) { 1364 &i))) {
1507 if (pcur != cur) 1365 if (pcur != cur)
1508 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR); 1366 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
1509 return error; 1367 return error;
1510 } 1368 }
1511 /* 1369 /*
1512 * See if the cursor we just used is trash. 1370 * See if the cursor we just used is trash.
1513 * Can't trash the caller's cursor, but otherwise we should 1371 * Can't trash the caller's cursor, but otherwise we should
1514 * if ncur is a new cursor or we're about to be done. 1372 * if ncur is a new cursor or we're about to be done.
1515 */ 1373 */
1516 if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) { 1374 if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {
1517 cur->bc_nlevels = pcur->bc_nlevels; 1375 cur->bc_nlevels = pcur->bc_nlevels;
1518 xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR); 1376 xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
1519 } 1377 }
1520 /* 1378 /*
1521 * If we got a new cursor, switch to it. 1379 * If we got a new cursor, switch to it.
1522 */ 1380 */
1523 if (ncur) { 1381 if (ncur) {
1524 pcur = ncur; 1382 pcur = ncur;
1525 ncur = NULL; 1383 ncur = NULL;
1526 } 1384 }
1527 } while (nbno != NULLAGBLOCK); 1385 } while (nbno != NULLAGBLOCK);
1528 *stat = i; 1386 *stat = i;
1529 return 0; 1387 return 0;
1530 } 1388 }
1531 1389
1532 STATIC struct xfs_btree_cur * 1390 STATIC struct xfs_btree_cur *
1533 xfs_allocbt_dup_cursor( 1391 xfs_allocbt_dup_cursor(
1534 struct xfs_btree_cur *cur) 1392 struct xfs_btree_cur *cur)
1535 { 1393 {
1536 return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp, 1394 return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
1537 cur->bc_private.a.agbp, cur->bc_private.a.agno, 1395 cur->bc_private.a.agbp, cur->bc_private.a.agno,
1538 cur->bc_btnum); 1396 cur->bc_btnum);
1539 } 1397 }
1540 1398
1541 /* 1399 /*
1542 * Update the longest extent in the AGF 1400 * Update the longest extent in the AGF
1543 */ 1401 */
1544 STATIC void 1402 STATIC void
1545 xfs_allocbt_update_lastrec( 1403 xfs_allocbt_update_lastrec(
1546 struct xfs_btree_cur *cur, 1404 struct xfs_btree_cur *cur,
1547 struct xfs_btree_block *block, 1405 struct xfs_btree_block *block,
1548 union xfs_btree_rec *rec, 1406 union xfs_btree_rec *rec,
1549 int ptr, 1407 int ptr,
1550 int reason) 1408 int reason)
1551 { 1409 {
1552 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 1410 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
1553 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); 1411 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
1554 __be32 len; 1412 __be32 len;
1555 1413
1556 ASSERT(cur->bc_btnum == XFS_BTNUM_CNT); 1414 ASSERT(cur->bc_btnum == XFS_BTNUM_CNT);
1557 1415
1558 switch (reason) { 1416 switch (reason) {
1559 case LASTREC_UPDATE: 1417 case LASTREC_UPDATE:
1560 /* 1418 /*
1561 * If this is the last leaf block and it's the last record, 1419 * If this is the last leaf block and it's the last record,
1562 * then update the size of the longest extent in the AG. 1420 * then update the size of the longest extent in the AG.
1563 */ 1421 */
1564 if (ptr != xfs_btree_get_numrecs(block)) 1422 if (ptr != xfs_btree_get_numrecs(block))
1565 return; 1423 return;
1566 len = rec->alloc.ar_blockcount; 1424 len = rec->alloc.ar_blockcount;
1567 break; 1425 break;
1568 default: 1426 default:
1569 ASSERT(0); 1427 ASSERT(0);
1570 return; 1428 return;
1571 } 1429 }
1572 1430
1573 agf->agf_longest = len; 1431 agf->agf_longest = len;
1574 cur->bc_mp->m_perag[seqno].pagf_longest = be32_to_cpu(len); 1432 cur->bc_mp->m_perag[seqno].pagf_longest = be32_to_cpu(len);
1575 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST); 1433 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST);
1576 } 1434 }
1577 1435
1578 STATIC int 1436 STATIC int
1579 xfs_allocbt_get_maxrecs( 1437 xfs_allocbt_get_maxrecs(
1580 struct xfs_btree_cur *cur, 1438 struct xfs_btree_cur *cur,
1581 int level) 1439 int level)
1582 { 1440 {
1583 return cur->bc_mp->m_alloc_mxr[level != 0]; 1441 return cur->bc_mp->m_alloc_mxr[level != 0];
1584 } 1442 }
1585 1443
1586 STATIC void 1444 STATIC void
1587 xfs_allocbt_init_key_from_rec( 1445 xfs_allocbt_init_key_from_rec(
1588 union xfs_btree_key *key, 1446 union xfs_btree_key *key,
1589 union xfs_btree_rec *rec) 1447 union xfs_btree_rec *rec)
1590 { 1448 {
1591 ASSERT(rec->alloc.ar_startblock != 0); 1449 ASSERT(rec->alloc.ar_startblock != 0);
1592 1450
1593 key->alloc.ar_startblock = rec->alloc.ar_startblock; 1451 key->alloc.ar_startblock = rec->alloc.ar_startblock;
1594 key->alloc.ar_blockcount = rec->alloc.ar_blockcount; 1452 key->alloc.ar_blockcount = rec->alloc.ar_blockcount;
1595 } 1453 }
1596 1454
1597 STATIC void 1455 STATIC void
1598 xfs_allocbt_init_ptr_from_cur( 1456 xfs_allocbt_init_ptr_from_cur(
1599 struct xfs_btree_cur *cur, 1457 struct xfs_btree_cur *cur,
1600 union xfs_btree_ptr *ptr) 1458 union xfs_btree_ptr *ptr)
1601 { 1459 {
1602 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 1460 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
1603 1461
1604 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno)); 1462 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno));
1605 ASSERT(agf->agf_roots[cur->bc_btnum] != 0); 1463 ASSERT(agf->agf_roots[cur->bc_btnum] != 0);
1606 1464
1607 ptr->s = agf->agf_roots[cur->bc_btnum]; 1465 ptr->s = agf->agf_roots[cur->bc_btnum];
1608 } 1466 }
1609 1467
1610 STATIC __int64_t 1468 STATIC __int64_t
1611 xfs_allocbt_key_diff( 1469 xfs_allocbt_key_diff(
1612 struct xfs_btree_cur *cur, 1470 struct xfs_btree_cur *cur,
1613 union xfs_btree_key *key) 1471 union xfs_btree_key *key)
1614 { 1472 {
1615 xfs_alloc_rec_incore_t *rec = &cur->bc_rec.a; 1473 xfs_alloc_rec_incore_t *rec = &cur->bc_rec.a;
1616 xfs_alloc_key_t *kp = &key->alloc; 1474 xfs_alloc_key_t *kp = &key->alloc;
1617 __int64_t diff; 1475 __int64_t diff;
1618 1476
1619 if (cur->bc_btnum == XFS_BTNUM_BNO) { 1477 if (cur->bc_btnum == XFS_BTNUM_BNO) {
1620 return (__int64_t)be32_to_cpu(kp->ar_startblock) - 1478 return (__int64_t)be32_to_cpu(kp->ar_startblock) -
1621 rec->ar_startblock; 1479 rec->ar_startblock;
1622 } 1480 }
1623 1481
1624 diff = (__int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount; 1482 diff = (__int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount;
1625 if (diff) 1483 if (diff)
1626 return diff; 1484 return diff;
1627 1485
1628 return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock; 1486 return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock;
1629 } 1487 }
1630 1488
1631 #ifdef XFS_BTREE_TRACE 1489 #ifdef XFS_BTREE_TRACE
1632 ktrace_t *xfs_allocbt_trace_buf; 1490 ktrace_t *xfs_allocbt_trace_buf;
1633 1491
1634 STATIC void 1492 STATIC void
1635 xfs_allocbt_trace_enter( 1493 xfs_allocbt_trace_enter(
1636 struct xfs_btree_cur *cur, 1494 struct xfs_btree_cur *cur,
1637 const char *func, 1495 const char *func,
1638 char *s, 1496 char *s,
1639 int type, 1497 int type,
1640 int line, 1498 int line,
1641 __psunsigned_t a0, 1499 __psunsigned_t a0,
1642 __psunsigned_t a1, 1500 __psunsigned_t a1,
1643 __psunsigned_t a2, 1501 __psunsigned_t a2,
1644 __psunsigned_t a3, 1502 __psunsigned_t a3,
1645 __psunsigned_t a4, 1503 __psunsigned_t a4,
1646 __psunsigned_t a5, 1504 __psunsigned_t a5,
1647 __psunsigned_t a6, 1505 __psunsigned_t a6,
1648 __psunsigned_t a7, 1506 __psunsigned_t a7,
1649 __psunsigned_t a8, 1507 __psunsigned_t a8,
1650 __psunsigned_t a9, 1508 __psunsigned_t a9,
1651 __psunsigned_t a10) 1509 __psunsigned_t a10)
1652 { 1510 {
1653 ktrace_enter(xfs_allocbt_trace_buf, (void *)(__psint_t)type, 1511 ktrace_enter(xfs_allocbt_trace_buf, (void *)(__psint_t)type,
1654 (void *)func, (void *)s, NULL, (void *)cur, 1512 (void *)func, (void *)s, NULL, (void *)cur,
1655 (void *)a0, (void *)a1, (void *)a2, (void *)a3, 1513 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
1656 (void *)a4, (void *)a5, (void *)a6, (void *)a7, 1514 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
1657 (void *)a8, (void *)a9, (void *)a10); 1515 (void *)a8, (void *)a9, (void *)a10);
1658 } 1516 }
1659 1517
1660 STATIC void 1518 STATIC void
1661 xfs_allocbt_trace_cursor( 1519 xfs_allocbt_trace_cursor(
1662 struct xfs_btree_cur *cur, 1520 struct xfs_btree_cur *cur,
1663 __uint32_t *s0, 1521 __uint32_t *s0,
1664 __uint64_t *l0, 1522 __uint64_t *l0,
1665 __uint64_t *l1) 1523 __uint64_t *l1)
1666 { 1524 {
1667 *s0 = cur->bc_private.a.agno; 1525 *s0 = cur->bc_private.a.agno;
1668 *l0 = cur->bc_rec.a.ar_startblock; 1526 *l0 = cur->bc_rec.a.ar_startblock;
1669 *l1 = cur->bc_rec.a.ar_blockcount; 1527 *l1 = cur->bc_rec.a.ar_blockcount;
1670 } 1528 }
1671 1529
1672 STATIC void 1530 STATIC void
1673 xfs_allocbt_trace_key( 1531 xfs_allocbt_trace_key(
1674 struct xfs_btree_cur *cur, 1532 struct xfs_btree_cur *cur,
1675 union xfs_btree_key *key, 1533 union xfs_btree_key *key,
1676 __uint64_t *l0, 1534 __uint64_t *l0,
1677 __uint64_t *l1) 1535 __uint64_t *l1)
1678 { 1536 {
1679 *l0 = be32_to_cpu(key->alloc.ar_startblock); 1537 *l0 = be32_to_cpu(key->alloc.ar_startblock);
1680 *l1 = be32_to_cpu(key->alloc.ar_blockcount); 1538 *l1 = be32_to_cpu(key->alloc.ar_blockcount);
1681 } 1539 }
1682 1540
1683 STATIC void 1541 STATIC void
1684 xfs_allocbt_trace_record( 1542 xfs_allocbt_trace_record(
1685 struct xfs_btree_cur *cur, 1543 struct xfs_btree_cur *cur,
1686 union xfs_btree_rec *rec, 1544 union xfs_btree_rec *rec,
1687 __uint64_t *l0, 1545 __uint64_t *l0,
1688 __uint64_t *l1, 1546 __uint64_t *l1,
1689 __uint64_t *l2) 1547 __uint64_t *l2)
1690 { 1548 {
1691 *l0 = be32_to_cpu(rec->alloc.ar_startblock); 1549 *l0 = be32_to_cpu(rec->alloc.ar_startblock);
1692 *l1 = be32_to_cpu(rec->alloc.ar_blockcount); 1550 *l1 = be32_to_cpu(rec->alloc.ar_blockcount);
1693 *l2 = 0; 1551 *l2 = 0;
1694 } 1552 }
1695 #endif /* XFS_BTREE_TRACE */ 1553 #endif /* XFS_BTREE_TRACE */
1696 1554
1697 static const struct xfs_btree_ops xfs_allocbt_ops = { 1555 static const struct xfs_btree_ops xfs_allocbt_ops = {
1698 .rec_len = sizeof(xfs_alloc_rec_t), 1556 .rec_len = sizeof(xfs_alloc_rec_t),
1699 .key_len = sizeof(xfs_alloc_key_t), 1557 .key_len = sizeof(xfs_alloc_key_t),
1700 1558
1701 .dup_cursor = xfs_allocbt_dup_cursor, 1559 .dup_cursor = xfs_allocbt_dup_cursor,
1702 .update_lastrec = xfs_allocbt_update_lastrec, 1560 .update_lastrec = xfs_allocbt_update_lastrec,
1703 .get_maxrecs = xfs_allocbt_get_maxrecs, 1561 .get_maxrecs = xfs_allocbt_get_maxrecs,
1704 .init_key_from_rec = xfs_allocbt_init_key_from_rec, 1562 .init_key_from_rec = xfs_allocbt_init_key_from_rec,
1705 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, 1563 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
1706 .key_diff = xfs_allocbt_key_diff, 1564 .key_diff = xfs_allocbt_key_diff,
1707 1565
1708 #ifdef XFS_BTREE_TRACE 1566 #ifdef XFS_BTREE_TRACE
1709 .trace_enter = xfs_allocbt_trace_enter, 1567 .trace_enter = xfs_allocbt_trace_enter,
1710 .trace_cursor = xfs_allocbt_trace_cursor, 1568 .trace_cursor = xfs_allocbt_trace_cursor,
1711 .trace_key = xfs_allocbt_trace_key, 1569 .trace_key = xfs_allocbt_trace_key,
1712 .trace_record = xfs_allocbt_trace_record, 1570 .trace_record = xfs_allocbt_trace_record,
1713 #endif 1571 #endif
1714 }; 1572 };
1715 1573
1716 /* 1574 /*
1717 * Allocate a new allocation btree cursor. 1575 * Allocate a new allocation btree cursor.
1718 */ 1576 */
1719 struct xfs_btree_cur * /* new alloc btree cursor */ 1577 struct xfs_btree_cur * /* new alloc btree cursor */
1720 xfs_allocbt_init_cursor( 1578 xfs_allocbt_init_cursor(
1721 struct xfs_mount *mp, /* file system mount point */ 1579 struct xfs_mount *mp, /* file system mount point */
1722 struct xfs_trans *tp, /* transaction pointer */ 1580 struct xfs_trans *tp, /* transaction pointer */
1723 struct xfs_buf *agbp, /* buffer for agf structure */ 1581 struct xfs_buf *agbp, /* buffer for agf structure */
1724 xfs_agnumber_t agno, /* allocation group number */ 1582 xfs_agnumber_t agno, /* allocation group number */
1725 xfs_btnum_t btnum) /* btree identifier */ 1583 xfs_btnum_t btnum) /* btree identifier */
1726 { 1584 {
1727 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); 1585 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
1728 struct xfs_btree_cur *cur; 1586 struct xfs_btree_cur *cur;
1729 1587
1730 ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT); 1588 ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
1731 1589
1732 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); 1590 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
1733 1591
1734 cur->bc_tp = tp; 1592 cur->bc_tp = tp;
1735 cur->bc_mp = mp; 1593 cur->bc_mp = mp;
1736 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]); 1594 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]);
1737 cur->bc_btnum = btnum; 1595 cur->bc_btnum = btnum;
1738 cur->bc_blocklog = mp->m_sb.sb_blocklog; 1596 cur->bc_blocklog = mp->m_sb.sb_blocklog;
1739 1597
1740 cur->bc_ops = &xfs_allocbt_ops; 1598 cur->bc_ops = &xfs_allocbt_ops;
1741 if (btnum == XFS_BTNUM_CNT) 1599 if (btnum == XFS_BTNUM_CNT)
1742 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE; 1600 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE;
1743 1601
1744 cur->bc_private.a.agbp = agbp; 1602 cur->bc_private.a.agbp = agbp;
1745 cur->bc_private.a.agno = agno; 1603 cur->bc_private.a.agno = agno;
1746 1604
1747 return cur; 1605 return cur;
1748 } 1606 }
1749 1607
fs/xfs/xfs_bmap_btree.c
1 /* 1 /*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_inum.h" 23 #include "xfs_inum.h"
24 #include "xfs_trans.h" 24 #include "xfs_trans.h"
25 #include "xfs_sb.h" 25 #include "xfs_sb.h"
26 #include "xfs_ag.h" 26 #include "xfs_ag.h"
27 #include "xfs_dir2.h" 27 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h" 28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h" 29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h" 31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h" 32 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h" 33 #include "xfs_dir2_sf.h"
34 #include "xfs_attr_sf.h" 34 #include "xfs_attr_sf.h"
35 #include "xfs_dinode.h" 35 #include "xfs_dinode.h"
36 #include "xfs_inode.h" 36 #include "xfs_inode.h"
37 #include "xfs_inode_item.h" 37 #include "xfs_inode_item.h"
38 #include "xfs_alloc.h" 38 #include "xfs_alloc.h"
39 #include "xfs_btree.h" 39 #include "xfs_btree.h"
40 #include "xfs_btree_trace.h" 40 #include "xfs_btree_trace.h"
41 #include "xfs_ialloc.h" 41 #include "xfs_ialloc.h"
42 #include "xfs_itable.h" 42 #include "xfs_itable.h"
43 #include "xfs_bmap.h" 43 #include "xfs_bmap.h"
44 #include "xfs_error.h" 44 #include "xfs_error.h"
45 #include "xfs_quota.h" 45 #include "xfs_quota.h"
46 46
47 /* 47 /*
48 * Prototypes for internal btree functions. 48 * Prototypes for internal btree functions.
49 */ 49 */
50 50
51 51
52 STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *); 52 STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *);
53 STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); 53 STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
54 STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); 54 STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
55 STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
56 STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *, 55 STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
57 __uint64_t *, xfs_btree_cur_t **, int *); 56 __uint64_t *, xfs_btree_cur_t **, int *);
58 57
59 #undef EXIT 58 #undef EXIT
60 59
61 #define ENTRY XBT_ENTRY 60 #define ENTRY XBT_ENTRY
62 #define ERROR XBT_ERROR 61 #define ERROR XBT_ERROR
63 #define EXIT XBT_EXIT 62 #define EXIT XBT_EXIT
64 63
65 /* 64 /*
66 * Keep the XFS_BMBT_TRACE_ names around for now until all code using them 65 * Keep the XFS_BMBT_TRACE_ names around for now until all code using them
67 * is converted to be generic and thus switches to the XFS_BTREE_TRACE_ names. 66 * is converted to be generic and thus switches to the XFS_BTREE_TRACE_ names.
68 */ 67 */
69 #define XFS_BMBT_TRACE_ARGBI(c,b,i) \ 68 #define XFS_BMBT_TRACE_ARGBI(c,b,i) \
70 XFS_BTREE_TRACE_ARGBI(c,b,i) 69 XFS_BTREE_TRACE_ARGBI(c,b,i)
71 #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) \ 70 #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) \
72 XFS_BTREE_TRACE_ARGBII(c,b,i,j) 71 XFS_BTREE_TRACE_ARGBII(c,b,i,j)
73 #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) \ 72 #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) \
74 XFS_BTREE_TRACE_ARGFFFI(c,o,b,i,j) 73 XFS_BTREE_TRACE_ARGFFFI(c,o,b,i,j)
75 #define XFS_BMBT_TRACE_ARGI(c,i) \ 74 #define XFS_BMBT_TRACE_ARGI(c,i) \
76 XFS_BTREE_TRACE_ARGI(c,i) 75 XFS_BTREE_TRACE_ARGI(c,i)
77 #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \ 76 #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \
78 XFS_BTREE_TRACE_ARGIPK(c,i,(union xfs_btree_ptr)f,s) 77 XFS_BTREE_TRACE_ARGIPK(c,i,(union xfs_btree_ptr)f,s)
79 #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \ 78 #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \
80 XFS_BTREE_TRACE_ARGIPR(c,i, \ 79 XFS_BTREE_TRACE_ARGIPR(c,i, \
81 (union xfs_btree_ptr)f, (union xfs_btree_rec *)r) 80 (union xfs_btree_ptr)f, (union xfs_btree_rec *)r)
82 #define XFS_BMBT_TRACE_ARGIK(c,i,k) \ 81 #define XFS_BMBT_TRACE_ARGIK(c,i,k) \
83 XFS_BTREE_TRACE_ARGIK(c,i,(union xfs_btree_key *)k) 82 XFS_BTREE_TRACE_ARGIK(c,i,(union xfs_btree_key *)k)
84 #define XFS_BMBT_TRACE_CURSOR(c,s) \ 83 #define XFS_BMBT_TRACE_CURSOR(c,s) \
85 XFS_BTREE_TRACE_CURSOR(c,s) 84 XFS_BTREE_TRACE_CURSOR(c,s)
86 85
87 86
88 /* 87 /*
89 * Internal functions. 88 * Internal functions.
90 */ 89 */
91 90
92 /* 91 /*
93 * Delete record pointed to by cur/level. 92 * Delete record pointed to by cur/level.
94 */ 93 */
95 STATIC int /* error */ 94 STATIC int /* error */
96 xfs_bmbt_delrec( 95 xfs_bmbt_delrec(
97 xfs_btree_cur_t *cur, 96 xfs_btree_cur_t *cur,
98 int level, 97 int level,
99 int *stat) /* success/failure */ 98 int *stat) /* success/failure */
100 { 99 {
101 xfs_bmbt_block_t *block; /* bmap btree block */ 100 xfs_bmbt_block_t *block; /* bmap btree block */
102 xfs_fsblock_t bno; /* fs-relative block number */ 101 xfs_fsblock_t bno; /* fs-relative block number */
103 xfs_buf_t *bp; /* buffer for block */ 102 xfs_buf_t *bp; /* buffer for block */
104 int error; /* error return value */ 103 int error; /* error return value */
105 int i; /* loop counter */ 104 int i; /* loop counter */
106 int j; /* temp state */ 105 int j; /* temp state */
107 xfs_bmbt_key_t key; /* bmap btree key */ 106 xfs_bmbt_key_t key; /* bmap btree key */
108 xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */ 107 xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */
109 xfs_fsblock_t lbno; /* left sibling block number */ 108 xfs_fsblock_t lbno; /* left sibling block number */
110 xfs_buf_t *lbp; /* left buffer pointer */ 109 xfs_buf_t *lbp; /* left buffer pointer */
111 xfs_bmbt_block_t *left; /* left btree block */ 110 xfs_bmbt_block_t *left; /* left btree block */
112 xfs_bmbt_key_t *lkp; /* left btree key */ 111 xfs_bmbt_key_t *lkp; /* left btree key */
113 xfs_bmbt_ptr_t *lpp; /* left address pointer */ 112 xfs_bmbt_ptr_t *lpp; /* left address pointer */
114 int lrecs=0; /* left record count */ 113 int lrecs=0; /* left record count */
115 xfs_bmbt_rec_t *lrp; /* left record pointer */ 114 xfs_bmbt_rec_t *lrp; /* left record pointer */
116 xfs_mount_t *mp; /* file system mount point */ 115 xfs_mount_t *mp; /* file system mount point */
117 xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ 116 xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
118 int ptr; /* key/record index */ 117 int ptr; /* key/record index */
119 xfs_fsblock_t rbno; /* right sibling block number */ 118 xfs_fsblock_t rbno; /* right sibling block number */
120 xfs_buf_t *rbp; /* right buffer pointer */ 119 xfs_buf_t *rbp; /* right buffer pointer */
121 xfs_bmbt_block_t *right; /* right btree block */ 120 xfs_bmbt_block_t *right; /* right btree block */
122 xfs_bmbt_key_t *rkp; /* right btree key */ 121 xfs_bmbt_key_t *rkp; /* right btree key */
123 xfs_bmbt_rec_t *rp; /* pointer to bmap btree rec */ 122 xfs_bmbt_rec_t *rp; /* pointer to bmap btree rec */
124 xfs_bmbt_ptr_t *rpp; /* right address pointer */ 123 xfs_bmbt_ptr_t *rpp; /* right address pointer */
125 xfs_bmbt_block_t *rrblock; /* right-right btree block */ 124 xfs_bmbt_block_t *rrblock; /* right-right btree block */
126 xfs_buf_t *rrbp; /* right-right buffer pointer */ 125 xfs_buf_t *rrbp; /* right-right buffer pointer */
127 int rrecs=0; /* right record count */ 126 int rrecs=0; /* right record count */
128 xfs_bmbt_rec_t *rrp; /* right record pointer */ 127 xfs_bmbt_rec_t *rrp; /* right record pointer */
129 xfs_btree_cur_t *tcur; /* temporary btree cursor */ 128 xfs_btree_cur_t *tcur; /* temporary btree cursor */
130 int numrecs; /* temporary numrec count */ 129 int numrecs; /* temporary numrec count */
131 int numlrecs, numrrecs; 130 int numlrecs, numrrecs;
132 131
133 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 132 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
134 XFS_BMBT_TRACE_ARGI(cur, level); 133 XFS_BMBT_TRACE_ARGI(cur, level);
135 ptr = cur->bc_ptrs[level]; 134 ptr = cur->bc_ptrs[level];
136 tcur = NULL; 135 tcur = NULL;
137 if (ptr == 0) { 136 if (ptr == 0) {
138 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 137 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
139 *stat = 0; 138 *stat = 0;
140 return 0; 139 return 0;
141 } 140 }
142 block = xfs_bmbt_get_block(cur, level, &bp); 141 block = xfs_bmbt_get_block(cur, level, &bp);
143 numrecs = be16_to_cpu(block->bb_numrecs); 142 numrecs = be16_to_cpu(block->bb_numrecs);
144 #ifdef DEBUG 143 #ifdef DEBUG
145 if ((error = xfs_btree_check_lblock(cur, block, level, bp))) { 144 if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
146 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 145 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
147 goto error0; 146 goto error0;
148 } 147 }
149 #endif 148 #endif
150 if (ptr > numrecs) { 149 if (ptr > numrecs) {
151 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 150 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
152 *stat = 0; 151 *stat = 0;
153 return 0; 152 return 0;
154 } 153 }
155 XFS_STATS_INC(xs_bmbt_delrec); 154 XFS_STATS_INC(xs_bmbt_delrec);
156 if (level > 0) { 155 if (level > 0) {
157 kp = XFS_BMAP_KEY_IADDR(block, 1, cur); 156 kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
158 pp = XFS_BMAP_PTR_IADDR(block, 1, cur); 157 pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
159 #ifdef DEBUG 158 #ifdef DEBUG
160 for (i = ptr; i < numrecs; i++) { 159 for (i = ptr; i < numrecs; i++) {
161 if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { 160 if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
162 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 161 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
163 goto error0; 162 goto error0;
164 } 163 }
165 } 164 }
166 #endif 165 #endif
167 if (ptr < numrecs) { 166 if (ptr < numrecs) {
168 memmove(&kp[ptr - 1], &kp[ptr], 167 memmove(&kp[ptr - 1], &kp[ptr],
169 (numrecs - ptr) * sizeof(*kp)); 168 (numrecs - ptr) * sizeof(*kp));
170 memmove(&pp[ptr - 1], &pp[ptr], 169 memmove(&pp[ptr - 1], &pp[ptr],
171 (numrecs - ptr) * sizeof(*pp)); 170 (numrecs - ptr) * sizeof(*pp));
172 xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1); 171 xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1);
173 xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1); 172 xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1);
174 } 173 }
175 } else { 174 } else {
176 rp = XFS_BMAP_REC_IADDR(block, 1, cur); 175 rp = XFS_BMAP_REC_IADDR(block, 1, cur);
177 if (ptr < numrecs) { 176 if (ptr < numrecs) {
178 memmove(&rp[ptr - 1], &rp[ptr], 177 memmove(&rp[ptr - 1], &rp[ptr],
179 (numrecs - ptr) * sizeof(*rp)); 178 (numrecs - ptr) * sizeof(*rp));
180 xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1); 179 xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
181 } 180 }
182 if (ptr == 1) { 181 if (ptr == 1) {
183 key.br_startoff = 182 key.br_startoff =
184 cpu_to_be64(xfs_bmbt_disk_get_startoff(rp)); 183 cpu_to_be64(xfs_bmbt_disk_get_startoff(rp));
185 kp = &key; 184 kp = &key;
186 } 185 }
187 } 186 }
188 numrecs--; 187 numrecs--;
189 block->bb_numrecs = cpu_to_be16(numrecs); 188 block->bb_numrecs = cpu_to_be16(numrecs);
190 xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS); 189 xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
191 /* 190 /*
192 * We're at the root level. 191 * We're at the root level.
193 * First, shrink the root block in-memory. 192 * First, shrink the root block in-memory.
194 * Try to get rid of the next level down. 193 * Try to get rid of the next level down.
195 * If we can't then there's nothing left to do. 194 * If we can't then there's nothing left to do.
196 */ 195 */
197 if (level == cur->bc_nlevels - 1) { 196 if (level == cur->bc_nlevels - 1) {
198 xfs_iroot_realloc(cur->bc_private.b.ip, -1, 197 xfs_iroot_realloc(cur->bc_private.b.ip, -1,
199 cur->bc_private.b.whichfork); 198 cur->bc_private.b.whichfork);
200 if ((error = xfs_bmbt_killroot(cur))) { 199 if ((error = xfs_bmbt_killroot(cur))) {
201 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 200 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
202 goto error0; 201 goto error0;
203 } 202 }
204 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) { 203 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
205 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 204 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
206 goto error0; 205 goto error0;
207 } 206 }
208 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 207 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
209 *stat = 1; 208 *stat = 1;
210 return 0; 209 return 0;
211 } 210 }
212 if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1))) { 211 if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1))) {
213 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 212 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
214 goto error0; 213 goto error0;
215 } 214 }
216 if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) { 215 if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
217 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) { 216 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
218 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 217 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
219 goto error0; 218 goto error0;
220 } 219 }
221 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 220 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
222 *stat = 1; 221 *stat = 1;
223 return 0; 222 return 0;
224 } 223 }
225 rbno = be64_to_cpu(block->bb_rightsib); 224 rbno = be64_to_cpu(block->bb_rightsib);
226 lbno = be64_to_cpu(block->bb_leftsib); 225 lbno = be64_to_cpu(block->bb_leftsib);
227 /* 226 /*
228 * One child of root, need to get a chance to copy its contents 227 * One child of root, need to get a chance to copy its contents
229 * into the root and delete it. Can't go up to next level, 228 * into the root and delete it. Can't go up to next level,
230 * there's nothing to delete there. 229 * there's nothing to delete there.
231 */ 230 */
232 if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK && 231 if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK &&
233 level == cur->bc_nlevels - 2) { 232 level == cur->bc_nlevels - 2) {
234 if ((error = xfs_bmbt_killroot(cur))) { 233 if ((error = xfs_bmbt_killroot(cur))) {
235 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 234 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
236 goto error0; 235 goto error0;
237 } 236 }
238 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) { 237 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
239 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 238 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
240 goto error0; 239 goto error0;
241 } 240 }
242 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 241 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
243 *stat = 1; 242 *stat = 1;
244 return 0; 243 return 0;
245 } 244 }
246 ASSERT(rbno != NULLFSBLOCK || lbno != NULLFSBLOCK); 245 ASSERT(rbno != NULLFSBLOCK || lbno != NULLFSBLOCK);
247 if ((error = xfs_btree_dup_cursor(cur, &tcur))) { 246 if ((error = xfs_btree_dup_cursor(cur, &tcur))) {
248 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 247 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
249 goto error0; 248 goto error0;
250 } 249 }
251 bno = NULLFSBLOCK; 250 bno = NULLFSBLOCK;
252 if (rbno != NULLFSBLOCK) { 251 if (rbno != NULLFSBLOCK) {
253 i = xfs_btree_lastrec(tcur, level); 252 i = xfs_btree_lastrec(tcur, level);
254 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 253 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
255 if ((error = xfs_btree_increment(tcur, level, &i))) { 254 if ((error = xfs_btree_increment(tcur, level, &i))) {
256 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 255 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
257 goto error0; 256 goto error0;
258 } 257 }
259 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 258 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
260 i = xfs_btree_lastrec(tcur, level); 259 i = xfs_btree_lastrec(tcur, level);
261 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 260 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
262 rbp = tcur->bc_bufs[level]; 261 rbp = tcur->bc_bufs[level];
263 right = XFS_BUF_TO_BMBT_BLOCK(rbp); 262 right = XFS_BUF_TO_BMBT_BLOCK(rbp);
264 #ifdef DEBUG 263 #ifdef DEBUG
265 if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) { 264 if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
266 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 265 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
267 goto error0; 266 goto error0;
268 } 267 }
269 #endif 268 #endif
270 bno = be64_to_cpu(right->bb_leftsib); 269 bno = be64_to_cpu(right->bb_leftsib);
271 if (be16_to_cpu(right->bb_numrecs) - 1 >= 270 if (be16_to_cpu(right->bb_numrecs) - 1 >=
272 XFS_BMAP_BLOCK_IMINRECS(level, cur)) { 271 XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
273 if ((error = xfs_bmbt_lshift(tcur, level, &i))) { 272 if ((error = xfs_btree_lshift(tcur, level, &i))) {
274 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 273 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
275 goto error0; 274 goto error0;
276 } 275 }
277 if (i) { 276 if (i) {
278 ASSERT(be16_to_cpu(block->bb_numrecs) >= 277 ASSERT(be16_to_cpu(block->bb_numrecs) >=
279 XFS_BMAP_BLOCK_IMINRECS(level, tcur)); 278 XFS_BMAP_BLOCK_IMINRECS(level, tcur));
280 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); 279 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
281 tcur = NULL; 280 tcur = NULL;
282 if (level > 0) { 281 if (level > 0) {
283 if ((error = xfs_btree_decrement(cur, 282 if ((error = xfs_btree_decrement(cur,
284 level, &i))) { 283 level, &i))) {
285 XFS_BMBT_TRACE_CURSOR(cur, 284 XFS_BMBT_TRACE_CURSOR(cur,
286 ERROR); 285 ERROR);
287 goto error0; 286 goto error0;
288 } 287 }
289 } 288 }
290 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 289 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
291 *stat = 1; 290 *stat = 1;
292 return 0; 291 return 0;
293 } 292 }
294 } 293 }
295 rrecs = be16_to_cpu(right->bb_numrecs); 294 rrecs = be16_to_cpu(right->bb_numrecs);
296 if (lbno != NULLFSBLOCK) { 295 if (lbno != NULLFSBLOCK) {
297 i = xfs_btree_firstrec(tcur, level); 296 i = xfs_btree_firstrec(tcur, level);
298 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 297 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
299 if ((error = xfs_btree_decrement(tcur, level, &i))) { 298 if ((error = xfs_btree_decrement(tcur, level, &i))) {
300 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 299 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
301 goto error0; 300 goto error0;
302 } 301 }
303 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 302 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
304 } 303 }
305 } 304 }
306 if (lbno != NULLFSBLOCK) { 305 if (lbno != NULLFSBLOCK) {
307 i = xfs_btree_firstrec(tcur, level); 306 i = xfs_btree_firstrec(tcur, level);
308 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 307 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
309 /* 308 /*
310 * decrement to last in block 309 * decrement to last in block
311 */ 310 */
312 if ((error = xfs_btree_decrement(tcur, level, &i))) { 311 if ((error = xfs_btree_decrement(tcur, level, &i))) {
313 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 312 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
314 goto error0; 313 goto error0;
315 } 314 }
316 i = xfs_btree_firstrec(tcur, level); 315 i = xfs_btree_firstrec(tcur, level);
317 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 316 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
318 lbp = tcur->bc_bufs[level]; 317 lbp = tcur->bc_bufs[level];
319 left = XFS_BUF_TO_BMBT_BLOCK(lbp); 318 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
320 #ifdef DEBUG 319 #ifdef DEBUG
321 if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) { 320 if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
322 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 321 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
323 goto error0; 322 goto error0;
324 } 323 }
325 #endif 324 #endif
326 bno = be64_to_cpu(left->bb_rightsib); 325 bno = be64_to_cpu(left->bb_rightsib);
327 if (be16_to_cpu(left->bb_numrecs) - 1 >= 326 if (be16_to_cpu(left->bb_numrecs) - 1 >=
328 XFS_BMAP_BLOCK_IMINRECS(level, cur)) { 327 XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
329 if ((error = xfs_btree_rshift(tcur, level, &i))) { 328 if ((error = xfs_btree_rshift(tcur, level, &i))) {
330 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 329 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
331 goto error0; 330 goto error0;
332 } 331 }
333 if (i) { 332 if (i) {
334 ASSERT(be16_to_cpu(block->bb_numrecs) >= 333 ASSERT(be16_to_cpu(block->bb_numrecs) >=
335 XFS_BMAP_BLOCK_IMINRECS(level, tcur)); 334 XFS_BMAP_BLOCK_IMINRECS(level, tcur));
336 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); 335 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
337 tcur = NULL; 336 tcur = NULL;
338 if (level == 0) 337 if (level == 0)
339 cur->bc_ptrs[0]++; 338 cur->bc_ptrs[0]++;
340 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 339 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
341 *stat = 1; 340 *stat = 1;
342 return 0; 341 return 0;
343 } 342 }
344 } 343 }
345 lrecs = be16_to_cpu(left->bb_numrecs); 344 lrecs = be16_to_cpu(left->bb_numrecs);
346 } 345 }
347 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); 346 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
348 tcur = NULL; 347 tcur = NULL;
349 mp = cur->bc_mp; 348 mp = cur->bc_mp;
350 ASSERT(bno != NULLFSBLOCK); 349 ASSERT(bno != NULLFSBLOCK);
351 if (lbno != NULLFSBLOCK && 350 if (lbno != NULLFSBLOCK &&
352 lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) { 351 lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
353 rbno = bno; 352 rbno = bno;
354 right = block; 353 right = block;
355 rbp = bp; 354 rbp = bp;
356 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, lbno, 0, &lbp, 355 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, lbno, 0, &lbp,
357 XFS_BMAP_BTREE_REF))) { 356 XFS_BMAP_BTREE_REF))) {
358 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 357 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
359 goto error0; 358 goto error0;
360 } 359 }
361 left = XFS_BUF_TO_BMBT_BLOCK(lbp); 360 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
362 if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) { 361 if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
363 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 362 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
364 goto error0; 363 goto error0;
365 } 364 }
366 } else if (rbno != NULLFSBLOCK && 365 } else if (rbno != NULLFSBLOCK &&
367 rrecs + be16_to_cpu(block->bb_numrecs) <= 366 rrecs + be16_to_cpu(block->bb_numrecs) <=
368 XFS_BMAP_BLOCK_IMAXRECS(level, cur)) { 367 XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
369 lbno = bno; 368 lbno = bno;
370 left = block; 369 left = block;
371 lbp = bp; 370 lbp = bp;
372 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, rbno, 0, &rbp, 371 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, rbno, 0, &rbp,
373 XFS_BMAP_BTREE_REF))) { 372 XFS_BMAP_BTREE_REF))) {
374 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 373 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
375 goto error0; 374 goto error0;
376 } 375 }
377 right = XFS_BUF_TO_BMBT_BLOCK(rbp); 376 right = XFS_BUF_TO_BMBT_BLOCK(rbp);
378 if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) { 377 if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
379 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 378 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
380 goto error0; 379 goto error0;
381 } 380 }
382 lrecs = be16_to_cpu(left->bb_numrecs); 381 lrecs = be16_to_cpu(left->bb_numrecs);
383 } else { 382 } else {
384 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) { 383 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
385 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 384 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
386 goto error0; 385 goto error0;
387 } 386 }
388 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 387 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
389 *stat = 1; 388 *stat = 1;
390 return 0; 389 return 0;
391 } 390 }
392 numlrecs = be16_to_cpu(left->bb_numrecs); 391 numlrecs = be16_to_cpu(left->bb_numrecs);
393 numrrecs = be16_to_cpu(right->bb_numrecs); 392 numrrecs = be16_to_cpu(right->bb_numrecs);
394 if (level > 0) { 393 if (level > 0) {
395 lkp = XFS_BMAP_KEY_IADDR(left, numlrecs + 1, cur); 394 lkp = XFS_BMAP_KEY_IADDR(left, numlrecs + 1, cur);
396 lpp = XFS_BMAP_PTR_IADDR(left, numlrecs + 1, cur); 395 lpp = XFS_BMAP_PTR_IADDR(left, numlrecs + 1, cur);
397 rkp = XFS_BMAP_KEY_IADDR(right, 1, cur); 396 rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
398 rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); 397 rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
399 #ifdef DEBUG 398 #ifdef DEBUG
400 for (i = 0; i < numrrecs; i++) { 399 for (i = 0; i < numrrecs; i++) {
401 if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) { 400 if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
402 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 401 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
403 goto error0; 402 goto error0;
404 } 403 }
405 } 404 }
406 #endif 405 #endif
407 memcpy(lkp, rkp, numrrecs * sizeof(*lkp)); 406 memcpy(lkp, rkp, numrrecs * sizeof(*lkp));
408 memcpy(lpp, rpp, numrrecs * sizeof(*lpp)); 407 memcpy(lpp, rpp, numrrecs * sizeof(*lpp));
409 xfs_bmbt_log_keys(cur, lbp, numlrecs + 1, numlrecs + numrrecs); 408 xfs_bmbt_log_keys(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
410 xfs_bmbt_log_ptrs(cur, lbp, numlrecs + 1, numlrecs + numrrecs); 409 xfs_bmbt_log_ptrs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
411 } else { 410 } else {
412 lrp = XFS_BMAP_REC_IADDR(left, numlrecs + 1, cur); 411 lrp = XFS_BMAP_REC_IADDR(left, numlrecs + 1, cur);
413 rrp = XFS_BMAP_REC_IADDR(right, 1, cur); 412 rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
414 memcpy(lrp, rrp, numrrecs * sizeof(*lrp)); 413 memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
415 xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs); 414 xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
416 } 415 }
417 be16_add_cpu(&left->bb_numrecs, numrrecs); 416 be16_add_cpu(&left->bb_numrecs, numrrecs);
418 left->bb_rightsib = right->bb_rightsib; 417 left->bb_rightsib = right->bb_rightsib;
419 xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS); 418 xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
420 if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) { 419 if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
421 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, 420 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp,
422 be64_to_cpu(left->bb_rightsib), 421 be64_to_cpu(left->bb_rightsib),
423 0, &rrbp, XFS_BMAP_BTREE_REF))) { 422 0, &rrbp, XFS_BMAP_BTREE_REF))) {
424 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 423 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
425 goto error0; 424 goto error0;
426 } 425 }
427 rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp); 426 rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
428 if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) { 427 if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
429 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 428 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
430 goto error0; 429 goto error0;
431 } 430 }
432 rrblock->bb_leftsib = cpu_to_be64(lbno); 431 rrblock->bb_leftsib = cpu_to_be64(lbno);
433 xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB); 432 xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
434 } 433 }
435 xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1, 434 xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1,
436 cur->bc_private.b.flist, mp); 435 cur->bc_private.b.flist, mp);
437 cur->bc_private.b.ip->i_d.di_nblocks--; 436 cur->bc_private.b.ip->i_d.di_nblocks--;
438 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE); 437 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
439 XFS_TRANS_MOD_DQUOT_BYINO(mp, cur->bc_tp, cur->bc_private.b.ip, 438 XFS_TRANS_MOD_DQUOT_BYINO(mp, cur->bc_tp, cur->bc_private.b.ip,
440 XFS_TRANS_DQ_BCOUNT, -1L); 439 XFS_TRANS_DQ_BCOUNT, -1L);
441 xfs_trans_binval(cur->bc_tp, rbp); 440 xfs_trans_binval(cur->bc_tp, rbp);
442 if (bp != lbp) { 441 if (bp != lbp) {
443 cur->bc_bufs[level] = lbp; 442 cur->bc_bufs[level] = lbp;
444 cur->bc_ptrs[level] += lrecs; 443 cur->bc_ptrs[level] += lrecs;
445 cur->bc_ra[level] = 0; 444 cur->bc_ra[level] = 0;
446 } else if ((error = xfs_btree_increment(cur, level + 1, &i))) { 445 } else if ((error = xfs_btree_increment(cur, level + 1, &i))) {
447 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 446 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
448 goto error0; 447 goto error0;
449 } 448 }
450 if (level > 0) 449 if (level > 0)
451 cur->bc_ptrs[level]--; 450 cur->bc_ptrs[level]--;
452 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 451 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
453 *stat = 2; 452 *stat = 2;
454 return 0; 453 return 0;
455 454
456 error0: 455 error0:
457 if (tcur) 456 if (tcur)
458 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); 457 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
459 return error; 458 return error;
460 } 459 }
461 460
462 /* 461 /*
463 * Insert one record/level. Return information to the caller 462 * Insert one record/level. Return information to the caller
464 * allowing the next level up to proceed if necessary. 463 * allowing the next level up to proceed if necessary.
465 */ 464 */
466 STATIC int /* error */ 465 STATIC int /* error */
467 xfs_bmbt_insrec( 466 xfs_bmbt_insrec(
468 xfs_btree_cur_t *cur, 467 xfs_btree_cur_t *cur,
469 int level, 468 int level,
470 xfs_fsblock_t *bnop, 469 xfs_fsblock_t *bnop,
471 xfs_bmbt_rec_t *recp, 470 xfs_bmbt_rec_t *recp,
472 xfs_btree_cur_t **curp, 471 xfs_btree_cur_t **curp,
473 int *stat) /* no-go/done/continue */ 472 int *stat) /* no-go/done/continue */
474 { 473 {
475 xfs_bmbt_block_t *block; /* bmap btree block */ 474 xfs_bmbt_block_t *block; /* bmap btree block */
476 xfs_buf_t *bp; /* buffer for block */ 475 xfs_buf_t *bp; /* buffer for block */
477 int error; /* error return value */ 476 int error; /* error return value */
478 int i; /* loop index */ 477 int i; /* loop index */
479 xfs_bmbt_key_t key; /* bmap btree key */ 478 xfs_bmbt_key_t key; /* bmap btree key */
480 xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */ 479 xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */
481 int logflags; /* inode logging flags */ 480 int logflags; /* inode logging flags */
482 xfs_fsblock_t nbno; /* new block number */ 481 xfs_fsblock_t nbno; /* new block number */
483 struct xfs_btree_cur *ncur; /* new btree cursor */ 482 struct xfs_btree_cur *ncur; /* new btree cursor */
484 __uint64_t startoff; /* new btree key value */ 483 __uint64_t startoff; /* new btree key value */
485 xfs_bmbt_rec_t nrec; /* new record count */ 484 xfs_bmbt_rec_t nrec; /* new record count */
486 int optr; /* old key/record index */ 485 int optr; /* old key/record index */
487 xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ 486 xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
488 int ptr; /* key/record index */ 487 int ptr; /* key/record index */
489 xfs_bmbt_rec_t *rp=NULL; /* pointer to bmap btree rec */ 488 xfs_bmbt_rec_t *rp=NULL; /* pointer to bmap btree rec */
490 int numrecs; 489 int numrecs;
491 490
492 ASSERT(level < cur->bc_nlevels); 491 ASSERT(level < cur->bc_nlevels);
493 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 492 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
494 XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp); 493 XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp);
495 ncur = NULL; 494 ncur = NULL;
496 key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp)); 495 key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp));
497 optr = ptr = cur->bc_ptrs[level]; 496 optr = ptr = cur->bc_ptrs[level];
498 if (ptr == 0) { 497 if (ptr == 0) {
499 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 498 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
500 *stat = 0; 499 *stat = 0;
501 return 0; 500 return 0;
502 } 501 }
503 XFS_STATS_INC(xs_bmbt_insrec); 502 XFS_STATS_INC(xs_bmbt_insrec);
504 block = xfs_bmbt_get_block(cur, level, &bp); 503 block = xfs_bmbt_get_block(cur, level, &bp);
505 numrecs = be16_to_cpu(block->bb_numrecs); 504 numrecs = be16_to_cpu(block->bb_numrecs);
506 #ifdef DEBUG 505 #ifdef DEBUG
507 if ((error = xfs_btree_check_lblock(cur, block, level, bp))) { 506 if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
508 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 507 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
509 return error; 508 return error;
510 } 509 }
511 if (ptr <= numrecs) { 510 if (ptr <= numrecs) {
512 if (level == 0) { 511 if (level == 0) {
513 rp = XFS_BMAP_REC_IADDR(block, ptr, cur); 512 rp = XFS_BMAP_REC_IADDR(block, ptr, cur);
514 xfs_btree_check_rec(XFS_BTNUM_BMAP, recp, rp); 513 xfs_btree_check_rec(XFS_BTNUM_BMAP, recp, rp);
515 } else { 514 } else {
516 kp = XFS_BMAP_KEY_IADDR(block, ptr, cur); 515 kp = XFS_BMAP_KEY_IADDR(block, ptr, cur);
517 xfs_btree_check_key(XFS_BTNUM_BMAP, &key, kp); 516 xfs_btree_check_key(XFS_BTNUM_BMAP, &key, kp);
518 } 517 }
519 } 518 }
520 #endif 519 #endif
521 nbno = NULLFSBLOCK; 520 nbno = NULLFSBLOCK;
522 if (numrecs == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) { 521 if (numrecs == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
523 if (numrecs < XFS_BMAP_BLOCK_DMAXRECS(level, cur)) { 522 if (numrecs < XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
524 /* 523 /*
525 * A root block, that can be made bigger. 524 * A root block, that can be made bigger.
526 */ 525 */
527 xfs_iroot_realloc(cur->bc_private.b.ip, 1, 526 xfs_iroot_realloc(cur->bc_private.b.ip, 1,
528 cur->bc_private.b.whichfork); 527 cur->bc_private.b.whichfork);
529 block = xfs_bmbt_get_block(cur, level, &bp); 528 block = xfs_bmbt_get_block(cur, level, &bp);
530 } else if (level == cur->bc_nlevels - 1) { 529 } else if (level == cur->bc_nlevels - 1) {
531 if ((error = xfs_bmbt_newroot(cur, &logflags, stat)) || 530 if ((error = xfs_bmbt_newroot(cur, &logflags, stat)) ||
532 *stat == 0) { 531 *stat == 0) {
533 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 532 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
534 return error; 533 return error;
535 } 534 }
536 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, 535 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
537 logflags); 536 logflags);
538 block = xfs_bmbt_get_block(cur, level, &bp); 537 block = xfs_bmbt_get_block(cur, level, &bp);
539 } else { 538 } else {
540 if ((error = xfs_btree_rshift(cur, level, &i))) { 539 if ((error = xfs_btree_rshift(cur, level, &i))) {
541 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 540 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
542 return error; 541 return error;
543 } 542 }
544 if (i) { 543 if (i) {
545 /* nothing */ 544 /* nothing */
546 } else { 545 } else {
547 if ((error = xfs_bmbt_lshift(cur, level, &i))) { 546 if ((error = xfs_btree_lshift(cur, level, &i))) {
548 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 547 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
549 return error; 548 return error;
550 } 549 }
551 if (i) { 550 if (i) {
552 optr = ptr = cur->bc_ptrs[level]; 551 optr = ptr = cur->bc_ptrs[level];
553 } else { 552 } else {
554 if ((error = xfs_bmbt_split(cur, level, 553 if ((error = xfs_bmbt_split(cur, level,
555 &nbno, &startoff, &ncur, 554 &nbno, &startoff, &ncur,
556 &i))) { 555 &i))) {
557 XFS_BMBT_TRACE_CURSOR(cur, 556 XFS_BMBT_TRACE_CURSOR(cur,
558 ERROR); 557 ERROR);
559 return error; 558 return error;
560 } 559 }
561 if (i) { 560 if (i) {
562 block = xfs_bmbt_get_block( 561 block = xfs_bmbt_get_block(
563 cur, level, &bp); 562 cur, level, &bp);
564 #ifdef DEBUG 563 #ifdef DEBUG
565 if ((error = 564 if ((error =
566 xfs_btree_check_lblock(cur, 565 xfs_btree_check_lblock(cur,
567 block, level, bp))) { 566 block, level, bp))) {
568 XFS_BMBT_TRACE_CURSOR( 567 XFS_BMBT_TRACE_CURSOR(
569 cur, ERROR); 568 cur, ERROR);
570 return error; 569 return error;
571 } 570 }
572 #endif 571 #endif
573 ptr = cur->bc_ptrs[level]; 572 ptr = cur->bc_ptrs[level];
574 xfs_bmbt_disk_set_allf(&nrec, 573 xfs_bmbt_disk_set_allf(&nrec,
575 startoff, 0, 0, 574 startoff, 0, 0,
576 XFS_EXT_NORM); 575 XFS_EXT_NORM);
577 } else { 576 } else {
578 XFS_BMBT_TRACE_CURSOR(cur, 577 XFS_BMBT_TRACE_CURSOR(cur,
579 EXIT); 578 EXIT);
580 *stat = 0; 579 *stat = 0;
581 return 0; 580 return 0;
582 } 581 }
583 } 582 }
584 } 583 }
585 } 584 }
586 } 585 }
587 numrecs = be16_to_cpu(block->bb_numrecs); 586 numrecs = be16_to_cpu(block->bb_numrecs);
588 if (level > 0) { 587 if (level > 0) {
589 kp = XFS_BMAP_KEY_IADDR(block, 1, cur); 588 kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
590 pp = XFS_BMAP_PTR_IADDR(block, 1, cur); 589 pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
591 #ifdef DEBUG 590 #ifdef DEBUG
592 for (i = numrecs; i >= ptr; i--) { 591 for (i = numrecs; i >= ptr; i--) {
593 if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1], 592 if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1],
594 level))) { 593 level))) {
595 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 594 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
596 return error; 595 return error;
597 } 596 }
598 } 597 }
599 #endif 598 #endif
600 memmove(&kp[ptr], &kp[ptr - 1], 599 memmove(&kp[ptr], &kp[ptr - 1],
601 (numrecs - ptr + 1) * sizeof(*kp)); 600 (numrecs - ptr + 1) * sizeof(*kp));
602 memmove(&pp[ptr], &pp[ptr - 1], 601 memmove(&pp[ptr], &pp[ptr - 1],
603 (numrecs - ptr + 1) * sizeof(*pp)); 602 (numrecs - ptr + 1) * sizeof(*pp));
604 #ifdef DEBUG 603 #ifdef DEBUG
605 if ((error = xfs_btree_check_lptr(cur, *bnop, level))) { 604 if ((error = xfs_btree_check_lptr(cur, *bnop, level))) {
606 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 605 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
607 return error; 606 return error;
608 } 607 }
609 #endif 608 #endif
610 kp[ptr - 1] = key; 609 kp[ptr - 1] = key;
611 pp[ptr - 1] = cpu_to_be64(*bnop); 610 pp[ptr - 1] = cpu_to_be64(*bnop);
612 numrecs++; 611 numrecs++;
613 block->bb_numrecs = cpu_to_be16(numrecs); 612 block->bb_numrecs = cpu_to_be16(numrecs);
614 xfs_bmbt_log_keys(cur, bp, ptr, numrecs); 613 xfs_bmbt_log_keys(cur, bp, ptr, numrecs);
615 xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs); 614 xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs);
616 } else { 615 } else {
617 rp = XFS_BMAP_REC_IADDR(block, 1, cur); 616 rp = XFS_BMAP_REC_IADDR(block, 1, cur);
618 memmove(&rp[ptr], &rp[ptr - 1], 617 memmove(&rp[ptr], &rp[ptr - 1],
619 (numrecs - ptr + 1) * sizeof(*rp)); 618 (numrecs - ptr + 1) * sizeof(*rp));
620 rp[ptr - 1] = *recp; 619 rp[ptr - 1] = *recp;
621 numrecs++; 620 numrecs++;
622 block->bb_numrecs = cpu_to_be16(numrecs); 621 block->bb_numrecs = cpu_to_be16(numrecs);
623 xfs_bmbt_log_recs(cur, bp, ptr, numrecs); 622 xfs_bmbt_log_recs(cur, bp, ptr, numrecs);
624 } 623 }
625 xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS); 624 xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
626 #ifdef DEBUG 625 #ifdef DEBUG
627 if (ptr < numrecs) { 626 if (ptr < numrecs) {
628 if (level == 0) 627 if (level == 0)
629 xfs_btree_check_rec(XFS_BTNUM_BMAP, rp + ptr - 1, 628 xfs_btree_check_rec(XFS_BTNUM_BMAP, rp + ptr - 1,
630 rp + ptr); 629 rp + ptr);
631 else 630 else
632 xfs_btree_check_key(XFS_BTNUM_BMAP, kp + ptr - 1, 631 xfs_btree_check_key(XFS_BTNUM_BMAP, kp + ptr - 1,
633 kp + ptr); 632 kp + ptr);
634 } 633 }
635 #endif 634 #endif
636 if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1))) { 635 if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1))) {
637 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 636 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
638 return error; 637 return error;
639 } 638 }
640 *bnop = nbno; 639 *bnop = nbno;
641 if (nbno != NULLFSBLOCK) { 640 if (nbno != NULLFSBLOCK) {
642 *recp = nrec; 641 *recp = nrec;
643 *curp = ncur; 642 *curp = ncur;
644 } 643 }
645 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 644 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
646 *stat = 1; 645 *stat = 1;
647 return 0; 646 return 0;
648 } 647 }
649 648
650 STATIC int 649 STATIC int
651 xfs_bmbt_killroot( 650 xfs_bmbt_killroot(
652 xfs_btree_cur_t *cur) 651 xfs_btree_cur_t *cur)
653 { 652 {
654 xfs_bmbt_block_t *block; 653 xfs_bmbt_block_t *block;
655 xfs_bmbt_block_t *cblock; 654 xfs_bmbt_block_t *cblock;
656 xfs_buf_t *cbp; 655 xfs_buf_t *cbp;
657 xfs_bmbt_key_t *ckp; 656 xfs_bmbt_key_t *ckp;
658 xfs_bmbt_ptr_t *cpp; 657 xfs_bmbt_ptr_t *cpp;
659 #ifdef DEBUG 658 #ifdef DEBUG
660 int error; 659 int error;
661 #endif 660 #endif
662 int i; 661 int i;
663 xfs_bmbt_key_t *kp; 662 xfs_bmbt_key_t *kp;
664 xfs_inode_t *ip; 663 xfs_inode_t *ip;
665 xfs_ifork_t *ifp; 664 xfs_ifork_t *ifp;
666 int level; 665 int level;
667 xfs_bmbt_ptr_t *pp; 666 xfs_bmbt_ptr_t *pp;
668 667
669 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 668 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
670 level = cur->bc_nlevels - 1; 669 level = cur->bc_nlevels - 1;
671 ASSERT(level >= 1); 670 ASSERT(level >= 1);
672 /* 671 /*
673 * Don't deal with the root block needs to be a leaf case. 672 * Don't deal with the root block needs to be a leaf case.
674 * We're just going to turn the thing back into extents anyway. 673 * We're just going to turn the thing back into extents anyway.
675 */ 674 */
676 if (level == 1) { 675 if (level == 1) {
677 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 676 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
678 return 0; 677 return 0;
679 } 678 }
680 block = xfs_bmbt_get_block(cur, level, &cbp); 679 block = xfs_bmbt_get_block(cur, level, &cbp);
681 /* 680 /*
682 * Give up if the root has multiple children. 681 * Give up if the root has multiple children.
683 */ 682 */
684 if (be16_to_cpu(block->bb_numrecs) != 1) { 683 if (be16_to_cpu(block->bb_numrecs) != 1) {
685 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 684 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
686 return 0; 685 return 0;
687 } 686 }
688 /* 687 /*
689 * Only do this if the next level will fit. 688 * Only do this if the next level will fit.
690 * Then the data must be copied up to the inode, 689 * Then the data must be copied up to the inode,
691 * instead of freeing the root you free the next level. 690 * instead of freeing the root you free the next level.
692 */ 691 */
693 cbp = cur->bc_bufs[level - 1]; 692 cbp = cur->bc_bufs[level - 1];
694 cblock = XFS_BUF_TO_BMBT_BLOCK(cbp); 693 cblock = XFS_BUF_TO_BMBT_BLOCK(cbp);
695 if (be16_to_cpu(cblock->bb_numrecs) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) { 694 if (be16_to_cpu(cblock->bb_numrecs) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) {
696 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 695 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
697 return 0; 696 return 0;
698 } 697 }
699 ASSERT(be64_to_cpu(cblock->bb_leftsib) == NULLDFSBNO); 698 ASSERT(be64_to_cpu(cblock->bb_leftsib) == NULLDFSBNO);
700 ASSERT(be64_to_cpu(cblock->bb_rightsib) == NULLDFSBNO); 699 ASSERT(be64_to_cpu(cblock->bb_rightsib) == NULLDFSBNO);
701 ip = cur->bc_private.b.ip; 700 ip = cur->bc_private.b.ip;
702 ifp = XFS_IFORK_PTR(ip, cur->bc_private.b.whichfork); 701 ifp = XFS_IFORK_PTR(ip, cur->bc_private.b.whichfork);
703 ASSERT(XFS_BMAP_BLOCK_IMAXRECS(level, cur) == 702 ASSERT(XFS_BMAP_BLOCK_IMAXRECS(level, cur) ==
704 XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes)); 703 XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes));
705 i = (int)(be16_to_cpu(cblock->bb_numrecs) - XFS_BMAP_BLOCK_IMAXRECS(level, cur)); 704 i = (int)(be16_to_cpu(cblock->bb_numrecs) - XFS_BMAP_BLOCK_IMAXRECS(level, cur));
706 if (i) { 705 if (i) {
707 xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork); 706 xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork);
708 block = ifp->if_broot; 707 block = ifp->if_broot;
709 } 708 }
710 be16_add_cpu(&block->bb_numrecs, i); 709 be16_add_cpu(&block->bb_numrecs, i);
711 ASSERT(block->bb_numrecs == cblock->bb_numrecs); 710 ASSERT(block->bb_numrecs == cblock->bb_numrecs);
712 kp = XFS_BMAP_KEY_IADDR(block, 1, cur); 711 kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
713 ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); 712 ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
714 memcpy(kp, ckp, be16_to_cpu(block->bb_numrecs) * sizeof(*kp)); 713 memcpy(kp, ckp, be16_to_cpu(block->bb_numrecs) * sizeof(*kp));
715 pp = XFS_BMAP_PTR_IADDR(block, 1, cur); 714 pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
716 cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); 715 cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
717 #ifdef DEBUG 716 #ifdef DEBUG
718 for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { 717 for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
719 if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) { 718 if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) {
720 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 719 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
721 return error; 720 return error;
722 } 721 }
723 } 722 }
724 #endif 723 #endif
725 memcpy(pp, cpp, be16_to_cpu(block->bb_numrecs) * sizeof(*pp)); 724 memcpy(pp, cpp, be16_to_cpu(block->bb_numrecs) * sizeof(*pp));
726 xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1, 725 xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1,
727 cur->bc_private.b.flist, cur->bc_mp); 726 cur->bc_private.b.flist, cur->bc_mp);
728 ip->i_d.di_nblocks--; 727 ip->i_d.di_nblocks--;
729 XFS_TRANS_MOD_DQUOT_BYINO(cur->bc_mp, cur->bc_tp, ip, 728 XFS_TRANS_MOD_DQUOT_BYINO(cur->bc_mp, cur->bc_tp, ip,
730 XFS_TRANS_DQ_BCOUNT, -1L); 729 XFS_TRANS_DQ_BCOUNT, -1L);
731 xfs_trans_binval(cur->bc_tp, cbp); 730 xfs_trans_binval(cur->bc_tp, cbp);
732 cur->bc_bufs[level - 1] = NULL; 731 cur->bc_bufs[level - 1] = NULL;
733 be16_add_cpu(&block->bb_level, -1); 732 be16_add_cpu(&block->bb_level, -1);
734 xfs_trans_log_inode(cur->bc_tp, ip, 733 xfs_trans_log_inode(cur->bc_tp, ip,
735 XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); 734 XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
736 cur->bc_nlevels--; 735 cur->bc_nlevels--;
737 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 736 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
738 return 0; 737 return 0;
739 } 738 }
740 739
741 /* 740 /*
742 * Log key values from the btree block. 741 * Log key values from the btree block.
743 */ 742 */
744 STATIC void 743 STATIC void
745 xfs_bmbt_log_keys( 744 xfs_bmbt_log_keys(
746 xfs_btree_cur_t *cur, 745 xfs_btree_cur_t *cur,
747 xfs_buf_t *bp, 746 xfs_buf_t *bp,
748 int kfirst, 747 int kfirst,
749 int klast) 748 int klast)
750 { 749 {
751 xfs_trans_t *tp; 750 xfs_trans_t *tp;
752 751
753 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 752 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
754 XFS_BMBT_TRACE_ARGBII(cur, bp, kfirst, klast); 753 XFS_BMBT_TRACE_ARGBII(cur, bp, kfirst, klast);
755 tp = cur->bc_tp; 754 tp = cur->bc_tp;
756 if (bp) { 755 if (bp) {
757 xfs_bmbt_block_t *block; 756 xfs_bmbt_block_t *block;
758 int first; 757 int first;
759 xfs_bmbt_key_t *kp; 758 xfs_bmbt_key_t *kp;
760 int last; 759 int last;
761 760
762 block = XFS_BUF_TO_BMBT_BLOCK(bp); 761 block = XFS_BUF_TO_BMBT_BLOCK(bp);
763 kp = XFS_BMAP_KEY_DADDR(block, 1, cur); 762 kp = XFS_BMAP_KEY_DADDR(block, 1, cur);
764 first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block); 763 first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
765 last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block); 764 last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
766 xfs_trans_log_buf(tp, bp, first, last); 765 xfs_trans_log_buf(tp, bp, first, last);
767 } else { 766 } else {
768 xfs_inode_t *ip; 767 xfs_inode_t *ip;
769 768
770 ip = cur->bc_private.b.ip; 769 ip = cur->bc_private.b.ip;
771 xfs_trans_log_inode(tp, ip, 770 xfs_trans_log_inode(tp, ip,
772 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); 771 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
773 } 772 }
774 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 773 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
775 } 774 }
776 775
777 /* 776 /*
778 * Log pointer values from the btree block. 777 * Log pointer values from the btree block.
779 */ 778 */
780 STATIC void 779 STATIC void
781 xfs_bmbt_log_ptrs( 780 xfs_bmbt_log_ptrs(
782 xfs_btree_cur_t *cur, 781 xfs_btree_cur_t *cur,
783 xfs_buf_t *bp, 782 xfs_buf_t *bp,
784 int pfirst, 783 int pfirst,
785 int plast) 784 int plast)
786 { 785 {
787 xfs_trans_t *tp; 786 xfs_trans_t *tp;
788 787
789 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 788 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
790 XFS_BMBT_TRACE_ARGBII(cur, bp, pfirst, plast); 789 XFS_BMBT_TRACE_ARGBII(cur, bp, pfirst, plast);
791 tp = cur->bc_tp; 790 tp = cur->bc_tp;
792 if (bp) { 791 if (bp) {
793 xfs_bmbt_block_t *block; 792 xfs_bmbt_block_t *block;
794 int first; 793 int first;
795 int last; 794 int last;
796 xfs_bmbt_ptr_t *pp; 795 xfs_bmbt_ptr_t *pp;
797 796
798 block = XFS_BUF_TO_BMBT_BLOCK(bp); 797 block = XFS_BUF_TO_BMBT_BLOCK(bp);
799 pp = XFS_BMAP_PTR_DADDR(block, 1, cur); 798 pp = XFS_BMAP_PTR_DADDR(block, 1, cur);
800 first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block); 799 first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
801 last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block); 800 last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
802 xfs_trans_log_buf(tp, bp, first, last); 801 xfs_trans_log_buf(tp, bp, first, last);
803 } else { 802 } else {
804 xfs_inode_t *ip; 803 xfs_inode_t *ip;
805 804
806 ip = cur->bc_private.b.ip; 805 ip = cur->bc_private.b.ip;
807 xfs_trans_log_inode(tp, ip, 806 xfs_trans_log_inode(tp, ip,
808 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); 807 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
809 } 808 }
810 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 809 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
811 }
812
813 /*
814 * Move 1 record left from cur/level if possible.
815 * Update cur to reflect the new path.
816 */
817 STATIC int /* error */
818 xfs_bmbt_lshift(
819 xfs_btree_cur_t *cur,
820 int level,
821 int *stat) /* success/failure */
822 {
823 int error; /* error return value */
824 #ifdef DEBUG
825 int i; /* loop counter */
826 #endif
827 xfs_bmbt_key_t key; /* bmap btree key */
828 xfs_buf_t *lbp; /* left buffer pointer */
829 xfs_bmbt_block_t *left; /* left btree block */
830 xfs_bmbt_key_t *lkp=NULL; /* left btree key */
831 xfs_bmbt_ptr_t *lpp; /* left address pointer */
832 int lrecs; /* left record count */
833 xfs_bmbt_rec_t *lrp=NULL; /* left record pointer */
834 xfs_mount_t *mp; /* file system mount point */
835 xfs_buf_t *rbp; /* right buffer pointer */
836 xfs_bmbt_block_t *right; /* right btree block */
837 xfs_bmbt_key_t *rkp=NULL; /* right btree key */
838 xfs_bmbt_ptr_t *rpp=NULL; /* right address pointer */
839 xfs_bmbt_rec_t *rrp=NULL; /* right record pointer */
840 int rrecs; /* right record count */
841
842 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
843 XFS_BMBT_TRACE_ARGI(cur, level);
844 if (level == cur->bc_nlevels - 1) {
845 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
846 *stat = 0;
847 return 0;
848 }
849 rbp = cur->bc_bufs[level];
850 right = XFS_BUF_TO_BMBT_BLOCK(rbp);
851 #ifdef DEBUG
852 if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
853 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
854 return error;
855 }
856 #endif
857 if (be64_to_cpu(right->bb_leftsib) == NULLDFSBNO) {
858 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
859 *stat = 0;
860 return 0;
861 }
862 if (cur->bc_ptrs[level] <= 1) {
863 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
864 *stat = 0;
865 return 0;
866 }
867 mp = cur->bc_mp;
868 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, be64_to_cpu(right->bb_leftsib), 0,
869 &lbp, XFS_BMAP_BTREE_REF))) {
870 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
871 return error;
872 }
873 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
874 if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
875 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
876 return error;
877 }
878 if (be16_to_cpu(left->bb_numrecs) == XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
879 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
880 *stat = 0;
881 return 0;
882 }
883 lrecs = be16_to_cpu(left->bb_numrecs) + 1;
884 if (level > 0) {
885 lkp = XFS_BMAP_KEY_IADDR(left, lrecs, cur);
886 rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
887 *lkp = *rkp;
888 xfs_bmbt_log_keys(cur, lbp, lrecs, lrecs);
889 lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur);
890 rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
891 #ifdef DEBUG
892 if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) {
893 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
894 return error;
895 }
896 #endif
897 *lpp = *rpp;
898 xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs);
899 } else {
900 lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur);
901 rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
902 *lrp = *rrp;
903 xfs_bmbt_log_recs(cur, lbp, lrecs, lrecs);
904 }
905 left->bb_numrecs = cpu_to_be16(lrecs);
906 xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS);
907 #ifdef DEBUG
908 if (level > 0)
909 xfs_btree_check_key(XFS_BTNUM_BMAP, lkp - 1, lkp);
910 else
911 xfs_btree_check_rec(XFS_BTNUM_BMAP, lrp - 1, lrp);
912 #endif
913 rrecs = be16_to_cpu(right->bb_numrecs) - 1;
914 right->bb_numrecs = cpu_to_be16(rrecs);
915 xfs_bmbt_log_block(cur, rbp, XFS_BB_NUMRECS);
916 if (level > 0) {
917 #ifdef DEBUG
918 for (i = 0; i < rrecs; i++) {
919 if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1],
920 level))) {
921 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
922 return error;
923 }
924 }
925 #endif
926 memmove(rkp, rkp + 1, rrecs * sizeof(*rkp));
927 memmove(rpp, rpp + 1, rrecs * sizeof(*rpp));
928 xfs_bmbt_log_keys(cur, rbp, 1, rrecs);
929 xfs_bmbt_log_ptrs(cur, rbp, 1, rrecs);
930 } else {
931 memmove(rrp, rrp + 1, rrecs * sizeof(*rrp));
932 xfs_bmbt_log_recs(cur, rbp, 1, rrecs);
933 key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
934 rkp = &key;
935 }
936 if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1))) {
937 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
938 return error;
939 }
940 cur->bc_ptrs[level]--;
941 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
942 *stat = 1;
943 return 0;
944 } 810 }
945 811
946 /* 812 /*
947 * Determine the extent state. 813 * Determine the extent state.
948 */ 814 */
949 /* ARGSUSED */ 815 /* ARGSUSED */
950 STATIC xfs_exntst_t 816 STATIC xfs_exntst_t
951 xfs_extent_state( 817 xfs_extent_state(
952 xfs_filblks_t blks, 818 xfs_filblks_t blks,
953 int extent_flag) 819 int extent_flag)
954 { 820 {
955 if (extent_flag) { 821 if (extent_flag) {
956 ASSERT(blks != 0); /* saved for DMIG */ 822 ASSERT(blks != 0); /* saved for DMIG */
957 return XFS_EXT_UNWRITTEN; 823 return XFS_EXT_UNWRITTEN;
958 } 824 }
959 return XFS_EXT_NORM; 825 return XFS_EXT_NORM;
960 } 826 }
961 827
962 828
963 /* 829 /*
964 * Split cur/level block in half. 830 * Split cur/level block in half.
965 * Return new block number and its first record (to be inserted into parent). 831 * Return new block number and its first record (to be inserted into parent).
966 */ 832 */
967 STATIC int /* error */ 833 STATIC int /* error */
968 xfs_bmbt_split( 834 xfs_bmbt_split(
969 xfs_btree_cur_t *cur, 835 xfs_btree_cur_t *cur,
970 int level, 836 int level,
971 xfs_fsblock_t *bnop, 837 xfs_fsblock_t *bnop,
972 __uint64_t *startoff, 838 __uint64_t *startoff,
973 xfs_btree_cur_t **curp, 839 xfs_btree_cur_t **curp,
974 int *stat) /* success/failure */ 840 int *stat) /* success/failure */
975 { 841 {
976 xfs_alloc_arg_t args; /* block allocation args */ 842 xfs_alloc_arg_t args; /* block allocation args */
977 int error; /* error return value */ 843 int error; /* error return value */
978 int i; /* loop counter */ 844 int i; /* loop counter */
979 xfs_fsblock_t lbno; /* left sibling block number */ 845 xfs_fsblock_t lbno; /* left sibling block number */
980 xfs_buf_t *lbp; /* left buffer pointer */ 846 xfs_buf_t *lbp; /* left buffer pointer */
981 xfs_bmbt_block_t *left; /* left btree block */ 847 xfs_bmbt_block_t *left; /* left btree block */
982 xfs_bmbt_key_t *lkp; /* left btree key */ 848 xfs_bmbt_key_t *lkp; /* left btree key */
983 xfs_bmbt_ptr_t *lpp; /* left address pointer */ 849 xfs_bmbt_ptr_t *lpp; /* left address pointer */
984 xfs_bmbt_rec_t *lrp; /* left record pointer */ 850 xfs_bmbt_rec_t *lrp; /* left record pointer */
985 xfs_buf_t *rbp; /* right buffer pointer */ 851 xfs_buf_t *rbp; /* right buffer pointer */
986 xfs_bmbt_block_t *right; /* right btree block */ 852 xfs_bmbt_block_t *right; /* right btree block */
987 xfs_bmbt_key_t *rkp; /* right btree key */ 853 xfs_bmbt_key_t *rkp; /* right btree key */
988 xfs_bmbt_ptr_t *rpp; /* right address pointer */ 854 xfs_bmbt_ptr_t *rpp; /* right address pointer */
989 xfs_bmbt_block_t *rrblock; /* right-right btree block */ 855 xfs_bmbt_block_t *rrblock; /* right-right btree block */
990 xfs_buf_t *rrbp; /* right-right buffer pointer */ 856 xfs_buf_t *rrbp; /* right-right buffer pointer */
991 xfs_bmbt_rec_t *rrp; /* right record pointer */ 857 xfs_bmbt_rec_t *rrp; /* right record pointer */
992 858
993 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 859 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
994 // disable until merged into common code 860 // disable until merged into common code
995 // XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff); 861 // XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff);
996 args.tp = cur->bc_tp; 862 args.tp = cur->bc_tp;
997 args.mp = cur->bc_mp; 863 args.mp = cur->bc_mp;
998 lbp = cur->bc_bufs[level]; 864 lbp = cur->bc_bufs[level];
999 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp)); 865 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
1000 left = XFS_BUF_TO_BMBT_BLOCK(lbp); 866 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
1001 args.fsbno = cur->bc_private.b.firstblock; 867 args.fsbno = cur->bc_private.b.firstblock;
1002 args.firstblock = args.fsbno; 868 args.firstblock = args.fsbno;
1003 args.minleft = 0; 869 args.minleft = 0;
1004 if (args.fsbno == NULLFSBLOCK) { 870 if (args.fsbno == NULLFSBLOCK) {
1005 args.fsbno = lbno; 871 args.fsbno = lbno;
1006 args.type = XFS_ALLOCTYPE_START_BNO; 872 args.type = XFS_ALLOCTYPE_START_BNO;
1007 /* 873 /*
1008 * Make sure there is sufficient room left in the AG to 874 * Make sure there is sufficient room left in the AG to
1009 * complete a full tree split for an extent insert. If 875 * complete a full tree split for an extent insert. If
1010 * we are converting the middle part of an extent then 876 * we are converting the middle part of an extent then
1011 * we may need space for two tree splits. 877 * we may need space for two tree splits.
1012 * 878 *
1013 * We are relying on the caller to make the correct block 879 * We are relying on the caller to make the correct block
1014 * reservation for this operation to succeed. If the 880 * reservation for this operation to succeed. If the
1015 * reservation amount is insufficient then we may fail a 881 * reservation amount is insufficient then we may fail a
1016 * block allocation here and corrupt the filesystem. 882 * block allocation here and corrupt the filesystem.
1017 */ 883 */
1018 args.minleft = xfs_trans_get_block_res(args.tp); 884 args.minleft = xfs_trans_get_block_res(args.tp);
1019 } else if (cur->bc_private.b.flist->xbf_low) 885 } else if (cur->bc_private.b.flist->xbf_low)
1020 args.type = XFS_ALLOCTYPE_START_BNO; 886 args.type = XFS_ALLOCTYPE_START_BNO;
1021 else 887 else
1022 args.type = XFS_ALLOCTYPE_NEAR_BNO; 888 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1023 args.mod = args.alignment = args.total = args.isfl = 889 args.mod = args.alignment = args.total = args.isfl =
1024 args.userdata = args.minalignslop = 0; 890 args.userdata = args.minalignslop = 0;
1025 args.minlen = args.maxlen = args.prod = 1; 891 args.minlen = args.maxlen = args.prod = 1;
1026 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 892 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
1027 if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) { 893 if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) {
1028 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 894 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1029 return XFS_ERROR(ENOSPC); 895 return XFS_ERROR(ENOSPC);
1030 } 896 }
1031 if ((error = xfs_alloc_vextent(&args))) { 897 if ((error = xfs_alloc_vextent(&args))) {
1032 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 898 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1033 return error; 899 return error;
1034 } 900 }
1035 if (args.fsbno == NULLFSBLOCK && args.minleft) { 901 if (args.fsbno == NULLFSBLOCK && args.minleft) {
1036 /* 902 /*
1037 * Could not find an AG with enough free space to satisfy 903 * Could not find an AG with enough free space to satisfy
1038 * a full btree split. Try again without minleft and if 904 * a full btree split. Try again without minleft and if
1039 * successful activate the lowspace algorithm. 905 * successful activate the lowspace algorithm.
1040 */ 906 */
1041 args.fsbno = 0; 907 args.fsbno = 0;
1042 args.type = XFS_ALLOCTYPE_FIRST_AG; 908 args.type = XFS_ALLOCTYPE_FIRST_AG;
1043 args.minleft = 0; 909 args.minleft = 0;
1044 if ((error = xfs_alloc_vextent(&args))) { 910 if ((error = xfs_alloc_vextent(&args))) {
1045 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 911 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1046 return error; 912 return error;
1047 } 913 }
1048 cur->bc_private.b.flist->xbf_low = 1; 914 cur->bc_private.b.flist->xbf_low = 1;
1049 } 915 }
1050 if (args.fsbno == NULLFSBLOCK) { 916 if (args.fsbno == NULLFSBLOCK) {
1051 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 917 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1052 *stat = 0; 918 *stat = 0;
1053 return 0; 919 return 0;
1054 } 920 }
1055 ASSERT(args.len == 1); 921 ASSERT(args.len == 1);
1056 cur->bc_private.b.firstblock = args.fsbno; 922 cur->bc_private.b.firstblock = args.fsbno;
1057 cur->bc_private.b.allocated++; 923 cur->bc_private.b.allocated++;
1058 cur->bc_private.b.ip->i_d.di_nblocks++; 924 cur->bc_private.b.ip->i_d.di_nblocks++;
1059 xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE); 925 xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
1060 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip, 926 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
1061 XFS_TRANS_DQ_BCOUNT, 1L); 927 XFS_TRANS_DQ_BCOUNT, 1L);
1062 rbp = xfs_btree_get_bufl(args.mp, args.tp, args.fsbno, 0); 928 rbp = xfs_btree_get_bufl(args.mp, args.tp, args.fsbno, 0);
1063 right = XFS_BUF_TO_BMBT_BLOCK(rbp); 929 right = XFS_BUF_TO_BMBT_BLOCK(rbp);
1064 #ifdef DEBUG 930 #ifdef DEBUG
1065 if ((error = xfs_btree_check_lblock(cur, left, level, rbp))) { 931 if ((error = xfs_btree_check_lblock(cur, left, level, rbp))) {
1066 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 932 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1067 return error; 933 return error;
1068 } 934 }
1069 #endif 935 #endif
1070 right->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); 936 right->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
1071 right->bb_level = left->bb_level; 937 right->bb_level = left->bb_level;
1072 right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2); 938 right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
1073 if ((be16_to_cpu(left->bb_numrecs) & 1) && 939 if ((be16_to_cpu(left->bb_numrecs) & 1) &&
1074 cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) 940 cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
1075 be16_add_cpu(&right->bb_numrecs, 1); 941 be16_add_cpu(&right->bb_numrecs, 1);
1076 i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; 942 i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
1077 if (level > 0) { 943 if (level > 0) {
1078 lkp = XFS_BMAP_KEY_IADDR(left, i, cur); 944 lkp = XFS_BMAP_KEY_IADDR(left, i, cur);
1079 lpp = XFS_BMAP_PTR_IADDR(left, i, cur); 945 lpp = XFS_BMAP_PTR_IADDR(left, i, cur);
1080 rkp = XFS_BMAP_KEY_IADDR(right, 1, cur); 946 rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
1081 rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); 947 rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
1082 #ifdef DEBUG 948 #ifdef DEBUG
1083 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { 949 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
1084 if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) { 950 if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) {
1085 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 951 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1086 return error; 952 return error;
1087 } 953 }
1088 } 954 }
1089 #endif 955 #endif
1090 memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); 956 memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
1091 memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); 957 memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
1092 xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 958 xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1093 xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 959 xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1094 *startoff = be64_to_cpu(rkp->br_startoff); 960 *startoff = be64_to_cpu(rkp->br_startoff);
1095 } else { 961 } else {
1096 lrp = XFS_BMAP_REC_IADDR(left, i, cur); 962 lrp = XFS_BMAP_REC_IADDR(left, i, cur);
1097 rrp = XFS_BMAP_REC_IADDR(right, 1, cur); 963 rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
1098 memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); 964 memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
1099 xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 965 xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1100 *startoff = xfs_bmbt_disk_get_startoff(rrp); 966 *startoff = xfs_bmbt_disk_get_startoff(rrp);
1101 } 967 }
1102 be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); 968 be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
1103 right->bb_rightsib = left->bb_rightsib; 969 right->bb_rightsib = left->bb_rightsib;
1104 left->bb_rightsib = cpu_to_be64(args.fsbno); 970 left->bb_rightsib = cpu_to_be64(args.fsbno);
1105 right->bb_leftsib = cpu_to_be64(lbno); 971 right->bb_leftsib = cpu_to_be64(lbno);
1106 xfs_bmbt_log_block(cur, rbp, XFS_BB_ALL_BITS); 972 xfs_bmbt_log_block(cur, rbp, XFS_BB_ALL_BITS);
1107 xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); 973 xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
1108 if (be64_to_cpu(right->bb_rightsib) != NULLDFSBNO) { 974 if (be64_to_cpu(right->bb_rightsib) != NULLDFSBNO) {
1109 if ((error = xfs_btree_read_bufl(args.mp, args.tp, 975 if ((error = xfs_btree_read_bufl(args.mp, args.tp,
1110 be64_to_cpu(right->bb_rightsib), 0, &rrbp, 976 be64_to_cpu(right->bb_rightsib), 0, &rrbp,
1111 XFS_BMAP_BTREE_REF))) { 977 XFS_BMAP_BTREE_REF))) {
1112 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 978 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1113 return error; 979 return error;
1114 } 980 }
1115 rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp); 981 rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
1116 if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) { 982 if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
1117 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 983 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1118 return error; 984 return error;
1119 } 985 }
1120 rrblock->bb_leftsib = cpu_to_be64(args.fsbno); 986 rrblock->bb_leftsib = cpu_to_be64(args.fsbno);
1121 xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB); 987 xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
1122 } 988 }
1123 if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) { 989 if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
1124 xfs_btree_setbuf(cur, level, rbp); 990 xfs_btree_setbuf(cur, level, rbp);
1125 cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs); 991 cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
1126 } 992 }
1127 if (level + 1 < cur->bc_nlevels) { 993 if (level + 1 < cur->bc_nlevels) {
1128 if ((error = xfs_btree_dup_cursor(cur, curp))) { 994 if ((error = xfs_btree_dup_cursor(cur, curp))) {
1129 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 995 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1130 return error; 996 return error;
1131 } 997 }
1132 (*curp)->bc_ptrs[level + 1]++; 998 (*curp)->bc_ptrs[level + 1]++;
1133 } 999 }
1134 *bnop = args.fsbno; 1000 *bnop = args.fsbno;
1135 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 1001 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1136 *stat = 1; 1002 *stat = 1;
1137 return 0; 1003 return 0;
1138 } 1004 }
1139 1005
1140 /* 1006 /*
1141 * Convert on-disk form of btree root to in-memory form. 1007 * Convert on-disk form of btree root to in-memory form.
1142 */ 1008 */
1143 void 1009 void
1144 xfs_bmdr_to_bmbt( 1010 xfs_bmdr_to_bmbt(
1145 xfs_bmdr_block_t *dblock, 1011 xfs_bmdr_block_t *dblock,
1146 int dblocklen, 1012 int dblocklen,
1147 xfs_bmbt_block_t *rblock, 1013 xfs_bmbt_block_t *rblock,
1148 int rblocklen) 1014 int rblocklen)
1149 { 1015 {
1150 int dmxr; 1016 int dmxr;
1151 xfs_bmbt_key_t *fkp; 1017 xfs_bmbt_key_t *fkp;
1152 __be64 *fpp; 1018 __be64 *fpp;
1153 xfs_bmbt_key_t *tkp; 1019 xfs_bmbt_key_t *tkp;
1154 __be64 *tpp; 1020 __be64 *tpp;
1155 1021
1156 rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); 1022 rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
1157 rblock->bb_level = dblock->bb_level; 1023 rblock->bb_level = dblock->bb_level;
1158 ASSERT(be16_to_cpu(rblock->bb_level) > 0); 1024 ASSERT(be16_to_cpu(rblock->bb_level) > 0);
1159 rblock->bb_numrecs = dblock->bb_numrecs; 1025 rblock->bb_numrecs = dblock->bb_numrecs;
1160 rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO); 1026 rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO);
1161 rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO); 1027 rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO);
1162 dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0); 1028 dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
1163 fkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); 1029 fkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1);
1164 tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); 1030 tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
1165 fpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); 1031 fpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr);
1166 tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); 1032 tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
1167 dmxr = be16_to_cpu(dblock->bb_numrecs); 1033 dmxr = be16_to_cpu(dblock->bb_numrecs);
1168 memcpy(tkp, fkp, sizeof(*fkp) * dmxr); 1034 memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
1169 memcpy(tpp, fpp, sizeof(*fpp) * dmxr); 1035 memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
1170 } 1036 }
1171 1037
1172 /* 1038 /*
1173 * Delete the record pointed to by cur. 1039 * Delete the record pointed to by cur.
1174 */ 1040 */
1175 int /* error */ 1041 int /* error */
1176 xfs_bmbt_delete( 1042 xfs_bmbt_delete(
1177 xfs_btree_cur_t *cur, 1043 xfs_btree_cur_t *cur,
1178 int *stat) /* success/failure */ 1044 int *stat) /* success/failure */
1179 { 1045 {
1180 int error; /* error return value */ 1046 int error; /* error return value */
1181 int i; 1047 int i;
1182 int level; 1048 int level;
1183 1049
1184 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 1050 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
1185 for (level = 0, i = 2; i == 2; level++) { 1051 for (level = 0, i = 2; i == 2; level++) {
1186 if ((error = xfs_bmbt_delrec(cur, level, &i))) { 1052 if ((error = xfs_bmbt_delrec(cur, level, &i))) {
1187 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1053 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1188 return error; 1054 return error;
1189 } 1055 }
1190 } 1056 }
1191 if (i == 0) { 1057 if (i == 0) {
1192 for (level = 1; level < cur->bc_nlevels; level++) { 1058 for (level = 1; level < cur->bc_nlevels; level++) {
1193 if (cur->bc_ptrs[level] == 0) { 1059 if (cur->bc_ptrs[level] == 0) {
1194 if ((error = xfs_btree_decrement(cur, level, 1060 if ((error = xfs_btree_decrement(cur, level,
1195 &i))) { 1061 &i))) {
1196 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1062 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1197 return error; 1063 return error;
1198 } 1064 }
1199 break; 1065 break;
1200 } 1066 }
1201 } 1067 }
1202 } 1068 }
1203 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 1069 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1204 *stat = i; 1070 *stat = i;
1205 return 0; 1071 return 0;
1206 } 1072 }
1207 1073
1208 /* 1074 /*
1209 * Convert a compressed bmap extent record to an uncompressed form. 1075 * Convert a compressed bmap extent record to an uncompressed form.
1210 * This code must be in sync with the routines xfs_bmbt_get_startoff, 1076 * This code must be in sync with the routines xfs_bmbt_get_startoff,
1211 * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. 1077 * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
1212 */ 1078 */
1213 1079
1214 STATIC_INLINE void 1080 STATIC_INLINE void
1215 __xfs_bmbt_get_all( 1081 __xfs_bmbt_get_all(
1216 __uint64_t l0, 1082 __uint64_t l0,
1217 __uint64_t l1, 1083 __uint64_t l1,
1218 xfs_bmbt_irec_t *s) 1084 xfs_bmbt_irec_t *s)
1219 { 1085 {
1220 int ext_flag; 1086 int ext_flag;
1221 xfs_exntst_t st; 1087 xfs_exntst_t st;
1222 1088
1223 ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN)); 1089 ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN));
1224 s->br_startoff = ((xfs_fileoff_t)l0 & 1090 s->br_startoff = ((xfs_fileoff_t)l0 &
1225 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 1091 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
1226 #if XFS_BIG_BLKNOS 1092 #if XFS_BIG_BLKNOS
1227 s->br_startblock = (((xfs_fsblock_t)l0 & XFS_MASK64LO(9)) << 43) | 1093 s->br_startblock = (((xfs_fsblock_t)l0 & XFS_MASK64LO(9)) << 43) |
1228 (((xfs_fsblock_t)l1) >> 21); 1094 (((xfs_fsblock_t)l1) >> 21);
1229 #else 1095 #else
1230 #ifdef DEBUG 1096 #ifdef DEBUG
1231 { 1097 {
1232 xfs_dfsbno_t b; 1098 xfs_dfsbno_t b;
1233 1099
1234 b = (((xfs_dfsbno_t)l0 & XFS_MASK64LO(9)) << 43) | 1100 b = (((xfs_dfsbno_t)l0 & XFS_MASK64LO(9)) << 43) |
1235 (((xfs_dfsbno_t)l1) >> 21); 1101 (((xfs_dfsbno_t)l1) >> 21);
1236 ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); 1102 ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b));
1237 s->br_startblock = (xfs_fsblock_t)b; 1103 s->br_startblock = (xfs_fsblock_t)b;
1238 } 1104 }
1239 #else /* !DEBUG */ 1105 #else /* !DEBUG */
1240 s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21); 1106 s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21);
1241 #endif /* DEBUG */ 1107 #endif /* DEBUG */
1242 #endif /* XFS_BIG_BLKNOS */ 1108 #endif /* XFS_BIG_BLKNOS */
1243 s->br_blockcount = (xfs_filblks_t)(l1 & XFS_MASK64LO(21)); 1109 s->br_blockcount = (xfs_filblks_t)(l1 & XFS_MASK64LO(21));
1244 /* This is xfs_extent_state() in-line */ 1110 /* This is xfs_extent_state() in-line */
1245 if (ext_flag) { 1111 if (ext_flag) {
1246 ASSERT(s->br_blockcount != 0); /* saved for DMIG */ 1112 ASSERT(s->br_blockcount != 0); /* saved for DMIG */
1247 st = XFS_EXT_UNWRITTEN; 1113 st = XFS_EXT_UNWRITTEN;
1248 } else 1114 } else
1249 st = XFS_EXT_NORM; 1115 st = XFS_EXT_NORM;
1250 s->br_state = st; 1116 s->br_state = st;
1251 } 1117 }
1252 1118
1253 void 1119 void
1254 xfs_bmbt_get_all( 1120 xfs_bmbt_get_all(
1255 xfs_bmbt_rec_host_t *r, 1121 xfs_bmbt_rec_host_t *r,
1256 xfs_bmbt_irec_t *s) 1122 xfs_bmbt_irec_t *s)
1257 { 1123 {
1258 __xfs_bmbt_get_all(r->l0, r->l1, s); 1124 __xfs_bmbt_get_all(r->l0, r->l1, s);
1259 } 1125 }
1260 1126
1261 /* 1127 /*
1262 * Get the block pointer for the given level of the cursor. 1128 * Get the block pointer for the given level of the cursor.
1263 * Fill in the buffer pointer, if applicable. 1129 * Fill in the buffer pointer, if applicable.
1264 */ 1130 */
1265 xfs_bmbt_block_t * 1131 xfs_bmbt_block_t *
1266 xfs_bmbt_get_block( 1132 xfs_bmbt_get_block(
1267 xfs_btree_cur_t *cur, 1133 xfs_btree_cur_t *cur,
1268 int level, 1134 int level,
1269 xfs_buf_t **bpp) 1135 xfs_buf_t **bpp)
1270 { 1136 {
1271 xfs_ifork_t *ifp; 1137 xfs_ifork_t *ifp;
1272 xfs_bmbt_block_t *rval; 1138 xfs_bmbt_block_t *rval;
1273 1139
1274 if (level < cur->bc_nlevels - 1) { 1140 if (level < cur->bc_nlevels - 1) {
1275 *bpp = cur->bc_bufs[level]; 1141 *bpp = cur->bc_bufs[level];
1276 rval = XFS_BUF_TO_BMBT_BLOCK(*bpp); 1142 rval = XFS_BUF_TO_BMBT_BLOCK(*bpp);
1277 } else { 1143 } else {
1278 *bpp = NULL; 1144 *bpp = NULL;
1279 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, 1145 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
1280 cur->bc_private.b.whichfork); 1146 cur->bc_private.b.whichfork);
1281 rval = ifp->if_broot; 1147 rval = ifp->if_broot;
1282 } 1148 }
1283 return rval; 1149 return rval;
1284 } 1150 }
1285 1151
1286 /* 1152 /*
1287 * Extract the blockcount field from an in memory bmap extent record. 1153 * Extract the blockcount field from an in memory bmap extent record.
1288 */ 1154 */
1289 xfs_filblks_t 1155 xfs_filblks_t
1290 xfs_bmbt_get_blockcount( 1156 xfs_bmbt_get_blockcount(
1291 xfs_bmbt_rec_host_t *r) 1157 xfs_bmbt_rec_host_t *r)
1292 { 1158 {
1293 return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21)); 1159 return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21));
1294 } 1160 }
1295 1161
1296 /* 1162 /*
1297 * Extract the startblock field from an in memory bmap extent record. 1163 * Extract the startblock field from an in memory bmap extent record.
1298 */ 1164 */
1299 xfs_fsblock_t 1165 xfs_fsblock_t
1300 xfs_bmbt_get_startblock( 1166 xfs_bmbt_get_startblock(
1301 xfs_bmbt_rec_host_t *r) 1167 xfs_bmbt_rec_host_t *r)
1302 { 1168 {
1303 #if XFS_BIG_BLKNOS 1169 #if XFS_BIG_BLKNOS
1304 return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) | 1170 return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) |
1305 (((xfs_fsblock_t)r->l1) >> 21); 1171 (((xfs_fsblock_t)r->l1) >> 21);
1306 #else 1172 #else
1307 #ifdef DEBUG 1173 #ifdef DEBUG
1308 xfs_dfsbno_t b; 1174 xfs_dfsbno_t b;
1309 1175
1310 b = (((xfs_dfsbno_t)r->l0 & XFS_MASK64LO(9)) << 43) | 1176 b = (((xfs_dfsbno_t)r->l0 & XFS_MASK64LO(9)) << 43) |
1311 (((xfs_dfsbno_t)r->l1) >> 21); 1177 (((xfs_dfsbno_t)r->l1) >> 21);
1312 ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); 1178 ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b));
1313 return (xfs_fsblock_t)b; 1179 return (xfs_fsblock_t)b;
1314 #else /* !DEBUG */ 1180 #else /* !DEBUG */
1315 return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21); 1181 return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21);
1316 #endif /* DEBUG */ 1182 #endif /* DEBUG */
1317 #endif /* XFS_BIG_BLKNOS */ 1183 #endif /* XFS_BIG_BLKNOS */
1318 } 1184 }
1319 1185
1320 /* 1186 /*
1321 * Extract the startoff field from an in memory bmap extent record. 1187 * Extract the startoff field from an in memory bmap extent record.
1322 */ 1188 */
1323 xfs_fileoff_t 1189 xfs_fileoff_t
1324 xfs_bmbt_get_startoff( 1190 xfs_bmbt_get_startoff(
1325 xfs_bmbt_rec_host_t *r) 1191 xfs_bmbt_rec_host_t *r)
1326 { 1192 {
1327 return ((xfs_fileoff_t)r->l0 & 1193 return ((xfs_fileoff_t)r->l0 &
1328 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 1194 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
1329 } 1195 }
1330 1196
1331 xfs_exntst_t 1197 xfs_exntst_t
1332 xfs_bmbt_get_state( 1198 xfs_bmbt_get_state(
1333 xfs_bmbt_rec_host_t *r) 1199 xfs_bmbt_rec_host_t *r)
1334 { 1200 {
1335 int ext_flag; 1201 int ext_flag;
1336 1202
1337 ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN)); 1203 ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN));
1338 return xfs_extent_state(xfs_bmbt_get_blockcount(r), 1204 return xfs_extent_state(xfs_bmbt_get_blockcount(r),
1339 ext_flag); 1205 ext_flag);
1340 } 1206 }
1341 1207
1342 /* Endian flipping versions of the bmbt extraction functions */ 1208 /* Endian flipping versions of the bmbt extraction functions */
1343 void 1209 void
1344 xfs_bmbt_disk_get_all( 1210 xfs_bmbt_disk_get_all(
1345 xfs_bmbt_rec_t *r, 1211 xfs_bmbt_rec_t *r,
1346 xfs_bmbt_irec_t *s) 1212 xfs_bmbt_irec_t *s)
1347 { 1213 {
1348 __xfs_bmbt_get_all(be64_to_cpu(r->l0), be64_to_cpu(r->l1), s); 1214 __xfs_bmbt_get_all(be64_to_cpu(r->l0), be64_to_cpu(r->l1), s);
1349 } 1215 }
1350 1216
1351 /* 1217 /*
1352 * Extract the blockcount field from an on disk bmap extent record. 1218 * Extract the blockcount field from an on disk bmap extent record.
1353 */ 1219 */
1354 xfs_filblks_t 1220 xfs_filblks_t
1355 xfs_bmbt_disk_get_blockcount( 1221 xfs_bmbt_disk_get_blockcount(
1356 xfs_bmbt_rec_t *r) 1222 xfs_bmbt_rec_t *r)
1357 { 1223 {
1358 return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21)); 1224 return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21));
1359 } 1225 }
1360 1226
1361 /* 1227 /*
1362 * Extract the startoff field from a disk format bmap extent record. 1228 * Extract the startoff field from a disk format bmap extent record.
1363 */ 1229 */
1364 xfs_fileoff_t 1230 xfs_fileoff_t
1365 xfs_bmbt_disk_get_startoff( 1231 xfs_bmbt_disk_get_startoff(
1366 xfs_bmbt_rec_t *r) 1232 xfs_bmbt_rec_t *r)
1367 { 1233 {
1368 return ((xfs_fileoff_t)be64_to_cpu(r->l0) & 1234 return ((xfs_fileoff_t)be64_to_cpu(r->l0) &
1369 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 1235 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
1370 } 1236 }
1371 1237
1372 /* 1238 /*
1373 * Insert the current record at the point referenced by cur. 1239 * Insert the current record at the point referenced by cur.
1374 * 1240 *
1375 * A multi-level split of the tree on insert will invalidate the original 1241 * A multi-level split of the tree on insert will invalidate the original
1376 * cursor. All callers of this function should assume that the cursor is 1242 * cursor. All callers of this function should assume that the cursor is
1377 * no longer valid and revalidate it. 1243 * no longer valid and revalidate it.
1378 */ 1244 */
1379 int /* error */ 1245 int /* error */
1380 xfs_bmbt_insert( 1246 xfs_bmbt_insert(
1381 xfs_btree_cur_t *cur, 1247 xfs_btree_cur_t *cur,
1382 int *stat) /* success/failure */ 1248 int *stat) /* success/failure */
1383 { 1249 {
1384 int error; /* error return value */ 1250 int error; /* error return value */
1385 int i; 1251 int i;
1386 int level; 1252 int level;
1387 xfs_fsblock_t nbno; 1253 xfs_fsblock_t nbno;
1388 xfs_btree_cur_t *ncur; 1254 xfs_btree_cur_t *ncur;
1389 xfs_bmbt_rec_t nrec; 1255 xfs_bmbt_rec_t nrec;
1390 xfs_btree_cur_t *pcur; 1256 xfs_btree_cur_t *pcur;
1391 1257
1392 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 1258 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
1393 level = 0; 1259 level = 0;
1394 nbno = NULLFSBLOCK; 1260 nbno = NULLFSBLOCK;
1395 xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b); 1261 xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);
1396 ncur = NULL; 1262 ncur = NULL;
1397 pcur = cur; 1263 pcur = cur;
1398 do { 1264 do {
1399 if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur, 1265 if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur,
1400 &i))) { 1266 &i))) {
1401 if (pcur != cur) 1267 if (pcur != cur)
1402 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR); 1268 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
1403 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1269 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1404 return error; 1270 return error;
1405 } 1271 }
1406 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1272 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1407 if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) { 1273 if (pcur != cur && (ncur || nbno == NULLFSBLOCK)) {
1408 cur->bc_nlevels = pcur->bc_nlevels; 1274 cur->bc_nlevels = pcur->bc_nlevels;
1409 cur->bc_private.b.allocated += 1275 cur->bc_private.b.allocated +=
1410 pcur->bc_private.b.allocated; 1276 pcur->bc_private.b.allocated;
1411 pcur->bc_private.b.allocated = 0; 1277 pcur->bc_private.b.allocated = 0;
1412 ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) || 1278 ASSERT((cur->bc_private.b.firstblock != NULLFSBLOCK) ||
1413 XFS_IS_REALTIME_INODE(cur->bc_private.b.ip)); 1279 XFS_IS_REALTIME_INODE(cur->bc_private.b.ip));
1414 cur->bc_private.b.firstblock = 1280 cur->bc_private.b.firstblock =
1415 pcur->bc_private.b.firstblock; 1281 pcur->bc_private.b.firstblock;
1416 ASSERT(cur->bc_private.b.flist == 1282 ASSERT(cur->bc_private.b.flist ==
1417 pcur->bc_private.b.flist); 1283 pcur->bc_private.b.flist);
1418 xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR); 1284 xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
1419 } 1285 }
1420 if (ncur) { 1286 if (ncur) {
1421 pcur = ncur; 1287 pcur = ncur;
1422 ncur = NULL; 1288 ncur = NULL;
1423 } 1289 }
1424 } while (nbno != NULLFSBLOCK); 1290 } while (nbno != NULLFSBLOCK);
1425 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 1291 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1426 *stat = i; 1292 *stat = i;
1427 return 0; 1293 return 0;
1428 error0: 1294 error0:
1429 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1295 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1430 return error; 1296 return error;
1431 } 1297 }
1432 1298
1433 /* 1299 /*
1434 * Log fields from the btree block header. 1300 * Log fields from the btree block header.
1435 */ 1301 */
1436 void 1302 void
1437 xfs_bmbt_log_block( 1303 xfs_bmbt_log_block(
1438 xfs_btree_cur_t *cur, 1304 xfs_btree_cur_t *cur,
1439 xfs_buf_t *bp, 1305 xfs_buf_t *bp,
1440 int fields) 1306 int fields)
1441 { 1307 {
1442 int first; 1308 int first;
1443 int last; 1309 int last;
1444 xfs_trans_t *tp; 1310 xfs_trans_t *tp;
1445 static const short offsets[] = { 1311 static const short offsets[] = {
1446 offsetof(xfs_bmbt_block_t, bb_magic), 1312 offsetof(xfs_bmbt_block_t, bb_magic),
1447 offsetof(xfs_bmbt_block_t, bb_level), 1313 offsetof(xfs_bmbt_block_t, bb_level),
1448 offsetof(xfs_bmbt_block_t, bb_numrecs), 1314 offsetof(xfs_bmbt_block_t, bb_numrecs),
1449 offsetof(xfs_bmbt_block_t, bb_leftsib), 1315 offsetof(xfs_bmbt_block_t, bb_leftsib),
1450 offsetof(xfs_bmbt_block_t, bb_rightsib), 1316 offsetof(xfs_bmbt_block_t, bb_rightsib),
1451 sizeof(xfs_bmbt_block_t) 1317 sizeof(xfs_bmbt_block_t)
1452 }; 1318 };
1453 1319
1454 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 1320 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
1455 XFS_BMBT_TRACE_ARGBI(cur, bp, fields); 1321 XFS_BMBT_TRACE_ARGBI(cur, bp, fields);
1456 tp = cur->bc_tp; 1322 tp = cur->bc_tp;
1457 if (bp) { 1323 if (bp) {
1458 xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, 1324 xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first,
1459 &last); 1325 &last);
1460 xfs_trans_log_buf(tp, bp, first, last); 1326 xfs_trans_log_buf(tp, bp, first, last);
1461 } else 1327 } else
1462 xfs_trans_log_inode(tp, cur->bc_private.b.ip, 1328 xfs_trans_log_inode(tp, cur->bc_private.b.ip,
1463 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); 1329 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
1464 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 1330 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1465 } 1331 }
1466 1332
1467 /* 1333 /*
1468 * Log record values from the btree block. 1334 * Log record values from the btree block.
1469 */ 1335 */
1470 void 1336 void
1471 xfs_bmbt_log_recs( 1337 xfs_bmbt_log_recs(
1472 xfs_btree_cur_t *cur, 1338 xfs_btree_cur_t *cur,
1473 xfs_buf_t *bp, 1339 xfs_buf_t *bp,
1474 int rfirst, 1340 int rfirst,
1475 int rlast) 1341 int rlast)
1476 { 1342 {
1477 xfs_bmbt_block_t *block; 1343 xfs_bmbt_block_t *block;
1478 int first; 1344 int first;
1479 int last; 1345 int last;
1480 xfs_bmbt_rec_t *rp; 1346 xfs_bmbt_rec_t *rp;
1481 xfs_trans_t *tp; 1347 xfs_trans_t *tp;
1482 1348
1483 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 1349 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
1484 XFS_BMBT_TRACE_ARGBII(cur, bp, rfirst, rlast); 1350 XFS_BMBT_TRACE_ARGBII(cur, bp, rfirst, rlast);
1485 ASSERT(bp); 1351 ASSERT(bp);
1486 tp = cur->bc_tp; 1352 tp = cur->bc_tp;
1487 block = XFS_BUF_TO_BMBT_BLOCK(bp); 1353 block = XFS_BUF_TO_BMBT_BLOCK(bp);
1488 rp = XFS_BMAP_REC_DADDR(block, 1, cur); 1354 rp = XFS_BMAP_REC_DADDR(block, 1, cur);
1489 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block); 1355 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
1490 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block); 1356 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
1491 xfs_trans_log_buf(tp, bp, first, last); 1357 xfs_trans_log_buf(tp, bp, first, last);
1492 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 1358 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1493 } 1359 }
1494 1360
1495 /* 1361 /*
1496 * Give the bmap btree a new root block. Copy the old broot contents 1362 * Give the bmap btree a new root block. Copy the old broot contents
1497 * down into a real block and make the broot point to it. 1363 * down into a real block and make the broot point to it.
1498 */ 1364 */
1499 int /* error */ 1365 int /* error */
1500 xfs_bmbt_newroot( 1366 xfs_bmbt_newroot(
1501 xfs_btree_cur_t *cur, /* btree cursor */ 1367 xfs_btree_cur_t *cur, /* btree cursor */
1502 int *logflags, /* logging flags for inode */ 1368 int *logflags, /* logging flags for inode */
1503 int *stat) /* return status - 0 fail */ 1369 int *stat) /* return status - 0 fail */
1504 { 1370 {
1505 xfs_alloc_arg_t args; /* allocation arguments */ 1371 xfs_alloc_arg_t args; /* allocation arguments */
1506 xfs_bmbt_block_t *block; /* bmap btree block */ 1372 xfs_bmbt_block_t *block; /* bmap btree block */
1507 xfs_buf_t *bp; /* buffer for block */ 1373 xfs_buf_t *bp; /* buffer for block */
1508 xfs_bmbt_block_t *cblock; /* child btree block */ 1374 xfs_bmbt_block_t *cblock; /* child btree block */
1509 xfs_bmbt_key_t *ckp; /* child key pointer */ 1375 xfs_bmbt_key_t *ckp; /* child key pointer */
1510 xfs_bmbt_ptr_t *cpp; /* child ptr pointer */ 1376 xfs_bmbt_ptr_t *cpp; /* child ptr pointer */
1511 int error; /* error return code */ 1377 int error; /* error return code */
1512 #ifdef DEBUG 1378 #ifdef DEBUG
1513 int i; /* loop counter */ 1379 int i; /* loop counter */
1514 #endif 1380 #endif
1515 xfs_bmbt_key_t *kp; /* pointer to bmap btree key */ 1381 xfs_bmbt_key_t *kp; /* pointer to bmap btree key */
1516 int level; /* btree level */ 1382 int level; /* btree level */
1517 xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ 1383 xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
1518 1384
1519 XFS_BMBT_TRACE_CURSOR(cur, ENTRY); 1385 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
1520 level = cur->bc_nlevels - 1; 1386 level = cur->bc_nlevels - 1;
1521 block = xfs_bmbt_get_block(cur, level, &bp); 1387 block = xfs_bmbt_get_block(cur, level, &bp);
1522 /* 1388 /*
1523 * Copy the root into a real block. 1389 * Copy the root into a real block.
1524 */ 1390 */
1525 args.mp = cur->bc_mp; 1391 args.mp = cur->bc_mp;
1526 pp = XFS_BMAP_PTR_IADDR(block, 1, cur); 1392 pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
1527 args.tp = cur->bc_tp; 1393 args.tp = cur->bc_tp;
1528 args.fsbno = cur->bc_private.b.firstblock; 1394 args.fsbno = cur->bc_private.b.firstblock;
1529 args.mod = args.minleft = args.alignment = args.total = args.isfl = 1395 args.mod = args.minleft = args.alignment = args.total = args.isfl =
1530 args.userdata = args.minalignslop = 0; 1396 args.userdata = args.minalignslop = 0;
1531 args.minlen = args.maxlen = args.prod = 1; 1397 args.minlen = args.maxlen = args.prod = 1;
1532 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 1398 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
1533 args.firstblock = args.fsbno; 1399 args.firstblock = args.fsbno;
1534 if (args.fsbno == NULLFSBLOCK) { 1400 if (args.fsbno == NULLFSBLOCK) {
1535 #ifdef DEBUG 1401 #ifdef DEBUG
1536 if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { 1402 if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) {
1537 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1403 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1538 return error; 1404 return error;
1539 } 1405 }
1540 #endif 1406 #endif
1541 args.fsbno = be64_to_cpu(*pp); 1407 args.fsbno = be64_to_cpu(*pp);
1542 args.type = XFS_ALLOCTYPE_START_BNO; 1408 args.type = XFS_ALLOCTYPE_START_BNO;
1543 } else if (cur->bc_private.b.flist->xbf_low) 1409 } else if (cur->bc_private.b.flist->xbf_low)
1544 args.type = XFS_ALLOCTYPE_START_BNO; 1410 args.type = XFS_ALLOCTYPE_START_BNO;
1545 else 1411 else
1546 args.type = XFS_ALLOCTYPE_NEAR_BNO; 1412 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1547 if ((error = xfs_alloc_vextent(&args))) { 1413 if ((error = xfs_alloc_vextent(&args))) {
1548 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1414 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1549 return error; 1415 return error;
1550 } 1416 }
1551 if (args.fsbno == NULLFSBLOCK) { 1417 if (args.fsbno == NULLFSBLOCK) {
1552 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 1418 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1553 *stat = 0; 1419 *stat = 0;
1554 return 0; 1420 return 0;
1555 } 1421 }
1556 ASSERT(args.len == 1); 1422 ASSERT(args.len == 1);
1557 cur->bc_private.b.firstblock = args.fsbno; 1423 cur->bc_private.b.firstblock = args.fsbno;
1558 cur->bc_private.b.allocated++; 1424 cur->bc_private.b.allocated++;
1559 cur->bc_private.b.ip->i_d.di_nblocks++; 1425 cur->bc_private.b.ip->i_d.di_nblocks++;
1560 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip, 1426 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip,
1561 XFS_TRANS_DQ_BCOUNT, 1L); 1427 XFS_TRANS_DQ_BCOUNT, 1L);
1562 bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0); 1428 bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0);
1563 cblock = XFS_BUF_TO_BMBT_BLOCK(bp); 1429 cblock = XFS_BUF_TO_BMBT_BLOCK(bp);
1564 *cblock = *block; 1430 *cblock = *block;
1565 be16_add_cpu(&block->bb_level, 1); 1431 be16_add_cpu(&block->bb_level, 1);
1566 block->bb_numrecs = cpu_to_be16(1); 1432 block->bb_numrecs = cpu_to_be16(1);
1567 cur->bc_nlevels++; 1433 cur->bc_nlevels++;
1568 cur->bc_ptrs[level + 1] = 1; 1434 cur->bc_ptrs[level + 1] = 1;
1569 kp = XFS_BMAP_KEY_IADDR(block, 1, cur); 1435 kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
1570 ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); 1436 ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur);
1571 memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp)); 1437 memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp));
1572 cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); 1438 cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
1573 #ifdef DEBUG 1439 #ifdef DEBUG
1574 for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { 1440 for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
1575 if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { 1441 if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
1576 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1442 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1577 return error; 1443 return error;
1578 } 1444 }
1579 } 1445 }
1580 #endif 1446 #endif
1581 memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp)); 1447 memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));
1582 #ifdef DEBUG 1448 #ifdef DEBUG
1583 if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) { 1449 if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) {
1584 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1450 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1585 return error; 1451 return error;
1586 } 1452 }
1587 #endif 1453 #endif
1588 *pp = cpu_to_be64(args.fsbno); 1454 *pp = cpu_to_be64(args.fsbno);
1589 xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs), 1455 xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),
1590 cur->bc_private.b.whichfork); 1456 cur->bc_private.b.whichfork);
1591 xfs_btree_setbuf(cur, level, bp); 1457 xfs_btree_setbuf(cur, level, bp);
1592 /* 1458 /*
1593 * Do all this logging at the end so that 1459 * Do all this logging at the end so that
1594 * the root is at the right level. 1460 * the root is at the right level.
1595 */ 1461 */
1596 xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS); 1462 xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS);
1597 xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs)); 1463 xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
1598 xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs)); 1464 xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs));
1599 XFS_BMBT_TRACE_CURSOR(cur, EXIT); 1465 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1600 *logflags |= 1466 *logflags |=
1601 XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork); 1467 XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork);
1602 *stat = 1; 1468 *stat = 1;
1603 return 0; 1469 return 0;
1604 } 1470 }
1605 1471
1606 /* 1472 /*
1607 * Set all the fields in a bmap extent record from the arguments. 1473 * Set all the fields in a bmap extent record from the arguments.
1608 */ 1474 */
1609 void 1475 void
1610 xfs_bmbt_set_allf( 1476 xfs_bmbt_set_allf(
1611 xfs_bmbt_rec_host_t *r, 1477 xfs_bmbt_rec_host_t *r,
1612 xfs_fileoff_t startoff, 1478 xfs_fileoff_t startoff,
1613 xfs_fsblock_t startblock, 1479 xfs_fsblock_t startblock,
1614 xfs_filblks_t blockcount, 1480 xfs_filblks_t blockcount,
1615 xfs_exntst_t state) 1481 xfs_exntst_t state)
1616 { 1482 {
1617 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; 1483 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
1618 1484
1619 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); 1485 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
1620 ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); 1486 ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
1621 ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); 1487 ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
1622 1488
1623 #if XFS_BIG_BLKNOS 1489 #if XFS_BIG_BLKNOS
1624 ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); 1490 ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
1625 1491
1626 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 1492 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
1627 ((xfs_bmbt_rec_base_t)startoff << 9) | 1493 ((xfs_bmbt_rec_base_t)startoff << 9) |
1628 ((xfs_bmbt_rec_base_t)startblock >> 43); 1494 ((xfs_bmbt_rec_base_t)startblock >> 43);
1629 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | 1495 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
1630 ((xfs_bmbt_rec_base_t)blockcount & 1496 ((xfs_bmbt_rec_base_t)blockcount &
1631 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 1497 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
1632 #else /* !XFS_BIG_BLKNOS */ 1498 #else /* !XFS_BIG_BLKNOS */
1633 if (ISNULLSTARTBLOCK(startblock)) { 1499 if (ISNULLSTARTBLOCK(startblock)) {
1634 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 1500 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
1635 ((xfs_bmbt_rec_base_t)startoff << 9) | 1501 ((xfs_bmbt_rec_base_t)startoff << 9) |
1636 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); 1502 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
1637 r->l1 = XFS_MASK64HI(11) | 1503 r->l1 = XFS_MASK64HI(11) |
1638 ((xfs_bmbt_rec_base_t)startblock << 21) | 1504 ((xfs_bmbt_rec_base_t)startblock << 21) |
1639 ((xfs_bmbt_rec_base_t)blockcount & 1505 ((xfs_bmbt_rec_base_t)blockcount &
1640 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 1506 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
1641 } else { 1507 } else {
1642 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 1508 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
1643 ((xfs_bmbt_rec_base_t)startoff << 9); 1509 ((xfs_bmbt_rec_base_t)startoff << 9);
1644 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | 1510 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
1645 ((xfs_bmbt_rec_base_t)blockcount & 1511 ((xfs_bmbt_rec_base_t)blockcount &
1646 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 1512 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
1647 } 1513 }
1648 #endif /* XFS_BIG_BLKNOS */ 1514 #endif /* XFS_BIG_BLKNOS */
1649 } 1515 }
1650 1516
1651 /* 1517 /*
1652 * Set all the fields in a bmap extent record from the uncompressed form. 1518 * Set all the fields in a bmap extent record from the uncompressed form.
1653 */ 1519 */
1654 void 1520 void
1655 xfs_bmbt_set_all( 1521 xfs_bmbt_set_all(
1656 xfs_bmbt_rec_host_t *r, 1522 xfs_bmbt_rec_host_t *r,
1657 xfs_bmbt_irec_t *s) 1523 xfs_bmbt_irec_t *s)
1658 { 1524 {
1659 xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock, 1525 xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock,
1660 s->br_blockcount, s->br_state); 1526 s->br_blockcount, s->br_state);
1661 } 1527 }
1662 1528
1663 1529
1664 /* 1530 /*
1665 * Set all the fields in a disk format bmap extent record from the arguments. 1531 * Set all the fields in a disk format bmap extent record from the arguments.
1666 */ 1532 */
1667 void 1533 void
1668 xfs_bmbt_disk_set_allf( 1534 xfs_bmbt_disk_set_allf(
1669 xfs_bmbt_rec_t *r, 1535 xfs_bmbt_rec_t *r,
1670 xfs_fileoff_t startoff, 1536 xfs_fileoff_t startoff,
1671 xfs_fsblock_t startblock, 1537 xfs_fsblock_t startblock,
1672 xfs_filblks_t blockcount, 1538 xfs_filblks_t blockcount,
1673 xfs_exntst_t state) 1539 xfs_exntst_t state)
1674 { 1540 {
1675 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; 1541 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
1676 1542
1677 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); 1543 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
1678 ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); 1544 ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
1679 ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); 1545 ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
1680 1546
1681 #if XFS_BIG_BLKNOS 1547 #if XFS_BIG_BLKNOS
1682 ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); 1548 ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
1683 1549
1684 r->l0 = cpu_to_be64( 1550 r->l0 = cpu_to_be64(
1685 ((xfs_bmbt_rec_base_t)extent_flag << 63) | 1551 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
1686 ((xfs_bmbt_rec_base_t)startoff << 9) | 1552 ((xfs_bmbt_rec_base_t)startoff << 9) |
1687 ((xfs_bmbt_rec_base_t)startblock >> 43)); 1553 ((xfs_bmbt_rec_base_t)startblock >> 43));
1688 r->l1 = cpu_to_be64( 1554 r->l1 = cpu_to_be64(
1689 ((xfs_bmbt_rec_base_t)startblock << 21) | 1555 ((xfs_bmbt_rec_base_t)startblock << 21) |
1690 ((xfs_bmbt_rec_base_t)blockcount & 1556 ((xfs_bmbt_rec_base_t)blockcount &
1691 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); 1557 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
1692 #else /* !XFS_BIG_BLKNOS */ 1558 #else /* !XFS_BIG_BLKNOS */
1693 if (ISNULLSTARTBLOCK(startblock)) { 1559 if (ISNULLSTARTBLOCK(startblock)) {
1694 r->l0 = cpu_to_be64( 1560 r->l0 = cpu_to_be64(
1695 ((xfs_bmbt_rec_base_t)extent_flag << 63) | 1561 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
1696 ((xfs_bmbt_rec_base_t)startoff << 9) | 1562 ((xfs_bmbt_rec_base_t)startoff << 9) |
1697 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); 1563 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
1698 r->l1 = cpu_to_be64(XFS_MASK64HI(11) | 1564 r->l1 = cpu_to_be64(XFS_MASK64HI(11) |
1699 ((xfs_bmbt_rec_base_t)startblock << 21) | 1565 ((xfs_bmbt_rec_base_t)startblock << 21) |
1700 ((xfs_bmbt_rec_base_t)blockcount & 1566 ((xfs_bmbt_rec_base_t)blockcount &
1701 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); 1567 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
1702 } else { 1568 } else {
1703 r->l0 = cpu_to_be64( 1569 r->l0 = cpu_to_be64(
1704 ((xfs_bmbt_rec_base_t)extent_flag << 63) | 1570 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
1705 ((xfs_bmbt_rec_base_t)startoff << 9)); 1571 ((xfs_bmbt_rec_base_t)startoff << 9));
1706 r->l1 = cpu_to_be64( 1572 r->l1 = cpu_to_be64(
1707 ((xfs_bmbt_rec_base_t)startblock << 21) | 1573 ((xfs_bmbt_rec_base_t)startblock << 21) |
1708 ((xfs_bmbt_rec_base_t)blockcount & 1574 ((xfs_bmbt_rec_base_t)blockcount &
1709 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); 1575 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
1710 } 1576 }
1711 #endif /* XFS_BIG_BLKNOS */ 1577 #endif /* XFS_BIG_BLKNOS */
1712 } 1578 }
1713 1579
1714 /* 1580 /*
1715 * Set all the fields in a bmap extent record from the uncompressed form. 1581 * Set all the fields in a bmap extent record from the uncompressed form.
1716 */ 1582 */
1717 void 1583 void
1718 xfs_bmbt_disk_set_all( 1584 xfs_bmbt_disk_set_all(
1719 xfs_bmbt_rec_t *r, 1585 xfs_bmbt_rec_t *r,
1720 xfs_bmbt_irec_t *s) 1586 xfs_bmbt_irec_t *s)
1721 { 1587 {
1722 xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock, 1588 xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock,
1723 s->br_blockcount, s->br_state); 1589 s->br_blockcount, s->br_state);
1724 } 1590 }
1725 1591
1726 /* 1592 /*
1727 * Set the blockcount field in a bmap extent record. 1593 * Set the blockcount field in a bmap extent record.
1728 */ 1594 */
1729 void 1595 void
1730 xfs_bmbt_set_blockcount( 1596 xfs_bmbt_set_blockcount(
1731 xfs_bmbt_rec_host_t *r, 1597 xfs_bmbt_rec_host_t *r,
1732 xfs_filblks_t v) 1598 xfs_filblks_t v)
1733 { 1599 {
1734 ASSERT((v & XFS_MASK64HI(43)) == 0); 1600 ASSERT((v & XFS_MASK64HI(43)) == 0);
1735 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(43)) | 1601 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(43)) |
1736 (xfs_bmbt_rec_base_t)(v & XFS_MASK64LO(21)); 1602 (xfs_bmbt_rec_base_t)(v & XFS_MASK64LO(21));
1737 } 1603 }
1738 1604
1739 /* 1605 /*
1740 * Set the startblock field in a bmap extent record. 1606 * Set the startblock field in a bmap extent record.
1741 */ 1607 */
1742 void 1608 void
1743 xfs_bmbt_set_startblock( 1609 xfs_bmbt_set_startblock(
1744 xfs_bmbt_rec_host_t *r, 1610 xfs_bmbt_rec_host_t *r,
1745 xfs_fsblock_t v) 1611 xfs_fsblock_t v)
1746 { 1612 {
1747 #if XFS_BIG_BLKNOS 1613 #if XFS_BIG_BLKNOS
1748 ASSERT((v & XFS_MASK64HI(12)) == 0); 1614 ASSERT((v & XFS_MASK64HI(12)) == 0);
1749 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) | 1615 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) |
1750 (xfs_bmbt_rec_base_t)(v >> 43); 1616 (xfs_bmbt_rec_base_t)(v >> 43);
1751 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) | 1617 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) |
1752 (xfs_bmbt_rec_base_t)(v << 21); 1618 (xfs_bmbt_rec_base_t)(v << 21);
1753 #else /* !XFS_BIG_BLKNOS */ 1619 #else /* !XFS_BIG_BLKNOS */
1754 if (ISNULLSTARTBLOCK(v)) { 1620 if (ISNULLSTARTBLOCK(v)) {
1755 r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); 1621 r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
1756 r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) | 1622 r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) |
1757 ((xfs_bmbt_rec_base_t)v << 21) | 1623 ((xfs_bmbt_rec_base_t)v << 21) |
1758 (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 1624 (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
1759 } else { 1625 } else {
1760 r->l0 &= ~(xfs_bmbt_rec_base_t)XFS_MASK64LO(9); 1626 r->l0 &= ~(xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
1761 r->l1 = ((xfs_bmbt_rec_base_t)v << 21) | 1627 r->l1 = ((xfs_bmbt_rec_base_t)v << 21) |
1762 (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 1628 (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
1763 } 1629 }
1764 #endif /* XFS_BIG_BLKNOS */ 1630 #endif /* XFS_BIG_BLKNOS */
1765 } 1631 }
1766 1632
1767 /* 1633 /*
1768 * Set the startoff field in a bmap extent record. 1634 * Set the startoff field in a bmap extent record.
1769 */ 1635 */
1770 void 1636 void
1771 xfs_bmbt_set_startoff( 1637 xfs_bmbt_set_startoff(
1772 xfs_bmbt_rec_host_t *r, 1638 xfs_bmbt_rec_host_t *r,
1773 xfs_fileoff_t v) 1639 xfs_fileoff_t v)
1774 { 1640 {
1775 ASSERT((v & XFS_MASK64HI(9)) == 0); 1641 ASSERT((v & XFS_MASK64HI(9)) == 0);
1776 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) XFS_MASK64HI(1)) | 1642 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) XFS_MASK64HI(1)) |
1777 ((xfs_bmbt_rec_base_t)v << 9) | 1643 ((xfs_bmbt_rec_base_t)v << 9) |
1778 (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); 1644 (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
1779 } 1645 }
1780 1646
1781 /* 1647 /*
1782 * Set the extent state field in a bmap extent record. 1648 * Set the extent state field in a bmap extent record.
1783 */ 1649 */
1784 void 1650 void
1785 xfs_bmbt_set_state( 1651 xfs_bmbt_set_state(
1786 xfs_bmbt_rec_host_t *r, 1652 xfs_bmbt_rec_host_t *r,
1787 xfs_exntst_t v) 1653 xfs_exntst_t v)
1788 { 1654 {
1789 ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); 1655 ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN);
1790 if (v == XFS_EXT_NORM) 1656 if (v == XFS_EXT_NORM)
1791 r->l0 &= XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN); 1657 r->l0 &= XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN);
1792 else 1658 else
1793 r->l0 |= XFS_MASK64HI(BMBT_EXNTFLAG_BITLEN); 1659 r->l0 |= XFS_MASK64HI(BMBT_EXNTFLAG_BITLEN);
1794 } 1660 }
1795 1661
1796 /* 1662 /*
1797 * Convert in-memory form of btree root to on-disk form. 1663 * Convert in-memory form of btree root to on-disk form.
1798 */ 1664 */
1799 void 1665 void
1800 xfs_bmbt_to_bmdr( 1666 xfs_bmbt_to_bmdr(
1801 xfs_bmbt_block_t *rblock, 1667 xfs_bmbt_block_t *rblock,
1802 int rblocklen, 1668 int rblocklen,
1803 xfs_bmdr_block_t *dblock, 1669 xfs_bmdr_block_t *dblock,
1804 int dblocklen) 1670 int dblocklen)
1805 { 1671 {
1806 int dmxr; 1672 int dmxr;
1807 xfs_bmbt_key_t *fkp; 1673 xfs_bmbt_key_t *fkp;
1808 __be64 *fpp; 1674 __be64 *fpp;
1809 xfs_bmbt_key_t *tkp; 1675 xfs_bmbt_key_t *tkp;
1810 __be64 *tpp; 1676 __be64 *tpp;
1811 1677
1812 ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); 1678 ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC);
1813 ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO); 1679 ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO);
1814 ASSERT(be64_to_cpu(rblock->bb_rightsib) == NULLDFSBNO); 1680 ASSERT(be64_to_cpu(rblock->bb_rightsib) == NULLDFSBNO);
1815 ASSERT(be16_to_cpu(rblock->bb_level) > 0); 1681 ASSERT(be16_to_cpu(rblock->bb_level) > 0);
1816 dblock->bb_level = rblock->bb_level; 1682 dblock->bb_level = rblock->bb_level;
1817 dblock->bb_numrecs = rblock->bb_numrecs; 1683 dblock->bb_numrecs = rblock->bb_numrecs;
1818 dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0); 1684 dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0);
1819 fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); 1685 fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen);
1820 tkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); 1686 tkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1);
1821 fpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); 1687 fpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
1822 tpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); 1688 tpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr);
1823 dmxr = be16_to_cpu(dblock->bb_numrecs); 1689 dmxr = be16_to_cpu(dblock->bb_numrecs);
1824 memcpy(tkp, fkp, sizeof(*fkp) * dmxr); 1690 memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
1825 memcpy(tpp, fpp, sizeof(*fpp) * dmxr); 1691 memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
1826 } 1692 }
1827 1693
1828 /* 1694 /*
1829 * Check extent records, which have just been read, for 1695 * Check extent records, which have just been read, for
1830 * any bit in the extent flag field. ASSERT on debug 1696 * any bit in the extent flag field. ASSERT on debug
1831 * kernels, as this condition should not occur. 1697 * kernels, as this condition should not occur.
1832 * Return an error condition (1) if any flags found, 1698 * Return an error condition (1) if any flags found,
1833 * otherwise return 0. 1699 * otherwise return 0.
1834 */ 1700 */
1835 1701
1836 int 1702 int
1837 xfs_check_nostate_extents( 1703 xfs_check_nostate_extents(
1838 xfs_ifork_t *ifp, 1704 xfs_ifork_t *ifp,
1839 xfs_extnum_t idx, 1705 xfs_extnum_t idx,
1840 xfs_extnum_t num) 1706 xfs_extnum_t num)
1841 { 1707 {
1842 for (; num > 0; num--, idx++) { 1708 for (; num > 0; num--, idx++) {
1843 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); 1709 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
1844 if ((ep->l0 >> 1710 if ((ep->l0 >>
1845 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { 1711 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
1846 ASSERT(0); 1712 ASSERT(0);
1847 return 1; 1713 return 1;
1848 } 1714 }
1849 } 1715 }
1850 return 0; 1716 return 0;
1851 } 1717 }
1852 1718
1853 1719
1854 STATIC struct xfs_btree_cur * 1720 STATIC struct xfs_btree_cur *
1855 xfs_bmbt_dup_cursor( 1721 xfs_bmbt_dup_cursor(
1856 struct xfs_btree_cur *cur) 1722 struct xfs_btree_cur *cur)
1857 { 1723 {
1858 struct xfs_btree_cur *new; 1724 struct xfs_btree_cur *new;
1859 1725
1860 new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp, 1726 new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp,
1861 cur->bc_private.b.ip, cur->bc_private.b.whichfork); 1727 cur->bc_private.b.ip, cur->bc_private.b.whichfork);
1862 1728
1863 /* 1729 /*
1864 * Copy the firstblock, flist, and flags values, 1730 * Copy the firstblock, flist, and flags values,
1865 * since init cursor doesn't get them. 1731 * since init cursor doesn't get them.
1866 */ 1732 */
1867 new->bc_private.b.firstblock = cur->bc_private.b.firstblock; 1733 new->bc_private.b.firstblock = cur->bc_private.b.firstblock;
1868 new->bc_private.b.flist = cur->bc_private.b.flist; 1734 new->bc_private.b.flist = cur->bc_private.b.flist;
1869 new->bc_private.b.flags = cur->bc_private.b.flags; 1735 new->bc_private.b.flags = cur->bc_private.b.flags;
1870 1736
1871 return new; 1737 return new;
1872 } 1738 }
1873 1739
1874 STATIC int 1740 STATIC int
1875 xfs_bmbt_get_maxrecs( 1741 xfs_bmbt_get_maxrecs(
1876 struct xfs_btree_cur *cur, 1742 struct xfs_btree_cur *cur,
1877 int level) 1743 int level)
1878 { 1744 {
1879 return XFS_BMAP_BLOCK_IMAXRECS(level, cur); 1745 return XFS_BMAP_BLOCK_IMAXRECS(level, cur);
1880 } 1746 }
1881 1747
1882 STATIC void 1748 STATIC void
1883 xfs_bmbt_init_key_from_rec( 1749 xfs_bmbt_init_key_from_rec(
1884 union xfs_btree_key *key, 1750 union xfs_btree_key *key,
1885 union xfs_btree_rec *rec) 1751 union xfs_btree_rec *rec)
1886 { 1752 {
1887 key->bmbt.br_startoff = 1753 key->bmbt.br_startoff =
1888 cpu_to_be64(xfs_bmbt_disk_get_startoff(&rec->bmbt)); 1754 cpu_to_be64(xfs_bmbt_disk_get_startoff(&rec->bmbt));
1889 } 1755 }
1890 1756
1891 STATIC void 1757 STATIC void
1892 xfs_bmbt_init_ptr_from_cur( 1758 xfs_bmbt_init_ptr_from_cur(
1893 struct xfs_btree_cur *cur, 1759 struct xfs_btree_cur *cur,
1894 union xfs_btree_ptr *ptr) 1760 union xfs_btree_ptr *ptr)
1895 { 1761 {
1896 ptr->l = 0; 1762 ptr->l = 0;
1897 } 1763 }
1898 1764
1899 STATIC __int64_t 1765 STATIC __int64_t
1900 xfs_bmbt_key_diff( 1766 xfs_bmbt_key_diff(
1901 struct xfs_btree_cur *cur, 1767 struct xfs_btree_cur *cur,
1902 union xfs_btree_key *key) 1768 union xfs_btree_key *key)
1903 { 1769 {
1904 return (__int64_t)be64_to_cpu(key->bmbt.br_startoff) - 1770 return (__int64_t)be64_to_cpu(key->bmbt.br_startoff) -
1905 cur->bc_rec.b.br_startoff; 1771 cur->bc_rec.b.br_startoff;
1906 } 1772 }
1907 1773
1908 #ifdef XFS_BTREE_TRACE 1774 #ifdef XFS_BTREE_TRACE
1909 ktrace_t *xfs_bmbt_trace_buf; 1775 ktrace_t *xfs_bmbt_trace_buf;
1910 1776
1911 STATIC void 1777 STATIC void
1912 xfs_bmbt_trace_enter( 1778 xfs_bmbt_trace_enter(
1913 struct xfs_btree_cur *cur, 1779 struct xfs_btree_cur *cur,
1914 const char *func, 1780 const char *func,
1915 char *s, 1781 char *s,
1916 int type, 1782 int type,
1917 int line, 1783 int line,
1918 __psunsigned_t a0, 1784 __psunsigned_t a0,
1919 __psunsigned_t a1, 1785 __psunsigned_t a1,
1920 __psunsigned_t a2, 1786 __psunsigned_t a2,
1921 __psunsigned_t a3, 1787 __psunsigned_t a3,
1922 __psunsigned_t a4, 1788 __psunsigned_t a4,
1923 __psunsigned_t a5, 1789 __psunsigned_t a5,
1924 __psunsigned_t a6, 1790 __psunsigned_t a6,
1925 __psunsigned_t a7, 1791 __psunsigned_t a7,
1926 __psunsigned_t a8, 1792 __psunsigned_t a8,
1927 __psunsigned_t a9, 1793 __psunsigned_t a9,
1928 __psunsigned_t a10) 1794 __psunsigned_t a10)
1929 { 1795 {
1930 struct xfs_inode *ip = cur->bc_private.b.ip; 1796 struct xfs_inode *ip = cur->bc_private.b.ip;
1931 int whichfork = cur->bc_private.b.whichfork; 1797 int whichfork = cur->bc_private.b.whichfork;
1932 1798
1933 ktrace_enter(xfs_bmbt_trace_buf, 1799 ktrace_enter(xfs_bmbt_trace_buf,
1934 (void *)((__psint_t)type | (whichfork << 8) | (line << 16)), 1800 (void *)((__psint_t)type | (whichfork << 8) | (line << 16)),
1935 (void *)func, (void *)s, (void *)ip, (void *)cur, 1801 (void *)func, (void *)s, (void *)ip, (void *)cur,
1936 (void *)a0, (void *)a1, (void *)a2, (void *)a3, 1802 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
1937 (void *)a4, (void *)a5, (void *)a6, (void *)a7, 1803 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
1938 (void *)a8, (void *)a9, (void *)a10); 1804 (void *)a8, (void *)a9, (void *)a10);
1939 ktrace_enter(ip->i_btrace, 1805 ktrace_enter(ip->i_btrace,
1940 (void *)((__psint_t)type | (whichfork << 8) | (line << 16)), 1806 (void *)((__psint_t)type | (whichfork << 8) | (line << 16)),
1941 (void *)func, (void *)s, (void *)ip, (void *)cur, 1807 (void *)func, (void *)s, (void *)ip, (void *)cur,
1942 (void *)a0, (void *)a1, (void *)a2, (void *)a3, 1808 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
1943 (void *)a4, (void *)a5, (void *)a6, (void *)a7, 1809 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
1944 (void *)a8, (void *)a9, (void *)a10); 1810 (void *)a8, (void *)a9, (void *)a10);
1945 } 1811 }
1946 1812
1947 STATIC void 1813 STATIC void
1948 xfs_bmbt_trace_cursor( 1814 xfs_bmbt_trace_cursor(
1949 struct xfs_btree_cur *cur, 1815 struct xfs_btree_cur *cur,
1950 __uint32_t *s0, 1816 __uint32_t *s0,
1951 __uint64_t *l0, 1817 __uint64_t *l0,
1952 __uint64_t *l1) 1818 __uint64_t *l1)
1953 { 1819 {
1954 struct xfs_bmbt_rec_host r; 1820 struct xfs_bmbt_rec_host r;
1955 1821
1956 xfs_bmbt_set_all(&r, &cur->bc_rec.b); 1822 xfs_bmbt_set_all(&r, &cur->bc_rec.b);
1957 1823
1958 *s0 = (cur->bc_nlevels << 24) | 1824 *s0 = (cur->bc_nlevels << 24) |
1959 (cur->bc_private.b.flags << 16) | 1825 (cur->bc_private.b.flags << 16) |
1960 cur->bc_private.b.allocated; 1826 cur->bc_private.b.allocated;
1961 *l0 = r.l0; 1827 *l0 = r.l0;
1962 *l1 = r.l1; 1828 *l1 = r.l1;
1963 } 1829 }
1964 1830
1965 STATIC void 1831 STATIC void
1966 xfs_bmbt_trace_key( 1832 xfs_bmbt_trace_key(
1967 struct xfs_btree_cur *cur, 1833 struct xfs_btree_cur *cur,
1968 union xfs_btree_key *key, 1834 union xfs_btree_key *key,
1969 __uint64_t *l0, 1835 __uint64_t *l0,
1970 __uint64_t *l1) 1836 __uint64_t *l1)
1971 { 1837 {
1972 *l0 = be64_to_cpu(key->bmbt.br_startoff); 1838 *l0 = be64_to_cpu(key->bmbt.br_startoff);
1973 *l1 = 0; 1839 *l1 = 0;
1974 } 1840 }
1975 1841
1976 STATIC void 1842 STATIC void
1977 xfs_bmbt_trace_record( 1843 xfs_bmbt_trace_record(
1978 struct xfs_btree_cur *cur, 1844 struct xfs_btree_cur *cur,
1979 union xfs_btree_rec *rec, 1845 union xfs_btree_rec *rec,
1980 __uint64_t *l0, 1846 __uint64_t *l0,
1981 __uint64_t *l1, 1847 __uint64_t *l1,
1982 __uint64_t *l2) 1848 __uint64_t *l2)
1983 { 1849 {
1984 struct xfs_bmbt_irec irec; 1850 struct xfs_bmbt_irec irec;
1985 1851
1986 xfs_bmbt_disk_get_all(&rec->bmbt, &irec); 1852 xfs_bmbt_disk_get_all(&rec->bmbt, &irec);
1987 *l0 = irec.br_startoff; 1853 *l0 = irec.br_startoff;
1988 *l1 = irec.br_startblock; 1854 *l1 = irec.br_startblock;
1989 *l2 = irec.br_blockcount; 1855 *l2 = irec.br_blockcount;
1990 } 1856 }
1991 #endif /* XFS_BTREE_TRACE */ 1857 #endif /* XFS_BTREE_TRACE */
1992 1858
1993 static const struct xfs_btree_ops xfs_bmbt_ops = { 1859 static const struct xfs_btree_ops xfs_bmbt_ops = {
1994 .rec_len = sizeof(xfs_bmbt_rec_t), 1860 .rec_len = sizeof(xfs_bmbt_rec_t),
1995 .key_len = sizeof(xfs_bmbt_key_t), 1861 .key_len = sizeof(xfs_bmbt_key_t),
1996 1862
1997 .dup_cursor = xfs_bmbt_dup_cursor, 1863 .dup_cursor = xfs_bmbt_dup_cursor,
1998 .get_maxrecs = xfs_bmbt_get_maxrecs, 1864 .get_maxrecs = xfs_bmbt_get_maxrecs,
1999 .init_key_from_rec = xfs_bmbt_init_key_from_rec, 1865 .init_key_from_rec = xfs_bmbt_init_key_from_rec,
2000 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, 1866 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
2001 .key_diff = xfs_bmbt_key_diff, 1867 .key_diff = xfs_bmbt_key_diff,
2002 1868
2003 #ifdef XFS_BTREE_TRACE 1869 #ifdef XFS_BTREE_TRACE
2004 .trace_enter = xfs_bmbt_trace_enter, 1870 .trace_enter = xfs_bmbt_trace_enter,
2005 .trace_cursor = xfs_bmbt_trace_cursor, 1871 .trace_cursor = xfs_bmbt_trace_cursor,
2006 .trace_key = xfs_bmbt_trace_key, 1872 .trace_key = xfs_bmbt_trace_key,
2007 .trace_record = xfs_bmbt_trace_record, 1873 .trace_record = xfs_bmbt_trace_record,
2008 #endif 1874 #endif
2009 }; 1875 };
2010 1876
2011 /* 1877 /*
2012 * Allocate a new bmap btree cursor. 1878 * Allocate a new bmap btree cursor.
2013 */ 1879 */
2014 struct xfs_btree_cur * /* new bmap btree cursor */ 1880 struct xfs_btree_cur * /* new bmap btree cursor */
2015 xfs_bmbt_init_cursor( 1881 xfs_bmbt_init_cursor(
2016 struct xfs_mount *mp, /* file system mount point */ 1882 struct xfs_mount *mp, /* file system mount point */
2017 struct xfs_trans *tp, /* transaction pointer */ 1883 struct xfs_trans *tp, /* transaction pointer */
2018 struct xfs_inode *ip, /* inode owning the btree */ 1884 struct xfs_inode *ip, /* inode owning the btree */
2019 int whichfork) /* data or attr fork */ 1885 int whichfork) /* data or attr fork */
2020 { 1886 {
2021 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 1887 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
2022 struct xfs_btree_cur *cur; 1888 struct xfs_btree_cur *cur;
2023 1889
2024 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); 1890 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
2025 1891
2026 cur->bc_tp = tp; 1892 cur->bc_tp = tp;
2027 cur->bc_mp = mp; 1893 cur->bc_mp = mp;
2028 cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; 1894 cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
2029 cur->bc_btnum = XFS_BTNUM_BMAP; 1895 cur->bc_btnum = XFS_BTNUM_BMAP;
2030 cur->bc_blocklog = mp->m_sb.sb_blocklog; 1896 cur->bc_blocklog = mp->m_sb.sb_blocklog;
2031 1897
2032 cur->bc_ops = &xfs_bmbt_ops; 1898 cur->bc_ops = &xfs_bmbt_ops;
2033 cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE; 1899 cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
2034 1900
2035 cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); 1901 cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
2036 cur->bc_private.b.ip = ip; 1902 cur->bc_private.b.ip = ip;
2037 cur->bc_private.b.firstblock = NULLFSBLOCK; 1903 cur->bc_private.b.firstblock = NULLFSBLOCK;
2038 cur->bc_private.b.flist = NULL; 1904 cur->bc_private.b.flist = NULL;
2039 cur->bc_private.b.allocated = 0; 1905 cur->bc_private.b.allocated = 0;
2040 cur->bc_private.b.flags = 0; 1906 cur->bc_private.b.flags = 0;
2041 cur->bc_private.b.whichfork = whichfork; 1907 cur->bc_private.b.whichfork = whichfork;
2042 1908
2043 return cur; 1909 return cur;
2044 } 1910 }
2045 1911
1 /* 1 /*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_inum.h" 23 #include "xfs_inum.h"
24 #include "xfs_trans.h" 24 #include "xfs_trans.h"
25 #include "xfs_sb.h" 25 #include "xfs_sb.h"
26 #include "xfs_ag.h" 26 #include "xfs_ag.h"
27 #include "xfs_dir2.h" 27 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h" 28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h" 29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h" 31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h" 32 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h" 33 #include "xfs_dir2_sf.h"
34 #include "xfs_attr_sf.h" 34 #include "xfs_attr_sf.h"
35 #include "xfs_dinode.h" 35 #include "xfs_dinode.h"
36 #include "xfs_inode.h" 36 #include "xfs_inode.h"
37 #include "xfs_inode_item.h" 37 #include "xfs_inode_item.h"
38 #include "xfs_btree.h" 38 #include "xfs_btree.h"
39 #include "xfs_btree_trace.h" 39 #include "xfs_btree_trace.h"
40 #include "xfs_ialloc.h" 40 #include "xfs_ialloc.h"
41 #include "xfs_error.h" 41 #include "xfs_error.h"
42 42
43 /* 43 /*
44 * Cursor allocation zone. 44 * Cursor allocation zone.
45 */ 45 */
46 kmem_zone_t *xfs_btree_cur_zone; 46 kmem_zone_t *xfs_btree_cur_zone;
47 47
48 /* 48 /*
49 * Btree magic numbers. 49 * Btree magic numbers.
50 */ 50 */
51 const __uint32_t xfs_magics[XFS_BTNUM_MAX] = { 51 const __uint32_t xfs_magics[XFS_BTNUM_MAX] = {
52 XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC 52 XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC
53 }; 53 };
54 54
55 /* 55 /*
56 * External routines. 56 * External routines.
57 */ 57 */
58 58
59 #ifdef DEBUG 59 #ifdef DEBUG
60 /* 60 /*
61 * Debug routine: check that keys are in the right order. 61 * Debug routine: check that keys are in the right order.
62 */ 62 */
63 void 63 void
64 xfs_btree_check_key( 64 xfs_btree_check_key(
65 xfs_btnum_t btnum, /* btree identifier */ 65 xfs_btnum_t btnum, /* btree identifier */
66 void *ak1, /* pointer to left (lower) key */ 66 void *ak1, /* pointer to left (lower) key */
67 void *ak2) /* pointer to right (higher) key */ 67 void *ak2) /* pointer to right (higher) key */
68 { 68 {
69 switch (btnum) { 69 switch (btnum) {
70 case XFS_BTNUM_BNO: { 70 case XFS_BTNUM_BNO: {
71 xfs_alloc_key_t *k1; 71 xfs_alloc_key_t *k1;
72 xfs_alloc_key_t *k2; 72 xfs_alloc_key_t *k2;
73 73
74 k1 = ak1; 74 k1 = ak1;
75 k2 = ak2; 75 k2 = ak2;
76 ASSERT(be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock)); 76 ASSERT(be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock));
77 break; 77 break;
78 } 78 }
79 case XFS_BTNUM_CNT: { 79 case XFS_BTNUM_CNT: {
80 xfs_alloc_key_t *k1; 80 xfs_alloc_key_t *k1;
81 xfs_alloc_key_t *k2; 81 xfs_alloc_key_t *k2;
82 82
83 k1 = ak1; 83 k1 = ak1;
84 k2 = ak2; 84 k2 = ak2;
85 ASSERT(be32_to_cpu(k1->ar_blockcount) < be32_to_cpu(k2->ar_blockcount) || 85 ASSERT(be32_to_cpu(k1->ar_blockcount) < be32_to_cpu(k2->ar_blockcount) ||
86 (k1->ar_blockcount == k2->ar_blockcount && 86 (k1->ar_blockcount == k2->ar_blockcount &&
87 be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock))); 87 be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock)));
88 break; 88 break;
89 } 89 }
90 case XFS_BTNUM_BMAP: { 90 case XFS_BTNUM_BMAP: {
91 xfs_bmbt_key_t *k1; 91 xfs_bmbt_key_t *k1;
92 xfs_bmbt_key_t *k2; 92 xfs_bmbt_key_t *k2;
93 93
94 k1 = ak1; 94 k1 = ak1;
95 k2 = ak2; 95 k2 = ak2;
96 ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff)); 96 ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff));
97 break; 97 break;
98 } 98 }
99 case XFS_BTNUM_INO: { 99 case XFS_BTNUM_INO: {
100 xfs_inobt_key_t *k1; 100 xfs_inobt_key_t *k1;
101 xfs_inobt_key_t *k2; 101 xfs_inobt_key_t *k2;
102 102
103 k1 = ak1; 103 k1 = ak1;
104 k2 = ak2; 104 k2 = ak2;
105 ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino)); 105 ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino));
106 break; 106 break;
107 } 107 }
108 default: 108 default:
109 ASSERT(0); 109 ASSERT(0);
110 } 110 }
111 } 111 }
112 112
113 /* 113 /*
114 * Debug routine: check that records are in the right order. 114 * Debug routine: check that records are in the right order.
115 */ 115 */
116 void 116 void
117 xfs_btree_check_rec( 117 xfs_btree_check_rec(
118 xfs_btnum_t btnum, /* btree identifier */ 118 xfs_btnum_t btnum, /* btree identifier */
119 void *ar1, /* pointer to left (lower) record */ 119 void *ar1, /* pointer to left (lower) record */
120 void *ar2) /* pointer to right (higher) record */ 120 void *ar2) /* pointer to right (higher) record */
121 { 121 {
122 switch (btnum) { 122 switch (btnum) {
123 case XFS_BTNUM_BNO: { 123 case XFS_BTNUM_BNO: {
124 xfs_alloc_rec_t *r1; 124 xfs_alloc_rec_t *r1;
125 xfs_alloc_rec_t *r2; 125 xfs_alloc_rec_t *r2;
126 126
127 r1 = ar1; 127 r1 = ar1;
128 r2 = ar2; 128 r2 = ar2;
129 ASSERT(be32_to_cpu(r1->ar_startblock) + 129 ASSERT(be32_to_cpu(r1->ar_startblock) +
130 be32_to_cpu(r1->ar_blockcount) <= 130 be32_to_cpu(r1->ar_blockcount) <=
131 be32_to_cpu(r2->ar_startblock)); 131 be32_to_cpu(r2->ar_startblock));
132 break; 132 break;
133 } 133 }
134 case XFS_BTNUM_CNT: { 134 case XFS_BTNUM_CNT: {
135 xfs_alloc_rec_t *r1; 135 xfs_alloc_rec_t *r1;
136 xfs_alloc_rec_t *r2; 136 xfs_alloc_rec_t *r2;
137 137
138 r1 = ar1; 138 r1 = ar1;
139 r2 = ar2; 139 r2 = ar2;
140 ASSERT(be32_to_cpu(r1->ar_blockcount) < be32_to_cpu(r2->ar_blockcount) || 140 ASSERT(be32_to_cpu(r1->ar_blockcount) < be32_to_cpu(r2->ar_blockcount) ||
141 (r1->ar_blockcount == r2->ar_blockcount && 141 (r1->ar_blockcount == r2->ar_blockcount &&
142 be32_to_cpu(r1->ar_startblock) < be32_to_cpu(r2->ar_startblock))); 142 be32_to_cpu(r1->ar_startblock) < be32_to_cpu(r2->ar_startblock)));
143 break; 143 break;
144 } 144 }
145 case XFS_BTNUM_BMAP: { 145 case XFS_BTNUM_BMAP: {
146 xfs_bmbt_rec_t *r1; 146 xfs_bmbt_rec_t *r1;
147 xfs_bmbt_rec_t *r2; 147 xfs_bmbt_rec_t *r2;
148 148
149 r1 = ar1; 149 r1 = ar1;
150 r2 = ar2; 150 r2 = ar2;
151 ASSERT(xfs_bmbt_disk_get_startoff(r1) + 151 ASSERT(xfs_bmbt_disk_get_startoff(r1) +
152 xfs_bmbt_disk_get_blockcount(r1) <= 152 xfs_bmbt_disk_get_blockcount(r1) <=
153 xfs_bmbt_disk_get_startoff(r2)); 153 xfs_bmbt_disk_get_startoff(r2));
154 break; 154 break;
155 } 155 }
156 case XFS_BTNUM_INO: { 156 case XFS_BTNUM_INO: {
157 xfs_inobt_rec_t *r1; 157 xfs_inobt_rec_t *r1;
158 xfs_inobt_rec_t *r2; 158 xfs_inobt_rec_t *r2;
159 159
160 r1 = ar1; 160 r1 = ar1;
161 r2 = ar2; 161 r2 = ar2;
162 ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <= 162 ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <=
163 be32_to_cpu(r2->ir_startino)); 163 be32_to_cpu(r2->ir_startino));
164 break; 164 break;
165 } 165 }
166 default: 166 default:
167 ASSERT(0); 167 ASSERT(0);
168 } 168 }
169 } 169 }
170 #endif /* DEBUG */ 170 #endif /* DEBUG */
171 171
172 int /* error (0 or EFSCORRUPTED) */ 172 int /* error (0 or EFSCORRUPTED) */
173 xfs_btree_check_lblock( 173 xfs_btree_check_lblock(
174 struct xfs_btree_cur *cur, /* btree cursor */ 174 struct xfs_btree_cur *cur, /* btree cursor */
175 struct xfs_btree_lblock *block, /* btree long form block pointer */ 175 struct xfs_btree_lblock *block, /* btree long form block pointer */
176 int level, /* level of the btree block */ 176 int level, /* level of the btree block */
177 struct xfs_buf *bp) /* buffer for block, if any */ 177 struct xfs_buf *bp) /* buffer for block, if any */
178 { 178 {
179 int lblock_ok; /* block passes checks */ 179 int lblock_ok; /* block passes checks */
180 struct xfs_mount *mp; /* file system mount point */ 180 struct xfs_mount *mp; /* file system mount point */
181 181
182 mp = cur->bc_mp; 182 mp = cur->bc_mp;
183 lblock_ok = 183 lblock_ok =
184 be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] && 184 be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
185 be16_to_cpu(block->bb_level) == level && 185 be16_to_cpu(block->bb_level) == level &&
186 be16_to_cpu(block->bb_numrecs) <= 186 be16_to_cpu(block->bb_numrecs) <=
187 cur->bc_ops->get_maxrecs(cur, level) && 187 cur->bc_ops->get_maxrecs(cur, level) &&
188 block->bb_leftsib && 188 block->bb_leftsib &&
189 (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO || 189 (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
190 XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) && 190 XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
191 block->bb_rightsib && 191 block->bb_rightsib &&
192 (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO || 192 (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
193 XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib))); 193 XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
194 if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, 194 if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp,
195 XFS_ERRTAG_BTREE_CHECK_LBLOCK, 195 XFS_ERRTAG_BTREE_CHECK_LBLOCK,
196 XFS_RANDOM_BTREE_CHECK_LBLOCK))) { 196 XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
197 if (bp) 197 if (bp)
198 xfs_buftrace("LBTREE ERROR", bp); 198 xfs_buftrace("LBTREE ERROR", bp);
199 XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW, 199 XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
200 mp); 200 mp);
201 return XFS_ERROR(EFSCORRUPTED); 201 return XFS_ERROR(EFSCORRUPTED);
202 } 202 }
203 return 0; 203 return 0;
204 } 204 }
205 205
206 int /* error (0 or EFSCORRUPTED) */ 206 int /* error (0 or EFSCORRUPTED) */
207 xfs_btree_check_sblock( 207 xfs_btree_check_sblock(
208 struct xfs_btree_cur *cur, /* btree cursor */ 208 struct xfs_btree_cur *cur, /* btree cursor */
209 struct xfs_btree_sblock *block, /* btree short form block pointer */ 209 struct xfs_btree_sblock *block, /* btree short form block pointer */
210 int level, /* level of the btree block */ 210 int level, /* level of the btree block */
211 struct xfs_buf *bp) /* buffer containing block */ 211 struct xfs_buf *bp) /* buffer containing block */
212 { 212 {
213 struct xfs_buf *agbp; /* buffer for ag. freespace struct */ 213 struct xfs_buf *agbp; /* buffer for ag. freespace struct */
214 struct xfs_agf *agf; /* ag. freespace structure */ 214 struct xfs_agf *agf; /* ag. freespace structure */
215 xfs_agblock_t agflen; /* native ag. freespace length */ 215 xfs_agblock_t agflen; /* native ag. freespace length */
216 int sblock_ok; /* block passes checks */ 216 int sblock_ok; /* block passes checks */
217 217
218 agbp = cur->bc_private.a.agbp; 218 agbp = cur->bc_private.a.agbp;
219 agf = XFS_BUF_TO_AGF(agbp); 219 agf = XFS_BUF_TO_AGF(agbp);
220 agflen = be32_to_cpu(agf->agf_length); 220 agflen = be32_to_cpu(agf->agf_length);
221 sblock_ok = 221 sblock_ok =
222 be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] && 222 be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
223 be16_to_cpu(block->bb_level) == level && 223 be16_to_cpu(block->bb_level) == level &&
224 be16_to_cpu(block->bb_numrecs) <= 224 be16_to_cpu(block->bb_numrecs) <=
225 cur->bc_ops->get_maxrecs(cur, level) && 225 cur->bc_ops->get_maxrecs(cur, level) &&
226 (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK || 226 (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK ||
227 be32_to_cpu(block->bb_leftsib) < agflen) && 227 be32_to_cpu(block->bb_leftsib) < agflen) &&
228 block->bb_leftsib && 228 block->bb_leftsib &&
229 (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK || 229 (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK ||
230 be32_to_cpu(block->bb_rightsib) < agflen) && 230 be32_to_cpu(block->bb_rightsib) < agflen) &&
231 block->bb_rightsib; 231 block->bb_rightsib;
232 if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp, 232 if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
233 XFS_ERRTAG_BTREE_CHECK_SBLOCK, 233 XFS_ERRTAG_BTREE_CHECK_SBLOCK,
234 XFS_RANDOM_BTREE_CHECK_SBLOCK))) { 234 XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
235 if (bp) 235 if (bp)
236 xfs_buftrace("SBTREE ERROR", bp); 236 xfs_buftrace("SBTREE ERROR", bp);
237 XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW, 237 XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW,
238 cur->bc_mp); 238 cur->bc_mp);
239 return XFS_ERROR(EFSCORRUPTED); 239 return XFS_ERROR(EFSCORRUPTED);
240 } 240 }
241 return 0; 241 return 0;
242 } 242 }
243 243
244 /* 244 /*
245 * Debug routine: check that block header is ok. 245 * Debug routine: check that block header is ok.
246 */ 246 */
247 int 247 int
248 xfs_btree_check_block( 248 xfs_btree_check_block(
249 struct xfs_btree_cur *cur, /* btree cursor */ 249 struct xfs_btree_cur *cur, /* btree cursor */
250 struct xfs_btree_block *block, /* generic btree block pointer */ 250 struct xfs_btree_block *block, /* generic btree block pointer */
251 int level, /* level of the btree block */ 251 int level, /* level of the btree block */
252 struct xfs_buf *bp) /* buffer containing block, if any */ 252 struct xfs_buf *bp) /* buffer containing block, if any */
253 { 253 {
254 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 254 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
255 return xfs_btree_check_lblock(cur, 255 return xfs_btree_check_lblock(cur,
256 (struct xfs_btree_lblock *)block, level, bp); 256 (struct xfs_btree_lblock *)block, level, bp);
257 } else { 257 } else {
258 return xfs_btree_check_sblock(cur, 258 return xfs_btree_check_sblock(cur,
259 (struct xfs_btree_sblock *)block, level, bp); 259 (struct xfs_btree_sblock *)block, level, bp);
260 } 260 }
261 } 261 }
262 262
263 /* 263 /*
264 * Check that (long) pointer is ok. 264 * Check that (long) pointer is ok.
265 */ 265 */
266 int /* error (0 or EFSCORRUPTED) */ 266 int /* error (0 or EFSCORRUPTED) */
267 xfs_btree_check_lptr( 267 xfs_btree_check_lptr(
268 struct xfs_btree_cur *cur, /* btree cursor */ 268 struct xfs_btree_cur *cur, /* btree cursor */
269 xfs_dfsbno_t bno, /* btree block disk address */ 269 xfs_dfsbno_t bno, /* btree block disk address */
270 int level) /* btree block level */ 270 int level) /* btree block level */
271 { 271 {
272 XFS_WANT_CORRUPTED_RETURN( 272 XFS_WANT_CORRUPTED_RETURN(
273 level > 0 && 273 level > 0 &&
274 bno != NULLDFSBNO && 274 bno != NULLDFSBNO &&
275 XFS_FSB_SANITY_CHECK(cur->bc_mp, bno)); 275 XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
276 return 0; 276 return 0;
277 } 277 }
278 278
279 /* 279 /*
280 * Check that (short) pointer is ok. 280 * Check that (short) pointer is ok.
281 */ 281 */
282 int /* error (0 or EFSCORRUPTED) */ 282 int /* error (0 or EFSCORRUPTED) */
283 xfs_btree_check_sptr( 283 xfs_btree_check_sptr(
284 struct xfs_btree_cur *cur, /* btree cursor */ 284 struct xfs_btree_cur *cur, /* btree cursor */
285 xfs_agblock_t bno, /* btree block disk address */ 285 xfs_agblock_t bno, /* btree block disk address */
286 int level) /* btree block level */ 286 int level) /* btree block level */
287 { 287 {
288 xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks; 288 xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks;
289 289
290 XFS_WANT_CORRUPTED_RETURN( 290 XFS_WANT_CORRUPTED_RETURN(
291 level > 0 && 291 level > 0 &&
292 bno != NULLAGBLOCK && 292 bno != NULLAGBLOCK &&
293 bno != 0 && 293 bno != 0 &&
294 bno < agblocks); 294 bno < agblocks);
295 return 0; 295 return 0;
296 } 296 }
297 297
298 /* 298 /*
299 * Check that block ptr is ok. 299 * Check that block ptr is ok.
300 */ 300 */
301 int /* error (0 or EFSCORRUPTED) */ 301 int /* error (0 or EFSCORRUPTED) */
302 xfs_btree_check_ptr( 302 xfs_btree_check_ptr(
303 struct xfs_btree_cur *cur, /* btree cursor */ 303 struct xfs_btree_cur *cur, /* btree cursor */
304 union xfs_btree_ptr *ptr, /* btree block disk address */ 304 union xfs_btree_ptr *ptr, /* btree block disk address */
305 int index, /* offset from ptr to check */ 305 int index, /* offset from ptr to check */
306 int level) /* btree block level */ 306 int level) /* btree block level */
307 { 307 {
308 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 308 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
309 return xfs_btree_check_lptr(cur, 309 return xfs_btree_check_lptr(cur,
310 be64_to_cpu((&ptr->l)[index]), level); 310 be64_to_cpu((&ptr->l)[index]), level);
311 } else { 311 } else {
312 return xfs_btree_check_sptr(cur, 312 return xfs_btree_check_sptr(cur,
313 be32_to_cpu((&ptr->s)[index]), level); 313 be32_to_cpu((&ptr->s)[index]), level);
314 } 314 }
315 } 315 }
316 316
317 /* 317 /*
318 * Delete the btree cursor. 318 * Delete the btree cursor.
319 */ 319 */
320 void 320 void
321 xfs_btree_del_cursor( 321 xfs_btree_del_cursor(
322 xfs_btree_cur_t *cur, /* btree cursor */ 322 xfs_btree_cur_t *cur, /* btree cursor */
323 int error) /* del because of error */ 323 int error) /* del because of error */
324 { 324 {
325 int i; /* btree level */ 325 int i; /* btree level */
326 326
327 /* 327 /*
328 * Clear the buffer pointers, and release the buffers. 328 * Clear the buffer pointers, and release the buffers.
329 * If we're doing this in the face of an error, we 329 * If we're doing this in the face of an error, we
330 * need to make sure to inspect all of the entries 330 * need to make sure to inspect all of the entries
331 * in the bc_bufs array for buffers to be unlocked. 331 * in the bc_bufs array for buffers to be unlocked.
332 * This is because some of the btree code works from 332 * This is because some of the btree code works from
333 * level n down to 0, and if we get an error along 333 * level n down to 0, and if we get an error along
334 * the way we won't have initialized all the entries 334 * the way we won't have initialized all the entries
335 * down to 0. 335 * down to 0.
336 */ 336 */
337 for (i = 0; i < cur->bc_nlevels; i++) { 337 for (i = 0; i < cur->bc_nlevels; i++) {
338 if (cur->bc_bufs[i]) 338 if (cur->bc_bufs[i])
339 xfs_btree_setbuf(cur, i, NULL); 339 xfs_btree_setbuf(cur, i, NULL);
340 else if (!error) 340 else if (!error)
341 break; 341 break;
342 } 342 }
343 /* 343 /*
344 * Can't free a bmap cursor without having dealt with the 344 * Can't free a bmap cursor without having dealt with the
345 * allocated indirect blocks' accounting. 345 * allocated indirect blocks' accounting.
346 */ 346 */
347 ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || 347 ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP ||
348 cur->bc_private.b.allocated == 0); 348 cur->bc_private.b.allocated == 0);
349 /* 349 /*
350 * Free the cursor. 350 * Free the cursor.
351 */ 351 */
352 kmem_zone_free(xfs_btree_cur_zone, cur); 352 kmem_zone_free(xfs_btree_cur_zone, cur);
353 } 353 }
354 354
355 /* 355 /*
356 * Duplicate the btree cursor. 356 * Duplicate the btree cursor.
357 * Allocate a new one, copy the record, re-get the buffers. 357 * Allocate a new one, copy the record, re-get the buffers.
358 */ 358 */
359 int /* error */ 359 int /* error */
360 xfs_btree_dup_cursor( 360 xfs_btree_dup_cursor(
361 xfs_btree_cur_t *cur, /* input cursor */ 361 xfs_btree_cur_t *cur, /* input cursor */
362 xfs_btree_cur_t **ncur) /* output cursor */ 362 xfs_btree_cur_t **ncur) /* output cursor */
363 { 363 {
364 xfs_buf_t *bp; /* btree block's buffer pointer */ 364 xfs_buf_t *bp; /* btree block's buffer pointer */
365 int error; /* error return value */ 365 int error; /* error return value */
366 int i; /* level number of btree block */ 366 int i; /* level number of btree block */
367 xfs_mount_t *mp; /* mount structure for filesystem */ 367 xfs_mount_t *mp; /* mount structure for filesystem */
368 xfs_btree_cur_t *new; /* new cursor value */ 368 xfs_btree_cur_t *new; /* new cursor value */
369 xfs_trans_t *tp; /* transaction pointer, can be NULL */ 369 xfs_trans_t *tp; /* transaction pointer, can be NULL */
370 370
371 tp = cur->bc_tp; 371 tp = cur->bc_tp;
372 mp = cur->bc_mp; 372 mp = cur->bc_mp;
373 373
374 /* 374 /*
375 * Allocate a new cursor like the old one. 375 * Allocate a new cursor like the old one.
376 */ 376 */
377 new = cur->bc_ops->dup_cursor(cur); 377 new = cur->bc_ops->dup_cursor(cur);
378 378
379 /* 379 /*
380 * Copy the record currently in the cursor. 380 * Copy the record currently in the cursor.
381 */ 381 */
382 new->bc_rec = cur->bc_rec; 382 new->bc_rec = cur->bc_rec;
383 383
384 /* 384 /*
385 * For each level current, re-get the buffer and copy the ptr value. 385 * For each level current, re-get the buffer and copy the ptr value.
386 */ 386 */
387 for (i = 0; i < new->bc_nlevels; i++) { 387 for (i = 0; i < new->bc_nlevels; i++) {
388 new->bc_ptrs[i] = cur->bc_ptrs[i]; 388 new->bc_ptrs[i] = cur->bc_ptrs[i];
389 new->bc_ra[i] = cur->bc_ra[i]; 389 new->bc_ra[i] = cur->bc_ra[i];
390 if ((bp = cur->bc_bufs[i])) { 390 if ((bp = cur->bc_bufs[i])) {
391 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 391 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
392 XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) { 392 XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) {
393 xfs_btree_del_cursor(new, error); 393 xfs_btree_del_cursor(new, error);
394 *ncur = NULL; 394 *ncur = NULL;
395 return error; 395 return error;
396 } 396 }
397 new->bc_bufs[i] = bp; 397 new->bc_bufs[i] = bp;
398 ASSERT(bp); 398 ASSERT(bp);
399 ASSERT(!XFS_BUF_GETERROR(bp)); 399 ASSERT(!XFS_BUF_GETERROR(bp));
400 } else 400 } else
401 new->bc_bufs[i] = NULL; 401 new->bc_bufs[i] = NULL;
402 } 402 }
403 *ncur = new; 403 *ncur = new;
404 return 0; 404 return 0;
405 } 405 }
406 406
407 /* 407 /*
408 * XFS btree block layout and addressing: 408 * XFS btree block layout and addressing:
409 * 409 *
410 * There are two types of blocks in the btree: leaf and non-leaf blocks. 410 * There are two types of blocks in the btree: leaf and non-leaf blocks.
411 * 411 *
412 * The leaf record start with a header then followed by records containing 412 * The leaf record start with a header then followed by records containing
413 * the values. A non-leaf block also starts with the same header, and 413 * the values. A non-leaf block also starts with the same header, and
414 * then first contains lookup keys followed by an equal number of pointers 414 * then first contains lookup keys followed by an equal number of pointers
415 * to the btree blocks at the previous level. 415 * to the btree blocks at the previous level.
416 * 416 *
417 * +--------+-------+-------+-------+-------+-------+-------+ 417 * +--------+-------+-------+-------+-------+-------+-------+
418 * Leaf: | header | rec 1 | rec 2 | rec 3 | rec 4 | rec 5 | rec N | 418 * Leaf: | header | rec 1 | rec 2 | rec 3 | rec 4 | rec 5 | rec N |
419 * +--------+-------+-------+-------+-------+-------+-------+ 419 * +--------+-------+-------+-------+-------+-------+-------+
420 * 420 *
421 * +--------+-------+-------+-------+-------+-------+-------+ 421 * +--------+-------+-------+-------+-------+-------+-------+
422 * Non-Leaf: | header | key 1 | key 2 | key N | ptr 1 | ptr 2 | ptr N | 422 * Non-Leaf: | header | key 1 | key 2 | key N | ptr 1 | ptr 2 | ptr N |
423 * +--------+-------+-------+-------+-------+-------+-------+ 423 * +--------+-------+-------+-------+-------+-------+-------+
424 * 424 *
425 * The header is called struct xfs_btree_block for reasons better left unknown 425 * The header is called struct xfs_btree_block for reasons better left unknown
426 * and comes in different versions for short (32bit) and long (64bit) block 426 * and comes in different versions for short (32bit) and long (64bit) block
427 * pointers. The record and key structures are defined by the btree instances 427 * pointers. The record and key structures are defined by the btree instances
428 * and opaque to the btree core. The block pointers are simple disk endian 428 * and opaque to the btree core. The block pointers are simple disk endian
429 * integers, available in a short (32bit) and long (64bit) variant. 429 * integers, available in a short (32bit) and long (64bit) variant.
430 * 430 *
431 * The helpers below calculate the offset of a given record, key or pointer 431 * The helpers below calculate the offset of a given record, key or pointer
432 * into a btree block (xfs_btree_*_offset) or return a pointer to the given 432 * into a btree block (xfs_btree_*_offset) or return a pointer to the given
433 * record, key or pointer (xfs_btree_*_addr). Note that all addressing 433 * record, key or pointer (xfs_btree_*_addr). Note that all addressing
434 * inside the btree block is done using indices starting at one, not zero! 434 * inside the btree block is done using indices starting at one, not zero!
435 */ 435 */
436 436
437 /* 437 /*
438 * Return size of the btree block header for this btree instance. 438 * Return size of the btree block header for this btree instance.
439 */ 439 */
440 static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur) 440 static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
441 { 441 {
442 return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? 442 return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
443 sizeof(struct xfs_btree_lblock) : 443 sizeof(struct xfs_btree_lblock) :
444 sizeof(struct xfs_btree_sblock); 444 sizeof(struct xfs_btree_sblock);
445 } 445 }
446 446
447 /* 447 /*
448 * Return size of btree block pointers for this btree instance. 448 * Return size of btree block pointers for this btree instance.
449 */ 449 */
450 static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur) 450 static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur)
451 { 451 {
452 return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? 452 return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
453 sizeof(__be64) : sizeof(__be32); 453 sizeof(__be64) : sizeof(__be32);
454 } 454 }
455 455
456 /* 456 /*
457 * Calculate offset of the n-th record in a btree block. 457 * Calculate offset of the n-th record in a btree block.
458 */ 458 */
459 STATIC size_t 459 STATIC size_t
460 xfs_btree_rec_offset( 460 xfs_btree_rec_offset(
461 struct xfs_btree_cur *cur, 461 struct xfs_btree_cur *cur,
462 int n) 462 int n)
463 { 463 {
464 return xfs_btree_block_len(cur) + 464 return xfs_btree_block_len(cur) +
465 (n - 1) * cur->bc_ops->rec_len; 465 (n - 1) * cur->bc_ops->rec_len;
466 } 466 }
467 467
468 /* 468 /*
469 * Calculate offset of the n-th key in a btree block. 469 * Calculate offset of the n-th key in a btree block.
470 */ 470 */
471 STATIC size_t 471 STATIC size_t
472 xfs_btree_key_offset( 472 xfs_btree_key_offset(
473 struct xfs_btree_cur *cur, 473 struct xfs_btree_cur *cur,
474 int n) 474 int n)
475 { 475 {
476 return xfs_btree_block_len(cur) + 476 return xfs_btree_block_len(cur) +
477 (n - 1) * cur->bc_ops->key_len; 477 (n - 1) * cur->bc_ops->key_len;
478 } 478 }
479 479
480 /* 480 /*
481 * Calculate offset of the n-th block pointer in a btree block. 481 * Calculate offset of the n-th block pointer in a btree block.
482 */ 482 */
483 STATIC size_t 483 STATIC size_t
484 xfs_btree_ptr_offset( 484 xfs_btree_ptr_offset(
485 struct xfs_btree_cur *cur, 485 struct xfs_btree_cur *cur,
486 int n, 486 int n,
487 int level) 487 int level)
488 { 488 {
489 return xfs_btree_block_len(cur) + 489 return xfs_btree_block_len(cur) +
490 cur->bc_ops->get_maxrecs(cur, level) * cur->bc_ops->key_len + 490 cur->bc_ops->get_maxrecs(cur, level) * cur->bc_ops->key_len +
491 (n - 1) * xfs_btree_ptr_len(cur); 491 (n - 1) * xfs_btree_ptr_len(cur);
492 } 492 }
493 493
494 /* 494 /*
495 * Return a pointer to the n-th record in the btree block. 495 * Return a pointer to the n-th record in the btree block.
496 */ 496 */
497 STATIC union xfs_btree_rec * 497 STATIC union xfs_btree_rec *
498 xfs_btree_rec_addr( 498 xfs_btree_rec_addr(
499 struct xfs_btree_cur *cur, 499 struct xfs_btree_cur *cur,
500 int n, 500 int n,
501 struct xfs_btree_block *block) 501 struct xfs_btree_block *block)
502 { 502 {
503 return (union xfs_btree_rec *) 503 return (union xfs_btree_rec *)
504 ((char *)block + xfs_btree_rec_offset(cur, n)); 504 ((char *)block + xfs_btree_rec_offset(cur, n));
505 } 505 }
506 506
507 /* 507 /*
508 * Return a pointer to the n-th key in the btree block. 508 * Return a pointer to the n-th key in the btree block.
509 */ 509 */
510 STATIC union xfs_btree_key * 510 STATIC union xfs_btree_key *
511 xfs_btree_key_addr( 511 xfs_btree_key_addr(
512 struct xfs_btree_cur *cur, 512 struct xfs_btree_cur *cur,
513 int n, 513 int n,
514 struct xfs_btree_block *block) 514 struct xfs_btree_block *block)
515 { 515 {
516 return (union xfs_btree_key *) 516 return (union xfs_btree_key *)
517 ((char *)block + xfs_btree_key_offset(cur, n)); 517 ((char *)block + xfs_btree_key_offset(cur, n));
518 } 518 }
519 519
520 /* 520 /*
521 * Return a pointer to the n-th block pointer in the btree block. 521 * Return a pointer to the n-th block pointer in the btree block.
522 */ 522 */
523 STATIC union xfs_btree_ptr * 523 STATIC union xfs_btree_ptr *
524 xfs_btree_ptr_addr( 524 xfs_btree_ptr_addr(
525 struct xfs_btree_cur *cur, 525 struct xfs_btree_cur *cur,
526 int n, 526 int n,
527 struct xfs_btree_block *block) 527 struct xfs_btree_block *block)
528 { 528 {
529 int level = xfs_btree_get_level(block); 529 int level = xfs_btree_get_level(block);
530 530
531 ASSERT(block->bb_level != 0); 531 ASSERT(block->bb_level != 0);
532 532
533 return (union xfs_btree_ptr *) 533 return (union xfs_btree_ptr *)
534 ((char *)block + xfs_btree_ptr_offset(cur, n, level)); 534 ((char *)block + xfs_btree_ptr_offset(cur, n, level));
535 } 535 }
536 536
537 /* 537 /*
538 * Get a the root block which is stored in the inode. 538 * Get a the root block which is stored in the inode.
539 * 539 *
540 * For now this btree implementation assumes the btree root is always 540 * For now this btree implementation assumes the btree root is always
541 * stored in the if_broot field of an inode fork. 541 * stored in the if_broot field of an inode fork.
542 */ 542 */
543 STATIC struct xfs_btree_block * 543 STATIC struct xfs_btree_block *
544 xfs_btree_get_iroot( 544 xfs_btree_get_iroot(
545 struct xfs_btree_cur *cur) 545 struct xfs_btree_cur *cur)
546 { 546 {
547 struct xfs_ifork *ifp; 547 struct xfs_ifork *ifp;
548 548
549 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork); 549 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork);
550 return (struct xfs_btree_block *)ifp->if_broot; 550 return (struct xfs_btree_block *)ifp->if_broot;
551 } 551 }
552 552
553 /* 553 /*
554 * Retrieve the block pointer from the cursor at the given level. 554 * Retrieve the block pointer from the cursor at the given level.
555 * This may be an inode btree root or from a buffer. 555 * This may be an inode btree root or from a buffer.
556 */ 556 */
557 STATIC struct xfs_btree_block * /* generic btree block pointer */ 557 STATIC struct xfs_btree_block * /* generic btree block pointer */
558 xfs_btree_get_block( 558 xfs_btree_get_block(
559 struct xfs_btree_cur *cur, /* btree cursor */ 559 struct xfs_btree_cur *cur, /* btree cursor */
560 int level, /* level in btree */ 560 int level, /* level in btree */
561 struct xfs_buf **bpp) /* buffer containing the block */ 561 struct xfs_buf **bpp) /* buffer containing the block */
562 { 562 {
563 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && 563 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
564 (level == cur->bc_nlevels - 1)) { 564 (level == cur->bc_nlevels - 1)) {
565 *bpp = NULL; 565 *bpp = NULL;
566 return xfs_btree_get_iroot(cur); 566 return xfs_btree_get_iroot(cur);
567 } 567 }
568 568
569 *bpp = cur->bc_bufs[level]; 569 *bpp = cur->bc_bufs[level];
570 return XFS_BUF_TO_BLOCK(*bpp); 570 return XFS_BUF_TO_BLOCK(*bpp);
571 } 571 }
572 572
573 /* 573 /*
574 * Get a buffer for the block, return it with no data read. 574 * Get a buffer for the block, return it with no data read.
575 * Long-form addressing. 575 * Long-form addressing.
576 */ 576 */
577 xfs_buf_t * /* buffer for fsbno */ 577 xfs_buf_t * /* buffer for fsbno */
578 xfs_btree_get_bufl( 578 xfs_btree_get_bufl(
579 xfs_mount_t *mp, /* file system mount point */ 579 xfs_mount_t *mp, /* file system mount point */
580 xfs_trans_t *tp, /* transaction pointer */ 580 xfs_trans_t *tp, /* transaction pointer */
581 xfs_fsblock_t fsbno, /* file system block number */ 581 xfs_fsblock_t fsbno, /* file system block number */
582 uint lock) /* lock flags for get_buf */ 582 uint lock) /* lock flags for get_buf */
583 { 583 {
584 xfs_buf_t *bp; /* buffer pointer (return value) */ 584 xfs_buf_t *bp; /* buffer pointer (return value) */
585 xfs_daddr_t d; /* real disk block address */ 585 xfs_daddr_t d; /* real disk block address */
586 586
587 ASSERT(fsbno != NULLFSBLOCK); 587 ASSERT(fsbno != NULLFSBLOCK);
588 d = XFS_FSB_TO_DADDR(mp, fsbno); 588 d = XFS_FSB_TO_DADDR(mp, fsbno);
589 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); 589 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
590 ASSERT(bp); 590 ASSERT(bp);
591 ASSERT(!XFS_BUF_GETERROR(bp)); 591 ASSERT(!XFS_BUF_GETERROR(bp));
592 return bp; 592 return bp;
593 } 593 }
594 594
595 /* 595 /*
596 * Get a buffer for the block, return it with no data read. 596 * Get a buffer for the block, return it with no data read.
597 * Short-form addressing. 597 * Short-form addressing.
598 */ 598 */
599 xfs_buf_t * /* buffer for agno/agbno */ 599 xfs_buf_t * /* buffer for agno/agbno */
600 xfs_btree_get_bufs( 600 xfs_btree_get_bufs(
601 xfs_mount_t *mp, /* file system mount point */ 601 xfs_mount_t *mp, /* file system mount point */
602 xfs_trans_t *tp, /* transaction pointer */ 602 xfs_trans_t *tp, /* transaction pointer */
603 xfs_agnumber_t agno, /* allocation group number */ 603 xfs_agnumber_t agno, /* allocation group number */
604 xfs_agblock_t agbno, /* allocation group block number */ 604 xfs_agblock_t agbno, /* allocation group block number */
605 uint lock) /* lock flags for get_buf */ 605 uint lock) /* lock flags for get_buf */
606 { 606 {
607 xfs_buf_t *bp; /* buffer pointer (return value) */ 607 xfs_buf_t *bp; /* buffer pointer (return value) */
608 xfs_daddr_t d; /* real disk block address */ 608 xfs_daddr_t d; /* real disk block address */
609 609
610 ASSERT(agno != NULLAGNUMBER); 610 ASSERT(agno != NULLAGNUMBER);
611 ASSERT(agbno != NULLAGBLOCK); 611 ASSERT(agbno != NULLAGBLOCK);
612 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 612 d = XFS_AGB_TO_DADDR(mp, agno, agbno);
613 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); 613 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
614 ASSERT(bp); 614 ASSERT(bp);
615 ASSERT(!XFS_BUF_GETERROR(bp)); 615 ASSERT(!XFS_BUF_GETERROR(bp));
616 return bp; 616 return bp;
617 } 617 }
618 618
619 /* 619 /*
620 * Check for the cursor referring to the last block at the given level. 620 * Check for the cursor referring to the last block at the given level.
621 */ 621 */
622 int /* 1=is last block, 0=not last block */ 622 int /* 1=is last block, 0=not last block */
623 xfs_btree_islastblock( 623 xfs_btree_islastblock(
624 xfs_btree_cur_t *cur, /* btree cursor */ 624 xfs_btree_cur_t *cur, /* btree cursor */
625 int level) /* level to check */ 625 int level) /* level to check */
626 { 626 {
627 xfs_btree_block_t *block; /* generic btree block pointer */ 627 xfs_btree_block_t *block; /* generic btree block pointer */
628 xfs_buf_t *bp; /* buffer containing block */ 628 xfs_buf_t *bp; /* buffer containing block */
629 629
630 block = xfs_btree_get_block(cur, level, &bp); 630 block = xfs_btree_get_block(cur, level, &bp);
631 xfs_btree_check_block(cur, block, level, bp); 631 xfs_btree_check_block(cur, block, level, bp);
632 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 632 if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
633 return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO; 633 return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO;
634 else 634 else
635 return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK; 635 return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK;
636 } 636 }
637 637
638 /* 638 /*
639 * Change the cursor to point to the first record at the given level. 639 * Change the cursor to point to the first record at the given level.
640 * Other levels are unaffected. 640 * Other levels are unaffected.
641 */ 641 */
642 int /* success=1, failure=0 */ 642 int /* success=1, failure=0 */
643 xfs_btree_firstrec( 643 xfs_btree_firstrec(
644 xfs_btree_cur_t *cur, /* btree cursor */ 644 xfs_btree_cur_t *cur, /* btree cursor */
645 int level) /* level to change */ 645 int level) /* level to change */
646 { 646 {
647 xfs_btree_block_t *block; /* generic btree block pointer */ 647 xfs_btree_block_t *block; /* generic btree block pointer */
648 xfs_buf_t *bp; /* buffer containing block */ 648 xfs_buf_t *bp; /* buffer containing block */
649 649
650 /* 650 /*
651 * Get the block pointer for this level. 651 * Get the block pointer for this level.
652 */ 652 */
653 block = xfs_btree_get_block(cur, level, &bp); 653 block = xfs_btree_get_block(cur, level, &bp);
654 xfs_btree_check_block(cur, block, level, bp); 654 xfs_btree_check_block(cur, block, level, bp);
655 /* 655 /*
656 * It's empty, there is no such record. 656 * It's empty, there is no such record.
657 */ 657 */
658 if (!block->bb_numrecs) 658 if (!block->bb_numrecs)
659 return 0; 659 return 0;
660 /* 660 /*
661 * Set the ptr value to 1, that's the first record/key. 661 * Set the ptr value to 1, that's the first record/key.
662 */ 662 */
663 cur->bc_ptrs[level] = 1; 663 cur->bc_ptrs[level] = 1;
664 return 1; 664 return 1;
665 } 665 }
666 666
667 /* 667 /*
668 * Change the cursor to point to the last record in the current block 668 * Change the cursor to point to the last record in the current block
669 * at the given level. Other levels are unaffected. 669 * at the given level. Other levels are unaffected.
670 */ 670 */
671 int /* success=1, failure=0 */ 671 int /* success=1, failure=0 */
672 xfs_btree_lastrec( 672 xfs_btree_lastrec(
673 xfs_btree_cur_t *cur, /* btree cursor */ 673 xfs_btree_cur_t *cur, /* btree cursor */
674 int level) /* level to change */ 674 int level) /* level to change */
675 { 675 {
676 xfs_btree_block_t *block; /* generic btree block pointer */ 676 xfs_btree_block_t *block; /* generic btree block pointer */
677 xfs_buf_t *bp; /* buffer containing block */ 677 xfs_buf_t *bp; /* buffer containing block */
678 678
679 /* 679 /*
680 * Get the block pointer for this level. 680 * Get the block pointer for this level.
681 */ 681 */
682 block = xfs_btree_get_block(cur, level, &bp); 682 block = xfs_btree_get_block(cur, level, &bp);
683 xfs_btree_check_block(cur, block, level, bp); 683 xfs_btree_check_block(cur, block, level, bp);
684 /* 684 /*
685 * It's empty, there is no such record. 685 * It's empty, there is no such record.
686 */ 686 */
687 if (!block->bb_numrecs) 687 if (!block->bb_numrecs)
688 return 0; 688 return 0;
689 /* 689 /*
690 * Set the ptr value to numrecs, that's the last record/key. 690 * Set the ptr value to numrecs, that's the last record/key.
691 */ 691 */
692 cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs); 692 cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs);
693 return 1; 693 return 1;
694 } 694 }
695 695
696 /* 696 /*
697 * Compute first and last byte offsets for the fields given. 697 * Compute first and last byte offsets for the fields given.
698 * Interprets the offsets table, which contains struct field offsets. 698 * Interprets the offsets table, which contains struct field offsets.
699 */ 699 */
700 void 700 void
701 xfs_btree_offsets( 701 xfs_btree_offsets(
702 __int64_t fields, /* bitmask of fields */ 702 __int64_t fields, /* bitmask of fields */
703 const short *offsets, /* table of field offsets */ 703 const short *offsets, /* table of field offsets */
704 int nbits, /* number of bits to inspect */ 704 int nbits, /* number of bits to inspect */
705 int *first, /* output: first byte offset */ 705 int *first, /* output: first byte offset */
706 int *last) /* output: last byte offset */ 706 int *last) /* output: last byte offset */
707 { 707 {
708 int i; /* current bit number */ 708 int i; /* current bit number */
709 __int64_t imask; /* mask for current bit number */ 709 __int64_t imask; /* mask for current bit number */
710 710
711 ASSERT(fields != 0); 711 ASSERT(fields != 0);
712 /* 712 /*
713 * Find the lowest bit, so the first byte offset. 713 * Find the lowest bit, so the first byte offset.
714 */ 714 */
715 for (i = 0, imask = 1LL; ; i++, imask <<= 1) { 715 for (i = 0, imask = 1LL; ; i++, imask <<= 1) {
716 if (imask & fields) { 716 if (imask & fields) {
717 *first = offsets[i]; 717 *first = offsets[i];
718 break; 718 break;
719 } 719 }
720 } 720 }
721 /* 721 /*
722 * Find the highest bit, so the last byte offset. 722 * Find the highest bit, so the last byte offset.
723 */ 723 */
724 for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) { 724 for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) {
725 if (imask & fields) { 725 if (imask & fields) {
726 *last = offsets[i + 1] - 1; 726 *last = offsets[i + 1] - 1;
727 break; 727 break;
728 } 728 }
729 } 729 }
730 } 730 }
731 731
732 /* 732 /*
733 * Get a buffer for the block, return it read in. 733 * Get a buffer for the block, return it read in.
734 * Long-form addressing. 734 * Long-form addressing.
735 */ 735 */
736 int /* error */ 736 int /* error */
737 xfs_btree_read_bufl( 737 xfs_btree_read_bufl(
738 xfs_mount_t *mp, /* file system mount point */ 738 xfs_mount_t *mp, /* file system mount point */
739 xfs_trans_t *tp, /* transaction pointer */ 739 xfs_trans_t *tp, /* transaction pointer */
740 xfs_fsblock_t fsbno, /* file system block number */ 740 xfs_fsblock_t fsbno, /* file system block number */
741 uint lock, /* lock flags for read_buf */ 741 uint lock, /* lock flags for read_buf */
742 xfs_buf_t **bpp, /* buffer for fsbno */ 742 xfs_buf_t **bpp, /* buffer for fsbno */
743 int refval) /* ref count value for buffer */ 743 int refval) /* ref count value for buffer */
744 { 744 {
745 xfs_buf_t *bp; /* return value */ 745 xfs_buf_t *bp; /* return value */
746 xfs_daddr_t d; /* real disk block address */ 746 xfs_daddr_t d; /* real disk block address */
747 int error; 747 int error;
748 748
749 ASSERT(fsbno != NULLFSBLOCK); 749 ASSERT(fsbno != NULLFSBLOCK);
750 d = XFS_FSB_TO_DADDR(mp, fsbno); 750 d = XFS_FSB_TO_DADDR(mp, fsbno);
751 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 751 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
752 mp->m_bsize, lock, &bp))) { 752 mp->m_bsize, lock, &bp))) {
753 return error; 753 return error;
754 } 754 }
755 ASSERT(!bp || !XFS_BUF_GETERROR(bp)); 755 ASSERT(!bp || !XFS_BUF_GETERROR(bp));
756 if (bp != NULL) { 756 if (bp != NULL) {
757 XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); 757 XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
758 } 758 }
759 *bpp = bp; 759 *bpp = bp;
760 return 0; 760 return 0;
761 } 761 }
762 762
763 /* 763 /*
764 * Get a buffer for the block, return it read in. 764 * Get a buffer for the block, return it read in.
765 * Short-form addressing. 765 * Short-form addressing.
766 */ 766 */
767 int /* error */ 767 int /* error */
768 xfs_btree_read_bufs( 768 xfs_btree_read_bufs(
769 xfs_mount_t *mp, /* file system mount point */ 769 xfs_mount_t *mp, /* file system mount point */
770 xfs_trans_t *tp, /* transaction pointer */ 770 xfs_trans_t *tp, /* transaction pointer */
771 xfs_agnumber_t agno, /* allocation group number */ 771 xfs_agnumber_t agno, /* allocation group number */
772 xfs_agblock_t agbno, /* allocation group block number */ 772 xfs_agblock_t agbno, /* allocation group block number */
773 uint lock, /* lock flags for read_buf */ 773 uint lock, /* lock flags for read_buf */
774 xfs_buf_t **bpp, /* buffer for agno/agbno */ 774 xfs_buf_t **bpp, /* buffer for agno/agbno */
775 int refval) /* ref count value for buffer */ 775 int refval) /* ref count value for buffer */
776 { 776 {
777 xfs_buf_t *bp; /* return value */ 777 xfs_buf_t *bp; /* return value */
778 xfs_daddr_t d; /* real disk block address */ 778 xfs_daddr_t d; /* real disk block address */
779 int error; 779 int error;
780 780
781 ASSERT(agno != NULLAGNUMBER); 781 ASSERT(agno != NULLAGNUMBER);
782 ASSERT(agbno != NULLAGBLOCK); 782 ASSERT(agbno != NULLAGBLOCK);
783 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 783 d = XFS_AGB_TO_DADDR(mp, agno, agbno);
784 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 784 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
785 mp->m_bsize, lock, &bp))) { 785 mp->m_bsize, lock, &bp))) {
786 return error; 786 return error;
787 } 787 }
788 ASSERT(!bp || !XFS_BUF_GETERROR(bp)); 788 ASSERT(!bp || !XFS_BUF_GETERROR(bp));
789 if (bp != NULL) { 789 if (bp != NULL) {
790 switch (refval) { 790 switch (refval) {
791 case XFS_ALLOC_BTREE_REF: 791 case XFS_ALLOC_BTREE_REF:
792 XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); 792 XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
793 break; 793 break;
794 case XFS_INO_BTREE_REF: 794 case XFS_INO_BTREE_REF:
795 XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval); 795 XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval);
796 break; 796 break;
797 } 797 }
798 } 798 }
799 *bpp = bp; 799 *bpp = bp;
800 return 0; 800 return 0;
801 } 801 }
802 802
803 /* 803 /*
804 * Read-ahead the block, don't wait for it, don't return a buffer. 804 * Read-ahead the block, don't wait for it, don't return a buffer.
805 * Long-form addressing. 805 * Long-form addressing.
806 */ 806 */
807 /* ARGSUSED */ 807 /* ARGSUSED */
808 void 808 void
809 xfs_btree_reada_bufl( 809 xfs_btree_reada_bufl(
810 xfs_mount_t *mp, /* file system mount point */ 810 xfs_mount_t *mp, /* file system mount point */
811 xfs_fsblock_t fsbno, /* file system block number */ 811 xfs_fsblock_t fsbno, /* file system block number */
812 xfs_extlen_t count) /* count of filesystem blocks */ 812 xfs_extlen_t count) /* count of filesystem blocks */
813 { 813 {
814 xfs_daddr_t d; 814 xfs_daddr_t d;
815 815
816 ASSERT(fsbno != NULLFSBLOCK); 816 ASSERT(fsbno != NULLFSBLOCK);
817 d = XFS_FSB_TO_DADDR(mp, fsbno); 817 d = XFS_FSB_TO_DADDR(mp, fsbno);
818 xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count); 818 xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
819 } 819 }
820 820
821 /* 821 /*
822 * Read-ahead the block, don't wait for it, don't return a buffer. 822 * Read-ahead the block, don't wait for it, don't return a buffer.
823 * Short-form addressing. 823 * Short-form addressing.
824 */ 824 */
825 /* ARGSUSED */ 825 /* ARGSUSED */
826 void 826 void
827 xfs_btree_reada_bufs( 827 xfs_btree_reada_bufs(
828 xfs_mount_t *mp, /* file system mount point */ 828 xfs_mount_t *mp, /* file system mount point */
829 xfs_agnumber_t agno, /* allocation group number */ 829 xfs_agnumber_t agno, /* allocation group number */
830 xfs_agblock_t agbno, /* allocation group block number */ 830 xfs_agblock_t agbno, /* allocation group block number */
831 xfs_extlen_t count) /* count of filesystem blocks */ 831 xfs_extlen_t count) /* count of filesystem blocks */
832 { 832 {
833 xfs_daddr_t d; 833 xfs_daddr_t d;
834 834
835 ASSERT(agno != NULLAGNUMBER); 835 ASSERT(agno != NULLAGNUMBER);
836 ASSERT(agbno != NULLAGBLOCK); 836 ASSERT(agbno != NULLAGBLOCK);
837 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 837 d = XFS_AGB_TO_DADDR(mp, agno, agbno);
838 xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count); 838 xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count);
839 } 839 }
840 840
841 STATIC int 841 STATIC int
842 xfs_btree_readahead_lblock( 842 xfs_btree_readahead_lblock(
843 struct xfs_btree_cur *cur, 843 struct xfs_btree_cur *cur,
844 int lr, 844 int lr,
845 struct xfs_btree_block *block) 845 struct xfs_btree_block *block)
846 { 846 {
847 int rval = 0; 847 int rval = 0;
848 xfs_fsblock_t left = be64_to_cpu(block->bb_u.l.bb_leftsib); 848 xfs_fsblock_t left = be64_to_cpu(block->bb_u.l.bb_leftsib);
849 xfs_fsblock_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); 849 xfs_fsblock_t right = be64_to_cpu(block->bb_u.l.bb_rightsib);
850 850
851 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { 851 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) {
852 xfs_btree_reada_bufl(cur->bc_mp, left, 1); 852 xfs_btree_reada_bufl(cur->bc_mp, left, 1);
853 rval++; 853 rval++;
854 } 854 }
855 855
856 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) { 856 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) {
857 xfs_btree_reada_bufl(cur->bc_mp, right, 1); 857 xfs_btree_reada_bufl(cur->bc_mp, right, 1);
858 rval++; 858 rval++;
859 } 859 }
860 860
861 return rval; 861 return rval;
862 } 862 }
863 863
864 STATIC int 864 STATIC int
865 xfs_btree_readahead_sblock( 865 xfs_btree_readahead_sblock(
866 struct xfs_btree_cur *cur, 866 struct xfs_btree_cur *cur,
867 int lr, 867 int lr,
868 struct xfs_btree_block *block) 868 struct xfs_btree_block *block)
869 { 869 {
870 int rval = 0; 870 int rval = 0;
871 xfs_agblock_t left = be32_to_cpu(block->bb_u.s.bb_leftsib); 871 xfs_agblock_t left = be32_to_cpu(block->bb_u.s.bb_leftsib);
872 xfs_agblock_t right = be32_to_cpu(block->bb_u.s.bb_rightsib); 872 xfs_agblock_t right = be32_to_cpu(block->bb_u.s.bb_rightsib);
873 873
874 874
875 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { 875 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
876 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 876 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
877 left, 1); 877 left, 1);
878 rval++; 878 rval++;
879 } 879 }
880 880
881 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { 881 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
882 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 882 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
883 right, 1); 883 right, 1);
884 rval++; 884 rval++;
885 } 885 }
886 886
887 return rval; 887 return rval;
888 } 888 }
889 889
890 /* 890 /*
891 * Read-ahead btree blocks, at the given level. 891 * Read-ahead btree blocks, at the given level.
892 * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA. 892 * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
893 */ 893 */
894 int 894 int
895 xfs_btree_readahead( 895 xfs_btree_readahead(
896 struct xfs_btree_cur *cur, /* btree cursor */ 896 struct xfs_btree_cur *cur, /* btree cursor */
897 int lev, /* level in btree */ 897 int lev, /* level in btree */
898 int lr) /* left/right bits */ 898 int lr) /* left/right bits */
899 { 899 {
900 struct xfs_btree_block *block; 900 struct xfs_btree_block *block;
901 901
902 /* 902 /*
903 * No readahead needed if we are at the root level and the 903 * No readahead needed if we are at the root level and the
904 * btree root is stored in the inode. 904 * btree root is stored in the inode.
905 */ 905 */
906 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && 906 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
907 (lev == cur->bc_nlevels - 1)) 907 (lev == cur->bc_nlevels - 1))
908 return 0; 908 return 0;
909 909
910 if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev]) 910 if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev])
911 return 0; 911 return 0;
912 912
913 cur->bc_ra[lev] |= lr; 913 cur->bc_ra[lev] |= lr;
914 block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]); 914 block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]);
915 915
916 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 916 if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
917 return xfs_btree_readahead_lblock(cur, lr, block); 917 return xfs_btree_readahead_lblock(cur, lr, block);
918 return xfs_btree_readahead_sblock(cur, lr, block); 918 return xfs_btree_readahead_sblock(cur, lr, block);
919 } 919 }
920 920
921 /* 921 /*
922 * Set the buffer for level "lev" in the cursor to bp, releasing 922 * Set the buffer for level "lev" in the cursor to bp, releasing
923 * any previous buffer. 923 * any previous buffer.
924 */ 924 */
925 void 925 void
926 xfs_btree_setbuf( 926 xfs_btree_setbuf(
927 xfs_btree_cur_t *cur, /* btree cursor */ 927 xfs_btree_cur_t *cur, /* btree cursor */
928 int lev, /* level in btree */ 928 int lev, /* level in btree */
929 xfs_buf_t *bp) /* new buffer to set */ 929 xfs_buf_t *bp) /* new buffer to set */
930 { 930 {
931 xfs_btree_block_t *b; /* btree block */ 931 xfs_btree_block_t *b; /* btree block */
932 xfs_buf_t *obp; /* old buffer pointer */ 932 xfs_buf_t *obp; /* old buffer pointer */
933 933
934 obp = cur->bc_bufs[lev]; 934 obp = cur->bc_bufs[lev];
935 if (obp) 935 if (obp)
936 xfs_trans_brelse(cur->bc_tp, obp); 936 xfs_trans_brelse(cur->bc_tp, obp);
937 cur->bc_bufs[lev] = bp; 937 cur->bc_bufs[lev] = bp;
938 cur->bc_ra[lev] = 0; 938 cur->bc_ra[lev] = 0;
939 if (!bp) 939 if (!bp)
940 return; 940 return;
941 b = XFS_BUF_TO_BLOCK(bp); 941 b = XFS_BUF_TO_BLOCK(bp);
942 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 942 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
943 if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO) 943 if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO)
944 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; 944 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
945 if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO) 945 if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO)
946 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; 946 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
947 } else { 947 } else {
948 if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK) 948 if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK)
949 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; 949 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
950 if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK) 950 if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK)
951 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; 951 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
952 } 952 }
953 } 953 }
954 954
955 STATIC int 955 STATIC int
956 xfs_btree_ptr_is_null( 956 xfs_btree_ptr_is_null(
957 struct xfs_btree_cur *cur, 957 struct xfs_btree_cur *cur,
958 union xfs_btree_ptr *ptr) 958 union xfs_btree_ptr *ptr)
959 { 959 {
960 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 960 if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
961 return be64_to_cpu(ptr->l) == NULLFSBLOCK; 961 return be64_to_cpu(ptr->l) == NULLFSBLOCK;
962 else 962 else
963 return be32_to_cpu(ptr->s) == NULLAGBLOCK; 963 return be32_to_cpu(ptr->s) == NULLAGBLOCK;
964 } 964 }
965 965
966 /* 966 /*
967 * Get/set/init sibling pointers 967 * Get/set/init sibling pointers
968 */ 968 */
969 STATIC void 969 STATIC void
970 xfs_btree_get_sibling( 970 xfs_btree_get_sibling(
971 struct xfs_btree_cur *cur, 971 struct xfs_btree_cur *cur,
972 struct xfs_btree_block *block, 972 struct xfs_btree_block *block,
973 union xfs_btree_ptr *ptr, 973 union xfs_btree_ptr *ptr,
974 int lr) 974 int lr)
975 { 975 {
976 ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB); 976 ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
977 977
978 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 978 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
979 if (lr == XFS_BB_RIGHTSIB) 979 if (lr == XFS_BB_RIGHTSIB)
980 ptr->l = block->bb_u.l.bb_rightsib; 980 ptr->l = block->bb_u.l.bb_rightsib;
981 else 981 else
982 ptr->l = block->bb_u.l.bb_leftsib; 982 ptr->l = block->bb_u.l.bb_leftsib;
983 } else { 983 } else {
984 if (lr == XFS_BB_RIGHTSIB) 984 if (lr == XFS_BB_RIGHTSIB)
985 ptr->s = block->bb_u.s.bb_rightsib; 985 ptr->s = block->bb_u.s.bb_rightsib;
986 else 986 else
987 ptr->s = block->bb_u.s.bb_leftsib; 987 ptr->s = block->bb_u.s.bb_leftsib;
988 } 988 }
989 } 989 }
990 990
991 /* 991 /*
992 * Return true if ptr is the last record in the btree and 992 * Return true if ptr is the last record in the btree and
993 * we need to track updateั• to this record. The decision 993 * we need to track updateั• to this record. The decision
994 * will be further refined in the update_lastrec method. 994 * will be further refined in the update_lastrec method.
995 */ 995 */
996 STATIC int 996 STATIC int
997 xfs_btree_is_lastrec( 997 xfs_btree_is_lastrec(
998 struct xfs_btree_cur *cur, 998 struct xfs_btree_cur *cur,
999 struct xfs_btree_block *block, 999 struct xfs_btree_block *block,
1000 int level) 1000 int level)
1001 { 1001 {
1002 union xfs_btree_ptr ptr; 1002 union xfs_btree_ptr ptr;
1003 1003
1004 if (level > 0) 1004 if (level > 0)
1005 return 0; 1005 return 0;
1006 if (!(cur->bc_flags & XFS_BTREE_LASTREC_UPDATE)) 1006 if (!(cur->bc_flags & XFS_BTREE_LASTREC_UPDATE))
1007 return 0; 1007 return 0;
1008 1008
1009 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB); 1009 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
1010 if (!xfs_btree_ptr_is_null(cur, &ptr)) 1010 if (!xfs_btree_ptr_is_null(cur, &ptr))
1011 return 0; 1011 return 0;
1012 return 1; 1012 return 1;
1013 } 1013 }
1014 1014
1015 STATIC xfs_daddr_t 1015 STATIC xfs_daddr_t
1016 xfs_btree_ptr_to_daddr( 1016 xfs_btree_ptr_to_daddr(
1017 struct xfs_btree_cur *cur, 1017 struct xfs_btree_cur *cur,
1018 union xfs_btree_ptr *ptr) 1018 union xfs_btree_ptr *ptr)
1019 { 1019 {
1020 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 1020 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
1021 ASSERT(be64_to_cpu(ptr->l) != NULLFSBLOCK); 1021 ASSERT(be64_to_cpu(ptr->l) != NULLFSBLOCK);
1022 1022
1023 return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l)); 1023 return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l));
1024 } else { 1024 } else {
1025 ASSERT(cur->bc_private.a.agno != NULLAGNUMBER); 1025 ASSERT(cur->bc_private.a.agno != NULLAGNUMBER);
1026 ASSERT(be32_to_cpu(ptr->s) != NULLAGBLOCK); 1026 ASSERT(be32_to_cpu(ptr->s) != NULLAGBLOCK);
1027 1027
1028 return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno, 1028 return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno,
1029 be32_to_cpu(ptr->s)); 1029 be32_to_cpu(ptr->s));
1030 } 1030 }
1031 } 1031 }
1032 1032
1033 STATIC void 1033 STATIC void
1034 xfs_btree_set_refs( 1034 xfs_btree_set_refs(
1035 struct xfs_btree_cur *cur, 1035 struct xfs_btree_cur *cur,
1036 struct xfs_buf *bp) 1036 struct xfs_buf *bp)
1037 { 1037 {
1038 switch (cur->bc_btnum) { 1038 switch (cur->bc_btnum) {
1039 case XFS_BTNUM_BNO: 1039 case XFS_BTNUM_BNO:
1040 case XFS_BTNUM_CNT: 1040 case XFS_BTNUM_CNT:
1041 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_MAP, XFS_ALLOC_BTREE_REF); 1041 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_MAP, XFS_ALLOC_BTREE_REF);
1042 break; 1042 break;
1043 case XFS_BTNUM_INO: 1043 case XFS_BTNUM_INO:
1044 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_INOMAP, XFS_INO_BTREE_REF); 1044 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_INOMAP, XFS_INO_BTREE_REF);
1045 break; 1045 break;
1046 case XFS_BTNUM_BMAP: 1046 case XFS_BTNUM_BMAP:
1047 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_MAP, XFS_BMAP_BTREE_REF); 1047 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_MAP, XFS_BMAP_BTREE_REF);
1048 break; 1048 break;
1049 default: 1049 default:
1050 ASSERT(0); 1050 ASSERT(0);
1051 } 1051 }
1052 } 1052 }
1053 1053
1054 /* 1054 /*
1055 * Read in the buffer at the given ptr and return the buffer and 1055 * Read in the buffer at the given ptr and return the buffer and
1056 * the block pointer within the buffer. 1056 * the block pointer within the buffer.
1057 */ 1057 */
1058 STATIC int 1058 STATIC int
1059 xfs_btree_read_buf_block( 1059 xfs_btree_read_buf_block(
1060 struct xfs_btree_cur *cur, 1060 struct xfs_btree_cur *cur,
1061 union xfs_btree_ptr *ptr, 1061 union xfs_btree_ptr *ptr,
1062 int level, 1062 int level,
1063 int flags, 1063 int flags,
1064 struct xfs_btree_block **block, 1064 struct xfs_btree_block **block,
1065 struct xfs_buf **bpp) 1065 struct xfs_buf **bpp)
1066 { 1066 {
1067 struct xfs_mount *mp = cur->bc_mp; 1067 struct xfs_mount *mp = cur->bc_mp;
1068 xfs_daddr_t d; 1068 xfs_daddr_t d;
1069 int error; 1069 int error;
1070 1070
1071 /* need to sort out how callers deal with failures first */ 1071 /* need to sort out how callers deal with failures first */
1072 ASSERT(!(flags & XFS_BUF_TRYLOCK)); 1072 ASSERT(!(flags & XFS_BUF_TRYLOCK));
1073 1073
1074 d = xfs_btree_ptr_to_daddr(cur, ptr); 1074 d = xfs_btree_ptr_to_daddr(cur, ptr);
1075 error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d, 1075 error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
1076 mp->m_bsize, flags, bpp); 1076 mp->m_bsize, flags, bpp);
1077 if (error) 1077 if (error)
1078 return error; 1078 return error;
1079 1079
1080 ASSERT(*bpp != NULL); 1080 ASSERT(*bpp != NULL);
1081 ASSERT(!XFS_BUF_GETERROR(*bpp)); 1081 ASSERT(!XFS_BUF_GETERROR(*bpp));
1082 1082
1083 xfs_btree_set_refs(cur, *bpp); 1083 xfs_btree_set_refs(cur, *bpp);
1084 *block = XFS_BUF_TO_BLOCK(*bpp); 1084 *block = XFS_BUF_TO_BLOCK(*bpp);
1085 1085
1086 error = xfs_btree_check_block(cur, *block, level, *bpp); 1086 error = xfs_btree_check_block(cur, *block, level, *bpp);
1087 if (error) 1087 if (error)
1088 xfs_trans_brelse(cur->bc_tp, *bpp); 1088 xfs_trans_brelse(cur->bc_tp, *bpp);
1089 return error; 1089 return error;
1090 } 1090 }
1091 1091
1092 /* 1092 /*
1093 * Copy keys from one btree block to another. 1093 * Copy keys from one btree block to another.
1094 */ 1094 */
1095 STATIC void 1095 STATIC void
1096 xfs_btree_copy_keys( 1096 xfs_btree_copy_keys(
1097 struct xfs_btree_cur *cur, 1097 struct xfs_btree_cur *cur,
1098 union xfs_btree_key *dst_key, 1098 union xfs_btree_key *dst_key,
1099 union xfs_btree_key *src_key, 1099 union xfs_btree_key *src_key,
1100 int numkeys) 1100 int numkeys)
1101 { 1101 {
1102 ASSERT(numkeys >= 0); 1102 ASSERT(numkeys >= 0);
1103 memcpy(dst_key, src_key, numkeys * cur->bc_ops->key_len); 1103 memcpy(dst_key, src_key, numkeys * cur->bc_ops->key_len);
1104 } 1104 }
1105 1105
1106 /* 1106 /*
1107 * Copy records from one btree block to another. 1107 * Copy records from one btree block to another.
1108 */ 1108 */
1109 STATIC void 1109 STATIC void
1110 xfs_btree_copy_recs( 1110 xfs_btree_copy_recs(
1111 struct xfs_btree_cur *cur, 1111 struct xfs_btree_cur *cur,
1112 union xfs_btree_rec *dst_rec, 1112 union xfs_btree_rec *dst_rec,
1113 union xfs_btree_rec *src_rec, 1113 union xfs_btree_rec *src_rec,
1114 int numrecs) 1114 int numrecs)
1115 { 1115 {
1116 ASSERT(numrecs >= 0); 1116 ASSERT(numrecs >= 0);
1117 memcpy(dst_rec, src_rec, numrecs * cur->bc_ops->rec_len); 1117 memcpy(dst_rec, src_rec, numrecs * cur->bc_ops->rec_len);
1118 } 1118 }
1119 1119
1120 /* 1120 /*
1121 * Copy block pointers from one btree block to another. 1121 * Copy block pointers from one btree block to another.
1122 */ 1122 */
1123 STATIC void 1123 STATIC void
1124 xfs_btree_copy_ptrs( 1124 xfs_btree_copy_ptrs(
1125 struct xfs_btree_cur *cur, 1125 struct xfs_btree_cur *cur,
1126 union xfs_btree_ptr *dst_ptr, 1126 union xfs_btree_ptr *dst_ptr,
1127 union xfs_btree_ptr *src_ptr, 1127 union xfs_btree_ptr *src_ptr,
1128 int numptrs) 1128 int numptrs)
1129 { 1129 {
1130 ASSERT(numptrs >= 0); 1130 ASSERT(numptrs >= 0);
1131 memcpy(dst_ptr, src_ptr, numptrs * xfs_btree_ptr_len(cur)); 1131 memcpy(dst_ptr, src_ptr, numptrs * xfs_btree_ptr_len(cur));
1132 } 1132 }
1133 1133
1134 /* 1134 /*
1135 * Shift keys one index left/right inside a single btree block. 1135 * Shift keys one index left/right inside a single btree block.
1136 */ 1136 */
1137 STATIC void 1137 STATIC void
1138 xfs_btree_shift_keys( 1138 xfs_btree_shift_keys(
1139 struct xfs_btree_cur *cur, 1139 struct xfs_btree_cur *cur,
1140 union xfs_btree_key *key, 1140 union xfs_btree_key *key,
1141 int dir, 1141 int dir,
1142 int numkeys) 1142 int numkeys)
1143 { 1143 {
1144 char *dst_key; 1144 char *dst_key;
1145 1145
1146 ASSERT(numkeys >= 0); 1146 ASSERT(numkeys >= 0);
1147 ASSERT(dir == 1 || dir == -1); 1147 ASSERT(dir == 1 || dir == -1);
1148 1148
1149 dst_key = (char *)key + (dir * cur->bc_ops->key_len); 1149 dst_key = (char *)key + (dir * cur->bc_ops->key_len);
1150 memmove(dst_key, key, numkeys * cur->bc_ops->key_len); 1150 memmove(dst_key, key, numkeys * cur->bc_ops->key_len);
1151 } 1151 }
1152 1152
1153 /* 1153 /*
1154 * Shift records one index left/right inside a single btree block. 1154 * Shift records one index left/right inside a single btree block.
1155 */ 1155 */
1156 STATIC void 1156 STATIC void
1157 xfs_btree_shift_recs( 1157 xfs_btree_shift_recs(
1158 struct xfs_btree_cur *cur, 1158 struct xfs_btree_cur *cur,
1159 union xfs_btree_rec *rec, 1159 union xfs_btree_rec *rec,
1160 int dir, 1160 int dir,
1161 int numrecs) 1161 int numrecs)
1162 { 1162 {
1163 char *dst_rec; 1163 char *dst_rec;
1164 1164
1165 ASSERT(numrecs >= 0); 1165 ASSERT(numrecs >= 0);
1166 ASSERT(dir == 1 || dir == -1); 1166 ASSERT(dir == 1 || dir == -1);
1167 1167
1168 dst_rec = (char *)rec + (dir * cur->bc_ops->rec_len); 1168 dst_rec = (char *)rec + (dir * cur->bc_ops->rec_len);
1169 memmove(dst_rec, rec, numrecs * cur->bc_ops->rec_len); 1169 memmove(dst_rec, rec, numrecs * cur->bc_ops->rec_len);
1170 } 1170 }
1171 1171
1172 /* 1172 /*
1173 * Shift block pointers one index left/right inside a single btree block. 1173 * Shift block pointers one index left/right inside a single btree block.
1174 */ 1174 */
1175 STATIC void 1175 STATIC void
1176 xfs_btree_shift_ptrs( 1176 xfs_btree_shift_ptrs(
1177 struct xfs_btree_cur *cur, 1177 struct xfs_btree_cur *cur,
1178 union xfs_btree_ptr *ptr, 1178 union xfs_btree_ptr *ptr,
1179 int dir, 1179 int dir,
1180 int numptrs) 1180 int numptrs)
1181 { 1181 {
1182 char *dst_ptr; 1182 char *dst_ptr;
1183 1183
1184 ASSERT(numptrs >= 0); 1184 ASSERT(numptrs >= 0);
1185 ASSERT(dir == 1 || dir == -1); 1185 ASSERT(dir == 1 || dir == -1);
1186 1186
1187 dst_ptr = (char *)ptr + (dir * xfs_btree_ptr_len(cur)); 1187 dst_ptr = (char *)ptr + (dir * xfs_btree_ptr_len(cur));
1188 memmove(dst_ptr, ptr, numptrs * xfs_btree_ptr_len(cur)); 1188 memmove(dst_ptr, ptr, numptrs * xfs_btree_ptr_len(cur));
1189 } 1189 }
1190 1190
1191 /* 1191 /*
1192 * Log key values from the btree block. 1192 * Log key values from the btree block.
1193 */ 1193 */
1194 STATIC void 1194 STATIC void
1195 xfs_btree_log_keys( 1195 xfs_btree_log_keys(
1196 struct xfs_btree_cur *cur, 1196 struct xfs_btree_cur *cur,
1197 struct xfs_buf *bp, 1197 struct xfs_buf *bp,
1198 int first, 1198 int first,
1199 int last) 1199 int last)
1200 { 1200 {
1201 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1201 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1202 XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); 1202 XFS_BTREE_TRACE_ARGBII(cur, bp, first, last);
1203 1203
1204 if (bp) { 1204 if (bp) {
1205 xfs_trans_log_buf(cur->bc_tp, bp, 1205 xfs_trans_log_buf(cur->bc_tp, bp,
1206 xfs_btree_key_offset(cur, first), 1206 xfs_btree_key_offset(cur, first),
1207 xfs_btree_key_offset(cur, last + 1) - 1); 1207 xfs_btree_key_offset(cur, last + 1) - 1);
1208 } else { 1208 } else {
1209 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, 1209 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
1210 xfs_ilog_fbroot(cur->bc_private.b.whichfork)); 1210 xfs_ilog_fbroot(cur->bc_private.b.whichfork));
1211 } 1211 }
1212 1212
1213 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1213 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1214 } 1214 }
1215 1215
1216 /* 1216 /*
1217 * Log record values from the btree block. 1217 * Log record values from the btree block.
1218 */ 1218 */
1219 STATIC void 1219 STATIC void
1220 xfs_btree_log_recs( 1220 xfs_btree_log_recs(
1221 struct xfs_btree_cur *cur, 1221 struct xfs_btree_cur *cur,
1222 struct xfs_buf *bp, 1222 struct xfs_buf *bp,
1223 int first, 1223 int first,
1224 int last) 1224 int last)
1225 { 1225 {
1226 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1226 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1227 XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); 1227 XFS_BTREE_TRACE_ARGBII(cur, bp, first, last);
1228 1228
1229 xfs_trans_log_buf(cur->bc_tp, bp, 1229 xfs_trans_log_buf(cur->bc_tp, bp,
1230 xfs_btree_rec_offset(cur, first), 1230 xfs_btree_rec_offset(cur, first),
1231 xfs_btree_rec_offset(cur, last + 1) - 1); 1231 xfs_btree_rec_offset(cur, last + 1) - 1);
1232 1232
1233 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1233 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1234 } 1234 }
1235 1235
1236 /* 1236 /*
1237 * Log block pointer fields from a btree block (nonleaf). 1237 * Log block pointer fields from a btree block (nonleaf).
1238 */ 1238 */
1239 STATIC void 1239 STATIC void
1240 xfs_btree_log_ptrs( 1240 xfs_btree_log_ptrs(
1241 struct xfs_btree_cur *cur, /* btree cursor */ 1241 struct xfs_btree_cur *cur, /* btree cursor */
1242 struct xfs_buf *bp, /* buffer containing btree block */ 1242 struct xfs_buf *bp, /* buffer containing btree block */
1243 int first, /* index of first pointer to log */ 1243 int first, /* index of first pointer to log */
1244 int last) /* index of last pointer to log */ 1244 int last) /* index of last pointer to log */
1245 { 1245 {
1246 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1246 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1247 XFS_BTREE_TRACE_ARGBII(cur, bp, first, last); 1247 XFS_BTREE_TRACE_ARGBII(cur, bp, first, last);
1248 1248
1249 if (bp) { 1249 if (bp) {
1250 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 1250 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
1251 int level = xfs_btree_get_level(block); 1251 int level = xfs_btree_get_level(block);
1252 1252
1253 xfs_trans_log_buf(cur->bc_tp, bp, 1253 xfs_trans_log_buf(cur->bc_tp, bp,
1254 xfs_btree_ptr_offset(cur, first, level), 1254 xfs_btree_ptr_offset(cur, first, level),
1255 xfs_btree_ptr_offset(cur, last + 1, level) - 1); 1255 xfs_btree_ptr_offset(cur, last + 1, level) - 1);
1256 } else { 1256 } else {
1257 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, 1257 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
1258 xfs_ilog_fbroot(cur->bc_private.b.whichfork)); 1258 xfs_ilog_fbroot(cur->bc_private.b.whichfork));
1259 } 1259 }
1260 1260
1261 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1261 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1262 } 1262 }
1263 1263
1264 /* 1264 /*
1265 * Log fields from a btree block header. 1265 * Log fields from a btree block header.
1266 */ 1266 */
1267 STATIC void 1267 STATIC void
1268 xfs_btree_log_block( 1268 xfs_btree_log_block(
1269 struct xfs_btree_cur *cur, /* btree cursor */ 1269 struct xfs_btree_cur *cur, /* btree cursor */
1270 struct xfs_buf *bp, /* buffer containing btree block */ 1270 struct xfs_buf *bp, /* buffer containing btree block */
1271 int fields) /* mask of fields: XFS_BB_... */ 1271 int fields) /* mask of fields: XFS_BB_... */
1272 { 1272 {
1273 int first; /* first byte offset logged */ 1273 int first; /* first byte offset logged */
1274 int last; /* last byte offset logged */ 1274 int last; /* last byte offset logged */
1275 static const short soffsets[] = { /* table of offsets (short) */ 1275 static const short soffsets[] = { /* table of offsets (short) */
1276 offsetof(struct xfs_btree_sblock, bb_magic), 1276 offsetof(struct xfs_btree_sblock, bb_magic),
1277 offsetof(struct xfs_btree_sblock, bb_level), 1277 offsetof(struct xfs_btree_sblock, bb_level),
1278 offsetof(struct xfs_btree_sblock, bb_numrecs), 1278 offsetof(struct xfs_btree_sblock, bb_numrecs),
1279 offsetof(struct xfs_btree_sblock, bb_leftsib), 1279 offsetof(struct xfs_btree_sblock, bb_leftsib),
1280 offsetof(struct xfs_btree_sblock, bb_rightsib), 1280 offsetof(struct xfs_btree_sblock, bb_rightsib),
1281 sizeof(struct xfs_btree_sblock) 1281 sizeof(struct xfs_btree_sblock)
1282 }; 1282 };
1283 static const short loffsets[] = { /* table of offsets (long) */ 1283 static const short loffsets[] = { /* table of offsets (long) */
1284 offsetof(struct xfs_btree_lblock, bb_magic), 1284 offsetof(struct xfs_btree_lblock, bb_magic),
1285 offsetof(struct xfs_btree_lblock, bb_level), 1285 offsetof(struct xfs_btree_lblock, bb_level),
1286 offsetof(struct xfs_btree_lblock, bb_numrecs), 1286 offsetof(struct xfs_btree_lblock, bb_numrecs),
1287 offsetof(struct xfs_btree_lblock, bb_leftsib), 1287 offsetof(struct xfs_btree_lblock, bb_leftsib),
1288 offsetof(struct xfs_btree_lblock, bb_rightsib), 1288 offsetof(struct xfs_btree_lblock, bb_rightsib),
1289 sizeof(struct xfs_btree_lblock) 1289 sizeof(struct xfs_btree_lblock)
1290 }; 1290 };
1291 1291
1292 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1292 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1293 XFS_BTREE_TRACE_ARGBI(cur, bp, fields); 1293 XFS_BTREE_TRACE_ARGBI(cur, bp, fields);
1294 1294
1295 if (bp) { 1295 if (bp) {
1296 xfs_btree_offsets(fields, 1296 xfs_btree_offsets(fields,
1297 (cur->bc_flags & XFS_BTREE_LONG_PTRS) ? 1297 (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
1298 loffsets : soffsets, 1298 loffsets : soffsets,
1299 XFS_BB_NUM_BITS, &first, &last); 1299 XFS_BB_NUM_BITS, &first, &last);
1300 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 1300 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
1301 } else { 1301 } else {
1302 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, 1302 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
1303 xfs_ilog_fbroot(cur->bc_private.b.whichfork)); 1303 xfs_ilog_fbroot(cur->bc_private.b.whichfork));
1304 } 1304 }
1305 1305
1306 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1306 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1307 } 1307 }
1308 1308
1309 /* 1309 /*
1310 * Increment cursor by one record at the level. 1310 * Increment cursor by one record at the level.
1311 * For nonzero levels the leaf-ward information is untouched. 1311 * For nonzero levels the leaf-ward information is untouched.
1312 */ 1312 */
1313 int /* error */ 1313 int /* error */
1314 xfs_btree_increment( 1314 xfs_btree_increment(
1315 struct xfs_btree_cur *cur, 1315 struct xfs_btree_cur *cur,
1316 int level, 1316 int level,
1317 int *stat) /* success/failure */ 1317 int *stat) /* success/failure */
1318 { 1318 {
1319 struct xfs_btree_block *block; 1319 struct xfs_btree_block *block;
1320 union xfs_btree_ptr ptr; 1320 union xfs_btree_ptr ptr;
1321 struct xfs_buf *bp; 1321 struct xfs_buf *bp;
1322 int error; /* error return value */ 1322 int error; /* error return value */
1323 int lev; 1323 int lev;
1324 1324
1325 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1325 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1326 XFS_BTREE_TRACE_ARGI(cur, level); 1326 XFS_BTREE_TRACE_ARGI(cur, level);
1327 1327
1328 ASSERT(level < cur->bc_nlevels); 1328 ASSERT(level < cur->bc_nlevels);
1329 1329
1330 /* Read-ahead to the right at this level. */ 1330 /* Read-ahead to the right at this level. */
1331 xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); 1331 xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
1332 1332
1333 /* Get a pointer to the btree block. */ 1333 /* Get a pointer to the btree block. */
1334 block = xfs_btree_get_block(cur, level, &bp); 1334 block = xfs_btree_get_block(cur, level, &bp);
1335 1335
1336 #ifdef DEBUG 1336 #ifdef DEBUG
1337 error = xfs_btree_check_block(cur, block, level, bp); 1337 error = xfs_btree_check_block(cur, block, level, bp);
1338 if (error) 1338 if (error)
1339 goto error0; 1339 goto error0;
1340 #endif 1340 #endif
1341 1341
1342 /* We're done if we remain in the block after the increment. */ 1342 /* We're done if we remain in the block after the increment. */
1343 if (++cur->bc_ptrs[level] <= xfs_btree_get_numrecs(block)) 1343 if (++cur->bc_ptrs[level] <= xfs_btree_get_numrecs(block))
1344 goto out1; 1344 goto out1;
1345 1345
1346 /* Fail if we just went off the right edge of the tree. */ 1346 /* Fail if we just went off the right edge of the tree. */
1347 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB); 1347 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
1348 if (xfs_btree_ptr_is_null(cur, &ptr)) 1348 if (xfs_btree_ptr_is_null(cur, &ptr))
1349 goto out0; 1349 goto out0;
1350 1350
1351 XFS_BTREE_STATS_INC(cur, increment); 1351 XFS_BTREE_STATS_INC(cur, increment);
1352 1352
1353 /* 1353 /*
1354 * March up the tree incrementing pointers. 1354 * March up the tree incrementing pointers.
1355 * Stop when we don't go off the right edge of a block. 1355 * Stop when we don't go off the right edge of a block.
1356 */ 1356 */
1357 for (lev = level + 1; lev < cur->bc_nlevels; lev++) { 1357 for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1358 block = xfs_btree_get_block(cur, lev, &bp); 1358 block = xfs_btree_get_block(cur, lev, &bp);
1359 1359
1360 #ifdef DEBUG 1360 #ifdef DEBUG
1361 error = xfs_btree_check_block(cur, block, lev, bp); 1361 error = xfs_btree_check_block(cur, block, lev, bp);
1362 if (error) 1362 if (error)
1363 goto error0; 1363 goto error0;
1364 #endif 1364 #endif
1365 1365
1366 if (++cur->bc_ptrs[lev] <= xfs_btree_get_numrecs(block)) 1366 if (++cur->bc_ptrs[lev] <= xfs_btree_get_numrecs(block))
1367 break; 1367 break;
1368 1368
1369 /* Read-ahead the right block for the next loop. */ 1369 /* Read-ahead the right block for the next loop. */
1370 xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA); 1370 xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
1371 } 1371 }
1372 1372
1373 /* 1373 /*
1374 * If we went off the root then we are either seriously 1374 * If we went off the root then we are either seriously
1375 * confused or have the tree root in an inode. 1375 * confused or have the tree root in an inode.
1376 */ 1376 */
1377 if (lev == cur->bc_nlevels) { 1377 if (lev == cur->bc_nlevels) {
1378 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) 1378 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
1379 goto out0; 1379 goto out0;
1380 ASSERT(0); 1380 ASSERT(0);
1381 error = EFSCORRUPTED; 1381 error = EFSCORRUPTED;
1382 goto error0; 1382 goto error0;
1383 } 1383 }
1384 ASSERT(lev < cur->bc_nlevels); 1384 ASSERT(lev < cur->bc_nlevels);
1385 1385
1386 /* 1386 /*
1387 * Now walk back down the tree, fixing up the cursor's buffer 1387 * Now walk back down the tree, fixing up the cursor's buffer
1388 * pointers and key numbers. 1388 * pointers and key numbers.
1389 */ 1389 */
1390 for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) { 1390 for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
1391 union xfs_btree_ptr *ptrp; 1391 union xfs_btree_ptr *ptrp;
1392 1392
1393 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); 1393 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
1394 error = xfs_btree_read_buf_block(cur, ptrp, --lev, 1394 error = xfs_btree_read_buf_block(cur, ptrp, --lev,
1395 0, &block, &bp); 1395 0, &block, &bp);
1396 if (error) 1396 if (error)
1397 goto error0; 1397 goto error0;
1398 1398
1399 xfs_btree_setbuf(cur, lev, bp); 1399 xfs_btree_setbuf(cur, lev, bp);
1400 cur->bc_ptrs[lev] = 1; 1400 cur->bc_ptrs[lev] = 1;
1401 } 1401 }
1402 out1: 1402 out1:
1403 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1403 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1404 *stat = 1; 1404 *stat = 1;
1405 return 0; 1405 return 0;
1406 1406
1407 out0: 1407 out0:
1408 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1408 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1409 *stat = 0; 1409 *stat = 0;
1410 return 0; 1410 return 0;
1411 1411
1412 error0: 1412 error0:
1413 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 1413 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1414 return error; 1414 return error;
1415 } 1415 }
1416 1416
1417 /* 1417 /*
1418 * Decrement cursor by one record at the level. 1418 * Decrement cursor by one record at the level.
1419 * For nonzero levels the leaf-ward information is untouched. 1419 * For nonzero levels the leaf-ward information is untouched.
1420 */ 1420 */
1421 int /* error */ 1421 int /* error */
1422 xfs_btree_decrement( 1422 xfs_btree_decrement(
1423 struct xfs_btree_cur *cur, 1423 struct xfs_btree_cur *cur,
1424 int level, 1424 int level,
1425 int *stat) /* success/failure */ 1425 int *stat) /* success/failure */
1426 { 1426 {
1427 struct xfs_btree_block *block; 1427 struct xfs_btree_block *block;
1428 xfs_buf_t *bp; 1428 xfs_buf_t *bp;
1429 int error; /* error return value */ 1429 int error; /* error return value */
1430 int lev; 1430 int lev;
1431 union xfs_btree_ptr ptr; 1431 union xfs_btree_ptr ptr;
1432 1432
1433 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1433 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1434 XFS_BTREE_TRACE_ARGI(cur, level); 1434 XFS_BTREE_TRACE_ARGI(cur, level);
1435 1435
1436 ASSERT(level < cur->bc_nlevels); 1436 ASSERT(level < cur->bc_nlevels);
1437 1437
1438 /* Read-ahead to the left at this level. */ 1438 /* Read-ahead to the left at this level. */
1439 xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA); 1439 xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
1440 1440
1441 /* We're done if we remain in the block after the decrement. */ 1441 /* We're done if we remain in the block after the decrement. */
1442 if (--cur->bc_ptrs[level] > 0) 1442 if (--cur->bc_ptrs[level] > 0)
1443 goto out1; 1443 goto out1;
1444 1444
1445 /* Get a pointer to the btree block. */ 1445 /* Get a pointer to the btree block. */
1446 block = xfs_btree_get_block(cur, level, &bp); 1446 block = xfs_btree_get_block(cur, level, &bp);
1447 1447
1448 #ifdef DEBUG 1448 #ifdef DEBUG
1449 error = xfs_btree_check_block(cur, block, level, bp); 1449 error = xfs_btree_check_block(cur, block, level, bp);
1450 if (error) 1450 if (error)
1451 goto error0; 1451 goto error0;
1452 #endif 1452 #endif
1453 1453
1454 /* Fail if we just went off the left edge of the tree. */ 1454 /* Fail if we just went off the left edge of the tree. */
1455 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB); 1455 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB);
1456 if (xfs_btree_ptr_is_null(cur, &ptr)) 1456 if (xfs_btree_ptr_is_null(cur, &ptr))
1457 goto out0; 1457 goto out0;
1458 1458
1459 XFS_BTREE_STATS_INC(cur, decrement); 1459 XFS_BTREE_STATS_INC(cur, decrement);
1460 1460
1461 /* 1461 /*
1462 * March up the tree decrementing pointers. 1462 * March up the tree decrementing pointers.
1463 * Stop when we don't go off the left edge of a block. 1463 * Stop when we don't go off the left edge of a block.
1464 */ 1464 */
1465 for (lev = level + 1; lev < cur->bc_nlevels; lev++) { 1465 for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1466 if (--cur->bc_ptrs[lev] > 0) 1466 if (--cur->bc_ptrs[lev] > 0)
1467 break; 1467 break;
1468 /* Read-ahead the left block for the next loop. */ 1468 /* Read-ahead the left block for the next loop. */
1469 xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA); 1469 xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
1470 } 1470 }
1471 1471
1472 /* 1472 /*
1473 * If we went off the root then we are seriously confused. 1473 * If we went off the root then we are seriously confused.
1474 * or the root of the tree is in an inode. 1474 * or the root of the tree is in an inode.
1475 */ 1475 */
1476 if (lev == cur->bc_nlevels) { 1476 if (lev == cur->bc_nlevels) {
1477 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) 1477 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
1478 goto out0; 1478 goto out0;
1479 ASSERT(0); 1479 ASSERT(0);
1480 error = EFSCORRUPTED; 1480 error = EFSCORRUPTED;
1481 goto error0; 1481 goto error0;
1482 } 1482 }
1483 ASSERT(lev < cur->bc_nlevels); 1483 ASSERT(lev < cur->bc_nlevels);
1484 1484
1485 /* 1485 /*
1486 * Now walk back down the tree, fixing up the cursor's buffer 1486 * Now walk back down the tree, fixing up the cursor's buffer
1487 * pointers and key numbers. 1487 * pointers and key numbers.
1488 */ 1488 */
1489 for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) { 1489 for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
1490 union xfs_btree_ptr *ptrp; 1490 union xfs_btree_ptr *ptrp;
1491 1491
1492 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); 1492 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
1493 error = xfs_btree_read_buf_block(cur, ptrp, --lev, 1493 error = xfs_btree_read_buf_block(cur, ptrp, --lev,
1494 0, &block, &bp); 1494 0, &block, &bp);
1495 if (error) 1495 if (error)
1496 goto error0; 1496 goto error0;
1497 xfs_btree_setbuf(cur, lev, bp); 1497 xfs_btree_setbuf(cur, lev, bp);
1498 cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block); 1498 cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block);
1499 } 1499 }
1500 out1: 1500 out1:
1501 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1501 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1502 *stat = 1; 1502 *stat = 1;
1503 return 0; 1503 return 0;
1504 1504
1505 out0: 1505 out0:
1506 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1506 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1507 *stat = 0; 1507 *stat = 0;
1508 return 0; 1508 return 0;
1509 1509
1510 error0: 1510 error0:
1511 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 1511 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1512 return error; 1512 return error;
1513 } 1513 }
1514 1514
1515 STATIC int 1515 STATIC int
1516 xfs_btree_lookup_get_block( 1516 xfs_btree_lookup_get_block(
1517 struct xfs_btree_cur *cur, /* btree cursor */ 1517 struct xfs_btree_cur *cur, /* btree cursor */
1518 int level, /* level in the btree */ 1518 int level, /* level in the btree */
1519 union xfs_btree_ptr *pp, /* ptr to btree block */ 1519 union xfs_btree_ptr *pp, /* ptr to btree block */
1520 struct xfs_btree_block **blkp) /* return btree block */ 1520 struct xfs_btree_block **blkp) /* return btree block */
1521 { 1521 {
1522 struct xfs_buf *bp; /* buffer pointer for btree block */ 1522 struct xfs_buf *bp; /* buffer pointer for btree block */
1523 int error = 0; 1523 int error = 0;
1524 1524
1525 /* special case the root block if in an inode */ 1525 /* special case the root block if in an inode */
1526 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && 1526 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
1527 (level == cur->bc_nlevels - 1)) { 1527 (level == cur->bc_nlevels - 1)) {
1528 *blkp = xfs_btree_get_iroot(cur); 1528 *blkp = xfs_btree_get_iroot(cur);
1529 return 0; 1529 return 0;
1530 } 1530 }
1531 1531
1532 /* 1532 /*
1533 * If the old buffer at this level for the disk address we are 1533 * If the old buffer at this level for the disk address we are
1534 * looking for re-use it. 1534 * looking for re-use it.
1535 * 1535 *
1536 * Otherwise throw it away and get a new one. 1536 * Otherwise throw it away and get a new one.
1537 */ 1537 */
1538 bp = cur->bc_bufs[level]; 1538 bp = cur->bc_bufs[level];
1539 if (bp && XFS_BUF_ADDR(bp) == xfs_btree_ptr_to_daddr(cur, pp)) { 1539 if (bp && XFS_BUF_ADDR(bp) == xfs_btree_ptr_to_daddr(cur, pp)) {
1540 *blkp = XFS_BUF_TO_BLOCK(bp); 1540 *blkp = XFS_BUF_TO_BLOCK(bp);
1541 return 0; 1541 return 0;
1542 } 1542 }
1543 1543
1544 error = xfs_btree_read_buf_block(cur, pp, level, 0, blkp, &bp); 1544 error = xfs_btree_read_buf_block(cur, pp, level, 0, blkp, &bp);
1545 if (error) 1545 if (error)
1546 return error; 1546 return error;
1547 1547
1548 xfs_btree_setbuf(cur, level, bp); 1548 xfs_btree_setbuf(cur, level, bp);
1549 return 0; 1549 return 0;
1550 } 1550 }
1551 1551
1552 /* 1552 /*
1553 * Get current search key. For level 0 we don't actually have a key 1553 * Get current search key. For level 0 we don't actually have a key
1554 * structure so we make one up from the record. For all other levels 1554 * structure so we make one up from the record. For all other levels
1555 * we just return the right key. 1555 * we just return the right key.
1556 */ 1556 */
1557 STATIC union xfs_btree_key * 1557 STATIC union xfs_btree_key *
1558 xfs_lookup_get_search_key( 1558 xfs_lookup_get_search_key(
1559 struct xfs_btree_cur *cur, 1559 struct xfs_btree_cur *cur,
1560 int level, 1560 int level,
1561 int keyno, 1561 int keyno,
1562 struct xfs_btree_block *block, 1562 struct xfs_btree_block *block,
1563 union xfs_btree_key *kp) 1563 union xfs_btree_key *kp)
1564 { 1564 {
1565 if (level == 0) { 1565 if (level == 0) {
1566 cur->bc_ops->init_key_from_rec(kp, 1566 cur->bc_ops->init_key_from_rec(kp,
1567 xfs_btree_rec_addr(cur, keyno, block)); 1567 xfs_btree_rec_addr(cur, keyno, block));
1568 return kp; 1568 return kp;
1569 } 1569 }
1570 1570
1571 return xfs_btree_key_addr(cur, keyno, block); 1571 return xfs_btree_key_addr(cur, keyno, block);
1572 } 1572 }
1573 1573
1574 /* 1574 /*
1575 * Lookup the record. The cursor is made to point to it, based on dir. 1575 * Lookup the record. The cursor is made to point to it, based on dir.
1576 * Return 0 if can't find any such record, 1 for success. 1576 * Return 0 if can't find any such record, 1 for success.
1577 */ 1577 */
1578 int /* error */ 1578 int /* error */
1579 xfs_btree_lookup( 1579 xfs_btree_lookup(
1580 struct xfs_btree_cur *cur, /* btree cursor */ 1580 struct xfs_btree_cur *cur, /* btree cursor */
1581 xfs_lookup_t dir, /* <=, ==, or >= */ 1581 xfs_lookup_t dir, /* <=, ==, or >= */
1582 int *stat) /* success/failure */ 1582 int *stat) /* success/failure */
1583 { 1583 {
1584 struct xfs_btree_block *block; /* current btree block */ 1584 struct xfs_btree_block *block; /* current btree block */
1585 __int64_t diff; /* difference for the current key */ 1585 __int64_t diff; /* difference for the current key */
1586 int error; /* error return value */ 1586 int error; /* error return value */
1587 int keyno; /* current key number */ 1587 int keyno; /* current key number */
1588 int level; /* level in the btree */ 1588 int level; /* level in the btree */
1589 union xfs_btree_ptr *pp; /* ptr to btree block */ 1589 union xfs_btree_ptr *pp; /* ptr to btree block */
1590 union xfs_btree_ptr ptr; /* ptr to btree block */ 1590 union xfs_btree_ptr ptr; /* ptr to btree block */
1591 1591
1592 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1592 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1593 XFS_BTREE_TRACE_ARGI(cur, dir); 1593 XFS_BTREE_TRACE_ARGI(cur, dir);
1594 1594
1595 XFS_BTREE_STATS_INC(cur, lookup); 1595 XFS_BTREE_STATS_INC(cur, lookup);
1596 1596
1597 block = NULL; 1597 block = NULL;
1598 keyno = 0; 1598 keyno = 0;
1599 1599
1600 /* initialise start pointer from cursor */ 1600 /* initialise start pointer from cursor */
1601 cur->bc_ops->init_ptr_from_cur(cur, &ptr); 1601 cur->bc_ops->init_ptr_from_cur(cur, &ptr);
1602 pp = &ptr; 1602 pp = &ptr;
1603 1603
1604 /* 1604 /*
1605 * Iterate over each level in the btree, starting at the root. 1605 * Iterate over each level in the btree, starting at the root.
1606 * For each level above the leaves, find the key we need, based 1606 * For each level above the leaves, find the key we need, based
1607 * on the lookup record, then follow the corresponding block 1607 * on the lookup record, then follow the corresponding block
1608 * pointer down to the next level. 1608 * pointer down to the next level.
1609 */ 1609 */
1610 for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) { 1610 for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
1611 /* Get the block we need to do the lookup on. */ 1611 /* Get the block we need to do the lookup on. */
1612 error = xfs_btree_lookup_get_block(cur, level, pp, &block); 1612 error = xfs_btree_lookup_get_block(cur, level, pp, &block);
1613 if (error) 1613 if (error)
1614 goto error0; 1614 goto error0;
1615 1615
1616 if (diff == 0) { 1616 if (diff == 0) {
1617 /* 1617 /*
1618 * If we already had a key match at a higher level, we 1618 * If we already had a key match at a higher level, we
1619 * know we need to use the first entry in this block. 1619 * know we need to use the first entry in this block.
1620 */ 1620 */
1621 keyno = 1; 1621 keyno = 1;
1622 } else { 1622 } else {
1623 /* Otherwise search this block. Do a binary search. */ 1623 /* Otherwise search this block. Do a binary search. */
1624 1624
1625 int high; /* high entry number */ 1625 int high; /* high entry number */
1626 int low; /* low entry number */ 1626 int low; /* low entry number */
1627 1627
1628 /* Set low and high entry numbers, 1-based. */ 1628 /* Set low and high entry numbers, 1-based. */
1629 low = 1; 1629 low = 1;
1630 high = xfs_btree_get_numrecs(block); 1630 high = xfs_btree_get_numrecs(block);
1631 if (!high) { 1631 if (!high) {
1632 /* Block is empty, must be an empty leaf. */ 1632 /* Block is empty, must be an empty leaf. */
1633 ASSERT(level == 0 && cur->bc_nlevels == 1); 1633 ASSERT(level == 0 && cur->bc_nlevels == 1);
1634 1634
1635 cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE; 1635 cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
1636 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1636 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1637 *stat = 0; 1637 *stat = 0;
1638 return 0; 1638 return 0;
1639 } 1639 }
1640 1640
1641 /* Binary search the block. */ 1641 /* Binary search the block. */
1642 while (low <= high) { 1642 while (low <= high) {
1643 union xfs_btree_key key; 1643 union xfs_btree_key key;
1644 union xfs_btree_key *kp; 1644 union xfs_btree_key *kp;
1645 1645
1646 XFS_BTREE_STATS_INC(cur, compare); 1646 XFS_BTREE_STATS_INC(cur, compare);
1647 1647
1648 /* keyno is average of low and high. */ 1648 /* keyno is average of low and high. */
1649 keyno = (low + high) >> 1; 1649 keyno = (low + high) >> 1;
1650 1650
1651 /* Get current search key */ 1651 /* Get current search key */
1652 kp = xfs_lookup_get_search_key(cur, level, 1652 kp = xfs_lookup_get_search_key(cur, level,
1653 keyno, block, &key); 1653 keyno, block, &key);
1654 1654
1655 /* 1655 /*
1656 * Compute difference to get next direction: 1656 * Compute difference to get next direction:
1657 * - less than, move right 1657 * - less than, move right
1658 * - greater than, move left 1658 * - greater than, move left
1659 * - equal, we're done 1659 * - equal, we're done
1660 */ 1660 */
1661 diff = cur->bc_ops->key_diff(cur, kp); 1661 diff = cur->bc_ops->key_diff(cur, kp);
1662 if (diff < 0) 1662 if (diff < 0)
1663 low = keyno + 1; 1663 low = keyno + 1;
1664 else if (diff > 0) 1664 else if (diff > 0)
1665 high = keyno - 1; 1665 high = keyno - 1;
1666 else 1666 else
1667 break; 1667 break;
1668 } 1668 }
1669 } 1669 }
1670 1670
1671 /* 1671 /*
1672 * If there are more levels, set up for the next level 1672 * If there are more levels, set up for the next level
1673 * by getting the block number and filling in the cursor. 1673 * by getting the block number and filling in the cursor.
1674 */ 1674 */
1675 if (level > 0) { 1675 if (level > 0) {
1676 /* 1676 /*
1677 * If we moved left, need the previous key number, 1677 * If we moved left, need the previous key number,
1678 * unless there isn't one. 1678 * unless there isn't one.
1679 */ 1679 */
1680 if (diff > 0 && --keyno < 1) 1680 if (diff > 0 && --keyno < 1)
1681 keyno = 1; 1681 keyno = 1;
1682 pp = xfs_btree_ptr_addr(cur, keyno, block); 1682 pp = xfs_btree_ptr_addr(cur, keyno, block);
1683 1683
1684 #ifdef DEBUG 1684 #ifdef DEBUG
1685 error = xfs_btree_check_ptr(cur, pp, 0, level); 1685 error = xfs_btree_check_ptr(cur, pp, 0, level);
1686 if (error) 1686 if (error)
1687 goto error0; 1687 goto error0;
1688 #endif 1688 #endif
1689 cur->bc_ptrs[level] = keyno; 1689 cur->bc_ptrs[level] = keyno;
1690 } 1690 }
1691 } 1691 }
1692 1692
1693 /* Done with the search. See if we need to adjust the results. */ 1693 /* Done with the search. See if we need to adjust the results. */
1694 if (dir != XFS_LOOKUP_LE && diff < 0) { 1694 if (dir != XFS_LOOKUP_LE && diff < 0) {
1695 keyno++; 1695 keyno++;
1696 /* 1696 /*
1697 * If ge search and we went off the end of the block, but it's 1697 * If ge search and we went off the end of the block, but it's
1698 * not the last block, we're in the wrong block. 1698 * not the last block, we're in the wrong block.
1699 */ 1699 */
1700 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB); 1700 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
1701 if (dir == XFS_LOOKUP_GE && 1701 if (dir == XFS_LOOKUP_GE &&
1702 keyno > xfs_btree_get_numrecs(block) && 1702 keyno > xfs_btree_get_numrecs(block) &&
1703 !xfs_btree_ptr_is_null(cur, &ptr)) { 1703 !xfs_btree_ptr_is_null(cur, &ptr)) {
1704 int i; 1704 int i;
1705 1705
1706 cur->bc_ptrs[0] = keyno; 1706 cur->bc_ptrs[0] = keyno;
1707 error = xfs_btree_increment(cur, 0, &i); 1707 error = xfs_btree_increment(cur, 0, &i);
1708 if (error) 1708 if (error)
1709 goto error0; 1709 goto error0;
1710 XFS_WANT_CORRUPTED_RETURN(i == 1); 1710 XFS_WANT_CORRUPTED_RETURN(i == 1);
1711 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1711 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1712 *stat = 1; 1712 *stat = 1;
1713 return 0; 1713 return 0;
1714 } 1714 }
1715 } else if (dir == XFS_LOOKUP_LE && diff > 0) 1715 } else if (dir == XFS_LOOKUP_LE && diff > 0)
1716 keyno--; 1716 keyno--;
1717 cur->bc_ptrs[0] = keyno; 1717 cur->bc_ptrs[0] = keyno;
1718 1718
1719 /* Return if we succeeded or not. */ 1719 /* Return if we succeeded or not. */
1720 if (keyno == 0 || keyno > xfs_btree_get_numrecs(block)) 1720 if (keyno == 0 || keyno > xfs_btree_get_numrecs(block))
1721 *stat = 0; 1721 *stat = 0;
1722 else if (dir != XFS_LOOKUP_EQ || diff == 0) 1722 else if (dir != XFS_LOOKUP_EQ || diff == 0)
1723 *stat = 1; 1723 *stat = 1;
1724 else 1724 else
1725 *stat = 0; 1725 *stat = 0;
1726 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1726 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1727 return 0; 1727 return 0;
1728 1728
1729 error0: 1729 error0:
1730 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 1730 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1731 return error; 1731 return error;
1732 } 1732 }
1733 1733
1734 /* 1734 /*
1735 * Update keys at all levels from here to the root along the cursor's path. 1735 * Update keys at all levels from here to the root along the cursor's path.
1736 */ 1736 */
1737 int 1737 int
1738 xfs_btree_updkey( 1738 xfs_btree_updkey(
1739 struct xfs_btree_cur *cur, 1739 struct xfs_btree_cur *cur,
1740 union xfs_btree_key *keyp, 1740 union xfs_btree_key *keyp,
1741 int level) 1741 int level)
1742 { 1742 {
1743 struct xfs_btree_block *block; 1743 struct xfs_btree_block *block;
1744 struct xfs_buf *bp; 1744 struct xfs_buf *bp;
1745 union xfs_btree_key *kp; 1745 union xfs_btree_key *kp;
1746 int ptr; 1746 int ptr;
1747 1747
1748 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1748 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1749 XFS_BTREE_TRACE_ARGIK(cur, level, keyp); 1749 XFS_BTREE_TRACE_ARGIK(cur, level, keyp);
1750 1750
1751 ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) || level >= 1); 1751 ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) || level >= 1);
1752 1752
1753 /* 1753 /*
1754 * Go up the tree from this level toward the root. 1754 * Go up the tree from this level toward the root.
1755 * At each level, update the key value to the value input. 1755 * At each level, update the key value to the value input.
1756 * Stop when we reach a level where the cursor isn't pointing 1756 * Stop when we reach a level where the cursor isn't pointing
1757 * at the first entry in the block. 1757 * at the first entry in the block.
1758 */ 1758 */
1759 for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) { 1759 for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
1760 #ifdef DEBUG 1760 #ifdef DEBUG
1761 int error; 1761 int error;
1762 #endif 1762 #endif
1763 block = xfs_btree_get_block(cur, level, &bp); 1763 block = xfs_btree_get_block(cur, level, &bp);
1764 #ifdef DEBUG 1764 #ifdef DEBUG
1765 error = xfs_btree_check_block(cur, block, level, bp); 1765 error = xfs_btree_check_block(cur, block, level, bp);
1766 if (error) { 1766 if (error) {
1767 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 1767 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1768 return error; 1768 return error;
1769 } 1769 }
1770 #endif 1770 #endif
1771 ptr = cur->bc_ptrs[level]; 1771 ptr = cur->bc_ptrs[level];
1772 kp = xfs_btree_key_addr(cur, ptr, block); 1772 kp = xfs_btree_key_addr(cur, ptr, block);
1773 xfs_btree_copy_keys(cur, kp, keyp, 1); 1773 xfs_btree_copy_keys(cur, kp, keyp, 1);
1774 xfs_btree_log_keys(cur, bp, ptr, ptr); 1774 xfs_btree_log_keys(cur, bp, ptr, ptr);
1775 } 1775 }
1776 1776
1777 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1777 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1778 return 0; 1778 return 0;
1779 } 1779 }
1780 1780
1781 /* 1781 /*
1782 * Update the record referred to by cur to the value in the 1782 * Update the record referred to by cur to the value in the
1783 * given record. This either works (return 0) or gets an 1783 * given record. This either works (return 0) or gets an
1784 * EFSCORRUPTED error. 1784 * EFSCORRUPTED error.
1785 */ 1785 */
1786 int 1786 int
1787 xfs_btree_update( 1787 xfs_btree_update(
1788 struct xfs_btree_cur *cur, 1788 struct xfs_btree_cur *cur,
1789 union xfs_btree_rec *rec) 1789 union xfs_btree_rec *rec)
1790 { 1790 {
1791 struct xfs_btree_block *block; 1791 struct xfs_btree_block *block;
1792 struct xfs_buf *bp; 1792 struct xfs_buf *bp;
1793 int error; 1793 int error;
1794 int ptr; 1794 int ptr;
1795 union xfs_btree_rec *rp; 1795 union xfs_btree_rec *rp;
1796 1796
1797 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 1797 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1798 XFS_BTREE_TRACE_ARGR(cur, rec); 1798 XFS_BTREE_TRACE_ARGR(cur, rec);
1799 1799
1800 /* Pick up the current block. */ 1800 /* Pick up the current block. */
1801 block = xfs_btree_get_block(cur, 0, &bp); 1801 block = xfs_btree_get_block(cur, 0, &bp);
1802 1802
1803 #ifdef DEBUG 1803 #ifdef DEBUG
1804 error = xfs_btree_check_block(cur, block, 0, bp); 1804 error = xfs_btree_check_block(cur, block, 0, bp);
1805 if (error) 1805 if (error)
1806 goto error0; 1806 goto error0;
1807 #endif 1807 #endif
1808 /* Get the address of the rec to be updated. */ 1808 /* Get the address of the rec to be updated. */
1809 ptr = cur->bc_ptrs[0]; 1809 ptr = cur->bc_ptrs[0];
1810 rp = xfs_btree_rec_addr(cur, ptr, block); 1810 rp = xfs_btree_rec_addr(cur, ptr, block);
1811 1811
1812 /* Fill in the new contents and log them. */ 1812 /* Fill in the new contents and log them. */
1813 xfs_btree_copy_recs(cur, rp, rec, 1); 1813 xfs_btree_copy_recs(cur, rp, rec, 1);
1814 xfs_btree_log_recs(cur, bp, ptr, ptr); 1814 xfs_btree_log_recs(cur, bp, ptr, ptr);
1815 1815
1816 /* 1816 /*
1817 * If we are tracking the last record in the tree and 1817 * If we are tracking the last record in the tree and
1818 * we are at the far right edge of the tree, update it. 1818 * we are at the far right edge of the tree, update it.
1819 */ 1819 */
1820 if (xfs_btree_is_lastrec(cur, block, 0)) { 1820 if (xfs_btree_is_lastrec(cur, block, 0)) {
1821 cur->bc_ops->update_lastrec(cur, block, rec, 1821 cur->bc_ops->update_lastrec(cur, block, rec,
1822 ptr, LASTREC_UPDATE); 1822 ptr, LASTREC_UPDATE);
1823 } 1823 }
1824 1824
1825 /* Updating first rec in leaf. Pass new key value up to our parent. */ 1825 /* Updating first rec in leaf. Pass new key value up to our parent. */
1826 if (ptr == 1) { 1826 if (ptr == 1) {
1827 union xfs_btree_key key; 1827 union xfs_btree_key key;
1828 1828
1829 cur->bc_ops->init_key_from_rec(&key, rec); 1829 cur->bc_ops->init_key_from_rec(&key, rec);
1830 error = xfs_btree_updkey(cur, &key, 1); 1830 error = xfs_btree_updkey(cur, &key, 1);
1831 if (error) 1831 if (error)
1832 goto error0; 1832 goto error0;
1833 } 1833 }
1834 1834
1835 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 1835 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1836 return 0; 1836 return 0;
1837 1837
1838 error0: 1838 error0:
1839 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 1839 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1840 return error; 1840 return error;
1841 } 1841 }
1842 1842
1843 /* 1843 /*
1844 * Move 1 record left from cur/level if possible.
1845 * Update cur to reflect the new path.
1846 */
1847 int /* error */
1848 xfs_btree_lshift(
1849 struct xfs_btree_cur *cur,
1850 int level,
1851 int *stat) /* success/failure */
1852 {
1853 union xfs_btree_key key; /* btree key */
1854 struct xfs_buf *lbp; /* left buffer pointer */
1855 struct xfs_btree_block *left; /* left btree block */
1856 int lrecs; /* left record count */
1857 struct xfs_buf *rbp; /* right buffer pointer */
1858 struct xfs_btree_block *right; /* right btree block */
1859 int rrecs; /* right record count */
1860 union xfs_btree_ptr lptr; /* left btree pointer */
1861 union xfs_btree_key *rkp = NULL; /* right btree key */
1862 union xfs_btree_ptr *rpp = NULL; /* right address pointer */
1863 union xfs_btree_rec *rrp = NULL; /* right record pointer */
1864 int error; /* error return value */
1865
1866 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1867 XFS_BTREE_TRACE_ARGI(cur, level);
1868
1869 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
1870 level == cur->bc_nlevels - 1)
1871 goto out0;
1872
1873 /* Set up variables for this block as "right". */
1874 right = xfs_btree_get_block(cur, level, &rbp);
1875
1876 #ifdef DEBUG
1877 error = xfs_btree_check_block(cur, right, level, rbp);
1878 if (error)
1879 goto error0;
1880 #endif
1881
1882 /* If we've got no left sibling then we can't shift an entry left. */
1883 xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
1884 if (xfs_btree_ptr_is_null(cur, &lptr))
1885 goto out0;
1886
1887 /*
1888 * If the cursor entry is the one that would be moved, don't
1889 * do it... it's too complicated.
1890 */
1891 if (cur->bc_ptrs[level] <= 1)
1892 goto out0;
1893
1894 /* Set up the left neighbor as "left". */
1895 error = xfs_btree_read_buf_block(cur, &lptr, level, 0, &left, &lbp);
1896 if (error)
1897 goto error0;
1898
1899 /* If it's full, it can't take another entry. */
1900 lrecs = xfs_btree_get_numrecs(left);
1901 if (lrecs == cur->bc_ops->get_maxrecs(cur, level))
1902 goto out0;
1903
1904 rrecs = xfs_btree_get_numrecs(right);
1905
1906 /*
1907 * We add one entry to the left side and remove one for the right side.
1908 * Accout for it here, the changes will be updated on disk and logged
1909 * later.
1910 */
1911 lrecs++;
1912 rrecs--;
1913
1914 XFS_BTREE_STATS_INC(cur, lshift);
1915 XFS_BTREE_STATS_ADD(cur, moves, 1);
1916
1917 /*
1918 * If non-leaf, copy a key and a ptr to the left block.
1919 * Log the changes to the left block.
1920 */
1921 if (level > 0) {
1922 /* It's a non-leaf. Move keys and pointers. */
1923 union xfs_btree_key *lkp; /* left btree key */
1924 union xfs_btree_ptr *lpp; /* left address pointer */
1925
1926 lkp = xfs_btree_key_addr(cur, lrecs, left);
1927 rkp = xfs_btree_key_addr(cur, 1, right);
1928
1929 lpp = xfs_btree_ptr_addr(cur, lrecs, left);
1930 rpp = xfs_btree_ptr_addr(cur, 1, right);
1931 #ifdef DEBUG
1932 error = xfs_btree_check_ptr(cur, rpp, 0, level);
1933 if (error)
1934 goto error0;
1935 #endif
1936 xfs_btree_copy_keys(cur, lkp, rkp, 1);
1937 xfs_btree_copy_ptrs(cur, lpp, rpp, 1);
1938
1939 xfs_btree_log_keys(cur, lbp, lrecs, lrecs);
1940 xfs_btree_log_ptrs(cur, lbp, lrecs, lrecs);
1941
1942 xfs_btree_check_key(cur->bc_btnum,
1943 xfs_btree_key_addr(cur, lrecs - 1, left),
1944 lkp);
1945 } else {
1946 /* It's a leaf. Move records. */
1947 union xfs_btree_rec *lrp; /* left record pointer */
1948
1949 lrp = xfs_btree_rec_addr(cur, lrecs, left);
1950 rrp = xfs_btree_rec_addr(cur, 1, right);
1951
1952 xfs_btree_copy_recs(cur, lrp, rrp, 1);
1953 xfs_btree_log_recs(cur, lbp, lrecs, lrecs);
1954
1955 xfs_btree_check_rec(cur->bc_btnum,
1956 xfs_btree_rec_addr(cur, lrecs - 1, left),
1957 lrp);
1958 }
1959
1960 xfs_btree_set_numrecs(left, lrecs);
1961 xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS);
1962
1963 xfs_btree_set_numrecs(right, rrecs);
1964 xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS);
1965
1966 /*
1967 * Slide the contents of right down one entry.
1968 */
1969 XFS_BTREE_STATS_ADD(cur, moves, rrecs - 1);
1970 if (level > 0) {
1971 /* It's a nonleaf. operate on keys and ptrs */
1972 #ifdef DEBUG
1973 int i; /* loop index */
1974
1975 for (i = 0; i < rrecs; i++) {
1976 error = xfs_btree_check_ptr(cur, rpp, i + 1, level);
1977 if (error)
1978 goto error0;
1979 }
1980 #endif
1981 xfs_btree_shift_keys(cur,
1982 xfs_btree_key_addr(cur, 2, right),
1983 -1, rrecs);
1984 xfs_btree_shift_ptrs(cur,
1985 xfs_btree_ptr_addr(cur, 2, right),
1986 -1, rrecs);
1987
1988 xfs_btree_log_keys(cur, rbp, 1, rrecs);
1989 xfs_btree_log_ptrs(cur, rbp, 1, rrecs);
1990 } else {
1991 /* It's a leaf. operate on records */
1992 xfs_btree_shift_recs(cur,
1993 xfs_btree_rec_addr(cur, 2, right),
1994 -1, rrecs);
1995 xfs_btree_log_recs(cur, rbp, 1, rrecs);
1996
1997 /*
1998 * If it's the first record in the block, we'll need a key
1999 * structure to pass up to the next level (updkey).
2000 */
2001 cur->bc_ops->init_key_from_rec(&key,
2002 xfs_btree_rec_addr(cur, 1, right));
2003 rkp = &key;
2004 }
2005
2006 /* Update the parent key values of right. */
2007 error = xfs_btree_updkey(cur, rkp, level + 1);
2008 if (error)
2009 goto error0;
2010
2011 /* Slide the cursor value left one. */
2012 cur->bc_ptrs[level]--;
2013
2014 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2015 *stat = 1;
2016 return 0;
2017
2018 out0:
2019 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2020 *stat = 0;
2021 return 0;
2022
2023 error0:
2024 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
2025 return error;
2026 }
2027
2028 /*
1844 * Move 1 record right from cur/level if possible. 2029 * Move 1 record right from cur/level if possible.
1845 * Update cur to reflect the new path. 2030 * Update cur to reflect the new path.
1846 */ 2031 */
1847 int /* error */ 2032 int /* error */
1848 xfs_btree_rshift( 2033 xfs_btree_rshift(
1849 struct xfs_btree_cur *cur, 2034 struct xfs_btree_cur *cur,
1850 int level, 2035 int level,
1851 int *stat) /* success/failure */ 2036 int *stat) /* success/failure */
1852 { 2037 {
1853 union xfs_btree_key key; /* btree key */ 2038 union xfs_btree_key key; /* btree key */
1854 struct xfs_buf *lbp; /* left buffer pointer */ 2039 struct xfs_buf *lbp; /* left buffer pointer */
1855 struct xfs_btree_block *left; /* left btree block */ 2040 struct xfs_btree_block *left; /* left btree block */
1856 struct xfs_buf *rbp; /* right buffer pointer */ 2041 struct xfs_buf *rbp; /* right buffer pointer */
1857 struct xfs_btree_block *right; /* right btree block */ 2042 struct xfs_btree_block *right; /* right btree block */
1858 struct xfs_btree_cur *tcur; /* temporary btree cursor */ 2043 struct xfs_btree_cur *tcur; /* temporary btree cursor */
1859 union xfs_btree_ptr rptr; /* right block pointer */ 2044 union xfs_btree_ptr rptr; /* right block pointer */
1860 union xfs_btree_key *rkp; /* right btree key */ 2045 union xfs_btree_key *rkp; /* right btree key */
1861 int rrecs; /* right record count */ 2046 int rrecs; /* right record count */
1862 int lrecs; /* left record count */ 2047 int lrecs; /* left record count */
1863 int error; /* error return value */ 2048 int error; /* error return value */
1864 int i; /* loop counter */ 2049 int i; /* loop counter */
1865 2050
1866 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 2051 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1867 XFS_BTREE_TRACE_ARGI(cur, level); 2052 XFS_BTREE_TRACE_ARGI(cur, level);
1868 2053
1869 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && 2054 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
1870 (level == cur->bc_nlevels - 1)) 2055 (level == cur->bc_nlevels - 1))
1871 goto out0; 2056 goto out0;
1872 2057
1873 /* Set up variables for this block as "left". */ 2058 /* Set up variables for this block as "left". */
1874 left = xfs_btree_get_block(cur, level, &lbp); 2059 left = xfs_btree_get_block(cur, level, &lbp);
1875 2060
1876 #ifdef DEBUG 2061 #ifdef DEBUG
1877 error = xfs_btree_check_block(cur, left, level, lbp); 2062 error = xfs_btree_check_block(cur, left, level, lbp);
1878 if (error) 2063 if (error)
1879 goto error0; 2064 goto error0;
1880 #endif 2065 #endif
1881 2066
1882 /* If we've got no right sibling then we can't shift an entry right. */ 2067 /* If we've got no right sibling then we can't shift an entry right. */
1883 xfs_btree_get_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB); 2068 xfs_btree_get_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB);
1884 if (xfs_btree_ptr_is_null(cur, &rptr)) 2069 if (xfs_btree_ptr_is_null(cur, &rptr))
1885 goto out0; 2070 goto out0;
1886 2071
1887 /* 2072 /*
1888 * If the cursor entry is the one that would be moved, don't 2073 * If the cursor entry is the one that would be moved, don't
1889 * do it... it's too complicated. 2074 * do it... it's too complicated.
1890 */ 2075 */
1891 lrecs = xfs_btree_get_numrecs(left); 2076 lrecs = xfs_btree_get_numrecs(left);
1892 if (cur->bc_ptrs[level] >= lrecs) 2077 if (cur->bc_ptrs[level] >= lrecs)
1893 goto out0; 2078 goto out0;
1894 2079
1895 /* Set up the right neighbor as "right". */ 2080 /* Set up the right neighbor as "right". */
1896 error = xfs_btree_read_buf_block(cur, &rptr, level, 0, &right, &rbp); 2081 error = xfs_btree_read_buf_block(cur, &rptr, level, 0, &right, &rbp);
1897 if (error) 2082 if (error)
1898 goto error0; 2083 goto error0;
1899 2084
1900 /* If it's full, it can't take another entry. */ 2085 /* If it's full, it can't take another entry. */
1901 rrecs = xfs_btree_get_numrecs(right); 2086 rrecs = xfs_btree_get_numrecs(right);
1902 if (rrecs == cur->bc_ops->get_maxrecs(cur, level)) 2087 if (rrecs == cur->bc_ops->get_maxrecs(cur, level))
1903 goto out0; 2088 goto out0;
1904 2089
1905 XFS_BTREE_STATS_INC(cur, rshift); 2090 XFS_BTREE_STATS_INC(cur, rshift);
1906 XFS_BTREE_STATS_ADD(cur, moves, rrecs); 2091 XFS_BTREE_STATS_ADD(cur, moves, rrecs);
1907 2092
1908 /* 2093 /*
1909 * Make a hole at the start of the right neighbor block, then 2094 * Make a hole at the start of the right neighbor block, then
1910 * copy the last left block entry to the hole. 2095 * copy the last left block entry to the hole.
1911 */ 2096 */
1912 if (level > 0) { 2097 if (level > 0) {
1913 /* It's a nonleaf. make a hole in the keys and ptrs */ 2098 /* It's a nonleaf. make a hole in the keys and ptrs */
1914 union xfs_btree_key *lkp; 2099 union xfs_btree_key *lkp;
1915 union xfs_btree_ptr *lpp; 2100 union xfs_btree_ptr *lpp;
1916 union xfs_btree_ptr *rpp; 2101 union xfs_btree_ptr *rpp;
1917 2102
1918 lkp = xfs_btree_key_addr(cur, lrecs, left); 2103 lkp = xfs_btree_key_addr(cur, lrecs, left);
1919 lpp = xfs_btree_ptr_addr(cur, lrecs, left); 2104 lpp = xfs_btree_ptr_addr(cur, lrecs, left);
1920 rkp = xfs_btree_key_addr(cur, 1, right); 2105 rkp = xfs_btree_key_addr(cur, 1, right);
1921 rpp = xfs_btree_ptr_addr(cur, 1, right); 2106 rpp = xfs_btree_ptr_addr(cur, 1, right);
1922 2107
1923 #ifdef DEBUG 2108 #ifdef DEBUG
1924 for (i = rrecs - 1; i >= 0; i--) { 2109 for (i = rrecs - 1; i >= 0; i--) {
1925 error = xfs_btree_check_ptr(cur, rpp, i, level); 2110 error = xfs_btree_check_ptr(cur, rpp, i, level);
1926 if (error) 2111 if (error)
1927 goto error0; 2112 goto error0;
1928 } 2113 }
1929 #endif 2114 #endif
1930 2115
1931 xfs_btree_shift_keys(cur, rkp, 1, rrecs); 2116 xfs_btree_shift_keys(cur, rkp, 1, rrecs);
1932 xfs_btree_shift_ptrs(cur, rpp, 1, rrecs); 2117 xfs_btree_shift_ptrs(cur, rpp, 1, rrecs);
1933 2118
1934 #ifdef DEBUG 2119 #ifdef DEBUG
1935 error = xfs_btree_check_ptr(cur, lpp, 0, level); 2120 error = xfs_btree_check_ptr(cur, lpp, 0, level);
1936 if (error) 2121 if (error)
1937 goto error0; 2122 goto error0;
1938 #endif 2123 #endif
1939 2124
1940 /* Now put the new data in, and log it. */ 2125 /* Now put the new data in, and log it. */
1941 xfs_btree_copy_keys(cur, rkp, lkp, 1); 2126 xfs_btree_copy_keys(cur, rkp, lkp, 1);
1942 xfs_btree_copy_ptrs(cur, rpp, lpp, 1); 2127 xfs_btree_copy_ptrs(cur, rpp, lpp, 1);
1943 2128
1944 xfs_btree_log_keys(cur, rbp, 1, rrecs + 1); 2129 xfs_btree_log_keys(cur, rbp, 1, rrecs + 1);
1945 xfs_btree_log_ptrs(cur, rbp, 1, rrecs + 1); 2130 xfs_btree_log_ptrs(cur, rbp, 1, rrecs + 1);
1946 2131
1947 xfs_btree_check_key(cur->bc_btnum, rkp, 2132 xfs_btree_check_key(cur->bc_btnum, rkp,
1948 xfs_btree_key_addr(cur, 2, right)); 2133 xfs_btree_key_addr(cur, 2, right));
1949 } else { 2134 } else {
1950 /* It's a leaf. make a hole in the records */ 2135 /* It's a leaf. make a hole in the records */
1951 union xfs_btree_rec *lrp; 2136 union xfs_btree_rec *lrp;
1952 union xfs_btree_rec *rrp; 2137 union xfs_btree_rec *rrp;
1953 2138
1954 lrp = xfs_btree_rec_addr(cur, lrecs, left); 2139 lrp = xfs_btree_rec_addr(cur, lrecs, left);
1955 rrp = xfs_btree_rec_addr(cur, 1, right); 2140 rrp = xfs_btree_rec_addr(cur, 1, right);
1956 2141
1957 xfs_btree_shift_recs(cur, rrp, 1, rrecs); 2142 xfs_btree_shift_recs(cur, rrp, 1, rrecs);
1958 2143
1959 /* Now put the new data in, and log it. */ 2144 /* Now put the new data in, and log it. */
1960 xfs_btree_copy_recs(cur, rrp, lrp, 1); 2145 xfs_btree_copy_recs(cur, rrp, lrp, 1);
1961 xfs_btree_log_recs(cur, rbp, 1, rrecs + 1); 2146 xfs_btree_log_recs(cur, rbp, 1, rrecs + 1);
1962 2147
1963 cur->bc_ops->init_key_from_rec(&key, rrp); 2148 cur->bc_ops->init_key_from_rec(&key, rrp);
1964 rkp = &key; 2149 rkp = &key;
1965 2150
1966 xfs_btree_check_rec(cur->bc_btnum, rrp, 2151 xfs_btree_check_rec(cur->bc_btnum, rrp,
1967 xfs_btree_rec_addr(cur, 2, right)); 2152 xfs_btree_rec_addr(cur, 2, right));
1968 } 2153 }
1969 2154
1970 /* 2155 /*
1971 * Decrement and log left's numrecs, bump and log right's numrecs. 2156 * Decrement and log left's numrecs, bump and log right's numrecs.
1972 */ 2157 */
1973 xfs_btree_set_numrecs(left, --lrecs); 2158 xfs_btree_set_numrecs(left, --lrecs);
1974 xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS); 2159 xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS);
1975 2160
1976 xfs_btree_set_numrecs(right, ++rrecs); 2161 xfs_btree_set_numrecs(right, ++rrecs);
1977 xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS); 2162 xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS);
1978 2163
1979 /* 2164 /*
1980 * Using a temporary cursor, update the parent key values of the 2165 * Using a temporary cursor, update the parent key values of the
1981 * block on the right. 2166 * block on the right.
1982 */ 2167 */
1983 error = xfs_btree_dup_cursor(cur, &tcur); 2168 error = xfs_btree_dup_cursor(cur, &tcur);
1984 if (error) 2169 if (error)
1985 goto error0; 2170 goto error0;
1986 i = xfs_btree_lastrec(tcur, level); 2171 i = xfs_btree_lastrec(tcur, level);
1987 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 2172 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1988 2173
1989 error = xfs_btree_increment(tcur, level, &i); 2174 error = xfs_btree_increment(tcur, level, &i);
1990 if (error) 2175 if (error)
1991 goto error1; 2176 goto error1;
1992 2177
1993 error = xfs_btree_updkey(tcur, rkp, level + 1); 2178 error = xfs_btree_updkey(tcur, rkp, level + 1);
1994 if (error) 2179 if (error)
1995 goto error1; 2180 goto error1;
1996 2181
1997 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); 2182 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
1998 2183
1999 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 2184 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2000 *stat = 1; 2185 *stat = 1;
2001 return 0; 2186 return 0;
2002 2187
2003 out0: 2188 out0:
2004 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 2189 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2005 *stat = 0; 2190 *stat = 0;
2006 return 0; 2191 return 0;
2007 2192
2008 error0: 2193 error0:
2009 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 2194 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
2010 return error; 2195 return error;
2011 2196
2012 error1: 2197 error1:
2013 XFS_BTREE_TRACE_CURSOR(tcur, XBT_ERROR); 2198 XFS_BTREE_TRACE_CURSOR(tcur, XBT_ERROR);
2014 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); 2199 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
2015 return error; 2200 return error;
2016 } 2201 }
2017 2202
1 /* 1 /*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #ifndef __XFS_BTREE_H__ 18 #ifndef __XFS_BTREE_H__
19 #define __XFS_BTREE_H__ 19 #define __XFS_BTREE_H__
20 20
21 struct xfs_buf; 21 struct xfs_buf;
22 struct xfs_bmap_free; 22 struct xfs_bmap_free;
23 struct xfs_inode; 23 struct xfs_inode;
24 struct xfs_mount; 24 struct xfs_mount;
25 struct xfs_trans; 25 struct xfs_trans;
26 26
27 extern kmem_zone_t *xfs_btree_cur_zone; 27 extern kmem_zone_t *xfs_btree_cur_zone;
28 28
29 /* 29 /*
30 * This nonsense is to make -wlint happy. 30 * This nonsense is to make -wlint happy.
31 */ 31 */
32 #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi) 32 #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi)
33 #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi) 33 #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi)
34 #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi) 34 #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi)
35 35
36 #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi) 36 #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi)
37 #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) 37 #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi)
38 #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) 38 #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi)
39 #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) 39 #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi)
40 40
41 /* 41 /*
42 * Short form header: space allocation btrees. 42 * Short form header: space allocation btrees.
43 */ 43 */
44 typedef struct xfs_btree_sblock { 44 typedef struct xfs_btree_sblock {
45 __be32 bb_magic; /* magic number for block type */ 45 __be32 bb_magic; /* magic number for block type */
46 __be16 bb_level; /* 0 is a leaf */ 46 __be16 bb_level; /* 0 is a leaf */
47 __be16 bb_numrecs; /* current # of data records */ 47 __be16 bb_numrecs; /* current # of data records */
48 __be32 bb_leftsib; /* left sibling block or NULLAGBLOCK */ 48 __be32 bb_leftsib; /* left sibling block or NULLAGBLOCK */
49 __be32 bb_rightsib; /* right sibling block or NULLAGBLOCK */ 49 __be32 bb_rightsib; /* right sibling block or NULLAGBLOCK */
50 } xfs_btree_sblock_t; 50 } xfs_btree_sblock_t;
51 51
52 /* 52 /*
53 * Long form header: bmap btrees. 53 * Long form header: bmap btrees.
54 */ 54 */
55 typedef struct xfs_btree_lblock { 55 typedef struct xfs_btree_lblock {
56 __be32 bb_magic; /* magic number for block type */ 56 __be32 bb_magic; /* magic number for block type */
57 __be16 bb_level; /* 0 is a leaf */ 57 __be16 bb_level; /* 0 is a leaf */
58 __be16 bb_numrecs; /* current # of data records */ 58 __be16 bb_numrecs; /* current # of data records */
59 __be64 bb_leftsib; /* left sibling block or NULLDFSBNO */ 59 __be64 bb_leftsib; /* left sibling block or NULLDFSBNO */
60 __be64 bb_rightsib; /* right sibling block or NULLDFSBNO */ 60 __be64 bb_rightsib; /* right sibling block or NULLDFSBNO */
61 } xfs_btree_lblock_t; 61 } xfs_btree_lblock_t;
62 62
63 /* 63 /*
64 * Combined header and structure, used by common code. 64 * Combined header and structure, used by common code.
65 */ 65 */
66 typedef struct xfs_btree_block { 66 typedef struct xfs_btree_block {
67 __be32 bb_magic; /* magic number for block type */ 67 __be32 bb_magic; /* magic number for block type */
68 __be16 bb_level; /* 0 is a leaf */ 68 __be16 bb_level; /* 0 is a leaf */
69 __be16 bb_numrecs; /* current # of data records */ 69 __be16 bb_numrecs; /* current # of data records */
70 union { 70 union {
71 struct { 71 struct {
72 __be32 bb_leftsib; 72 __be32 bb_leftsib;
73 __be32 bb_rightsib; 73 __be32 bb_rightsib;
74 } s; /* short form pointers */ 74 } s; /* short form pointers */
75 struct { 75 struct {
76 __be64 bb_leftsib; 76 __be64 bb_leftsib;
77 __be64 bb_rightsib; 77 __be64 bb_rightsib;
78 } l; /* long form pointers */ 78 } l; /* long form pointers */
79 } bb_u; /* rest */ 79 } bb_u; /* rest */
80 } xfs_btree_block_t; 80 } xfs_btree_block_t;
81 81
82 /* 82 /*
83 * Generic key, ptr and record wrapper structures. 83 * Generic key, ptr and record wrapper structures.
84 * 84 *
85 * These are disk format structures, and are converted where necessary 85 * These are disk format structures, and are converted where necessary
86 * by the btree specific code that needs to interpret them. 86 * by the btree specific code that needs to interpret them.
87 */ 87 */
88 union xfs_btree_ptr { 88 union xfs_btree_ptr {
89 __be32 s; /* short form ptr */ 89 __be32 s; /* short form ptr */
90 __be64 l; /* long form ptr */ 90 __be64 l; /* long form ptr */
91 }; 91 };
92 92
93 union xfs_btree_key { 93 union xfs_btree_key {
94 xfs_bmbt_key_t bmbt; 94 xfs_bmbt_key_t bmbt;
95 xfs_bmdr_key_t bmbr; /* bmbt root block */ 95 xfs_bmdr_key_t bmbr; /* bmbt root block */
96 xfs_alloc_key_t alloc; 96 xfs_alloc_key_t alloc;
97 xfs_inobt_key_t inobt; 97 xfs_inobt_key_t inobt;
98 }; 98 };
99 99
100 union xfs_btree_rec { 100 union xfs_btree_rec {
101 xfs_bmbt_rec_t bmbt; 101 xfs_bmbt_rec_t bmbt;
102 xfs_bmdr_rec_t bmbr; /* bmbt root block */ 102 xfs_bmdr_rec_t bmbr; /* bmbt root block */
103 xfs_alloc_rec_t alloc; 103 xfs_alloc_rec_t alloc;
104 xfs_inobt_rec_t inobt; 104 xfs_inobt_rec_t inobt;
105 }; 105 };
106 106
107 /* 107 /*
108 * For logging record fields. 108 * For logging record fields.
109 */ 109 */
110 #define XFS_BB_MAGIC 0x01 110 #define XFS_BB_MAGIC 0x01
111 #define XFS_BB_LEVEL 0x02 111 #define XFS_BB_LEVEL 0x02
112 #define XFS_BB_NUMRECS 0x04 112 #define XFS_BB_NUMRECS 0x04
113 #define XFS_BB_LEFTSIB 0x08 113 #define XFS_BB_LEFTSIB 0x08
114 #define XFS_BB_RIGHTSIB 0x10 114 #define XFS_BB_RIGHTSIB 0x10
115 #define XFS_BB_NUM_BITS 5 115 #define XFS_BB_NUM_BITS 5
116 #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) 116 #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1)
117 117
118 /* 118 /*
119 * Magic numbers for btree blocks. 119 * Magic numbers for btree blocks.
120 */ 120 */
121 extern const __uint32_t xfs_magics[]; 121 extern const __uint32_t xfs_magics[];
122 122
123 /* 123 /*
124 * Generic stats interface 124 * Generic stats interface
125 */ 125 */
126 #define __XFS_BTREE_STATS_INC(type, stat) \ 126 #define __XFS_BTREE_STATS_INC(type, stat) \
127 XFS_STATS_INC(xs_ ## type ## _2_ ## stat) 127 XFS_STATS_INC(xs_ ## type ## _2_ ## stat)
128 #define XFS_BTREE_STATS_INC(cur, stat) \ 128 #define XFS_BTREE_STATS_INC(cur, stat) \
129 do { \ 129 do { \
130 switch (cur->bc_btnum) { \ 130 switch (cur->bc_btnum) { \
131 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \ 131 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \
132 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ 132 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \
133 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ 133 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \
134 case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ 134 case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \
135 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ 135 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
136 } \ 136 } \
137 } while (0) 137 } while (0)
138 138
139 #define __XFS_BTREE_STATS_ADD(type, stat, val) \ 139 #define __XFS_BTREE_STATS_ADD(type, stat, val) \
140 XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val) 140 XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val)
141 #define XFS_BTREE_STATS_ADD(cur, stat, val) \ 141 #define XFS_BTREE_STATS_ADD(cur, stat, val) \
142 do { \ 142 do { \
143 switch (cur->bc_btnum) { \ 143 switch (cur->bc_btnum) { \
144 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \ 144 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \
145 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ 145 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \
146 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ 146 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
147 case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ 147 case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
148 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ 148 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
149 } \ 149 } \
150 } while (0) 150 } while (0)
151 /* 151 /*
152 * Maximum and minimum records in a btree block. 152 * Maximum and minimum records in a btree block.
153 * Given block size, type prefix, and leaf flag (0 or 1). 153 * Given block size, type prefix, and leaf flag (0 or 1).
154 * The divisor below is equivalent to lf ? (e1) : (e2) but that produces 154 * The divisor below is equivalent to lf ? (e1) : (e2) but that produces
155 * compiler warnings. 155 * compiler warnings.
156 */ 156 */
157 #define XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) \ 157 #define XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) \
158 ((int)(((bsz) - (uint)sizeof(t ## _block_t)) / \ 158 ((int)(((bsz) - (uint)sizeof(t ## _block_t)) / \
159 (((lf) * (uint)sizeof(t ## _rec_t)) + \ 159 (((lf) * (uint)sizeof(t ## _rec_t)) + \
160 ((1 - (lf)) * \ 160 ((1 - (lf)) * \
161 ((uint)sizeof(t ## _key_t) + (uint)sizeof(t ## _ptr_t)))))) 161 ((uint)sizeof(t ## _key_t) + (uint)sizeof(t ## _ptr_t))))))
162 #define XFS_BTREE_BLOCK_MINRECS(bsz,t,lf) \ 162 #define XFS_BTREE_BLOCK_MINRECS(bsz,t,lf) \
163 (XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) / 2) 163 (XFS_BTREE_BLOCK_MAXRECS(bsz,t,lf) / 2)
164 164
165 /* 165 /*
166 * Record, key, and pointer address calculation macros. 166 * Record, key, and pointer address calculation macros.
167 * Given block size, type prefix, block pointer, and index of requested entry 167 * Given block size, type prefix, block pointer, and index of requested entry
168 * (first entry numbered 1). 168 * (first entry numbered 1).
169 */ 169 */
170 #define XFS_BTREE_REC_ADDR(t,bb,i) \ 170 #define XFS_BTREE_REC_ADDR(t,bb,i) \
171 ((t ## _rec_t *)((char *)(bb) + sizeof(t ## _block_t) + \ 171 ((t ## _rec_t *)((char *)(bb) + sizeof(t ## _block_t) + \
172 ((i) - 1) * sizeof(t ## _rec_t))) 172 ((i) - 1) * sizeof(t ## _rec_t)))
173 #define XFS_BTREE_KEY_ADDR(t,bb,i) \ 173 #define XFS_BTREE_KEY_ADDR(t,bb,i) \
174 ((t ## _key_t *)((char *)(bb) + sizeof(t ## _block_t) + \ 174 ((t ## _key_t *)((char *)(bb) + sizeof(t ## _block_t) + \
175 ((i) - 1) * sizeof(t ## _key_t))) 175 ((i) - 1) * sizeof(t ## _key_t)))
176 #define XFS_BTREE_PTR_ADDR(t,bb,i,mxr) \ 176 #define XFS_BTREE_PTR_ADDR(t,bb,i,mxr) \
177 ((t ## _ptr_t *)((char *)(bb) + sizeof(t ## _block_t) + \ 177 ((t ## _ptr_t *)((char *)(bb) + sizeof(t ## _block_t) + \
178 (mxr) * sizeof(t ## _key_t) + ((i) - 1) * sizeof(t ## _ptr_t))) 178 (mxr) * sizeof(t ## _key_t) + ((i) - 1) * sizeof(t ## _ptr_t)))
179 179
180 #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */ 180 #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */
181 181
182 struct xfs_btree_ops { 182 struct xfs_btree_ops {
183 /* size of the key and record structures */ 183 /* size of the key and record structures */
184 size_t key_len; 184 size_t key_len;
185 size_t rec_len; 185 size_t rec_len;
186 186
187 /* cursor operations */ 187 /* cursor operations */
188 struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); 188 struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
189 189
190 /* update last record information */ 190 /* update last record information */
191 void (*update_lastrec)(struct xfs_btree_cur *cur, 191 void (*update_lastrec)(struct xfs_btree_cur *cur,
192 struct xfs_btree_block *block, 192 struct xfs_btree_block *block,
193 union xfs_btree_rec *rec, 193 union xfs_btree_rec *rec,
194 int ptr, int reason); 194 int ptr, int reason);
195 195
196 /* records in block/level */ 196 /* records in block/level */
197 int (*get_maxrecs)(struct xfs_btree_cur *cur, int level); 197 int (*get_maxrecs)(struct xfs_btree_cur *cur, int level);
198 198
199 /* init values of btree structures */ 199 /* init values of btree structures */
200 void (*init_key_from_rec)(union xfs_btree_key *key, 200 void (*init_key_from_rec)(union xfs_btree_key *key,
201 union xfs_btree_rec *rec); 201 union xfs_btree_rec *rec);
202 void (*init_ptr_from_cur)(struct xfs_btree_cur *cur, 202 void (*init_ptr_from_cur)(struct xfs_btree_cur *cur,
203 union xfs_btree_ptr *ptr); 203 union xfs_btree_ptr *ptr);
204 204
205 /* difference between key value and cursor value */ 205 /* difference between key value and cursor value */
206 __int64_t (*key_diff)(struct xfs_btree_cur *cur, 206 __int64_t (*key_diff)(struct xfs_btree_cur *cur,
207 union xfs_btree_key *key); 207 union xfs_btree_key *key);
208 208
209 /* btree tracing */ 209 /* btree tracing */
210 #ifdef XFS_BTREE_TRACE 210 #ifdef XFS_BTREE_TRACE
211 void (*trace_enter)(struct xfs_btree_cur *, const char *, 211 void (*trace_enter)(struct xfs_btree_cur *, const char *,
212 char *, int, int, __psunsigned_t, 212 char *, int, int, __psunsigned_t,
213 __psunsigned_t, __psunsigned_t, 213 __psunsigned_t, __psunsigned_t,
214 __psunsigned_t, __psunsigned_t, 214 __psunsigned_t, __psunsigned_t,
215 __psunsigned_t, __psunsigned_t, 215 __psunsigned_t, __psunsigned_t,
216 __psunsigned_t, __psunsigned_t, 216 __psunsigned_t, __psunsigned_t,
217 __psunsigned_t, __psunsigned_t); 217 __psunsigned_t, __psunsigned_t);
218 void (*trace_cursor)(struct xfs_btree_cur *, __uint32_t *, 218 void (*trace_cursor)(struct xfs_btree_cur *, __uint32_t *,
219 __uint64_t *, __uint64_t *); 219 __uint64_t *, __uint64_t *);
220 void (*trace_key)(struct xfs_btree_cur *, 220 void (*trace_key)(struct xfs_btree_cur *,
221 union xfs_btree_key *, __uint64_t *, 221 union xfs_btree_key *, __uint64_t *,
222 __uint64_t *); 222 __uint64_t *);
223 void (*trace_record)(struct xfs_btree_cur *, 223 void (*trace_record)(struct xfs_btree_cur *,
224 union xfs_btree_rec *, __uint64_t *, 224 union xfs_btree_rec *, __uint64_t *,
225 __uint64_t *, __uint64_t *); 225 __uint64_t *, __uint64_t *);
226 #endif 226 #endif
227 }; 227 };
228 228
229 /* 229 /*
230 * Reasons for the update_lastrec method to be called. 230 * Reasons for the update_lastrec method to be called.
231 */ 231 */
232 #define LASTREC_UPDATE 0 232 #define LASTREC_UPDATE 0
233 233
234 234
235 /* 235 /*
236 * Btree cursor structure. 236 * Btree cursor structure.
237 * This collects all information needed by the btree code in one place. 237 * This collects all information needed by the btree code in one place.
238 */ 238 */
239 typedef struct xfs_btree_cur 239 typedef struct xfs_btree_cur
240 { 240 {
241 struct xfs_trans *bc_tp; /* transaction we're in, if any */ 241 struct xfs_trans *bc_tp; /* transaction we're in, if any */
242 struct xfs_mount *bc_mp; /* file system mount struct */ 242 struct xfs_mount *bc_mp; /* file system mount struct */
243 const struct xfs_btree_ops *bc_ops; 243 const struct xfs_btree_ops *bc_ops;
244 uint bc_flags; /* btree features - below */ 244 uint bc_flags; /* btree features - below */
245 union { 245 union {
246 xfs_alloc_rec_incore_t a; 246 xfs_alloc_rec_incore_t a;
247 xfs_bmbt_irec_t b; 247 xfs_bmbt_irec_t b;
248 xfs_inobt_rec_incore_t i; 248 xfs_inobt_rec_incore_t i;
249 } bc_rec; /* current insert/search record value */ 249 } bc_rec; /* current insert/search record value */
250 struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ 250 struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */
251 int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ 251 int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */
252 __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */ 252 __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */
253 #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ 253 #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */
254 #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ 254 #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */
255 __uint8_t bc_nlevels; /* number of levels in the tree */ 255 __uint8_t bc_nlevels; /* number of levels in the tree */
256 __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ 256 __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */
257 xfs_btnum_t bc_btnum; /* identifies which btree type */ 257 xfs_btnum_t bc_btnum; /* identifies which btree type */
258 union { 258 union {
259 struct { /* needed for BNO, CNT, INO */ 259 struct { /* needed for BNO, CNT, INO */
260 struct xfs_buf *agbp; /* agf/agi buffer pointer */ 260 struct xfs_buf *agbp; /* agf/agi buffer pointer */
261 xfs_agnumber_t agno; /* ag number */ 261 xfs_agnumber_t agno; /* ag number */
262 } a; 262 } a;
263 struct { /* needed for BMAP */ 263 struct { /* needed for BMAP */
264 struct xfs_inode *ip; /* pointer to our inode */ 264 struct xfs_inode *ip; /* pointer to our inode */
265 struct xfs_bmap_free *flist; /* list to free after */ 265 struct xfs_bmap_free *flist; /* list to free after */
266 xfs_fsblock_t firstblock; /* 1st blk allocated */ 266 xfs_fsblock_t firstblock; /* 1st blk allocated */
267 int allocated; /* count of alloced */ 267 int allocated; /* count of alloced */
268 short forksize; /* fork's inode space */ 268 short forksize; /* fork's inode space */
269 char whichfork; /* data or attr fork */ 269 char whichfork; /* data or attr fork */
270 char flags; /* flags */ 270 char flags; /* flags */
271 #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ 271 #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */
272 } b; 272 } b;
273 } bc_private; /* per-btree type data */ 273 } bc_private; /* per-btree type data */
274 } xfs_btree_cur_t; 274 } xfs_btree_cur_t;
275 275
276 /* cursor flags */ 276 /* cursor flags */
277 #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ 277 #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */
278 #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ 278 #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */
279 #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ 279 #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */
280 280
281 281
282 #define XFS_BTREE_NOERROR 0 282 #define XFS_BTREE_NOERROR 0
283 #define XFS_BTREE_ERROR 1 283 #define XFS_BTREE_ERROR 1
284 284
285 /* 285 /*
286 * Convert from buffer to btree block header. 286 * Convert from buffer to btree block header.
287 */ 287 */
288 #define XFS_BUF_TO_BLOCK(bp) ((xfs_btree_block_t *)XFS_BUF_PTR(bp)) 288 #define XFS_BUF_TO_BLOCK(bp) ((xfs_btree_block_t *)XFS_BUF_PTR(bp))
289 #define XFS_BUF_TO_LBLOCK(bp) ((xfs_btree_lblock_t *)XFS_BUF_PTR(bp)) 289 #define XFS_BUF_TO_LBLOCK(bp) ((xfs_btree_lblock_t *)XFS_BUF_PTR(bp))
290 #define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)XFS_BUF_PTR(bp)) 290 #define XFS_BUF_TO_SBLOCK(bp) ((xfs_btree_sblock_t *)XFS_BUF_PTR(bp))
291 291
292 292
293 #ifdef __KERNEL__ 293 #ifdef __KERNEL__
294 294
295 /* 295 /*
296 * Check that long form block header is ok. 296 * Check that long form block header is ok.
297 */ 297 */
298 int /* error (0 or EFSCORRUPTED) */ 298 int /* error (0 or EFSCORRUPTED) */
299 xfs_btree_check_lblock( 299 xfs_btree_check_lblock(
300 struct xfs_btree_cur *cur, /* btree cursor */ 300 struct xfs_btree_cur *cur, /* btree cursor */
301 struct xfs_btree_lblock *block, /* btree long form block pointer */ 301 struct xfs_btree_lblock *block, /* btree long form block pointer */
302 int level, /* level of the btree block */ 302 int level, /* level of the btree block */
303 struct xfs_buf *bp); /* buffer containing block, if any */ 303 struct xfs_buf *bp); /* buffer containing block, if any */
304 304
305 /* 305 /*
306 * Check that short form block header is ok. 306 * Check that short form block header is ok.
307 */ 307 */
308 int /* error (0 or EFSCORRUPTED) */ 308 int /* error (0 or EFSCORRUPTED) */
309 xfs_btree_check_sblock( 309 xfs_btree_check_sblock(
310 struct xfs_btree_cur *cur, /* btree cursor */ 310 struct xfs_btree_cur *cur, /* btree cursor */
311 struct xfs_btree_sblock *block, /* btree short form block pointer */ 311 struct xfs_btree_sblock *block, /* btree short form block pointer */
312 int level, /* level of the btree block */ 312 int level, /* level of the btree block */
313 struct xfs_buf *bp); /* buffer containing block */ 313 struct xfs_buf *bp); /* buffer containing block */
314 314
315 /* 315 /*
316 * Check that block header is ok. 316 * Check that block header is ok.
317 */ 317 */
318 int 318 int
319 xfs_btree_check_block( 319 xfs_btree_check_block(
320 struct xfs_btree_cur *cur, /* btree cursor */ 320 struct xfs_btree_cur *cur, /* btree cursor */
321 struct xfs_btree_block *block, /* generic btree block pointer */ 321 struct xfs_btree_block *block, /* generic btree block pointer */
322 int level, /* level of the btree block */ 322 int level, /* level of the btree block */
323 struct xfs_buf *bp); /* buffer containing block, if any */ 323 struct xfs_buf *bp); /* buffer containing block, if any */
324 324
325 /* 325 /*
326 * Check that (long) pointer is ok. 326 * Check that (long) pointer is ok.
327 */ 327 */
328 int /* error (0 or EFSCORRUPTED) */ 328 int /* error (0 or EFSCORRUPTED) */
329 xfs_btree_check_lptr( 329 xfs_btree_check_lptr(
330 struct xfs_btree_cur *cur, /* btree cursor */ 330 struct xfs_btree_cur *cur, /* btree cursor */
331 xfs_dfsbno_t ptr, /* btree block disk address */ 331 xfs_dfsbno_t ptr, /* btree block disk address */
332 int level); /* btree block level */ 332 int level); /* btree block level */
333 333
334 #define xfs_btree_check_lptr_disk(cur, ptr, level) \ 334 #define xfs_btree_check_lptr_disk(cur, ptr, level) \
335 xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level) 335 xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level)
336 336
337 337
338 /* 338 /*
339 * Check that (short) pointer is ok. 339 * Check that (short) pointer is ok.
340 */ 340 */
341 int /* error (0 or EFSCORRUPTED) */ 341 int /* error (0 or EFSCORRUPTED) */
342 xfs_btree_check_sptr( 342 xfs_btree_check_sptr(
343 struct xfs_btree_cur *cur, /* btree cursor */ 343 struct xfs_btree_cur *cur, /* btree cursor */
344 xfs_agblock_t ptr, /* btree block disk address */ 344 xfs_agblock_t ptr, /* btree block disk address */
345 int level); /* btree block level */ 345 int level); /* btree block level */
346 346
347 /* 347 /*
348 * Check that (short) pointer is ok. 348 * Check that (short) pointer is ok.
349 */ 349 */
350 int /* error (0 or EFSCORRUPTED) */ 350 int /* error (0 or EFSCORRUPTED) */
351 xfs_btree_check_ptr( 351 xfs_btree_check_ptr(
352 struct xfs_btree_cur *cur, /* btree cursor */ 352 struct xfs_btree_cur *cur, /* btree cursor */
353 union xfs_btree_ptr *ptr, /* btree block disk address */ 353 union xfs_btree_ptr *ptr, /* btree block disk address */
354 int index, /* offset from ptr to check */ 354 int index, /* offset from ptr to check */
355 int level); /* btree block level */ 355 int level); /* btree block level */
356 356
357 #ifdef DEBUG 357 #ifdef DEBUG
358 358
359 /* 359 /*
360 * Debug routine: check that keys are in the right order. 360 * Debug routine: check that keys are in the right order.
361 */ 361 */
362 void 362 void
363 xfs_btree_check_key( 363 xfs_btree_check_key(
364 xfs_btnum_t btnum, /* btree identifier */ 364 xfs_btnum_t btnum, /* btree identifier */
365 void *ak1, /* pointer to left (lower) key */ 365 void *ak1, /* pointer to left (lower) key */
366 void *ak2); /* pointer to right (higher) key */ 366 void *ak2); /* pointer to right (higher) key */
367 367
368 /* 368 /*
369 * Debug routine: check that records are in the right order. 369 * Debug routine: check that records are in the right order.
370 */ 370 */
371 void 371 void
372 xfs_btree_check_rec( 372 xfs_btree_check_rec(
373 xfs_btnum_t btnum, /* btree identifier */ 373 xfs_btnum_t btnum, /* btree identifier */
374 void *ar1, /* pointer to left (lower) record */ 374 void *ar1, /* pointer to left (lower) record */
375 void *ar2); /* pointer to right (higher) record */ 375 void *ar2); /* pointer to right (higher) record */
376 #else 376 #else
377 #define xfs_btree_check_key(a, b, c) 377 #define xfs_btree_check_key(a, b, c)
378 #define xfs_btree_check_rec(a, b, c) 378 #define xfs_btree_check_rec(a, b, c)
379 #endif /* DEBUG */ 379 #endif /* DEBUG */
380 380
381 /* 381 /*
382 * Delete the btree cursor. 382 * Delete the btree cursor.
383 */ 383 */
384 void 384 void
385 xfs_btree_del_cursor( 385 xfs_btree_del_cursor(
386 xfs_btree_cur_t *cur, /* btree cursor */ 386 xfs_btree_cur_t *cur, /* btree cursor */
387 int error); /* del because of error */ 387 int error); /* del because of error */
388 388
389 /* 389 /*
390 * Duplicate the btree cursor. 390 * Duplicate the btree cursor.
391 * Allocate a new one, copy the record, re-get the buffers. 391 * Allocate a new one, copy the record, re-get the buffers.
392 */ 392 */
393 int /* error */ 393 int /* error */
394 xfs_btree_dup_cursor( 394 xfs_btree_dup_cursor(
395 xfs_btree_cur_t *cur, /* input cursor */ 395 xfs_btree_cur_t *cur, /* input cursor */
396 xfs_btree_cur_t **ncur);/* output cursor */ 396 xfs_btree_cur_t **ncur);/* output cursor */
397 397
398 /* 398 /*
399 * Change the cursor to point to the first record in the current block 399 * Change the cursor to point to the first record in the current block
400 * at the given level. Other levels are unaffected. 400 * at the given level. Other levels are unaffected.
401 */ 401 */
402 int /* success=1, failure=0 */ 402 int /* success=1, failure=0 */
403 xfs_btree_firstrec( 403 xfs_btree_firstrec(
404 xfs_btree_cur_t *cur, /* btree cursor */ 404 xfs_btree_cur_t *cur, /* btree cursor */
405 int level); /* level to change */ 405 int level); /* level to change */
406 406
407 /* 407 /*
408 * Get a buffer for the block, return it with no data read. 408 * Get a buffer for the block, return it with no data read.
409 * Long-form addressing. 409 * Long-form addressing.
410 */ 410 */
411 struct xfs_buf * /* buffer for fsbno */ 411 struct xfs_buf * /* buffer for fsbno */
412 xfs_btree_get_bufl( 412 xfs_btree_get_bufl(
413 struct xfs_mount *mp, /* file system mount point */ 413 struct xfs_mount *mp, /* file system mount point */
414 struct xfs_trans *tp, /* transaction pointer */ 414 struct xfs_trans *tp, /* transaction pointer */
415 xfs_fsblock_t fsbno, /* file system block number */ 415 xfs_fsblock_t fsbno, /* file system block number */
416 uint lock); /* lock flags for get_buf */ 416 uint lock); /* lock flags for get_buf */
417 417
418 /* 418 /*
419 * Get a buffer for the block, return it with no data read. 419 * Get a buffer for the block, return it with no data read.
420 * Short-form addressing. 420 * Short-form addressing.
421 */ 421 */
422 struct xfs_buf * /* buffer for agno/agbno */ 422 struct xfs_buf * /* buffer for agno/agbno */
423 xfs_btree_get_bufs( 423 xfs_btree_get_bufs(
424 struct xfs_mount *mp, /* file system mount point */ 424 struct xfs_mount *mp, /* file system mount point */
425 struct xfs_trans *tp, /* transaction pointer */ 425 struct xfs_trans *tp, /* transaction pointer */
426 xfs_agnumber_t agno, /* allocation group number */ 426 xfs_agnumber_t agno, /* allocation group number */
427 xfs_agblock_t agbno, /* allocation group block number */ 427 xfs_agblock_t agbno, /* allocation group block number */
428 uint lock); /* lock flags for get_buf */ 428 uint lock); /* lock flags for get_buf */
429 429
430 /* 430 /*
431 * Check for the cursor referring to the last block at the given level. 431 * Check for the cursor referring to the last block at the given level.
432 */ 432 */
433 int /* 1=is last block, 0=not last block */ 433 int /* 1=is last block, 0=not last block */
434 xfs_btree_islastblock( 434 xfs_btree_islastblock(
435 xfs_btree_cur_t *cur, /* btree cursor */ 435 xfs_btree_cur_t *cur, /* btree cursor */
436 int level); /* level to check */ 436 int level); /* level to check */
437 437
438 /* 438 /*
439 * Change the cursor to point to the last record in the current block 439 * Change the cursor to point to the last record in the current block
440 * at the given level. Other levels are unaffected. 440 * at the given level. Other levels are unaffected.
441 */ 441 */
442 int /* success=1, failure=0 */ 442 int /* success=1, failure=0 */
443 xfs_btree_lastrec( 443 xfs_btree_lastrec(
444 xfs_btree_cur_t *cur, /* btree cursor */ 444 xfs_btree_cur_t *cur, /* btree cursor */
445 int level); /* level to change */ 445 int level); /* level to change */
446 446
447 /* 447 /*
448 * Compute first and last byte offsets for the fields given. 448 * Compute first and last byte offsets for the fields given.
449 * Interprets the offsets table, which contains struct field offsets. 449 * Interprets the offsets table, which contains struct field offsets.
450 */ 450 */
451 void 451 void
452 xfs_btree_offsets( 452 xfs_btree_offsets(
453 __int64_t fields, /* bitmask of fields */ 453 __int64_t fields, /* bitmask of fields */
454 const short *offsets,/* table of field offsets */ 454 const short *offsets,/* table of field offsets */
455 int nbits, /* number of bits to inspect */ 455 int nbits, /* number of bits to inspect */
456 int *first, /* output: first byte offset */ 456 int *first, /* output: first byte offset */
457 int *last); /* output: last byte offset */ 457 int *last); /* output: last byte offset */
458 458
459 /* 459 /*
460 * Get a buffer for the block, return it read in. 460 * Get a buffer for the block, return it read in.
461 * Long-form addressing. 461 * Long-form addressing.
462 */ 462 */
463 int /* error */ 463 int /* error */
464 xfs_btree_read_bufl( 464 xfs_btree_read_bufl(
465 struct xfs_mount *mp, /* file system mount point */ 465 struct xfs_mount *mp, /* file system mount point */
466 struct xfs_trans *tp, /* transaction pointer */ 466 struct xfs_trans *tp, /* transaction pointer */
467 xfs_fsblock_t fsbno, /* file system block number */ 467 xfs_fsblock_t fsbno, /* file system block number */
468 uint lock, /* lock flags for read_buf */ 468 uint lock, /* lock flags for read_buf */
469 struct xfs_buf **bpp, /* buffer for fsbno */ 469 struct xfs_buf **bpp, /* buffer for fsbno */
470 int refval);/* ref count value for buffer */ 470 int refval);/* ref count value for buffer */
471 471
472 /* 472 /*
473 * Get a buffer for the block, return it read in. 473 * Get a buffer for the block, return it read in.
474 * Short-form addressing. 474 * Short-form addressing.
475 */ 475 */
476 int /* error */ 476 int /* error */
477 xfs_btree_read_bufs( 477 xfs_btree_read_bufs(
478 struct xfs_mount *mp, /* file system mount point */ 478 struct xfs_mount *mp, /* file system mount point */
479 struct xfs_trans *tp, /* transaction pointer */ 479 struct xfs_trans *tp, /* transaction pointer */
480 xfs_agnumber_t agno, /* allocation group number */ 480 xfs_agnumber_t agno, /* allocation group number */
481 xfs_agblock_t agbno, /* allocation group block number */ 481 xfs_agblock_t agbno, /* allocation group block number */
482 uint lock, /* lock flags for read_buf */ 482 uint lock, /* lock flags for read_buf */
483 struct xfs_buf **bpp, /* buffer for agno/agbno */ 483 struct xfs_buf **bpp, /* buffer for agno/agbno */
484 int refval);/* ref count value for buffer */ 484 int refval);/* ref count value for buffer */
485 485
486 /* 486 /*
487 * Read-ahead the block, don't wait for it, don't return a buffer. 487 * Read-ahead the block, don't wait for it, don't return a buffer.
488 * Long-form addressing. 488 * Long-form addressing.
489 */ 489 */
490 void /* error */ 490 void /* error */
491 xfs_btree_reada_bufl( 491 xfs_btree_reada_bufl(
492 struct xfs_mount *mp, /* file system mount point */ 492 struct xfs_mount *mp, /* file system mount point */
493 xfs_fsblock_t fsbno, /* file system block number */ 493 xfs_fsblock_t fsbno, /* file system block number */
494 xfs_extlen_t count); /* count of filesystem blocks */ 494 xfs_extlen_t count); /* count of filesystem blocks */
495 495
496 /* 496 /*
497 * Read-ahead the block, don't wait for it, don't return a buffer. 497 * Read-ahead the block, don't wait for it, don't return a buffer.
498 * Short-form addressing. 498 * Short-form addressing.
499 */ 499 */
500 void /* error */ 500 void /* error */
501 xfs_btree_reada_bufs( 501 xfs_btree_reada_bufs(
502 struct xfs_mount *mp, /* file system mount point */ 502 struct xfs_mount *mp, /* file system mount point */
503 xfs_agnumber_t agno, /* allocation group number */ 503 xfs_agnumber_t agno, /* allocation group number */
504 xfs_agblock_t agbno, /* allocation group block number */ 504 xfs_agblock_t agbno, /* allocation group block number */
505 xfs_extlen_t count); /* count of filesystem blocks */ 505 xfs_extlen_t count); /* count of filesystem blocks */
506 506
507 /* 507 /*
508 * Read-ahead btree blocks, at the given level. 508 * Read-ahead btree blocks, at the given level.
509 * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA. 509 * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
510 */ 510 */
511 int /* readahead block count */ 511 int /* readahead block count */
512 xfs_btree_readahead( 512 xfs_btree_readahead(
513 xfs_btree_cur_t *cur, /* btree cursor */ 513 xfs_btree_cur_t *cur, /* btree cursor */
514 int lev, /* level in btree */ 514 int lev, /* level in btree */
515 int lr); /* left/right bits */ 515 int lr); /* left/right bits */
516 516
517 /* 517 /*
518 * Set the buffer for level "lev" in the cursor to bp, releasing 518 * Set the buffer for level "lev" in the cursor to bp, releasing
519 * any previous buffer. 519 * any previous buffer.
520 */ 520 */
521 void 521 void
522 xfs_btree_setbuf( 522 xfs_btree_setbuf(
523 xfs_btree_cur_t *cur, /* btree cursor */ 523 xfs_btree_cur_t *cur, /* btree cursor */
524 int lev, /* level in btree */ 524 int lev, /* level in btree */
525 struct xfs_buf *bp); /* new buffer to set */ 525 struct xfs_buf *bp); /* new buffer to set */
526 526
527 527
528 /* 528 /*
529 * Common btree core entry points. 529 * Common btree core entry points.
530 */ 530 */
531 int xfs_btree_increment(struct xfs_btree_cur *, int, int *); 531 int xfs_btree_increment(struct xfs_btree_cur *, int, int *);
532 int xfs_btree_decrement(struct xfs_btree_cur *, int, int *); 532 int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
533 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *); 533 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
534 int xfs_btree_updkey(struct xfs_btree_cur *, union xfs_btree_key *, int); 534 int xfs_btree_updkey(struct xfs_btree_cur *, union xfs_btree_key *, int);
535 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *); 535 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);
536 int xfs_btree_lshift(struct xfs_btree_cur *, int, int *);
536 int xfs_btree_rshift(struct xfs_btree_cur *, int, int *); 537 int xfs_btree_rshift(struct xfs_btree_cur *, int, int *);
537 538
538 /* 539 /*
539 * Helpers. 540 * Helpers.
540 */ 541 */
541 static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block) 542 static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block)
542 { 543 {
543 return be16_to_cpu(block->bb_numrecs); 544 return be16_to_cpu(block->bb_numrecs);
544 } 545 }
545 546
546 static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block, 547 static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block,
547 __uint16_t numrecs) 548 __uint16_t numrecs)
548 { 549 {
549 block->bb_numrecs = cpu_to_be16(numrecs); 550 block->bb_numrecs = cpu_to_be16(numrecs);
550 } 551 }
551 552
552 static inline int xfs_btree_get_level(struct xfs_btree_block *block) 553 static inline int xfs_btree_get_level(struct xfs_btree_block *block)
553 { 554 {
554 return be16_to_cpu(block->bb_level); 555 return be16_to_cpu(block->bb_level);
555 } 556 }
556 557
557 #endif /* __KERNEL__ */ 558 #endif /* __KERNEL__ */
558 559
559 560
560 /* 561 /*
561 * Min and max functions for extlen, agblock, fileoff, and filblks types. 562 * Min and max functions for extlen, agblock, fileoff, and filblks types.
562 */ 563 */
563 #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) 564 #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b))
564 #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) 565 #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b))
565 #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) 566 #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b))
566 #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) 567 #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b))
567 #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) 568 #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b))
568 #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) 569 #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b))
569 #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) 570 #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b))
570 #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) 571 #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b))
571 572
572 #define XFS_FSB_SANITY_CHECK(mp,fsb) \ 573 #define XFS_FSB_SANITY_CHECK(mp,fsb) \
573 (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ 574 (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \
574 XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks) 575 XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks)
575 576
576 #endif /* __XFS_BTREE_H__ */ 577 #endif /* __XFS_BTREE_H__ */
577 578
fs/xfs/xfs_ialloc_btree.c
1 /* 1 /*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 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 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_inum.h" 23 #include "xfs_inum.h"
24 #include "xfs_trans.h" 24 #include "xfs_trans.h"
25 #include "xfs_sb.h" 25 #include "xfs_sb.h"
26 #include "xfs_ag.h" 26 #include "xfs_ag.h"
27 #include "xfs_dir2.h" 27 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h" 28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h" 29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h" 31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h" 32 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h" 33 #include "xfs_dir2_sf.h"
34 #include "xfs_attr_sf.h" 34 #include "xfs_attr_sf.h"
35 #include "xfs_dinode.h" 35 #include "xfs_dinode.h"
36 #include "xfs_inode.h" 36 #include "xfs_inode.h"
37 #include "xfs_btree.h" 37 #include "xfs_btree.h"
38 #include "xfs_ialloc.h" 38 #include "xfs_ialloc.h"
39 #include "xfs_alloc.h" 39 #include "xfs_alloc.h"
40 #include "xfs_error.h" 40 #include "xfs_error.h"
41 41
42 STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int); 42 STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int);
43 STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); 43 STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
44 STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); 44 STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
45 STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int); 45 STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
46 STATIC int xfs_inobt_lshift(xfs_btree_cur_t *, int, int *);
47 STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *); 46 STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);
48 STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *, 47 STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
49 xfs_inobt_key_t *, xfs_btree_cur_t **, int *); 48 xfs_inobt_key_t *, xfs_btree_cur_t **, int *);
50 49
51 /* 50 /*
52 * Single level of the xfs_inobt_delete record deletion routine. 51 * Single level of the xfs_inobt_delete record deletion routine.
53 * Delete record pointed to by cur/level. 52 * Delete record pointed to by cur/level.
54 * Remove the record from its block then rebalance the tree. 53 * Remove the record from its block then rebalance the tree.
55 * Return 0 for error, 1 for done, 2 to go on to the next level. 54 * Return 0 for error, 1 for done, 2 to go on to the next level.
56 */ 55 */
57 STATIC int /* error */ 56 STATIC int /* error */
58 xfs_inobt_delrec( 57 xfs_inobt_delrec(
59 xfs_btree_cur_t *cur, /* btree cursor */ 58 xfs_btree_cur_t *cur, /* btree cursor */
60 int level, /* level removing record from */ 59 int level, /* level removing record from */
61 int *stat) /* fail/done/go-on */ 60 int *stat) /* fail/done/go-on */
62 { 61 {
63 xfs_buf_t *agbp; /* buffer for a.g. inode header */ 62 xfs_buf_t *agbp; /* buffer for a.g. inode header */
64 xfs_mount_t *mp; /* mount structure */ 63 xfs_mount_t *mp; /* mount structure */
65 xfs_agi_t *agi; /* allocation group inode header */ 64 xfs_agi_t *agi; /* allocation group inode header */
66 xfs_inobt_block_t *block; /* btree block record/key lives in */ 65 xfs_inobt_block_t *block; /* btree block record/key lives in */
67 xfs_agblock_t bno; /* btree block number */ 66 xfs_agblock_t bno; /* btree block number */
68 xfs_buf_t *bp; /* buffer for block */ 67 xfs_buf_t *bp; /* buffer for block */
69 int error; /* error return value */ 68 int error; /* error return value */
70 int i; /* loop index */ 69 int i; /* loop index */
71 xfs_inobt_key_t key; /* kp points here if block is level 0 */ 70 xfs_inobt_key_t key; /* kp points here if block is level 0 */
72 xfs_inobt_key_t *kp = NULL; /* pointer to btree keys */ 71 xfs_inobt_key_t *kp = NULL; /* pointer to btree keys */
73 xfs_agblock_t lbno; /* left block's block number */ 72 xfs_agblock_t lbno; /* left block's block number */
74 xfs_buf_t *lbp; /* left block's buffer pointer */ 73 xfs_buf_t *lbp; /* left block's buffer pointer */
75 xfs_inobt_block_t *left; /* left btree block */ 74 xfs_inobt_block_t *left; /* left btree block */
76 xfs_inobt_key_t *lkp; /* left block key pointer */ 75 xfs_inobt_key_t *lkp; /* left block key pointer */
77 xfs_inobt_ptr_t *lpp; /* left block address pointer */ 76 xfs_inobt_ptr_t *lpp; /* left block address pointer */
78 int lrecs = 0; /* number of records in left block */ 77 int lrecs = 0; /* number of records in left block */
79 xfs_inobt_rec_t *lrp; /* left block record pointer */ 78 xfs_inobt_rec_t *lrp; /* left block record pointer */
80 xfs_inobt_ptr_t *pp = NULL; /* pointer to btree addresses */ 79 xfs_inobt_ptr_t *pp = NULL; /* pointer to btree addresses */
81 int ptr; /* index in btree block for this rec */ 80 int ptr; /* index in btree block for this rec */
82 xfs_agblock_t rbno; /* right block's block number */ 81 xfs_agblock_t rbno; /* right block's block number */
83 xfs_buf_t *rbp; /* right block's buffer pointer */ 82 xfs_buf_t *rbp; /* right block's buffer pointer */
84 xfs_inobt_block_t *right; /* right btree block */ 83 xfs_inobt_block_t *right; /* right btree block */
85 xfs_inobt_key_t *rkp; /* right block key pointer */ 84 xfs_inobt_key_t *rkp; /* right block key pointer */
86 xfs_inobt_rec_t *rp; /* pointer to btree records */ 85 xfs_inobt_rec_t *rp; /* pointer to btree records */
87 xfs_inobt_ptr_t *rpp; /* right block address pointer */ 86 xfs_inobt_ptr_t *rpp; /* right block address pointer */
88 int rrecs = 0; /* number of records in right block */ 87 int rrecs = 0; /* number of records in right block */
89 int numrecs; 88 int numrecs;
90 xfs_inobt_rec_t *rrp; /* right block record pointer */ 89 xfs_inobt_rec_t *rrp; /* right block record pointer */
91 xfs_btree_cur_t *tcur; /* temporary btree cursor */ 90 xfs_btree_cur_t *tcur; /* temporary btree cursor */
92 91
93 mp = cur->bc_mp; 92 mp = cur->bc_mp;
94 93
95 /* 94 /*
96 * Get the index of the entry being deleted, check for nothing there. 95 * Get the index of the entry being deleted, check for nothing there.
97 */ 96 */
98 ptr = cur->bc_ptrs[level]; 97 ptr = cur->bc_ptrs[level];
99 if (ptr == 0) { 98 if (ptr == 0) {
100 *stat = 0; 99 *stat = 0;
101 return 0; 100 return 0;
102 } 101 }
103 102
104 /* 103 /*
105 * Get the buffer & block containing the record or key/ptr. 104 * Get the buffer & block containing the record or key/ptr.
106 */ 105 */
107 bp = cur->bc_bufs[level]; 106 bp = cur->bc_bufs[level];
108 block = XFS_BUF_TO_INOBT_BLOCK(bp); 107 block = XFS_BUF_TO_INOBT_BLOCK(bp);
109 #ifdef DEBUG 108 #ifdef DEBUG
110 if ((error = xfs_btree_check_sblock(cur, block, level, bp))) 109 if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
111 return error; 110 return error;
112 #endif 111 #endif
113 /* 112 /*
114 * Fail if we're off the end of the block. 113 * Fail if we're off the end of the block.
115 */ 114 */
116 115
117 numrecs = be16_to_cpu(block->bb_numrecs); 116 numrecs = be16_to_cpu(block->bb_numrecs);
118 if (ptr > numrecs) { 117 if (ptr > numrecs) {
119 *stat = 0; 118 *stat = 0;
120 return 0; 119 return 0;
121 } 120 }
122 /* 121 /*
123 * It's a nonleaf. Excise the key and ptr being deleted, by 122 * It's a nonleaf. Excise the key and ptr being deleted, by
124 * sliding the entries past them down one. 123 * sliding the entries past them down one.
125 * Log the changed areas of the block. 124 * Log the changed areas of the block.
126 */ 125 */
127 if (level > 0) { 126 if (level > 0) {
128 kp = XFS_INOBT_KEY_ADDR(block, 1, cur); 127 kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
129 pp = XFS_INOBT_PTR_ADDR(block, 1, cur); 128 pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
130 #ifdef DEBUG 129 #ifdef DEBUG
131 for (i = ptr; i < numrecs; i++) { 130 for (i = ptr; i < numrecs; i++) {
132 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i]), level))) 131 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i]), level)))
133 return error; 132 return error;
134 } 133 }
135 #endif 134 #endif
136 if (ptr < numrecs) { 135 if (ptr < numrecs) {
137 memmove(&kp[ptr - 1], &kp[ptr], 136 memmove(&kp[ptr - 1], &kp[ptr],
138 (numrecs - ptr) * sizeof(*kp)); 137 (numrecs - ptr) * sizeof(*kp));
139 memmove(&pp[ptr - 1], &pp[ptr], 138 memmove(&pp[ptr - 1], &pp[ptr],
140 (numrecs - ptr) * sizeof(*kp)); 139 (numrecs - ptr) * sizeof(*kp));
141 xfs_inobt_log_keys(cur, bp, ptr, numrecs - 1); 140 xfs_inobt_log_keys(cur, bp, ptr, numrecs - 1);
142 xfs_inobt_log_ptrs(cur, bp, ptr, numrecs - 1); 141 xfs_inobt_log_ptrs(cur, bp, ptr, numrecs - 1);
143 } 142 }
144 } 143 }
145 /* 144 /*
146 * It's a leaf. Excise the record being deleted, by sliding the 145 * It's a leaf. Excise the record being deleted, by sliding the
147 * entries past it down one. Log the changed areas of the block. 146 * entries past it down one. Log the changed areas of the block.
148 */ 147 */
149 else { 148 else {
150 rp = XFS_INOBT_REC_ADDR(block, 1, cur); 149 rp = XFS_INOBT_REC_ADDR(block, 1, cur);
151 if (ptr < numrecs) { 150 if (ptr < numrecs) {
152 memmove(&rp[ptr - 1], &rp[ptr], 151 memmove(&rp[ptr - 1], &rp[ptr],
153 (numrecs - ptr) * sizeof(*rp)); 152 (numrecs - ptr) * sizeof(*rp));
154 xfs_inobt_log_recs(cur, bp, ptr, numrecs - 1); 153 xfs_inobt_log_recs(cur, bp, ptr, numrecs - 1);
155 } 154 }
156 /* 155 /*
157 * If it's the first record in the block, we'll need a key 156 * If it's the first record in the block, we'll need a key
158 * structure to pass up to the next level (updkey). 157 * structure to pass up to the next level (updkey).
159 */ 158 */
160 if (ptr == 1) { 159 if (ptr == 1) {
161 key.ir_startino = rp->ir_startino; 160 key.ir_startino = rp->ir_startino;
162 kp = &key; 161 kp = &key;
163 } 162 }
164 } 163 }
165 /* 164 /*
166 * Decrement and log the number of entries in the block. 165 * Decrement and log the number of entries in the block.
167 */ 166 */
168 numrecs--; 167 numrecs--;
169 block->bb_numrecs = cpu_to_be16(numrecs); 168 block->bb_numrecs = cpu_to_be16(numrecs);
170 xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); 169 xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
171 /* 170 /*
172 * Is this the root level? If so, we're almost done. 171 * Is this the root level? If so, we're almost done.
173 */ 172 */
174 if (level == cur->bc_nlevels - 1) { 173 if (level == cur->bc_nlevels - 1) {
175 /* 174 /*
176 * If this is the root level, 175 * If this is the root level,
177 * and there's only one entry left, 176 * and there's only one entry left,
178 * and it's NOT the leaf level, 177 * and it's NOT the leaf level,
179 * then we can get rid of this level. 178 * then we can get rid of this level.
180 */ 179 */
181 if (numrecs == 1 && level > 0) { 180 if (numrecs == 1 && level > 0) {
182 agbp = cur->bc_private.a.agbp; 181 agbp = cur->bc_private.a.agbp;
183 agi = XFS_BUF_TO_AGI(agbp); 182 agi = XFS_BUF_TO_AGI(agbp);
184 /* 183 /*
185 * pp is still set to the first pointer in the block. 184 * pp is still set to the first pointer in the block.
186 * Make it the new root of the btree. 185 * Make it the new root of the btree.
187 */ 186 */
188 bno = be32_to_cpu(agi->agi_root); 187 bno = be32_to_cpu(agi->agi_root);
189 agi->agi_root = *pp; 188 agi->agi_root = *pp;
190 be32_add_cpu(&agi->agi_level, -1); 189 be32_add_cpu(&agi->agi_level, -1);
191 /* 190 /*
192 * Free the block. 191 * Free the block.
193 */ 192 */
194 if ((error = xfs_free_extent(cur->bc_tp, 193 if ((error = xfs_free_extent(cur->bc_tp,
195 XFS_AGB_TO_FSB(mp, cur->bc_private.a.agno, bno), 1))) 194 XFS_AGB_TO_FSB(mp, cur->bc_private.a.agno, bno), 1)))
196 return error; 195 return error;
197 xfs_trans_binval(cur->bc_tp, bp); 196 xfs_trans_binval(cur->bc_tp, bp);
198 xfs_ialloc_log_agi(cur->bc_tp, agbp, 197 xfs_ialloc_log_agi(cur->bc_tp, agbp,
199 XFS_AGI_ROOT | XFS_AGI_LEVEL); 198 XFS_AGI_ROOT | XFS_AGI_LEVEL);
200 /* 199 /*
201 * Update the cursor so there's one fewer level. 200 * Update the cursor so there's one fewer level.
202 */ 201 */
203 cur->bc_bufs[level] = NULL; 202 cur->bc_bufs[level] = NULL;
204 cur->bc_nlevels--; 203 cur->bc_nlevels--;
205 } else if (level > 0 && 204 } else if (level > 0 &&
206 (error = xfs_btree_decrement(cur, level, &i))) 205 (error = xfs_btree_decrement(cur, level, &i)))
207 return error; 206 return error;
208 *stat = 1; 207 *stat = 1;
209 return 0; 208 return 0;
210 } 209 }
211 /* 210 /*
212 * If we deleted the leftmost entry in the block, update the 211 * If we deleted the leftmost entry in the block, update the
213 * key values above us in the tree. 212 * key values above us in the tree.
214 */ 213 */
215 if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1))) 214 if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1)))
216 return error; 215 return error;
217 /* 216 /*
218 * If the number of records remaining in the block is at least 217 * If the number of records remaining in the block is at least
219 * the minimum, we're done. 218 * the minimum, we're done.
220 */ 219 */
221 if (numrecs >= XFS_INOBT_BLOCK_MINRECS(level, cur)) { 220 if (numrecs >= XFS_INOBT_BLOCK_MINRECS(level, cur)) {
222 if (level > 0 && 221 if (level > 0 &&
223 (error = xfs_btree_decrement(cur, level, &i))) 222 (error = xfs_btree_decrement(cur, level, &i)))
224 return error; 223 return error;
225 *stat = 1; 224 *stat = 1;
226 return 0; 225 return 0;
227 } 226 }
228 /* 227 /*
229 * Otherwise, we have to move some records around to keep the 228 * Otherwise, we have to move some records around to keep the
230 * tree balanced. Look at the left and right sibling blocks to 229 * tree balanced. Look at the left and right sibling blocks to
231 * see if we can re-balance by moving only one record. 230 * see if we can re-balance by moving only one record.
232 */ 231 */
233 rbno = be32_to_cpu(block->bb_rightsib); 232 rbno = be32_to_cpu(block->bb_rightsib);
234 lbno = be32_to_cpu(block->bb_leftsib); 233 lbno = be32_to_cpu(block->bb_leftsib);
235 bno = NULLAGBLOCK; 234 bno = NULLAGBLOCK;
236 ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK); 235 ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
237 /* 236 /*
238 * Duplicate the cursor so our btree manipulations here won't 237 * Duplicate the cursor so our btree manipulations here won't
239 * disrupt the next level up. 238 * disrupt the next level up.
240 */ 239 */
241 if ((error = xfs_btree_dup_cursor(cur, &tcur))) 240 if ((error = xfs_btree_dup_cursor(cur, &tcur)))
242 return error; 241 return error;
243 /* 242 /*
244 * If there's a right sibling, see if it's ok to shift an entry 243 * If there's a right sibling, see if it's ok to shift an entry
245 * out of it. 244 * out of it.
246 */ 245 */
247 if (rbno != NULLAGBLOCK) { 246 if (rbno != NULLAGBLOCK) {
248 /* 247 /*
249 * Move the temp cursor to the last entry in the next block. 248 * Move the temp cursor to the last entry in the next block.
250 * Actually any entry but the first would suffice. 249 * Actually any entry but the first would suffice.
251 */ 250 */
252 i = xfs_btree_lastrec(tcur, level); 251 i = xfs_btree_lastrec(tcur, level);
253 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 252 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
254 if ((error = xfs_btree_increment(tcur, level, &i))) 253 if ((error = xfs_btree_increment(tcur, level, &i)))
255 goto error0; 254 goto error0;
256 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 255 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
257 i = xfs_btree_lastrec(tcur, level); 256 i = xfs_btree_lastrec(tcur, level);
258 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 257 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
259 /* 258 /*
260 * Grab a pointer to the block. 259 * Grab a pointer to the block.
261 */ 260 */
262 rbp = tcur->bc_bufs[level]; 261 rbp = tcur->bc_bufs[level];
263 right = XFS_BUF_TO_INOBT_BLOCK(rbp); 262 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
264 #ifdef DEBUG 263 #ifdef DEBUG
265 if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) 264 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
266 goto error0; 265 goto error0;
267 #endif 266 #endif
268 /* 267 /*
269 * Grab the current block number, for future use. 268 * Grab the current block number, for future use.
270 */ 269 */
271 bno = be32_to_cpu(right->bb_leftsib); 270 bno = be32_to_cpu(right->bb_leftsib);
272 /* 271 /*
273 * If right block is full enough so that removing one entry 272 * If right block is full enough so that removing one entry
274 * won't make it too empty, and left-shifting an entry out 273 * won't make it too empty, and left-shifting an entry out
275 * of right to us works, we're done. 274 * of right to us works, we're done.
276 */ 275 */
277 if (be16_to_cpu(right->bb_numrecs) - 1 >= 276 if (be16_to_cpu(right->bb_numrecs) - 1 >=
278 XFS_INOBT_BLOCK_MINRECS(level, cur)) { 277 XFS_INOBT_BLOCK_MINRECS(level, cur)) {
279 if ((error = xfs_inobt_lshift(tcur, level, &i))) 278 if ((error = xfs_btree_lshift(tcur, level, &i)))
280 goto error0; 279 goto error0;
281 if (i) { 280 if (i) {
282 ASSERT(be16_to_cpu(block->bb_numrecs) >= 281 ASSERT(be16_to_cpu(block->bb_numrecs) >=
283 XFS_INOBT_BLOCK_MINRECS(level, cur)); 282 XFS_INOBT_BLOCK_MINRECS(level, cur));
284 xfs_btree_del_cursor(tcur, 283 xfs_btree_del_cursor(tcur,
285 XFS_BTREE_NOERROR); 284 XFS_BTREE_NOERROR);
286 if (level > 0 && 285 if (level > 0 &&
287 (error = xfs_btree_decrement(cur, level, 286 (error = xfs_btree_decrement(cur, level,
288 &i))) 287 &i)))
289 return error; 288 return error;
290 *stat = 1; 289 *stat = 1;
291 return 0; 290 return 0;
292 } 291 }
293 } 292 }
294 /* 293 /*
295 * Otherwise, grab the number of records in right for 294 * Otherwise, grab the number of records in right for
296 * future reference, and fix up the temp cursor to point 295 * future reference, and fix up the temp cursor to point
297 * to our block again (last record). 296 * to our block again (last record).
298 */ 297 */
299 rrecs = be16_to_cpu(right->bb_numrecs); 298 rrecs = be16_to_cpu(right->bb_numrecs);
300 if (lbno != NULLAGBLOCK) { 299 if (lbno != NULLAGBLOCK) {
301 xfs_btree_firstrec(tcur, level); 300 xfs_btree_firstrec(tcur, level);
302 if ((error = xfs_btree_decrement(tcur, level, &i))) 301 if ((error = xfs_btree_decrement(tcur, level, &i)))
303 goto error0; 302 goto error0;
304 } 303 }
305 } 304 }
306 /* 305 /*
307 * If there's a left sibling, see if it's ok to shift an entry 306 * If there's a left sibling, see if it's ok to shift an entry
308 * out of it. 307 * out of it.
309 */ 308 */
310 if (lbno != NULLAGBLOCK) { 309 if (lbno != NULLAGBLOCK) {
311 /* 310 /*
312 * Move the temp cursor to the first entry in the 311 * Move the temp cursor to the first entry in the
313 * previous block. 312 * previous block.
314 */ 313 */
315 xfs_btree_firstrec(tcur, level); 314 xfs_btree_firstrec(tcur, level);
316 if ((error = xfs_btree_decrement(tcur, level, &i))) 315 if ((error = xfs_btree_decrement(tcur, level, &i)))
317 goto error0; 316 goto error0;
318 xfs_btree_firstrec(tcur, level); 317 xfs_btree_firstrec(tcur, level);
319 /* 318 /*
320 * Grab a pointer to the block. 319 * Grab a pointer to the block.
321 */ 320 */
322 lbp = tcur->bc_bufs[level]; 321 lbp = tcur->bc_bufs[level];
323 left = XFS_BUF_TO_INOBT_BLOCK(lbp); 322 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
324 #ifdef DEBUG 323 #ifdef DEBUG
325 if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) 324 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
326 goto error0; 325 goto error0;
327 #endif 326 #endif
328 /* 327 /*
329 * Grab the current block number, for future use. 328 * Grab the current block number, for future use.
330 */ 329 */
331 bno = be32_to_cpu(left->bb_rightsib); 330 bno = be32_to_cpu(left->bb_rightsib);
332 /* 331 /*
333 * If left block is full enough so that removing one entry 332 * If left block is full enough so that removing one entry
334 * won't make it too empty, and right-shifting an entry out 333 * won't make it too empty, and right-shifting an entry out
335 * of left to us works, we're done. 334 * of left to us works, we're done.
336 */ 335 */
337 if (be16_to_cpu(left->bb_numrecs) - 1 >= 336 if (be16_to_cpu(left->bb_numrecs) - 1 >=
338 XFS_INOBT_BLOCK_MINRECS(level, cur)) { 337 XFS_INOBT_BLOCK_MINRECS(level, cur)) {
339 if ((error = xfs_btree_rshift(tcur, level, &i))) 338 if ((error = xfs_btree_rshift(tcur, level, &i)))
340 goto error0; 339 goto error0;
341 if (i) { 340 if (i) {
342 ASSERT(be16_to_cpu(block->bb_numrecs) >= 341 ASSERT(be16_to_cpu(block->bb_numrecs) >=
343 XFS_INOBT_BLOCK_MINRECS(level, cur)); 342 XFS_INOBT_BLOCK_MINRECS(level, cur));
344 xfs_btree_del_cursor(tcur, 343 xfs_btree_del_cursor(tcur,
345 XFS_BTREE_NOERROR); 344 XFS_BTREE_NOERROR);
346 if (level == 0) 345 if (level == 0)
347 cur->bc_ptrs[0]++; 346 cur->bc_ptrs[0]++;
348 *stat = 1; 347 *stat = 1;
349 return 0; 348 return 0;
350 } 349 }
351 } 350 }
352 /* 351 /*
353 * Otherwise, grab the number of records in right for 352 * Otherwise, grab the number of records in right for
354 * future reference. 353 * future reference.
355 */ 354 */
356 lrecs = be16_to_cpu(left->bb_numrecs); 355 lrecs = be16_to_cpu(left->bb_numrecs);
357 } 356 }
358 /* 357 /*
359 * Delete the temp cursor, we're done with it. 358 * Delete the temp cursor, we're done with it.
360 */ 359 */
361 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); 360 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
362 /* 361 /*
363 * If here, we need to do a join to keep the tree balanced. 362 * If here, we need to do a join to keep the tree balanced.
364 */ 363 */
365 ASSERT(bno != NULLAGBLOCK); 364 ASSERT(bno != NULLAGBLOCK);
366 /* 365 /*
367 * See if we can join with the left neighbor block. 366 * See if we can join with the left neighbor block.
368 */ 367 */
369 if (lbno != NULLAGBLOCK && 368 if (lbno != NULLAGBLOCK &&
370 lrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) { 369 lrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
371 /* 370 /*
372 * Set "right" to be the starting block, 371 * Set "right" to be the starting block,
373 * "left" to be the left neighbor. 372 * "left" to be the left neighbor.
374 */ 373 */
375 rbno = bno; 374 rbno = bno;
376 right = block; 375 right = block;
377 rrecs = be16_to_cpu(right->bb_numrecs); 376 rrecs = be16_to_cpu(right->bb_numrecs);
378 rbp = bp; 377 rbp = bp;
379 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 378 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
380 cur->bc_private.a.agno, lbno, 0, &lbp, 379 cur->bc_private.a.agno, lbno, 0, &lbp,
381 XFS_INO_BTREE_REF))) 380 XFS_INO_BTREE_REF)))
382 return error; 381 return error;
383 left = XFS_BUF_TO_INOBT_BLOCK(lbp); 382 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
384 lrecs = be16_to_cpu(left->bb_numrecs); 383 lrecs = be16_to_cpu(left->bb_numrecs);
385 if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) 384 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
386 return error; 385 return error;
387 } 386 }
388 /* 387 /*
389 * If that won't work, see if we can join with the right neighbor block. 388 * If that won't work, see if we can join with the right neighbor block.
390 */ 389 */
391 else if (rbno != NULLAGBLOCK && 390 else if (rbno != NULLAGBLOCK &&
392 rrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) { 391 rrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
393 /* 392 /*
394 * Set "left" to be the starting block, 393 * Set "left" to be the starting block,
395 * "right" to be the right neighbor. 394 * "right" to be the right neighbor.
396 */ 395 */
397 lbno = bno; 396 lbno = bno;
398 left = block; 397 left = block;
399 lrecs = be16_to_cpu(left->bb_numrecs); 398 lrecs = be16_to_cpu(left->bb_numrecs);
400 lbp = bp; 399 lbp = bp;
401 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 400 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
402 cur->bc_private.a.agno, rbno, 0, &rbp, 401 cur->bc_private.a.agno, rbno, 0, &rbp,
403 XFS_INO_BTREE_REF))) 402 XFS_INO_BTREE_REF)))
404 return error; 403 return error;
405 right = XFS_BUF_TO_INOBT_BLOCK(rbp); 404 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
406 rrecs = be16_to_cpu(right->bb_numrecs); 405 rrecs = be16_to_cpu(right->bb_numrecs);
407 if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) 406 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
408 return error; 407 return error;
409 } 408 }
410 /* 409 /*
411 * Otherwise, we can't fix the imbalance. 410 * Otherwise, we can't fix the imbalance.
412 * Just return. This is probably a logic error, but it's not fatal. 411 * Just return. This is probably a logic error, but it's not fatal.
413 */ 412 */
414 else { 413 else {
415 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) 414 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
416 return error; 415 return error;
417 *stat = 1; 416 *stat = 1;
418 return 0; 417 return 0;
419 } 418 }
420 /* 419 /*
421 * We're now going to join "left" and "right" by moving all the stuff 420 * We're now going to join "left" and "right" by moving all the stuff
422 * in "right" to "left" and deleting "right". 421 * in "right" to "left" and deleting "right".
423 */ 422 */
424 if (level > 0) { 423 if (level > 0) {
425 /* 424 /*
426 * It's a non-leaf. Move keys and pointers. 425 * It's a non-leaf. Move keys and pointers.
427 */ 426 */
428 lkp = XFS_INOBT_KEY_ADDR(left, lrecs + 1, cur); 427 lkp = XFS_INOBT_KEY_ADDR(left, lrecs + 1, cur);
429 lpp = XFS_INOBT_PTR_ADDR(left, lrecs + 1, cur); 428 lpp = XFS_INOBT_PTR_ADDR(left, lrecs + 1, cur);
430 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur); 429 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
431 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur); 430 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
432 #ifdef DEBUG 431 #ifdef DEBUG
433 for (i = 0; i < rrecs; i++) { 432 for (i = 0; i < rrecs; i++) {
434 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level))) 433 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
435 return error; 434 return error;
436 } 435 }
437 #endif 436 #endif
438 memcpy(lkp, rkp, rrecs * sizeof(*lkp)); 437 memcpy(lkp, rkp, rrecs * sizeof(*lkp));
439 memcpy(lpp, rpp, rrecs * sizeof(*lpp)); 438 memcpy(lpp, rpp, rrecs * sizeof(*lpp));
440 xfs_inobt_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs); 439 xfs_inobt_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
441 xfs_inobt_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs); 440 xfs_inobt_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
442 } else { 441 } else {
443 /* 442 /*
444 * It's a leaf. Move records. 443 * It's a leaf. Move records.
445 */ 444 */
446 lrp = XFS_INOBT_REC_ADDR(left, lrecs + 1, cur); 445 lrp = XFS_INOBT_REC_ADDR(left, lrecs + 1, cur);
447 rrp = XFS_INOBT_REC_ADDR(right, 1, cur); 446 rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
448 memcpy(lrp, rrp, rrecs * sizeof(*lrp)); 447 memcpy(lrp, rrp, rrecs * sizeof(*lrp));
449 xfs_inobt_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs); 448 xfs_inobt_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
450 } 449 }
451 /* 450 /*
452 * If we joined with the left neighbor, set the buffer in the 451 * If we joined with the left neighbor, set the buffer in the
453 * cursor to the left block, and fix up the index. 452 * cursor to the left block, and fix up the index.
454 */ 453 */
455 if (bp != lbp) { 454 if (bp != lbp) {
456 xfs_btree_setbuf(cur, level, lbp); 455 xfs_btree_setbuf(cur, level, lbp);
457 cur->bc_ptrs[level] += lrecs; 456 cur->bc_ptrs[level] += lrecs;
458 } 457 }
459 /* 458 /*
460 * If we joined with the right neighbor and there's a level above 459 * If we joined with the right neighbor and there's a level above
461 * us, increment the cursor at that level. 460 * us, increment the cursor at that level.
462 */ 461 */
463 else if (level + 1 < cur->bc_nlevels && 462 else if (level + 1 < cur->bc_nlevels &&
464 (error = xfs_btree_increment(cur, level + 1, &i))) 463 (error = xfs_btree_increment(cur, level + 1, &i)))
465 return error; 464 return error;
466 /* 465 /*
467 * Fix up the number of records in the surviving block. 466 * Fix up the number of records in the surviving block.
468 */ 467 */
469 lrecs += rrecs; 468 lrecs += rrecs;
470 left->bb_numrecs = cpu_to_be16(lrecs); 469 left->bb_numrecs = cpu_to_be16(lrecs);
471 /* 470 /*
472 * Fix up the right block pointer in the surviving block, and log it. 471 * Fix up the right block pointer in the surviving block, and log it.
473 */ 472 */
474 left->bb_rightsib = right->bb_rightsib; 473 left->bb_rightsib = right->bb_rightsib;
475 xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); 474 xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
476 /* 475 /*
477 * If there is a right sibling now, make it point to the 476 * If there is a right sibling now, make it point to the
478 * remaining block. 477 * remaining block.
479 */ 478 */
480 if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) { 479 if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
481 xfs_inobt_block_t *rrblock; 480 xfs_inobt_block_t *rrblock;
482 xfs_buf_t *rrbp; 481 xfs_buf_t *rrbp;
483 482
484 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, 483 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
485 cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0, 484 cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0,
486 &rrbp, XFS_INO_BTREE_REF))) 485 &rrbp, XFS_INO_BTREE_REF)))
487 return error; 486 return error;
488 rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp); 487 rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
489 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp))) 488 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
490 return error; 489 return error;
491 rrblock->bb_leftsib = cpu_to_be32(lbno); 490 rrblock->bb_leftsib = cpu_to_be32(lbno);
492 xfs_inobt_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB); 491 xfs_inobt_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
493 } 492 }
494 /* 493 /*
495 * Free the deleting block. 494 * Free the deleting block.
496 */ 495 */
497 if ((error = xfs_free_extent(cur->bc_tp, XFS_AGB_TO_FSB(mp, 496 if ((error = xfs_free_extent(cur->bc_tp, XFS_AGB_TO_FSB(mp,
498 cur->bc_private.a.agno, rbno), 1))) 497 cur->bc_private.a.agno, rbno), 1)))
499 return error; 498 return error;
500 xfs_trans_binval(cur->bc_tp, rbp); 499 xfs_trans_binval(cur->bc_tp, rbp);
501 /* 500 /*
502 * Readjust the ptr at this level if it's not a leaf, since it's 501 * Readjust the ptr at this level if it's not a leaf, since it's
503 * still pointing at the deletion point, which makes the cursor 502 * still pointing at the deletion point, which makes the cursor
504 * inconsistent. If this makes the ptr 0, the caller fixes it up. 503 * inconsistent. If this makes the ptr 0, the caller fixes it up.
505 * We can't use decrement because it would change the next level up. 504 * We can't use decrement because it would change the next level up.
506 */ 505 */
507 if (level > 0) 506 if (level > 0)
508 cur->bc_ptrs[level]--; 507 cur->bc_ptrs[level]--;
509 /* 508 /*
510 * Return value means the next level up has something to do. 509 * Return value means the next level up has something to do.
511 */ 510 */
512 *stat = 2; 511 *stat = 2;
513 return 0; 512 return 0;
514 513
515 error0: 514 error0:
516 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); 515 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
517 return error; 516 return error;
518 } 517 }
519 518
520 /* 519 /*
521 * Insert one record/level. Return information to the caller 520 * Insert one record/level. Return information to the caller
522 * allowing the next level up to proceed if necessary. 521 * allowing the next level up to proceed if necessary.
523 */ 522 */
524 STATIC int /* error */ 523 STATIC int /* error */
525 xfs_inobt_insrec( 524 xfs_inobt_insrec(
526 xfs_btree_cur_t *cur, /* btree cursor */ 525 xfs_btree_cur_t *cur, /* btree cursor */
527 int level, /* level to insert record at */ 526 int level, /* level to insert record at */
528 xfs_agblock_t *bnop, /* i/o: block number inserted */ 527 xfs_agblock_t *bnop, /* i/o: block number inserted */
529 xfs_inobt_rec_t *recp, /* i/o: record data inserted */ 528 xfs_inobt_rec_t *recp, /* i/o: record data inserted */
530 xfs_btree_cur_t **curp, /* output: new cursor replacing cur */ 529 xfs_btree_cur_t **curp, /* output: new cursor replacing cur */
531 int *stat) /* success/failure */ 530 int *stat) /* success/failure */
532 { 531 {
533 xfs_inobt_block_t *block; /* btree block record/key lives in */ 532 xfs_inobt_block_t *block; /* btree block record/key lives in */
534 xfs_buf_t *bp; /* buffer for block */ 533 xfs_buf_t *bp; /* buffer for block */
535 int error; /* error return value */ 534 int error; /* error return value */
536 int i; /* loop index */ 535 int i; /* loop index */
537 xfs_inobt_key_t key; /* key value being inserted */ 536 xfs_inobt_key_t key; /* key value being inserted */
538 xfs_inobt_key_t *kp=NULL; /* pointer to btree keys */ 537 xfs_inobt_key_t *kp=NULL; /* pointer to btree keys */
539 xfs_agblock_t nbno; /* block number of allocated block */ 538 xfs_agblock_t nbno; /* block number of allocated block */
540 xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */ 539 xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
541 xfs_inobt_key_t nkey; /* new key value, from split */ 540 xfs_inobt_key_t nkey; /* new key value, from split */
542 xfs_inobt_rec_t nrec; /* new record value, for caller */ 541 xfs_inobt_rec_t nrec; /* new record value, for caller */
543 int numrecs; 542 int numrecs;
544 int optr; /* old ptr value */ 543 int optr; /* old ptr value */
545 xfs_inobt_ptr_t *pp; /* pointer to btree addresses */ 544 xfs_inobt_ptr_t *pp; /* pointer to btree addresses */
546 int ptr; /* index in btree block for this rec */ 545 int ptr; /* index in btree block for this rec */
547 xfs_inobt_rec_t *rp=NULL; /* pointer to btree records */ 546 xfs_inobt_rec_t *rp=NULL; /* pointer to btree records */
548 547
549 /* 548 /*
550 * GCC doesn't understand the (arguably complex) control flow in 549 * GCC doesn't understand the (arguably complex) control flow in
551 * this function and complains about uninitialized structure fields 550 * this function and complains about uninitialized structure fields
552 * without this. 551 * without this.
553 */ 552 */
554 memset(&nrec, 0, sizeof(nrec)); 553 memset(&nrec, 0, sizeof(nrec));
555 554
556 /* 555 /*
557 * If we made it to the root level, allocate a new root block 556 * If we made it to the root level, allocate a new root block
558 * and we're done. 557 * and we're done.
559 */ 558 */
560 if (level >= cur->bc_nlevels) { 559 if (level >= cur->bc_nlevels) {
561 error = xfs_inobt_newroot(cur, &i); 560 error = xfs_inobt_newroot(cur, &i);
562 *bnop = NULLAGBLOCK; 561 *bnop = NULLAGBLOCK;
563 *stat = i; 562 *stat = i;
564 return error; 563 return error;
565 } 564 }
566 /* 565 /*
567 * Make a key out of the record data to be inserted, and save it. 566 * Make a key out of the record data to be inserted, and save it.
568 */ 567 */
569 key.ir_startino = recp->ir_startino; 568 key.ir_startino = recp->ir_startino;
570 optr = ptr = cur->bc_ptrs[level]; 569 optr = ptr = cur->bc_ptrs[level];
571 /* 570 /*
572 * If we're off the left edge, return failure. 571 * If we're off the left edge, return failure.
573 */ 572 */
574 if (ptr == 0) { 573 if (ptr == 0) {
575 *stat = 0; 574 *stat = 0;
576 return 0; 575 return 0;
577 } 576 }
578 /* 577 /*
579 * Get pointers to the btree buffer and block. 578 * Get pointers to the btree buffer and block.
580 */ 579 */
581 bp = cur->bc_bufs[level]; 580 bp = cur->bc_bufs[level];
582 block = XFS_BUF_TO_INOBT_BLOCK(bp); 581 block = XFS_BUF_TO_INOBT_BLOCK(bp);
583 numrecs = be16_to_cpu(block->bb_numrecs); 582 numrecs = be16_to_cpu(block->bb_numrecs);
584 #ifdef DEBUG 583 #ifdef DEBUG
585 if ((error = xfs_btree_check_sblock(cur, block, level, bp))) 584 if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
586 return error; 585 return error;
587 /* 586 /*
588 * Check that the new entry is being inserted in the right place. 587 * Check that the new entry is being inserted in the right place.
589 */ 588 */
590 if (ptr <= numrecs) { 589 if (ptr <= numrecs) {
591 if (level == 0) { 590 if (level == 0) {
592 rp = XFS_INOBT_REC_ADDR(block, ptr, cur); 591 rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
593 xfs_btree_check_rec(cur->bc_btnum, recp, rp); 592 xfs_btree_check_rec(cur->bc_btnum, recp, rp);
594 } else { 593 } else {
595 kp = XFS_INOBT_KEY_ADDR(block, ptr, cur); 594 kp = XFS_INOBT_KEY_ADDR(block, ptr, cur);
596 xfs_btree_check_key(cur->bc_btnum, &key, kp); 595 xfs_btree_check_key(cur->bc_btnum, &key, kp);
597 } 596 }
598 } 597 }
599 #endif 598 #endif
600 nbno = NULLAGBLOCK; 599 nbno = NULLAGBLOCK;
601 ncur = NULL; 600 ncur = NULL;
602 /* 601 /*
603 * If the block is full, we can't insert the new entry until we 602 * If the block is full, we can't insert the new entry until we
604 * make the block un-full. 603 * make the block un-full.
605 */ 604 */
606 if (numrecs == XFS_INOBT_BLOCK_MAXRECS(level, cur)) { 605 if (numrecs == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
607 /* 606 /*
608 * First, try shifting an entry to the right neighbor. 607 * First, try shifting an entry to the right neighbor.
609 */ 608 */
610 if ((error = xfs_btree_rshift(cur, level, &i))) 609 if ((error = xfs_btree_rshift(cur, level, &i)))
611 return error; 610 return error;
612 if (i) { 611 if (i) {
613 /* nothing */ 612 /* nothing */
614 } 613 }
615 /* 614 /*
616 * Next, try shifting an entry to the left neighbor. 615 * Next, try shifting an entry to the left neighbor.
617 */ 616 */
618 else { 617 else {
619 if ((error = xfs_inobt_lshift(cur, level, &i))) 618 if ((error = xfs_btree_lshift(cur, level, &i)))
620 return error; 619 return error;
621 if (i) { 620 if (i) {
622 optr = ptr = cur->bc_ptrs[level]; 621 optr = ptr = cur->bc_ptrs[level];
623 } else { 622 } else {
624 /* 623 /*
625 * Next, try splitting the current block 624 * Next, try splitting the current block
626 * in half. If this works we have to 625 * in half. If this works we have to
627 * re-set our variables because 626 * re-set our variables because
628 * we could be in a different block now. 627 * we could be in a different block now.
629 */ 628 */
630 if ((error = xfs_inobt_split(cur, level, &nbno, 629 if ((error = xfs_inobt_split(cur, level, &nbno,
631 &nkey, &ncur, &i))) 630 &nkey, &ncur, &i)))
632 return error; 631 return error;
633 if (i) { 632 if (i) {
634 bp = cur->bc_bufs[level]; 633 bp = cur->bc_bufs[level];
635 block = XFS_BUF_TO_INOBT_BLOCK(bp); 634 block = XFS_BUF_TO_INOBT_BLOCK(bp);
636 #ifdef DEBUG 635 #ifdef DEBUG
637 if ((error = xfs_btree_check_sblock(cur, 636 if ((error = xfs_btree_check_sblock(cur,
638 block, level, bp))) 637 block, level, bp)))
639 return error; 638 return error;
640 #endif 639 #endif
641 ptr = cur->bc_ptrs[level]; 640 ptr = cur->bc_ptrs[level];
642 nrec.ir_startino = nkey.ir_startino; 641 nrec.ir_startino = nkey.ir_startino;
643 } else { 642 } else {
644 /* 643 /*
645 * Otherwise the insert fails. 644 * Otherwise the insert fails.
646 */ 645 */
647 *stat = 0; 646 *stat = 0;
648 return 0; 647 return 0;
649 } 648 }
650 } 649 }
651 } 650 }
652 } 651 }
653 /* 652 /*
654 * At this point we know there's room for our new entry in the block 653 * At this point we know there's room for our new entry in the block
655 * we're pointing at. 654 * we're pointing at.
656 */ 655 */
657 numrecs = be16_to_cpu(block->bb_numrecs); 656 numrecs = be16_to_cpu(block->bb_numrecs);
658 if (level > 0) { 657 if (level > 0) {
659 /* 658 /*
660 * It's a non-leaf entry. Make a hole for the new data 659 * It's a non-leaf entry. Make a hole for the new data
661 * in the key and ptr regions of the block. 660 * in the key and ptr regions of the block.
662 */ 661 */
663 kp = XFS_INOBT_KEY_ADDR(block, 1, cur); 662 kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
664 pp = XFS_INOBT_PTR_ADDR(block, 1, cur); 663 pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
665 #ifdef DEBUG 664 #ifdef DEBUG
666 for (i = numrecs; i >= ptr; i--) { 665 for (i = numrecs; i >= ptr; i--) {
667 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level))) 666 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
668 return error; 667 return error;
669 } 668 }
670 #endif 669 #endif
671 memmove(&kp[ptr], &kp[ptr - 1], 670 memmove(&kp[ptr], &kp[ptr - 1],
672 (numrecs - ptr + 1) * sizeof(*kp)); 671 (numrecs - ptr + 1) * sizeof(*kp));
673 memmove(&pp[ptr], &pp[ptr - 1], 672 memmove(&pp[ptr], &pp[ptr - 1],
674 (numrecs - ptr + 1) * sizeof(*pp)); 673 (numrecs - ptr + 1) * sizeof(*pp));
675 /* 674 /*
676 * Now stuff the new data in, bump numrecs and log the new data. 675 * Now stuff the new data in, bump numrecs and log the new data.
677 */ 676 */
678 #ifdef DEBUG 677 #ifdef DEBUG
679 if ((error = xfs_btree_check_sptr(cur, *bnop, level))) 678 if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
680 return error; 679 return error;
681 #endif 680 #endif
682 kp[ptr - 1] = key; 681 kp[ptr - 1] = key;
683 pp[ptr - 1] = cpu_to_be32(*bnop); 682 pp[ptr - 1] = cpu_to_be32(*bnop);
684 numrecs++; 683 numrecs++;
685 block->bb_numrecs = cpu_to_be16(numrecs); 684 block->bb_numrecs = cpu_to_be16(numrecs);
686 xfs_inobt_log_keys(cur, bp, ptr, numrecs); 685 xfs_inobt_log_keys(cur, bp, ptr, numrecs);
687 xfs_inobt_log_ptrs(cur, bp, ptr, numrecs); 686 xfs_inobt_log_ptrs(cur, bp, ptr, numrecs);
688 } else { 687 } else {
689 /* 688 /*
690 * It's a leaf entry. Make a hole for the new record. 689 * It's a leaf entry. Make a hole for the new record.
691 */ 690 */
692 rp = XFS_INOBT_REC_ADDR(block, 1, cur); 691 rp = XFS_INOBT_REC_ADDR(block, 1, cur);
693 memmove(&rp[ptr], &rp[ptr - 1], 692 memmove(&rp[ptr], &rp[ptr - 1],
694 (numrecs - ptr + 1) * sizeof(*rp)); 693 (numrecs - ptr + 1) * sizeof(*rp));
695 /* 694 /*
696 * Now stuff the new record in, bump numrecs 695 * Now stuff the new record in, bump numrecs
697 * and log the new data. 696 * and log the new data.
698 */ 697 */
699 rp[ptr - 1] = *recp; 698 rp[ptr - 1] = *recp;
700 numrecs++; 699 numrecs++;
701 block->bb_numrecs = cpu_to_be16(numrecs); 700 block->bb_numrecs = cpu_to_be16(numrecs);
702 xfs_inobt_log_recs(cur, bp, ptr, numrecs); 701 xfs_inobt_log_recs(cur, bp, ptr, numrecs);
703 } 702 }
704 /* 703 /*
705 * Log the new number of records in the btree header. 704 * Log the new number of records in the btree header.
706 */ 705 */
707 xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); 706 xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
708 #ifdef DEBUG 707 #ifdef DEBUG
709 /* 708 /*
710 * Check that the key/record is in the right place, now. 709 * Check that the key/record is in the right place, now.
711 */ 710 */
712 if (ptr < numrecs) { 711 if (ptr < numrecs) {
713 if (level == 0) 712 if (level == 0)
714 xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1, 713 xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
715 rp + ptr); 714 rp + ptr);
716 else 715 else
717 xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1, 716 xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
718 kp + ptr); 717 kp + ptr);
719 } 718 }
720 #endif 719 #endif
721 /* 720 /*
722 * If we inserted at the start of a block, update the parents' keys. 721 * If we inserted at the start of a block, update the parents' keys.
723 */ 722 */
724 if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1))) 723 if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1)))
725 return error; 724 return error;
726 /* 725 /*
727 * Return the new block number, if any. 726 * Return the new block number, if any.
728 * If there is one, give back a record value and a cursor too. 727 * If there is one, give back a record value and a cursor too.
729 */ 728 */
730 *bnop = nbno; 729 *bnop = nbno;
731 if (nbno != NULLAGBLOCK) { 730 if (nbno != NULLAGBLOCK) {
732 *recp = nrec; 731 *recp = nrec;
733 *curp = ncur; 732 *curp = ncur;
734 } 733 }
735 *stat = 1; 734 *stat = 1;
736 return 0; 735 return 0;
737 } 736 }
738 737
739 /* 738 /*
740 * Log header fields from a btree block. 739 * Log header fields from a btree block.
741 */ 740 */
742 STATIC void 741 STATIC void
743 xfs_inobt_log_block( 742 xfs_inobt_log_block(
744 xfs_trans_t *tp, /* transaction pointer */ 743 xfs_trans_t *tp, /* transaction pointer */
745 xfs_buf_t *bp, /* buffer containing btree block */ 744 xfs_buf_t *bp, /* buffer containing btree block */
746 int fields) /* mask of fields: XFS_BB_... */ 745 int fields) /* mask of fields: XFS_BB_... */
747 { 746 {
748 int first; /* first byte offset logged */ 747 int first; /* first byte offset logged */
749 int last; /* last byte offset logged */ 748 int last; /* last byte offset logged */
750 static const short offsets[] = { /* table of offsets */ 749 static const short offsets[] = { /* table of offsets */
751 offsetof(xfs_inobt_block_t, bb_magic), 750 offsetof(xfs_inobt_block_t, bb_magic),
752 offsetof(xfs_inobt_block_t, bb_level), 751 offsetof(xfs_inobt_block_t, bb_level),
753 offsetof(xfs_inobt_block_t, bb_numrecs), 752 offsetof(xfs_inobt_block_t, bb_numrecs),
754 offsetof(xfs_inobt_block_t, bb_leftsib), 753 offsetof(xfs_inobt_block_t, bb_leftsib),
755 offsetof(xfs_inobt_block_t, bb_rightsib), 754 offsetof(xfs_inobt_block_t, bb_rightsib),
756 sizeof(xfs_inobt_block_t) 755 sizeof(xfs_inobt_block_t)
757 }; 756 };
758 757
759 xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last); 758 xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last);
760 xfs_trans_log_buf(tp, bp, first, last); 759 xfs_trans_log_buf(tp, bp, first, last);
761 } 760 }
762 761
763 /* 762 /*
764 * Log keys from a btree block (nonleaf). 763 * Log keys from a btree block (nonleaf).
765 */ 764 */
766 STATIC void 765 STATIC void
767 xfs_inobt_log_keys( 766 xfs_inobt_log_keys(
768 xfs_btree_cur_t *cur, /* btree cursor */ 767 xfs_btree_cur_t *cur, /* btree cursor */
769 xfs_buf_t *bp, /* buffer containing btree block */ 768 xfs_buf_t *bp, /* buffer containing btree block */
770 int kfirst, /* index of first key to log */ 769 int kfirst, /* index of first key to log */
771 int klast) /* index of last key to log */ 770 int klast) /* index of last key to log */
772 { 771 {
773 xfs_inobt_block_t *block; /* btree block to log from */ 772 xfs_inobt_block_t *block; /* btree block to log from */
774 int first; /* first byte offset logged */ 773 int first; /* first byte offset logged */
775 xfs_inobt_key_t *kp; /* key pointer in btree block */ 774 xfs_inobt_key_t *kp; /* key pointer in btree block */
776 int last; /* last byte offset logged */ 775 int last; /* last byte offset logged */
777 776
778 block = XFS_BUF_TO_INOBT_BLOCK(bp); 777 block = XFS_BUF_TO_INOBT_BLOCK(bp);
779 kp = XFS_INOBT_KEY_ADDR(block, 1, cur); 778 kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
780 first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block); 779 first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
781 last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block); 780 last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
782 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 781 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
783 } 782 }
784 783
785 /* 784 /*
786 * Log block pointer fields from a btree block (nonleaf). 785 * Log block pointer fields from a btree block (nonleaf).
787 */ 786 */
788 STATIC void 787 STATIC void
789 xfs_inobt_log_ptrs( 788 xfs_inobt_log_ptrs(
790 xfs_btree_cur_t *cur, /* btree cursor */ 789 xfs_btree_cur_t *cur, /* btree cursor */
791 xfs_buf_t *bp, /* buffer containing btree block */ 790 xfs_buf_t *bp, /* buffer containing btree block */
792 int pfirst, /* index of first pointer to log */ 791 int pfirst, /* index of first pointer to log */
793 int plast) /* index of last pointer to log */ 792 int plast) /* index of last pointer to log */
794 { 793 {
795 xfs_inobt_block_t *block; /* btree block to log from */ 794 xfs_inobt_block_t *block; /* btree block to log from */
796 int first; /* first byte offset logged */ 795 int first; /* first byte offset logged */
797 int last; /* last byte offset logged */ 796 int last; /* last byte offset logged */
798 xfs_inobt_ptr_t *pp; /* block-pointer pointer in btree blk */ 797 xfs_inobt_ptr_t *pp; /* block-pointer pointer in btree blk */
799 798
800 block = XFS_BUF_TO_INOBT_BLOCK(bp); 799 block = XFS_BUF_TO_INOBT_BLOCK(bp);
801 pp = XFS_INOBT_PTR_ADDR(block, 1, cur); 800 pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
802 first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block); 801 first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
803 last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block); 802 last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
804 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 803 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
805 } 804 }
806 805
807 /* 806 /*
808 * Log records from a btree block (leaf). 807 * Log records from a btree block (leaf).
809 */ 808 */
810 STATIC void 809 STATIC void
811 xfs_inobt_log_recs( 810 xfs_inobt_log_recs(
812 xfs_btree_cur_t *cur, /* btree cursor */ 811 xfs_btree_cur_t *cur, /* btree cursor */
813 xfs_buf_t *bp, /* buffer containing btree block */ 812 xfs_buf_t *bp, /* buffer containing btree block */
814 int rfirst, /* index of first record to log */ 813 int rfirst, /* index of first record to log */
815 int rlast) /* index of last record to log */ 814 int rlast) /* index of last record to log */
816 { 815 {
817 xfs_inobt_block_t *block; /* btree block to log from */ 816 xfs_inobt_block_t *block; /* btree block to log from */
818 int first; /* first byte offset logged */ 817 int first; /* first byte offset logged */
819 int last; /* last byte offset logged */ 818 int last; /* last byte offset logged */
820 xfs_inobt_rec_t *rp; /* record pointer for btree block */ 819 xfs_inobt_rec_t *rp; /* record pointer for btree block */
821 820
822 block = XFS_BUF_TO_INOBT_BLOCK(bp); 821 block = XFS_BUF_TO_INOBT_BLOCK(bp);
823 rp = XFS_INOBT_REC_ADDR(block, 1, cur); 822 rp = XFS_INOBT_REC_ADDR(block, 1, cur);
824 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block); 823 first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
825 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block); 824 last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
826 xfs_trans_log_buf(cur->bc_tp, bp, first, last); 825 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
827 }
828
829 /*
830 * Move 1 record left from cur/level if possible.
831 * Update cur to reflect the new path.
832 */
833 STATIC int /* error */
834 xfs_inobt_lshift(
835 xfs_btree_cur_t *cur, /* btree cursor */
836 int level, /* level to shift record on */
837 int *stat) /* success/failure */
838 {
839 int error; /* error return value */
840 #ifdef DEBUG
841 int i; /* loop index */
842 #endif
843 xfs_inobt_key_t key; /* key value for leaf level upward */
844 xfs_buf_t *lbp; /* buffer for left neighbor block */
845 xfs_inobt_block_t *left; /* left neighbor btree block */
846 xfs_inobt_key_t *lkp=NULL; /* key pointer for left block */
847 xfs_inobt_ptr_t *lpp; /* address pointer for left block */
848 xfs_inobt_rec_t *lrp=NULL; /* record pointer for left block */
849 int nrec; /* new number of left block entries */
850 xfs_buf_t *rbp; /* buffer for right (current) block */
851 xfs_inobt_block_t *right; /* right (current) btree block */
852 xfs_inobt_key_t *rkp=NULL; /* key pointer for right block */
853 xfs_inobt_ptr_t *rpp=NULL; /* address pointer for right block */
854 xfs_inobt_rec_t *rrp=NULL; /* record pointer for right block */
855
856 /*
857 * Set up variables for this block as "right".
858 */
859 rbp = cur->bc_bufs[level];
860 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
861 #ifdef DEBUG
862 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
863 return error;
864 #endif
865 /*
866 * If we've got no left sibling then we can't shift an entry left.
867 */
868 if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
869 *stat = 0;
870 return 0;
871 }
872 /*
873 * If the cursor entry is the one that would be moved, don't
874 * do it... it's too complicated.
875 */
876 if (cur->bc_ptrs[level] <= 1) {
877 *stat = 0;
878 return 0;
879 }
880 /*
881 * Set up the left neighbor as "left".
882 */
883 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
884 cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
885 0, &lbp, XFS_INO_BTREE_REF)))
886 return error;
887 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
888 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
889 return error;
890 /*
891 * If it's full, it can't take another entry.
892 */
893 if (be16_to_cpu(left->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
894 *stat = 0;
895 return 0;
896 }
897 nrec = be16_to_cpu(left->bb_numrecs) + 1;
898 /*
899 * If non-leaf, copy a key and a ptr to the left block.
900 */
901 if (level > 0) {
902 lkp = XFS_INOBT_KEY_ADDR(left, nrec, cur);
903 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
904 *lkp = *rkp;
905 xfs_inobt_log_keys(cur, lbp, nrec, nrec);
906 lpp = XFS_INOBT_PTR_ADDR(left, nrec, cur);
907 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
908 #ifdef DEBUG
909 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
910 return error;
911 #endif
912 *lpp = *rpp;
913 xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
914 }
915 /*
916 * If leaf, copy a record to the left block.
917 */
918 else {
919 lrp = XFS_INOBT_REC_ADDR(left, nrec, cur);
920 rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
921 *lrp = *rrp;
922 xfs_inobt_log_recs(cur, lbp, nrec, nrec);
923 }
924 /*
925 * Bump and log left's numrecs, decrement and log right's numrecs.
926 */
927 be16_add_cpu(&left->bb_numrecs, 1);
928 xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
929 #ifdef DEBUG
930 if (level > 0)
931 xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
932 else
933 xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
934 #endif
935 be16_add_cpu(&right->bb_numrecs, -1);
936 xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
937 /*
938 * Slide the contents of right down one entry.
939 */
940 if (level > 0) {
941 #ifdef DEBUG
942 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
943 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
944 level)))
945 return error;
946 }
947 #endif
948 memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
949 memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
950 xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
951 xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
952 } else {
953 memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
954 xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
955 key.ir_startino = rrp->ir_startino;
956 rkp = &key;
957 }
958 /*
959 * Update the parent key values of right.
960 */
961 if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
962 return error;
963 /*
964 * Slide the cursor value left one.
965 */
966 cur->bc_ptrs[level]--;
967 *stat = 1;
968 return 0;
969 } 826 }
970 827
971 /* 828 /*
972 * Allocate a new root block, fill it in. 829 * Allocate a new root block, fill it in.
973 */ 830 */
974 STATIC int /* error */ 831 STATIC int /* error */
975 xfs_inobt_newroot( 832 xfs_inobt_newroot(
976 xfs_btree_cur_t *cur, /* btree cursor */ 833 xfs_btree_cur_t *cur, /* btree cursor */
977 int *stat) /* success/failure */ 834 int *stat) /* success/failure */
978 { 835 {
979 xfs_agi_t *agi; /* a.g. inode header */ 836 xfs_agi_t *agi; /* a.g. inode header */
980 xfs_alloc_arg_t args; /* allocation argument structure */ 837 xfs_alloc_arg_t args; /* allocation argument structure */
981 xfs_inobt_block_t *block; /* one half of the old root block */ 838 xfs_inobt_block_t *block; /* one half of the old root block */
982 xfs_buf_t *bp; /* buffer containing block */ 839 xfs_buf_t *bp; /* buffer containing block */
983 int error; /* error return value */ 840 int error; /* error return value */
984 xfs_inobt_key_t *kp; /* btree key pointer */ 841 xfs_inobt_key_t *kp; /* btree key pointer */
985 xfs_agblock_t lbno; /* left block number */ 842 xfs_agblock_t lbno; /* left block number */
986 xfs_buf_t *lbp; /* left buffer pointer */ 843 xfs_buf_t *lbp; /* left buffer pointer */
987 xfs_inobt_block_t *left; /* left btree block */ 844 xfs_inobt_block_t *left; /* left btree block */
988 xfs_buf_t *nbp; /* new (root) buffer */ 845 xfs_buf_t *nbp; /* new (root) buffer */
989 xfs_inobt_block_t *new; /* new (root) btree block */ 846 xfs_inobt_block_t *new; /* new (root) btree block */
990 int nptr; /* new value for key index, 1 or 2 */ 847 int nptr; /* new value for key index, 1 or 2 */
991 xfs_inobt_ptr_t *pp; /* btree address pointer */ 848 xfs_inobt_ptr_t *pp; /* btree address pointer */
992 xfs_agblock_t rbno; /* right block number */ 849 xfs_agblock_t rbno; /* right block number */
993 xfs_buf_t *rbp; /* right buffer pointer */ 850 xfs_buf_t *rbp; /* right buffer pointer */
994 xfs_inobt_block_t *right; /* right btree block */ 851 xfs_inobt_block_t *right; /* right btree block */
995 xfs_inobt_rec_t *rp; /* btree record pointer */ 852 xfs_inobt_rec_t *rp; /* btree record pointer */
996 853
997 ASSERT(cur->bc_nlevels < XFS_IN_MAXLEVELS(cur->bc_mp)); 854 ASSERT(cur->bc_nlevels < XFS_IN_MAXLEVELS(cur->bc_mp));
998 855
999 /* 856 /*
1000 * Get a block & a buffer. 857 * Get a block & a buffer.
1001 */ 858 */
1002 agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); 859 agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
1003 args.tp = cur->bc_tp; 860 args.tp = cur->bc_tp;
1004 args.mp = cur->bc_mp; 861 args.mp = cur->bc_mp;
1005 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, 862 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno,
1006 be32_to_cpu(agi->agi_root)); 863 be32_to_cpu(agi->agi_root));
1007 args.mod = args.minleft = args.alignment = args.total = args.wasdel = 864 args.mod = args.minleft = args.alignment = args.total = args.wasdel =
1008 args.isfl = args.userdata = args.minalignslop = 0; 865 args.isfl = args.userdata = args.minalignslop = 0;
1009 args.minlen = args.maxlen = args.prod = 1; 866 args.minlen = args.maxlen = args.prod = 1;
1010 args.type = XFS_ALLOCTYPE_NEAR_BNO; 867 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1011 if ((error = xfs_alloc_vextent(&args))) 868 if ((error = xfs_alloc_vextent(&args)))
1012 return error; 869 return error;
1013 /* 870 /*
1014 * None available, we fail. 871 * None available, we fail.
1015 */ 872 */
1016 if (args.fsbno == NULLFSBLOCK) { 873 if (args.fsbno == NULLFSBLOCK) {
1017 *stat = 0; 874 *stat = 0;
1018 return 0; 875 return 0;
1019 } 876 }
1020 ASSERT(args.len == 1); 877 ASSERT(args.len == 1);
1021 nbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0); 878 nbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
1022 new = XFS_BUF_TO_INOBT_BLOCK(nbp); 879 new = XFS_BUF_TO_INOBT_BLOCK(nbp);
1023 /* 880 /*
1024 * Set the root data in the a.g. inode structure. 881 * Set the root data in the a.g. inode structure.
1025 */ 882 */
1026 agi->agi_root = cpu_to_be32(args.agbno); 883 agi->agi_root = cpu_to_be32(args.agbno);
1027 be32_add_cpu(&agi->agi_level, 1); 884 be32_add_cpu(&agi->agi_level, 1);
1028 xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp, 885 xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp,
1029 XFS_AGI_ROOT | XFS_AGI_LEVEL); 886 XFS_AGI_ROOT | XFS_AGI_LEVEL);
1030 /* 887 /*
1031 * At the previous root level there are now two blocks: the old 888 * At the previous root level there are now two blocks: the old
1032 * root, and the new block generated when it was split. 889 * root, and the new block generated when it was split.
1033 * We don't know which one the cursor is pointing at, so we 890 * We don't know which one the cursor is pointing at, so we
1034 * set up variables "left" and "right" for each case. 891 * set up variables "left" and "right" for each case.
1035 */ 892 */
1036 bp = cur->bc_bufs[cur->bc_nlevels - 1]; 893 bp = cur->bc_bufs[cur->bc_nlevels - 1];
1037 block = XFS_BUF_TO_INOBT_BLOCK(bp); 894 block = XFS_BUF_TO_INOBT_BLOCK(bp);
1038 #ifdef DEBUG 895 #ifdef DEBUG
1039 if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp))) 896 if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp)))
1040 return error; 897 return error;
1041 #endif 898 #endif
1042 if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) { 899 if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
1043 /* 900 /*
1044 * Our block is left, pick up the right block. 901 * Our block is left, pick up the right block.
1045 */ 902 */
1046 lbp = bp; 903 lbp = bp;
1047 lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp)); 904 lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
1048 left = block; 905 left = block;
1049 rbno = be32_to_cpu(left->bb_rightsib); 906 rbno = be32_to_cpu(left->bb_rightsib);
1050 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno, 907 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
1051 rbno, 0, &rbp, XFS_INO_BTREE_REF))) 908 rbno, 0, &rbp, XFS_INO_BTREE_REF)))
1052 return error; 909 return error;
1053 bp = rbp; 910 bp = rbp;
1054 right = XFS_BUF_TO_INOBT_BLOCK(rbp); 911 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
1055 if ((error = xfs_btree_check_sblock(cur, right, 912 if ((error = xfs_btree_check_sblock(cur, right,
1056 cur->bc_nlevels - 1, rbp))) 913 cur->bc_nlevels - 1, rbp)))
1057 return error; 914 return error;
1058 nptr = 1; 915 nptr = 1;
1059 } else { 916 } else {
1060 /* 917 /*
1061 * Our block is right, pick up the left block. 918 * Our block is right, pick up the left block.
1062 */ 919 */
1063 rbp = bp; 920 rbp = bp;
1064 rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp)); 921 rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp));
1065 right = block; 922 right = block;
1066 lbno = be32_to_cpu(right->bb_leftsib); 923 lbno = be32_to_cpu(right->bb_leftsib);
1067 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno, 924 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
1068 lbno, 0, &lbp, XFS_INO_BTREE_REF))) 925 lbno, 0, &lbp, XFS_INO_BTREE_REF)))
1069 return error; 926 return error;
1070 bp = lbp; 927 bp = lbp;
1071 left = XFS_BUF_TO_INOBT_BLOCK(lbp); 928 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
1072 if ((error = xfs_btree_check_sblock(cur, left, 929 if ((error = xfs_btree_check_sblock(cur, left,
1073 cur->bc_nlevels - 1, lbp))) 930 cur->bc_nlevels - 1, lbp)))
1074 return error; 931 return error;
1075 nptr = 2; 932 nptr = 2;
1076 } 933 }
1077 /* 934 /*
1078 * Fill in the new block's btree header and log it. 935 * Fill in the new block's btree header and log it.
1079 */ 936 */
1080 new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); 937 new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
1081 new->bb_level = cpu_to_be16(cur->bc_nlevels); 938 new->bb_level = cpu_to_be16(cur->bc_nlevels);
1082 new->bb_numrecs = cpu_to_be16(2); 939 new->bb_numrecs = cpu_to_be16(2);
1083 new->bb_leftsib = cpu_to_be32(NULLAGBLOCK); 940 new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
1084 new->bb_rightsib = cpu_to_be32(NULLAGBLOCK); 941 new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
1085 xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS); 942 xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS);
1086 ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK); 943 ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
1087 /* 944 /*
1088 * Fill in the key data in the new root. 945 * Fill in the key data in the new root.
1089 */ 946 */
1090 kp = XFS_INOBT_KEY_ADDR(new, 1, cur); 947 kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
1091 if (be16_to_cpu(left->bb_level) > 0) { 948 if (be16_to_cpu(left->bb_level) > 0) {
1092 kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); 949 kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur);
1093 kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); 950 kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur);
1094 } else { 951 } else {
1095 rp = XFS_INOBT_REC_ADDR(left, 1, cur); 952 rp = XFS_INOBT_REC_ADDR(left, 1, cur);
1096 kp[0].ir_startino = rp->ir_startino; 953 kp[0].ir_startino = rp->ir_startino;
1097 rp = XFS_INOBT_REC_ADDR(right, 1, cur); 954 rp = XFS_INOBT_REC_ADDR(right, 1, cur);
1098 kp[1].ir_startino = rp->ir_startino; 955 kp[1].ir_startino = rp->ir_startino;
1099 } 956 }
1100 xfs_inobt_log_keys(cur, nbp, 1, 2); 957 xfs_inobt_log_keys(cur, nbp, 1, 2);
1101 /* 958 /*
1102 * Fill in the pointer data in the new root. 959 * Fill in the pointer data in the new root.
1103 */ 960 */
1104 pp = XFS_INOBT_PTR_ADDR(new, 1, cur); 961 pp = XFS_INOBT_PTR_ADDR(new, 1, cur);
1105 pp[0] = cpu_to_be32(lbno); 962 pp[0] = cpu_to_be32(lbno);
1106 pp[1] = cpu_to_be32(rbno); 963 pp[1] = cpu_to_be32(rbno);
1107 xfs_inobt_log_ptrs(cur, nbp, 1, 2); 964 xfs_inobt_log_ptrs(cur, nbp, 1, 2);
1108 /* 965 /*
1109 * Fix up the cursor. 966 * Fix up the cursor.
1110 */ 967 */
1111 xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); 968 xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
1112 cur->bc_ptrs[cur->bc_nlevels] = nptr; 969 cur->bc_ptrs[cur->bc_nlevels] = nptr;
1113 cur->bc_nlevels++; 970 cur->bc_nlevels++;
1114 *stat = 1; 971 *stat = 1;
1115 return 0; 972 return 0;
1116 } 973 }
1117 974
1118 /* 975 /*
1119 * Split cur/level block in half. 976 * Split cur/level block in half.
1120 * Return new block number and its first record (to be inserted into parent). 977 * Return new block number and its first record (to be inserted into parent).
1121 */ 978 */
1122 STATIC int /* error */ 979 STATIC int /* error */
1123 xfs_inobt_split( 980 xfs_inobt_split(
1124 xfs_btree_cur_t *cur, /* btree cursor */ 981 xfs_btree_cur_t *cur, /* btree cursor */
1125 int level, /* level to split */ 982 int level, /* level to split */
1126 xfs_agblock_t *bnop, /* output: block number allocated */ 983 xfs_agblock_t *bnop, /* output: block number allocated */
1127 xfs_inobt_key_t *keyp, /* output: first key of new block */ 984 xfs_inobt_key_t *keyp, /* output: first key of new block */
1128 xfs_btree_cur_t **curp, /* output: new cursor */ 985 xfs_btree_cur_t **curp, /* output: new cursor */
1129 int *stat) /* success/failure */ 986 int *stat) /* success/failure */
1130 { 987 {
1131 xfs_alloc_arg_t args; /* allocation argument structure */ 988 xfs_alloc_arg_t args; /* allocation argument structure */
1132 int error; /* error return value */ 989 int error; /* error return value */
1133 int i; /* loop index/record number */ 990 int i; /* loop index/record number */
1134 xfs_agblock_t lbno; /* left (current) block number */ 991 xfs_agblock_t lbno; /* left (current) block number */
1135 xfs_buf_t *lbp; /* buffer for left block */ 992 xfs_buf_t *lbp; /* buffer for left block */
1136 xfs_inobt_block_t *left; /* left (current) btree block */ 993 xfs_inobt_block_t *left; /* left (current) btree block */
1137 xfs_inobt_key_t *lkp; /* left btree key pointer */ 994 xfs_inobt_key_t *lkp; /* left btree key pointer */
1138 xfs_inobt_ptr_t *lpp; /* left btree address pointer */ 995 xfs_inobt_ptr_t *lpp; /* left btree address pointer */
1139 xfs_inobt_rec_t *lrp; /* left btree record pointer */ 996 xfs_inobt_rec_t *lrp; /* left btree record pointer */
1140 xfs_buf_t *rbp; /* buffer for right block */ 997 xfs_buf_t *rbp; /* buffer for right block */
1141 xfs_inobt_block_t *right; /* right (new) btree block */ 998 xfs_inobt_block_t *right; /* right (new) btree block */
1142 xfs_inobt_key_t *rkp; /* right btree key pointer */ 999 xfs_inobt_key_t *rkp; /* right btree key pointer */
1143 xfs_inobt_ptr_t *rpp; /* right btree address pointer */ 1000 xfs_inobt_ptr_t *rpp; /* right btree address pointer */
1144 xfs_inobt_rec_t *rrp; /* right btree record pointer */ 1001 xfs_inobt_rec_t *rrp; /* right btree record pointer */
1145 1002
1146 /* 1003 /*
1147 * Set up left block (current one). 1004 * Set up left block (current one).
1148 */ 1005 */
1149 lbp = cur->bc_bufs[level]; 1006 lbp = cur->bc_bufs[level];
1150 args.tp = cur->bc_tp; 1007 args.tp = cur->bc_tp;
1151 args.mp = cur->bc_mp; 1008 args.mp = cur->bc_mp;
1152 lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp)); 1009 lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
1153 /* 1010 /*
1154 * Allocate the new block. 1011 * Allocate the new block.
1155 * If we can't do it, we're toast. Give up. 1012 * If we can't do it, we're toast. Give up.
1156 */ 1013 */
1157 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, lbno); 1014 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, lbno);
1158 args.mod = args.minleft = args.alignment = args.total = args.wasdel = 1015 args.mod = args.minleft = args.alignment = args.total = args.wasdel =
1159 args.isfl = args.userdata = args.minalignslop = 0; 1016 args.isfl = args.userdata = args.minalignslop = 0;
1160 args.minlen = args.maxlen = args.prod = 1; 1017 args.minlen = args.maxlen = args.prod = 1;
1161 args.type = XFS_ALLOCTYPE_NEAR_BNO; 1018 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1162 if ((error = xfs_alloc_vextent(&args))) 1019 if ((error = xfs_alloc_vextent(&args)))
1163 return error; 1020 return error;
1164 if (args.fsbno == NULLFSBLOCK) { 1021 if (args.fsbno == NULLFSBLOCK) {
1165 *stat = 0; 1022 *stat = 0;
1166 return 0; 1023 return 0;
1167 } 1024 }
1168 ASSERT(args.len == 1); 1025 ASSERT(args.len == 1);
1169 rbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0); 1026 rbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
1170 /* 1027 /*
1171 * Set up the new block as "right". 1028 * Set up the new block as "right".
1172 */ 1029 */
1173 right = XFS_BUF_TO_INOBT_BLOCK(rbp); 1030 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
1174 /* 1031 /*
1175 * "Left" is the current (according to the cursor) block. 1032 * "Left" is the current (according to the cursor) block.
1176 */ 1033 */
1177 left = XFS_BUF_TO_INOBT_BLOCK(lbp); 1034 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
1178 #ifdef DEBUG 1035 #ifdef DEBUG
1179 if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) 1036 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
1180 return error; 1037 return error;
1181 #endif 1038 #endif
1182 /* 1039 /*
1183 * Fill in the btree header for the new block. 1040 * Fill in the btree header for the new block.
1184 */ 1041 */
1185 right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); 1042 right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
1186 right->bb_level = left->bb_level; 1043 right->bb_level = left->bb_level;
1187 right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2); 1044 right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
1188 /* 1045 /*
1189 * Make sure that if there's an odd number of entries now, that 1046 * Make sure that if there's an odd number of entries now, that
1190 * each new block will have the same number of entries. 1047 * each new block will have the same number of entries.
1191 */ 1048 */
1192 if ((be16_to_cpu(left->bb_numrecs) & 1) && 1049 if ((be16_to_cpu(left->bb_numrecs) & 1) &&
1193 cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) 1050 cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
1194 be16_add_cpu(&right->bb_numrecs, 1); 1051 be16_add_cpu(&right->bb_numrecs, 1);
1195 i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; 1052 i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
1196 /* 1053 /*
1197 * For non-leaf blocks, copy keys and addresses over to the new block. 1054 * For non-leaf blocks, copy keys and addresses over to the new block.
1198 */ 1055 */
1199 if (level > 0) { 1056 if (level > 0) {
1200 lkp = XFS_INOBT_KEY_ADDR(left, i, cur); 1057 lkp = XFS_INOBT_KEY_ADDR(left, i, cur);
1201 lpp = XFS_INOBT_PTR_ADDR(left, i, cur); 1058 lpp = XFS_INOBT_PTR_ADDR(left, i, cur);
1202 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur); 1059 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
1203 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur); 1060 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
1204 #ifdef DEBUG 1061 #ifdef DEBUG
1205 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { 1062 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
1206 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level))) 1063 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
1207 return error; 1064 return error;
1208 } 1065 }
1209 #endif 1066 #endif
1210 memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); 1067 memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
1211 memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); 1068 memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
1212 xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 1069 xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1213 xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 1070 xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1214 *keyp = *rkp; 1071 *keyp = *rkp;
1215 } 1072 }
1216 /* 1073 /*
1217 * For leaf blocks, copy records over to the new block. 1074 * For leaf blocks, copy records over to the new block.
1218 */ 1075 */
1219 else { 1076 else {
1220 lrp = XFS_INOBT_REC_ADDR(left, i, cur); 1077 lrp = XFS_INOBT_REC_ADDR(left, i, cur);
1221 rrp = XFS_INOBT_REC_ADDR(right, 1, cur); 1078 rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
1222 memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); 1079 memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
1223 xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); 1080 xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1224 keyp->ir_startino = rrp->ir_startino; 1081 keyp->ir_startino = rrp->ir_startino;
1225 } 1082 }
1226 /* 1083 /*
1227 * Find the left block number by looking in the buffer. 1084 * Find the left block number by looking in the buffer.
1228 * Adjust numrecs, sibling pointers. 1085 * Adjust numrecs, sibling pointers.
1229 */ 1086 */
1230 be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); 1087 be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
1231 right->bb_rightsib = left->bb_rightsib; 1088 right->bb_rightsib = left->bb_rightsib;
1232 left->bb_rightsib = cpu_to_be32(args.agbno); 1089 left->bb_rightsib = cpu_to_be32(args.agbno);
1233 right->bb_leftsib = cpu_to_be32(lbno); 1090 right->bb_leftsib = cpu_to_be32(lbno);
1234 xfs_inobt_log_block(args.tp, rbp, XFS_BB_ALL_BITS); 1091 xfs_inobt_log_block(args.tp, rbp, XFS_BB_ALL_BITS);
1235 xfs_inobt_log_block(args.tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB); 1092 xfs_inobt_log_block(args.tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
1236 /* 1093 /*
1237 * If there's a block to the new block's right, make that block 1094 * If there's a block to the new block's right, make that block
1238 * point back to right instead of to left. 1095 * point back to right instead of to left.
1239 */ 1096 */
1240 if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) { 1097 if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
1241 xfs_inobt_block_t *rrblock; /* rr btree block */ 1098 xfs_inobt_block_t *rrblock; /* rr btree block */
1242 xfs_buf_t *rrbp; /* buffer for rrblock */ 1099 xfs_buf_t *rrbp; /* buffer for rrblock */
1243 1100
1244 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno, 1101 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
1245 be32_to_cpu(right->bb_rightsib), 0, &rrbp, 1102 be32_to_cpu(right->bb_rightsib), 0, &rrbp,
1246 XFS_INO_BTREE_REF))) 1103 XFS_INO_BTREE_REF)))
1247 return error; 1104 return error;
1248 rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp); 1105 rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
1249 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp))) 1106 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
1250 return error; 1107 return error;
1251 rrblock->bb_leftsib = cpu_to_be32(args.agbno); 1108 rrblock->bb_leftsib = cpu_to_be32(args.agbno);
1252 xfs_inobt_log_block(args.tp, rrbp, XFS_BB_LEFTSIB); 1109 xfs_inobt_log_block(args.tp, rrbp, XFS_BB_LEFTSIB);
1253 } 1110 }
1254 /* 1111 /*
1255 * If the cursor is really in the right block, move it there. 1112 * If the cursor is really in the right block, move it there.
1256 * If it's just pointing past the last entry in left, then we'll 1113 * If it's just pointing past the last entry in left, then we'll
1257 * insert there, so don't change anything in that case. 1114 * insert there, so don't change anything in that case.
1258 */ 1115 */
1259 if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) { 1116 if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
1260 xfs_btree_setbuf(cur, level, rbp); 1117 xfs_btree_setbuf(cur, level, rbp);
1261 cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs); 1118 cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
1262 } 1119 }
1263 /* 1120 /*
1264 * If there are more levels, we'll need another cursor which refers 1121 * If there are more levels, we'll need another cursor which refers
1265 * the right block, no matter where this cursor was. 1122 * the right block, no matter where this cursor was.
1266 */ 1123 */
1267 if (level + 1 < cur->bc_nlevels) { 1124 if (level + 1 < cur->bc_nlevels) {
1268 if ((error = xfs_btree_dup_cursor(cur, curp))) 1125 if ((error = xfs_btree_dup_cursor(cur, curp)))
1269 return error; 1126 return error;
1270 (*curp)->bc_ptrs[level + 1]++; 1127 (*curp)->bc_ptrs[level + 1]++;
1271 } 1128 }
1272 *bnop = args.agbno; 1129 *bnop = args.agbno;
1273 *stat = 1; 1130 *stat = 1;
1274 return 0; 1131 return 0;
1275 } 1132 }
1276 1133
1277 /* 1134 /*
1278 * Externally visible routines. 1135 * Externally visible routines.
1279 */ 1136 */
1280 1137
1281 /* 1138 /*
1282 * Delete the record pointed to by cur. 1139 * Delete the record pointed to by cur.
1283 * The cursor refers to the place where the record was (could be inserted) 1140 * The cursor refers to the place where the record was (could be inserted)
1284 * when the operation returns. 1141 * when the operation returns.
1285 */ 1142 */
1286 int /* error */ 1143 int /* error */
1287 xfs_inobt_delete( 1144 xfs_inobt_delete(
1288 xfs_btree_cur_t *cur, /* btree cursor */ 1145 xfs_btree_cur_t *cur, /* btree cursor */
1289 int *stat) /* success/failure */ 1146 int *stat) /* success/failure */
1290 { 1147 {
1291 int error; 1148 int error;
1292 int i; /* result code */ 1149 int i; /* result code */
1293 int level; /* btree level */ 1150 int level; /* btree level */
1294 1151
1295 /* 1152 /*
1296 * Go up the tree, starting at leaf level. 1153 * Go up the tree, starting at leaf level.
1297 * If 2 is returned then a join was done; go to the next level. 1154 * If 2 is returned then a join was done; go to the next level.
1298 * Otherwise we are done. 1155 * Otherwise we are done.
1299 */ 1156 */
1300 for (level = 0, i = 2; i == 2; level++) { 1157 for (level = 0, i = 2; i == 2; level++) {
1301 if ((error = xfs_inobt_delrec(cur, level, &i))) 1158 if ((error = xfs_inobt_delrec(cur, level, &i)))
1302 return error; 1159 return error;
1303 } 1160 }
1304 if (i == 0) { 1161 if (i == 0) {
1305 for (level = 1; level < cur->bc_nlevels; level++) { 1162 for (level = 1; level < cur->bc_nlevels; level++) {
1306 if (cur->bc_ptrs[level] == 0) { 1163 if (cur->bc_ptrs[level] == 0) {
1307 if ((error = xfs_btree_decrement(cur, level, &i))) 1164 if ((error = xfs_btree_decrement(cur, level, &i)))
1308 return error; 1165 return error;
1309 break; 1166 break;
1310 } 1167 }
1311 } 1168 }
1312 } 1169 }
1313 *stat = i; 1170 *stat = i;
1314 return 0; 1171 return 0;
1315 } 1172 }
1316 1173
1317 1174
1318 /* 1175 /*
1319 * Get the data from the pointed-to record. 1176 * Get the data from the pointed-to record.
1320 */ 1177 */
1321 int /* error */ 1178 int /* error */
1322 xfs_inobt_get_rec( 1179 xfs_inobt_get_rec(
1323 xfs_btree_cur_t *cur, /* btree cursor */ 1180 xfs_btree_cur_t *cur, /* btree cursor */
1324 xfs_agino_t *ino, /* output: starting inode of chunk */ 1181 xfs_agino_t *ino, /* output: starting inode of chunk */
1325 __int32_t *fcnt, /* output: number of free inodes */ 1182 __int32_t *fcnt, /* output: number of free inodes */
1326 xfs_inofree_t *free, /* output: free inode mask */ 1183 xfs_inofree_t *free, /* output: free inode mask */
1327 int *stat) /* output: success/failure */ 1184 int *stat) /* output: success/failure */
1328 { 1185 {
1329 xfs_inobt_block_t *block; /* btree block */ 1186 xfs_inobt_block_t *block; /* btree block */
1330 xfs_buf_t *bp; /* buffer containing btree block */ 1187 xfs_buf_t *bp; /* buffer containing btree block */
1331 #ifdef DEBUG 1188 #ifdef DEBUG
1332 int error; /* error return value */ 1189 int error; /* error return value */
1333 #endif 1190 #endif
1334 int ptr; /* record number */ 1191 int ptr; /* record number */
1335 xfs_inobt_rec_t *rec; /* record data */ 1192 xfs_inobt_rec_t *rec; /* record data */
1336 1193
1337 bp = cur->bc_bufs[0]; 1194 bp = cur->bc_bufs[0];
1338 ptr = cur->bc_ptrs[0]; 1195 ptr = cur->bc_ptrs[0];
1339 block = XFS_BUF_TO_INOBT_BLOCK(bp); 1196 block = XFS_BUF_TO_INOBT_BLOCK(bp);
1340 #ifdef DEBUG 1197 #ifdef DEBUG
1341 if ((error = xfs_btree_check_sblock(cur, block, 0, bp))) 1198 if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))
1342 return error; 1199 return error;
1343 #endif 1200 #endif
1344 /* 1201 /*
1345 * Off the right end or left end, return failure. 1202 * Off the right end or left end, return failure.
1346 */ 1203 */
1347 if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) { 1204 if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
1348 *stat = 0; 1205 *stat = 0;
1349 return 0; 1206 return 0;
1350 } 1207 }
1351 /* 1208 /*
1352 * Point to the record and extract its data. 1209 * Point to the record and extract its data.
1353 */ 1210 */
1354 rec = XFS_INOBT_REC_ADDR(block, ptr, cur); 1211 rec = XFS_INOBT_REC_ADDR(block, ptr, cur);
1355 *ino = be32_to_cpu(rec->ir_startino); 1212 *ino = be32_to_cpu(rec->ir_startino);
1356 *fcnt = be32_to_cpu(rec->ir_freecount); 1213 *fcnt = be32_to_cpu(rec->ir_freecount);
1357 *free = be64_to_cpu(rec->ir_free); 1214 *free = be64_to_cpu(rec->ir_free);
1358 *stat = 1; 1215 *stat = 1;
1359 return 0; 1216 return 0;
1360 } 1217 }
1361 1218
1362 /* 1219 /*
1363 * Insert the current record at the point referenced by cur. 1220 * Insert the current record at the point referenced by cur.
1364 * The cursor may be inconsistent on return if splits have been done. 1221 * The cursor may be inconsistent on return if splits have been done.
1365 */ 1222 */
1366 int /* error */ 1223 int /* error */
1367 xfs_inobt_insert( 1224 xfs_inobt_insert(
1368 xfs_btree_cur_t *cur, /* btree cursor */ 1225 xfs_btree_cur_t *cur, /* btree cursor */
1369 int *stat) /* success/failure */ 1226 int *stat) /* success/failure */
1370 { 1227 {
1371 int error; /* error return value */ 1228 int error; /* error return value */
1372 int i; /* result value, 0 for failure */ 1229 int i; /* result value, 0 for failure */
1373 int level; /* current level number in btree */ 1230 int level; /* current level number in btree */
1374 xfs_agblock_t nbno; /* new block number (split result) */ 1231 xfs_agblock_t nbno; /* new block number (split result) */
1375 xfs_btree_cur_t *ncur; /* new cursor (split result) */ 1232 xfs_btree_cur_t *ncur; /* new cursor (split result) */
1376 xfs_inobt_rec_t nrec; /* record being inserted this level */ 1233 xfs_inobt_rec_t nrec; /* record being inserted this level */
1377 xfs_btree_cur_t *pcur; /* previous level's cursor */ 1234 xfs_btree_cur_t *pcur; /* previous level's cursor */
1378 1235
1379 level = 0; 1236 level = 0;
1380 nbno = NULLAGBLOCK; 1237 nbno = NULLAGBLOCK;
1381 nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino); 1238 nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
1382 nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount); 1239 nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);
1383 nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free); 1240 nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
1384 ncur = NULL; 1241 ncur = NULL;
1385 pcur = cur; 1242 pcur = cur;
1386 /* 1243 /*
1387 * Loop going up the tree, starting at the leaf level. 1244 * Loop going up the tree, starting at the leaf level.
1388 * Stop when we don't get a split block, that must mean that 1245 * Stop when we don't get a split block, that must mean that
1389 * the insert is finished with this level. 1246 * the insert is finished with this level.
1390 */ 1247 */
1391 do { 1248 do {
1392 /* 1249 /*
1393 * Insert nrec/nbno into this level of the tree. 1250 * Insert nrec/nbno into this level of the tree.
1394 * Note if we fail, nbno will be null. 1251 * Note if we fail, nbno will be null.
1395 */ 1252 */
1396 if ((error = xfs_inobt_insrec(pcur, level++, &nbno, &nrec, &ncur, 1253 if ((error = xfs_inobt_insrec(pcur, level++, &nbno, &nrec, &ncur,
1397 &i))) { 1254 &i))) {
1398 if (pcur != cur) 1255 if (pcur != cur)
1399 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR); 1256 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
1400 return error; 1257 return error;
1401 } 1258 }
1402 /* 1259 /*
1403 * See if the cursor we just used is trash. 1260 * See if the cursor we just used is trash.
1404 * Can't trash the caller's cursor, but otherwise we should 1261 * Can't trash the caller's cursor, but otherwise we should
1405 * if ncur is a new cursor or we're about to be done. 1262 * if ncur is a new cursor or we're about to be done.
1406 */ 1263 */
1407 if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) { 1264 if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {
1408 cur->bc_nlevels = pcur->bc_nlevels; 1265 cur->bc_nlevels = pcur->bc_nlevels;
1409 xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR); 1266 xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
1410 } 1267 }
1411 /* 1268 /*
1412 * If we got a new cursor, switch to it. 1269 * If we got a new cursor, switch to it.
1413 */ 1270 */
1414 if (ncur) { 1271 if (ncur) {
1415 pcur = ncur; 1272 pcur = ncur;
1416 ncur = NULL; 1273 ncur = NULL;
1417 } 1274 }
1418 } while (nbno != NULLAGBLOCK); 1275 } while (nbno != NULLAGBLOCK);
1419 *stat = i; 1276 *stat = i;
1420 return 0; 1277 return 0;
1421 } 1278 }
1422 1279
1423 STATIC struct xfs_btree_cur * 1280 STATIC struct xfs_btree_cur *
1424 xfs_inobt_dup_cursor( 1281 xfs_inobt_dup_cursor(
1425 struct xfs_btree_cur *cur) 1282 struct xfs_btree_cur *cur)
1426 { 1283 {
1427 return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, 1284 return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp,
1428 cur->bc_private.a.agbp, cur->bc_private.a.agno); 1285 cur->bc_private.a.agbp, cur->bc_private.a.agno);
1429 } 1286 }
1430 1287
1431 STATIC int 1288 STATIC int
1432 xfs_inobt_get_maxrecs( 1289 xfs_inobt_get_maxrecs(
1433 struct xfs_btree_cur *cur, 1290 struct xfs_btree_cur *cur,
1434 int level) 1291 int level)
1435 { 1292 {
1436 return cur->bc_mp->m_inobt_mxr[level != 0]; 1293 return cur->bc_mp->m_inobt_mxr[level != 0];
1437 } 1294 }
1438 1295
1439 STATIC void 1296 STATIC void
1440 xfs_inobt_init_key_from_rec( 1297 xfs_inobt_init_key_from_rec(
1441 union xfs_btree_key *key, 1298 union xfs_btree_key *key,
1442 union xfs_btree_rec *rec) 1299 union xfs_btree_rec *rec)
1443 { 1300 {
1444 key->inobt.ir_startino = rec->inobt.ir_startino; 1301 key->inobt.ir_startino = rec->inobt.ir_startino;
1445 } 1302 }
1446 1303
1447 /* 1304 /*
1448 * intial value of ptr for lookup 1305 * intial value of ptr for lookup
1449 */ 1306 */
1450 STATIC void 1307 STATIC void
1451 xfs_inobt_init_ptr_from_cur( 1308 xfs_inobt_init_ptr_from_cur(
1452 struct xfs_btree_cur *cur, 1309 struct xfs_btree_cur *cur,
1453 union xfs_btree_ptr *ptr) 1310 union xfs_btree_ptr *ptr)
1454 { 1311 {
1455 struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); 1312 struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
1456 1313
1457 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno)); 1314 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno));
1458 1315
1459 ptr->s = agi->agi_root; 1316 ptr->s = agi->agi_root;
1460 } 1317 }
1461 1318
1462 STATIC __int64_t 1319 STATIC __int64_t
1463 xfs_inobt_key_diff( 1320 xfs_inobt_key_diff(
1464 struct xfs_btree_cur *cur, 1321 struct xfs_btree_cur *cur,
1465 union xfs_btree_key *key) 1322 union xfs_btree_key *key)
1466 { 1323 {
1467 return (__int64_t)be32_to_cpu(key->inobt.ir_startino) - 1324 return (__int64_t)be32_to_cpu(key->inobt.ir_startino) -
1468 cur->bc_rec.i.ir_startino; 1325 cur->bc_rec.i.ir_startino;
1469 } 1326 }
1470 1327
1471 #ifdef XFS_BTREE_TRACE 1328 #ifdef XFS_BTREE_TRACE
1472 ktrace_t *xfs_inobt_trace_buf; 1329 ktrace_t *xfs_inobt_trace_buf;
1473 1330
1474 STATIC void 1331 STATIC void
1475 xfs_inobt_trace_enter( 1332 xfs_inobt_trace_enter(
1476 struct xfs_btree_cur *cur, 1333 struct xfs_btree_cur *cur,
1477 const char *func, 1334 const char *func,
1478 char *s, 1335 char *s,
1479 int type, 1336 int type,
1480 int line, 1337 int line,
1481 __psunsigned_t a0, 1338 __psunsigned_t a0,
1482 __psunsigned_t a1, 1339 __psunsigned_t a1,
1483 __psunsigned_t a2, 1340 __psunsigned_t a2,
1484 __psunsigned_t a3, 1341 __psunsigned_t a3,
1485 __psunsigned_t a4, 1342 __psunsigned_t a4,
1486 __psunsigned_t a5, 1343 __psunsigned_t a5,
1487 __psunsigned_t a6, 1344 __psunsigned_t a6,
1488 __psunsigned_t a7, 1345 __psunsigned_t a7,
1489 __psunsigned_t a8, 1346 __psunsigned_t a8,
1490 __psunsigned_t a9, 1347 __psunsigned_t a9,
1491 __psunsigned_t a10) 1348 __psunsigned_t a10)
1492 { 1349 {
1493 ktrace_enter(xfs_inobt_trace_buf, (void *)(__psint_t)type, 1350 ktrace_enter(xfs_inobt_trace_buf, (void *)(__psint_t)type,
1494 (void *)func, (void *)s, NULL, (void *)cur, 1351 (void *)func, (void *)s, NULL, (void *)cur,
1495 (void *)a0, (void *)a1, (void *)a2, (void *)a3, 1352 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
1496 (void *)a4, (void *)a5, (void *)a6, (void *)a7, 1353 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
1497 (void *)a8, (void *)a9, (void *)a10); 1354 (void *)a8, (void *)a9, (void *)a10);
1498 } 1355 }
1499 1356
1500 STATIC void 1357 STATIC void
1501 xfs_inobt_trace_cursor( 1358 xfs_inobt_trace_cursor(
1502 struct xfs_btree_cur *cur, 1359 struct xfs_btree_cur *cur,
1503 __uint32_t *s0, 1360 __uint32_t *s0,
1504 __uint64_t *l0, 1361 __uint64_t *l0,
1505 __uint64_t *l1) 1362 __uint64_t *l1)
1506 { 1363 {
1507 *s0 = cur->bc_private.a.agno; 1364 *s0 = cur->bc_private.a.agno;
1508 *l0 = cur->bc_rec.i.ir_startino; 1365 *l0 = cur->bc_rec.i.ir_startino;
1509 *l1 = cur->bc_rec.i.ir_free; 1366 *l1 = cur->bc_rec.i.ir_free;
1510 } 1367 }
1511 1368
1512 STATIC void 1369 STATIC void
1513 xfs_inobt_trace_key( 1370 xfs_inobt_trace_key(
1514 struct xfs_btree_cur *cur, 1371 struct xfs_btree_cur *cur,
1515 union xfs_btree_key *key, 1372 union xfs_btree_key *key,
1516 __uint64_t *l0, 1373 __uint64_t *l0,
1517 __uint64_t *l1) 1374 __uint64_t *l1)
1518 { 1375 {
1519 *l0 = be32_to_cpu(key->inobt.ir_startino); 1376 *l0 = be32_to_cpu(key->inobt.ir_startino);
1520 *l1 = 0; 1377 *l1 = 0;
1521 } 1378 }
1522 1379
1523 STATIC void 1380 STATIC void
1524 xfs_inobt_trace_record( 1381 xfs_inobt_trace_record(
1525 struct xfs_btree_cur *cur, 1382 struct xfs_btree_cur *cur,
1526 union xfs_btree_rec *rec, 1383 union xfs_btree_rec *rec,
1527 __uint64_t *l0, 1384 __uint64_t *l0,
1528 __uint64_t *l1, 1385 __uint64_t *l1,
1529 __uint64_t *l2) 1386 __uint64_t *l2)
1530 { 1387 {
1531 *l0 = be32_to_cpu(rec->inobt.ir_startino); 1388 *l0 = be32_to_cpu(rec->inobt.ir_startino);
1532 *l1 = be32_to_cpu(rec->inobt.ir_freecount); 1389 *l1 = be32_to_cpu(rec->inobt.ir_freecount);
1533 *l2 = be64_to_cpu(rec->inobt.ir_free); 1390 *l2 = be64_to_cpu(rec->inobt.ir_free);
1534 } 1391 }
1535 #endif /* XFS_BTREE_TRACE */ 1392 #endif /* XFS_BTREE_TRACE */
1536 1393
1537 static const struct xfs_btree_ops xfs_inobt_ops = { 1394 static const struct xfs_btree_ops xfs_inobt_ops = {
1538 .rec_len = sizeof(xfs_inobt_rec_t), 1395 .rec_len = sizeof(xfs_inobt_rec_t),
1539 .key_len = sizeof(xfs_inobt_key_t), 1396 .key_len = sizeof(xfs_inobt_key_t),
1540 1397
1541 .dup_cursor = xfs_inobt_dup_cursor, 1398 .dup_cursor = xfs_inobt_dup_cursor,
1542 .get_maxrecs = xfs_inobt_get_maxrecs, 1399 .get_maxrecs = xfs_inobt_get_maxrecs,
1543 .init_key_from_rec = xfs_inobt_init_key_from_rec, 1400 .init_key_from_rec = xfs_inobt_init_key_from_rec,
1544 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, 1401 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
1545 .key_diff = xfs_inobt_key_diff, 1402 .key_diff = xfs_inobt_key_diff,
1546 1403
1547 #ifdef XFS_BTREE_TRACE 1404 #ifdef XFS_BTREE_TRACE
1548 .trace_enter = xfs_inobt_trace_enter, 1405 .trace_enter = xfs_inobt_trace_enter,
1549 .trace_cursor = xfs_inobt_trace_cursor, 1406 .trace_cursor = xfs_inobt_trace_cursor,
1550 .trace_key = xfs_inobt_trace_key, 1407 .trace_key = xfs_inobt_trace_key,
1551 .trace_record = xfs_inobt_trace_record, 1408 .trace_record = xfs_inobt_trace_record,
1552 #endif 1409 #endif
1553 }; 1410 };
1554 1411
1555 /* 1412 /*
1556 * Allocate a new inode btree cursor. 1413 * Allocate a new inode btree cursor.
1557 */ 1414 */
1558 struct xfs_btree_cur * /* new inode btree cursor */ 1415 struct xfs_btree_cur * /* new inode btree cursor */
1559 xfs_inobt_init_cursor( 1416 xfs_inobt_init_cursor(
1560 struct xfs_mount *mp, /* file system mount point */ 1417 struct xfs_mount *mp, /* file system mount point */
1561 struct xfs_trans *tp, /* transaction pointer */ 1418 struct xfs_trans *tp, /* transaction pointer */
1562 struct xfs_buf *agbp, /* buffer for agi structure */ 1419 struct xfs_buf *agbp, /* buffer for agi structure */
1563 xfs_agnumber_t agno) /* allocation group number */ 1420 xfs_agnumber_t agno) /* allocation group number */
1564 { 1421 {
1565 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); 1422 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1566 struct xfs_btree_cur *cur; 1423 struct xfs_btree_cur *cur;
1567 1424
1568 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); 1425 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
1569 1426
1570 cur->bc_tp = tp; 1427 cur->bc_tp = tp;
1571 cur->bc_mp = mp; 1428 cur->bc_mp = mp;
1572 cur->bc_nlevels = be32_to_cpu(agi->agi_level); 1429 cur->bc_nlevels = be32_to_cpu(agi->agi_level);
1573 cur->bc_btnum = XFS_BTNUM_INO; 1430 cur->bc_btnum = XFS_BTNUM_INO;
1574 cur->bc_blocklog = mp->m_sb.sb_blocklog; 1431 cur->bc_blocklog = mp->m_sb.sb_blocklog;
1575 1432
1576 cur->bc_ops = &xfs_inobt_ops; 1433 cur->bc_ops = &xfs_inobt_ops;
1577 1434
1578 cur->bc_private.a.agbp = agbp; 1435 cur->bc_private.a.agbp = agbp;
1579 cur->bc_private.a.agno = agno; 1436 cur->bc_private.a.agno = agno;
1580 1437
1581 return cur; 1438 return cur;
1582 } 1439 }
1583 1440