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

Commit 0650b554 authored by Dave Chinner's avatar Dave Chinner Committed by Dave Chinner
Browse files

xfs: introduce directory geometry structure



The directory code has a dependency on the struct xfs_mount to
supply the directory block geometry. Block size, block log size,
and other parameters are pre-caclulated in the struct xfs_mount or
access directly from the superblock embedded in the struct
xfs_mount.

Extract all of this geometry information out of the struct xfs_mount
and superblock and place it into a new struct xfs_da_geometry
defined by the directory code. Allocate and initialise it at mount
time, and attach it to the struct xfs_mount so it canbe passed back
into the directory code appropriately rather than using the struct
xfs_mount.

Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 2d6dcc6d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ xfs_attr_args_init(
		return EINVAL;

	memset(args, 0, sizeof(*args));
	args->geo = dp->i_mount->m_attr_geo;
	args->whichfork = XFS_ATTR_FORK;
	args->dp = dp;
	args->flags = flags;
+2 −0
Original line number Diff line number Diff line
@@ -711,6 +711,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)

	memset((char *)&nargs, 0, sizeof(nargs));
	nargs.dp = dp;
	nargs.geo = args->geo;
	nargs.firstblock = args->firstblock;
	nargs.flist = args->flist;
	nargs.total = args->total;
@@ -838,6 +839,7 @@ xfs_attr3_leaf_to_shortform(
	 * Copy the attributes
	 */
	memset((char *)&nargs, 0, sizeof(nargs));
	nargs.geo = args->geo;
	nargs.dp = dp;
	nargs.firstblock = args->firstblock;
	nargs.flist = args->flist;
+1 −0
Original line number Diff line number Diff line
@@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int(
				xfs_da_args_t args;

				memset((char *)&args, 0, sizeof(args));
				args.geo = context->dp->i_mount->m_attr_geo;
				args.dp = context->dp;
				args.whichfork = XFS_ATTR_FORK;
				args.valuelen = valuelen;
+18 −0
Original line number Diff line number Diff line
@@ -25,6 +25,23 @@ struct xfs_trans;
struct zone;
struct xfs_dir_ops;

/*
 * Directory/attribute geometry information. There will be one of these for each
 * data fork type, and it will be passed around via the xfs_da_args. Global
 * structures will be attached to the xfs_mount.
 */
struct xfs_da_geometry {
	int		blksize;	/* da block size in bytes */
	int		fsbcount;	/* da block size in filesystem blocks */
	uint8_t		fsblog;		/* log2 of _filesystem_ block size */
	uint8_t		blklog;		/* log2 of da block size */
	uint		node_ents;	/* # of entries in a danode */
	int		magicpct;	/* 37% of block size in bytes */
	xfs_dablk_t	datablk;	/* blockno of dir data v2 */
	xfs_dablk_t	leafblk;	/* blockno of leaf data v2 */
	xfs_dablk_t	freeblk;	/* blockno of free data v2 */
};

/*========================================================================
 * Btree searching and modification structure definitions.
 *========================================================================*/
@@ -42,6 +59,7 @@ enum xfs_dacmp {
 * Structure to ease passing around component names.
 */
typedef struct xfs_da_args {
	struct xfs_da_geometry *geo;	/* da block geometry */
	const __uint8_t	*name;		/* string (maybe not NULL terminated) */
	int		namelen;	/* length of string (maybe no NULL) */
	__uint8_t	filetype;	/* filetype of inode for directories */
+60 −13
Original line number Diff line number Diff line
@@ -85,10 +85,11 @@ static struct xfs_nameops xfs_ascii_ci_nameops = {
	.compname	= xfs_ascii_ci_compname,
};

void
xfs_dir_mount(
	xfs_mount_t	*mp)
int
xfs_da_mount(
	struct xfs_mount	*mp)
{
	struct xfs_da_geometry	*dageo;
	int			nodehdr_size;


@@ -99,24 +100,64 @@ xfs_dir_mount(
	mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
	mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL);

	mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
	mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog;
	mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp));
	mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp));
	mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp));

	nodehdr_size = mp->m_dir_inode_ops->node_hdr_size;
	mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - nodehdr_size) /
	mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
				    KM_SLEEP | KM_MAYFAIL);
	mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
				     KM_SLEEP | KM_MAYFAIL);
	if (!mp->m_dir_geo || !mp->m_attr_geo) {
		kmem_free(mp->m_dir_geo);
		kmem_free(mp->m_attr_geo);
		return ENOMEM;
	}

	/* set up directory geometry */
	dageo = mp->m_dir_geo;
	dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog;
	dageo->fsblog = mp->m_sb.sb_blocklog;
	dageo->blksize = 1 << dageo->blklog;
	dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
	dageo->datablk = xfs_dir2_byte_to_da(mp, XFS_DIR2_DATA_OFFSET);
	dageo->leafblk = xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET);
	dageo->freeblk = xfs_dir2_byte_to_da(mp, XFS_DIR2_FREE_OFFSET);
	dageo->node_ents = (dageo->blksize - nodehdr_size) /
				(uint)sizeof(xfs_da_node_entry_t);
	mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) /
	dageo->magicpct = (dageo->blksize * 37) / 100;

	/* set up attribute geometry - single fsb only */
	dageo = mp->m_attr_geo;
	dageo->blklog = mp->m_sb.sb_blocklog;
	dageo->fsblog = mp->m_sb.sb_blocklog;
	dageo->blksize = 1 << dageo->blklog;
	dageo->fsbcount = 1;
	dageo->node_ents = (dageo->blksize - nodehdr_size) /
				(uint)sizeof(xfs_da_node_entry_t);
	dageo->magicpct = (dageo->blksize * 37) / 100;

	mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100;
	if (xfs_sb_version_hasasciici(&mp->m_sb))
		mp->m_dirnameops = &xfs_ascii_ci_nameops;
	else
		mp->m_dirnameops = &xfs_default_nameops;

	/* XXX: these are to be removed as code is converted to use geo */
	mp->m_dirblksize = mp->m_dir_geo->blksize;
	mp->m_dirblkfsbs = mp->m_dir_geo->fsbcount;
	mp->m_dirdatablk = mp->m_dir_geo->datablk;
	mp->m_dirleafblk = mp->m_dir_geo->leafblk;
	mp->m_dirfreeblk = mp->m_dir_geo->freeblk;
	mp->m_dir_node_ents = mp->m_dir_geo->node_ents;
	mp->m_dir_magicpct = mp->m_dir_geo->magicpct;
	mp->m_attr_node_ents = mp->m_attr_geo->node_ents;
	mp->m_attr_magicpct = mp->m_attr_geo->magicpct;
	return 0;
}

