/*****************************************************************************/
/* The development of this program is partly supported by IPA                */
/* (Information-Technology Promotion Agency, Japan).                         */
/*****************************************************************************/

/*****************************************************************************/
/*  ext2_liveinfo.c - gathering live information (ext2 function)             */
/*  Copyright: Copyright (c) Hitachi, Ltd. 2004-2007                         */
/*             Authors: Yumiko Sugita (yumiko.sugita.yf@hitachi.com),        */
/*                      Satoshi Fujiwara (sa-fuji@sdl.hitachi.co.jp)         */
/*                                                                           */
/*  This program is free software; you can redistribute it and/or modify     */
/*  it under the terms of the GNU General Public License as published by     */
/*  the Free Software Foundation; either version 2 of the License, or        */
/*  (at your option) any later version.                                      */
/*                                                                           */
/*  This program is distributed in the hope that it will be useful,          */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
/*  GNU General Public License for more details.                             */
/*                                                                           */
/*  You should have received a copy of the GNU General Public License        */
/*  along with this program; if not, write to the Free Software              */
/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
/*****************************************************************************/

#include <linux/sched.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/ext2_fs.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
#include "ext2.h"
#endif
#include "liveinfo.h"


#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
#  define GET_EXT2_INODE(inode) EXT2_I((inode))
#else
#  define GET_EXT2_INODE(inode)	(&(inode)->u.ext2_i)
#endif

ssize_t ext2_get_fbinfo(struct inode *inode, char *buf, size_t len) {
	int			rc, addr_per_block;
	struct fblocks_info	fbinfo = {0, 0};
	char			*max = buf + len;
	__u32			*i_data;

	i_data = GET_EXT2_INODE(inode)->i_data;
	addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
	rc = get_fbinfo(inode, i_data, EXT2_NDIR_BLOCKS,
			0, addr_per_block, &fbinfo, &buf, max);
	if (rc < 0)
		return rc;
	rc = get_fbinfo(inode, i_data + EXT2_IND_BLOCK, 1,
			1, addr_per_block, &fbinfo, &buf, max);
	if (rc < 0)
		return rc;
	rc = get_fbinfo(inode, i_data + EXT2_DIND_BLOCK, 1,
			2, addr_per_block, &fbinfo, &buf, max);
	if (rc < 0)
		return rc;
	rc = get_fbinfo(inode, i_data + EXT2_TIND_BLOCK, 1,
			3, addr_per_block, &fbinfo, &buf, max);
	if (rc < 0)
		return rc;
	rc = write_fbinfo(&fbinfo, &buf, max);
	if (rc < 0)
		return rc;

	return (len - (max - buf));
}

ssize_t ext2_get_xattr_binfo(struct inode *inode, char *buf, size_t len) {
	struct fblocks_info	fbinfo = {0, 1};
	char 			*buf_sv = buf;
	int			rc;

	fbinfo.bn = GET_EXT2_INODE(inode)->i_file_acl;
	rc = write_fbinfo(&fbinfo, &buf, buf + len);
	if (rc < 0)
		return rc;
	return (buf - buf_sv);
}
