Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8186e517 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Lachlan McIlroy
Browse files

[XFS] make btree root in inode support generic



The bmap btree is rooted in the inode and not in a disk block. Make the
support for this feature more generic by adding a btree flag to for this
feature instead of relying on the XFS_BTNUM_BMAP btnum check.

Also clean up xfs_btree_get_block where this new flag is used.

Based upon a patch from Dave Chinner.

SGI-PV: 985583

SGI-Modid: xfs-linux-melb:xfs-kern:32180a

Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: default avatarBill O'Donnell <billodo@sgi.com>
Signed-off-by: default avatarDavid Chinner <david@fromorbit.com>
parent de227dd9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2656,6 +2656,7 @@ xfs_bmbt_init_cursor(
	cur->bc_blocklog = mp->m_sb.sb_blocklog;

	cur->bc_ops = &xfs_bmbt_ops;
	cur->bc_flags = XFS_BTREE_ROOT_IN_INODE;

	cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
	cur->bc_private.b.ip = ip;
+27 −20
Original line number Diff line number Diff line
@@ -421,33 +421,40 @@ xfs_btree_dup_cursor(
	return 0;
}

/*
 * Get a the root block which is stored in the inode.
 *
 * For now this btree implementation assumes the btree root is always
 * stored in the if_broot field of an inode fork.
 */
STATIC struct xfs_btree_block *
xfs_btree_get_iroot(
       struct xfs_btree_cur    *cur)
{
       struct xfs_ifork        *ifp;

       ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork);
       return (struct xfs_btree_block *)ifp->if_broot;
}

/*
 * Retrieve the block pointer from the cursor at the given level.
 * This may be a bmap btree root or from a buffer.
 * This may be an inode btree root or from a buffer.
 */
STATIC xfs_btree_block_t *		/* generic btree block pointer */
STATIC struct xfs_btree_block *		/* generic btree block pointer */
xfs_btree_get_block(
	xfs_btree_cur_t		*cur,	/* btree cursor */
	struct xfs_btree_cur	*cur,	/* btree cursor */
	int			level,	/* level in btree */
	xfs_buf_t		**bpp)	/* buffer containing the block */
	struct xfs_buf		**bpp)	/* buffer containing the block */
{
	xfs_btree_block_t	*block;	/* return value */
	xfs_buf_t		*bp;	/* return buffer */
	xfs_ifork_t		*ifp;	/* inode fork pointer */
	int			whichfork; /* data or attr fork */

	if (cur->bc_btnum == XFS_BTNUM_BMAP && level == cur->bc_nlevels - 1) {
		whichfork = cur->bc_private.b.whichfork;
		ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, whichfork);
		block = (xfs_btree_block_t *)ifp->if_broot;
		bp = NULL;
	} else {
		bp = cur->bc_bufs[level];
		block = XFS_BUF_TO_BLOCK(bp);
	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
	    (level == cur->bc_nlevels - 1)) {
		*bpp = NULL;
		return xfs_btree_get_iroot(cur);
	}
	ASSERT(block != NULL);
	*bpp = bp;
	return block;

	*bpp = cur->bc_bufs[level];
	return XFS_BUF_TO_BLOCK(*bpp);
}

/*
+5 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ typedef struct xfs_btree_cur
	struct xfs_trans	*bc_tp;	/* transaction we're in, if any */
	struct xfs_mount	*bc_mp;	/* file system mount struct */
	const struct xfs_btree_ops *bc_ops;
	uint			bc_flags; /* btree features - below */
	union {
		xfs_alloc_rec_incore_t	a;
		xfs_bmbt_irec_t		b;
@@ -201,6 +202,10 @@ typedef struct xfs_btree_cur
	}		bc_private;	/* per-btree type data */
} xfs_btree_cur_t;

/* cursor flags */
#define XFS_BTREE_ROOT_IN_INODE		(1<<1)	/* root may be variable size */


#define	XFS_BTREE_NOERROR	0
#define	XFS_BTREE_ERROR		1