ARM: 7759/1: decouple CPU offlining from reboot/shutdown
[sfrench/cifs-2.6.git] / fs / xfs / xfs_btree.c
1 /*
2  * Copyright (c) 2000-2002,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_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_mount.h"
27 #include "xfs_bmap_btree.h"
28 #include "xfs_alloc_btree.h"
29 #include "xfs_ialloc_btree.h"
30 #include "xfs_dinode.h"
31 #include "xfs_inode.h"
32 #include "xfs_inode_item.h"
33 #include "xfs_buf_item.h"
34 #include "xfs_btree.h"
35 #include "xfs_error.h"
36 #include "xfs_trace.h"
37 #include "xfs_cksum.h"
38
39 /*
40  * Cursor allocation zone.
41  */
42 kmem_zone_t     *xfs_btree_cur_zone;
43
44 /*
45  * Btree magic numbers.
46  */
47 static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = {
48         { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC },
49         { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC,
50           XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC }
51 };
52 #define xfs_btree_magic(cur) \
53         xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum]
54
55
56 STATIC int                              /* error (0 or EFSCORRUPTED) */
57 xfs_btree_check_lblock(
58         struct xfs_btree_cur    *cur,   /* btree cursor */
59         struct xfs_btree_block  *block, /* btree long form block pointer */
60         int                     level,  /* level of the btree block */
61         struct xfs_buf          *bp)    /* buffer for block, if any */
62 {
63         int                     lblock_ok = 1; /* block passes checks */
64         struct xfs_mount        *mp;    /* file system mount point */
65
66         mp = cur->bc_mp;
67
68         if (xfs_sb_version_hascrc(&mp->m_sb)) {
69                 lblock_ok = lblock_ok &&
70                         uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid) &&
71                         block->bb_u.l.bb_blkno == cpu_to_be64(
72                                 bp ? bp->b_bn : XFS_BUF_DADDR_NULL);
73         }
74
75         lblock_ok = lblock_ok &&
76                 be32_to_cpu(block->bb_magic) == xfs_btree_magic(cur) &&
77                 be16_to_cpu(block->bb_level) == level &&
78                 be16_to_cpu(block->bb_numrecs) <=
79                         cur->bc_ops->get_maxrecs(cur, level) &&
80                 block->bb_u.l.bb_leftsib &&
81                 (block->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO) ||
82                  XFS_FSB_SANITY_CHECK(mp,
83                         be64_to_cpu(block->bb_u.l.bb_leftsib))) &&
84                 block->bb_u.l.bb_rightsib &&
85                 (block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO) ||
86                  XFS_FSB_SANITY_CHECK(mp,
87                         be64_to_cpu(block->bb_u.l.bb_rightsib)));
88
89         if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp,
90                         XFS_ERRTAG_BTREE_CHECK_LBLOCK,
91                         XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
92                 if (bp)
93                         trace_xfs_btree_corrupt(bp, _RET_IP_);
94                 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
95                 return XFS_ERROR(EFSCORRUPTED);
96         }
97         return 0;
98 }
99
100 STATIC int                              /* error (0 or EFSCORRUPTED) */
101 xfs_btree_check_sblock(
102         struct xfs_btree_cur    *cur,   /* btree cursor */
103         struct xfs_btree_block  *block, /* btree short form block pointer */
104         int                     level,  /* level of the btree block */
105         struct xfs_buf          *bp)    /* buffer containing block */
106 {
107         struct xfs_mount        *mp;    /* file system mount point */
108         struct xfs_buf          *agbp;  /* buffer for ag. freespace struct */
109         struct xfs_agf          *agf;   /* ag. freespace structure */
110         xfs_agblock_t           agflen; /* native ag. freespace length */
111         int                     sblock_ok = 1; /* block passes checks */
112
113         mp = cur->bc_mp;
114         agbp = cur->bc_private.a.agbp;
115         agf = XFS_BUF_TO_AGF(agbp);
116         agflen = be32_to_cpu(agf->agf_length);
117
118         if (xfs_sb_version_hascrc(&mp->m_sb)) {
119                 sblock_ok = sblock_ok &&
120                         uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid) &&
121                         block->bb_u.s.bb_blkno == cpu_to_be64(
122                                 bp ? bp->b_bn : XFS_BUF_DADDR_NULL);
123         }
124
125         sblock_ok = sblock_ok &&
126                 be32_to_cpu(block->bb_magic) == xfs_btree_magic(cur) &&
127                 be16_to_cpu(block->bb_level) == level &&
128                 be16_to_cpu(block->bb_numrecs) <=
129                         cur->bc_ops->get_maxrecs(cur, level) &&
130                 (block->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK) ||
131                  be32_to_cpu(block->bb_u.s.bb_leftsib) < agflen) &&
132                 block->bb_u.s.bb_leftsib &&
133                 (block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK) ||
134                  be32_to_cpu(block->bb_u.s.bb_rightsib) < agflen) &&
135                 block->bb_u.s.bb_rightsib;
136
137         if (unlikely(XFS_TEST_ERROR(!sblock_ok, mp,
138                         XFS_ERRTAG_BTREE_CHECK_SBLOCK,
139                         XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
140                 if (bp)
141                         trace_xfs_btree_corrupt(bp, _RET_IP_);
142                 XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
143                 return XFS_ERROR(EFSCORRUPTED);
144         }
145         return 0;
146 }
147
148 /*
149  * Debug routine: check that block header is ok.
150  */
151 int
152 xfs_btree_check_block(
153         struct xfs_btree_cur    *cur,   /* btree cursor */
154         struct xfs_btree_block  *block, /* generic btree block pointer */
155         int                     level,  /* level of the btree block */
156         struct xfs_buf          *bp)    /* buffer containing block, if any */
157 {
158         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
159                 return xfs_btree_check_lblock(cur, block, level, bp);
160         else
161                 return xfs_btree_check_sblock(cur, block, level, bp);
162 }
163
164 /*
165  * Check that (long) pointer is ok.
166  */
167 int                                     /* error (0 or EFSCORRUPTED) */
168 xfs_btree_check_lptr(
169         struct xfs_btree_cur    *cur,   /* btree cursor */
170         xfs_dfsbno_t            bno,    /* btree block disk address */
171         int                     level)  /* btree block level */
172 {
173         XFS_WANT_CORRUPTED_RETURN(
174                 level > 0 &&
175                 bno != NULLDFSBNO &&
176                 XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
177         return 0;
178 }
179
180 #ifdef DEBUG
181 /*
182  * Check that (short) pointer is ok.
183  */
184 STATIC int                              /* error (0 or EFSCORRUPTED) */
185 xfs_btree_check_sptr(
186         struct xfs_btree_cur    *cur,   /* btree cursor */
187         xfs_agblock_t           bno,    /* btree block disk address */
188         int                     level)  /* btree block level */
189 {
190         xfs_agblock_t           agblocks = cur->bc_mp->m_sb.sb_agblocks;
191
192         XFS_WANT_CORRUPTED_RETURN(
193                 level > 0 &&
194                 bno != NULLAGBLOCK &&
195                 bno != 0 &&
196                 bno < agblocks);
197         return 0;
198 }
199
200 /*
201  * Check that block ptr is ok.
202  */
203 STATIC int                              /* error (0 or EFSCORRUPTED) */
204 xfs_btree_check_ptr(
205         struct xfs_btree_cur    *cur,   /* btree cursor */
206         union xfs_btree_ptr     *ptr,   /* btree block disk address */
207         int                     index,  /* offset from ptr to check */
208         int                     level)  /* btree block level */
209 {
210         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
211                 return xfs_btree_check_lptr(cur,
212                                 be64_to_cpu((&ptr->l)[index]), level);
213         } else {
214                 return xfs_btree_check_sptr(cur,
215                                 be32_to_cpu((&ptr->s)[index]), level);
216         }
217 }
218 #endif
219
220 /*
221  * Calculate CRC on the whole btree block and stuff it into the
222  * long-form btree header.
223  *
224  * Prior to calculting the CRC, pull the LSN out of the buffer log item and put
225  * it into the buffer so recovery knows what the last modifcation was that made
226  * it to disk.
227  */
228 void
229 xfs_btree_lblock_calc_crc(
230         struct xfs_buf          *bp)
231 {
232         struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
233         struct xfs_buf_log_item *bip = bp->b_fspriv;
234
235         if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
236                 return;
237         if (bip)
238                 block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
239         xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
240                          XFS_BTREE_LBLOCK_CRC_OFF);
241 }
242
243 bool
244 xfs_btree_lblock_verify_crc(
245         struct xfs_buf          *bp)
246 {
247         if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
248                 return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
249                                         XFS_BTREE_LBLOCK_CRC_OFF);
250         return true;
251 }
252
253 /*
254  * Calculate CRC on the whole btree block and stuff it into the
255  * short-form btree header.
256  *
257  * Prior to calculting the CRC, pull the LSN out of the buffer log item and put
258  * it into the buffer so recovery knows what the last modifcation was that made
259  * it to disk.
260  */
261 void
262 xfs_btree_sblock_calc_crc(
263         struct xfs_buf          *bp)
264 {
265         struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
266         struct xfs_buf_log_item *bip = bp->b_fspriv;
267
268         if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
269                 return;
270         if (bip)
271                 block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
272         xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
273                          XFS_BTREE_SBLOCK_CRC_OFF);
274 }
275
276 bool
277 xfs_btree_sblock_verify_crc(
278         struct xfs_buf          *bp)
279 {
280         if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
281                 return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
282                                         XFS_BTREE_SBLOCK_CRC_OFF);
283         return true;
284 }
285
286 /*
287  * Delete the btree cursor.
288  */
289 void
290 xfs_btree_del_cursor(
291         xfs_btree_cur_t *cur,           /* btree cursor */
292         int             error)          /* del because of error */
293 {
294         int             i;              /* btree level */
295
296         /*
297          * Clear the buffer pointers, and release the buffers.
298          * If we're doing this in the face of an error, we
299          * need to make sure to inspect all of the entries
300          * in the bc_bufs array for buffers to be unlocked.
301          * This is because some of the btree code works from
302          * level n down to 0, and if we get an error along
303          * the way we won't have initialized all the entries
304          * down to 0.
305          */
306         for (i = 0; i < cur->bc_nlevels; i++) {
307                 if (cur->bc_bufs[i])
308                         xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]);
309                 else if (!error)
310                         break;
311         }
312         /*
313          * Can't free a bmap cursor without having dealt with the
314          * allocated indirect blocks' accounting.
315          */
316         ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP ||
317                cur->bc_private.b.allocated == 0);
318         /*
319          * Free the cursor.
320          */
321         kmem_zone_free(xfs_btree_cur_zone, cur);
322 }
323
324 /*
325  * Duplicate the btree cursor.
326  * Allocate a new one, copy the record, re-get the buffers.
327  */
328 int                                     /* error */
329 xfs_btree_dup_cursor(
330         xfs_btree_cur_t *cur,           /* input cursor */
331         xfs_btree_cur_t **ncur)         /* output cursor */
332 {
333         xfs_buf_t       *bp;            /* btree block's buffer pointer */
334         int             error;          /* error return value */
335         int             i;              /* level number of btree block */
336         xfs_mount_t     *mp;            /* mount structure for filesystem */
337         xfs_btree_cur_t *new;           /* new cursor value */
338         xfs_trans_t     *tp;            /* transaction pointer, can be NULL */
339
340         tp = cur->bc_tp;
341         mp = cur->bc_mp;
342
343         /*
344          * Allocate a new cursor like the old one.
345          */
346         new = cur->bc_ops->dup_cursor(cur);
347
348         /*
349          * Copy the record currently in the cursor.
350          */
351         new->bc_rec = cur->bc_rec;
352
353         /*
354          * For each level current, re-get the buffer and copy the ptr value.
355          */
356         for (i = 0; i < new->bc_nlevels; i++) {
357                 new->bc_ptrs[i] = cur->bc_ptrs[i];
358                 new->bc_ra[i] = cur->bc_ra[i];
359                 bp = cur->bc_bufs[i];
360                 if (bp) {
361                         error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
362                                                    XFS_BUF_ADDR(bp), mp->m_bsize,
363                                                    0, &bp,
364                                                    cur->bc_ops->buf_ops);
365                         if (error) {
366                                 xfs_btree_del_cursor(new, error);
367                                 *ncur = NULL;
368                                 return error;
369                         }
370                 }
371                 new->bc_bufs[i] = bp;
372         }
373         *ncur = new;
374         return 0;
375 }
376
377 /*
378  * XFS btree block layout and addressing:
379  *
380  * There are two types of blocks in the btree: leaf and non-leaf blocks.
381  *
382  * The leaf record start with a header then followed by records containing
383  * the values.  A non-leaf block also starts with the same header, and
384  * then first contains lookup keys followed by an equal number of pointers
385  * to the btree blocks at the previous level.
386  *
387  *              +--------+-------+-------+-------+-------+-------+-------+
388  * Leaf:        | header | rec 1 | rec 2 | rec 3 | rec 4 | rec 5 | rec N |
389  *              +--------+-------+-------+-------+-------+-------+-------+
390  *
391  *              +--------+-------+-------+-------+-------+-------+-------+
392  * Non-Leaf:    | header | key 1 | key 2 | key N | ptr 1 | ptr 2 | ptr N |
393  *              +--------+-------+-------+-------+-------+-------+-------+
394  *
395  * The header is called struct xfs_btree_block for reasons better left unknown
396  * and comes in different versions for short (32bit) and long (64bit) block
397  * pointers.  The record and key structures are defined by the btree instances
398  * and opaque to the btree core.  The block pointers are simple disk endian
399  * integers, available in a short (32bit) and long (64bit) variant.
400  *
401  * The helpers below calculate the offset of a given record, key or pointer
402  * into a btree block (xfs_btree_*_offset) or return a pointer to the given
403  * record, key or pointer (xfs_btree_*_addr).  Note that all addressing
404  * inside the btree block is done using indices starting at one, not zero!
405  */
406
407 /*
408  * Return size of the btree block header for this btree instance.
409  */
410 static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
411 {
412         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
413                 if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS)
414                         return XFS_BTREE_LBLOCK_CRC_LEN;
415                 return XFS_BTREE_LBLOCK_LEN;
416         }
417         if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS)
418                 return XFS_BTREE_SBLOCK_CRC_LEN;
419         return XFS_BTREE_SBLOCK_LEN;
420 }
421
422 /*
423  * Return size of btree block pointers for this btree instance.
424  */
425 static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur)
426 {
427         return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
428                 sizeof(__be64) : sizeof(__be32);
429 }
430
431 /*
432  * Calculate offset of the n-th record in a btree block.
433  */
434 STATIC size_t
435 xfs_btree_rec_offset(
436         struct xfs_btree_cur    *cur,
437         int                     n)
438 {
439         return xfs_btree_block_len(cur) +
440                 (n - 1) * cur->bc_ops->rec_len;
441 }
442
443 /*
444  * Calculate offset of the n-th key in a btree block.
445  */
446 STATIC size_t
447 xfs_btree_key_offset(
448         struct xfs_btree_cur    *cur,
449         int                     n)
450 {
451         return xfs_btree_block_len(cur) +
452                 (n - 1) * cur->bc_ops->key_len;
453 }
454
455 /*
456  * Calculate offset of the n-th block pointer in a btree block.
457  */
458 STATIC size_t
459 xfs_btree_ptr_offset(
460         struct xfs_btree_cur    *cur,
461         int                     n,
462         int                     level)
463 {
464         return xfs_btree_block_len(cur) +
465                 cur->bc_ops->get_maxrecs(cur, level) * cur->bc_ops->key_len +
466                 (n - 1) * xfs_btree_ptr_len(cur);
467 }
468
469 /*
470  * Return a pointer to the n-th record in the btree block.
471  */
472 STATIC union xfs_btree_rec *
473 xfs_btree_rec_addr(
474         struct xfs_btree_cur    *cur,
475         int                     n,
476         struct xfs_btree_block  *block)
477 {
478         return (union xfs_btree_rec *)
479                 ((char *)block + xfs_btree_rec_offset(cur, n));
480 }
481
482 /*
483  * Return a pointer to the n-th key in the btree block.
484  */
485 STATIC union xfs_btree_key *
486 xfs_btree_key_addr(
487         struct xfs_btree_cur    *cur,
488         int                     n,
489         struct xfs_btree_block  *block)
490 {
491         return (union xfs_btree_key *)
492                 ((char *)block + xfs_btree_key_offset(cur, n));
493 }
494
495 /*
496  * Return a pointer to the n-th block pointer in the btree block.
497  */
498 STATIC union xfs_btree_ptr *
499 xfs_btree_ptr_addr(
500         struct xfs_btree_cur    *cur,
501         int                     n,
502         struct xfs_btree_block  *block)
503 {
504         int                     level = xfs_btree_get_level(block);
505
506         ASSERT(block->bb_level != 0);
507
508         return (union xfs_btree_ptr *)
509                 ((char *)block + xfs_btree_ptr_offset(cur, n, level));
510 }
511
512 /*
513  * Get a the root block which is stored in the inode.
514  *
515  * For now this btree implementation assumes the btree root is always
516  * stored in the if_broot field of an inode fork.
517  */
518 STATIC struct xfs_btree_block *
519 xfs_btree_get_iroot(
520        struct xfs_btree_cur    *cur)
521 {
522        struct xfs_ifork        *ifp;
523
524        ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork);
525        return (struct xfs_btree_block *)ifp->if_broot;
526 }
527
528 /*
529  * Retrieve the block pointer from the cursor at the given level.
530  * This may be an inode btree root or from a buffer.
531  */
532 STATIC struct xfs_btree_block *         /* generic btree block pointer */
533 xfs_btree_get_block(
534         struct xfs_btree_cur    *cur,   /* btree cursor */
535         int                     level,  /* level in btree */
536         struct xfs_buf          **bpp)  /* buffer containing the block */
537 {
538         if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
539             (level == cur->bc_nlevels - 1)) {
540                 *bpp = NULL;
541                 return xfs_btree_get_iroot(cur);
542         }
543
544         *bpp = cur->bc_bufs[level];
545         return XFS_BUF_TO_BLOCK(*bpp);
546 }
547
548 /*
549  * Get a buffer for the block, return it with no data read.
550  * Long-form addressing.
551  */
552 xfs_buf_t *                             /* buffer for fsbno */
553 xfs_btree_get_bufl(
554         xfs_mount_t     *mp,            /* file system mount point */
555         xfs_trans_t     *tp,            /* transaction pointer */
556         xfs_fsblock_t   fsbno,          /* file system block number */
557         uint            lock)           /* lock flags for get_buf */
558 {
559         xfs_buf_t       *bp;            /* buffer pointer (return value) */
560         xfs_daddr_t             d;              /* real disk block address */
561
562         ASSERT(fsbno != NULLFSBLOCK);
563         d = XFS_FSB_TO_DADDR(mp, fsbno);
564         bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
565         ASSERT(!xfs_buf_geterror(bp));
566         return bp;
567 }
568
569 /*
570  * Get a buffer for the block, return it with no data read.
571  * Short-form addressing.
572  */
573 xfs_buf_t *                             /* buffer for agno/agbno */
574 xfs_btree_get_bufs(
575         xfs_mount_t     *mp,            /* file system mount point */
576         xfs_trans_t     *tp,            /* transaction pointer */
577         xfs_agnumber_t  agno,           /* allocation group number */
578         xfs_agblock_t   agbno,          /* allocation group block number */
579         uint            lock)           /* lock flags for get_buf */
580 {
581         xfs_buf_t       *bp;            /* buffer pointer (return value) */
582         xfs_daddr_t             d;              /* real disk block address */
583
584         ASSERT(agno != NULLAGNUMBER);
585         ASSERT(agbno != NULLAGBLOCK);
586         d = XFS_AGB_TO_DADDR(mp, agno, agbno);
587         bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
588         ASSERT(!xfs_buf_geterror(bp));
589         return bp;
590 }
591
592 /*
593  * Check for the cursor referring to the last block at the given level.
594  */
595 int                                     /* 1=is last block, 0=not last block */
596 xfs_btree_islastblock(
597         xfs_btree_cur_t         *cur,   /* btree cursor */
598         int                     level)  /* level to check */
599 {
600         struct xfs_btree_block  *block; /* generic btree block pointer */
601         xfs_buf_t               *bp;    /* buffer containing block */
602
603         block = xfs_btree_get_block(cur, level, &bp);
604         xfs_btree_check_block(cur, block, level, bp);
605         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
606                 return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO);
607         else
608                 return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK);
609 }
610
611 /*
612  * Change the cursor to point to the first record at the given level.
613  * Other levels are unaffected.
614  */
615 STATIC int                              /* success=1, failure=0 */
616 xfs_btree_firstrec(
617         xfs_btree_cur_t         *cur,   /* btree cursor */
618         int                     level)  /* level to change */
619 {
620         struct xfs_btree_block  *block; /* generic btree block pointer */
621         xfs_buf_t               *bp;    /* buffer containing block */
622
623         /*
624          * Get the block pointer for this level.
625          */
626         block = xfs_btree_get_block(cur, level, &bp);
627         xfs_btree_check_block(cur, block, level, bp);
628         /*
629          * It's empty, there is no such record.
630          */
631         if (!block->bb_numrecs)
632                 return 0;
633         /*
634          * Set the ptr value to 1, that's the first record/key.
635          */
636         cur->bc_ptrs[level] = 1;
637         return 1;
638 }
639
640 /*
641  * Change the cursor to point to the last record in the current block
642  * at the given level.  Other levels are unaffected.
643  */
644 STATIC int                              /* success=1, failure=0 */
645 xfs_btree_lastrec(
646         xfs_btree_cur_t         *cur,   /* btree cursor */
647         int                     level)  /* level to change */
648 {
649         struct xfs_btree_block  *block; /* generic btree block pointer */
650         xfs_buf_t               *bp;    /* buffer containing block */
651
652         /*
653          * Get the block pointer for this level.
654          */
655         block = xfs_btree_get_block(cur, level, &bp);
656         xfs_btree_check_block(cur, block, level, bp);
657         /*
658          * It's empty, there is no such record.
659          */
660         if (!block->bb_numrecs)
661                 return 0;
662         /*
663          * Set the ptr value to numrecs, that's the last record/key.
664          */
665         cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs);
666         return 1;
667 }
668
669 /*
670  * Compute first and last byte offsets for the fields given.
671  * Interprets the offsets table, which contains struct field offsets.
672  */
673 void
674 xfs_btree_offsets(
675         __int64_t       fields,         /* bitmask of fields */
676         const short     *offsets,       /* table of field offsets */
677         int             nbits,          /* number of bits to inspect */
678         int             *first,         /* output: first byte offset */
679         int             *last)          /* output: last byte offset */
680 {
681         int             i;              /* current bit number */
682         __int64_t       imask;          /* mask for current bit number */
683
684         ASSERT(fields != 0);
685         /*
686          * Find the lowest bit, so the first byte offset.
687          */
688         for (i = 0, imask = 1LL; ; i++, imask <<= 1) {
689                 if (imask & fields) {
690                         *first = offsets[i];
691                         break;
692                 }
693         }
694         /*
695          * Find the highest bit, so the last byte offset.
696          */
697         for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) {
698                 if (imask & fields) {
699                         *last = offsets[i + 1] - 1;
700                         break;
701                 }
702         }
703 }
704
705 /*
706  * Get a buffer for the block, return it read in.
707  * Long-form addressing.
708  */
709 int
710 xfs_btree_read_bufl(
711         struct xfs_mount        *mp,            /* file system mount point */
712         struct xfs_trans        *tp,            /* transaction pointer */
713         xfs_fsblock_t           fsbno,          /* file system block number */
714         uint                    lock,           /* lock flags for read_buf */
715         struct xfs_buf          **bpp,          /* buffer for fsbno */
716         int                     refval,         /* ref count value for buffer */
717         const struct xfs_buf_ops *ops)
718 {
719         struct xfs_buf          *bp;            /* return value */
720         xfs_daddr_t             d;              /* real disk block address */
721         int                     error;
722
723         ASSERT(fsbno != NULLFSBLOCK);
724         d = XFS_FSB_TO_DADDR(mp, fsbno);
725         error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
726                                    mp->m_bsize, lock, &bp, ops);
727         if (error)
728                 return error;
729         ASSERT(!xfs_buf_geterror(bp));
730         if (bp)
731                 xfs_buf_set_ref(bp, refval);
732         *bpp = bp;
733         return 0;
734 }
735
736 /*
737  * Read-ahead the block, don't wait for it, don't return a buffer.
738  * Long-form addressing.
739  */
740 /* ARGSUSED */
741 void
742 xfs_btree_reada_bufl(
743         struct xfs_mount        *mp,            /* file system mount point */
744         xfs_fsblock_t           fsbno,          /* file system block number */
745         xfs_extlen_t            count,          /* count of filesystem blocks */
746         const struct xfs_buf_ops *ops)
747 {
748         xfs_daddr_t             d;
749
750         ASSERT(fsbno != NULLFSBLOCK);
751         d = XFS_FSB_TO_DADDR(mp, fsbno);
752         xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
753 }
754
755 /*
756  * Read-ahead the block, don't wait for it, don't return a buffer.
757  * Short-form addressing.
758  */
759 /* ARGSUSED */
760 void
761 xfs_btree_reada_bufs(
762         struct xfs_mount        *mp,            /* file system mount point */
763         xfs_agnumber_t          agno,           /* allocation group number */
764         xfs_agblock_t           agbno,          /* allocation group block number */
765         xfs_extlen_t            count,          /* count of filesystem blocks */
766         const struct xfs_buf_ops *ops)
767 {
768         xfs_daddr_t             d;
769
770         ASSERT(agno != NULLAGNUMBER);
771         ASSERT(agbno != NULLAGBLOCK);
772         d = XFS_AGB_TO_DADDR(mp, agno, agbno);
773         xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
774 }
775
776 STATIC int
777 xfs_btree_readahead_lblock(
778         struct xfs_btree_cur    *cur,
779         int                     lr,
780         struct xfs_btree_block  *block)
781 {
782         int                     rval = 0;
783         xfs_dfsbno_t            left = be64_to_cpu(block->bb_u.l.bb_leftsib);
784         xfs_dfsbno_t            right = be64_to_cpu(block->bb_u.l.bb_rightsib);
785
786         if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) {
787                 xfs_btree_reada_bufl(cur->bc_mp, left, 1,
788                                      cur->bc_ops->buf_ops);
789                 rval++;
790         }
791
792         if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) {
793                 xfs_btree_reada_bufl(cur->bc_mp, right, 1,
794                                      cur->bc_ops->buf_ops);
795                 rval++;
796         }
797
798         return rval;
799 }
800
801 STATIC int
802 xfs_btree_readahead_sblock(
803         struct xfs_btree_cur    *cur,
804         int                     lr,
805         struct xfs_btree_block *block)
806 {
807         int                     rval = 0;
808         xfs_agblock_t           left = be32_to_cpu(block->bb_u.s.bb_leftsib);
809         xfs_agblock_t           right = be32_to_cpu(block->bb_u.s.bb_rightsib);
810
811
812         if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
813                 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
814                                      left, 1, cur->bc_ops->buf_ops);
815                 rval++;
816         }
817
818         if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
819                 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
820                                      right, 1, cur->bc_ops->buf_ops);
821                 rval++;
822         }
823
824         return rval;
825 }
826
827 /*
828  * Read-ahead btree blocks, at the given level.
829  * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
830  */
831 STATIC int
832 xfs_btree_readahead(
833         struct xfs_btree_cur    *cur,           /* btree cursor */
834         int                     lev,            /* level in btree */
835         int                     lr)             /* left/right bits */
836 {
837         struct xfs_btree_block  *block;
838
839         /*
840          * No readahead needed if we are at the root level and the
841          * btree root is stored in the inode.
842          */
843         if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
844             (lev == cur->bc_nlevels - 1))
845                 return 0;
846
847         if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev])
848                 return 0;
849
850         cur->bc_ra[lev] |= lr;
851         block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]);
852
853         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
854                 return xfs_btree_readahead_lblock(cur, lr, block);
855         return xfs_btree_readahead_sblock(cur, lr, block);
856 }
857
858 /*
859  * Set the buffer for level "lev" in the cursor to bp, releasing
860  * any previous buffer.
861  */
862 STATIC void
863 xfs_btree_setbuf(
864         xfs_btree_cur_t         *cur,   /* btree cursor */
865         int                     lev,    /* level in btree */
866         xfs_buf_t               *bp)    /* new buffer to set */
867 {
868         struct xfs_btree_block  *b;     /* btree block */
869
870         if (cur->bc_bufs[lev])
871                 xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[lev]);
872         cur->bc_bufs[lev] = bp;
873         cur->bc_ra[lev] = 0;
874
875         b = XFS_BUF_TO_BLOCK(bp);
876         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
877                 if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO))
878                         cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
879                 if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO))
880                         cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
881         } else {
882                 if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK))
883                         cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
884                 if (b->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK))
885                         cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
886         }
887 }
888
889 STATIC int
890 xfs_btree_ptr_is_null(
891         struct xfs_btree_cur    *cur,
892         union xfs_btree_ptr     *ptr)
893 {
894         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
895                 return ptr->l == cpu_to_be64(NULLDFSBNO);
896         else
897                 return ptr->s == cpu_to_be32(NULLAGBLOCK);
898 }
899
900 STATIC void
901 xfs_btree_set_ptr_null(
902         struct xfs_btree_cur    *cur,
903         union xfs_btree_ptr     *ptr)
904 {
905         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
906                 ptr->l = cpu_to_be64(NULLDFSBNO);
907         else
908                 ptr->s = cpu_to_be32(NULLAGBLOCK);
909 }
910
911 /*
912  * Get/set/init sibling pointers
913  */
914 STATIC void
915 xfs_btree_get_sibling(
916         struct xfs_btree_cur    *cur,
917         struct xfs_btree_block  *block,
918         union xfs_btree_ptr     *ptr,
919         int                     lr)
920 {
921         ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
922
923         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
924                 if (lr == XFS_BB_RIGHTSIB)
925                         ptr->l = block->bb_u.l.bb_rightsib;
926                 else
927                         ptr->l = block->bb_u.l.bb_leftsib;
928         } else {
929                 if (lr == XFS_BB_RIGHTSIB)
930                         ptr->s = block->bb_u.s.bb_rightsib;
931                 else
932                         ptr->s = block->bb_u.s.bb_leftsib;
933         }
934 }
935
936 STATIC void
937 xfs_btree_set_sibling(
938         struct xfs_btree_cur    *cur,
939         struct xfs_btree_block  *block,
940         union xfs_btree_ptr     *ptr,
941         int                     lr)
942 {
943         ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
944
945         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
946                 if (lr == XFS_BB_RIGHTSIB)
947                         block->bb_u.l.bb_rightsib = ptr->l;
948                 else
949                         block->bb_u.l.bb_leftsib = ptr->l;
950         } else {
951                 if (lr == XFS_BB_RIGHTSIB)
952                         block->bb_u.s.bb_rightsib = ptr->s;
953                 else
954                         block->bb_u.s.bb_leftsib = ptr->s;
955         }
956 }
957
958 void
959 xfs_btree_init_block_int(
960         struct xfs_mount        *mp,
961         struct xfs_btree_block  *buf,
962         xfs_daddr_t             blkno,
963         __u32                   magic,
964         __u16                   level,
965         __u16                   numrecs,
966         __u64                   owner,
967         unsigned int            flags)
968 {
969         buf->bb_magic = cpu_to_be32(magic);
970         buf->bb_level = cpu_to_be16(level);
971         buf->bb_numrecs = cpu_to_be16(numrecs);
972
973         if (flags & XFS_BTREE_LONG_PTRS) {
974                 buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
975                 buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
976                 if (flags & XFS_BTREE_CRC_BLOCKS) {
977                         buf->bb_u.l.bb_blkno = cpu_to_be64(blkno);
978                         buf->bb_u.l.bb_owner = cpu_to_be64(owner);
979                         uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid);
980                         buf->bb_u.l.bb_pad = 0;
981                 }
982         } else {
983                 /* owner is a 32 bit value on short blocks */
984                 __u32 __owner = (__u32)owner;
985
986                 buf->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
987                 buf->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
988                 if (flags & XFS_BTREE_CRC_BLOCKS) {
989                         buf->bb_u.s.bb_blkno = cpu_to_be64(blkno);
990                         buf->bb_u.s.bb_owner = cpu_to_be32(__owner);
991                         uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid);
992                 }
993         }
994 }
995
996 void
997 xfs_btree_init_block(
998         struct xfs_mount *mp,
999         struct xfs_buf  *bp,
1000         __u32           magic,
1001         __u16           level,
1002         __u16           numrecs,
1003         __u64           owner,
1004         unsigned int    flags)
1005 {
1006         xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,
1007                                  magic, level, numrecs, owner, flags);
1008 }
1009
1010 STATIC void
1011 xfs_btree_init_block_cur(
1012         struct xfs_btree_cur    *cur,
1013         struct xfs_buf          *bp,
1014         int                     level,
1015         int                     numrecs)
1016 {
1017         __u64 owner;
1018
1019         /*
1020          * we can pull the owner from the cursor right now as the different
1021          * owners align directly with the pointer size of the btree. This may
1022          * change in future, but is safe for current users of the generic btree
1023          * code.
1024          */
1025         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
1026                 owner = cur->bc_private.b.ip->i_ino;
1027         else
1028                 owner = cur->bc_private.a.agno;
1029
1030         xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,
1031                                  xfs_btree_magic(cur), level, numrecs,
1032                                  owner, cur->bc_flags);
1033 }
1034
1035 /*
1036  * Return true if ptr is the last record in the btree and
1037  * we need to track updates to this record.  The decision
1038  * will be further refined in the update_lastrec method.
1039  */
1040 STATIC int
1041 xfs_btree_is_lastrec(
1042         struct xfs_btree_cur    *cur,
1043         struct xfs_btree_block  *block,
1044         int                     level)
1045 {
1046         union xfs_btree_ptr     ptr;
1047
1048         if (level > 0)
1049                 return 0;
1050         if (!(cur->bc_flags & XFS_BTREE_LASTREC_UPDATE))
1051                 return 0;
1052
1053         xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
1054         if (!xfs_btree_ptr_is_null(cur, &ptr))
1055                 return 0;
1056         return 1;
1057 }
1058
1059 STATIC void
1060 xfs_btree_buf_to_ptr(
1061         struct xfs_btree_cur    *cur,
1062         struct xfs_buf          *bp,
1063         union xfs_btree_ptr     *ptr)
1064 {
1065         if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
1066                 ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp,
1067                                         XFS_BUF_ADDR(bp)));
1068         else {
1069                 ptr->s = cpu_to_be32(xfs_daddr_to_agbno(cur->bc_mp,
1070                                         XFS_BUF_ADDR(bp)));
1071         }
1072 }
1073
1074 STATIC xfs_daddr_t
1075 xfs_btree_ptr_to_daddr(
1076         struct xfs_btree_cur    *cur,
1077         union xfs_btree_ptr     *ptr)
1078 {
1079         if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
1080                 ASSERT(ptr->l != cpu_to_be64(NULLDFSBNO));
1081
1082                 return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l));
1083         } else {
1084                 ASSERT(cur->bc_private.a.agno != NULLAGNUMBER);
1085                 ASSERT(ptr->s != cpu_to_be32(NULLAGBLOCK));
1086
1087                 return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno,
1088                                         be32_to_cpu(ptr->s));
1089         }
1090 }
1091
1092 STATIC void
1093 xfs_btree_set_refs(
1094         struct xfs_btree_cur    *cur,
1095         struct xfs_buf          *bp)
1096 {
1097         switch (cur->bc_btnum) {
1098         case XFS_BTNUM_BNO:
1099         case XFS_BTNUM_CNT:
1100                 xfs_buf_set_ref(bp, XFS_ALLOC_BTREE_REF);
1101                 break;
1102         case XFS_BTNUM_INO:
1103                 xfs_buf_set_ref(bp, XFS_INO_BTREE_REF);
1104                 break;
1105         case XFS_BTNUM_BMAP:
1106                 xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF);
1107                 break;
1108         default:
1109                 ASSERT(0);
1110         }
1111 }
1112
1113 STATIC int
1114 xfs_btree_get_buf_block(
1115         struct xfs_btree_cur    *cur,
1116         union xfs_btree_ptr     *ptr,
1117         int                     flags,
1118         struct xfs_btree_block  **block,
1119         struct xfs_buf          **bpp)
1120 {
1121         struct xfs_mount        *mp = cur->bc_mp;
1122         xfs_daddr_t             d;
1123
1124         /* need to sort out how callers deal with failures first */
1125         ASSERT(!(flags & XBF_TRYLOCK));
1126
1127         d = xfs_btree_ptr_to_daddr(cur, ptr);
1128         *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d,
1129                                  mp->m_bsize, flags);
1130
1131         if (!*bpp)
1132                 return ENOMEM;
1133
1134         (*bpp)->b_ops = cur->bc_ops->buf_ops;
1135         *block = XFS_BUF_TO_BLOCK(*bpp);
1136         return 0;
1137 }
1138
1139 /*
1140  * Read in the buffer at the given ptr and return the buffer and
1141  * the block pointer within the buffer.
1142  */
1143 STATIC int
1144 xfs_btree_read_buf_block(
1145         struct xfs_btree_cur    *cur,
1146         union xfs_btree_ptr     *ptr,
1147         int                     level,
1148         int                     flags,
1149         struct xfs_btree_block  **block,
1150         struct xfs_buf          **bpp)
1151 {
1152         struct xfs_mount        *mp = cur->bc_mp;
1153         xfs_daddr_t             d;
1154         int                     error;
1155
1156         /* need to sort out how callers deal with failures first */
1157         ASSERT(!(flags & XBF_TRYLOCK));
1158
1159         d = xfs_btree_ptr_to_daddr(cur, ptr);
1160         error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
1161                                    mp->m_bsize, flags, bpp,
1162                                    cur->bc_ops->buf_ops);
1163         if (error)
1164                 return error;
1165
1166         ASSERT(!xfs_buf_geterror(*bpp));
1167         xfs_btree_set_refs(cur, *bpp);
1168         *block = XFS_BUF_TO_BLOCK(*bpp);
1169         return 0;
1170 }
1171
1172 /*
1173  * Copy keys from one btree block to another.
1174  */
1175 STATIC void
1176 xfs_btree_copy_keys(
1177         struct xfs_btree_cur    *cur,
1178         union xfs_btree_key     *dst_key,
1179         union xfs_btree_key     *src_key,
1180         int                     numkeys)
1181 {
1182         ASSERT(numkeys >= 0);
1183         memcpy(dst_key, src_key, numkeys * cur->bc_ops->key_len);
1184 }
1185
1186 /*
1187  * Copy records from one btree block to another.
1188  */
1189 STATIC void
1190 xfs_btree_copy_recs(
1191         struct xfs_btree_cur    *cur,
1192         union xfs_btree_rec     *dst_rec,
1193         union xfs_btree_rec     *src_rec,
1194         int                     numrecs)
1195 {
1196         ASSERT(numrecs >= 0);
1197         memcpy(dst_rec, src_rec, numrecs * cur->bc_ops->rec_len);
1198 }
1199
1200 /*
1201  * Copy block pointers from one btree block to another.
1202  */
1203 STATIC void
1204 xfs_btree_copy_ptrs(
1205         struct xfs_btree_cur    *cur,
1206         union xfs_btree_ptr     *dst_ptr,
1207         union xfs_btree_ptr     *src_ptr,
1208         int                     numptrs)
1209 {
1210         ASSERT(numptrs >= 0);
1211         memcpy(dst_ptr, src_ptr, numptrs * xfs_btree_ptr_len(cur));
1212 }
1213
1214 /*
1215  * Shift keys one index left/right inside a single btree block.
1216  */
1217 STATIC void
1218 xfs_btree_shift_keys(
1219         struct xfs_btree_cur    *cur,
1220         union xfs_btree_key     *key,
1221         int                     dir,
1222         int                     numkeys)
1223 {
1224         char                    *dst_key;
1225
1226         ASSERT(numkeys >= 0);
1227         ASSERT(dir == 1 || dir == -1);
1228
1229         dst_key = (char *)key + (dir * cur->bc_ops->key_len);
1230         memmove(dst_key, key, numkeys * cur->bc_ops->key_len);
1231 }
1232
1233 /*
1234  * Shift records one index left/right inside a single btree block.
1235  */
1236 STATIC void
1237 xfs_btree_shift_recs(
1238         struct xfs_btree_cur    *cur,
1239         union xfs_btree_rec     *rec,
1240         int                     dir,
1241         int                     numrecs)
1242 {
1243         char                    *dst_rec;
1244
1245         ASSERT(numrecs >= 0);
1246         ASSERT(dir == 1 || dir == -1);
1247
1248         dst_rec = (char *)rec + (dir * cur->bc_ops->rec_len);
1249         memmove(dst_rec, rec, numrecs * cur->bc_ops->rec_len);
1250 }
1251
1252 /*
1253  * Shift block pointers one index left/right inside a single btree block.
1254  */
1255 STATIC void
1256 xfs_btree_shift_ptrs(
1257         struct xfs_btree_cur    *cur,
1258         union xfs_btree_ptr     *ptr,
1259         int                     dir,
1260         int                     numptrs)
1261 {
1262         char                    *dst_ptr;
1263
1264         ASSERT(numptrs >= 0);
1265         ASSERT(dir == 1 || dir == -1);
1266
1267         dst_ptr = (char *)ptr + (dir * xfs_btree_ptr_len(cur));
1268         memmove(dst_ptr, ptr, numptrs * xfs_btree_ptr_len(cur));
1269 }
1270
1271 /*
1272  * Log key values from the btree block.
1273  */
1274 STATIC void
1275 xfs_btree_log_keys(
1276         struct xfs_btree_cur    *cur,
1277         struct xfs_buf          *bp,
1278         int                     first,
1279         int                     last)
1280 {
1281         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1282         XFS_BTREE_TRACE_ARGBII(cur, bp, first, last);
1283
1284         if (bp) {
1285                 xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
1286                 xfs_trans_log_buf(cur->bc_tp, bp,
1287                                   xfs_btree_key_offset(cur, first),
1288                                   xfs_btree_key_offset(cur, last + 1) - 1);
1289         } else {
1290                 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
1291                                 xfs_ilog_fbroot(cur->bc_private.b.whichfork));
1292         }
1293
1294         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1295 }
1296
1297 /*
1298  * Log record values from the btree block.
1299  */
1300 void
1301 xfs_btree_log_recs(
1302         struct xfs_btree_cur    *cur,
1303         struct xfs_buf          *bp,
1304         int                     first,
1305         int                     last)
1306 {
1307         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1308         XFS_BTREE_TRACE_ARGBII(cur, bp, first, last);
1309
1310         xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
1311         xfs_trans_log_buf(cur->bc_tp, bp,
1312                           xfs_btree_rec_offset(cur, first),
1313                           xfs_btree_rec_offset(cur, last + 1) - 1);
1314
1315         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1316 }
1317
1318 /*
1319  * Log block pointer fields from a btree block (nonleaf).
1320  */
1321 STATIC void
1322 xfs_btree_log_ptrs(
1323         struct xfs_btree_cur    *cur,   /* btree cursor */
1324         struct xfs_buf          *bp,    /* buffer containing btree block */
1325         int                     first,  /* index of first pointer to log */
1326         int                     last)   /* index of last pointer to log */
1327 {
1328         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1329         XFS_BTREE_TRACE_ARGBII(cur, bp, first, last);
1330
1331         if (bp) {
1332                 struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
1333                 int                     level = xfs_btree_get_level(block);
1334
1335                 xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
1336                 xfs_trans_log_buf(cur->bc_tp, bp,
1337                                 xfs_btree_ptr_offset(cur, first, level),
1338                                 xfs_btree_ptr_offset(cur, last + 1, level) - 1);
1339         } else {
1340                 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
1341                         xfs_ilog_fbroot(cur->bc_private.b.whichfork));
1342         }
1343
1344         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1345 }
1346
1347 /*
1348  * Log fields from a btree block header.
1349  */
1350 void
1351 xfs_btree_log_block(
1352         struct xfs_btree_cur    *cur,   /* btree cursor */
1353         struct xfs_buf          *bp,    /* buffer containing btree block */
1354         int                     fields) /* mask of fields: XFS_BB_... */
1355 {
1356         int                     first;  /* first byte offset logged */
1357         int                     last;   /* last byte offset logged */
1358         static const short      soffsets[] = {  /* table of offsets (short) */
1359                 offsetof(struct xfs_btree_block, bb_magic),
1360                 offsetof(struct xfs_btree_block, bb_level),
1361                 offsetof(struct xfs_btree_block, bb_numrecs),
1362                 offsetof(struct xfs_btree_block, bb_u.s.bb_leftsib),
1363                 offsetof(struct xfs_btree_block, bb_u.s.bb_rightsib),
1364                 offsetof(struct xfs_btree_block, bb_u.s.bb_blkno),
1365                 offsetof(struct xfs_btree_block, bb_u.s.bb_lsn),
1366                 offsetof(struct xfs_btree_block, bb_u.s.bb_uuid),
1367                 offsetof(struct xfs_btree_block, bb_u.s.bb_owner),
1368                 offsetof(struct xfs_btree_block, bb_u.s.bb_crc),
1369                 XFS_BTREE_SBLOCK_CRC_LEN
1370         };
1371         static const short      loffsets[] = {  /* table of offsets (long) */
1372                 offsetof(struct xfs_btree_block, bb_magic),
1373                 offsetof(struct xfs_btree_block, bb_level),
1374                 offsetof(struct xfs_btree_block, bb_numrecs),
1375                 offsetof(struct xfs_btree_block, bb_u.l.bb_leftsib),
1376                 offsetof(struct xfs_btree_block, bb_u.l.bb_rightsib),
1377                 offsetof(struct xfs_btree_block, bb_u.l.bb_blkno),
1378                 offsetof(struct xfs_btree_block, bb_u.l.bb_lsn),
1379                 offsetof(struct xfs_btree_block, bb_u.l.bb_uuid),
1380                 offsetof(struct xfs_btree_block, bb_u.l.bb_owner),
1381                 offsetof(struct xfs_btree_block, bb_u.l.bb_crc),
1382                 offsetof(struct xfs_btree_block, bb_u.l.bb_pad),
1383                 XFS_BTREE_LBLOCK_CRC_LEN
1384         };
1385
1386         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1387         XFS_BTREE_TRACE_ARGBI(cur, bp, fields);
1388
1389         if (bp) {
1390                 int nbits;
1391
1392                 if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
1393                         /*
1394                          * We don't log the CRC when updating a btree
1395                          * block but instead recreate it during log
1396                          * recovery.  As the log buffers have checksums
1397                          * of their own this is safe and avoids logging a crc
1398                          * update in a lot of places.
1399                          */
1400                         if (fields == XFS_BB_ALL_BITS)
1401                                 fields = XFS_BB_ALL_BITS_CRC;
1402                         nbits = XFS_BB_NUM_BITS_CRC;
1403                 } else {
1404                         nbits = XFS_BB_NUM_BITS;
1405                 }
1406                 xfs_btree_offsets(fields,
1407                                   (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
1408                                         loffsets : soffsets,
1409                                   nbits, &first, &last);
1410                 xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
1411                 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
1412         } else {
1413                 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip,
1414                         xfs_ilog_fbroot(cur->bc_private.b.whichfork));
1415         }
1416
1417         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1418 }
1419
1420 /*
1421  * Increment cursor by one record at the level.
1422  * For nonzero levels the leaf-ward information is untouched.
1423  */
1424 int                                             /* error */
1425 xfs_btree_increment(
1426         struct xfs_btree_cur    *cur,
1427         int                     level,
1428         int                     *stat)          /* success/failure */
1429 {
1430         struct xfs_btree_block  *block;
1431         union xfs_btree_ptr     ptr;
1432         struct xfs_buf          *bp;
1433         int                     error;          /* error return value */
1434         int                     lev;
1435
1436         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1437         XFS_BTREE_TRACE_ARGI(cur, level);
1438
1439         ASSERT(level < cur->bc_nlevels);
1440
1441         /* Read-ahead to the right at this level. */
1442         xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
1443
1444         /* Get a pointer to the btree block. */
1445         block = xfs_btree_get_block(cur, level, &bp);
1446
1447 #ifdef DEBUG
1448         error = xfs_btree_check_block(cur, block, level, bp);
1449         if (error)
1450                 goto error0;
1451 #endif
1452
1453         /* We're done if we remain in the block after the increment. */
1454         if (++cur->bc_ptrs[level] <= xfs_btree_get_numrecs(block))
1455                 goto out1;
1456
1457         /* Fail if we just went off the right edge of the tree. */
1458         xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
1459         if (xfs_btree_ptr_is_null(cur, &ptr))
1460                 goto out0;
1461
1462         XFS_BTREE_STATS_INC(cur, increment);
1463
1464         /*
1465          * March up the tree incrementing pointers.
1466          * Stop when we don't go off the right edge of a block.
1467          */
1468         for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1469                 block = xfs_btree_get_block(cur, lev, &bp);
1470
1471 #ifdef DEBUG
1472                 error = xfs_btree_check_block(cur, block, lev, bp);
1473                 if (error)
1474                         goto error0;
1475 #endif
1476
1477                 if (++cur->bc_ptrs[lev] <= xfs_btree_get_numrecs(block))
1478                         break;
1479
1480                 /* Read-ahead the right block for the next loop. */
1481                 xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
1482         }
1483
1484         /*
1485          * If we went off the root then we are either seriously
1486          * confused or have the tree root in an inode.
1487          */
1488         if (lev == cur->bc_nlevels) {
1489                 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
1490                         goto out0;
1491                 ASSERT(0);
1492                 error = EFSCORRUPTED;
1493                 goto error0;
1494         }
1495         ASSERT(lev < cur->bc_nlevels);
1496
1497         /*
1498          * Now walk back down the tree, fixing up the cursor's buffer
1499          * pointers and key numbers.
1500          */
1501         for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
1502                 union xfs_btree_ptr     *ptrp;
1503
1504                 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
1505                 error = xfs_btree_read_buf_block(cur, ptrp, --lev,
1506                                                         0, &block, &bp);
1507                 if (error)
1508                         goto error0;
1509
1510                 xfs_btree_setbuf(cur, lev, bp);
1511                 cur->bc_ptrs[lev] = 1;
1512         }
1513 out1:
1514         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1515         *stat = 1;
1516         return 0;
1517
1518 out0:
1519         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1520         *stat = 0;
1521         return 0;
1522
1523 error0:
1524         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1525         return error;
1526 }
1527
1528 /*
1529  * Decrement cursor by one record at the level.
1530  * For nonzero levels the leaf-ward information is untouched.
1531  */
1532 int                                             /* error */
1533 xfs_btree_decrement(
1534         struct xfs_btree_cur    *cur,
1535         int                     level,
1536         int                     *stat)          /* success/failure */
1537 {
1538         struct xfs_btree_block  *block;
1539         xfs_buf_t               *bp;
1540         int                     error;          /* error return value */
1541         int                     lev;
1542         union xfs_btree_ptr     ptr;
1543
1544         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1545         XFS_BTREE_TRACE_ARGI(cur, level);
1546
1547         ASSERT(level < cur->bc_nlevels);
1548
1549         /* Read-ahead to the left at this level. */
1550         xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
1551
1552         /* We're done if we remain in the block after the decrement. */
1553         if (--cur->bc_ptrs[level] > 0)
1554                 goto out1;
1555
1556         /* Get a pointer to the btree block. */
1557         block = xfs_btree_get_block(cur, level, &bp);
1558
1559 #ifdef DEBUG
1560         error = xfs_btree_check_block(cur, block, level, bp);
1561         if (error)
1562                 goto error0;
1563 #endif
1564
1565         /* Fail if we just went off the left edge of the tree. */
1566         xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB);
1567         if (xfs_btree_ptr_is_null(cur, &ptr))
1568                 goto out0;
1569
1570         XFS_BTREE_STATS_INC(cur, decrement);
1571
1572         /*
1573          * March up the tree decrementing pointers.
1574          * Stop when we don't go off the left edge of a block.
1575          */
1576         for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1577                 if (--cur->bc_ptrs[lev] > 0)
1578                         break;
1579                 /* Read-ahead the left block for the next loop. */
1580                 xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
1581         }
1582
1583         /*
1584          * If we went off the root then we are seriously confused.
1585          * or the root of the tree is in an inode.
1586          */
1587         if (lev == cur->bc_nlevels) {
1588                 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
1589                         goto out0;
1590                 ASSERT(0);
1591                 error = EFSCORRUPTED;
1592                 goto error0;
1593         }
1594         ASSERT(lev < cur->bc_nlevels);
1595
1596         /*
1597          * Now walk back down the tree, fixing up the cursor's buffer
1598          * pointers and key numbers.
1599          */
1600         for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
1601                 union xfs_btree_ptr     *ptrp;
1602
1603                 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
1604                 error = xfs_btree_read_buf_block(cur, ptrp, --lev,
1605                                                         0, &block, &bp);
1606                 if (error)
1607                         goto error0;
1608                 xfs_btree_setbuf(cur, lev, bp);
1609                 cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block);
1610         }
1611 out1:
1612         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1613         *stat = 1;
1614         return 0;
1615
1616 out0:
1617         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1618         *stat = 0;
1619         return 0;
1620
1621 error0:
1622         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1623         return error;
1624 }
1625
1626 STATIC int
1627 xfs_btree_lookup_get_block(
1628         struct xfs_btree_cur    *cur,   /* btree cursor */
1629         int                     level,  /* level in the btree */
1630         union xfs_btree_ptr     *pp,    /* ptr to btree block */
1631         struct xfs_btree_block  **blkp) /* return btree block */
1632 {
1633         struct xfs_buf          *bp;    /* buffer pointer for btree block */
1634         int                     error = 0;
1635
1636         /* special case the root block if in an inode */
1637         if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
1638             (level == cur->bc_nlevels - 1)) {
1639                 *blkp = xfs_btree_get_iroot(cur);
1640                 return 0;
1641         }
1642
1643         /*
1644          * If the old buffer at this level for the disk address we are
1645          * looking for re-use it.
1646          *
1647          * Otherwise throw it away and get a new one.
1648          */
1649         bp = cur->bc_bufs[level];
1650         if (bp && XFS_BUF_ADDR(bp) == xfs_btree_ptr_to_daddr(cur, pp)) {
1651                 *blkp = XFS_BUF_TO_BLOCK(bp);
1652                 return 0;
1653         }
1654
1655         error = xfs_btree_read_buf_block(cur, pp, level, 0, blkp, &bp);
1656         if (error)
1657                 return error;
1658
1659         xfs_btree_setbuf(cur, level, bp);
1660         return 0;
1661 }
1662
1663 /*
1664  * Get current search key.  For level 0 we don't actually have a key
1665  * structure so we make one up from the record.  For all other levels
1666  * we just return the right key.
1667  */
1668 STATIC union xfs_btree_key *
1669 xfs_lookup_get_search_key(
1670         struct xfs_btree_cur    *cur,
1671         int                     level,
1672         int                     keyno,
1673         struct xfs_btree_block  *block,
1674         union xfs_btree_key     *kp)
1675 {
1676         if (level == 0) {
1677                 cur->bc_ops->init_key_from_rec(kp,
1678                                 xfs_btree_rec_addr(cur, keyno, block));
1679                 return kp;
1680         }
1681
1682         return xfs_btree_key_addr(cur, keyno, block);
1683 }
1684
1685 /*
1686  * Lookup the record.  The cursor is made to point to it, based on dir.
1687  * Return 0 if can't find any such record, 1 for success.
1688  */
1689 int                                     /* error */
1690 xfs_btree_lookup(
1691         struct xfs_btree_cur    *cur,   /* btree cursor */
1692         xfs_lookup_t            dir,    /* <=, ==, or >= */
1693         int                     *stat)  /* success/failure */
1694 {
1695         struct xfs_btree_block  *block; /* current btree block */
1696         __int64_t               diff;   /* difference for the current key */
1697         int                     error;  /* error return value */
1698         int                     keyno;  /* current key number */
1699         int                     level;  /* level in the btree */
1700         union xfs_btree_ptr     *pp;    /* ptr to btree block */
1701         union xfs_btree_ptr     ptr;    /* ptr to btree block */
1702
1703         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1704         XFS_BTREE_TRACE_ARGI(cur, dir);
1705
1706         XFS_BTREE_STATS_INC(cur, lookup);
1707
1708         block = NULL;
1709         keyno = 0;
1710
1711         /* initialise start pointer from cursor */
1712         cur->bc_ops->init_ptr_from_cur(cur, &ptr);
1713         pp = &ptr;
1714
1715         /*
1716          * Iterate over each level in the btree, starting at the root.
1717          * For each level above the leaves, find the key we need, based
1718          * on the lookup record, then follow the corresponding block
1719          * pointer down to the next level.
1720          */
1721         for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
1722                 /* Get the block we need to do the lookup on. */
1723                 error = xfs_btree_lookup_get_block(cur, level, pp, &block);
1724                 if (error)
1725                         goto error0;
1726
1727                 if (diff == 0) {
1728                         /*
1729                          * If we already had a key match at a higher level, we
1730                          * know we need to use the first entry in this block.
1731                          */
1732                         keyno = 1;
1733                 } else {
1734                         /* Otherwise search this block. Do a binary search. */
1735
1736                         int     high;   /* high entry number */
1737                         int     low;    /* low entry number */
1738
1739                         /* Set low and high entry numbers, 1-based. */
1740                         low = 1;
1741                         high = xfs_btree_get_numrecs(block);
1742                         if (!high) {
1743                                 /* Block is empty, must be an empty leaf. */
1744                                 ASSERT(level == 0 && cur->bc_nlevels == 1);
1745
1746                                 cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
1747                                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1748                                 *stat = 0;
1749                                 return 0;
1750                         }
1751
1752                         /* Binary search the block. */
1753                         while (low <= high) {
1754                                 union xfs_btree_key     key;
1755                                 union xfs_btree_key     *kp;
1756
1757                                 XFS_BTREE_STATS_INC(cur, compare);
1758
1759                                 /* keyno is average of low and high. */
1760                                 keyno = (low + high) >> 1;
1761
1762                                 /* Get current search key */
1763                                 kp = xfs_lookup_get_search_key(cur, level,
1764                                                 keyno, block, &key);
1765
1766                                 /*
1767                                  * Compute difference to get next direction:
1768                                  *  - less than, move right
1769                                  *  - greater than, move left
1770                                  *  - equal, we're done
1771                                  */
1772                                 diff = cur->bc_ops->key_diff(cur, kp);
1773                                 if (diff < 0)
1774                                         low = keyno + 1;
1775                                 else if (diff > 0)
1776                                         high = keyno - 1;
1777                                 else
1778                                         break;
1779                         }
1780                 }
1781
1782                 /*
1783                  * If there are more levels, set up for the next level
1784                  * by getting the block number and filling in the cursor.
1785                  */
1786                 if (level > 0) {
1787                         /*
1788                          * If we moved left, need the previous key number,
1789                          * unless there isn't one.
1790                          */
1791                         if (diff > 0 && --keyno < 1)
1792                                 keyno = 1;
1793                         pp = xfs_btree_ptr_addr(cur, keyno, block);
1794
1795 #ifdef DEBUG
1796                         error = xfs_btree_check_ptr(cur, pp, 0, level);
1797                         if (error)
1798                                 goto error0;
1799 #endif
1800                         cur->bc_ptrs[level] = keyno;
1801                 }
1802         }
1803
1804         /* Done with the search. See if we need to adjust the results. */
1805         if (dir != XFS_LOOKUP_LE && diff < 0) {
1806                 keyno++;
1807                 /*
1808                  * If ge search and we went off the end of the block, but it's
1809                  * not the last block, we're in the wrong block.
1810                  */
1811                 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
1812                 if (dir == XFS_LOOKUP_GE &&
1813                     keyno > xfs_btree_get_numrecs(block) &&
1814                     !xfs_btree_ptr_is_null(cur, &ptr)) {
1815                         int     i;
1816
1817                         cur->bc_ptrs[0] = keyno;
1818                         error = xfs_btree_increment(cur, 0, &i);
1819                         if (error)
1820                                 goto error0;
1821                         XFS_WANT_CORRUPTED_RETURN(i == 1);
1822                         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1823                         *stat = 1;
1824                         return 0;
1825                 }
1826         } else if (dir == XFS_LOOKUP_LE && diff > 0)
1827                 keyno--;
1828         cur->bc_ptrs[0] = keyno;
1829
1830         /* Return if we succeeded or not. */
1831         if (keyno == 0 || keyno > xfs_btree_get_numrecs(block))
1832                 *stat = 0;
1833         else if (dir != XFS_LOOKUP_EQ || diff == 0)
1834                 *stat = 1;
1835         else
1836                 *stat = 0;
1837         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1838         return 0;
1839
1840 error0:
1841         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1842         return error;
1843 }
1844
1845 /*
1846  * Update keys at all levels from here to the root along the cursor's path.
1847  */
1848 STATIC int
1849 xfs_btree_updkey(
1850         struct xfs_btree_cur    *cur,
1851         union xfs_btree_key     *keyp,
1852         int                     level)
1853 {
1854         struct xfs_btree_block  *block;
1855         struct xfs_buf          *bp;
1856         union xfs_btree_key     *kp;
1857         int                     ptr;
1858
1859         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1860         XFS_BTREE_TRACE_ARGIK(cur, level, keyp);
1861
1862         ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) || level >= 1);
1863
1864         /*
1865          * Go up the tree from this level toward the root.
1866          * At each level, update the key value to the value input.
1867          * Stop when we reach a level where the cursor isn't pointing
1868          * at the first entry in the block.
1869          */
1870         for (ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
1871 #ifdef DEBUG
1872                 int             error;
1873 #endif
1874                 block = xfs_btree_get_block(cur, level, &bp);
1875 #ifdef DEBUG
1876                 error = xfs_btree_check_block(cur, block, level, bp);
1877                 if (error) {
1878                         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1879                         return error;
1880                 }
1881 #endif
1882                 ptr = cur->bc_ptrs[level];
1883                 kp = xfs_btree_key_addr(cur, ptr, block);
1884                 xfs_btree_copy_keys(cur, kp, keyp, 1);
1885                 xfs_btree_log_keys(cur, bp, ptr, ptr);
1886         }
1887
1888         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1889         return 0;
1890 }
1891
1892 /*
1893  * Update the record referred to by cur to the value in the
1894  * given record. This either works (return 0) or gets an
1895  * EFSCORRUPTED error.
1896  */
1897 int
1898 xfs_btree_update(
1899         struct xfs_btree_cur    *cur,
1900         union xfs_btree_rec     *rec)
1901 {
1902         struct xfs_btree_block  *block;
1903         struct xfs_buf          *bp;
1904         int                     error;
1905         int                     ptr;
1906         union xfs_btree_rec     *rp;
1907
1908         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1909         XFS_BTREE_TRACE_ARGR(cur, rec);
1910
1911         /* Pick up the current block. */
1912         block = xfs_btree_get_block(cur, 0, &bp);
1913
1914 #ifdef DEBUG
1915         error = xfs_btree_check_block(cur, block, 0, bp);
1916         if (error)
1917                 goto error0;
1918 #endif
1919         /* Get the address of the rec to be updated. */
1920         ptr = cur->bc_ptrs[0];
1921         rp = xfs_btree_rec_addr(cur, ptr, block);
1922
1923         /* Fill in the new contents and log them. */
1924         xfs_btree_copy_recs(cur, rp, rec, 1);
1925         xfs_btree_log_recs(cur, bp, ptr, ptr);
1926
1927         /*
1928          * If we are tracking the last record in the tree and
1929          * we are at the far right edge of the tree, update it.
1930          */
1931         if (xfs_btree_is_lastrec(cur, block, 0)) {
1932                 cur->bc_ops->update_lastrec(cur, block, rec,
1933                                             ptr, LASTREC_UPDATE);
1934         }
1935
1936         /* Updating first rec in leaf. Pass new key value up to our parent. */
1937         if (ptr == 1) {
1938                 union xfs_btree_key     key;
1939
1940                 cur->bc_ops->init_key_from_rec(&key, rec);
1941                 error = xfs_btree_updkey(cur, &key, 1);
1942                 if (error)
1943                         goto error0;
1944         }
1945
1946         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1947         return 0;
1948
1949 error0:
1950         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1951         return error;
1952 }
1953
1954 /*
1955  * Move 1 record left from cur/level if possible.
1956  * Update cur to reflect the new path.
1957  */
1958 STATIC int                                      /* error */
1959 xfs_btree_lshift(
1960         struct xfs_btree_cur    *cur,
1961         int                     level,
1962         int                     *stat)          /* success/failure */
1963 {
1964         union xfs_btree_key     key;            /* btree key */
1965         struct xfs_buf          *lbp;           /* left buffer pointer */
1966         struct xfs_btree_block  *left;          /* left btree block */
1967         int                     lrecs;          /* left record count */
1968         struct xfs_buf          *rbp;           /* right buffer pointer */
1969         struct xfs_btree_block  *right;         /* right btree block */
1970         int                     rrecs;          /* right record count */
1971         union xfs_btree_ptr     lptr;           /* left btree pointer */
1972         union xfs_btree_key     *rkp = NULL;    /* right btree key */
1973         union xfs_btree_ptr     *rpp = NULL;    /* right address pointer */
1974         union xfs_btree_rec     *rrp = NULL;    /* right record pointer */
1975         int                     error;          /* error return value */
1976
1977         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1978         XFS_BTREE_TRACE_ARGI(cur, level);
1979
1980         if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
1981             level == cur->bc_nlevels - 1)
1982                 goto out0;
1983
1984         /* Set up variables for this block as "right". */
1985         right = xfs_btree_get_block(cur, level, &rbp);
1986
1987 #ifdef DEBUG
1988         error = xfs_btree_check_block(cur, right, level, rbp);
1989         if (error)
1990                 goto error0;
1991 #endif
1992
1993         /* If we've got no left sibling then we can't shift an entry left. */
1994         xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
1995         if (xfs_btree_ptr_is_null(cur, &lptr))
1996                 goto out0;
1997
1998         /*
1999          * If the cursor entry is the one that would be moved, don't
2000          * do it... it's too complicated.
2001          */
2002         if (cur->bc_ptrs[level] <= 1)
2003                 goto out0;
2004
2005         /* Set up the left neighbor as "left". */
2006         error = xfs_btree_read_buf_block(cur, &lptr, level, 0, &left, &lbp);
2007         if (error)
2008                 goto error0;
2009
2010         /* If it's full, it can't take another entry. */
2011         lrecs = xfs_btree_get_numrecs(left);
2012         if (lrecs == cur->bc_ops->get_maxrecs(cur, level))
2013                 goto out0;
2014
2015         rrecs = xfs_btree_get_numrecs(right);
2016
2017         /*
2018          * We add one entry to the left side and remove one for the right side.
2019          * Account for it here, the changes will be updated on disk and logged
2020          * later.
2021          */
2022         lrecs++;
2023         rrecs--;
2024
2025         XFS_BTREE_STATS_INC(cur, lshift);
2026         XFS_BTREE_STATS_ADD(cur, moves, 1);
2027
2028         /*
2029          * If non-leaf, copy a key and a ptr to the left block.
2030          * Log the changes to the left block.
2031          */
2032         if (level > 0) {
2033                 /* It's a non-leaf.  Move keys and pointers. */
2034                 union xfs_btree_key     *lkp;   /* left btree key */
2035                 union xfs_btree_ptr     *lpp;   /* left address pointer */
2036
2037                 lkp = xfs_btree_key_addr(cur, lrecs, left);
2038                 rkp = xfs_btree_key_addr(cur, 1, right);
2039
2040                 lpp = xfs_btree_ptr_addr(cur, lrecs, left);
2041                 rpp = xfs_btree_ptr_addr(cur, 1, right);
2042 #ifdef DEBUG
2043                 error = xfs_btree_check_ptr(cur, rpp, 0, level);
2044                 if (error)
2045                         goto error0;
2046 #endif
2047                 xfs_btree_copy_keys(cur, lkp, rkp, 1);
2048                 xfs_btree_copy_ptrs(cur, lpp, rpp, 1);
2049
2050                 xfs_btree_log_keys(cur, lbp, lrecs, lrecs);
2051                 xfs_btree_log_ptrs(cur, lbp, lrecs, lrecs);
2052
2053                 ASSERT(cur->bc_ops->keys_inorder(cur,
2054                         xfs_btree_key_addr(cur, lrecs - 1, left), lkp));
2055         } else {
2056                 /* It's a leaf.  Move records.  */
2057                 union xfs_btree_rec     *lrp;   /* left record pointer */
2058
2059                 lrp = xfs_btree_rec_addr(cur, lrecs, left);
2060                 rrp = xfs_btree_rec_addr(cur, 1, right);
2061
2062                 xfs_btree_copy_recs(cur, lrp, rrp, 1);
2063                 xfs_btree_log_recs(cur, lbp, lrecs, lrecs);
2064
2065                 ASSERT(cur->bc_ops->recs_inorder(cur,
2066                         xfs_btree_rec_addr(cur, lrecs - 1, left), lrp));
2067         }
2068
2069         xfs_btree_set_numrecs(left, lrecs);
2070         xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS);
2071
2072         xfs_btree_set_numrecs(right, rrecs);
2073         xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS);
2074
2075         /*
2076          * Slide the contents of right down one entry.
2077          */
2078         XFS_BTREE_STATS_ADD(cur, moves, rrecs - 1);
2079         if (level > 0) {
2080                 /* It's a nonleaf. operate on keys and ptrs */
2081 #ifdef DEBUG
2082                 int                     i;              /* loop index */
2083
2084                 for (i = 0; i < rrecs; i++) {
2085                         error = xfs_btree_check_ptr(cur, rpp, i + 1, level);
2086                         if (error)
2087                                 goto error0;
2088                 }
2089 #endif
2090                 xfs_btree_shift_keys(cur,
2091                                 xfs_btree_key_addr(cur, 2, right),
2092                                 -1, rrecs);
2093                 xfs_btree_shift_ptrs(cur,
2094                                 xfs_btree_ptr_addr(cur, 2, right),
2095                                 -1, rrecs);
2096
2097                 xfs_btree_log_keys(cur, rbp, 1, rrecs);
2098                 xfs_btree_log_ptrs(cur, rbp, 1, rrecs);
2099         } else {
2100                 /* It's a leaf. operate on records */
2101                 xfs_btree_shift_recs(cur,
2102                         xfs_btree_rec_addr(cur, 2, right),
2103                         -1, rrecs);
2104                 xfs_btree_log_recs(cur, rbp, 1, rrecs);
2105
2106                 /*
2107                  * If it's the first record in the block, we'll need a key
2108                  * structure to pass up to the next level (updkey).
2109                  */
2110                 cur->bc_ops->init_key_from_rec(&key,
2111                         xfs_btree_rec_addr(cur, 1, right));
2112                 rkp = &key;
2113         }
2114
2115         /* Update the parent key values of right. */
2116         error = xfs_btree_updkey(cur, rkp, level + 1);
2117         if (error)
2118                 goto error0;
2119
2120         /* Slide the cursor value left one. */
2121         cur->bc_ptrs[level]--;
2122
2123         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2124         *stat = 1;
2125         return 0;
2126
2127 out0:
2128         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2129         *stat = 0;
2130         return 0;
2131
2132 error0:
2133         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
2134         return error;
2135 }
2136
2137 /*
2138  * Move 1 record right from cur/level if possible.
2139  * Update cur to reflect the new path.
2140  */
2141 STATIC int                                      /* error */
2142 xfs_btree_rshift(
2143         struct xfs_btree_cur    *cur,
2144         int                     level,
2145         int                     *stat)          /* success/failure */
2146 {
2147         union xfs_btree_key     key;            /* btree key */
2148         struct xfs_buf          *lbp;           /* left buffer pointer */
2149         struct xfs_btree_block  *left;          /* left btree block */
2150         struct xfs_buf          *rbp;           /* right buffer pointer */
2151         struct xfs_btree_block  *right;         /* right btree block */
2152         struct xfs_btree_cur    *tcur;          /* temporary btree cursor */
2153         union xfs_btree_ptr     rptr;           /* right block pointer */
2154         union xfs_btree_key     *rkp;           /* right btree key */
2155         int                     rrecs;          /* right record count */
2156         int                     lrecs;          /* left record count */
2157         int                     error;          /* error return value */
2158         int                     i;              /* loop counter */
2159
2160         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
2161         XFS_BTREE_TRACE_ARGI(cur, level);
2162
2163         if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
2164             (level == cur->bc_nlevels - 1))
2165                 goto out0;
2166
2167         /* Set up variables for this block as "left". */
2168         left = xfs_btree_get_block(cur, level, &lbp);
2169
2170 #ifdef DEBUG
2171         error = xfs_btree_check_block(cur, left, level, lbp);
2172         if (error)
2173                 goto error0;
2174 #endif
2175
2176         /* If we've got no right sibling then we can't shift an entry right. */
2177         xfs_btree_get_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB);
2178         if (xfs_btree_ptr_is_null(cur, &rptr))
2179                 goto out0;
2180
2181         /*
2182          * If the cursor entry is the one that would be moved, don't
2183          * do it... it's too complicated.
2184          */
2185         lrecs = xfs_btree_get_numrecs(left);
2186         if (cur->bc_ptrs[level] >= lrecs)
2187                 goto out0;
2188
2189         /* Set up the right neighbor as "right". */
2190         error = xfs_btree_read_buf_block(cur, &rptr, level, 0, &right, &rbp);
2191         if (error)
2192                 goto error0;
2193
2194         /* If it's full, it can't take another entry. */
2195         rrecs = xfs_btree_get_numrecs(right);
2196         if (rrecs == cur->bc_ops->get_maxrecs(cur, level))
2197                 goto out0;
2198
2199         XFS_BTREE_STATS_INC(cur, rshift);
2200         XFS_BTREE_STATS_ADD(cur, moves, rrecs);
2201
2202         /*
2203          * Make a hole at the start of the right neighbor block, then
2204          * copy the last left block entry to the hole.
2205          */
2206         if (level > 0) {
2207                 /* It's a nonleaf. make a hole in the keys and ptrs */
2208                 union xfs_btree_key     *lkp;
2209                 union xfs_btree_ptr     *lpp;
2210                 union xfs_btree_ptr     *rpp;
2211
2212                 lkp = xfs_btree_key_addr(cur, lrecs, left);
2213                 lpp = xfs_btree_ptr_addr(cur, lrecs, left);
2214                 rkp = xfs_btree_key_addr(cur, 1, right);
2215                 rpp = xfs_btree_ptr_addr(cur, 1, right);
2216
2217 #ifdef DEBUG
2218                 for (i = rrecs - 1; i >= 0; i--) {
2219                         error = xfs_btree_check_ptr(cur, rpp, i, level);
2220                         if (error)
2221                                 goto error0;
2222                 }
2223 #endif
2224
2225                 xfs_btree_shift_keys(cur, rkp, 1, rrecs);
2226                 xfs_btree_shift_ptrs(cur, rpp, 1, rrecs);
2227
2228 #ifdef DEBUG
2229                 error = xfs_btree_check_ptr(cur, lpp, 0, level);
2230                 if (error)
2231                         goto error0;
2232 #endif
2233
2234                 /* Now put the new data in, and log it. */
2235                 xfs_btree_copy_keys(cur, rkp, lkp, 1);
2236                 xfs_btree_copy_ptrs(cur, rpp, lpp, 1);
2237
2238                 xfs_btree_log_keys(cur, rbp, 1, rrecs + 1);
2239                 xfs_btree_log_ptrs(cur, rbp, 1, rrecs + 1);
2240
2241                 ASSERT(cur->bc_ops->keys_inorder(cur, rkp,
2242                         xfs_btree_key_addr(cur, 2, right)));
2243         } else {
2244                 /* It's a leaf. make a hole in the records */
2245                 union xfs_btree_rec     *lrp;
2246                 union xfs_btree_rec     *rrp;
2247
2248                 lrp = xfs_btree_rec_addr(cur, lrecs, left);
2249                 rrp = xfs_btree_rec_addr(cur, 1, right);
2250
2251                 xfs_btree_shift_recs(cur, rrp, 1, rrecs);
2252
2253                 /* Now put the new data in, and log it. */
2254                 xfs_btree_copy_recs(cur, rrp, lrp, 1);
2255                 xfs_btree_log_recs(cur, rbp, 1, rrecs + 1);
2256
2257                 cur->bc_ops->init_key_from_rec(&key, rrp);
2258                 rkp = &key;
2259
2260                 ASSERT(cur->bc_ops->recs_inorder(cur, rrp,
2261                         xfs_btree_rec_addr(cur, 2, right)));
2262         }
2263
2264         /*
2265          * Decrement and log left's numrecs, bump and log right's numrecs.
2266          */
2267         xfs_btree_set_numrecs(left, --lrecs);
2268         xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS);
2269
2270         xfs_btree_set_numrecs(right, ++rrecs);
2271         xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS);
2272
2273         /*
2274          * Using a temporary cursor, update the parent key values of the
2275          * block on the right.
2276          */
2277         error = xfs_btree_dup_cursor(cur, &tcur);
2278         if (error)
2279                 goto error0;
2280         i = xfs_btree_lastrec(tcur, level);
2281         XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
2282
2283         error = xfs_btree_increment(tcur, level, &i);
2284         if (error)
2285                 goto error1;
2286
2287         error = xfs_btree_updkey(tcur, rkp, level + 1);
2288         if (error)
2289                 goto error1;
2290
2291         xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
2292
2293         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2294         *stat = 1;
2295         return 0;
2296
2297 out0:
2298         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2299         *stat = 0;
2300         return 0;
2301
2302 error0:
2303         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
2304         return error;
2305
2306 error1:
2307         XFS_BTREE_TRACE_CURSOR(tcur, XBT_ERROR);
2308         xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
2309         return error;
2310 }
2311
2312 /*
2313  * Split cur/level block in half.
2314  * Return new block number and the key to its first
2315  * record (to be inserted into parent).
2316  */
2317 STATIC int                                      /* error */
2318 xfs_btree_split(
2319         struct xfs_btree_cur    *cur,
2320         int                     level,
2321         union xfs_btree_ptr     *ptrp,
2322         union xfs_btree_key     *key,
2323         struct xfs_btree_cur    **curp,
2324         int                     *stat)          /* success/failure */
2325 {
2326         union xfs_btree_ptr     lptr;           /* left sibling block ptr */
2327         struct xfs_buf          *lbp;           /* left buffer pointer */
2328         struct xfs_btree_block  *left;          /* left btree block */
2329         union xfs_btree_ptr     rptr;           /* right sibling block ptr */
2330         struct xfs_buf          *rbp;           /* right buffer pointer */
2331         struct xfs_btree_block  *right;         /* right btree block */
2332         union xfs_btree_ptr     rrptr;          /* right-right sibling ptr */
2333         struct xfs_buf          *rrbp;          /* right-right buffer pointer */
2334         struct xfs_btree_block  *rrblock;       /* right-right btree block */
2335         int                     lrecs;
2336         int                     rrecs;
2337         int                     src_index;
2338         int                     error;          /* error return value */
2339 #ifdef DEBUG
2340         int                     i;
2341 #endif
2342
2343         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
2344         XFS_BTREE_TRACE_ARGIPK(cur, level, *ptrp, key);
2345
2346         XFS_BTREE_STATS_INC(cur, split);
2347
2348         /* Set up left block (current one). */
2349         left = xfs_btree_get_block(cur, level, &lbp);
2350
2351 #ifdef DEBUG
2352         error = xfs_btree_check_block(cur, left, level, lbp);
2353         if (error)
2354                 goto error0;
2355 #endif
2356
2357         xfs_btree_buf_to_ptr(cur, lbp, &lptr);
2358
2359         /* Allocate the new block. If we can't do it, we're toast. Give up. */
2360         error = cur->bc_ops->alloc_block(cur, &lptr, &rptr, 1, stat);
2361         if (error)
2362                 goto error0;
2363         if (*stat == 0)
2364                 goto out0;
2365         XFS_BTREE_STATS_INC(cur, alloc);
2366
2367         /* Set up the new block as "right". */
2368         error = xfs_btree_get_buf_block(cur, &rptr, 0, &right, &rbp);
2369         if (error)
2370                 goto error0;
2371
2372         /* Fill in the btree header for the new right block. */
2373         xfs_btree_init_block_cur(cur, rbp, xfs_btree_get_level(left), 0);
2374
2375         /*
2376          * Split the entries between the old and the new block evenly.
2377          * Make sure that if there's an odd number of entries now, that
2378          * each new block will have the same number of entries.
2379          */
2380         lrecs = xfs_btree_get_numrecs(left);
2381         rrecs = lrecs / 2;
2382         if ((lrecs & 1) && cur->bc_ptrs[level] <= rrecs + 1)
2383                 rrecs++;
2384         src_index = (lrecs - rrecs + 1);
2385
2386         XFS_BTREE_STATS_ADD(cur, moves, rrecs);
2387
2388         /*
2389          * Copy btree block entries from the left block over to the
2390          * new block, the right. Update the right block and log the
2391          * changes.
2392          */
2393         if (level > 0) {
2394                 /* It's a non-leaf.  Move keys and pointers. */
2395                 union xfs_btree_key     *lkp;   /* left btree key */
2396                 union xfs_btree_ptr     *lpp;   /* left address pointer */
2397                 union xfs_btree_key     *rkp;   /* right btree key */
2398                 union xfs_btree_ptr     *rpp;   /* right address pointer */
2399
2400                 lkp = xfs_btree_key_addr(cur, src_index, left);
2401                 lpp = xfs_btree_ptr_addr(cur, src_index, left);
2402                 rkp = xfs_btree_key_addr(cur, 1, right);
2403                 rpp = xfs_btree_ptr_addr(cur, 1, right);
2404
2405 #ifdef DEBUG
2406                 for (i = src_index; i < rrecs; i++) {
2407                         error = xfs_btree_check_ptr(cur, lpp, i, level);
2408                         if (error)
2409                                 goto error0;
2410                 }
2411 #endif
2412
2413                 xfs_btree_copy_keys(cur, rkp, lkp, rrecs);
2414                 xfs_btree_copy_ptrs(cur, rpp, lpp, rrecs);
2415
2416                 xfs_btree_log_keys(cur, rbp, 1, rrecs);
2417                 xfs_btree_log_ptrs(cur, rbp, 1, rrecs);
2418
2419                 /* Grab the keys to the entries moved to the right block */
2420                 xfs_btree_copy_keys(cur, key, rkp, 1);
2421         } else {
2422                 /* It's a leaf.  Move records.  */
2423                 union xfs_btree_rec     *lrp;   /* left record pointer */
2424                 union xfs_btree_rec     *rrp;   /* right record pointer */
2425
2426                 lrp = xfs_btree_rec_addr(cur, src_index, left);
2427                 rrp = xfs_btree_rec_addr(cur, 1, right);
2428
2429                 xfs_btree_copy_recs(cur, rrp, lrp, rrecs);
2430                 xfs_btree_log_recs(cur, rbp, 1, rrecs);
2431
2432                 cur->bc_ops->init_key_from_rec(key,
2433                         xfs_btree_rec_addr(cur, 1, right));
2434         }
2435
2436
2437         /*
2438          * Find the left block number by looking in the buffer.
2439          * Adjust numrecs, sibling pointers.
2440          */
2441         xfs_btree_get_sibling(cur, left, &rrptr, XFS_BB_RIGHTSIB);
2442         xfs_btree_set_sibling(cur, right, &rrptr, XFS_BB_RIGHTSIB);
2443         xfs_btree_set_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
2444         xfs_btree_set_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB);
2445
2446         lrecs -= rrecs;
2447         xfs_btree_set_numrecs(left, lrecs);
2448         xfs_btree_set_numrecs(right, xfs_btree_get_numrecs(right) + rrecs);
2449
2450         xfs_btree_log_block(cur, rbp, XFS_BB_ALL_BITS);
2451         xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
2452
2453         /*
2454          * If there's a block to the new block's right, make that block
2455          * point back to right instead of to left.
2456          */
2457         if (!xfs_btree_ptr_is_null(cur, &rrptr)) {
2458                 error = xfs_btree_read_buf_block(cur, &rrptr, level,
2459                                                         0, &rrblock, &rrbp);
2460                 if (error)
2461                         goto error0;
2462                 xfs_btree_set_sibling(cur, rrblock, &rptr, XFS_BB_LEFTSIB);
2463                 xfs_btree_log_block(cur, rrbp, XFS_BB_LEFTSIB);
2464         }
2465         /*
2466          * If the cursor is really in the right block, move it there.
2467          * If it's just pointing past the last entry in left, then we'll
2468          * insert there, so don't change anything in that case.
2469          */
2470         if (cur->bc_ptrs[level] > lrecs + 1) {
2471                 xfs_btree_setbuf(cur, level, rbp);
2472                 cur->bc_ptrs[level] -= lrecs;
2473         }
2474         /*
2475          * If there are more levels, we'll need another cursor which refers
2476          * the right block, no matter where this cursor was.
2477          */
2478         if (level + 1 < cur->bc_nlevels) {
2479                 error = xfs_btree_dup_cursor(cur, curp);
2480                 if (error)
2481                         goto error0;
2482                 (*curp)->bc_ptrs[level + 1]++;
2483         }
2484         *ptrp = rptr;
2485         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2486         *stat = 1;
2487         return 0;
2488 out0:
2489         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2490         *stat = 0;
2491         return 0;
2492
2493 error0:
2494         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
2495         return error;
2496 }
2497
2498 /*
2499  * Copy the old inode root contents into a real block and make the
2500  * broot point to it.
2501  */
2502 int                                             /* error */
2503 xfs_btree_new_iroot(
2504         struct xfs_btree_cur    *cur,           /* btree cursor */
2505         int                     *logflags,      /* logging flags for inode */
2506         int                     *stat)          /* return status - 0 fail */
2507 {
2508         struct xfs_buf          *cbp;           /* buffer for cblock */
2509         struct xfs_btree_block  *block;         /* btree block */
2510         struct xfs_btree_block  *cblock;        /* child btree block */
2511         union xfs_btree_key     *ckp;           /* child key pointer */
2512         union xfs_btree_ptr     *cpp;           /* child ptr pointer */
2513         union xfs_btree_key     *kp;            /* pointer to btree key */
2514         union xfs_btree_ptr     *pp;            /* pointer to block addr */
2515         union xfs_btree_ptr     nptr;           /* new block addr */
2516         int                     level;          /* btree level */
2517         int                     error;          /* error return code */
2518 #ifdef DEBUG
2519         int                     i;              /* loop counter */
2520 #endif
2521
2522         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
2523         XFS_BTREE_STATS_INC(cur, newroot);
2524
2525         ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
2526
2527         level = cur->bc_nlevels - 1;
2528
2529         block = xfs_btree_get_iroot(cur);
2530         pp = xfs_btree_ptr_addr(cur, 1, block);
2531
2532         /* Allocate the new block. If we can't do it, we're toast. Give up. */
2533         error = cur->bc_ops->alloc_block(cur, pp, &nptr, 1, stat);
2534         if (error)
2535                 goto error0;
2536         if (*stat == 0) {
2537                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2538                 return 0;
2539         }
2540         XFS_BTREE_STATS_INC(cur, alloc);
2541
2542         /* Copy the root into a real block. */
2543         error = xfs_btree_get_buf_block(cur, &nptr, 0, &cblock, &cbp);
2544         if (error)
2545                 goto error0;
2546
2547         memcpy(cblock, block, xfs_btree_block_len(cur));
2548
2549         be16_add_cpu(&block->bb_level, 1);
2550         xfs_btree_set_numrecs(block, 1);
2551         cur->bc_nlevels++;
2552         cur->bc_ptrs[level + 1] = 1;
2553
2554         kp = xfs_btree_key_addr(cur, 1, block);
2555         ckp = xfs_btree_key_addr(cur, 1, cblock);
2556         xfs_btree_copy_keys(cur, ckp, kp, xfs_btree_get_numrecs(cblock));
2557
2558         cpp = xfs_btree_ptr_addr(cur, 1, cblock);
2559 #ifdef DEBUG
2560         for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
2561                 error = xfs_btree_check_ptr(cur, pp, i, level);
2562                 if (error)
2563                         goto error0;
2564         }
2565 #endif
2566         xfs_btree_copy_ptrs(cur, cpp, pp, xfs_btree_get_numrecs(cblock));
2567
2568 #ifdef DEBUG
2569         error = xfs_btree_check_ptr(cur, &nptr, 0, level);
2570         if (error)
2571                 goto error0;
2572 #endif
2573         xfs_btree_copy_ptrs(cur, pp, &nptr, 1);
2574
2575         xfs_iroot_realloc(cur->bc_private.b.ip,
2576                           1 - xfs_btree_get_numrecs(cblock),
2577                           cur->bc_private.b.whichfork);
2578
2579         xfs_btree_setbuf(cur, level, cbp);
2580
2581         /*
2582          * Do all this logging at the end so that
2583          * the root is at the right level.
2584          */
2585         xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS);
2586         xfs_btree_log_keys(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs));
2587         xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs));
2588
2589         *logflags |=
2590                 XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork);
2591         *stat = 1;
2592         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2593         return 0;
2594 error0:
2595         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
2596         return error;
2597 }
2598
2599 /*
2600  * Allocate a new root block, fill it in.
2601  */
2602 STATIC int                              /* error */
2603 xfs_btree_new_root(
2604         struct xfs_btree_cur    *cur,   /* btree cursor */
2605         int                     *stat)  /* success/failure */
2606 {
2607         struct xfs_btree_block  *block; /* one half of the old root block */
2608         struct xfs_buf          *bp;    /* buffer containing block */
2609         int                     error;  /* error return value */
2610         struct xfs_buf          *lbp;   /* left buffer pointer */
2611         struct xfs_btree_block  *left;  /* left btree block */
2612         struct xfs_buf          *nbp;   /* new (root) buffer */
2613         struct xfs_btree_block  *new;   /* new (root) btree block */
2614         int                     nptr;   /* new value for key index, 1 or 2 */
2615         struct xfs_buf          *rbp;   /* right buffer pointer */
2616         struct xfs_btree_block  *right; /* right btree block */
2617         union xfs_btree_ptr     rptr;
2618         union xfs_btree_ptr     lptr;
2619
2620         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
2621         XFS_BTREE_STATS_INC(cur, newroot);
2622
2623         /* initialise our start point from the cursor */
2624         cur->bc_ops->init_ptr_from_cur(cur, &rptr);
2625
2626         /* Allocate the new block. If we can't do it, we're toast. Give up. */
2627         error = cur->bc_ops->alloc_block(cur, &rptr, &lptr, 1, stat);
2628         if (error)
2629                 goto error0;
2630         if (*stat == 0)
2631                 goto out0;
2632         XFS_BTREE_STATS_INC(cur, alloc);
2633
2634         /* Set up the new block. */
2635         error = xfs_btree_get_buf_block(cur, &lptr, 0, &new, &nbp);
2636         if (error)
2637                 goto error0;
2638
2639         /* Set the root in the holding structure  increasing the level by 1. */
2640         cur->bc_ops->set_root(cur, &lptr, 1);
2641
2642         /*
2643          * At the previous root level there are now two blocks: the old root,
2644          * and the new block generated when it was split.  We don't know which
2645          * one the cursor is pointing at, so we set up variables "left" and
2646          * "right" for each case.
2647          */
2648         block = xfs_btree_get_block(cur, cur->bc_nlevels - 1, &bp);
2649
2650 #ifdef DEBUG
2651         error = xfs_btree_check_block(cur, block, cur->bc_nlevels - 1, bp);
2652         if (error)
2653                 goto error0;
2654 #endif
2655
2656         xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB);
2657         if (!xfs_btree_ptr_is_null(cur, &rptr)) {
2658                 /* Our block is left, pick up the right block. */
2659                 lbp = bp;
2660                 xfs_btree_buf_to_ptr(cur, lbp, &lptr);
2661                 left = block;
2662                 error = xfs_btree_read_buf_block(cur, &rptr,
2663                                         cur->bc_nlevels - 1, 0, &right, &rbp);
2664                 if (error)
2665                         goto error0;
2666                 bp = rbp;
2667                 nptr = 1;
2668         } else {
2669                 /* Our block is right, pick up the left block. */
2670                 rbp = bp;
2671                 xfs_btree_buf_to_ptr(cur, rbp, &rptr);
2672                 right = block;
2673                 xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
2674                 error = xfs_btree_read_buf_block(cur, &lptr,
2675                                         cur->bc_nlevels - 1, 0, &left, &lbp);
2676                 if (error)
2677                         goto error0;
2678                 bp = lbp;
2679                 nptr = 2;
2680         }
2681         /* Fill in the new block's btree header and log it. */
2682         xfs_btree_init_block_cur(cur, nbp, cur->bc_nlevels, 2);
2683         xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS);
2684         ASSERT(!xfs_btree_ptr_is_null(cur, &lptr) &&
2685                         !xfs_btree_ptr_is_null(cur, &rptr));
2686
2687         /* Fill in the key data in the new root. */
2688         if (xfs_btree_get_level(left) > 0) {
2689                 xfs_btree_copy_keys(cur,
2690                                 xfs_btree_key_addr(cur, 1, new),
2691                                 xfs_btree_key_addr(cur, 1, left), 1);
2692                 xfs_btree_copy_keys(cur,
2693                                 xfs_btree_key_addr(cur, 2, new),
2694                                 xfs_btree_key_addr(cur, 1, right), 1);
2695         } else {
2696                 cur->bc_ops->init_key_from_rec(
2697                                 xfs_btree_key_addr(cur, 1, new),
2698                                 xfs_btree_rec_addr(cur, 1, left));
2699                 cur->bc_ops->init_key_from_rec(
2700                                 xfs_btree_key_addr(cur, 2, new),
2701                                 xfs_btree_rec_addr(cur, 1, right));
2702         }
2703         xfs_btree_log_keys(cur, nbp, 1, 2);
2704
2705         /* Fill in the pointer data in the new root. */
2706         xfs_btree_copy_ptrs(cur,
2707                 xfs_btree_ptr_addr(cur, 1, new), &lptr, 1);
2708         xfs_btree_copy_ptrs(cur,
2709                 xfs_btree_ptr_addr(cur, 2, new), &rptr, 1);
2710         xfs_btree_log_ptrs(cur, nbp, 1, 2);
2711
2712         /* Fix up the cursor. */
2713         xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
2714         cur->bc_ptrs[cur->bc_nlevels] = nptr;
2715         cur->bc_nlevels++;
2716         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2717         *stat = 1;
2718         return 0;
2719 error0:
2720         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
2721         return error;
2722 out0:
2723         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2724         *stat = 0;
2725         return 0;
2726 }
2727
2728 STATIC int
2729 xfs_btree_make_block_unfull(
2730         struct xfs_btree_cur    *cur,   /* btree cursor */
2731         int                     level,  /* btree level */
2732         int                     numrecs,/* # of recs in block */
2733         int                     *oindex,/* old tree index */
2734         int                     *index, /* new tree index */
2735         union xfs_btree_ptr     *nptr,  /* new btree ptr */
2736         struct xfs_btree_cur    **ncur, /* new btree cursor */
2737         union xfs_btree_rec     *nrec,  /* new record */
2738         int                     *stat)
2739 {
2740         union xfs_btree_key     key;    /* new btree key value */
2741         int                     error = 0;
2742
2743         if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
2744             level == cur->bc_nlevels - 1) {
2745                 struct xfs_inode *ip = cur->bc_private.b.ip;
2746
2747                 if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) {
2748                         /* A root block that can be made bigger. */
2749
2750                         xfs_iroot_realloc(ip, 1, cur->bc_private.b.whichfork);
2751                 } else {
2752                         /* A root block that needs replacing */
2753                         int     logflags = 0;
2754
2755                         error = xfs_btree_new_iroot(cur, &logflags, stat);
2756                         if (error || *stat == 0)
2757                                 return error;
2758
2759                         xfs_trans_log_inode(cur->bc_tp, ip, logflags);
2760                 }
2761
2762                 return 0;
2763         }
2764
2765         /* First, try shifting an entry to the right neighbor. */
2766         error = xfs_btree_rshift(cur, level, stat);
2767         if (error || *stat)
2768                 return error;
2769
2770         /* Next, try shifting an entry to the left neighbor. */
2771         error = xfs_btree_lshift(cur, level, stat);
2772         if (error)
2773                 return error;
2774
2775         if (*stat) {
2776                 *oindex = *index = cur->bc_ptrs[level];
2777                 return 0;
2778         }
2779
2780         /*
2781          * Next, try splitting the current block in half.
2782          *
2783          * If this works we have to re-set our variables because we
2784          * could be in a different block now.
2785          */
2786         error = xfs_btree_split(cur, level, nptr, &key, ncur, stat);
2787         if (error || *stat == 0)
2788                 return error;
2789
2790
2791         *index = cur->bc_ptrs[level];
2792         cur->bc_ops->init_rec_from_key(&key, nrec);
2793         return 0;
2794 }
2795
2796 /*
2797  * Insert one record/level.  Return information to the caller
2798  * allowing the next level up to proceed if necessary.
2799  */
2800 STATIC int
2801 xfs_btree_insrec(
2802         struct xfs_btree_cur    *cur,   /* btree cursor */
2803         int                     level,  /* level to insert record at */
2804         union xfs_btree_ptr     *ptrp,  /* i/o: block number inserted */
2805         union xfs_btree_rec     *recp,  /* i/o: record data inserted */
2806         struct xfs_btree_cur    **curp, /* output: new cursor replacing cur */
2807         int                     *stat)  /* success/failure */
2808 {
2809         struct xfs_btree_block  *block; /* btree block */
2810         struct xfs_buf          *bp;    /* buffer for block */
2811         union xfs_btree_key     key;    /* btree key */
2812         union xfs_btree_ptr     nptr;   /* new block ptr */
2813         struct xfs_btree_cur    *ncur;  /* new btree cursor */
2814         union xfs_btree_rec     nrec;   /* new record count */
2815         int                     optr;   /* old key/record index */
2816         int                     ptr;    /* key/record index */
2817         int                     numrecs;/* number of records */
2818         int                     error;  /* error return value */
2819 #ifdef DEBUG
2820         int                     i;
2821 #endif
2822
2823         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
2824         XFS_BTREE_TRACE_ARGIPR(cur, level, *ptrp, recp);
2825
2826         ncur = NULL;
2827
2828         /*
2829          * If we have an external root pointer, and we've made it to the
2830          * root level, allocate a new root block and we're done.
2831          */
2832         if (!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
2833             (level >= cur->bc_nlevels)) {
2834                 error = xfs_btree_new_root(cur, stat);
2835                 xfs_btree_set_ptr_null(cur, ptrp);
2836
2837                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2838                 return error;
2839         }
2840
2841         /* If we're off the left edge, return failure. */
2842         ptr = cur->bc_ptrs[level];
2843         if (ptr == 0) {
2844                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2845                 *stat = 0;
2846                 return 0;
2847         }
2848
2849         /* Make a key out of the record data to be inserted, and save it. */
2850         cur->bc_ops->init_key_from_rec(&key, recp);
2851
2852         optr = ptr;
2853
2854         XFS_BTREE_STATS_INC(cur, insrec);
2855
2856         /* Get pointers to the btree buffer and block. */
2857         block = xfs_btree_get_block(cur, level, &bp);
2858         numrecs = xfs_btree_get_numrecs(block);
2859
2860 #ifdef DEBUG
2861         error = xfs_btree_check_block(cur, block, level, bp);
2862         if (error)
2863                 goto error0;
2864
2865         /* Check that the new entry is being inserted in the right place. */
2866         if (ptr <= numrecs) {
2867                 if (level == 0) {
2868                         ASSERT(cur->bc_ops->recs_inorder(cur, recp,
2869                                 xfs_btree_rec_addr(cur, ptr, block)));
2870                 } else {
2871                         ASSERT(cur->bc_ops->keys_inorder(cur, &key,
2872                                 xfs_btree_key_addr(cur, ptr, block)));
2873                 }
2874         }
2875 #endif
2876
2877         /*
2878          * If the block is full, we can't insert the new entry until we
2879          * make the block un-full.
2880          */
2881         xfs_btree_set_ptr_null(cur, &nptr);
2882         if (numrecs == cur->bc_ops->get_maxrecs(cur, level)) {
2883                 error = xfs_btree_make_block_unfull(cur, level, numrecs,
2884                                         &optr, &ptr, &nptr, &ncur, &nrec, stat);
2885                 if (error || *stat == 0)
2886                         goto error0;
2887         }
2888
2889         /*
2890          * The current block may have changed if the block was
2891          * previously full and we have just made space in it.
2892          */
2893         block = xfs_btree_get_block(cur, level, &bp);
2894         numrecs = xfs_btree_get_numrecs(block);
2895
2896 #ifdef DEBUG
2897         error = xfs_btree_check_block(cur, block, level, bp);
2898         if (error)
2899                 return error;
2900 #endif
2901
2902         /*
2903          * At this point we know there's room for our new entry in the block
2904          * we're pointing at.
2905          */
2906         XFS_BTREE_STATS_ADD(cur, moves, numrecs - ptr + 1);
2907
2908         if (level > 0) {
2909                 /* It's a nonleaf. make a hole in the keys and ptrs */
2910                 union xfs_btree_key     *kp;
2911                 union xfs_btree_ptr     *pp;
2912
2913                 kp = xfs_btree_key_addr(cur, ptr, block);
2914                 pp = xfs_btree_ptr_addr(cur, ptr, block);
2915
2916 #ifdef DEBUG
2917                 for (i = numrecs - ptr; i >= 0; i--) {
2918                         error = xfs_btree_check_ptr(cur, pp, i, level);
2919                         if (error)
2920                                 return error;
2921                 }
2922 #endif
2923
2924                 xfs_btree_shift_keys(cur, kp, 1, numrecs - ptr + 1);
2925                 xfs_btree_shift_ptrs(cur, pp, 1, numrecs - ptr + 1);
2926
2927 #ifdef DEBUG
2928                 error = xfs_btree_check_ptr(cur, ptrp, 0, level);
2929                 if (error)
2930                         goto error0;
2931 #endif
2932
2933                 /* Now put the new data in, bump numrecs and log it. */
2934                 xfs_btree_copy_keys(cur, kp, &key, 1);
2935                 xfs_btree_copy_ptrs(cur, pp, ptrp, 1);
2936                 numrecs++;
2937                 xfs_btree_set_numrecs(block, numrecs);
2938                 xfs_btree_log_ptrs(cur, bp, ptr, numrecs);
2939                 xfs_btree_log_keys(cur, bp, ptr, numrecs);
2940 #ifdef DEBUG
2941                 if (ptr < numrecs) {
2942                         ASSERT(cur->bc_ops->keys_inorder(cur, kp,
2943                                 xfs_btree_key_addr(cur, ptr + 1, block)));
2944                 }
2945 #endif
2946         } else {
2947                 /* It's a leaf. make a hole in the records */
2948                 union xfs_btree_rec             *rp;
2949
2950                 rp = xfs_btree_rec_addr(cur, ptr, block);
2951
2952                 xfs_btree_shift_recs(cur, rp, 1, numrecs - ptr + 1);
2953
2954                 /* Now put the new data in, bump numrecs and log it. */
2955                 xfs_btree_copy_recs(cur, rp, recp, 1);
2956                 xfs_btree_set_numrecs(block, ++numrecs);
2957                 xfs_btree_log_recs(cur, bp, ptr, numrecs);
2958 #ifdef DEBUG
2959                 if (ptr < numrecs) {
2960                         ASSERT(cur->bc_ops->recs_inorder(cur, rp,
2961                                 xfs_btree_rec_addr(cur, ptr + 1, block)));
2962                 }
2963 #endif
2964         }
2965
2966         /* Log the new number of records in the btree header. */
2967         xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS);
2968
2969         /* If we inserted at the start of a block, update the parents' keys. */
2970         if (optr == 1) {
2971                 error = xfs_btree_updkey(cur, &key, level + 1);
2972                 if (error)
2973                         goto error0;
2974         }
2975
2976         /*
2977          * If we are tracking the last record in the tree and
2978          * we are at the far right edge of the tree, update it.
2979          */
2980         if (xfs_btree_is_lastrec(cur, block, level)) {
2981                 cur->bc_ops->update_lastrec(cur, block, recp,
2982                                             ptr, LASTREC_INSREC);
2983         }
2984
2985         /*
2986          * Return the new block number, if any.
2987          * If there is one, give back a record value and a cursor too.
2988          */
2989         *ptrp = nptr;
2990         if (!xfs_btree_ptr_is_null(cur, &nptr)) {
2991                 *recp = nrec;
2992                 *curp = ncur;
2993         }
2994
2995         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
2996         *stat = 1;
2997         return 0;
2998
2999 error0:
3000         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
3001         return error;
3002 }
3003
3004 /*
3005  * Insert the record at the point referenced by cur.
3006  *
3007  * A multi-level split of the tree on insert will invalidate the original
3008  * cursor.  All callers of this function should assume that the cursor is
3009  * no longer valid and revalidate it.
3010  */
3011 int
3012 xfs_btree_insert(
3013         struct xfs_btree_cur    *cur,
3014         int                     *stat)
3015 {
3016         int                     error;  /* error return value */
3017         int                     i;      /* result value, 0 for failure */
3018         int                     level;  /* current level number in btree */
3019         union xfs_btree_ptr     nptr;   /* new block number (split result) */
3020         struct xfs_btree_cur    *ncur;  /* new cursor (split result) */
3021         struct xfs_btree_cur    *pcur;  /* previous level's cursor */
3022         union xfs_btree_rec     rec;    /* record to insert */
3023
3024         level = 0;
3025         ncur = NULL;
3026         pcur = cur;
3027
3028         xfs_btree_set_ptr_null(cur, &nptr);
3029         cur->bc_ops->init_rec_from_cur(cur, &rec);
3030
3031         /*
3032          * Loop going up the tree, starting at the leaf level.
3033          * Stop when we don't get a split block, that must mean that
3034          * the insert is finished with this level.
3035          */
3036         do {
3037                 /*
3038                  * Insert nrec/nptr into this level of the tree.
3039                  * Note if we fail, nptr will be null.
3040                  */
3041                 error = xfs_btree_insrec(pcur, level, &nptr, &rec, &ncur, &i);
3042                 if (error) {
3043                         if (pcur != cur)
3044                                 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
3045                         goto error0;
3046                 }
3047
3048                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3049                 level++;
3050
3051                 /*
3052                  * See if the cursor we just used is trash.
3053                  * Can't trash the caller's cursor, but otherwise we should
3054                  * if ncur is a new cursor or we're about to be done.
3055                  */
3056                 if (pcur != cur &&
3057                     (ncur || xfs_btree_ptr_is_null(cur, &nptr))) {
3058                         /* Save the state from the cursor before we trash it */
3059                         if (cur->bc_ops->update_cursor)
3060                                 cur->bc_ops->update_cursor(pcur, cur);
3061                         cur->bc_nlevels = pcur->bc_nlevels;
3062                         xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
3063                 }
3064                 /* If we got a new cursor, switch to it. */
3065                 if (ncur) {
3066                         pcur = ncur;
3067                         ncur = NULL;
3068                 }
3069         } while (!xfs_btree_ptr_is_null(cur, &nptr));
3070
3071         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3072         *stat = i;
3073         return 0;
3074 error0:
3075         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
3076         return error;
3077 }
3078
3079 /*
3080  * Try to merge a non-leaf block back into the inode root.
3081  *
3082  * Note: the killroot names comes from the fact that we're effectively
3083  * killing the old root block.  But because we can't just delete the
3084  * inode we have to copy the single block it was pointing to into the
3085  * inode.
3086  */
3087 STATIC int
3088 xfs_btree_kill_iroot(
3089         struct xfs_btree_cur    *cur)
3090 {
3091         int                     whichfork = cur->bc_private.b.whichfork;
3092         struct xfs_inode        *ip = cur->bc_private.b.ip;
3093         struct xfs_ifork        *ifp = XFS_IFORK_PTR(ip, whichfork);
3094         struct xfs_btree_block  *block;
3095         struct xfs_btree_block  *cblock;
3096         union xfs_btree_key     *kp;
3097         union xfs_btree_key     *ckp;
3098         union xfs_btree_ptr     *pp;
3099         union xfs_btree_ptr     *cpp;
3100         struct xfs_buf          *cbp;
3101         int                     level;
3102         int                     index;
3103         int                     numrecs;
3104 #ifdef DEBUG
3105         union xfs_btree_ptr     ptr;
3106         int                     i;
3107 #endif
3108
3109         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
3110
3111         ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
3112         ASSERT(cur->bc_nlevels > 1);
3113
3114         /*
3115          * Don't deal with the root block needs to be a leaf case.
3116          * We're just going to turn the thing back into extents anyway.
3117          */
3118         level = cur->bc_nlevels - 1;
3119         if (level == 1)
3120                 goto out0;
3121
3122         /*
3123          * Give up if the root has multiple children.
3124          */
3125         block = xfs_btree_get_iroot(cur);
3126         if (xfs_btree_get_numrecs(block) != 1)
3127                 goto out0;
3128
3129         cblock = xfs_btree_get_block(cur, level - 1, &cbp);
3130         numrecs = xfs_btree_get_numrecs(cblock);
3131
3132         /*
3133          * Only do this if the next level will fit.
3134          * Then the data must be copied up to the inode,
3135          * instead of freeing the root you free the next level.
3136          */
3137         if (numrecs > cur->bc_ops->get_dmaxrecs(cur, level))
3138                 goto out0;
3139
3140         XFS_BTREE_STATS_INC(cur, killroot);
3141
3142 #ifdef DEBUG
3143         xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB);
3144         ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
3145         xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
3146         ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
3147 #endif
3148
3149         index = numrecs - cur->bc_ops->get_maxrecs(cur, level);
3150         if (index) {
3151                 xfs_iroot_realloc(cur->bc_private.b.ip, index,
3152                                   cur->bc_private.b.whichfork);
3153                 block = ifp->if_broot;
3154         }
3155
3156         be16_add_cpu(&block->bb_numrecs, index);
3157         ASSERT(block->bb_numrecs == cblock->bb_numrecs);
3158
3159         kp = xfs_btree_key_addr(cur, 1, block);
3160         ckp = xfs_btree_key_addr(cur, 1, cblock);
3161         xfs_btree_copy_keys(cur, kp, ckp, numrecs);
3162
3163         pp = xfs_btree_ptr_addr(cur, 1, block);
3164         cpp = xfs_btree_ptr_addr(cur, 1, cblock);
3165 #ifdef DEBUG
3166         for (i = 0; i < numrecs; i++) {
3167                 int             error;
3168
3169                 error = xfs_btree_check_ptr(cur, cpp, i, level - 1);
3170                 if (error) {
3171                         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
3172                         return error;
3173                 }
3174         }
3175 #endif
3176         xfs_btree_copy_ptrs(cur, pp, cpp, numrecs);
3177
3178         cur->bc_ops->free_block(cur, cbp);
3179         XFS_BTREE_STATS_INC(cur, free);
3180
3181         cur->bc_bufs[level - 1] = NULL;
3182         be16_add_cpu(&block->bb_level, -1);
3183         xfs_trans_log_inode(cur->bc_tp, ip,
3184                 XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork));
3185         cur->bc_nlevels--;
3186 out0:
3187         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3188         return 0;
3189 }
3190
3191 /*
3192  * Kill the current root node, and replace it with it's only child node.
3193  */
3194 STATIC int
3195 xfs_btree_kill_root(
3196         struct xfs_btree_cur    *cur,
3197         struct xfs_buf          *bp,
3198         int                     level,
3199         union xfs_btree_ptr     *newroot)
3200 {
3201         int                     error;
3202
3203         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
3204         XFS_BTREE_STATS_INC(cur, killroot);
3205
3206         /*
3207          * Update the root pointer, decreasing the level by 1 and then
3208          * free the old root.
3209          */
3210         cur->bc_ops->set_root(cur, newroot, -1);
3211
3212         error = cur->bc_ops->free_block(cur, bp);
3213         if (error) {
3214                 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
3215                 return error;
3216         }
3217
3218         XFS_BTREE_STATS_INC(cur, free);
3219
3220         cur->bc_bufs[level] = NULL;
3221         cur->bc_ra[level] = 0;
3222         cur->bc_nlevels--;
3223
3224         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3225         return 0;
3226 }
3227
3228 STATIC int
3229 xfs_btree_dec_cursor(
3230         struct xfs_btree_cur    *cur,
3231         int                     level,
3232         int                     *stat)
3233 {
3234         int                     error;
3235         int                     i;
3236
3237         if (level > 0) {
3238                 error = xfs_btree_decrement(cur, level, &i);
3239                 if (error)
3240                         return error;
3241         }
3242
3243         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3244         *stat = 1;
3245         return 0;
3246 }
3247
3248 /*
3249  * Single level of the btree record deletion routine.
3250  * Delete record pointed to by cur/level.
3251  * Remove the record from its block then rebalance the tree.
3252  * Return 0 for error, 1 for done, 2 to go on to the next level.
3253  */
3254 STATIC int                                      /* error */
3255 xfs_btree_delrec(
3256         struct xfs_btree_cur    *cur,           /* btree cursor */
3257         int                     level,          /* level removing record from */
3258         int                     *stat)          /* fail/done/go-on */
3259 {
3260         struct xfs_btree_block  *block;         /* btree block */
3261         union xfs_btree_ptr     cptr;           /* current block ptr */
3262         struct xfs_buf          *bp;            /* buffer for block */
3263         int                     error;          /* error return value */
3264         int                     i;              /* loop counter */
3265         union xfs_btree_key     key;            /* storage for keyp */
3266         union xfs_btree_key     *keyp = &key;   /* passed to the next level */
3267         union xfs_btree_ptr     lptr;           /* left sibling block ptr */
3268         struct xfs_buf          *lbp;           /* left buffer pointer */
3269         struct xfs_btree_block  *left;          /* left btree block */
3270         int                     lrecs = 0;      /* left record count */
3271         int                     ptr;            /* key/record index */
3272         union xfs_btree_ptr     rptr;           /* right sibling block ptr */
3273         struct xfs_buf          *rbp;           /* right buffer pointer */
3274         struct xfs_btree_block  *right;         /* right btree block */
3275         struct xfs_btree_block  *rrblock;       /* right-right btree block */
3276         struct xfs_buf          *rrbp;          /* right-right buffer pointer */
3277         int                     rrecs = 0;      /* right record count */
3278         struct xfs_btree_cur    *tcur;          /* temporary btree cursor */
3279         int                     numrecs;        /* temporary numrec count */
3280
3281         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
3282         XFS_BTREE_TRACE_ARGI(cur, level);
3283
3284         tcur = NULL;
3285
3286         /* Get the index of the entry being deleted, check for nothing there. */
3287         ptr = cur->bc_ptrs[level];
3288         if (ptr == 0) {
3289                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3290                 *stat = 0;
3291                 return 0;
3292         }
3293
3294         /* Get the buffer & block containing the record or key/ptr. */
3295         block = xfs_btree_get_block(cur, level, &bp);
3296         numrecs = xfs_btree_get_numrecs(block);
3297
3298 #ifdef DEBUG
3299         error = xfs_btree_check_block(cur, block, level, bp);
3300         if (error)
3301                 goto error0;
3302 #endif
3303
3304         /* Fail if we're off the end of the block. */
3305         if (ptr > numrecs) {
3306                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3307                 *stat = 0;
3308                 return 0;
3309         }
3310
3311         XFS_BTREE_STATS_INC(cur, delrec);
3312         XFS_BTREE_STATS_ADD(cur, moves, numrecs - ptr);
3313
3314         /* Excise the entries being deleted. */
3315         if (level > 0) {
3316                 /* It's a nonleaf. operate on keys and ptrs */
3317                 union xfs_btree_key     *lkp;
3318                 union xfs_btree_ptr     *lpp;
3319
3320                 lkp = xfs_btree_key_addr(cur, ptr + 1, block);
3321                 lpp = xfs_btree_ptr_addr(cur, ptr + 1, block);
3322
3323 #ifdef DEBUG
3324                 for (i = 0; i < numrecs - ptr; i++) {
3325                         error = xfs_btree_check_ptr(cur, lpp, i, level);
3326                         if (error)
3327                                 goto error0;
3328                 }
3329 #endif
3330
3331                 if (ptr < numrecs) {
3332                         xfs_btree_shift_keys(cur, lkp, -1, numrecs - ptr);
3333                         xfs_btree_shift_ptrs(cur, lpp, -1, numrecs - ptr);
3334                         xfs_btree_log_keys(cur, bp, ptr, numrecs - 1);
3335                         xfs_btree_log_ptrs(cur, bp, ptr, numrecs - 1);
3336                 }
3337
3338                 /*
3339                  * If it's the first record in the block, we'll need to pass a
3340                  * key up to the next level (updkey).
3341                  */
3342                 if (ptr == 1)
3343                         keyp = xfs_btree_key_addr(cur, 1, block);
3344         } else {
3345                 /* It's a leaf. operate on records */
3346                 if (ptr < numrecs) {
3347                         xfs_btree_shift_recs(cur,
3348                                 xfs_btree_rec_addr(cur, ptr + 1, block),
3349                                 -1, numrecs - ptr);
3350                         xfs_btree_log_recs(cur, bp, ptr, numrecs - 1);
3351                 }
3352
3353                 /*
3354                  * If it's the first record in the block, we'll need a key
3355                  * structure to pass up to the next level (updkey).
3356                  */
3357                 if (ptr == 1) {
3358                         cur->bc_ops->init_key_from_rec(&key,
3359                                         xfs_btree_rec_addr(cur, 1, block));
3360                         keyp = &key;
3361                 }
3362         }
3363
3364         /*
3365          * Decrement and log the number of entries in the block.
3366          */
3367         xfs_btree_set_numrecs(block, --numrecs);
3368         xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS);
3369
3370         /*
3371          * If we are tracking the last record in the tree and
3372          * we are at the far right edge of the tree, update it.
3373          */
3374         if (xfs_btree_is_lastrec(cur, block, level)) {
3375                 cur->bc_ops->update_lastrec(cur, block, NULL,
3376                                             ptr, LASTREC_DELREC);
3377         }
3378
3379         /*
3380          * We're at the root level.  First, shrink the root block in-memory.
3381          * Try to get rid of the next level down.  If we can't then there's
3382          * nothing left to do.
3383          */
3384         if (level == cur->bc_nlevels - 1) {
3385                 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
3386                         xfs_iroot_realloc(cur->bc_private.b.ip, -1,
3387                                           cur->bc_private.b.whichfork);
3388
3389                         error = xfs_btree_kill_iroot(cur);
3390                         if (error)
3391                                 goto error0;
3392
3393                         error = xfs_btree_dec_cursor(cur, level, stat);
3394                         if (error)
3395                                 goto error0;
3396                         *stat = 1;
3397                         return 0;
3398                 }
3399
3400                 /*
3401                  * If this is the root level, and there's only one entry left,
3402                  * and it's NOT the leaf level, then we can get rid of this
3403                  * level.
3404                  */
3405                 if (numrecs == 1 && level > 0) {
3406                         union xfs_btree_ptr     *pp;
3407                         /*
3408                          * pp is still set to the first pointer in the block.
3409                          * Make it the new root of the btree.
3410                          */
3411                         pp = xfs_btree_ptr_addr(cur, 1, block);
3412                         error = xfs_btree_kill_root(cur, bp, level, pp);
3413                         if (error)
3414                                 goto error0;
3415                 } else if (level > 0) {
3416                         error = xfs_btree_dec_cursor(cur, level, stat);
3417                         if (error)
3418                                 goto error0;
3419                 }
3420                 *stat = 1;
3421                 return 0;
3422         }
3423
3424         /*
3425          * If we deleted the leftmost entry in the block, update the
3426          * key values above us in the tree.
3427          */
3428         if (ptr == 1) {
3429                 error = xfs_btree_updkey(cur, keyp, level + 1);
3430                 if (error)
3431                         goto error0;
3432         }
3433
3434         /*
3435          * If the number of records remaining in the block is at least
3436          * the minimum, we're done.
3437          */
3438         if (numrecs >= cur->bc_ops->get_minrecs(cur, level)) {
3439                 error = xfs_btree_dec_cursor(cur, level, stat);
3440                 if (error)
3441                         goto error0;
3442                 return 0;
3443         }
3444
3445         /*
3446          * Otherwise, we have to move some records around to keep the
3447          * tree balanced.  Look at the left and right sibling blocks to
3448          * see if we can re-balance by moving only one record.
3449          */
3450         xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB);
3451         xfs_btree_get_sibling(cur, block, &lptr, XFS_BB_LEFTSIB);
3452
3453         if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
3454                 /*
3455                  * One child of root, need to get a chance to copy its contents
3456                  * into the root and delete it. Can't go up to next level,
3457                  * there's nothing to delete there.
3458                  */
3459                 if (xfs_btree_ptr_is_null(cur, &rptr) &&
3460                     xfs_btree_ptr_is_null(cur, &lptr) &&
3461                     level == cur->bc_nlevels - 2) {
3462                         error = xfs_btree_kill_iroot(cur);
3463                         if (!error)
3464                                 error = xfs_btree_dec_cursor(cur, level, stat);
3465                         if (error)
3466                                 goto error0;
3467                         return 0;
3468                 }
3469         }
3470
3471         ASSERT(!xfs_btree_ptr_is_null(cur, &rptr) ||
3472                !xfs_btree_ptr_is_null(cur, &lptr));
3473
3474         /*
3475          * Duplicate the cursor so our btree manipulations here won't
3476          * disrupt the next level up.
3477          */
3478         error = xfs_btree_dup_cursor(cur, &tcur);
3479         if (error)
3480                 goto error0;
3481
3482         /*
3483          * If there's a right sibling, see if it's ok to shift an entry
3484          * out of it.
3485          */
3486         if (!xfs_btree_ptr_is_null(cur, &rptr)) {
3487                 /*
3488                  * Move the temp cursor to the last entry in the next block.
3489                  * Actually any entry but the first would suffice.
3490                  */
3491                 i = xfs_btree_lastrec(tcur, level);
3492                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3493
3494                 error = xfs_btree_increment(tcur, level, &i);
3495                 if (error)
3496                         goto error0;
3497                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3498
3499                 i = xfs_btree_lastrec(tcur, level);
3500                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3501
3502                 /* Grab a pointer to the block. */
3503                 right = xfs_btree_get_block(tcur, level, &rbp);
3504 #ifdef DEBUG
3505                 error = xfs_btree_check_block(tcur, right, level, rbp);
3506                 if (error)
3507                         goto error0;
3508 #endif
3509                 /* Grab the current block number, for future use. */
3510                 xfs_btree_get_sibling(tcur, right, &cptr, XFS_BB_LEFTSIB);
3511
3512                 /*
3513                  * If right block is full enough so that removing one entry
3514                  * won't make it too empty, and left-shifting an entry out
3515                  * of right to us works, we're done.
3516                  */
3517                 if (xfs_btree_get_numrecs(right) - 1 >=
3518                     cur->bc_ops->get_minrecs(tcur, level)) {
3519                         error = xfs_btree_lshift(tcur, level, &i);
3520                         if (error)
3521                                 goto error0;
3522                         if (i) {
3523                                 ASSERT(xfs_btree_get_numrecs(block) >=
3524                                        cur->bc_ops->get_minrecs(tcur, level));
3525
3526                                 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
3527                                 tcur = NULL;
3528
3529                                 error = xfs_btree_dec_cursor(cur, level, stat);
3530                                 if (error)
3531                                         goto error0;
3532                                 return 0;
3533                         }
3534                 }
3535
3536                 /*
3537                  * Otherwise, grab the number of records in right for
3538                  * future reference, and fix up the temp cursor to point
3539                  * to our block again (last record).
3540                  */
3541                 rrecs = xfs_btree_get_numrecs(right);
3542                 if (!xfs_btree_ptr_is_null(cur, &lptr)) {
3543                         i = xfs_btree_firstrec(tcur, level);
3544                         XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3545
3546                         error = xfs_btree_decrement(tcur, level, &i);
3547                         if (error)
3548                                 goto error0;
3549                         XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3550                 }
3551         }
3552
3553         /*
3554          * If there's a left sibling, see if it's ok to shift an entry
3555          * out of it.
3556          */
3557         if (!xfs_btree_ptr_is_null(cur, &lptr)) {
3558                 /*
3559                  * Move the temp cursor to the first entry in the
3560                  * previous block.
3561                  */
3562                 i = xfs_btree_firstrec(tcur, level);
3563                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3564
3565                 error = xfs_btree_decrement(tcur, level, &i);
3566                 if (error)
3567                         goto error0;
3568                 i = xfs_btree_firstrec(tcur, level);
3569                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
3570
3571                 /* Grab a pointer to the block. */
3572                 left = xfs_btree_get_block(tcur, level, &lbp);
3573 #ifdef DEBUG
3574                 error = xfs_btree_check_block(cur, left, level, lbp);
3575                 if (error)
3576                         goto error0;
3577 #endif
3578                 /* Grab the current block number, for future use. */
3579                 xfs_btree_get_sibling(tcur, left, &cptr, XFS_BB_RIGHTSIB);
3580
3581                 /*
3582                  * If left block is full enough so that removing one entry
3583                  * won't make it too empty, and right-shifting an entry out
3584                  * of left to us works, we're done.
3585                  */
3586                 if (xfs_btree_get_numrecs(left) - 1 >=
3587                     cur->bc_ops->get_minrecs(tcur, level)) {
3588                         error = xfs_btree_rshift(tcur, level, &i);
3589                         if (error)
3590                                 goto error0;
3591                         if (i) {
3592                                 ASSERT(xfs_btree_get_numrecs(block) >=
3593                                        cur->bc_ops->get_minrecs(tcur, level));
3594                                 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
3595                                 tcur = NULL;
3596                                 if (level == 0)
3597                                         cur->bc_ptrs[0]++;
3598                                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3599                                 *stat = 1;
3600                                 return 0;
3601                         }
3602                 }
3603
3604                 /*
3605                  * Otherwise, grab the number of records in right for
3606                  * future reference.
3607                  */
3608                 lrecs = xfs_btree_get_numrecs(left);
3609         }
3610
3611         /* Delete the temp cursor, we're done with it. */
3612         xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
3613         tcur = NULL;
3614
3615         /* If here, we need to do a join to keep the tree balanced. */
3616         ASSERT(!xfs_btree_ptr_is_null(cur, &cptr));
3617
3618         if (!xfs_btree_ptr_is_null(cur, &lptr) &&
3619             lrecs + xfs_btree_get_numrecs(block) <=
3620                         cur->bc_ops->get_maxrecs(cur, level)) {
3621                 /*
3622                  * Set "right" to be the starting block,
3623                  * "left" to be the left neighbor.
3624                  */
3625                 rptr = cptr;
3626                 right = block;
3627                 rbp = bp;
3628                 error = xfs_btree_read_buf_block(cur, &lptr, level,
3629                                                         0, &left, &lbp);
3630                 if (error)
3631                         goto error0;
3632
3633         /*
3634          * If that won't work, see if we can join with the right neighbor block.
3635          */
3636         } else if (!xfs_btree_ptr_is_null(cur, &rptr) &&
3637                    rrecs + xfs_btree_get_numrecs(block) <=
3638                         cur->bc_ops->get_maxrecs(cur, level)) {
3639                 /*
3640                  * Set "left" to be the starting block,
3641                  * "right" to be the right neighbor.
3642                  */
3643                 lptr = cptr;
3644                 left = block;
3645                 lbp = bp;
3646                 error = xfs_btree_read_buf_block(cur, &rptr, level,
3647                                                         0, &right, &rbp);
3648                 if (error)
3649                         goto error0;
3650
3651         /*
3652          * Otherwise, we can't fix the imbalance.
3653          * Just return.  This is probably a logic error, but it's not fatal.
3654          */
3655         } else {
3656                 error = xfs_btree_dec_cursor(cur, level, stat);
3657                 if (error)
3658                         goto error0;
3659                 return 0;
3660         }
3661
3662         rrecs = xfs_btree_get_numrecs(right);
3663         lrecs = xfs_btree_get_numrecs(left);
3664
3665         /*
3666          * We're now going to join "left" and "right" by moving all the stuff
3667          * in "right" to "left" and deleting "right".
3668          */
3669         XFS_BTREE_STATS_ADD(cur, moves, rrecs);
3670         if (level > 0) {
3671                 /* It's a non-leaf.  Move keys and pointers. */
3672                 union xfs_btree_key     *lkp;   /* left btree key */
3673                 union xfs_btree_ptr     *lpp;   /* left address pointer */
3674                 union xfs_btree_key     *rkp;   /* right btree key */
3675                 union xfs_btree_ptr     *rpp;   /* right address pointer */
3676
3677                 lkp = xfs_btree_key_addr(cur, lrecs + 1, left);
3678                 lpp = xfs_btree_ptr_addr(cur, lrecs + 1, left);
3679                 rkp = xfs_btree_key_addr(cur, 1, right);
3680                 rpp = xfs_btree_ptr_addr(cur, 1, right);
3681 #ifdef DEBUG
3682                 for (i = 1; i < rrecs; i++) {
3683                         error = xfs_btree_check_ptr(cur, rpp, i, level);
3684                         if (error)
3685                                 goto error0;
3686                 }
3687 #endif
3688                 xfs_btree_copy_keys(cur, lkp, rkp, rrecs);
3689                 xfs_btree_copy_ptrs(cur, lpp, rpp, rrecs);
3690
3691                 xfs_btree_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
3692                 xfs_btree_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
3693         } else {
3694                 /* It's a leaf.  Move records.  */
3695                 union xfs_btree_rec     *lrp;   /* left record pointer */
3696                 union xfs_btree_rec     *rrp;   /* right record pointer */
3697
3698                 lrp = xfs_btree_rec_addr(cur, lrecs + 1, left);
3699                 rrp = xfs_btree_rec_addr(cur, 1, right);
3700
3701                 xfs_btree_copy_recs(cur, lrp, rrp, rrecs);
3702                 xfs_btree_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
3703         }
3704
3705         XFS_BTREE_STATS_INC(cur, join);
3706
3707         /*
3708          * Fix up the number of records and right block pointer in the
3709          * surviving block, and log it.
3710          */
3711         xfs_btree_set_numrecs(left, lrecs + rrecs);
3712         xfs_btree_get_sibling(cur, right, &cptr, XFS_BB_RIGHTSIB),
3713         xfs_btree_set_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB);
3714         xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
3715
3716         /* If there is a right sibling, point it to the remaining block. */
3717         xfs_btree_get_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB);
3718         if (!xfs_btree_ptr_is_null(cur, &cptr)) {
3719                 error = xfs_btree_read_buf_block(cur, &cptr, level,
3720                                                         0, &rrblock, &rrbp);
3721                 if (error)
3722                         goto error0;
3723                 xfs_btree_set_sibling(cur, rrblock, &lptr, XFS_BB_LEFTSIB);
3724                 xfs_btree_log_block(cur, rrbp, XFS_BB_LEFTSIB);
3725         }
3726
3727         /* Free the deleted block. */
3728         error = cur->bc_ops->free_block(cur, rbp);
3729         if (error)
3730                 goto error0;
3731         XFS_BTREE_STATS_INC(cur, free);
3732
3733         /*
3734          * If we joined with the left neighbor, set the buffer in the
3735          * cursor to the left block, and fix up the index.
3736          */
3737         if (bp != lbp) {
3738                 cur->bc_bufs[level] = lbp;
3739                 cur->bc_ptrs[level] += lrecs;
3740                 cur->bc_ra[level] = 0;
3741         }
3742         /*
3743          * If we joined with the right neighbor and there's a level above
3744          * us, increment the cursor at that level.
3745          */
3746         else if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) ||
3747                    (level + 1 < cur->bc_nlevels)) {
3748                 error = xfs_btree_increment(cur, level + 1, &i);
3749                 if (error)
3750                         goto error0;
3751         }
3752
3753         /*
3754          * Readjust the ptr at this level if it's not a leaf, since it's
3755          * still pointing at the deletion point, which makes the cursor
3756          * inconsistent.  If this makes the ptr 0, the caller fixes it up.
3757          * We can't use decrement because it would change the next level up.
3758          */
3759         if (level > 0)
3760                 cur->bc_ptrs[level]--;
3761
3762         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3763         /* Return value means the next level up has something to do. */
3764         *stat = 2;
3765         return 0;
3766
3767 error0:
3768         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
3769         if (tcur)
3770                 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
3771         return error;
3772 }
3773
3774 /*
3775  * Delete the record pointed to by cur.
3776  * The cursor refers to the place where the record was (could be inserted)
3777  * when the operation returns.
3778  */
3779 int                                     /* error */
3780 xfs_btree_delete(
3781         struct xfs_btree_cur    *cur,
3782         int                     *stat)  /* success/failure */
3783 {
3784         int                     error;  /* error return value */
3785         int                     level;
3786         int                     i;
3787
3788         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
3789
3790         /*
3791          * Go up the tree, starting at leaf level.
3792          *
3793          * If 2 is returned then a join was done; go to the next level.
3794          * Otherwise we are done.
3795          */
3796         for (level = 0, i = 2; i == 2; level++) {
3797                 error = xfs_btree_delrec(cur, level, &i);
3798                 if (error)
3799                         goto error0;
3800         }
3801
3802         if (i == 0) {
3803                 for (level = 1; level < cur->bc_nlevels; level++) {
3804                         if (cur->bc_ptrs[level] == 0) {
3805                                 error = xfs_btree_decrement(cur, level, &i);
3806                                 if (error)
3807                                         goto error0;
3808                                 break;
3809                         }
3810                 }
3811         }
3812
3813         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
3814         *stat = i;
3815         return 0;
3816 error0:
3817         XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
3818         return error;
3819 }
3820
3821 /*
3822  * Get the data from the pointed-to record.
3823  */
3824 int                                     /* error */
3825 xfs_btree_get_rec(
3826         struct xfs_btree_cur    *cur,   /* btree cursor */
3827         union xfs_btree_rec     **recp, /* output: btree record */
3828         int                     *stat)  /* output: success/failure */
3829 {
3830         struct xfs_btree_block  *block; /* btree block */
3831         struct xfs_buf          *bp;    /* buffer pointer */
3832         int                     ptr;    /* record number */
3833 #ifdef DEBUG
3834         int                     error;  /* error return value */
3835 #endif
3836
3837         ptr = cur->bc_ptrs[0];
3838         block = xfs_btree_get_block(cur, 0, &bp);
3839
3840 #ifdef DEBUG
3841         error = xfs_btree_check_block(cur, block, 0, bp);
3842         if (error)
3843                 return error;
3844 #endif
3845
3846         /*
3847          * Off the right end or left end, return failure.
3848          */
3849         if (ptr > xfs_btree_get_numrecs(block) || ptr <= 0) {
3850                 *stat = 0;
3851                 return 0;
3852         }
3853
3854         /*
3855          * Point to the record and extract its data.
3856          */
3857         *recp = xfs_btree_rec_addr(cur, ptr, block);
3858         *stat = 1;
3859         return 0;
3860 }