/*
 *  linux/ibcs/open.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/* Keep track of which struct definition we really want */
#include <linux/vfs.h>
#define statfs ibcs_statfs
#include <ibcs/vfs.h>
#undef statfs
#include <linux/types.h>
#include <linux/utime.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/tty.h>
#include <linux/time.h>

#include <asm/segment.h>

#ifdef __cplusplus
extern "C" 
#endif
int ibcs_statfs(const char * path, struct ibcs_statfs * buf)
{
	struct inode * inode;
	struct statfs lxstat;
	struct ibcs_statfs ibcsstat;
	int error;
	int old_fs;

	error = verify_area(VERIFY_WRITE, buf, sizeof(struct ibcs_statfs));
	if (error)
		return error;
	error = namei(path,&inode);
	if (error)
		return error;
	if (!inode->i_sb->s_op->statfs) {
		iput(inode);
		return -ENOSYS;
	}
	old_fs = get_fs();
	set_fs(get_ds());

	inode->i_sb->s_op->statfs(inode->i_sb, &lxstat);

	set_fs(old_fs);
	iput(inode);

	ibcsstat.f_type = lxstat.f_type;
	ibcsstat.f_bsize = lxstat.f_bsize;
	ibcsstat.f_frsize = lxstat.f_bsize;
	ibcsstat.f_blocks = lxstat.f_blocks;
	ibcsstat.f_bfree = lxstat.f_bfree;
	ibcsstat.f_files = lxstat.f_files;
	ibcsstat.f_ffree = lxstat.f_ffree;
	memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname));
	memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack));

	/* Finally, copy it to the user's buffer */
	memcpy_tofs(&ibcsstat, buf, sizeof(ibcsstat));
	return 0;
}

#ifdef __cplusplus
extern "C" 
#endif
int ibcs_fstatfs(unsigned int fd, struct ibcs_statfs * buf)
{
	struct inode * inode;
	struct file * file;
	struct statfs lxstat;
	struct ibcs_statfs ibcsstat;
	int error;
	int old_fs;

	error = verify_area(VERIFY_WRITE, buf, sizeof(struct ibcs_statfs));
	if (error)
		return error;
	if (fd >= NR_OPEN || !(file = current->filp[fd]))
		return -EBADF;
	if (!(inode = file->f_inode))
		return -ENOENT;
	if (!inode->i_sb->s_op->statfs)
		return -ENOSYS;

	old_fs = get_fs();
	set_fs(get_ds());

	inode->i_sb->s_op->statfs(inode->i_sb, &lxstat);

	set_fs(old_fs);


	ibcsstat.f_type = lxstat.f_type;
	ibcsstat.f_bsize = lxstat.f_bsize;
	ibcsstat.f_frsize = lxstat.f_bsize;
	ibcsstat.f_blocks = lxstat.f_blocks;
	ibcsstat.f_bfree = lxstat.f_bfree;
	ibcsstat.f_files = lxstat.f_files;
	ibcsstat.f_ffree = lxstat.f_ffree;
	memset(ibcsstat.f_fname, 0, sizeof(ibcsstat.f_fname));
	memset(ibcsstat.f_fpack, 0, sizeof(ibcsstat.f_fpack));

	/* Finally, copy it to the user's buffer */
	memcpy_tofs(&ibcsstat, buf, sizeof(ibcsstat));
	return 0;
}
