Skip to content

Commit

Permalink
xfs: factor out a helper to initialize a local format inode fork
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
  • Loading branch information
Christoph Hellwig authored and Dave Chinner committed Apr 5, 2016
1 parent f55532a commit 143f4ae
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 34 deletions.
9 changes: 3 additions & 6 deletions fs/xfs/libxfs/xfs_dir2_sf.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,12 @@ xfs_dir2_block_to_sf(
*
* 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);
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;
memcpy(dp->i_df.if_u1.if_data, dst, size);
dp->i_d.di_size = size;
xfs_dir2_sf_check(args);
out:
xfs_trans_log_inode(args->trans, dp, logflags);
Expand Down
48 changes: 30 additions & 18 deletions fs/xfs/libxfs/xfs_inode_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,34 @@ xfs_iformat_fork(
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.
* If it fits into if_inline_data, then copy
Expand All @@ -248,8 +276,6 @@ xfs_iformat_local(
int whichfork,
int size)
{
xfs_ifork_t *ifp;
int real_size;

/*
* If the size is unreasonable, then something
Expand All @@ -265,22 +291,8 @@ xfs_iformat_local(
ip->i_mount, dip);
return -EFSCORRUPTED;
}
ifp = XFS_IFORK_PTR(ip, whichfork);
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);
}
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;

xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size);
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions fs/xfs/libxfs/xfs_inode_fork.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
int);
void xfs_init_local_fork(struct xfs_inode *, int, const void *, int);

struct xfs_bmbt_rec_host *
xfs_iext_get_ext(struct xfs_ifork *, xfs_extnum_t);
Expand Down
12 changes: 2 additions & 10 deletions fs/xfs/xfs_symlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,11 @@ xfs_symlink(
* If the symlink will fit into the inode, write it inline.
*/
if (pathlen <= XFS_IFORK_DSIZE(ip)) {
xfs_idata_realloc(ip, pathlen, XFS_DATA_FORK);
memcpy(ip->i_df.if_u1.if_data, target_path, 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;
xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);

ip->i_d.di_size = pathlen;
ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);

} else {
int offset;

Expand Down

0 comments on commit 143f4ae

Please sign in to comment.