]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - libxfs/xfs_da_btree.c
xfsprogs: Release v6.7.0
[thirdparty/xfsprogs-dev.git] / libxfs / xfs_da_btree.c
CommitLineData
37b3b4d6 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
88b32f06 4 * Copyright (c) 2013 Red Hat, Inc.
da23017d 5 * All Rights Reserved.
2bd0ea18 6 */
9c799827 7#include "libxfs_priv.h"
b626fb59
DC
8#include "xfs_fs.h"
9#include "xfs_shared.h"
10#include "xfs_format.h"
11#include "xfs_log_format.h"
12#include "xfs_trans_resv.h"
13#include "xfs_bit.h"
14#include "xfs_mount.h"
e169cc9b 15#include "xfs_inode.h"
b626fb59
DC
16#include "xfs_dir2.h"
17#include "xfs_dir2_priv.h"
b626fb59 18#include "xfs_trans.h"
b626fb59
DC
19#include "xfs_bmap.h"
20#include "xfs_attr_leaf.h"
21#include "xfs_trace.h"
2bd0ea18
NS
22
23/*
24 * xfs_da_btree.c
25 *
26 * Routines to implement directories as Btrees of hashed names.
27 */
28
5e656dbb
BN
29/*========================================================================
30 * Function prototypes for the kernel.
31 *========================================================================*/
32
33/*
34 * Routines used for growing the Btree.
35 */
88b32f06 36STATIC int xfs_da3_root_split(xfs_da_state_t *state,
5e656dbb
BN
37 xfs_da_state_blk_t *existing_root,
38 xfs_da_state_blk_t *new_child);
88b32f06 39STATIC int xfs_da3_node_split(xfs_da_state_t *state,
5e656dbb
BN
40 xfs_da_state_blk_t *existing_blk,
41 xfs_da_state_blk_t *split_blk,
42 xfs_da_state_blk_t *blk_to_add,
43 int treelevel,
44 int *result);
88b32f06 45STATIC void xfs_da3_node_rebalance(xfs_da_state_t *state,
5e656dbb
BN
46 xfs_da_state_blk_t *node_blk_1,
47 xfs_da_state_blk_t *node_blk_2);
88b32f06 48STATIC void xfs_da3_node_add(xfs_da_state_t *state,
5e656dbb
BN
49 xfs_da_state_blk_t *old_node_blk,
50 xfs_da_state_blk_t *new_node_blk);
51
52/*
53 * Routines used for shrinking the Btree.
54 */
88b32f06 55STATIC int xfs_da3_root_join(xfs_da_state_t *state,
5e656dbb 56 xfs_da_state_blk_t *root_blk);
88b32f06
DC
57STATIC int xfs_da3_node_toosmall(xfs_da_state_t *state, int *retval);
58STATIC void xfs_da3_node_remove(xfs_da_state_t *state,
5e656dbb 59 xfs_da_state_blk_t *drop_blk);
88b32f06 60STATIC void xfs_da3_node_unbalance(xfs_da_state_t *state,
5e656dbb
BN
61 xfs_da_state_blk_t *src_node_blk,
62 xfs_da_state_blk_t *dst_node_blk);
63
64/*
65 * Utility routines.
66 */
88b32f06 67STATIC int xfs_da3_blk_unlink(xfs_da_state_t *state,
5e656dbb
BN
68 xfs_da_state_blk_t *drop_blk,
69 xfs_da_state_blk_t *save_blk);
5e656dbb 70
88b32f06 71
2e1394fc 72struct kmem_cache *xfs_da_state_cache; /* anchor for dir/attr state */
88b32f06
DC
73
74/*
75 * Allocate a dir-state structure.
76 * We don't put them on the stack since they're large.
77 */
2db3075b
CM
78struct xfs_da_state *
79xfs_da_state_alloc(
80 struct xfs_da_args *args)
88b32f06 81{
2db3075b
CM
82 struct xfs_da_state *state;
83
2e1394fc 84 state = kmem_cache_zalloc(xfs_da_state_cache, GFP_NOFS | __GFP_NOFAIL);
2db3075b
CM
85 state->args = args;
86 state->mp = args->dp->i_mount;
87 return state;
88b32f06
DC
88}
89
90/*
91 * Kill the altpath contents of a da-state structure.
92 */
93STATIC void
94xfs_da_state_kill_altpath(xfs_da_state_t *state)
95{
96 int i;
97
98 for (i = 0; i < state->altpath.active; i++)
99 state->altpath.blk[i].bp = NULL;
100 state->altpath.active = 0;
101}
102
103/*
104 * Free a da-state structure.
105 */
106void
107xfs_da_state_free(xfs_da_state_t *state)
108{
109 xfs_da_state_kill_altpath(state);
110#ifdef DEBUG
111 memset((char *)state, 0, sizeof(*state));
112#endif /* DEBUG */
2e1394fc 113 kmem_cache_free(xfs_da_state_cache, state);
88b32f06
DC
114}
115
ecc6ab2b
DW
116void
117xfs_da_state_reset(
118 struct xfs_da_state *state,
119 struct xfs_da_args *args)
120{
121 xfs_da_state_kill_altpath(state);
122 memset(state, 0, sizeof(struct xfs_da_state));
123 state->args = args;
124 state->mp = state->args->dp->i_mount;
125}
126
59ab3748
CH
127static inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)
128{
129 if (whichfork == XFS_DATA_FORK)
130 return mp->m_dir_geo->fsbcount;
131 return mp->m_attr_geo->fsbcount;
132}
133
08c16786
CH
134void
135xfs_da3_node_hdr_from_disk(
136 struct xfs_mount *mp,
137 struct xfs_da3_icnode_hdr *to,
138 struct xfs_da_intnode *from)
139{
94541a16 140 if (xfs_has_crc(mp)) {
08c16786
CH
141 struct xfs_da3_intnode *from3 = (struct xfs_da3_intnode *)from;
142
143 to->forw = be32_to_cpu(from3->hdr.info.hdr.forw);
144 to->back = be32_to_cpu(from3->hdr.info.hdr.back);
145 to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);
146 to->count = be16_to_cpu(from3->hdr.__count);
147 to->level = be16_to_cpu(from3->hdr.__level);
8faa51a8 148 to->btree = from3->__btree;
08c16786
CH
149 ASSERT(to->magic == XFS_DA3_NODE_MAGIC);
150 } else {
151 to->forw = be32_to_cpu(from->hdr.info.forw);
152 to->back = be32_to_cpu(from->hdr.info.back);
153 to->magic = be16_to_cpu(from->hdr.info.magic);
154 to->count = be16_to_cpu(from->hdr.__count);
155 to->level = be16_to_cpu(from->hdr.__level);
8faa51a8 156 to->btree = from->__btree;
08c16786
CH
157 ASSERT(to->magic == XFS_DA_NODE_MAGIC);
158 }
159}
160
b81278fa
CH
161void
162xfs_da3_node_hdr_to_disk(
163 struct xfs_mount *mp,
164 struct xfs_da_intnode *to,
165 struct xfs_da3_icnode_hdr *from)
166{
94541a16 167 if (xfs_has_crc(mp)) {
b81278fa
CH
168 struct xfs_da3_intnode *to3 = (struct xfs_da3_intnode *)to;
169
170 ASSERT(from->magic == XFS_DA3_NODE_MAGIC);
171 to3->hdr.info.hdr.forw = cpu_to_be32(from->forw);
172 to3->hdr.info.hdr.back = cpu_to_be32(from->back);
173 to3->hdr.info.hdr.magic = cpu_to_be16(from->magic);
174 to3->hdr.__count = cpu_to_be16(from->count);
175 to3->hdr.__level = cpu_to_be16(from->level);
176 } else {
177 ASSERT(from->magic == XFS_DA_NODE_MAGIC);
178 to->hdr.info.forw = cpu_to_be32(from->forw);
179 to->hdr.info.back = cpu_to_be32(from->back);
180 to->hdr.info.magic = cpu_to_be16(from->magic);
181 to->hdr.__count = cpu_to_be16(from->count);
182 to->hdr.__level = cpu_to_be16(from->level);
183 }
184}
185
6b27f70a
BF
186/*
187 * Verify an xfs_da3_blkinfo structure. Note that the da3 fields are only
188 * accessible on v5 filesystems. This header format is common across da node,
189 * attr leaf and dir leaf blocks.
190 */
191xfs_failaddr_t
192xfs_da3_blkinfo_verify(
193 struct xfs_buf *bp,
194 struct xfs_da3_blkinfo *hdr3)
195{
7861ef77 196 struct xfs_mount *mp = bp->b_mount;
6b27f70a
BF
197 struct xfs_da_blkinfo *hdr = &hdr3->hdr;
198
9e26de8f 199 if (!xfs_verify_magic16(bp, hdr->magic))
6b27f70a
BF
200 return __this_address;
201
94541a16 202 if (xfs_has_crc(mp)) {
6b27f70a
BF
203 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
204 return __this_address;
f1208396 205 if (be64_to_cpu(hdr3->blkno) != xfs_buf_daddr(bp))
6b27f70a
BF
206 return __this_address;
207 if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
208 return __this_address;
209 }
210
9e26de8f 211 return NULL;
6b27f70a
BF
212}
213
bc01119d 214static xfs_failaddr_t
88b32f06 215xfs_da3_node_verify(
a2ceac1f
DC
216 struct xfs_buf *bp)
217{
7861ef77 218 struct xfs_mount *mp = bp->b_mount;
88b32f06
DC
219 struct xfs_da_intnode *hdr = bp->b_addr;
220 struct xfs_da3_icnode_hdr ichdr;
6b27f70a 221 xfs_failaddr_t fa;
ff105f75 222
08c16786 223 xfs_da3_node_hdr_from_disk(mp, &ichdr, hdr);
88b32f06 224
6b27f70a
BF
225 fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
226 if (fa)
227 return fa;
68dbe77f 228
88b32f06 229 if (ichdr.level == 0)
bc01119d 230 return __this_address;
88b32f06 231 if (ichdr.level > XFS_DA_NODE_MAXDEPTH)
bc01119d 232 return __this_address;
88b32f06 233 if (ichdr.count == 0)
bc01119d 234 return __this_address;
88b32f06
DC
235
236 /*
237 * we don't know if the node is for and attribute or directory tree,
238 * so only fail if the count is outside both bounds
239 */
ff105f75
DC
240 if (ichdr.count > mp->m_dir_geo->node_ents &&
241 ichdr.count > mp->m_attr_geo->node_ents)
bc01119d 242 return __this_address;
88b32f06
DC
243
244 /* XXX: hash order check? */
a2ceac1f 245
bc01119d 246 return NULL;
a2ceac1f
DC
247}
248
249static void
88b32f06 250xfs_da3_node_write_verify(
a2ceac1f
DC
251 struct xfs_buf *bp)
252{
7861ef77 253 struct xfs_mount *mp = bp->b_mount;
37d086ca 254 struct xfs_buf_log_item *bip = bp->b_log_item;
88b32f06 255 struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
1e697959 256 xfs_failaddr_t fa;
88b32f06 257
1e697959
DW
258 fa = xfs_da3_node_verify(bp);
259 if (fa) {
260 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
88b32f06
DC
261 return;
262 }
263
b16a427a 264 if (!xfs_has_crc(mp))
88b32f06
DC
265 return;
266
267 if (bip)
268 hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
269
43b5aeed 270 xfs_buf_update_cksum(bp, XFS_DA3_NODE_CRC_OFF);
a2ceac1f
DC
271}
272
273/*
274 * leaf/node format detection on trees is sketchy, so a node read can be done on
275 * leaf level blocks when detection identifies the tree as a node format tree
276 * incorrectly. In this case, we need to swap the verifier to match the correct
277 * format of the block being read.
278 */
279static void
88b32f06 280xfs_da3_node_read_verify(
a2ceac1f
DC
281 struct xfs_buf *bp)
282{
a2ceac1f 283 struct xfs_da_blkinfo *info = bp->b_addr;
1e697959 284 xfs_failaddr_t fa;
a2ceac1f
DC
285
286 switch (be16_to_cpu(info->magic)) {
88b32f06 287 case XFS_DA3_NODE_MAGIC:
45922933 288 if (!xfs_buf_verify_cksum(bp, XFS_DA3_NODE_CRC_OFF)) {
1e697959
DW
289 xfs_verifier_error(bp, -EFSBADCRC,
290 __this_address);
88b32f06 291 break;
45922933 292 }
df9c7d8d 293 fallthrough;
a2ceac1f 294 case XFS_DA_NODE_MAGIC:
1e697959
DW
295 fa = xfs_da3_node_verify(bp);
296 if (fa)
297 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
88b32f06 298 return;
a2ceac1f 299 case XFS_ATTR_LEAF_MAGIC:
a24374f4
DC
300 case XFS_ATTR3_LEAF_MAGIC:
301 bp->b_ops = &xfs_attr3_leaf_buf_ops;
a2ceac1f
DC
302 bp->b_ops->verify_read(bp);
303 return;
304 case XFS_DIR2_LEAFN_MAGIC:
65b80c98
DC
305 case XFS_DIR3_LEAFN_MAGIC:
306 bp->b_ops = &xfs_dir3_leafn_buf_ops;
a2ceac1f
DC
307 bp->b_ops->verify_read(bp);
308 return;
309 default:
1e697959 310 xfs_verifier_error(bp, -EFSCORRUPTED, __this_address);
a2ceac1f
DC
311 break;
312 }
313}
314
95d9582b
DW
315/* Verify the structure of a da3 block. */
316static xfs_failaddr_t
317xfs_da3_node_verify_struct(
318 struct xfs_buf *bp)
319{
320 struct xfs_da_blkinfo *info = bp->b_addr;
321
322 switch (be16_to_cpu(info->magic)) {
323 case XFS_DA3_NODE_MAGIC:
324 case XFS_DA_NODE_MAGIC:
325 return xfs_da3_node_verify(bp);
326 case XFS_ATTR_LEAF_MAGIC:
327 case XFS_ATTR3_LEAF_MAGIC:
328 bp->b_ops = &xfs_attr3_leaf_buf_ops;
329 return bp->b_ops->verify_struct(bp);
330 case XFS_DIR2_LEAFN_MAGIC:
331 case XFS_DIR3_LEAFN_MAGIC:
332 bp->b_ops = &xfs_dir3_leafn_buf_ops;
333 return bp->b_ops->verify_struct(bp);
334 default:
335 return __this_address;
336 }
337}
338
88b32f06 339const struct xfs_buf_ops xfs_da3_node_buf_ops = {
a3fac935 340 .name = "xfs_da3_node",
9e26de8f
DW
341 .magic16 = { cpu_to_be16(XFS_DA_NODE_MAGIC),
342 cpu_to_be16(XFS_DA3_NODE_MAGIC) },
88b32f06
DC
343 .verify_read = xfs_da3_node_read_verify,
344 .verify_write = xfs_da3_node_write_verify,
95d9582b 345 .verify_struct = xfs_da3_node_verify_struct,
a2ceac1f
DC
346};
347
02cc4995
CH
348static int
349xfs_da3_node_set_type(
350 struct xfs_trans *tp,
351 struct xfs_buf *bp)
352{
353 struct xfs_da_blkinfo *info = bp->b_addr;
354
355 switch (be16_to_cpu(info->magic)) {
356 case XFS_DA_NODE_MAGIC:
357 case XFS_DA3_NODE_MAGIC:
358 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
359 return 0;
360 case XFS_ATTR_LEAF_MAGIC:
361 case XFS_ATTR3_LEAF_MAGIC:
362 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_ATTR_LEAF_BUF);
363 return 0;
364 case XFS_DIR2_LEAFN_MAGIC:
365 case XFS_DIR3_LEAFN_MAGIC:
366 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF);
367 return 0;
368 default:
369 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp,
370 info, sizeof(*info));
371 xfs_trans_brelse(tp, bp);
372 return -EFSCORRUPTED;
373 }
374}
375
a2ceac1f 376int
88b32f06 377xfs_da3_node_read(
a2ceac1f
DC
378 struct xfs_trans *tp,
379 struct xfs_inode *dp,
380 xfs_dablk_t bno,
a2ceac1f 381 struct xfs_buf **bpp,
02cc4995 382 int whichfork)
a2ceac1f 383{
02cc4995 384 int error;
8b4dc4a9 385
5f356ae6 386 error = xfs_da_read_buf(tp, dp, bno, 0, bpp, whichfork,
02cc4995
CH
387 &xfs_da3_node_buf_ops);
388 if (error || !*bpp || !tp)
389 return error;
390 return xfs_da3_node_set_type(tp, *bpp);
391}
8b4dc4a9 392
02cc4995
CH
393int
394xfs_da3_node_read_mapped(
395 struct xfs_trans *tp,
396 struct xfs_inode *dp,
397 xfs_daddr_t mappedbno,
398 struct xfs_buf **bpp,
399 int whichfork)
400{
5f356ae6 401 struct xfs_mount *mp = dp->i_mount;
02cc4995
CH
402 int error;
403
5f356ae6
CH
404 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, mappedbno,
405 XFS_FSB_TO_BB(mp, xfs_dabuf_nfsb(mp, whichfork)), 0,
406 bpp, &xfs_da3_node_buf_ops);
407 if (error || !*bpp)
02cc4995 408 return error;
5f356ae6
CH
409
410 if (whichfork == XFS_ATTR_FORK)
411 xfs_buf_set_ref(*bpp, XFS_ATTR_BTREE_REF);
412 else
413 xfs_buf_set_ref(*bpp, XFS_DIR_BTREE_REF);
414
415 if (!tp)
416 return 0;
02cc4995 417 return xfs_da3_node_set_type(tp, *bpp);
a2ceac1f
DC
418}
419
2bd0ea18
NS
420/*========================================================================
421 * Routines used for growing the Btree.
422 *========================================================================*/
423
424/*
425 * Create the initial contents of an intermediate node.
426 */
427int
88b32f06
DC
428xfs_da3_node_create(
429 struct xfs_da_args *args,
430 xfs_dablk_t blkno,
431 int level,
432 struct xfs_buf **bpp,
433 int whichfork)
2bd0ea18 434{
88b32f06
DC
435 struct xfs_da_intnode *node;
436 struct xfs_trans *tp = args->trans;
437 struct xfs_mount *mp = tp->t_mountp;
438 struct xfs_da3_icnode_hdr ichdr = {0};
439 struct xfs_buf *bp;
440 int error;
ff105f75 441 struct xfs_inode *dp = args->dp;
2bd0ea18 442
a2ceac1f 443 trace_xfs_da_node_create(args);
88b32f06 444 ASSERT(level <= XFS_DA_NODE_MAXDEPTH);
a2ceac1f 445
c1d19744 446 error = xfs_da_get_buf(tp, dp, blkno, &bp, whichfork);
2bd0ea18 447 if (error)
af43ca9f 448 return error;
8b4dc4a9 449 bp->b_ops = &xfs_da3_node_buf_ops;
bdc16ee5 450 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
a2ceac1f 451 node = bp->b_addr;
2bd0ea18 452
b16a427a 453 if (xfs_has_crc(mp)) {
88b32f06
DC
454 struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
455
a65d8d29 456 memset(hdr3, 0, sizeof(struct xfs_da3_node_hdr));
88b32f06 457 ichdr.magic = XFS_DA3_NODE_MAGIC;
f1208396 458 hdr3->info.blkno = cpu_to_be64(xfs_buf_daddr(bp));
88b32f06 459 hdr3->info.owner = cpu_to_be64(args->dp->i_ino);
9c4e12fb 460 uuid_copy(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid);
88b32f06
DC
461 } else {
462 ichdr.magic = XFS_DA_NODE_MAGIC;
463 }
464 ichdr.level = level;
465
b81278fa 466 xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr);
a2ceac1f 467 xfs_trans_log_buf(tp, bp,
52be9b6a 468 XFS_DA_LOGRANGE(node, &node->hdr, args->geo->node_hdr_size));
2bd0ea18
NS
469
470 *bpp = bp;
af43ca9f 471 return 0;
2bd0ea18
NS
472}
473
474/*
475 * Split a leaf node, rebalance, then possibly split
476 * intermediate nodes, rebalance, etc.
477 */
478int /* error */
88b32f06
DC
479xfs_da3_split(
480 struct xfs_da_state *state)
2bd0ea18 481{
88b32f06
DC
482 struct xfs_da_state_blk *oldblk;
483 struct xfs_da_state_blk *newblk;
484 struct xfs_da_state_blk *addblk;
485 struct xfs_da_intnode *node;
88b32f06 486 int max;
6bddecbc 487 int action = 0;
88b32f06
DC
488 int error;
489 int i;
2bd0ea18 490
a2ceac1f
DC
491 trace_xfs_da_split(state->args);
492
7f92d9ee
AH
493 if (XFS_TEST_ERROR(false, state->mp, XFS_ERRTAG_DA_LEAF_SPLIT))
494 return -EIO;
495
2bd0ea18
NS
496 /*
497 * Walk back up the tree splitting/inserting/adjusting as necessary.
498 * If we need to insert and there isn't room, split the node, then
499 * decide which fragment to insert the new block from below into.
500 * Note that we may split the root this way, but we need more fixup.
501 */
502 max = state->path.active - 1;
503 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
504 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
5e656dbb 505 state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
2bd0ea18
NS
506
507 addblk = &state->path.blk[max]; /* initial dummy value */
508 for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
509 oldblk = &state->path.blk[i];
510 newblk = &state->altpath.blk[i];
511
512 /*
513 * If a leaf node then
514 * Allocate a new leaf node, then rebalance across them.
515 * else if an intermediate node then
516 * We split on the last layer, must we split the node?
517 */
518 switch (oldblk->magic) {
519 case XFS_ATTR_LEAF_MAGIC:
a24374f4 520 error = xfs_attr3_leaf_split(state, oldblk, newblk);
12b53197 521 if ((error != 0) && (error != -ENOSPC)) {
af43ca9f 522 return error; /* GROT: attr is inconsistent */
2bd0ea18
NS
523 }
524 if (!error) {
525 addblk = newblk;
526 break;
527 }
528 /*
4280e59d
DC
529 * Entry wouldn't fit, split the leaf again. The new
530 * extrablk will be consumed by xfs_da3_node_split if
531 * the node is split.
2bd0ea18
NS
532 */
533 state->extravalid = 1;
534 if (state->inleaf) {
535 state->extraafter = 0; /* before newblk */
a2ceac1f 536 trace_xfs_attr_leaf_split_before(state->args);
a24374f4 537 error = xfs_attr3_leaf_split(state, oldblk,
2bd0ea18
NS
538 &state->extrablk);
539 } else {
540 state->extraafter = 1; /* after newblk */
a2ceac1f 541 trace_xfs_attr_leaf_split_after(state->args);
a24374f4 542 error = xfs_attr3_leaf_split(state, newblk,
2bd0ea18
NS
543 &state->extrablk);
544 }
545 if (error)
af43ca9f 546 return error; /* GROT: attr inconsistent */
2bd0ea18
NS
547 addblk = newblk;
548 break;
2bd0ea18 549 case XFS_DIR2_LEAFN_MAGIC:
2bd0ea18
NS
550 error = xfs_dir2_leafn_split(state, oldblk, newblk);
551 if (error)
552 return error;
553 addblk = newblk;
554 break;
555 case XFS_DA_NODE_MAGIC:
88b32f06 556 error = xfs_da3_node_split(state, oldblk, newblk, addblk,
2bd0ea18 557 max - i, &action);
2bd0ea18
NS
558 addblk->bp = NULL;
559 if (error)
af43ca9f 560 return error; /* GROT: dir is inconsistent */
2bd0ea18
NS
561 /*
562 * Record the newly split block for the next time thru?
563 */
564 if (action)
565 addblk = newblk;
566 else
567 addblk = NULL;
568 break;
569 }
570
571 /*
572 * Update the btree to show the new hashval for this child.
573 */
88b32f06 574 xfs_da3_fixhashpath(state, &state->path);
2bd0ea18
NS
575 }
576 if (!addblk)
af43ca9f 577 return 0;
2bd0ea18 578
4280e59d
DC
579 /*
580 * xfs_da3_node_split() should have consumed any extra blocks we added
581 * during a double leaf split in the attr fork. This is guaranteed as
582 * we can't be here if the attr fork only has a single leaf block.
583 */
584 ASSERT(state->extravalid == 0 ||
585 state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
586
2bd0ea18
NS
587 /*
588 * Split the root node.
589 */
590 ASSERT(state->path.active == 0);
591 oldblk = &state->path.blk[0];
88b32f06 592 error = xfs_da3_root_split(state, oldblk, addblk);
ffab1122
DW
593 if (error)
594 goto out;
2bd0ea18
NS
595
596 /*
4280e59d
DC
597 * Update pointers to the node which used to be block 0 and just got
598 * bumped because of the addition of a new root node. Note that the
599 * original block 0 could be at any position in the list of blocks in
600 * the tree.
88b32f06 601 *
4280e59d
DC
602 * Note: the magic numbers and sibling pointers are in the same physical
603 * place for both v2 and v3 headers (by design). Hence it doesn't matter
604 * which version of the xfs_da_intnode structure we use here as the
605 * result will be the same using either structure.
2bd0ea18 606 */
a2ceac1f 607 node = oldblk->bp->b_addr;
46eca962 608 if (node->hdr.info.forw) {
ffab1122 609 if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {
1be76d11 610 xfs_buf_mark_corrupt(oldblk->bp);
ffab1122
DW
611 error = -EFSCORRUPTED;
612 goto out;
613 }
4280e59d 614 node = addblk->bp->b_addr;
5e656dbb 615 node->hdr.info.back = cpu_to_be32(oldblk->blkno);
4280e59d
DC
616 xfs_trans_log_buf(state->args->trans, addblk->bp,
617 XFS_DA_LOGRANGE(node, &node->hdr.info,
618 sizeof(node->hdr.info)));
2bd0ea18 619 }
a2ceac1f 620 node = oldblk->bp->b_addr;
5e656dbb 621 if (node->hdr.info.back) {
ffab1122 622 if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {
1be76d11 623 xfs_buf_mark_corrupt(oldblk->bp);
ffab1122
DW
624 error = -EFSCORRUPTED;
625 goto out;
626 }
4280e59d 627 node = addblk->bp->b_addr;
5e656dbb 628 node->hdr.info.forw = cpu_to_be32(oldblk->blkno);
4280e59d
DC
629 xfs_trans_log_buf(state->args->trans, addblk->bp,
630 XFS_DA_LOGRANGE(node, &node->hdr.info,
631 sizeof(node->hdr.info)));
2bd0ea18 632 }
ffab1122 633out:
2bd0ea18 634 addblk->bp = NULL;
ffab1122 635 return error;
2bd0ea18
NS
636}
637
638/*
639 * Split the root. We have to create a new root and point to the two
640 * parts (the split old root) that we just created. Copy block zero to
641 * the EOF, extending the inode in process.
642 */
643STATIC int /* error */
88b32f06
DC
644xfs_da3_root_split(
645 struct xfs_da_state *state,
646 struct xfs_da_state_blk *blk1,
647 struct xfs_da_state_blk *blk2)
2bd0ea18 648{
88b32f06
DC
649 struct xfs_da_intnode *node;
650 struct xfs_da_intnode *oldroot;
651 struct xfs_da_node_entry *btree;
652 struct xfs_da3_icnode_hdr nodehdr;
653 struct xfs_da_args *args;
654 struct xfs_buf *bp;
655 struct xfs_inode *dp;
656 struct xfs_trans *tp;
88b32f06
DC
657 struct xfs_dir2_leaf *leaf;
658 xfs_dablk_t blkno;
659 int level;
660 int error;
661 int size;
2bd0ea18 662
a2ceac1f
DC
663 trace_xfs_da_root_split(state->args);
664
2bd0ea18
NS
665 /*
666 * Copy the existing (incorrect) block from the root node position
667 * to a free space somewhere.
668 */
669 args = state->args;
2bd0ea18
NS
670 error = xfs_da_grow_inode(args, &blkno);
671 if (error)
88b32f06
DC
672 return error;
673
2bd0ea18
NS
674 dp = args->dp;
675 tp = args->trans;
c1d19744 676 error = xfs_da_get_buf(tp, dp, blkno, &bp, args->whichfork);
2bd0ea18 677 if (error)
88b32f06 678 return error;
a2ceac1f
DC
679 node = bp->b_addr;
680 oldroot = blk1->bp->b_addr;
88b32f06
DC
681 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
682 oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) {
19ebedcf 683 struct xfs_da3_icnode_hdr icnodehdr;
88b32f06 684
08c16786 685 xfs_da3_node_hdr_from_disk(dp->i_mount, &icnodehdr, oldroot);
8faa51a8 686 btree = icnodehdr.btree;
19ebedcf
DC
687 size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot);
688 level = icnodehdr.level;
8b4dc4a9
DC
689
690 /*
691 * we are about to copy oldroot to bp, so set up the type
692 * of bp while we know exactly what it will be.
693 */
bdc16ee5 694 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
2bd0ea18 695 } else {
65b80c98 696 struct xfs_dir3_icleaf_hdr leafhdr;
65b80c98 697
2bd0ea18 698 leaf = (xfs_dir2_leaf_t *)oldroot;
9db68faf 699 xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
65b80c98
DC
700
701 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
702 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
a2279497
CH
703 size = (int)((char *)&leafhdr.ents[leafhdr.count] -
704 (char *)leaf);
88b32f06 705 level = 0;
8b4dc4a9
DC
706
707 /*
708 * we are about to copy oldroot to bp, so set up the type
709 * of bp while we know exactly what it will be.
710 */
bdc16ee5 711 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF);
2bd0ea18 712 }
88b32f06
DC
713
714 /*
715 * we can copy most of the information in the node from one block to
716 * another, but for CRC enabled headers we have to make sure that the
717 * block specific identifiers are kept intact. We update the buffer
718 * directly for this.
719 */
32181a02 720 memcpy(node, oldroot, size);
88b32f06
DC
721 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) ||
722 oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
723 struct xfs_da3_intnode *node3 = (struct xfs_da3_intnode *)node;
724
f1208396 725 node3->hdr.info.blkno = cpu_to_be64(xfs_buf_daddr(bp));
88b32f06 726 }
a2ceac1f
DC
727 xfs_trans_log_buf(tp, bp, 0, size - 1);
728
729 bp->b_ops = blk1->bp->b_ops;
e26915ee 730 xfs_trans_buf_copy_type(bp, blk1->bp);
2bd0ea18
NS
731 blk1->bp = bp;
732 blk1->blkno = blkno;
733
734 /*
735 * Set up the new root node.
736 */
88b32f06 737 error = xfs_da3_node_create(args,
ff105f75 738 (args->whichfork == XFS_DATA_FORK) ? args->geo->leafblk : 0,
88b32f06 739 level + 1, &bp, args->whichfork);
2bd0ea18 740 if (error)
88b32f06
DC
741 return error;
742
a2ceac1f 743 node = bp->b_addr;
08c16786 744 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
8faa51a8 745 btree = nodehdr.btree;
88b32f06
DC
746 btree[0].hashval = cpu_to_be32(blk1->hashval);
747 btree[0].before = cpu_to_be32(blk1->blkno);
748 btree[1].hashval = cpu_to_be32(blk2->hashval);
749 btree[1].before = cpu_to_be32(blk2->blkno);
750 nodehdr.count = 2;
b81278fa 751 xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
6bef826c
NS
752
753#ifdef DEBUG
65b80c98
DC
754 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
755 oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
ff105f75
DC
756 ASSERT(blk1->blkno >= args->geo->leafblk &&
757 blk1->blkno < args->geo->freeblk);
758 ASSERT(blk2->blkno >= args->geo->leafblk &&
759 blk2->blkno < args->geo->freeblk);
2bd0ea18 760 }
6bef826c
NS
761#endif
762
2bd0ea18 763 /* Header is already logged by xfs_da_node_create */
a2ceac1f 764 xfs_trans_log_buf(tp, bp,
88b32f06 765 XFS_DA_LOGRANGE(node, btree, sizeof(xfs_da_node_entry_t) * 2));
2bd0ea18 766
88b32f06 767 return 0;
2bd0ea18
NS
768}
769
770/*
771 * Split the node, rebalance, then add the new entry.
772 */
773STATIC int /* error */
88b32f06
DC
774xfs_da3_node_split(
775 struct xfs_da_state *state,
776 struct xfs_da_state_blk *oldblk,
777 struct xfs_da_state_blk *newblk,
778 struct xfs_da_state_blk *addblk,
779 int treelevel,
780 int *result)
2bd0ea18 781{
88b32f06
DC
782 struct xfs_da_intnode *node;
783 struct xfs_da3_icnode_hdr nodehdr;
784 xfs_dablk_t blkno;
785 int newcount;
786 int error;
787 int useextra;
ff105f75 788 struct xfs_inode *dp = state->args->dp;
2bd0ea18 789
a2ceac1f
DC
790 trace_xfs_da_node_split(state->args);
791
792 node = oldblk->bp->b_addr;
08c16786 793 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
2bd0ea18
NS
794
795 /*
5e656dbb 796 * With V2 dirs the extra block is data or freespace.
2bd0ea18 797 */
5e656dbb 798 useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;
2bd0ea18
NS
799 newcount = 1 + useextra;
800 /*
801 * Do we have to split the node?
802 */
ff105f75 803 if (nodehdr.count + newcount > state->args->geo->node_ents) {
2bd0ea18
NS
804 /*
805 * Allocate a new node, add to the doubly linked chain of
806 * nodes, then move some of our excess entries into it.
807 */
808 error = xfs_da_grow_inode(state->args, &blkno);
809 if (error)
af43ca9f 810 return error; /* GROT: dir is inconsistent */
5000d01d 811
88b32f06 812 error = xfs_da3_node_create(state->args, blkno, treelevel,
2bd0ea18
NS
813 &newblk->bp, state->args->whichfork);
814 if (error)
af43ca9f 815 return error; /* GROT: dir is inconsistent */
2bd0ea18
NS
816 newblk->blkno = blkno;
817 newblk->magic = XFS_DA_NODE_MAGIC;
88b32f06
DC
818 xfs_da3_node_rebalance(state, oldblk, newblk);
819 error = xfs_da3_blk_link(state, oldblk, newblk);
2bd0ea18 820 if (error)
af43ca9f 821 return error;
2bd0ea18
NS
822 *result = 1;
823 } else {
824 *result = 0;
825 }
826
827 /*
828 * Insert the new entry(s) into the correct block
829 * (updating last hashval in the process).
830 *
88b32f06 831 * xfs_da3_node_add() inserts BEFORE the given index,
2bd0ea18
NS
832 * and as a result of using node_lookup_int() we always
833 * point to a valid entry (not after one), but a split
834 * operation always results in a new block whose hashvals
835 * FOLLOW the current block.
836 *
837 * If we had double-split op below us, then add the extra block too.
838 */
a2ceac1f 839 node = oldblk->bp->b_addr;
08c16786 840 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
88b32f06 841 if (oldblk->index <= nodehdr.count) {
2bd0ea18 842 oldblk->index++;
88b32f06 843 xfs_da3_node_add(state, oldblk, addblk);
2bd0ea18
NS
844 if (useextra) {
845 if (state->extraafter)
846 oldblk->index++;
88b32f06 847 xfs_da3_node_add(state, oldblk, &state->extrablk);
2bd0ea18
NS
848 state->extravalid = 0;
849 }
850 } else {
851 newblk->index++;
88b32f06 852 xfs_da3_node_add(state, newblk, addblk);
2bd0ea18
NS
853 if (useextra) {
854 if (state->extraafter)
855 newblk->index++;
88b32f06 856 xfs_da3_node_add(state, newblk, &state->extrablk);
2bd0ea18
NS
857 state->extravalid = 0;
858 }
859 }
860
af43ca9f 861 return 0;
2bd0ea18
NS
862}
863
864/*
865 * Balance the btree elements between two intermediate nodes,
866 * usually one full and one empty.
867 *
868 * NOTE: if blk2 is empty, then it will get the upper half of blk1.
869 */
870STATIC void
88b32f06
DC
871xfs_da3_node_rebalance(
872 struct xfs_da_state *state,
873 struct xfs_da_state_blk *blk1,
874 struct xfs_da_state_blk *blk2)
2bd0ea18 875{
88b32f06
DC
876 struct xfs_da_intnode *node1;
877 struct xfs_da_intnode *node2;
88b32f06
DC
878 struct xfs_da_node_entry *btree1;
879 struct xfs_da_node_entry *btree2;
880 struct xfs_da_node_entry *btree_s;
881 struct xfs_da_node_entry *btree_d;
882 struct xfs_da3_icnode_hdr nodehdr1;
883 struct xfs_da3_icnode_hdr nodehdr2;
884 struct xfs_trans *tp;
885 int count;
886 int tmp;
887 int swap = 0;
ff105f75 888 struct xfs_inode *dp = state->args->dp;
2bd0ea18 889
a2ceac1f
DC
890 trace_xfs_da_node_rebalance(state->args);
891
892 node1 = blk1->bp->b_addr;
893 node2 = blk2->bp->b_addr;
08c16786
CH
894 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
895 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
8faa51a8
CH
896 btree1 = nodehdr1.btree;
897 btree2 = nodehdr2.btree;
88b32f06 898
2bd0ea18
NS
899 /*
900 * Figure out how many entries need to move, and in which direction.
901 * Swap the nodes around if that makes it simpler.
902 */
88b32f06
DC
903 if (nodehdr1.count > 0 && nodehdr2.count > 0 &&
904 ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) ||
905 (be32_to_cpu(btree2[nodehdr2.count - 1].hashval) <
906 be32_to_cpu(btree1[nodehdr1.count - 1].hashval)))) {
016bb3d1 907 swap(node1, node2);
08c16786
CH
908 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
909 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
8faa51a8
CH
910 btree1 = nodehdr1.btree;
911 btree2 = nodehdr2.btree;
88b32f06 912 swap = 1;
2bd0ea18 913 }
88b32f06
DC
914
915 count = (nodehdr1.count - nodehdr2.count) / 2;
2bd0ea18
NS
916 if (count == 0)
917 return;
918 tp = state->args->trans;
919 /*
920 * Two cases: high-to-low and low-to-high.
921 */
922 if (count > 0) {
923 /*
924 * Move elements in node2 up to make a hole.
925 */
88b32f06
DC
926 tmp = nodehdr2.count;
927 if (tmp > 0) {
2bd0ea18 928 tmp *= (uint)sizeof(xfs_da_node_entry_t);
88b32f06
DC
929 btree_s = &btree2[0];
930 btree_d = &btree2[count];
32181a02 931 memmove(btree_d, btree_s, tmp);
2bd0ea18
NS
932 }
933
934 /*
935 * Move the req'd B-tree elements from high in node1 to
936 * low in node2.
937 */
88b32f06 938 nodehdr2.count += count;
2bd0ea18 939 tmp = count * (uint)sizeof(xfs_da_node_entry_t);
7b02556d 940 btree_s = &btree1[nodehdr1.count - count];
88b32f06 941 btree_d = &btree2[0];
32181a02 942 memcpy(btree_d, btree_s, tmp);
88b32f06 943 nodehdr1.count -= count;
2bd0ea18
NS
944 } else {
945 /*
946 * Move the req'd B-tree elements from low in node2 to
947 * high in node1.
948 */
949 count = -count;
950 tmp = count * (uint)sizeof(xfs_da_node_entry_t);
88b32f06
DC
951 btree_s = &btree2[0];
952 btree_d = &btree1[nodehdr1.count];
32181a02 953 memcpy(btree_d, btree_s, tmp);
88b32f06
DC
954 nodehdr1.count += count;
955
a2ceac1f 956 xfs_trans_log_buf(tp, blk1->bp,
2bd0ea18
NS
957 XFS_DA_LOGRANGE(node1, btree_d, tmp));
958
959 /*
960 * Move elements in node2 down to fill the hole.
961 */
88b32f06 962 tmp = nodehdr2.count - count;
2bd0ea18 963 tmp *= (uint)sizeof(xfs_da_node_entry_t);
88b32f06
DC
964 btree_s = &btree2[count];
965 btree_d = &btree2[0];
32181a02 966 memmove(btree_d, btree_s, tmp);
88b32f06 967 nodehdr2.count -= count;
2bd0ea18
NS
968 }
969
970 /*
971 * Log header of node 1 and all current bits of node 2.
972 */
b81278fa 973 xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1);
a2ceac1f 974 xfs_trans_log_buf(tp, blk1->bp,
52be9b6a
CH
975 XFS_DA_LOGRANGE(node1, &node1->hdr,
976 state->args->geo->node_hdr_size));
88b32f06 977
b81278fa 978 xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2);
a2ceac1f 979 xfs_trans_log_buf(tp, blk2->bp,
2bd0ea18 980 XFS_DA_LOGRANGE(node2, &node2->hdr,
52be9b6a 981 state->args->geo->node_hdr_size +
88b32f06 982 (sizeof(btree2[0]) * nodehdr2.count)));
2bd0ea18
NS
983
984 /*
985 * Record the last hashval from each block for upward propagation.
986 * (note: don't use the swapped node pointers)
987 */
88b32f06
DC
988 if (swap) {
989 node1 = blk1->bp->b_addr;
990 node2 = blk2->bp->b_addr;
08c16786
CH
991 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);
992 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);
8faa51a8
CH
993 btree1 = nodehdr1.btree;
994 btree2 = nodehdr2.btree;
88b32f06
DC
995 }
996 blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval);
997 blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval);
2bd0ea18
NS
998
999 /*
1000 * Adjust the expected index for insertion.
1001 */
88b32f06
DC
1002 if (blk1->index >= nodehdr1.count) {
1003 blk2->index = blk1->index - nodehdr1.count;
1004 blk1->index = nodehdr1.count + 1; /* make it invalid */
2bd0ea18
NS
1005 }
1006}
1007
1008/*
1009 * Add a new entry to an intermediate node.
1010 */
1011STATIC void
88b32f06
DC
1012xfs_da3_node_add(
1013 struct xfs_da_state *state,
1014 struct xfs_da_state_blk *oldblk,
1015 struct xfs_da_state_blk *newblk)
2bd0ea18 1016{
88b32f06
DC
1017 struct xfs_da_intnode *node;
1018 struct xfs_da3_icnode_hdr nodehdr;
1019 struct xfs_da_node_entry *btree;
1020 int tmp;
ff105f75 1021 struct xfs_inode *dp = state->args->dp;
2bd0ea18 1022
a2ceac1f
DC
1023 trace_xfs_da_node_add(state->args);
1024
1025 node = oldblk->bp->b_addr;
08c16786 1026 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
8faa51a8 1027 btree = nodehdr.btree;
88b32f06
DC
1028
1029 ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
2bd0ea18 1030 ASSERT(newblk->blkno != 0);
5e656dbb 1031 if (state->args->whichfork == XFS_DATA_FORK)
ff105f75
DC
1032 ASSERT(newblk->blkno >= state->args->geo->leafblk &&
1033 newblk->blkno < state->args->geo->freeblk);
2bd0ea18
NS
1034
1035 /*
1036 * We may need to make some room before we insert the new node.
1037 */
1038 tmp = 0;
88b32f06
DC
1039 if (oldblk->index < nodehdr.count) {
1040 tmp = (nodehdr.count - oldblk->index) * (uint)sizeof(*btree);
1041 memmove(&btree[oldblk->index + 1], &btree[oldblk->index], tmp);
2bd0ea18 1042 }
88b32f06
DC
1043 btree[oldblk->index].hashval = cpu_to_be32(newblk->hashval);
1044 btree[oldblk->index].before = cpu_to_be32(newblk->blkno);
a2ceac1f 1045 xfs_trans_log_buf(state->args->trans, oldblk->bp,
88b32f06
DC
1046 XFS_DA_LOGRANGE(node, &btree[oldblk->index],
1047 tmp + sizeof(*btree)));
1048
1049 nodehdr.count += 1;
b81278fa 1050 xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
a2ceac1f 1051 xfs_trans_log_buf(state->args->trans, oldblk->bp,
52be9b6a
CH
1052 XFS_DA_LOGRANGE(node, &node->hdr,
1053 state->args->geo->node_hdr_size));
2bd0ea18
NS
1054
1055 /*
1056 * Copy the last hash value from the oldblk to propagate upwards.
1057 */
88b32f06 1058 oldblk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval);
2bd0ea18
NS
1059}
1060
1061/*========================================================================
1062 * Routines used for shrinking the Btree.
1063 *========================================================================*/
1064
1065/*
1066 * Deallocate an empty leaf node, remove it from its parent,
1067 * possibly deallocating that block, etc...
1068 */
1069int
88b32f06
DC
1070xfs_da3_join(
1071 struct xfs_da_state *state)
2bd0ea18 1072{
88b32f06
DC
1073 struct xfs_da_state_blk *drop_blk;
1074 struct xfs_da_state_blk *save_blk;
1075 int action = 0;
1076 int error;
2bd0ea18 1077
a2ceac1f
DC
1078 trace_xfs_da_join(state->args);
1079
2bd0ea18
NS
1080 drop_blk = &state->path.blk[ state->path.active-1 ];
1081 save_blk = &state->altpath.blk[ state->path.active-1 ];
1082 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
1083 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
5e656dbb 1084 drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
2bd0ea18
NS
1085
1086 /*
1087 * Walk back up the tree joining/deallocating as necessary.
1088 * When we stop dropping blocks, break out.
1089 */
1090 for ( ; state->path.active >= 2; drop_blk--, save_blk--,
1091 state->path.active--) {
1092 /*
1093 * See if we can combine the block with a neighbor.
1094 * (action == 0) => no options, just leave
1095 * (action == 1) => coalesce, then unlink
1096 * (action == 2) => block empty, unlink it
1097 */
1098 switch (drop_blk->magic) {
1099 case XFS_ATTR_LEAF_MAGIC:
a24374f4 1100 error = xfs_attr3_leaf_toosmall(state, &action);
2bd0ea18 1101 if (error)
af43ca9f 1102 return error;
2bd0ea18 1103 if (action == 0)
af43ca9f 1104 return 0;
a24374f4 1105 xfs_attr3_leaf_unbalance(state, drop_blk, save_blk);
2bd0ea18 1106 break;
2bd0ea18 1107 case XFS_DIR2_LEAFN_MAGIC:
2bd0ea18
NS
1108 error = xfs_dir2_leafn_toosmall(state, &action);
1109 if (error)
1110 return error;
1111 if (action == 0)
1112 return 0;
1113 xfs_dir2_leafn_unbalance(state, drop_blk, save_blk);
1114 break;
1115 case XFS_DA_NODE_MAGIC:
1116 /*
1117 * Remove the offending node, fixup hashvals,
1118 * check for a toosmall neighbor.
1119 */
88b32f06
DC
1120 xfs_da3_node_remove(state, drop_blk);
1121 xfs_da3_fixhashpath(state, &state->path);
1122 error = xfs_da3_node_toosmall(state, &action);
2bd0ea18 1123 if (error)
af43ca9f 1124 return error;
2bd0ea18
NS
1125 if (action == 0)
1126 return 0;
88b32f06 1127 xfs_da3_node_unbalance(state, drop_blk, save_blk);
2bd0ea18
NS
1128 break;
1129 }
88b32f06
DC
1130 xfs_da3_fixhashpath(state, &state->altpath);
1131 error = xfs_da3_blk_unlink(state, drop_blk, save_blk);
2bd0ea18
NS
1132 xfs_da_state_kill_altpath(state);
1133 if (error)
af43ca9f 1134 return error;
2bd0ea18
NS
1135 error = xfs_da_shrink_inode(state->args, drop_blk->blkno,
1136 drop_blk->bp);
1137 drop_blk->bp = NULL;
1138 if (error)
af43ca9f 1139 return error;
2bd0ea18
NS
1140 }
1141 /*
1142 * We joined all the way to the top. If it turns out that
1143 * we only have one entry in the root, make the child block
1144 * the new root.
1145 */
88b32f06
DC
1146 xfs_da3_node_remove(state, drop_blk);
1147 xfs_da3_fixhashpath(state, &state->path);
1148 error = xfs_da3_root_join(state, &state->path.blk[0]);
af43ca9f 1149 return error;
2bd0ea18
NS
1150}
1151
a2ceac1f
DC
1152#ifdef DEBUG
1153static void
1154xfs_da_blkinfo_onlychild_validate(struct xfs_da_blkinfo *blkinfo, __u16 level)
1155{
1156 __be16 magic = blkinfo->magic;
1157
1158 if (level == 1) {
1159 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
65b80c98 1160 magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
a24374f4
DC
1161 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
1162 magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
88b32f06
DC
1163 } else {
1164 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
1165 magic == cpu_to_be16(XFS_DA3_NODE_MAGIC));
1166 }
a2ceac1f
DC
1167 ASSERT(!blkinfo->forw);
1168 ASSERT(!blkinfo->back);
1169}
1170#else /* !DEBUG */
1171#define xfs_da_blkinfo_onlychild_validate(blkinfo, level)
1172#endif /* !DEBUG */
1173
2bd0ea18 1174/*
dfc130f3 1175 * We have only one entry in the root. Copy the only remaining child of
2bd0ea18
NS
1176 * the old root to block 0 as the new root node.
1177 */
1178STATIC int
88b32f06
DC
1179xfs_da3_root_join(
1180 struct xfs_da_state *state,
1181 struct xfs_da_state_blk *root_blk)
2bd0ea18 1182{
88b32f06
DC
1183 struct xfs_da_intnode *oldroot;
1184 struct xfs_da_args *args;
1185 xfs_dablk_t child;
1186 struct xfs_buf *bp;
1187 struct xfs_da3_icnode_hdr oldroothdr;
88b32f06 1188 int error;
ff105f75 1189 struct xfs_inode *dp = state->args->dp;
2bd0ea18 1190
a2ceac1f
DC
1191 trace_xfs_da_root_join(state->args);
1192
2bd0ea18 1193 ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC);
88b32f06
DC
1194
1195 args = state->args;
a2ceac1f 1196 oldroot = root_blk->bp->b_addr;
08c16786 1197 xfs_da3_node_hdr_from_disk(dp->i_mount, &oldroothdr, oldroot);
88b32f06
DC
1198 ASSERT(oldroothdr.forw == 0);
1199 ASSERT(oldroothdr.back == 0);
2bd0ea18
NS
1200
1201 /*
1202 * If the root has more than one child, then don't do anything.
1203 */
88b32f06
DC
1204 if (oldroothdr.count > 1)
1205 return 0;
2bd0ea18
NS
1206
1207 /*
1208 * Read in the (only) child block, then copy those bytes into
1209 * the root block's buffer and free the original child block.
1210 */
8faa51a8 1211 child = be32_to_cpu(oldroothdr.btree[0].before);
2bd0ea18 1212 ASSERT(child != 0);
02cc4995 1213 error = xfs_da3_node_read(args->trans, dp, child, &bp, args->whichfork);
2bd0ea18 1214 if (error)
88b32f06
DC
1215 return error;
1216 xfs_da_blkinfo_onlychild_validate(bp->b_addr, oldroothdr.level);
a2ceac1f
DC
1217
1218 /*
1219 * This could be copying a leaf back into the root block in the case of
1220 * there only being a single leaf block left in the tree. Hence we have
1221 * to update the b_ops pointer as well to match the buffer type change
88b32f06
DC
1222 * that could occur. For dir3 blocks we also need to update the block
1223 * number in the buffer header.
a2ceac1f 1224 */
ff105f75 1225 memcpy(root_blk->bp->b_addr, bp->b_addr, args->geo->blksize);
a2ceac1f 1226 root_blk->bp->b_ops = bp->b_ops;
8b4dc4a9 1227 xfs_trans_buf_copy_type(root_blk->bp, bp);
88b32f06
DC
1228 if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) {
1229 struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr;
f1208396 1230 da3->blkno = cpu_to_be64(xfs_buf_daddr(root_blk->bp));
88b32f06 1231 }
ff105f75
DC
1232 xfs_trans_log_buf(args->trans, root_blk->bp, 0,
1233 args->geo->blksize - 1);
2bd0ea18 1234 error = xfs_da_shrink_inode(args, child, bp);
af43ca9f 1235 return error;
2bd0ea18
NS
1236}
1237
1238/*
1239 * Check a node block and its neighbors to see if the block should be
1240 * collapsed into one or the other neighbor. Always keep the block
1241 * with the smaller block number.
1242 * If the current block is over 50% full, don't try to join it, return 0.
1243 * If the block is empty, fill in the state structure and return 2.
1244 * If it can be collapsed, fill in the state structure and return 1.
1245 * If nothing can be done, return 0.
1246 */
1247STATIC int
88b32f06
DC
1248xfs_da3_node_toosmall(
1249 struct xfs_da_state *state,
1250 int *action)
2bd0ea18 1251{
88b32f06
DC
1252 struct xfs_da_intnode *node;
1253 struct xfs_da_state_blk *blk;
1254 struct xfs_da_blkinfo *info;
1255 xfs_dablk_t blkno;
1256 struct xfs_buf *bp;
1257 struct xfs_da3_icnode_hdr nodehdr;
1258 int count;
1259 int forward;
1260 int error;
1261 int retval;
1262 int i;
ff105f75 1263 struct xfs_inode *dp = state->args->dp;
a2ceac1f
DC
1264
1265 trace_xfs_da_node_toosmall(state->args);
2bd0ea18
NS
1266
1267 /*
1268 * Check for the degenerate case of the block being over 50% full.
1269 * If so, it's not worth even looking to see if we might be able
1270 * to coalesce with a sibling.
1271 */
1272 blk = &state->path.blk[ state->path.active-1 ];
a2ceac1f 1273 info = blk->bp->b_addr;
2bd0ea18 1274 node = (xfs_da_intnode_t *)info;
08c16786 1275 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
ff105f75 1276 if (nodehdr.count > (state->args->geo->node_ents >> 1)) {
4ca431fc 1277 *action = 0; /* blk over 50%, don't try to join */
af43ca9f 1278 return 0; /* blk over 50%, don't try to join */
2bd0ea18
NS
1279 }
1280
1281 /*
1282 * Check for the degenerate case of the block being empty.
1283 * If the block is empty, we'll simply delete it, no need to
5e656dbb 1284 * coalesce it with a sibling block. We choose (arbitrarily)
2bd0ea18
NS
1285 * to merge with the forward block unless it is NULL.
1286 */
88b32f06 1287 if (nodehdr.count == 0) {
2bd0ea18
NS
1288 /*
1289 * Make altpath point to the block we want to keep and
1290 * path point to the block we want to drop (this one).
1291 */
5e656dbb 1292 forward = (info->forw != 0);
32181a02 1293 memcpy(&state->altpath, &state->path, sizeof(state->path));
88b32f06 1294 error = xfs_da3_path_shift(state, &state->altpath, forward,
2bd0ea18
NS
1295 0, &retval);
1296 if (error)
af43ca9f 1297 return error;
2bd0ea18
NS
1298 if (retval) {
1299 *action = 0;
1300 } else {
1301 *action = 2;
1302 }
af43ca9f 1303 return 0;
2bd0ea18
NS
1304 }
1305
1306 /*
1307 * Examine each sibling block to see if we can coalesce with
1308 * at least 25% free space to spare. We need to figure out
1309 * whether to merge with the forward or the backward block.
1310 * We prefer coalescing with the lower numbered sibling so as
1311 * to shrink a directory over time.
1312 */
ff105f75
DC
1313 count = state->args->geo->node_ents;
1314 count -= state->args->geo->node_ents >> 2;
88b32f06
DC
1315 count -= nodehdr.count;
1316
2bd0ea18 1317 /* start with smaller blk num */
88b32f06 1318 forward = nodehdr.forw < nodehdr.back;
2bd0ea18 1319 for (i = 0; i < 2; forward = !forward, i++) {
c9522f4d 1320 struct xfs_da3_icnode_hdr thdr;
2bd0ea18 1321 if (forward)
88b32f06 1322 blkno = nodehdr.forw;
2bd0ea18 1323 else
88b32f06 1324 blkno = nodehdr.back;
2bd0ea18
NS
1325 if (blkno == 0)
1326 continue;
02cc4995
CH
1327 error = xfs_da3_node_read(state->args->trans, dp, blkno, &bp,
1328 state->args->whichfork);
2bd0ea18 1329 if (error)
af43ca9f 1330 return error;
2bd0ea18 1331
a2ceac1f 1332 node = bp->b_addr;
08c16786 1333 xfs_da3_node_hdr_from_disk(dp->i_mount, &thdr, node);
a2ceac1f 1334 xfs_trans_brelse(state->args->trans, bp);
88b32f06 1335
c9522f4d 1336 if (count - thdr.count >= 0)
2bd0ea18
NS
1337 break; /* fits with at least 25% to spare */
1338 }
1339 if (i >= 2) {
1340 *action = 0;
88b32f06 1341 return 0;
2bd0ea18
NS
1342 }
1343
1344 /*
1345 * Make altpath point to the block we want to keep (the lower
1346 * numbered block) and path point to the block we want to drop.
1347 */
32181a02 1348 memcpy(&state->altpath, &state->path, sizeof(state->path));
2bd0ea18 1349 if (blkno < blk->blkno) {
88b32f06 1350 error = xfs_da3_path_shift(state, &state->altpath, forward,
2bd0ea18 1351 0, &retval);
2bd0ea18 1352 } else {
88b32f06 1353 error = xfs_da3_path_shift(state, &state->path, forward,
2bd0ea18 1354 0, &retval);
88b32f06
DC
1355 }
1356 if (error)
1357 return error;
1358 if (retval) {
1359 *action = 0;
1360 return 0;
2bd0ea18
NS
1361 }
1362 *action = 1;
88b32f06
DC
1363 return 0;
1364}
1365
1366/*
1367 * Pick up the last hashvalue from an intermediate node.
1368 */
1369STATIC uint
1370xfs_da3_node_lasthash(
ff105f75 1371 struct xfs_inode *dp,
88b32f06
DC
1372 struct xfs_buf *bp,
1373 int *count)
1374{
88b32f06
DC
1375 struct xfs_da3_icnode_hdr nodehdr;
1376
8faa51a8 1377 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, bp->b_addr);
88b32f06
DC
1378 if (count)
1379 *count = nodehdr.count;
1380 if (!nodehdr.count)
1381 return 0;
8faa51a8 1382 return be32_to_cpu(nodehdr.btree[nodehdr.count - 1].hashval);
2bd0ea18
NS
1383}
1384
2bd0ea18
NS
1385/*
1386 * Walk back up the tree adjusting hash values as necessary,
1387 * when we stop making changes, return.
1388 */
1389void
88b32f06
DC
1390xfs_da3_fixhashpath(
1391 struct xfs_da_state *state,
1392 struct xfs_da_state_path *path)
2bd0ea18 1393{
88b32f06
DC
1394 struct xfs_da_state_blk *blk;
1395 struct xfs_da_intnode *node;
1396 struct xfs_da_node_entry *btree;
1397 xfs_dahash_t lasthash=0;
1398 int level;
1399 int count;
ff105f75 1400 struct xfs_inode *dp = state->args->dp;
2bd0ea18 1401
a2ceac1f
DC
1402 trace_xfs_da_fixhashpath(state->args);
1403
2bd0ea18
NS
1404 level = path->active-1;
1405 blk = &path->blk[ level ];
1406 switch (blk->magic) {
2bd0ea18
NS
1407 case XFS_ATTR_LEAF_MAGIC:
1408 lasthash = xfs_attr_leaf_lasthash(blk->bp, &count);
1409 if (count == 0)
1410 return;
1411 break;
2bd0ea18 1412 case XFS_DIR2_LEAFN_MAGIC:
94ffb80a 1413 lasthash = xfs_dir2_leaf_lasthash(dp, blk->bp, &count);
2bd0ea18
NS
1414 if (count == 0)
1415 return;
1416 break;
1417 case XFS_DA_NODE_MAGIC:
ff105f75 1418 lasthash = xfs_da3_node_lasthash(dp, blk->bp, &count);
2bd0ea18
NS
1419 if (count == 0)
1420 return;
1421 break;
1422 }
1423 for (blk--, level--; level >= 0; blk--, level--) {
88b32f06
DC
1424 struct xfs_da3_icnode_hdr nodehdr;
1425
a2ceac1f 1426 node = blk->bp->b_addr;
08c16786 1427 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
8faa51a8 1428 btree = nodehdr.btree;
0a3717c9 1429 if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
2bd0ea18
NS
1430 break;
1431 blk->hashval = lasthash;
88b32f06 1432 btree[blk->index].hashval = cpu_to_be32(lasthash);
a2ceac1f 1433 xfs_trans_log_buf(state->args->trans, blk->bp,
88b32f06
DC
1434 XFS_DA_LOGRANGE(node, &btree[blk->index],
1435 sizeof(*btree)));
2bd0ea18 1436
88b32f06 1437 lasthash = be32_to_cpu(btree[nodehdr.count - 1].hashval);
2bd0ea18
NS
1438 }
1439}
1440
2bd0ea18
NS
1441/*
1442 * Remove an entry from an intermediate node.
1443 */
1444STATIC void
88b32f06
DC
1445xfs_da3_node_remove(
1446 struct xfs_da_state *state,
1447 struct xfs_da_state_blk *drop_blk)
2bd0ea18 1448{
88b32f06
DC
1449 struct xfs_da_intnode *node;
1450 struct xfs_da3_icnode_hdr nodehdr;
1451 struct xfs_da_node_entry *btree;
1452 int index;
1453 int tmp;
ff105f75 1454 struct xfs_inode *dp = state->args->dp;
2bd0ea18 1455
a2ceac1f
DC
1456 trace_xfs_da_node_remove(state->args);
1457
1458 node = drop_blk->bp->b_addr;
08c16786 1459 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
88b32f06 1460 ASSERT(drop_blk->index < nodehdr.count);
2bd0ea18
NS
1461 ASSERT(drop_blk->index >= 0);
1462
1463 /*
1464 * Copy over the offending entry, or just zero it out.
1465 */
88b32f06 1466 index = drop_blk->index;
8faa51a8 1467 btree = nodehdr.btree;
88b32f06
DC
1468 if (index < nodehdr.count - 1) {
1469 tmp = nodehdr.count - index - 1;
2bd0ea18 1470 tmp *= (uint)sizeof(xfs_da_node_entry_t);
88b32f06 1471 memmove(&btree[index], &btree[index + 1], tmp);
a2ceac1f 1472 xfs_trans_log_buf(state->args->trans, drop_blk->bp,
88b32f06
DC
1473 XFS_DA_LOGRANGE(node, &btree[index], tmp));
1474 index = nodehdr.count - 1;
2bd0ea18 1475 }
88b32f06 1476 memset(&btree[index], 0, sizeof(xfs_da_node_entry_t));
a2ceac1f 1477 xfs_trans_log_buf(state->args->trans, drop_blk->bp,
88b32f06
DC
1478 XFS_DA_LOGRANGE(node, &btree[index], sizeof(btree[index])));
1479 nodehdr.count -= 1;
b81278fa 1480 xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);
a2ceac1f 1481 xfs_trans_log_buf(state->args->trans, drop_blk->bp,
52be9b6a 1482 XFS_DA_LOGRANGE(node, &node->hdr, state->args->geo->node_hdr_size));
2bd0ea18
NS
1483
1484 /*
1485 * Copy the last hash value from the block to propagate upwards.
1486 */
88b32f06 1487 drop_blk->hashval = be32_to_cpu(btree[index - 1].hashval);
2bd0ea18
NS
1488}
1489
1490/*
88b32f06 1491 * Unbalance the elements between two intermediate nodes,
2bd0ea18
NS
1492 * move all Btree elements from one node into another.
1493 */
1494STATIC void
88b32f06
DC
1495xfs_da3_node_unbalance(
1496 struct xfs_da_state *state,
1497 struct xfs_da_state_blk *drop_blk,
1498 struct xfs_da_state_blk *save_blk)
2bd0ea18 1499{
88b32f06
DC
1500 struct xfs_da_intnode *drop_node;
1501 struct xfs_da_intnode *save_node;
7b02556d
DC
1502 struct xfs_da_node_entry *drop_btree;
1503 struct xfs_da_node_entry *save_btree;
1504 struct xfs_da3_icnode_hdr drop_hdr;
1505 struct xfs_da3_icnode_hdr save_hdr;
88b32f06
DC
1506 struct xfs_trans *tp;
1507 int sindex;
1508 int tmp;
ff105f75 1509 struct xfs_inode *dp = state->args->dp;
2bd0ea18 1510
a2ceac1f
DC
1511 trace_xfs_da_node_unbalance(state->args);
1512
1513 drop_node = drop_blk->bp->b_addr;
1514 save_node = save_blk->bp->b_addr;
08c16786
CH
1515 xfs_da3_node_hdr_from_disk(dp->i_mount, &drop_hdr, drop_node);
1516 xfs_da3_node_hdr_from_disk(dp->i_mount, &save_hdr, save_node);
8faa51a8
CH
1517 drop_btree = drop_hdr.btree;
1518 save_btree = save_hdr.btree;
2bd0ea18
NS
1519 tp = state->args->trans;
1520
1521 /*
1522 * If the dying block has lower hashvals, then move all the
1523 * elements in the remaining block up to make a hole.
1524 */
7b02556d
DC
1525 if ((be32_to_cpu(drop_btree[0].hashval) <
1526 be32_to_cpu(save_btree[0].hashval)) ||
1527 (be32_to_cpu(drop_btree[drop_hdr.count - 1].hashval) <
1528 be32_to_cpu(save_btree[save_hdr.count - 1].hashval))) {
88b32f06 1529 /* XXX: check this - is memmove dst correct? */
7b02556d
DC
1530 tmp = save_hdr.count * sizeof(xfs_da_node_entry_t);
1531 memmove(&save_btree[drop_hdr.count], &save_btree[0], tmp);
88b32f06
DC
1532
1533 sindex = 0;
a2ceac1f 1534 xfs_trans_log_buf(tp, save_blk->bp,
7b02556d
DC
1535 XFS_DA_LOGRANGE(save_node, &save_btree[0],
1536 (save_hdr.count + drop_hdr.count) *
88b32f06 1537 sizeof(xfs_da_node_entry_t)));
2bd0ea18 1538 } else {
7b02556d 1539 sindex = save_hdr.count;
a2ceac1f 1540 xfs_trans_log_buf(tp, save_blk->bp,
7b02556d
DC
1541 XFS_DA_LOGRANGE(save_node, &save_btree[sindex],
1542 drop_hdr.count * sizeof(xfs_da_node_entry_t)));
2bd0ea18
NS
1543 }
1544
1545 /*
1546 * Move all the B-tree elements from drop_blk to save_blk.
1547 */
7b02556d
DC
1548 tmp = drop_hdr.count * (uint)sizeof(xfs_da_node_entry_t);
1549 memcpy(&save_btree[sindex], &drop_btree[0], tmp);
1550 save_hdr.count += drop_hdr.count;
2bd0ea18 1551
b81278fa 1552 xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr);
a2ceac1f 1553 xfs_trans_log_buf(tp, save_blk->bp,
2bd0ea18 1554 XFS_DA_LOGRANGE(save_node, &save_node->hdr,
52be9b6a 1555 state->args->geo->node_hdr_size));
2bd0ea18
NS
1556
1557 /*
1558 * Save the last hashval in the remaining block for upward propagation.
1559 */
7b02556d 1560 save_blk->hashval = be32_to_cpu(save_btree[save_hdr.count - 1].hashval);
2bd0ea18
NS
1561}
1562
2bd0ea18
NS
1563/*========================================================================
1564 * Routines used for finding things in the Btree.
1565 *========================================================================*/
1566
1567/*
1568 * Walk down the Btree looking for a particular filename, filling
1569 * in the state structure as we go.
1570 *
1571 * We will set the state structure to point to each of the elements
1572 * in each of the nodes where either the hashval is or should be.
1573 *
1574 * We support duplicate hashval's so for each entry in the current
1575 * node that could contain the desired hashval, descend. This is a
1576 * pruned depth-first tree search.
1577 */
1578int /* error */
88b32f06
DC
1579xfs_da3_node_lookup_int(
1580 struct xfs_da_state *state,
1581 int *result)
2bd0ea18 1582{
88b32f06
DC
1583 struct xfs_da_state_blk *blk;
1584 struct xfs_da_blkinfo *curr;
1585 struct xfs_da_intnode *node;
1586 struct xfs_da_node_entry *btree;
1587 struct xfs_da3_icnode_hdr nodehdr;
1588 struct xfs_da_args *args;
1589 xfs_dablk_t blkno;
1590 xfs_dahash_t hashval;
1591 xfs_dahash_t btreehashval;
1592 int probe;
1593 int span;
1594 int max;
1595 int error;
1596 int retval;
9473ee32 1597 unsigned int expected_level = 0;
ea09a747 1598 uint16_t magic;
ff105f75 1599 struct xfs_inode *dp = state->args->dp;
2bd0ea18
NS
1600
1601 args = state->args;
32a82561 1602
2bd0ea18
NS
1603 /*
1604 * Descend thru the B-tree searching each level for the right
1605 * node to use, until the right hashval is found.
1606 */
9473ee32 1607 blkno = args->geo->leafblk;
2bd0ea18
NS
1608 for (blk = &state->path.blk[0], state->path.active = 1;
1609 state->path.active <= XFS_DA_NODE_MAXDEPTH;
1610 blk++, state->path.active++) {
1611 /*
1612 * Read the next node down in the tree.
1613 */
1614 blk->blkno = blkno;
88b32f06 1615 error = xfs_da3_node_read(args->trans, args->dp, blkno,
02cc4995 1616 &blk->bp, args->whichfork);
2bd0ea18
NS
1617 if (error) {
1618 blk->blkno = 0;
1619 state->path.active--;
af43ca9f 1620 return error;
2bd0ea18 1621 }
a2ceac1f 1622 curr = blk->bp->b_addr;
ea09a747 1623 magic = be16_to_cpu(curr->magic);
88b32f06 1624
ea09a747
DW
1625 if (magic == XFS_ATTR_LEAF_MAGIC ||
1626 magic == XFS_ATTR3_LEAF_MAGIC) {
a24374f4 1627 blk->magic = XFS_ATTR_LEAF_MAGIC;
88b32f06
DC
1628 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
1629 break;
1630 }
1631
ea09a747
DW
1632 if (magic == XFS_DIR2_LEAFN_MAGIC ||
1633 magic == XFS_DIR3_LEAFN_MAGIC) {
88b32f06 1634 blk->magic = XFS_DIR2_LEAFN_MAGIC;
94ffb80a
DW
1635 blk->hashval = xfs_dir2_leaf_lasthash(args->dp,
1636 blk->bp, NULL);
88b32f06
DC
1637 break;
1638 }
1639
a0264b73 1640 if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) {
1be76d11 1641 xfs_buf_mark_corrupt(blk->bp);
b403e029 1642 return -EFSCORRUPTED;
a0264b73 1643 }
88b32f06 1644
b403e029 1645 blk->magic = XFS_DA_NODE_MAGIC;
2bd0ea18
NS
1646
1647 /*
1648 * Search an intermediate node for a match.
1649 */
88b32f06 1650 node = blk->bp->b_addr;
08c16786 1651 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);
8faa51a8 1652 btree = nodehdr.btree;
2bd0ea18 1653
9473ee32 1654 /* Tree taller than we can handle; bail out! */
a0264b73 1655 if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
1be76d11 1656 xfs_buf_mark_corrupt(blk->bp);
9473ee32 1657 return -EFSCORRUPTED;
a0264b73 1658 }
9473ee32
DW
1659
1660 /* Check the level from the root. */
1661 if (blkno == args->geo->leafblk)
1662 expected_level = nodehdr.level - 1;
a0264b73 1663 else if (expected_level != nodehdr.level) {
1be76d11 1664 xfs_buf_mark_corrupt(blk->bp);
9473ee32 1665 return -EFSCORRUPTED;
a0264b73 1666 } else
9473ee32
DW
1667 expected_level--;
1668
88b32f06
DC
1669 max = nodehdr.count;
1670 blk->hashval = be32_to_cpu(btree[max - 1].hashval);
2bd0ea18 1671
88b32f06
DC
1672 /*
1673 * Binary search. (note: small blocks will skip loop)
1674 */
1675 probe = span = max / 2;
1676 hashval = args->hashval;
1677 while (span > 4) {
1678 span /= 2;
1679 btreehashval = be32_to_cpu(btree[probe].hashval);
1680 if (btreehashval < hashval)
1681 probe += span;
1682 else if (btreehashval > hashval)
1683 probe -= span;
1684 else
1685 break;
1686 }
1687 ASSERT((probe >= 0) && (probe < max));
1688 ASSERT((span <= 4) ||
1689 (be32_to_cpu(btree[probe].hashval) == hashval));
2bd0ea18 1690
88b32f06
DC
1691 /*
1692 * Since we may have duplicate hashval's, find the first
1693 * matching hashval in the node.
1694 */
1695 while (probe > 0 &&
1696 be32_to_cpu(btree[probe].hashval) >= hashval) {
1697 probe--;
1698 }
1699 while (probe < max &&
1700 be32_to_cpu(btree[probe].hashval) < hashval) {
1701 probe++;
1702 }
1703
1704 /*
1705 * Pick the right block to descend on.
1706 */
1707 if (probe == max) {
1708 blk->index = max - 1;
1709 blkno = be32_to_cpu(btree[max - 1].before);
1710 } else {
1711 blk->index = probe;
1712 blkno = be32_to_cpu(btree[probe].before);
2bd0ea18 1713 }
9473ee32
DW
1714
1715 /* We can't point back to the root. */
bc73da84 1716 if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk))
9473ee32 1717 return -EFSCORRUPTED;
2bd0ea18
NS
1718 }
1719
bc73da84 1720 if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0))
9473ee32
DW
1721 return -EFSCORRUPTED;
1722
2bd0ea18
NS
1723 /*
1724 * A leaf block that ends in the hashval that we are interested in
1725 * (final hashval == search hashval) means that the next block may
1726 * contain more entries with the same hashval, shift upward to the
1727 * next leaf and keep searching.
1728 */
1729 for (;;) {
5e656dbb 1730 if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
32a82561 1731 retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
2bd0ea18 1732 &blk->index, state);
5e656dbb 1733 } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
a24374f4 1734 retval = xfs_attr3_leaf_lookup_int(blk->bp, args);
32a82561
NS
1735 blk->index = args->index;
1736 args->blkno = blk->blkno;
5e656dbb
BN
1737 } else {
1738 ASSERT(0);
12b53197 1739 return -EFSCORRUPTED;
2bd0ea18 1740 }
12b53197 1741 if (((retval == -ENOENT) || (retval == -ENOATTR)) &&
32a82561 1742 (blk->hashval == args->hashval)) {
88b32f06 1743 error = xfs_da3_path_shift(state, &state->path, 1, 1,
2bd0ea18
NS
1744 &retval);
1745 if (error)
af43ca9f 1746 return error;
2bd0ea18
NS
1747 if (retval == 0) {
1748 continue;
5e656dbb 1749 } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
2bd0ea18 1750 /* path_shift() gives ENOENT */
12b53197 1751 retval = -ENOATTR;
2bd0ea18 1752 }
2bd0ea18
NS
1753 }
1754 break;
1755 }
1756 *result = retval;
af43ca9f 1757 return 0;
2bd0ea18
NS
1758}
1759
2bd0ea18
NS
1760/*========================================================================
1761 * Utility routines.
1762 *========================================================================*/
1763
88b32f06
DC
1764/*
1765 * Compare two intermediate nodes for "order".
1766 */
1767STATIC int
1768xfs_da3_node_order(
ff105f75 1769 struct xfs_inode *dp,
88b32f06
DC
1770 struct xfs_buf *node1_bp,
1771 struct xfs_buf *node2_bp)
1772{
1773 struct xfs_da_intnode *node1;
1774 struct xfs_da_intnode *node2;
1775 struct xfs_da_node_entry *btree1;
1776 struct xfs_da_node_entry *btree2;
1777 struct xfs_da3_icnode_hdr node1hdr;
1778 struct xfs_da3_icnode_hdr node2hdr;
1779
1780 node1 = node1_bp->b_addr;
1781 node2 = node2_bp->b_addr;
08c16786
CH
1782 xfs_da3_node_hdr_from_disk(dp->i_mount, &node1hdr, node1);
1783 xfs_da3_node_hdr_from_disk(dp->i_mount, &node2hdr, node2);
8faa51a8
CH
1784 btree1 = node1hdr.btree;
1785 btree2 = node2hdr.btree;
88b32f06
DC
1786
1787 if (node1hdr.count > 0 && node2hdr.count > 0 &&
1788 ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) ||
1789 (be32_to_cpu(btree2[node2hdr.count - 1].hashval) <
1790 be32_to_cpu(btree1[node1hdr.count - 1].hashval)))) {
1791 return 1;
1792 }
1793 return 0;
1794}
1795
2bd0ea18
NS
1796/*
1797 * Link a new block into a doubly linked list of blocks (of whatever type).
1798 */
1799int /* error */
88b32f06
DC
1800xfs_da3_blk_link(
1801 struct xfs_da_state *state,
1802 struct xfs_da_state_blk *old_blk,
1803 struct xfs_da_state_blk *new_blk)
2bd0ea18 1804{
88b32f06
DC
1805 struct xfs_da_blkinfo *old_info;
1806 struct xfs_da_blkinfo *new_info;
1807 struct xfs_da_blkinfo *tmp_info;
1808 struct xfs_da_args *args;
1809 struct xfs_buf *bp;
1810 int before = 0;
1811 int error;
ff105f75 1812 struct xfs_inode *dp = state->args->dp;
2bd0ea18
NS
1813
1814 /*
1815 * Set up environment.
1816 */
1817 args = state->args;
1818 ASSERT(args != NULL);
a2ceac1f
DC
1819 old_info = old_blk->bp->b_addr;
1820 new_info = new_blk->bp->b_addr;
2bd0ea18 1821 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
5e656dbb 1822 old_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
2bd0ea18 1823 old_blk->magic == XFS_ATTR_LEAF_MAGIC);
2bd0ea18
NS
1824
1825 switch (old_blk->magic) {
2bd0ea18
NS
1826 case XFS_ATTR_LEAF_MAGIC:
1827 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
1828 break;
2bd0ea18 1829 case XFS_DIR2_LEAFN_MAGIC:
ff105f75 1830 before = xfs_dir2_leafn_order(dp, old_blk->bp, new_blk->bp);
2bd0ea18
NS
1831 break;
1832 case XFS_DA_NODE_MAGIC:
ff105f75 1833 before = xfs_da3_node_order(dp, old_blk->bp, new_blk->bp);
2bd0ea18
NS
1834 break;
1835 }
1836
1837 /*
1838 * Link blocks in appropriate order.
1839 */
1840 if (before) {
1841 /*
1842 * Link new block in before existing block.
1843 */
a2ceac1f 1844 trace_xfs_da_link_before(args);
5e656dbb
BN
1845 new_info->forw = cpu_to_be32(old_blk->blkno);
1846 new_info->back = old_info->back;
1847 if (old_info->back) {
ff105f75 1848 error = xfs_da3_node_read(args->trans, dp,
5e656dbb 1849 be32_to_cpu(old_info->back),
02cc4995 1850 &bp, args->whichfork);
2bd0ea18 1851 if (error)
af43ca9f 1852 return error;
2bd0ea18 1853 ASSERT(bp != NULL);
a2ceac1f 1854 tmp_info = bp->b_addr;
88b32f06 1855 ASSERT(tmp_info->magic == old_info->magic);
5e656dbb
BN
1856 ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno);
1857 tmp_info->forw = cpu_to_be32(new_blk->blkno);
a2ceac1f 1858 xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
2bd0ea18 1859 }
5e656dbb 1860 old_info->back = cpu_to_be32(new_blk->blkno);
2bd0ea18
NS
1861 } else {
1862 /*
1863 * Link new block in after existing block.
1864 */
a2ceac1f 1865 trace_xfs_da_link_after(args);
5e656dbb
BN
1866 new_info->forw = old_info->forw;
1867 new_info->back = cpu_to_be32(old_blk->blkno);
1868 if (old_info->forw) {
ff105f75 1869 error = xfs_da3_node_read(args->trans, dp,
5e656dbb 1870 be32_to_cpu(old_info->forw),
02cc4995 1871 &bp, args->whichfork);
2bd0ea18 1872 if (error)
af43ca9f 1873 return error;
2bd0ea18 1874 ASSERT(bp != NULL);
a2ceac1f 1875 tmp_info = bp->b_addr;
5e656dbb
BN
1876 ASSERT(tmp_info->magic == old_info->magic);
1877 ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno);
1878 tmp_info->back = cpu_to_be32(new_blk->blkno);
a2ceac1f 1879 xfs_trans_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
2bd0ea18 1880 }
5e656dbb 1881 old_info->forw = cpu_to_be32(new_blk->blkno);
2bd0ea18
NS
1882 }
1883
a2ceac1f
DC
1884 xfs_trans_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1);
1885 xfs_trans_log_buf(args->trans, new_blk->bp, 0, sizeof(*tmp_info) - 1);
af43ca9f 1886 return 0;
2bd0ea18
NS
1887}
1888
2bd0ea18
NS
1889/*
1890 * Unlink a block from a doubly linked list of blocks.
1891 */
5e656dbb 1892STATIC int /* error */
88b32f06
DC
1893xfs_da3_blk_unlink(
1894 struct xfs_da_state *state,
1895 struct xfs_da_state_blk *drop_blk,
1896 struct xfs_da_state_blk *save_blk)
2bd0ea18 1897{
88b32f06
DC
1898 struct xfs_da_blkinfo *drop_info;
1899 struct xfs_da_blkinfo *save_info;
1900 struct xfs_da_blkinfo *tmp_info;
1901 struct xfs_da_args *args;
1902 struct xfs_buf *bp;
1903 int error;
2bd0ea18
NS
1904
1905 /*
1906 * Set up environment.
1907 */
1908 args = state->args;
1909 ASSERT(args != NULL);
a2ceac1f
DC
1910 save_info = save_blk->bp->b_addr;
1911 drop_info = drop_blk->bp->b_addr;
2bd0ea18 1912 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
5e656dbb 1913 save_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
2bd0ea18 1914 save_blk->magic == XFS_ATTR_LEAF_MAGIC);
2bd0ea18 1915 ASSERT(save_blk->magic == drop_blk->magic);
5e656dbb
BN
1916 ASSERT((be32_to_cpu(save_info->forw) == drop_blk->blkno) ||
1917 (be32_to_cpu(save_info->back) == drop_blk->blkno));
1918 ASSERT((be32_to_cpu(drop_info->forw) == save_blk->blkno) ||
1919 (be32_to_cpu(drop_info->back) == save_blk->blkno));
2bd0ea18
NS
1920
1921 /*
1922 * Unlink the leaf block from the doubly linked chain of leaves.
1923 */
5e656dbb 1924 if (be32_to_cpu(save_info->back) == drop_blk->blkno) {
a2ceac1f 1925 trace_xfs_da_unlink_back(args);
5e656dbb
BN
1926 save_info->back = drop_info->back;
1927 if (drop_info->back) {
88b32f06 1928 error = xfs_da3_node_read(args->trans, args->dp,
5e656dbb 1929 be32_to_cpu(drop_info->back),
02cc4995 1930 &bp, args->whichfork);
2bd0ea18 1931 if (error)
af43ca9f 1932 return error;
2bd0ea18 1933 ASSERT(bp != NULL);
a2ceac1f 1934 tmp_info = bp->b_addr;
5e656dbb
BN
1935 ASSERT(tmp_info->magic == save_info->magic);
1936 ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno);
1937 tmp_info->forw = cpu_to_be32(save_blk->blkno);
a2ceac1f 1938 xfs_trans_log_buf(args->trans, bp, 0,
2bd0ea18 1939 sizeof(*tmp_info) - 1);
2bd0ea18
NS
1940 }
1941 } else {
a2ceac1f 1942 trace_xfs_da_unlink_forward(args);
5e656dbb
BN
1943 save_info->forw = drop_info->forw;
1944 if (drop_info->forw) {
88b32f06 1945 error = xfs_da3_node_read(args->trans, args->dp,
5e656dbb 1946 be32_to_cpu(drop_info->forw),
02cc4995 1947 &bp, args->whichfork);
2bd0ea18 1948 if (error)
af43ca9f 1949 return error;
2bd0ea18 1950 ASSERT(bp != NULL);
a2ceac1f 1951 tmp_info = bp->b_addr;
5e656dbb
BN
1952 ASSERT(tmp_info->magic == save_info->magic);
1953 ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno);
1954 tmp_info->back = cpu_to_be32(save_blk->blkno);
a2ceac1f 1955 xfs_trans_log_buf(args->trans, bp, 0,
2bd0ea18 1956 sizeof(*tmp_info) - 1);
2bd0ea18
NS
1957 }
1958 }
1959
a2ceac1f 1960 xfs_trans_log_buf(args->trans, save_blk->bp, 0, sizeof(*save_info) - 1);
af43ca9f 1961 return 0;
2bd0ea18
NS
1962}
1963
1964/*
1965 * Move a path "forward" or "!forward" one block at the current level.
1966 *
1967 * This routine will adjust a "path" to point to the next block
1968 * "forward" (higher hashvalues) or "!forward" (lower hashvals) in the
1969 * Btree, including updating pointers to the intermediate nodes between
1970 * the new bottom and the root.
1971 */
1972int /* error */
88b32f06
DC
1973xfs_da3_path_shift(
1974 struct xfs_da_state *state,
1975 struct xfs_da_state_path *path,
1976 int forward,
1977 int release,
1978 int *result)
2bd0ea18 1979{
88b32f06
DC
1980 struct xfs_da_state_blk *blk;
1981 struct xfs_da_blkinfo *info;
88b32f06
DC
1982 struct xfs_da_args *args;
1983 struct xfs_da_node_entry *btree;
1984 struct xfs_da3_icnode_hdr nodehdr;
c063b960 1985 struct xfs_buf *bp;
88b32f06
DC
1986 xfs_dablk_t blkno = 0;
1987 int level;
1988 int error;
ff105f75 1989 struct xfs_inode *dp = state->args->dp;
2bd0ea18 1990
a2ceac1f
DC
1991 trace_xfs_da_path_shift(state->args);
1992
2bd0ea18
NS
1993 /*
1994 * Roll up the Btree looking for the first block where our
1995 * current index is not at the edge of the block. Note that
1996 * we skip the bottom layer because we want the sibling block.
1997 */
1998 args = state->args;
1999 ASSERT(args != NULL);
2000 ASSERT(path != NULL);
2001 ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
2002 level = (path->active-1) - 1; /* skip bottom layer in path */
dfab3d49
QC
2003 for (; level >= 0; level--) {
2004 blk = &path->blk[level];
8faa51a8
CH
2005 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,
2006 blk->bp->b_addr);
88b32f06
DC
2007
2008 if (forward && (blk->index < nodehdr.count - 1)) {
2bd0ea18 2009 blk->index++;
8faa51a8 2010 blkno = be32_to_cpu(nodehdr.btree[blk->index].before);
2bd0ea18
NS
2011 break;
2012 } else if (!forward && (blk->index > 0)) {
2013 blk->index--;
8faa51a8 2014 blkno = be32_to_cpu(nodehdr.btree[blk->index].before);
2bd0ea18
NS
2015 break;
2016 }
2017 }
2018 if (level < 0) {
12b53197 2019 *result = -ENOENT; /* we're out of our tree */
5e656dbb 2020 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT);
af43ca9f 2021 return 0;
2bd0ea18
NS
2022 }
2023
2024 /*
2025 * Roll down the edge of the subtree until we reach the
2026 * same depth we were at originally.
2027 */
2028 for (blk++, level++; level < path->active; blk++, level++) {
2029 /*
c063b960 2030 * Read the next child block into a local buffer.
2bd0ea18 2031 */
02cc4995 2032 error = xfs_da3_node_read(args->trans, dp, blkno, &bp,
c063b960
BF
2033 args->whichfork);
2034 if (error)
2035 return error;
2bd0ea18
NS
2036
2037 /*
c063b960
BF
2038 * Release the old block (if it's dirty, the trans doesn't
2039 * actually let go) and swap the local buffer into the path
2040 * structure. This ensures failure of the above read doesn't set
2041 * a NULL buffer in an active slot in the path.
2bd0ea18 2042 */
c063b960
BF
2043 if (release)
2044 xfs_trans_brelse(args->trans, blk->bp);
2bd0ea18 2045 blk->blkno = blkno;
c063b960
BF
2046 blk->bp = bp;
2047
a2ceac1f
DC
2048 info = blk->bp->b_addr;
2049 ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
88b32f06 2050 info->magic == cpu_to_be16(XFS_DA3_NODE_MAGIC) ||
a2ceac1f 2051 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
65b80c98 2052 info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) ||
a24374f4
DC
2053 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
2054 info->magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
88b32f06
DC
2055
2056
2057 /*
2058 * Note: we flatten the magic number to a single type so we
2059 * don't have to compare against crc/non-crc types elsewhere.
2060 */
2061 switch (be16_to_cpu(info->magic)) {
2062 case XFS_DA_NODE_MAGIC:
2063 case XFS_DA3_NODE_MAGIC:
2064 blk->magic = XFS_DA_NODE_MAGIC;
8faa51a8
CH
2065 xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,
2066 bp->b_addr);
2067 btree = nodehdr.btree;
88b32f06 2068 blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval);
2bd0ea18
NS
2069 if (forward)
2070 blk->index = 0;
2071 else
88b32f06
DC
2072 blk->index = nodehdr.count - 1;
2073 blkno = be32_to_cpu(btree[blk->index].before);
2074 break;
2075 case XFS_ATTR_LEAF_MAGIC:
a24374f4 2076 case XFS_ATTR3_LEAF_MAGIC:
88b32f06 2077 blk->magic = XFS_ATTR_LEAF_MAGIC;
2bd0ea18
NS
2078 ASSERT(level == path->active-1);
2079 blk->index = 0;
ff105f75 2080 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
88b32f06
DC
2081 break;
2082 case XFS_DIR2_LEAFN_MAGIC:
2083 case XFS_DIR3_LEAFN_MAGIC:
2084 blk->magic = XFS_DIR2_LEAFN_MAGIC;
2085 ASSERT(level == path->active-1);
2086 blk->index = 0;
94ffb80a
DW
2087 blk->hashval = xfs_dir2_leaf_lasthash(args->dp,
2088 blk->bp, NULL);
88b32f06
DC
2089 break;
2090 default:
2091 ASSERT(0);
2092 break;
2bd0ea18
NS
2093 }
2094 }
2095 *result = 0;
88b32f06 2096 return 0;
2bd0ea18
NS
2097}
2098
2099
2100/*========================================================================
2101 * Utility routines.
2102 *========================================================================*/
2103
2104/*
2105 * Implement a simple hash on a character string.
2106 * Rotate the hash value by 7 bits, then XOR each character in.
2107 * This is implemented with some source-level loop unrolling.
2108 */
2109xfs_dahash_t
4a492e72 2110xfs_da_hashname(const uint8_t *name, int namelen)
2bd0ea18
NS
2111{
2112 xfs_dahash_t hash;
2113
2bd0ea18
NS
2114 /*
2115 * Do four characters at a time as long as we can.
2116 */
f9c48a87 2117 for (hash = 0; namelen >= 4; namelen -= 4, name += 4)
2bd0ea18 2118 hash = (name[0] << 21) ^ (name[1] << 14) ^ (name[2] << 7) ^
f9c48a87
NS
2119 (name[3] << 0) ^ rol32(hash, 7 * 4);
2120
2bd0ea18
NS
2121 /*
2122 * Now do the rest of the characters.
2123 */
2124 switch (namelen) {
2125 case 3:
2126 return (name[0] << 14) ^ (name[1] << 7) ^ (name[2] << 0) ^
f9c48a87 2127 rol32(hash, 7 * 3);
2bd0ea18 2128 case 2:
f9c48a87 2129 return (name[0] << 7) ^ (name[1] << 0) ^ rol32(hash, 7 * 2);
2bd0ea18 2130 case 1:
f9c48a87
NS
2131 return (name[0] << 0) ^ rol32(hash, 7 * 1);
2132 default: /* case 0: */
2bd0ea18
NS
2133 return hash;
2134 }
2bd0ea18
NS
2135}
2136
51ca7008 2137enum xfs_dacmp
5e656dbb
BN
2138xfs_da_compname(
2139 struct xfs_da_args *args,
56b2de80
DC
2140 const unsigned char *name,
2141 int len)
51ca7008 2142{
5e656dbb 2143 return (args->namelen == len && memcmp(args->name, name, len) == 0) ?
51ca7008
BN
2144 XFS_CMP_EXACT : XFS_CMP_DIFFERENT;
2145}
2146
2bd0ea18 2147int
a2ceac1f
DC
2148xfs_da_grow_inode_int(
2149 struct xfs_da_args *args,
2150 xfs_fileoff_t *bno,
2151 int count)
2bd0ea18 2152{
a2ceac1f
DC
2153 struct xfs_trans *tp = args->trans;
2154 struct xfs_inode *dp = args->dp;
2155 int w = args->whichfork;
aa00f286 2156 xfs_rfsblock_t nblks = dp->i_nblocks;
a2ceac1f
DC
2157 struct xfs_bmbt_irec map, *mapp;
2158 int nmap, error, got, i, mapi;
56b2de80 2159
2bd0ea18
NS
2160 /*
2161 * Find a spot in the file space to put the new block.
2162 */
a2ceac1f
DC
2163 error = xfs_bmap_first_unused(tp, dp, count, bno, w);
2164 if (error)
2bd0ea18 2165 return error;
a2ceac1f 2166
2bd0ea18
NS
2167 /*
2168 * Try mapping it in one filesystem block.
2169 */
2170 nmap = 1;
a2ceac1f
DC
2171 error = xfs_bmapi_write(tp, dp, *bno, count,
2172 xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
b39f9fcb 2173 args->total, &map, &nmap);
a2ceac1f 2174 if (error)
2bd0ea18 2175 return error;
a2ceac1f 2176
2bd0ea18
NS
2177 ASSERT(nmap <= 1);
2178 if (nmap == 1) {
2179 mapp = &map;
2180 mapi = 1;
a2ceac1f
DC
2181 } else if (nmap == 0 && count > 1) {
2182 xfs_fileoff_t b;
2183 int c;
2184
2185 /*
2186 * If we didn't get it and the block might work if fragmented,
2187 * try without the CONTIG flag. Loop until we get it all.
2188 */
6cd1e6db 2189 mapp = kmem_alloc(sizeof(*mapp) * count, 0);
a2ceac1f 2190 for (b = *bno, mapi = 0; b < *bno + count; ) {
a2ceac1f 2191 c = (int)(*bno + count - b);
04d4c27a 2192 nmap = min(XFS_BMAP_MAX_NMAP, c);
a2ceac1f
DC
2193 error = xfs_bmapi_write(tp, dp, b, c,
2194 xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA,
b39f9fcb 2195 args->total, &mapp[mapi], &nmap);
a2ceac1f
DC
2196 if (error)
2197 goto out_free_map;
2bd0ea18
NS
2198 if (nmap < 1)
2199 break;
2200 mapi += nmap;
2201 b = mapp[mapi - 1].br_startoff +
2202 mapp[mapi - 1].br_blockcount;
2203 }
2204 } else {
2bd0ea18
NS
2205 mapi = 0;
2206 mapp = NULL;
2207 }
a2ceac1f 2208
2bd0ea18
NS
2209 /*
2210 * Count the blocks we got, make sure it matches the total.
2211 */
2212 for (i = 0, got = 0; i < mapi; i++)
2213 got += mapp[i].br_blockcount;
a2ceac1f 2214 if (got != count || mapp[0].br_startoff != *bno ||
2bd0ea18 2215 mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount !=
a2ceac1f 2216 *bno + count) {
12b53197 2217 error = -ENOSPC;
a2ceac1f 2218 goto out_free_map;
2bd0ea18 2219 }
a2ceac1f 2220
56b2de80 2221 /* account for newly allocated blocks in reserved blocks total */
aa00f286 2222 args->total -= dp->i_nblocks - nblks;
a2ceac1f
DC
2223
2224out_free_map:
2225 if (mapp != &map)
2226 kmem_free(mapp);
2227 return error;
2228}
2229
2230/*
2231 * Add a block to the btree ahead of the file.
2232 * Return the new block number to the caller.
2233 */
2234int
2235xfs_da_grow_inode(
2236 struct xfs_da_args *args,
2237 xfs_dablk_t *new_blkno)
2238{
2239 xfs_fileoff_t bno;
a2ceac1f
DC
2240 int error;
2241
2242 trace_xfs_da_grow_inode(args);
2243
ff105f75
DC
2244 bno = args->geo->leafblk;
2245 error = xfs_da_grow_inode_int(args, &bno, args->geo->fsbcount);
a2ceac1f
DC
2246 if (!error)
2247 *new_blkno = (xfs_dablk_t)bno;
2248 return error;
2bd0ea18
NS
2249}
2250
2bd0ea18 2251/*
dfc130f3 2252 * Ick. We need to always be able to remove a btree block, even
2bd0ea18
NS
2253 * if there's no space reservation because the filesystem is full.
2254 * This is called if xfs_bunmapi on a btree block fails due to ENOSPC.
2255 * It swaps the target block with the last block in the file. The
2256 * last block in the file can always be removed since it can't cause
2257 * a bmap btree split to do that.
2258 */
2259STATIC int
88b32f06
DC
2260xfs_da3_swap_lastblock(
2261 struct xfs_da_args *args,
2262 xfs_dablk_t *dead_blknop,
2263 struct xfs_buf **dead_bufp)
2bd0ea18 2264{
88b32f06
DC
2265 struct xfs_da_blkinfo *dead_info;
2266 struct xfs_da_blkinfo *sib_info;
2267 struct xfs_da_intnode *par_node;
2268 struct xfs_da_intnode *dead_node;
2269 struct xfs_dir2_leaf *dead_leaf2;
2270 struct xfs_da_node_entry *btree;
2271 struct xfs_da3_icnode_hdr par_hdr;
ff105f75 2272 struct xfs_inode *dp;
88b32f06
DC
2273 struct xfs_trans *tp;
2274 struct xfs_mount *mp;
2275 struct xfs_buf *dead_buf;
2276 struct xfs_buf *last_buf;
2277 struct xfs_buf *sib_buf;
2278 struct xfs_buf *par_buf;
2279 xfs_dahash_t dead_hash;
2280 xfs_fileoff_t lastoff;
2281 xfs_dablk_t dead_blkno;
2282 xfs_dablk_t last_blkno;
2283 xfs_dablk_t sib_blkno;
2284 xfs_dablk_t par_blkno;
2285 int error;
2286 int w;
2287 int entno;
2288 int level;
2289 int dead_level;
2bd0ea18 2290
a2ceac1f
DC
2291 trace_xfs_da_swap_lastblock(args);
2292
2bd0ea18
NS
2293 dead_buf = *dead_bufp;
2294 dead_blkno = *dead_blknop;
2295 tp = args->trans;
ff105f75 2296 dp = args->dp;
2bd0ea18
NS
2297 w = args->whichfork;
2298 ASSERT(w == XFS_DATA_FORK);
ff105f75
DC
2299 mp = dp->i_mount;
2300 lastoff = args->geo->freeblk;
2301 error = xfs_bmap_last_before(tp, dp, &lastoff, w);
2bd0ea18
NS
2302 if (error)
2303 return error;
bc73da84 2304 if (XFS_IS_CORRUPT(mp, lastoff == 0))
12b53197 2305 return -EFSCORRUPTED;
2bd0ea18
NS
2306 /*
2307 * Read the last block in the btree space.
2308 */
ff105f75 2309 last_blkno = (xfs_dablk_t)lastoff - args->geo->fsbcount;
02cc4995 2310 error = xfs_da3_node_read(tp, dp, last_blkno, &last_buf, w);
a2ceac1f 2311 if (error)
2bd0ea18
NS
2312 return error;
2313 /*
2314 * Copy the last block into the dead buffer and log it.
2315 */
ff105f75
DC
2316 memcpy(dead_buf->b_addr, last_buf->b_addr, args->geo->blksize);
2317 xfs_trans_log_buf(tp, dead_buf, 0, args->geo->blksize - 1);
a2ceac1f 2318 dead_info = dead_buf->b_addr;
2bd0ea18
NS
2319 /*
2320 * Get values from the moved block.
2321 */
65b80c98
DC
2322 if (dead_info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
2323 dead_info->magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
2324 struct xfs_dir3_icleaf_hdr leafhdr;
2325 struct xfs_dir2_leaf_entry *ents;
2326
2bd0ea18 2327 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
9db68faf
CH
2328 xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr,
2329 dead_leaf2);
a2279497 2330 ents = leafhdr.ents;
2bd0ea18 2331 dead_level = 0;
65b80c98 2332 dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
2bd0ea18 2333 } else {
88b32f06
DC
2334 struct xfs_da3_icnode_hdr deadhdr;
2335
2bd0ea18 2336 dead_node = (xfs_da_intnode_t *)dead_info;
08c16786 2337 xfs_da3_node_hdr_from_disk(dp->i_mount, &deadhdr, dead_node);
8faa51a8 2338 btree = deadhdr.btree;
88b32f06
DC
2339 dead_level = deadhdr.level;
2340 dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval);
2bd0ea18
NS
2341 }
2342 sib_buf = par_buf = NULL;
2343 /*
2344 * If the moved block has a left sibling, fix up the pointers.
2345 */
5e656dbb 2346 if ((sib_blkno = be32_to_cpu(dead_info->back))) {
02cc4995 2347 error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w);
a2ceac1f 2348 if (error)
2bd0ea18 2349 goto done;
a2ceac1f 2350 sib_info = sib_buf->b_addr;
bc73da84
DW
2351 if (XFS_IS_CORRUPT(mp,
2352 be32_to_cpu(sib_info->forw) != last_blkno ||
2353 sib_info->magic != dead_info->magic)) {
12b53197 2354 error = -EFSCORRUPTED;
2bd0ea18
NS
2355 goto done;
2356 }
5e656dbb 2357 sib_info->forw = cpu_to_be32(dead_blkno);
a2ceac1f 2358 xfs_trans_log_buf(tp, sib_buf,
2bd0ea18
NS
2359 XFS_DA_LOGRANGE(sib_info, &sib_info->forw,
2360 sizeof(sib_info->forw)));
2bd0ea18
NS
2361 sib_buf = NULL;
2362 }
2363 /*
2364 * If the moved block has a right sibling, fix up the pointers.
2365 */
5e656dbb 2366 if ((sib_blkno = be32_to_cpu(dead_info->forw))) {
02cc4995 2367 error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w);
a2ceac1f 2368 if (error)
2bd0ea18 2369 goto done;
a2ceac1f 2370 sib_info = sib_buf->b_addr;
bc73da84
DW
2371 if (XFS_IS_CORRUPT(mp,
2372 be32_to_cpu(sib_info->back) != last_blkno ||
2373 sib_info->magic != dead_info->magic)) {
12b53197 2374 error = -EFSCORRUPTED;
2bd0ea18
NS
2375 goto done;
2376 }
5e656dbb 2377 sib_info->back = cpu_to_be32(dead_blkno);
a2ceac1f 2378 xfs_trans_log_buf(tp, sib_buf,
2bd0ea18
NS
2379 XFS_DA_LOGRANGE(sib_info, &sib_info->back,
2380 sizeof(sib_info->back)));
2bd0ea18
NS
2381 sib_buf = NULL;
2382 }
ff105f75 2383 par_blkno = args->geo->leafblk;
2bd0ea18
NS
2384 level = -1;
2385 /*
2386 * Walk down the tree looking for the parent of the moved block.
2387 */
2388 for (;;) {
02cc4995 2389 error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w);
a2ceac1f 2390 if (error)
2bd0ea18 2391 goto done;
a2ceac1f 2392 par_node = par_buf->b_addr;
08c16786 2393 xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
bc73da84
DW
2394 if (XFS_IS_CORRUPT(mp,
2395 level >= 0 && level != par_hdr.level + 1)) {
12b53197 2396 error = -EFSCORRUPTED;
2bd0ea18
NS
2397 goto done;
2398 }
88b32f06 2399 level = par_hdr.level;
8faa51a8 2400 btree = par_hdr.btree;
2bd0ea18 2401 for (entno = 0;
88b32f06
DC
2402 entno < par_hdr.count &&
2403 be32_to_cpu(btree[entno].hashval) < dead_hash;
2bd0ea18
NS
2404 entno++)
2405 continue;
bc73da84 2406 if (XFS_IS_CORRUPT(mp, entno == par_hdr.count)) {
12b53197 2407 error = -EFSCORRUPTED;
2bd0ea18
NS
2408 goto done;
2409 }
88b32f06 2410 par_blkno = be32_to_cpu(btree[entno].before);
2bd0ea18
NS
2411 if (level == dead_level + 1)
2412 break;
a2ceac1f 2413 xfs_trans_brelse(tp, par_buf);
2bd0ea18
NS
2414 par_buf = NULL;
2415 }
2416 /*
2417 * We're in the right parent block.
2418 * Look for the right entry.
2419 */
2420 for (;;) {
2421 for (;
88b32f06
DC
2422 entno < par_hdr.count &&
2423 be32_to_cpu(btree[entno].before) != last_blkno;
2bd0ea18
NS
2424 entno++)
2425 continue;
88b32f06 2426 if (entno < par_hdr.count)
2bd0ea18 2427 break;
88b32f06 2428 par_blkno = par_hdr.forw;
a2ceac1f 2429 xfs_trans_brelse(tp, par_buf);
2bd0ea18 2430 par_buf = NULL;
bc73da84 2431 if (XFS_IS_CORRUPT(mp, par_blkno == 0)) {
12b53197 2432 error = -EFSCORRUPTED;
2bd0ea18
NS
2433 goto done;
2434 }
02cc4995 2435 error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w);
a2ceac1f 2436 if (error)
2bd0ea18 2437 goto done;
a2ceac1f 2438 par_node = par_buf->b_addr;
08c16786 2439 xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
bc73da84 2440 if (XFS_IS_CORRUPT(mp, par_hdr.level != level)) {
12b53197 2441 error = -EFSCORRUPTED;
2bd0ea18
NS
2442 goto done;
2443 }
8faa51a8 2444 btree = par_hdr.btree;
2bd0ea18
NS
2445 entno = 0;
2446 }
2447 /*
2448 * Update the parent entry pointing to the moved block.
2449 */
88b32f06 2450 btree[entno].before = cpu_to_be32(dead_blkno);
a2ceac1f 2451 xfs_trans_log_buf(tp, par_buf,
88b32f06
DC
2452 XFS_DA_LOGRANGE(par_node, &btree[entno].before,
2453 sizeof(btree[entno].before)));
2bd0ea18
NS
2454 *dead_blknop = last_blkno;
2455 *dead_bufp = last_buf;
2456 return 0;
2457done:
2458 if (par_buf)
a2ceac1f 2459 xfs_trans_brelse(tp, par_buf);
2bd0ea18 2460 if (sib_buf)
a2ceac1f
DC
2461 xfs_trans_brelse(tp, sib_buf);
2462 xfs_trans_brelse(tp, last_buf);
2bd0ea18
NS
2463 return error;
2464}
2465
2466/*
2467 * Remove a btree block from a directory or attribute.
2468 */
2469int
a2ceac1f 2470xfs_da_shrink_inode(
a50d2ab0
BF
2471 struct xfs_da_args *args,
2472 xfs_dablk_t dead_blkno,
2473 struct xfs_buf *dead_buf)
2bd0ea18 2474{
a50d2ab0
BF
2475 struct xfs_inode *dp;
2476 int done, error, w, count;
2477 struct xfs_trans *tp;
2bd0ea18 2478
a2ceac1f
DC
2479 trace_xfs_da_shrink_inode(args);
2480
2bd0ea18
NS
2481 dp = args->dp;
2482 w = args->whichfork;
2483 tp = args->trans;
ff105f75 2484 count = args->geo->fsbcount;
2bd0ea18
NS
2485 for (;;) {
2486 /*
2487 * Remove extents. If we get ENOSPC for a dir we have to move
2488 * the last block to the place we want to kill.
2489 */
88b32f06 2490 error = xfs_bunmapi(tp, dp, dead_blkno, count,
d3c5f3dd 2491 xfs_bmapi_aflag(w), 0, &done);
12b53197 2492 if (error == -ENOSPC) {
2bd0ea18 2493 if (w != XFS_DATA_FORK)
5e656dbb 2494 break;
88b32f06
DC
2495 error = xfs_da3_swap_lastblock(args, &dead_blkno,
2496 &dead_buf);
2497 if (error)
5e656dbb
BN
2498 break;
2499 } else {
2bd0ea18 2500 break;
2bd0ea18
NS
2501 }
2502 }
a2ceac1f 2503 xfs_trans_binval(tp, dead_buf);
2bd0ea18
NS
2504 return error;
2505}
2506
a2ceac1f
DC
2507static int
2508xfs_dabuf_map(
a2ceac1f
DC
2509 struct xfs_inode *dp,
2510 xfs_dablk_t bno,
48d1399b 2511 unsigned int flags,
a2ceac1f 2512 int whichfork,
571973e8 2513 struct xfs_buf_map **mapp,
a2ceac1f
DC
2514 int *nmaps)
2515{
2516 struct xfs_mount *mp = dp->i_mount;
59ab3748 2517 int nfsb = xfs_dabuf_nfsb(mp, whichfork);
571973e8
CH
2518 struct xfs_bmbt_irec irec, *irecs = &irec;
2519 struct xfs_buf_map *map = *mapp;
2520 xfs_fileoff_t off = bno;
2521 int error = 0, nirecs, i;
2bd0ea18 2522
571973e8 2523 if (nfsb > 1)
59ab3748 2524 irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_NOFS);
571973e8 2525
59ab3748 2526 nirecs = nfsb;
571973e8
CH
2527 error = xfs_bmapi_read(dp, bno, nfsb, irecs, &nirecs,
2528 xfs_bmapi_aflag(whichfork));
59ab3748 2529 if (error)
571973e8 2530 goto out_free_irecs;
a2ceac1f 2531
571973e8
CH
2532 /*
2533 * Use the caller provided map for the single map case, else allocate a
2534 * larger one that needs to be free by the caller.
2535 */
2536 if (nirecs > 1) {
2537 map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_NOFS);
a2a0a99a
DW
2538 if (!map) {
2539 error = -ENOMEM;
571973e8 2540 goto out_free_irecs;
a2a0a99a 2541 }
571973e8
CH
2542 *mapp = map;
2543 }
3af5535c 2544
571973e8
CH
2545 for (i = 0; i < nirecs; i++) {
2546 if (irecs[i].br_startblock == HOLESTARTBLOCK ||
2547 irecs[i].br_startblock == DELAYSTARTBLOCK)
2548 goto invalid_mapping;
2549 if (off != irecs[i].br_startoff)
2550 goto invalid_mapping;
2551
2552 map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock);
2553 map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount);
2554 off += irecs[i].br_blockcount;
2555 }
2556
2557 if (off != bno + nfsb)
2558 goto invalid_mapping;
2559
2560 *nmaps = nirecs;
2561out_free_irecs:
2562 if (irecs != &irec)
2563 kmem_free(irecs);
2564 return error;
2565
2566invalid_mapping:
2567 /* Caller ok with no mapping. */
48d1399b 2568 if (XFS_IS_CORRUPT(mp, !(flags & XFS_DABUF_MAP_HOLE_OK))) {
571973e8 2569 error = -EFSCORRUPTED;
3af5535c 2570 if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
571973e8
CH
2571 xfs_alert(mp, "%s: bno %u inode %llu",
2572 __func__, bno, dp->i_ino);
3af5535c 2573
571973e8 2574 for (i = 0; i < nirecs; i++) {
3af5535c 2575 xfs_alert(mp,
a2ceac1f 2576"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d",
571973e8
CH
2577 i, irecs[i].br_startoff,
2578 irecs[i].br_startblock,
2579 irecs[i].br_blockcount,
3af5535c 2580 irecs[i].br_state);
4ca431fc 2581 }
4ca431fc 2582 }
571973e8
CH
2583 } else {
2584 *nmaps = 0;
2bd0ea18 2585 }
571973e8 2586 goto out_free_irecs;
a2ceac1f
DC
2587}
2588
2589/*
2590 * Get a buffer for the dir/attr block.
2591 */
2592int
2593xfs_da_get_buf(
59ab3748 2594 struct xfs_trans *tp,
a2ceac1f
DC
2595 struct xfs_inode *dp,
2596 xfs_dablk_t bno,
a2ceac1f
DC
2597 struct xfs_buf **bpp,
2598 int whichfork)
2599{
59ab3748 2600 struct xfs_mount *mp = dp->i_mount;
a2ceac1f 2601 struct xfs_buf *bp;
59ab3748
CH
2602 struct xfs_buf_map map, *mapp = &map;
2603 int nmap = 1;
a2ceac1f
DC
2604 int error;
2605
2606 *bpp = NULL;
c1d19744 2607 error = xfs_dabuf_map(dp, bno, 0, whichfork, &mapp, &nmap);
48d1399b 2608 if (error || nmap == 0)
a2ceac1f 2609 goto out_free;
a2ceac1f 2610
51409fcc
DW
2611 error = xfs_trans_get_buf_map(tp, mp->m_ddev_targp, mapp, nmap, 0, &bp);
2612 if (error)
a2ceac1f 2613 goto out_free;
a2ceac1f
DC
2614
2615 *bpp = bp;
2616
2617out_free:
2618 if (mapp != &map)
2619 kmem_free(mapp);
2620
2621 return error;
2622}
2623
2624/*
2625 * Get a buffer for the dir/attr block, fill in the contents.
2626 */
2627int
2628xfs_da_read_buf(
59ab3748 2629 struct xfs_trans *tp,
a2ceac1f
DC
2630 struct xfs_inode *dp,
2631 xfs_dablk_t bno,
5f356ae6 2632 unsigned int flags,
a2ceac1f
DC
2633 struct xfs_buf **bpp,
2634 int whichfork,
2635 const struct xfs_buf_ops *ops)
2636{
59ab3748 2637 struct xfs_mount *mp = dp->i_mount;
a2ceac1f 2638 struct xfs_buf *bp;
59ab3748
CH
2639 struct xfs_buf_map map, *mapp = &map;
2640 int nmap = 1;
a2ceac1f
DC
2641 int error;
2642
2643 *bpp = NULL;
5f356ae6 2644 error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap);
48d1399b 2645 if (error || !nmap)
a2ceac1f 2646 goto out_free;
a2ceac1f 2647
59ab3748
CH
2648 error = xfs_trans_read_buf_map(mp, tp, mp->m_ddev_targp, mapp, nmap, 0,
2649 &bp, ops);
a2ceac1f
DC
2650 if (error)
2651 goto out_free;
2652
2653 if (whichfork == XFS_ATTR_FORK)
2654 xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF);
2bd0ea18 2655 else
a2ceac1f 2656 xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF);
a2ceac1f
DC
2657 *bpp = bp;
2658out_free:
2bd0ea18 2659 if (mapp != &map)
5e656dbb 2660 kmem_free(mapp);
2bd0ea18 2661
a2ceac1f 2662 return error;
2bd0ea18
NS
2663}
2664
2665/*
5e656dbb 2666 * Readahead the dir/attr block.
2bd0ea18 2667 */
3a65062f 2668int
5e656dbb 2669xfs_da_reada_buf(
a2ceac1f
DC
2670 struct xfs_inode *dp,
2671 xfs_dablk_t bno,
c6c4bbf3 2672 unsigned int flags,
a2ceac1f
DC
2673 int whichfork,
2674 const struct xfs_buf_ops *ops)
2bd0ea18 2675{
a2ceac1f
DC
2676 struct xfs_buf_map map;
2677 struct xfs_buf_map *mapp;
2678 int nmap;
2679 int error;
2bd0ea18 2680
a2ceac1f
DC
2681 mapp = &map;
2682 nmap = 1;
c6c4bbf3 2683 error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap);
48d1399b 2684 if (error || !nmap)
a2ceac1f 2685 goto out_free;
a2ceac1f 2686
a2ceac1f
DC
2687 xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, ops);
2688
2689out_free:
2690 if (mapp != &map)
2691 kmem_free(mapp);
2692
3a65062f 2693 return error;
2bd0ea18 2694}