cd8bb519cb5fe23a2ac9c9a30291d0488518905c
[safe/jmp/linux-2.6] / fs / xfs / xfs_ialloc_btree.c
1 /*
2  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_types.h"
21 #include "xfs_bit.h"
22 #include "xfs_log.h"
23 #include "xfs_inum.h"
24 #include "xfs_trans.h"
25 #include "xfs_sb.h"
26 #include "xfs_ag.h"
27 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h"
34 #include "xfs_attr_sf.h"
35 #include "xfs_dinode.h"
36 #include "xfs_inode.h"
37 #include "xfs_btree.h"
38 #include "xfs_ialloc.h"
39 #include "xfs_alloc.h"
40 #include "xfs_error.h"
41
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);
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);
46 STATIC int xfs_inobt_lshift(xfs_btree_cur_t *, int, int *);
47 STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);
48 STATIC int xfs_inobt_rshift(xfs_btree_cur_t *, int, int *);
49 STATIC int xfs_inobt_split(xfs_btree_cur_t *, int, xfs_agblock_t *,
50                 xfs_inobt_key_t *, xfs_btree_cur_t **, int *);
51
52 /*
53  * Single level of the xfs_inobt_delete record deletion routine.
54  * Delete record pointed to by cur/level.
55  * Remove the record from its block then rebalance the tree.
56  * Return 0 for error, 1 for done, 2 to go on to the next level.
57  */
58 STATIC int                              /* error */
59 xfs_inobt_delrec(
60         xfs_btree_cur_t         *cur,   /* btree cursor */
61         int                     level,  /* level removing record from */
62         int                     *stat)  /* fail/done/go-on */
63 {
64         xfs_buf_t               *agbp;  /* buffer for a.g. inode header */
65         xfs_mount_t             *mp;    /* mount structure */
66         xfs_agi_t               *agi;   /* allocation group inode header */
67         xfs_inobt_block_t       *block; /* btree block record/key lives in */
68         xfs_agblock_t           bno;    /* btree block number */
69         xfs_buf_t               *bp;    /* buffer for block */
70         int                     error;  /* error return value */
71         int                     i;      /* loop index */
72         xfs_inobt_key_t         key;    /* kp points here if block is level 0 */
73         xfs_inobt_key_t         *kp = NULL;     /* pointer to btree keys */
74         xfs_agblock_t           lbno;   /* left block's block number */
75         xfs_buf_t               *lbp;   /* left block's buffer pointer */
76         xfs_inobt_block_t       *left;  /* left btree block */
77         xfs_inobt_key_t         *lkp;   /* left block key pointer */
78         xfs_inobt_ptr_t         *lpp;   /* left block address pointer */
79         int                     lrecs = 0;      /* number of records in left block */
80         xfs_inobt_rec_t         *lrp;   /* left block record pointer */
81         xfs_inobt_ptr_t         *pp = NULL;     /* pointer to btree addresses */
82         int                     ptr;    /* index in btree block for this rec */
83         xfs_agblock_t           rbno;   /* right block's block number */
84         xfs_buf_t               *rbp;   /* right block's buffer pointer */
85         xfs_inobt_block_t       *right; /* right btree block */
86         xfs_inobt_key_t         *rkp;   /* right block key pointer */
87         xfs_inobt_rec_t         *rp;    /* pointer to btree records */
88         xfs_inobt_ptr_t         *rpp;   /* right block address pointer */
89         int                     rrecs = 0;      /* number of records in right block */
90         int                     numrecs;
91         xfs_inobt_rec_t         *rrp;   /* right block record pointer */
92         xfs_btree_cur_t         *tcur;  /* temporary btree cursor */
93
94         mp = cur->bc_mp;
95
96         /*
97          * Get the index of the entry being deleted, check for nothing there.
98          */
99         ptr = cur->bc_ptrs[level];
100         if (ptr == 0) {
101                 *stat = 0;
102                 return 0;
103         }
104
105         /*
106          * Get the buffer & block containing the record or key/ptr.
107          */
108         bp = cur->bc_bufs[level];
109         block = XFS_BUF_TO_INOBT_BLOCK(bp);
110 #ifdef DEBUG
111         if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
112                 return error;
113 #endif
114         /*
115          * Fail if we're off the end of the block.
116          */
117
118         numrecs = be16_to_cpu(block->bb_numrecs);
119         if (ptr > numrecs) {
120                 *stat = 0;
121                 return 0;
122         }
123         /*
124          * It's a nonleaf.  Excise the key and ptr being deleted, by
125          * sliding the entries past them down one.
126          * Log the changed areas of the block.
127          */
128         if (level > 0) {
129                 kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
130                 pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
131 #ifdef DEBUG
132                 for (i = ptr; i < numrecs; i++) {
133                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i]), level)))
134                                 return error;
135                 }
136 #endif
137                 if (ptr < numrecs) {
138                         memmove(&kp[ptr - 1], &kp[ptr],
139                                 (numrecs - ptr) * sizeof(*kp));
140                         memmove(&pp[ptr - 1], &pp[ptr],
141                                 (numrecs - ptr) * sizeof(*kp));
142                         xfs_inobt_log_keys(cur, bp, ptr, numrecs - 1);
143                         xfs_inobt_log_ptrs(cur, bp, ptr, numrecs - 1);
144                 }
145         }
146         /*
147          * 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.
149          */
150         else {
151                 rp = XFS_INOBT_REC_ADDR(block, 1, cur);
152                 if (ptr < numrecs) {
153                         memmove(&rp[ptr - 1], &rp[ptr],
154                                 (numrecs - ptr) * sizeof(*rp));
155                         xfs_inobt_log_recs(cur, bp, ptr, numrecs - 1);
156                 }
157                 /*
158                  * If it's the first record in the block, we'll need a key
159                  * structure to pass up to the next level (updkey).
160                  */
161                 if (ptr == 1) {
162                         key.ir_startino = rp->ir_startino;
163                         kp = &key;
164                 }
165         }
166         /*
167          * Decrement and log the number of entries in the block.
168          */
169         numrecs--;
170         block->bb_numrecs = cpu_to_be16(numrecs);
171         xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
172         /*
173          * Is this the root level?  If so, we're almost done.
174          */
175         if (level == cur->bc_nlevels - 1) {
176                 /*
177                  * If this is the root level,
178                  * and there's only one entry left,
179                  * and it's NOT the leaf level,
180                  * then we can get rid of this level.
181                  */
182                 if (numrecs == 1 && level > 0) {
183                         agbp = cur->bc_private.a.agbp;
184                         agi = XFS_BUF_TO_AGI(agbp);
185                         /*
186                          * pp is still set to the first pointer in the block.
187                          * Make it the new root of the btree.
188                          */
189                         bno = be32_to_cpu(agi->agi_root);
190                         agi->agi_root = *pp;
191                         be32_add_cpu(&agi->agi_level, -1);
192                         /*
193                          * Free the block.
194                          */
195                         if ((error = xfs_free_extent(cur->bc_tp,
196                                 XFS_AGB_TO_FSB(mp, cur->bc_private.a.agno, bno), 1)))
197                                 return error;
198                         xfs_trans_binval(cur->bc_tp, bp);
199                         xfs_ialloc_log_agi(cur->bc_tp, agbp,
200                                 XFS_AGI_ROOT | XFS_AGI_LEVEL);
201                         /*
202                          * Update the cursor so there's one fewer level.
203                          */
204                         cur->bc_bufs[level] = NULL;
205                         cur->bc_nlevels--;
206                 } else if (level > 0 &&
207                            (error = xfs_btree_decrement(cur, level, &i)))
208                         return error;
209                 *stat = 1;
210                 return 0;
211         }
212         /*
213          * If we deleted the leftmost entry in the block, update the
214          * key values above us in the tree.
215          */
216         if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1)))
217                 return error;
218         /*
219          * If the number of records remaining in the block is at least
220          * the minimum, we're done.
221          */
222         if (numrecs >= XFS_INOBT_BLOCK_MINRECS(level, cur)) {
223                 if (level > 0 &&
224                     (error = xfs_btree_decrement(cur, level, &i)))
225                         return error;
226                 *stat = 1;
227                 return 0;
228         }
229         /*
230          * Otherwise, we have to move some records around to keep the
231          * tree balanced.  Look at the left and right sibling blocks to
232          * see if we can re-balance by moving only one record.
233          */
234         rbno = be32_to_cpu(block->bb_rightsib);
235         lbno = be32_to_cpu(block->bb_leftsib);
236         bno = NULLAGBLOCK;
237         ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
238         /*
239          * Duplicate the cursor so our btree manipulations here won't
240          * disrupt the next level up.
241          */
242         if ((error = xfs_btree_dup_cursor(cur, &tcur)))
243                 return error;
244         /*
245          * If there's a right sibling, see if it's ok to shift an entry
246          * out of it.
247          */
248         if (rbno != NULLAGBLOCK) {
249                 /*
250                  * Move the temp cursor to the last entry in the next block.
251                  * Actually any entry but the first would suffice.
252                  */
253                 i = xfs_btree_lastrec(tcur, level);
254                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
255                 if ((error = xfs_btree_increment(tcur, level, &i)))
256                         goto error0;
257                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
258                 i = xfs_btree_lastrec(tcur, level);
259                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
260                 /*
261                  * Grab a pointer to the block.
262                  */
263                 rbp = tcur->bc_bufs[level];
264                 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
265 #ifdef DEBUG
266                 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
267                         goto error0;
268 #endif
269                 /*
270                  * Grab the current block number, for future use.
271                  */
272                 bno = be32_to_cpu(right->bb_leftsib);
273                 /*
274                  * If right block is full enough so that removing one entry
275                  * won't make it too empty, and left-shifting an entry out
276                  * of right to us works, we're done.
277                  */
278                 if (be16_to_cpu(right->bb_numrecs) - 1 >=
279                      XFS_INOBT_BLOCK_MINRECS(level, cur)) {
280                         if ((error = xfs_inobt_lshift(tcur, level, &i)))
281                                 goto error0;
282                         if (i) {
283                                 ASSERT(be16_to_cpu(block->bb_numrecs) >=
284                                        XFS_INOBT_BLOCK_MINRECS(level, cur));
285                                 xfs_btree_del_cursor(tcur,
286                                                      XFS_BTREE_NOERROR);
287                                 if (level > 0 &&
288                                     (error = xfs_btree_decrement(cur, level,
289                                                 &i)))
290                                         return error;
291                                 *stat = 1;
292                                 return 0;
293                         }
294                 }
295                 /*
296                  * Otherwise, grab the number of records in right for
297                  * future reference, and fix up the temp cursor to point
298                  * to our block again (last record).
299                  */
300                 rrecs = be16_to_cpu(right->bb_numrecs);
301                 if (lbno != NULLAGBLOCK) {
302                         xfs_btree_firstrec(tcur, level);
303                         if ((error = xfs_btree_decrement(tcur, level, &i)))
304                                 goto error0;
305                 }
306         }
307         /*
308          * If there's a left sibling, see if it's ok to shift an entry
309          * out of it.
310          */
311         if (lbno != NULLAGBLOCK) {
312                 /*
313                  * Move the temp cursor to the first entry in the
314                  * previous block.
315                  */
316                 xfs_btree_firstrec(tcur, level);
317                 if ((error = xfs_btree_decrement(tcur, level, &i)))
318                         goto error0;
319                 xfs_btree_firstrec(tcur, level);
320                 /*
321                  * Grab a pointer to the block.
322                  */
323                 lbp = tcur->bc_bufs[level];
324                 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
325 #ifdef DEBUG
326                 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
327                         goto error0;
328 #endif
329                 /*
330                  * Grab the current block number, for future use.
331                  */
332                 bno = be32_to_cpu(left->bb_rightsib);
333                 /*
334                  * If left block is full enough so that removing one entry
335                  * won't make it too empty, and right-shifting an entry out
336                  * of left to us works, we're done.
337                  */
338                 if (be16_to_cpu(left->bb_numrecs) - 1 >=
339                      XFS_INOBT_BLOCK_MINRECS(level, cur)) {
340                         if ((error = xfs_inobt_rshift(tcur, level, &i)))
341                                 goto error0;
342                         if (i) {
343                                 ASSERT(be16_to_cpu(block->bb_numrecs) >=
344                                        XFS_INOBT_BLOCK_MINRECS(level, cur));
345                                 xfs_btree_del_cursor(tcur,
346                                                      XFS_BTREE_NOERROR);
347                                 if (level == 0)
348                                         cur->bc_ptrs[0]++;
349                                 *stat = 1;
350                                 return 0;
351                         }
352                 }
353                 /*
354                  * Otherwise, grab the number of records in right for
355                  * future reference.
356                  */
357                 lrecs = be16_to_cpu(left->bb_numrecs);
358         }
359         /*
360          * Delete the temp cursor, we're done with it.
361          */
362         xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
363         /*
364          * If here, we need to do a join to keep the tree balanced.
365          */
366         ASSERT(bno != NULLAGBLOCK);
367         /*
368          * See if we can join with the left neighbor block.
369          */
370         if (lbno != NULLAGBLOCK &&
371             lrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
372                 /*
373                  * Set "right" to be the starting block,
374                  * "left" to be the left neighbor.
375                  */
376                 rbno = bno;
377                 right = block;
378                 rrecs = be16_to_cpu(right->bb_numrecs);
379                 rbp = bp;
380                 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
381                                 cur->bc_private.a.agno, lbno, 0, &lbp,
382                                 XFS_INO_BTREE_REF)))
383                         return error;
384                 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
385                 lrecs = be16_to_cpu(left->bb_numrecs);
386                 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
387                         return error;
388         }
389         /*
390          * If that won't work, see if we can join with the right neighbor block.
391          */
392         else if (rbno != NULLAGBLOCK &&
393                  rrecs + numrecs <= XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
394                 /*
395                  * Set "left" to be the starting block,
396                  * "right" to be the right neighbor.
397                  */
398                 lbno = bno;
399                 left = block;
400                 lrecs = be16_to_cpu(left->bb_numrecs);
401                 lbp = bp;
402                 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
403                                 cur->bc_private.a.agno, rbno, 0, &rbp,
404                                 XFS_INO_BTREE_REF)))
405                         return error;
406                 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
407                 rrecs = be16_to_cpu(right->bb_numrecs);
408                 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
409                         return error;
410         }
411         /*
412          * Otherwise, we can't fix the imbalance.
413          * Just return.  This is probably a logic error, but it's not fatal.
414          */
415         else {
416                 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
417                         return error;
418                 *stat = 1;
419                 return 0;
420         }
421         /*
422          * We're now going to join "left" and "right" by moving all the stuff
423          * in "right" to "left" and deleting "right".
424          */
425         if (level > 0) {
426                 /*
427                  * It's a non-leaf.  Move keys and pointers.
428                  */
429                 lkp = XFS_INOBT_KEY_ADDR(left, lrecs + 1, cur);
430                 lpp = XFS_INOBT_PTR_ADDR(left, lrecs + 1, cur);
431                 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
432                 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
433 #ifdef DEBUG
434                 for (i = 0; i < rrecs; i++) {
435                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
436                                 return error;
437                 }
438 #endif
439                 memcpy(lkp, rkp, rrecs * sizeof(*lkp));
440                 memcpy(lpp, rpp, rrecs * sizeof(*lpp));
441                 xfs_inobt_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
442                 xfs_inobt_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
443         } else {
444                 /*
445                  * It's a leaf.  Move records.
446                  */
447                 lrp = XFS_INOBT_REC_ADDR(left, lrecs + 1, cur);
448                 rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
449                 memcpy(lrp, rrp, rrecs * sizeof(*lrp));
450                 xfs_inobt_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
451         }
452         /*
453          * If we joined with the left neighbor, set the buffer in the
454          * cursor to the left block, and fix up the index.
455          */
456         if (bp != lbp) {
457                 xfs_btree_setbuf(cur, level, lbp);
458                 cur->bc_ptrs[level] += lrecs;
459         }
460         /*
461          * If we joined with the right neighbor and there's a level above
462          * us, increment the cursor at that level.
463          */
464         else if (level + 1 < cur->bc_nlevels &&
465                  (error = xfs_btree_increment(cur, level + 1, &i)))
466                 return error;
467         /*
468          * Fix up the number of records in the surviving block.
469          */
470         lrecs += rrecs;
471         left->bb_numrecs = cpu_to_be16(lrecs);
472         /*
473          * Fix up the right block pointer in the surviving block, and log it.
474          */
475         left->bb_rightsib = right->bb_rightsib;
476         xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
477         /*
478          * If there is a right sibling now, make it point to the
479          * remaining block.
480          */
481         if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
482                 xfs_inobt_block_t       *rrblock;
483                 xfs_buf_t               *rrbp;
484
485                 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
486                                 cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0,
487                                 &rrbp, XFS_INO_BTREE_REF)))
488                         return error;
489                 rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
490                 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
491                         return error;
492                 rrblock->bb_leftsib = cpu_to_be32(lbno);
493                 xfs_inobt_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
494         }
495         /*
496          * Free the deleting block.
497          */
498         if ((error = xfs_free_extent(cur->bc_tp, XFS_AGB_TO_FSB(mp,
499                                      cur->bc_private.a.agno, rbno), 1)))
500                 return error;
501         xfs_trans_binval(cur->bc_tp, rbp);
502         /*
503          * Readjust the ptr at this level if it's not a leaf, since it's
504          * still pointing at the deletion point, which makes the cursor
505          * inconsistent.  If this makes the ptr 0, the caller fixes it up.
506          * We can't use decrement because it would change the next level up.
507          */
508         if (level > 0)
509                 cur->bc_ptrs[level]--;
510         /*
511          * Return value means the next level up has something to do.
512          */
513         *stat = 2;
514         return 0;
515
516 error0:
517         xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
518         return error;
519 }
520
521 /*
522  * Insert one record/level.  Return information to the caller
523  * allowing the next level up to proceed if necessary.
524  */
525 STATIC int                              /* error */
526 xfs_inobt_insrec(
527         xfs_btree_cur_t         *cur,   /* btree cursor */
528         int                     level,  /* level to insert record at */
529         xfs_agblock_t           *bnop,  /* i/o: block number inserted */
530         xfs_inobt_rec_t         *recp,  /* i/o: record data inserted */
531         xfs_btree_cur_t         **curp, /* output: new cursor replacing cur */
532         int                     *stat)  /* success/failure */
533 {
534         xfs_inobt_block_t       *block; /* btree block record/key lives in */
535         xfs_buf_t               *bp;    /* buffer for block */
536         int                     error;  /* error return value */
537         int                     i;      /* loop index */
538         xfs_inobt_key_t         key;    /* key value being inserted */
539         xfs_inobt_key_t         *kp=NULL;       /* pointer to btree keys */
540         xfs_agblock_t           nbno;   /* block number of allocated block */
541         xfs_btree_cur_t         *ncur;  /* new cursor to be used at next lvl */
542         xfs_inobt_key_t         nkey;   /* new key value, from split */
543         xfs_inobt_rec_t         nrec;   /* new record value, for caller */
544         int                     numrecs;
545         int                     optr;   /* old ptr value */
546         xfs_inobt_ptr_t         *pp;    /* pointer to btree addresses */
547         int                     ptr;    /* index in btree block for this rec */
548         xfs_inobt_rec_t         *rp=NULL;       /* pointer to btree records */
549
550         /*
551          * GCC doesn't understand the (arguably complex) control flow in
552          * this function and complains about uninitialized structure fields
553          * without this.
554          */
555         memset(&nrec, 0, sizeof(nrec));
556
557         /*
558          * If we made it to the root level, allocate a new root block
559          * and we're done.
560          */
561         if (level >= cur->bc_nlevels) {
562                 error = xfs_inobt_newroot(cur, &i);
563                 *bnop = NULLAGBLOCK;
564                 *stat = i;
565                 return error;
566         }
567         /*
568          * Make a key out of the record data to be inserted, and save it.
569          */
570         key.ir_startino = recp->ir_startino;
571         optr = ptr = cur->bc_ptrs[level];
572         /*
573          * If we're off the left edge, return failure.
574          */
575         if (ptr == 0) {
576                 *stat = 0;
577                 return 0;
578         }
579         /*
580          * Get pointers to the btree buffer and block.
581          */
582         bp = cur->bc_bufs[level];
583         block = XFS_BUF_TO_INOBT_BLOCK(bp);
584         numrecs = be16_to_cpu(block->bb_numrecs);
585 #ifdef DEBUG
586         if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
587                 return error;
588         /*
589          * Check that the new entry is being inserted in the right place.
590          */
591         if (ptr <= numrecs) {
592                 if (level == 0) {
593                         rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
594                         xfs_btree_check_rec(cur->bc_btnum, recp, rp);
595                 } else {
596                         kp = XFS_INOBT_KEY_ADDR(block, ptr, cur);
597                         xfs_btree_check_key(cur->bc_btnum, &key, kp);
598                 }
599         }
600 #endif
601         nbno = NULLAGBLOCK;
602         ncur = NULL;
603         /*
604          * If the block is full, we can't insert the new entry until we
605          * make the block un-full.
606          */
607         if (numrecs == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
608                 /*
609                  * First, try shifting an entry to the right neighbor.
610                  */
611                 if ((error = xfs_inobt_rshift(cur, level, &i)))
612                         return error;
613                 if (i) {
614                         /* nothing */
615                 }
616                 /*
617                  * Next, try shifting an entry to the left neighbor.
618                  */
619                 else {
620                         if ((error = xfs_inobt_lshift(cur, level, &i)))
621                                 return error;
622                         if (i) {
623                                 optr = ptr = cur->bc_ptrs[level];
624                         } else {
625                                 /*
626                                  * Next, try splitting the current block
627                                  * in half. If this works we have to
628                                  * re-set our variables because
629                                  * we could be in a different block now.
630                                  */
631                                 if ((error = xfs_inobt_split(cur, level, &nbno,
632                                                 &nkey, &ncur, &i)))
633                                         return error;
634                                 if (i) {
635                                         bp = cur->bc_bufs[level];
636                                         block = XFS_BUF_TO_INOBT_BLOCK(bp);
637 #ifdef DEBUG
638                                         if ((error = xfs_btree_check_sblock(cur,
639                                                         block, level, bp)))
640                                                 return error;
641 #endif
642                                         ptr = cur->bc_ptrs[level];
643                                         nrec.ir_startino = nkey.ir_startino;
644                                 } else {
645                                         /*
646                                          * Otherwise the insert fails.
647                                          */
648                                         *stat = 0;
649                                         return 0;
650                                 }
651                         }
652                 }
653         }
654         /*
655          * At this point we know there's room for our new entry in the block
656          * we're pointing at.
657          */
658         numrecs = be16_to_cpu(block->bb_numrecs);
659         if (level > 0) {
660                 /*
661                  * It's a non-leaf entry.  Make a hole for the new data
662                  * in the key and ptr regions of the block.
663                  */
664                 kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
665                 pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
666 #ifdef DEBUG
667                 for (i = numrecs; i >= ptr; i--) {
668                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
669                                 return error;
670                 }
671 #endif
672                 memmove(&kp[ptr], &kp[ptr - 1],
673                         (numrecs - ptr + 1) * sizeof(*kp));
674                 memmove(&pp[ptr], &pp[ptr - 1],
675                         (numrecs - ptr + 1) * sizeof(*pp));
676                 /*
677                  * Now stuff the new data in, bump numrecs and log the new data.
678                  */
679 #ifdef DEBUG
680                 if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
681                         return error;
682 #endif
683                 kp[ptr - 1] = key;
684                 pp[ptr - 1] = cpu_to_be32(*bnop);
685                 numrecs++;
686                 block->bb_numrecs = cpu_to_be16(numrecs);
687                 xfs_inobt_log_keys(cur, bp, ptr, numrecs);
688                 xfs_inobt_log_ptrs(cur, bp, ptr, numrecs);
689         } else {
690                 /*
691                  * It's a leaf entry.  Make a hole for the new record.
692                  */
693                 rp = XFS_INOBT_REC_ADDR(block, 1, cur);
694                 memmove(&rp[ptr], &rp[ptr - 1],
695                         (numrecs - ptr + 1) * sizeof(*rp));
696                 /*
697                  * Now stuff the new record in, bump numrecs
698                  * and log the new data.
699                  */
700                 rp[ptr - 1] = *recp;
701                 numrecs++;
702                 block->bb_numrecs = cpu_to_be16(numrecs);
703                 xfs_inobt_log_recs(cur, bp, ptr, numrecs);
704         }
705         /*
706          * Log the new number of records in the btree header.
707          */
708         xfs_inobt_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
709 #ifdef DEBUG
710         /*
711          * Check that the key/record is in the right place, now.
712          */
713         if (ptr < numrecs) {
714                 if (level == 0)
715                         xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
716                                 rp + ptr);
717                 else
718                         xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
719                                 kp + ptr);
720         }
721 #endif
722         /*
723          * If we inserted at the start of a block, update the parents' keys.
724          */
725         if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1)))
726                 return error;
727         /*
728          * Return the new block number, if any.
729          * If there is one, give back a record value and a cursor too.
730          */
731         *bnop = nbno;
732         if (nbno != NULLAGBLOCK) {
733                 *recp = nrec;
734                 *curp = ncur;
735         }
736         *stat = 1;
737         return 0;
738 }
739
740 /*
741  * Log header fields from a btree block.
742  */
743 STATIC void
744 xfs_inobt_log_block(
745         xfs_trans_t             *tp,    /* transaction pointer */
746         xfs_buf_t               *bp,    /* buffer containing btree block */
747         int                     fields) /* mask of fields: XFS_BB_... */
748 {
749         int                     first;  /* first byte offset logged */
750         int                     last;   /* last byte offset logged */
751         static const short      offsets[] = {   /* table of offsets */
752                 offsetof(xfs_inobt_block_t, bb_magic),
753                 offsetof(xfs_inobt_block_t, bb_level),
754                 offsetof(xfs_inobt_block_t, bb_numrecs),
755                 offsetof(xfs_inobt_block_t, bb_leftsib),
756                 offsetof(xfs_inobt_block_t, bb_rightsib),
757                 sizeof(xfs_inobt_block_t)
758         };
759
760         xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last);
761         xfs_trans_log_buf(tp, bp, first, last);
762 }
763
764 /*
765  * Log keys from a btree block (nonleaf).
766  */
767 STATIC void
768 xfs_inobt_log_keys(
769         xfs_btree_cur_t         *cur,   /* btree cursor */
770         xfs_buf_t               *bp,    /* buffer containing btree block */
771         int                     kfirst, /* index of first key to log */
772         int                     klast)  /* index of last key to log */
773 {
774         xfs_inobt_block_t       *block; /* btree block to log from */
775         int                     first;  /* first byte offset logged */
776         xfs_inobt_key_t         *kp;    /* key pointer in btree block */
777         int                     last;   /* last byte offset logged */
778
779         block = XFS_BUF_TO_INOBT_BLOCK(bp);
780         kp = XFS_INOBT_KEY_ADDR(block, 1, cur);
781         first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
782         last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
783         xfs_trans_log_buf(cur->bc_tp, bp, first, last);
784 }
785
786 /*
787  * Log block pointer fields from a btree block (nonleaf).
788  */
789 STATIC void
790 xfs_inobt_log_ptrs(
791         xfs_btree_cur_t         *cur,   /* btree cursor */
792         xfs_buf_t               *bp,    /* buffer containing btree block */
793         int                     pfirst, /* index of first pointer to log */
794         int                     plast)  /* index of last pointer to log */
795 {
796         xfs_inobt_block_t       *block; /* btree block to log from */
797         int                     first;  /* first byte offset logged */
798         int                     last;   /* last byte offset logged */
799         xfs_inobt_ptr_t         *pp;    /* block-pointer pointer in btree blk */
800
801         block = XFS_BUF_TO_INOBT_BLOCK(bp);
802         pp = XFS_INOBT_PTR_ADDR(block, 1, cur);
803         first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
804         last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
805         xfs_trans_log_buf(cur->bc_tp, bp, first, last);
806 }
807
808 /*
809  * Log records from a btree block (leaf).
810  */
811 STATIC void
812 xfs_inobt_log_recs(
813         xfs_btree_cur_t         *cur,   /* btree cursor */
814         xfs_buf_t               *bp,    /* buffer containing btree block */
815         int                     rfirst, /* index of first record to log */
816         int                     rlast)  /* index of last record to log */
817 {
818         xfs_inobt_block_t       *block; /* btree block to log from */
819         int                     first;  /* first byte offset logged */
820         int                     last;   /* last byte offset logged */
821         xfs_inobt_rec_t         *rp;    /* record pointer for btree block */
822
823         block = XFS_BUF_TO_INOBT_BLOCK(bp);
824         rp = XFS_INOBT_REC_ADDR(block, 1, cur);
825         first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
826         last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
827         xfs_trans_log_buf(cur->bc_tp, bp, first, last);
828 }
829
830 /*
831  * Move 1 record left from cur/level if possible.
832  * Update cur to reflect the new path.
833  */
834 STATIC int                              /* error */
835 xfs_inobt_lshift(
836         xfs_btree_cur_t         *cur,   /* btree cursor */
837         int                     level,  /* level to shift record on */
838         int                     *stat)  /* success/failure */
839 {
840         int                     error;  /* error return value */
841 #ifdef DEBUG
842         int                     i;      /* loop index */
843 #endif
844         xfs_inobt_key_t         key;    /* key value for leaf level upward */
845         xfs_buf_t               *lbp;   /* buffer for left neighbor block */
846         xfs_inobt_block_t       *left;  /* left neighbor btree block */
847         xfs_inobt_key_t         *lkp=NULL;      /* key pointer for left block */
848         xfs_inobt_ptr_t         *lpp;   /* address pointer for left block */
849         xfs_inobt_rec_t         *lrp=NULL;      /* record pointer for left block */
850         int                     nrec;   /* new number of left block entries */
851         xfs_buf_t               *rbp;   /* buffer for right (current) block */
852         xfs_inobt_block_t       *right; /* right (current) btree block */
853         xfs_inobt_key_t         *rkp=NULL;      /* key pointer for right block */
854         xfs_inobt_ptr_t         *rpp=NULL;      /* address pointer for right block */
855         xfs_inobt_rec_t         *rrp=NULL;      /* record pointer for right block */
856
857         /*
858          * Set up variables for this block as "right".
859          */
860         rbp = cur->bc_bufs[level];
861         right = XFS_BUF_TO_INOBT_BLOCK(rbp);
862 #ifdef DEBUG
863         if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
864                 return error;
865 #endif
866         /*
867          * If we've got no left sibling then we can't shift an entry left.
868          */
869         if (be32_to_cpu(right->bb_leftsib) == NULLAGBLOCK) {
870                 *stat = 0;
871                 return 0;
872         }
873         /*
874          * If the cursor entry is the one that would be moved, don't
875          * do it... it's too complicated.
876          */
877         if (cur->bc_ptrs[level] <= 1) {
878                 *stat = 0;
879                 return 0;
880         }
881         /*
882          * Set up the left neighbor as "left".
883          */
884         if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
885                         cur->bc_private.a.agno, be32_to_cpu(right->bb_leftsib),
886                         0, &lbp, XFS_INO_BTREE_REF)))
887                 return error;
888         left = XFS_BUF_TO_INOBT_BLOCK(lbp);
889         if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
890                 return error;
891         /*
892          * If it's full, it can't take another entry.
893          */
894         if (be16_to_cpu(left->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
895                 *stat = 0;
896                 return 0;
897         }
898         nrec = be16_to_cpu(left->bb_numrecs) + 1;
899         /*
900          * If non-leaf, copy a key and a ptr to the left block.
901          */
902         if (level > 0) {
903                 lkp = XFS_INOBT_KEY_ADDR(left, nrec, cur);
904                 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
905                 *lkp = *rkp;
906                 xfs_inobt_log_keys(cur, lbp, nrec, nrec);
907                 lpp = XFS_INOBT_PTR_ADDR(left, nrec, cur);
908                 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
909 #ifdef DEBUG
910                 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
911                         return error;
912 #endif
913                 *lpp = *rpp;
914                 xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
915         }
916         /*
917          * If leaf, copy a record to the left block.
918          */
919         else {
920                 lrp = XFS_INOBT_REC_ADDR(left, nrec, cur);
921                 rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
922                 *lrp = *rrp;
923                 xfs_inobt_log_recs(cur, lbp, nrec, nrec);
924         }
925         /*
926          * Bump and log left's numrecs, decrement and log right's numrecs.
927          */
928         be16_add_cpu(&left->bb_numrecs, 1);
929         xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
930 #ifdef DEBUG
931         if (level > 0)
932                 xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
933         else
934                 xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp);
935 #endif
936         be16_add_cpu(&right->bb_numrecs, -1);
937         xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
938         /*
939          * Slide the contents of right down one entry.
940          */
941         if (level > 0) {
942 #ifdef DEBUG
943                 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
944                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i + 1]),
945                                         level)))
946                                 return error;
947                 }
948 #endif
949                 memmove(rkp, rkp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
950                 memmove(rpp, rpp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
951                 xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
952                 xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
953         } else {
954                 memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
955                 xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
956                 key.ir_startino = rrp->ir_startino;
957                 rkp = &key;
958         }
959         /*
960          * Update the parent key values of right.
961          */
962         if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)rkp, level + 1)))
963                 return error;
964         /*
965          * Slide the cursor value left one.
966          */
967         cur->bc_ptrs[level]--;
968         *stat = 1;
969         return 0;
970 }
971
972 /*
973  * Allocate a new root block, fill it in.
974  */
975 STATIC int                              /* error */
976 xfs_inobt_newroot(
977         xfs_btree_cur_t         *cur,   /* btree cursor */
978         int                     *stat)  /* success/failure */
979 {
980         xfs_agi_t               *agi;   /* a.g. inode header */
981         xfs_alloc_arg_t         args;   /* allocation argument structure */
982         xfs_inobt_block_t       *block; /* one half of the old root block */
983         xfs_buf_t               *bp;    /* buffer containing block */
984         int                     error;  /* error return value */
985         xfs_inobt_key_t         *kp;    /* btree key pointer */
986         xfs_agblock_t           lbno;   /* left block number */
987         xfs_buf_t               *lbp;   /* left buffer pointer */
988         xfs_inobt_block_t       *left;  /* left btree block */
989         xfs_buf_t               *nbp;   /* new (root) buffer */
990         xfs_inobt_block_t       *new;   /* new (root) btree block */
991         int                     nptr;   /* new value for key index, 1 or 2 */
992         xfs_inobt_ptr_t         *pp;    /* btree address pointer */
993         xfs_agblock_t           rbno;   /* right block number */
994         xfs_buf_t               *rbp;   /* right buffer pointer */
995         xfs_inobt_block_t       *right; /* right btree block */
996         xfs_inobt_rec_t         *rp;    /* btree record pointer */
997
998         ASSERT(cur->bc_nlevels < XFS_IN_MAXLEVELS(cur->bc_mp));
999
1000         /*
1001          * Get a block & a buffer.
1002          */
1003         agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
1004         args.tp = cur->bc_tp;
1005         args.mp = cur->bc_mp;
1006         args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno,
1007                 be32_to_cpu(agi->agi_root));
1008         args.mod = args.minleft = args.alignment = args.total = args.wasdel =
1009                 args.isfl = args.userdata = args.minalignslop = 0;
1010         args.minlen = args.maxlen = args.prod = 1;
1011         args.type = XFS_ALLOCTYPE_NEAR_BNO;
1012         if ((error = xfs_alloc_vextent(&args)))
1013                 return error;
1014         /*
1015          * None available, we fail.
1016          */
1017         if (args.fsbno == NULLFSBLOCK) {
1018                 *stat = 0;
1019                 return 0;
1020         }
1021         ASSERT(args.len == 1);
1022         nbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
1023         new = XFS_BUF_TO_INOBT_BLOCK(nbp);
1024         /*
1025          * Set the root data in the a.g. inode structure.
1026          */
1027         agi->agi_root = cpu_to_be32(args.agbno);
1028         be32_add_cpu(&agi->agi_level, 1);
1029         xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp,
1030                 XFS_AGI_ROOT | XFS_AGI_LEVEL);
1031         /*
1032          * At the previous root level there are now two blocks: the old
1033          * root, and the new block generated when it was split.
1034          * We don't know which one the cursor is pointing at, so we
1035          * set up variables "left" and "right" for each case.
1036          */
1037         bp = cur->bc_bufs[cur->bc_nlevels - 1];
1038         block = XFS_BUF_TO_INOBT_BLOCK(bp);
1039 #ifdef DEBUG
1040         if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp)))
1041                 return error;
1042 #endif
1043         if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) {
1044                 /*
1045                  * Our block is left, pick up the right block.
1046                  */
1047                 lbp = bp;
1048                 lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
1049                 left = block;
1050                 rbno = be32_to_cpu(left->bb_rightsib);
1051                 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
1052                                 rbno, 0, &rbp, XFS_INO_BTREE_REF)))
1053                         return error;
1054                 bp = rbp;
1055                 right = XFS_BUF_TO_INOBT_BLOCK(rbp);
1056                 if ((error = xfs_btree_check_sblock(cur, right,
1057                                 cur->bc_nlevels - 1, rbp)))
1058                         return error;
1059                 nptr = 1;
1060         } else {
1061                 /*
1062                  * Our block is right, pick up the left block.
1063                  */
1064                 rbp = bp;
1065                 rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp));
1066                 right = block;
1067                 lbno = be32_to_cpu(right->bb_leftsib);
1068                 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
1069                                 lbno, 0, &lbp, XFS_INO_BTREE_REF)))
1070                         return error;
1071                 bp = lbp;
1072                 left = XFS_BUF_TO_INOBT_BLOCK(lbp);
1073                 if ((error = xfs_btree_check_sblock(cur, left,
1074                                 cur->bc_nlevels - 1, lbp)))
1075                         return error;
1076                 nptr = 2;
1077         }
1078         /*
1079          * Fill in the new block's btree header and log it.
1080          */
1081         new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
1082         new->bb_level = cpu_to_be16(cur->bc_nlevels);
1083         new->bb_numrecs = cpu_to_be16(2);
1084         new->bb_leftsib = cpu_to_be32(NULLAGBLOCK);
1085         new->bb_rightsib = cpu_to_be32(NULLAGBLOCK);
1086         xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS);
1087         ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK);
1088         /*
1089          * Fill in the key data in the new root.
1090          */
1091         kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
1092         if (be16_to_cpu(left->bb_level) > 0) {
1093                 kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur);
1094                 kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur);
1095         } else {
1096                 rp = XFS_INOBT_REC_ADDR(left, 1, cur);
1097                 kp[0].ir_startino = rp->ir_startino;
1098                 rp = XFS_INOBT_REC_ADDR(right, 1, cur);
1099                 kp[1].ir_startino = rp->ir_startino;
1100         }
1101         xfs_inobt_log_keys(cur, nbp, 1, 2);
1102         /*
1103          * Fill in the pointer data in the new root.
1104          */
1105         pp = XFS_INOBT_PTR_ADDR(new, 1, cur);
1106         pp[0] = cpu_to_be32(lbno);
1107         pp[1] = cpu_to_be32(rbno);
1108         xfs_inobt_log_ptrs(cur, nbp, 1, 2);
1109         /*
1110          * Fix up the cursor.
1111          */
1112         xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
1113         cur->bc_ptrs[cur->bc_nlevels] = nptr;
1114         cur->bc_nlevels++;
1115         *stat = 1;
1116         return 0;
1117 }
1118
1119 /*
1120  * Move 1 record right from cur/level if possible.
1121  * Update cur to reflect the new path.
1122  */
1123 STATIC int                              /* error */
1124 xfs_inobt_rshift(
1125         xfs_btree_cur_t         *cur,   /* btree cursor */
1126         int                     level,  /* level to shift record on */
1127         int                     *stat)  /* success/failure */
1128 {
1129         int                     error;  /* error return value */
1130         int                     i;      /* loop index */
1131         xfs_inobt_key_t         key;    /* key value for leaf level upward */
1132         xfs_buf_t               *lbp;   /* buffer for left (current) block */
1133         xfs_inobt_block_t       *left;  /* left (current) btree block */
1134         xfs_inobt_key_t         *lkp;   /* key pointer for left block */
1135         xfs_inobt_ptr_t         *lpp;   /* address pointer for left block */
1136         xfs_inobt_rec_t         *lrp;   /* record pointer for left block */
1137         xfs_buf_t               *rbp;   /* buffer for right neighbor block */
1138         xfs_inobt_block_t       *right; /* right neighbor btree block */
1139         xfs_inobt_key_t         *rkp;   /* key pointer for right block */
1140         xfs_inobt_ptr_t         *rpp;   /* address pointer for right block */
1141         xfs_inobt_rec_t         *rrp=NULL;      /* record pointer for right block */
1142         xfs_btree_cur_t         *tcur;  /* temporary cursor */
1143
1144         /*
1145          * Set up variables for this block as "left".
1146          */
1147         lbp = cur->bc_bufs[level];
1148         left = XFS_BUF_TO_INOBT_BLOCK(lbp);
1149 #ifdef DEBUG
1150         if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
1151                 return error;
1152 #endif
1153         /*
1154          * If we've got no right sibling then we can't shift an entry right.
1155          */
1156         if (be32_to_cpu(left->bb_rightsib) == NULLAGBLOCK) {
1157                 *stat = 0;
1158                 return 0;
1159         }
1160         /*
1161          * If the cursor entry is the one that would be moved, don't
1162          * do it... it's too complicated.
1163          */
1164         if (cur->bc_ptrs[level] >= be16_to_cpu(left->bb_numrecs)) {
1165                 *stat = 0;
1166                 return 0;
1167         }
1168         /*
1169          * Set up the right neighbor as "right".
1170          */
1171         if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
1172                         cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib),
1173                         0, &rbp, XFS_INO_BTREE_REF)))
1174                 return error;
1175         right = XFS_BUF_TO_INOBT_BLOCK(rbp);
1176         if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
1177                 return error;
1178         /*
1179          * If it's full, it can't take another entry.
1180          */
1181         if (be16_to_cpu(right->bb_numrecs) == XFS_INOBT_BLOCK_MAXRECS(level, cur)) {
1182                 *stat = 0;
1183                 return 0;
1184         }
1185         /*
1186          * Make a hole at the start of the right neighbor block, then
1187          * copy the last left block entry to the hole.
1188          */
1189         if (level > 0) {
1190                 lkp = XFS_INOBT_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
1191                 lpp = XFS_INOBT_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
1192                 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
1193                 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
1194 #ifdef DEBUG
1195                 for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
1196                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
1197                                 return error;
1198                 }
1199 #endif
1200                 memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
1201                 memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
1202 #ifdef DEBUG
1203                 if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
1204                         return error;
1205 #endif
1206                 *rkp = *lkp;
1207                 *rpp = *lpp;
1208                 xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
1209                 xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
1210         } else {
1211                 lrp = XFS_INOBT_REC_ADDR(left, be16_to_cpu(left->bb_numrecs), cur);
1212                 rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
1213                 memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
1214                 *rrp = *lrp;
1215                 xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
1216                 key.ir_startino = rrp->ir_startino;
1217                 rkp = &key;
1218         }
1219         /*
1220          * Decrement and log left's numrecs, bump and log right's numrecs.
1221          */
1222         be16_add_cpu(&left->bb_numrecs, -1);
1223         xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS);
1224         be16_add_cpu(&right->bb_numrecs, 1);
1225 #ifdef DEBUG
1226         if (level > 0)
1227                 xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
1228         else
1229                 xfs_btree_check_rec(cur->bc_btnum, rrp, rrp + 1);
1230 #endif
1231         xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS);
1232         /*
1233          * Using a temporary cursor, update the parent key values of the
1234          * block on the right.
1235          */
1236         if ((error = xfs_btree_dup_cursor(cur, &tcur)))
1237                 return error;
1238         xfs_btree_lastrec(tcur, level);
1239         if ((error = xfs_btree_increment(tcur, level, &i)) ||
1240             (error = xfs_btree_updkey(tcur, (union xfs_btree_key *)rkp, level + 1))) {
1241                 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
1242                 return error;
1243         }
1244         xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
1245         *stat = 1;
1246         return 0;
1247 }
1248
1249 /*
1250  * Split cur/level block in half.
1251  * Return new block number and its first record (to be inserted into parent).
1252  */
1253 STATIC int                              /* error */
1254 xfs_inobt_split(
1255         xfs_btree_cur_t         *cur,   /* btree cursor */
1256         int                     level,  /* level to split */
1257         xfs_agblock_t           *bnop,  /* output: block number allocated */
1258         xfs_inobt_key_t         *keyp,  /* output: first key of new block */
1259         xfs_btree_cur_t         **curp, /* output: new cursor */
1260         int                     *stat)  /* success/failure */
1261 {
1262         xfs_alloc_arg_t         args;   /* allocation argument structure */
1263         int                     error;  /* error return value */
1264         int                     i;      /* loop index/record number */
1265         xfs_agblock_t           lbno;   /* left (current) block number */
1266         xfs_buf_t               *lbp;   /* buffer for left block */
1267         xfs_inobt_block_t       *left;  /* left (current) btree block */
1268         xfs_inobt_key_t         *lkp;   /* left btree key pointer */
1269         xfs_inobt_ptr_t         *lpp;   /* left btree address pointer */
1270         xfs_inobt_rec_t         *lrp;   /* left btree record pointer */
1271         xfs_buf_t               *rbp;   /* buffer for right block */
1272         xfs_inobt_block_t       *right; /* right (new) btree block */
1273         xfs_inobt_key_t         *rkp;   /* right btree key pointer */
1274         xfs_inobt_ptr_t         *rpp;   /* right btree address pointer */
1275         xfs_inobt_rec_t         *rrp;   /* right btree record pointer */
1276
1277         /*
1278          * Set up left block (current one).
1279          */
1280         lbp = cur->bc_bufs[level];
1281         args.tp = cur->bc_tp;
1282         args.mp = cur->bc_mp;
1283         lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp));
1284         /*
1285          * Allocate the new block.
1286          * If we can't do it, we're toast.  Give up.
1287          */
1288         args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, lbno);
1289         args.mod = args.minleft = args.alignment = args.total = args.wasdel =
1290                 args.isfl = args.userdata = args.minalignslop = 0;
1291         args.minlen = args.maxlen = args.prod = 1;
1292         args.type = XFS_ALLOCTYPE_NEAR_BNO;
1293         if ((error = xfs_alloc_vextent(&args)))
1294                 return error;
1295         if (args.fsbno == NULLFSBLOCK) {
1296                 *stat = 0;
1297                 return 0;
1298         }
1299         ASSERT(args.len == 1);
1300         rbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0);
1301         /*
1302          * Set up the new block as "right".
1303          */
1304         right = XFS_BUF_TO_INOBT_BLOCK(rbp);
1305         /*
1306          * "Left" is the current (according to the cursor) block.
1307          */
1308         left = XFS_BUF_TO_INOBT_BLOCK(lbp);
1309 #ifdef DEBUG
1310         if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
1311                 return error;
1312 #endif
1313         /*
1314          * Fill in the btree header for the new block.
1315          */
1316         right->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]);
1317         right->bb_level = left->bb_level;
1318         right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2);
1319         /*
1320          * Make sure that if there's an odd number of entries now, that
1321          * each new block will have the same number of entries.
1322          */
1323         if ((be16_to_cpu(left->bb_numrecs) & 1) &&
1324             cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1)
1325                 be16_add_cpu(&right->bb_numrecs, 1);
1326         i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1;
1327         /*
1328          * For non-leaf blocks, copy keys and addresses over to the new block.
1329          */
1330         if (level > 0) {
1331                 lkp = XFS_INOBT_KEY_ADDR(left, i, cur);
1332                 lpp = XFS_INOBT_PTR_ADDR(left, i, cur);
1333                 rkp = XFS_INOBT_KEY_ADDR(right, 1, cur);
1334                 rpp = XFS_INOBT_PTR_ADDR(right, 1, cur);
1335 #ifdef DEBUG
1336                 for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
1337                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
1338                                 return error;
1339                 }
1340 #endif
1341                 memcpy(rkp, lkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
1342                 memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
1343                 xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1344                 xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1345                 *keyp = *rkp;
1346         }
1347         /*
1348          * For leaf blocks, copy records over to the new block.
1349          */
1350         else {
1351                 lrp = XFS_INOBT_REC_ADDR(left, i, cur);
1352                 rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
1353                 memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
1354                 xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
1355                 keyp->ir_startino = rrp->ir_startino;
1356         }
1357         /*
1358          * Find the left block number by looking in the buffer.
1359          * Adjust numrecs, sibling pointers.
1360          */
1361         be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
1362         right->bb_rightsib = left->bb_rightsib;
1363         left->bb_rightsib = cpu_to_be32(args.agbno);
1364         right->bb_leftsib = cpu_to_be32(lbno);
1365         xfs_inobt_log_block(args.tp, rbp, XFS_BB_ALL_BITS);
1366         xfs_inobt_log_block(args.tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
1367         /*
1368          * If there's a block to the new block's right, make that block
1369          * point back to right instead of to left.
1370          */
1371         if (be32_to_cpu(right->bb_rightsib) != NULLAGBLOCK) {
1372                 xfs_inobt_block_t       *rrblock;       /* rr btree block */
1373                 xfs_buf_t               *rrbp;          /* buffer for rrblock */
1374
1375                 if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno,
1376                                 be32_to_cpu(right->bb_rightsib), 0, &rrbp,
1377                                 XFS_INO_BTREE_REF)))
1378                         return error;
1379                 rrblock = XFS_BUF_TO_INOBT_BLOCK(rrbp);
1380                 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
1381                         return error;
1382                 rrblock->bb_leftsib = cpu_to_be32(args.agbno);
1383                 xfs_inobt_log_block(args.tp, rrbp, XFS_BB_LEFTSIB);
1384         }
1385         /*
1386          * If the cursor is really in the right block, move it there.
1387          * If it's just pointing past the last entry in left, then we'll
1388          * insert there, so don't change anything in that case.
1389          */
1390         if (cur->bc_ptrs[level] > be16_to_cpu(left->bb_numrecs) + 1) {
1391                 xfs_btree_setbuf(cur, level, rbp);
1392                 cur->bc_ptrs[level] -= be16_to_cpu(left->bb_numrecs);
1393         }
1394         /*
1395          * If there are more levels, we'll need another cursor which refers
1396          * the right block, no matter where this cursor was.
1397          */
1398         if (level + 1 < cur->bc_nlevels) {
1399                 if ((error = xfs_btree_dup_cursor(cur, curp)))
1400                         return error;
1401                 (*curp)->bc_ptrs[level + 1]++;
1402         }
1403         *bnop = args.agbno;
1404         *stat = 1;
1405         return 0;
1406 }
1407
1408 /*
1409  * Externally visible routines.
1410  */
1411
1412 /*
1413  * Delete the record pointed to by cur.
1414  * The cursor refers to the place where the record was (could be inserted)
1415  * when the operation returns.
1416  */
1417 int                                     /* error */
1418 xfs_inobt_delete(
1419         xfs_btree_cur_t *cur,           /* btree cursor */
1420         int             *stat)          /* success/failure */
1421 {
1422         int             error;
1423         int             i;              /* result code */
1424         int             level;          /* btree level */
1425
1426         /*
1427          * Go up the tree, starting at leaf level.
1428          * If 2 is returned then a join was done; go to the next level.
1429          * Otherwise we are done.
1430          */
1431         for (level = 0, i = 2; i == 2; level++) {
1432                 if ((error = xfs_inobt_delrec(cur, level, &i)))
1433                         return error;
1434         }
1435         if (i == 0) {
1436                 for (level = 1; level < cur->bc_nlevels; level++) {
1437                         if (cur->bc_ptrs[level] == 0) {
1438                                 if ((error = xfs_btree_decrement(cur, level, &i)))
1439                                         return error;
1440                                 break;
1441                         }
1442                 }
1443         }
1444         *stat = i;
1445         return 0;
1446 }
1447
1448
1449 /*
1450  * Get the data from the pointed-to record.
1451  */
1452 int                                     /* error */
1453 xfs_inobt_get_rec(
1454         xfs_btree_cur_t         *cur,   /* btree cursor */
1455         xfs_agino_t             *ino,   /* output: starting inode of chunk */
1456         __int32_t               *fcnt,  /* output: number of free inodes */
1457         xfs_inofree_t           *free,  /* output: free inode mask */
1458         int                     *stat)  /* output: success/failure */
1459 {
1460         xfs_inobt_block_t       *block; /* btree block */
1461         xfs_buf_t               *bp;    /* buffer containing btree block */
1462 #ifdef DEBUG
1463         int                     error;  /* error return value */
1464 #endif
1465         int                     ptr;    /* record number */
1466         xfs_inobt_rec_t         *rec;   /* record data */
1467
1468         bp = cur->bc_bufs[0];
1469         ptr = cur->bc_ptrs[0];
1470         block = XFS_BUF_TO_INOBT_BLOCK(bp);
1471 #ifdef DEBUG
1472         if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))
1473                 return error;
1474 #endif
1475         /*
1476          * Off the right end or left end, return failure.
1477          */
1478         if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
1479                 *stat = 0;
1480                 return 0;
1481         }
1482         /*
1483          * Point to the record and extract its data.
1484          */
1485         rec = XFS_INOBT_REC_ADDR(block, ptr, cur);
1486         *ino = be32_to_cpu(rec->ir_startino);
1487         *fcnt = be32_to_cpu(rec->ir_freecount);
1488         *free = be64_to_cpu(rec->ir_free);
1489         *stat = 1;
1490         return 0;
1491 }
1492
1493 /*
1494  * Insert the current record at the point referenced by cur.
1495  * The cursor may be inconsistent on return if splits have been done.
1496  */
1497 int                                     /* error */
1498 xfs_inobt_insert(
1499         xfs_btree_cur_t *cur,           /* btree cursor */
1500         int             *stat)          /* success/failure */
1501 {
1502         int             error;          /* error return value */
1503         int             i;              /* result value, 0 for failure */
1504         int             level;          /* current level number in btree */
1505         xfs_agblock_t   nbno;           /* new block number (split result) */
1506         xfs_btree_cur_t *ncur;          /* new cursor (split result) */
1507         xfs_inobt_rec_t nrec;           /* record being inserted this level */
1508         xfs_btree_cur_t *pcur;          /* previous level's cursor */
1509
1510         level = 0;
1511         nbno = NULLAGBLOCK;
1512         nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
1513         nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);
1514         nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
1515         ncur = NULL;
1516         pcur = cur;
1517         /*
1518          * Loop going up the tree, starting at the leaf level.
1519          * Stop when we don't get a split block, that must mean that
1520          * the insert is finished with this level.
1521          */
1522         do {
1523                 /*
1524                  * Insert nrec/nbno into this level of the tree.
1525                  * Note if we fail, nbno will be null.
1526                  */
1527                 if ((error = xfs_inobt_insrec(pcur, level++, &nbno, &nrec, &ncur,
1528                                 &i))) {
1529                         if (pcur != cur)
1530                                 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
1531                         return error;
1532                 }
1533                 /*
1534                  * See if the cursor we just used is trash.
1535                  * Can't trash the caller's cursor, but otherwise we should
1536                  * if ncur is a new cursor or we're about to be done.
1537                  */
1538                 if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {
1539                         cur->bc_nlevels = pcur->bc_nlevels;
1540                         xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
1541                 }
1542                 /*
1543                  * If we got a new cursor, switch to it.
1544                  */
1545                 if (ncur) {
1546                         pcur = ncur;
1547                         ncur = NULL;
1548                 }
1549         } while (nbno != NULLAGBLOCK);
1550         *stat = i;
1551         return 0;
1552 }
1553
1554 /*
1555  * Update the record referred to by cur, to the value given
1556  * by [ino, fcnt, free].
1557  * This either works (return 0) or gets an EFSCORRUPTED error.
1558  */
1559 int                                     /* error */
1560 xfs_inobt_update(
1561         xfs_btree_cur_t         *cur,   /* btree cursor */
1562         xfs_agino_t             ino,    /* starting inode of chunk */
1563         __int32_t               fcnt,   /* free inode count */
1564         xfs_inofree_t           free)   /* free inode mask */
1565 {
1566         xfs_inobt_block_t       *block; /* btree block to update */
1567         xfs_buf_t               *bp;    /* buffer containing btree block */
1568         int                     error;  /* error return value */
1569         int                     ptr;    /* current record number (updating) */
1570         xfs_inobt_rec_t         *rp;    /* pointer to updated record */
1571
1572         /*
1573          * Pick up the current block.
1574          */
1575         bp = cur->bc_bufs[0];
1576         block = XFS_BUF_TO_INOBT_BLOCK(bp);
1577 #ifdef DEBUG
1578         if ((error = xfs_btree_check_sblock(cur, block, 0, bp)))
1579                 return error;
1580 #endif
1581         /*
1582          * Get the address of the rec to be updated.
1583          */
1584         ptr = cur->bc_ptrs[0];
1585         rp = XFS_INOBT_REC_ADDR(block, ptr, cur);
1586         /*
1587          * Fill in the new contents and log them.
1588          */
1589         rp->ir_startino = cpu_to_be32(ino);
1590         rp->ir_freecount = cpu_to_be32(fcnt);
1591         rp->ir_free = cpu_to_be64(free);
1592         xfs_inobt_log_recs(cur, bp, ptr, ptr);
1593         /*
1594          * Updating first record in leaf. Pass new key value up to our parent.
1595          */
1596         if (ptr == 1) {
1597                 xfs_inobt_key_t key;    /* key containing [ino] */
1598
1599                 key.ir_startino = cpu_to_be32(ino);
1600                 if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, 1)))
1601                         return error;
1602         }
1603         return 0;
1604 }
1605
1606 STATIC struct xfs_btree_cur *
1607 xfs_inobt_dup_cursor(
1608         struct xfs_btree_cur    *cur)
1609 {
1610         return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp,
1611                         cur->bc_private.a.agbp, cur->bc_private.a.agno);
1612 }
1613
1614 STATIC int
1615 xfs_inobt_get_maxrecs(
1616         struct xfs_btree_cur    *cur,
1617         int                     level)
1618 {
1619         return cur->bc_mp->m_inobt_mxr[level != 0];
1620 }
1621
1622 STATIC void
1623 xfs_inobt_init_key_from_rec(
1624         union xfs_btree_key     *key,
1625         union xfs_btree_rec     *rec)
1626 {
1627         key->inobt.ir_startino = rec->inobt.ir_startino;
1628 }
1629
1630 /*
1631  * intial value of ptr for lookup
1632  */
1633 STATIC void
1634 xfs_inobt_init_ptr_from_cur(
1635         struct xfs_btree_cur    *cur,
1636         union xfs_btree_ptr     *ptr)
1637 {
1638         struct xfs_agi          *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
1639
1640         ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno));
1641
1642         ptr->s = agi->agi_root;
1643 }
1644
1645 STATIC __int64_t
1646 xfs_inobt_key_diff(
1647         struct xfs_btree_cur    *cur,
1648         union xfs_btree_key     *key)
1649 {
1650         return (__int64_t)be32_to_cpu(key->inobt.ir_startino) -
1651                           cur->bc_rec.i.ir_startino;
1652 }
1653
1654 #ifdef XFS_BTREE_TRACE
1655 ktrace_t        *xfs_inobt_trace_buf;
1656
1657 STATIC void
1658 xfs_inobt_trace_enter(
1659         struct xfs_btree_cur    *cur,
1660         const char              *func,
1661         char                    *s,
1662         int                     type,
1663         int                     line,
1664         __psunsigned_t          a0,
1665         __psunsigned_t          a1,
1666         __psunsigned_t          a2,
1667         __psunsigned_t          a3,
1668         __psunsigned_t          a4,
1669         __psunsigned_t          a5,
1670         __psunsigned_t          a6,
1671         __psunsigned_t          a7,
1672         __psunsigned_t          a8,
1673         __psunsigned_t          a9,
1674         __psunsigned_t          a10)
1675 {
1676         ktrace_enter(xfs_inobt_trace_buf, (void *)(__psint_t)type,
1677                 (void *)func, (void *)s, NULL, (void *)cur,
1678                 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
1679                 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
1680                 (void *)a8, (void *)a9, (void *)a10);
1681 }
1682
1683 STATIC void
1684 xfs_inobt_trace_cursor(
1685         struct xfs_btree_cur    *cur,
1686         __uint32_t              *s0,
1687         __uint64_t              *l0,
1688         __uint64_t              *l1)
1689 {
1690         *s0 = cur->bc_private.a.agno;
1691         *l0 = cur->bc_rec.i.ir_startino;
1692         *l1 = cur->bc_rec.i.ir_free;
1693 }
1694
1695 STATIC void
1696 xfs_inobt_trace_key(
1697         struct xfs_btree_cur    *cur,
1698         union xfs_btree_key     *key,
1699         __uint64_t              *l0,
1700         __uint64_t              *l1)
1701 {
1702         *l0 = be32_to_cpu(key->inobt.ir_startino);
1703         *l1 = 0;
1704 }
1705
1706 STATIC void
1707 xfs_inobt_trace_record(
1708         struct xfs_btree_cur    *cur,
1709         union xfs_btree_rec     *rec,
1710         __uint64_t              *l0,
1711         __uint64_t              *l1,
1712         __uint64_t              *l2)
1713 {
1714         *l0 = be32_to_cpu(rec->inobt.ir_startino);
1715         *l1 = be32_to_cpu(rec->inobt.ir_freecount);
1716         *l2 = be64_to_cpu(rec->inobt.ir_free);
1717 }
1718 #endif /* XFS_BTREE_TRACE */
1719
1720 static const struct xfs_btree_ops xfs_inobt_ops = {
1721         .rec_len                = sizeof(xfs_inobt_rec_t),
1722         .key_len                = sizeof(xfs_inobt_key_t),
1723
1724         .dup_cursor             = xfs_inobt_dup_cursor,
1725         .get_maxrecs            = xfs_inobt_get_maxrecs,
1726         .init_key_from_rec      = xfs_inobt_init_key_from_rec,
1727         .init_ptr_from_cur      = xfs_inobt_init_ptr_from_cur,
1728         .key_diff               = xfs_inobt_key_diff,
1729
1730 #ifdef XFS_BTREE_TRACE
1731         .trace_enter            = xfs_inobt_trace_enter,
1732         .trace_cursor           = xfs_inobt_trace_cursor,
1733         .trace_key              = xfs_inobt_trace_key,
1734         .trace_record           = xfs_inobt_trace_record,
1735 #endif
1736 };
1737
1738 /*
1739  * Allocate a new inode btree cursor.
1740  */
1741 struct xfs_btree_cur *                          /* new inode btree cursor */
1742 xfs_inobt_init_cursor(
1743         struct xfs_mount        *mp,            /* file system mount point */
1744         struct xfs_trans        *tp,            /* transaction pointer */
1745         struct xfs_buf          *agbp,          /* buffer for agi structure */
1746         xfs_agnumber_t          agno)           /* allocation group number */
1747 {
1748         struct xfs_agi          *agi = XFS_BUF_TO_AGI(agbp);
1749         struct xfs_btree_cur    *cur;
1750
1751         cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
1752
1753         cur->bc_tp = tp;
1754         cur->bc_mp = mp;
1755         cur->bc_nlevels = be32_to_cpu(agi->agi_level);
1756         cur->bc_btnum = XFS_BTNUM_INO;
1757         cur->bc_blocklog = mp->m_sb.sb_blocklog;
1758
1759         cur->bc_ops = &xfs_inobt_ops;
1760
1761         cur->bc_private.a.agbp = agbp;
1762         cur->bc_private.a.agno = agno;
1763
1764         return cur;
1765 }