| .. | .. | 
|---|
| 12 | 12 |  #include "xfs_trans_resv.h" | 
|---|
| 13 | 13 |  #include "xfs_bit.h" | 
|---|
| 14 | 14 |  #include "xfs_mount.h" | 
|---|
| 15 |  | -#include "xfs_da_format.h"  | 
|---|
| 16 |  | -#include "xfs_da_btree.h"  | 
|---|
 | 15 | +#include "xfs_inode.h"  | 
|---|
| 17 | 16 |  #include "xfs_dir2.h" | 
|---|
| 18 | 17 |  #include "xfs_dir2_priv.h" | 
|---|
| 19 |  | -#include "xfs_inode.h"  | 
|---|
| 20 | 18 |  #include "xfs_trans.h" | 
|---|
| 21 |  | -#include "xfs_inode_item.h"  | 
|---|
| 22 |  | -#include "xfs_alloc.h"  | 
|---|
| 23 | 19 |  #include "xfs_bmap.h" | 
|---|
| 24 |  | -#include "xfs_attr.h"  | 
|---|
| 25 | 20 |  #include "xfs_attr_leaf.h" | 
|---|
| 26 | 21 |  #include "xfs_error.h" | 
|---|
| 27 | 22 |  #include "xfs_trace.h" | 
|---|
| 28 |  | -#include "xfs_cksum.h"  | 
|---|
| 29 | 23 |  #include "xfs_buf_item.h" | 
|---|
| 30 | 24 |  #include "xfs_log.h" | 
|---|
| 31 | 25 |   | 
|---|
| .. | .. | 
|---|
| 84 | 78 |   * Allocate a dir-state structure. | 
|---|
| 85 | 79 |   * We don't put them on the stack since they're large. | 
|---|
| 86 | 80 |   */ | 
|---|
| 87 |  | -xfs_da_state_t *  | 
|---|
| 88 |  | -xfs_da_state_alloc(void)  | 
|---|
 | 81 | +struct xfs_da_state *  | 
|---|
 | 82 | +xfs_da_state_alloc(  | 
|---|
 | 83 | +	struct xfs_da_args	*args)  | 
|---|
| 89 | 84 |  { | 
|---|
| 90 |  | -	return kmem_zone_zalloc(xfs_da_state_zone, KM_NOFS);  | 
|---|
 | 85 | +	struct xfs_da_state	*state;  | 
|---|
 | 86 | +  | 
|---|
 | 87 | +	state = kmem_cache_zalloc(xfs_da_state_zone, GFP_NOFS | __GFP_NOFAIL);  | 
|---|
 | 88 | +	state->args = args;  | 
|---|
 | 89 | +	state->mp = args->dp->i_mount;  | 
|---|
 | 90 | +	return state;  | 
|---|
| 91 | 91 |  } | 
|---|
| 92 | 92 |   | 
|---|
| 93 | 93 |  /* | 
|---|
| .. | .. | 
|---|
| 113 | 113 |  #ifdef DEBUG | 
|---|
| 114 | 114 |  	memset((char *)state, 0, sizeof(*state)); | 
|---|
| 115 | 115 |  #endif /* DEBUG */ | 
|---|
| 116 |  | -	kmem_zone_free(xfs_da_state_zone, state);  | 
|---|
 | 116 | +	kmem_cache_free(xfs_da_state_zone, state);  | 
|---|
 | 117 | +}  | 
|---|
 | 118 | +  | 
|---|
 | 119 | +static inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)  | 
|---|
 | 120 | +{  | 
|---|
 | 121 | +	if (whichfork == XFS_DATA_FORK)  | 
|---|
 | 122 | +		return mp->m_dir_geo->fsbcount;  | 
|---|
 | 123 | +	return mp->m_attr_geo->fsbcount;  | 
|---|
 | 124 | +}  | 
|---|
 | 125 | +  | 
|---|
 | 126 | +void  | 
|---|
 | 127 | +xfs_da3_node_hdr_from_disk(  | 
|---|
 | 128 | +	struct xfs_mount		*mp,  | 
|---|
 | 129 | +	struct xfs_da3_icnode_hdr	*to,  | 
|---|
 | 130 | +	struct xfs_da_intnode		*from)  | 
|---|
 | 131 | +{  | 
|---|
 | 132 | +	if (xfs_sb_version_hascrc(&mp->m_sb)) {  | 
|---|
 | 133 | +		struct xfs_da3_intnode	*from3 = (struct xfs_da3_intnode *)from;  | 
|---|
 | 134 | +  | 
|---|
 | 135 | +		to->forw = be32_to_cpu(from3->hdr.info.hdr.forw);  | 
|---|
 | 136 | +		to->back = be32_to_cpu(from3->hdr.info.hdr.back);  | 
|---|
 | 137 | +		to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);  | 
|---|
 | 138 | +		to->count = be16_to_cpu(from3->hdr.__count);  | 
|---|
 | 139 | +		to->level = be16_to_cpu(from3->hdr.__level);  | 
|---|
 | 140 | +		to->btree = from3->__btree;  | 
|---|
 | 141 | +		ASSERT(to->magic == XFS_DA3_NODE_MAGIC);  | 
|---|
 | 142 | +	} else {  | 
|---|
 | 143 | +		to->forw = be32_to_cpu(from->hdr.info.forw);  | 
|---|
 | 144 | +		to->back = be32_to_cpu(from->hdr.info.back);  | 
|---|
 | 145 | +		to->magic = be16_to_cpu(from->hdr.info.magic);  | 
|---|
 | 146 | +		to->count = be16_to_cpu(from->hdr.__count);  | 
|---|
 | 147 | +		to->level = be16_to_cpu(from->hdr.__level);  | 
|---|
 | 148 | +		to->btree = from->__btree;  | 
|---|
 | 149 | +		ASSERT(to->magic == XFS_DA_NODE_MAGIC);  | 
|---|
 | 150 | +	}  | 
|---|
 | 151 | +}  | 
|---|
 | 152 | +  | 
|---|
 | 153 | +void  | 
|---|
 | 154 | +xfs_da3_node_hdr_to_disk(  | 
|---|
 | 155 | +	struct xfs_mount		*mp,  | 
|---|
 | 156 | +	struct xfs_da_intnode		*to,  | 
|---|
 | 157 | +	struct xfs_da3_icnode_hdr	*from)  | 
|---|
 | 158 | +{  | 
|---|
 | 159 | +	if (xfs_sb_version_hascrc(&mp->m_sb)) {  | 
|---|
 | 160 | +		struct xfs_da3_intnode	*to3 = (struct xfs_da3_intnode *)to;  | 
|---|
 | 161 | +  | 
|---|
 | 162 | +		ASSERT(from->magic == XFS_DA3_NODE_MAGIC);  | 
|---|
 | 163 | +		to3->hdr.info.hdr.forw = cpu_to_be32(from->forw);  | 
|---|
 | 164 | +		to3->hdr.info.hdr.back = cpu_to_be32(from->back);  | 
|---|
 | 165 | +		to3->hdr.info.hdr.magic = cpu_to_be16(from->magic);  | 
|---|
 | 166 | +		to3->hdr.__count = cpu_to_be16(from->count);  | 
|---|
 | 167 | +		to3->hdr.__level = cpu_to_be16(from->level);  | 
|---|
 | 168 | +	} else {  | 
|---|
 | 169 | +		ASSERT(from->magic == XFS_DA_NODE_MAGIC);  | 
|---|
 | 170 | +		to->hdr.info.forw = cpu_to_be32(from->forw);  | 
|---|
 | 171 | +		to->hdr.info.back = cpu_to_be32(from->back);  | 
|---|
 | 172 | +		to->hdr.info.magic = cpu_to_be16(from->magic);  | 
|---|
 | 173 | +		to->hdr.__count = cpu_to_be16(from->count);  | 
|---|
 | 174 | +		to->hdr.__level = cpu_to_be16(from->level);  | 
|---|
 | 175 | +	}  | 
|---|
 | 176 | +}  | 
|---|
 | 177 | +  | 
|---|
 | 178 | +/*  | 
|---|
 | 179 | + * Verify an xfs_da3_blkinfo structure. Note that the da3 fields are only  | 
|---|
 | 180 | + * accessible on v5 filesystems. This header format is common across da node,  | 
|---|
 | 181 | + * attr leaf and dir leaf blocks.  | 
|---|
 | 182 | + */  | 
|---|
 | 183 | +xfs_failaddr_t  | 
|---|
 | 184 | +xfs_da3_blkinfo_verify(  | 
|---|
 | 185 | +	struct xfs_buf		*bp,  | 
|---|
 | 186 | +	struct xfs_da3_blkinfo	*hdr3)  | 
|---|
 | 187 | +{  | 
|---|
 | 188 | +	struct xfs_mount	*mp = bp->b_mount;  | 
|---|
 | 189 | +	struct xfs_da_blkinfo	*hdr = &hdr3->hdr;  | 
|---|
 | 190 | +  | 
|---|
 | 191 | +	if (!xfs_verify_magic16(bp, hdr->magic))  | 
|---|
 | 192 | +		return __this_address;  | 
|---|
 | 193 | +  | 
|---|
 | 194 | +	if (xfs_sb_version_hascrc(&mp->m_sb)) {  | 
|---|
 | 195 | +		if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))  | 
|---|
 | 196 | +			return __this_address;  | 
|---|
 | 197 | +		if (be64_to_cpu(hdr3->blkno) != bp->b_bn)  | 
|---|
 | 198 | +			return __this_address;  | 
|---|
 | 199 | +		if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))  | 
|---|
 | 200 | +			return __this_address;  | 
|---|
 | 201 | +	}  | 
|---|
 | 202 | +  | 
|---|
 | 203 | +	return NULL;  | 
|---|
| 117 | 204 |  } | 
|---|
| 118 | 205 |   | 
|---|
| 119 | 206 |  static xfs_failaddr_t | 
|---|
| 120 | 207 |  xfs_da3_node_verify( | 
|---|
| 121 | 208 |  	struct xfs_buf		*bp) | 
|---|
| 122 | 209 |  { | 
|---|
| 123 |  | -	struct xfs_mount	*mp = bp->b_target->bt_mount;  | 
|---|
 | 210 | +	struct xfs_mount	*mp = bp->b_mount;  | 
|---|
| 124 | 211 |  	struct xfs_da_intnode	*hdr = bp->b_addr; | 
|---|
| 125 | 212 |  	struct xfs_da3_icnode_hdr ichdr; | 
|---|
| 126 |  | -	const struct xfs_dir_ops *ops;  | 
|---|
 | 213 | +	xfs_failaddr_t		fa;  | 
|---|
| 127 | 214 |   | 
|---|
| 128 |  | -	ops = xfs_dir_get_ops(mp, NULL);  | 
|---|
 | 215 | +	xfs_da3_node_hdr_from_disk(mp, &ichdr, hdr);  | 
|---|
| 129 | 216 |   | 
|---|
| 130 |  | -	ops->node_hdr_from_disk(&ichdr, hdr);  | 
|---|
 | 217 | +	fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);  | 
|---|
 | 218 | +	if (fa)  | 
|---|
 | 219 | +		return fa;  | 
|---|
| 131 | 220 |   | 
|---|
| 132 |  | -	if (xfs_sb_version_hascrc(&mp->m_sb)) {  | 
|---|
| 133 |  | -		struct xfs_da3_node_hdr *hdr3 = bp->b_addr;  | 
|---|
| 134 |  | -  | 
|---|
| 135 |  | -		if (ichdr.magic != XFS_DA3_NODE_MAGIC)  | 
|---|
| 136 |  | -			return __this_address;  | 
|---|
| 137 |  | -  | 
|---|
| 138 |  | -		if (!uuid_equal(&hdr3->info.uuid, &mp->m_sb.sb_meta_uuid))  | 
|---|
| 139 |  | -			return __this_address;  | 
|---|
| 140 |  | -		if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn)  | 
|---|
| 141 |  | -			return __this_address;  | 
|---|
| 142 |  | -		if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn)))  | 
|---|
| 143 |  | -			return __this_address;  | 
|---|
| 144 |  | -	} else {  | 
|---|
| 145 |  | -		if (ichdr.magic != XFS_DA_NODE_MAGIC)  | 
|---|
| 146 |  | -			return __this_address;  | 
|---|
| 147 |  | -	}  | 
|---|
| 148 | 221 |  	if (ichdr.level == 0) | 
|---|
| 149 | 222 |  		return __this_address; | 
|---|
| 150 | 223 |  	if (ichdr.level > XFS_DA_NODE_MAXDEPTH) | 
|---|
| .. | .. | 
|---|
| 169 | 242 |  xfs_da3_node_write_verify( | 
|---|
| 170 | 243 |  	struct xfs_buf	*bp) | 
|---|
| 171 | 244 |  { | 
|---|
| 172 |  | -	struct xfs_mount	*mp = bp->b_target->bt_mount;  | 
|---|
 | 245 | +	struct xfs_mount	*mp = bp->b_mount;  | 
|---|
| 173 | 246 |  	struct xfs_buf_log_item	*bip = bp->b_log_item; | 
|---|
| 174 | 247 |  	struct xfs_da3_node_hdr *hdr3 = bp->b_addr; | 
|---|
| 175 | 248 |  	xfs_failaddr_t		fa; | 
|---|
| .. | .. | 
|---|
| 257 | 330 |   | 
|---|
| 258 | 331 |  const struct xfs_buf_ops xfs_da3_node_buf_ops = { | 
|---|
| 259 | 332 |  	.name = "xfs_da3_node", | 
|---|
 | 333 | +	.magic16 = { cpu_to_be16(XFS_DA_NODE_MAGIC),  | 
|---|
 | 334 | +		     cpu_to_be16(XFS_DA3_NODE_MAGIC) },  | 
|---|
| 260 | 335 |  	.verify_read = xfs_da3_node_read_verify, | 
|---|
| 261 | 336 |  	.verify_write = xfs_da3_node_write_verify, | 
|---|
| 262 | 337 |  	.verify_struct = xfs_da3_node_verify_struct, | 
|---|
| 263 | 338 |  }; | 
|---|
 | 339 | +  | 
|---|
 | 340 | +static int  | 
|---|
 | 341 | +xfs_da3_node_set_type(  | 
|---|
 | 342 | +	struct xfs_trans	*tp,  | 
|---|
 | 343 | +	struct xfs_buf		*bp)  | 
|---|
 | 344 | +{  | 
|---|
 | 345 | +	struct xfs_da_blkinfo	*info = bp->b_addr;  | 
|---|
 | 346 | +  | 
|---|
 | 347 | +	switch (be16_to_cpu(info->magic)) {  | 
|---|
 | 348 | +	case XFS_DA_NODE_MAGIC:  | 
|---|
 | 349 | +	case XFS_DA3_NODE_MAGIC:  | 
|---|
 | 350 | +		xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);  | 
|---|
 | 351 | +		return 0;  | 
|---|
 | 352 | +	case XFS_ATTR_LEAF_MAGIC:  | 
|---|
 | 353 | +	case XFS_ATTR3_LEAF_MAGIC:  | 
|---|
 | 354 | +		xfs_trans_buf_set_type(tp, bp, XFS_BLFT_ATTR_LEAF_BUF);  | 
|---|
 | 355 | +		return 0;  | 
|---|
 | 356 | +	case XFS_DIR2_LEAFN_MAGIC:  | 
|---|
 | 357 | +	case XFS_DIR3_LEAFN_MAGIC:  | 
|---|
 | 358 | +		xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF);  | 
|---|
 | 359 | +		return 0;  | 
|---|
 | 360 | +	default:  | 
|---|
 | 361 | +		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp,  | 
|---|
 | 362 | +				info, sizeof(*info));  | 
|---|
 | 363 | +		xfs_trans_brelse(tp, bp);  | 
|---|
 | 364 | +		return -EFSCORRUPTED;  | 
|---|
 | 365 | +	}  | 
|---|
 | 366 | +}  | 
|---|
| 264 | 367 |   | 
|---|
| 265 | 368 |  int | 
|---|
| 266 | 369 |  xfs_da3_node_read( | 
|---|
| 267 | 370 |  	struct xfs_trans	*tp, | 
|---|
| 268 | 371 |  	struct xfs_inode	*dp, | 
|---|
| 269 | 372 |  	xfs_dablk_t		bno, | 
|---|
 | 373 | +	struct xfs_buf		**bpp,  | 
|---|
 | 374 | +	int			whichfork)  | 
|---|
 | 375 | +{  | 
|---|
 | 376 | +	int			error;  | 
|---|
 | 377 | +  | 
|---|
 | 378 | +	error = xfs_da_read_buf(tp, dp, bno, 0, bpp, whichfork,  | 
|---|
 | 379 | +			&xfs_da3_node_buf_ops);  | 
|---|
 | 380 | +	if (error || !*bpp || !tp)  | 
|---|
 | 381 | +		return error;  | 
|---|
 | 382 | +	return xfs_da3_node_set_type(tp, *bpp);  | 
|---|
 | 383 | +}  | 
|---|
 | 384 | +  | 
|---|
 | 385 | +int  | 
|---|
 | 386 | +xfs_da3_node_read_mapped(  | 
|---|
 | 387 | +	struct xfs_trans	*tp,  | 
|---|
 | 388 | +	struct xfs_inode	*dp,  | 
|---|
| 270 | 389 |  	xfs_daddr_t		mappedbno, | 
|---|
| 271 | 390 |  	struct xfs_buf		**bpp, | 
|---|
| 272 |  | -	int			which_fork)  | 
|---|
 | 391 | +	int			whichfork)  | 
|---|
| 273 | 392 |  { | 
|---|
| 274 |  | -	int			err;  | 
|---|
 | 393 | +	struct xfs_mount	*mp = dp->i_mount;  | 
|---|
 | 394 | +	int			error;  | 
|---|
| 275 | 395 |   | 
|---|
| 276 |  | -	err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,  | 
|---|
| 277 |  | -					which_fork, &xfs_da3_node_buf_ops);  | 
|---|
| 278 |  | -	if (!err && tp && *bpp) {  | 
|---|
| 279 |  | -		struct xfs_da_blkinfo	*info = (*bpp)->b_addr;  | 
|---|
| 280 |  | -		int			type;  | 
|---|
 | 396 | +	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, mappedbno,  | 
|---|
 | 397 | +			XFS_FSB_TO_BB(mp, xfs_dabuf_nfsb(mp, whichfork)), 0,  | 
|---|
 | 398 | +			bpp, &xfs_da3_node_buf_ops);  | 
|---|
 | 399 | +	if (error || !*bpp)  | 
|---|
 | 400 | +		return error;  | 
|---|
| 281 | 401 |   | 
|---|
| 282 |  | -		switch (be16_to_cpu(info->magic)) {  | 
|---|
| 283 |  | -		case XFS_DA_NODE_MAGIC:  | 
|---|
| 284 |  | -		case XFS_DA3_NODE_MAGIC:  | 
|---|
| 285 |  | -			type = XFS_BLFT_DA_NODE_BUF;  | 
|---|
| 286 |  | -			break;  | 
|---|
| 287 |  | -		case XFS_ATTR_LEAF_MAGIC:  | 
|---|
| 288 |  | -		case XFS_ATTR3_LEAF_MAGIC:  | 
|---|
| 289 |  | -			type = XFS_BLFT_ATTR_LEAF_BUF;  | 
|---|
| 290 |  | -			break;  | 
|---|
| 291 |  | -		case XFS_DIR2_LEAFN_MAGIC:  | 
|---|
| 292 |  | -		case XFS_DIR3_LEAFN_MAGIC:  | 
|---|
| 293 |  | -			type = XFS_BLFT_DIR_LEAFN_BUF;  | 
|---|
| 294 |  | -			break;  | 
|---|
| 295 |  | -		default:  | 
|---|
| 296 |  | -			XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,  | 
|---|
| 297 |  | -					tp->t_mountp, info, sizeof(*info));  | 
|---|
| 298 |  | -			xfs_trans_brelse(tp, *bpp);  | 
|---|
| 299 |  | -			*bpp = NULL;  | 
|---|
| 300 |  | -			return -EFSCORRUPTED;  | 
|---|
| 301 |  | -		}  | 
|---|
| 302 |  | -		xfs_trans_buf_set_type(tp, *bpp, type);  | 
|---|
| 303 |  | -	}  | 
|---|
| 304 |  | -	return err;  | 
|---|
 | 402 | +	if (whichfork == XFS_ATTR_FORK)  | 
|---|
 | 403 | +		xfs_buf_set_ref(*bpp, XFS_ATTR_BTREE_REF);  | 
|---|
 | 404 | +	else  | 
|---|
 | 405 | +		xfs_buf_set_ref(*bpp, XFS_DIR_BTREE_REF);  | 
|---|
 | 406 | +  | 
|---|
 | 407 | +	if (!tp)  | 
|---|
 | 408 | +		return 0;  | 
|---|
 | 409 | +	return xfs_da3_node_set_type(tp, *bpp);  | 
|---|
| 305 | 410 |  } | 
|---|
| 306 | 411 |   | 
|---|
| 307 | 412 |  /*======================================================================== | 
|---|
| .. | .. | 
|---|
| 330 | 435 |  	trace_xfs_da_node_create(args); | 
|---|
| 331 | 436 |  	ASSERT(level <= XFS_DA_NODE_MAXDEPTH); | 
|---|
| 332 | 437 |   | 
|---|
| 333 |  | -	error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, whichfork);  | 
|---|
 | 438 | +	error = xfs_da_get_buf(tp, dp, blkno, &bp, whichfork);  | 
|---|
| 334 | 439 |  	if (error) | 
|---|
| 335 | 440 |  		return error; | 
|---|
| 336 | 441 |  	bp->b_ops = &xfs_da3_node_buf_ops; | 
|---|
| .. | .. | 
|---|
| 350 | 455 |  	} | 
|---|
| 351 | 456 |  	ichdr.level = level; | 
|---|
| 352 | 457 |   | 
|---|
| 353 |  | -	dp->d_ops->node_hdr_to_disk(node, &ichdr);  | 
|---|
 | 458 | +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr);  | 
|---|
| 354 | 459 |  	xfs_trans_log_buf(tp, bp, | 
|---|
| 355 |  | -		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));  | 
|---|
 | 460 | +		XFS_DA_LOGRANGE(node, &node->hdr, args->geo->node_hdr_size));  | 
|---|
| 356 | 461 |   | 
|---|
| 357 | 462 |  	*bpp = bp; | 
|---|
| 358 | 463 |  	return 0; | 
|---|
| .. | .. | 
|---|
| 474 | 579 |  	ASSERT(state->path.active == 0); | 
|---|
| 475 | 580 |  	oldblk = &state->path.blk[0]; | 
|---|
| 476 | 581 |  	error = xfs_da3_root_split(state, oldblk, addblk); | 
|---|
| 477 |  | -	if (error) {  | 
|---|
| 478 |  | -		addblk->bp = NULL;  | 
|---|
| 479 |  | -		return error;	/* GROT: dir is inconsistent */  | 
|---|
| 480 |  | -	}  | 
|---|
 | 582 | +	if (error)  | 
|---|
 | 583 | +		goto out;  | 
