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