mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
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: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
2d6dcc6d7e
commit
0650b55497
@ -88,6 +88,7 @@ xfs_attr_args_init(
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
memset(args, 0, sizeof(*args));
|
memset(args, 0, sizeof(*args));
|
||||||
|
args->geo = dp->i_mount->m_attr_geo;
|
||||||
args->whichfork = XFS_ATTR_FORK;
|
args->whichfork = XFS_ATTR_FORK;
|
||||||
args->dp = dp;
|
args->dp = dp;
|
||||||
args->flags = flags;
|
args->flags = flags;
|
||||||
|
@ -711,6 +711,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
|
|||||||
|
|
||||||
memset((char *)&nargs, 0, sizeof(nargs));
|
memset((char *)&nargs, 0, sizeof(nargs));
|
||||||
nargs.dp = dp;
|
nargs.dp = dp;
|
||||||
|
nargs.geo = args->geo;
|
||||||
nargs.firstblock = args->firstblock;
|
nargs.firstblock = args->firstblock;
|
||||||
nargs.flist = args->flist;
|
nargs.flist = args->flist;
|
||||||
nargs.total = args->total;
|
nargs.total = args->total;
|
||||||
@ -838,6 +839,7 @@ xfs_attr3_leaf_to_shortform(
|
|||||||
* Copy the attributes
|
* Copy the attributes
|
||||||
*/
|
*/
|
||||||
memset((char *)&nargs, 0, sizeof(nargs));
|
memset((char *)&nargs, 0, sizeof(nargs));
|
||||||
|
nargs.geo = args->geo;
|
||||||
nargs.dp = dp;
|
nargs.dp = dp;
|
||||||
nargs.firstblock = args->firstblock;
|
nargs.firstblock = args->firstblock;
|
||||||
nargs.flist = args->flist;
|
nargs.flist = args->flist;
|
||||||
|
@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int(
|
|||||||
xfs_da_args_t args;
|
xfs_da_args_t args;
|
||||||
|
|
||||||
memset((char *)&args, 0, sizeof(args));
|
memset((char *)&args, 0, sizeof(args));
|
||||||
|
args.geo = context->dp->i_mount->m_attr_geo;
|
||||||
args.dp = context->dp;
|
args.dp = context->dp;
|
||||||
args.whichfork = XFS_ATTR_FORK;
|
args.whichfork = XFS_ATTR_FORK;
|
||||||
args.valuelen = valuelen;
|
args.valuelen = valuelen;
|
||||||
|
@ -25,6 +25,23 @@ struct xfs_trans;
|
|||||||
struct zone;
|
struct zone;
|
||||||
struct xfs_dir_ops;
|
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.
|
* Btree searching and modification structure definitions.
|
||||||
*========================================================================*/
|
*========================================================================*/
|
||||||
@ -42,6 +59,7 @@ enum xfs_dacmp {
|
|||||||
* Structure to ease passing around component names.
|
* Structure to ease passing around component names.
|
||||||
*/
|
*/
|
||||||
typedef struct xfs_da_args {
|
typedef struct xfs_da_args {
|
||||||
|
struct xfs_da_geometry *geo; /* da block geometry */
|
||||||
const __uint8_t *name; /* string (maybe not NULL terminated) */
|
const __uint8_t *name; /* string (maybe not NULL terminated) */
|
||||||
int namelen; /* length of string (maybe no NULL) */
|
int namelen; /* length of string (maybe no NULL) */
|
||||||
__uint8_t filetype; /* filetype of inode for directories */
|
__uint8_t filetype; /* filetype of inode for directories */
|
||||||
|
@ -85,11 +85,12 @@ static struct xfs_nameops xfs_ascii_ci_nameops = {
|
|||||||
.compname = xfs_ascii_ci_compname,
|
.compname = xfs_ascii_ci_compname,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
int
|
||||||
xfs_dir_mount(
|
xfs_da_mount(
|
||||||
xfs_mount_t *mp)
|
struct xfs_mount *mp)
|
||||||
{
|
{
|
||||||
int nodehdr_size;
|
struct xfs_da_geometry *dageo;
|
||||||
|
int nodehdr_size;
|
||||||
|
|
||||||
|
|
||||||
ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb));
|
ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb));
|
||||||
@ -99,24 +100,64 @@ xfs_dir_mount(
|
|||||||
mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
|
mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
|
||||||
mp->m_nondir_inode_ops = xfs_nondir_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;
|
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),
|
||||||
(uint)sizeof(xfs_da_node_entry_t);
|
KM_SLEEP | KM_MAYFAIL);
|
||||||
mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) /
|
mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
|
||||||
(uint)sizeof(xfs_da_node_entry_t);
|
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);
|
||||||
|
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))
|
if (xfs_sb_version_hasasciici(&mp->m_sb))
|
||||||
mp->m_dirnameops = &xfs_ascii_ci_nameops;
|
mp->m_dirnameops = &xfs_ascii_ci_nameops;
|
||||||
else
|
else
|
||||||
mp->m_dirnameops = &xfs_default_nameops;
|
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)
|
if (!args)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
args->geo = dp->i_mount->m_dir_geo;
|
||||||
args->dp = dp;
|
args->dp = dp;
|
||||||
args->trans = tp;
|
args->trans = tp;
|
||||||
error = xfs_dir2_sf_create(args, pdp->i_ino);
|
error = xfs_dir2_sf_create(args, pdp->i_ino);
|
||||||
@ -226,6 +268,7 @@ xfs_dir_createname(
|
|||||||
if (!args)
|
if (!args)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
args->geo = dp->i_mount->m_dir_geo;
|
||||||
args->name = name->name;
|
args->name = name->name;
|
||||||
args->namelen = name->len;
|
args->namelen = name->len;
|
||||||
args->filetype = name->type;
|
args->filetype = name->type;
|
||||||
@ -320,6 +363,7 @@ xfs_dir_lookup(
|
|||||||
* annotations into the reclaim path for the ilock.
|
* annotations into the reclaim path for the ilock.
|
||||||
*/
|
*/
|
||||||
args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
|
args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
|
||||||
|
args->geo = dp->i_mount->m_dir_geo;
|
||||||
args->name = name->name;
|
args->name = name->name;
|
||||||
args->namelen = name->len;
|
args->namelen = name->len;
|
||||||
args->filetype = name->type;
|
args->filetype = name->type;
|
||||||
@ -391,6 +435,7 @@ xfs_dir_removename(
|
|||||||
if (!args)
|
if (!args)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
args->geo = dp->i_mount->m_dir_geo;
|
||||||
args->name = name->name;
|
args->name = name->name;
|
||||||
args->namelen = name->len;
|
args->namelen = name->len;
|
||||||
args->filetype = name->type;
|
args->filetype = name->type;
|
||||||
@ -455,6 +500,7 @@ xfs_dir_replace(
|
|||||||
if (!args)
|
if (!args)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
args->geo = dp->i_mount->m_dir_geo;
|
||||||
args->name = name->name;
|
args->name = name->name;
|
||||||
args->namelen = name->len;
|
args->namelen = name->len;
|
||||||
args->filetype = name->type;
|
args->filetype = name->type;
|
||||||
@ -516,6 +562,7 @@ xfs_dir_canenter(
|
|||||||
if (!args)
|
if (!args)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
args->geo = dp->i_mount->m_dir_geo;
|
||||||
args->name = name->name;
|
args->name = name->name;
|
||||||
args->namelen = name->len;
|
args->namelen = name->len;
|
||||||
args->filetype = name->type;
|
args->filetype = name->type;
|
||||||
|
@ -112,7 +112,9 @@ extern const struct xfs_dir_ops *
|
|||||||
* Generic directory interface routines
|
* Generic directory interface routines
|
||||||
*/
|
*/
|
||||||
extern void xfs_dir_startup(void);
|
extern void xfs_dir_startup(void);
|
||||||
extern void xfs_dir_mount(struct xfs_mount *mp);
|
extern int xfs_da_mount(struct xfs_mount *mp);
|
||||||
|
extern void xfs_da_unmount(struct xfs_mount *mp);
|
||||||
|
|
||||||
extern int xfs_dir_isempty(struct xfs_inode *dp);
|
extern int xfs_dir_isempty(struct xfs_inode *dp);
|
||||||
extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
|
extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||||
struct xfs_inode *pdp);
|
struct xfs_inode *pdp);
|
||||||
|
@ -774,12 +774,11 @@ xfs_mountfs(
|
|||||||
|
|
||||||
mp->m_dmevmask = 0; /* not persistent; set after each mount */
|
mp->m_dmevmask = 0; /* not persistent; set after each mount */
|
||||||
|
|
||||||
xfs_dir_mount(mp);
|
error = xfs_da_mount(mp);
|
||||||
|
if (error) {
|
||||||
/*
|
xfs_warn(mp, "Failed dir/attr init: %d", error);
|
||||||
* Initialize the attribute manager's entries.
|
goto out_remove_uuid;
|
||||||
*/
|
}
|
||||||
mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the precomputed transaction reservations values.
|
* Initialize the precomputed transaction reservations values.
|
||||||
@ -794,7 +793,7 @@ xfs_mountfs(
|
|||||||
error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
|
error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
|
||||||
if (error) {
|
if (error) {
|
||||||
xfs_warn(mp, "Failed per-ag init: %d", error);
|
xfs_warn(mp, "Failed per-ag init: %d", error);
|
||||||
goto out_remove_uuid;
|
goto out_free_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sbp->sb_logblocks) {
|
if (!sbp->sb_logblocks) {
|
||||||
@ -969,6 +968,8 @@ xfs_mountfs(
|
|||||||
xfs_wait_buftarg(mp->m_ddev_targp);
|
xfs_wait_buftarg(mp->m_ddev_targp);
|
||||||
out_free_perag:
|
out_free_perag:
|
||||||
xfs_free_perag(mp);
|
xfs_free_perag(mp);
|
||||||
|
out_free_dir:
|
||||||
|
xfs_da_unmount(mp);
|
||||||
out_remove_uuid:
|
out_remove_uuid:
|
||||||
xfs_uuid_unmount(mp);
|
xfs_uuid_unmount(mp);
|
||||||
out:
|
out:
|
||||||
@ -1046,6 +1047,7 @@ xfs_unmountfs(
|
|||||||
"Freespace may not be correct on next mount.");
|
"Freespace may not be correct on next mount.");
|
||||||
|
|
||||||
xfs_log_unmount(mp);
|
xfs_log_unmount(mp);
|
||||||
|
xfs_da_unmount(mp);
|
||||||
xfs_uuid_unmount(mp);
|
xfs_uuid_unmount(mp);
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
|
@ -27,6 +27,7 @@ struct xfs_nameops;
|
|||||||
struct xfs_ail;
|
struct xfs_ail;
|
||||||
struct xfs_quotainfo;
|
struct xfs_quotainfo;
|
||||||
struct xfs_dir_ops;
|
struct xfs_dir_ops;
|
||||||
|
struct xfs_da_geometry;
|
||||||
|
|
||||||
#ifdef HAVE_PERCPU_SB
|
#ifdef HAVE_PERCPU_SB
|
||||||
|
|
||||||
@ -96,6 +97,8 @@ typedef struct xfs_mount {
|
|||||||
uint m_readio_blocks; /* min read size blocks */
|
uint m_readio_blocks; /* min read size blocks */
|
||||||
uint m_writeio_log; /* min write size log bytes */
|
uint m_writeio_log; /* min write size log bytes */
|
||||||
uint m_writeio_blocks; /* min write size blocks */
|
uint m_writeio_blocks; /* min write size blocks */
|
||||||
|
struct xfs_da_geometry *m_dir_geo; /* directory block geometry */
|
||||||
|
struct xfs_da_geometry *m_attr_geo; /* attribute block geometry */
|
||||||
struct xlog *m_log; /* log specific stuff */
|
struct xlog *m_log; /* log specific stuff */
|
||||||
int m_logbufs; /* number of log buffers */
|
int m_logbufs; /* number of log buffers */
|
||||||
int m_logbsize; /* size of each log buffer */
|
int m_logbsize; /* size of each log buffer */
|
||||||
|
Loading…
Reference in New Issue
Block a user