/*************************************************************
 *                                                           *
 *    ths  Filesystem                  04.10.94      V1.1    *
 *                                                           *
 *    Thomas Scheuermann     ths@ai-lab.fh-furtwangen.de     *
 *                                                           *
 *************************************************************/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/locks.h>
#include <linux/fs.h>
#include <linux/malloc.h>

#include <asm/system.h>
#include <asm/segment.h>
#include <asm/bitops.h>

#include "ths.h"
#include "ths_i.h"

int ths_read(struct inode *in, struct file *fp, char *buffer, int len)
{
	int i,diff;
	long pos;
	struct ths_buffer tbf;
	struct ths_inode_info *ths_inode;
	struct ths_sb_info *ths_sb;
	unsigned char *data;

#ifdef DEBUG
	printk("ths_read : %d Bytes\n",len);
#endif

	ths_inode = (struct ths_inode_info *)&(in->u.generic_ip);
	ths_sb = (struct ths_sb_info *)in->i_sb->u.generic_sbp;

	pos = fp->f_pos;
	if(pos>=in->i_size)
		return 0;

	if(ths_read_cluster(in->i_sb,ths_inode->Cluster,pos,&tbf))
	{
		printk("Fehler\n");
		return -1;
	}
	data = tbf.data[(pos/512)%tbf.sektore];

	i = 0;

	diff = 512-(pos%512);
	if(diff>len)
		diff=len;
	if((pos+diff)>in->i_size)
		diff=in->i_size-pos;
	memcpy_tofs(&buffer[i],&data[pos%512],diff);
	i+=diff;
	pos+=diff;

	if(!((pos/512)%tbf.sektore))
		ths_free_cluster(&tbf);

	for(;i<len && pos<in->i_size;)
	{
		if(!(pos&0x1ff))
		{
			if(!((pos/512)%ths_sb->SektorenProCluster))
			{
				if(ths_read_cluster(in->i_sb,ths_inode->Cluster,pos,&tbf))
				{
					printk("Fehler\n");
					return -1;
				}
			}
			data = tbf.data[(pos/512)%tbf.sektore];
		}
		diff=512;
		if(i+diff>len)
			diff=len-i;
		if((pos+diff)>in->i_size)
			diff=in->i_size-pos;
		memcpy_tofs(&buffer[i],&data[pos%512],diff);
		i+=diff;
		pos+=diff;

		if(!((pos/512)%tbf.sektore))
			ths_free_cluster(&tbf);
	}
	if((pos/512)%ths_sb->SektorenProCluster)
		ths_free_cluster(&tbf);
	fp->f_pos = pos;
	return i;
}



