Commit 6d200bdc authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

Merge tag 'make-attr-fork-permanent-5.20_2022-07-14' of...

Merge tag 'make-attr-fork-permanent-5.20_2022-07-14' of git://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux

 into xfs-5.20-mergeB

xfs: make attr forks permanent

This series fixes a use-after-free bug that syzbot uncovered.  The UAF
itself is a result of a race condition between getxattr and removexattr
because callers to getxattr do not necessarily take any sort of locks
before calling into the filesystem.

Although the race condition itself can be fixed through clever use of a
memory barrier, further consideration of the use cases of extended
attributes shows that most files always have at least one attribute, so
we might as well make them permanent.

v2: Minor tweaks suggested by Dave, and convert some more macros to
helper functions.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>

* tag 'make-attr-fork-permanent-5.20_2022-07-14' of git://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: replace inode fork size macros with functions
  xfs: replace XFS_IFORK_Q with a proper predicate function
  xfs: use XFS_IFORK_Q to determine the presence of an xattr fork
  xfs: make inode attribute forks a permanent part of struct xfs_inode
  xfs: convert XFS_IFORK_PTR to a static inline helper
parents 35c5a09f c01147d9
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -67,12 +67,10 @@ int
xfs_inode_hasattr(
	struct xfs_inode	*ip)
{
	if (!XFS_IFORK_Q(ip))
	if (!xfs_inode_has_attr_fork(ip))
		return 0;
	if (!ip->i_afp)
		return 0;
	if (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
	    ip->i_afp->if_nextents == 0)
	if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
	    ip->i_af.if_nextents == 0)
		return 0;
	return 1;
}
@@ -85,7 +83,7 @@ bool
xfs_attr_is_leaf(
	struct xfs_inode	*ip)
{
	struct xfs_ifork	*ifp = ip->i_afp;
	struct xfs_ifork	*ifp = &ip->i_af;
	struct xfs_iext_cursor	icur;
	struct xfs_bmbt_irec	imap;

@@ -231,7 +229,7 @@ xfs_attr_get_ilocked(
	if (!xfs_inode_hasattr(args->dp))
		return -ENOATTR;

	if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
	if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
		return xfs_attr_shortform_getvalue(args);
	if (xfs_attr_is_leaf(args->dp))
		return xfs_attr_leaf_get(args);
@@ -354,7 +352,7 @@ xfs_attr_try_sf_addname(
	/*
	 * Build initial attribute list (if required).
	 */
	if (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS)
	if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
		xfs_attr_shortform_create(args);

	error = xfs_attr_shortform_addname(args);
@@ -864,7 +862,7 @@ xfs_attr_lookup(
	if (!xfs_inode_hasattr(dp))
		return -ENOATTR;

	if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
	if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
		return xfs_attr_sf_findname(args, NULL, NULL);

	if (xfs_attr_is_leaf(dp)) {
@@ -1001,7 +999,7 @@ xfs_attr_set(
		 * If the inode doesn't have an attribute fork, add one.
		 * (inode must not be locked when we call this routine)
		 */
		if (XFS_IFORK_Q(dp) == 0) {
		if (xfs_inode_has_attr_fork(dp) == 0) {
			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
				xfs_attr_sf_entsize_byname(args->namelen,
						args->valuelen);
@@ -1101,7 +1099,7 @@ static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
{
	struct xfs_attr_shortform *sf;

	sf = (struct xfs_attr_shortform *)dp->i_afp->if_u1.if_data;
	sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
	return be16_to_cpu(sf->hdr.totsize);
}

+5 −5
Original line number Diff line number Diff line
@@ -560,9 +560,9 @@ static inline bool
xfs_attr_is_shortform(
	struct xfs_inode    *ip)
{
	return ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL ||
	       (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
		ip->i_afp->if_nextents == 0);
	return ip->i_af.if_format == XFS_DINODE_FMT_LOCAL ||
	       (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
		ip->i_af.if_nextents == 0);
}

static inline enum xfs_delattr_state
@@ -573,10 +573,10 @@ xfs_attr_init_add_state(struct xfs_da_args *args)
	 * next state, the attribute fork may be null. This can occur only occur
	 * on a pure remove, but we grab the next state before we check if a
	 * replace operation is being performed. If we are called from any other
	 * context, i_afp is guaranteed to exist. Hence if the attr fork is
	 * context, i_af is guaranteed to exist. Hence if the attr fork is
	 * null, we were called from a pure remove operation and so we are done.
	 */
	if (!args->dp->i_afp)
	if (!xfs_inode_has_attr_fork(args->dp))
		return XFS_DAS_DONE;

	args->op_flags |= XFS_DA_OP_ADDNAME;
+14 −15
Original line number Diff line number Diff line
@@ -590,7 +590,7 @@ xfs_attr_shortform_bytesfit(
	 * to real extents, or the delalloc conversion will take care of the
	 * literal area rebalancing.
	 */
	if (bytes <= XFS_IFORK_ASIZE(dp))
	if (bytes <= xfs_inode_attr_fork_size(dp))
		return dp->i_forkoff;

	/*
@@ -682,7 +682,7 @@ xfs_attr_shortform_create(
	struct xfs_da_args	*args)
{
	struct xfs_inode	*dp = args->dp;
	struct xfs_ifork	*ifp = dp->i_afp;
	struct xfs_ifork	*ifp = &dp->i_af;
	struct xfs_attr_sf_hdr	*hdr;

	trace_xfs_attr_sf_create(args);
@@ -719,7 +719,7 @@ xfs_attr_sf_findname(
	int			end;
	int			i;

	sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data;
	sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
	sfe = &sf->list[0];
	end = sf->hdr.count;
	for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
@@ -764,7 +764,7 @@ xfs_attr_shortform_add(
	mp = dp->i_mount;
	dp->i_forkoff = forkoff;

	ifp = dp->i_afp;
	ifp = &dp->i_af;
	ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
	sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
	if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
@@ -797,11 +797,10 @@ xfs_attr_fork_remove(
	struct xfs_inode	*ip,
	struct xfs_trans	*tp)
{
	ASSERT(ip->i_afp->if_nextents == 0);
	ASSERT(ip->i_af.if_nextents == 0);

	xfs_idestroy_fork(ip->i_afp);
	kmem_cache_free(xfs_ifork_cache, ip->i_afp);
	ip->i_afp = NULL;
	xfs_idestroy_fork(&ip->i_af);
	xfs_ifork_zap_attr(ip);
	ip->i_forkoff = 0;
	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
}
@@ -825,7 +824,7 @@ xfs_attr_sf_removename(

	dp = args->dp;
	mp = dp->i_mount;
	sf = (struct xfs_attr_shortform *)dp->i_afp->if_u1.if_data;
	sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;

	error = xfs_attr_sf_findname(args, &sfe, &base);

@@ -889,7 +888,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)

	trace_xfs_attr_sf_lookup(args);

	ifp = args->dp->i_afp;
	ifp = &args->dp->i_af;
	ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
	sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
	sfe = &sf->list[0];
@@ -917,8 +916,8 @@ xfs_attr_shortform_getvalue(
	struct xfs_attr_sf_entry *sfe;
	int			i;

	ASSERT(args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL);
	sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data;
	ASSERT(args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL);
	sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
	sfe = &sf->list[0];
	for (i = 0; i < sf->hdr.count;
				sfe = xfs_attr_sf_nextentry(sfe), i++) {
@@ -948,7 +947,7 @@ xfs_attr_shortform_to_leaf(
	trace_xfs_attr_sf_to_leaf(args);

	dp = args->dp;
	ifp = dp->i_afp;
	ifp = &dp->i_af;
	sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
	size = be16_to_cpu(sf->hdr.totsize);
	tmpbuffer = kmem_alloc(size, 0);
@@ -1055,8 +1054,8 @@ xfs_attr_shortform_verify(
	int				i;
	int64_t				size;

	ASSERT(ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL);
	ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK);
	ASSERT(ip->i_af.if_format == XFS_DINODE_FMT_LOCAL);
	ifp = xfs_ifork_ptr(ip, XFS_ATTR_FORK);
	sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
	size = ifp->if_bytes;

+40 −41
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ xfs_bmbt_lookup_first(
 */
static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
{
	struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);

	return whichfork != XFS_COW_FORK &&
		ifp->if_format == XFS_DINODE_FMT_EXTENTS &&
@@ -140,7 +140,7 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
 */
static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
{
	struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);

	return whichfork != XFS_COW_FORK &&
		ifp->if_format == XFS_DINODE_FMT_BTREE &&
@@ -319,7 +319,7 @@ xfs_bmap_check_leaf_extents(
	int			whichfork)	/* data or attr fork */
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_btree_block	*block;	/* current btree block */
	xfs_fsblock_t		bno;	/* block # of "block" */
	struct xfs_buf		*bp;	/* buffer for "block" */
@@ -538,7 +538,7 @@ xfs_bmap_btree_to_extents(
	int			*logflagsp, /* inode logging flags */
	int			whichfork)  /* data or attr fork */
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_btree_block	*rblock = ifp->if_broot;
	struct xfs_btree_block	*cblock;/* child btree block */
@@ -616,7 +616,7 @@ xfs_bmap_extents_to_btree(

	mp = ip->i_mount;
	ASSERT(whichfork != XFS_COW_FORK);
	ifp = XFS_IFORK_PTR(ip, whichfork);
	ifp = xfs_ifork_ptr(ip, whichfork);
	ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS);

	/*
@@ -745,7 +745,7 @@ xfs_bmap_local_to_extents_empty(
	struct xfs_inode	*ip,
	int			whichfork)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);

	ASSERT(whichfork != XFS_COW_FORK);
	ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
@@ -785,7 +785,7 @@ xfs_bmap_local_to_extents(
	 * So sending the data fork of a regular inode is invalid.
	 */
	ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK));
	ifp = XFS_IFORK_PTR(ip, whichfork);
	ifp = xfs_ifork_ptr(ip, whichfork);
	ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);

	if (!ifp->if_bytes) {
@@ -880,7 +880,7 @@ xfs_bmap_add_attrfork_btree(

	mp = ip->i_mount;

	if (XFS_BMAP_BMDR_SPACE(block) <= XFS_IFORK_DSIZE(ip))
	if (XFS_BMAP_BMDR_SPACE(block) <= xfs_inode_data_fork_size(ip))
		*flags |= XFS_ILOG_DBROOT;
	else {
		cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK);
@@ -920,7 +920,7 @@ xfs_bmap_add_attrfork_extents(
	int			error;		/* error return value */

	if (ip->i_df.if_nextents * sizeof(struct xfs_bmbt_rec) <=
	    XFS_IFORK_DSIZE(ip))
	    xfs_inode_data_fork_size(ip))
		return 0;
	cur = NULL;
	error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags,
@@ -951,7 +951,7 @@ xfs_bmap_add_attrfork_local(
{
	struct xfs_da_args	dargs;		/* args for dir/attr code */

	if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
	if (ip->i_df.if_bytes <= xfs_inode_data_fork_size(ip))
		return 0;

	if (S_ISDIR(VFS_I(ip)->i_mode)) {
@@ -1023,7 +1023,7 @@ xfs_bmap_add_attrfork(
	int			logflags;	/* logging flags */
	int			error;		/* error return value */

	ASSERT(XFS_IFORK_Q(ip) == 0);
	ASSERT(xfs_inode_has_attr_fork(ip) == 0);

	mp = ip->i_mount;
	ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
@@ -1034,16 +1034,15 @@ xfs_bmap_add_attrfork(
			rsvd, &tp);
	if (error)
		return error;
	if (XFS_IFORK_Q(ip))
	if (xfs_inode_has_attr_fork(ip))
		goto trans_cancel;

	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
	error = xfs_bmap_set_attrforkoff(ip, size, &version);
	if (error)
		goto trans_cancel;
	ASSERT(ip->i_afp == NULL);

	ip->i_afp = xfs_ifork_alloc(XFS_DINODE_FMT_EXTENTS, 0);
	xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0);
	logflags = 0;
	switch (ip->i_df.if_format) {
	case XFS_DINODE_FMT_LOCAL:
@@ -1116,7 +1115,7 @@ xfs_iread_bmbt_block(
	xfs_extnum_t		num_recs;
	xfs_extnum_t		j;
	int			whichfork = cur->bc_ino.whichfork;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);

	block = xfs_btree_get_block(cur, level, &bp);

@@ -1164,7 +1163,7 @@ xfs_iread_extents(
	int			whichfork)
{
	struct xfs_iread_state	ir;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_btree_cur	*cur;
	int			error;
@@ -1208,7 +1207,7 @@ xfs_bmap_first_unused(
	xfs_fileoff_t		*first_unused,	/* unused block */
	int			whichfork)	/* data or attr fork */
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_bmbt_irec	got;
	struct xfs_iext_cursor	icur;
	xfs_fileoff_t		lastaddr = 0;
@@ -1255,7 +1254,7 @@ xfs_bmap_last_before(
	xfs_fileoff_t		*last_block,	/* last block */
	int			whichfork)	/* data or attr fork */
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_bmbt_irec	got;
	struct xfs_iext_cursor	icur;
	int			error;
@@ -1289,7 +1288,7 @@ xfs_bmap_last_extent(
	struct xfs_bmbt_irec	*rec,
	int			*is_empty)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_iext_cursor	icur;
	int			error;

@@ -1355,7 +1354,7 @@ xfs_bmap_last_offset(
	xfs_fileoff_t		*last_block,
	int			whichfork)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_bmbt_irec	rec;
	int			is_empty;
	int			error;
@@ -1389,7 +1388,7 @@ xfs_bmap_add_extent_delay_real(
	int			whichfork)
{
	struct xfs_mount	*mp = bma->ip->i_mount;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(bma->ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(bma->ip, whichfork);
	struct xfs_bmbt_irec	*new = &bma->got;
	int			error;	/* error return value */
	int			i;	/* temp state */
@@ -1955,7 +1954,7 @@ xfs_bmap_add_extent_unwritten_real(
	*logflagsp = 0;

	cur = *curp;
	ifp = XFS_IFORK_PTR(ip, whichfork);
	ifp = xfs_ifork_ptr(ip, whichfork);

	ASSERT(!isnullstartblock(new->br_startblock));

@@ -2480,7 +2479,7 @@ xfs_bmap_add_extent_hole_delay(
	uint32_t		state = xfs_bmap_fork_to_state(whichfork);
	xfs_filblks_t		temp;	 /* temp for indirect calculations */

	ifp = XFS_IFORK_PTR(ip, whichfork);
	ifp = xfs_ifork_ptr(ip, whichfork);
	ASSERT(isnullstartblock(new->br_startblock));

	/*
@@ -2616,7 +2615,7 @@ xfs_bmap_add_extent_hole_real(
	int			*logflagsp,
	uint32_t		flags)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_btree_cur	*cur = *curp;
	int			error;	/* error return value */
@@ -3867,7 +3866,7 @@ xfs_bmapi_read(
{
	struct xfs_mount	*mp = ip->i_mount;
	int			whichfork = xfs_bmapi_whichfork(flags);
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_bmbt_irec	got;
	xfs_fileoff_t		obno;
	xfs_fileoff_t		end;
@@ -3960,7 +3959,7 @@ xfs_bmapi_reserve_delalloc(
	int			eof)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	xfs_extlen_t		alen;
	xfs_extlen_t		indlen;
	int			error;
@@ -4087,7 +4086,7 @@ xfs_bmapi_allocate(
{
	struct xfs_mount	*mp = bma->ip->i_mount;
	int			whichfork = xfs_bmapi_whichfork(bma->flags);
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(bma->ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(bma->ip, whichfork);
	int			tmp_logflags = 0;
	int			error;

@@ -4186,7 +4185,7 @@ xfs_bmapi_convert_unwritten(
	uint32_t		flags)
{
	int			whichfork = xfs_bmapi_whichfork(flags);
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(bma->ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(bma->ip, whichfork);
	int			tmp_logflags = 0;
	int			error;

@@ -4263,7 +4262,7 @@ xfs_bmapi_minleft(
	struct xfs_inode	*ip,
	int			fork)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, fork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, fork);

	if (tp && tp->t_firstblock != NULLFSBLOCK)
		return 0;
@@ -4284,7 +4283,7 @@ xfs_bmapi_finish(
	int			whichfork,
	int			error)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(bma->ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(bma->ip, whichfork);

	if ((bma->logflags & xfs_ilog_fext(whichfork)) &&
	    ifp->if_format != XFS_DINODE_FMT_EXTENTS)
@@ -4323,7 +4322,7 @@ xfs_bmapi_write(
	};
	struct xfs_mount	*mp = ip->i_mount;
	int			whichfork = xfs_bmapi_whichfork(flags);
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	xfs_fileoff_t		end;		/* end of mapped file region */
	bool			eof = false;	/* after the end of extents */
	int			error;		/* error return */
@@ -4504,7 +4503,7 @@ xfs_bmapi_convert_delalloc(
	struct iomap		*iomap,
	unsigned int		*seq)
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_mount	*mp = ip->i_mount;
	xfs_fileoff_t		offset_fsb = XFS_B_TO_FSBT(mp, offset);
	struct xfs_bmalloca	bma = { NULL };
@@ -4641,7 +4640,7 @@ xfs_bmapi_remap(
	int			whichfork = xfs_bmapi_whichfork(flags);
	int			logflags = 0, error;

	ifp = XFS_IFORK_PTR(ip, whichfork);
	ifp = xfs_ifork_ptr(ip, whichfork);
	ASSERT(len > 0);
	ASSERT(len <= (xfs_filblks_t)XFS_MAX_BMBT_EXTLEN);
	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
@@ -4798,7 +4797,7 @@ xfs_bmap_del_extent_delay(
	struct xfs_bmbt_irec	*del)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_bmbt_irec	new;
	int64_t			da_old, da_new, da_diff = 0;
	xfs_fileoff_t		del_endoff, got_endoff;
@@ -4925,7 +4924,7 @@ xfs_bmap_del_extent_cow(
	struct xfs_bmbt_irec	*del)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, XFS_COW_FORK);
	struct xfs_bmbt_irec	new;
	xfs_fileoff_t		del_endoff, got_endoff;
	uint32_t		state = BMAP_COWFORK;
@@ -5023,7 +5022,7 @@ xfs_bmap_del_extent_real(
	mp = ip->i_mount;
	XFS_STATS_INC(mp, xs_del_exlist);

	ifp = XFS_IFORK_PTR(ip, whichfork);
	ifp = xfs_ifork_ptr(ip, whichfork);
	ASSERT(del->br_blockcount > 0);
	xfs_iext_get_extent(ifp, icur, &got);
	ASSERT(got.br_startoff <= del->br_startoff);
@@ -5289,7 +5288,7 @@ __xfs_bunmapi(

	whichfork = xfs_bmapi_whichfork(flags);
	ASSERT(whichfork != XFS_COW_FORK);
	ifp = XFS_IFORK_PTR(ip, whichfork);
	ifp = xfs_ifork_ptr(ip, whichfork);
	if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)))
		return -EFSCORRUPTED;
	if (xfs_is_shutdown(mp))
@@ -5630,7 +5629,7 @@ xfs_bmse_merge(
	struct xfs_btree_cur		*cur,
	int				*logflags)	/* output */
{
	struct xfs_ifork		*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork		*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_bmbt_irec		new;
	xfs_filblks_t			blockcount;
	int				error, i;
@@ -5751,7 +5750,7 @@ xfs_bmap_collapse_extents(
{
	int			whichfork = XFS_DATA_FORK;
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_btree_cur	*cur = NULL;
	struct xfs_bmbt_irec	got, prev;
	struct xfs_iext_cursor	icur;
@@ -5866,7 +5865,7 @@ xfs_bmap_insert_extents(
{
	int			whichfork = XFS_DATA_FORK;
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_btree_cur	*cur = NULL;
	struct xfs_bmbt_irec	got, next;
	struct xfs_iext_cursor	icur;
@@ -5966,7 +5965,7 @@ xfs_bmap_split_extent(
	xfs_fileoff_t		split_fsb)
{
	int				whichfork = XFS_DATA_FORK;
	struct xfs_ifork		*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork		*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_btree_cur		*cur = NULL;
	struct xfs_bmbt_irec		got;
	struct xfs_bmbt_irec		new; /* split extent */
+5 −5
Original line number Diff line number Diff line
@@ -304,7 +304,7 @@ xfs_bmbt_get_minrecs(
	if (level == cur->bc_nlevels - 1) {
		struct xfs_ifork	*ifp;

		ifp = XFS_IFORK_PTR(cur->bc_ino.ip,
		ifp = xfs_ifork_ptr(cur->bc_ino.ip,
				    cur->bc_ino.whichfork);

		return xfs_bmbt_maxrecs(cur->bc_mp,
@@ -322,7 +322,7 @@ xfs_bmbt_get_maxrecs(
	if (level == cur->bc_nlevels - 1) {
		struct xfs_ifork	*ifp;

		ifp = XFS_IFORK_PTR(cur->bc_ino.ip,
		ifp = xfs_ifork_ptr(cur->bc_ino.ip,
				    cur->bc_ino.whichfork);

		return xfs_bmbt_maxrecs(cur->bc_mp,
@@ -550,7 +550,7 @@ xfs_bmbt_init_cursor(
	struct xfs_inode	*ip,		/* inode owning the btree */
	int			whichfork)	/* data or attr fork */
{
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);
	struct xfs_btree_cur	*cur;
	ASSERT(whichfork != XFS_COW_FORK);

@@ -564,7 +564,7 @@ xfs_bmbt_init_cursor(
	if (xfs_has_crc(mp))
		cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;

	cur->bc_ino.forksize = XFS_IFORK_SIZE(ip, whichfork);
	cur->bc_ino.forksize = xfs_inode_fork_size(ip, whichfork);
	cur->bc_ino.ip = ip;
	cur->bc_ino.allocated = 0;
	cur->bc_ino.flags = 0;
@@ -664,7 +664,7 @@ xfs_bmbt_change_owner(

	ASSERT(tp || buffer_list);
	ASSERT(!(tp && buffer_list));
	ASSERT(XFS_IFORK_PTR(ip, whichfork)->if_format == XFS_DINODE_FMT_BTREE);
	ASSERT(xfs_ifork_ptr(ip, whichfork)->if_format == XFS_DINODE_FMT_BTREE);

	cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork);
	cur->bc_ino.flags |= XFS_BTCUR_BMBT_INVALID_OWNER;
Loading