mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
xfs: hoist inode free function to libxfs
Create a libxfs helper function that marks an inode free on disk. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
c1f0bad423
commit
1964435d19
@ -22,6 +22,7 @@
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_iunlink_item.h"
|
||||
#include "xfs_inode_item.h"
|
||||
|
||||
uint16_t
|
||||
xfs_flags2diflags(
|
||||
@ -695,3 +696,54 @@ xfs_bumplink(
|
||||
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
}
|
||||
|
||||
/* Free an inode in the ondisk index and zero it out. */
|
||||
int
|
||||
xfs_inode_uninit(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_perag *pag,
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_icluster *xic)
|
||||
{
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Free the inode first so that we guarantee that the AGI lock is going
|
||||
* to be taken before we remove the inode from the unlinked list. This
|
||||
* makes the AGI lock -> unlinked list modification order the same as
|
||||
* used in O_TMPFILE creation.
|
||||
*/
|
||||
error = xfs_difree(tp, pag, ip->i_ino, xic);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = xfs_iunlink_remove(tp, pag, ip);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* Free any local-format data sitting around before we reset the
|
||||
* data fork to extents format. Note that the attr fork data has
|
||||
* already been freed by xfs_attr_inactive.
|
||||
*/
|
||||
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
|
||||
kfree(ip->i_df.if_data);
|
||||
ip->i_df.if_data = NULL;
|
||||
ip->i_df.if_bytes = 0;
|
||||
}
|
||||
|
||||
VFS_I(ip)->i_mode = 0; /* mark incore inode as free */
|
||||
ip->i_diflags = 0;
|
||||
ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
|
||||
ip->i_forkoff = 0; /* mark the attr fork not in use */
|
||||
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
|
||||
|
||||
/*
|
||||
* Bump the generation count so no one will be confused
|
||||
* by reincarnations of this inode.
|
||||
*/
|
||||
VFS_I(ip)->i_generation++;
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#ifndef __XFS_INODE_UTIL_H__
|
||||
#define __XFS_INODE_UTIL_H__
|
||||
|
||||
struct xfs_icluster;
|
||||
|
||||
uint16_t xfs_flags2diflags(struct xfs_inode *ip, unsigned int xflags);
|
||||
uint64_t xfs_flags2diflags2(struct xfs_inode *ip, unsigned int xflags);
|
||||
uint32_t xfs_dic2xflags(struct xfs_inode *ip);
|
||||
@ -48,6 +50,9 @@ void xfs_trans_ichgtime(struct xfs_trans *tp, struct xfs_inode *ip, int flags);
|
||||
void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args,
|
||||
struct xfs_inode *ip);
|
||||
|
||||
int xfs_inode_uninit(struct xfs_trans *tp, struct xfs_perag *pag,
|
||||
struct xfs_inode *ip, struct xfs_icluster *xic);
|
||||
|
||||
int xfs_iunlink(struct xfs_trans *tp, struct xfs_inode *ip);
|
||||
int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag,
|
||||
struct xfs_inode *ip);
|
||||
|
@ -1945,36 +1945,10 @@ xfs_ifree(
|
||||
|
||||
pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
|
||||
|
||||
/*
|
||||
* Free the inode first so that we guarantee that the AGI lock is going
|
||||
* to be taken before we remove the inode from the unlinked list. This
|
||||
* makes the AGI lock -> unlinked list modification order the same as
|
||||
* used in O_TMPFILE creation.
|
||||
*/
|
||||
error = xfs_difree(tp, pag, ip->i_ino, &xic);
|
||||
error = xfs_inode_uninit(tp, pag, ip, &xic);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = xfs_iunlink_remove(tp, pag, ip);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Free any local-format data sitting around before we reset the
|
||||
* data fork to extents format. Note that the attr fork data has
|
||||
* already been freed by xfs_attr_inactive.
|
||||
*/
|
||||
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
|
||||
kfree(ip->i_df.if_data);
|
||||
ip->i_df.if_data = NULL;
|
||||
ip->i_df.if_bytes = 0;
|
||||
}
|
||||
|
||||
VFS_I(ip)->i_mode = 0; /* mark incore inode as free */
|
||||
ip->i_diflags = 0;
|
||||
ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
|
||||
ip->i_forkoff = 0; /* mark the attr fork not in use */
|
||||
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
|
||||
if (xfs_iflags_test(ip, XFS_IPRESERVE_DM_FIELDS))
|
||||
xfs_iflags_clear(ip, XFS_IPRESERVE_DM_FIELDS);
|
||||
|
||||
@ -1983,13 +1957,6 @@ xfs_ifree(
|
||||
iip->ili_fields &= ~(XFS_ILOG_AOWNER | XFS_ILOG_DOWNER);
|
||||
spin_unlock(&iip->ili_lock);
|
||||
|
||||
/*
|
||||
* Bump the generation count so no one will be confused
|
||||
* by reincarnations of this inode.
|
||||
*/
|
||||
VFS_I(ip)->i_generation++;
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
|
||||
if (xic.deleted)
|
||||
error = xfs_ifree_cluster(tp, pag, ip, &xic);
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user