|---|
| 481 | 584 |   | 
|---|
| 482 | 585 |  	/* | 
|---|
| 483 | 586 |  	 * Update pointers to the node which used to be block 0 and just got | 
|---|
| .. | .. | 
|---|
| 492 | 595 |  	 */ | 
|---|
| 493 | 596 |  	node = oldblk->bp->b_addr; | 
|---|
| 494 | 597 |  	if (node->hdr.info.forw) { | 
|---|
| 495 |  | -		ASSERT(be32_to_cpu(node->hdr.info.forw) == addblk->blkno);  | 
|---|
 | 598 | +		if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {  | 
|---|
 | 599 | +			xfs_buf_mark_corrupt(oldblk->bp);  | 
|---|
 | 600 | +			error = -EFSCORRUPTED;  | 
|---|
 | 601 | +			goto out;  | 
|---|
 | 602 | +		}  | 
|---|
| 496 | 603 |  		node = addblk->bp->b_addr; | 
|---|
| 497 | 604 |  		node->hdr.info.back = cpu_to_be32(oldblk->blkno); | 
|---|
| 498 | 605 |  		xfs_trans_log_buf(state->args->trans, addblk->bp, | 
|---|
| .. | .. | 
|---|
| 501 | 608 |  	} | 
|---|
| 502 | 609 |  	node = oldblk->bp->b_addr; | 
|---|
| 503 | 610 |  	if (node->hdr.info.back) { | 
|---|
| 504 |  | -		ASSERT(be32_to_cpu(node->hdr.info.back) == addblk->blkno);  | 
|---|
 | 611 | +		if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {  | 
|---|
 | 612 | +			xfs_buf_mark_corrupt(oldblk->bp);  | 
|---|
 | 613 | +			error = -EFSCORRUPTED;  | 
|---|
 | 614 | +			goto out;  | 
|---|
 | 615 | +		}  | 
|---|
| 505 | 616 |  		node = addblk->bp->b_addr; | 
|---|
| 506 | 617 |  		node->hdr.info.forw = cpu_to_be32(oldblk->blkno); | 
|---|
| 507 | 618 |  		xfs_trans_log_buf(state->args->trans, addblk->bp, | 
|---|
| 508 | 619 |  				  XFS_DA_LOGRANGE(node, &node->hdr.info, | 
|---|
| 509 | 620 |  				  sizeof(node->hdr.info))); | 
|---|
| 510 | 621 |  	} | 
|---|
 | 622 | +out:  | 
|---|
| 511 | 623 |  	addblk->bp = NULL; | 
|---|
| 512 |  | -	return 0;  | 
|---|
 | 624 | +	return error;  | 
|---|
| 513 | 625 |  } | 
|---|
| 514 | 626 |   | 
|---|
| 515 | 627 |  /* | 
|---|
| .. | .. | 
|---|
| 550 | 662 |   | 
|---|
| 551 | 663 |  	dp = args->dp; | 
|---|
| 552 | 664 |  	tp = args->trans; | 
|---|
| 553 |  | -	error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork);  | 
|---|
 | 665 | +	error = xfs_da_get_buf(tp, dp, blkno, &bp, args->whichfork);  | 
|---|
| 554 | 666 |  	if (error) | 
|---|
| 555 | 667 |  		return error; | 
|---|
| 556 | 668 |  	node = bp->b_addr; | 
|---|
| .. | .. | 
|---|
| 559 | 671 |  	    oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) { | 
|---|
| 560 | 672 |  		struct xfs_da3_icnode_hdr icnodehdr; | 
|---|
| 561 | 673 |   | 
|---|
| 562 |  | -		dp->d_ops->node_hdr_from_disk(&icnodehdr, oldroot);  | 
|---|
| 563 |  | -		btree = dp->d_ops->node_tree_p(oldroot);  | 
|---|
 | 674 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &icnodehdr, oldroot);  | 
|---|
 | 675 | +		btree = icnodehdr.btree;  | 
|---|
| 564 | 676 |  		size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot); | 
|---|
| 565 | 677 |  		level = icnodehdr.level; | 
|---|
| 566 | 678 |   | 
|---|
| .. | .. | 
|---|
| 571 | 683 |  		xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF); | 
|---|
| 572 | 684 |  	} else { | 
|---|
| 573 | 685 |  		struct xfs_dir3_icleaf_hdr leafhdr; | 
|---|
| 574 |  | -		struct xfs_dir2_leaf_entry *ents;  | 
|---|
| 575 | 686 |   | 
|---|
| 576 | 687 |  		leaf = (xfs_dir2_leaf_t *)oldroot; | 
|---|
| 577 |  | -		dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);  | 
|---|
| 578 |  | -		ents = dp->d_ops->leaf_ents_p(leaf);  | 
|---|
 | 688 | +		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);  | 
|---|
| 579 | 689 |   | 
|---|
| 580 | 690 |  		ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || | 
|---|
| 581 | 691 |  		       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); | 
|---|
| 582 |  | -		size = (int)((char *)&ents[leafhdr.count] - (char *)leaf);  | 
|---|
 | 692 | +		size = (int)((char *)&leafhdr.ents[leafhdr.count] -  | 
|---|
 | 693 | +			(char *)leaf);  | 
|---|
| 583 | 694 |  		level = 0; | 
|---|
| 584 | 695 |   | 
|---|
| 585 | 696 |  		/* | 
|---|
| .. | .. | 
|---|
| 619 | 730 |  		return error; | 
|---|
| 620 | 731 |   | 
|---|
| 621 | 732 |  	node = bp->b_addr; | 
|---|
| 622 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
| 623 |  | -	btree = dp->d_ops->node_tree_p(node);  | 
|---|
 | 733 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
 | 734 | +	btree = nodehdr.btree;  | 
|---|
| 624 | 735 |  	btree[0].hashval = cpu_to_be32(blk1->hashval); | 
|---|
| 625 | 736 |  	btree[0].before = cpu_to_be32(blk1->blkno); | 
|---|
| 626 | 737 |  	btree[1].hashval = cpu_to_be32(blk2->hashval); | 
|---|
| 627 | 738 |  	btree[1].before = cpu_to_be32(blk2->blkno); | 
|---|
| 628 | 739 |  	nodehdr.count = 2; | 
|---|
| 629 |  | -	dp->d_ops->node_hdr_to_disk(node, &nodehdr);  | 
|---|
 | 740 | +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);  | 
|---|
| 630 | 741 |   | 
|---|
| 631 | 742 |  #ifdef DEBUG | 
|---|
| 632 | 743 |  	if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || | 
|---|
| .. | .. | 
|---|
| 668 | 779 |  	trace_xfs_da_node_split(state->args); | 
|---|
| 669 | 780 |   | 
|---|
| 670 | 781 |  	node = oldblk->bp->b_addr; | 
|---|
| 671 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
 | 782 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
| 672 | 783 |   | 
|---|
| 673 | 784 |  	/* | 
|---|
| 674 | 785 |  	 * With V2 dirs the extra block is data or freespace. | 
|---|
| .. | .. | 
|---|
| 715 | 826 |  	 * If we had double-split op below us, then add the extra block too. | 
|---|
| 716 | 827 |  	 */ | 
|---|
| 717 | 828 |  	node = oldblk->bp->b_addr; | 
|---|
| 718 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
 | 829 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
| 719 | 830 |  	if (oldblk->index <= nodehdr.count) { | 
|---|
| 720 | 831 |  		oldblk->index++; | 
|---|
| 721 | 832 |  		xfs_da3_node_add(state, oldblk, addblk); | 
|---|
| .. | .. | 
|---|
| 770 | 881 |   | 
|---|
| 771 | 882 |  	node1 = blk1->bp->b_addr; | 
|---|
| 772 | 883 |  	node2 = blk2->bp->b_addr; | 
|---|
| 773 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);  | 
|---|
| 774 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);  | 
|---|
| 775 |  | -	btree1 = dp->d_ops->node_tree_p(node1);  | 
|---|
| 776 |  | -	btree2 = dp->d_ops->node_tree_p(node2);  | 
|---|
 | 884 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);  | 
|---|
 | 885 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);  | 
|---|
 | 886 | +	btree1 = nodehdr1.btree;  | 
|---|
 | 887 | +	btree2 = nodehdr2.btree;  | 
|---|
| 777 | 888 |   | 
|---|
| 778 | 889 |  	/* | 
|---|
| 779 | 890 |  	 * Figure out how many entries need to move, and in which direction. | 
|---|
| .. | .. | 
|---|
| 786 | 897 |  		tmpnode = node1; | 
|---|
| 787 | 898 |  		node1 = node2; | 
|---|
| 788 | 899 |  		node2 = tmpnode; | 
|---|
| 789 |  | -		dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);  | 
|---|
| 790 |  | -		dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);  | 
|---|
| 791 |  | -		btree1 = dp->d_ops->node_tree_p(node1);  | 
|---|
| 792 |  | -		btree2 = dp->d_ops->node_tree_p(node2);  | 
|---|
 | 900 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);  | 
|---|
 | 901 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);  | 
|---|
 | 902 | +		btree1 = nodehdr1.btree;  | 
|---|
 | 903 | +		btree2 = nodehdr2.btree;  | 
|---|
| 793 | 904 |  		swap = 1; | 
|---|
| 794 | 905 |  	} | 
|---|
| 795 | 906 |   | 
|---|
| .. | .. | 
|---|
| 851 | 962 |  	/* | 
|---|
| 852 | 963 |  	 * Log header of node 1 and all current bits of node 2. | 
|---|
| 853 | 964 |  	 */ | 
|---|
| 854 |  | -	dp->d_ops->node_hdr_to_disk(node1, &nodehdr1);  | 
|---|
 | 965 | +	xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1);  | 
|---|
| 855 | 966 |  	xfs_trans_log_buf(tp, blk1->bp, | 
|---|
| 856 |  | -		XFS_DA_LOGRANGE(node1, &node1->hdr, dp->d_ops->node_hdr_size));  | 
|---|
 | 967 | +		XFS_DA_LOGRANGE(node1, &node1->hdr,  | 
|---|
 | 968 | +				state->args->geo->node_hdr_size));  | 
|---|
| 857 | 969 |   | 
|---|
| 858 |  | -	dp->d_ops->node_hdr_to_disk(node2, &nodehdr2);  | 
|---|
 | 970 | +	xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2);  | 
|---|
| 859 | 971 |  	xfs_trans_log_buf(tp, blk2->bp, | 
|---|
| 860 | 972 |  		XFS_DA_LOGRANGE(node2, &node2->hdr, | 
|---|
| 861 |  | -				dp->d_ops->node_hdr_size +  | 
|---|
 | 973 | +				state->args->geo->node_hdr_size +  | 
|---|
| 862 | 974 |  				(sizeof(btree2[0]) * nodehdr2.count))); | 
|---|
| 863 | 975 |   | 
|---|
| 864 | 976 |  	/* | 
|---|
| .. | .. | 
|---|
| 868 | 980 |  	if (swap) { | 
|---|
| 869 | 981 |  		node1 = blk1->bp->b_addr; | 
|---|
| 870 | 982 |  		node2 = blk2->bp->b_addr; | 
|---|
| 871 |  | -		dp->d_ops->node_hdr_from_disk(&nodehdr1, node1);  | 
|---|
| 872 |  | -		dp->d_ops->node_hdr_from_disk(&nodehdr2, node2);  | 
|---|
| 873 |  | -		btree1 = dp->d_ops->node_tree_p(node1);  | 
|---|
| 874 |  | -		btree2 = dp->d_ops->node_tree_p(node2);  | 
|---|
 | 983 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1);  | 
|---|
 | 984 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2);  | 
|---|
 | 985 | +		btree1 = nodehdr1.btree;  | 
|---|
 | 986 | +		btree2 = nodehdr2.btree;  | 
|---|
| 875 | 987 |  	} | 
|---|
| 876 | 988 |  	blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval); | 
|---|
| 877 | 989 |  	blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval); | 
|---|
| .. | .. | 
|---|
| 903 | 1015 |  	trace_xfs_da_node_add(state->args); | 
|---|
| 904 | 1016 |   | 
|---|
| 905 | 1017 |  	node = oldblk->bp->b_addr; | 
|---|
| 906 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
| 907 |  | -	btree = dp->d_ops->node_tree_p(node);  | 
|---|
 | 1018 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
 | 1019 | +	btree = nodehdr.btree;  | 
|---|
| 908 | 1020 |   | 
|---|
| 909 | 1021 |  	ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count); | 
|---|
| 910 | 1022 |  	ASSERT(newblk->blkno != 0); | 
|---|
| .. | .. | 
|---|
| 927 | 1039 |  				tmp + sizeof(*btree))); | 
|---|
| 928 | 1040 |   | 
|---|
| 929 | 1041 |  	nodehdr.count += 1; | 
|---|
| 930 |  | -	dp->d_ops->node_hdr_to_disk(node, &nodehdr);  | 
|---|
 | 1042 | +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);  | 
|---|
| 931 | 1043 |  	xfs_trans_log_buf(state->args->trans, oldblk->bp, | 
|---|
| 932 |  | -		XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));  | 
|---|
 | 1044 | +		XFS_DA_LOGRANGE(node, &node->hdr,  | 
|---|
 | 1045 | +				state->args->geo->node_hdr_size));  | 
|---|
| 933 | 1046 |   | 
|---|
| 934 | 1047 |  	/* | 
|---|
| 935 | 1048 |  	 * Copy the last hash value from the oldblk to propagate upwards. | 
|---|
| .. | .. | 
|---|
| 1064 | 1177 |  	xfs_dablk_t		child; | 
|---|
| 1065 | 1178 |  	struct xfs_buf		*bp; | 
|---|
| 1066 | 1179 |  	struct xfs_da3_icnode_hdr oldroothdr; | 
|---|
| 1067 |  | -	struct xfs_da_node_entry *btree;  | 
|---|
| 1068 | 1180 |  	int			error; | 
|---|
| 1069 | 1181 |  	struct xfs_inode	*dp = state->args->dp; | 
|---|
| 1070 | 1182 |   | 
|---|
| .. | .. | 
|---|
| 1074 | 1186 |   | 
|---|
| 1075 | 1187 |  	args = state->args; | 
|---|
| 1076 | 1188 |  	oldroot = root_blk->bp->b_addr; | 
|---|
| 1077 |  | -	dp->d_ops->node_hdr_from_disk(&oldroothdr, oldroot);  | 
|---|
 | 1189 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &oldroothdr, oldroot);  | 
|---|
| 1078 | 1190 |  	ASSERT(oldroothdr.forw == 0); | 
|---|
| 1079 | 1191 |  	ASSERT(oldroothdr.back == 0); | 
|---|
| 1080 | 1192 |   | 
|---|
| .. | .. | 
|---|
| 1088 | 1200 |  	 * Read in the (only) child block, then copy those bytes into | 
|---|
| 1089 | 1201 |  	 * the root block's buffer and free the original child block. | 
|---|
| 1090 | 1202 |  	 */ | 
|---|
| 1091 |  | -	btree = dp->d_ops->node_tree_p(oldroot);  | 
|---|
| 1092 |  | -	child = be32_to_cpu(btree[0].before);  | 
|---|
 | 1203 | +	child = be32_to_cpu(oldroothdr.btree[0].before);  | 
|---|
| 1093 | 1204 |  	ASSERT(child != 0); | 
|---|
| 1094 |  | -	error = xfs_da3_node_read(args->trans, dp, child, -1, &bp,  | 
|---|
| 1095 |  | -					     args->whichfork);  | 
|---|
 | 1205 | +	error = xfs_da3_node_read(args->trans, dp, child, &bp, args->whichfork);  | 
|---|
| 1096 | 1206 |  	if (error) | 
|---|
| 1097 | 1207 |  		return error; | 
|---|
| 1098 | 1208 |  	xfs_da_blkinfo_onlychild_validate(bp->b_addr, oldroothdr.level); | 
|---|
| .. | .. | 
|---|
| 1154 | 1264 |  	blk = &state->path.blk[ state->path.active-1 ]; | 
|---|
| 1155 | 1265 |  	info = blk->bp->b_addr; | 
|---|
| 1156 | 1266 |  	node = (xfs_da_intnode_t *)info; | 
|---|
| 1157 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
 | 1267 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
| 1158 | 1268 |  	if (nodehdr.count > (state->args->geo->node_ents >> 1)) { | 
|---|
| 1159 | 1269 |  		*action = 0;	/* blk over 50%, don't try to join */ | 
|---|
| 1160 | 1270 |  		return 0;	/* blk over 50%, don't try to join */ | 
|---|
| .. | .. | 
|---|
| 1206 | 1316 |  			blkno = nodehdr.back; | 
|---|
| 1207 | 1317 |  		if (blkno == 0) | 
|---|
| 1208 | 1318 |  			continue; | 
|---|
| 1209 |  | -		error = xfs_da3_node_read(state->args->trans, dp,  | 
|---|
| 1210 |  | -					blkno, -1, &bp, state->args->whichfork);  | 
|---|
 | 1319 | +		error = xfs_da3_node_read(state->args->trans, dp, blkno, &bp,  | 
|---|
 | 1320 | +				state->args->whichfork);  | 
|---|
| 1211 | 1321 |  		if (error) | 
|---|
| 1212 | 1322 |  			return error; | 
|---|
| 1213 | 1323 |   | 
|---|
| 1214 | 1324 |  		node = bp->b_addr; | 
|---|
| 1215 |  | -		dp->d_ops->node_hdr_from_disk(&thdr, node);  | 
|---|
 | 1325 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &thdr, node);  | 
|---|
| 1216 | 1326 |  		xfs_trans_brelse(state->args->trans, bp); | 
|---|
| 1217 | 1327 |   | 
|---|
| 1218 | 1328 |  		if (count - thdr.count >= 0) | 
|---|
| .. | .. | 
|---|
| 1254 | 1364 |  	struct xfs_buf		*bp, | 
|---|
| 1255 | 1365 |  	int			*count) | 
|---|
| 1256 | 1366 |  { | 
|---|
| 1257 |  | -	struct xfs_da_intnode	 *node;  | 
|---|
| 1258 |  | -	struct xfs_da_node_entry *btree;  | 
|---|
| 1259 | 1367 |  	struct xfs_da3_icnode_hdr nodehdr; | 
|---|
| 1260 | 1368 |   | 
|---|
| 1261 |  | -	node = bp->b_addr;  | 
|---|
| 1262 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
 | 1369 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, bp->b_addr);  | 
|---|
| 1263 | 1370 |  	if (count) | 
|---|
| 1264 | 1371 |  		*count = nodehdr.count; | 
|---|
| 1265 | 1372 |  	if (!nodehdr.count) | 
|---|
| 1266 | 1373 |  		return 0; | 
|---|
| 1267 |  | -	btree = dp->d_ops->node_tree_p(node);  | 
|---|
| 1268 |  | -	return be32_to_cpu(btree[nodehdr.count - 1].hashval);  | 
|---|
 | 1374 | +	return be32_to_cpu(nodehdr.btree[nodehdr.count - 1].hashval);  | 
|---|
| 1269 | 1375 |  } | 
|---|
| 1270 | 1376 |   | 
|---|
| 1271 | 1377 |  /* | 
|---|
| .. | .. | 
|---|
| 1310 | 1416 |  		struct xfs_da3_icnode_hdr nodehdr; | 
|---|
| 1311 | 1417 |   | 
|---|
| 1312 | 1418 |  		node = blk->bp->b_addr; | 
|---|
| 1313 |  | -		dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
| 1314 |  | -		btree = dp->d_ops->node_tree_p(node);  | 
|---|
 | 1419 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
 | 1420 | +		btree = nodehdr.btree;  | 
|---|
| 1315 | 1421 |  		if (be32_to_cpu(btree[blk->index].hashval) == lasthash) | 
|---|
| 1316 | 1422 |  			break; | 
|---|
| 1317 | 1423 |  		blk->hashval = lasthash; | 
|---|
| .. | .. | 
|---|
| 1342 | 1448 |  	trace_xfs_da_node_remove(state->args); | 
|---|
| 1343 | 1449 |   | 
|---|
| 1344 | 1450 |  	node = drop_blk->bp->b_addr; | 
|---|
| 1345 |  | -	dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
 | 1451 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
| 1346 | 1452 |  	ASSERT(drop_blk->index < nodehdr.count); | 
|---|
| 1347 | 1453 |  	ASSERT(drop_blk->index >= 0); | 
|---|
| 1348 | 1454 |   | 
|---|
| .. | .. | 
|---|
| 1350 | 1456 |  	 * Copy over the offending entry, or just zero it out. | 
|---|
| 1351 | 1457 |  	 */ | 
|---|
| 1352 | 1458 |  	index = drop_blk->index; | 
|---|
| 1353 |  | -	btree = dp->d_ops->node_tree_p(node);  | 
|---|
 | 1459 | +	btree = nodehdr.btree;  | 
|---|
| 1354 | 1460 |  	if (index < nodehdr.count - 1) { | 
|---|
| 1355 | 1461 |  		tmp  = nodehdr.count - index - 1; | 
|---|
| 1356 | 1462 |  		tmp *= (uint)sizeof(xfs_da_node_entry_t); | 
|---|
| .. | .. | 
|---|
| 1363 | 1469 |  	xfs_trans_log_buf(state->args->trans, drop_blk->bp, | 
|---|
| 1364 | 1470 |  	    XFS_DA_LOGRANGE(node, &btree[index], sizeof(btree[index]))); | 
|---|
| 1365 | 1471 |  	nodehdr.count -= 1; | 
|---|
| 1366 |  | -	dp->d_ops->node_hdr_to_disk(node, &nodehdr);  | 
|---|
 | 1472 | +	xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr);  | 
|---|
| 1367 | 1473 |  	xfs_trans_log_buf(state->args->trans, drop_blk->bp, | 
|---|
| 1368 |  | -	    XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size));  | 
|---|
 | 1474 | +	    XFS_DA_LOGRANGE(node, &node->hdr, state->args->geo->node_hdr_size));  | 
|---|
| 1369 | 1475 |   | 
|---|
| 1370 | 1476 |  	/* | 
|---|
| 1371 | 1477 |  	 * Copy the last hash value from the block to propagate upwards. | 
|---|
| .. | .. | 
|---|
| 1398 | 1504 |   | 
|---|
| 1399 | 1505 |  	drop_node = drop_blk->bp->b_addr; | 
|---|
| 1400 | 1506 |  	save_node = save_blk->bp->b_addr; | 
|---|
| 1401 |  | -	dp->d_ops->node_hdr_from_disk(&drop_hdr, drop_node);  | 
|---|
| 1402 |  | -	dp->d_ops->node_hdr_from_disk(&save_hdr, save_node);  | 
|---|
| 1403 |  | -	drop_btree = dp->d_ops->node_tree_p(drop_node);  | 
|---|
| 1404 |  | -	save_btree = dp->d_ops->node_tree_p(save_node);  | 
|---|
 | 1507 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &drop_hdr, drop_node);  | 
|---|
 | 1508 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &save_hdr, save_node);  | 
|---|
 | 1509 | +	drop_btree = drop_hdr.btree;  | 
|---|
 | 1510 | +	save_btree = save_hdr.btree;  | 
|---|
| 1405 | 1511 |  	tp = state->args->trans; | 
|---|
| 1406 | 1512 |   | 
|---|
| 1407 | 1513 |  	/* | 
|---|
| .. | .. | 
|---|
| 1435 | 1541 |  	memcpy(&save_btree[sindex], &drop_btree[0], tmp); | 
|---|
| 1436 | 1542 |  	save_hdr.count += drop_hdr.count; | 
|---|
| 1437 | 1543 |   | 
|---|
| 1438 |  | -	dp->d_ops->node_hdr_to_disk(save_node, &save_hdr);  | 
|---|
 | 1544 | +	xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr);  | 
|---|
| 1439 | 1545 |  	xfs_trans_log_buf(tp, save_blk->bp, | 
|---|
| 1440 | 1546 |  		XFS_DA_LOGRANGE(save_node, &save_node->hdr, | 
|---|
| 1441 |  | -				dp->d_ops->node_hdr_size));  | 
|---|
 | 1547 | +				state->args->geo->node_hdr_size));  | 
|---|
| 1442 | 1548 |   | 
|---|
| 1443 | 1549 |  	/* | 
|---|
| 1444 | 1550 |  	 * Save the last hashval in the remaining block for upward propagation. | 
|---|
| .. | .. | 
|---|
| 1499 | 1605 |  		 */ | 
|---|
| 1500 | 1606 |  		blk->blkno = blkno; | 
|---|
| 1501 | 1607 |  		error = xfs_da3_node_read(args->trans, args->dp, blkno, | 
|---|
| 1502 |  | -					-1, &blk->bp, args->whichfork);  | 
|---|
 | 1608 | +					&blk->bp, args->whichfork);  | 
