Merge branch 'xfs-misc-fixes-for-3.19-2' into for-next
Conflicts: fs/xfs/xfs_iops.c
This commit is contained in:
		
				commit
				
					
						6044e4386c
					
				
			
		
					 24 changed files with 270 additions and 385 deletions
				
			
		| 
						 | 
				
			
			@ -5447,13 +5447,11 @@ xfs_bmse_merge(
 | 
			
		|||
	struct xfs_btree_cur		*cur,
 | 
			
		||||
	int				*logflags)	/* output */
 | 
			
		||||
{
 | 
			
		||||
	struct xfs_ifork		*ifp;
 | 
			
		||||
	struct xfs_bmbt_irec		got;
 | 
			
		||||
	struct xfs_bmbt_irec		left;
 | 
			
		||||
	xfs_filblks_t			blockcount;
 | 
			
		||||
	int				error, i;
 | 
			
		||||
 | 
			
		||||
	ifp = XFS_IFORK_PTR(ip, whichfork);
 | 
			
		||||
	xfs_bmbt_get_all(gotp, &got);
 | 
			
		||||
	xfs_bmbt_get_all(leftp, &left);
 | 
			
		||||
	blockcount = left.br_blockcount + got.br_blockcount;
 | 
			
		||||
| 
						 | 
				
			
			@ -5486,32 +5484,25 @@ xfs_bmse_merge(
 | 
			
		|||
	error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
 | 
			
		||||
				   got.br_blockcount, &i);
 | 
			
		||||
	if (error)
 | 
			
		||||
		goto out_error;
 | 
			
		||||
	XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
 | 
			
		||||
		return error;
 | 
			
		||||
	XFS_WANT_CORRUPTED_RETURN(i == 1);
 | 
			
		||||
 | 
			
		||||
	error = xfs_btree_delete(cur, &i);
 | 
			
		||||
	if (error)
 | 
			
		||||
		goto out_error;
 | 
			
		||||
	XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
 | 
			
		||||
		return error;
 | 
			
		||||
	XFS_WANT_CORRUPTED_RETURN(i == 1);
 | 
			
		||||
 | 
			
		||||
	/* lookup and update size of the previous extent */
 | 
			
		||||
	error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock,
 | 
			
		||||
				   left.br_blockcount, &i);
 | 
			
		||||
	if (error)
 | 
			
		||||
		goto out_error;
 | 
			
		||||
	XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
 | 
			
		||||
		return error;
 | 
			
		||||
	XFS_WANT_CORRUPTED_RETURN(i == 1);
 | 
			
		||||
 | 
			
		||||
	left.br_blockcount = blockcount;
 | 
			
		||||
 | 
			
		||||
	error = xfs_bmbt_update(cur, left.br_startoff, left.br_startblock,
 | 
			
		||||
				left.br_blockcount, left.br_state);
 | 
			
		||||
	if (error)
 | 
			
		||||
		goto out_error;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
out_error:
 | 
			
		||||
	return error;
 | 
			
		||||
	return xfs_bmbt_update(cur, left.br_startoff, left.br_startblock,
 | 
			
		||||
			       left.br_blockcount, left.br_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -5541,35 +5532,29 @@ xfs_bmse_shift_one(
 | 
			
		|||
	startoff = got.br_startoff - offset_shift_fsb;
 | 
			
		||||
 | 
			
		||||
	/* delalloc extents should be prevented by caller */
 | 
			
		||||
	XFS_WANT_CORRUPTED_GOTO(!isnullstartblock(got.br_startblock),
 | 
			
		||||
				out_error);
 | 
			
		||||
	XFS_WANT_CORRUPTED_RETURN(!isnullstartblock(got.br_startblock));
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If this is the first extent in the file, make sure there's enough
 | 
			
		||||
	 * room at the start of the file and jump right to the shift as there's
 | 
			
		||||
	 * no left extent to merge.
 | 
			
		||||
	 * Check for merge if we've got an extent to the left, otherwise make
 | 
			
		||||
	 * sure there's enough room at the start of the file for the shift.
 | 
			
		||||
	 */
 | 
			
		||||
	if (*current_ext == 0) {
 | 
			
		||||
		if (got.br_startoff < offset_shift_fsb)
 | 
			
		||||
	if (*current_ext) {
 | 
			
		||||
		/* grab the left extent and check for a large enough hole */
 | 
			
		||||
		leftp = xfs_iext_get_ext(ifp, *current_ext - 1);
 | 
			
		||||
		xfs_bmbt_get_all(leftp, &left);
 | 
			
		||||
 | 
			
		||||
		if (startoff < left.br_startoff + left.br_blockcount)
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		goto shift_extent;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* grab the left extent and check for a large enough hole */
 | 
			
		||||
	leftp = xfs_iext_get_ext(ifp, *current_ext - 1);
 | 
			
		||||
	xfs_bmbt_get_all(leftp, &left);
 | 
			
		||||
 | 
			
		||||
	if (startoff < left.br_startoff + left.br_blockcount)
 | 
			
		||||
		/* check whether to merge the extent or shift it down */
 | 
			
		||||
		if (xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) {
 | 
			
		||||
			return xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
 | 
			
		||||
					      *current_ext, gotp, leftp, cur,
 | 
			
		||||
					      logflags);
 | 
			
		||||
		}
 | 
			
		||||
	} else if (got.br_startoff < offset_shift_fsb)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	/* check whether to merge the extent or shift it down */
 | 
			
		||||
	if (!xfs_bmse_can_merge(&left, &got, offset_shift_fsb))
 | 
			
		||||
		goto shift_extent;
 | 
			
		||||
 | 
			
		||||
	return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, *current_ext,
 | 
			
		||||
			      gotp, leftp, cur, logflags);
 | 
			
		||||
 | 
			
		||||
shift_extent:
 | 
			
		||||
	/*
 | 
			
		||||
	 * Increment the extent index for the next iteration, update the start
 | 
			
		||||
	 * offset of the in-core extent and update the btree if applicable.
 | 
			
		||||
| 
						 | 
				
			
			@ -5586,14 +5571,11 @@ shift_extent:
 | 
			
		|||
				   got.br_blockcount, &i);
 | 
			
		||||
	if (error)
 | 
			
		||||
		return error;
 | 
			
		||||
	XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
 | 
			
		||||
	XFS_WANT_CORRUPTED_RETURN(i == 1);
 | 
			
		||||
 | 
			
		||||
	got.br_startoff = startoff;
 | 
			
		||||
	return xfs_bmbt_update(cur, got.br_startoff, got.br_startblock,
 | 
			
		||||
				got.br_blockcount, got.br_state);
 | 
			
		||||
 | 
			
		||||
out_error:
 | 
			
		||||
	return error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -512,7 +512,6 @@ xfs_da3_root_split(
 | 
			
		|||
	struct xfs_buf		*bp;
 | 
			
		||||
	struct xfs_inode	*dp;
 | 
			
		||||
	struct xfs_trans	*tp;
 | 
			
		||||
	struct xfs_mount	*mp;
 | 
			
		||||
	struct xfs_dir2_leaf	*leaf;
 | 
			
		||||
	xfs_dablk_t		blkno;
 | 
			
		||||
	int			level;
 | 
			
		||||
| 
						 | 
				
			
			@ -532,7 +531,6 @@ xfs_da3_root_split(
 | 
			
		|||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	mp = state->mp;
 | 
			
		||||
	error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork);
 | 
			
		||||
	if (error)
 | 
			
		||||
		return error;
 | 
			
		||||
| 
						 | 
				
			
			@ -2340,14 +2338,12 @@ xfs_da_shrink_inode(
 | 
			
		|||
	xfs_inode_t *dp;
 | 
			
		||||
	int done, error, w, count;
 | 
			
		||||
	xfs_trans_t *tp;
 | 
			
		||||
	xfs_mount_t *mp;
 | 
			
		||||
 | 
			
		||||
	trace_xfs_da_shrink_inode(args);
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	w = args->whichfork;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	count = args->geo->fsbcount;
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,22 @@
 | 
			
		|||
 | 
			
		||||
struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR };
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * @mode, if set, indicates that the type field needs to be set up.
 | 
			
		||||
 * This uses the transformation from file mode to DT_* as defined in linux/fs.h
 | 
			
		||||
 * for file type specification. This will be propagated into the directory
 | 
			
		||||
 * structure if appropriate for the given operation and filesystem config.
 | 
			
		||||
 */
 | 
			
		||||
const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
 | 
			
		||||
	[0]			= XFS_DIR3_FT_UNKNOWN,
 | 
			
		||||
	[S_IFREG >> S_SHIFT]    = XFS_DIR3_FT_REG_FILE,
 | 
			
		||||
	[S_IFDIR >> S_SHIFT]    = XFS_DIR3_FT_DIR,
 | 
			
		||||
	[S_IFCHR >> S_SHIFT]    = XFS_DIR3_FT_CHRDEV,
 | 
			
		||||
	[S_IFBLK >> S_SHIFT]    = XFS_DIR3_FT_BLKDEV,
 | 
			
		||||
	[S_IFIFO >> S_SHIFT]    = XFS_DIR3_FT_FIFO,
 | 
			
		||||
	[S_IFSOCK >> S_SHIFT]   = XFS_DIR3_FT_SOCK,
 | 
			
		||||
	[S_IFLNK >> S_SHIFT]    = XFS_DIR3_FT_SYMLINK,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ASCII case-insensitive (ie. A-Z) support for directories that was
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,12 @@ struct xfs_dir2_data_unused;
 | 
			
		|||
 | 
			
		||||
extern struct xfs_name	xfs_name_dotdot;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * directory filetype conversion tables.
 | 
			
		||||
 */
 | 
			
		||||
#define S_SHIFT 12
 | 
			
		||||
extern const unsigned char xfs_mode_to_ftype[];
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * directory operations vector for encode/decode routines
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -177,4 +183,138 @@ extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
 | 
			
		|||
extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
 | 
			
		||||
extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Directory offset/block conversion functions.
 | 
			
		||||
 *
 | 
			
		||||
 * DB blocks here are logical directory block numbers, not filesystem blocks.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert dataptr to byte in file space
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_off_t
 | 
			
		||||
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in file space to dataptr.  It had better be aligned.
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_dataptr_t
 | 
			
		||||
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in space to (DB) block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_db_t
 | 
			
		||||
xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_db_t)(by >> geo->blklog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert dataptr to a block number
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_db_t
 | 
			
		||||
xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in space to offset in a block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_data_aoff_t
 | 
			
		||||
xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert dataptr to a byte offset in a block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_data_aoff_t
 | 
			
		||||
xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block and offset to byte in space
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_off_t
 | 
			
		||||
xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
 | 
			
		||||
			xfs_dir2_data_aoff_t o)
 | 
			
		||||
{
 | 
			
		||||
	return ((xfs_dir2_off_t)db << geo->blklog) + o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block (DB) to block (dablk)
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dablk_t
 | 
			
		||||
xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in space to (DA) block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dablk_t
 | 
			
		||||
xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block and offset to dataptr
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_dataptr_t
 | 
			
		||||
xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
 | 
			
		||||
			   xfs_dir2_data_aoff_t o)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block (dablk) to block (DB)
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_db_t
 | 
			
		||||
xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block (dablk) to byte offset in space
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_off_t
 | 
			
		||||
xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Directory tail pointer accessor functions. Based on block geometry.
 | 
			
		||||
 */
 | 
			
		||||
static inline struct xfs_dir2_block_tail *
 | 
			
		||||
xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	return ((struct xfs_dir2_block_tail *)
 | 
			
		||||
		((char *)hdr + geo->blksize)) - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline struct xfs_dir2_leaf_tail *
 | 
			
		||||
xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
 | 
			
		||||
{
 | 
			
		||||
	return (struct xfs_dir2_leaf_tail *)
 | 
			
		||||
		((char *)lp + geo->blksize -
 | 
			
		||||
		  sizeof(struct xfs_dir2_leaf_tail));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif	/* __XFS_DIR2_H__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -350,7 +350,6 @@ xfs_dir2_block_addname(
 | 
			
		|||
	int			low;		/* low index for binary srch */
 | 
			
		||||
	int			lowstale;	/* low stale index */
 | 
			
		||||
	int			mid=0;		/* midpoint for binary srch */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	int			needlog;	/* need to log header */
 | 
			
		||||
	int			needscan;	/* need to rescan freespace */
 | 
			
		||||
	__be16			*tagp;		/* pointer to tag value */
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +359,6 @@ xfs_dir2_block_addname(
 | 
			
		|||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
 | 
			
		||||
	/* Read the (one and only) directory block into bp. */
 | 
			
		||||
	error = xfs_dir3_block_read(tp, dp, &bp);
 | 
			
		||||
| 
						 | 
				
			
			@ -615,7 +613,6 @@ xfs_dir2_block_lookup(
 | 
			
		|||
	xfs_inode_t		*dp;		/* incore inode */
 | 
			
		||||
	int			ent;		/* entry index */
 | 
			
		||||
	int			error;		/* error return value */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
 | 
			
		||||
	trace_xfs_dir2_block_lookup(args);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -626,7 +623,6 @@ xfs_dir2_block_lookup(
 | 
			
		|||
	if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent)))
 | 
			
		||||
		return error;
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	hdr = bp->b_addr;
 | 
			
		||||
	xfs_dir3_data_check(dp, bp);
 | 
			
		||||
	btp = xfs_dir2_block_tail_p(args->geo, hdr);
 | 
			
		||||
| 
						 | 
				
			
			@ -767,7 +763,6 @@ xfs_dir2_block_removename(
 | 
			
		|||
	xfs_inode_t		*dp;		/* incore inode */
 | 
			
		||||
	int			ent;		/* block leaf entry index */
 | 
			
		||||
	int			error;		/* error return value */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	int			needlog;	/* need to log block header */
 | 
			
		||||
	int			needscan;	/* need to fixup bestfree */
 | 
			
		||||
	xfs_dir2_sf_hdr_t	sfh;		/* shortform header */
 | 
			
		||||
| 
						 | 
				
			
			@ -785,7 +780,6 @@ xfs_dir2_block_removename(
 | 
			
		|||
	}
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	hdr = bp->b_addr;
 | 
			
		||||
	btp = xfs_dir2_block_tail_p(args->geo, hdr);
 | 
			
		||||
	blp = xfs_dir2_block_leaf_p(btp);
 | 
			
		||||
| 
						 | 
				
			
			@ -849,7 +843,6 @@ xfs_dir2_block_replace(
 | 
			
		|||
	xfs_inode_t		*dp;		/* incore inode */
 | 
			
		||||
	int			ent;		/* leaf entry index */
 | 
			
		||||
	int			error;		/* error return value */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
 | 
			
		||||
	trace_xfs_dir2_block_replace(args);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -861,7 +854,6 @@ xfs_dir2_block_replace(
 | 
			
		|||
		return error;
 | 
			
		||||
	}
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	hdr = bp->b_addr;
 | 
			
		||||
	btp = xfs_dir2_block_tail_p(args->geo, hdr);
 | 
			
		||||
	blp = xfs_dir2_block_leaf_p(btp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -382,7 +382,6 @@ xfs_dir2_block_to_leaf(
 | 
			
		|||
	xfs_dir2_db_t		ldb;		/* leaf block's bno */
 | 
			
		||||
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
 | 
			
		||||
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf's tail */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	int			needlog;	/* need to log block header */
 | 
			
		||||
	int			needscan;	/* need to rescan bestfree */
 | 
			
		||||
	xfs_trans_t		*tp;		/* transaction pointer */
 | 
			
		||||
| 
						 | 
				
			
			@ -393,7 +392,6 @@ xfs_dir2_block_to_leaf(
 | 
			
		|||
	trace_xfs_dir2_block_to_leaf(args);
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Add the leaf block to the inode.
 | 
			
		||||
| 
						 | 
				
			
			@ -624,7 +622,6 @@ xfs_dir2_leaf_addname(
 | 
			
		|||
	int			lfloghigh;	/* high leaf logging index */
 | 
			
		||||
	int			lowstale;	/* index of prev stale leaf */
 | 
			
		||||
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail pointer */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	int			needbytes;	/* leaf block bytes needed */
 | 
			
		||||
	int			needlog;	/* need to log data header */
 | 
			
		||||
	int			needscan;	/* need to rescan data free */
 | 
			
		||||
| 
						 | 
				
			
			@ -639,7 +636,6 @@ xfs_dir2_leaf_addname(
 | 
			
		|||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
 | 
			
		||||
	error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
 | 
			
		||||
	if (error)
 | 
			
		||||
| 
						 | 
				
			
			@ -1354,11 +1350,9 @@ xfs_dir2_leaf_removename(
 | 
			
		|||
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
 | 
			
		||||
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
 | 
			
		||||
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	int			needlog;	/* need to log data header */
 | 
			
		||||
	int			needscan;	/* need to rescan data frees */
 | 
			
		||||
	xfs_dir2_data_off_t	oldbest;	/* old value of best free */
 | 
			
		||||
	xfs_trans_t		*tp;		/* transaction pointer */
 | 
			
		||||
	struct xfs_dir2_data_free *bf;		/* bestfree table */
 | 
			
		||||
	struct xfs_dir2_leaf_entry *ents;
 | 
			
		||||
	struct xfs_dir3_icleaf_hdr leafhdr;
 | 
			
		||||
| 
						 | 
				
			
			@ -1372,8 +1366,6 @@ xfs_dir2_leaf_removename(
 | 
			
		|||
		return error;
 | 
			
		||||
	}
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	leaf = lbp->b_addr;
 | 
			
		||||
	hdr = dbp->b_addr;
 | 
			
		||||
	xfs_dir3_data_check(dp, dbp);
 | 
			
		||||
| 
						 | 
				
			
			@ -1605,11 +1597,9 @@ xfs_dir2_leaf_trim_data(
 | 
			
		|||
	int			error;		/* error return value */
 | 
			
		||||
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
 | 
			
		||||
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	xfs_trans_t		*tp;		/* transaction pointer */
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Read the offending data block.  We need its buffer.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -295,7 +295,6 @@ xfs_dir2_leaf_to_node(
 | 
			
		|||
	int			i;		/* leaf freespace index */
 | 
			
		||||
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
 | 
			
		||||
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	int			n;		/* count of live freespc ents */
 | 
			
		||||
	xfs_dir2_data_off_t	off;		/* freespace entry value */
 | 
			
		||||
	__be16			*to;		/* pointer to freespace entry */
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +304,6 @@ xfs_dir2_leaf_to_node(
 | 
			
		|||
	trace_xfs_dir2_leaf_to_node(args);
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Add a freespace block to the directory.
 | 
			
		||||
| 
						 | 
				
			
			@ -385,16 +383,12 @@ xfs_dir2_leafn_add(
 | 
			
		|||
	int			lfloghigh;	/* high leaf entry logging */
 | 
			
		||||
	int			lfloglow;	/* low leaf entry logging */
 | 
			
		||||
	int			lowstale;	/* previous stale entry */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	xfs_trans_t		*tp;		/* transaction pointer */
 | 
			
		||||
	struct xfs_dir3_icleaf_hdr leafhdr;
 | 
			
		||||
	struct xfs_dir2_leaf_entry *ents;
 | 
			
		||||
 | 
			
		||||
	trace_xfs_dir2_leafn_add(args, index);
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	leaf = bp->b_addr;
 | 
			
		||||
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
 | 
			
		||||
	ents = dp->d_ops->leaf_ents_p(leaf);
 | 
			
		||||
| 
						 | 
				
			
			@ -1168,7 +1162,6 @@ xfs_dir2_leafn_remove(
 | 
			
		|||
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
 | 
			
		||||
	int			longest;	/* longest data free entry */
 | 
			
		||||
	int			off;		/* data block entry offset */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	int			needlog;	/* need to log data header */
 | 
			
		||||
	int			needscan;	/* need to rescan data frees */
 | 
			
		||||
	xfs_trans_t		*tp;		/* transaction pointer */
 | 
			
		||||
| 
						 | 
				
			
			@ -1180,7 +1173,6 @@ xfs_dir2_leafn_remove(
 | 
			
		|||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	leaf = bp->b_addr;
 | 
			
		||||
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
 | 
			
		||||
	ents = dp->d_ops->leaf_ents_p(leaf);
 | 
			
		||||
| 
						 | 
				
			
			@ -1321,7 +1313,6 @@ xfs_dir2_leafn_split(
 | 
			
		|||
	xfs_da_args_t		*args;		/* operation arguments */
 | 
			
		||||
	xfs_dablk_t		blkno;		/* new leaf block number */
 | 
			
		||||
	int			error;		/* error return value */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	struct xfs_inode	*dp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1329,7 +1320,6 @@ xfs_dir2_leafn_split(
 | 
			
		|||
	 */
 | 
			
		||||
	args = state->args;
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC);
 | 
			
		||||
	error = xfs_da_grow_inode(args, &blkno);
 | 
			
		||||
	if (error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2229,12 +2219,10 @@ xfs_dir2_node_trim_free(
 | 
			
		|||
	xfs_inode_t		*dp;		/* incore directory inode */
 | 
			
		||||
	int			error;		/* error return code */
 | 
			
		||||
	xfs_dir2_free_t		*free;		/* freespace structure */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	xfs_trans_t		*tp;		/* transaction pointer */
 | 
			
		||||
	struct xfs_dir3_icfree_hdr freehdr;
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
	tp = args->trans;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Read the freespace block.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,140 +20,6 @@
 | 
			
		|||
 | 
			
		||||
struct dir_context;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Directory offset/block conversion functions.
 | 
			
		||||
 *
 | 
			
		||||
 * DB blocks here are logical directory block numbers, not filesystem blocks.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert dataptr to byte in file space
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_off_t
 | 
			
		||||
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in file space to dataptr.  It had better be aligned.
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_dataptr_t
 | 
			
		||||
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in space to (DB) block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_db_t
 | 
			
		||||
xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_db_t)(by >> geo->blklog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert dataptr to a block number
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_db_t
 | 
			
		||||
xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in space to offset in a block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_data_aoff_t
 | 
			
		||||
xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert dataptr to a byte offset in a block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_data_aoff_t
 | 
			
		||||
xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block and offset to byte in space
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_off_t
 | 
			
		||||
xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
 | 
			
		||||
			xfs_dir2_data_aoff_t o)
 | 
			
		||||
{
 | 
			
		||||
	return ((xfs_dir2_off_t)db << geo->blklog) + o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block (DB) to block (dablk)
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dablk_t
 | 
			
		||||
xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert byte in space to (DA) block
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dablk_t
 | 
			
		||||
xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block and offset to dataptr
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_dataptr_t
 | 
			
		||||
xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
 | 
			
		||||
			   xfs_dir2_data_aoff_t o)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block (dablk) to block (DB)
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_db_t
 | 
			
		||||
xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
 | 
			
		||||
{
 | 
			
		||||
	return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert block (dablk) to byte offset in space
 | 
			
		||||
 */
 | 
			
		||||
static inline xfs_dir2_off_t
 | 
			
		||||
xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
 | 
			
		||||
{
 | 
			
		||||
	return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Directory tail pointer accessor functions. Based on block geometry.
 | 
			
		||||
 */
 | 
			
		||||
static inline struct xfs_dir2_block_tail *
 | 
			
		||||
xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	return ((struct xfs_dir2_block_tail *)
 | 
			
		||||
		((char *)hdr + geo->blksize)) - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline struct xfs_dir2_leaf_tail *
 | 
			
		||||
xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
 | 
			
		||||
{
 | 
			
		||||
	return (struct xfs_dir2_leaf_tail *)
 | 
			
		||||
		((char *)lp + geo->blksize -
 | 
			
		||||
		  sizeof(struct xfs_dir2_leaf_tail));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* xfs_dir2.c */
 | 
			
		||||
extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
 | 
			
		||||
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
 | 
			
		||||
| 
						 | 
				
			
			@ -161,12 +27,6 @@ extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
 | 
			
		|||
extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
 | 
			
		||||
				const unsigned char *name, int len);
 | 
			
		||||
 | 
			
		||||
#define S_SHIFT 12
 | 
			
		||||
extern const unsigned char xfs_mode_to_ftype[];
 | 
			
		||||
 | 
			
		||||
extern unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp,
 | 
			
		||||
					__uint8_t filetype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* xfs_dir2_block.c */
 | 
			
		||||
extern int xfs_dir3_block_read(struct xfs_trans *tp, struct xfs_inode *dp,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -452,13 +452,11 @@ xfs_dir2_sf_addname_hard(
 | 
			
		|||
	xfs_dir2_sf_hdr_t	*oldsfp;	/* original shortform dir */
 | 
			
		||||
	xfs_dir2_sf_entry_t	*sfep;		/* entry in new dir */
 | 
			
		||||
	xfs_dir2_sf_hdr_t	*sfp;		/* new shortform dir */
 | 
			
		||||
	struct xfs_mount	*mp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Copy the old directory to the stack buffer.
 | 
			
		||||
	 */
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
 | 
			
		||||
	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 | 
			
		||||
	old_isize = (int)dp->i_d.di_size;
 | 
			
		||||
| 
						 | 
				
			
			@ -539,7 +537,6 @@ xfs_dir2_sf_addname_pick(
 | 
			
		|||
	xfs_inode_t		*dp;		/* incore directory inode */
 | 
			
		||||
	int			holefit;	/* found hole it will fit in */
 | 
			
		||||
	int			i;		/* entry number */
 | 
			
		||||
	xfs_mount_t		*mp;		/* filesystem mount point */
 | 
			
		||||
	xfs_dir2_data_aoff_t	offset;		/* data block offset */
 | 
			
		||||
	xfs_dir2_sf_entry_t	*sfep;		/* shortform entry */
 | 
			
		||||
	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
 | 
			
		||||
| 
						 | 
				
			
			@ -547,7 +544,6 @@ xfs_dir2_sf_addname_pick(
 | 
			
		|||
	int			used;		/* data bytes used */
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
 | 
			
		||||
	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 | 
			
		||||
	size = dp->d_ops->data_entsize(args->namelen);
 | 
			
		||||
| 
						 | 
				
			
			@ -613,10 +609,8 @@ xfs_dir2_sf_check(
 | 
			
		|||
	int			offset;		/* data offset */
 | 
			
		||||
	xfs_dir2_sf_entry_t	*sfep;		/* shortform dir entry */
 | 
			
		||||
	xfs_dir2_sf_hdr_t	*sfp;		/* shortform structure */
 | 
			
		||||
	struct xfs_mount	*mp;
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
 | 
			
		||||
	sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
 | 
			
		||||
	offset = dp->d_ops->data_first_offset;
 | 
			
		||||
| 
						 | 
				
			
			@ -1013,12 +1007,10 @@ xfs_dir2_sf_toino4(
 | 
			
		|||
	int			oldsize;	/* old inode size */
 | 
			
		||||
	xfs_dir2_sf_entry_t	*sfep;		/* new sf entry */
 | 
			
		||||
	xfs_dir2_sf_hdr_t	*sfp;		/* new sf directory */
 | 
			
		||||
	struct xfs_mount	*mp;
 | 
			
		||||
 | 
			
		||||
	trace_xfs_dir2_sf_toino4(args);
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Copy the old directory to the buffer.
 | 
			
		||||
| 
						 | 
				
			
			@ -1091,12 +1083,10 @@ xfs_dir2_sf_toino8(
 | 
			
		|||
	int			oldsize;	/* old inode size */
 | 
			
		||||
	xfs_dir2_sf_entry_t	*sfep;		/* new sf entry */
 | 
			
		||||
	xfs_dir2_sf_hdr_t	*sfp;		/* new sf directory */
 | 
			
		||||
	struct xfs_mount	*mp;
 | 
			
		||||
 | 
			
		||||
	trace_xfs_dir2_sf_toino8(args);
 | 
			
		||||
 | 
			
		||||
	dp = args->dp;
 | 
			
		||||
	mp = dp->i_mount;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Copy the old directory to the buffer.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,12 +45,12 @@
 | 
			
		|||
 */
 | 
			
		||||
static inline int
 | 
			
		||||
xfs_ialloc_cluster_alignment(
 | 
			
		||||
	xfs_alloc_arg_t	*args)
 | 
			
		||||
	struct xfs_mount	*mp)
 | 
			
		||||
{
 | 
			
		||||
	if (xfs_sb_version_hasalign(&args->mp->m_sb) &&
 | 
			
		||||
	    args->mp->m_sb.sb_inoalignmt >=
 | 
			
		||||
	     XFS_B_TO_FSBT(args->mp, args->mp->m_inode_cluster_size))
 | 
			
		||||
		return args->mp->m_sb.sb_inoalignmt;
 | 
			
		||||
	if (xfs_sb_version_hasalign(&mp->m_sb) &&
 | 
			
		||||
	    mp->m_sb.sb_inoalignmt >=
 | 
			
		||||
			XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
 | 
			
		||||
		return mp->m_sb.sb_inoalignmt;
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -409,7 +409,7 @@ xfs_ialloc_ag_alloc(
 | 
			
		|||
		 * but not to use them in the actual exact allocation.
 | 
			
		||||
		 */
 | 
			
		||||
		args.alignment = 1;
 | 
			
		||||
		args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1;
 | 
			
		||||
		args.minalignslop = xfs_ialloc_cluster_alignment(args.mp) - 1;
 | 
			
		||||
 | 
			
		||||
		/* Allow space for the inode btree to split. */
 | 
			
		||||
		args.minleft = args.mp->m_in_maxlevels - 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -445,7 +445,7 @@ xfs_ialloc_ag_alloc(
 | 
			
		|||
			args.alignment = args.mp->m_dalign;
 | 
			
		||||
			isaligned = 1;
 | 
			
		||||
		} else
 | 
			
		||||
			args.alignment = xfs_ialloc_cluster_alignment(&args);
 | 
			
		||||
			args.alignment = xfs_ialloc_cluster_alignment(args.mp);
 | 
			
		||||
		/*
 | 
			
		||||
		 * Need to figure out where to allocate the inode blocks.
 | 
			
		||||
		 * Ideally they should be spaced out through the a.g.
 | 
			
		||||
| 
						 | 
				
			
			@ -474,7 +474,7 @@ xfs_ialloc_ag_alloc(
 | 
			
		|||
		args.type = XFS_ALLOCTYPE_NEAR_BNO;
 | 
			
		||||
		args.agbno = be32_to_cpu(agi->agi_root);
 | 
			
		||||
		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
 | 
			
		||||
		args.alignment = xfs_ialloc_cluster_alignment(&args);
 | 
			
		||||
		args.alignment = xfs_ialloc_cluster_alignment(args.mp);
 | 
			
		||||
		if ((error = xfs_alloc_vextent(&args)))
 | 
			
		||||
			return error;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -629,10 +629,24 @@ xfs_ialloc_ag_select(
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Is there enough free space for the file plus a block of
 | 
			
		||||
		 * inodes? (if we need to allocate some)?
 | 
			
		||||
		 * Check that there is enough free space for the file plus a
 | 
			
		||||
		 * chunk of inodes if we need to allocate some. If this is the
 | 
			
		||||
		 * first pass across the AGs, take into account the potential
 | 
			
		||||
		 * space needed for alignment of inode chunks when checking the
 | 
			
		||||
		 * longest contiguous free space in the AG - this prevents us
 | 
			
		||||
		 * from getting ENOSPC because we have free space larger than
 | 
			
		||||
		 * m_ialloc_blks but alignment constraints prevent us from using
 | 
			
		||||
		 * it.
 | 
			
		||||
		 *
 | 
			
		||||
		 * If we can't find an AG with space for full alignment slack to
 | 
			
		||||
		 * be taken into account, we must be near ENOSPC in all AGs.
 | 
			
		||||
		 * Hence we don't include alignment for the second pass and so
 | 
			
		||||
		 * if we fail allocation due to alignment issues then it is most
 | 
			
		||||
		 * likely a real ENOSPC condition.
 | 
			
		||||
		 */
 | 
			
		||||
		ineed = mp->m_ialloc_blks;
 | 
			
		||||
		if (flags && ineed > 1)
 | 
			
		||||
			ineed += xfs_ialloc_cluster_alignment(mp);
 | 
			
		||||
		longest = pag->pagf_longest;
 | 
			
		||||
		if (!longest)
 | 
			
		||||
			longest = pag->pagf_flcount > 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1041,7 +1041,7 @@ xfs_buf_ioend_work(
 | 
			
		|||
	struct work_struct	*work)
 | 
			
		||||
{
 | 
			
		||||
	struct xfs_buf		*bp =
 | 
			
		||||
		container_of(work, xfs_buf_t, b_iodone_work);
 | 
			
		||||
		container_of(work, xfs_buf_t, b_ioend_work);
 | 
			
		||||
 | 
			
		||||
	xfs_buf_ioend(bp);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1050,8 +1050,8 @@ void
 | 
			
		|||
xfs_buf_ioend_async(
 | 
			
		||||
	struct xfs_buf	*bp)
 | 
			
		||||
{
 | 
			
		||||
	INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work);
 | 
			
		||||
	queue_work(bp->b_target->bt_mount->m_buf_workqueue, &bp->b_iodone_work);
 | 
			
		||||
	INIT_WORK(&bp->b_ioend_work, xfs_buf_ioend_work);
 | 
			
		||||
	queue_work(bp->b_ioend_wq, &bp->b_ioend_work);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			@ -1220,6 +1220,13 @@ _xfs_buf_ioapply(
 | 
			
		|||
	 */
 | 
			
		||||
	bp->b_error = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Initialize the I/O completion workqueue if we haven't yet or the
 | 
			
		||||
	 * submitter has not opted to specify a custom one.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!bp->b_ioend_wq)
 | 
			
		||||
		bp->b_ioend_wq = bp->b_target->bt_mount->m_buf_workqueue;
 | 
			
		||||
 | 
			
		||||
	if (bp->b_flags & XBF_WRITE) {
 | 
			
		||||
		if (bp->b_flags & XBF_SYNCIO)
 | 
			
		||||
			rw = WRITE_SYNC;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -164,7 +164,8 @@ typedef struct xfs_buf {
 | 
			
		|||
	struct xfs_perag	*b_pag;		/* contains rbtree root */
 | 
			
		||||
	xfs_buftarg_t		*b_target;	/* buffer target (device) */
 | 
			
		||||
	void			*b_addr;	/* virtual address of buffer */
 | 
			
		||||
	struct work_struct	b_iodone_work;
 | 
			
		||||
	struct work_struct	b_ioend_work;
 | 
			
		||||
	struct workqueue_struct	*b_ioend_wq;	/* I/O completion wq */
 | 
			
		||||
	xfs_buf_iodone_t	b_iodone;	/* I/O completion function */
 | 
			
		||||
	struct completion	b_iowait;	/* queue for I/O waiters */
 | 
			
		||||
	void			*b_fspriv;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ static unsigned char xfs_dir3_filetype_table[] = {
 | 
			
		|||
	DT_FIFO, DT_SOCK, DT_LNK, DT_WHT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned char
 | 
			
		||||
static unsigned char
 | 
			
		||||
xfs_dir3_get_dtype(
 | 
			
		||||
	struct xfs_mount	*mp,
 | 
			
		||||
	__uint8_t		filetype)
 | 
			
		||||
| 
						 | 
				
			
			@ -54,22 +54,6 @@ xfs_dir3_get_dtype(
 | 
			
		|||
 | 
			
		||||
	return xfs_dir3_filetype_table[filetype];
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * @mode, if set, indicates that the type field needs to be set up.
 | 
			
		||||
 * This uses the transformation from file mode to DT_* as defined in linux/fs.h
 | 
			
		||||
 * for file type specification. This will be propagated into the directory
 | 
			
		||||
 * structure if appropriate for the given operation and filesystem config.
 | 
			
		||||
 */
 | 
			
		||||
const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
 | 
			
		||||
	[0]			= XFS_DIR3_FT_UNKNOWN,
 | 
			
		||||
	[S_IFREG >> S_SHIFT]    = XFS_DIR3_FT_REG_FILE,
 | 
			
		||||
	[S_IFDIR >> S_SHIFT]    = XFS_DIR3_FT_DIR,
 | 
			
		||||
	[S_IFCHR >> S_SHIFT]    = XFS_DIR3_FT_CHRDEV,
 | 
			
		||||
	[S_IFBLK >> S_SHIFT]    = XFS_DIR3_FT_BLKDEV,
 | 
			
		||||
	[S_IFIFO >> S_SHIFT]    = XFS_DIR3_FT_FIFO,
 | 
			
		||||
	[S_IFSOCK >> S_SHIFT]   = XFS_DIR3_FT_SOCK,
 | 
			
		||||
	[S_IFLNK >> S_SHIFT]    = XFS_DIR3_FT_SYMLINK,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
STATIC int
 | 
			
		||||
xfs_dir2_sf_getdents(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@
 | 
			
		|||
#include "xfs_trans_resv.h"
 | 
			
		||||
#include "xfs_mount.h"
 | 
			
		||||
#include "xfs_da_format.h"
 | 
			
		||||
#include "xfs_da_btree.h"
 | 
			
		||||
#include "xfs_dir2.h"
 | 
			
		||||
#include "xfs_export.h"
 | 
			
		||||
#include "xfs_inode.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,7 @@ xfs_inode_alloc(
 | 
			
		|||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	XFS_STATS_INC(vn_active);
 | 
			
		||||
	ASSERT(atomic_read(&ip->i_pincount) == 0);
 | 
			
		||||
	ASSERT(!spin_is_locked(&ip->i_flags_lock));
 | 
			
		||||
	ASSERT(!xfs_isiflocked(ip));
 | 
			
		||||
| 
						 | 
				
			
			@ -128,6 +129,7 @@ xfs_inode_free(
 | 
			
		|||
	/* asserts to verify all state is correct here */
 | 
			
		||||
	ASSERT(atomic_read(&ip->i_pincount) == 0);
 | 
			
		||||
	ASSERT(!xfs_isiflocked(ip));
 | 
			
		||||
	XFS_STATS_DEC(vn_active);
 | 
			
		||||
 | 
			
		||||
	call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2483,9 +2483,7 @@ xfs_remove(
 | 
			
		|||
	xfs_fsblock_t           first_block;
 | 
			
		||||
	int			cancel_flags;
 | 
			
		||||
	int			committed;
 | 
			
		||||
	int			link_zero;
 | 
			
		||||
	uint			resblks;
 | 
			
		||||
	uint			log_count;
 | 
			
		||||
 | 
			
		||||
	trace_xfs_remove(dp, name);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2500,13 +2498,10 @@ xfs_remove(
 | 
			
		|||
	if (error)
 | 
			
		||||
		goto std_return;
 | 
			
		||||
 | 
			
		||||
	if (is_dir) {
 | 
			
		||||
	if (is_dir)
 | 
			
		||||
		tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR);
 | 
			
		||||
		log_count = XFS_DEFAULT_LOG_COUNT;
 | 
			
		||||
	} else {
 | 
			
		||||
	else
 | 
			
		||||
		tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE);
 | 
			
		||||
		log_count = XFS_REMOVE_LOG_COUNT;
 | 
			
		||||
	}
 | 
			
		||||
	cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -2574,9 +2569,6 @@ xfs_remove(
 | 
			
		|||
	if (error)
 | 
			
		||||
		goto out_trans_cancel;
 | 
			
		||||
 | 
			
		||||
	/* Determine if this is the last link while the inode is locked */
 | 
			
		||||
	link_zero = (ip->i_d.di_nlink == 0);
 | 
			
		||||
 | 
			
		||||
	xfs_bmap_init(&free_list, &first_block);
 | 
			
		||||
	error = xfs_dir_removename(tp, dp, name, ip->i_ino,
 | 
			
		||||
					&first_block, &free_list, resblks);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,6 @@ xfs_iomap_eof_align_last_fsb(
 | 
			
		|||
	xfs_extlen_t	extsize,
 | 
			
		||||
	xfs_fileoff_t	*last_fsb)
 | 
			
		||||
{
 | 
			
		||||
	xfs_fileoff_t	new_last_fsb = 0;
 | 
			
		||||
	xfs_extlen_t	align = 0;
 | 
			
		||||
	int		eof, error;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +66,8 @@ xfs_iomap_eof_align_last_fsb(
 | 
			
		|||
		else if (mp->m_dalign)
 | 
			
		||||
			align = mp->m_dalign;
 | 
			
		||||
 | 
			
		||||
		if (align && XFS_ISIZE(ip) >= XFS_FSB_TO_B(mp, align))
 | 
			
		||||
			new_last_fsb = roundup_64(*last_fsb, align);
 | 
			
		||||
		if (align && XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, align))
 | 
			
		||||
			align = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -76,14 +75,14 @@ xfs_iomap_eof_align_last_fsb(
 | 
			
		|||
	 * (when file on a real-time subvolume or has di_extsize hint).
 | 
			
		||||
	 */
 | 
			
		||||
	if (extsize) {
 | 
			
		||||
		if (new_last_fsb)
 | 
			
		||||
			align = roundup_64(new_last_fsb, extsize);
 | 
			
		||||
		if (align)
 | 
			
		||||
			align = roundup_64(align, extsize);
 | 
			
		||||
		else
 | 
			
		||||
			align = extsize;
 | 
			
		||||
		new_last_fsb = roundup_64(*last_fsb, align);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (new_last_fsb) {
 | 
			
		||||
	if (align) {
 | 
			
		||||
		xfs_fileoff_t	new_last_fsb = roundup_64(*last_fsb, align);
 | 
			
		||||
		error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
 | 
			
		||||
		if (error)
 | 
			
		||||
			return error;
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +260,6 @@ xfs_iomap_eof_want_preallocate(
 | 
			
		|||
{
 | 
			
		||||
	xfs_fileoff_t   start_fsb;
 | 
			
		||||
	xfs_filblks_t   count_fsb;
 | 
			
		||||
	xfs_fsblock_t	firstblock;
 | 
			
		||||
	int		n, error, imaps;
 | 
			
		||||
	int		found_delalloc = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -286,7 +284,6 @@ xfs_iomap_eof_want_preallocate(
 | 
			
		|||
	count_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
 | 
			
		||||
	while (count_fsb > 0) {
 | 
			
		||||
		imaps = nimaps;
 | 
			
		||||
		firstblock = NULLFSBLOCK;
 | 
			
		||||
		error = xfs_bmapi_read(ip, start_fsb, count_fsb, imap, &imaps,
 | 
			
		||||
				       0);
 | 
			
		||||
		if (error)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@
 | 
			
		|||
#include "xfs_icache.h"
 | 
			
		||||
#include "xfs_symlink.h"
 | 
			
		||||
#include "xfs_da_btree.h"
 | 
			
		||||
#include "xfs_dir2_priv.h"
 | 
			
		||||
#include "xfs_dir2.h"
 | 
			
		||||
#include "xfs_trans_space.h"
 | 
			
		||||
 | 
			
		||||
#include <linux/capability.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -348,7 +348,6 @@ xfs_bulkstat(
 | 
			
		|||
	int			*done)	/* 1 if there are more stats to get */
 | 
			
		||||
{
 | 
			
		||||
	xfs_buf_t		*agbp;	/* agi header buffer */
 | 
			
		||||
	xfs_agi_t		*agi;	/* agi header data */
 | 
			
		||||
	xfs_agino_t		agino;	/* inode # in allocation group */
 | 
			
		||||
	xfs_agnumber_t		agno;	/* allocation group number */
 | 
			
		||||
	xfs_btree_cur_t		*cur;	/* btree cursor for ialloc btree */
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +398,6 @@ xfs_bulkstat(
 | 
			
		|||
		error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp);
 | 
			
		||||
		if (error)
 | 
			
		||||
			break;
 | 
			
		||||
		agi = XFS_BUF_TO_AGI(agbp);
 | 
			
		||||
		/*
 | 
			
		||||
		 * Allocate and initialize a btree cursor for ialloc btree.
 | 
			
		||||
		 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1806,6 +1806,8 @@ xlog_sync(
 | 
			
		|||
	XFS_BUF_ZEROFLAGS(bp);
 | 
			
		||||
	XFS_BUF_ASYNC(bp);
 | 
			
		||||
	bp->b_flags |= XBF_SYNCIO;
 | 
			
		||||
	/* use high priority completion wq */
 | 
			
		||||
	bp->b_ioend_wq = log->l_mp->m_log_workqueue;
 | 
			
		||||
 | 
			
		||||
	if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) {
 | 
			
		||||
		bp->b_flags |= XBF_FUA;
 | 
			
		||||
| 
						 | 
				
			
			@ -1854,6 +1856,8 @@ xlog_sync(
 | 
			
		|||
		bp->b_flags |= XBF_SYNCIO;
 | 
			
		||||
		if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
 | 
			
		||||
			bp->b_flags |= XBF_FUA;
 | 
			
		||||
		/* use high priority completion wq */
 | 
			
		||||
		bp->b_ioend_wq = log->l_mp->m_log_workqueue;
 | 
			
		||||
 | 
			
		||||
		ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
 | 
			
		||||
		ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@
 | 
			
		|||
#include "xfs_sb.h"
 | 
			
		||||
#include "xfs_mount.h"
 | 
			
		||||
#include "xfs_da_format.h"
 | 
			
		||||
#include "xfs_da_btree.h"
 | 
			
		||||
#include "xfs_inode.h"
 | 
			
		||||
#include "xfs_trans.h"
 | 
			
		||||
#include "xfs_log.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@
 | 
			
		|||
#include "xfs_sb.h"
 | 
			
		||||
#include "xfs_mount.h"
 | 
			
		||||
#include "xfs_da_format.h"
 | 
			
		||||
#include "xfs_da_btree.h"
 | 
			
		||||
#include "xfs_inode.h"
 | 
			
		||||
#include "xfs_dir2.h"
 | 
			
		||||
#include "xfs_ialloc.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -839,8 +839,7 @@ xfs_init_mount_workqueues(
 | 
			
		|||
	struct xfs_mount	*mp)
 | 
			
		||||
{
 | 
			
		||||
	mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s",
 | 
			
		||||
			WQ_MEM_RECLAIM|WQ_HIGHPRI|WQ_FREEZABLE, 1,
 | 
			
		||||
			mp->m_fsname);
 | 
			
		||||
			WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_fsname);
 | 
			
		||||
	if (!mp->m_buf_workqueue)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -865,7 +864,7 @@ xfs_init_mount_workqueues(
 | 
			
		|||
		goto out_destroy_cil;
 | 
			
		||||
 | 
			
		||||
	mp->m_log_workqueue = alloc_workqueue("xfs-log/%s",
 | 
			
		||||
			WQ_FREEZABLE, 0, mp->m_fsname);
 | 
			
		||||
			WQ_FREEZABLE|WQ_HIGHPRI, 0, mp->m_fsname);
 | 
			
		||||
	if (!mp->m_log_workqueue)
 | 
			
		||||
		goto out_destroy_reclaim;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1005,7 +1004,6 @@ xfs_fs_evict_inode(
 | 
			
		|||
	clear_inode(inode);
 | 
			
		||||
	XFS_STATS_INC(vn_rele);
 | 
			
		||||
	XFS_STATS_INC(vn_remove);
 | 
			
		||||
	XFS_STATS_DEC(vn_active);
 | 
			
		||||
 | 
			
		||||
	xfs_inactive(ip);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -227,13 +227,6 @@ xfs_trans_getsb(xfs_trans_t	*tp,
 | 
			
		|||
	return bp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
xfs_buftarg_t *xfs_error_target;
 | 
			
		||||
int	xfs_do_error;
 | 
			
		||||
int	xfs_req_num;
 | 
			
		||||
int	xfs_error_mod = 33;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get and lock the buffer for the caller if it is not already
 | 
			
		||||
 * locked within the given transaction.  If it has not yet been
 | 
			
		||||
| 
						 | 
				
			
			@ -255,46 +248,11 @@ xfs_trans_read_buf_map(
 | 
			
		|||
	struct xfs_buf		**bpp,
 | 
			
		||||
	const struct xfs_buf_ops *ops)
 | 
			
		||||
{
 | 
			
		||||
	xfs_buf_t		*bp;
 | 
			
		||||
	xfs_buf_log_item_t	*bip;
 | 
			
		||||
	struct xfs_buf		*bp = NULL;
 | 
			
		||||
	struct xfs_buf_log_item	*bip;
 | 
			
		||||
	int			error;
 | 
			
		||||
 | 
			
		||||
	*bpp = NULL;
 | 
			
		||||
	if (!tp) {
 | 
			
		||||
		bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
 | 
			
		||||
		if (!bp)
 | 
			
		||||
			return (flags & XBF_TRYLOCK) ?
 | 
			
		||||
					-EAGAIN : -ENOMEM;
 | 
			
		||||
 | 
			
		||||
		if (bp->b_error) {
 | 
			
		||||
			error = bp->b_error;
 | 
			
		||||
			xfs_buf_ioerror_alert(bp, __func__);
 | 
			
		||||
			XFS_BUF_UNDONE(bp);
 | 
			
		||||
			xfs_buf_stale(bp);
 | 
			
		||||
			xfs_buf_relse(bp);
 | 
			
		||||
 | 
			
		||||
			/* bad CRC means corrupted metadata */
 | 
			
		||||
			if (error == -EFSBADCRC)
 | 
			
		||||
				error = -EFSCORRUPTED;
 | 
			
		||||
			return error;
 | 
			
		||||
		}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		if (xfs_do_error) {
 | 
			
		||||
			if (xfs_error_target == target) {
 | 
			
		||||
				if (((xfs_req_num++) % xfs_error_mod) == 0) {
 | 
			
		||||
					xfs_buf_relse(bp);
 | 
			
		||||
					xfs_debug(mp, "Returning error!");
 | 
			
		||||
					return -EIO;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
		if (XFS_FORCED_SHUTDOWN(mp))
 | 
			
		||||
			goto shutdown_abort;
 | 
			
		||||
		*bpp = bp;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If we find the buffer in the cache with this transaction
 | 
			
		||||
	 * pointer in its b_fsprivate2 field, then we know we already
 | 
			
		||||
| 
						 | 
				
			
			@ -303,49 +261,24 @@ xfs_trans_read_buf_map(
 | 
			
		|||
	 * If the buffer is not yet read in, then we read it in, increment
 | 
			
		||||
	 * the lock recursion count, and return it to the caller.
 | 
			
		||||
	 */
 | 
			
		||||
	bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
 | 
			
		||||
	if (bp != NULL) {
 | 
			
		||||
	if (tp)
 | 
			
		||||
		bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
 | 
			
		||||
	if (bp) {
 | 
			
		||||
		ASSERT(xfs_buf_islocked(bp));
 | 
			
		||||
		ASSERT(bp->b_transp == tp);
 | 
			
		||||
		ASSERT(bp->b_fspriv != NULL);
 | 
			
		||||
		ASSERT(!bp->b_error);
 | 
			
		||||
		if (!(XFS_BUF_ISDONE(bp))) {
 | 
			
		||||
			trace_xfs_trans_read_buf_io(bp, _RET_IP_);
 | 
			
		||||
			ASSERT(!XFS_BUF_ISASYNC(bp));
 | 
			
		||||
			ASSERT(bp->b_iodone == NULL);
 | 
			
		||||
			XFS_BUF_READ(bp);
 | 
			
		||||
			bp->b_ops = ops;
 | 
			
		||||
		ASSERT(bp->b_flags & XBF_DONE);
 | 
			
		||||
 | 
			
		||||
			error = xfs_buf_submit_wait(bp);
 | 
			
		||||
			if (error) {
 | 
			
		||||
				if (!XFS_FORCED_SHUTDOWN(mp))
 | 
			
		||||
					xfs_buf_ioerror_alert(bp, __func__);
 | 
			
		||||
				xfs_buf_relse(bp);
 | 
			
		||||
				/*
 | 
			
		||||
				 * We can gracefully recover from most read
 | 
			
		||||
				 * errors. Ones we can't are those that happen
 | 
			
		||||
				 * after the transaction's already dirty.
 | 
			
		||||
				 */
 | 
			
		||||
				if (tp->t_flags & XFS_TRANS_DIRTY)
 | 
			
		||||
					xfs_force_shutdown(tp->t_mountp,
 | 
			
		||||
							SHUTDOWN_META_IO_ERROR);
 | 
			
		||||
				/* bad CRC means corrupted metadata */
 | 
			
		||||
				if (error == -EFSBADCRC)
 | 
			
		||||
					error = -EFSCORRUPTED;
 | 
			
		||||
				return error;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		 * We never locked this buf ourselves, so we shouldn't
 | 
			
		||||
		 * brelse it either. Just get out.
 | 
			
		||||
		 */
 | 
			
		||||
		if (XFS_FORCED_SHUTDOWN(mp)) {
 | 
			
		||||
			trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
 | 
			
		||||
			*bpp = NULL;
 | 
			
		||||
			return -EIO;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		bip = bp->b_fspriv;
 | 
			
		||||
		bip->bli_recur++;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -356,17 +289,29 @@ xfs_trans_read_buf_map(
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
 | 
			
		||||
	if (bp == NULL) {
 | 
			
		||||
		*bpp = NULL;
 | 
			
		||||
		return (flags & XBF_TRYLOCK) ?
 | 
			
		||||
					0 : -ENOMEM;
 | 
			
		||||
	if (!bp) {
 | 
			
		||||
		if (!(flags & XBF_TRYLOCK))
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
		return tp ? 0 : -EAGAIN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If we've had a read error, then the contents of the buffer are
 | 
			
		||||
	 * invalid and should not be used. To ensure that a followup read tries
 | 
			
		||||
	 * to pull the buffer from disk again, we clear the XBF_DONE flag and
 | 
			
		||||
	 * mark the buffer stale. This ensures that anyone who has a current
 | 
			
		||||
	 * reference to the buffer will interpret it's contents correctly and
 | 
			
		||||
	 * future cache lookups will also treat it as an empty, uninitialised
 | 
			
		||||
	 * buffer.
 | 
			
		||||
	 */
 | 
			
		||||
	if (bp->b_error) {
 | 
			
		||||
		error = bp->b_error;
 | 
			
		||||
		if (!XFS_FORCED_SHUTDOWN(mp))
 | 
			
		||||
			xfs_buf_ioerror_alert(bp, __func__);
 | 
			
		||||
		bp->b_flags &= ~XBF_DONE;
 | 
			
		||||
		xfs_buf_stale(bp);
 | 
			
		||||
		XFS_BUF_DONE(bp);
 | 
			
		||||
		xfs_buf_ioerror_alert(bp, __func__);
 | 
			
		||||
		if (tp->t_flags & XFS_TRANS_DIRTY)
 | 
			
		||||
 | 
			
		||||
		if (tp && (tp->t_flags & XFS_TRANS_DIRTY))
 | 
			
		||||
			xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
 | 
			
		||||
		xfs_buf_relse(bp);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -375,33 +320,19 @@ xfs_trans_read_buf_map(
 | 
			
		|||
			error = -EFSCORRUPTED;
 | 
			
		||||
		return error;
 | 
			
		||||
	}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if (xfs_do_error && !(tp->t_flags & XFS_TRANS_DIRTY)) {
 | 
			
		||||
		if (xfs_error_target == target) {
 | 
			
		||||
			if (((xfs_req_num++) % xfs_error_mod) == 0) {
 | 
			
		||||
				xfs_force_shutdown(tp->t_mountp,
 | 
			
		||||
						   SHUTDOWN_META_IO_ERROR);
 | 
			
		||||
				xfs_buf_relse(bp);
 | 
			
		||||
				xfs_debug(mp, "Returning trans error!");
 | 
			
		||||
				return -EIO;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	if (XFS_FORCED_SHUTDOWN(mp)) {
 | 
			
		||||
		xfs_buf_relse(bp);
 | 
			
		||||
		trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
 | 
			
		||||
		return -EIO;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	if (XFS_FORCED_SHUTDOWN(mp))
 | 
			
		||||
		goto shutdown_abort;
 | 
			
		||||
 | 
			
		||||
	_xfs_trans_bjoin(tp, bp, 1);
 | 
			
		||||
	if (tp)
 | 
			
		||||
		_xfs_trans_bjoin(tp, bp, 1);
 | 
			
		||||
	trace_xfs_trans_read_buf(bp->b_fspriv);
 | 
			
		||||
 | 
			
		||||
	*bpp = bp;
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
shutdown_abort:
 | 
			
		||||
	trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
 | 
			
		||||
	xfs_buf_relse(bp);
 | 
			
		||||
	*bpp = NULL;
 | 
			
		||||
	return -EIO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue