Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24f211ba authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Niv Sardi
Browse files

[XFS] move inode allocation out xfs_iread



Allocate the inode in xfs_iget_cache_miss and pass it into xfs_iread.  This
simplifies the error handling and allows xfs_iread to be shared with userspace
which already uses these semantics.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <david@fromorbit.com>
Signed-off-by: default avatarNiv Sardi <xaiki@sgi.com>
parent b48d8d64
Loading
Loading
Loading
Loading
+82 −6
Original line number Original line Diff line number Diff line
@@ -40,6 +40,82 @@
#include "xfs_utils.h"
#include "xfs_utils.h"
#include "xfs_trans_priv.h"
#include "xfs_trans_priv.h"
#include "xfs_inode_item.h"
#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_btree_trace.h"
#include "xfs_dir2_trace.h"


/*
 * Allocate and initialise an xfs_inode.
 */
STATIC struct xfs_inode *
xfs_inode_alloc(
	struct xfs_mount	*mp,
	xfs_ino_t		ino)
{
	struct xfs_inode	*ip;

	/*
	 * if this didn't occur in transactions, we could use
	 * KM_MAYFAIL and return NULL here on ENOMEM. Set the
	 * code up to do this anyway.
	 */
	ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
	if (!ip)
		return NULL;

	ASSERT(atomic_read(&ip->i_iocount) == 0);
	ASSERT(atomic_read(&ip->i_pincount) == 0);
	ASSERT(!spin_is_locked(&ip->i_flags_lock));
	ASSERT(completion_done(&ip->i_flush));

	/*
	 * initialise the VFS inode here to get failures
	 * out of the way early.
	 */
	if (!inode_init_always(mp->m_super, VFS_I(ip))) {
		kmem_zone_free(xfs_inode_zone, ip);
		return NULL;
	}

	/* initialise the xfs inode */
	ip->i_ino = ino;
	ip->i_mount = mp;
	memset(&ip->i_imap, 0, sizeof(struct xfs_imap));
	ip->i_afp = NULL;
	memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
	ip->i_flags = 0;
	ip->i_update_core = 0;
	ip->i_update_size = 0;
	ip->i_delayed_blks = 0;
	memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
	ip->i_size = 0;
	ip->i_new_size = 0;

	/*
	 * Initialize inode's trace buffers.
	 */
#ifdef	XFS_INODE_TRACE
	ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_BMAP_TRACE
	ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_BTREE_TRACE
	ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_RW_TRACE
	ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_ILOCK_TRACE
	ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_DIR2_TRACE
	ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
#endif

	return ip;
}


/*
/*
 * Check the validity of the inode we just found it the cache
 * Check the validity of the inode we just found it the cache
@@ -155,13 +231,13 @@ xfs_iget_cache_miss(
	unsigned long		first_index, mask;
	unsigned long		first_index, mask;
	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ino);
	xfs_agino_t		agino = XFS_INO_TO_AGINO(mp, ino);


	/*
	ip = xfs_inode_alloc(mp, ino);
	 * Read the disk inode attributes into a new inode structure and get
	if (!ip)
	 * a new vnode for it. This should also initialize i_ino and i_mount.
		return ENOMEM;
	 */

	error = xfs_iread(mp, tp, ino, &ip, bno, flags);
	error = xfs_iread(mp, tp, ip, bno, flags);
	if (error)
	if (error)
		return error;
		goto out_destroy;


	xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
	xfs_itrace_exit_tag(ip, "xfs_iget.alloc");


+7 −96
Original line number Original line Diff line number Diff line
@@ -758,119 +758,36 @@ xfs_dic2xflags(
}
}


/*
/*
 * Allocate and initialise an xfs_inode.
 * Read the disk inode attributes into the in-core inode structure.
 */
STATIC struct xfs_inode *
xfs_inode_alloc(
	struct xfs_mount	*mp,
	xfs_ino_t		ino)
{
	struct xfs_inode	*ip;

	/*
	 * if this didn't occur in transactions, we could use
	 * KM_MAYFAIL and return NULL here on ENOMEM. Set the
	 * code up to do this anyway.
	 */
	ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
	if (!ip)
		return NULL;

	ASSERT(atomic_read(&ip->i_iocount) == 0);
	ASSERT(atomic_read(&ip->i_pincount) == 0);
	ASSERT(!spin_is_locked(&ip->i_flags_lock));
	ASSERT(completion_done(&ip->i_flush));

	/*
	 * initialise the VFS inode here to get failures
	 * out of the way early.
	 */
	if (!inode_init_always(mp->m_super, VFS_I(ip))) {
		kmem_zone_free(xfs_inode_zone, ip);
		return NULL;
	}

	/* initialise the xfs inode */
	ip->i_ino = ino;
	ip->i_mount = mp;
	memset(&ip->i_imap, 0, sizeof(struct xfs_imap));
	ip->i_afp = NULL;
	memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
	ip->i_flags = 0;
	ip->i_update_core = 0;
	ip->i_update_size = 0;
	ip->i_delayed_blks = 0;
	memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
	ip->i_size = 0;
	ip->i_new_size = 0;

	/*
	 * Initialize inode's trace buffers.
	 */
#ifdef	XFS_INODE_TRACE
	ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_BMAP_TRACE
	ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_BTREE_TRACE
	ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_RW_TRACE
	ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_ILOCK_TRACE
	ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
#endif
#ifdef XFS_DIR2_TRACE
	ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
#endif

	return ip;
}

/*
 * Given a mount structure and an inode number, return a pointer
 * to a newly allocated in-core inode corresponding to the given
 * inode number.
 *
 * Initialize the inode's attributes and extent pointers if it
 * already has them (it will not if the inode has no links).
 */
 */
int
int
xfs_iread(
xfs_iread(
	xfs_mount_t	*mp,
	xfs_mount_t	*mp,
	xfs_trans_t	*tp,
	xfs_trans_t	*tp,
	xfs_ino_t	ino,
	xfs_inode_t	*ip,
	xfs_inode_t	**ipp,
	xfs_daddr_t	bno,
	xfs_daddr_t	bno,
	uint		imap_flags)
	uint		iget_flags)
{
{
	xfs_buf_t	*bp;
	xfs_buf_t	*bp;
	xfs_dinode_t	*dip;
	xfs_dinode_t	*dip;
	xfs_inode_t	*ip;
	int		error;
	int		error;


	ip = xfs_inode_alloc(mp, ino);
	if (!ip)
		return ENOMEM;

	/*
	/*
	 * Fill in the location information in the in-core inode.
	 * Fill in the location information in the in-core inode.
	 */
	 */
	ip->i_imap.im_blkno = bno;
	ip->i_imap.im_blkno = bno;
	error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, imap_flags);
	error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags);
	if (error)
	if (error)
		goto out_destroy_inode;
		return error;
	ASSERT(bno == 0 || bno == ip->i_imap.im_blkno);
	ASSERT(bno == 0 || bno == ip->i_imap.im_blkno);


	/*
	/*
	 * Get pointers to the on-disk inode and the buffer containing it.
	 * Get pointers to the on-disk inode and the buffer containing it.
	 */
	 */
	error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp,
	error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp,
			       XFS_BUF_LOCK, imap_flags);
			       XFS_BUF_LOCK, iget_flags);
	if (error)
	if (error)
		goto out_destroy_inode;
		return error;
	dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset);
	dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset);


	/*
	/*
@@ -968,14 +885,8 @@ xfs_iread(
	 * to worry about the inode being changed just because we released
	 * to worry about the inode being changed just because we released
	 * the buffer.
	 * the buffer.
	 */
	 */
	xfs_trans_brelse(tp, bp);
	*ipp = ip;
	return 0;

 out_brelse:
 out_brelse:
	xfs_trans_brelse(tp, bp);
	xfs_trans_brelse(tp, bp);
 out_destroy_inode:
	xfs_destroy_inode(ip);
	return error;
	return error;
}
}


+2 −2
Original line number Original line Diff line number Diff line
@@ -516,8 +516,8 @@ void xfs_ireclaim(xfs_inode_t *);
/*
/*
 * xfs_inode.c prototypes.
 * xfs_inode.c prototypes.
 */
 */
int		xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
int		xfs_iread(struct xfs_mount *, struct xfs_trans *,
			  xfs_inode_t **, xfs_daddr_t, uint);
			  struct xfs_inode *, xfs_daddr_t, uint);
int		xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
int		xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
			   xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
			   xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
			   int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
			   int, struct xfs_buf **, boolean_t *, xfs_inode_t **);