|---|
| 1503 | 1609 |  		if (error) { | 
|---|
| 1504 | 1610 |  			blk->blkno = 0; | 
|---|
| 1505 | 1611 |  			state->path.active--; | 
|---|
| .. | .. | 
|---|
| 1523 | 1629 |  			break; | 
|---|
| 1524 | 1630 |  		} | 
|---|
| 1525 | 1631 |   | 
|---|
| 1526 |  | -		if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC)  | 
|---|
 | 1632 | +		if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) {  | 
|---|
 | 1633 | +			xfs_buf_mark_corrupt(blk->bp);  | 
|---|
| 1527 | 1634 |  			return -EFSCORRUPTED; | 
|---|
 | 1635 | +		}  | 
|---|
| 1528 | 1636 |   | 
|---|
| 1529 | 1637 |  		blk->magic = XFS_DA_NODE_MAGIC; | 
|---|
| 1530 | 1638 |   | 
|---|
| .. | .. | 
|---|
| 1532 | 1640 |  		 * Search an intermediate node for a match. | 
|---|
| 1533 | 1641 |  		 */ | 
|---|
| 1534 | 1642 |  		node = blk->bp->b_addr; | 
|---|
| 1535 |  | -		dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
| 1536 |  | -		btree = dp->d_ops->node_tree_p(node);  | 
|---|
 | 1643 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node);  | 
|---|
 | 1644 | +		btree = nodehdr.btree;  | 
|---|
| 1537 | 1645 |   | 
|---|
| 1538 | 1646 |  		/* Tree taller than we can handle; bail out! */ | 
|---|
| 1539 |  | -		if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)  | 
|---|
 | 1647 | +		if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {  | 
|---|
 | 1648 | +			xfs_buf_mark_corrupt(blk->bp);  | 
|---|
| 1540 | 1649 |  			return -EFSCORRUPTED; | 
|---|
 | 1650 | +		}  | 
|---|
| 1541 | 1651 |   | 
|---|
| 1542 | 1652 |  		/* Check the level from the root. */ | 
|---|
| 1543 | 1653 |  		if (blkno == args->geo->leafblk) | 
|---|
| 1544 | 1654 |  			expected_level = nodehdr.level - 1; | 
|---|
| 1545 |  | -		else if (expected_level != nodehdr.level)  | 
|---|
 | 1655 | +		else if (expected_level != nodehdr.level) {  | 
|---|
 | 1656 | +			xfs_buf_mark_corrupt(blk->bp);  | 
|---|
| 1546 | 1657 |  			return -EFSCORRUPTED; | 
|---|
| 1547 |  | -		else  | 
|---|
 | 1658 | +		} else  | 
|---|
| 1548 | 1659 |  			expected_level--; | 
|---|
| 1549 | 1660 |   | 
|---|
| 1550 | 1661 |  		max = nodehdr.count; | 
|---|
| .. | .. | 
|---|
| 1594 | 1705 |  		} | 
|---|
| 1595 | 1706 |   | 
|---|
| 1596 | 1707 |  		/* We can't point back to the root. */ | 
|---|
| 1597 |  | -		if (blkno == args->geo->leafblk)  | 
|---|
 | 1708 | +		if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk))  | 
|---|
| 1598 | 1709 |  			return -EFSCORRUPTED; | 
|---|
| 1599 | 1710 |  	} | 
|---|
| 1600 | 1711 |   | 
|---|
| 1601 |  | -	if (expected_level != 0)  | 
|---|
 | 1712 | +	if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0))  | 
|---|
| 1602 | 1713 |  		return -EFSCORRUPTED; | 
|---|
| 1603 | 1714 |   | 
|---|
| 1604 | 1715 |  	/* | 
|---|
| .. | .. | 
|---|
| 1660 | 1771 |   | 
|---|
| 1661 | 1772 |  	node1 = node1_bp->b_addr; | 
|---|
| 1662 | 1773 |  	node2 = node2_bp->b_addr; | 
|---|
| 1663 |  | -	dp->d_ops->node_hdr_from_disk(&node1hdr, node1);  | 
|---|
| 1664 |  | -	dp->d_ops->node_hdr_from_disk(&node2hdr, node2);  | 
|---|
| 1665 |  | -	btree1 = dp->d_ops->node_tree_p(node1);  | 
|---|
| 1666 |  | -	btree2 = dp->d_ops->node_tree_p(node2);  | 
|---|
 | 1774 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &node1hdr, node1);  | 
|---|
 | 1775 | +	xfs_da3_node_hdr_from_disk(dp->i_mount, &node2hdr, node2);  | 
|---|
 | 1776 | +	btree1 = node1hdr.btree;  | 
|---|
 | 1777 | +	btree2 = node2hdr.btree;  | 
|---|
| 1667 | 1778 |   | 
|---|
| 1668 | 1779 |  	if (node1hdr.count > 0 && node2hdr.count > 0 && | 
|---|
| 1669 | 1780 |  	    ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) || | 
|---|
| .. | .. | 
|---|
| 1728 | 1839 |  		if (old_info->back) { | 
|---|
| 1729 | 1840 |  			error = xfs_da3_node_read(args->trans, dp, | 
|---|
| 1730 | 1841 |  						be32_to_cpu(old_info->back), | 
|---|
| 1731 |  | -						-1, &bp, args->whichfork);  | 
|---|
 | 1842 | +						&bp, args->whichfork);  | 
|---|
| 1732 | 1843 |  			if (error) | 
|---|
| 1733 | 1844 |  				return error; | 
|---|
| 1734 | 1845 |  			ASSERT(bp != NULL); | 
|---|
| .. | .. | 
|---|
| 1749 | 1860 |  		if (old_info->forw) { | 
|---|
| 1750 | 1861 |  			error = xfs_da3_node_read(args->trans, dp, | 
|---|
| 1751 | 1862 |  						be32_to_cpu(old_info->forw), | 
|---|
| 1752 |  | -						-1, &bp, args->whichfork);  | 
|---|
 | 1863 | +						&bp, args->whichfork);  | 
|---|
| 1753 | 1864 |  			if (error) | 
|---|
| 1754 | 1865 |  				return error; | 
|---|
| 1755 | 1866 |  			ASSERT(bp != NULL); | 
|---|
| .. | .. | 
|---|
| 1808 | 1919 |  		if (drop_info->back) { | 
|---|
| 1809 | 1920 |  			error = xfs_da3_node_read(args->trans, args->dp, | 
|---|
| 1810 | 1921 |  						be32_to_cpu(drop_info->back), | 
|---|
| 1811 |  | -						-1, &bp, args->whichfork);  | 
|---|
 | 1922 | +						&bp, args->whichfork);  | 
|---|
| 1812 | 1923 |  			if (error) | 
|---|
| 1813 | 1924 |  				return error; | 
|---|
| 1814 | 1925 |  			ASSERT(bp != NULL); | 
|---|
| .. | .. | 
|---|
| 1825 | 1936 |  		if (drop_info->forw) { | 
|---|
| 1826 | 1937 |  			error = xfs_da3_node_read(args->trans, args->dp, | 
|---|
| 1827 | 1938 |  						be32_to_cpu(drop_info->forw), | 
|---|
| 1828 |  | -						-1, &bp, args->whichfork);  | 
|---|
 | 1939 | +						&bp, args->whichfork);  | 
|---|
| 1829 | 1940 |  			if (error) | 
|---|
| 1830 | 1941 |  				return error; | 
|---|
| 1831 | 1942 |  			ASSERT(bp != NULL); | 
|---|
| .. | .. | 
|---|
| 1860 | 1971 |  { | 
|---|
| 1861 | 1972 |  	struct xfs_da_state_blk	*blk; | 
|---|
| 1862 | 1973 |  	struct xfs_da_blkinfo	*info; | 
|---|
| 1863 |  | -	struct xfs_da_intnode	*node;  | 
|---|
| 1864 | 1974 |  	struct xfs_da_args	*args; | 
|---|
| 1865 | 1975 |  	struct xfs_da_node_entry *btree; | 
|---|
| 1866 | 1976 |  	struct xfs_da3_icnode_hdr nodehdr; | 
|---|
| .. | .. | 
|---|
| 1882 | 1992 |  	ASSERT(path != NULL); | 
|---|
| 1883 | 1993 |  	ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); | 
|---|
| 1884 | 1994 |  	level = (path->active-1) - 1;	/* skip bottom layer in path */ | 
|---|
| 1885 |  | -	for (blk = &path->blk[level]; level >= 0; blk--, level--) {  | 
|---|
| 1886 |  | -		node = blk->bp->b_addr;  | 
|---|
| 1887 |  | -		dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
| 1888 |  | -		btree = dp->d_ops->node_tree_p(node);  | 
|---|
 | 1995 | +	for (; level >= 0; level--) {  | 
|---|
 | 1996 | +		blk = &path->blk[level];  | 
|---|
 | 1997 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,  | 
|---|
 | 1998 | +					   blk->bp->b_addr);  | 
|---|
| 1889 | 1999 |   | 
|---|
| 1890 | 2000 |  		if (forward && (blk->index < nodehdr.count - 1)) { | 
|---|
| 1891 | 2001 |  			blk->index++; | 
|---|
| 1892 |  | -			blkno = be32_to_cpu(btree[blk->index].before);  | 
|---|
 | 2002 | +			blkno = be32_to_cpu(nodehdr.btree[blk->index].before);  | 
|---|
| 1893 | 2003 |  			break; | 
|---|
| 1894 | 2004 |  		} else if (!forward && (blk->index > 0)) { | 
|---|
| 1895 | 2005 |  			blk->index--; | 
|---|
| 1896 |  | -			blkno = be32_to_cpu(btree[blk->index].before);  | 
|---|
 | 2006 | +			blkno = be32_to_cpu(nodehdr.btree[blk->index].before);  | 
|---|
| 1897 | 2007 |  			break; | 
|---|
| 1898 | 2008 |  		} | 
|---|
| 1899 | 2009 |  	} | 
|---|
| .. | .. | 
|---|
| 1911 | 2021 |  		/* | 
|---|
| 1912 | 2022 |  		 * Read the next child block into a local buffer. | 
|---|
| 1913 | 2023 |  		 */ | 
|---|
| 1914 |  | -		error = xfs_da3_node_read(args->trans, dp, blkno, -1, &bp,  | 
|---|
 | 2024 | +		error = xfs_da3_node_read(args->trans, dp, blkno, &bp,  | 
|---|
| 1915 | 2025 |  					  args->whichfork); | 
|---|
| 1916 | 2026 |  		if (error) | 
|---|
| 1917 | 2027 |  			return error; | 
|---|
| .. | .. | 
|---|
| 1944 | 2054 |  		case XFS_DA_NODE_MAGIC: | 
|---|
| 1945 | 2055 |  		case XFS_DA3_NODE_MAGIC: | 
|---|
| 1946 | 2056 |  			blk->magic = XFS_DA_NODE_MAGIC; | 
|---|
| 1947 |  | -			node = (xfs_da_intnode_t *)info;  | 
|---|
| 1948 |  | -			dp->d_ops->node_hdr_from_disk(&nodehdr, node);  | 
|---|
| 1949 |  | -			btree = dp->d_ops->node_tree_p(node);  | 
|---|
 | 2057 | +			xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr,  | 
|---|
 | 2058 | +						   bp->b_addr);  | 
|---|
 | 2059 | +			btree = nodehdr.btree;  | 
