Skip to content

Commit 1964435

Browse files
author
Darrick J. Wong
committed
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 <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent c1f0bad commit 1964435

File tree

3 files changed

+58
-34
lines changed

3 files changed

+58
-34
lines changed

fs/xfs/libxfs/xfs_inode_util.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "xfs_trace.h"
2323
#include "xfs_ag.h"
2424
#include "xfs_iunlink_item.h"
25+
#include "xfs_inode_item.h"
2526

2627
uint16_t
2728
xfs_flags2diflags(
@@ -695,3 +696,54 @@ xfs_bumplink(
695696

696697
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
697698
}
699+
700+
/* Free an inode in the ondisk index and zero it out. */
701+
int
702+
xfs_inode_uninit(
703+
struct xfs_trans *tp,
704+
struct xfs_perag *pag,
705+
struct xfs_inode *ip,
706+
struct xfs_icluster *xic)
707+
{
708+
struct xfs_mount *mp = ip->i_mount;
709+
int error;
710+
711+
/*
712+
* Free the inode first so that we guarantee that the AGI lock is going
713+
* to be taken before we remove the inode from the unlinked list. This
714+
* makes the AGI lock -> unlinked list modification order the same as
715+
* used in O_TMPFILE creation.
716+
*/
717+
error = xfs_difree(tp, pag, ip->i_ino, xic);
718+
if (error)
719+
return error;
720+
721+
error = xfs_iunlink_remove(tp, pag, ip);
722+
if (error)
723+
return error;
724+
725+
/*
726+
* Free any local-format data sitting around before we reset the
727+
* data fork to extents format. Note that the attr fork data has
728+
* already been freed by xfs_attr_inactive.
729+
*/
730+
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
731+
kfree(ip->i_df.if_data);
732+
ip->i_df.if_data = NULL;
733+
ip->i_df.if_bytes = 0;
734+
}
735+
736+
VFS_I(ip)->i_mode = 0; /* mark incore inode as free */
737+
ip->i_diflags = 0;
738+
ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
739+
ip->i_forkoff = 0; /* mark the attr fork not in use */
740+
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
741+
742+
/*
743+
* Bump the generation count so no one will be confused
744+
* by reincarnations of this inode.
745+
*/
746+
VFS_I(ip)->i_generation++;
747+
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
748+
return 0;
749+
}

fs/xfs/libxfs/xfs_inode_util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef __XFS_INODE_UTIL_H__
77
#define __XFS_INODE_UTIL_H__
88

9+
struct xfs_icluster;
10+
911
uint16_t xfs_flags2diflags(struct xfs_inode *ip, unsigned int xflags);
1012
uint64_t xfs_flags2diflags2(struct xfs_inode *ip, unsigned int xflags);
1113
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);
4850
void xfs_inode_init(struct xfs_trans *tp, const struct xfs_icreate_args *args,
4951
struct xfs_inode *ip);
5052

53+
int xfs_inode_uninit(struct xfs_trans *tp, struct xfs_perag *pag,
54+
struct xfs_inode *ip, struct xfs_icluster *xic);
55+
5156
int xfs_iunlink(struct xfs_trans *tp, struct xfs_inode *ip);
5257
int xfs_iunlink_remove(struct xfs_trans *tp, struct xfs_perag *pag,
5358
struct xfs_inode *ip);

fs/xfs/xfs_inode.c

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,36 +1945,10 @@ xfs_ifree(
19451945

19461946
pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
19471947

1948-
/*
1949-
* Free the inode first so that we guarantee that the AGI lock is going
1950-
* to be taken before we remove the inode from the unlinked list. This
1951-
* makes the AGI lock -> unlinked list modification order the same as
1952-
* used in O_TMPFILE creation.
1953-
*/
1954-
error = xfs_difree(tp, pag, ip->i_ino, &xic);
1948+
error = xfs_inode_uninit(tp, pag, ip, &xic);
19551949
if (error)
19561950
goto out;
19571951

1958-
error = xfs_iunlink_remove(tp, pag, ip);
1959-
if (error)
1960-
goto out;
1961-
1962-
/*
1963-
* Free any local-format data sitting around before we reset the
1964-
* data fork to extents format. Note that the attr fork data has
1965-
* already been freed by xfs_attr_inactive.
1966-
*/
1967-
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
1968-
kfree(ip->i_df.if_data);
1969-
ip->i_df.if_data = NULL;
1970-
ip->i_df.if_bytes = 0;
1971-
}
1972-
1973-
VFS_I(ip)->i_mode = 0; /* mark incore inode as free */
1974-
ip->i_diflags = 0;
1975-
ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
1976-
ip->i_forkoff = 0; /* mark the attr fork not in use */
1977-
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
19781952
if (xfs_iflags_test(ip, XFS_IPRESERVE_DM_FIELDS))
19791953
xfs_iflags_clear(ip, XFS_IPRESERVE_DM_FIELDS);
19801954

@@ -1983,13 +1957,6 @@ xfs_ifree(
19831957
iip->ili_fields &= ~(XFS_ILOG_AOWNER | XFS_ILOG_DOWNER);
19841958
spin_unlock(&iip->ili_lock);
19851959

1986-
/*
1987-
* Bump the generation count so no one will be confused
1988-
* by reincarnations of this inode.
1989-
*/
1990-
VFS_I(ip)->i_generation++;
1991-
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1992-
19931960
if (xic.deleted)
19941961
error = xfs_ifree_cluster(tp, pag, ip, &xic);
19951962
out:

0 commit comments

Comments
 (0)