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