struct xfs_ifork_ops *ifork_ops)
{
struct xfs_inode *ip;
+ struct xfs_dinode *dip;
+ struct xfs_buf *bp;
int error = 0;
ip = kmem_zone_zalloc(xfs_inode_zone, 0);
ip->i_ino = ino;
ip->i_mount = mp;
- error = xfs_iread(mp, tp, ip, 0);
- if (error) {
- kmem_cache_free(xfs_inode_zone, ip);
- *ipp = NULL;
- return error;
- }
+ error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, 0);
+ if (error)
+ goto out_destroy;
+
+ error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0);
+ if (error)
+ goto out_destroy;
+
+ error = xfs_inode_from_disk(ip, dip);
+ if (!error)
+ xfs_buf_set_ref(bp, XFS_INO_REF);
+ xfs_trans_brelse(tp, bp);
+
+ if (error)
+ goto out_destroy;
ip->i_fork_ops = ifork_ops;
+
if (!libxfs_inode_verify_forks(ip)) {
libxfs_irele(ip);
return -EFSCORRUPTED;
*ipp = ip;
return 0;
+
+out_destroy:
+ kmem_cache_free(xfs_inode_zone, ip);
+ *ipp = NULL;
+ return error;
}
static void
dip->di_crc = xfs_end_cksum(crc);
}
-/*
- * Read the disk inode attributes into the in-core inode structure.
- *
- * For version 5 superblocks, if we are initialising a new inode and we are not
- * utilising the XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new
- * inode core with a random generation number. If we are keeping inodes around,
- * we need to read the inode cluster to get the existing generation number off
- * disk. Further, if we are using version 4 superblocks (i.e. v1/v2 inode
- * format) then log recovery is dependent on the di_flushiter field being
- * initialised from the current on-disk value and hence we must also read the
- * inode off disk.
- */
-int
-xfs_iread(
- xfs_mount_t *mp,
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- uint iget_flags)
-{
- xfs_buf_t *bp;
- xfs_dinode_t *dip;
- int error;
-
- /*
- * Fill in the location information in the in-core inode.
- */
- error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags);
- if (error)
- return error;
-
- /* shortcut IO on inode allocation if possible */
- if ((iget_flags & XFS_IGET_CREATE) &&
- xfs_sb_version_has_v3inode(&mp->m_sb) &&
- !(mp->m_flags & XFS_MOUNT_IKEEP)) {
- VFS_I(ip)->i_generation = prandom_u32();
- return 0;
- }
-
- /*
- * Get pointers to the on-disk inode and the buffer containing it.
- */
- error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0);
- if (error)
- return error;
-
- error = xfs_inode_from_disk(ip, dip);
- if (error)
- goto out_brelse;
-
- /*
- * Mark the buffer containing the inode as something to keep
- * around for a while. This helps to keep recently accessed
- * meta-data in-core longer.
- */
- xfs_buf_set_ref(bp, XFS_INO_REF);
-
- /*
- * Use xfs_trans_brelse() to release the buffer containing the on-disk
- * inode, because it was acquired with xfs_trans_read_buf() in
- * xfs_imap_to_bp() above. If tp is NULL, this is just a normal
- * brelse(). If we're within a transaction, then xfs_trans_brelse()
- * will only release the buffer if it is not dirty within the
- * transaction. It will be OK to release the buffer in this case,
- * because inodes on disk are never destroyed and we will be locking the
- * new in-core inode before putting it in the cache where other
- * processes can find it. Thus we don't have to worry about the inode
- * being changed just because we released the buffer.
- */
- out_brelse:
- xfs_trans_brelse(tp, bp);
- return error;
-}
-
/*
* Validate di_extsize hint.
*
int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
struct xfs_imap *, struct xfs_dinode **,
struct xfs_buf **, uint);
-int xfs_iread(struct xfs_mount *, struct xfs_trans *,
- struct xfs_inode *, uint);
void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to,
xfs_lsn_t lsn);