|---|
| 1950 | 2060 |  			blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval); | 
|---|
| 1951 | 2061 |  			if (forward) | 
|---|
| 1952 | 2062 |  				blk->index = 0; | 
|---|
| .. | .. | 
|---|
| 2026 | 2136 |  					XFS_CMP_EXACT : XFS_CMP_DIFFERENT; | 
|---|
| 2027 | 2137 |  } | 
|---|
| 2028 | 2138 |   | 
|---|
| 2029 |  | -static xfs_dahash_t  | 
|---|
| 2030 |  | -xfs_default_hashname(  | 
|---|
| 2031 |  | -	struct xfs_name	*name)  | 
|---|
| 2032 |  | -{  | 
|---|
| 2033 |  | -	return xfs_da_hashname(name->name, name->len);  | 
|---|
| 2034 |  | -}  | 
|---|
| 2035 |  | -  | 
|---|
| 2036 |  | -const struct xfs_nameops xfs_default_nameops = {  | 
|---|
| 2037 |  | -	.hashname	= xfs_default_hashname,  | 
|---|
| 2038 |  | -	.compname	= xfs_da_compname  | 
|---|
| 2039 |  | -};  | 
|---|
| 2040 |  | -  | 
|---|
| 2041 | 2139 |  int | 
|---|
| 2042 | 2140 |  xfs_da_grow_inode_int( | 
|---|
| 2043 | 2141 |  	struct xfs_da_args	*args, | 
|---|
| .. | .. | 
|---|
| 2080 | 2178 |  		 * If we didn't get it and the block might work if fragmented, | 
|---|
| 2081 | 2179 |  		 * try without the CONTIG flag.  Loop until we get it all. | 
|---|
| 2082 | 2180 |  		 */ | 
|---|
| 2083 |  | -		mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP);  | 
|---|
 | 2181 | +		mapp = kmem_alloc(sizeof(*mapp) * count, 0);  | 
|---|
| 2084 | 2182 |  		for (b = *bno, mapi = 0; b < *bno + count; ) { | 
|---|
| 2085 | 2183 |  			nmap = min(XFS_BMAP_MAX_NMAP, count); | 
|---|
| 2086 | 2184 |  			c = (int)(*bno + count - b); | 
|---|
| .. | .. | 
|---|
| 2195 | 2293 |  	error = xfs_bmap_last_before(tp, dp, &lastoff, w); | 
|---|
| 2196 | 2294 |  	if (error) | 
|---|
| 2197 | 2295 |  		return error; | 
|---|
| 2198 |  | -	if (unlikely(lastoff == 0)) {  | 
|---|
| 2199 |  | -		XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW,  | 
|---|
| 2200 |  | -				 mp);  | 
|---|
 | 2296 | +	if (XFS_IS_CORRUPT(mp, lastoff == 0))  | 
|---|
| 2201 | 2297 |  		return -EFSCORRUPTED; | 
|---|
| 2202 |  | -	}  | 
|---|
| 2203 | 2298 |  	/* | 
|---|
| 2204 | 2299 |  	 * Read the last block in the btree space. | 
|---|
| 2205 | 2300 |  	 */ | 
|---|
| 2206 | 2301 |  	last_blkno = (xfs_dablk_t)lastoff - args->geo->fsbcount; | 
|---|
| 2207 |  | -	error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w);  | 
|---|
 | 2302 | +	error = xfs_da3_node_read(tp, dp, last_blkno, &last_buf, w);  | 
|---|
| 2208 | 2303 |  	if (error) | 
|---|
| 2209 | 2304 |  		return error; | 
|---|
| 2210 | 2305 |  	/* | 
|---|
| .. | .. | 
|---|
| 2222 | 2317 |  		struct xfs_dir2_leaf_entry *ents; | 
|---|
| 2223 | 2318 |   | 
|---|
| 2224 | 2319 |  		dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; | 
|---|
| 2225 |  | -		dp->d_ops->leaf_hdr_from_disk(&leafhdr, dead_leaf2);  | 
|---|
| 2226 |  | -		ents = dp->d_ops->leaf_ents_p(dead_leaf2);  | 
|---|
 | 2320 | +		xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr,  | 
|---|
 | 2321 | +					    dead_leaf2);  | 
|---|
 | 2322 | +		ents = leafhdr.ents;  | 
|---|
| 2227 | 2323 |  		dead_level = 0; | 
|---|
| 2228 | 2324 |  		dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval); | 
|---|
| 2229 | 2325 |  	} else { | 
|---|
| 2230 | 2326 |  		struct xfs_da3_icnode_hdr deadhdr; | 
|---|
| 2231 | 2327 |   | 
|---|
| 2232 | 2328 |  		dead_node = (xfs_da_intnode_t *)dead_info; | 
|---|
| 2233 |  | -		dp->d_ops->node_hdr_from_disk(&deadhdr, dead_node);  | 
|---|
| 2234 |  | -		btree = dp->d_ops->node_tree_p(dead_node);  | 
|---|
 | 2329 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &deadhdr, dead_node);  | 
|---|
 | 2330 | +		btree = deadhdr.btree;  | 
|---|
| 2235 | 2331 |  		dead_level = deadhdr.level; | 
|---|
| 2236 | 2332 |  		dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval); | 
|---|
| 2237 | 2333 |  	} | 
|---|
| .. | .. | 
|---|
| 2240 | 2336 |  	 * If the moved block has a left sibling, fix up the pointers. | 
|---|
| 2241 | 2337 |  	 */ | 
|---|
| 2242 | 2338 |  	if ((sib_blkno = be32_to_cpu(dead_info->back))) { | 
|---|
| 2243 |  | -		error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w);  | 
|---|
 | 2339 | +		error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w);  | 
|---|
| 2244 | 2340 |  		if (error) | 
|---|
| 2245 | 2341 |  			goto done; | 
|---|
| 2246 | 2342 |  		sib_info = sib_buf->b_addr; | 
|---|
| 2247 |  | -		if (unlikely(  | 
|---|
| 2248 |  | -		    be32_to_cpu(sib_info->forw) != last_blkno ||  | 
|---|
| 2249 |  | -		    sib_info->magic != dead_info->magic)) {  | 
|---|
| 2250 |  | -			XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)",  | 
|---|
| 2251 |  | -					 XFS_ERRLEVEL_LOW, mp);  | 
|---|
 | 2343 | +		if (XFS_IS_CORRUPT(mp,  | 
|---|
 | 2344 | +				   be32_to_cpu(sib_info->forw) != last_blkno ||  | 
|---|
 | 2345 | +				   sib_info->magic != dead_info->magic)) {  | 
|---|
| 2252 | 2346 |  			error = -EFSCORRUPTED; | 
|---|
| 2253 | 2347 |  			goto done; | 
|---|
| 2254 | 2348 |  		} | 
|---|
| .. | .. | 
|---|
| 2262 | 2356 |  	 * If the moved block has a right sibling, fix up the pointers. | 
|---|
| 2263 | 2357 |  	 */ | 
|---|
| 2264 | 2358 |  	if ((sib_blkno = be32_to_cpu(dead_info->forw))) { | 
|---|
| 2265 |  | -		error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w);  | 
|---|
 | 2359 | +		error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w);  | 
|---|
| 2266 | 2360 |  		if (error) | 
|---|
| 2267 | 2361 |  			goto done; | 
|---|
| 2268 | 2362 |  		sib_info = sib_buf->b_addr; | 
|---|
| 2269 |  | -		if (unlikely(  | 
|---|
| 2270 |  | -		       be32_to_cpu(sib_info->back) != last_blkno ||  | 
|---|
| 2271 |  | -		       sib_info->magic != dead_info->magic)) {  | 
|---|
| 2272 |  | -			XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)",  | 
|---|
| 2273 |  | -					 XFS_ERRLEVEL_LOW, mp);  | 
|---|
 | 2363 | +		if (XFS_IS_CORRUPT(mp,  | 
|---|
 | 2364 | +				   be32_to_cpu(sib_info->back) != last_blkno ||  | 
|---|
 | 2365 | +				   sib_info->magic != dead_info->magic)) {  | 
|---|
| 2274 | 2366 |  			error = -EFSCORRUPTED; | 
|---|
| 2275 | 2367 |  			goto done; | 
|---|
| 2276 | 2368 |  		} | 
|---|
| .. | .. | 
|---|
| 2286 | 2378 |  	 * Walk down the tree looking for the parent of the moved block. | 
|---|
| 2287 | 2379 |  	 */ | 
|---|
| 2288 | 2380 |  	for (;;) { | 
|---|
| 2289 |  | -		error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w);  | 
|---|
 | 2381 | +		error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w);  | 
|---|
| 2290 | 2382 |  		if (error) | 
|---|
| 2291 | 2383 |  			goto done; | 
|---|
| 2292 | 2384 |  		par_node = par_buf->b_addr; | 
|---|
| 2293 |  | -		dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);  | 
|---|
| 2294 |  | -		if (level >= 0 && level != par_hdr.level + 1) {  | 
|---|
| 2295 |  | -			XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",  | 
|---|
| 2296 |  | -					 XFS_ERRLEVEL_LOW, mp);  | 
|---|
 | 2385 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);  | 
|---|
 | 2386 | +		if (XFS_IS_CORRUPT(mp,  | 
|---|
 | 2387 | +				   level >= 0 && level != par_hdr.level + 1)) {  | 
|---|
| 2297 | 2388 |  			error = -EFSCORRUPTED; | 
|---|
| 2298 | 2389 |  			goto done; | 
|---|
| 2299 | 2390 |  		} | 
|---|
| 2300 | 2391 |  		level = par_hdr.level; | 
|---|
| 2301 |  | -		btree = dp->d_ops->node_tree_p(par_node);  | 
|---|
 | 2392 | +		btree = par_hdr.btree;  | 
|---|
| 2302 | 2393 |  		for (entno = 0; | 
|---|
| 2303 | 2394 |  		     entno < par_hdr.count && | 
|---|
| 2304 | 2395 |  		     be32_to_cpu(btree[entno].hashval) < dead_hash; | 
|---|
| 2305 | 2396 |  		     entno++) | 
|---|
| 2306 | 2397 |  			continue; | 
|---|
| 2307 |  | -		if (entno == par_hdr.count) {  | 
|---|
| 2308 |  | -			XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)",  | 
|---|
| 2309 |  | -					 XFS_ERRLEVEL_LOW, mp);  | 
|---|
 | 2398 | +		if (XFS_IS_CORRUPT(mp, entno == par_hdr.count)) {  | 
|---|
| 2310 | 2399 |  			error = -EFSCORRUPTED; | 
|---|
| 2311 | 2400 |  			goto done; | 
|---|
| 2312 | 2401 |  		} | 
|---|
| .. | .. | 
|---|
| 2331 | 2420 |  		par_blkno = par_hdr.forw; | 
|---|
| 2332 | 2421 |  		xfs_trans_brelse(tp, par_buf); | 
|---|
| 2333 | 2422 |  		par_buf = NULL; | 
|---|
| 2334 |  | -		if (unlikely(par_blkno == 0)) {  | 
|---|
| 2335 |  | -			XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)",  | 
|---|
| 2336 |  | -					 XFS_ERRLEVEL_LOW, mp);  | 
|---|
 | 2423 | +		if (XFS_IS_CORRUPT(mp, par_blkno == 0)) {  | 
|---|
| 2337 | 2424 |  			error = -EFSCORRUPTED; | 
|---|
| 2338 | 2425 |  			goto done; | 
|---|
| 2339 | 2426 |  		} | 
|---|
| 2340 |  | -		error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w);  | 
|---|
 | 2427 | +		error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w);  | 
|---|
| 2341 | 2428 |  		if (error) | 
|---|
| 2342 | 2429 |  			goto done; | 
|---|
| 2343 | 2430 |  		par_node = par_buf->b_addr; | 
|---|
| 2344 |  | -		dp->d_ops->node_hdr_from_disk(&par_hdr, par_node);  | 
|---|
| 2345 |  | -		if (par_hdr.level != level) {  | 
|---|
| 2346 |  | -			XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",  | 
|---|
| 2347 |  | -					 XFS_ERRLEVEL_LOW, mp);  | 
|---|
 | 2431 | +		xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);  | 
|---|
 | 2432 | +		if (XFS_IS_CORRUPT(mp, par_hdr.level != level)) {  | 
|---|
| 2348 | 2433 |  			error = -EFSCORRUPTED; | 
|---|
| 2349 | 2434 |  			goto done; | 
|---|
| 2350 | 2435 |  		} | 
|---|
| 2351 |  | -		btree = dp->d_ops->node_tree_p(par_node);  | 
|---|
 | 2436 | +		btree = par_hdr.btree;  | 