void
xfs_da_unmount(
	struct xfs_mount	*mp)
{
	kmem_free(mp->m_dir_geo);
	kmem_free(mp->m_attr_geo);
}

/*
@@ -192,6 +233,7 @@ xfs_dir_init(
	if (!args)
		return ENOMEM;

	args->geo = dp->i_mount->m_dir_geo;
	args->dp = dp;
	args->trans = tp;
	error = xfs_dir2_sf_create(args, pdp->i_ino);
@@ -226,6 +268,7 @@ xfs_dir_createname(
	if (!args)
		return ENOMEM;

	args->geo = dp->i_mount->m_dir_geo;
	args->name = name->name;
	args->namelen = name->len;
	args->filetype = name->type;
@@ -320,6 +363,7 @@ xfs_dir_lookup(
	 * annotations into the reclaim path for the ilock.
	 */
	args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
	args->geo = dp->i_mount->m_dir_geo;
	args->name = name->name;
	args->namelen = name->len;
	args->filetype = name->type;
@@ -391,6 +435,7 @@ xfs_dir_removename(
	if (!args)
		return ENOMEM;

	args->geo = dp->i_mount->m_dir_geo;
	args->name = name->name;
	args->namelen = name->len;
	args->filetype = name->type;
@@ -455,6 +500,7 @@ xfs_dir_replace(
	if (!args)
		return ENOMEM;

	args->geo = dp->i_mount->m_dir_geo;
	args->name = name->name;
	args->namelen = name->len;
	args->filetype = name->type;
@@ -516,6 +562,7 @@ xfs_dir_canenter(
	if (!args)
		return ENOMEM;

	args->geo = dp->i_mount->m_dir_geo;
	args->name = name->name;
	args->namelen = name->len;
	args->filetype = name->type;
Loading