xfs: factor out attr fork reset handling

We currently duplicate code to reset the attribute fork after the last
attribute has been deleted.  Factor this out into a small helper.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Felix Blyakher <felixb@sgi.com>
This commit is contained in:
Christoph Hellwig 2009-02-04 09:36:00 +01:00 committed by Christoph Hellwig
parent c52e9fd8a9
commit e1486dea0b
1 changed files with 25 additions and 30 deletions

View File

@ -297,6 +297,26 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
xfs_sbversion_add_attr2(mp, args->trans);
}
/*
* After the last attribute is removed revert to original inode format,
* making all literal area available to the data fork once more.
*/
STATIC void
xfs_attr_fork_reset(
struct xfs_inode *ip,
struct xfs_trans *tp)
{
xfs_idestroy_fork(ip, XFS_ATTR_FORK);
ip->i_d.di_forkoff = 0;
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
ASSERT(ip->i_d.di_anextents == 0);
ASSERT(ip->i_afp == NULL);
ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
}
/*
* Remove an attribute from the shortform attribute list structure.
*/
@ -344,22 +364,10 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
*/
totsize -= size;
if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
!(args->op_flags & XFS_DA_OP_ADDNAME) &&
(mp->m_flags & XFS_MOUNT_ATTR2) &&
(dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) {
/*
* Last attribute now removed, revert to original
* inode format making all literal area available
* to the data fork once more.
*/
xfs_idestroy_fork(dp, XFS_ATTR_FORK);
dp->i_d.di_forkoff = 0;
dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
ASSERT(dp->i_d.di_anextents == 0);
ASSERT(dp->i_afp == NULL);
dp->i_df.if_ext_max =
XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
(mp->m_flags & XFS_MOUNT_ATTR2) &&
(dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
!(args->op_flags & XFS_DA_OP_ADDNAME)) {
xfs_attr_fork_reset(dp, args->trans);
} else {
xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
@ -786,20 +794,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
if (forkoff == -1) {
ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
/*
* Last attribute was removed, revert to original
* inode format making all literal area available
* to the data fork once more.
*/
xfs_idestroy_fork(dp, XFS_ATTR_FORK);
dp->i_d.di_forkoff = 0;
dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
ASSERT(dp->i_d.di_anextents == 0);
ASSERT(dp->i_afp == NULL);
dp->i_df.if_ext_max =
XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
xfs_attr_fork_reset(dp, args->trans);
goto out;
}