|---|
| 2352 | 2437 |  		entno = 0; | 
|---|
| 2353 | 2438 |  	} | 
|---|
| 2354 | 2439 |  	/* | 
|---|
| .. | .. | 
|---|
| 2411 | 2496 |  	return error; | 
|---|
| 2412 | 2497 |  } | 
|---|
| 2413 | 2498 |   | 
|---|
| 2414 |  | -/*  | 
|---|
| 2415 |  | - * See if the mapping(s) for this btree block are valid, i.e.  | 
|---|
| 2416 |  | - * don't contain holes, are logically contiguous, and cover the whole range.  | 
|---|
| 2417 |  | - */  | 
|---|
| 2418 |  | -STATIC int  | 
|---|
| 2419 |  | -xfs_da_map_covers_blocks(  | 
|---|
| 2420 |  | -	int		nmap,  | 
|---|
| 2421 |  | -	xfs_bmbt_irec_t	*mapp,  | 
|---|
| 2422 |  | -	xfs_dablk_t	bno,  | 
|---|
| 2423 |  | -	int		count)  | 
|---|
| 2424 |  | -{  | 
|---|
| 2425 |  | -	int		i;  | 
|---|
| 2426 |  | -	xfs_fileoff_t	off;  | 
|---|
| 2427 |  | -  | 
|---|
| 2428 |  | -	for (i = 0, off = bno; i < nmap; i++) {  | 
|---|
| 2429 |  | -		if (mapp[i].br_startblock == HOLESTARTBLOCK ||  | 
|---|
| 2430 |  | -		    mapp[i].br_startblock == DELAYSTARTBLOCK) {  | 
|---|
| 2431 |  | -			return 0;  | 
|---|
| 2432 |  | -		}  | 
|---|
| 2433 |  | -		if (off != mapp[i].br_startoff) {  | 
|---|
| 2434 |  | -			return 0;  | 
|---|
| 2435 |  | -		}  | 
|---|
| 2436 |  | -		off += mapp[i].br_blockcount;  | 
|---|
| 2437 |  | -	}  | 
|---|
| 2438 |  | -	return off == bno + count;  | 
|---|
| 2439 |  | -}  | 
|---|
| 2440 |  | -  | 
|---|
| 2441 |  | -/*  | 
|---|
| 2442 |  | - * Convert a struct xfs_bmbt_irec to a struct xfs_buf_map.  | 
|---|
| 2443 |  | - *  | 
|---|
| 2444 |  | - * For the single map case, it is assumed that the caller has provided a pointer  | 
|---|
| 2445 |  | - * to a valid xfs_buf_map.  For the multiple map case, this function will  | 
|---|
| 2446 |  | - * allocate the xfs_buf_map to hold all the maps and replace the caller's single  | 
|---|
| 2447 |  | - * map pointer with the allocated map.  | 
|---|
| 2448 |  | - */  | 
|---|
| 2449 |  | -static int  | 
|---|
| 2450 |  | -xfs_buf_map_from_irec(  | 
|---|
| 2451 |  | -	struct xfs_mount	*mp,  | 
|---|
| 2452 |  | -	struct xfs_buf_map	**mapp,  | 
|---|
| 2453 |  | -	int			*nmaps,  | 
|---|
| 2454 |  | -	struct xfs_bmbt_irec	*irecs,  | 
|---|
| 2455 |  | -	int			nirecs)  | 
|---|
| 2456 |  | -{  | 
|---|
| 2457 |  | -	struct xfs_buf_map	*map;  | 
|---|
| 2458 |  | -	int			i;  | 
|---|
| 2459 |  | -  | 
|---|
| 2460 |  | -	ASSERT(*nmaps == 1);  | 
|---|
| 2461 |  | -	ASSERT(nirecs >= 1);  | 
|---|
| 2462 |  | -  | 
|---|
| 2463 |  | -	if (nirecs > 1) {  | 
|---|
| 2464 |  | -		map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map),  | 
|---|
| 2465 |  | -				  KM_SLEEP | KM_NOFS);  | 
|---|
| 2466 |  | -		if (!map)  | 
|---|
| 2467 |  | -			return -ENOMEM;  | 
|---|
| 2468 |  | -		*mapp = map;  | 
|---|
| 2469 |  | -	}  | 
|---|
| 2470 |  | -  | 
|---|
| 2471 |  | -	*nmaps = nirecs;  | 
|---|
| 2472 |  | -	map = *mapp;  | 
|---|
| 2473 |  | -	for (i = 0; i < *nmaps; i++) {  | 
|---|
| 2474 |  | -		ASSERT(irecs[i].br_startblock != DELAYSTARTBLOCK &&  | 
|---|
| 2475 |  | -		       irecs[i].br_startblock != HOLESTARTBLOCK);  | 
|---|
| 2476 |  | -		map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock);  | 
|---|
| 2477 |  | -		map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount);  | 
|---|
| 2478 |  | -	}  | 
|---|
| 2479 |  | -	return 0;  | 
|---|
| 2480 |  | -}  | 
|---|
| 2481 |  | -  | 
|---|
| 2482 |  | -/*  | 
|---|
| 2483 |  | - * Map the block we are given ready for reading. There are three possible return  | 
|---|
| 2484 |  | - * values:  | 
|---|
| 2485 |  | - *	-1 - will be returned if we land in a hole and mappedbno == -2 so the  | 
|---|
| 2486 |  | - *	     caller knows not to execute a subsequent read.  | 
|---|
| 2487 |  | - *	 0 - if we mapped the block successfully  | 
|---|
| 2488 |  | - *	>0 - positive error number if there was an error.  | 
|---|
| 2489 |  | - */  | 
|---|
| 2490 | 2499 |  static int | 
|---|
| 2491 | 2500 |  xfs_dabuf_map( | 
|---|
| 2492 | 2501 |  	struct xfs_inode	*dp, | 
|---|
| 2493 | 2502 |  	xfs_dablk_t		bno, | 
|---|
| 2494 |  | -	xfs_daddr_t		mappedbno,  | 
|---|
 | 2503 | +	unsigned int		flags,  | 
|---|
| 2495 | 2504 |  	int			whichfork, | 
|---|
| 2496 |  | -	struct xfs_buf_map	**map,  | 
|---|
 | 2505 | +	struct xfs_buf_map	**mapp,  | 
|---|
| 2497 | 2506 |  	int			*nmaps) | 
|---|
| 2498 | 2507 |  { | 
|---|
| 2499 | 2508 |  	struct xfs_mount	*mp = dp->i_mount; | 
|---|
| 2500 |  | -	int			nfsb;  | 
|---|
| 2501 |  | -	int			error = 0;  | 
|---|
| 2502 |  | -	struct xfs_bmbt_irec	irec;  | 
|---|
| 2503 |  | -	struct xfs_bmbt_irec	*irecs = &irec;  | 
|---|
| 2504 |  | -	int			nirecs;  | 
|---|
 | 2509 | +	int			nfsb = xfs_dabuf_nfsb(mp, whichfork);  | 
|---|
 | 2510 | +	struct xfs_bmbt_irec	irec, *irecs = &irec;  | 
|---|
 | 2511 | +	struct xfs_buf_map	*map = *mapp;  | 
|---|
 | 2512 | +	xfs_fileoff_t		off = bno;  | 
|---|
 | 2513 | +	int			error = 0, nirecs, i;  | 
|---|
| 2505 | 2514 |   | 
|---|
| 2506 |  | -	ASSERT(map && *map);  | 
|---|
| 2507 |  | -	ASSERT(*nmaps == 1);  | 
|---|
 | 2515 | +	if (nfsb > 1)  | 
|---|
 | 2516 | +		irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_NOFS);  | 
|---|
| 2508 | 2517 |   | 
|---|
| 2509 |  | -	if (whichfork == XFS_DATA_FORK)  | 
|---|
| 2510 |  | -		nfsb = mp->m_dir_geo->fsbcount;  | 
|---|
| 2511 |  | -	else  | 
|---|
| 2512 |  | -		nfsb = mp->m_attr_geo->fsbcount;  | 
|---|
 | 2518 | +	nirecs = nfsb;  | 
|---|
 | 2519 | +	error = xfs_bmapi_read(dp, bno, nfsb, irecs, &nirecs,  | 
|---|
 | 2520 | +			xfs_bmapi_aflag(whichfork));  | 
|---|
 | 2521 | +	if (error)  | 
|---|
 | 2522 | +		goto out_free_irecs;  | 
|---|
| 2513 | 2523 |   | 
|---|
| 2514 | 2524 |  	/* | 
|---|
| 2515 |  | -	 * Caller doesn't have a mapping.  -2 means don't complain  | 
|---|
| 2516 |  | -	 * if we land in a hole.  | 
|---|
 | 2525 | +	 * Use the caller provided map for the single map case, else allocate a  | 
|---|
 | 2526 | +	 * larger one that needs to be free by the caller.  | 
|---|
| 2517 | 2527 |  	 */ | 
|---|
| 2518 |  | -	if (mappedbno == -1 || mappedbno == -2) {  | 
|---|
| 2519 |  | -		/*  | 
|---|
| 2520 |  | -		 * Optimize the one-block case.  | 
|---|
| 2521 |  | -		 */  | 
|---|
| 2522 |  | -		if (nfsb != 1)  | 
|---|
| 2523 |  | -			irecs = kmem_zalloc(sizeof(irec) * nfsb,  | 
|---|
| 2524 |  | -					    KM_SLEEP | KM_NOFS);  | 
|---|
| 2525 |  | -  | 
|---|
| 2526 |  | -		nirecs = nfsb;  | 
|---|
| 2527 |  | -		error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs,  | 
|---|
| 2528 |  | -				       &nirecs, xfs_bmapi_aflag(whichfork));  | 
|---|
| 2529 |  | -		if (error)  | 
|---|
| 2530 |  | -			goto out;  | 
|---|
| 2531 |  | -	} else {  | 
|---|
| 2532 |  | -		irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno);  | 
|---|
| 2533 |  | -		irecs->br_startoff = (xfs_fileoff_t)bno;  | 
|---|
| 2534 |  | -		irecs->br_blockcount = nfsb;  | 
|---|
| 2535 |  | -		irecs->br_state = 0;  | 
|---|
| 2536 |  | -		nirecs = 1;  | 
|---|
| 2537 |  | -	}  | 
|---|
| 2538 |  | -  | 
|---|
| 2539 |  | -	if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) {  | 
|---|
| 2540 |  | -		error = mappedbno == -2 ? -1 : -EFSCORRUPTED;  | 
|---|
| 2541 |  | -		if (unlikely(error == -EFSCORRUPTED)) {  | 
|---|
| 2542 |  | -			if (xfs_error_level >= XFS_ERRLEVEL_LOW) {  | 
|---|
| 2543 |  | -				int i;  | 
|---|
| 2544 |  | -				xfs_alert(mp, "%s: bno %lld dir: inode %lld",  | 
|---|
| 2545 |  | -					__func__, (long long)bno,  | 
|---|
| 2546 |  | -					(long long)dp->i_ino);  | 
|---|
| 2547 |  | -				for (i = 0; i < *nmaps; i++) {  | 
|---|
| 2548 |  | -					xfs_alert(mp,  | 
|---|
| 2549 |  | -"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d",  | 
|---|
| 2550 |  | -						i,  | 
|---|
| 2551 |  | -						(long long)irecs[i].br_startoff,  | 
|---|
| 2552 |  | -						(long long)irecs[i].br_startblock,  | 
|---|
| 2553 |  | -						(long long)irecs[i].br_blockcount,  | 
|---|
| 2554 |  | -						irecs[i].br_state);  | 
|---|
| 2555 |  | -				}  | 
|---|
| 2556 |  | -			}  | 
|---|
| 2557 |  | -			XFS_ERROR_REPORT("xfs_da_do_buf(1)",  | 
|---|
| 2558 |  | -					 XFS_ERRLEVEL_LOW, mp);  | 
|---|
 | 2528 | +	if (nirecs > 1) {  | 
|---|
 | 2529 | +		map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_NOFS);  | 
|---|
 | 2530 | +		if (!map) {  | 
|---|
 | 2531 | +			error = -ENOMEM;  | 
|---|
 | 2532 | +			goto out_free_irecs;  | 
|---|
| 2559 | 2533 |  		} | 
|---|
| 2560 |  | -		goto out;  | 
|---|
 | 2534 | +		*mapp = map;  | 
|---|
| 2561 | 2535 |  	} | 
|---|
| 2562 |  | -	error = xfs_buf_map_from_irec(mp, map, nmaps, irecs, nirecs);  | 
|---|
| 2563 |  | -out:  | 
|---|
 | 2536 | +  | 
|---|
 | 2537 | +	for (i = 0; i < nirecs; i++) {  | 
|---|
 | 2538 | +		if (irecs[i].br_startblock == HOLESTARTBLOCK ||  | 
|---|
 | 2539 | +		    irecs[i].br_startblock == DELAYSTARTBLOCK)  | 
|---|
 | 2540 | +			goto invalid_mapping;  | 
|---|
 | 2541 | +		if (off != irecs[i].br_startoff)  | 
|---|
 | 2542 | +			goto invalid_mapping;  | 
|---|
 | 2543 | +  | 
|---|
 | 2544 | +		map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock);  | 
|---|
 | 2545 | +		map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount);  | 
