brintos

brintos / linux-shallow public Read only

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