xfs: refactor xfs_inode_item_format
Split out a function to handle the data and attr fork, as well as a helper for the really old v1 inodes. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
ce9641d6c9
commit
3de559fbd0
|
@ -180,63 +180,41 @@ xfs_inode_item_format_extents(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called to fill in the vector of log iovecs for the
|
* If this is a v1 format inode, then we need to log it as such. This means
|
||||||
* given inode log item. It fills the first item with an inode
|
* that we have to copy the link count from the new field to the old. We
|
||||||
* log format structure, the second with the on-disk inode structure,
|
* don't have to worry about the new fields, because nothing trusts them as
|
||||||
* and a possible third and/or fourth with the inode data/extents/b-tree
|
* long as the old inode version number is there.
|
||||||
* root and inode attributes data/extents/b-tree root.
|
|
||||||
*/
|
*/
|
||||||
STATIC void
|
STATIC void
|
||||||
xfs_inode_item_format(
|
xfs_inode_item_format_v1_inode(
|
||||||
struct xfs_log_item *lip,
|
struct xfs_inode *ip)
|
||||||
struct xfs_log_iovec *vecp)
|
|
||||||
{
|
{
|
||||||
struct xfs_inode_log_item *iip = INODE_ITEM(lip);
|
if (!xfs_sb_version_hasnlink(&ip->i_mount->m_sb)) {
|
||||||
struct xfs_inode *ip = iip->ili_inode;
|
/*
|
||||||
uint nvecs;
|
* Convert it back.
|
||||||
size_t data_bytes;
|
*/
|
||||||
xfs_mount_t *mp;
|
ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
|
||||||
|
ip->i_d.di_onlink = ip->i_d.di_nlink;
|
||||||
vecp->i_addr = &iip->ili_format;
|
} else {
|
||||||
vecp->i_len = sizeof(xfs_inode_log_format_t);
|
/*
|
||||||
vecp->i_type = XLOG_REG_TYPE_IFORMAT;
|
* The superblock version has already been bumped,
|
||||||
vecp++;
|
* so just make the conversion to the new inode
|
||||||
nvecs = 1;
|
* format permanent.
|
||||||
|
*/
|
||||||
vecp->i_addr = &ip->i_d;
|
ip->i_d.di_version = 2;
|
||||||
vecp->i_len = xfs_icdinode_size(ip->i_d.di_version);
|
ip->i_d.di_onlink = 0;
|
||||||
vecp->i_type = XLOG_REG_TYPE_ICORE;
|
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
|
||||||
vecp++;
|
|
||||||
nvecs++;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If this is really an old format inode, then we need to
|
|
||||||
* log it as such. This means that we have to copy the link
|
|
||||||
* count from the new field to the old. We don't have to worry
|
|
||||||
* about the new fields, because nothing trusts them as long as
|
|
||||||
* the old inode version number is there. If the superblock already
|
|
||||||
* has a new version number, then we don't bother converting back.
|
|
||||||
*/
|
|
||||||
mp = ip->i_mount;
|
|
||||||
ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb));
|
|
||||||
if (ip->i_d.di_version == 1) {
|
|
||||||
if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
|
|
||||||
/*
|
|
||||||
* Convert it back.
|
|
||||||
*/
|
|
||||||
ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
|
|
||||||
ip->i_d.di_onlink = ip->i_d.di_nlink;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* The superblock version has already been bumped,
|
|
||||||
* so just make the conversion to the new inode
|
|
||||||
* format permanent.
|
|
||||||
*/
|
|
||||||
ip->i_d.di_version = 2;
|
|
||||||
ip->i_d.di_onlink = 0;
|
|
||||||
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC struct xfs_log_iovec *
|
||||||
|
xfs_inode_item_format_data_fork(
|
||||||
|
struct xfs_inode_log_item *iip,
|
||||||
|
struct xfs_log_iovec *vecp,
|
||||||
|
int *nvecs)
|
||||||
|
{
|
||||||
|
struct xfs_inode *ip = iip->ili_inode;
|
||||||
|
size_t data_bytes;
|
||||||
|
|
||||||
switch (ip->i_d.di_format) {
|
switch (ip->i_d.di_format) {
|
||||||
case XFS_DINODE_FMT_EXTENTS:
|
case XFS_DINODE_FMT_EXTENTS:
|
||||||
|
@ -271,12 +249,11 @@ xfs_inode_item_format(
|
||||||
ASSERT(vecp->i_len <= ip->i_df.if_bytes);
|
ASSERT(vecp->i_len <= ip->i_df.if_bytes);
|
||||||
iip->ili_format.ilf_dsize = vecp->i_len;
|
iip->ili_format.ilf_dsize = vecp->i_len;
|
||||||
vecp++;
|
vecp++;
|
||||||
nvecs++;
|
(*nvecs)++;
|
||||||
} else {
|
} else {
|
||||||
iip->ili_fields &= ~XFS_ILOG_DEXT;
|
iip->ili_fields &= ~XFS_ILOG_DEXT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XFS_DINODE_FMT_BTREE:
|
case XFS_DINODE_FMT_BTREE:
|
||||||
iip->ili_fields &=
|
iip->ili_fields &=
|
||||||
~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
|
~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
|
||||||
|
@ -289,7 +266,7 @@ xfs_inode_item_format(
|
||||||
vecp->i_len = ip->i_df.if_broot_bytes;
|
vecp->i_len = ip->i_df.if_broot_bytes;
|
||||||
vecp->i_type = XLOG_REG_TYPE_IBROOT;
|
vecp->i_type = XLOG_REG_TYPE_IBROOT;
|
||||||
vecp++;
|
vecp++;
|
||||||
nvecs++;
|
(*nvecs)++;
|
||||||
iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;
|
iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;
|
||||||
} else {
|
} else {
|
||||||
ASSERT(!(iip->ili_fields &
|
ASSERT(!(iip->ili_fields &
|
||||||
|
@ -297,7 +274,6 @@ xfs_inode_item_format(
|
||||||
iip->ili_fields &= ~XFS_ILOG_DBROOT;
|
iip->ili_fields &= ~XFS_ILOG_DBROOT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XFS_DINODE_FMT_LOCAL:
|
case XFS_DINODE_FMT_LOCAL:
|
||||||
iip->ili_fields &=
|
iip->ili_fields &=
|
||||||
~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
|
~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
|
||||||
|
@ -319,13 +295,12 @@ xfs_inode_item_format(
|
||||||
vecp->i_len = (int)data_bytes;
|
vecp->i_len = (int)data_bytes;
|
||||||
vecp->i_type = XLOG_REG_TYPE_ILOCAL;
|
vecp->i_type = XLOG_REG_TYPE_ILOCAL;
|
||||||
vecp++;
|
vecp++;
|
||||||
nvecs++;
|
(*nvecs)++;
|
||||||
iip->ili_format.ilf_dsize = (unsigned)data_bytes;
|
iip->ili_format.ilf_dsize = (unsigned)data_bytes;
|
||||||
} else {
|
} else {
|
||||||
iip->ili_fields &= ~XFS_ILOG_DDATA;
|
iip->ili_fields &= ~XFS_ILOG_DDATA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XFS_DINODE_FMT_DEV:
|
case XFS_DINODE_FMT_DEV:
|
||||||
iip->ili_fields &=
|
iip->ili_fields &=
|
||||||
~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
|
~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
|
||||||
|
@ -335,7 +310,6 @@ xfs_inode_item_format(
|
||||||
ip->i_df.if_u2.if_rdev;
|
ip->i_df.if_u2.if_rdev;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XFS_DINODE_FMT_UUID:
|
case XFS_DINODE_FMT_UUID:
|
||||||
iip->ili_fields &=
|
iip->ili_fields &=
|
||||||
~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
|
~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
|
||||||
|
@ -345,20 +319,22 @@ xfs_inode_item_format(
|
||||||
ip->i_df.if_u2.if_uuid;
|
ip->i_df.if_u2.if_uuid;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return vecp;
|
||||||
* If there are no attributes associated with the file, then we're done.
|
}
|
||||||
*/
|
|
||||||
if (!XFS_IFORK_Q(ip)) {
|
STATIC struct xfs_log_iovec *
|
||||||
iip->ili_fields &=
|
xfs_inode_item_format_attr_fork(
|
||||||
~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
|
struct xfs_inode_log_item *iip,
|
||||||
goto out;
|
struct xfs_log_iovec *vecp,
|
||||||
}
|
int *nvecs)
|
||||||
|
{
|
||||||
|
struct xfs_inode *ip = iip->ili_inode;
|
||||||
|
size_t data_bytes;
|
||||||
|
|
||||||
switch (ip->i_d.di_aformat) {
|
switch (ip->i_d.di_aformat) {
|
||||||
case XFS_DINODE_FMT_EXTENTS:
|
case XFS_DINODE_FMT_EXTENTS:
|
||||||
|
@ -386,12 +362,11 @@ xfs_inode_item_format(
|
||||||
#endif
|
#endif
|
||||||
iip->ili_format.ilf_asize = vecp->i_len;
|
iip->ili_format.ilf_asize = vecp->i_len;
|
||||||
vecp++;
|
vecp++;
|
||||||
nvecs++;
|
(*nvecs)++;
|
||||||
} else {
|
} else {
|
||||||
iip->ili_fields &= ~XFS_ILOG_AEXT;
|
iip->ili_fields &= ~XFS_ILOG_AEXT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XFS_DINODE_FMT_BTREE:
|
case XFS_DINODE_FMT_BTREE:
|
||||||
iip->ili_fields &=
|
iip->ili_fields &=
|
||||||
~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
|
~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
|
||||||
|
@ -404,13 +379,12 @@ xfs_inode_item_format(
|
||||||
vecp->i_len = ip->i_afp->if_broot_bytes;
|
vecp->i_len = ip->i_afp->if_broot_bytes;
|
||||||
vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT;
|
vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT;
|
||||||
vecp++;
|
vecp++;
|
||||||
nvecs++;
|
(*nvecs)++;
|
||||||
iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;
|
iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;
|
||||||
} else {
|
} else {
|
||||||
iip->ili_fields &= ~XFS_ILOG_ABROOT;
|
iip->ili_fields &= ~XFS_ILOG_ABROOT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XFS_DINODE_FMT_LOCAL:
|
case XFS_DINODE_FMT_LOCAL:
|
||||||
iip->ili_fields &=
|
iip->ili_fields &=
|
||||||
~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
|
~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
|
||||||
|
@ -431,19 +405,59 @@ xfs_inode_item_format(
|
||||||
vecp->i_len = (int)data_bytes;
|
vecp->i_len = (int)data_bytes;
|
||||||
vecp->i_type = XLOG_REG_TYPE_IATTR_LOCAL;
|
vecp->i_type = XLOG_REG_TYPE_IATTR_LOCAL;
|
||||||
vecp++;
|
vecp++;
|
||||||
nvecs++;
|
(*nvecs)++;
|
||||||
iip->ili_format.ilf_asize = (unsigned)data_bytes;
|
iip->ili_format.ilf_asize = (unsigned)data_bytes;
|
||||||
} else {
|
} else {
|
||||||
iip->ili_fields &= ~XFS_ILOG_ADATA;
|
iip->ili_fields &= ~XFS_ILOG_ADATA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
return vecp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is called to fill in the vector of log iovecs for the given inode
|
||||||
|
* log item. It fills the first item with an inode log format structure,
|
||||||
|
* the second with the on-disk inode structure, and a possible third and/or
|
||||||
|
* fourth with the inode data/extents/b-tree root and inode attributes
|
||||||
|
* data/extents/b-tree root.
|
||||||
|
*/
|
||||||
|
STATIC void
|
||||||
|
xfs_inode_item_format(
|
||||||
|
struct xfs_log_item *lip,
|
||||||
|
struct xfs_log_iovec *vecp)
|
||||||
|
{
|
||||||
|
struct xfs_inode_log_item *iip = INODE_ITEM(lip);
|
||||||
|
struct xfs_inode *ip = iip->ili_inode;
|
||||||
|
uint nvecs;
|
||||||
|
|
||||||
|
vecp->i_addr = &iip->ili_format;
|
||||||
|
vecp->i_len = sizeof(xfs_inode_log_format_t);
|
||||||
|
vecp->i_type = XLOG_REG_TYPE_IFORMAT;
|
||||||
|
vecp++;
|
||||||
|
nvecs = 1;
|
||||||
|
|
||||||
|
vecp->i_addr = &ip->i_d;
|
||||||
|
vecp->i_len = xfs_icdinode_size(ip->i_d.di_version);
|
||||||
|
vecp->i_type = XLOG_REG_TYPE_ICORE;
|
||||||
|
vecp++;
|
||||||
|
nvecs++;
|
||||||
|
|
||||||
|
if (ip->i_d.di_version == 1)
|
||||||
|
xfs_inode_item_format_v1_inode(ip);
|
||||||
|
|
||||||
|
vecp = xfs_inode_item_format_data_fork(iip, vecp, &nvecs);
|
||||||
|
if (XFS_IFORK_Q(ip)) {
|
||||||
|
vecp = xfs_inode_item_format_attr_fork(iip, vecp, &nvecs);
|
||||||
|
} else {
|
||||||
|
iip->ili_fields &=
|
||||||
|
~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now update the log format that goes out to disk from the in-core
|
* Now update the log format that goes out to disk from the in-core
|
||||||
* values. We always write the inode core to make the arithmetic
|
* values. We always write the inode core to make the arithmetic
|
||||||
|
@ -455,7 +469,6 @@ out:
|
||||||
iip->ili_format.ilf_size = nvecs;
|
iip->ili_format.ilf_size = nvecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called to pin the inode associated with the inode log
|
* This is called to pin the inode associated with the inode log
|
||||||
* item in memory so it cannot be written out.
|
* item in memory so it cannot be written out.
|
||||||
|
|
Loading…
Reference in New Issue