|---|
 | 2546 | +		off += irecs[i].br_blockcount;  | 
|---|
 | 2547 | +	}  | 
|---|
 | 2548 | +  | 
|---|
 | 2549 | +	if (off != bno + nfsb)  | 
|---|
 | 2550 | +		goto invalid_mapping;  | 
|---|
 | 2551 | +  | 
|---|
 | 2552 | +	*nmaps = nirecs;  | 
|---|
 | 2553 | +out_free_irecs:  | 
|---|
| 2564 | 2554 |  	if (irecs != &irec) | 
|---|
| 2565 | 2555 |  		kmem_free(irecs); | 
|---|
| 2566 | 2556 |  	return error; | 
|---|
 | 2557 | +  | 
|---|
 | 2558 | +invalid_mapping:  | 
|---|
 | 2559 | +	/* Caller ok with no mapping. */  | 
|---|
 | 2560 | +	if (XFS_IS_CORRUPT(mp, !(flags & XFS_DABUF_MAP_HOLE_OK))) {  | 
|---|
 | 2561 | +		error = -EFSCORRUPTED;  | 
|---|
 | 2562 | +		if (xfs_error_level >= XFS_ERRLEVEL_LOW) {  | 
|---|
 | 2563 | +			xfs_alert(mp, "%s: bno %u inode %llu",  | 
|---|
 | 2564 | +					__func__, bno, dp->i_ino);  | 
|---|
 | 2565 | +  | 
|---|
 | 2566 | +			for (i = 0; i < nirecs; i++) {  | 
|---|
 | 2567 | +				xfs_alert(mp,  | 
|---|
 | 2568 | +"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d",  | 
|---|
 | 2569 | +					i, irecs[i].br_startoff,  | 
|---|
 | 2570 | +					irecs[i].br_startblock,  | 
|---|
 | 2571 | +					irecs[i].br_blockcount,  | 
|---|
 | 2572 | +					irecs[i].br_state);  | 
|---|
 | 2573 | +			}  | 
|---|
 | 2574 | +		}  | 
|---|
 | 2575 | +	} else {  | 
|---|
 | 2576 | +		*nmaps = 0;  | 
|---|
 | 2577 | +	}  | 
|---|
 | 2578 | +	goto out_free_irecs;  | 
|---|
| 2567 | 2579 |  } | 
|---|
| 2568 | 2580 |   | 
|---|
| 2569 | 2581 |  /* | 
|---|
| .. | .. | 
|---|
| 2571 | 2583 |   */ | 
|---|
| 2572 | 2584 |  int | 
|---|
| 2573 | 2585 |  xfs_da_get_buf( | 
|---|
| 2574 |  | -	struct xfs_trans	*trans,  | 
|---|
 | 2586 | +	struct xfs_trans	*tp,  | 
|---|
| 2575 | 2587 |  	struct xfs_inode	*dp, | 
|---|
| 2576 | 2588 |  	xfs_dablk_t		bno, | 
|---|
| 2577 |  | -	xfs_daddr_t		mappedbno,  | 
|---|
| 2578 | 2589 |  	struct xfs_buf		**bpp, | 
|---|
| 2579 | 2590 |  	int			whichfork) | 
|---|
| 2580 | 2591 |  { | 
|---|
 | 2592 | +	struct xfs_mount	*mp = dp->i_mount;  | 
|---|
| 2581 | 2593 |  	struct xfs_buf		*bp; | 
|---|
| 2582 |  | -	struct xfs_buf_map	map;  | 
|---|
| 2583 |  | -	struct xfs_buf_map	*mapp;  | 
|---|
| 2584 |  | -	int			nmap;  | 
|---|
 | 2594 | +	struct xfs_buf_map	map, *mapp = ↦  | 
|---|
 | 2595 | +	int			nmap = 1;  | 
|---|
| 2585 | 2596 |  	int			error; | 
|---|
| 2586 | 2597 |   | 
|---|
| 2587 | 2598 |  	*bpp = NULL; | 
|---|
| 2588 |  | -	mapp = ↦  | 
|---|
| 2589 |  | -	nmap = 1;  | 
|---|
| 2590 |  | -	error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,  | 
|---|
| 2591 |  | -				&mapp, &nmap);  | 
|---|
| 2592 |  | -	if (error) {  | 
|---|
| 2593 |  | -		/* mapping a hole is not an error, but we don't continue */  | 
|---|
| 2594 |  | -		if (error == -1)  | 
|---|
| 2595 |  | -			error = 0;  | 
|---|
 | 2599 | +	error = xfs_dabuf_map(dp, bno, 0, whichfork, &mapp, &nmap);  | 
|---|
 | 2600 | +	if (error || nmap == 0)  | 
|---|
| 2596 | 2601 |  		goto out_free; | 
|---|
| 2597 |  | -	}  | 
|---|
| 2598 | 2602 |   | 
|---|
| 2599 |  | -	bp = xfs_trans_get_buf_map(trans, dp->i_mount->m_ddev_targp,  | 
|---|
| 2600 |  | -				    mapp, nmap, 0);  | 
|---|
| 2601 |  | -	error = bp ? bp->b_error : -EIO;  | 
|---|
| 2602 |  | -	if (error) {  | 
|---|
| 2603 |  | -		if (bp)  | 
|---|
| 2604 |  | -			xfs_trans_brelse(trans, bp);  | 
|---|
 | 2603 | +	error = xfs_trans_get_buf_map(tp, mp->m_ddev_targp, mapp, nmap, 0, &bp);  | 
|---|
 | 2604 | +	if (error)  | 
|---|
| 2605 | 2605 |  		goto out_free; | 
|---|
| 2606 |  | -	}  | 
|---|
| 2607 | 2606 |   | 
|---|
| 2608 | 2607 |  	*bpp = bp; | 
|---|
| 2609 | 2608 |   | 
|---|
| .. | .. | 
|---|
| 2619 | 2618 |   */ | 
|---|
| 2620 | 2619 |  int | 
|---|
| 2621 | 2620 |  xfs_da_read_buf( | 
|---|
| 2622 |  | -	struct xfs_trans	*trans,  | 
|---|
 | 2621 | +	struct xfs_trans	*tp,  | 
|---|
| 2623 | 2622 |  	struct xfs_inode	*dp, | 
|---|
| 2624 | 2623 |  	xfs_dablk_t		bno, | 
|---|
| 2625 |  | -	xfs_daddr_t		mappedbno,  | 
|---|
 | 2624 | +	unsigned int		flags,  | 
|---|
| 2626 | 2625 |  	struct xfs_buf		**bpp, | 
|---|
| 2627 | 2626 |  	int			whichfork, | 
|---|
| 2628 | 2627 |  	const struct xfs_buf_ops *ops) | 
|---|
| 2629 | 2628 |  { | 
|---|
 | 2629 | +	struct xfs_mount	*mp = dp->i_mount;  | 
|---|
| 2630 | 2630 |  	struct xfs_buf		*bp; | 
|---|
| 2631 |  | -	struct xfs_buf_map	map;  | 
|---|
| 2632 |  | -	struct xfs_buf_map	*mapp;  | 
|---|
| 2633 |  | -	int			nmap;  | 
|---|
 | 2631 | +	struct xfs_buf_map	map, *mapp = ↦  | 
|---|
 | 2632 | +	int			nmap = 1;  | 
|---|
| 2634 | 2633 |  	int			error; | 
|---|
| 2635 | 2634 |   | 
|---|
| 2636 | 2635 |  	*bpp = NULL; | 
|---|
| 2637 |  | -	mapp = ↦  | 
|---|
| 2638 |  | -	nmap = 1;  | 
|---|
| 2639 |  | -	error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,  | 
|---|
| 2640 |  | -				&mapp, &nmap);  | 
|---|
| 2641 |  | -	if (error) {  | 
|---|
| 2642 |  | -		/* mapping a hole is not an error, but we don't continue */  | 
|---|
| 2643 |  | -		if (error == -1)  | 
|---|
| 2644 |  | -			error = 0;  | 
|---|
 | 2636 | +	error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap);  | 
|---|
 | 2637 | +	if (error || !nmap)  | 
|---|
| 2645 | 2638 |  		goto out_free; | 
|---|
| 2646 |  | -	}  | 
|---|
| 2647 | 2639 |   | 
|---|
| 2648 |  | -	error = xfs_trans_read_buf_map(dp->i_mount, trans,  | 
|---|
| 2649 |  | -					dp->i_mount->m_ddev_targp,  | 
|---|
| 2650 |  | -					mapp, nmap, 0, &bp, ops);  | 
|---|
 | 2640 | +	error = xfs_trans_read_buf_map(mp, tp, mp->m_ddev_targp, mapp, nmap, 0,  | 
|---|
 | 2641 | +			&bp, ops);  | 
|---|
| 2651 | 2642 |  	if (error) | 
|---|
| 2652 | 2643 |  		goto out_free; | 
|---|
| 2653 | 2644 |   | 
|---|
| .. | .. | 
|---|
| 2670 | 2661 |  xfs_da_reada_buf( | 
|---|
| 2671 | 2662 |  	struct xfs_inode	*dp, | 
|---|
| 2672 | 2663 |  	xfs_dablk_t		bno, | 
|---|
| 2673 |  | -	xfs_daddr_t		mappedbno,  | 
|---|
 | 2664 | +	unsigned int		flags,  | 
|---|
| 2674 | 2665 |  	int			whichfork, | 
|---|
| 2675 | 2666 |  	const struct xfs_buf_ops *ops) | 
|---|
| 2676 | 2667 |  { | 
|---|
| .. | .. | 
|---|
| 2681 | 2672 |   | 
|---|
| 2682 | 2673 |  	mapp = ↦ | 
|---|
| 2683 | 2674 |  	nmap = 1; | 
|---|
| 2684 |  | -	error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,  | 
|---|
| 2685 |  | -				&mapp, &nmap);  | 
|---|
| 2686 |  | -	if (error) {  | 
|---|
| 2687 |  | -		/* mapping a hole is not an error, but we don't continue */  | 
|---|
| 2688 |  | -		if (error == -1)  | 
|---|
| 2689 |  | -			error = 0;  | 
|---|
 | 2675 | +	error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap);  | 
|---|
 | 2676 | +	if (error || !nmap)  | 
|---|
| 2690 | 2677 |  		goto out_free; | 
|---|
| 2691 |  | -	}  | 
|---|
| 2692 | 2678 |   | 
|---|
| 2693 |  | -	mappedbno = mapp[0].bm_bn;  | 
|---|
| 2694 | 2679 |  	xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, ops); | 
|---|
| 2695 | 2680 |   | 
|---|
| 2696 | 2681 |  out_free: | 
|---|