FreeBSD/sys/fs/ext2fs/ext2_subr.c
/*
 * Return buffer with the contents of block "offset" from the beginning of
 * directory "ip".  If "res" is non-zero, fill it in with a pointer to the
 * remaining space in the directory.
 */
Return buffer with the contents of block "offset" from the beginning of
directory "ip".  If "res" is non-zero, fill it in with a pointer to the
remaining space in the directory.
Return buffer with the contents of block " offset " from the beginning of directory " ip " . If " res " is non - zero fill it in with a pointer to the remaining space in the directory .
int
ext2_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp)
{
	struct inode *ip;
	struct m_ext2fs *fs;
	struct buf *bp;
	e2fs_lbn_t lbn;
	int bsize, error;
	daddr_t newblk;
	struct ext4_extent *ep;
	struct ext4_extent_path path;
	ip = VTOI(vp);
	fs = ip->i_e2fs;
	lbn = lblkno(fs, offset);
	bsize = blksize(fs, ip, lbn);
	*bpp = NULL;
	if (!(ip->i_flag & IN_E4EXTENTS))
		goto normal;
	memset(&path, 0, sizeof(path));
	if (ext4_ext_find_extent(fs, ip, lbn, &path) == NULL)
		goto normal;
	ep = path.ep_ext;
	if (ep == NULL)
		goto normal;
	newblk = lbn - ep->e_blk +
	    (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32);
	if (path.ep_bp != NULL) {
		brelse(path.ep_bp);
		path.ep_bp = NULL;
	}
	error = bread(ip->i_devvp, fsbtodb(fs, newblk), bsize, NOCRED, &bp);
	if (error != 0) {
		brelse(bp);
		return (error);
	}
	if (res)
		*res = (char *)bp->b_data + blkoff(fs, offset);
	bp->b_offset = lbn * bsize;
	*bpp = bp;
	return (0);
normal:
	if (*bpp == NULL) {
		if ((error = bread(vp, lbn, bsize, NOCRED, &bp)) != 0) {
			brelse(bp);
			return (error);
		}
		if (res)
			*res = (char *)bp->b_data + blkoff(fs, offset);
		*bpp = bp;
	}
	return (0);
}
int ext2_blkatoff ( struct vnode * vp , off_t offset , char * * res , struct buf * * bpp ) { struct inode * ip ; struct m_ext2fs * fs ; struct buf * bp ; e2fs_lbn_t lbn ; int bsize , error ; daddr_t newblk ; struct ext4_extent * ep ; struct ext4_extent_path path ; ip = VTOI ( vp ) ; fs = ip -> i_e2fs ; lbn = lblkno ( fs , offset ) ; bsize = blksize ( fs , ip , lbn ) ; * bpp = NULL ; if ( ! ( ip -> i_flag & IN_E4EXTENTS ) ) goto normal ; memset ( & path , 0 , sizeof ( path ) ) ; if ( ext4_ext_find_extent ( fs , ip , lbn , & path ) == NULL ) goto normal ; ep = path . ep_ext ; if ( ep == NULL ) goto normal ; newblk = lbn - ep -> e_blk + ( ep -> e_start_lo | ( daddr_t ) ep -> e_start_hi << 32 ) ; if ( path . ep_bp != NULL ) { brelse ( path . ep_bp ) ; path . ep_bp = NULL ; } error = bread ( ip -> i_devvp , fsbtodb ( fs , newblk ) , bsize , NOCRED , & bp ) ; if ( error != 0 ) { brelse ( bp ) ; return ( error ) ; } if ( res ) * res = ( char * ) bp -> b_data + blkoff ( fs , offset ) ; bp -> b_offset = lbn * bsize ; * bpp = bp ; return ( 0 ) ; normal : if ( * bpp == NULL ) { if ( ( error = bread ( vp , lbn , bsize , NOCRED , & bp ) ) != 0 ) { brelse ( bp ) ; return ( error ) ; } if ( res ) * res = ( char * ) bp -> b_data + blkoff ( fs , offset ) ; * bpp = bp ; } return ( 0 ) ; }
Return buffer with the contents of block "offset" from the beginning of
 directory "ip".
Return buffer with the contents of block " offset " from the beginning of directory " ip " .
/*
	 * IN_E4EXTENTS requires special treatment as we can otherwise fall
	 * back to the normal path.
	 */ /*
	 * If IN_E4EXTENTS is enabled we would get a wrong offset so
	 * reset b_offset here.
	 */