xfs: factor out a helper to initialize a local format inode fork
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:
Родитель
f55532a0c0
Коммит
143f4aede7
|
@ -257,15 +257,12 @@ xfs_dir2_block_to_sf(
|
||||||
*
|
*
|
||||||
* Convert the inode to local format and copy the data in.
|
* Convert the inode to local format and copy the data in.
|
||||||
*/
|
*/
|
||||||
dp->i_df.if_flags &= ~XFS_IFEXTENTS;
|
|
||||||
dp->i_df.if_flags |= XFS_IFINLINE;
|
|
||||||
dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
|
|
||||||
ASSERT(dp->i_df.if_bytes == 0);
|
ASSERT(dp->i_df.if_bytes == 0);
|
||||||
xfs_idata_realloc(dp, size, XFS_DATA_FORK);
|
xfs_init_local_fork(dp, XFS_DATA_FORK, dst, size);
|
||||||
|
dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
|
||||||
|
dp->i_d.di_size = size;
|
||||||
|
|
||||||
logflags |= XFS_ILOG_DDATA;
|
logflags |= XFS_ILOG_DDATA;
|
||||||
memcpy(dp->i_df.if_u1.if_data, dst, size);
|
|
||||||
dp->i_d.di_size = size;
|
|
||||||
xfs_dir2_sf_check(args);
|
xfs_dir2_sf_check(args);
|
||||||
out:
|
out:
|
||||||
xfs_trans_log_inode(args->trans, dp, logflags);
|
xfs_trans_log_inode(args->trans, dp, logflags);
|
||||||
|
|
|
@ -231,6 +231,34 @@ xfs_iformat_fork(
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xfs_init_local_fork(
|
||||||
|
struct xfs_inode *ip,
|
||||||
|
int whichfork,
|
||||||
|
const void *data,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||||
|
int real_size = 0;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
ifp->if_u1.if_data = NULL;
|
||||||
|
else if (size <= sizeof(ifp->if_u2.if_inline_data))
|
||||||
|
ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
|
||||||
|
else {
|
||||||
|
real_size = roundup(size, 4);
|
||||||
|
ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
memcpy(ifp->if_u1.if_data, data, size);
|
||||||
|
|
||||||
|
ifp->if_bytes = size;
|
||||||
|
ifp->if_real_bytes = real_size;
|
||||||
|
ifp->if_flags &= ~(XFS_IFEXTENTS | XFS_IFBROOT);
|
||||||
|
ifp->if_flags |= XFS_IFINLINE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The file is in-lined in the on-disk inode.
|
* The file is in-lined in the on-disk inode.
|
||||||
* If it fits into if_inline_data, then copy
|
* If it fits into if_inline_data, then copy
|
||||||
|
@ -248,8 +276,6 @@ xfs_iformat_local(
|
||||||
int whichfork,
|
int whichfork,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
xfs_ifork_t *ifp;
|
|
||||||
int real_size;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the size is unreasonable, then something
|
* If the size is unreasonable, then something
|
||||||
|
@ -265,22 +291,8 @@ xfs_iformat_local(
|
||||||
ip->i_mount, dip);
|
ip->i_mount, dip);
|
||||||
return -EFSCORRUPTED;
|
return -EFSCORRUPTED;
|
||||||
}
|
}
|
||||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
||||||
real_size = 0;
|
xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size);
|
||||||
if (size == 0)
|
|
||||||
ifp->if_u1.if_data = NULL;
|
|
||||||
else if (size <= sizeof(ifp->if_u2.if_inline_data))
|
|
||||||
ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
|
|
||||||
else {
|
|
||||||
real_size = roundup(size, 4);
|
|
||||||
ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
|
|
||||||
}
|
|
||||||
ifp->if_bytes = size;
|
|
||||||
ifp->if_real_bytes = real_size;
|
|
||||||
if (size)
|
|
||||||
memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);
|
|
||||||
ifp->if_flags &= ~XFS_IFEXTENTS;
|
|
||||||
ifp->if_flags |= XFS_IFINLINE;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ void xfs_iroot_realloc(struct xfs_inode *, int, int);
|
||||||
int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
|
int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
|
||||||
int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
|
int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
|
||||||
int);
|
int);
|
||||||
|
void xfs_init_local_fork(struct xfs_inode *, int, const void *, int);
|
||||||
|
|
||||||
struct xfs_bmbt_rec_host *
|
struct xfs_bmbt_rec_host *
|
||||||
xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t);
|
xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t);
|
||||||
|
|
|
@ -302,19 +302,11 @@ xfs_symlink(
|
||||||
* If the symlink will fit into the inode, write it inline.
|
* If the symlink will fit into the inode, write it inline.
|
||||||
*/
|
*/
|
||||||
if (pathlen <= XFS_IFORK_DSIZE(ip)) {
|
if (pathlen <= XFS_IFORK_DSIZE(ip)) {
|
||||||
xfs_idata_realloc(ip, pathlen, XFS_DATA_FORK);
|
xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
|
||||||
memcpy(ip->i_df.if_u1.if_data, target_path, pathlen);
|
|
||||||
ip->i_d.di_size = pathlen;
|
ip->i_d.di_size = pathlen;
|
||||||
|
|
||||||
/*
|
|
||||||
* The inode was initially created in extent format.
|
|
||||||
*/
|
|
||||||
ip->i_df.if_flags &= ~(XFS_IFEXTENTS | XFS_IFBROOT);
|
|
||||||
ip->i_df.if_flags |= XFS_IFINLINE;
|
|
||||||
|
|
||||||
ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
|
ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
|
||||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
|
xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче