diff options
| -rw-r--r-- | fs/xfs/xfs_dir2_block.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2_data.c | 32 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 38 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2_node.c | 8 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2_priv.h | 2 | 
5 files changed, 56 insertions, 27 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 57351b86886..ca03b109772 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c @@ -970,8 +970,7 @@ xfs_dir2_leaf_to_block(  	 * Read the data block if we don't already have it, give up if it fails.  	 */  	if (!dbp) { -		error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp, -					XFS_DATA_FORK, NULL); +		error = xfs_dir2_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp);  		if (error)  			return error;  	} diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index cb117234e32..0ef04f1bf51 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c @@ -185,6 +185,38 @@ __xfs_dir2_data_check(  	return 0;  } +static void +xfs_dir2_data_verify( +	struct xfs_buf		*bp) +{ +	struct xfs_mount	*mp = bp->b_target->bt_mount; +	struct xfs_dir2_data_hdr *hdr = bp->b_addr; +	int			block_ok = 0; + +	block_ok = hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC); +	block_ok = block_ok && __xfs_dir2_data_check(NULL, bp) == 0; + +	if (!block_ok) { +		XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); +		xfs_buf_ioerror(bp, EFSCORRUPTED); +	} + +	bp->b_iodone = NULL; +	xfs_buf_ioend(bp, 0); +} + +int +xfs_dir2_data_read( +	struct xfs_trans	*tp, +	struct xfs_inode	*dp, +	xfs_dablk_t		bno, +	xfs_daddr_t		mapped_bno, +	struct xfs_buf		**bpp) +{ +	return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, +					XFS_DATA_FORK, xfs_dir2_data_verify); +} +  /*   * Given a data block and an unused entry from that block,   * return the bestfree entry if any that corresponds to it. diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 6c1359dc989..0fdf765c917 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -493,14 +493,14 @@ xfs_dir2_leaf_addname(  		hdr = dbp->b_addr;  		bestsp[use_block] = hdr->bestfree[0].length;  		grown = 1; -	} -	/* -	 * Already had space in some data block. -	 * Just read that one in. -	 */ -	else { -		error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), -					-1, &dbp, XFS_DATA_FORK, NULL); +	} else { +		/* +		 * Already had space in some data block. +		 * Just read that one in. +		 */ +		error = xfs_dir2_data_read(tp, dp, +					   xfs_dir2_db_to_da(mp, use_block), +					   -1, &dbp);  		if (error) {  			xfs_trans_brelse(tp, lbp);  			return error; @@ -508,7 +508,6 @@ xfs_dir2_leaf_addname(  		hdr = dbp->b_addr;  		grown = 0;  	} -	xfs_dir2_data_check(dp, dbp);  	/*  	 * Point to the biggest freespace in our data block.  	 */ @@ -891,10 +890,9 @@ xfs_dir2_leaf_readbuf(  	 * Read the directory block starting at the first mapping.  	 */  	mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); -	error = xfs_da_read_buf(NULL, dp, map->br_startoff, +	error = xfs_dir2_data_read(NULL, dp, map->br_startoff,  			map->br_blockcount >= mp->m_dirblkfsbs ? -			    XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, -			&bp, XFS_DATA_FORK, NULL); +			    XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);  	/*  	 * Should just skip over the data block instead of giving up. @@ -1408,14 +1406,13 @@ xfs_dir2_leaf_lookup_int(  		if (newdb != curdb) {  			if (dbp)  				xfs_trans_brelse(tp, dbp); -			error = xfs_da_read_buf(tp, dp, -						xfs_dir2_db_to_da(mp, newdb), -						-1, &dbp, XFS_DATA_FORK, NULL); +			error = xfs_dir2_data_read(tp, dp, +						   xfs_dir2_db_to_da(mp, newdb), +						   -1, &dbp);  			if (error) {  				xfs_trans_brelse(tp, lbp);  				return error;  			} -			xfs_dir2_data_check(dp, dbp);  			curdb = newdb;  		}  		/* @@ -1450,9 +1447,9 @@ xfs_dir2_leaf_lookup_int(  		ASSERT(cidb != -1);  		if (cidb != curdb) {  			xfs_trans_brelse(tp, dbp); -			error = xfs_da_read_buf(tp, dp, -						xfs_dir2_db_to_da(mp, cidb), -						-1, &dbp, XFS_DATA_FORK, NULL); +			error = xfs_dir2_data_read(tp, dp, +						   xfs_dir2_db_to_da(mp, cidb), +						   -1, &dbp);  			if (error) {  				xfs_trans_brelse(tp, lbp);  				return error; @@ -1737,8 +1734,7 @@ xfs_dir2_leaf_trim_data(  	/*  	 * Read the offending data block.  We need its buffer.  	 */ -	error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp, -				XFS_DATA_FORK, NULL); +	error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp);  	if (error)  		return error; diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index d7f899dfbff..67b811c17ea 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c @@ -583,9 +583,9 @@ xfs_dir2_leafn_lookup_for_entry(  				ASSERT(state->extravalid);  				curbp = state->extrablk.bp;  			} else { -				error = xfs_da_read_buf(tp, dp, +				error = xfs_dir2_data_read(tp, dp,  						xfs_dir2_db_to_da(mp, newdb), -						-1, &curbp, XFS_DATA_FORK, NULL); +						-1, &curbp);  				if (error)  					return error;  			} @@ -1692,8 +1692,8 @@ xfs_dir2_node_addname_int(  		/*  		 * Read the data block in.  		 */ -		error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno), -					-1, &dbp, XFS_DATA_FORK, NULL); +		error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno), +					   -1, &dbp);  		if (error)  			return error;  		hdr = dbp->b_addr; diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h index 263a6328791..71ec8283910 100644 --- a/fs/xfs/xfs_dir2_priv.h +++ b/fs/xfs/xfs_dir2_priv.h @@ -46,6 +46,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,  #define	xfs_dir2_data_check(dp,bp)  #endif  extern int __xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_buf *bp); +extern int xfs_dir2_data_read(struct xfs_trans *tp, struct xfs_inode *dp, +		xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp);  extern struct xfs_dir2_data_free *  xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,  |