FreeBSD/sys/fs/ext2fs/ext2_vfsops.c
/*
 * Look up an EXT2FS dinode number to find its incore vnode, otherwise read it
 * in from disk.  If it is in core, wait for the lock bit to clear, then
 * return the inode locked.  Detection and handling of mount points must be
 * done by the calling routine.
 */
Look up an EXT2FS dinode number to find its incore vnode, otherwise read it
in from disk.  If it is in core, wait for the lock bit to clear, then
return the inode locked.  Detection and handling of mount points must be
done by the calling routine.
Look up an EXT2FS dinode number to find its incore vnode otherwise read it in from disk . If it is in core wait for the lock bit to clear then return the inode locked . Detection and handling of mount points must be done by the calling routine .
static int
ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
{
	struct m_ext2fs *fs;
	struct inode *ip;
	struct ext2mount *ump;
	struct buf *bp;
	struct vnode *vp;
	struct thread *td;
	int i, error;
	int used_blocks;
	td = curthread;
	error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL);
	if (error || *vpp != NULL)
		return (error);
	ump = VFSTOEXT2(mp);
	ip = malloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK | M_ZERO);
	if ((error = getnewvnode("ext2fs", mp, &ext2_vnodeops, &vp)) != 0) {
		*vpp = NULL;
		free(ip, M_EXT2NODE);
		return (error);
	}
	vp->v_data = ip;
	ip->i_vnode = vp;
	ip->i_e2fs = fs = ump->um_e2fs;
	ip->i_ump  = ump;
	ip->i_number = ino;
	lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL);
	error = insmntque(vp, mp);
	if (error != 0) {
		free(ip, M_EXT2NODE);
		*vpp = NULL;
		return (error);
	}
	error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL);
	if (error || *vpp != NULL)
		return (error);
	if ((error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
	    (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) {
		brelse(bp);
		vput(vp);
		*vpp = NULL;
		return (error);
	}
	ext2_ei2i((struct ext2fs_dinode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) *
			ino_to_fsbo(fs, ino)), ip);
	ip->i_block_group = ino_to_cg(fs, ino);
	ip->i_next_alloc_block = 0;
	ip->i_next_alloc_goal = 0;
	if (!(ip->i_flag & IN_E4EXTENTS) &&
	    (S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode))) {
		used_blocks = howmany(ip->i_size, fs->e2fs_bsize);
		for (i = used_blocks; i < EXT2_NDIR_BLOCKS; i++)
			ip->i_db[i] = 0;
	}
#ifdef EXT2FS_DEBUG
	ext2_print_inode(ip);
#endif
	bqrelse(bp);
	if ((error = ext2_vinit(mp, &ext2_fifoops, &vp)) != 0) {
		vput(vp);
		*vpp = NULL;
		return (error);
	}
	*vpp = vp;
	return (0);
}
static int ext2_vget ( struct mount * mp , ino_t ino , int flags , struct vnode * * vpp ) { struct m_ext2fs * fs ; struct inode * ip ; struct ext2mount * ump ; struct buf * bp ; struct vnode * vp ; struct thread * td ; int i , error ; int used_blocks ; td = curthread ; error = vfs_hash_get ( mp , ino , flags , td , vpp , NULL , NULL ) ; if ( error || * vpp != NULL ) return ( error ) ; ump = VFSTOEXT2 ( mp ) ; ip = malloc ( sizeof ( struct inode ) , M_EXT2NODE , M_WAITOK | M_ZERO ) ; if ( ( error = getnewvnode ( " " , mp , & ext2_vnodeops , & vp ) ) != 0 ) { * vpp = NULL ; free ( ip , M_EXT2NODE ) ; return ( error ) ; } vp -> v_data = ip ; ip -> i_vnode = vp ; ip -> i_e2fs = fs = ump -> um_e2fs ; ip -> i_ump = ump ; ip -> i_number = ino ; lockmgr ( vp -> v_vnlock , LK_EXCLUSIVE , NULL ) ; error = insmntque ( vp , mp ) ; if ( error != 0 ) { free ( ip , M_EXT2NODE ) ; * vpp = NULL ; return ( error ) ; } error = vfs_hash_insert ( vp , ino , flags , td , vpp , NULL , NULL ) ; if ( error || * vpp != NULL ) return ( error ) ; if ( ( error = bread ( ump -> um_devvp , fsbtodb ( fs , ino_to_fsba ( fs , ino ) ) , ( int ) fs -> e2fs_bsize , NOCRED , & bp ) ) != 0 ) { brelse ( bp ) ; vput ( vp ) ; * vpp = NULL ; return ( error ) ; } ext2_ei2i ( ( struct ext2fs_dinode * ) ( ( char * ) bp -> b_data + EXT2_INODE_SIZE ( fs ) * ino_to_fsbo ( fs , ino ) ) , ip ) ; ip -> i_block_group = ino_to_cg ( fs , ino ) ; ip -> i_next_alloc_block = 0 ; ip -> i_next_alloc_goal = 0 ; if ( ! ( ip -> i_flag & IN_E4EXTENTS ) && ( S_ISDIR ( ip -> i_mode ) || S_ISREG ( ip -> i_mode ) ) ) { used_blocks = howmany ( ip -> i_size , fs -> e2fs_bsize ) ; for ( i = used_blocks ; i < EXT2_NDIR_BLOCKS ; i ++ ) ip -> i_db [ i ] = 0 ; } #ifdef EXT2FS_DEBUG ext2_print_inode ( ip ) ; #endif bqrelse ( bp ) ; if ( ( error = ext2_vinit ( mp , & ext2_fifoops , & vp ) ) != 0 ) { vput ( vp ) ; * vpp = NULL ; return ( error ) ; } * vpp = vp ; return ( 0 ) ; }
Look up an EXT2FS dinode number to find its incore vnode, otherwise read it
 in from disk.
Look up an EXT2FS dinode number to find its incore vnode otherwise read it in from disk .
/* Allocate a new vnode/inode. */ /* Read in the disk contents for the inode, copy into the inode. */ /*
		 * The inode does not contain anything useful, so it would
		 * be misleading to leave it on its hash chain. With mode
		 * still zero, it will be unlinked and returned to the free
		 * list by vput().
		 */ /* convert ext2 inode to dinode */ /*
	 * Now we want to make sure that block pointers for unused
	 * blocks are zeroed out - ext2_balloc depends on this
	 * although for regular files and directories only
	 *
	 * If IN_E4EXTENTS is enabled, unused blocks are not zeroed
	 * out because we could corrupt the extent tree.
	 */ /*
	 * Initialize the vnode from the inode, check for aliases.
	 * Note that the underlying vnode may have changed.
	 */ /*
	 * Finish inode initialization.
	 */