]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/xfs/xfs_alloc_btree.c
[XFS] implement semi-generic xfs_btree_new_root
[linux-2.6-omap-h63xx.git] / fs / xfs / xfs_alloc_btree.c
1 /*
2  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_types.h"
21 #include "xfs_bit.h"
22 #include "xfs_log.h"
23 #include "xfs_inum.h"
24 #include "xfs_trans.h"
25 #include "xfs_sb.h"
26 #include "xfs_ag.h"
27 #include "xfs_dir2.h"
28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h"
33 #include "xfs_dir2_sf.h"
34 #include "xfs_attr_sf.h"
35 #include "xfs_dinode.h"
36 #include "xfs_inode.h"
37 #include "xfs_btree.h"
38 #include "xfs_btree_trace.h"
39 #include "xfs_ialloc.h"
40 #include "xfs_alloc.h"
41 #include "xfs_error.h"
42
43 /*
44  * Prototypes for internal functions.
45  */
46
47 STATIC void xfs_alloc_log_block(xfs_trans_t *, xfs_buf_t *, int);
48 STATIC void xfs_alloc_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
49 STATIC void xfs_alloc_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
50 STATIC void xfs_alloc_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
51
52 /*
53  * Internal functions.
54  */
55
56 /*
57  * Single level of the xfs_alloc_delete record deletion routine.
58  * Delete record pointed to by cur/level.
59  * Remove the record from its block then rebalance the tree.
60  * Return 0 for error, 1 for done, 2 to go on to the next level.
61  */
62 STATIC int                              /* error */
63 xfs_alloc_delrec(
64         xfs_btree_cur_t         *cur,   /* btree cursor */
65         int                     level,  /* level removing record from */
66         int                     *stat)  /* fail/done/go-on */
67 {
68         xfs_agf_t               *agf;   /* allocation group freelist header */
69         xfs_alloc_block_t       *block; /* btree block record/key lives in */
70         xfs_agblock_t           bno;    /* btree block number */
71         xfs_buf_t               *bp;    /* buffer for block */
72         int                     error;  /* error return value */
73         int                     i;      /* loop index */
74         xfs_alloc_key_t         key;    /* kp points here if block is level 0 */
75         xfs_agblock_t           lbno;   /* left block's block number */
76         xfs_buf_t               *lbp;   /* left block's buffer pointer */
77         xfs_alloc_block_t       *left;  /* left btree block */
78         xfs_alloc_key_t         *lkp=NULL;      /* left block key pointer */
79         xfs_alloc_ptr_t         *lpp=NULL;      /* left block address pointer */
80         int                     lrecs=0;        /* number of records in left block */
81         xfs_alloc_rec_t         *lrp;   /* left block record pointer */
82         xfs_mount_t             *mp;    /* mount structure */
83         int                     ptr;    /* index in btree block for this rec */
84         xfs_agblock_t           rbno;   /* right block's block number */
85         xfs_buf_t               *rbp;   /* right block's buffer pointer */
86         xfs_alloc_block_t       *right; /* right btree block */
87         xfs_alloc_key_t         *rkp;   /* right block key pointer */
88         xfs_alloc_ptr_t         *rpp;   /* right block address pointer */
89         int                     rrecs=0;        /* number of records in right block */
90         int                     numrecs;
91         xfs_alloc_rec_t         *rrp;   /* right block record pointer */
92         xfs_btree_cur_t         *tcur;  /* temporary btree cursor */
93
94         /*
95          * Get the index of the entry being deleted, check for nothing there.
96          */
97         ptr = cur->bc_ptrs[level];
98         if (ptr == 0) {
99                 *stat = 0;
100                 return 0;
101         }
102         /*
103          * Get the buffer & block containing the record or key/ptr.
104          */
105         bp = cur->bc_bufs[level];
106         block = XFS_BUF_TO_ALLOC_BLOCK(bp);
107 #ifdef DEBUG
108         if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
109                 return error;
110 #endif
111         /*
112          * Fail if we're off the end of the block.
113          */
114         numrecs = be16_to_cpu(block->bb_numrecs);
115         if (ptr > numrecs) {
116                 *stat = 0;
117                 return 0;
118         }
119         XFS_STATS_INC(xs_abt_delrec);
120         /*
121          * It's a nonleaf.  Excise the key and ptr being deleted, by
122          * sliding the entries past them down one.
123          * Log the changed areas of the block.
124          */
125         if (level > 0) {
126                 lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
127                 lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
128 #ifdef DEBUG
129                 for (i = ptr; i < numrecs; i++) {
130                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
131                                 return error;
132                 }
133 #endif
134                 if (ptr < numrecs) {
135                         memmove(&lkp[ptr - 1], &lkp[ptr],
136                                 (numrecs - ptr) * sizeof(*lkp));
137                         memmove(&lpp[ptr - 1], &lpp[ptr],
138                                 (numrecs - ptr) * sizeof(*lpp));
139                         xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1);
140                         xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1);
141                 }
142         }
143         /*
144          * It's a leaf.  Excise the record being deleted, by sliding the
145          * entries past it down one.  Log the changed areas of the block.
146          */
147         else {
148                 lrp = XFS_ALLOC_REC_ADDR(block, 1, cur);
149                 if (ptr < numrecs) {
150                         memmove(&lrp[ptr - 1], &lrp[ptr],
151                                 (numrecs - ptr) * sizeof(*lrp));
152                         xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1);
153                 }
154                 /*
155                  * If it's the first record in the block, we'll need a key
156                  * structure to pass up to the next level (updkey).
157                  */
158                 if (ptr == 1) {
159                         key.ar_startblock = lrp->ar_startblock;
160                         key.ar_blockcount = lrp->ar_blockcount;
161                         lkp = &key;
162                 }
163         }
164         /*
165          * Decrement and log the number of entries in the block.
166          */
167         numrecs--;
168         block->bb_numrecs = cpu_to_be16(numrecs);
169         xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
170         /*
171          * See if the longest free extent in the allocation group was
172          * changed by this operation.  True if it's the by-size btree, and
173          * this is the leaf level, and there is no right sibling block,
174          * and this was the last record.
175          */
176         agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
177         mp = cur->bc_mp;
178
179         if (level == 0 &&
180             cur->bc_btnum == XFS_BTNUM_CNT &&
181             be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
182             ptr > numrecs) {
183                 ASSERT(ptr == numrecs + 1);
184                 /*
185                  * There are still records in the block.  Grab the size
186                  * from the last one.
187                  */
188                 if (numrecs) {
189                         rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur);
190                         agf->agf_longest = rrp->ar_blockcount;
191                 }
192                 /*
193                  * No free extents left.
194                  */
195                 else
196                         agf->agf_longest = 0;
197                 mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest =
198                         be32_to_cpu(agf->agf_longest);
199                 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
200                         XFS_AGF_LONGEST);
201         }
202         /*
203          * Is this the root level?  If so, we're almost done.
204          */
205         if (level == cur->bc_nlevels - 1) {
206                 /*
207                  * If this is the root level,
208                  * and there's only one entry left,
209                  * and it's NOT the leaf level,
210                  * then we can get rid of this level.
211                  */
212                 if (numrecs == 1 && level > 0) {
213                         /*
214                          * lpp is still set to the first pointer in the block.
215                          * Make it the new root of the btree.
216                          */
217                         bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]);
218                         agf->agf_roots[cur->bc_btnum] = *lpp;
219                         be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1);
220                         mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--;
221                         /*
222                          * Put this buffer/block on the ag's freelist.
223                          */
224                         error = xfs_alloc_put_freelist(cur->bc_tp,
225                                         cur->bc_private.a.agbp, NULL, bno, 1);
226                         if (error)
227                                 return error;
228                         /*
229                          * Since blocks move to the free list without the
230                          * coordination used in xfs_bmap_finish, we can't allow
231                          * block to be available for reallocation and
232                          * non-transaction writing (user data) until we know
233                          * that the transaction that moved it to the free list
234                          * is permanently on disk. We track the blocks by
235                          * declaring these blocks as "busy"; the busy list is
236                          * maintained on a per-ag basis and each transaction
237                          * records which entries should be removed when the
238                          * iclog commits to disk. If a busy block is
239                          * allocated, the iclog is pushed up to the LSN
240                          * that freed the block.
241                          */
242                         xfs_alloc_mark_busy(cur->bc_tp,
243                                 be32_to_cpu(agf->agf_seqno), bno, 1);
244
245                         xfs_trans_agbtree_delta(cur->bc_tp, -1);
246                         xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
247                                 XFS_AGF_ROOTS | XFS_AGF_LEVELS);
248                         /*
249                          * Update the cursor so there's one fewer level.
250                          */
251                         xfs_btree_setbuf(cur, level, NULL);
252                         cur->bc_nlevels--;
253                 } else if (level > 0 &&
254                            (error = xfs_btree_decrement(cur, level, &i)))
255                         return error;
256                 *stat = 1;
257                 return 0;
258         }
259         /*
260          * If we deleted the leftmost entry in the block, update the
261          * key values above us in the tree.
262          */
263         if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)lkp, level + 1)))
264                 return error;
265         /*
266          * If the number of records remaining in the block is at least
267          * the minimum, we're done.
268          */
269         if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
270                 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
271                         return error;
272                 *stat = 1;
273                 return 0;
274         }
275         /*
276          * Otherwise, we have to move some records around to keep the
277          * tree balanced.  Look at the left and right sibling blocks to
278          * see if we can re-balance by moving only one record.
279          */
280         rbno = be32_to_cpu(block->bb_rightsib);
281         lbno = be32_to_cpu(block->bb_leftsib);
282         bno = NULLAGBLOCK;
283         ASSERT(rbno != NULLAGBLOCK || lbno != NULLAGBLOCK);
284         /*
285          * Duplicate the cursor so our btree manipulations here won't
286          * disrupt the next level up.
287          */
288         if ((error = xfs_btree_dup_cursor(cur, &tcur)))
289                 return error;
290         /*
291          * If there's a right sibling, see if it's ok to shift an entry
292          * out of it.
293          */
294         if (rbno != NULLAGBLOCK) {
295                 /*
296                  * Move the temp cursor to the last entry in the next block.
297                  * Actually any entry but the first would suffice.
298                  */
299                 i = xfs_btree_lastrec(tcur, level);
300                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
301                 if ((error = xfs_btree_increment(tcur, level, &i)))
302                         goto error0;
303                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
304                 i = xfs_btree_lastrec(tcur, level);
305                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
306                 /*
307                  * Grab a pointer to the block.
308                  */
309                 rbp = tcur->bc_bufs[level];
310                 right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
311 #ifdef DEBUG
312                 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
313                         goto error0;
314 #endif
315                 /*
316                  * Grab the current block number, for future use.
317                  */
318                 bno = be32_to_cpu(right->bb_leftsib);
319                 /*
320                  * If right block is full enough so that removing one entry
321                  * won't make it too empty, and left-shifting an entry out
322                  * of right to us works, we're done.
323                  */
324                 if (be16_to_cpu(right->bb_numrecs) - 1 >=
325                      XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
326                         if ((error = xfs_btree_lshift(tcur, level, &i)))
327                                 goto error0;
328                         if (i) {
329                                 ASSERT(be16_to_cpu(block->bb_numrecs) >=
330                                        XFS_ALLOC_BLOCK_MINRECS(level, cur));
331                                 xfs_btree_del_cursor(tcur,
332                                                      XFS_BTREE_NOERROR);
333                                 if (level > 0 &&
334                                     (error = xfs_btree_decrement(cur, level,
335                                             &i)))
336                                         return error;
337                                 *stat = 1;
338                                 return 0;
339                         }
340                 }
341                 /*
342                  * Otherwise, grab the number of records in right for
343                  * future reference, and fix up the temp cursor to point
344                  * to our block again (last record).
345                  */
346                 rrecs = be16_to_cpu(right->bb_numrecs);
347                 if (lbno != NULLAGBLOCK) {
348                         i = xfs_btree_firstrec(tcur, level);
349                         XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
350                         if ((error = xfs_btree_decrement(tcur, level, &i)))
351                                 goto error0;
352                         XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
353                 }
354         }
355         /*
356          * If there's a left sibling, see if it's ok to shift an entry
357          * out of it.
358          */
359         if (lbno != NULLAGBLOCK) {
360                 /*
361                  * Move the temp cursor to the first entry in the
362                  * previous block.
363                  */
364                 i = xfs_btree_firstrec(tcur, level);
365                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
366                 if ((error = xfs_btree_decrement(tcur, level, &i)))
367                         goto error0;
368                 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
369                 xfs_btree_firstrec(tcur, level);
370                 /*
371                  * Grab a pointer to the block.
372                  */
373                 lbp = tcur->bc_bufs[level];
374                 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
375 #ifdef DEBUG
376                 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
377                         goto error0;
378 #endif
379                 /*
380                  * Grab the current block number, for future use.
381                  */
382                 bno = be32_to_cpu(left->bb_rightsib);
383                 /*
384                  * If left block is full enough so that removing one entry
385                  * won't make it too empty, and right-shifting an entry out
386                  * of left to us works, we're done.
387                  */
388                 if (be16_to_cpu(left->bb_numrecs) - 1 >=
389                      XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
390                         if ((error = xfs_btree_rshift(tcur, level, &i)))
391                                 goto error0;
392                         if (i) {
393                                 ASSERT(be16_to_cpu(block->bb_numrecs) >=
394                                        XFS_ALLOC_BLOCK_MINRECS(level, cur));
395                                 xfs_btree_del_cursor(tcur,
396                                                      XFS_BTREE_NOERROR);
397                                 if (level == 0)
398                                         cur->bc_ptrs[0]++;
399                                 *stat = 1;
400                                 return 0;
401                         }
402                 }
403                 /*
404                  * Otherwise, grab the number of records in right for
405                  * future reference.
406                  */
407                 lrecs = be16_to_cpu(left->bb_numrecs);
408         }
409         /*
410          * Delete the temp cursor, we're done with it.
411          */
412         xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
413         /*
414          * If here, we need to do a join to keep the tree balanced.
415          */
416         ASSERT(bno != NULLAGBLOCK);
417         /*
418          * See if we can join with the left neighbor block.
419          */
420         if (lbno != NULLAGBLOCK &&
421             lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
422                 /*
423                  * Set "right" to be the starting block,
424                  * "left" to be the left neighbor.
425                  */
426                 rbno = bno;
427                 right = block;
428                 rrecs = be16_to_cpu(right->bb_numrecs);
429                 rbp = bp;
430                 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
431                                 cur->bc_private.a.agno, lbno, 0, &lbp,
432                                 XFS_ALLOC_BTREE_REF)))
433                         return error;
434                 left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
435                 lrecs = be16_to_cpu(left->bb_numrecs);
436                 if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
437                         return error;
438         }
439         /*
440          * If that won't work, see if we can join with the right neighbor block.
441          */
442         else if (rbno != NULLAGBLOCK &&
443                  rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
444                 /*
445                  * Set "left" to be the starting block,
446                  * "right" to be the right neighbor.
447                  */
448                 lbno = bno;
449                 left = block;
450                 lrecs = be16_to_cpu(left->bb_numrecs);
451                 lbp = bp;
452                 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
453                                 cur->bc_private.a.agno, rbno, 0, &rbp,
454                                 XFS_ALLOC_BTREE_REF)))
455                         return error;
456                 right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
457                 rrecs = be16_to_cpu(right->bb_numrecs);
458                 if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
459                         return error;
460         }
461         /*
462          * Otherwise, we can't fix the imbalance.
463          * Just return.  This is probably a logic error, but it's not fatal.
464          */
465         else {
466                 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
467                         return error;
468                 *stat = 1;
469                 return 0;
470         }
471         /*
472          * We're now going to join "left" and "right" by moving all the stuff
473          * in "right" to "left" and deleting "right".
474          */
475         if (level > 0) {
476                 /*
477                  * It's a non-leaf.  Move keys and pointers.
478                  */
479                 lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur);
480                 lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur);
481                 rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
482                 rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
483 #ifdef DEBUG
484                 for (i = 0; i < rrecs; i++) {
485                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
486                                 return error;
487                 }
488 #endif
489                 memcpy(lkp, rkp, rrecs * sizeof(*lkp));
490                 memcpy(lpp, rpp, rrecs * sizeof(*lpp));
491                 xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
492                 xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
493         } else {
494                 /*
495                  * It's a leaf.  Move records.
496                  */
497                 lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur);
498                 rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
499                 memcpy(lrp, rrp, rrecs * sizeof(*lrp));
500                 xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
501         }
502         /*
503          * If we joined with the left neighbor, set the buffer in the
504          * cursor to the left block, and fix up the index.
505          */
506         if (bp != lbp) {
507                 xfs_btree_setbuf(cur, level, lbp);
508                 cur->bc_ptrs[level] += lrecs;
509         }
510         /*
511          * If we joined with the right neighbor and there's a level above
512          * us, increment the cursor at that level.
513          */
514         else if (level + 1 < cur->bc_nlevels &&
515                  (error = xfs_btree_increment(cur, level + 1, &i)))
516                 return error;
517         /*
518          * Fix up the number of records in the surviving block.
519          */
520         lrecs += rrecs;
521         left->bb_numrecs = cpu_to_be16(lrecs);
522         /*
523          * Fix up the right block pointer in the surviving block, and log it.
524          */
525         left->bb_rightsib = right->bb_rightsib;
526         xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
527         /*
528          * If there is a right sibling now, make it point to the
529          * remaining block.
530          */
531         if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) {
532                 xfs_alloc_block_t       *rrblock;
533                 xfs_buf_t               *rrbp;
534
535                 if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
536                                 cur->bc_private.a.agno, be32_to_cpu(left->bb_rightsib), 0,
537                                 &rrbp, XFS_ALLOC_BTREE_REF)))
538                         return error;
539                 rrblock = XFS_BUF_TO_ALLOC_BLOCK(rrbp);
540                 if ((error = xfs_btree_check_sblock(cur, rrblock, level, rrbp)))
541                         return error;
542                 rrblock->bb_leftsib = cpu_to_be32(lbno);
543                 xfs_alloc_log_block(cur->bc_tp, rrbp, XFS_BB_LEFTSIB);
544         }
545         /*
546          * Free the deleting block by putting it on the freelist.
547          */
548         error = xfs_alloc_put_freelist(cur->bc_tp,
549                                          cur->bc_private.a.agbp, NULL, rbno, 1);
550         if (error)
551                 return error;
552         /*
553          * Since blocks move to the free list without the coordination
554          * used in xfs_bmap_finish, we can't allow block to be available
555          * for reallocation and non-transaction writing (user data)
556          * until we know that the transaction that moved it to the free
557          * list is permanently on disk. We track the blocks by declaring
558          * these blocks as "busy"; the busy list is maintained on a
559          * per-ag basis and each transaction records which entries
560          * should be removed when the iclog commits to disk. If a
561          * busy block is allocated, the iclog is pushed up to the
562          * LSN that freed the block.
563          */
564         xfs_alloc_mark_busy(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1);
565         xfs_trans_agbtree_delta(cur->bc_tp, -1);
566
567         /*
568          * Adjust the current level's cursor so that we're left referring
569          * to the right node, after we're done.
570          * If this leaves the ptr value 0 our caller will fix it up.
571          */
572         if (level > 0)
573                 cur->bc_ptrs[level]--;
574         /*
575          * Return value means the next level up has something to do.
576          */
577         *stat = 2;
578         return 0;
579
580 error0:
581         xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
582         return error;
583 }
584
585 /*
586  * Insert one record/level.  Return information to the caller
587  * allowing the next level up to proceed if necessary.
588  */
589 STATIC int                              /* error */
590 xfs_alloc_insrec(
591         xfs_btree_cur_t         *cur,   /* btree cursor */
592         int                     level,  /* level to insert record at */
593         xfs_agblock_t           *bnop,  /* i/o: block number inserted */
594         xfs_alloc_rec_t         *recp,  /* i/o: record data inserted */
595         xfs_btree_cur_t         **curp, /* output: new cursor replacing cur */
596         int                     *stat)  /* output: success/failure */
597 {
598         xfs_agf_t               *agf;   /* allocation group freelist header */
599         xfs_alloc_block_t       *block; /* btree block record/key lives in */
600         xfs_buf_t               *bp;    /* buffer for block */
601         int                     error;  /* error return value */
602         int                     i;      /* loop index */
603         xfs_alloc_key_t         key;    /* key value being inserted */
604         xfs_alloc_key_t         *kp;    /* pointer to btree keys */
605         xfs_agblock_t           nbno;   /* block number of allocated block */
606         xfs_btree_cur_t         *ncur;  /* new cursor to be used at next lvl */
607         xfs_alloc_key_t         nkey;   /* new key value, from split */
608         xfs_alloc_rec_t         nrec;   /* new record value, for caller */
609         int                     numrecs;
610         int                     optr;   /* old ptr value */
611         xfs_alloc_ptr_t         *pp;    /* pointer to btree addresses */
612         int                     ptr;    /* index in btree block for this rec */
613         xfs_alloc_rec_t         *rp;    /* pointer to btree records */
614
615         ASSERT(be32_to_cpu(recp->ar_blockcount) > 0);
616
617         /*
618          * GCC doesn't understand the (arguably complex) control flow in
619          * this function and complains about uninitialized structure fields
620          * without this.
621          */
622         memset(&nrec, 0, sizeof(nrec));
623
624         /*
625          * If we made it to the root level, allocate a new root block
626          * and we're done.
627          */
628         if (level >= cur->bc_nlevels) {
629                 XFS_STATS_INC(xs_abt_insrec);
630                 if ((error = xfs_btree_new_root(cur, &i)))
631                         return error;
632                 *bnop = NULLAGBLOCK;
633                 *stat = i;
634                 return 0;
635         }
636         /*
637          * Make a key out of the record data to be inserted, and save it.
638          */
639         key.ar_startblock = recp->ar_startblock;
640         key.ar_blockcount = recp->ar_blockcount;
641         optr = ptr = cur->bc_ptrs[level];
642         /*
643          * If we're off the left edge, return failure.
644          */
645         if (ptr == 0) {
646                 *stat = 0;
647                 return 0;
648         }
649         XFS_STATS_INC(xs_abt_insrec);
650         /*
651          * Get pointers to the btree buffer and block.
652          */
653         bp = cur->bc_bufs[level];
654         block = XFS_BUF_TO_ALLOC_BLOCK(bp);
655         numrecs = be16_to_cpu(block->bb_numrecs);
656 #ifdef DEBUG
657         if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
658                 return error;
659         /*
660          * Check that the new entry is being inserted in the right place.
661          */
662         if (ptr <= numrecs) {
663                 if (level == 0) {
664                         rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
665                         xfs_btree_check_rec(cur->bc_btnum, recp, rp);
666                 } else {
667                         kp = XFS_ALLOC_KEY_ADDR(block, ptr, cur);
668                         xfs_btree_check_key(cur->bc_btnum, &key, kp);
669                 }
670         }
671 #endif
672         nbno = NULLAGBLOCK;
673         ncur = NULL;
674         /*
675          * If the block is full, we can't insert the new entry until we
676          * make the block un-full.
677          */
678         if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
679                 /*
680                  * First, try shifting an entry to the right neighbor.
681                  */
682                 if ((error = xfs_btree_rshift(cur, level, &i)))
683                         return error;
684                 if (i) {
685                         /* nothing */
686                 }
687                 /*
688                  * Next, try shifting an entry to the left neighbor.
689                  */
690                 else {
691                         if ((error = xfs_btree_lshift(cur, level, &i)))
692                                 return error;
693                         if (i)
694                                 optr = ptr = cur->bc_ptrs[level];
695                         else {
696                                 union xfs_btree_ptr bno = { .s = cpu_to_be32(nbno) };
697                                 /*
698                                  * Next, try splitting the current block in
699                                  * half. If this works we have to re-set our
700                                  * variables because we could be in a
701                                  * different block now.
702                                  */
703                                 if ((error = xfs_btree_split(cur, level, &bno,
704                                                 (union xfs_btree_key *)&nkey,
705                                                 &ncur, &i)))
706                                         return error;
707                                 nbno = be32_to_cpu(bno.s);
708                                 if (i) {
709                                         bp = cur->bc_bufs[level];
710                                         block = XFS_BUF_TO_ALLOC_BLOCK(bp);
711 #ifdef DEBUG
712                                         if ((error =
713                                                 xfs_btree_check_sblock(cur,
714                                                         block, level, bp)))
715                                                 return error;
716 #endif
717                                         ptr = cur->bc_ptrs[level];
718                                         nrec.ar_startblock = nkey.ar_startblock;
719                                         nrec.ar_blockcount = nkey.ar_blockcount;
720                                 }
721                                 /*
722                                  * Otherwise the insert fails.
723                                  */
724                                 else {
725                                         *stat = 0;
726                                         return 0;
727                                 }
728                         }
729                 }
730         }
731         /*
732          * At this point we know there's room for our new entry in the block
733          * we're pointing at.
734          */
735         numrecs = be16_to_cpu(block->bb_numrecs);
736         if (level > 0) {
737                 /*
738                  * It's a non-leaf entry.  Make a hole for the new data
739                  * in the key and ptr regions of the block.
740                  */
741                 kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
742                 pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
743 #ifdef DEBUG
744                 for (i = numrecs; i >= ptr; i--) {
745                         if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
746                                 return error;
747                 }
748 #endif
749                 memmove(&kp[ptr], &kp[ptr - 1],
750                         (numrecs - ptr + 1) * sizeof(*kp));
751                 memmove(&pp[ptr], &pp[ptr - 1],
752                         (numrecs - ptr + 1) * sizeof(*pp));
753 #ifdef DEBUG
754                 if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
755                         return error;
756 #endif
757                 /*
758                  * Now stuff the new data in, bump numrecs and log the new data.
759                  */
760                 kp[ptr - 1] = key;
761                 pp[ptr - 1] = cpu_to_be32(*bnop);
762                 numrecs++;
763                 block->bb_numrecs = cpu_to_be16(numrecs);
764                 xfs_alloc_log_keys(cur, bp, ptr, numrecs);
765                 xfs_alloc_log_ptrs(cur, bp, ptr, numrecs);
766 #ifdef DEBUG
767                 if (ptr < numrecs)
768                         xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
769                                 kp + ptr);
770 #endif
771         } else {
772                 /*
773                  * It's a leaf entry.  Make a hole for the new record.
774                  */
775                 rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
776                 memmove(&rp[ptr], &rp[ptr - 1],
777                         (numrecs - ptr + 1) * sizeof(*rp));
778                 /*
779                  * Now stuff the new record in, bump numrecs
780                  * and log the new data.
781                  */
782                 rp[ptr - 1] = *recp;
783                 numrecs++;
784                 block->bb_numrecs = cpu_to_be16(numrecs);
785                 xfs_alloc_log_recs(cur, bp, ptr, numrecs);
786 #ifdef DEBUG
787                 if (ptr < numrecs)
788                         xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
789                                 rp + ptr);
790 #endif
791         }
792         /*
793          * Log the new number of records in the btree header.
794          */
795         xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
796         /*
797          * If we inserted at the start of a block, update the parents' keys.
798          */
799         if (optr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, level + 1)))
800                 return error;
801         /*
802          * Look to see if the longest extent in the allocation group
803          * needs to be updated.
804          */
805
806         agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
807         if (level == 0 &&
808             cur->bc_btnum == XFS_BTNUM_CNT &&
809             be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
810             be32_to_cpu(recp->ar_blockcount) > be32_to_cpu(agf->agf_longest)) {
811                 /*
812                  * If this is a leaf in the by-size btree and there
813                  * is no right sibling block and this block is bigger
814                  * than the previous longest block, update it.
815                  */
816                 agf->agf_longest = recp->ar_blockcount;
817                 cur->bc_mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_longest
818                         = be32_to_cpu(recp->ar_blockcount);
819                 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
820                         XFS_AGF_LONGEST);
821         }
822         /*
823          * Return the new block number, if any.
824          * If there is one, give back a record value and a cursor too.
825          */
826         *bnop = nbno;
827         if (nbno != NULLAGBLOCK) {
828                 *recp = nrec;
829                 *curp = ncur;
830         }
831         *stat = 1;
832         return 0;
833 }
834
835 /*
836  * Log header fields from a btree block.
837  */
838 STATIC void
839 xfs_alloc_log_block(
840         xfs_trans_t             *tp,    /* transaction pointer */
841         xfs_buf_t               *bp,    /* buffer containing btree block */
842         int                     fields) /* mask of fields: XFS_BB_... */
843 {
844         int                     first;  /* first byte offset logged */
845         int                     last;   /* last byte offset logged */
846         static const short      offsets[] = {   /* table of offsets */
847                 offsetof(xfs_alloc_block_t, bb_magic),
848                 offsetof(xfs_alloc_block_t, bb_level),
849                 offsetof(xfs_alloc_block_t, bb_numrecs),
850                 offsetof(xfs_alloc_block_t, bb_leftsib),
851                 offsetof(xfs_alloc_block_t, bb_rightsib),
852                 sizeof(xfs_alloc_block_t)
853         };
854
855         xfs_btree_offsets(fields, offsets, XFS_BB_NUM_BITS, &first, &last);
856         xfs_trans_log_buf(tp, bp, first, last);
857 }
858
859 /*
860  * Log keys from a btree block (nonleaf).
861  */
862 STATIC void
863 xfs_alloc_log_keys(
864         xfs_btree_cur_t         *cur,   /* btree cursor */
865         xfs_buf_t               *bp,    /* buffer containing btree block */
866         int                     kfirst, /* index of first key to log */
867         int                     klast)  /* index of last key to log */
868 {
869         xfs_alloc_block_t       *block; /* btree block to log from */
870         int                     first;  /* first byte offset logged */
871         xfs_alloc_key_t         *kp;    /* key pointer in btree block */
872         int                     last;   /* last byte offset logged */
873
874         block = XFS_BUF_TO_ALLOC_BLOCK(bp);
875         kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
876         first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
877         last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
878         xfs_trans_log_buf(cur->bc_tp, bp, first, last);
879 }
880
881 /*
882  * Log block pointer fields from a btree block (nonleaf).
883  */
884 STATIC void
885 xfs_alloc_log_ptrs(
886         xfs_btree_cur_t         *cur,   /* btree cursor */
887         xfs_buf_t               *bp,    /* buffer containing btree block */
888         int                     pfirst, /* index of first pointer to log */
889         int                     plast)  /* index of last pointer to log */
890 {
891         xfs_alloc_block_t       *block; /* btree block to log from */
892         int                     first;  /* first byte offset logged */
893         int                     last;   /* last byte offset logged */
894         xfs_alloc_ptr_t         *pp;    /* block-pointer pointer in btree blk */
895
896         block = XFS_BUF_TO_ALLOC_BLOCK(bp);
897         pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
898         first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
899         last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
900         xfs_trans_log_buf(cur->bc_tp, bp, first, last);
901 }
902
903 /*
904  * Log records from a btree block (leaf).
905  */
906 STATIC void
907 xfs_alloc_log_recs(
908         xfs_btree_cur_t         *cur,   /* btree cursor */
909         xfs_buf_t               *bp,    /* buffer containing btree block */
910         int                     rfirst, /* index of first record to log */
911         int                     rlast)  /* index of last record to log */
912 {
913         xfs_alloc_block_t       *block; /* btree block to log from */
914         int                     first;  /* first byte offset logged */
915         int                     last;   /* last byte offset logged */
916         xfs_alloc_rec_t         *rp;    /* record pointer for btree block */
917
918
919         block = XFS_BUF_TO_ALLOC_BLOCK(bp);
920         rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
921 #ifdef DEBUG
922         {
923                 xfs_agf_t       *agf;
924                 xfs_alloc_rec_t *p;
925
926                 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
927                 for (p = &rp[rfirst - 1]; p <= &rp[rlast - 1]; p++)
928                         ASSERT(be32_to_cpu(p->ar_startblock) +
929                                be32_to_cpu(p->ar_blockcount) <=
930                                be32_to_cpu(agf->agf_length));
931         }
932 #endif
933         first = (int)((xfs_caddr_t)&rp[rfirst - 1] - (xfs_caddr_t)block);
934         last = (int)(((xfs_caddr_t)&rp[rlast] - 1) - (xfs_caddr_t)block);
935         xfs_trans_log_buf(cur->bc_tp, bp, first, last);
936 }
937
938
939 /*
940  * Externally visible routines.
941  */
942
943 /*
944  * Delete the record pointed to by cur.
945  * The cursor refers to the place where the record was (could be inserted)
946  * when the operation returns.
947  */
948 int                                     /* error */
949 xfs_alloc_delete(
950         xfs_btree_cur_t *cur,           /* btree cursor */
951         int             *stat)          /* success/failure */
952 {
953         int             error;          /* error return value */
954         int             i;              /* result code */
955         int             level;          /* btree level */
956
957         /*
958          * Go up the tree, starting at leaf level.
959          * If 2 is returned then a join was done; go to the next level.
960          * Otherwise we are done.
961          */
962         for (level = 0, i = 2; i == 2; level++) {
963                 if ((error = xfs_alloc_delrec(cur, level, &i)))
964                         return error;
965         }
966         if (i == 0) {
967                 for (level = 1; level < cur->bc_nlevels; level++) {
968                         if (cur->bc_ptrs[level] == 0) {
969                                 if ((error = xfs_btree_decrement(cur, level, &i)))
970                                         return error;
971                                 break;
972                         }
973                 }
974         }
975         *stat = i;
976         return 0;
977 }
978
979 /*
980  * Get the data from the pointed-to record.
981  */
982 int                                     /* error */
983 xfs_alloc_get_rec(
984         xfs_btree_cur_t         *cur,   /* btree cursor */
985         xfs_agblock_t           *bno,   /* output: starting block of extent */
986         xfs_extlen_t            *len,   /* output: length of extent */
987         int                     *stat)  /* output: success/failure */
988 {
989         xfs_alloc_block_t       *block; /* btree block */
990 #ifdef DEBUG
991         int                     error;  /* error return value */
992 #endif
993         int                     ptr;    /* record number */
994
995         ptr = cur->bc_ptrs[0];
996         block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[0]);
997 #ifdef DEBUG
998         if ((error = xfs_btree_check_sblock(cur, block, 0, cur->bc_bufs[0])))
999                 return error;
1000 #endif
1001         /*
1002          * Off the right end or left end, return failure.
1003          */
1004         if (ptr > be16_to_cpu(block->bb_numrecs) || ptr <= 0) {
1005                 *stat = 0;
1006                 return 0;
1007         }
1008         /*
1009          * Point to the record and extract its data.
1010          */
1011         {
1012                 xfs_alloc_rec_t         *rec;   /* record data */
1013
1014                 rec = XFS_ALLOC_REC_ADDR(block, ptr, cur);
1015                 *bno = be32_to_cpu(rec->ar_startblock);
1016                 *len = be32_to_cpu(rec->ar_blockcount);
1017         }
1018         *stat = 1;
1019         return 0;
1020 }
1021
1022 /*
1023  * Insert the current record at the point referenced by cur.
1024  * The cursor may be inconsistent on return if splits have been done.
1025  */
1026 int                                     /* error */
1027 xfs_alloc_insert(
1028         xfs_btree_cur_t *cur,           /* btree cursor */
1029         int             *stat)          /* success/failure */
1030 {
1031         int             error;          /* error return value */
1032         int             i;              /* result value, 0 for failure */
1033         int             level;          /* current level number in btree */
1034         xfs_agblock_t   nbno;           /* new block number (split result) */
1035         xfs_btree_cur_t *ncur;          /* new cursor (split result) */
1036         xfs_alloc_rec_t nrec;           /* record being inserted this level */
1037         xfs_btree_cur_t *pcur;          /* previous level's cursor */
1038
1039         level = 0;
1040         nbno = NULLAGBLOCK;
1041         nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
1042         nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
1043         ncur = NULL;
1044         pcur = cur;
1045         /*
1046          * Loop going up the tree, starting at the leaf level.
1047          * Stop when we don't get a split block, that must mean that
1048          * the insert is finished with this level.
1049          */
1050         do {
1051                 /*
1052                  * Insert nrec/nbno into this level of the tree.
1053                  * Note if we fail, nbno will be null.
1054                  */
1055                 if ((error = xfs_alloc_insrec(pcur, level++, &nbno, &nrec, &ncur,
1056                                 &i))) {
1057                         if (pcur != cur)
1058                                 xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
1059                         return error;
1060                 }
1061                 /*
1062                  * See if the cursor we just used is trash.
1063                  * Can't trash the caller's cursor, but otherwise we should
1064                  * if ncur is a new cursor or we're about to be done.
1065                  */
1066                 if (pcur != cur && (ncur || nbno == NULLAGBLOCK)) {
1067                         cur->bc_nlevels = pcur->bc_nlevels;
1068                         xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
1069                 }
1070                 /*
1071                  * If we got a new cursor, switch to it.
1072                  */
1073                 if (ncur) {
1074                         pcur = ncur;
1075                         ncur = NULL;
1076                 }
1077         } while (nbno != NULLAGBLOCK);
1078         *stat = i;
1079         return 0;
1080 }
1081
1082 STATIC struct xfs_btree_cur *
1083 xfs_allocbt_dup_cursor(
1084         struct xfs_btree_cur    *cur)
1085 {
1086         return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
1087                         cur->bc_private.a.agbp, cur->bc_private.a.agno,
1088                         cur->bc_btnum);
1089 }
1090
1091 STATIC void
1092 xfs_allocbt_set_root(
1093         struct xfs_btree_cur    *cur,
1094         union xfs_btree_ptr     *ptr,
1095         int                     inc)
1096 {
1097         struct xfs_buf          *agbp = cur->bc_private.a.agbp;
1098         struct xfs_agf          *agf = XFS_BUF_TO_AGF(agbp);
1099         xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
1100         int                     btnum = cur->bc_btnum;
1101
1102         ASSERT(ptr->s != 0);
1103
1104         agf->agf_roots[btnum] = ptr->s;
1105         be32_add_cpu(&agf->agf_levels[btnum], inc);
1106         cur->bc_mp->m_perag[seqno].pagf_levels[btnum] += inc;
1107
1108         xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
1109 }
1110
1111 STATIC int
1112 xfs_allocbt_alloc_block(
1113         struct xfs_btree_cur    *cur,
1114         union xfs_btree_ptr     *start,
1115         union xfs_btree_ptr     *new,
1116         int                     length,
1117         int                     *stat)
1118 {
1119         int                     error;
1120         xfs_agblock_t           bno;
1121
1122         XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1123
1124         /* Allocate the new block from the freelist. If we can't, give up.  */
1125         error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp,
1126                                        &bno, 1);
1127         if (error) {
1128                 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1129                 return error;
1130         }
1131
1132         if (bno == NULLAGBLOCK) {
1133                 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1134                 *stat = 0;
1135                 return 0;
1136         }
1137
1138         xfs_trans_agbtree_delta(cur->bc_tp, 1);
1139         new->s = cpu_to_be32(bno);
1140
1141         XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1142         *stat = 1;
1143         return 0;
1144 }
1145
1146 /*
1147  * Update the longest extent in the AGF
1148  */
1149 STATIC void
1150 xfs_allocbt_update_lastrec(
1151         struct xfs_btree_cur    *cur,
1152         struct xfs_btree_block  *block,
1153         union xfs_btree_rec     *rec,
1154         int                     ptr,
1155         int                     reason)
1156 {
1157         struct xfs_agf          *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
1158         xfs_agnumber_t          seqno = be32_to_cpu(agf->agf_seqno);
1159         __be32                  len;
1160
1161         ASSERT(cur->bc_btnum == XFS_BTNUM_CNT);
1162
1163         switch (reason) {
1164         case LASTREC_UPDATE:
1165                 /*
1166                  * If this is the last leaf block and it's the last record,
1167                  * then update the size of the longest extent in the AG.
1168                  */
1169                 if (ptr != xfs_btree_get_numrecs(block))
1170                         return;
1171                 len = rec->alloc.ar_blockcount;
1172                 break;
1173         default:
1174                 ASSERT(0);
1175                 return;
1176         }
1177
1178         agf->agf_longest = len;
1179         cur->bc_mp->m_perag[seqno].pagf_longest = be32_to_cpu(len);
1180         xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST);
1181 }
1182
1183 STATIC int
1184 xfs_allocbt_get_maxrecs(
1185         struct xfs_btree_cur    *cur,
1186         int                     level)
1187 {
1188         return cur->bc_mp->m_alloc_mxr[level != 0];
1189 }
1190
1191 STATIC void
1192 xfs_allocbt_init_key_from_rec(
1193         union xfs_btree_key     *key,
1194         union xfs_btree_rec     *rec)
1195 {
1196         ASSERT(rec->alloc.ar_startblock != 0);
1197
1198         key->alloc.ar_startblock = rec->alloc.ar_startblock;
1199         key->alloc.ar_blockcount = rec->alloc.ar_blockcount;
1200 }
1201
1202 STATIC void
1203 xfs_allocbt_init_ptr_from_cur(
1204         struct xfs_btree_cur    *cur,
1205         union xfs_btree_ptr     *ptr)
1206 {
1207         struct xfs_agf          *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
1208
1209         ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno));
1210         ASSERT(agf->agf_roots[cur->bc_btnum] != 0);
1211
1212         ptr->s = agf->agf_roots[cur->bc_btnum];
1213 }
1214
1215 STATIC __int64_t
1216 xfs_allocbt_key_diff(
1217         struct xfs_btree_cur    *cur,
1218         union xfs_btree_key     *key)
1219 {
1220         xfs_alloc_rec_incore_t  *rec = &cur->bc_rec.a;
1221         xfs_alloc_key_t         *kp = &key->alloc;
1222         __int64_t               diff;
1223
1224         if (cur->bc_btnum == XFS_BTNUM_BNO) {
1225                 return (__int64_t)be32_to_cpu(kp->ar_startblock) -
1226                                 rec->ar_startblock;
1227         }
1228
1229         diff = (__int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount;
1230         if (diff)
1231                 return diff;
1232
1233         return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock;
1234 }
1235
1236 #ifdef XFS_BTREE_TRACE
1237 ktrace_t        *xfs_allocbt_trace_buf;
1238
1239 STATIC void
1240 xfs_allocbt_trace_enter(
1241         struct xfs_btree_cur    *cur,
1242         const char              *func,
1243         char                    *s,
1244         int                     type,
1245         int                     line,
1246         __psunsigned_t          a0,
1247         __psunsigned_t          a1,
1248         __psunsigned_t          a2,
1249         __psunsigned_t          a3,
1250         __psunsigned_t          a4,
1251         __psunsigned_t          a5,
1252         __psunsigned_t          a6,
1253         __psunsigned_t          a7,
1254         __psunsigned_t          a8,
1255         __psunsigned_t          a9,
1256         __psunsigned_t          a10)
1257 {
1258         ktrace_enter(xfs_allocbt_trace_buf, (void *)(__psint_t)type,
1259                 (void *)func, (void *)s, NULL, (void *)cur,
1260                 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
1261                 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
1262                 (void *)a8, (void *)a9, (void *)a10);
1263 }
1264
1265 STATIC void
1266 xfs_allocbt_trace_cursor(
1267         struct xfs_btree_cur    *cur,
1268         __uint32_t              *s0,
1269         __uint64_t              *l0,
1270         __uint64_t              *l1)
1271 {
1272         *s0 = cur->bc_private.a.agno;
1273         *l0 = cur->bc_rec.a.ar_startblock;
1274         *l1 = cur->bc_rec.a.ar_blockcount;
1275 }
1276
1277 STATIC void
1278 xfs_allocbt_trace_key(
1279         struct xfs_btree_cur    *cur,
1280         union xfs_btree_key     *key,
1281         __uint64_t              *l0,
1282         __uint64_t              *l1)
1283 {
1284         *l0 = be32_to_cpu(key->alloc.ar_startblock);
1285         *l1 = be32_to_cpu(key->alloc.ar_blockcount);
1286 }
1287
1288 STATIC void
1289 xfs_allocbt_trace_record(
1290         struct xfs_btree_cur    *cur,
1291         union xfs_btree_rec     *rec,
1292         __uint64_t              *l0,
1293         __uint64_t              *l1,
1294         __uint64_t              *l2)
1295 {
1296         *l0 = be32_to_cpu(rec->alloc.ar_startblock);
1297         *l1 = be32_to_cpu(rec->alloc.ar_blockcount);
1298         *l2 = 0;
1299 }
1300 #endif /* XFS_BTREE_TRACE */
1301
1302 static const struct xfs_btree_ops xfs_allocbt_ops = {
1303         .rec_len                = sizeof(xfs_alloc_rec_t),
1304         .key_len                = sizeof(xfs_alloc_key_t),
1305
1306         .dup_cursor             = xfs_allocbt_dup_cursor,
1307         .set_root               = xfs_allocbt_set_root,
1308         .alloc_block            = xfs_allocbt_alloc_block,
1309         .update_lastrec         = xfs_allocbt_update_lastrec,
1310         .get_maxrecs            = xfs_allocbt_get_maxrecs,
1311         .init_key_from_rec      = xfs_allocbt_init_key_from_rec,
1312         .init_ptr_from_cur      = xfs_allocbt_init_ptr_from_cur,
1313         .key_diff               = xfs_allocbt_key_diff,
1314
1315 #ifdef XFS_BTREE_TRACE
1316         .trace_enter            = xfs_allocbt_trace_enter,
1317         .trace_cursor           = xfs_allocbt_trace_cursor,
1318         .trace_key              = xfs_allocbt_trace_key,
1319         .trace_record           = xfs_allocbt_trace_record,
1320 #endif
1321 };
1322
1323 /*
1324  * Allocate a new allocation btree cursor.
1325  */
1326 struct xfs_btree_cur *                  /* new alloc btree cursor */
1327 xfs_allocbt_init_cursor(
1328         struct xfs_mount        *mp,            /* file system mount point */
1329         struct xfs_trans        *tp,            /* transaction pointer */
1330         struct xfs_buf          *agbp,          /* buffer for agf structure */
1331         xfs_agnumber_t          agno,           /* allocation group number */
1332         xfs_btnum_t             btnum)          /* btree identifier */
1333 {
1334         struct xfs_agf          *agf = XFS_BUF_TO_AGF(agbp);
1335         struct xfs_btree_cur    *cur;
1336
1337         ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
1338
1339         cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
1340
1341         cur->bc_tp = tp;
1342         cur->bc_mp = mp;
1343         cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]);
1344         cur->bc_btnum = btnum;
1345         cur->bc_blocklog = mp->m_sb.sb_blocklog;
1346
1347         cur->bc_ops = &xfs_allocbt_ops;
1348         if (btnum == XFS_BTNUM_CNT)
1349                 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE;
1350
1351         cur->bc_private.a.agbp = agbp;
1352         cur->bc_private.a.agno = agno;
1353
1354         return cur;
1355 }